Changeset 24107 for main/trunk


Ignore:
Timestamp:
2011-06-01T12:33:42+12:00 (13 years ago)
Author:
sjm84
Message:

Updating the ExifTool perl modules

Location:
main/trunk/greenstone2/perllib/cpan
Files:
89 added
87 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone2/perllib/cpan/File/RandomAccess.pm

    r16844 r24107  
    44# Description:  Buffer to support random access reading of sequential file
    55#
    6 # Revisions:    02/11/04 - P. Harvey Created
    7 #               02/20/04 - P. Harvey Added flag to disable SeekTest in new()
    8 #               11/18/04 - P. Harvey Fixed bug with seek relative to end of file
    9 #               01/02/05 - P. Harvey Added DEBUG code
    10 #               01/09/06 - P. Harvey Fixed bug in ReadLine() when using
    11 #                          multi-character EOL sequences
    12 #               02/20/06 - P. Harvey Fixed bug where seek past end of file could
    13 #                          generate "substr outside string" warning
    14 #               06/10/06 - P. Harvey Decreased $CHUNK_SIZE from 64k to 8k
    15 #               11/23/06 - P. Harvey Limit reads to < 0x80000000 bytes
     6# Revisions:    02/11/2004 - P. Harvey Created
     7#               02/20/2004 - P. Harvey Added flag to disable SeekTest in new()
     8#               11/18/2004 - P. Harvey Fixed bug with seek relative to end of file
     9#               01/02/2005 - P. Harvey Added DEBUG code
     10#               01/09/2006 - P. Harvey Fixed bug in ReadLine() when using
     11#                            multi-character EOL sequences
     12#               02/20/2006 - P. Harvey Fixed bug where seek past end of file could
     13#                            generate "substr outside string" warning
     14#               06/10/2006 - P. Harvey Decreased $CHUNK_SIZE from 64k to 8k
     15#               11/23/2006 - P. Harvey Limit reads to < 0x80000000 bytes
     16#               11/26/2008 - P. Harvey Fixed bug in ReadLine when reading from a
     17#                            scalar with a multi-character newline
     18#               01/24/2009 - PH Protect against reading too much at once
    1619#
    1720# Notes:        Calls the normal file i/o routines unless SeekTest() fails, in
     
    2225#               May also be used for string i/o (just pass a scalar reference)
    2326#
    24 # Legal:        Copyright (c) 2004-2006 Phil Harvey (phil at owl.phy.queensu.ca)
     27# Legal:        Copyright (c) 2003-2010 Phil Harvey (phil at owl.phy.queensu.ca)
    2528#               This library is free software; you can redistribute it and/or
    2629#               modify it under the same terms as Perl itself.
     
    3437
    3538use vars qw($VERSION @ISA @EXPORT_OK);
    36 $VERSION = '1.07';
     39$VERSION = '1.10';
    3740@ISA = qw(Exporter);
     41
     42sub Read($$$);
    3843
    3944# constants
     
    6469        # file i/o
    6570        my $buff = '';
    66         $self = { 
     71        $self = {
    6772            FILE_PT => $filePt, # file pointer
    6873            BUFF_PT => \$buff,  # reference to file data
     
    156161#------------------------------------------------------------------------------
    157162# Read from the file
    158 # Inputs: 0) reference to RandomAccess object
    159 #         1) buffer, 2) bytes to read
     163# Inputs: 0) reference to RandomAccess object, 1) buffer, 2) bytes to read
    160164# Returns: Number of bytes read
    161165sub Read($$$)
     
    165169    my $rtnVal;
    166170
    167     # avoid dying with "Negative length" error
    168     return 0 if $len & 0x80000000;
    169 
     171    # protect against reading too much at once
     172    # (also from dying with a "Negative length" error)
     173    if ($len & 0xf8000000) {
     174        return 0 if $len < 0;
     175        # read in smaller blocks because Windows attempts to pre-allocate
     176        # memory for the full size, which can lead to an out-of-memory error
     177        my $maxLen = 0x4000000; # (MUST be less than bitmask in "if" above)
     178        my $num = Read($self, $_[0], $maxLen);
     179        return $num if $num < $maxLen;
     180        for (;;) {
     181            $len -= $maxLen;
     182            last if $len <= 0;
     183            my $l = $len < $maxLen ? $len : $maxLen;
     184            my $buff;
     185            my $n = Read($self, $buff, $l);
     186            last unless $n;
     187            $_[0] .= $buff;
     188            $num += $n;
     189            last if $n < $l;
     190        }
     191        return $num;
     192    }
     193    # read through our buffer if necessary
    170194    if ($self->{TESTED} < 0) {
    171195        my $buff;
     
    196220        $self->{POS} += $rtnVal;
    197221    } else {
     222        # read directly from file
    198223        $_[0] = '' unless defined $_[0];
    199224        $rtnVal = read($self->{FILE_PT}, $_[0], $len) || 0;
     
    204229            $self->{DEBUG}->{$pos} = $rtnVal;
    205230        }
    206     } 
     231    }
    207232    return $rtnVal;
    208233}
     
    217242    my $rtnVal;
    218243    my $fp = $self->{FILE_PT};
    219    
     244
    220245    if ($self->{TESTED} < 0) {
    221246        my ($num, $buff);
     
    231256            # scan and read until we find the EOL (or hit EOF)
    232257            for (;;) {
    233                 $pos = index(${$self->{BUFF_PT}}, $/, $pos) + length($/);
    234                 last if $pos > 0;
     258                $pos = index(${$self->{BUFF_PT}}, $/, $pos);
     259                if ($pos >= 0) {
     260                    $pos += length($/);
     261                    last;
     262                }
    235263                $pos = $self->{LEN};    # have scanned to end of buffer
    236264                $num = read($fp, $buff, $CHUNK_SIZE) or last;
     
    240268        } else {
    241269            # string i/o
    242             $pos = index(${$self->{BUFF_PT}}, $/, $pos) + length($/);
    243             $pos <= 0 and $pos = $self->{LEN};
     270            $pos = index(${$self->{BUFF_PT}}, $/, $pos);
     271            if ($pos < 0) {
     272                $pos = $self->{LEN};
     273                $self->{POS} = $pos if $self->{POS} > $pos;
     274            } else {
     275                $pos += length($/);
     276            }
    244277        }
    245278        # read the line from our buffer
     
    260293            $self->{DEBUG}->{$pos} = $rtnVal;
    261294        }
    262     } 
    263     return $rtnVal; 
     295    }
     296    return $rtnVal;
    264297}
    265298
     
    295328{
    296329    my $self = shift;
    297    
     330
    298331    if ($self->{DEBUG}) {
    299332        local $_;
  • main/trunk/greenstone2/perllib/cpan/File/RandomAccess.pod

    r16844 r24107  
    44# Description:  Buffer to support random access reading of sequential file
    55#
    6 # Legal:        Copyright (c) 2004-2006 Phil Harvey (phil at owl.phy.queensu.ca)
     6# Legal:        Copyright (c) 2003-2010 Phil Harvey (phil at owl.phy.queensu.ca)
    77#               This library is free software; you can redistribute it and/or
    88#               modify it under the same terms as Perl itself.
     
    218218=head1 AUTHOR
    219219
    220 Copyright 2004-2006 Phil Harvey (phil at owl.phy.queensu.ca)
     220Copyright 2003-2011 Phil Harvey (phil at owl.phy.queensu.ca)
    221221
    222222This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool.pm

    r23771 r24107  
    66# URL:          http://owl.phy.queensu.ca/~phil/exiftool/
    77#
    8 # Revisions:    Nov. 12/03 - P. Harvey Created
     8# Revisions:    Nov. 12/2003 - P. Harvey Created
    99#               (See html/history.html for revision history)
    1010#
    11 # Legal:        Copyright (c) 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     11# Legal:        Copyright (c) 2003-2010, Phil Harvey (phil at owl.phy.queensu.ca)
    1212#               This library is free software; you can redistribute it and/or
    1313#               modify it under the same terms as Perl itself.
     
    2020require Exporter;
    2121use File::RandomAccess;
    22    
     22
    2323use vars qw($VERSION $RELEASE @ISA %EXPORT_TAGS $AUTOLOAD @fileTypes %allTables
    24             @tableOrder $exifAPP1hdr $xmpAPP1hdr $psAPP13hdr $psAPP13old
    25             @loadAllTables %UserDefined $evalWarning);
    26 
    27 $VERSION = '7.00';
     24            @tableOrder $exifAPP1hdr $xmpAPP1hdr $xmpExtAPP1hdr $psAPP13hdr
     25            $psAPP13old @loadAllTables %UserDefined $evalWarning %noWriteFile
     26            %magicNumber @langs $defaultLang %langName %charsetName %mimeType
     27            $swapBytes $swapWords $currentByteOrder %unpackStd);
     28
     29$VERSION = '8.57';
    2830$RELEASE = '';
    2931@ISA = qw(Exporter);
    3032%EXPORT_TAGS = (
    31     # all public non-object-oriented functions
     33    # all public non-object-oriented functions:
    3234    Public => [qw(
    3335        ImageInfo GetTagName GetShortcuts GetAllTags GetWritableTags
    3436        GetAllGroups GetDeleteGroups GetFileType CanWrite CanCreate
    3537    )],
     38    # exports not part of the public API, but used by ExifTool modules:
    3639    DataAccess => [qw(
    3740        ReadValue GetByteOrder SetByteOrder ToggleByteOrder Get8u Get8s Get16u
    38         Get16s Get32u Get32s GetFloat GetDouble GetFixed32s Write WriteValue
    39         Tell Set8u Set8s Set16u Set32u
     41        Get16s Get32u Get32s Get64u GetFloat GetDouble GetFixed32s Write
     42        WriteValue Tell Set8u Set8s Set16u Set32u
    4043    )],
    41     Utils => [qw(
    42         GetTagTable TagTableKeys GetTagInfoList GenerateTagIDs SetFileType
    43         HtmlDump
    44     )],
    45     Vars => [qw(
    46         %allTables @tableOrder @fileTypes
    47     )],
     44    Utils => [qw(GetTagTable TagTableKeys GetTagInfoList)],
     45    Vars  => [qw(%allTables @tableOrder @fileTypes)],
    4846);
    4947# set all of our EXPORT_TAGS in EXPORT_OK
     
    5452
    5553# The following functions defined in Image::ExifTool::Writer are declared
    56 # here so their prototypes will be available.  The Writer routines will be
    57 # autoloaded when any of these are called.
     54# here so their prototypes will be available.  These Writer routines will be
     55# autoloaded when any of them is called.
    5856sub SetNewValue($;$$%);
    5957sub SetNewValuesFromFile($$;@);
     
    7472sub IsWritable($);
    7573sub GetNewFileName($$);
     74sub NextTagKey($$);
    7675sub LoadAllTables();
    7776sub GetNewTagInfoList($;$);
     
    8887sub VerboseInfo($$$%);
    8988sub VerboseDir($$;$$);
     89sub VerboseValue($$$;$);
    9090sub VPrint($$@);
    9191sub Rationalize($;$);
    9292sub Write($@);
    93 sub ProcessTrailers($$);
    9493sub WriteTrailerBuffer($$$);
    9594sub AddNewTrailers($;@);
     
    10099sub CheckBinaryData($$$);
    101100sub WriteTIFF($$$);
    102 sub Charset2Unicode($$;$);
    103 sub Latin2Unicode($$);
    104 sub UTF82Unicode($$;$);
    105 sub Unicode2Charset($$;$);
    106 sub Unicode2Latin($$;$);
    107 sub Unicode2UTF8($$);
    108101sub PackUTF8(@);
    109102sub UnpackUTF8($);
     103sub SetPreferredByteOrder($);
     104sub CopyBlock($$$);
     105sub CopyFileAttrs($$);
     106
     107# other subroutine definitions
     108sub DoEscape($$);
     109sub ConvertFileSize($);
     110sub ParseArguments($;@); #(defined in attempt to avoid mod_perl problem)
    110111
    111112# list of main tag tables to load in LoadAllTables() (sub-tables are recursed
    112113# automatically).  Note: They will appear in this order in the documentation
    113 # (unless tweaked in BuildTagLookup::GetTableOrder()), so put Exif first.
     114# unless tweaked in BuildTagLookup::GetTableOrder().
    114115@loadAllTables = qw(
    115     PhotoMechanic Exif GeoTiff CanonRaw KyoceraRaw MinoltaRaw SigmaRaw JPEG
    116     Jpeg2000 BMP BMP PICT PNG MNG MIFF PDF PostScript Photoshop::Header
    117     FujiFilm::RAF Panasonic::Raw Sony::SR2SubIFD ID3 Vorbis FLAC APE
    118     APE::NewHeader APE::OldHeader MPC MPEG::Audio MPEG::Video QuickTime
    119     QuickTime::ImageFile Flash Flash::FLV Real::Media Real::Audio
    120     Real::Metafile RIFF AIFF ASF DICOM MIE HTML
     116    PhotoMechanic Exif GeoTiff CanonRaw KyoceraRaw MinoltaRaw PanasonicRaw
     117    SigmaRaw JPEG GIMP Jpeg2000 GIF BMP BMP::OS2 PICT PNG MNG DjVu PGF MIFF PSP
     118    PDF PostScript Photoshop::Header FujiFilm::RAF Sony::SRF2 Sony::SR2SubIFD
     119    Sony::PMP ITC ID3 Vorbis FLAC APE APE::NewHeader APE::OldHeader MPC
     120    MPEG::Audio MPEG::Video MPEG::Xing M2TS QuickTime QuickTime::ImageFile
     121    Matroska MXF DV Flash Flash::FLV Real::Media Real::Audio Real::Metafile RIFF
     122    AIFF ASF DICOM MIE HTML XMP::SVG EXE EXE::PEVersion EXE::PEString EXE::MachO
     123    EXE::PEF EXE::ELF LNK Font RSRC Rawzor ZIP ZIP::GZIP ZIP::RAR RTF OOXML
     124    iWork
     125);
     126
     127# alphabetical list of current Lang modules
     128@langs = qw(cs de en en_ca en_gb es fr it ja ko nl pl ru sv tr zh_cn zh_tw);
     129
     130$defaultLang = 'en';    # default language
     131
     132# language names
     133%langName = (
     134    cs => 'Czech (ČeÅ¡tina)',
     135    de => 'German (Deutsch)',
     136    en => 'English',
     137    en_ca => 'Canadian English',
     138    en_gb => 'British English',
     139    es => 'Spanish (Español)',
     140    fr => 'French (Français)',
     141    it => 'Italian (Italiano)',
     142    ja => 'Japanese (日本語)',
     143    ko => 'Korean (한국얎)',
     144    nl => 'Dutch (Nederlands)',
     145    pl => 'Polish (Polski)',
     146    ru => 'Russian (РусскОй)',
     147    sv => 'Swedish (Svenska)',
     148   'tr'=> 'Turkish (TÃŒrkçe)',
     149    zh_cn => 'Simplified Chinese (简䜓䞭文)',
     150    zh_tw => 'Traditional Chinese (繁體䞭文)',
    121151);
    122152
    123153# recognized file types, in the order we test unknown files
    124154# Notes: 1) There is no need to test for like types separately here
    125 # 2) Put types with no file signature at end of list to avoid false matches
     155# 2) Put types with weak file signatures at end of list to avoid false matches
    126156@fileTypes = qw(JPEG CRW TIFF GIF MRW RAF X3F JP2 PNG MIE MIFF PS PDF PSD XMP
    127                 BMP PPM RIFF AIFF ASF MOV MPEG Real SWF FLV OGG FLAC APE MPC
    128                 ICC HTML VRD QTIF FPX PICT MP3 DICM RAW);
     157                BMP PPM RIFF AIFF ASF MOV MPEG Real SWF PSP FLV OGG FLAC APE MPC
     158                MKV MXF DV PMP IND PGF ICC ITC HTML VRD RTF XCF QTIF FPX PICT
     159                ZIP GZIP RAR BZ2 TAR RWZ EXE LNK RAW Font RSRC M2TS MP3 DICM);
    129160
    130161# file types that we can write (edit)
    131 my @writeTypes = qw(JPEG TIFF GIF CRW MRW ORF PNG MIE PSD XMP PPM EPS PS ICC
    132                     VRD JP2);
     162my @writeTypes = qw(JPEG TIFF GIF CRW MRW ORF RAF RAW PNG MIE PSD XMP PPM
     163                    EPS X3F PS PDF ICC VRD JP2 EXIF AI AIT IND);
     164
     165# file extensions that we can't write for various base types
     166%noWriteFile = (
     167    TIFF => [ qw(3FR DCR K25 KDC SRF) ],
     168    XMP  => [ 'SVG' ],
     169);
    133170
    134171# file types that we can create from scratch
    135 my @createTypes = qw(XMP ICC MIE VRD);
     172# - must update CanCreate() documentation if this list is changed!
     173my %createTypes = (XMP=>1, ICC=>1, MIE=>1, VRD=>1, EXIF=>1);
    136174
    137175# file type lookup for all recognized file extensions
    138176my %fileTypeLookup = (
     177   '3FR' => ['TIFF', 'Hasselblad RAW format'],
     178   '3G2' => ['MOV',  '3rd Gen. Partnership Project 2 audio/video'],
     179   '3GP' => ['MOV',  '3rd Gen. Partnership Project audio/video'],
     180   '3GP2'=>  '3G2',
     181   '3GPP'=>  '3GP',
    139182    ACR  => ['DICM', 'American College of Radiology ACR-NEMA'],
    140     AI   => [['PDF','PS'], 'Adobe Illustrator (PDF-like or PS-like)'],
    141     AIF  => ['AIFF', 'Audio Interchange File Format'],
     183    ACFM => ['Font', 'Adobe Composite Font Metrics'],
     184    AFM  => ['Font', 'Adobe Font Metrics'],
     185    AMFM => ['Font', 'Adobe Multiple Master Font Metrics'],
     186    AI   => [['PDF','PS'], 'Adobe Illustrator'],
     187    AIF  =>  'AIFF',
    142188    AIFC => ['AIFF', 'Audio Interchange File Format Compressed'],
    143189    AIFF => ['AIFF', 'Audio Interchange File Format'],
     190    AIT  =>  'AI',
    144191    APE  => ['APE',  "Monkey's Audio format"],
    145     ARW  => ['TIFF', 'Sony Alpha RAW format (TIFF-like)'],
     192    ARW  => ['TIFF', 'Sony Alpha RAW format'],
    146193    ASF  => ['ASF',  'Microsoft Advanced Systems Format'],
    147     AVI  => ['RIFF', 'Audio Video Interleaved (RIFF-based)'],
    148     BMP  => ['BMP',  'Windows BitMaP'],
    149     BTF  => ['BTF',  'Big Tagged Image File Format'],
    150     CIFF => ['CRW',  'Camera Image File Format (same as CRW)'],
    151     CR2  => ['TIFF', 'Canon RAW 2 format (TIFF-like)'],
     194    AVI  => ['RIFF', 'Audio Video Interleaved'],
     195    BMP  => ['BMP',  'Windows Bitmap'],
     196    BTF  => ['BTF',  'Big Tagged Image File Format'], #(unofficial)
     197    BZ2  => ['BZ2',  'BZIP2 archive'],
     198    CIFF => ['CRW',  'Camera Image File Format'],
     199    COS  => ['COS',  'Capture One Settings'],
     200    CR2  => ['TIFF', 'Canon RAW 2 format'],
    152201    CRW  => ['CRW',  'Canon RAW format'],
    153     CS1  => ['PSD',  'Sinar CaptureShop 1-Shot RAW (PSD-like)'],
    154     DC3  => ['DICM', 'DICOM image file'],
    155     DCM  => ['DICM', 'DICOM image file'],
    156     DIB  => ['BMP',  'Device Independent Bitmap (aka. BMP)'],
    157     DIC  => ['DICM', 'DICOM image file'],
    158     DICM => ['DICM', 'DICOM image file'],
    159     DNG  => ['TIFF', 'Digital Negative (TIFF-like)'],
    160     DCR  => ['TIFF', 'Kodak Digital Camera RAW (TIFF-like)'],
    161     DOC  => ['FPX',  'Microsoft Word Document (FPX-like)'],
     202    CS1  => ['PSD',  'Sinar CaptureShop 1-Shot RAW'],
     203    DC3  =>  'DICM',
     204    DCM  =>  'DICM',
     205    DCP  => ['TIFF', 'DNG Camera Profile'],
     206    DCR  => ['TIFF', 'Kodak Digital Camera RAW'],
     207    DFONT=> ['Font', 'Macintosh Data fork Font'],
     208    DIB  => ['BMP',  'Device Independent Bitmap'],
     209    DIC  =>  'DICM',
     210    DICM => ['DICM', 'Digital Imaging and Communications in Medicine'],
     211    DIVX => ['ASF',  'DivX media format'],
     212    DJV  =>  'DJVU',
     213    DJVU => ['AIFF', 'DjVu image'],
     214    DLL  => ['EXE',  'Windows Dynamic Link Library'],
     215    DNG  => ['TIFF', 'Digital Negative'],
     216    DOC  => ['FPX',  'Microsoft Word Document'],
     217    DOCM => [['ZIP','FPX'], 'Office Open XML Document Macro-enabled'],
     218    # Note: I have seen a password-protected DOCX file which was FPX-like, so I assume
     219    # that any other MS Office file could be like this too.  The only difference is
     220    # that the ZIP and FPX formats are checked first, so if this is wrong, no biggie.
     221    DOCX => [['ZIP','FPX'], 'Office Open XML Document'],
     222    DOT  => ['FPX',  'Microsoft Word Template'],
     223    DOTM => [['ZIP','FPX'], 'Office Open XML Document Template Macro-enabled'],
     224    DOTX => [['ZIP','FPX'], 'Office Open XML Document Template'],
     225    DV   => ['DV',   'Digital Video'],
     226    DVB  => ['MOV',  'Digital Video Broadcasting'],
     227    DYLIB=> ['EXE',  'Mach-O Dynamic Link Library'],
     228    EIP  => ['ZIP',  'Capture One Enhanced Image Package'],
    162229    EPS  => ['EPS',  'Encapsulated PostScript Format'],
    163     EPSF => ['EPS',  'Encapsulated PostScript Format'],
    164     ERF  => ['TIFF', 'Epson Raw Format (TIFF-like)'],
     230    EPS2 =>  'EPS',
     231    EPS3 =>  'EPS',
     232    EPSF =>  'EPS',
     233    ERF  => ['TIFF', 'Epson Raw Format'],
     234    EXE  => ['EXE',  'Windows executable file'],
     235    EXIF => ['EXIF', 'Exchangable Image File Metadata'],
     236    F4A  => ['MOV',  'Adobe Flash Player 9+ Audio'],
     237    F4B  => ['MOV',  'Adobe Flash Player 9+ audio Book'],
     238    F4P  => ['MOV',  'Adobe Flash Player 9+ Protected'],
     239    F4V  => ['MOV',  'Adobe Flash Player 9+ Video'],
    165240    FLAC => ['FLAC', 'Free Lossless Audio Codec'],
     241    FLA  => ['FPX',  'Macromedia/Adobe Flash project'],
    166242    FLV  => ['FLV',  'Flash Video'],
    167243    FPX  => ['FPX',  'FlashPix'],
    168244    GIF  => ['GIF',  'Compuserve Graphics Interchange Format'],
    169     HTM  => ['HTML', 'HyperText Markup Language'],
     245    GZ   =>  'GZIP',
     246    GZIP => ['GZIP', 'GNU ZIP compressed archive'],
     247    HDP  => ['TIFF', 'Windows HD Photo'],
     248    HTM  =>  'HTML',
    170249    HTML => ['HTML', 'HyperText Markup Language'],
    171250    ICC  => ['ICC',  'International Color Consortium'],
    172     ICM  => ['ICC',  'International Color Consortium'],
    173     JNG  => ['PNG',  'JPG Network Graphics (PNG-like)'],
     251    ICM  =>  'ICC',
     252    IIQ  => ['TIFF', 'Phase One Intelligent Image Quality RAW'],
     253    IND  => ['IND',  'Adobe InDesign'],
     254    INDD => ['IND',  'Adobe InDesign Document'],
     255    INDT => ['IND',  'Adobe InDesign Template'],
     256    ITC  => ['ITC',  'iTunes Cover Flow'],
     257    JNG  => ['PNG',  'JPG Network Graphics'],
    174258    JP2  => ['JP2',  'JPEG 2000 file'],
    175     JPEG => ['JPEG', 'Joint Photographic Experts Group'],
     259    # JP4? - looks like a JPEG but the image data is different
     260    JPEG =>  'JPG',
    176261    JPG  => ['JPEG', 'Joint Photographic Experts Group'],
    177     JPX  => ['JP2',  'JPEG 2000 file'],
    178     K25  => ['TIFF', 'Kodak DC25 RAW (TIFF-like)'],
    179     M4A  => ['MOV',  'MPG4 Audio (QuickTime-based)'],
    180     MEF  => ['TIFF', 'Mamiya (RAW) Electronic Format (TIFF-like)'],
     262    JPM  => ['JP2',  'JPEG 2000 compound image'],
     263    JPX  => ['JP2',  'JPEG 2000 with extensions'],
     264    K25  => ['TIFF', 'Kodak DC25 RAW'],
     265    KDC  => ['TIFF', 'Kodak Digital Camera RAW'],
     266    KEY  => ['ZIP',  'Apple Keynote presentation'],
     267    KTH  => ['ZIP',  'Apple Keynote Theme'],
     268    LNK  => ['LNK',  'Windows shortcut'],
     269    M2T  =>  'M2TS',
     270    M2TS => ['M2TS', 'MPEG-2 Transport Stream'],
     271    M2V  => ['MPEG', 'MPEG-2 Video'],
     272    M4A  => ['MOV',  'MPEG-4 Audio'],
     273    M4B  => ['MOV',  'MPEG-4 audio Book'],
     274    M4P  => ['MOV',  'MPEG-4 Protected'],
     275    M4V  => ['MOV',  'MPEG-4 Video'],
     276    MEF  => ['TIFF', 'Mamiya (RAW) Electronic Format'],
    181277    MIE  => ['MIE',  'Meta Information Encapsulation format'],
    182     MIF  => ['MIFF', 'Magick Image File Format'],
     278    MIF  =>  'MIFF',
    183279    MIFF => ['MIFF', 'Magick Image File Format'],
    184     MNG  => ['PNG',  'Multiple-image Network Graphics (PNG-like)'],
    185     MOS  => ['TIFF', 'Creo Leaf Mosaic (TIFF-like)'],
     280    MKA  => ['MKV',  'Matroska Audio'],
     281    MKS  => ['MKV',  'Matroska Subtitle'],
     282    MKV  => ['MKV',  'Matroska Video'],
     283    MNG  => ['PNG',  'Multiple-image Network Graphics'],
     284  # MODD => ['PLIST','Sony Picture Motion Metadata'],
     285    MOS  => ['TIFF', 'Creo Leaf Mosaic'],
    186286    MOV  => ['MOV',  'Apple QuickTime movie'],
    187     MP3  => ['MP3',  'MPEG Layer 3 audio (uses ID3 information)'],
    188     MP4  => ['MOV',  'MPEG Layer 4 video (QuickTime-based)'],
     287    MP3  => ['MP3',  'MPEG-1 Layer 3 audio'],
     288    MP4  => ['MOV',  'MPEG-4 video'],
    189289    MPC  => ['MPC',  'Musepack Audio'],
    190     MPEG => ['MPEG', 'MPEG audio/video format 1'],
    191     MPG  => ['MPEG', 'MPEG audio/video format 1'],
     290    MPEG => ['MPEG', 'MPEG-1 or MPEG-2 audio/video'],
     291    MPG  =>  'MPEG',
     292    MPO  => ['JPEG', 'Extended Multi-Picture format'],
     293    MQV  => ['MOV',  'Sony Mobile Quicktime Video'],
    192294    MRW  => ['MRW',  'Minolta RAW format'],
    193     NEF  => ['TIFF', 'Nikon (RAW) Electronic Format (TIFF-like)'],
     295    MTS  => ['M2TS', 'MPEG-2 Transport Stream'],
     296    MXF  => ['MXF',  'Material Exchange Format'],
     297  # NDPI => ['TIFF', 'Hamamatsu NanoZoomer Digital Pathology Image'],
     298    NEF  => ['TIFF', 'Nikon (RAW) Electronic Format'],
     299    NEWER => 'COS',
     300    NMBTEMPLATE => ['ZIP','Apple Numbers Template'],
     301    NRW  => ['TIFF', 'Nikon RAW (2)'],
     302    NUMBERS => ['ZIP','Apple Numbers spreadsheet'],
     303    ODP  => ['ZIP',  'Open Document Presentation'],
     304    ODS  => ['ZIP',  'Open Document Spreadsheet'],
     305    ODT  => ['ZIP',  'Open Document Text file'],
    194306    OGG  => ['OGG',  'Ogg Vorbis audio file'],
    195307    ORF  => ['ORF',  'Olympus RAW format'],
    196     PBM  => ['PPM',  'Portable BitMap (PPM-like)'],
    197     PCT  => ['PICT', 'Apple PICTure'],
     308    OTF  => ['Font', 'Open Type Font'],
     309    PAGES => ['ZIP', 'Apple Pages document'],
     310    PBM  => ['PPM',  'Portable BitMap'],
     311    PCT  =>  'PICT',
    198312    PDF  => ['PDF',  'Adobe Portable Document Format'],
    199     PEF  => ['TIFF', 'Pentax (RAW) Electronic Format (TIFF-like)'],
    200     PGM  => ['PPM',  'Portable Gray Map (PPM-like)'],
     313    PEF  => ['TIFF', 'Pentax (RAW) Electronic Format'],
     314    PFA  => ['Font', 'PostScript Font ASCII'],
     315    PFB  => ['Font', 'PostScript Font Binary'],
     316    PFM  => ['Font', 'Printer Font Metrics'],
     317    PGF  => ['PGF',  'Progressive Graphics File'],
     318    PGM  => ['PPM',  'Portable Gray Map'],
    201319    PICT => ['PICT', 'Apple PICTure'],
     320  # PLIST=> ['PLIST','Apple Property List'],
     321    PMP  => ['PMP',  'Sony DSC-F1 Cyber-Shot PMP'], # should stand for Proprietery Metadata Package ;)
    202322    PNG  => ['PNG',  'Portable Network Graphics'],
     323    POT  => ['FPX',  'Microsoft PowerPoint Template'],
     324    POTM => [['ZIP','FPX'], 'Office Open XML Presentation Template Macro-enabled'],
     325    POTX => [['ZIP','FPX'], 'Office Open XML Presentation Template'],
    203326    PPM  => ['PPM',  'Portable Pixel Map'],
    204     PPT  => ['FPX',  'Microsoft PowerPoint presentation (FPX-like)'],
     327    PPS  => ['FPX',  'Microsoft PowerPoint Slideshow'],
     328    PPSM => [['ZIP','FPX'], 'Office Open XML Presentation Slideshow Macro-enabled'],
     329    PPSX => [['ZIP','FPX'], 'Office Open XML Presentation Slideshow'],
     330    PPT  => ['FPX',  'Microsoft PowerPoint Presentation'],
     331    PPTM => [['ZIP','FPX'], 'Office Open XML Presentation Macro-enabled'],
     332    PPTX => [['ZIP','FPX'], 'Office Open XML Presentation'],
    205333    PS   => ['PS',   'PostScript'],
    206     PSD  => ['PSD',  'PhotoShop Drawing'],
    207     QIF  => ['QTIF', 'QuickTime Image File'],
     334    PS2  =>  'PS',
     335    PS3  =>  'PS',
     336    PSB  => ['PSD',  'Photoshop Large Document'],
     337    PSD  => ['PSD',  'Photoshop Drawing'],
     338    PSP  => ['PSP',  'Paint Shop Pro'],
     339    PSPFRAME => 'PSP',
     340    PSPIMAGE => 'PSP',
     341    PSPSHAPE => 'PSP',
     342    PSPTUBE  => 'PSP',
     343    QIF  =>  'QTIF',
    208344    QT   => ['MOV',  'QuickTime movie'],
    209     QTI  => ['QTIF', 'QuickTime Image File'],
     345    QTI  =>  'QTIF',
    210346    QTIF => ['QTIF', 'QuickTime Image File'],
    211347    RA   => ['Real', 'Real Audio'],
    212348    RAF  => ['RAF',  'FujiFilm RAW Format'],
    213349    RAM  => ['Real', 'Real Audio Metafile'],
    214     RAW  => ['RAW',  'Kyocera Contax N Digital RAW or Panasonic RAW'],
    215     RIF  => ['RIFF', 'Resource Interchange File Format'],
     350    RAR  => ['RAR',  'RAR Archive'],
     351    RAW  => [['RAW','TIFF'], 'Kyocera Contax N Digital RAW or Panasonic RAW'],
     352    RIF  =>  'RIFF',
    216353    RIFF => ['RIFF', 'Resource Interchange File Format'],
    217354    RM   => ['Real', 'Real Media'],
    218355    RMVB => ['Real', 'Real Media Variable Bitrate'],
    219356    RPM  => ['Real', 'Real Media Plug-in Metafile'],
     357    RSRC => ['RSRC', 'Mac OS Resource'],
     358    RTF  => ['RTF',  'Rich Text Format'],
    220359    RV   => ['Real', 'Real Video'],
    221     SR2  => ['TIFF', 'Sony RAW Format 2 (TIFF-like)'],
    222     SRF  => ['TIFF', 'Sony RAW Format (TIFF-like)'],
     360    RW2  => ['TIFF', 'Panasonic RAW 2'],
     361    RWL  => ['TIFF', 'Leica RAW'],
     362    RWZ  => ['RWZ',  'Rawzor compressed image'],
     363    SO   => ['EXE',  'Shared Object file'],
     364    SR2  => ['TIFF', 'Sony RAW Format 2'],
     365    SRF  => ['TIFF', 'Sony RAW Format'],
     366    SRW  => ['TIFF', 'Samsung RAW format'],
     367    SVG  => ['XMP',  'Scalable Vector Graphics'],
    223368    SWF  => ['SWF',  'Shockwave Flash'],
    224     THM  => ['JPEG', 'Canon Thumbnail (aka. JPG)'],
    225     TIF  => ['TIFF', 'Tagged Image File Format'],
     369    TAR  => ['TAR',  'TAR archive'],
     370    THM  => ['JPEG', 'Canon Thumbnail'],
     371    THMX => [['ZIP','FPX'], 'Office Open XML Theme'],
     372    TIF  =>  'TIFF',
    226373    TIFF => ['TIFF', 'Tagged Image File Format'],
    227     VRD  => ['VRD',  'Canon VRD Recipe Data (written by DPP)'],
    228     WAV  => ['RIFF', 'WAVeform (Windows digital audio format)'],
    229     WDP  => ['TIFF', 'Windows Media Photo (TIFF-based)'],
    230     WMA  => ['ASF',  'Windows Media Audio (ASF-based)'],
    231     WMV  => ['ASF',  'Windows Media Video (ASF-based)'],
     374    TS   =>  'M2TS',
     375    TTC  => ['Font', 'True Type Font Collection'],
     376    TTF  => ['Font', 'True Type Font'],
     377    TUB  => 'PSP',
     378    VOB  => ['MPEG', 'Video Object'],
     379    VRD  => ['VRD',  'Canon VRD Recipe Data'],
     380    VSD  => ['FPX',  'Microsoft Visio Drawing'],
     381    WAV  => ['RIFF', 'WAVeform (Windows digital audio)'],
     382    WDP  => ['TIFF', 'Windows Media Photo'],
     383    WEBM => ['MKV',  'Google Web Movie'],
     384    WEBP => ['RIFF', 'Google Web Picture'],
     385    WMA  => ['ASF',  'Windows Media Audio'],
     386    WMV  => ['ASF',  'Windows Media Video'],
    232387    X3F  => ['X3F',  'Sigma RAW format'],
     388    XCF  => ['XCF',  'GIMP native image format'],
    233389    XHTML=> ['HTML', 'Extensible HyperText Markup Language'],
    234     XLS  => ['FPX',  'Microsoft Excel worksheet (FPX-like)'],
    235     XMP  => ['XMP',  'Extensible Metadata Platform data file'],
     390    XLA  => ['FPX',  'Microsoft Excel Add-in'],
     391    XLAM => [['ZIP','FPX'], 'Office Open XML Spreadsheet Add-in Macro-enabled'],
     392    XLS  => ['FPX',  'Microsoft Excel Spreadsheet'],
     393    XLSB => [['ZIP','FPX'], 'Office Open XML Spreadsheet Binary'],
     394    XLSM => [['ZIP','FPX'], 'Office Open XML Spreadsheet Macro-enabled'],
     395    XLSX => [['ZIP','FPX'], 'Office Open XML Spreadsheet'],
     396    XLT  => ['FPX',  'Microsoft Excel Template'],
     397    XLTM => [['ZIP','FPX'], 'Office Open XML Spreadsheet Template Macro-enabled'],
     398    XLTX => [['ZIP','FPX'], 'Office Open XML Spreadsheet Template'],
     399    XMP  => ['XMP',  'Extensible Metadata Platform'],
     400    ZIP  => ['ZIP',  'ZIP archive'],
    236401);
    237402
     403# descriptions for file types not found in above file extension lookup
     404my %fileDescription = (
     405    DICOM => 'Digital Imaging and Communications in Medicine',
     406    PLIST => 'Property List',
     407    XML   => 'Extensible Markup Language',
     408    'DJVU (multi-page)' => 'DjVu multi-page image',
     409    'Win32 EXE' => 'Windows 32-bit Executable',
     410    'Win32 DLL' => 'Windows 32-bit Dynamic Link Library',
     411);
     412
    238413# MIME types for applicable file types above
    239 # (missing entries default to 'application/unknown')
    240 my %mimeType = (
    241     AIFF => 'audio/aiff',
     414# (missing entries default to 'application/unknown', but note that
     415#  other mime types may be specified by some modules, ie. QuickTime.pm)
     416%mimeType = (
     417   '3FR' => 'image/x-hasselblad-3fr',
     418    AI   => 'application/vnd.adobe.illustrator',
     419    AIFF => 'audio/x-aiff',
    242420    APE  => 'audio/x-monkeys-audio',
    243421    ASF  => 'video/x-ms-asf',
    244     ARW  => 'image/x-raw',
    245     AVI  => 'video/avi',
     422    ARW  => 'image/x-sony-arw',
     423    AVI  => 'video/x-msvideo',
    246424    BMP  => 'image/bmp',
    247     BTF  => 'application/unknown', #TEMPORARY!
    248     CR2  => 'image/x-raw',
    249     CRW  => 'image/x-raw',
     425    BTF  => 'image/x-tiff-big', #(NC) (ref http://www.asmail.be/msg0055371937.html)
     426    BZ2  => 'application/bzip2',
     427   'Canon 1D RAW' => 'image/x-raw', # (uses .TIF file extension)
     428    CR2  => 'image/x-canon-cr2',
     429    CRW  => 'image/x-canon-crw',
     430    DCR  => 'image/x-kodak-dcr',
     431    DFONT=> 'application/x-dfont',
     432    DICM => 'application/dicom',
     433    DIVX => 'video/divx',
     434    DJVU => 'image/vnd.djvu',
     435    DNG  => 'image/x-adobe-dng',
     436    DOC  => 'application/msword',
     437    DOCM => 'application/vnd.ms-word.document.macroEnabled',
     438    DOCX => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
     439    DOT  => 'application/msword',
     440    DOTM => 'application/vnd.ms-word.template.macroEnabledTemplate',
     441    DOTX => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
     442    DV   => 'video/x-dv',
     443    EIP  => 'application/x-captureone', #(NC)
    250444    EPS  => 'application/postscript',
    251     ERF  => 'image/x-raw',
    252     DCR  => 'image/x-raw',
    253     DICM => 'application/dicom',
    254     DNG  => 'image/x-raw',
    255     DOC  => 'application/msword',
     445    ERF  => 'image/x-epson-erf',
     446    EXE  => 'application/octet-stream',
     447    FLA  => 'application/vnd.adobe.fla',
    256448    FLAC => 'audio/flac',
    257449    FLV  => 'video/x-flv',
     450    Font => 'application/x-font-type1', # covers PFA, PFB and PFM (not sure about PFM)
    258451    FPX  => 'image/vnd.fpx',
    259452    GIF  => 'image/gif',
     453    GZIP => 'application/x-gzip',
     454    HDP  => 'image/vnd.ms-photo',
    260455    HTML => 'text/html',
     456    ICC  => 'application/vnd.iccprofile',
     457    IIQ  => 'image/x-raw',
     458    IND  => 'application/x-indesign',
     459    ITC  => 'application/itunes',
    261460    JNG  => 'image/jng',
    262     JP2  => 'image/jpeg2000',
     461    JP2  => 'image/jp2',
    263462    JPEG => 'image/jpeg',
    264     K25  => 'image/x-raw',
    265     M4A  => 'audio/mp4',
    266     MEF  => 'image/x-raw',
     463    JPM  => 'image/jpm',
     464    JPX  => 'image/jpx',
     465    K25  => 'image/x-kodak-k25',
     466    KDC  => 'image/x-kodak-kdc',
     467    LNK  => 'application/octet-stream',
     468    M2T  => 'video/mpeg',
     469    M2TS => 'video/m2ts',
     470    MEF  => 'image/x-mamiya-mef',
    267471    MIE  => 'application/x-mie',
    268472    MIFF => 'application/x-magick-image',
     473    MKA  => 'audio/x-matroska',
     474    MKS  => 'application/x-matroska',
     475    MKV  => 'video/x-matroska',
    269476    MNG  => 'video/mng',
    270477    MOS  => 'image/x-raw',
     
    274481    MPC  => 'audio/x-musepack',
    275482    MPEG => 'video/mpeg',
    276     MRW  => 'image/x-raw',
    277     NEF  => 'image/x-raw',
     483    MRW  => 'image/x-minolta-mrw',
     484    MXF  => 'application/mxf',
     485    NEF  => 'image/x-nikon-nef',
     486    NRW  => 'image/x-nikon-nrw',
     487    ODP  => 'application/vnd.oasis.opendocument.presentation',
     488    ODS  => 'application/vnd.oasis.opendocument.spreadsheet',
     489    ODT  => 'application/vnd.oasis.opendocument.text',
    278490    OGG  => 'audio/x-ogg',
    279     ORF  => 'image/x-raw',
     491    ORF  => 'image/x-olympus-orf',
     492    OTF  => 'application/x-font-otf',
    280493    PBM  => 'image/x-portable-bitmap',
    281494    PDF  => 'application/pdf',
    282     PEF  => 'image/x-raw',
     495    PEF  => 'image/x-pentax-pef',
     496    PGF  => 'image/pgf',
    283497    PGM  => 'image/x-portable-graymap',
    284498    PICT => 'image/pict',
     499    PLIST=> 'application/xml',
    285500    PNG  => 'image/png',
     501    POT  => 'application/vnd.ms-powerpoint',
     502    POTM => 'application/vnd.ms-powerpoint.template.macroEnabled',
     503    POTX => 'application/vnd.openxmlformats-officedocument.presentationml.template',
    286504    PPM  => 'image/x-portable-pixmap',
     505    PPS  => 'application/vnd.ms-powerpoint',
     506    PPSM => 'application/vnd.ms-powerpoint.slideshow.macroEnabled',
     507    PPSX => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
    287508    PPT  => 'application/vnd.ms-powerpoint',
     509    PPTM => 'application/vnd.ms-powerpoint.presentation.macroEnabled',
     510    PPTX => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
    288511    PS   => 'application/postscript',
    289     PSD  => 'application/photoshop',
     512    PSD  => 'application/vnd.adobe.photoshop',
     513    PSP  => 'image/x-paintshoppro', #(NC)
    290514    QTIF => 'image/x-quicktime',
    291515    RA   => 'audio/x-pn-realaudio',
    292     RAF  => 'image/x-raw',
     516    RAF  => 'image/x-fujifilm-raf',
    293517    RAM  => 'audio/x-pn-realaudio',
     518    RAR  => 'application/x-rar-compressed',
    294519    RAW  => 'image/x-raw',
    295520    RM   => 'application/vnd.rn-realmedia',
    296521    RMVB => 'application/vnd.rn-realmedia-vbr',
    297522    RPM  => 'audio/x-pn-realaudio-plugin',
     523    RSRC => 'application/ResEdit',
     524    RTF  => 'text/rtf',
    298525    RV   => 'video/vnd.rn-realvideo',
    299     SR2  => 'image/x-raw',
    300     SRF  => 'image/x-raw',
     526    RW2  => 'image/x-panasonic-rw2',
     527    RWL  => 'image/x-leica-rwl',
     528    RWZ  => 'image/x-rawzor', #(duplicated in Rawzor.pm)
     529    SR2  => 'image/x-sony-sr2',
     530    SRF  => 'image/x-sony-srf',
     531    SRW  => 'image/x-samsung-srw',
     532    SVG  => 'image/svg+xml',
    301533    SWF  => 'application/x-shockwave-flash',
     534    TAR  => 'application/x-tar',
     535    THMX => 'application/vnd.ms-officetheme',
    302536    TIFF => 'image/tiff',
     537    TTC  => 'application/x-font-ttf',
     538    TTF  => 'application/x-font-ttf',
     539    VSD  => 'application/x-visio',
    303540    WAV  => 'audio/x-wav',
    304541    WDP  => 'image/vnd.ms-photo',
     542    WEBM => 'video/webm',
     543    WEBP => 'image/webp',
    305544    WMA  => 'audio/x-ms-wma',
    306545    WMV  => 'video/x-ms-wmv',
    307     X3F  => 'image/x-raw',
     546    X3F  => 'image/x-sigma-x3f',
     547    XCF  => 'image/x-xcf',
     548    XLA  => 'application/vnd.ms-excel',
     549    XLAM => 'application/vnd.ms-excel.addin.macroEnabled',
    308550    XLS  => 'application/vnd.ms-excel',
     551    XLSB => 'application/vnd.ms-excel.sheet.binary.macroEnabled',
     552    XLSM => 'application/vnd.ms-excel.sheet.macroEnabled',
     553    XLSX => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
     554    XLT  => 'application/vnd.ms-excel',
     555    XLTM => 'application/vnd.ms-excel.template.macroEnabled',
     556    XLTX => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
     557    XML  => 'application/xml',
    309558    XMP  => 'application/rdf+xml',
     559    ZIP  => 'application/zip',
    310560);
    311561
    312 # module names for each file type
    313 # (missing entries have same module name as file type)
     562# module names for processing routines of each file type
     563# - undefined entries default to same module name as file type
     564# - module name '' defaults to Image::ExifTool
     565# - module name '0' indicates a recognized but unsupported file
    314566my %moduleName = (
    315567    BTF  => 'BigTIFF',
     568    BZ2  => 0,
    316569    CRW  => 'CanonRaw',
    317570    DICM => 'DICOM',
     571    COS  => 'CaptureOne',
     572    DOCX => 'OOXML',
    318573    EPS  => 'PostScript',
     574    EXIF => '',
    319575    ICC  => 'ICC_Profile',
     576    IND  => 'InDesign',
    320577    FLV  => 'Flash',
    321578    FPX  => 'FlashPix',
     579    GZIP => 'ZIP',
    322580    JP2  => 'Jpeg2000',
    323     JPEG => '',     # (in the current module)
     581    JPEG => '',
     582  # MODD => 'XML',
    324583    MOV  => 'QuickTime',
     584    MKV  => 'Matroska',
    325585    MP3  => 'ID3',
    326586    MRW  => 'MinoltaRaw',
    327587    OGG  => 'Vorbis',
    328588    ORF  => 'Olympus',
     589  # PLIST=> 'XML',
     590    PMP  => 'Sony',
    329591    PS   => 'PostScript',
    330592    PSD  => 'Photoshop',
    331593    QTIF => 'QuickTime',
    332594    RAF  => 'FujiFilm',
     595    RAR  => 'ZIP',
    333596    RAW  => 'KyoceraRaw',
     597    RWZ  => 'Rawzor',
    334598    SWF  => 'Flash',
     599    TAR  => 0,
    335600    TIFF => '',
    336601    VRD  => 'CanonVRD',
    337602    X3F  => 'SigmaRaw',
     603    XCF  => 'GIMP',
     604);
     605
     606# quick "magic number" file test used to avoid loading module unnecessarily:
     607# - regular expression evaluated on first 1024 bytes of file
     608# - must match beginning at first byte in file
     609# - this test must not be more stringent than module logic
     610%magicNumber = (
     611    AIFF => '(FORM....AIF[FC]|AT&TFORM)',
     612    APE  => '(MAC |APETAGEX|ID3)',
     613    ASF  => '\x30\x26\xb2\x75\x8e\x66\xcf\x11\xa6\xd9\x00\xaa\x00\x62\xce\x6c',
     614    BMP  => 'BM',
     615    BTF  => '(II\x2b\0|MM\0\x2b)',
     616    BZ2  => 'BZh[1-9]\x31\x41\x59\x26\x53\x59',
     617    CRW  => '(II|MM).{4}HEAP(CCDR|JPGM)',
     618    DICM => '(.{128}DICM|\0[\x02\x04\x06\x08]\0[\0-\x20]|[\x02\x04\x06\x08]\0[\0-\x20]\0)',
     619    DOCX => 'PK\x03\x04',
     620    DV   => '\x1f\x07\0[\x3f\xbf]', # (not tested if extension recognized)
     621    EPS  => '(%!PS|%!Ad|\xc5\xd0\xd3\xc6)',
     622    EXE  => '(MZ|\xca\xfe\xba\xbe|\xfe\xed\xfa[\xce\xcf]|[\xce\xcf]\xfa\xed\xfe|Joy!peff|\x7fELF|#!\s*/\S*bin/|!<arch>\x0a)',
     623    EXIF => '(II\x2a\0|MM\0\x2a)',
     624    FLAC => '(fLaC|ID3)',
     625    FLV  => 'FLV\x01',
     626    Font => '((\0\x01\0\0|OTTO|true|typ1)[\0\x01]|ttcf\0[\x01\x02]\0\0|\0[\x01\x02]|' .
     627            '(.{6})?%!(PS-(AdobeFont-|Bitstream )|FontType1-)|Start(Comp|Master)?FontMetrics)',
     628    FPX  => '\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1',
     629    GIF  => 'GIF8[79]a',
     630    GZIP => '\x1f\x8b\x08',
     631    HTML => '(?i)<(!DOCTYPE\s+HTML|HTML|\?xml)', # (case insensitive)
     632    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}',
     633    IND  => '\x06\x06\xed\xf5\xd8\x1d\x46\xe5\xbd\x31\xef\xe7\xfe\x74\xb7\x1d',
     634    ITC  => '.{4}itch',
     635    JP2  => '\0\0\0\x0cjP(  |\x1a\x1a)\x0d\x0a\x87\x0a',
     636    JPEG => '\xff\xd8\xff',
     637    LNK  => '.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46',
     638    M2TS => '(....)?\x47',
     639    MIE  => '~[\x10\x18]\x04.0MIE',
     640    MIFF => 'id=ImageMagick',
     641    MKV  => '\x1a\x45\xdf\xa3',
     642    MOV  => '.{4}(free|skip|wide|ftyp|pnot|PICT|pict|moov|mdat|junk|uuid)',
     643  # MP3  =>  difficult to rule out
     644    MPC  => '(MP\+|ID3)',
     645    MPEG => '\0\0\x01[\xb0-\xbf]',
     646    MRW  => '\0MR[MI]',
     647    MXF  => '\x06\x0e\x2b\x34\x02\x05\x01\x01\x0d\x01\x02', # (not tested if extension recognized)
     648    OGG  => '(OggS|ID3)',
     649    ORF  => '(II|MM)',
     650    PDF  => '%PDF-\d+\.\d+',
     651    PGF  => 'PGF',
     652    PICT => '(.{10}|.{522})(\x11\x01|\x00\x11)',
     653    PMP  => '.{8}\0{3}\x7c.{112}\xff\xd8\xff\xdb',
     654    PNG  => '(\x89P|\x8aM|\x8bJ)NG\r\n\x1a\n',
     655    PPM  => 'P[1-6]\s+',
     656    PS   => '(%!PS|%!Ad|\xc5\xd0\xd3\xc6)',
     657    PSD  => '8BPS\0[\x01\x02]',
     658    PSP  => 'Paint Shop Pro Image File\x0a\x1a\0{5}',
     659    QTIF => '.{4}(idsc|idat|iicc)',
     660    RAF  => 'FUJIFILM',
     661    RAR  => 'Rar!\x1a\x07\0',
     662    RAW  => '(.{25}ARECOYK|II|MM)',
     663    Real => '(\.RMF|\.ra\xfd|pnm://|rtsp://|http://)',
     664    RIFF => 'RIFF',
     665    RSRC => '(....)?\0\0\x01\0',
     666    RTF  => '[\n\r]*\\{[\n\r]*\\\\rtf',
     667    # (don't be too restrictive for RW2/RWL -- how does magic number change for big-endian?)
     668    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)
     669    RWL  => '(II|MM)', #(ditto)
     670    RWZ  => 'rawzor',
     671    SWF  => '[FC]WS[^\0]',
     672    TAR  => '.{257}ustar(  )?\0', # (this doesn't catch old-style tar files)
     673    TIFF => '(II|MM)', # don't test magic number (some raw formats are different)
     674    VRD  => 'CANON OPTIONAL DATA\0',
     675    X3F  => 'FOVb',
     676    XCF  => 'gimp xcf ',
     677    XMP  => '\0{0,3}(\xfe\xff|\xff\xfe|\xef\xbb\xbf)?\0{0,3}\s*<',
     678    ZIP  => 'PK\x03\x04',
     679);
     680
     681# lookup for valid character set names (keys are all lower case)
     682%charsetName = (
     683    #   Charset setting                       alias(es)
     684    # -------------------------   --------------------------------------------
     685    utf8        => 'UTF8',        cp65001 => 'UTF8', 'utf-8' => 'UTF8',
     686    latin       => 'Latin',       cp1252  => 'Latin', latin1 => 'Latin',
     687    latin2      => 'Latin2',      cp1250  => 'Latin2',
     688    cyrillic    => 'Cyrillic',    cp1251  => 'Cyrillic', russian => 'Cyrillic',
     689    greek       => 'Greek',       cp1253  => 'Greek',
     690    turkish     => 'Turkish',     cp1254  => 'Turkish',
     691    hebrew      => 'Hebrew',      cp1255  => 'Hebrew',
     692    arabic      => 'Arabic',      cp1256  => 'Arabic',
     693    baltic      => 'Baltic',      cp1257  => 'Baltic',
     694    vietnam     => 'Vietnam',     cp1258  => 'Vietnam',
     695    thai        => 'Thai',        cp874   => 'Thai',
     696    macroman    => 'MacRoman',    cp10000 => 'MacRoman', mac => 'MacRoman', roman => 'MacRoman',
     697    maclatin2   => 'MacLatin2',   cp10029 => 'MacLatin2',
     698    maccyrillic => 'MacCyrillic', cp10007 => 'MacCyrillic',
     699    macgreek    => 'MacGreek',    cp10006 => 'MacGreek',
     700    macturkish  => 'MacTurkish',  cp10081 => 'MacTurkish',
     701    macromanian => 'MacRomanian', cp10010 => 'MacRomanian',
     702    maciceland  => 'MacIceland',  cp10079 => 'MacIceland',
     703    maccroatian => 'MacCroatian', cp10082 => 'MacCroatian',
    338704);
    339705
     
    343709# group hash for ExifTool-generated tags
    344710my %allGroupsExifTool = ( 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'ExifTool' );
     711
     712# special tag names (not used for tag info)
     713my %specialTags = (
     714    TABLE_NAME=>1, SHORT_NAME=>1, PROCESS_PROC=>1, WRITE_PROC=>1, CHECK_PROC=>1,
     715    GROUPS=>1, FORMAT=>1, FIRST_ENTRY=>1, TAG_PREFIX=>1, PRINT_CONV=>1,
     716    WRITABLE=>1, TABLE_DESC=>1, NOTES=>1, IS_OFFSET=>1, EXTRACT_UNKNOWN=>1,
     717    NAMESPACE=>1, PREFERRED=>1, SRC_TABLE=>1, PRIORITY=>1, WRITE_GROUP=>1,
     718    LANG_INFO=>1, VARS=>1, DATAMEMBER=>1, IS_SUBDIR=>1, SET_GROUP1=>1,
     719);
    345720
    346721# headers for various segment types
    347722$exifAPP1hdr = "Exif\0\0";
    348723$xmpAPP1hdr = "http://ns.adobe.com/xap/1.0/\0";
     724$xmpExtAPP1hdr = "http://ns.adobe.com/xmp/extension/\0";
    349725$psAPP13hdr = "Photoshop 3.0\0";
    350726$psAPP13old = 'Adobe_Photoshop2.5:';
    351727
    352728sub DummyWriteProc { return 1; }
     729
     730# lookup for user lenses defined in @Image::ExifTool::UserDefined::Lenses
     731%Image::ExifTool::userLens = ( );
     732
     733# queued plug-in tags to add to lookup
     734@Image::ExifTool::pluginTags = ( );
     735%Image::ExifTool::pluginTags = ( );
    353736
    354737# tag information for preview image -- this should be used for all
     
    360743    WriteCheck => '$val eq "none" ? undef : $self->CheckImage(\$val)',
    361744    DataTag => 'PreviewImage',
     745    # accept either scalar or scalar reference
     746    RawConv => '$self->ValidateImage(ref $val ? $val : \$val, $tag)',
    362747    # we allow preview image to be set to '', but we don't want a zero-length value
    363748    # in the IFD, so set it temorarily to 'none'.  Note that the length is <= 4,
    364749    # so this value will fit in the IFD so the preview fixup won't be generated.
    365     ValueConv => '$self->ValidateImage(\$val,$tag)',
    366750    ValueConvInv => '$val eq "" and $val="none"; $val',
    367751);
     
    372756%Image::ExifTool::Extra = (
    373757    GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
    374     DID_TAG_ID => 1,  # tag ID's aren't meaningful for these tags
     758    VARS => { NO_ID => 1 }, # tag ID's aren't meaningful for these tags
    375759    WRITE_PROC => \&DummyWriteProc,
     760    Error   => { Priority => 0, Groups => \%allGroupsExifTool },
     761    Warning => { Priority => 0, Groups => \%allGroupsExifTool },
    376762    Comment => {
    377763        Notes => 'comment embedded in JPEG, GIF89a or PPM/PGM/PBM image',
     
    381767    },
    382768    Directory => {
     769        Groups => { 1 => 'System' },
    383770        Writable => 1,
    384771        Protected => 1,
     
    387774    },
    388775    FileName => {
     776        Groups => { 1 => 'System' },
    389777        Writable => 1,
    390778        Protected => 1,
     779        Notes => q{
     780            may be written with a full path name to set FileName and Directory in one
     781            operation.  See L<filename.html|../filename.html> for more information on
     782            writing the FileName and Directory tags
     783        },
    391784        ValueConvInv => '$val=~tr/\\\\/\//; $val',
    392785    },
    393786    FileSize => {
    394         PrintConv => sub {
    395             my $val = shift;
    396             $val < 2048 and return "$val bytes";
    397             $val < 2097152 and return sprintf('%.0f kB', $val / 1024);
    398             return sprintf('%.0f MB', $val / 1048576);
     787        Groups => { 1 => 'System' },
     788        PrintConv => \&ConvertFileSize,
     789    },
     790    ResourceForkSize => {
     791        Groups => { 1 => 'System' },
     792        Notes => q{
     793            [Mac OS only] size of the file's resource fork if it contains data.  If this
     794            tag is generated the ExtractEmbedded option may be used to extract
     795            resource-fork information as a sub-document
    399796        },
     797        PrintConv => \&ConvertFileSize,
    400798    },
    401799    FileType    => { },
     
    403801        Description => 'File Modification Date/Time',
    404802        Notes => 'the filesystem modification time',
    405         Groups => { 2 => 'Time' },
     803        Groups => { 1 => 'System', 2 => 'Time' },
    406804        Writable => 1,
     805        # all pseudo-tags must be protected so -tagsfromfile fails with
     806        # unrecognized files unless a pseudo tag is specified explicitly
     807        Protected => 1,
    407808        Shift => 'Time',
    408         ValueConv => 'ConvertUnixTime($val,"local")',
    409         ValueConvInv => 'GetUnixTime($val,"local")',
     809        ValueConv => 'ConvertUnixTime($val,1)',
     810        ValueConvInv => 'GetUnixTime($val,1)',
    410811        PrintConv => '$self->ConvertDateTime($val)',
    411         PrintConvInv => '$val',
     812        PrintConvInv => '$self->InverseDateTime($val)',
     813    },
     814    FilePermissions => {
     815        Groups => { 1 => 'System' },
     816        Notes => q{
     817            r=read, w=write and x=execute permissions for the file owner, group and
     818            others.  The ValueConv value is an octal number so bit test operations on
     819            this value should be done in octal, ie. "oct($filePermissions) & 0200"
     820        },
     821        ValueConv => 'sprintf("%.3o", $val & 0777)',
     822        PrintConv => sub {
     823            my ($mask, $str, $val) = (0400, '', oct(shift));
     824            while ($mask) {
     825                foreach (qw(r w x)) {
     826                    $str .= $val & $mask ? $_ : '-';
     827                    $mask >>= 1;
     828                }
     829            }
     830            return $str;
     831        },
    412832    },
    413833    MIMEType    => { },
     
    418838    MaxVal      => { }, # max pixel value in PPM or PGM image
    419839    EXIF => {
    420         Notes => 'the full EXIF data block',
    421         Groups => { 0 => 'EXIF' },
    422         Binary => 1,
     840        Notes => 'the full EXIF data block from JPEG, PNG, JP2, MIE and MIFF images',
     841        Groups => { 0 => 'EXIF', 1 => 'EXIF' },
     842        Flags => ['Writable' ,'Protected', 'Binary'],
     843        WriteCheck => q{
     844            return undef if $val =~ /^(II\x2a\0|MM\0\x2a)/;
     845            return 'Invalid EXIF data';
     846        },
    423847    },
    424848    ICC_Profile => {
    425849        Notes => 'the full ICC_Profile data block',
    426         Groups => { 0 => 'ICC_Profile' },
     850        Groups => { 0 => 'ICC_Profile', 1 => 'ICC_Profile' },
    427851        Flags => ['Writable' ,'Protected', 'Binary'],
    428852        WriteCheck => q{
     
    433857    XMP => {
    434858        Notes => 'the full XMP data block',
    435         Groups => { 0 => 'XMP' },
    436         Flags => [ 'Writable', 'Binary' ],
     859        Groups => { 0 => 'XMP', 1 => 'XMP' },
     860        Flags => ['Writable', 'Protected', 'Binary'],
     861        Priority => 0,  # so main xmp (which usually comes first) takes priority
    437862        WriteCheck => q{
    438863            require Image::ExifTool::XMP;
     
    442867    CanonVRD => {
    443868        Notes => 'the full Canon DPP VRD trailer block',
    444         Groups => { 0 => 'CanonVRD' },
     869        Groups => { 0 => 'CanonVRD', 1 => 'CanonVRD' },
    445870        Flags => ['Writable' ,'Protected', 'Binary'],
     871        Permanent => 0, # (this is 1 by default for MakerNotes tags)
    446872        WriteCheck => q{
    447873            return undef if $val =~ /^CANON OPTIONAL DATA\0/;
     
    449875        },
    450876    },
    451     Encryption  => { }, # PDF encryption filter
     877    CurrentIPTCDigest => {
     878        Notes => q{
     879            MD5 digest of existing IPTC data.  All zeros if IPTC exists but Digest::MD5
     880            is not installed.  Only calculated for IPTC in the standard location as
     881            specified by the L<MWG|http://www.metadataworkinggroup.org/>.  ExifTool
     882            automates the handling of this tag in the MWG module -- see the
     883            L<MWG Tag Name documentation|MWG.html> for details
     884        },
     885        ValueConv => 'unpack("H*", $val)',
     886    },
     887    PreviewImage => {
     888        Writable => 1,
     889        WriteCheck => '$self->CheckImage(\$val)',
     890        # can't delete, so set to empty string and return no error
     891        DelCheck => '$val = ""; return undef',
     892        # accept either scalar or scalar reference
     893        RawConv => '$self->ValidateImage(ref $val ? $val : \$val, $tag)',
     894    },
     895    PreviewPNG  => { Binary => 1 },
    452896    ExifByteOrder => {
    453897        Writable => 1,
    454898        Notes => 'only writable for newly created EXIF segments',
    455899        PrintConv => {
    456             II => 'Little-endian (Intel)',
    457             MM => 'Big-endian (Motorola)',
     900            II => 'Little-endian (Intel, II)',
     901            MM => 'Big-endian (Motorola, MM)',
     902        },
     903    },
     904    ExifUnicodeByteOrder => {
     905        Writable => 1,
     906        Notes => q{
     907            the EXIF specification is particularly vague about the byte ordering for
     908            Unicode text, and different applications use different conventions.  By
     909            default ExifTool writes Unicode text in EXIF byte order, but this write-only
     910            tag may be used to force a specific byte order
     911        },
     912        PrintConv => {
     913            II => 'Little-endian (Intel, II)',
     914            MM => 'Big-endian (Motorola, MM)',
    458915        },
    459916    },
    460917    ExifToolVersion => {
    461918        Description => 'ExifTool Version Number',
    462         Groups      => \%allGroupsExifTool
     919        Groups => \%allGroupsExifTool,
    463920    },
    464     Error       => { Priority => 0, Groups => \%allGroupsExifTool },
    465     Warning     => { Priority => 0, Groups => \%allGroupsExifTool },
     921    RAFVersion => { },
     922    JPEGDigest => {
     923        Notes => q{
     924            an MD5 digest of the JPEG quantization tables is combined with the component
     925            sub-sampling values to generate the value of this tag.  The result is
     926            compared to known values in an attempt to deduce the originating software
     927            based only on the JPEG image data.  For performance reasons, this tag is
     928            generated only if specifically requested
     929        },
     930    },
     931    Now => {
     932        Groups => { 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'Time' },
     933        Notes => q{
     934            the current date/time.  Useful when setting the tag values, ie.
     935            C<"-modifydate<now">.  Not generated unless specifically requested
     936        },
     937        ValueConv => sub {
     938            my $time = shift;
     939            my @tm = localtime $time;
     940            my $tz = Image::ExifTool::TimeZoneString(\@tm, $time);
     941            sprintf("%4d:%.2d:%.2d %.2d:%.2d:%.2d%s", $tm[5]+1900, $tm[4]+1, $tm[3],
     942                    $tm[2], $tm[1], $tm[0], $tz);
     943        },
     944        PrintConv => '$self->ConvertDateTime($val)',
     945    },
     946    ID3Size     => { },
     947    Geotag => {
     948        Writable => 1,
     949        AllowGroup => '(exif|gps|xmp|xmp-exif)',
     950        Notes => q{
     951            this write-only tag is used to define the GPS track log data or track log
     952            file name.  Currently supported track log formats are GPX, NMEA RMC/GGA/GLL,
     953            KML, IGC, Garmin XML and TCX, and Magellan PMGNTRK.  See
     954            L<geotag.html|../geotag.html> for details
     955        },
     956        DelCheck => q{
     957            require Image::ExifTool::Geotag;
     958            # delete associated tags
     959            Image::ExifTool::Geotag::SetGeoValues($self, undef, $wantGroup);
     960        },
     961        ValueConvInv => q{
     962            require Image::ExifTool::Geotag;
     963            # always warn because this tag is never set (warning is "\n" on success)
     964            my $result = Image::ExifTool::Geotag::LoadTrackLog($self, $val);
     965            return '' if not defined $result;   # deleting geo tags
     966            return $result if ref $result;      # geotag data hash reference
     967            warn "$result\n";                   # error string
     968        },
     969    },
     970    Geotime => {
     971        Writable => 1,
     972        AllowGroup => '(exif|gps|xmp|xmp-exif)',
     973        Notes => q{
     974            this write-only tag is used to define a date/time for interpolating a
     975            position in the GPS track specified by the Geotag tag.  Writing this tag
     976            causes the following 8 tags to be written:  GPSLatitude, GPSLatitudeRef,
     977            GPSLongitude, GPSLongitudeRef, GPSAltitude, GPSAltitudeRef, GPSDateStamp and
     978            GPSTimeStamp.  The local system timezone is assumed if the date/time value
     979            does not contain a timezone.  May be deleted to delete associated GPS tags.
     980            A group name of 'EXIF' or 'XMP' may be specified to write or delete only
     981            EXIF or XMP GPS tags.  The value of Geotag must be assigned before this tag
     982        },
     983        DelCheck => q{
     984            require Image::ExifTool::Geotag;
     985            # delete associated tags
     986            Image::ExifTool::Geotag::SetGeoValues($self, undef, $wantGroup);
     987        },
     988        ValueConvInv => q{
     989            require Image::ExifTool::Geotag;
     990            warn Image::ExifTool::Geotag::SetGeoValues($self, $val, $wantGroup) . "\n";
     991            return undef;
     992        },
     993    },
     994    Geosync => {
     995        Writable => 1,
     996        AllowGroup => '(exif|gps|xmp|xmp-exif)',
     997        Shift => 'Time', # enables "+=" syntax as well as "=+"
     998        Notes => q{
     999            this write-only tag specifies a time difference to add to Geotime for
     1000            synchronization with the GPS clock.  For example, set this to "-12" if the
     1001            camera clock is 12 seconds faster than GPS time.  Input format is
     1002            "[+-][[[DD ]HH:]MM:]SS[.ss]".  Must be set before Geotime to be effective.
     1003            Additional features allow calculation of time differences and time drifts,
     1004            and extraction of synchronization times from image files. See the
     1005            L<geotagging documentation|../geotag.html> for details
     1006        },
     1007        ValueConvInv => q{
     1008            require Image::ExifTool::Geotag;
     1009            return Image::ExifTool::Geotag::ConvertGeosync($self, $val);
     1010        },
     1011    },
    4661012);
    4671013
    468 # information decoded from JPEG SOF frame
    469 # (define this here to avoid loading JPEG.pm)
     1014# YCbCrSubSampling values (used by JPEG SOF, EXIF and XMP)
     1015%Image::ExifTool::JPEG::yCbCrSubSampling = (
     1016    '1 1' => 'YCbCr4:4:4 (1 1)', #PH
     1017    '2 1' => 'YCbCr4:2:2 (2 1)', #14 in Exif.pm
     1018    '2 2' => 'YCbCr4:2:0 (2 2)', #14 in Exif.pm
     1019    '4 1' => 'YCbCr4:1:1 (4 1)', #14 in Exif.pm
     1020    '4 2' => 'YCbCr4:1:0 (4 2)', #PH
     1021    '1 2' => 'YCbCr4:4:0 (1 2)', #PH
     1022    '1 4' => 'YCbCr4:4:1 (1 4)', #JD
     1023    '2 4' => 'YCbCr4:2:1 (2 4)', #JD
     1024);
     1025
     1026# define common JPEG segments here to avoid overhead of loading JPEG module
     1027
     1028# JPEG SOF (start of frame) tags
    4701029# (ref http://www.w3.org/Graphics/JPEG/itu-t81.pdf)
    4711030%Image::ExifTool::JPEG::SOF = (
    4721031    GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
    4731032    NOTES => 'This information is extracted from the JPEG Start Of Frame segment.',
    474     VARS => { NO_ID => 1 },
    475     EncodingProcess => {
    476         PrintHex => 1,
    477         PrintConv => {
    478             0x0 => 'Baseline DCT, Huffman coding',
     1033    VARS => { NO_ID => 1 }, # tag ID's aren't meaningful for these tags
     1034    EncodingProcess => {
     1035        PrintHex => 1,
     1036        PrintConv => {
     1037            0x0 => 'Baseline DCT, Huffman coding',
    4791038            0x1 => 'Extended sequential DCT, Huffman coding',
    4801039            0x2 => 'Progressive DCT, Huffman coding',
     
    4971056    YCbCrSubSampling => {
    4981057        Notes => 'calculated from components table',
    499         PrintConv => {
    500             '1 1' => 'YCbCr4:4:4 (1 1)',
    501             '2 1' => 'YCbCr4:2:2 (2 1)',
    502             '2 2' => 'YCbCr4:2:0 (2 2)',
    503             '4 1' => 'YCbCr4:1:1 (4 1)',
    504             '4 2' => 'YCbCr4:1:0 (4 2)',
    505             '1 2' => 'YCbCr4:4:0 (1 2)',
    506         },
     1058        PrintConv => \%Image::ExifTool::JPEG::yCbCrSubSampling,
    5071059    },
    5081060);
    5091061
    510 # static private ExifTool variables
    511 
    512 %allTables = ( );   # list of all tables loaded (except composite tags)
    513 @tableOrder = ( );  # order the tables were loaded
    514 
    515 my $didTagID;       # flag indicating we are accessing tag ID's
    516 
    517 # composite tags (accumulation of all Composite tag tables)
    518 %Image::ExifTool::Composite = (
    519     GROUPS => { 0 => 'Composite', 1 => 'Composite' },
    520     DID_TAG_ID => 1,    # want empty tagID's for composite tags
    521     WRITE_PROC => \&DummyWriteProc,
    522 );
    523 
    524 # JFIF APP0 definitions
     1062# JPEG JFIF APP0 definitions
    5251063%Image::ExifTool::JFIF::Main = (
    5261064    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     
    5321070        Name => 'JFIFVersion',
    5331071        Format => 'int8u[2]',
    534         PrintConv => '$val=~tr/ /./;$val',
     1072        PrintConv => 'sprintf("%d.%.2d", split(" ",$val))',
    5351073    },
    5361074    2 => {
     
    5641102    0x10 => {
    5651103        Name => 'ThumbnailImage',
    566         ValueConv => '$self->ValidateImage(\$val,$tag)',
     1104        RawConv => '$self->ValidateImage(\$val,$tag)',
    5671105    },
    5681106);
    5691107
    570 # special tag names (not used for tag info)
    571 my %specialTags = (
    572     PROCESS_PROC=>1, WRITE_PROC=>1, CHECK_PROC=>1, GROUPS=>1, FORMAT=>1,
    573     FIRST_ENTRY=>1, TAG_PREFIX=>1, PRINT_CONV=>1, DID_TAG_ID=>1, WRITABLE=>1,
    574     NOTES=>1, IS_OFFSET=>1, EXTRACT_UNKNOWN=>1, NAMESPACE=>1, PREFERRED=>1,
    575     PARENT=>1, PRIORITY=>1, WRITE_GROUP=>1, LANG_INFO=>1, VARS=>1,
    576     DATAMEMBER=>1,
     1108# Composite tags (accumulation of all Composite tag tables)
     1109%Image::ExifTool::Composite = (
     1110    GROUPS => { 0 => 'Composite', 1 => 'Composite' },
     1111    TABLE_NAME => 'Image::ExifTool::Composite',
     1112    SHORT_NAME => 'Composite',
     1113    VARS => { NO_ID => 1 }, # want empty tagID's for Composite tags
     1114    WRITE_PROC => \&DummyWriteProc,
    5771115);
     1116
     1117# static private ExifTool variables
     1118
     1119%allTables = ( );   # list of all tables loaded (except Composite tags)
     1120@tableOrder = ( );  # order the tables were loaded
    5781121
    5791122#------------------------------------------------------------------------------
     
    6051148# New - create new ExifTool object
    6061149# Inputs: 0) reference to exiftool object or ExifTool class name
     1150# Returns: blessed ExifTool object ref
    6071151sub new
    6081152{
     
    6171161    $self->ClearOptions();      # create default options hash
    6181162    $self->{VALUE} = { };       # must initialize this for warning messages
    619     $self->{DEL_GROUP} = { };   # list of groups to delete when writing
     1163    $self->{DEL_GROUP} = { };   # lookup for groups to delete when writing
    6201164
    6211165    # initialize our new groups for writing
     
    6331177# Notes:
    6341178#   - if no tags names are specified, the values of all tags are returned
    635 #   - tags may be specified with leading '-' to exclude
     1179#   - tags may be specified with leading '-' to exclude, or trailing '#' for ValueConv
    6361180#   - can pass a reference to list of tags to find, in which case the list will
    6371181#     be updated with the tags found in the proper case and in the specified order.
     
    6841228    while (@_) {
    6851229        my $param = shift;
    686         $oldVal = $options->{$param};
     1230        $oldVal = $$options{$param};
    6871231        last unless @_;
    688         $options->{$param} = shift;
    689         # clone Exclude list and expand shortcuts
    690         if ($param eq 'Exclude' and defined $options->{$param}) {
     1232        my $newVal = shift;
     1233        if ($param eq 'Lang') {
     1234            # allow this to be set to undef to select the default language
     1235            $newVal = $defaultLang unless defined $newVal;
     1236            if ($newVal eq $defaultLang) {
     1237                $$options{$param} = $newVal;
     1238                delete $$self{CUR_LANG};
     1239            # make sure the language is available
     1240            } elsif (eval "require Image::ExifTool::Lang::$newVal") {
     1241                my $xlat = "Image::ExifTool::Lang::${newVal}::Translate";
     1242                no strict 'refs';
     1243                if (%$xlat) {
     1244                    $$self{CUR_LANG} = \%$xlat;
     1245                    $$options{$param} = $newVal;
     1246                }
     1247            } # else don't change Lang
     1248        } elsif ($param eq 'Exclude' and defined $newVal) {
     1249            # clone Exclude list and expand shortcuts
    6911250            my @exclude;
    692             my $val = $options->{$param};
    693             if (ref $val eq 'ARRAY') {
    694                 @exclude = @$val;
     1251            if (ref $newVal eq 'ARRAY') {
     1252                @exclude = @$newVal;
    6951253            } else {
    696                 @exclude = ($val);
    697             }
    698             ExpandShortcuts(\@exclude);
    699             $options->{$param} = \@exclude;
     1254                @exclude = ($newVal);
     1255            }
     1256            ExpandShortcuts(\@exclude, 1);  # (also remove '#' suffix)
     1257            $$options{$param} = \@exclude;
     1258        } elsif ($param =~ /^Charset/ or $param eq 'IPTCCharset') {
     1259            # only allow valid character sets to be set
     1260            if ($newVal) {
     1261                my $charset = $charsetName{lc $newVal};
     1262                if ($charset) {
     1263                    $$options{$param} = $charset;
     1264                    # maintain backward-compatibility with old IPTCCharset option
     1265                    $$options{CharsetIPTC} = $charset if $param eq 'IPTCCharset';
     1266                } else {
     1267                    warn "Invalid Charset $newVal\n";
     1268                }
     1269            }
     1270        } else {
     1271            if ($param eq 'Escape') {
     1272                # set ESCAPE_PROC
     1273                if (defined $newVal and $newVal eq 'XML') {
     1274                    require Image::ExifTool::XMP;
     1275                    $$self{ESCAPE_PROC} = \&Image::ExifTool::XMP::EscapeXML;
     1276                } elsif (defined $newVal and $newVal eq 'HTML') {
     1277                    require Image::ExifTool::HTML;
     1278                    $$self{ESCAPE_PROC} = \&Image::ExifTool::HTML::EscapeHTML;
     1279                } else {
     1280                    delete $$self{ESCAPE_PROC};
     1281                }
     1282                # must forget saved values since they depend on Escape method
     1283                $self->{BOTH} = { };
     1284            }
     1285            $$options{$param} = $newVal;
    7001286        }
    7011287    }
     
    7131299    # create options hash with default values
    7141300    # (commented out options don't need initializing)
     1301    # +-----------------------------------------------------+
     1302    # ! DON'T FORGET!!  When adding any new option, must    !
     1303    # ! decide how it is handled in SetNewValuesFromFile()  !
     1304    # +-----------------------------------------------------+
    7151305    $self->{OPTIONS} = {
    7161306    #   Binary      => undef,   # flag to extract binary values even if tag not specified
    7171307    #   ByteOrder   => undef,   # default byte order when creating EXIF information
    7181308        Charset     => 'UTF8',  # character set for converting Unicode characters
     1309        CharsetID3  => 'Latin', # internal ID3v1 character set
     1310        CharsetIPTC => 'Latin', # fallback IPTC character set if no CodedCharacterSet
    7191311    #   Compact     => undef,   # compact XMP and IPTC data
    7201312        Composite   => 1,       # flag to calculate Composite tags
     
    7231315    #   DateFormat  => undef,   # format for date/time
    7241316        Duplicates  => 1,       # flag to save duplicate tag values
     1317    #   Escape      => undef,   # escape special characters
    7251318    #   Exclude     => undef,   # tags to exclude
     1319    #   ExtractEmbedded =>undef,# flag to extract information from embedded documents
    7261320    #   FastScan    => undef,   # flag to avoid scanning for trailer
    7271321    #   FixBase     => undef,   # fix maker notes base offsets
     1322    #   GeoMaxIntSecs => undef, # geotag maximum interpolation time (secs)
     1323    #   GeoMaxExtSecs => undef, # geotag maximum extrapolation time (secs)
     1324    #   GeoMaxHDOP  => undef,   # geotag maximum HDOP
     1325    #   GeoMaxPDOP  => undef,   # geotag maximum PDOP
     1326    #   GeoMinSats  => undef,   # geotag minimum satellites
    7281327    #   Group#      => undef,   # return tags for specified groups in family #
    7291328        HtmlDump    => 0,       # HTML dump (0-3, higher # = bigger limit)
    7301329    #   HtmlDumpBase => undef,  # base address for HTML dump
    7311330    #   IgnoreMinorErrors => undef, # ignore minor errors when reading/writing
     1331        Lang        => $defaultLang,# localized language for descriptions etc
     1332    #   LargeFileSupport => undef,  # flag indicating support of 64-bit file offsets
    7321333    #   List        => undef,   # extract lists of PrintConv values into arrays
     1334        ListSep     => ', ',    # list item separator
     1335    #   ListSplit   => undef,   # regex for splitting list-type tag values when writing
    7331336    #   MakerNotes  => undef,   # extract maker notes as a block
    7341337    #   MissingTagValue =>undef,# value for missing tags when expanded in expressions
     1338    #   Password    => undef,   # password for password-protected PDF documents
    7351339        PrintConv   => 1,       # flag to enable print conversion
     1340    #   SavePath    => undef,   # (undocumented) save family 5 location path
    7361341    #   ScanForXMP  => undef,   # flag to scan for XMP information in all files
    7371342        Sort        => 'Input', # order to sort found tags (Input, File, Alpha, Group#)
    7381343    #   StrictDate  => undef,   # flag to return undef for invalid date conversions
     1344    #   Struct      => undef,   # return structures as hash references
    7391345        TextOut     => \*STDOUT,# file for Verbose/HtmlDump output
    7401346        Unknown     => 0,       # flag to get values of unknown tags (0-2)
    741         Verbose     => 0,       # print verbose messages (0-4, higher # = more verbose)
     1347        Verbose     => 0,       # print verbose messages (0-5, higher # = more verbose)
    7421348    };
     1349    # keep necessary member variables in sync with options
     1350    delete $$self{CUR_LANG};
     1351    delete $$self{ESCAPE_PROC};
     1352
     1353    # load user-defined default options
     1354    if (%Image::ExifTool::UserDefined::Options) {
     1355        foreach (keys %Image::ExifTool::UserDefined::Options) {
     1356            $self->Options($_, $Image::ExifTool::UserDefined::Options{$_});
     1357        }
     1358    }
    7431359}
    7441360
     
    7491365# Returns: 1 if this was a valid image, 0 otherwise
    7501366# Notes: pass an undefined value to avoid parsing arguments
     1367# Internal 'ReEntry' option allows this routine to be called recursively
    7511368sub ExtractInfo($;@)
    7521369{
     
    7541371    my $self = shift;
    7551372    my $options = $self->{OPTIONS};     # pointer to current options
    756     my %saveOptions;
    757 
    758     if (defined $_[0] or $options->{HtmlDump}) {
    759         %saveOptions = %$options;       # save original options
    760        
    761         # require duplicates for html dump
    762         $self->Options(Duplicates => 1) if $options->{HtmlDump};
    763 
    764         if (defined $_[0]) {
    765             # only initialize filename if called with arguments
    766             $self->{FILENAME} = undef;  # name of file (or '' if we didn't open it)
    767             $self->{RAF} = undef;       # RandomAccess object reference
     1373    my (%saveOptions, $reEntry, $rsize);
     1374
     1375    # check for internal ReEntry option to allow recursive calls to ExtractInfo
     1376    if (ref $_[1] eq 'HASH' and $_[1]{ReEntry} and
     1377       (ref $_[0] eq 'SCALAR' or ref $_[0] eq 'GLOB'))
     1378    {
     1379        # save necessary members for restoring later
     1380        $reEntry = {
     1381            RAF       => $$self{RAF},
     1382            PROCESSED => $$self{PROCESSED},
     1383            EXIF_DATA => $$self{EXIF_DATA},
     1384            EXIF_POS  => $$self{EXIF_POS},
     1385            FILE_TYPE => $$self{FILE_TYPE},
     1386        };
     1387        $self->{RAF} = new File::RandomAccess($_[0]);
     1388        $$self{PROCESSED} = { };
     1389        delete $$self{EXIF_DATA};
     1390        delete $$self{EXIF_POS};
     1391    } else {
     1392        if (defined $_[0] or $options->{HtmlDump}) {
     1393            %saveOptions = %$options;       # save original options
    7681394   
    769             $self->ParseArguments(@_);  # initialize from our arguments
    770         }
    771     }
    772     # initialize ExifTool object members
    773     $self->Init();
    774 
    775     delete $self->{MAKER_NOTE_FIXUP};   # fixup information for extracted maker notes
    776     delete $self->{MAKER_NOTE_BYTE_ORDER};
    777     delete $self->{DONE_ID3};
    778 
     1395            # require duplicates for html dump
     1396            $self->Options(Duplicates => 1) if $options->{HtmlDump};
     1397   
     1398            if (defined $_[0]) {
     1399                # only initialize filename if called with arguments
     1400                $self->{FILENAME} = undef;  # name of file (or '' if we didn't open it)
     1401                $self->{RAF} = undef;       # RandomAccess object reference
     1402   
     1403                $self->ParseArguments(@_);  # initialize from our arguments
     1404            }
     1405        }
     1406        # initialize ExifTool object members
     1407        $self->Init();
     1408
     1409        delete $self->{MAKER_NOTE_FIXUP};   # fixup information for extracted maker notes
     1410        delete $self->{MAKER_NOTE_BYTE_ORDER};
     1411
     1412        # return our version number
     1413        $self->FoundTag('ExifToolVersion', "$VERSION$RELEASE");
     1414        $self->FoundTag('Now', time()) if $self->{REQ_TAG_LOOKUP}{now} or $self->{TAGS_FROM_FILE};
     1415    }
    7791416    my $filename = $self->{FILENAME};   # image file name ('' if already open)
    7801417    my $raf = $self->{RAF};             # RandomAccess object
    7811418
    782     # return our version number
    783     $self->FoundTag('ExifToolVersion', "$VERSION$RELEASE");
    784 
    7851419    local *EXIFTOOL_FILE;   # avoid clashes with global namespace
    7861420
     1421    my $realname = $filename;
    7871422    unless ($raf) {
    7881423        # save file name
    7891424        if (defined $filename and $filename ne '') {
    7901425            unless ($filename eq '-') {
    791                 my $name = $filename;
    7921426                # extract file name from pipe if necessary
    793                 $name =~ /\|$/ and $name =~ s/.*?"(.*)".*/$1/;
    794                 my $dir;
     1427                $realname =~ /\|$/ and $realname =~ s/.*?"(.*?)".*/$1/;
     1428                my ($dir, $name);
    7951429                if (eval 'require File::Basename') {
    796                     $dir = File::Basename::dirname($name);
    797                     $name = File::Basename::basename($name);
     1430                    $dir = File::Basename::dirname($realname);
     1431                    $name = File::Basename::basename($realname);
    7981432                } else {
    799                     $name =~ tr/\\/\//;
    800                     if ($name =~ s/(.*)\///) {  # remove path
    801                         $dir = length($1) ? $1 : '/';
    802                     }
     1433                    ($name = $realname) =~ tr/\\/\//;
     1434                    # remove path
     1435                    $dir = length($1) ? $1 : '/' if $name =~ s/(.*)\///;
    8031436                }
    8041437                $self->FoundTag('FileName', $name);
    8051438                $self->FoundTag('Directory', $dir) if defined $dir and length $dir;
     1439                # get size of resource fork on Mac OS
     1440                $rsize = -s "$filename/rsrc" if $^O eq 'darwin' and not $$self{IN_RESOURCE};
    8061441            }
    8071442            # open the file
    808             if (open(EXIFTOOL_FILE,$filename)) {
    809                 my $filePt = \*EXIFTOOL_FILE;
     1443            if (open(EXIFTOOL_FILE, $filename)) {
    8101444                # create random access file object
    811                 $raf = new File::RandomAccess($filePt);
     1445                $raf = new File::RandomAccess(\*EXIFTOOL_FILE);
    8121446                # patch to force pipe to be buffered because seek returns success
    8131447                # in Windows cmd shell pipe even though it really failed
     
    8231457
    8241458    if ($raf) {
    825         # get file size and last modified time if this is a plain file
    826         if ($raf->{FILE_PT} and -f $raf->{FILE_PT}) {
     1459        if ($reEntry) {
     1460            # we already set these tags
     1461        } elsif (not $raf->{FILE_PT}) {
     1462            # get file size from image in memory
     1463            $self->FoundTag('FileSize', length ${$raf->{BUFF_PT}});
     1464        } elsif (-f $raf->{FILE_PT}) {
     1465            # get file size and last modified time if this is a plain file
    8271466            my $fileSize = -s _;
    8281467            my $fileTime = -M _;
     1468            my @stat = stat _;
    8291469            $self->FoundTag('FileSize', $fileSize) if defined $fileSize;
     1470            $self->FoundTag('ResourceForkSize', $rsize) if $rsize;
    8301471            $self->FoundTag('FileModifyDate', $^T - $fileTime*(24*3600)) if defined $fileTime;
     1472            $self->FoundTag('FilePermissions', $stat[2]) if defined $stat[2];
    8311473        }
    8321474
    8331475        # get list of file types to check
    834         my $tiffType;
    835         $self->{FILE_EXT} = GetFileExtension($filename);
    836         my @fileTypeList = GetFileType($filename);
     1476        my ($tiffType, %noMagic);
     1477        $self->{FILE_EXT} = GetFileExtension($realname);
     1478        my @fileTypeList = GetFileType($realname);
    8371479        if (@fileTypeList) {
    8381480            # add remaining types to end of list so we test them all
     
    8401482            push @fileTypeList, grep(!/^($pat)$/, @fileTypes);
    8411483            $tiffType = $self->{FILE_EXT};
     1484            $noMagic{MXF} = 1;  # don't do magic number test on MXF or DV files
     1485            $noMagic{DV} = 1;
    8421486        } else {
    8431487            # scan through all recognized file types
     
    8511495        my %dirInfo = ( RAF => $raf, Base => $pos );
    8521496        # loop through list of file types to test
    853         my $type;
    854         for (;;) {
     1497        my ($type, $buff, $seekErr);
     1498        # read first 1024 bytes of file for testing
     1499        $raf->Read($buff, 1024) or $buff = '';
     1500        $raf->Seek($pos, 0) or $seekErr = 1;
     1501        until ($seekErr) {
    8551502            $type = shift @fileTypeList;
    856             unless ($type) {
     1503            if ($type) {
     1504                # do quick test for this file type to avoid loading module unnecessarily
     1505                next if $magicNumber{$type} and $buff !~ /^$magicNumber{$type}/s and
     1506                        not $noMagic{$type};
     1507            } else {
    8571508                last unless defined $type;
    8581509                # last ditch effort to scan past unknown header for JPEG/TIFF
    859                 my $buff;
    860                 $raf->Read($buff, 1024);
    8611510                next unless $buff =~ /(\xff\xd8\xff|MM\0\x2a|II\x2a\0)/g;
    8621511                $type = ($1 eq "\xff\xd8\xff") ? 'JPEG' : 'TIFF';
    8631512                my $skip = pos($buff) - length($1);
    8641513                $dirInfo{Base} = $pos + $skip;
    865                 $raf->Seek($pos + $skip, 0);
     1514                $raf->Seek($pos + $skip, 0) or $seekErr = 1, last;
    8661515                $self->Warn("Skipped unknown $skip byte header");
    8671516            }
    8681517            # save file type in member variable
    869             $self->{FILE_TYPE} = $type;
     1518            $self->{FILE_TYPE} = $self->{PATH}[0] = $type;
    8701519            $dirInfo{Parent} = ($type eq 'TIFF') ? $tiffType : $type;
    8711520            my $module = $moduleName{$type};
     
    8771526                require "Image/ExifTool/$module.pm";
    8781527                $func = "Image::ExifTool::${module}::$func";
     1528            } elsif ($module eq '0') {
     1529                $self->SetFileType();
     1530                $self->Warn('Unsupported file type');
     1531                last;
    8791532            }
    8801533            # process the file
     
    8841537
    8851538            # seek back to try again from the same position in the file
    886             unless ($raf->Seek($pos, 0)) {
    887                 $self->Error('Error seeking in file');
    888                 last;
    889             }
    890         }
    891         # scan for XMP if specified
    892         if ($self->Options('ScanForXMP') and (not defined $type or
     1539            $raf->Seek($pos, 0) or $seekErr = 1, last;
     1540        }
     1541        if ($seekErr) {
     1542            $self->Error('Error seeking in file');
     1543        } elsif ($self->Options('ScanForXMP') and (not defined $type or
    8931544            (not $self->Options('FastScan') and not $$self{FoundXMP})))
    8941545        {
     1546            # scan for XMP
    8951547            $raf->Seek($pos, 0);
    8961548            require Image::ExifTool::XMP;
     
    9011553            # must be a format error since we couldn't read it, otherwise
    9021554            # it is likely we don't support images of this type
    903             $self->Error(GetFileType($filename) ?
    904                 'File format error' : 'Unknown file type');
     1555            my $fileType = GetFileType($realname);
     1556            my $err;
     1557            if (not $fileType) {
     1558                $err = 'Unknown file type';
     1559            } elsif ($fileType eq 'RAW') {
     1560                $err = 'Unsupported RAW file type';
     1561            } else {
     1562                $err = 'File format error';
     1563            }
     1564            $self->Error($err);
    9051565        }
    9061566        # extract binary EXIF data block only if requested
    907         if (defined $self->{EXIF_DATA} and $self->{REQ_TAG_LOOKUP}->{exif}) {
     1567        if (defined $self->{EXIF_DATA} and length $$self{EXIF_DATA} > 16 and
     1568            ($self->{REQ_TAG_LOOKUP}{exif} or $self->{OPTIONS}{Binary}))
     1569        {
    9081570            $self->FoundTag('EXIF', $self->{EXIF_DATA});
    9091571        }
    910         # calculate composite tags
    911         $self->BuildCompositeTags() if $options->{Composite};
    912 
    913         # do our HTML dump if requested
    914         if ($self->{HTML_DUMP}) {
    915             $raf->Seek(0, 2);   # seek to end of file
    916             $self->{HTML_DUMP}->FinishTiffDump($self, $raf->Tell());
    917             my $pos = $options->{HtmlDumpBase};
    918             $pos = ($self->{FIRST_EXIF_POS} || 0) unless defined $pos;
    919             my $dataPt = defined $self->{EXIF_DATA} ? \$self->{EXIF_DATA} : undef;
    920             undef $dataPt if defined $self->{EXIF_POS} and $pos != $self->{EXIF_POS};
    921             $self->{HTML_DUMP}->Print($raf, $dataPt, $pos,
    922                 $options->{TextOut}, $options->{HtmlDump},
    923                 $self->{FILENAME} ? "HTML Dump ($self->{FILENAME})" : 'HTML Dump');
    924         }
    925 
    926         $raf->Close() if $filename;     # close the file if we opened it
     1572        unless ($reEntry) {
     1573            $self->{PATH} = [ ];    # reset PATH
     1574            # calculate Composite tags
     1575            $self->BuildCompositeTags() if $options->{Composite};
     1576            # do our HTML dump if requested
     1577            if ($self->{HTML_DUMP}) {
     1578                $raf->Seek(0, 2);   # seek to end of file
     1579                $self->{HTML_DUMP}->FinishTiffDump($self, $raf->Tell());
     1580                my $pos = $options->{HtmlDumpBase};
     1581                $pos = ($self->{FIRST_EXIF_POS} || 0) unless defined $pos;
     1582                my $dataPt = defined $self->{EXIF_DATA} ? \$self->{EXIF_DATA} : undef;
     1583                undef $dataPt if defined $self->{EXIF_POS} and $pos != $self->{EXIF_POS};
     1584                my $success = $self->{HTML_DUMP}->Print($raf, $dataPt, $pos,
     1585                    $options->{TextOut}, $options->{HtmlDump},
     1586                    $self->{FILENAME} ? "HTML Dump ($self->{FILENAME})" : 'HTML Dump');
     1587                $self->Warn("Error reading $self->{HTML_DUMP}{ERROR}") if $success < 0;
     1588            }
     1589        }
     1590        if ($filename) {
     1591            $raf->Close();  # close the file if we opened it
     1592            # process the resource fork as an embedded file on Mac filesystems
     1593            if ($rsize and $options->{ExtractEmbedded}) {
     1594                local *RESOURCE_FILE;
     1595                if (open(RESOURCE_FILE, "$filename/rsrc")) {
     1596                    $$self{DOC_NUM} = $$self{DOC_COUNT} + 1;
     1597                    $$self{IN_RESOURCE} = 1;
     1598                    $self->ExtractInfo(\*RESOURCE_FILE, { ReEntry => 1 });
     1599                    close RESOURCE_FILE;
     1600                    delete $$self{IN_RESOURCE};
     1601                } else {
     1602                    $self->Warn('Error opening resource fork');
     1603                }
     1604            }
     1605        }
    9271606    }
    9281607
     
    9301609    %saveOptions and $self->{OPTIONS} = \%saveOptions;
    9311610
    932     return exists $self->{VALUE}->{Error} ? 0 : 1;
     1611    if ($reEntry) {
     1612        # restore necessary members when exiting re-entrant code
     1613        $$self{$_} = $$reEntry{$_} foreach keys %$reEntry;
     1614    }
     1615
     1616    return exists $self->{VALUE}{Error} ? 0 : 1;
    9331617}
    9341618
     
    9411625#        - If groups are specified, first groups take precedence if duplicate
    9421626#          tags found but Duplicates option not set.
     1627#        - tag names may end in '#' to extract ValueConv value
    9431628sub GetInfo($;@)
    9441629{
     
    9551640
    9561641    # get reference to list of tags for which we will return info
    957     my $rtnTags = $self->SetFoundTags();
     1642    my ($rtnTags, $byValue) = $self->SetFoundTags();
    9581643
    9591644    # build hash of tag information
    9601645    my (%info, %ignored);
    961     my $conv = $self->{OPTIONS}->{PrintConv} ? 'PrintConv' : 'ValueConv';
     1646    my $conv = $self->{OPTIONS}{PrintConv} ? 'PrintConv' : 'ValueConv';
    9621647    foreach (@$rtnTags) {
    9631648        my $val = $self->GetValue($_, $conv);
    9641649        defined $val or $ignored{$_} = 1, next;
    9651650        $info{$_} = $val;
     1651    }
     1652
     1653    # override specified tags with ValueConv value if necessary
     1654    if (@$byValue and $conv ne 'ValueConv') {
     1655        # first determine the number of times each non-ValueConv value is used
     1656        my %nonVal;
     1657        $nonVal{$_} = ($nonVal{$_} || 0) + 1 foreach @$rtnTags;
     1658        --$nonVal{$$rtnTags[$_]} foreach @$byValue;
     1659        # loop through ValueConv tags, updating tag keys and returned values
     1660        foreach (@$byValue) {
     1661            my $tag = $$rtnTags[$_];
     1662            my $val = $self->GetValue($tag, 'ValueConv');
     1663            next unless defined $val;
     1664            my $vtag = $tag;
     1665            # generate a new tag key like "Tag #" or "Tag #(1)"
     1666            $vtag =~ s/( |$)/ #/;
     1667            unless (defined $self->{VALUE}->{$vtag}) {
     1668                $self->{VALUE}{$vtag} = $self->{VALUE}{$tag};
     1669                $self->{TAG_INFO}{$vtag} = $self->{TAG_INFO}{$tag};
     1670                $self->{TAG_EXTRA}{$vtag} = $self->{TAG_EXTRA}{$tag};
     1671                $self->{FILE_ORDER}{$vtag} = $self->{FILE_ORDER}{$tag};
     1672                # remove existing PrintConv entry unless we are using it too
     1673                delete $info{$tag} unless $nonVal{$tag};
     1674            }
     1675            $$rtnTags[$_] = $vtag;  # store ValueConv value with new tag key
     1676            $info{$vtag} = $val;    # return ValueConv value
     1677        }
    9661678    }
    9671679
     
    9801692        # use file order by default if no tags specified
    9811693        # (no such thing as 'Input' order in this case)
    982         my $sortOrder = $self->{OPTIONS}->{Sort};
     1694        my $sortOrder = $self->{OPTIONS}{Sort};
    9831695        unless (@$reqTags or ($sortOrder and $sortOrder ne 'Input')) {
    9841696            $sortOrder = 'File';
     
    10031715    local $_;
    10041716    my $self = shift;
    1005     my (%combinedInfo, $info);
    1006 
    1007     if ($self->{OPTIONS}->{Duplicates}) {
     1717    my (%combinedInfo, $info, $tag, %haveInfo);
     1718
     1719    if ($self->{OPTIONS}{Duplicates}) {
    10081720        while ($info = shift) {
    1009             my $key;
    1010             foreach $key (keys %$info) {
    1011                 $combinedInfo{$key} = $$info{$key};
     1721            foreach $tag (keys %$info) {
     1722                $combinedInfo{$tag} = $$info{$tag};
    10121723            }
    10131724        }
    10141725    } else {
    1015         my (%haveInfo, $tag);
    10161726        while ($info = shift) {
    10171727            foreach $tag (keys %$info) {
     
    10561766        $foundTags = $self->{FOUND_TAGS} || $self->SetFoundTags() or return undef;
    10571767    }
    1058     $sortOrder or $sortOrder = $self->{OPTIONS}->{Sort};
     1768    $sortOrder or $sortOrder = $self->{OPTIONS}{Sort};
    10591769
    10601770    # return original list if no sort order specified
     
    10631773    if ($sortOrder eq 'Alpha') {
    10641774        return sort @$foundTags;
    1065     } elsif ($sortOrder =~ /^Group(\d*)/) {
     1775    } elsif ($sortOrder =~ /^Group(\d*(:\d+)*)/) {
    10661776        my $family = $1 || 0;
    10671777        # want to maintain a basic file order with the groups
     
    10861796# Get list of found tags in specified sort order
    10871797# Inputs: 0) ExifTool object reference, 1) sort order ('File', 'Input', ...)
    1088 # Returns: List of tags in specified order
     1798# Returns: List of tag keys in specified order
    10891799# Notes: If not specified, sort order is taken from OPTIONS
    10901800sub GetFoundTags($;$)
     
    10991809# Get list of requested tags
    11001810# Inputs: 0) ExifTool object reference
    1101 # Returns: List of requested tags
     1811# Returns: List of requested tag keys
    11021812sub GetRequestedTags($)
    11031813{
    11041814    local $_;
    1105     return @{$_[0]->{REQUESTED_TAGS}};
     1815    return @{$_[0]{REQUESTED_TAGS}};
    11061816}
    11071817
    11081818#------------------------------------------------------------------------------
    11091819# Get tag value
    1110 # Inputs: 0) ExifTool object reference, 1) tag key
     1820# Inputs: 0) ExifTool object reference
     1821#         1) tag key (or flattened tagInfo for getting field values, not part of public API)
    11111822#         2) [optional] Value type: PrintConv, ValueConv, Both or Raw, the default
    11121823#            is PrintConv or ValueConv, depending on the PrintConv option setting
     1824#         3) raw field value (not part of public API)
    11131825# Returns: Scalar context: tag value or undefined
    11141826#          List context: list of values or empty list
     
    11161828{
    11171829    local $_;
    1118     my ($self, $tag, $type) = @_;
     1830    my ($self, $tag, $type) = @_; # plus: ($fieldValue)
     1831    my (@convTypes, $tagInfo, $valueConv, $both);
     1832
     1833    # figure out what conversions to do
     1834    $type or $type = $self->{OPTIONS}{PrintConv} ? 'PrintConv' : 'ValueConv';
    11191835
    11201836    # start with the raw value
    1121     my $value = $self->{VALUE}->{$tag};
    1122     return wantarray ? () : undef unless defined $value;
    1123 
    1124     # figure out what conversions to do
    1125     my (@convTypes, $tagInfo);
    1126     $type or $type = $self->{OPTIONS}->{PrintConv} ? 'PrintConv' : 'ValueConv';
    1127     unless ($type eq 'Raw') {
    1128         $tagInfo = $self->{TAG_INFO}->{$tag};
    1129         push @convTypes, 'ValueConv';
    1130         push @convTypes, 'PrintConv' unless $type eq 'ValueConv';
     1837    my $value = $self->{VALUE}{$tag};
     1838    if (not defined $value) {
     1839        return wantarray ? () : undef unless ref $tag;
     1840        # get the value of a structure field
     1841        $tagInfo = $tag;
     1842        $tag = $$tagInfo{Name};
     1843        $value = $_[3];
     1844        # (note: type "Both" is not allowed for structure fields)
     1845        if ($type ne 'Raw') {
     1846            push @convTypes, 'ValueConv';
     1847            push @convTypes, 'PrintConv' unless $type eq 'ValueConv';
     1848        }
     1849    } else {
     1850        $tagInfo = $self->{TAG_INFO}{$tag};
     1851        if ($$tagInfo{Struct} and ref $value) {
     1852            # must load XMPStruct.pl just in case (should already be loaded if
     1853            # a structure was extracted, but we could also arrive here if a simple
     1854            # list of values was stored incorrectly in a Struct tag)
     1855            require 'Image/ExifTool/XMPStruct.pl';
     1856            # convert strucure field values
     1857            unless ($type eq 'Both') {
     1858                # (note: ConvertStruct handles the escape too if necessary)
     1859                return Image::ExifTool::XMP::ConvertStruct($self,$tagInfo,$value,$type);
     1860            }
     1861            $valueConv = Image::ExifTool::XMP::ConvertStruct($self,$tagInfo,$value,'ValueConv');
     1862            $value = Image::ExifTool::XMP::ConvertStruct($self,$tagInfo,$value,'PrintConv');
     1863            # (must not save these in $$self{BOTH} because the values may have been escaped)
     1864            return ($valueConv, $value);
     1865        }
     1866        if ($type ne 'Raw') {
     1867            # use values we calculated already if we stored them
     1868            $both = $self->{BOTH}{$tag};
     1869            if ($both) {
     1870                if ($type eq 'PrintConv') {
     1871                    $value = $$both[1];
     1872                } elsif ($type eq 'ValueConv') {
     1873                    $value = $$both[0];
     1874                    $value = $$both[1] unless defined $value;
     1875                } else {
     1876                    ($valueConv, $value) = @$both;
     1877                }
     1878            } else {
     1879                push @convTypes, 'ValueConv';
     1880                push @convTypes, 'PrintConv' unless $type eq 'ValueConv';
     1881            }
     1882        }
    11311883    }
    11321884
    11331885    # do the conversions
    1134     my (@val, @prt, @raw, $convType, $valueConv);
     1886    my (@val, @prt, @raw, $convType);
    11351887    foreach $convType (@convTypes) {
    1136         last if ref $value eq 'SCALAR'; # don't convert a scalar reference
     1888        # don't convert a scalar reference or structure
     1889        last if ref $value eq 'SCALAR';
    11371890        my $conv = $$tagInfo{$convType};
    11381891        unless (defined $conv) {
     
    11411894                $conv = '\$val';  # return scalar reference for binary values
    11421895            } else {
    1143                 # use PRINT_CONV from tag table if PrintConv not defined
    1144                 next unless defined($conv = $tagInfo->{Table}->{PRINT_CONV});
     1896                # use PRINT_CONV from tag table if PrintConv doesn't exist
     1897                next unless defined($conv = $tagInfo->{Table}{PRINT_CONV});
     1898                next if exists $$tagInfo{$convType};
    11451899            }
    11461900        }
     
    11531907            $conv = $$convList[0];
    11541908            my @valList = split ' ', $value;
    1155             $value = \@valList;
     1909            # reorganize list if specified (Note: The writer currently doesn't
     1910            # relist values, so they may be grouped but the order must not change)
     1911            my $relist = $$tagInfo{Relist};
     1912            if ($relist) {
     1913                my (@newList, $oldIndex);
     1914                foreach $oldIndex (@$relist) {
     1915                    my ($newVal, @join);
     1916                    if (ref $oldIndex) {
     1917                        foreach (@$oldIndex) {
     1918                            push @join, $valList[$_] if defined $valList[$_];
     1919                        }
     1920                        $newVal = join(' ', @join) if @join;
     1921                    } else {
     1922                        $newVal = $valList[$oldIndex];
     1923                    }
     1924                    push @newList, $newVal if defined $newVal;
     1925                }
     1926                $value = \@newList;
     1927            } else {
     1928                $value = \@valList;
     1929            }
    11561930        }
    11571931        # initialize array so we can iterate over values in list
     
    11661940        for (;;) {
    11671941            if (defined $conv) {
    1168                 # get values of required tags if this is a composite tag
     1942                # get values of required tags if this is a Composite tag
    11691943                if (ref $val eq 'HASH' and not @val) {
     1944                    # disable escape of source values so we don't double escape them
     1945                    my $oldEscape = $$self{ESCAPE_PROC};
     1946                    delete $$self{ESCAPE_PROC};
    11701947                    foreach (keys %$val) {
    1171                         $raw[$_] = $self->{VALUE}->{$$val{$_}};
     1948                        $raw[$_] = $self->{VALUE}{$$val{$_}};
    11721949                        ($val[$_], $prt[$_]) = $self->GetValue($$val{$_}, 'Both');
    1173                         next if defined $val[$_] or not $tagInfo->{Require}->{$_};
     1950                        next if defined $val[$_] or not $tagInfo->{Require}{$_};
     1951                        $$self{ESCAPE_PROC} = $oldEscape;
    11741952                        return wantarray ? () : undef;
    11751953                    }
     1954                    $$self{ESCAPE_PROC} = $oldEscape;
    11761955                    # set $val to $val[0], or \@val for a CODE ref conversion
    11771956                    $val = ref $conv eq 'CODE' ? \@val : $val[0];
     
    11791958                if (ref $conv eq 'HASH') {
    11801959                    # look up converted value in hash
    1181                     unless (defined($value = $$conv{$val})) {
     1960                    my $lc;
     1961                    if (defined($value = $$conv{$val})) {
     1962                        # override with our localized language PrintConv if available
     1963                        if ($$self{CUR_LANG} and $convType eq 'PrintConv' and
     1964                            # (no need to check for lang-alt tag names -- they won't have a PrintConv)
     1965                            ref($lc = $self->{CUR_LANG}{$$tagInfo{Name}}) eq 'HASH' and
     1966                            ($lc = $$lc{PrintConv}) and ($lc = $$lc{$value}))
     1967                        {
     1968                            $value = $self->Decode($lc, 'UTF8');
     1969                        }
     1970                    } else {
    11821971                        if ($$conv{BITMASK}) {
    11831972                            $value = DecodeBits($val, $$conv{BITMASK});
    1184                         } else {
    1185                             if ($$tagInfo{PrintHex} and $val and IsInt($val) and
    1186                                 $convType eq 'PrintConv')
     1973                            # override with localized language strings
     1974                            if (defined $value and $$self{CUR_LANG} and $convType eq 'PrintConv' and
     1975                                ref($lc = $self->{CUR_LANG}{$$tagInfo{Name}}) eq 'HASH' and
     1976                                ($lc = $$lc{PrintConv}))
     1977                            {
     1978                                my @vals = split ', ', $value;
     1979                                foreach (@vals) {
     1980                                    $_ = $$lc{$_} if defined $$lc{$_};
     1981                                }
     1982                                $value = join ', ', @vals;
     1983                            }
     1984                        } elsif (not $$conv{OTHER} or
     1985                                 # use alternate conversion routine if available
     1986                                 not defined($value = &{$$conv{OTHER}}($val, undef, $conv)))
     1987                        {
     1988                            if (($$tagInfo{PrintHex} or
     1989                                ($$tagInfo{Mask} and not defined $$tagInfo{PrintHex}))
     1990                                and $val and IsInt($val) and $convType eq 'PrintConv')
    11871991                            {
    11881992                                $val = sprintf('0x%x',$val);
     
    12022006                        $@ and $evalWarning = $@;
    12032007                    }
    1204                     if ($evalWarning) {
    1205                         delete $SIG{'__WARN__'};
    1206                         warn "$convType $tag: " . CleanWarning() . "\n";
    1207                     }
     2008                    $self->Warn("$convType $tag: " . CleanWarning()) if $evalWarning;
    12082009                }
    12092010            } else {
     
    12282029    }
    12292030    if ($type eq 'Both') {
    1230         # $valueConv is undefined if there was no print conversion done
    1231         $valueConv = $value unless defined $valueConv;
     2031        # save both (unescaped) values because we often need them again
     2032        # (Composite tags need "Both" and often Require one tag for various Composite tags)
     2033        $self->{BOTH}{$tag} = [ $valueConv, $value ] unless $both;
     2034        # escape values if necessary
     2035        if ($$self{ESCAPE_PROC}) {
     2036            DoEscape($value, $$self{ESCAPE_PROC});
     2037            if (defined $valueConv) {
     2038                DoEscape($valueConv, $$self{ESCAPE_PROC});
     2039            } else {
     2040                $valueConv = $value;
     2041            }
     2042        } elsif (not defined $valueConv) {
     2043            # $valueConv is undefined if there was no print conversion done
     2044            $valueConv = $value;
     2045        }
    12322046        # return Both values as a list (ValueConv, PrintConv)
    12332047        return ($valueConv, $value);
    12342048    }
     2049    # escape value if necessary
     2050    DoEscape($value, $$self{ESCAPE_PROC}) if $$self{ESCAPE_PROC};
     2051
    12352052    if (ref $value eq 'ARRAY') {
    12362053        # return array if requested
    12372054        return @$value if wantarray;
    1238         # return list reference for Raw, ValueConv or if List option set
    1239         return $value if @convTypes < 2 or $self->{OPTIONS}->{List};
     2055        # return list reference for Raw, ValueConv or if List or not a list of scalars
     2056        return $value if $type ne 'PrintConv' or $self->{OPTIONS}{List} or ref $$value[0];
    12402057        # otherwise join in comma-separated string
    1241         $value = join ', ', @$value;
     2058        $value = join $self->{OPTIONS}{ListSep}, @$value;
    12422059    }
    12432060    return $value;
     
    12472064# Get tag identification number
    12482065# Inputs: 0) ExifTool object reference, 1) tag key
    1249 # Returns: Tag ID if available, otherwise ''
     2066# Returns: Scalar context: Tag ID if available, otherwise ''
     2067#          List context: 0) Tag ID (or ''), 1) language code (or undef)
    12502068sub GetTagID($$)
    12512069{
    1252     local $_;
    12532070    my ($self, $tag) = @_;
    1254     my $tagInfo = $self->{TAG_INFO}->{$tag};
    1255 
    1256     if ($tagInfo) {
    1257         GenerateAllTagIDs();    # make sure tag ID's are generated
    1258         defined $$tagInfo{TagID} and return $$tagInfo{TagID};
    1259     }
    1260     # no ID for this tag (shouldn't happen)
    1261     return '';
     2071    my $tagInfo = $self->{TAG_INFO}{$tag};
     2072    return '' unless $tagInfo and defined $$tagInfo{TagID};
     2073    return ($$tagInfo{TagID}, $$tagInfo{LangCode}) if wantarray;
     2074    return $$tagInfo{TagID};
     2075}
     2076
     2077#------------------------------------------------------------------------------
     2078# Get tag table name
     2079# Inputs: 0) ExifTool object reference, 1) tag key
     2080# Returns: Table name if available, otherwise ''
     2081sub GetTableName($$)
     2082{
     2083    my ($self, $tag) = @_;
     2084    my $tagInfo = $self->{TAG_INFO}{$tag} or return '';
     2085    return $tagInfo->{Table}{SHORT_NAME};
     2086}
     2087
     2088#------------------------------------------------------------------------------
     2089# Get tag index number
     2090# Inputs: 0) ExifTool object reference, 1) tag key
     2091# Returns: Table index number, or undefined if this tag isn't indexed
     2092sub GetTagIndex($$)
     2093{
     2094    my ($self, $tag) = @_;
     2095    my $tagInfo = $self->{TAG_INFO}{$tag} or return undef;
     2096    return $$tagInfo{Index};
    12622097}
    12632098
     
    12712106    local $_;
    12722107    my ($self, $tag) = @_;
    1273     my $tagInfo = $self->{TAG_INFO}->{$tag};
    1274     # ($tagInfo should be defined for any extracted tag,
    1275     # but we might as well handle the case where it isn't)
    1276     my $desc;
    1277     $desc = $$tagInfo{Description} if $tagInfo;
     2108    my ($desc, $name);
     2109    my $tagInfo = $self->{TAG_INFO}{$tag};
     2110    # ($tagInfo won't be defined for missing tags extracted with -f)
     2111    if ($tagInfo) {
     2112        # use alternate language description if available
     2113        while ($$self{CUR_LANG}) {
     2114            $desc = $self->{CUR_LANG}{$$tagInfo{Name}};
     2115            if ($desc) {
     2116                # must look up Description if this tag also has a PrintConv
     2117                $desc = $$desc{Description} or last if ref $desc;
     2118            } else {
     2119                # look up default language of lang-alt tag
     2120                last unless $$tagInfo{LangCode} and
     2121                    ($name = $$tagInfo{Name}) =~ s/-$$tagInfo{LangCode}$// and
     2122                    $desc = $self->{CUR_LANG}{$name};
     2123                $desc = $$desc{Description} or last if ref $desc;
     2124                $desc .= " ($$tagInfo{LangCode})";
     2125            }
     2126            # escape description if necessary
     2127            DoEscape($desc, $$self{ESCAPE_PROC}) if $$self{ESCAPE_PROC};
     2128            # return description in proper Charset
     2129            return $self->Decode($desc, 'UTF8');
     2130        }
     2131        $desc = $$tagInfo{Description};
     2132    }
    12782133    # just make the tag more readable if description doesn't exist
    12792134    unless ($desc) {
     
    12892144# Inputs: 0) ExifTool object reference
    12902145#         1) tag key (or reference to tagInfo hash, not part of the public API)
    1291 #         2) [optional] group family number (-1 to get extended group list)
     2146#         2) [optional] group family (-1 to get extended group list)
    12922147# Returns: Scalar context: Group name (for family 0 if not otherwise specified)
    12932148#          Array context: Group name if family specified, otherwise list of
    1294 #          group names for each family.
     2149#          group names for each family.  Returns '' for undefined tag.
     2150# Notes: Mutiple families may be specified with ':' in family argument (ie. '1:2')
    12952151sub GetGroup($$;$)
    12962152{
    12972153    local $_;
    12982154    my ($self, $tag, $family) = @_;
    1299     my ($tagInfo, @groups, $extra);
     2155    my ($tagInfo, @groups, @families, $simplify, $byTagInfo);
    13002156    if (ref $tag eq 'HASH') {
    13012157        $tagInfo = $tag;
    1302         $tag = $tagInfo->{Name};
     2158        $tag = $$tagInfo{Name};
     2159        # set flag so we don't get extra information for an extracted tag
     2160        $byTagInfo = 1;
    13032161    } else {
    1304         $tagInfo = $self->{TAG_INFO}->{$tag} or return '';
     2162        $tagInfo = $self->{TAG_INFO}{$tag} or return '';
    13052163    }
    13062164    my $groups = $$tagInfo{Groups};
    13072165    # fill in default groups unless already done
     2166    # (after this, Groups 0-2 in tagInfo are guaranteed to be defined)
    13082167    unless ($$tagInfo{GotGroups}) {
    13092168        my $tagTablePtr = $$tagInfo{Table};
     
    13132172            # fill in default groups
    13142173            foreach (keys %{$$tagTablePtr{GROUPS}}) {
    1315                 $$groups{$_} or $$groups{$_} = $tagTablePtr->{GROUPS}->{$_};
     2174                $$groups{$_} or $$groups{$_} = $tagTablePtr->{GROUPS}{$_};
    13162175            }
    13172176        }
     
    13192178        $$tagInfo{GotGroups} = 1;
    13202179    }
    1321     if (defined $family and $family >= 0) {
    1322         return $$groups{$family} || 'Other' unless $family == 1;
    1323         $groups[$family] = $$groups{$family};
     2180    if (defined $family and $family ne '-1') {
     2181        if ($family =~ /[^\d]/) {
     2182            @families = ($family =~ /\d+/g);
     2183            return $$groups{0} unless @families;
     2184            $simplify = 1 unless $family =~ /^:/;
     2185            undef $family;
     2186            foreach (0..2) { $groups[$_] = $$groups{$_}; }
     2187        } else {
     2188            return $$groups{$family} if $family == 0 or $family == 2;
     2189            $groups[1] = $$groups{1};
     2190        }
    13242191    } else {
    13252192        return $$groups{0} unless wantarray;
    13262193        foreach (0..2) { $groups[$_] = $$groups{$_}; }
    13272194    }
    1328     # modify family 1 group name if necessary
    1329     if ($extra = $self->{GROUP1}->{$tag}) {
    1330         if ($extra =~ /^\+(.*)/) {
    1331             $groups[1] .= $1;
    1332         } else {
    1333             $groups[1] = $extra;
    1334         }
     2195    $groups[3] = 'Main';
     2196    $groups[4] = ($tag =~ /\((\d+)\)$/) ? "Copy$1" : '';
     2197    # handle dynamic group names if necessary
     2198    my $ex = $self->{TAG_EXTRA}{$tag};
     2199    if ($ex and not $byTagInfo) {
     2200        $groups[0] = $$ex{G0} if $$ex{G0};
     2201        $groups[1] = $$ex{G1} =~ /^\+(.*)/ ? "$groups[1]$1" : $$ex{G1} if $$ex{G1};
     2202        $groups[3] = 'Doc' . $$ex{G3} if $$ex{G3};
     2203        $groups[5] = $$ex{G5} || $groups[1] if defined $$ex{G5};
    13352204    }
    13362205    if ($family) {
    1337         return $groups[1] if $family == 1;
     2206        return $groups[$family] || '' if $family > 0;
    13382207        # add additional matching group names to list
    13392208        # ie) for MIE-Doc, also add MIE1, MIE1-Doc, MIE-Doc1 and MIE1-Doc1
     
    13462215        }
    13472216    }
     2217    if (@families) {
     2218        my @grps;
     2219        # create list of group names (without identical adjacent groups if simplifying)
     2220        foreach (@families) {
     2221            my $grp = $groups[$_] or next;
     2222            push @grps, $grp unless $simplify and @grps and $grp eq $grps[-1];
     2223        }
     2224        # remove leading "Main:" if simplifying
     2225        shift @grps if $simplify and @grps > 1 and $grps[0] eq 'Main';
     2226        # return colon-separated string of group names
     2227        return join ':', @grps;
     2228    }
    13482229    return @groups;
    13492230}
     
    13532234# Inputs: 0) ExifTool object reference
    13542235#         1) [optional] information hash reference (default all extracted info)
    1355 #         2) [optional] group family number (default 0)
     2236#         2) [optional] group family (default 0)
    13562237# Returns: List of group names in alphabetical order
    13572238sub GetGroups($;$$)
     
    14012282
    14022283#------------------------------------------------------------------------------
    1403 # Build composite tags from required tags
     2284# Build Composite tags from Require'd/Desire'd tags
    14042285# Inputs: 0) ExifTool object reference
    14052286# Note: Tag values are calculated in alphabetical order unless a tag Require's
    1406 #       or Desire's another composite tag, in which case the calculation is
     2287#       or Desire's another Composite tag, in which case the calculation is
    14072288#       deferred until after the other tag is calculated.
    14082289sub BuildCompositeTags($)
     
    14112292    my $self = shift;
    14122293
    1413     # first, add user-defined composite tags if necessary
     2294    $$self{BuildingComposite} = 1;
     2295    # first, add user-defined Composite tags if necessary
    14142296    if (%UserDefined and $UserDefined{'Image::ExifTool::Composite'}) {
    1415         AddCompositeTags($UserDefined{'Image::ExifTool::Composite'},1);
     2297        AddCompositeTags($UserDefined{'Image::ExifTool::Composite'}, 1);
    14162298        delete $UserDefined{'Image::ExifTool::Composite'};
    14172299    }
     
    14222304    for (;;) {
    14232305        my %notBuilt;
    1424         foreach (@tagList) {
    1425             $notBuilt{$_} = 1;
    1426         }
     2306        $notBuilt{$_} = 1 foreach @tagList;
    14272307        my @deferredTags;
    14282308        my $tag;
     
    14332313            next unless $tagInfo;
    14342314            # put required tags into array and make sure they all exist
    1435             my (%tagKey, $type, $found);
    1436             foreach $type ('Require','Desire') {
    1437                 my $req = $$tagInfo{$type} or next;
     2315            my $subDoc = ($$tagInfo{SubDoc} and $$self{DOC_COUNT});
     2316            my $require = $$tagInfo{Require} || { };
     2317            my $desire = $$tagInfo{Desire} || { };
     2318            # loop through sub-documents if necessary
     2319            my $doc;
     2320            for (;;) {
     2321                my (%tagKey, $found, $index);
    14382322                # save Require'd and Desire'd tag values in list
    1439                 my $index;
    1440                 foreach $index (keys %$req) {
    1441                     my $reqTag = $$req{$index};
     2323                for ($index=0; ; ++$index) {
     2324                    my $reqTag = $$require{$index} || $$desire{$index} or last;
     2325                    # add family 3 group if generating Composite tags for sub-documents
     2326                    # (unless tag already begins with family 3 group name)
     2327                    if ($subDoc and $reqTag !~ /^(Main|Doc\d+):/) {
     2328                        $reqTag = ($doc ? "Doc$doc:" : 'Main:') . $reqTag;
     2329                    }
    14422330                    # allow tag group to be specified
    1443                     if ($reqTag =~ /(.+?):(.+)/) {
     2331                    if ($reqTag =~ /^(.*):(.+)/) {
    14442332                        my ($reqGroup, $name) = ($1, $2);
    1445                         my $family;
    1446                         $family = $1 if $reqGroup =~ s/^(\d+)//;
    1447                         my $i = 0;
    1448                         for (;;++$i) {
    1449                             $reqTag = $name;
    1450                             $reqTag .= " ($i)" if $i;
    1451                             last unless defined $$rawValue{$reqTag};
    1452                             my @groups = $self->GetGroup($reqTag, $family);
    1453                             last if grep { $reqGroup eq $_ } @groups;
     2333                        if ($reqGroup eq 'Composite' and $notBuilt{$name}) {
     2334                            push @deferredTags, $tag;
     2335                            next COMPOSITE_TAG;
    14542336                        }
     2337                        my ($i, $key, @keys);
     2338                        for ($i=0; ; ++$i) {
     2339                            $key = $name;
     2340                            $key .= " ($i)" if $i;
     2341                            last unless defined $$rawValue{$key};
     2342                            push @keys, $key;
     2343                        }
     2344                        # find first matching tag
     2345                        $key = $self->GroupMatches($reqGroup, \@keys);
     2346                        $reqTag = $key if $key;
    14552347                    } elsif ($notBuilt{$reqTag}) {
    14562348                        # calculate this tag later if it relies on another
     
    14612353                    if (defined $$rawValue{$reqTag}) {
    14622354                        $found = 1;
    1463                     } else {
    1464                         # don't continue if we require this tag
    1465                         $type eq 'Require' and next COMPOSITE_TAG;
     2355                    } elsif ($$require{$index}) {
     2356                        $found = 0;
     2357                        last;   # don't continue since we require this tag
    14662358                    }
    14672359                    $tagKey{$index} = $reqTag;
    14682360                }
    1469             }
    1470             delete $notBuilt{$tag}; # this tag is OK to build now
    1471             next unless $found;     # can't build tag if no values found
    1472             # keep track of all require'd tag keys
    1473             foreach (keys %tagKey) {
    1474                 # only tag keys with same name as a composite tag can be replaced
    1475                 # (also eliminates keys with instance numbers which can't be replaced either)
    1476                 next unless $Image::ExifTool::Composite{$tagKey{$_}};
    1477                 my $keyRef = \$tagKey{$_};
    1478                 $tagsUsed{$$keyRef} or $tagsUsed{$$keyRef} = [ ];
    1479                 push @{$tagsUsed{$$keyRef}}, $keyRef;
    1480             }
    1481             # save reference to tag key lookup as value for composite tag
    1482             my $key = $self->FoundTag($tagInfo, \%tagKey);
    1483             # check to see if we just replaced one of the tag keys we require'd
    1484             next unless defined $key and $tagsUsed{$key};
    1485             foreach (@{$tagsUsed{$key}}) {
    1486                 $$_ = $self->{MOVED_KEY};   # replace with new tag key
    1487             }
    1488             delete $tagsUsed{$key};         # can't be replaced again
     2361                if ($doc) {
     2362                    if ($found) {
     2363                        $self->{DOC_NUM} = $doc;
     2364                        $self->FoundTag($tagInfo, \%tagKey);
     2365                        delete $self->{DOC_NUM};
     2366                    }
     2367                    next if ++$doc <= $self->{DOC_COUNT};
     2368                    last;
     2369                } elsif ($found) {
     2370                    delete $notBuilt{$tag}; # this tag is OK to build now
     2371                    # keep track of all Require'd tag keys
     2372                    foreach (keys %tagKey) {
     2373                        # only tag keys with same name as a Composite tag
     2374                        # can be replaced (also eliminates keys with
     2375                        # instance numbers which can't be replaced either)
     2376                        next unless $Image::ExifTool::Composite{$tagKey{$_}};
     2377                        my $keyRef = \$tagKey{$_};
     2378                        $tagsUsed{$$keyRef} or $tagsUsed{$$keyRef} = [ ];
     2379                        push @{$tagsUsed{$$keyRef}}, $keyRef;
     2380                    }
     2381                    # save reference to tag key lookup as value for Composite tag
     2382                    my $key = $self->FoundTag($tagInfo, \%tagKey);
     2383                    # check to see if we just replaced one of the tag keys we Require'd
     2384                    if (defined $key and $tagsUsed{$key}) {
     2385                        foreach (@{$tagsUsed{$key}}) {
     2386                            $$_ = $self->{MOVED_KEY};   # replace with new tag key
     2387                        }
     2388                        delete $tagsUsed{$key};         # can't be replaced again
     2389                    }
     2390                } elsif (not defined $found) {
     2391                    delete $notBuilt{$tag}; # tag can't be built anyway
     2392                }
     2393                last unless $subDoc;
     2394                $doc = 1;   # continue to process the 1st sub-document
     2395            }
    14892396        }
    14902397        last unless @deferredTags;
     
    14972404        @tagList = @deferredTags; # calculate deferred tags now
    14982405    }
     2406    delete $$self{BuildingComposite};
    14992407}
    15002408
     
    15222430#------------------------------------------------------------------------------
    15232431# Get file type for specified extension
    1524 # Inputs: 0) file name or extension (case is not significant)
    1525 #         1) flag to return long description instead of type
    1526 # Returns: File type (or desc) or undef if extension not supported.  In array
     2432# Inputs: 0) file name or extension (case is not significant),
     2433#            or FileType value if a description is requested
     2434#         1) flag to return long description instead of type ('0' to return any recognized type)
     2435# Returns: File type (or desc) or undef if extension not supported or if
     2436#          description is the same as the input FileType.  In array
    15272437#          context, may return more than one file type if the file may be
    1528 #          different formats.  Returns list of all recognized extensions if no
     2438#          different formats.  Returns list of all supported extensions if no
    15292439#          file specified
    15302440sub GetFileType(;$$)
     
    15322442    local $_;
    15332443    my ($file, $desc) = @_;
    1534     return sort keys %fileTypeLookup unless defined $file;
     2444    unless (defined $file) {
     2445        my @types;
     2446        if (defined $desc and $desc eq '0') {
     2447            # return all recognized types
     2448            @types = sort keys %fileTypeLookup;
     2449        } else {
     2450            # return all supported types
     2451            foreach (sort keys %fileTypeLookup) {
     2452                push @types, $_ unless defined $moduleName{$_} and $moduleName{$_} eq '0';
     2453            }
     2454        }
     2455        return @types;
     2456    }
    15352457    my $fileType;
    15362458    my $fileExt = GetFileExtension($file);
    15372459    $fileExt = uc($file) unless $fileExt;
    15382460    $fileExt and $fileType = $fileTypeLookup{$fileExt}; # look up the file type
    1539     return $$fileType[1] if $desc;  # return description if specified
     2461    $fileType = $fileTypeLookup{$fileType} unless ref $fileType or not $fileType;
     2462    # return description if specified
     2463    # (allow input $file to be a FileType for this purpose)
     2464    if ($desc) {
     2465        return $fileType ? $$fileType[1] : $fileDescription{$file};
     2466    } elsif ($fileType and (not defined $desc or $desc ne '0')) {
     2467        # return only supported file types
     2468        my $mod = $moduleName{$$fileType[0]};
     2469        undef $fileType if defined $mod and $mod eq '0';
     2470    }
     2471    $fileType or return wantarray ? () : undef;
    15402472    $fileType = $$fileType[0];      # get file type (or list of types)
    15412473    if (wantarray) {
    1542         return () unless $fileType;
    15432474        return @$fileType if ref $fileType eq 'ARRAY';
    15442475    } elsif ($fileType) {
     
    15502481#------------------------------------------------------------------------------
    15512482# Return true if we can write the specified file type
    1552 # Inputs: 0) file name or ext,
     2483# Inputs: 0) file name or ext
    15532484# Returns: true if writable, 0 if not writable, undef if unrecognized
    1554 # Note: This will return true for some TIFF-based RAW images which we shouldn't really write
    15552485sub CanWrite($)
    15562486{
     
    15582488    my $file = shift or return undef;
    15592489    my $type = GetFileType($file) or return undef;
     2490    if ($noWriteFile{$type}) {
     2491        # can't write TIFF files with certain extensions (various RAW formats)
     2492        my $ext = GetFileExtension($file) || uc($file);
     2493        return grep(/^$ext$/, @{$noWriteFile{$type}}) ? 0 : 1 if $ext;
     2494    }
    15602495    return scalar(grep /^$type$/, @writeTypes);
    15612496}
     
    15632498#------------------------------------------------------------------------------
    15642499# Return true if we can create the specified file type
    1565 # Inputs: 0) file name or ext,
     2500# Inputs: 0) file name or ext
    15662501# Returns: true if creatable, 0 if not writable, undef if unrecognized
    15672502sub CanCreate($)
     
    15692504    local $_;
    15702505    my $file = shift or return undef;
     2506    my $ext = GetFileExtension($file) || uc($file);
    15712507    my $type = GetFileType($file) or return undef;
    1572     return scalar(grep /^$type$/, @createTypes);
     2508    return 1 if $createTypes{$ext} or $createTypes{$type};
     2509    return 0;
    15732510}
    15742511
     
    15902527    delete $self->{EXIF_POS};       # EXIF position in file
    15912528    delete $self->{FIRST_EXIF_POS}; # position of first EXIF in file
    1592     delete $self->{EXIF_BYTE_ORDER};# the EXIF byte ordering
    15932529    delete $self->{HTML_DUMP};      # html dump information
     2530    delete $self->{SET_GROUP1};     # group1 name override
     2531    delete $self->{DOC_NUM};        # current embedded document number
     2532    $self->{DOC_COUNT}  = 0;        # count of embedded documents processed
    15942533    $self->{BASE}       = 0;        # base for offsets from start of file
    1595     $self->{FILE_ORDER} = { };      # hash of tag order in file
    1596     $self->{VALUE}      = { };      # hash of raw tag values
    1597     $self->{TAG_INFO}   = { };      # hash of tag information
    1598     $self->{GROUP1}     = { };      # hash of family 1 group names
    1599     $self->{PRIORITY}   = { };      # priority of current tags
     2534    $self->{FILE_ORDER} = { };      # * hash of tag order in file
     2535    $self->{VALUE}      = { };      # * hash of raw tag values
     2536    $self->{BOTH}       = { };      # * hash for Value/PrintConv values of Require'd tags
     2537    $self->{TAG_INFO}   = { };      # * hash of tag information
     2538    $self->{TAG_EXTRA}  = { };      # * hash of extra tag information (dynamic group names)
     2539    $self->{PRIORITY}   = { };      # * priority of current tags
     2540    $self->{LIST_TAGS}  = { };      # hash of tagInfo refs for active List-type tags
    16002541    $self->{PROCESSED}  = { };      # hash of processed directory start positions
    16012542    $self->{DIR_COUNT}  = { };      # count various types of directories
     2543    $self->{DUPL_TAG}   = { };      # last-used index for duplicate-tag keys
     2544    $self->{WARNED_ONCE}= { };      # WarnOnce() warnings already issued
     2545    $self->{PATH}       = [ ];      # current subdirectory path in file when reading
    16022546    $self->{NUM_FOUND}  = 0;        # total number of tags found (incl. duplicates)
    16032547    $self->{CHANGED}    = 0;        # number of tags changed (writer only)
    16042548    $self->{INDENT}     = '  ';     # initial indent for verbose messages
    16052549    $self->{PRIORITY_DIR} = '';     # the priority directory name
     2550    $self->{LOW_PRIORITY_DIR} = { PreviewIFD => 1 }; # names of priority 0 directories
    16062551    $self->{TIFF_TYPE}  = '';       # type of TIFF data (APP1, TIFF, NEF, etc...)
    1607     $self->{CameraMake} = '';       # camera make
    1608     $self->{CameraModel}= '';       # camera model
     2552    $self->{Make}      = '';       # camera make
     2553    $self->{Model}      = '';       # camera model
    16092554    $self->{CameraType} = '';       # Olympus camera type
    16102555    if ($self->Options('HtmlDump')) {
     
    16132558    }
    16142559    # make sure our TextOut is a file reference
    1615     $self->{OPTIONS}->{TextOut} = \*STDOUT unless ref $self->{OPTIONS}->{TextOut};
     2560    $self->{OPTIONS}{TextOut} = \*STDOUT unless ref $self->{OPTIONS}{TextOut};
    16162561}
    16172562
     
    16552600                        undef @oldGroupOpts;
    16562601                    }
    1657                     $options->{$opt} = $$arg{$opt};
     2602                    $self->Options($opt, $$arg{$opt});
    16582603                    $opt eq 'Exclude' and $wasExcludeOpt = 1;
    16592604                }
     
    16622607                # convert image data from UTF-8 to character stream if necessary
    16632608                # (patches RHEL 3 UTF8 LANG problem)
    1664                 if (ref $arg eq 'SCALAR' and eval 'require Encode; Encode::is_utf8($$arg)') {
    1665                     my $buff = pack('C*', unpack('U0U*', $$arg));
     2609                if (ref $arg eq 'SCALAR' and $] >= 5.006 and
     2610                    (eval 'require Encode; Encode::is_utf8($$arg)' or $@))
     2611                {
     2612                    # repack by hand if Encode isn't available
     2613                    my $buff = $@ ? pack('C*',unpack('U0C*',$$arg)) : Encode::encode('utf8',$$arg);
    16662614                    $arg = \$buff;
    16672615                }
     
    16702618                # we have a file but we didn't open it
    16712619                $self->{FILENAME} = '';
     2620            } elsif (UNIVERSAL::isa($arg, 'File::RandomAccess')) {
     2621                $self->{RAF} = $arg;
     2622                $self->{FILENAME} = '';
    16722623            } else {
    16732624                warn "Don't understand ImageInfo argument $arg\n";
     
    16882639        # initialize lookup for requested tags
    16892640        foreach (@{$self->{REQUESTED_TAGS}}) {
    1690             $self->{REQ_TAG_LOOKUP}->{lc(/.+?:(.+)/ ? $1 : $_)} = 1;
     2641            $self->{REQ_TAG_LOOKUP}{lc(/.+:(.+)/ ? $1 : $_)} = 1;
    16912642        }
    16922643    }
     
    17032654        $options->{Exclude} = \@exclude;
    17042655        # expand shortcuts in new exclude list
    1705         ExpandShortcuts($options->{Exclude});
    1706     }
    1707 }
    1708 
    1709 #------------------------------------------------------------------------------
    1710 # Set list of found tags
     2656        ExpandShortcuts($options->{Exclude}, 1); # (also remove '#' suffix)
     2657    }
     2658}
     2659
     2660#------------------------------------------------------------------------------
     2661# Get list of tags in specified group
     2662# Inputs: 0) ExifTool ref, 1) group spec, 2) tag key or reference to list of tag keys
     2663# Returns: list of matching tags in list context, or first match in scalar context
     2664# Notes: Group spec may contain multiple groups separated by colons, each
     2665#        possibly with a leading family number
     2666sub GroupMatches($$$)
     2667{
     2668    my ($self, $group, $tagList) = @_;
     2669    $tagList = [ $tagList ] unless ref $tagList;
     2670    my ($tag, @matches);
     2671    if ($group =~ /:/) {
     2672        # check each group name individually (ie. "Author:1IPTC")
     2673        my @grps = split ':', lc $group;
     2674        my (@fmys, $g);
     2675        for ($g=0; $g<@grps; ++$g) {
     2676            $fmys[$g] = $1 if $grps[$g] =~ s/^(\d+)//;
     2677        }
     2678        foreach $tag (@$tagList) {
     2679            my @groups = $self->GetGroup($tag, -1);
     2680            for ($g=0; $g<@grps; ++$g) {
     2681                my $grp = $grps[$g];
     2682                next if $grp eq '*' or $grp eq 'all';
     2683                if (defined $fmys[$g]) {
     2684                    my $f = $fmys[$g];
     2685                    last unless $groups[$f] and $grps[$g] eq lc $groups[$f];
     2686                } else {
     2687                    last unless grep /^$grps[$g]$/i, @groups;
     2688                }
     2689            }
     2690            push @matches, $tag if $g == @grps;
     2691        }
     2692    } else {
     2693        my $family = ($group =~ s/^(\d+)//) ? $1 : -1;
     2694        foreach $tag (@$tagList) {
     2695            my @groups = $self->GetGroup($tag, $family);
     2696            push @matches, $tag if grep(/^$group$/i, @groups);
     2697        }
     2698    }
     2699    return wantarray ? @matches : $matches[0];
     2700}
     2701
     2702#------------------------------------------------------------------------------
     2703# Set list of found tags from previously requested tags
    17112704# Inputs: 0) ExifTool object reference
    1712 # Returns: Reference to found tags list (in order of requested tags)
     2705# Returns: 0) Reference to list of found tag keys (in order of requested tags)
     2706#          1) Reference to list of indices for tags requested by value
    17132707sub SetFoundTags($)
    17142708{
     
    17212715    my @groupOptions = sort grep /^Group/, keys %$options;
    17222716    my $doDups = $duplicates || $exclude || @groupOptions;
    1723     my ($tag, $rtnTags);
     2717    my ($tag, $rtnTags, @byValue);
    17242718
    17252719    # only return requested tags if specified
     
    17302724        my $reqTag;
    17312725        foreach $reqTag (@$reqTags) {
    1732             my (@matches, $group, $family, $allGrp, $allTag);
    1733             if ($reqTag =~ /^(\d+)?(.+?):(.+)/) {
    1734                 ($family, $group, $tag) = ($1, $2, $3);
    1735                 $allGrp = 1 if $group =~ /^(\*|all)$/i;
    1736                 $family = -1 unless defined $family;
     2726            my (@matches, $group, $allGrp, $allTag, $byValue);
     2727            if ($reqTag =~ /^(.*):(.+)/) {
     2728                ($group, $tag) = ($1, $2);
     2729                if ($group =~ /^(\*|all)$/i) {
     2730                    $allGrp = 1;
     2731                } elsif ($group !~ /^[-\w:]*$/) {
     2732                    $self->Warn("Invalid group name '$group'");
     2733                    $group = 'invalid';
     2734                }
    17372735            } else {
    17382736                $tag = $reqTag;
    1739                 $family = -1;
    1740             }
     2737            }
     2738            $byValue = 1 if $tag =~ s/#$//;
    17412739            if (defined $tagHash->{$reqTag} and not $doDups) {
    17422740                $matches[0] = $tag;
     
    17502748                next unless @matches;   # don't want entry in list for '*' tag
    17512749                $allTag = 1;
     2750            } elsif ($tag =~ /[*?]/) {
     2751                # allow wildcards in tag names
     2752                $tag =~ s/\*/[-\\w]*/g;
     2753                $tag =~ s/\?/[-\\w]/g;
     2754                $tag .= '( .*)?' if $doDups or $allGrp;
     2755                @matches = grep(/^$tag$/i, keys %$tagHash);
     2756                next unless @matches;   # don't want entry in list for wildcard tags
     2757                $allTag = 1;
    17522758            } elsif ($doDups or defined $group) {
    17532759                # must also look for tags like "Tag (1)"
    1754                 @matches = grep(/^$tag(\s|$)/i, keys %$tagHash);
    1755             } else {
     2760                @matches = grep(/^$tag( |$)/i, keys %$tagHash);
     2761            } elsif ($tag =~ /^[-\w]+$/) {
    17562762                # find first matching value
    17572763                # (use in list context to return value instead of count)
    17582764                ($matches[0]) = grep /^$tag$/i, keys %$tagHash;
    17592765                defined $matches[0] or undef @matches;
     2766            } else {
     2767                $self->Warn("Invalid tag name '$tag'");
    17602768            }
    17612769            if (defined $group and not $allGrp) {
    17622770                # keep only specified group
    1763                 my @grpMatches;
    1764                 foreach (@matches) {
    1765                     my @groups = $self->GetGroup($_, $family);
    1766                     next unless grep /^$group$/i, @groups;
    1767                     push @grpMatches, $_;
    1768                 }
    1769                 @matches = @grpMatches;
     2771                @matches = $self->GroupMatches($group, \@matches);
    17702772                next unless @matches or not $allTag;
    17712773            }
     
    17762778                unless ($doDups or $allTag or $allGrp) {
    17772779                    $tag = shift @matches;
    1778                     my $oldPriority = $self->{PRIORITY}->{$tag} || 1;
     2780                    my $oldPriority = $self->{PRIORITY}{$tag} || 1;
    17792781                    foreach (@matches) {
    1780                         my $priority = $self->{PRIORITY}->{$_};
     2782                        my $priority = $self->{PRIORITY}{$_};
    17812783                        $priority = 1 unless defined $priority;
    17822784                        next unless $priority >= $oldPriority;
     
    17902792                $matches[0] = "$tag (0)";
    17912793                # bogus file order entry to avoid warning if sorting in file order
    1792                 $self->{FILE_ORDER}->{$matches[0]} = 999;
    1793             }
     2794                $self->{FILE_ORDER}{$matches[0]} = 999;
     2795            }
     2796            # save indices of tags extracted by value
     2797            push @byValue, scalar(@$rtnTags) .. (scalar(@$rtnTags)+scalar(@matches)-1) if $byValue;
    17942798            push @$rtnTags, @matches;
    17952799        }
     
    18112815    while (($exclude or @groupOptions) and @$rtnTags) {
    18122816        if ($exclude) {
    1813             my @filteredTags;
    1814 EX_TAG:     foreach $tag (@$rtnTags) {
    1815                 my $tagName = GetTagName($tag);
    1816                 my @matches = grep /(^|:)($tagName|\*|all)$/i, @$exclude;
    1817                 foreach (@matches) {
    1818                     next EX_TAG unless /^(\d+)?(.+?):/;
    1819                     my ($family, $group) = ($1, $2);
    1820                     next EX_TAG if $group =~ /^(\*|all)$/i;
    1821                     $family = -1 unless defined $family;
    1822                     my @groups = $self->GetGroup($tag, $family);
    1823                     next EX_TAG if grep /^$group$/i, @groups;
     2817            my ($pat, %exclude);
     2818            foreach $pat (@$exclude) {
     2819                my $group;
     2820                if ($pat =~ /^(.*):(.+)/) {
     2821                    ($group, $tag) = ($1, $2);
     2822                    if ($group =~ /^(\*|all)$/i) {
     2823                        undef $group;
     2824                    } elsif ($group !~ /^[-\w:]*$/) {
     2825                        $self->Warn("Invalid group name '$group'");
     2826                        $group = 'invalid';
     2827                    }
     2828                } else {
     2829                    $tag = $pat;
    18242830                }
    1825                 push @filteredTags, $tag;
    1826             }
    1827             $rtnTags = \@filteredTags;      # use new filtered tag list
     2831                my @matches;
     2832                if ($tag =~ /^(\*|all)$/i) {
     2833                    @matches = @$rtnTags;
     2834                } else {
     2835                    # allow wildcards in tag names
     2836                    $tag =~ s/\*/[-\\w]*/g;
     2837                    $tag =~ s/\?/[-\\w]/g;
     2838                    @matches = grep(/^$tag( |$)/i, @$rtnTags);
     2839                }
     2840                @matches = $self->GroupMatches($group, \@matches) if $group and @matches;
     2841                $exclude{$_} = 1 foreach @matches;
     2842            }
     2843            if (%exclude) {
     2844                my @filteredTags;
     2845                $exclude{$_} or push @filteredTags, $_ foreach @$rtnTags;
     2846                $rtnTags = \@filteredTags;      # use new filtered tag list
     2847                last unless @filteredTags;      # all done if nothing left
     2848            }
    18282849            last if $duplicates and not @groupOptions;
    18292850        }
     
    18342855        my $wantOrder = 0;
    18352856        foreach $groupOpt (@groupOptions) {
    1836             $groupOpt =~ /^Group(\d*)/ or next;
     2857            $groupOpt =~ /^Group(\d*(:\d+)*)/ or next;
    18372858            $family = $1 || 0;
    18382859            $wantGroup{$family} or $wantGroup{$family} = { };
     
    18562877                    $allGroups = 0;     # don't want all groups if we requested one
    18572878                }
    1858                 $wantGroup{$family}->{$groupName} = $want;
     2879                $wantGroup{$family}{$groupName} = $want;
    18592880            }
    18602881        }
     
    18652886            foreach $family (keys %wantGroup) {
    18662887                my $group = $self->GetGroup($tag, $family);
    1867                 my $wanted = $wantGroup{$family}->{$group};
     2888                my $wanted = $wantGroup{$family}{$group};
    18682889                next unless defined $wanted;
    18692890                next GR_TAG unless $wanted;     # skip tag if group excluded
     
    19032924        last;
    19042925    }
    1905 
    1906     # save found tags and return reference
    1907     return $self->{FOUND_TAGS} = $rtnTags;
     2926    $self->{FOUND_TAGS} = $rtnTags;     # save found tags
     2927
     2928    # return reference to found tag keys (and list of indices of tags to extract by value)
     2929    return wantarray ? ($rtnTags, \@byValue) : $rtnTags;
    19082930}
    19092931
     
    19552977    my ($self, $str, $ignorable) = @_;
    19562978    if ($ignorable) {
    1957         return 0 if $self->{OPTIONS}->{IgnoreMinorErrors};
     2979        return 0 if $self->{OPTIONS}{IgnoreMinorErrors};
    19582980        $str = "[minor] $str";
    19592981    }
    19602982    $self->FoundTag('Warning', $str);
     2983    return 1;
     2984}
     2985
     2986#------------------------------------------------------------------------------
     2987# Add warning tag only once per processed file
     2988# Inputs: 0) ExifTool object reference, 1) warning message, 2) true if minor
     2989# Returns: true if warning tag was added
     2990sub WarnOnce($$;$)
     2991{
     2992    my ($self, $str, $ignorable) = @_;
     2993    return 0 if $ignorable and $self->{OPTIONS}{IgnoreMinorErrors};
     2994    unless ($$self{WARNED_ONCE}{$str}) {
     2995        $self->Warn($str, $ignorable);
     2996        $$self{WARNED_ONCE}{$str} = 1;
     2997    }
    19612998    return 1;
    19622999}
     
    19703007    my ($self, $str, $ignorable) = @_;
    19713008    if ($ignorable) {
    1972         if ($self->{OPTIONS}->{IgnoreMinorErrors}) {
     3009        if ($self->{OPTIONS}{IgnoreMinorErrors}) {
    19733010            $self->Warn($str);
    19743011            return 0;
     
    19823019#------------------------------------------------------------------------------
    19833020# Expand shortcuts
    1984 # Inputs: 0) reference to list of tags
    1985 # Notes: Handles leading '-' for excluded tags, group names, and redirected tags
    1986 sub ExpandShortcuts($)
    1987 {
    1988     my $tagList = shift || return;
     3021# Inputs: 0) reference to list of tags, 1) set to remove trailing '#'
     3022# Notes: Handles leading '-' for excluded tags, trailing '#' for ValueConv,
     3023#        multiple group names, and redirected tags
     3024sub ExpandShortcuts($;$)
     3025{
     3026    my ($tagList, $removeSuffix) = @_;
     3027    return unless $tagList and @$tagList;
    19893028
    19903029    require Image::ExifTool::Shortcuts;
    19913030
    19923031    # expand shortcuts
     3032    my $suffix = $removeSuffix ? '' : '#';
    19933033    my @expandedTags;
    19943034    my ($entry, $tag, $excl);
    19953035    foreach $entry (@$tagList) {
     3036        # skip things like options hash references in list
     3037        if (ref $entry) {
     3038            push @expandedTags, $entry;
     3039            next;
     3040        }
    19963041        # remove leading '-'
    19973042        ($excl, $tag) = $entry =~ /^(-?)(.*)/s;
    1998         my ($post, @post);
     3043        my ($post, @post, $pre, $v);
    19993044        # handle redirection
    2000         if ($tag =~ /(.+?)([-+]?[<>].+)/s and not $excl) {
     3045        if (not $excl and $tag =~ /(.+?)([-+]?[<>].+)/s) {
    20013046            ($tag, $post) = ($1, $2);
    20023047            if ($post =~ /^[-+]?>/ or $post !~ /\$/) {
    20033048                # expand shortcuts in postfix (rhs of redirection)
    2004                 my ($op, $p2, $t2) = ($post =~ /([-+]?[<>])(.+?:)?(.+)/);
     3049                my ($op, $p2, $t2) = ($post =~ /([-+]?[<>])(.+:)?(.+)/);
    20053050                $p2 = '' unless defined $p2;
     3051                $v = ($t2 =~ s/#$//) ? $suffix : ''; # ValueConv suffix
    20063052                my ($match) = grep /^\Q$t2\E$/i, keys %Image::ExifTool::Shortcuts::Main;
    20073053                if ($match) {
    20083054                    foreach (@{$Image::ExifTool::Shortcuts::Main{$match}}) {
    20093055                        /^-/ and next;  # ignore excluded tags
    2010                         if ($p2 and /(.+?:)(.+)/) {
    2011                             push @post, "$op$_";
     3056                        if ($p2 and /(.+:)(.+)/) {
     3057                            push @post, "$op$_$v";
    20123058                        } else {
    2013                             push @post, "$op$p2$_";
     3059                            push @post, "$op$p2$_$v";
    20143060                        }
    20153061                    }
     
    20223068        }
    20233069        # handle group names
    2024         my $pre;
    2025         if ($tag =~ /(.+?:)(.+)/) {
     3070        if ($tag =~ /(.+:)(.+)/) {
    20263071            ($pre, $tag) = ($1, $2);
    20273072        } else {
    20283073            $pre = '';
    20293074        }
     3075        $v = ($tag =~ s/#$//) ? $suffix : '';   # ValueConv suffix
    20303076        # loop over all postfixes
    20313077        for (;;) {
     
    20383084                        /^-/ and next;  # ignore excluded exclude tags
    20393085                        # group of expanded tag takes precedence
    2040                         if ($pre and /(.+?:)(.+)/) {
     3086                        if ($pre and /(.+:)(.+)/) {
    20413087                            push @expandedTags, "$excl$_";
    20423088                        } else {
     
    20443090                        }
    20453091                    }
    2046                 } elsif (length $pre or length $post) {
     3092                } elsif (length $pre or length $post or $v) {
    20473093                    foreach (@{$Image::ExifTool::Shortcuts::Main{$match}}) {
    2048                         /(-?)(.+?:)?(.+)/;
     3094                        /(-?)(.+:)?(.+)/;
    20493095                        if ($2) {
    20503096                            # group from expanded tag takes precedence
    2051                             push @expandedTags, "$_$post";
     3097                            push @expandedTags, "$_$v$post";
    20523098                        } else {
    2053                             push @expandedTags, "$1$pre$3$post";
     3099                            push @expandedTags, "$1$pre$3$v$post";
    20543100                        }
    20553101                    }
     
    20583104                }
    20593105            } else {
    2060                 push @expandedTags, "$excl$pre$tag$post";
     3106                push @expandedTags, "$excl$pre$tag$v$post";
    20613107            }
    20623108            last unless @post;
     
    20683114
    20693115#------------------------------------------------------------------------------
    2070 # Add hash of composite tags to our composites
    2071 # Inputs: 0) hash reference to table of composite tags to add or module name,
     3116# Add hash of Composite tags to our composites
     3117# Inputs: 0) hash reference to table of Composite tags to add or module name,
    20723118#         1) overwrite existing tag
    20733119sub AddCompositeTags($;$)
     
    20923138        $defaultGroups = $$add{GROUPS} = { 0 => 'Composite', 1 => 'Composite', 2 => 'Other' };
    20933139    }
    2094     SetupTagTable($add);
     3140    SetupTagTable($add);    # generate tag Name, etc
    20953141    my $tagID;
    2096     foreach $tagID (keys %$add) {
     3142    foreach $tagID (sort keys %$add) {
    20973143        next if $specialTags{$tagID};   # must skip special tags
    20983144        my $tagInfo = $$add{$tagID};
     
    21003146        my $tag = $$tagInfo{Name};
    21013147        $$tagInfo{Module} = $module if $$tagInfo{Writable};
    2102         # allow composite tags with the same name
     3148        # allow Composite tags with the same name
    21033149        my ($t, $n, $type);
    21043150        while ($Image::ExifTool::Composite{$tag} and not $overwrite) {
    2105             $n ? $n += 1 : $n = 2, $t = $tag;
     3151            $n ? $n += 1 : ($n = 2, $t = $tag);
    21063152            $tag = "${t}_$n";
     3153            $$tagInfo{NewTagID} = $tag; # save new ID so we can use it in TagLookup
    21073154        }
    21083155        # convert scalar Require/Desire entries
     
    21113158            $$tagInfo{$type} = { 0 => $req } if ref($req) ne 'HASH';
    21123159        }
    2113         # add this composite tag to our main composite table
     3160        # add this Composite tag to our main Composite table
    21143161        $$tagInfo{Table} = \%Image::ExifTool::Composite;
     3162        # (use the original TagID, even if we changed it)
     3163        # $$tagInfo{TagID} = $tag;
     3164        # save new tag ID so we can find entry in Composite table
    21153165        $Image::ExifTool::Composite{$tag} = $tagInfo;
    21163166        # set all default groups in tag
     
    21273177
    21283178#------------------------------------------------------------------------------
     3179# Add tags to TagLookup (used for writing)
     3180# Inputs: 0) source hash of tag definitions, 1) name of destination tag table
     3181sub AddTagsToLookup($$)
     3182{
     3183    my ($tagHash, $table) = @_;
     3184    if (defined &Image::ExifTool::TagLookup::AddTags) {
     3185        Image::ExifTool::TagLookup::AddTags($tagHash, $table);
     3186    } elsif (not $Image::ExifTool::pluginTags{$tagHash}) {
     3187        # queue these tags until TagLookup is loaded
     3188        push @Image::ExifTool::pluginTags, [ $tagHash, $table ];
     3189        # set flag so we don't load same tags twice
     3190        $Image::ExifTool::pluginTags{$tagHash} = 1;
     3191    }
     3192}
     3193
     3194#------------------------------------------------------------------------------
    21293195# Expand tagInfo Flags
    21303196# Inputs: 0) tagInfo hash ref
     
    21523218# Inputs: 0) Reference to tag table
    21533219# Notes: - generates 'Name' field from key if it doesn't exist
    2154 #        - stores 'Table' pointer
     3220#        - stores 'Table' pointer and 'TagID' value
    21553221#        - expands 'Flags' for quick lookup
    21563222sub SetupTagTable($)
    21573223{
    21583224    my $tagTablePtr = shift;
    2159     my $tagID;
     3225    my ($tagID, $tagInfo);
    21603226    foreach $tagID (TagTableKeys($tagTablePtr)) {
    21613227        my @infoArray = GetTagInfoList($tagTablePtr,$tagID);
    21623228        # process conditional tagInfo arrays
    2163         my $tagInfo;
    21643229        foreach $tagInfo (@infoArray) {
    21653230            $$tagInfo{Table} = $tagTablePtr;
     3231            $$tagInfo{TagID} = $tagID;
    21663232            my $tag = $$tagInfo{Name};
    21673233            unless (defined $tag) {
     
    21723238            $$tagInfo{Flags} and ExpandFlags($tagInfo);
    21733239        }
     3240        next unless @infoArray > 1;
     3241        # add an "Index" member to each tagInfo in a list
     3242        my $index = 0;
     3243        foreach $tagInfo (@infoArray) {
     3244            $$tagInfo{Index} = $index++;
     3245        }
    21743246    }
    21753247}
     
    21803252# Notes: May change commas to decimals in floats for use in other locales
    21813253sub IsFloat($) {
    2182     return 1 if $_[0] =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
     3254    return 1 if $_[0] =~ /^[+-]?(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
    21833255    # allow comma separators (for other locales)
    2184     return 0 unless $_[0] =~ /^([+-]?)(?=\d|,\d)\d*(,\d*)?([Ee]([+-]?\d+))?$/;
     3256    return 0 unless $_[0] =~ /^[+-]?(?=\d|,\d)\d*(,\d*)?([Ee]([+-]?\d+))?$/;
    21853257    $_[0] =~ tr/,/./;   # but translate ',' to '.'
    21863258    return 1;
    21873259}
    2188 sub IsInt($)   { return scalar($_[0] =~ /^[+-]?\d+$/); }
    2189 sub IsHex($)   { return scalar($_[0] =~ /^(0x)?[0-9a-f]{1,8}$/i); }
     3260sub IsInt($)      { return scalar($_[0] =~ /^[+-]?\d+$/); }
     3261sub IsHex($)      { return scalar($_[0] =~ /^(0x)?[0-9a-f]{1,8}$/i); }
     3262sub IsRational($) { return scalar($_[0] =~ m{^[-+]?\d+/\d+$}); }
    21903263
    21913264# round floating point value to specified number of significant digits
     
    22013274}
    22023275
     3276# Convert strings to floating point numbers (or undef)
     3277# Inputs: 0-N) list of strings (may be undef)
     3278# Returns: last value converted
     3279sub ToFloat(@)
     3280{
     3281    local $_;
     3282    foreach (@_) {
     3283        next unless defined $_;
     3284        # (add 0 to convert "0.0" to "0" for tests)
     3285        $_ = /((?:[+-]?)(?=\d|\.\d)\d*(?:\.\d*)?(?:[Ee](?:[+-]?\d+))?)/ ? $1 + 0 : undef;
     3286    }
     3287    return $_[-1];
     3288}
     3289
    22033290#------------------------------------------------------------------------------
    22043291# Utility routines to for reading binary data values from file
    22053292
    2206 my $swapBytes;               # set if EXIF header is not native byte ordering
    2207 my $swapWords;               # swap 32-bit words in doubles (ARM quirk)
    2208 my $currentByteOrder = 'MM'; # current byte ordering ('II' or 'MM')
    22093293my %unpackMotorola = ( S => 'n', L => 'N', C => 'C', c => 'c' );
    22103294my %unpackIntel    = ( S => 'v', L => 'V', C => 'C', c => 'c' );
    2211 my %unpackStd = %unpackMotorola;
     3295my %unpackRev = ( N => 'V', V => 'N', C => 'C', n => 'v', v => 'n', c => 'c' );
     3296
     3297# the following 4 variables are defined in 'use vars' instead of using 'my'
     3298# because mod_perl 5.6.1 apparently has a problem with setting file-scope 'my'
     3299# variables from within subroutines (ref communication with Pavel Merdin):
     3300# $swapBytes - set if EXIF header is not native byte ordering
     3301# $swapWords - swap 32-bit words in doubles (ARM quirk)
     3302$currentByteOrder = 'MM'; # current byte ordering ('II' or 'MM')
     3303%unpackStd = %unpackMotorola;
    22123304
    22133305# Swap bytes in data if necessary
     
    22403332    return unpack($unpackStd{$_[0]}, ${$_[1]});
    22413333}
     3334# same, but with reversed byte order
     3335sub DoUnpackRev(@)
     3336{
     3337    my $fmt = $unpackRev{$unpackStd{$_[0]}};
     3338    $_[2] and return unpack("x$_[2] $fmt", ${$_[1]});
     3339    return unpack($fmt, ${$_[1]});
     3340}
    22423341# Pack value
    22433342# Inputs: 0) template, 1) value, 2) data ref (or undef), 3) offset (if data ref)
     
    22463345{
    22473346    my $val = pack($unpackStd{$_[0]}, $_[1]);
     3347    $_[2] and substr(${$_[2]}, $_[3], length($val)) = $val;
     3348    return $val;
     3349}
     3350# same, but with reversed byte order
     3351sub DoPackRev(@)
     3352{
     3353    my $val = pack($unpackRev{$unpackStd{$_[0]}}, $_[1]);
    22483354    $_[2] and substr(${$_[2]}, $_[3], length($val)) = $val;
    22493355    return $val;
     
    22893395sub GetFloat($$)  { return DoUnpack(4, 'f', @_); }
    22903396sub GetDouble($$) { return DoUnpackDbl('d', @_); }
    2291 
     3397sub Get16uRev($$) { return DoUnpackRev('S', @_); }
     3398
     3399# rationals may be a floating point number, 'inf' or 'undef'
    22923400sub GetRational32s($$)
    22933401{
    22943402    my ($dataPt, $pos) = @_;
    2295     my $denom = Get16s($dataPt, $pos + 2) or return 'inf';
     3403    my $numer = Get16s($dataPt,$pos);
     3404    my $denom = Get16s($dataPt, $pos + 2) or return $numer ? 'inf' : 'undef';
    22963405    # round off to a reasonable number of significant figures
    2297     return RoundFloat(Get16s($dataPt,$pos) / $denom, 7);
     3406    return RoundFloat($numer / $denom, 7);
    22983407}
    22993408sub GetRational32u($$)
    23003409{
    23013410    my ($dataPt, $pos) = @_;
    2302     my $denom = Get16u($dataPt, $pos + 2) or return 'inf';
    2303     return RoundFloat(Get16u($dataPt,$pos) / $denom, 7);
     3411    my $numer = Get16u($dataPt,$pos);
     3412    my $denom = Get16u($dataPt, $pos + 2) or return $numer ? 'inf' : 'undef';
     3413    return RoundFloat($numer / $denom, 7);
    23043414}
    23053415sub GetRational64s($$)
    23063416{
    23073417    my ($dataPt, $pos) = @_;
    2308     my $denom = Get32s($dataPt, $pos + 4) or return 'inf';
    2309     return RoundFloat(Get32s($dataPt,$pos) / $denom, 10);
     3418    my $numer = Get32s($dataPt,$pos);
     3419    my $denom = Get32s($dataPt, $pos + 4) or return $numer ? 'inf' : 'undef';
     3420    return RoundFloat($numer / $denom, 10);
    23103421}
    23113422sub GetRational64u($$)
    23123423{
    23133424    my ($dataPt, $pos) = @_;
    2314     my $denom = Get32u($dataPt, $pos + 4) or return 'inf';
    2315     return RoundFloat(Get32u($dataPt,$pos) / $denom, 10);
     3425    my $numer = Get32u($dataPt,$pos);
     3426    my $denom = Get32u($dataPt, $pos + 4) or return $numer ? 'inf' : 'undef';
     3427    return RoundFloat($numer / $denom, 10);
    23163428}
    23173429sub GetFixed16s($$)
     
    23443456sub Set16u(@) { return DoPackStd('S', @_); }
    23453457sub Set32u(@) { return DoPackStd('L', @_); }
     3458sub Set16uRev(@) { return DoPackRev('S', @_); }
    23463459
    23473460#------------------------------------------------------------------------------
     
    23513464#------------------------------------------------------------------------------
    23523465# Set byte ordering
    2353 # Inputs: 0) 'II'=intel, 'MM'=motorola
     3466# Inputs: 0) 'MM'=motorola, 'II'=intel (will translate 'BigEndian', 'LittleEndian')
    23543467# Returns: 1 on success
    23553468sub SetByteOrder($)
     
    23603473        %unpackStd = %unpackMotorola;
    23613474    } elsif ($order eq 'II') {  # little endian (Intel)
     3475        %unpackStd = %unpackIntel;
     3476    } elsif ($order =~ /^Big/i) {
     3477        $order = 'MM';
     3478        %unpackStd = %unpackMotorola;
     3479    } elsif ($order =~ /^Little/i) {
     3480        $order = 'II';
    23623481        %unpackStd = %unpackIntel;
    23633482    } else {
     
    24023521    int16s => 2,
    24033522    int16u => 2,
     3523    int16uRev => 2,
    24043524    int32s => 4,
    24053525    int32u => 4,
     
    24173537    double => 8,
    24183538    extended => 10,
     3539    unicode => 2,
     3540    complex => 8,
    24193541    string => 1,
    24203542    binary => 1,
    24213543   'undef' => 1,
    24223544    ifd => 4,
    2423     ifd8 => 8,
     3545    ifd64 => 8,
    24243546);
    24253547my %readValueProc = (
     
    24283550    int16s => \&Get16s,
    24293551    int16u => \&Get16u,
     3552    int16uRev => \&Get16uRev,
    24303553    int32s => \&Get32s,
    24313554    int32u => \&Get32u,
     
    24443567    extended => \&GetExtended,
    24453568    ifd => \&Get32u,
    2446     ifd8 => \&Get64u,
     3569    ifd64 => \&Get64u,
    24473570);
    24483571sub FormatSize($) { return $formatSize{$_[0]}; }
     
    24823605        }
    24833606    } else {
    2484         # handle undef/binary/string
    2485         $vals[0] = substr($$dataPt, $offset, $count);
     3607        # handle undef/binary/string (also unsupported unicode/complex)
     3608        $vals[0] = substr($$dataPt, $offset, $count * $len);
    24863609        # truncate string at null terminator if necessary
    24873610        $vals[0] =~ s/\0.*//s if $format eq 'string';
    24883611    }
    2489     if (wantarray) {
    2490         return @vals;
    2491     } elsif (@vals > 1) {
    2492         return join(' ', @vals);
    2493     } else {
    2494         return $vals[0];
    2495     }
    2496 }
    2497 
    2498 #------------------------------------------------------------------------------
    2499 # Convert UTF-8 to current character set
    2500 # Inputs: 0) ExifTool ref, 1) UTF-8 string
    2501 # Return: Converted string
    2502 sub UTF82Charset($$)
    2503 {
    2504     my ($self, $val) = @_;
    2505     if ($self->{OPTIONS}->{Charset} eq 'Latin' and $val =~ /[\x80-\xff]/) {
    2506         $val = Image::ExifTool::UTF82Unicode($val,'n',$self);
    2507         $val = Image::ExifTool::Unicode2Latin($val,'n',$self);
     3612    return @vals if wantarray;
     3613    return join(' ', @vals) if @vals > 1;
     3614    return $vals[0];
     3615}
     3616
     3617#------------------------------------------------------------------------------
     3618# Decode string with specified encoding
     3619# Inputs: 0) ExifTool object ref, 1) string to decode
     3620#         2) source character set name (undef for current Charset)
     3621#         3) optional source byte order (2-byte and 4-byte fixed-width sets only)
     3622#         4) optional destination character set (defaults to Charset setting)
     3623#         5) optional destination byte order (2-byte and 4-byte fixed-width only)
     3624# Returns: string in destination encoding
     3625# Note: ExifTool ref may be undef if character both character sets are provided
     3626#       (but in this case no warnings will be issued)
     3627sub Decode($$$;$$$)
     3628{
     3629    my ($self, $val, $from, $fromOrder, $to, $toOrder) = @_;
     3630    $from or $from = $$self{OPTIONS}{Charset};
     3631    $to or $to = $$self{OPTIONS}{Charset};
     3632    if ($from ne $to and length $val) {
     3633        require Image::ExifTool::Charset;
     3634        my $cs1 = $Image::ExifTool::Charset::csType{$from};
     3635        my $cs2 = $Image::ExifTool::Charset::csType{$to};
     3636        if ($cs1 and $cs2 and not $cs2 & 0x002) {
     3637            # treat as straight ASCII if no character will need remapping
     3638            if (($cs1 | $cs2) & 0x680 or $val =~ /[\x80-\xff]/) {
     3639                my $uni = Image::ExifTool::Charset::Decompose($self, $val, $from, $fromOrder);
     3640                $val = Image::ExifTool::Charset::Recompose($self, $uni, $to, $toOrder);
     3641            }
     3642        } elsif ($self) {
     3643            my $set = $cs1 ? $to : $from;
     3644            unless ($$self{"DecodeWarn$set"}) {
     3645                $self->Warn("Unsupported character set ($set)");
     3646                $$self{"DecodeWarn$set"} = 1;
     3647            }
     3648        }
    25083649    }
    25093650    return $val;
     
    25113652
    25123653#------------------------------------------------------------------------------
    2513 # Convert Latin to current character set
    2514 # Inputs: 0) ExifTool ref, 1) Latin string
    2515 # Return: Converted string
    2516 sub Latin2Charset($$)
    2517 {
    2518     my ($self, $val) = @_;
    2519     if ($self->{OPTIONS}->{Charset} eq 'UTF8' and $val =~ /[\x80-\xff]/) {
    2520         $val = Image::ExifTool::Latin2Unicode($val,'n');
    2521         $val = Image::ExifTool::Unicode2UTF8($val,'n');
    2522     }
    2523     return $val;
     3654# Encode string with specified encoding
     3655# Inputs: 0) ExifTool object ref, 1) string, 2) destination character set name,
     3656#         3) optional destination byte order (2-byte and 4-byte fixed-width sets only)
     3657# Returns: string in specified encoding
     3658sub Encode($$$;$)
     3659{
     3660    my ($self, $val, $to, $toOrder) = @_;
     3661    return $self->Decode($val, undef, undef, $to, $toOrder);
    25243662}
    25253663
     
    25543692#------------------------------------------------------------------------------
    25553693# Validate an extracted image and repair if necessary
    2556 # Inputs: 0) ExifTool object reference, 1) image reference, 2) tag name
     3694# Inputs: 0) ExifTool object reference, 1) image reference, 2) tag name or key
    25573695# Returns: image reference or undef if it wasn't valid
     3696# Note: should be called from RawConv, not ValueConv
    25583697sub ValidateImage($$$)
    25593698{
     
    25633702            # the first byte of the preview of some Minolta cameras is wrong,
    25643703            # so check for this and set it back to 0xff if necessary
    2565             $$imagePt =~ s/^.(\xd8\xff\xdb)/\xff$1/ or
     3704            $$imagePt =~ s/^.(\xd8\xff\xdb)/\xff$1/s or
    25663705            $self->Options('IgnoreMinorErrors'))
    25673706    {
    25683707        # issue warning only if the tag was specifically requested
    2569         if ($self->{REQ_TAG_LOOKUP}->{lc($tag)}) {
     3708        if ($self->{REQ_TAG_LOOKUP}{lc GetTagName($tag)}) {
    25703709            $self->Warn("$tag is not a valid JPEG image",1);
    25713710            return undef;
     
    25843723    # start with the tag name and force first letter to be upper case
    25853724    my $desc = ucfirst($tag);
    2586     $desc =~ tr/_/ /;       # translate underlines to spaces
     3725    # translate underlines to spaces
     3726    $desc =~ tr/_/ /;
     3727    # remove hex TagID from name (to avoid inserting spaces in the number)
     3728    $desc =~ s/ (0x[\da-f]+)$//i and $tagID = $1 unless defined $tagID;
    25873729    # put a space between lower/UPPER case and lower/number combinations
    25883730    $desc =~ s/([a-z])([A-Z\d])/$1 $2/g;
     
    25913733    # put spaces after numbers (if more than one character following number)
    25923734    $desc =~ s/(\d)([A-Z]\S)/$1 $2/g;
    2593     # remove space in hex number
    2594     $desc =~ s/ 0x ([\dA-Fa-f])/ 0x$1/g;
     3735    # add TagID to description
    25953736    $desc .= ' ' . $tagID if defined $tagID;
    25963737    return $desc;
     
    26003741# Return printable value
    26013742# Inputs: 0) ExifTool object reference
    2602 #         1) value to print, 2) true for unlimited line length
     3743#         1) value to print, 2) line length limit (undef defaults to 60, 0=unlimited)
    26033744sub Printable($;$)
    26043745{
    2605     my ($self, $outStr, $unlimited) = @_;
     3746    my ($self, $outStr, $maxLen) = @_;
    26063747    return '(undef)' unless defined $outStr;
    26073748    $outStr =~ tr/\x01-\x1f\x7f-\xff/./;
    26083749    $outStr =~ s/\x00//g;
    2609     # limit length if verbose < 4
    2610     if (length($outStr) > 60 and not $unlimited and $self->{OPTIONS}->{Verbose} < 4) {
    2611         $outStr = substr($outStr,0,54) . '[snip]';
     3750    if (defined $maxLen) {
     3751        # minimum length is 20 (0 is unlimited)
     3752        $maxLen = 20 if $maxLen and $maxLen < 20;
     3753    } else {
     3754        $maxLen = 60;                   # default length is 60
     3755    }
     3756    # limit length only if verbose < 4
     3757    if ($maxLen and length($outStr) > $maxLen and $self->{OPTIONS}{Verbose} < 4) {
     3758        $outStr = substr($outStr,0,$maxLen-6) . '[snip]';
    26123759    }
    26133760    return $outStr;
     
    26213768{
    26223769    my ($self, $date) = @_;
    2623     my $dateFormat = $self->{OPTIONS}->{DateFormat};
     3770    my $dateFormat = $self->{OPTIONS}{DateFormat};
    26243771    # only convert date if a format was specified and the date is recognizable
    26253772    if ($dateFormat) {
    2626         if ($date =~ /^(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)/ and eval 'require POSIX') {
    2627             $date = POSIX::strftime($dateFormat, $6, $5, $4, $3, $2-1, $1-1900);
    2628         } elsif ($self->{OPTIONS}->{StrictDate}) {
     3773        # a few cameras use incorrect date/time formatting:
     3774        # - slashes instead of colons in date (RolleiD330, ImpressCam)
     3775        # - date/time values separated by colon instead of space (Polariod, Sanyo, Sharp, Vivitar)
     3776        # - single-digit seconds with leading space (HP scanners)
     3777        $date =~ s/[-+]\d{2}:\d{2}$//;  # remove timezone if it exists
     3778        my @a = ($date =~ /\d+/g);      # be very flexible about date/time format
     3779        if (@a and $a[0] > 1900 and $a[0] < 3000 and eval 'require POSIX') {
     3780            $date = POSIX::strftime($dateFormat, $a[5]||0, $a[4]||0, $a[3]||0,
     3781                                                 $a[2]||1, ($a[1]||1)-1, $a[0]-1900);
     3782        } elsif ($self->{OPTIONS}{StrictDate}) {
    26293783            undef $date;
    26303784        }
     
    26343788
    26353789#------------------------------------------------------------------------------
     3790# Print conversion for time span value
     3791# Inputs: 0) time ticks, 1) number of seconds per tick (default 1)
     3792# Returns: readable time
     3793sub ConvertTimeSpan($;$)
     3794{
     3795    my ($val, $mult) = @_;
     3796    if (Image::ExifTool::IsFloat($val) and $val != 0) {
     3797        $val *= $mult if $mult;
     3798        if ($val < 60) {
     3799            $val = "$val seconds";
     3800        } elsif ($val < 3600) {
     3801            my $fmt = ($mult and $mult >= 60) ? '%d' : '%.1f';
     3802            my $s = ($val == 60 and $mult) ? '' : 's';
     3803            $val = sprintf("$fmt minute$s", $val / 60);
     3804        } elsif ($val < 24 * 3600) {
     3805            $val = sprintf("%.1f hours", $val / 3600);
     3806        } else {
     3807            $val = sprintf("%.1f days", $val / (24 * 3600));
     3808        }
     3809    }
     3810    return $val;
     3811}
     3812
     3813#------------------------------------------------------------------------------
     3814# Patched timelocal() that fixes ActivePerl timezone bug
     3815# Inputs/Returns: same as timelocal()
     3816# Notes: must 'require Time::Local' before calling this routine
     3817sub TimeLocal(@)
     3818{
     3819    my $tm = Time::Local::timelocal(@_);
     3820    if ($^O eq 'MSWin32') {
     3821        # patch for ActivePerl timezone bug
     3822        my @t2 = localtime($tm);
     3823        my $t2 = Time::Local::timelocal(@t2);
     3824        # adjust timelocal() return value to be consistent with localtime()
     3825        $tm += $tm - $t2;
     3826    }
     3827    return $tm;
     3828}
     3829
     3830#------------------------------------------------------------------------------
     3831# Get time zone in minutes
     3832# Inputs: 0) localtime array ref, 1) gmtime array ref
     3833# Returns: time zone offset in minutes
     3834sub GetTimeZone(;$$)
     3835{
     3836    my ($tm, $gm) = @_;
     3837    # compute the number of minutes between localtime and gmtime
     3838    my $min = $$tm[2] * 60 + $$tm[1] - ($$gm[2] * 60 + $$gm[1]);
     3839    if ($$tm[3] != $$gm[3]) {
     3840        # account for case where one date wraps to the first of the next month
     3841        $$gm[3] = $$tm[3] - ($$tm[3]==1 ? 1 : -1) if abs($$tm[3]-$$gm[3]) != 1;
     3842        # adjust for the +/- one day difference
     3843        $min += ($$tm[3] - $$gm[3]) * 24 * 60;
     3844    }
     3845    return $min;
     3846}
     3847
     3848#------------------------------------------------------------------------------
     3849# Get time zone string
     3850# Inputs: 0) time zone offset in minutes
     3851#     or  0) localtime array ref, 1) corresponding time value
     3852# Returns: time zone string ("+/-HH:MM")
     3853sub TimeZoneString($;$)
     3854{
     3855    my $min = shift;
     3856    if (ref $min) {
     3857        my @gm = gmtime(shift);
     3858        $min = GetTimeZone($min, \@gm);
     3859    }
     3860    my $sign = '+';
     3861    $min < 0 and $sign = '-', $min = -$min;
     3862    my $h = int($min / 60);
     3863    return sprintf('%s%.2d:%.2d', $sign, $h, $min - $h * 60);
     3864}
     3865
     3866#------------------------------------------------------------------------------
    26363867# Convert Unix time to EXIF date/time string
    2637 # Inputs: 0) Unix time value, 1) non-zero to use local instead of GMT time
    2638 # Returns: EXIF date/time string
     3868# Inputs: 0) Unix time value, 1) non-zero to convert to local time
     3869# Returns: EXIF date/time string (with timezone for local times)
     3870# Notes: fractional seconds are ignored
    26393871sub ConvertUnixTime($;$)
    26403872{
    2641     my $time = shift;
     3873    my ($time, $toLocal) = @_;
    26423874    return '0000:00:00 00:00:00' if $time == 0;
    2643     my @tm = shift() ? localtime($time) : gmtime($time);
    2644     return sprintf("%4d:%.2d:%.2d %.2d:%.2d:%.2d", $tm[5]+1900, $tm[4]+1,
    2645                    $tm[3], $tm[2], $tm[1], $tm[0]);
    2646 }
    2647 
    2648 #------------------------------------------------------------------------------
    2649 # Get Unix time from EXIF-formatted date/time string
    2650 # Inputs: 0) EXIF date/time string, 1) non-zero to use local instead of GMT time
    2651 # Returns: Unix time or undefined on error
     3875    my (@tm, $tz);
     3876    if ($toLocal) {
     3877        @tm = localtime($time);
     3878        $tz = TimeZoneString(\@tm, $time);
     3879    } else {
     3880        @tm = gmtime($time);
     3881        $tz = '';
     3882    }
     3883    my $str = sprintf("%4d:%.2d:%.2d %.2d:%.2d:%.2d%s",
     3884                      $tm[5]+1900, $tm[4]+1, $tm[3], $tm[2], $tm[1], $tm[0], $tz);
     3885    return $str;
     3886}
     3887
     3888#------------------------------------------------------------------------------
     3889# Get Unix time from EXIF-formatted date/time string with optional timezone
     3890# Inputs: 0) EXIF date/time string, 1) non-zero if time is local
     3891# Returns: Unix time (seconds since 0:00 GMT Jan 1, 1970) or undefined on error
    26523892sub GetUnixTime($;$)
    26533893{
    2654     my $timeStr = shift;
     3894    my ($timeStr, $isLocal) = @_;
    26553895    return 0 if $timeStr eq '0000:00:00 00:00:00';
    26563896    my @tm = ($timeStr =~ /^(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)/);
    2657     return undef unless @tm == 6;
    2658     return undef unless eval 'require Time::Local';
     3897    return undef unless @tm == 6 and eval 'require Time::Local';
     3898    my $tzsec = 0;
     3899    # use specified timezone offset (if given) instead of local system time
     3900    # if we are converting a local time value
     3901    if ($isLocal and $timeStr =~ /(?:Z|([-+])(\d+):(\d+))$/i) {
     3902        # use specified timezone if one exists
     3903        $tzsec = ($2 * 60 + $3) * ($1 eq '-' ? -60 : 60) if $1;
     3904        undef $isLocal; # convert using GMT corrected for specified timezone
     3905    }
    26593906    $tm[0] -= 1900;     # convert year
    26603907    $tm[1] -= 1;        # convert month
    26613908    @tm = reverse @tm;  # change to order required by timelocal()
    2662     return shift() ? Time::Local::timelocal(@tm) : Time::Local::timegm(@tm);
     3909    return $isLocal ? TimeLocal(@tm) : Time::Local::timegm(@tm) - $tzsec;
     3910}
     3911
     3912#------------------------------------------------------------------------------
     3913# Print conversion for file size
     3914# Inputs: 0) file size in bytes
     3915# Returns: converted file size
     3916sub ConvertFileSize($)
     3917{
     3918    my $val = shift;
     3919    $val < 2048 and return "$val bytes";
     3920    $val < 10240 and return sprintf('%.1f kB', $val / 1024);
     3921    $val < 2097152 and return sprintf('%.0f kB', $val / 1024);
     3922    $val < 10485760 and return sprintf('%.1f MB', $val / 1048576);
     3923    return sprintf('%.0f MB', $val / 1048576);
     3924}
     3925
     3926#------------------------------------------------------------------------------
     3927# Convert seconds to duration string (handles negative durations)
     3928# Inputs: 0) floating point seconds
     3929# Returns: duration string in form "S.SS s", "MM:SS" or "H:MM:SS"
     3930sub ConvertDuration($)
     3931{
     3932    my $time = shift;
     3933    return $time unless IsFloat($time);
     3934    return '0 s' if $time == 0;
     3935    my $sign = ($time > 0 ? '' : (($time = -$time), '-'));
     3936    return sprintf("$sign%.2f s", $time) if $time < 30;
     3937    my $h = int($time / 3600);
     3938    $time -= $h * 3600;
     3939    my $m = int($time / 60);
     3940    $time -= $m * 60;
     3941    return sprintf("$sign%d:%.2d:%.2d", $h, $m, int($time));
     3942}
     3943
     3944#------------------------------------------------------------------------------
     3945# Print conversion for bitrate values
     3946# Inputs: 0) bitrate in bits per second
     3947# Returns: human-readable bitrate string
     3948# Notes: returns input value without formatting if it isn't numerical
     3949sub ConvertBitrate($)
     3950{
     3951    my $bitrate = shift;
     3952    IsFloat($bitrate) or return $bitrate;
     3953    my @units = ('bps', 'kbps', 'Mbps', 'Gbps');
     3954    for (;;) {
     3955        my $units = shift @units;
     3956        $bitrate >= 1000 and @units and $bitrate /= 1000, next;
     3957        my $fmt = $bitrate < 100 ? '%.3g' : '%.0f';
     3958        return sprintf("$fmt $units", $bitrate);
     3959    }
    26633960}
    26643961
     
    26673964# Inputs: 0) ExifTool hash ref, 1) start offset, 2) data size
    26683965#         3) comment string, 4) tool tip (or SAME), 5) flags
    2669 sub HtmlDump($$$$;$$)
     3966sub HDump($$$$;$$)
    26703967{
    26713968    my $self = shift;
     
    27524049
    27534050#------------------------------------------------------------------------------
     4051# Read/rewrite trailer information (including multiple trailers)
     4052# Inputs: 0) ExifTool object ref, 1) DirInfo ref:
     4053# - requires RAF and DirName
     4054# - OutFile is a scalar reference for writing
     4055# - scans from current file position if ScanForAFCP is set
     4056# Returns: 1 if trailer was processed or couldn't be processed (or written OK)
     4057#          0 if trailer was recognized but offsets need fixing (or write error)
     4058# - DirName, DirLen, DataPos, Offset, Fixup and OutFile are updated
     4059# - preserves current file position and byte order
     4060sub ProcessTrailers($$)
     4061{
     4062    my ($self, $dirInfo) = @_;
     4063    my $dirName = $$dirInfo{DirName};
     4064    my $outfile = $$dirInfo{OutFile};
     4065    my $offset = $$dirInfo{Offset} || 0;
     4066    my $fixup = $$dirInfo{Fixup};
     4067    my $raf = $$dirInfo{RAF};
     4068    my $pos = $raf->Tell();
     4069    my $byteOrder = GetByteOrder();
     4070    my $success = 1;
     4071    my $path = $$self{PATH};
     4072
     4073    for (;;) { # loop through all trailers
     4074        require "Image/ExifTool/$dirName.pm";
     4075        my $proc = "Image::ExifTool::${dirName}::Process$dirName";
     4076        my $outBuff;
     4077        if ($outfile) {
     4078            # write to local buffer so we can add trailer in proper order later
     4079            $$outfile and $$dirInfo{OutFile} = \$outBuff, $outBuff = '';
     4080            # must generate new fixup if necessary so we can shift
     4081            # the old fixup separately after we prepend this trailer
     4082            delete $$dirInfo{Fixup};
     4083        }
     4084        delete $$dirInfo{DirLen};       # reset trailer length
     4085        $$dirInfo{Offset} = $offset;    # set offset from end of file
     4086        $$dirInfo{Trailer} = 1;         # set Trailer flag in case proc cares
     4087        # add trailer and DirName to SubDirectory PATH
     4088        push @$path, 'Trailer', $dirName;
     4089
     4090        # read or write this trailer
     4091        # (proc takes Offset as offset from end of trailer to end of file,
     4092        #  and returns DataPos and DirLen, and Fixup if applicable)
     4093        no strict 'refs';
     4094        my $result = &$proc($self, $dirInfo);
     4095        use strict 'refs';
     4096
     4097        # restore PATH
     4098        pop @$path;
     4099        pop @$path;
     4100        # check result
     4101        if ($outfile) {
     4102            if ($result > 0) {
     4103                if ($outBuff) {
     4104                    # write trailers to OutFile in original order
     4105                    $$outfile = $outBuff . $$outfile;
     4106                    # must adjust old fixup start if it exists
     4107                    $$fixup{Start} += length($outBuff) if $fixup;
     4108                    $outBuff = '';      # free memory
     4109                }
     4110                if ($fixup) {
     4111                    # add new fixup information if any
     4112                    $fixup->AddFixup($$dirInfo{Fixup}) if $$dirInfo{Fixup};
     4113                } else {
     4114                    $fixup = $$dirInfo{Fixup};  # save fixup
     4115                }
     4116            } else {
     4117                $success = 0 if $self->Error("Error rewriting $dirName trailer", 1);
     4118                last;
     4119            }
     4120        } elsif ($result < 0) {
     4121            # can't continue if we must scan for this trailer
     4122            $success = 0;
     4123            last;
     4124        }
     4125        last unless $result > 0 and $$dirInfo{DirLen};
     4126        # look for next trailer
     4127        $offset += $$dirInfo{DirLen};
     4128        my $nextTrail = IdentifyTrailer($raf, $offset) or last;
     4129        $dirName = $$dirInfo{DirName} = $$nextTrail{DirName};
     4130        $raf->Seek($pos, 0);
     4131    }
     4132    SetByteOrder($byteOrder);       # restore original byte order
     4133    $raf->Seek($pos, 0);            # restore original file position
     4134    $$dirInfo{OutFile} = $outfile;  # restore original outfile
     4135    $$dirInfo{Offset} = $offset;    # return offset from EOF to start of first trailer
     4136    $$dirInfo{Fixup} = $fixup;      # return fixup information
     4137    return $success;
     4138}
     4139
     4140#------------------------------------------------------------------------------
    27544141# Extract EXIF information from a jpg image
    27554142# Inputs: 0) ExifTool object reference, 1) dirInfo ref with RAF set
     
    27574144sub ProcessJPEG($$)
    27584145{
     4146    local $_;
    27594147    my ($self, $dirInfo) = @_;
    2760     my ($ch,$s,$length);
    2761     my $verbose = $self->{OPTIONS}->{Verbose};
    2762     my $out = $self->{OPTIONS}->{TextOut};
     4148    my ($ch, $s, $length);
     4149    my $verbose = $self->{OPTIONS}{Verbose};
     4150    my $out = $self->{OPTIONS}{TextOut};
     4151    my $fast = $self->{OPTIONS}{FastScan};
    27634152    my $raf = $$dirInfo{RAF};
    27644153    my $htmlDump = $self->{HTML_DUMP};
    27654154    my %dumpParms = ( Out => $out );
    2766     my ($success, $icc_profile, $wantPreview, $trailInfo);
     4155    my ($success, $icc_profile, $wantTrailer, $trailInfo, %extendedXMP);
     4156    my ($preview, $scalado, @dqt, $subSampling, $dumpEnd);
    27674157
    27684158    # check to be sure this is a valid JPG file
    27694159    return 0 unless $raf->Read($s, 2) == 2 and $s eq "\xff\xd8";
    27704160    $dumpParms{MaxLen} = 128 if $verbose < 4;
    2771     $self->SetFileType();   # set FileType tag
     4161    unless ($self->{VALUE}{FileType}) {
     4162        $self->SetFileType();               # set FileType tag
     4163        $$self{LOW_PRIORITY_DIR}{IFD1} = 1; # lower priority of IFD1 tags
     4164    }
    27724165    if ($htmlDump) {
    2773         my $pos = $raf->Tell() - 2;
    2774         $self->HtmlDump(0, $pos, '[unknown header]') if $pos;
    2775         $self->HtmlDump($pos, 2, 'JPEG header', 'SOI Marker');
    2776     }
     4166        $dumpEnd = $raf->Tell();
     4167        my $pos = $dumpEnd - 2;
     4168        $self->HDump(0, $pos, '[unknown header]') if $pos;
     4169        $self->HDump($pos, 2, 'JPEG header', 'SOI Marker');
     4170    }
     4171    my $path = $$self{PATH};
     4172    my $pn = scalar @$path;
    27774173
    27784174    # set input record separator to 0xff (the JPEG marker) to make reading quicker
    2779     my $oldsep = $/;
    2780     $/ = "\xff";
    2781 
    2782     my ($nextMarker, $nextSegDataPt, $nextSegPos, $combinedSegData, $dumpEnd);
     4175    local $/ = "\xff";
     4176
     4177    my ($nextMarker, $nextSegDataPt, $nextSegPos, $combinedSegData);
    27834178
    27844179    # read file until we reach an end of image (EOI) or start of scan (SOS)
     
    27934188# read ahead to the next segment unless we have reached EOI or SOS
    27944189#
    2795         unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantPreview))) {
     4190        unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer))) {
    27964191            # read up to next marker (JPEG markers begin with 0xff)
    27974192            my $buff;
     
    28214216        }
    28224217        # set some useful variables for the current segment
    2823         my $hdr = "\xff" . chr($marker);    # header for this segment
    28244218        my $markerName = JpegMarkerName($marker);
     4219        $$path[$pn] = $markerName;
    28254220#
    28264221# parse the current segment
     
    28454240            my ($i, $hmin, $hmax, $vmin, $vmax);
    28464241            # loop through all components to determine sampling frequency
     4242            $subSampling = '';
    28474243            for ($i=0; $i<$n; ++$i) {
    28484244                my $sf = Get8u($segDataPt, 7 + 3 * $i);
     4245                $subSampling .= sprintf('%.2x', $sf);
    28494246                # isolate horizontal and vertical components
    28504247                my ($hf, $vf) = ($sf >> 4, $sf & 0x0f);
     
    28664263            next;
    28674264        } elsif ($marker == 0xd9) {         # EOI
     4265            pop @$path;
    28684266            $verbose and print $out "JPEG EOI\n";
    28694267            my $pos = $raf->Tell();
    28704268            if ($htmlDump and $dumpEnd) {
    2871                 $self->HtmlDump($dumpEnd, $pos-2-$dumpEnd, '[JPEG Image Data]', undef, 0x08);
    2872                 $self->HtmlDump($pos-2, 2, 'JPEG EOI', undef);
     4269                $self->HDump($dumpEnd, $pos-2-$dumpEnd, '[JPEG Image Data]', undef, 0x08);
     4270                $self->HDump($pos-2, 2, 'JPEG EOI', undef);
    28734271                $dumpEnd = 0;
    28744272            }
    28754273            $success = 1;
    28764274            # we are here because we are looking for trailer information
    2877             if ($wantPreview and $self->{VALUE}->{PreviewImageStart}) {
    2878                 my $buff;
    2879                 # most previews start right after the JPEG EOI, but the Olympus E-20
    2880                 # preview is 508 bytes into the trailer, and the K-M Maxxum 7D preview
    2881                 # is 979 bytes in, but Minolta previews can have a random first byte...
    2882                 if ($raf->Read($buff, 1024) and ($buff =~ /\xff\xd8\xff./g or
    2883                     ($self->{CameraMake} =~ /Minolta/i and $buff =~ /.\xd8\xff\xdb/g)))
    2884                 {
    2885                     # adjust PreviewImageStart to this location
    2886                     my $start = $self->{VALUE}->{PreviewImageStart};
    2887                     my $actual = $pos + pos($buff) - 4;
    2888                     if ($start ne $actual and $verbose > 1) {
    2889                         print $out "(Fixed PreviewImage location: $start -> $actual)\n";
     4275            if ($wantTrailer) {
     4276                my $start = $$self{PreviewImageStart};
     4277                if ($start) {
     4278                    my $buff;
     4279                    # most previews start right after the JPEG EOI, but the Olympus E-20
     4280                    # preview is 508 bytes into the trailer, the K-M Maxxum 7D preview is
     4281                    # 979 bytes in, and Sony previews can start up to 32 kB into the trailer.
     4282                    # (and Minolta and Sony previews can have a random first byte...)
     4283                    my $scanLen = $$self{Make} =~ /Sony/i ? 65536 : 1024;
     4284                    if ($raf->Read($buff, $scanLen) and ($buff =~ /\xff\xd8\xff./g or
     4285                        ($self->{Make} =~ /(Minolta|Sony)/i and $buff =~ /.\xd8\xff\xdb/g)))
     4286                    {
     4287                        # adjust PreviewImageStart to this location
     4288                        my $actual = $pos + pos($buff) - 4;
     4289                        if ($start ne $actual and $verbose > 1) {
     4290                            print $out "(Fixed PreviewImage location: $start -> $actual)\n";
     4291                        }
     4292                        # update preview image offsets
     4293                        $self->{VALUE}{PreviewImageStart} = $actual if $self->{VALUE}{PreviewImageStart};
     4294                        $$self{PreviewImageStart} = $actual;
     4295                        # load preview now if we tried and failed earlier
     4296                        if ($$self{PreviewError} and $$self{PreviewImageLength}) {
     4297                            if ($raf->Seek($actual, 0) and $raf->Read($buff, $$self{PreviewImageLength})) {
     4298                                $self->FoundTag('PreviewImage', $buff);
     4299                                delete $$self{PreviewError};
     4300                            }
     4301                        }
    28904302                    }
    2891                     $self->{VALUE}->{PreviewImageStart} = $actual;
     4303                    $raf->Seek($pos, 0);
    28924304                }
    2893                 $raf->Seek($pos, 0);
    28944305            }
    28954306            # process trailer now or finish processing trailers
     
    29034314                undef $trailInfo;
    29044315            }
     4316            if ($$self{LeicaTrailer}) {
     4317                $raf->Seek(0, 2);
     4318                $$self{LeicaTrailer}{TrailPos} = $pos;
     4319                $$self{LeicaTrailer}{TrailLen} = $raf->Tell() - $pos - $fromEnd;
     4320                Image::ExifTool::Panasonic::ProcessLeicaTrailer($self);
     4321            }
    29054322            # finally, dump remaining information in JPEG trailer
    29064323            if ($verbose or $htmlDump) {
    2907                 $raf->Seek(0, 2);
    2908                 my $endPos = $raf->Tell() - $fromEnd;
     4324                my $endPos = $$self{LeicaTrailerPos};
     4325                unless ($endPos) {
     4326                    $raf->Seek(0, 2);
     4327                    $endPos = $raf->Tell() - $fromEnd;
     4328                }
    29094329                $self->DumpUnknownTrailer({
    29104330                    RAF => $raf,
     
    29154335            last;       # all done parsing file
    29164336        } elsif ($marker == 0xda) {         # SOS
     4337            pop @$path;
    29174338            # all done with meta information unless we have a trailer
    29184339            $verbose and print $out "JPEG SOS\n";
    2919             unless ($self->Options('FastScan')) {
     4340            unless ($fast) {
    29204341                $trailInfo = IdentifyTrailer($raf);
    29214342                # process trailer now unless we are doing verbose dump
     
    29254346                    $self->ProcessTrailers($trailInfo) and undef $trailInfo;
    29264347                }
    2927                 if ($wantPreview) {
     4348                if ($wantTrailer) {
    29284349                    # seek ahead and validate preview image
    29294350                    my $buff;
    29304351                    my $curPos = $raf->Tell();
    2931                     if ($raf->Seek($self->GetValue('PreviewImageStart'), 0) and
     4352                    if ($raf->Seek($$self{PreviewImageStart}, 0) and
    29324353                        $raf->Read($buff, 4) == 4 and
    29334354                        $buff =~ /^.\xd8\xff[\xc4\xdb\xe0-\xef]/)
    29344355                    {
    2935                         undef $wantPreview;
     4356                        undef $wantTrailer;
    29364357                    }
    29374358                    $raf->Seek($curPos, 0) or last;
    29384359                }
    2939                 next if $trailInfo or $wantPreview or $verbose > 2 or $htmlDump;
     4360                # seek ahead and process Leica trailer
     4361                if ($$self{LeicaTrailer}) {
     4362                    require Image::ExifTool::Panasonic;
     4363                    Image::ExifTool::Panasonic::ProcessLeicaTrailer($self);
     4364                    $wantTrailer = 1 if $$self{LeicaTrailer};
     4365                }
     4366                next if $trailInfo or $wantTrailer or $verbose > 2 or $htmlDump;
    29404367            }
    29414368            # nothing interesting to parse after start of scan (SOS)
     
    29464373            $verbose and $marker and print $out "JPEG $markerName:\n";
    29474374            next;
     4375        } elsif ($marker == 0xdb and length($$segDataPt) and    # DQT
     4376            # save the DQT data only if JPEGDigest has been requested
     4377            $self->{REQ_TAG_LOOKUP}->{jpegdigest})
     4378        {
     4379            my $num = unpack('C',$$segDataPt) & 0x0f;   # get table index
     4380            $dqt[$num] = $$segDataPt if $num < 4;       # save for MD5 calculation
    29484381        }
    29494382        # handle all other markers
     
    29584391            }
    29594392        }
    2960         if ($marker == 0xe0) {              # APP0 (JFIF, CIFF)
     4393        if ($marker == 0xe0) {              # APP0 (JFIF, JFXX, CIFF, AVI1, Ocad)
    29614394            if ($$segDataPt =~ /^JFIF\0/) {
    29624395                $dumpType = 'JFIF';
     
    29764409                $self->FoundTag($tagInfo, substr($$segDataPt, 6));
    29774410            } elsif ($$segDataPt =~ /^(II|MM).{4}HEAPJPGM/s) {
     4411                next if $fast and $fast > 1;    # skip processing for very fast
    29784412                $dumpType = 'CIFF';
    29794413                my %dirInfo = (
     
    29844418                Image::ExifTool::CanonRaw::ProcessCRW($self, \%dirInfo);
    29854419                delete $self->{SET_GROUP1};
    2986             }
    2987         } elsif ($marker == 0xe1) {         # APP1 (EXIF, XMP)
     4420            } elsif ($$segDataPt =~ /^(AVI1|Ocad)/) {
     4421                $dumpType = $1;
     4422                SetByteOrder('MM');
     4423                my $tagTablePtr = GetTagTable("Image::ExifTool::JPEG::$dumpType");
     4424                my %dirInfo = (
     4425                    DataPt   => $segDataPt,
     4426                    DataPos  => $segPos,
     4427                    DirStart => 4,
     4428                    DirLen   => $length - 4,
     4429                );
     4430                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
     4431            }
     4432        } elsif ($marker == 0xe1) {         # APP1 (EXIF, XMP, QVCI)
    29884433            if ($$segDataPt =~ /^Exif\0/) { # (some Kodak cameras don't put a second \0)
    29894434                undef $dumpType;    # (will be dumped here)
     
    29994444                );
    30004445                if ($htmlDump) {
    3001                     $self->HtmlDump($segPos-4, 4, 'APP1 header',
    3002                              "Data size: $length bytes");
    3003                     $self->HtmlDump($segPos, $hdrLen, 'Exif header',
    3004                              'APP1 data type: Exif');
     4446                    $self->HDump($segPos-4, 4, 'APP1 header', "Data size: $length bytes");
     4447                    $self->HDump($segPos, $hdrLen, 'Exif header', 'APP1 data type: Exif');
    30054448                    $dumpEnd = $segPos + $length;
    30064449                }
     
    30124455                my $start = $self->GetValue('PreviewImageStart');
    30134456                my $length = $self->GetValue('PreviewImageLength');
     4457                if (not $start or not $length and $$self{PreviewError}) {
     4458                    $start = $$self{PreviewImageStart};
     4459                    $length = $$self{PreviewImageLength};
     4460                }
    30144461                if ($start and $length and
    30154462                    $start + $length > $self->{EXIF_POS} + length($self->{EXIF_DATA}) and
    3016                     $self->{REQ_TAG_LOOKUP}->{previewimage})
     4463                    $self->{REQ_TAG_LOOKUP}{previewimage})
    30174464                {
    3018                     $wantPreview = 1;
     4465                    $$self{PreviewImageStart} = $start;
     4466                    $$self{PreviewImageLength} = $length;
     4467                    $wantTrailer = 1;
    30194468                }
     4469            } elsif ($$segDataPt =~ /^$xmpExtAPP1hdr/) {
     4470                # off len -- extended XMP header (75 bytes total):
     4471                #   0  35 bytes - signature
     4472                #  35  32 bytes - GUID (MD5 hash of full extended XMP data in ASCII)
     4473                #  67   4 bytes - total size of extended XMP data
     4474                #  71   4 bytes - offset for this XMP data portion
     4475                $dumpType = 'Extended XMP';
     4476                if (length $$segDataPt > 75) {
     4477                    my ($size, $off) = unpack('x67N2', $$segDataPt);
     4478                    my $guid = substr($$segDataPt, 35, 32);
     4479                    my $extXMP = $extendedXMP{$guid};
     4480                    $extXMP or $extXMP = $extendedXMP{$guid} = { };
     4481                    $$extXMP{Size} = $size;
     4482                    $$extXMP{$off} = substr($$segDataPt, 75);
     4483                    # process extended XMP if complete
     4484                    my @offsets;
     4485                    for ($off=0; $off<$size; ) {
     4486                        last unless defined $$extXMP{$off};
     4487                        push @offsets, $off;
     4488                        $off += length $$extXMP{$off};
     4489                    }
     4490                    if ($off == $size) {
     4491                        my $buff = '';
     4492                        # assemble XMP all together
     4493                        $buff .= $$extXMP{$_} foreach @offsets;
     4494                        $dumpType = 'Extended XMP';
     4495                        my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
     4496                        my %dirInfo = (
     4497                            DataPt   => \$buff,
     4498                            Parent   => $markerName,
     4499                        );
     4500                        $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
     4501                        delete $extendedXMP{$guid};
     4502                    }
     4503                } else {
     4504                    $self->Warn('Invalid extended XMP segment');
     4505                }
     4506            } elsif ($$segDataPt =~ /^QVCI\0/) {
     4507                $dumpType = 'QVCI';
     4508                my $tagTablePtr = GetTagTable('Image::ExifTool::Casio::QVCI');
     4509                my %dirInfo = (
     4510                    Base     => 0,
     4511                    DataPt   => $segDataPt,
     4512                    DataPos  => $segPos,
     4513                    DataLen  => $length,
     4514                    DirStart => 0,
     4515                    DirLen   => $length,
     4516                    Parent   => $markerName,
     4517                );
     4518                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
    30204519            } else {
    30214520                # Hmmm.  Could be XMP, let's see
     
    30234522                if ($$segDataPt =~ /^http/ or $$segDataPt =~ /<exif:/) {
    30244523                    $dumpType = 'XMP';
     4524                    # also try to parse XMP with a non-standard header
     4525                    # (note: this non-standard XMP is ignored when writing)
    30254526                    my $start = ($$segDataPt =~ /^$xmpAPP1hdr/) ? length($xmpAPP1hdr) : 0;
    30264527                    my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
     
    30354536                    );
    30364537                    $processed = $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
     4538                    if ($processed and not $start) {
     4539                        $self->Warn('Non-standard header for APP1 XMP segment');
     4540                    }
    30374541                }
    30384542                if ($verbose and not $processed) {
     
    30404544                }
    30414545            }
    3042         } elsif ($marker == 0xe2) {         # APP2 (ICC Profile, FPXR)
     4546        } elsif ($marker == 0xe2) {         # APP2 (ICC Profile, FPXR, MPF, PreviewImage)
    30434547            if ($$segDataPt =~ /^ICC_PROFILE\0/) {
    30444548                $dumpType = 'ICC_Profile';
     
    30644568                }
    30654569            } elsif ($$segDataPt =~ /^FPXR\0/) {
     4570                next if $fast and $fast > 1;    # skip processing for very fast
    30664571                $dumpType = 'FPXR';
    30674572                my $tagTablePtr = GetTagTable('Image::ExifTool::FlashPix::Main');
     
    30774582                );
    30784583                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
    3079             }
    3080         } elsif ($marker == 0xe3) {         # APP3 (Kodak "Meta")
     4584            } elsif ($$segDataPt =~ /^MPF\0/) {
     4585                undef $dumpType;    # (will be dumped here)
     4586                my %dirInfo = (
     4587                    Parent => $markerName,
     4588                    DataPt => $segDataPt,
     4589                    DataPos => $segPos,
     4590                    DirStart => 4,
     4591                    Base => $segPos + 4,
     4592                    Multi => 1, # the MP Attribute IFD will be MPF1
     4593                );
     4594                if ($htmlDump) {
     4595                    $self->HDump($segPos-4, 4, 'APP2 header', "Data size: $length bytes");
     4596                    $self->HDump($segPos, 4, 'MPF header', 'APP2 data type: MPF');
     4597                    $dumpEnd = $segPos + $length;
     4598                }
     4599                # extract the MPF information (it is in standard TIFF format)
     4600                my $tagTablePtr = GetTagTable('Image::ExifTool::MPF::Main');
     4601                $self->ProcessTIFF(\%dirInfo, $tagTablePtr);
     4602            } elsif ($$segDataPt =~ /^\xff\xd8\xff\xdb/) {
     4603                $preview = $$segDataPt;
     4604                $dumpType = 'Samsung Preview';
     4605            } elsif ($preview) {
     4606                $preview .= $$segDataPt;
     4607                $dumpType = 'Samsung Preview';
     4608            }
     4609            if ($preview and $nextMarker ne $marker) {
     4610                $self->FoundTag('PreviewImage', $preview);
     4611                undef $preview;
     4612            }
     4613        } elsif ($marker == 0xe3) {         # APP3 (Kodak "Meta", Stim)
    30814614            if ($$segDataPt =~ /^(Meta|META|Exif)\0\0/) {
    30824615                undef $dumpType;    # (will be dumped here)
     
    30894622                );
    30904623                if ($htmlDump) {
    3091                     $self->HtmlDump($segPos-4, 10, 'APP3 Meta header');
     4624                    $self->HDump($segPos-4, 10, 'APP3 Meta header');
    30924625                    $dumpEnd = $segPos + $length;
    30934626                }
    30944627                my $tagTablePtr = GetTagTable('Image::ExifTool::Kodak::Meta');
    30954628                $self->ProcessTIFF(\%dirInfo, $tagTablePtr);
     4629            } elsif ($$segDataPt =~ /^Stim\0/) {
     4630                undef $dumpType;    # (will be dumped here)
     4631                my %dirInfo = (
     4632                    Parent => $markerName,
     4633                    DataPt => $segDataPt,
     4634                    DataPos => $segPos,
     4635                    DirStart => 6,
     4636                    Base => $segPos + 6,
     4637                );
     4638                if ($htmlDump) {
     4639                    $self->HDump($segPos-4, 4, 'APP3 header', "Data size: $length bytes");
     4640                    $self->HDump($segPos, 5, 'Stim header', 'APP3 data type: Stim');
     4641                    $dumpEnd = $segPos + $length;
     4642                }
     4643                # extract the Stim information (it is in standard TIFF format)
     4644                my $tagTablePtr = GetTagTable('Image::ExifTool::Stim::Main');
     4645                $self->ProcessTIFF(\%dirInfo, $tagTablePtr);
     4646            } elsif ($$segDataPt =~ /^\xff\xd8\xff\xdb/) {
     4647                $preview = $$segDataPt;
     4648                $dumpType = 'Samsung/HP Preview';
     4649            }
     4650            # Samsung continues the preview in APP4
     4651            if ($preview and $nextMarker ne 0xe4) {
     4652                $self->FoundTag('PreviewImage', $preview);
     4653                undef $preview;
     4654            }
     4655        } elsif ($marker == 0xe4) {         # APP4 ("SCALADO", FPXR, PreviewImage)
     4656            if ($$segDataPt =~ /^SCALADO\0/ and $length >= 16) {
     4657                $dumpType = 'SCALADO';
     4658                my ($num, $idx, $len) = unpack('x8n2N', $$segDataPt);
     4659                # assume that the segments are in order and just concatinate them
     4660                $scalado = '' unless defined $scalado;
     4661                $scalado .= substr($$segDataPt, 16);
     4662                if ($idx == $num - 1) {
     4663                    if ($len != length $scalado) {
     4664                        $self->Warn('Possibly corrupted APP4 SCALADO data', 1);
     4665                    }
     4666                    my %dirInfo = (
     4667                        Parent => $markerName,
     4668                        DataPt => \$scalado,
     4669                    );
     4670                    my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::Scalado');
     4671                    $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
     4672                    undef $scalado;
     4673                }
     4674            } elsif ($$segDataPt =~ /^FPXR\0/) {
     4675                next if $fast and $fast > 1;    # skip processing for very fast
     4676                $dumpType = 'FPXR';
     4677                my $tagTablePtr = GetTagTable('Image::ExifTool::FlashPix::Main');
     4678                my %dirInfo = (
     4679                    DataPt   => $segDataPt,
     4680                    DataPos  => $segPos,
     4681                    DataLen  => $length,
     4682                    DirStart => 0,
     4683                    DirLen   => $length,
     4684                    Parent   => $markerName,
     4685                    # set flag if this is the last FPXR segment
     4686                    LastFPXR => not ($nextMarker==$marker and $$nextSegDataPt=~/^FPXR\0/),
     4687                );
     4688                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
     4689            } elsif ($preview) {
     4690                # continued Samsung S1060 preview from APP3
     4691                $preview .= $$segDataPt;
     4692                # (not sure if next part would be APP5 or APP4 again, but assume APP4)
     4693                if ($nextMarker ne $marker) {
     4694                    $self->FoundTag('PreviewImage', $preview);
     4695                    undef $preview;
     4696                }
    30964697            }
    30974698        } elsif ($marker == 0xe5) {         # APP5 (Ricoh "RMETA")
     
    31084709                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
    31094710            }
    3110         } elsif ($marker == 0xe6) {         # APP6 (Toshiba EPPIM)
     4711        } elsif ($marker == 0xe6) {         # APP6 (Toshiba EPPIM, NITF, HP_TDHD)
    31114712            if ($$segDataPt =~ /^EPPIM\0/) {
    31124713                undef $dumpType;    # (will be dumped here)
     
    31194720                );
    31204721                if ($htmlDump) {
    3121                     $self->HtmlDump($segPos-4, 10, 'APP6 EPPIM header');
     4722                    $self->HDump($segPos-4, 10, 'APP6 EPPIM header');
    31224723                    $dumpEnd = $segPos + $length;
    31234724                }
    31244725                my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::EPPIM');
    31254726                $self->ProcessTIFF(\%dirInfo, $tagTablePtr);
     4727            } elsif ($$segDataPt =~ /^NITF\0/) {
     4728                $dumpType = 'NITF';
     4729                SetByteOrder('MM');
     4730                my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::NITF');
     4731                my %dirInfo = (
     4732                    DataPt   => $segDataPt,
     4733                    DataPos  => $segPos,
     4734                    DirStart => 5,
     4735                    DirLen   => $length - 5,
     4736                );
     4737                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
     4738            } elsif ($$segDataPt =~ /^TDHD\x01\0\0\0/ and $length > 12) {
     4739                # HP Photosmart R837 APP6 "TDHD" segment
     4740                $dumpType = 'TDHD';
     4741                my $tagTablePtr = GetTagTable('Image::ExifTool::HP::TDHD');
     4742                my %dirInfo = (
     4743                    DataPt   => $segDataPt,
     4744                    DataPos  => $segPos,
     4745                    DirStart => 12, # (ignore first TDHD element because size includes 12-byte tag header)
     4746                    DirLen   => $length - 12,
     4747                );
     4748                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
    31264749            }
    31274750        } elsif ($marker == 0xe8) {         # APP8 (SPIFF)
     
    31414764            if ($$segDataPt =~ /^UNICODE\0/) {
    31424765                $dumpType = 'PhotoStudio';
    3143                 my $comment = $self->Unicode2Charset(substr($$segDataPt,8), 'MM');
     4766                my $comment = $self->Decode(substr($$segDataPt,8), 'UCS2', 'MM');
    31444767                $self->FoundTag('Comment', $comment);
    31454768            }
     
    31654788                $dumpType = 'Photoshop';
    31664789                # add this data to the combined data if it exists
     4790                my $dataPt = $segDataPt;
    31674791                if (defined $combinedSegData) {
    31684792                    $combinedSegData .= substr($$segDataPt,length($psAPP13hdr));
    3169                     $segDataPt = \$combinedSegData;
    3170                     $length = length $combinedSegData;  # update length
     4793                    $dataPt = \$combinedSegData;
    31714794                }
    31724795                # peek ahead to see if the next segment is photoshop data too
     
    31744797                    # initialize combined data if necessary
    31754798                    $combinedSegData = $$segDataPt unless defined $combinedSegData;
    3176                     next;   # will handle the combined data the next time around
     4799                    # (will handle the Photoshop data the next time around)
     4800                } else {
     4801                    my $hdrlen = $isOld ? 27 : 14;
     4802                    # process APP13 Photoshop record
     4803                    my $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
     4804                    my %dirInfo = (
     4805                        DataPt   => $dataPt,
     4806                        DataPos  => $segPos,
     4807                        DataLen  => length $$dataPt,
     4808                        DirStart => $hdrlen,    # directory starts after identifier
     4809                        DirLen   => length($$dataPt) - $hdrlen,
     4810                        Parent   => $markerName,
     4811                    );
     4812                    $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
     4813                    undef $combinedSegData;
    31774814                }
    3178                 my $hdrlen = $isOld ? 27 : 14;
    3179                 # process APP13 Photoshop record
    3180                 my $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
    3181                 my %dirInfo = (
    3182                     DataPt   => $segDataPt,
    3183                     DataPos  => $segPos,
    3184                     DataLen  => $length,
    3185                     DirStart => $hdrlen,    # directory starts after identifier
    3186                     DirLen   => $length - $hdrlen,
    3187                     Parent   => $markerName,
    3188                 );
    3189                 $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
    3190                 undef $combinedSegData;
    31914815            } elsif ($$segDataPt =~ /^Adobe_CM/) {
    31924816                $dumpType = 'Adobe_CM';
     
    32224846        } elsif ($marker == 0xfe) {         # COM (JPEG comment)
    32234847            $dumpType = 'Comment';
     4848            $$segDataPt =~ s/\0+$//;    # some dumb softwares add null terminators
    32244849            $self->FoundTag('Comment', $$segDataPt);
    32254850        } elsif (($marker & 0xf0) != 0xe0) {
     
    32274852        }
    32284853        if (defined $dumpType) {
    3229             if (not $dumpType and $self->{OPTIONS}->{Unknown}) {
     4854            if (not $dumpType and $self->{OPTIONS}{Unknown}) {
    32304855                $self->Warn("Unknown $markerName segment", 1);
    32314856            }
    32324857            if ($htmlDump) {
    32334858                my $desc = $markerName . ($dumpType ? " $dumpType" : '') . ' segment';
    3234                 $self->HtmlDump($segPos-4, $length+4, $desc, undef, 0x08);
     4859                $self->HDump($segPos-4, $length+4, $desc, undef, 0x08);
    32354860                $dumpEnd = $segPos + $length;
    32364861            }
     
    32384863        undef $$segDataPt;
    32394864    }
    3240     $/ = $oldsep;     # restore separator to original value
     4865    # calculate JPEGDigest if requested
     4866    if (@dqt and $subSampling) {
     4867        require Image::ExifTool::JPEGDigest;
     4868        Image::ExifTool::JPEGDigest::Calculate($self, \@dqt, $subSampling);
     4869    }
     4870    $self->Warn('Error reading PreviewImage', 1) if $$self{PreviewError};
     4871    $self->Warn('Invalid extended XMP') if %extendedXMP;
    32414872    $success or $self->Warn('JPEG format error');
     4873    pop @$path if @$path > $pn;
    32424874    return 1;
    32434875}
    32444876
    32454877#------------------------------------------------------------------------------
    3246 # Process TIFF data
    3247 # Inputs: 0) ExifTool object reference, 1) directory information reference
    3248 #         2) optional tag table reference
     4878# Process EXIF file
     4879# Inputs/Returns: same as ProcessTIFF
     4880sub ProcessEXIF($$;$)
     4881{
     4882    my ($self, $dirInfo, $tagTablePtr) = @_;
     4883    return $self->ProcessTIFF($dirInfo, $tagTablePtr);
     4884}
     4885
     4886#------------------------------------------------------------------------------
     4887# Process TIFF data (wrapper for DoProcessTIFF to allow re-entry)
     4888# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) optional tag table ref
    32494889# Returns: 1 if this looked like a valid EXIF block, 0 otherwise, or -1 on write error
    32504890sub ProcessTIFF($$;$)
     4891{
     4892    my ($self, $dirInfo, $tagTablePtr) = @_;
     4893    my $exifData = $$self{EXIF_DATA};
     4894    my $exifPos = $$self{EXIF_POS};
     4895    my $rtnVal = $self->DoProcessTIFF($dirInfo, $tagTablePtr);
     4896    # restore original EXIF information (in case ProcessTIFF is nested)
     4897    if (defined $exifData) {
     4898        $$self{EXIF_DATA} = $exifData;
     4899        $$self{EXIF_POS} = $exifPos;
     4900    }
     4901    return $rtnVal;
     4902}
     4903
     4904#------------------------------------------------------------------------------
     4905# Process TIFF data
     4906# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) optional tag table ref
     4907# Returns: 1 if this looked like a valid EXIF block, 0 otherwise, or -1 on write error
     4908sub DoProcessTIFF($$;$)
    32514909{
    32524910    my ($self, $dirInfo, $tagTablePtr) = @_;
     
    32564914    my $base = $$dirInfo{Base} || 0;
    32574915    my $outfile = $$dirInfo{OutFile};
    3258     my ($length, $err, $canonSig);
    3259 
    3260     # read the image file header and offset to 0th IFD if necessary
     4916    my ($err, $canonSig, $otherSig);
     4917
     4918    # attempt to read TIFF header
     4919    $self->{EXIF_DATA} = '';
    32614920    if ($raf) {
    32624921        if ($outfile) {
     
    32694928            $raf->Seek($base, 0) or return 0;
    32704929        }
    3271         $raf->Read($self->{EXIF_DATA}, 8) == 8 or return 0;
    3272     } elsif ($dataPt) {
     4930        # extract full EXIF block (for block copy) from EXIF file
     4931        my $amount = $fileType eq 'EXIF' ? 65536 * 8 : 8;
     4932        my $n = $raf->Read($self->{EXIF_DATA}, $amount);
     4933        if ($n < 8) {
     4934            return 0 if $n or not $outfile or $fileType ne 'EXIF';
     4935            # create EXIF file from scratch
     4936            delete $self->{EXIF_DATA};
     4937            undef $raf;
     4938        }
     4939        if ($n > 8) {
     4940            $raf->Seek(8, 0);
     4941            if ($n == $amount) {
     4942                $self->{EXIF_DATA} = substr($self->{EXIF_DATA}, 0, 8);
     4943                $self->Warn('EXIF too large to extract as a block'); #(shouldn't happen)
     4944            }
     4945        }
     4946    } elsif ($dataPt and length $$dataPt) {
    32734947        # save a copy of the EXIF data
    32744948        my $dirStart = $$dirInfo{DirStart} || 0;
    3275         $self->{EXIF_DATA} = substr(${$$dirInfo{DataPt}}, $dirStart);
     4949        my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
     4950        $self->{EXIF_DATA} = substr($$dataPt, $dirStart, $dirLen);
     4951        $self->VerboseDir('TIFF') if $self->{OPTIONS}{Verbose} and length($$self{INDENT}) > 2;
    32764952    } elsif ($outfile) {
    3277         # create TIFF information from scratch
    3278         $self->{EXIF_DATA} = "MM\0\x2a\0\0\0\x08";
     4953        delete $self->{EXIF_DATA};  # create from scratch
    32794954    } else {
    32804955        $self->{EXIF_DATA} = '';
    32814956    }
     4957    unless (defined $self->{EXIF_DATA}) {
     4958        # create TIFF information from scratch
     4959        if ($self->SetPreferredByteOrder() eq 'MM') {
     4960            $self->{EXIF_DATA} = "MM\0\x2a\0\0\0\x08";
     4961        } else {
     4962            $self->{EXIF_DATA} = "II\x2a\0\x08\0\0\0";
     4963        }
     4964    }
    32824965    $$self{FIRST_EXIF_POS} = $base + $$self{BASE} unless defined $$self{FIRST_EXIF_POS};
    3283     $$self{EXIF_POS} = $base;
     4966    $$self{EXIF_POS} = $base + $$self{BASE};
    32844967    $dataPt = \$self->{EXIF_DATA};
    32854968
    32864969    # set byte ordering
    3287     SetByteOrder(substr($$dataPt,0,2)) or return 0;
    3288     # save EXIF byte ordering
    3289     $self->{EXIF_BYTE_ORDER} = GetByteOrder();
     4970    my $byteOrder = substr($$dataPt,0,2);
     4971    SetByteOrder($byteOrder) or return 0;
    32904972
    32914973    # verify the byte ordering
    32924974    my $identifier = Get16u($dataPt, 2);
    32934975    # identifier is 0x2a for TIFF (but 0x4f52, 0x5352 or ?? for ORF)
    3294   # no longer do this because ORF files use different values
     4976  # no longer do this because various files use different values
     4977  # (TIFF=0x2a, RW2/RWL=0x55, HDP=0xbc, BTF=0x2b, ORF=0x4f52/0x5352/0x????)
    32954978  #  return 0 unless $identifier == 0x2a;
    32964979
     
    33054988            $raf->Read($canonSig, 8) == 8 or return 0;
    33064989            $$dataPt .= $canonSig;
    3307             if ($canonSig =~ /^CR\x02\0/) {
    3308                 $fileType = 'CR2';
    3309                 $self->HtmlDump($base+8, 8, '[CR2 header]') if $self->{HTML_DUMP};
     4990            if ($canonSig =~ /^(CR\x02\0|\xba\xb0\xac\xbb)/) {
     4991                $fileType = $canonSig =~ /^CR/ ? 'CR2' : 'Canon 1D RAW';
     4992                $self->HDump($base+8, 8, "[$fileType header]") if $self->{HTML_DUMP};
    33104993            } else {
    33114994                undef $canonSig;
    33124995            }
    3313         } elsif ($identifier == 0x55 and $fileType =~ /^(RAW|TIFF)$/) {
    3314             $fileType = 'RAW';  # Panasonic RAW file
    3315             $tagTablePtr = GetTagTable('Image::ExifTool::Panasonic::Raw');
     4996        } elsif ($identifier == 0x55 and $fileType =~ /^(RAW|RW2|RWL|TIFF)$/) {
     4997            # panasonic RAW, RW2 or RWL file
     4998            my $magic;
     4999            # test for RW2/RWL magic number
     5000            if ($offset >= 0x18 and $raf->Read($magic, 16) and
     5001                $magic eq "\x88\xe7\x74\xd8\xf8\x25\x1d\x4d\x94\x7a\x6e\x77\x82\x2b\x5d\x6a")
     5002            {
     5003                $fileType = 'RW2' unless $fileType eq 'RWL';
     5004                $self->HDump($base + 8, 16, '[RW2/RWL header]') if $$self{HTML_DUMP};
     5005                $otherSig = $magic; # save signature for writing
     5006            } else {
     5007                $fileType = 'RAW';
     5008            }
     5009            $tagTablePtr = GetTagTable('Image::ExifTool::PanasonicRaw::Main');
    33165010        } elsif ($identifier == 0x2b and $fileType eq 'TIFF') {
    33175011            # this looks like a BigTIFF image
     
    33195013            require Image::ExifTool::BigTIFF;
    33205014            return 1 if Image::ExifTool::BigTIFF::ProcessBTF($self, $dirInfo);
    3321         } elsif (Get8u($dataPt, 2) == 0xbc and $fileType eq 'TIFF') {
    3322             $fileType = 'WDP';  # Windows Media Photo file
     5015        } elsif (Get8u($dataPt, 2) == 0xbc and $byteOrder eq 'II' and $fileType eq 'TIFF') {
     5016            $fileType = 'HDP';  # Windows HD Photo file
     5017            # check version number
     5018            my $ver = Get8u($dataPt, 3);
     5019            if ($ver > 1) {
     5020                $self->Error("Windows HD Photo version $ver files not yet supported");
     5021                return 1;
     5022            }
     5023        } elsif ($identifier == 0x4352 and $fileType eq 'TIFF') {
     5024            $fileType = 'DCP';
    33235025        }
    33245026        # we have a valid TIFF (or whatever) file
    3325         if ($fileType and not $self->{VALUE}->{FileType}) {
    3326             $self->SetFileType($fileType);
    3327         }
    3328     }
    3329     $self->FoundTag('ExifByteOrder', GetByteOrder());
     5027        if ($fileType and not $self->{VALUE}{FileType}) {
     5028            my $lookup = $fileTypeLookup{$fileType};
     5029            $lookup = $fileTypeLookup{$lookup} unless ref $lookup or not $lookup;
     5030            # use file extension to pre-determine type if extension is TIFF-based or type is RAW
     5031            my $t = (($lookup and $$lookup[0] eq 'TIFF') or $fileType =~ /RAW/) ? $fileType : undef;
     5032            $self->SetFileType($t);
     5033        }
     5034    }
     5035    my $ifdName = 'IFD0';
     5036    if (not $tagTablePtr or $$tagTablePtr{GROUPS}{0} eq 'EXIF') {
     5037        $self->FoundTag('ExifByteOrder', $byteOrder);
     5038    } else {
     5039        $ifdName = $$tagTablePtr{GROUPS}{1};
     5040    }
    33305041    if ($self->{HTML_DUMP}) {
    3331         my $o = (GetByteOrder() eq 'II') ? 'Little' : 'Big';
    3332         $self->HtmlDump($base, 4, "TIFF header", "Byte order: $o endian", 0);
    3333         $self->HtmlDump($base+4, 4, "IFD0 pointer", sprintf("Offset: 0x%.4x",$offset), 0);
     5042        my $tip = sprintf("Byte order: %s endian\nIdentifier: 0x%.4x\n$ifdName offset: 0x%.4x",
     5043                          ($byteOrder eq 'II') ? 'Little' : 'Big', $identifier, $offset);
     5044        $self->HDump($base, 8, 'TIFF header', $tip, 0);
    33345045    }
    33355046    # remember where we found the TIFF data (APP1, APP3, TIFF, NEF, etc...)
     
    33465057        DataPos  => 0,
    33475058        DirStart => $offset,
    3348         DirLen   => length $$dataPt,
     5059        DirLen   => length($$dataPt) - $offset,
    33495060        RAF      => $raf,
    3350         DirName  => 'IFD0',
     5061        DirName  => $ifdName,
    33515062        Parent   => $fileType,
    3352         ImageData=> 1, # set flag to get information to copy image data later
     5063        ImageData=> 'Main', # set flag to get information to copy main image data later
     5064        Multi    => $$dirInfo{Multi},
    33535065    );
    33545066
     
    33585070        $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
    33595071        # process GeoTiff information if available
    3360         if ($self->{VALUE}->{GeoTiffDirectory}) {
     5072        if ($self->{VALUE}{GeoTiffDirectory}) {
    33615073            require Image::ExifTool::GeoTiff;
    33625074            Image::ExifTool::GeoTiff::ProcessGeoTiff($self);
     
    33695081                $self->ProcessTrailers($trailInfo);
    33705082            }
     5083            # dump any other known trailer (ie. A100 RAW Data)
     5084            if ($$self{HTML_DUMP} and $$self{KnownTrailer}) {
     5085                my $known = $$self{KnownTrailer};
     5086                $raf->Seek(0, 2);
     5087                my $len = $raf->Tell() - $$known{Start};
     5088                $len -= $$trailInfo{Offset} if $trailInfo;  # account for other trailers
     5089                $self->HDump($$known{Start}, $len, "[$$known{Name}]") if $len > 0;
     5090           }
     5091        }
     5092        # update FileType if necessary now that we know more about the file
     5093        if ($$self{DNGVersion} and $self->{VALUE}{FileType} ne 'DNG') {
     5094            # override whatever FileType we set since we now know it is DNG
     5095            $self->OverrideFileType('DNG');
    33715096        }
    33725097        return 1;
     
    33885113        Image::ExifTool::CanonRaw::WriteCR2($self, \%dirInfo, $tagTablePtr) or $err = 1;
    33895114    } else {
    3390         # write TIFF header (8 bytes to be immediately followed by IFD)
    3391         $dirInfo{NewDataPos} = 8;
     5115        # write TIFF header (8 bytes [plus optional signature] followed by IFD)
     5116        $otherSig = '' unless defined $otherSig;
     5117        my $offset = 8 + length($otherSig);
     5118        # construct tiff header
     5119        my $header = substr($$dataPt, 0, 4) . Set32u($offset) . $otherSig;
     5120        $dirInfo{NewDataPos} = $offset;
     5121        $dirInfo{HeaderPtr} = \$header;
    33925122        # preserve padding between image data blocks in ORF images
    33935123        # (otherwise dcraw has problems because it assumes fixed block spacing)
     
    33975127            $err = 1;
    33985128        } elsif (length($newData)) {
    3399             my $offset = 8;
    3400             my $header = substr($$dataPt, 0, 4) . Set32u($offset);
    3401             Write($outfile, $header, $newData) or $err = 1;
     5129            # update header length in case more was added
     5130            my $hdrLen = length $header;
     5131            if ($hdrLen != 8) {
     5132                Set32u($hdrLen, \$header, 4);
     5133                # also update preview fixup if necessary
     5134                my $pi = $$self{PREVIEW_INFO};
     5135                $$pi{Fixup}{Start} += $hdrLen - 8 if $pi and $$pi{Fixup};
     5136            }
     5137            if ($$self{TIFF_TYPE} eq 'ARW' and not $err) {
     5138                # write any required ARW trailer and patch other ARW quirks
     5139                require Image::ExifTool::Sony;
     5140                my $errStr = Image::ExifTool::Sony::FinishARW($self, $dirInfo, \$newData,
     5141                                                              $dirInfo{ImageData});
     5142                $errStr and $self->Error($errStr);
     5143                delete $dirInfo{ImageData}; # (was copied by FinishARW)
     5144            } else {
     5145                Write($outfile, $header, $newData) or $err = 1;
     5146            }
    34025147            undef $newData; # free memory
    34035148        }
     
    34085153        }
    34095154    }
     5155    # make local copy of TIFF_END now (it may be reset when processing trailers)
     5156    my $tiffEnd = $self->{TIFF_END};
     5157    delete $self->{TIFF_END};
     5158
    34105159    # rewrite trailers if they exist
    3411     if ($raf and $self->{TIFF_END} and not $err) {
     5160    if ($raf and $tiffEnd and not $err) {
    34125161        my ($buf, $trailInfo);
    34135162        $raf->Seek(0, 2) or $err = 1;
    3414         my $extra = $raf->Tell() - $self->{TIFF_END};
     5163        my $extra = $raf->Tell() - $tiffEnd;
    34155164        # check for trailer and process if possible
    34165165        for (;;) {
    34175166            last unless $extra > 12;
    3418             $raf->Seek($self->{TIFF_END});  # seek back to end of image
     5167            $raf->Seek($tiffEnd);  # seek back to end of image
    34195168            $trailInfo = IdentifyTrailer($raf);
    34205169            last unless $trailInfo;
     
    34295178            }
    34305179            # calculate unused bytes before trailer
    3431             $extra = $$trailInfo{DataPos} - $self->{TIFF_END};
     5180            $extra = $$trailInfo{DataPos} - $tiffEnd;
    34325181            last; # yes, the 'for' loop was just a cheap 'goto'
    34335182        }
    34345183        # ignore a single zero byte if used for padding
    3435         # (note that Photoshop CS adds a trailer with 2 zero bytes
    3436         #  for some reason, and these will be preserved)
    3437         if ($extra > 0 and $self->{TIFF_END} & 0x01) {
    3438             $raf->Seek($self->{TIFF_END}, 0) or $err = 1;
     5184        if ($extra > 0 and $tiffEnd & 0x01) {
     5185            $raf->Seek($tiffEnd, 0) or $err = 1;
    34395186            $raf->Read($buf, 1) or $err = 1;
    3440             $buf eq "\0" and --$extra, ++$self->{TIFF_END};
     5187            defined $buf and $buf eq "\0" and --$extra, ++$tiffEnd;
    34415188        }
    34425189        if ($extra > 0) {
    3443             if ($self->{DEL_GROUP}->{Trailer}) {
     5190            my $known = $$self{KnownTrailer};
     5191            if ($self->{DEL_GROUP}{Trailer} and not $known) {
    34445192                $self->VPrint(0, "  Deleting unknown trailer ($extra bytes)\n");
    34455193                ++$self->{CHANGED};
     5194            } elsif ($known) {
     5195                $self->VPrint(0, "  Copying $$known{Name} ($extra bytes)\n");
     5196                $raf->Seek($tiffEnd, 0) or $err = 1;
     5197                CopyBlock($raf, $outfile, $extra) or $err = 1;
    34465198            } else {
    3447                 $self->VPrint(0, "  Preserving unknown trailer ($extra bytes)\n");
    3448                 $raf->Seek($self->{TIFF_END}, 0) or $err = 1;
    3449                 while ($extra) {
    3450                     my $n = $extra < 65536 ? $extra : 65536;
     5199                $raf->Seek($tiffEnd, 0) or $err = 1;
     5200                # preserve unknown trailer only if it contains non-null data
     5201                # (Photoshop CS adds a trailer with 2 null bytes)
     5202                my $size = $extra;
     5203                for (;;) {
     5204                    my $n = $size > 65536 ? 65536 : $size;
    34515205                    $raf->Read($buf, $n) == $n or $err = 1, last;
    3452                     Write($outfile, $buf) or $err = 1, last;
    3453                     $extra -= $n;
     5206                    if ($buf =~ /[^\0]/) {
     5207                        $self->VPrint(0, "  Preserving unknown trailer ($extra bytes)\n");
     5208                        # copy the trailer since it contains non-null data
     5209                        Write($outfile, "\0"x($extra-$size)) or $err = 1, last if $size != $extra;
     5210                        Write($outfile, $buf) or $err = 1, last;
     5211                        CopyBlock($raf, $outfile, $size-$n) or $err = 1 if $size > $n;
     5212                        last;
     5213                    }
     5214                    $size -= $n;
     5215                    next if $size > 0;
     5216                    $self->VPrint(0, "  Deleting blank trailer ($extra bytes)\n");
     5217                    last;
    34545218                }
    34555219            }
     
    34615225        Write($outfile, $$trailPt) or $err = 1 if $trailPt;
    34625226    }
    3463     delete $self->{TIFF_END};
     5227    # check DNG version
     5228    if ($$self{DNGVersion}) {
     5229        my $ver = $$self{DNGVersion};
     5230        # currently support up to DNG version 1.2
     5231        unless ($ver =~ /^(\d+) (\d+)/ and "$1.$2" <= 1.3) {
     5232            $ver =~ tr/ /./;
     5233            $self->Error("DNG Version $ver not yet supported", 1);
     5234        }
     5235    }
    34645236    return $err ? -1 : 1;
    34655237}
     
    34955267{
    34965268    my $tableName = shift or return undef;
    3497 
    34985269    my $table = $allTables{$tableName};
    34995270
     
    35045275            if ($tableName =~ /(.*)::/) {
    35055276                my $module = $1;
    3506                 unless (eval "require $module") {
     5277                if (eval "require $module") {
     5278                    # load additional XMP modules if required
     5279                    if (not %$tableName and $module eq 'Image::ExifTool::XMP') {
     5280                        require 'Image/ExifTool/XMP2.pl';
     5281                    }
     5282                } else {
    35075283                    $@ and warn $@;
    35085284                }
     
    35165292        $table = \%$tableName;
    35175293        use strict 'refs';
     5294        $$table{TABLE_NAME} = $tableName;   # set table name
     5295        ($$table{SHORT_NAME} = $tableName) =~ s/^Image::ExifTool:://;
    35185296        # set default group 0 and 1 from module name unless already specified
    35195297        my $defaultGroups = $$table{GROUPS};
     
    35295307        }
    35305308        $$defaultGroups{2} = 'Other' unless $$defaultGroups{2};
     5309        if ($$defaultGroups{0} eq 'XMP' or $$table{NAMESPACE}) {
     5310            # initialize some XMP table defaults
     5311            require Image::ExifTool::XMP;
     5312            Image::ExifTool::XMP::RegisterNamespace($table); # register all table namespaces
     5313            # set default write/check procs
     5314            $$table{WRITE_PROC} = \&Image::ExifTool::XMP::WriteXMP unless $$table{WRITE_PROC};
     5315            $$table{CHECK_PROC} = \&Image::ExifTool::XMP::CheckXMP unless $$table{CHECK_PROC};
     5316            $$table{LANG_INFO} = \&Image::ExifTool::XMP::GetLangInfo unless $$table{LANG_INFO};
     5317        }
    35315318        # generate a tag prefix for unknown tags if necessary
    35325319        unless ($$table{TAG_PREFIX}) {
     
    35455332            my $tagID;
    35465333            foreach $tagID (TagTableKeys($UserDefined{$tableName})) {
    3547                 my $tagInfo = $UserDefined{$tableName}->{$tagID};
     5334                my $tagInfo = $UserDefined{$tableName}{$tagID};
    35485335                if (ref $tagInfo eq 'HASH') {
    35495336                    $$tagInfo{Name} or $$tagInfo{Name} = ucfirst($tagID);
     
    35605347            }
    35615348        }
    3562         # generate tag ID's if necessary
    3563         GenerateTagIDs($table) if $didTagID;
    35645349        # remember order we loaded the tables in
    35655350        push @tableOrder, $tableName;
     
    35775362sub ProcessDirectory($$$;$)
    35785363{
    3579     my ($self, $dirInfo, $tagTablePtr, $processProc) = @_;
     5364    my ($self, $dirInfo, $tagTablePtr, $proc) = @_;
    35805365
    35815366    return 0 unless $tagTablePtr and $dirInfo;
    3582     # use default proc from tag table if no proc specified
    3583     $processProc or $processProc = $$tagTablePtr{PROCESS_PROC};
     5367    # use default proc from tag table or EXIF proc as fallback if no proc specified
     5368    $proc or $proc = $$tagTablePtr{PROCESS_PROC} || \&Image::ExifTool::Exif::ProcessExif;
    35845369    # set directory name from default group0 name if not done already
    3585     $$dirInfo{DirName} or $$dirInfo{DirName} = $tagTablePtr->{GROUPS}->{0};
     5370    $$dirInfo{DirName} or $$dirInfo{DirName} = $tagTablePtr->{GROUPS}{0};
    35865371    # guard against cyclical recursion into the same directory
    35875372    if (defined $$dirInfo{DirStart} and defined $$dirInfo{DataPos}) {
    35885373        my $addr = $$dirInfo{DirStart} + $$dirInfo{DataPos} + ($$dirInfo{Base}||0);
    3589         if ($self->{PROCESSED}->{$addr}) {
    3590             $self->Warn("$$dirInfo{DirName} pointer references previous $self->{PROCESSED}->{$addr} directory");
     5374        if ($self->{PROCESSED}{$addr}) {
     5375            $self->Warn("$$dirInfo{DirName} pointer references previous $self->{PROCESSED}{$addr} directory");
    35915376            return 0;
    35925377        }
    3593         $self->{PROCESSED}->{$addr} = $$dirInfo{DirName};
    3594     }
    3595     # otherwise process as an EXIF directory
    3596     $processProc or $processProc = \&Image::ExifTool::Exif::ProcessExif;
     5378        $self->{PROCESSED}{$addr} = $$dirInfo{DirName};
     5379    }
    35975380    my $oldOrder = GetByteOrder();
    35985381    my $oldIndent = $self->{INDENT};
    35995382    my $oldDir = $self->{DIR_NAME};
     5383    $self->{LIST_TAGS} = { };  # don't build lists across different directories
    36005384    $self->{INDENT} .= '| ';
    36015385    $self->{DIR_NAME} = $$dirInfo{DirName};
    3602     my $rtnVal = &$processProc($self, $dirInfo, $tagTablePtr);
     5386    push @{$self->{PATH}}, $$dirInfo{DirName};
     5387
     5388    # process the directory
     5389    my $rtnVal = &$proc($self, $dirInfo, $tagTablePtr);
     5390
     5391    pop @{$self->{PATH}};
    36035392    $self->{INDENT} = $oldIndent;
    36045393    $self->{DIR_NAME} = $oldDir;
     
    36085397
    36095398#------------------------------------------------------------------------------
     5399# Get Metadata path
     5400# Inputs: 0) Exiftool object ref
     5401# Return: Metadata path string
     5402sub MetadataPath($)
     5403{
     5404    my $self = shift;
     5405    return join '-', @{$$self{PATH}}
     5406}
     5407
     5408#------------------------------------------------------------------------------
    36105409# Get standardized file extension
    36115410# Inputs: 0) file name
    3612 # Returns: standardized extension (all uppercase)
     5411# Returns: standardized extension (all uppercase), or undefined if no extension
    36135412sub GetFileExtension($)
    36145413{
     
    36695468            return '' if $condition =~ /\$(valPt|format|count)\b/ and not defined $valPt;
    36705469            # set old value for use in condition if needed
    3671             my $oldVal = $self->{VALUE}->{$$tagInfo{Name}};
    3672             #### eval Condition ($self, $oldVal, [$valPt, $format, $count])
     5470            local $SIG{'__WARN__'} = \&SetWarning;
     5471            undef $evalWarning;
     5472            #### eval Condition ($self, [$valPt, $format, $count])
    36735473            unless (eval $condition) {
    3674                 $@ and warn "Condition $$tagInfo{Name}: $@";
     5474                $@ and $evalWarning = $@;
     5475                $self->Warn("Condition $$tagInfo{Name}: " . CleanWarning()) if $evalWarning;
    36755476                next;
    36765477            }
    36775478        }
    3678         if ($$tagInfo{Unknown} and not $self->{OPTIONS}->{Unknown}) {
     5479        if ($$tagInfo{Unknown} and not $$self{OPTIONS}{Unknown} and not $$self{OPTIONS}{Verbose}) {
    36795480            # don't return Unknown tags unless that option is set
    36805481            return undef;
     
    36845485    }
    36855486    # generate information for unknown tags (numerical only) if required
    3686     if (not $tagInfo and $self->{OPTIONS}->{Unknown} and $tagID =~ /^\d+$/ and
    3687         not $$self{NO_UNKNOWN})
     5487    if (not $tagInfo and ($$self{OPTIONS}{Unknown} or $$self{OPTIONS}{Verbose}) and
     5488        $tagID =~ /^\d+$/ and not $$self{NO_UNKNOWN})
    36885489    {
    36895490        my $printConv;
     
    37145515# Add new tag to table (must use this routine to add new tags to a table)
    37155516# Inputs: 0) reference to tag table, 1) tag ID
    3716 #         2) reference to tag information hash
     5517#         2) [optional] reference to tag information hash
    37175518# Notes: - will not overwrite existing entry in table
    37185519# - info need contain no entries when this routine is called
    3719 sub AddTagToTable($$$)
     5520sub AddTagToTable($$;$)
    37205521{
    37215522    my ($tagTablePtr, $tagID, $tagInfo) = @_;
     5523    $tagInfo or $tagInfo = { };
    37225524
    37235525    # define necessary entries in information hash
     
    37255527        # fill in default groups from table GROUPS
    37265528        foreach (keys %{$$tagTablePtr{GROUPS}}) {
    3727             next if $tagInfo->{Groups}->{$_};
    3728             $tagInfo->{Groups}->{$_} = $tagTablePtr->{GROUPS}->{$_};
     5529            next if $tagInfo->{Groups}{$_};
     5530            $tagInfo->{Groups}{$_} = $tagTablePtr->{GROUPS}{$_};
    37295531        }
    37305532    } else {
    3731         $$tagInfo{Groups} = $$tagTablePtr{GROUPS};
     5533        $$tagInfo{Groups} = { %{$$tagTablePtr{GROUPS}} };
    37325534    }
    37335535    $$tagInfo{Flags} and ExpandFlags($tagInfo);
     
    37365538    $$tagInfo{TagID} = $tagID;
    37375539
    3738     unless ($$tagInfo{Name}) {
     5540    my $name = $$tagInfo{Name};
     5541    if (defined $name) {
     5542        $name =~ tr/-_a-zA-Z0-9//dc;    # remove illegal characters
     5543    } else {
     5544        # construct a name from the tag ID
     5545        $name = $tagID;
     5546        $name =~ tr/-_a-zA-Z0-9//dc;    # remove illegal characters
     5547        $name = ucfirst $name;          # start with uppercase
     5548        # make sure name is a reasonable length
    37395549        my $prefix = $$tagTablePtr{TAG_PREFIX};
    3740         $$tagInfo{Name} = "${prefix}_$tagID";
    3741         # make description to prevent tagID from getting mangled by MakeDescription()
    3742         $$tagInfo{Description} = MakeDescription($prefix, $tagID);
    3743     }
     5550        if ($prefix) {
     5551            # make description to prevent tagID from getting mangled by MakeDescription()
     5552            $$tagInfo{Description} = MakeDescription($prefix, $name);
     5553            $name = "${prefix}_$name";
     5554        }
     5555    }
     5556    # tag names must be at least 2 characters long and begin with a letter
     5557    $name = "Tag$name" if length($name) <= 1 or $name !~ /^[A-Z]/i;
     5558    $$tagInfo{Name} = $name;
    37445559    # add tag to table, but never overwrite existing entries (could potentially happen
    37455560    # if someone thinks there isn't any tagInfo because a condition wasn't satisfied)
     
    37515566# Inputs: 0) ExifTool object ref, 1) tag table reference, 2) tagID, 3) value,
    37525567#         4-N) parameters hash: Index, DataPt, DataPos, Start, Size, Parent,
    3753 #              TagInfo, ProcessProc
     5568#              TagInfo, ProcessProc, RAF
    37545569# Returns: tag key or undef if tag not found
     5570# Notes: if value is not defined, it is extracted from DataPt using TagInfo
     5571#        Format and Count if provided
    37555572sub HandleTag($$$$;%)
    37565573{
    37575574    my ($self, $tagTablePtr, $tag, $val, %parms) = @_;
    3758     my $verbose = $self->{OPTIONS}->{Verbose};
    3759     my $tagInfo = $parms{TagInfo} || $self->GetTagInfo($tagTablePtr, $tag);
     5575    my $verbose = $self->{OPTIONS}{Verbose};
     5576    my $tagInfo = $parms{TagInfo} || $self->GetTagInfo($tagTablePtr, $tag, \$val);
    37605577    my $dataPt = $parms{DataPt};
    3761     my $subdir;
     5578    my ($subdir, $format, $count, $size, $noTagInfo);
    37625579
    37635580    if ($tagInfo) {
     
    37655582    } else {
    37665583        return undef unless $verbose;
     5584        $tagInfo = { Name => "tag $tag" };  # create temporary tagInfo hash
     5585        $noTagInfo = 1;
    37675586    }
    37685587    # read value if not done already (not necessary for subdir)
    3769     unless (defined $val or $subdir) {
     5588    unless (defined $val or ($subdir and not $$tagInfo{Writable})) {
    37705589        my $start = $parms{Start} || 0;
    37715590        my $size = $parms{Size} || 0;
    37725591        # read from data in memory if possible
    37735592        if ($dataPt and $start >= 0 and $start + $size <= length($$dataPt)) {
    3774             $val = substr($$dataPt, $start, $size);
     5593            $format = $$tagInfo{Format} || $$tagTablePtr{FORMAT};
     5594            if ($format) {
     5595                $val = ReadValue($dataPt, $start, $format, $$tagInfo{Count}, $size);
     5596            } else {
     5597                $val = substr($$dataPt, $start, $size);
     5598            }
    37755599        } else {
    3776             my $name = $tagInfo ? $$tagInfo{Name} : "tag $tag";
    3777             $self->Warn("Error extracting value for $name");
     5600            $self->Warn("Error extracting value for $$tagInfo{Name}");
    37785601            return undef;
    37795602        }
     
    37815604    # do verbose print if necessary
    37825605    if ($verbose) {
     5606        undef $tagInfo if $noTagInfo;
    37835607        $parms{Value} = $val;
    37845608        $parms{Table} = $tagTablePtr;
     5609        if ($format) {
     5610            $count or $count = int(($parms{Size} || 0) / ($formatSize{$format} || 1));
     5611            $parms{Format} = $format . "[$count]";
     5612        }
    37855613        $self->VerboseInfo($tag, $tagInfo, %parms);
    37865614    }
    37875615    if ($tagInfo) {
    37885616        if ($subdir) {
     5617            my $subdirStart = $parms{Start};
     5618            my $subdirLen = $parms{Size};
     5619            if ($$subdir{Start}) {
     5620                my $valuePtr = 0;
     5621                #### eval Start ($valuePtr)
     5622                my $off = eval $$subdir{Start};               
     5623                $subdirStart += $off;
     5624                $subdirLen -= $off;
     5625            }
    37895626            $dataPt or $dataPt = \$val;
    37905627            # process subdirectory information
    37915628            my %dirInfo = (
    3792                 DirName  => $$tagInfo{Name},
     5629                DirName  => $$subdir{DirName} || $$tagInfo{Name},
    37935630                DataPt   => $dataPt,
    37945631                DataLen  => length $$dataPt,
    37955632                DataPos  => $parms{DataPos},
    3796                 DirStart => $parms{Start},
    3797                 DirLen   => $parms{Size},
     5633                DirStart => $subdirStart,
     5634                DirLen   => $subdirLen,
    37985635                Parent   => $parms{Parent},
     5636                Base     => $parms{Base},
     5637                Multi    => $$subdir{Multi},
     5638                TagInfo  => $tagInfo,
     5639                RAF      => $parms{RAF},
    37995640            );
     5641            my $oldOrder = GetByteOrder();
     5642            SetByteOrder($$subdir{ByteOrder}) if $$subdir{ByteOrder};
    38005643            my $subTablePtr = GetTagTable($$subdir{TagTable}) || $tagTablePtr;
    3801             $self->ProcessDirectory(\%dirInfo, $subTablePtr, $$subdir{ProcessProc});
    3802         } else {
    3803             return $self->FoundTag($tagInfo, $val);
    3804         }
     5644            $self->ProcessDirectory(\%dirInfo, $subTablePtr, $$subdir{ProcessProc} || $parms{ProcessProc});
     5645            SetByteOrder($oldOrder);
     5646            # return now unless directory is writable as a block
     5647            return undef unless $$tagInfo{Writable};
     5648        }
     5649        return $self->FoundTag($tagInfo, $val);
    38055650    }
    38065651    return undef;
     
    38095654#------------------------------------------------------------------------------
    38105655# Add tag to hash of extracted information
    3811 # Inputs: 0) reference to ExifTool object
     5656# Inputs: 0) ExifTool object reference
    38125657#         1) reference to tagInfo hash or tag name
    3813 #         2) data value (or reference to require hash if composite)
     5658#         2) data value (or reference to require hash if Composite)
    38145659# Returns: tag key or undef if no value
    38155660sub FoundTag($$$)
     
    38285673        # (not advised to do this since the tag won't show in list)
    38295674        $tagInfo or $tagInfo = { Name => $tag, Groups => \%allGroupsExifTool };
    3830         $self->{OPTIONS}->{Verbose} and $self->VerboseInfo(undef, $tagInfo, Value => $value);
     5675        $self->{OPTIONS}{Verbose} and $self->VerboseInfo(undef, $tagInfo, Value => $value);
    38315676    }
    38325677    my $rawValueHash = $self->{VALUE};
    38335678    if ($$tagInfo{RawConv}) {
    3834         my $conv = $$tagInfo{RawConv};
    3835         my $val = $value;   # must do this in case eval references $val
    38365679        # initialize @val for use in Composite RawConv expressions
    38375680        my @val;
    3838         if (ref $val eq 'HASH') {
    3839             foreach (keys %$val) { $val[$_] = $$rawValueHash{$$val{$_}}; }
    3840         }
     5681        if (ref $value eq 'HASH') {
     5682            foreach (keys %$value) { $val[$_] = $$rawValueHash{$$value{$_}}; }
     5683        }
     5684        my $conv = $$tagInfo{RawConv};
     5685        local $SIG{'__WARN__'} = \&SetWarning;
     5686        undef $evalWarning;
    38415687        if (ref $conv eq 'CODE') {
    3842             $value = &$conv($val, $self);
     5688            $value = &$conv($value, $self);
    38435689        } else {
    3844             #### eval RawConv ($self, $val)
     5690            my $val = $value;   # must do this in case eval references $val
     5691            # NOTE: RawConv is also evaluated in Writer.pl
     5692            #### eval RawConv ($self, $val, $tag, $tagInfo)
    38455693            $value = eval $conv;
    3846             $@ and warn "RawConv: $@\n";
    3847         }
     5694            $@ and $evalWarning = $@;
     5695        }
     5696        $self->Warn("RawConv $tag: " . CleanWarning()) if $evalWarning;
    38485697        return undef unless defined $value;
    38495698    }
    38505699    # get tag priority
    38515700    my $priority = $$tagInfo{Priority};
    3852     defined $priority or $priority = $tagInfo->{Table}->{PRIORITY};
     5701    defined $priority or $priority = $tagInfo->{Table}{PRIORITY};
    38535702    # handle duplicate tag names
    3854     if (defined $rawValueHash->{$tag}) {
    3855         if ($$tagInfo{List} and $tagInfo eq $self->{TAG_INFO}->{$tag} and
    3856             not $self->{NO_LIST})
    3857         {
    3858             # use a list reference for multiple values
    3859             if (ref $rawValueHash->{$tag} ne 'ARRAY') {
    3860                 $rawValueHash->{$tag} = [ $rawValueHash->{$tag} ];
    3861             }
    3862             push @{$rawValueHash->{$tag}}, $value;
     5703    if (defined $$rawValueHash{$tag}) {
     5704        # add to list if there is an active list for this tag
     5705        if ($self->{LIST_TAGS}{$tagInfo}) {
     5706            $tag = $self->{LIST_TAGS}{$tagInfo};  # use key from previous list tag
     5707            if (ref $$rawValueHash{$tag} ne 'ARRAY') {
     5708                $$rawValueHash{$tag} = [ $$rawValueHash{$tag} ];
     5709            }
     5710            push @{$$rawValueHash{$tag}}, $value;
    38635711            return $tag;    # return without creating a new entry
    38645712        }
    38655713        # get next available tag key
    3866         my $nextTag = NextTagKey($rawValueHash, $tag);
     5714        my $nextInd = $self->{DUPL_TAG}{$tag} = ($self->{DUPL_TAG}{$tag} || 0) + 1;
     5715        my $nextTag = "$tag ($nextInd)";
    38675716#
    38685717# take tag with highest priority
    38695718#
    38705719        # promote existing 0-priority tag so it takes precedence over a new 0-tag
    3871         my $oldPriority = $self->{PRIORITY}->{$tag} || 1;
    3872         # set priority for this tag (default is 1)
    3873         $priority = 1 if not defined $priority or
     5720        # (unless old tag was a sub-document and new tag isn't)
     5721        my $oldPriority = $self->{PRIORITY}{$tag};
     5722        unless ($oldPriority) {
     5723            if ($self->{DOC_NUM} or not $self->{TAG_EXTRA}{$tag} or
     5724                                    not $self->{TAG_EXTRA}{$tag}{G3})
     5725            {
     5726                $oldPriority = 1;
     5727            } else {
     5728                $oldPriority = 0; # don't promote sub-document tag over main document
     5729            }
     5730        }
     5731        # set priority for this tag
     5732        if (defined $priority) {
    38745733            # increase 0-priority tags if this is the priority directory
    3875             ($priority == 0 and $self->{DIR_NAME} and $self->{PRIORITY_DIR} and
    3876             $self->{DIR_NAME} eq $self->{PRIORITY_DIR});
    3877         if ($priority >= $oldPriority) {
     5734            $priority = 1 if not $priority and $$self{DIR_NAME} and
     5735                             $$self{DIR_NAME} eq $$self{PRIORITY_DIR};
     5736        } elsif ($$self{DIR_NAME} and $$self{LOW_PRIORITY_DIR}{$$self{DIR_NAME}}) {
     5737            $priority = 0;  # default is 0 for a LOW_PRIORITY_DIR
     5738        } else {
     5739            $priority = 1;  # the normal default
     5740        }
     5741        if ($priority >= $oldPriority and not $self->{DOC_NUM}) {
     5742            # move existing tag out of the way since this tag is higher priority
    38785743            $self->{MOVED_KEY} = $nextTag;  # used in BuildCompositeTags()
    3879             $self->{PRIORITY}->{$nextTag} = $self->{PRIORITY}->{$tag};
    3880             $rawValueHash->{$nextTag} = $rawValueHash->{$tag};
    3881             $self->{FILE_ORDER}->{$nextTag} = $self->{FILE_ORDER}->{$tag};
    3882             $self->{TAG_INFO}->{$nextTag} = $self->{TAG_INFO}->{$tag};
    3883             if ($self->{GROUP1}->{$tag}) {
    3884                 $self->{GROUP1}->{$nextTag} = $self->{GROUP1}->{$tag};
    3885                 delete $self->{GROUP1}->{$tag};
    3886             }
     5744            $self->{PRIORITY}{$nextTag} = $self->{PRIORITY}{$tag};
     5745            $$rawValueHash{$nextTag} = $$rawValueHash{$tag};
     5746            $self->{FILE_ORDER}{$nextTag} = $self->{FILE_ORDER}{$tag};
     5747            my $oldInfo = $self->{TAG_INFO}{$nextTag} = $self->{TAG_INFO}{$tag};
     5748            if ($self->{TAG_EXTRA}{$tag}) {
     5749                $self->{TAG_EXTRA}{$nextTag} = $self->{TAG_EXTRA}{$tag};
     5750                delete $self->{TAG_EXTRA}{$tag};
     5751            }
     5752            # update tag key for list if necessary
     5753            $self->{LIST_TAGS}{$oldInfo} = $nextTag if $self->{LIST_TAGS}{$oldInfo};
    38875754        } else {
    38885755            $tag = $nextTag;        # don't override the existing tag
    38895756        }
    3890         $self->{PRIORITY}->{$tag} = $priority;
     5757        $self->{PRIORITY}{$tag} = $priority;
    38915758    } elsif ($priority) {
    38925759        # set tag priority (only if exists and non-zero)
    3893         $self->{PRIORITY}->{$tag} = $priority;
    3894     }
    3895 
    3896     # save the raw value, file order, tagInfo ref and group1 name if necessary
    3897     $rawValueHash->{$tag} = $value;
    3898     $self->{FILE_ORDER}->{$tag} = ++$self->{NUM_FOUND};
    3899     $self->{TAG_INFO}->{$tag} = $tagInfo;
    3900     $self->{GROUP1}->{$tag} = $self->{SET_GROUP1} if $self->{SET_GROUP1};
     5760        $self->{PRIORITY}{$tag} = $priority;
     5761    }
     5762
     5763    # save the raw value, file order, tagInfo ref, group1 name,
     5764    # and tag key for lists if necessary
     5765    $$rawValueHash{$tag} = $value;
     5766    $self->{FILE_ORDER}{$tag} = ++$self->{NUM_FOUND};
     5767    $self->{TAG_INFO}{$tag} = $tagInfo;
     5768    # set dynamic groups 1 and 3 if necessary
     5769    $self->{TAG_EXTRA}{$tag}{G1} = $self->{SET_GROUP1} if $self->{SET_GROUP1};
     5770    if ($self->{DOC_NUM}) {
     5771        $self->{TAG_EXTRA}{$tag}{G3} = $self->{DOC_NUM};
     5772        if ($self->{DOC_NUM} =~ /^(\d+)/) {
     5773            # keep track of maximum 1st-level sub-document number
     5774            $self->{DOC_COUNT} = $1 unless $self->{DOC_COUNT} >= $1;
     5775        }
     5776    }
     5777    # save path if requested
     5778    $self->{TAG_EXTRA}{$tag}{G5} = $self->MetadataPath() if $self->{OPTIONS}{SavePath};
     5779
     5780    # remember this tagInfo if we will be accumulating values in a list
     5781    $self->{LIST_TAGS}{$tagInfo} = $tag if $$tagInfo{List} and not $$self{NO_LIST};
    39015782
    39025783    return $tag;
     
    39045785
    39055786#------------------------------------------------------------------------------
    3906 # Get next available tag key
    3907 # Inputs: 0) hash reference (keys are tag keys), 1) tag name
    3908 # Returns: next available tag key
    3909 sub NextTagKey($$)
    3910 {
    3911     my ($info, $tag) = @_;
    3912     if (exists $$info{$tag}) {
    3913         my $name = $tag;
    3914         my $i;
    3915         for ($i=1; ; ++$i) {
    3916             $tag = "$name ($i)";
    3917             last unless exists $$info{$tag};
    3918         }
    3919     }
    3920     return $tag;
    3921 }
    3922 
    3923 #------------------------------------------------------------------------------
    39245787# Make current directory the priority directory if not set already
    3925 # Inputs: 0) reference to ExifTool object
     5788# Inputs: 0) ExifTool object reference
    39265789sub SetPriorityDir($)
    39275790{
     
    39315794
    39325795#------------------------------------------------------------------------------
    3933 # Set family 1 group name specific to this tag instance
    3934 # Inputs: 0) reference to ExifTool object, 1) tag key, 2) group name
    3935 sub SetGroup1($$$)
    3936 {
    3937     my ($self, $tagKey, $extra) = @_;
    3938     $self->{GROUP1}->{$tagKey} = $extra;
    3939 }
    3940 
    3941 #------------------------------------------------------------------------------
    3942 # Set ID's for all tags in specified table
    3943 # Inputs: 0) tag table reference
    3944 sub GenerateTagIDs($)
    3945 {
    3946     my $table = shift;
    3947 
    3948     unless ($$table{DID_TAG_ID}) {
    3949         $$table{DID_TAG_ID} = 1;    # set flag so we won't do this table again
    3950         my ($tagID, $tagInfo);
    3951         foreach $tagID (keys %$table) {
    3952             next if $specialTags{$tagID};
    3953             # define tag ID in each element of conditional array
    3954             my @infoArray = GetTagInfoList($table,$tagID);
    3955             foreach $tagInfo (@infoArray) {
    3956                 # define tag ID's in info hash
    3957                 $$tagInfo{TagID} = $tagID;
    3958             }
    3959         }
    3960     }
    3961 }
    3962 
    3963 #------------------------------------------------------------------------------
    3964 # Generate TagID's for all loaded tables
    3965 # Inputs: None
    3966 # Notes: Causes subsequently loaded tables to automatically generate TagID's too
    3967 sub GenerateAllTagIDs()
    3968 {
    3969     unless ($didTagID) {
    3970         my $tableName;
    3971         foreach $tableName (keys %allTables) {
    3972             # generate tag ID's for all tags in this table
    3973             GenerateTagIDs($allTables{$tableName});
    3974         }
    3975         $didTagID = 1;
    3976     }
     5796# Set family 0 or 1 group name specific to this tag instance
     5797# Inputs: 0) ExifTool ref, 1) tag key, 2) group name, 3) family (default 1)
     5798sub SetGroup($$$;$)
     5799{
     5800    my ($self, $tagKey, $extra, $fam) = @_;
     5801    $self->{TAG_EXTRA}{$tagKey}{defined $fam ? "G$fam" : 'G1'} = $extra;
    39775802}
    39785803
    39795804#------------------------------------------------------------------------------
    39805805# Delete specified tag
    3981 # Inputs: 0) reference to ExifTool object
    3982 #         1) tag key
     5806# Inputs: 0) ExifTool object ref, 1) tag key
    39835807sub DeleteTag($$)
    39845808{
    39855809    my ($self, $tag) = @_;
    3986     delete $self->{VALUE}->{$tag};
    3987     delete $self->{FILE_ORDER}->{$tag};
    3988     delete $self->{TAG_INFO}->{$tag};
    3989     delete $self->{GROUP1}->{$tag};
     5810    delete $self->{VALUE}{$tag};
     5811    delete $self->{FILE_ORDER}{$tag};
     5812    delete $self->{TAG_INFO}{$tag};
     5813    delete $self->{TAG_EXTRA}{$tag};
     5814}
     5815
     5816#------------------------------------------------------------------------------
     5817# Escape all elements of a value
     5818# Inputs: 0) value, 1) escape proc
     5819sub DoEscape($$)
     5820{
     5821    my ($val, $key);
     5822    if (not ref $_[0]) {
     5823        $_[0] = &{$_[1]}($_[0]);
     5824    } elsif (ref $_[0] eq 'ARRAY') {
     5825        foreach $val (@{$_[0]}) {
     5826            DoEscape($val, $_[1]);
     5827        }
     5828    } elsif (ref $_[0] eq 'HASH') {
     5829        foreach $key (keys %{$_[0]}) {
     5830            DoEscape($_[0]{$key}, $_[1]);
     5831        }
     5832    }
    39905833}
    39915834
     
    39945837# Inputs: 0) ExifTool object reference
    39955838#         1) Optional file type (uses FILE_TYPE if not specified)
    3996 sub SetFileType($;$)
    3997 {
    3998     my $self = shift;
    3999     my $baseType = $self->{FILE_TYPE};
    4000     my $fileType = shift || $baseType;
    4001     my $mimeType = $mimeType{$fileType};
    4002     # use base file type if necessary (except if 'TIFF', which is a special case)
    4003     $mimeType = $mimeType{$baseType} unless $mimeType or $baseType eq 'TIFF';
    4004     $self->FoundTag('FileType', $fileType);
    4005     $self->FoundTag('MIMEType', $mimeType || 'application/unknown');
     5839#         2) Optional MIME type (uses our lookup if not specified)
     5840# Notes:  Will NOT set file type twice (subsequent calls ignored)
     5841sub SetFileType($;$$)
     5842{
     5843    my ($self, $fileType, $mimeType) = @_;
     5844    unless ($self->{VALUE}{FileType}) {
     5845        my $baseType = $self->{FILE_TYPE};
     5846        $fileType or $fileType = $baseType;
     5847        $mimeType or $mimeType = $mimeType{$fileType};
     5848        # use base file type if necessary (except if 'TIFF', which is a special case)
     5849        $mimeType = $mimeType{$baseType} unless $mimeType or $baseType eq 'TIFF';
     5850        $self->FoundTag('FileType', $fileType);
     5851        $self->FoundTag('MIMEType', $mimeType || 'application/unknown');
     5852    }
     5853}
     5854
     5855#------------------------------------------------------------------------------
     5856# Override the FileType and MIMEType tags
     5857# Inputs: 0) ExifTool object ref, 1) file type
     5858# Notes:  does nothing if FileType was not previously defined (ie. when writing)
     5859sub OverrideFileType($$)
     5860{
     5861    my ($self, $fileType) = @_;
     5862    if (defined $$self{VALUE}{FileType} and $fileType ne $$self{VALUE}{FileType}) {
     5863        $$self{VALUE}{FileType} = $fileType;
     5864        $$self{VALUE}{MIMEType} = $mimeType{$fileType} || 'application/unknown';
     5865        if ($$self{OPTIONS}{Verbose}) {
     5866            $self->VPrint(0,"$$self{INDENT}FileType [override] = $fileType\n");
     5867            $self->VPrint(0,"$$self{INDENT}MIMEType [override] = $$self{VALUE}{MIMEType}\n");
     5868        }
     5869    }
    40065870}
    40075871
     
    40145878    my ($self, $mime) = @_;
    40155879    $mime =~ m{/} or $mime = $mimeType{$mime} or return;
    4016     my $old = $self->{VALUE}->{MIMEType};
     5880    my $old = $self->{VALUE}{MIMEType};
    40175881    if (defined $old) {
    40185882        my ($a, $b) = split '/', $old;
    40195883        my ($c, $d) = split '/', $mime;
    40205884        $d =~ s/^x-//;
    4021         $self->{VALUE}->{MIMEType} = "$c/$b-$d";
     5885        $self->{VALUE}{MIMEType} = "$c/$b-$d";
    40225886        $self->VPrint(0, "  Modified MIMEType = $c/$b-$d\n");
    40235887    } else {
     
    40335897    my $self = shift;
    40345898    my $level = shift;
    4035     if ($self->{OPTIONS}->{Verbose} and $self->{OPTIONS}->{Verbose} > $level) {
    4036         my $out = $self->{OPTIONS}->{TextOut};
     5899    if ($self->{OPTIONS}{Verbose} and $self->{OPTIONS}{Verbose} > $level) {
     5900        my $out = $self->{OPTIONS}{TextOut};
    40375901        print $out @_;
    40385902    }
     
    40465910    my $self = shift;
    40475911    my $dataPt = shift;
    4048     if ($self->{OPTIONS}->{Verbose} and $self->{OPTIONS}->{Verbose} > 2) {
    4049         HexDump($dataPt, undef,
    4050             Out => $self->{OPTIONS}->{TextOut},
    4051             MaxLen => $self->{OPTIONS}->{Verbose} < 4 ? 96 : undef,
    4052             @_
     5912    if ($self->{OPTIONS}{Verbose} and $self->{OPTIONS}{Verbose} > 2) {
     5913        my %parms = (
     5914            Prefix => $self->{INDENT},
     5915            Out    => $self->{OPTIONS}{TextOut},
     5916            MaxLen => $self->{OPTIONS}{Verbose} < 4 ? 96 : undef,
    40535917        );
     5918        HexDump($dataPt, undef, %parms, @_);
    40545919    }
    40555920}
     
    40645929{
    40655930    my ($self, $offset, $length, $tag) = @_;
    4066 
    4067     if ($tag and not $self->{OPTIONS}->{Binary} and
    4068         not $self->{REQ_TAG_LOOKUP}->{lc($tag)})
     5931    my ($isPreview, $buff);
     5932
     5933    if ($tag and $tag eq 'PreviewImage') {
     5934        # save PreviewImage start/length in case we want to dump trailer
     5935        $$self{PreviewImageStart} = $offset;
     5936        $$self{PreviewImageLength} = $length;
     5937        $isPreview = 1;
     5938    }
     5939    if ($tag and not $self->{OPTIONS}{Binary} and not $self->{OPTIONS}{Verbose} and
     5940        not $self->{REQ_TAG_LOOKUP}{lc($tag)})
    40695941    {
    40705942        return "Binary data $length bytes";
    40715943    }
    4072     my $buff;
    40735944    unless ($self->{RAF}->Seek($offset,0)
    40745945        and $self->{RAF}->Read($buff, $length) == $length)
    40755946    {
    40765947        $tag or $tag = 'binary data';
    4077         $self->Warn("Error reading $tag from file");
     5948        if ($isPreview and not $$self{BuildingComposite}) {
     5949            $$self{PreviewError} = 1;
     5950        } else {
     5951            $self->Warn("Error reading $tag from file", $isPreview);
     5952        }
    40785953        return undef;
    40795954    }
     
    40835958#------------------------------------------------------------------------------
    40845959# Process binary data
    4085 # Inputs: 0) ExifTool object reference, 1) directory information reference
    4086 #         2) tag table reference
     5960# Inputs: 0) ExifTool object ref, 1) directory information ref, 2) tag table ref
    40875961# Returns: 1 on success
     5962# Notes: dirInfo may contain VarFormatData (reference to empty list) to return
     5963#        details about any variable-length-format tags in the table (used when writing)
    40885964sub ProcessBinaryData($$$)
    40895965{
     
    40935969    my $size = $$dirInfo{DirLen} || (length($$dataPt) - $offset);
    40945970    my $base = $$dirInfo{Base} || 0;
    4095     my $verbose = $self->{OPTIONS}->{Verbose};
    4096     my $unknown = $self->{OPTIONS}->{Unknown};
    4097     my $dataPos;
     5971    my $verbose = $self->{OPTIONS}{Verbose};
     5972    my $unknown = $self->{OPTIONS}{Unknown};
     5973    my $dataPos = $$dirInfo{DataPos} || 0;
    40985974
    40995975    # get default format ('int8u' unless specified)
     
    41105986        # scan through entire binary table
    41115987        @tags = ($$tagTablePtr{FIRST_ENTRY}..(int($size/$increment) - 1));
     5988        # add in floating point tag ID's if they exist
     5989        my @ftags = grep /\./, TagTableKeys($tagTablePtr);
     5990        @tags = sort { $a <=> $b } @tags, @ftags if @ftags;
    41125991    } elsif ($$dirInfo{DataMember}) {
    41135992        @tags = @{$$dirInfo{DataMember}};
     
    41175996        @tags = sort { $a <=> $b } TagTableKeys($tagTablePtr);
    41185997    }
    4119     if ($verbose) {
    4120         $self->VerboseDir('BinaryData', undef, $size);
    4121         $dataPos = $$dirInfo{DataPos} || 0;
    4122     }
    4123     my $index;
     5998    $self->VerboseDir('BinaryData', undef, $size) if $verbose;
     5999    # avoid creating unknown tags for tags that fail condition if Unknown is 1
     6000    $$self{NO_UNKNOWN} = 1 if $unknown < 2;
     6001    my ($index, %val);
    41246002    my $nextIndex = 0;
    4125     my %val;
     6003    my $varSize = 0;
    41266004    foreach $index (@tags) {
    4127         my $tagInfo;
     6005        my ($tagInfo, $val, $saveNextIndex, $len, $mask, $wasVar);
    41286006        if ($$tagTablePtr{$index}) {
    4129             $tagInfo = $self->GetTagInfo($tagTablePtr, $index) or next;
     6007            $tagInfo = $self->GetTagInfo($tagTablePtr, $index);
     6008            unless ($tagInfo) {
     6009                next unless defined $tagInfo;
     6010                my $entry = int($index) * $increment + $varSize;
     6011                next if $entry >= $size;
     6012                my $more = $size - $entry;
     6013                $more = 128 if $more > 128;
     6014                my $v = substr($$dataPt, $entry+$offset, $more);
     6015                $tagInfo = $self->GetTagInfo($tagTablePtr, $index, \$v);
     6016                next unless $tagInfo;
     6017            }
    41306018            next if $$tagInfo{Unknown} and
    41316019                   ($$tagInfo{Unknown} > $unknown or $index < $nextIndex);
     
    41376025            $$tagInfo{Unknown} = 2;    # set unknown to 2 for binary unknowns
    41386026        }
     6027        # get relative offset of this entry
     6028        my $entry = int($index) * $increment + $varSize;
     6029        my $more = $size - $entry;
     6030        last if $more <= 0;     # all done if we have reached the end of data
    41396031        my $count = 1;
    41406032        my $format = $$tagInfo{Format};
    4141         my $entry = $index * $increment;        # relative offset of this entry
    4142         if ($format) {
     6033        if (not $format) {
     6034            $format = $defaultFormat;
     6035        } elsif ($format eq 'string') {
     6036            # string with no specified count runs to end of block
     6037            $count = $more;
     6038        } elsif ($format eq 'pstring') {
     6039            $format = 'string';
     6040            $count = Get8u($dataPt, ($entry++)+$offset);
     6041            --$more;
     6042        } elsif (not $formatSize{$format}) {
    41436043            if ($format =~ /(.*)\[(.*)\]/) {
     6044                # handle format count field
    41446045                $format = $1;
    41456046                $count = $2;
    41466047                # evaluate count to allow count to be based on previous values
    4147                 #### eval Format (%val, $size)
     6048                #### eval Format size (%val, $size, $self)
    41486049                $count = eval $count;
    41496050                $@ and warn("Format $$tagInfo{Name}: $@"), next;
    41506051                next if $count < 0;
    4151             } elsif ($format eq 'string') {
    4152                 # allow string with no specified count to run to end of block
    4153                 $count = ($size > $entry) ? $size - $entry : 0;
    4154             }
    4155         } else {
    4156             $format = $defaultFormat;
     6052                # allow a variable-length of any format type (with base $count = 1)
     6053                if ($format =~ s/^var_//) {
     6054                    $varSize += ($count - 1) * ($formatSize{$format} || 1);
     6055                    # save variable size data if required for writing
     6056                    if ($$dirInfo{VarFormatData}) {
     6057                        push @{$$dirInfo{VarFormatData}}, $index, $varSize;
     6058                    }
     6059                }
     6060            } elsif ($format =~ /^var_/) {
     6061                # handle variable-length string formats
     6062                $format = substr($format, 4);
     6063                pos($$dataPt) = $entry + $offset;
     6064                undef $count;
     6065                if ($format eq 'ustring') {
     6066                    $count = pos($$dataPt) - ($entry+$offset) if $$dataPt =~ /\G(..)*?\0\0/sg;
     6067                    $varSize -= 2;  # ($count includes base size of 2 bytes)
     6068                } elsif ($format eq 'pstring') {
     6069                    $count = Get8u($dataPt, ($entry++)+$offset);
     6070                    --$more;
     6071                } elsif ($format eq 'pstr32') {
     6072                    last if $more < 4;
     6073                    $count = Get32u($dataPt, $entry + $offset);
     6074                    $entry += 4;
     6075                    $more -= 4;
     6076                } elsif ($format eq 'int16u') {
     6077                    # int16u size of binary data to follow
     6078                    last if $more < 2;
     6079                    $count = Get16u($dataPt, $entry + $offset) + 2;
     6080                    $varSize -= 2;  # ($count includes size word)
     6081                    $format = 'undef';
     6082                } elsif ($$dataPt =~ /\0/g) {
     6083                    $count = pos($$dataPt) - ($entry+$offset);
     6084                    --$varSize;     # ($count includes base size of 1 byte)
     6085                }
     6086                $count = $more if not defined $count or $count > $more;
     6087                $varSize += $count; # shift subsequent indices
     6088                $val = substr($$dataPt, $entry+$offset, $count);
     6089                $val = $self->Decode($val, 'UCS2') if $format eq 'ustring';
     6090                $val =~ s/\0.*//s unless $format eq 'undef';  # truncate at null
     6091                $wasVar = 1;
     6092                # save variable size data if required for writing
     6093                if ($$dirInfo{VarFormatData}) {
     6094                    push @{$$dirInfo{VarFormatData}}, $index, $varSize;
     6095                }
     6096            }
     6097        }
     6098        # hook to allow format, etc to be set dynamically
     6099        if (defined $$tagInfo{Hook}) {
     6100            #### eval Hook ($format, $varSize)
     6101            eval $$tagInfo{Hook};
     6102            # save variable size data if required for writing (in case changed by Hook)
     6103            if ($$dirInfo{VarFormatData}) {
     6104                $#{$$dirInfo{VarFormatData}} -= 2 if $wasVar; # remove previous entries for this tag
     6105                push @{$$dirInfo{VarFormatData}}, $index, $varSize;
     6106            }
    41576107        }
    41586108        if ($unknown > 1) {
    41596109            # calculate next valid index for unknown tag
    4160             my $ni = $index + ($formatSize{$format} * $count) / $increment;
     6110            my $ni = int $index;
     6111            $ni += (($formatSize{$format} || 1) * $count) / $increment unless $wasVar;
     6112            $saveNextIndex = $nextIndex;
    41616113            $nextIndex = $ni unless $nextIndex > $ni;
    41626114        }
    4163         my $val = ReadValue($dataPt, $entry+$offset, $format, $count, $size-$entry);
    4164         next unless defined $val;
    4165         if ($verbose) {
    4166             my $len = $count * ($formatSize{$format} || 1);
    4167             $len > $size - $entry and $len = $size - $entry;
     6115        # read value now if necessary
     6116        unless (defined $val and not $$tagInfo{SubDirectory}) {
     6117            $val = ReadValue($dataPt, $entry+$offset, $format, $count, $more);
     6118            $mask = $$tagInfo{Mask};
     6119            $val &= $mask if $mask;
     6120        }
     6121        if ($verbose and not $$tagInfo{Hidden}) {
     6122            if (not $$tagInfo{SubDirectory} or $$tagInfo{Format}) {
     6123                $len = $count * ($formatSize{$format} || 1);
     6124                $len = $more if $len > $more;
     6125            } else {
     6126                $len = $more;
     6127            }
    41686128            $self->VerboseInfo($index, $tagInfo,
    41696129                Table  => $tagTablePtr,
     
    41756135                Format => $format,
    41766136                Count  => $count,
     6137                Extra  => $mask ? sprintf(', mask 0x%.2x',$mask) : undef,
    41776138            );
    41786139        }
    4179         $val += $base + $$self{BASE} if $$tagInfo{IsOffset};
     6140        # parse nested BinaryData directories
     6141        if ($$tagInfo{SubDirectory}) {
     6142            my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}{TagTable});
     6143            # use specified subdirectory length if given
     6144            if ($$tagInfo{Format} and $formatSize{$format}) {
     6145                $len = $count * $formatSize{$format};
     6146                $len = $more if $len > $more;
     6147            } else {
     6148                $len = $more;
     6149                if ($$subTablePtr{PROCESS_PROC} and
     6150                    $$subTablePtr{PROCESS_PROC} eq \&ProcessBinaryData)
     6151                {
     6152                    # the rest of the data will be printed in the subdirectory
     6153                    $nextIndex = $size / $increment;
     6154                }
     6155            }
     6156            my %subdirInfo = (
     6157                DataPt   => $dataPt,
     6158                DataPos  => $dataPos,
     6159                DirStart => $entry + $offset,
     6160                DirLen   => $len,
     6161                Base     => $base,
     6162            );
     6163            $self->ProcessDirectory(\%subdirInfo, $subTablePtr);
     6164            next;
     6165        }
     6166        if ($$tagInfo{IsOffset} and $$tagInfo{IsOffset} ne '3') {
     6167            my $exifTool = $self;
     6168            #### eval IsOffset ($val, $exifTool)
     6169            $val += $base + $$self{BASE} if eval $$tagInfo{IsOffset};
     6170        }
    41806171        $val{$index} = $val;
    4181         $self->FoundTag($tagInfo,$val);
    4182     }
     6172        unless ($self->FoundTag($tagInfo,$val)) {
     6173            # don't increment nextIndex if we didn't extract a tag
     6174            $nextIndex = $saveNextIndex if defined $saveNextIndex;
     6175        }
     6176    }
     6177    delete $$self{NO_UNKNOWN};
    41836178    return 1;
    41846179}
    41856180
    41866181#..............................................................................
    4187 # Load .ExifTool_config file from user's home directory (unless 'noConfig' set)
    4188 unless ($Image::ExifTool::noConfig) {
    4189     my $config = '.ExifTool_config';
    4190     # get our home directory (HOMEDRIVE and HOMEPATH are used in Windows cmd shell)
    4191     my $home = $ENV{EXIFTOOL_HOME} || $ENV{HOME} ||
    4192                ($ENV{HOMEDRIVE} || '') . ($ENV{HOMEPATH} || '') || '.';
    4193     # look for the config file in 1) the home directory, 2) the program dir
    4194     my $file = "$home/$config";
    4195     -r $file or $file = ($0 =~ /(.*[\\\/])/ ? $1 : './') . $config;
    4196     if (-r $file) {
    4197         eval "require '$file'"; # load the config file
    4198         # print warning (minus "Compilation failed" part)
    4199         $@ and $_=$@, s/Compilation failed.*//s, warn $_;
    4200     }
     6182# Load .ExifTool_config file from user's home directory
     6183# (use of noConfig is now deprecated, use configFile = '' instead)
     6184until ($Image::ExifTool::noConfig) {
     6185    my $file = $Image::ExifTool::configFile;
     6186    if (not defined $file) {
     6187        my $config = '.ExifTool_config';
     6188        # get our home directory (HOMEDRIVE and HOMEPATH are used in Windows cmd shell)
     6189        my $home = $ENV{EXIFTOOL_HOME} || $ENV{HOME} ||
     6190                   ($ENV{HOMEDRIVE} || '') . ($ENV{HOMEPATH} || '') || '.';
     6191        # look for the config file in 1) the home directory, 2) the program dir
     6192        $file = "$home/$config";
     6193        -r $file or $file = ($0 =~ /(.*[\\\/])/ ? $1 : './') . $config;
     6194        -r $file or last;
     6195    } else {
     6196        length $file or last;   # filename of "" disables configuration
     6197        -r $file or warn("Config file not found\n"), last;
     6198    }
     6199    eval "require '$file'"; # load the config file
     6200    # print warning (minus "Compilation failed" part)
     6201    $@ and $_=$@, s/Compilation failed.*//s, warn $_;
     6202    if (@Image::ExifTool::UserDefined::Lenses) {
     6203        foreach (@Image::ExifTool::UserDefined::Lenses) {
     6204            $Image::ExifTool::userLens{$_} = 1;
     6205        }
     6206    }
     6207    last;
    42016208}
    42026209
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool.pod

    r16842 r24107  
    66# URL:          http://owl.phy.queensu.ca/~phil/exiftool/
    77#
    8 # Legal:        Copyright (c) 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     8# Legal:        Copyright (c) 2003-2010, Phil Harvey (phil at owl.phy.queensu.ca)
    99#               This library is free software; you can redistribute it and/or
    1010#               modify it under the same terms as Perl itself.
     
    5555
    5656ExifTool provides an extensible set of perl modules to read and write meta
    57 information in image, audio and video files, including the maker note
    58 information of many digital cameras by various manufacturers such as Canon,
    59 Casio, FujiFilm, HP, JVC/Victor, Kodak, Leaf, Minolta/Konica-Minolta, Nikon,
    60 Olympus/Epson, Panasonic/Leica, Pentax/Asahi, Ricoh, Sanyo, Sigma/Foveon and
    61 Sony.
     57information in a wide variety of files, including the maker note information
     58of many digital cameras by various manufacturers such as Canon, Casio,
     59FujiFilm, GE, HP, JVC/Victor, Kodak, Leaf, Minolta/Konica-Minolta, Nikon,
     60Olympus/Epson, Panasonic/Leica, Pentax/Asahi, Reconyx, Ricoh, Samsung,
     61Sanyo, Sigma/Foveon and Sony.
    6262
    6363Below is a list of file types and meta information formats currently
    6464supported by ExifTool (r = read, w = write, c = create):
    6565
    66                 File Types                 |    Meta Information
    67   ---------------------------------------  |  --------------------
    68   ACR   r       JP2   r/w     PPT   r      |  EXIF           r/w/c
    69   AI    r       JPEG  r/w     PS    r/w    |  GPS            r/w/c
    70   AIFF  r       K25   r       PSD   r/w    |  IPTC           r/w/c
    71   APE   r       M4A   r       QTIF  r      |  XMP            r/w/c
    72   ARW   r       MEF   r/w     RA    r      |  MakerNotes     r/w/c
    73   ASF   r       MIE   r/w/c   RAF   r      |  Photoshop IRB  r/w/c
    74   AVI   r       MIFF  r       RAM   r      |  ICC Profile    r/w/c
    75   BMP   r       MNG   r/w     RAW   r/w    |  MIE            r/w/c
    76   BTF   r       MOS   r/w     RIFF  r      |  JFIF           r/w/c
    77   CR2   r/w     MOV   r       RM    r      |  Ducky APP12    r/w/c
    78   CRW   r/w     MP3   r       SR2   r      |  CIFF           r/w
    79   CS1   r/w     MP4   r       SRF   r      |  AFCP           r/w
    80   DCM   r       MPC   r       SWF   r      |  DICOM          r
    81   DCR   r       MPG   r       THM   r/w    |  Flash          r
    82   DNG   r/w     MRW   r/w     TIFF  r/w    |  FlashPix       r
    83   DOC   r       NEF   r/w     VRD   r/w/c  |  GeoTIFF        r
    84   EPS   r/w     OGG   r       WAV   r      |  PrintIM        r
    85   ERF   r/w     ORF   r/w     WDP   r/w    |  ID3            r
    86   FLAC  r       PBM   r/w     WMA   r      |  Kodak Meta     r
    87   FLV   r       PDF   r       WMV   r      |  Ricoh RMETA    r
    88   FPX   r       PEF   r/w     X3F   r      |  Picture Info   r
    89   GIF   r/w     PGM   r/w     XLS   r      |  Adobe APP14    r
    90   HTML  r       PICT  r       XMP   r/w/c  |  APE            r
    91   ICC   r/w/c   PNG   r/w                  |  Vorbis         r
    92   JNG   r/w     PPM   r/w                  |  (and more)
     66  File Types
     67  ------------+-------------+-------------+-------------+------------
     68  3FR   r     | DVB   r     | M4A/V r     | PBM   r/w   | RWL   r/w
     69  3G2   r     | DYLIB r     | MEF   r/w   | PDF   r/w   | RWZ   r
     70  3GP   r     | EIP   r     | MIE   r/w/c | PEF   r/w   | RM    r
     71  ACR   r     | EPS   r/w   | MIFF  r     | PFA   r     | SO    r
     72  AFM   r     | ERF   r/w   | MKA   r     | PFB   r     | SR2   r/w
     73  AI    r/w   | EXE   r     | MKS   r     | PFM   r     | SRF   r
     74  AIFF  r     | EXIF  r/w/c | MKV   r     | PGF   r     | SRW   r/w
     75  APE   r     | F4A/V r     | MNG   r/w   | PGM   r/w   | SVG   r
     76  ARW   r/w   | FLA   r     | MOS   r/w   | PICT  r     | SWF   r
     77  ASF   r     | FLAC  r     | MOV   r     | PMP   r     | THM   r/w
     78  AVI   r     | FLV   r     | MP3   r     | PNG   r/w   | TIFF  r/w
     79  BMP   r     | FPX   r     | MP4   r     | PPM   r/w   | TTC   r
     80  BTF   r     | GIF   r/w   | MPC   r     | PPT   r     | TTF   r
     81  COS   r     | GZ    r     | MPG   r     | PPTX  r     | VRD   r/w/c
     82  CR2   r/w   | HDP   r/w   | MPO   r/w   | PS    r/w   | VSD   r
     83  CRW   r/w   | HTML  r     | MQV   r     | PSB   r/w   | WAV   r
     84  CS1   r/w   | ICC   r/w/c | MRW   r/w   | PSD   r/w   | WDP   r/w
     85  DCM   r     | IIQ   r/w   | MXF   r     | PSP   r     | WEBP  r
     86  DCP   r/w   | IND   r/w   | NEF   r/w   | QTIF  r     | WEBM  r
     87  DCR   r     | ITC   r     | NRW   r/w   | RA    r     | WMA   r
     88  DFONT r     | JNG   r/w   | NUMBERS r   | RAF   r/w   | WMV   r
     89  DIVX  r     | JP2   r/w   | ODP   r     | RAM   r     | X3F   r/w
     90  DJVU  r     | JPEG  r/w   | ODS   r     | RAR   r     | XCF   r
     91  DLL   r     | K25   r     | ODT   r     | RAW   r/w   | XLS   r
     92  DNG   r/w   | KDC   r     | OGG   r     | RIFF  r     | XLSX  r
     93  DOC   r     | KEY   r     | ORF   r/w   | RSRC  r     | XMP   r/w/c
     94  DOCX  r     | LNK   r     | OTF   r     | RTF   r     | ZIP   r
     95  DV    r     | M2TS  r     | PAGES r     | RW2   r/w   |
     96
     97  Meta Information
     98  ----------------------+----------------------+---------------------
     99  EXIF           r/w/c  |  CIFF           r/w  |  Ricoh RMETA    r
     100  GPS            r/w/c  |  AFCP           r/w  |  Picture Info   r
     101  IPTC           r/w/c  |  Kodak Meta     r/w  |  Adobe APP14    r
     102  XMP            r/w/c  |  FotoStation    r/w  |  MPF            r
     103  MakerNotes     r/w/c  |  PhotoMechanic  r/w  |  Stim           r
     104  Photoshop IRB  r/w/c  |  JPEG 2000      r    |  APE            r
     105  ICC Profile    r/w/c  |  DICOM          r    |  Vorbis         r
     106  MIE            r/w/c  |  Flash          r    |  SPIFF          r
     107  JFIF           r/w/c  |  FlashPix       r    |  DjVu           r
     108  Ducky APP12    r/w/c  |  QuickTime      r    |  M2TS           r
     109  PDF            r/w/c  |  Matroska       r    |  PE/COFF        r
     110  PNG            r/w/c  |  GeoTIFF        r    |  AVCHD          r
     111  Canon VRD      r/w/c  |  PrintIM        r    |  ZIP            r
     112  Nikon Capture  r/w/c  |  ID3            r    |  (and more)
    93113
    94114=head1 CONFIGURATION
    95115
    96 User-defined tags can be added via the ExifTool configuration file.  See
    97 "ExifTool_config" in the ExifTool distribution for more details.  If
    98 necessary, the configuration feature can be disabled by setting the ExifTool
    99 C<noConfig> flag before loading Image::ExifTool.  For example:
    100 
    101     BEGIN { $Image::ExifTool::noConfig = 1 }
     116User-defined tags can be added via the ExifTool configuration file, or by
     117defining the %Image::ExifTool::UserDefined hash before calling any ExifTool
     118methods.  See "ExifTool_config" in the ExifTool distribution for more
     119details.
     120
     121By default ExifTool looks for a configuration file named ".ExifTool_config"
     122first in your home directory, then in the directory of the application
     123script, but a different file may be specified by setting the ExifTool
     124C<configFile> variable before using Image::ExifTool.  For example:
     125
     126    BEGIN { $Image::ExifTool::configFile = '/Users/phil/myconfig.cfg' }
    102127    use Image::ExifTool;
    103128
     129or the configuration feature may be disabled by setting C<configFile> to an
     130empty string:
     131
     132    BEGIN { $Image::ExifTool::configFile = '' }
     133    use Image::ExifTool;
     134
     135=head1 EXPORTS
     136
     137Exports nothing by default, but L</ImageInfo> and all static methods may be
     138exported with the C<:Public> export list.
     139
    104140=head1 METHODS
     141
     142All ExifTool features are accessed through the methods of the public
     143interface listed below.  Other Image::ExifTool methods and modules should
     144not be accessed directly because their interface may change with future
     145versions.
     146
     147None of these methods should ever die or issue warnings to STDERR if called
     148with the proper arguments (with the exception of L</SetNewValue> which
     149returns an error string when called in list context, or sends the error to
     150STDERR otherwise).  Error and warning messages that occur during processing
     151are stored in the values of the Error and Warning tags, and are accessible
     152via the L</GetValue> method.
    105153
    106154=head2 new
     
    121169=head2 ImageInfo
    122170
    123 Obtain meta information from image.  This is the one step function for
    124 obtaining meta information from an image.  Internally, L</ImageInfo> calls
    125 L</ExtractInfo> to extract the information, L</GetInfo> to generate the
    126 information hash, and L</GetTagList> for the returned tag list.
    127 
    128     # Return meta information for 2 tags only (procedural)
     171Read image file and return meta information.  This is the one step function
     172for retrieving meta information from an image.  Internally, L</ImageInfo>
     173calls L</ExtractInfo> to extract the information, L</GetInfo> to generate
     174the information hash, and L</GetTagList> for the returned tag list.
     175
     176    # return meta information for 2 tags only (procedural)
    129177    $info = ImageInfo($filename, $tag1, $tag2);
    130178
    131     # Return information about an open image file (object-oriented)
     179    # return information about an open image file (object-oriented)
    132180    $info = $exifTool->ImageInfo(\*FILE);
    133181
    134     # Return information from image data in memory for specified tags
     182    # return information from image data in memory for specified tags
    135183    %options = (PrintConv => 0);
    136184    @tagList = qw(filename imagesize xmp:creator exif:* -ifd1:*);
    137185    $info = ImageInfo(\$imageData, \@tagList, \%options);
    138186
    139     # Extract information from an embedded thumbnail image
     187    # extract information from an embedded thumbnail image
    140188    $info = ImageInfo('image.jpg', 'thumbnailimage');
    141189    $thumbInfo = ImageInfo($$info{ThumbnailImage});
     
    171219argument specified the image data via a file reference (file ref) or data
    172220reference (SCALAR ref).  The remaining scalar arguments are names of tags
    173 for requested information.  If no tags are specified, all possible
    174 information is extracted.
    175 
    176 Tag names are case-insensitive and may be prefixed by an optional group name
    177 followed by a colon.  The group name may begin with a family number
    178 (ie. '1IPTC:Keywords'), to restrict matches to a specific family.  A tag
    179 name of '*' may be used, thus allowing 'GROUP:*' to represent all tags in a
    180 specific group, or a group name of '*' may be used, in which case all
    181 available instances of the specified tag are returned regardless of the
    182 L</Duplicates> setting (ie. '*:WhiteBalance').  And finally, a leading '-'
    183 indicates tags to be excluded (ie. '-IFD1:*').
     221for requested information.  All tags are returned if no tags are specified.
     222
     223Tag names are case-insensitive and may be prefixed by optional group names
     224separated by colons.  A group name may begin with a family number (ie.
     225'1IPTC:Keywords'), to restrict matches to a specific family.  In the tag
     226name, a '?' matches any single character and a '*' matches zero or more
     227characters.  Thus 'GROUP:*' represents all tags in a specific group.
     228Wildcards may not be used in group names, with the exception that a group
     229name of '*' may be used to extract all available instances of a tag
     230regardless of the L</Duplicates> setting (ie. '*:WhiteBalance').  Multiple
     231groups may be specified (ie. 'EXIF:Time:*' extracts all EXIF Time tags). And
     232finally, a leading '-' indicates a tag to be excluded (ie. '-IFD1:*'), or a
     233trailing '#' causes the ValueConv value to be returned for this tag.
    184234
    185235Note that keys in the returned information hash and elements of the returned
    186 tag list are not necessarily the same as these tag names -- group names are
    187 removed, the case may be changed, and an instance number may be added.  For
    188 this reason it is best to use either the keys of the returned hash or the
    189 elements of the tag array when accessing the tag values.
     236tag list are not necessarily the same as these tag names because group names
     237are removed, the case may be changed, and an instance number may be added.
     238For this reason it is best to use either the keys of the returned hash or
     239the elements of the tag array when accessing the tag values.
    190240
    191241See L<Image::ExifTool::TagNames|Image::ExifTool::TagNames> for a complete
     
    196246A reference to an open image file.  If you use this method (or a SCALAR
    197247reference) to access information in an image, the FileName and Directory
    198 tags will not be returned.  (Also, the FileSize and FileModifyDate tags will
    199 not be returned unless it is a plain file.)  Image processing begins at the
    200 current file position, and on return the file position is unspecified.
     248tags will not be returned.  (Also, the FileSize, FileModifyDate and
     249FilePermissions tags will not be returned unless it is a plain file.)  Image
     250processing begins at the current file position, and on return the file
     251position is unspecified.  May be either a standard filehandle, or a
     252reference to a L<File::RandomAccess|File::RandomAccess> object.  Note that
     253the file remains open and must be closed by the caller after L</ImageInfo>
     254returns.
     255
     256[Advanced:  To allow a non-rewindable stream (ie. a network socket) to be
     257re-read after processing with ExifTool, first wrap the file reference in a
     258L<File::RandomAccess|File::RandomAccess> object, then pass this object to
     259L</ImageInfo>.  The L<File::RandomAccess|File::RandomAccess> object will
     260buffer the file if necessary, and may be used to re-read the file after
     261L</ImageInfo> returns.]
    201262
    202263=item SCALAR ref
     
    209270added to the list of requested tags.  Tags with names beginning with '-' are
    210271excluded.  On return, this list is updated to contain an ordered list of tag
    211 keys for all extracted tags.
     272keys for the returned information.
     273
     274There will be 1:1 correspondence between the requested tags and the returned
     275tag keys only if the L</Duplicates> option is 0 and L</Sort> is 'Input'.
     276(With L</Duplicates> enabled, there may be more entries in the returned list
     277of tag keys, and with other L</Sort> settings the entries may not be in the
     278same order as requested.)
    212279
    213280=item HASH ref
     
    225292embedded instance number if multiple tags with the same name were extracted
    226293from the image.  Many of the ExifTool functions require a tag key as an
    227 argument. Use L</GetTagName> to get the tag name for a given tag key.  Note
    228 that the case of the tag names may not be the same as requested.  Here is a
    229 simple example to print out the information returned by L</ImageInfo>:
     294argument. Use L</GetTagName [static]> to get the tag name for a given tag
     295key.  Note that the case of the tag names may not be the same as requested.
     296Here is a simple example to print out the information returned by
     297L</ImageInfo>:
    230298
    231299    foreach (sort keys %$info) {
     
    235303Values of the returned hash are usually simple scalars, but a scalar
    236304reference is used to indicate binary data and an array reference may be used
    237 to indicate a list.  Lists of values are joined by commas into a single
    238 string if and only if the PrintConv option is enabled and the List option is
     305to indicate a list.  Also, a hash reference may be returned if the L</Struct>
     306option is used.  Lists of values are joined by commas into a single
     307string only if the PrintConv option is enabled and the List option is
    239308disabled (which are the defaults).  Note that binary values are not
    240309necessarily extracted unless specifically requested or the Binary option is
     
    268337    }
    269338
     339=item Notes:
     340
     341ExifTool returns all values as byte strings of encoded characters.  Perl
     342wide characters are not used.  See L</CHARACTER ENCODINGS> for details about
     343the encodings.
     344
    270345As well as tags representing information extracted from the image,
    271346the following tags generated by ExifTool may be returned:
     
    273348    ExifToolVersion - The ExifTool version number.
    274349
    275     Error - An error message if the image could not be read.
    276 
    277     Warning - A warning message if problems were encountered
    278               while extracting information from the image.
     350    Error - An error message if the image could not be processed.
     351
     352    Warning - A warning message if problems were encountered while
     353              processing the image.
    279354
    280355=back
     
    285360options for an ExifTool object.  Options set this way are in effect for
    286361all function calls but may be overridden by options passed as arguments
    287 to a specific function.
    288 
    289     # Exclude the 'OwnerName' tag from returned information
     362to some functions.
     363
     364The initial default options are obtained from values in the
     365%Image::ExifTool::UserDefined::Options hash if it exists.  See the
     366.ExifTool_config file in the full ExifTool distribution for details.
     367
     368    # exclude the 'OwnerName' tag from returned information
    290369    $exifTool->Options(Exclude => 'OwnerName');
    291370
    292     # Only get information in EXIF or MakerNotes groups
     371    # only get information in EXIF or MakerNotes groups
    293372    $exifTool->Options(Group0 => ['EXIF', 'MakerNotes']);
    294373
    295     # Ignore information from IFD1
     374    # ignore information from IFD1
    296375    $exifTool->Options(Group1 => '-IFD1');
    297376
    298     # Sort by groups in family 2, and extract unknown tags
     377    # sort by groups in family 2, and extract unknown tags
    299378    $exifTool->Options(Sort => 'Group2', Unknown => 1);
    300379
    301     # Do not extract duplicate tag names
     380    # reset DateFormat option
     381    $exifTool->Options(DateFormat => undef);
     382
     383    # do not extract duplicate tag names
    302384    $oldSetting = $exifTool->Options(Duplicates => 0);
    303385
    304     # Get current setting
     386    # get current Verbose setting
    305387    $isVerbose = $exifTool->Options('Verbose');
    306388
     
    340422=item Charset
    341423
    342 Character set for converting special characters.  Valid values are:
    343 
    344   UTF8  - UTF-8 characters (the default)
    345   Latin - Windows Latin1 (cp1252)
     424Character set for encoding character strings passed to/from ExifTool with
     425code points above U+007F.  Default is UTF8.  Valid values are listed below,
     426case is not significant:
     427
     428  Value        Alias(es)        Description
     429  -----------  ---------------  ----------------------------------
     430  UTF8         cp65001, UTF-8   UTF-8 characters
     431  Latin        cp1252, Latin1   Windows Latin1 (West European)
     432  Latin2       cp1250           Windows Latin2 (Central European)
     433  Cyrillic     cp1251, Russian  Windows Cyrillic
     434  Greek        cp1253           Windows Greek
     435  Turkish      cp1254           Windows Turkish
     436  Hebrew       cp1255           Windows Hebrew
     437  Arabic       cp1256           Windows Arabic
     438  Baltic       cp1257           Windows Baltic
     439  Vietnam      cp1258           Windows Vietnamese
     440  Thai         cp874            Windows Thai
     441  MacRoman     cp10000, Roman   Macintosh Roman
     442  MacLatin2    cp10029          Macintosh Latin2 (Central Europe)
     443  MacCyrillic  cp10007          Macintosh Cyrillic
     444  MacGreek     cp10006          Macintosh Greek
     445  MacTurkish   cp10081          Macintosh Turkish
     446  MacRomanian  cp10010          Macintosh Romanian
     447  MacIceland   cp10079          Macintosh Icelandic
     448  MacCroatian  cp10082          Macintosh Croatian
    346449
    347450Note that this option affects some types of information when reading/writing
     
    349452defined for both types of access.
    350453
     454=item CharsetID3
     455
     456Character encoding to assume for ID3v1 strings.  By the specification ID3v1
     457strings should be encoded in ISO 8859-1 (essentially Latin), but some
     458applications may use local encoding instead.  Default is Latin.
     459
     460=item CharsetIPTC
     461
     462Fallback IPTC character set to assume if IPTC information contains no
     463CodedCharacterSet tag.  Possible values are the same as the L</Charset>
     464option.  Default is Latin.
     465
     466Note that this option affects some types of information when reading/writing
     467the file and other types when getting/setting tag values, so it must be
     468defined for both types of access.
     469
     470=item CharsetPhotoshop
     471
     472Character encoding to assume for Photoshop IRB resource names.  Default is
     473Latin.
     474
    351475=item Compact
    352476
    353477Flag to write compact output.  Default is 0.  The XMP specification suggests
    354 that the data be padded with blanks to allow in-place editing.  By setting
    355 this flag, 2kB is saved for files with XMP data.
     478that the data be padded with blanks to allow in-place editing.  With this
     479flag set the 2kB of padding is not written.  Note that this only effects
     480embedded XMP since padding is never written for stand-alone XMP files.
    356481
    357482=item Composite
     
    371496output for the same coordinate using various formats:
    372497
    373         CoordFormat          Example Output
    374     -------------------    ------------------
    375     q{%d deg %d' %.2f"}    54 deg 59' 22.80"   (the default)
    376     q{%d deg %.4f min}     54 deg 59.3800 min
    377     q{%.6f degrees}        54.989667 degrees
     498      CoordFormat        Example Output
     499  -------------------  ------------------
     500  q{%d deg %d' %.2f"}  54 deg 59' 22.80"  (default for reading)
     501  q{%d %d %.8f}        54 59 22.80000000  (default for copying)
     502  q{%d deg %.4f min}   54 deg 59.3800 min
     503  q{%.6f degrees}      54.989667 degrees
     504
     505Note:  To avoid loss of precision, the default coordinate format is
     506different when copying tags with L</SetNewValuesFromFile>.
    378507
    379508=item DateFormat
    380509
    381 Format for printing EXIF date/time.  See C<strftime> in the L<POSIX> package
    382 for details about the format string.  The default format is equivalent to
    383 "%Y:%m:%d %H:%M:%S".  If date can not be converted, value is left unchanged
    384 unless the StrictDate option is set.
     510Format for printing date/time values.  See C<strftime> in the L<POSIX>
     511package for details about the format string.  The default is similar to a
     512format of "%Y:%m:%d %H:%M:%S".  If date can not be converted, value is left
     513unchanged unless the StrictDate option is set.  Timezones are ignored.
    385514
    386515=item Duplicates
    387516
    388 Flag to preserve values of duplicate tags (instead of overwriting existing
    389 value).  Default is 1.
     517Flag to return values from tags with duplicate names when extracting
     518information.  Default is 1.
     519
     520=item Escape
     521
     522Escape special characters in extracted values for HTML or XML.  Also
     523unescapes HTML or XML character entities in input values passed to
     524L</SetNewValue>.  Valid settings are 'HTML', 'XML' or undef.  Default is
     525undef.
    390526
    391527=item Exclude
     
    397533name with a '-' in the arguments to L</ImageInfo>.
    398534
     535=item ExtractEmbedded
     536
     537Flag to extract information from embedded documents in EPS and PDF files,
     538embedded MPF images in JPEG and MPO files, streaming metadata in AVCHD
     539videos, and the resource fork of Mac OS files.  Default is 0.
     540
    399541=item FastScan
    400542
    401543Flag to increase speed of extracting information from JPEG images.  With
    402 this option set, ExifTool will not scan to the end of a JPEG image to check
    403 for an AFCP, CanonVRD, FotoStation, PhotoMechanic, MIE or PreviewImage
    404 trailer.  Also, when combined with the ScanForXMP option, prevents scanning
    405 for XMP in recognized file types.  Default 0.
     544this option set to 1, ExifTool will not scan to the end of a JPEG image to
     545check for an AFCP, CanonVRD, FotoStation, PhotoMechanic, MIE or PreviewImage
     546trailer.  This also stops the parsing after the first comment in GIF images,
     547and at the audio/video data with RIFF-format files (AVI, WAV, etc), so any
     548trailing metadata (ie. XMP written by some utilities) may be missed.  When
     549combined with the ScanForXMP option, prevents scanning for XMP in recognized
     550file types.  With a value of 2, ExifTool will also avoid extracting any EXIF
     551MakerNote information.  Default is 0.
    406552
    407553=item FixBase
     
    415561or undef (the default) for no base adjustment.
    416562
     563=item GeoMaxIntSecs
     564
     565Maximum interpolation time in seconds for geotagging.  Geotagging fails if
     566the Geotime value lies between two fixes in the same track which are
     567separated by a number of seconds greater than this.  Default is 1800.
     568
     569=item GeoMaxExtSecs
     570
     571Maximum extrapolation time in seconds for geotagging.  Geotagging fails if
     572the Geotime value lies outside a GPS track by a number of seconds greater
     573than this.  Default is 1800.
     574
     575=item GeoMaxHDOP
     576
     577Maximum Horizontal (2D) Dilution Of Precision for geotagging.  GPS fixes are
     578ignored if the HDOP is greater than this.  Default is undef.
     579
     580=item GeoMaxPDOP
     581
     582Maximum Position (3D) Dilution Of Precision for geotagging.  GPS fixes are
     583ignored if the PDOP is greater than this.  Default is undef.
     584
     585=item GeoMinSats
     586
     587Minimum number of satellites for geotagging.  GPS fixes are ignored if the
     588number of acquired satellites is less than this.  Default is undef.
     589
    417590=item Group#
    418591
    419592Extract tags only for specified groups in family # (Group0 assumed if #
    420593not given).  The option value may be a single group name or a reference
    421 to a list of groups.  Case is significant in group names.  Specify a
    422 group to be excluded by preceding group name with a '-'.  See
    423 L</GetAllGroups> for a list of available groups.
     594to a list of groups.  Case is significant in group names.  Specify a group
     595to be excluded by preceding group name with a '-'.  See L</GetGroup> for a
     596description of group families, and L</GetAllGroups [static]> for lists of
     597group names.
    424598
    425599=item HtmlDump
     
    438612Flag to ignore minor errors.  Causes minor errors to be downgraded to
    439613warnings, and minor warnings to be ignored.  This option is provided mainly
    440 to allow writing of files when minor errors occur, but also allows thumbnail
    441 and preview images to be extracted even if they don't have a recognizable
    442 header.  Minor errors/warnings are denoted by '[minor]' at the start of the
    443 message.
     614to allow writing of files when minor errors occur, but by ignoring some
     615minor warnings the behaviour of ExifTool may be changed to allow some
     616questionable operations to proceed (such as extracting thumbnail and preview
     617images even if they don't have a recognizable header).  Minor
     618errors/warnings are denoted by '[minor]' at the start of the message.
     619
     620=item Lang
     621
     622Localized language for exiftool tag descriptions, etc.  Available languages
     623are given by the Image::ExifTool::Lang module names (ie. 'fr').  If the
     624specified language isn't available, the option is not changed.  May be set
     625to undef to select the built-in default language.  Default is 'en'.
     626
     627=item LargeFileSupport
     628
     629Flag to indicate that 64-bit file offsets are supported on this system.
     630Default is 0.
    444631
    445632=item List
    446633
    447 Flag to extract lists of PrintConv values into arrays instead of
    448 concatenating them into comma-separated strings.  Default is 0.
     634Flag to extract lists of PrintConv values into arrays instead of joining
     635them into a string of values.  The L</ListSep> option specifies the
     636separator used when combining values.  Default is 0.
     637
     638=item ListSep
     639
     640Separator string used to join lists of PrintConv values when L</List> option
     641is not set.  Default is ', '.
     642
     643=item ListSplit
     644
     645Regular expression used to split values of list-type tags into individual
     646items when writing.  (ie. use ',\\s*' to split a comma-separated list.)
     647Default is undef.
    449648
    450649=item MakerNotes
     
    456655are:
    457656
    458   0 - Do not extract writable subdirectories [default]
     657  0 - Do not extract writable subdirectories (default)
    459658  1 - Extract and rebuild maker notes into self-contained block
    460659  2 - Extract without rebuilding maker notes
     
    466665to '' if L</IgnoreMinorErrors> is set.  Default is undef.
    467666
     667=item Password
     668
     669Password for processing password-protected PDF documents.  Ignored if a
     670password is not required.  Character encoding of the password is determined
     671by the value of the Charset option at processing time.  Default is undef.
     672
    468673=item PrintConv
    469674
     
    481686Specifies order to sort tags in returned list:
    482687
     688  Input  - Sort in same order as input tag arguments (default)
    483689  Alpha  - Sort alphabetically
    484690  File   - Sort in order that tags were found in the file
    485   Group# - Sort by tag group, where # is the group family
    486            number.  If # is not specified, Group0 is assumed.
    487            See GetGroup for a list of groups.
    488   Input  - Sort in same order as input tag arguments (default)
     691  Group# - Sort by tag group, where # is zero or more family
     692           numbers separated by colons. If # is not specified,
     693           Group0 is assumed.  See GetGroup for a description
     694           of group families.
    489695
    490696=item StrictDate
    491697
    492698Flag to return undefined value for any date which can't be converted when
    493 the DateFormat option is used.  Default is 0.
     699the DateFormat option is used.  Default is undef.
     700
     701=item Struct
     702
     703Flag to return XMP structures as hash references instead of flattening into
     704individual tags.  If not defined (the default), tags are flattened when
     705reading (with L<ExtractInfo>), and structured when copying (with
     706L</SetNewValuesFromFile>).  Has no effect when writing since both flattened
     707and structured tags may always be written.  Possible values are:
     708
     709  undef - Read flattened tags, copy structured tags (default)
     710    0   - Read and copy flattened tags
     711    1   - Read and copy structured tags
    494712
    495713=item TextOut
     
    524742=head2 ClearOptions
    525743
    526 Reset all options to their default values.
     744Reset all options to their default values.  Loads user-defined default
     745option values from the %Image::ExifTool::UserDefined::Options hash in the
     746.ExifTool_config file if it exists.
    527747
    528748    $exifTool->ClearOptions();
     
    555775L</ExtractInfo>:
    556776
    557 Binary, Composite, DateFormat, Unknown and Verbose.
     777Binary, Charset, CharsetID3, CharsetIPTC, Composite, ExtractEmbedded,
     778FastScan, FixBase, HtmlDump, HtmlDumpBase, IgnoreMinorErrors, Lang,
     779LargeFileSupport, MakerNotes, ScanForXMP, Struct, TextOut, Unknown and
     780Verbose.
    558781
    559782=item Return Value:
    560783
    561 1 if image was valid, 0 otherwise (and 'Error' tag set).
     7841 if this was a recognized file format, 0 otherwise (and 'Error' tag set).
    562785
    563786=back
     
    570793L</ImageInfo>.
    571794
    572     # Get image width and hieght only
     795    # get image width and hieght only
    573796    $info = $exifTool->GetInfo('ImageWidth', 'ImageHeight');
    574797
    575     # Get information for all tags in list (list updated with tags found)
     798    # get information for all tags in list (list updated with tags found)
    576799    $info = $exifTool->GetInfo(\@ioTagList);
    577800
    578     # Get all information in Author or Location groups
     801    # get all information in Author or Location groups
    579802    $info = $exifTool->GetInfo({Group2 => ['Author', 'Location']});
    580803
     
    586809image can not be specified.  Options in effect are:
    587810
    588 Duplicates, Exclude, Group#, PrintConv (and Sort if tag list reference is
    589 given).
     811Charset, CoordFormat, DateFormat, Duplicates, Escape, Exclude, Group#, Lang,
     812List, ListSep, PrintConv, Sort (if a tag list reference is given) and
     813StrictDate.
    590814
    591815=item Return Value:
     
    610834    $exifTool->WriteInfo(undef, $dstfile, 'XMP');
    611835
    612     # edit file in place (you do have backups, right?)
     836    # overwrite file (you do have backups, right?)
    613837    $exifTool->WriteInfo($srcfile);
    614838
     
    6198430) ExifTool object reference
    620844
    621 1) Source file name, file reference, scalar reference, or undefined to
    622 create a file from scratch
    623 
    624 2) [optional] Destination file name, file or scalar reference
     8451) Source file name, file reference, scalar reference, or undef to create a
     846file from scratch
     847
     8482) [optional] Destination file name, file reference, scalar reference, or
     849undef to overwrite the original file
    625850
    6268513) [optional] Destination file type
     
    633858If an error code is returned, an Error tag is set and GetValue('Error') can
    634859be called to obtain the error description.  A Warning tag may be set even if
    635 this routine is successful.
     860this routine is successful.  Calling WriteInfo clears any pre-existing Error
     861and Warning tags.
    636862
    637863    $errorMessage = $exifTool->GetValue('Error');
     
    641867
    642868The source file name may be undefined to create a file from scratch
    643 (currently only XMP, ICC and MIE files can be created in this way).  If
    644 undefined, the destination file type is required unless the type can be
    645 determined from the destination file name.
    646 
    647 The destination file name may be undefined to edit a file in place (make
    648 sure you have backups!).  If a destination file name is given, the specified
    649 file must not exist because existing destination files will not be
    650 overwritten.
     869(currently only XMP, MIE, ICC, VRD and EXIF files can be created in this way
     870-- see L</CanCreate> for details).  If undefined, the destination file type
     871is required unless the type can be determined from the destination file
     872name.
     873
     874If a destination file name is given, the specified file must not exist
     875because an existing destination file will not be overwritten.  The
     876destination file name may be undefined to overwrite the original file (make
     877sure you have backups!).  In this case, if a source file name is provided, a
     878temporary file is created and renamed to replace the source file if no
     879errors occurred while writing.  Otherwise, if a source file reference or
     880scalar reference is used, the image is first written to memory then copied
     881back to replace the original if there were no errors.
    651882
    652883The destination file type is only used if the source file is undefined.
    653884
    654 =back
     885On Mac OS systems, the file resource fork is preserved if this routine is
     886called with a source file name.
     887
     888=back
     889
     890The following ExifTool options are effective in the call to L</WriteInfo>:
     891
     892ByteOrder, Charset, CharsetID3, CharsetIPTC, Compact, Compress, FixBase,
     893IgnoreMinorErrors and Verbose.
    655894
    656895=head2 CombineInfo
     
    699938=item Return Values:
    700939
    701 A list of tags in the specified order.
     940A list of tag keys in the specified order.
    702941
    703942=back
     
    724963=item Return Values:
    725964
    726 A list of tags in the specified order.
     965A list of tag keys in the specified order.
    727966
    728967=back
     
    745984=item Return Values:
    746985
    747 List of requested tags in the same order that they were specified.
     986List of requested tag keys in the same order that the tags were specified.
    748987Note that this list will be empty if tags were not specifically requested
    749988(ie. If extracting all tags).
     
    7631002Tags which represent lists of multiple values (as may happen with 'Keywords'
    7641003for example) are handled specially.  In scalar context, the returned
    765 PrintConv value for these tags is either a comma-separated string of values
    766 or a list reference (depending on the List option setting), and the
    767 ValueConv value is always a list reference.  But in list context,
    768 L</GetValue> always returns the list itself.
     1004PrintConv value for these tags is either a string of values or a list
     1005reference (depending on the List option setting), and the ValueConv value is
     1006always a list reference.  But in list context, L</GetValue> always returns
     1007the list itself.
     1008
     1009Note that L</GetValue> requires a case-sensitive tag key as an argument.  To
     1010retrieve tag information based on a case-insensitive tag name (with an
     1011optional group specifier), use L</GetInfo> instead.
    7691012
    7701013    # PrintConv example
     
    7881031    my @keywords = $exifTool->GetValue('Keywords', 'ValueConv');
    7891032
     1033The following options are in effect when <L/GetValue> is called:
     1034
     1035Charset, CoordFormat, DateFormat, Escape, Lang, List, ListSep, PrintConv and
     1036StrictDate.
     1037
    7901038=over 4
    7911039
     
    8051053
    8061054The value of the specified tag.  If the tag represents a list of values and
    807 the List option is disabled then PrintConv returns a comma separated string
    808 of values, otherwise a reference to the list is returned in scalar context.
    809 The list itself is returned in list context.  Values may also be scalar
    810 references to binary data.
     1055the List option is disabled then PrintConv returns a string of values,
     1056otherwise a reference to the list is returned in scalar context.  The list
     1057itself is returned in list context.  Values may also be scalar references to
     1058binary data, or hash references if the Struct option is set.
    8111059
    8121060Note: It is possible for L</GetValue> to return an undefined ValueConv or
     
    8411089    $exifTool->SetNewValue('Keywords', $word, DelValue => 1);
    8421090
    843     # write a list of keywords
    844     $exifTool->SetNewValue('Keywords', ['word1','word2']);
    845 
    846     # add a keyword without replacing existing keywords
     1091    # set keywords (a List-type tag) with two new values
     1092    $exifTool->SetNewValue(Keywords => 'word1');
     1093    $exifTool->SetNewValue(Keywords => 'word2');
     1094    # equivalent, but set both in one call using an array reference
     1095    $exifTool->SetNewValue(Keywords => ['word1','word2']);
     1096
     1097    # add a keyword without replacing existing keywords in the file
    8471098    $exifTool->SetNewValue(Keywords => $word, AddValue => 1);
    8481099
    8491100    # set a tag in a specific group
    8501101    $exifTool->SetNewValue(Headline => $val, Group => 'XMP');
    851     $exifTool->SetNewValue('XMP:Headline' => $val);  # equivalent
     1102    $exifTool->SetNewValue('XMP:Headline' => $val);  # (equivalent)
    8521103
    8531104    # shift original date/time back by 1 hour
    8541105    $exifTool->SetNewValue(DateTimeOriginal => '1:00', Shift => -1);
    8551106
     1107    # write a tag only if it had a specific value
     1108    # (the order of the following calls is not significant)
     1109    $exifTool->SetNewValue(Title => $oldVal, DelValue => 1);
     1110    $exifTool->SetNewValue(Title => $newVal);
     1111
     1112    # write tag by numerical value
     1113    $exifTool->SetNewValue(Orientation => 6, Type => 'ValueConv');
     1114    $exifTool->SetNewValue('Orientation#' => 6);  # (equivalent)
     1115
     1116    # delete all but EXIF tags
     1117    $exifTool->SetNewValue('*');  # delete all...
     1118    $exifTool->SetNewValue('EXIF:*', undef, Replace => 2); # ...but EXIF
     1119
     1120    # write structured information as a HASH reference
     1121    $exifTool->SetNewValue('XMP:Flash' => {
     1122        mode   => 'on',
     1123        fired  => 'true',
     1124        return => 'not'
     1125    });
     1126
     1127    # write structured information as a serialized string
     1128    $exifTool->SetNewValue('XMP:Flash'=>'{mode=on,fired=true,return=not}');
     1129
     1130(See L<http://owl.phy.queensu.ca/~phil/exiftool/struct.html#Serialize> for
     1131a description of the structure serialization technique.)
     1132
    8561133=over 4
    8571134
     
    86011370) ExifTool object reference
    8611138
    862 1) [optional] Tag key or tag name, or undefined to clear all new values.  A
    863 tag name of '*' can be used when deleting tags to delete all tags, or all
    864 tags in a specified group.  The tag name may be prefixed by group name,
    865 separated by a colon (ie. 'GROUP:TAG'), which is equivalent to using a
    866 'Group' option argument.
     11391) [optional] Tag key or tag name, or undef to clear all new values.  A tag
     1140name of '*' can be used when deleting tags to delete all tags, or all tags
     1141in a specified group.  The tag name may be prefixed by group name, separated
     1142by a colon (ie. 'EXIF:Artist'), which is equivalent to using a Group option
     1143argument.  Also, a '#' may be appended to the tag name (ie.
     1144'EXIF:Orientation#'), with the same effect as setting Type to 'ValueConv'.
    8671145
    86811462) [optional] New value for tag.  Undefined to delete tag from file.  May be
    869 a scalar, scalar reference, or list reference to set a list of values.
    870 
    871 3-N) [optional] SetNewValue options hash entries (see below)
     1147a scalar, scalar reference, list reference to set a list of values, or hash
     1148reference for a structure.  Integer values may be specified as a hexadecimal
     1149string (with a leading '0x'), and simple rational values may be specified in
     1150fractional form (ie. '4/10').  Structure tags may be specified either as a
     1151hash reference or a serialized string (see the last two examples above).
     1152
     11533-N) [optional] SetNewValue option/value pairs (see below).
    8721154
    8731155=item SetNewValue Options:
    8741156
    8751157=over 4
    876 
    877 =item Type
    878 
    879 The type of value being set.  Valid values are PrintConv, ValueConv or Raw.
    880 Default is PrintConv if the L</PrintConv> Option is set, otherwise
    881 ValueConv.
    8821158
    8831159=item AddValue
     
    8901166Delete the existing tag if it has the specified value.  Valid values are
    89111670 or 1.  Default is 0.
     1168
     1169=item EditGroup
     1170
     1171Create tags in existing groups only.  Don't create new group.  Valid values
     1172are 0 and 1.  Default is 0.
     1173
     1174=item EditOnly
     1175
     1176Edit tag only if it already exists.  Don't create new tag.  Valid values are
     11770 and 1.  Default is 0.
    8921178
    8931179=item Group
     
    9131199=item Replace
    9141200
    915 Flag to replace the previous new value for this tag (ie. replace the value
    916 set in a previous call to L</SetNewValue>).  Valid values are 0 (don't
    917 replace), 1 (replace with specified new value) or 2 (reset previous new
    918 value only).
     1201Flag to replace the previous new values for this tag (ie. replace the values
     1202set in previous calls to L</SetNewValue>).  This option is most commonly
     1203used to replace previously-set new values for List-type tags.  Valid values
     1204are 0 (set new value normally -- adds to new values for List-type tags), 1
     1205(reset previous new values for this tag and replace with the specified new
     1206value) or 2 (reset previous new values only).
    9191207
    9201208=item Shift
     
    9221210Shift the tag by the specified value.  Currently only date/time tags can be
    9231211shifted.  Undefined for no shift, 1 for a positive shift, or -1 for a
    924 negative shift.  If 0, the shift is applied only if the tag is shiftable.
    925 In this case, the direction of the shift is positive if AddValue is set, or
    926 negative if DelValue is set.  Default is undef.  See
     1212negative shift.  If 0, the shift is applied only if the tag is shiftable,
     1213and the shift is positive if AddValue is set, or negative if DelValue is
     1214set.  Default is undef.  See
    9271215L<Image::ExifTool::Shift.pl|Image::ExifTool::Shift.pl> for more information.
     1216
     1217=item Type
     1218
     1219The type of value being set.  Valid values are PrintConv, ValueConv or Raw.
     1220Default is PrintConv if the L</PrintConv> Option is set, otherwise
     1221ValueConv.
    9281222
    9291223=back
     
    9351229error string.
    9361230
    937 =back
     1231=item Notes:
     1232
     1233When deleting groups of tags, the Replace option may be used as in the last
     1234example above to exclude specific groups from a mass delete.  However, this
     1235technique may not be used to exclude individual tags.  Instead, use
     1236L</SetNewValuesFromFile> to recover the values of individual tags after
     1237deleting a group.
     1238
     1239=back
     1240
     1241The following ExifTool options are effective in the call to L</SetNewValue>:
     1242
     1243Charset, Escape, IgnoreMinorErrors, Lang, ListSep, ListSplit, PrintConv and
     1244Verbose.
    9381245
    9391246=head2 SetNewValuesFromFile
     
    9631270        'Comment<ISO=$ISO Aperture=$aperture Exposure=$shutterSpeed');
    9641271
     1272    # set keywords list from the values of multiple tags
     1273    $exifTool->SetNewValuesFromFile($file, { Replace => 0 },
     1274        'keywords<xmp:subject', 'keywords<filename');
     1275
     1276    # copy all EXIF information, preserving the original IFD
     1277    # (without '>*.*' tags would be copied to the preferred EXIF IFD)
     1278    $exifTool->SetNewValuesFromFile($file, 'EXIF:*>*:*');
     1279
    9651280=over 4
    9661281
     
    97112861) File name, file reference, or scalar reference
    9721287
    973 2-N) [optional] List of tag names to set.  All writable tags are set if none
    974 are specified.  The tag names are not case sensitive, and may be prefixed by
    975 an optional family 0 or 1 group name, separated by a colon (ie. 'exif:iso').
    976 A leading '-' indicates tags to be excluded (ie. '-comment').  An asterisk
    977 ('*') may be used for the tag name, and is useful when a group is specified
    978 to set all tags from a group (ie. 'XMP:*').  A special feature allows tag
    979 names of the form 'SRCTAG>DSTTAG' (or 'DSTTAGE<lt>SRCTAG') to be specified
    980 to copy information to a tag with a different name or a specified group.
    981 Both 'SRCTAG' and 'DSTTAG' may use '*' and/or be prefixed by a group name
    982 (ie. 'modifyDate>fileModifyDate' or '*>xmp:*').  Copied tags may also be
    983 added or deleted from a list with arguments of the form 'SRCTAG+>DSTTAG' or
    984 'SRCTAG->DSTTAG'.  Tags are evaluated in order, so exclusions apply only to
    985 tags included earlier in the list.  An extension of this feature allows the
    986 tag value to be set from an expression containing tag names with leading '$'
    987 symbols (ie. 'CommentE<lt>Filename: $filename').  Braces '{}' may be used
    988 around the tag name to separate it from subsequent text, and a '$$' is used
    989 to to represent a '$' symbol.  (The behaviour for missing tags in
    990 expressions is defined by the L</MissingTagValue> option.)
     12882-N) [optional] List of tag names to set or options hash references.  All
     1289writable tags are set if none are specified.  The tag names are not case
     1290sensitive, and may be prefixed by an optional family 0 or 1 group name,
     1291separated by a colon (ie. 'exif:iso').  A leading '-' indicates tags to be
     1292excluded (ie. '-comment'), or a trailing '#' causes the ValueConv value to
     1293be copied (same as setting the Type option to 'ValueConv' for this tag
     1294only).  An asterisk ('*') may be used for the tag name, and is useful when a
     1295group is specified to set all tags from a group (ie. 'XMP:*').  A special
     1296feature allows tag names of the form 'SRCTAG>DSTTAG' (or
     1297'DSTTAGE<lt>SRCTAG') to be specified to copy information to a tag with a
     1298different name or a specified group. Both 'SRCTAG' and 'DSTTAG' may use '*'
     1299and/or be prefixed by a group name (ie. 'modifyDate>fileModifyDate' or
     1300'*>xmp:*').  Copied tags may also be added or deleted from a list with
     1301arguments of the form 'SRCTAG+>DSTTAG' or 'SRCTAG->DSTTAG'.  Tags are
     1302evaluated in order, so exclusions apply only to tags included earlier in the
     1303list.  An extension of this feature allows the tag value to be set from an
     1304expression containing tag names with leading '$' symbols (ie.
     1305'CommentE<lt>the file is $filename').  Braces '{}' may be used around the tag
     1306name to separate it from subsequent text, and a '$$' is used to to represent
     1307a '$' symbol.  (The behaviour for missing tags in expressions is defined by
     1308the L</MissingTagValue> option.)  Multiple options hash references may be
     1309passed to set different options for different tags. Options apply to
     1310subsequent tags in the argument list.
    9911311
    9921312By default, this routine will commute information between same-named tags in
     
    9951315name for extracted tags (even if '*' is used as a group name), in which case
    9961316the information is written to the original group, unless redirected to a
    997 different group.  (For example, a tag name of '*:*' may be specified to copy
    998 all information while preserving the original groups.)
     1317different group.  When '*' is used for a group name, the family 1 group of
     1318the original tag is preserved.  (For example, specifying '*:*' copies all
     1319information while preserving the original family 1 groups.)
     1320
     1321=item SetNewValuesFromFile Options:
     1322
     1323The options are the same was for L</SetNewValue>, and are passed directly
     1324to L</SetNewValue> internally, with a few exceptions:
     1325
     1326- The Replace option defaults to 1 instead of 0 as with L</SetNewValue>.
     1327
     1328- The AddValue or DelValue option is set for individual tags if '+>' or '->'
     1329(or '+E<lt>' or '-E<lt>') are used.
     1330
     1331- The Group option is set for tags where a group name is given.
     1332
     1333- The Protected flag is set to 1 for individually specified tags.
     1334
     1335- The Type option also applies to extracted tags.
    9991336
    10001337=item Return Values:
     
    10091346
    10101347If a preview image exists, it is not copied.  The preview image must be
    1011 transferred separately if desired.
     1348transferred separately if desired, in a separate call to L</WriteInfo>
    10121349
    10131350When simply copying all information between files of the same type, it is
     
    10151352the tags to set.
    10161353
     1354The L</Duplicates> option is always in effect for tags extracted from the
     1355source file using this routine.
     1356
     1357The L</Struct> option is enabled by default for tags extracted by this
     1358routine.  This allows the hierarchy of complex structures to be preserved
     1359when copying, but the Struct option may be set to 0 to override this
     1360behaviour and copy as flattened tags instead.
     1361
    10171362=back
    10181363
     
    103313780) ExifTool object reference
    10341379
    1035 1) Tag key or tag name
     13801) Tag name (case sensitive, may be prefixed by family 0 or 1 group name)
    10361381
    10371382=item Return Values:
    10381383
    1039 List of new Raw tag values.  The list may be empty if the tag is being
    1040 deleted (ie. if SetNewValue was called without a value).
     1384List of new Raw tag values, or first value in list when called in scalar
     1385context.  The list may be empty either if the tag isn't being written, or if
     1386it is being deleted (ie. if L</SetNewValue> was called without a value).
    10411387
    10421388=back
     
    11081454Set the file modification time from the new value of the FileModifyDate tag.
    11091455
     1456    $exifTool->SetNewValue(FileModifyDate => '2000:01:02 03:04:05-05:00',
     1457                           Protected => 1);
    11101458    $result = $exifTool->SetFileModifyDate($file);
    11111459
     
    112414721 if the time was changed, 0 if nothing was done, or -1 if there was an
    11251473error setting the time.
     1474
     1475=item Notes:
     1476
     1477Equivalent to, but more efficient than calling L</WriteInfo> when only the
     1478FileModifyDate tag has been set.  If a timezone is not specified in the
     1479FileModifyDate value, local time is assumed.  When shifting FileModifyDate,
     1480the time of the original file is used unless an optional base time is
     1481specified.
    11261482
    11271483=back
     
    11661522first valid group of this list.  This has an impact only if the group is not
    11671523specified when calling L</SetNewValue> and if the tag name exists in more
    1168 than one group.  The default order is EXIF, IPTC, XMP then MakerNotes.  Any
    1169 family 0 group name may be used.  Case is not significant.
     1524than one group.  The default order is EXIF, IPTC then XMP.  Any family 0
     1525group name may be used.  Case is not significant.
    11701526
    11711527    $exifTool->SetNewGroups('XMP','EXIF','IPTC');
     
    12081564Get the ID for the specified tag.  The ID is the IFD tag number in EXIF
    12091565information, the property name in XMP information, or the data offset in a
    1210 binary data block. For some tags, such as Composite tags where there is no ID,
    1211 an empty string is returned.
     1566binary data block.  For some tags, such as Composite tags where there is no
     1567ID, an empty string is returned.  In list context, also returns a language
     1568code for the tag if available and different from the default language (ie.
     1569with alternate language entries for XMP "lang-alt" tags).
    12121570
    12131571    $id = $exifTool->GetTagID($tag);
     1572    ($id, $lang) = $exifTool->GetTagID($tag);
    12141573
    12151574=over 4
     
    12231582=item Return Values:
    12241583
    1225 Tag ID or '' of there is no ID for this tag.
     1584In scalar context, returns the tag ID or '' if there is no ID for this tag.
     1585In list context, returns the tag ID (or '') and the language code (or
     1586undef).
    12261587
    12271588=back
     
    12301591
    12311592Get description for specified tag.  This function will always return a
    1232 defined value.  In the case where the description doesn't exist, the tag
    1233 name is returned.
     1593defined value.  In the case where the description doesn't exist, one is
     1594generated from the tag name.
    12341595
    12351596=over 4
     
    12491610=head2 GetGroup
    12501611
    1251 Get group name for specified tag.
    1252 
     1612Get group name(s) for a specified tag.
     1613
     1614    # return family 0 group name (ie. 'EXIF');
    12531615    $group = $exifTool->GetGroup($tag, 0);
    12541616
     1617    # return all groups (ie. qw{EXIF IFD0 Author Main})
     1618    @groups = $exifTool->GetGroup($tag);
     1619
     1620    # return groups as a string (ie. 'Main:IFD0:Author')
     1621    $group = $exifTool->GetGroup($tag, ':3:1:2');
     1622
     1623    # return groups as a simplified string (ie. 'IFD0:Author')
     1624    $group = $exifTool->GetGroup($tag, '3:1:2');
     1625
    12551626=over 4
    12561627
     
    126116321) Tag key
    12621633
    1263 2) [optional] Group family number
     16342) [optional] Group family number, or string of numbers separated by colons
    12641635
    12651636=item Return Values:
    12661637
    1267 Group name (or 'Other' if tag has no group).  If no group family is
    1268 specified, L</GetGroup> returns the name of the group in family 0 when
    1269 called in scalar context, or the names of groups for all families in list
    1270 context. See L</GetAllGroups> for a list of groups in each famly.
     1638Group name (or '' if tag has no group).  If no group family is specified,
     1639L</GetGroup> returns the name of the group in family 0 when called in scalar
     1640context, or the names of groups for all families in list context.  Returns a
     1641string of group names separated by colons if the input group family contains
     1642a colon.  The string is simplified to remove a leading 'Main:' and adjacent
     1643identical group names unless the family string begins with a colon.
     1644
     1645=item Notes:
     1646
     1647The group family numbers are currently available:
     1648
     1649    0) Information Type             (ie. EXIF, XMP, IPTC)
     1650    1) Specific Location            (ie. IFD0, XMP-dc)
     1651    2) Category                     (ie. Author, Time)
     1652    3) Document Number              (ie. Main, Doc1, Doc3-2)
     1653    4) Instance Number              (ie. Copy1, Copy2, Copy3...)
     1654
     1655Families 0 and 1 are based on the file structure, and are similar except
     1656that family 1 is more specific and sub-divides some groups to give more
     1657detail about the specific location where the information was found.  For
     1658example, the EXIF group is split up based on the specific IFD (Image File
     1659Directory), the MakerNotes group is divided into groups for each
     1660manufacturer, and the XMP group is separated based on the XMP namespace
     1661prefix.  Note that only common XMP namespaces are listed in the
     1662L<GetAllGroups documentation|/GetAllGroups [static]>, but additional
     1663namespaces may be present in some XMP data.  Also note that the 'XMP-xmp...'
     1664group names may appear in the older form 'XMP-xap...' since these names
     1665evolved as the XMP standard was developed.  The ICC_Profile group is broken
     1666down to give information about the specific ICC_Profile tag from which
     1667multiple values were extracted.  As well, information extracted from the
     1668ICC_Profile header is separated into the ICC-header group.
     1669
     1670Family 2 classifies information based on the logical category to which the
     1671information refers.
     1672
     1673Family 3 gives the document number for tags extracted from embedded
     1674documents, or 'Main' for tags from the main document.  (See the
     1675L</ExtractEmbedded> option for extracting tags from embedded documents.)
     1676Nested sub-documents (if they exist) are indicated by numbers separated with
     1677dashes in the group name, to an arbitrary depth. (ie. 'Doc2-3-1' is the 1st
     1678sub-sub-document of the 3rd sub-document of the 2nd embedded document of the
     1679main file.)
     1680
     1681Family 4 provides a method for differentiating tags when multiple tags exist
     1682with the same name in the same location.  The primary instance of a tag (the
     1683tag extracted when the Duplicates option is disabled and no group is
     1684specified) has no family 4 group name, but additional instances have have
     1685family 4 group names of 'Copy1', 'Copy2', 'Copy3', etc.
     1686
     1687See L</GetAllGroups [static]> for complete lists of group names.
    12711688
    12721689=back
     
    12741691=head2 GetGroups
    12751692
    1276 Get list of group names for specified information.
     1693Get list of group names that exist in the specified information.
    12771694
    12781695    @groups = $exifTool->GetGroups($info, 2);
     1696    @groups = $exifTool->GetGroups('3:1');
    12791697
    12801698=over 4
     
    128617041) [optional] Info hash ref (default is all extracted info)
    12871705
    1288 2) [optional] Group family number (default 0)
     17062) [optional] Group family number, or string of numbers (default 0)
    12891707
    12901708=item Return Values:
    12911709
    12921710List of group names in alphabetical order. If information hash is not
    1293 specified, the group names are returned for all extracted information.
     1711specified, the group names are returned for all extracted information. See
     1712L</GetGroup> for an description of family numbers and family number strings.
    12941713
    12951714=back
     
    13771796=item Inputs:
    13781797
    1379 0) [optional] Group name
     17980) [optional] Group name, or string of group names separated by colons
    13801799
    13811800=item Return Values:
    13821801
    1383 A list of all available tags in alphabetical order, or all tags in specified
    1384 group.  The group name is case insensitive, and any group in any family may
    1385 be used except for EXIF family 1 groups (ie. the specific IFD).
     1802A list of all available tags in alphabetical order, or all tags in a
     1803specified group or intersection of groups.  The group name is case
     1804insensitive, and any group in families 0-2 may be used except for EXIF
     1805family 1 groups (ie. the specific IFD).
    13861806
    13871807=back
     
    13971817=item Inputs:
    13981818
    1399 0) [optional] Group name
     18190) [optional] Group name, or string of group names separated by colons
    14001820
    14011821=item Return Values:
     
    14031823A list of all writable tags in alphabetical order.  These are the tags for
    14041824which values may be set through L</SetNewValue>.  If a group name is given,
    1405 returns only writable tags in specified group.  The group name is case
    1406 insensitive, and any group in any family may be used except for EXIF family
    1407 1 groups (ie. the specific IFD).
     1825returns only writable tags in specified group(s).  The group name is case
     1826insensitive, and any group in families 0-2 may be used except for EXIF
     1827family 1 groups (ie. the specific IFD).
    14081828
    14091829=back
     
    14191839=item Inputs:
    14201840
    1421 0) Group family number (0-2)
     18410) Group family number (0-4)
    14221842
    14231843=item Return Values:
     
    14271847=back
    14281848
    1429 Three families of groups are currently defined: 0, 1 and 2. Families 0 and 1
    1430 are based on the file structure, and family 2 classifies information based
    1431 on the logical category to which the information refers.
    1432 
    1433 Families 0 and 1 are similar except that family 1 is more specific, and
    1434 sub-divides the EXIF, MakerNotes, XMP and ICC_Profile groups to give more
    1435 detail about the specific location where the information was found.  The
    1436 EXIF group is split up based on the specific IFD (Image File Directory), the
    1437 MakerNotes group is divided into groups for each manufacturer, and the XMP
    1438 group is separated based on the XMP namespace prefix.  Note that only common
    1439 XMP namespaces are listed below but additional namespaces may be present in
    1440 some XMP data.  Also note that the 'XMP-xmp...' group names may appear in
    1441 the older form 'XMP-xap...' since these names evolved as the XMP standard
    1442 was developed.  The ICC_Profile group is broken down to give information
    1443 about the specific ICC_Profile tag from which multiple values were
    1444 extracted.  As well, information extracted from the ICC_Profile header is
    1445 separated into the ICC-header group.
    1446 
    1447 Here is a complete list of groups for each family:
     1849Here is a complete list of groups for each of these families:
    14481850
    14491851=over 4
     
    14511853=item Family 0 (Information Type):
    14521854
    1453 AFCP, AIFF, APE, APP12, APP13, APP14, APP15, APP5, APP6, APP8, ASF, BMP,
    1454 CanonVRD, Composite, DICOM, DNG, Ducky, EXIF, ExifTool, FLAC, File, Flash,
    1455 FlashPix, FotoStation, GeoTiff, HTML, ICC_Profile, ID3, IPTC, JFIF, JPEG,
    1456 Jpeg2000, Leaf, MIE, MIFF, MNG, MPC, MPEG, MakerNotes, Meta, PDF, PICT, PNG,
    1457 PhotoMechanic, Photoshop, PostScript, PrintIM, QuickTime, RAF, RIFF, Real,
    1458 SigmaRaw, Vorbis, XMP
     1855AFCP, AIFF, APE, APP0, APP12, APP13, APP14, APP15, APP4, APP5, APP6, APP8,
     1856ASF, CanonVRD, Composite, DICOM, DNG, DV, DjVu, Ducky, EXE, EXIF, ExifTool,
     1857FLAC, File, Flash, FlashPix, Font, FotoStation, GIF, GIMP, GeoTiff, H264,
     1858HTML, ICC_Profile, ID3, IPTC, ITC, JFIF, JPEG, Jpeg2000, LNK, Leaf, M2TS,
     1859MIE, MIFF, MNG, MPC, MPEG, MPF, MXF, MakerNotes, Matroska, Meta, PDF, PICT,
     1860PNG, PSP, PhotoMechanic, Photoshop, PostScript, PrintIM, QuickTime, RAF,
     1861RIFF, RSRC, RTF, Rawzor, Real, SVG, SigmaRaw, Stim, Vorbis, XML, XMP, ZIP
    14591862
    14601863=item Family 1 (Specific Location):
    14611864
    1462 AFCP, AIFF, APE, ASF, Adobe, AdobeCM, BMP, Canon, CanonCustom, CanonRaw,
    1463 CanonVRD, Casio, Composite, DICOM, DNG, Ducky, EPPIM, ExifIFD, ExifTool,
    1464 FLAC, File, Flash, FlashPix, FotoStation, FujiFilm, GPS, GeoTiff,
    1465 GlobParamIFD, GraphConv, HP, HTML, HTML-dc, HTML-ncc, HTML-prod, HTML-vw96,
    1466 HTTP-equiv, ICC-chrm, ICC-clrt, ICC-header, ICC-meas, ICC-view, ICC_Profile,
    1467 ID3, ID3v1, ID3v2_2, ID3v2_3, ID3v2_4, IFD0, IFD1, IPTC, InteropIFD, JFIF,
    1468 JPEG, JVC, Jpeg2000, Kodak, KodakBordersIFD, KodakEffectsIFD, KyoceraRaw,
    1469 Leaf, LeafSubIFD, MAC, MIE-Audio, MIE-Camera, MIE-Doc, MIE-Extender,
    1470 MIE-Flash, MIE-GPS, MIE-Geo, MIE-Image, MIE-Lens, MIE-Main, MIE-MakerNotes,
    1471 MIE-Meta, MIE-Orient, MIE-Preview, MIE-Thumbnail, MIE-UTM, MIE-Unknown,
    1472 MIE-Video, MIFF, MNG, MPC, MPEG, MakerNotes, MakerUnknown, MetaIFD, Minolta,
    1473 MinoltaRaw, Nikon, NikonCapture, NikonPreview, NikonScan, Olympus, PDF,
    1474 PICT, PNG, Panasonic, Pentax, PhotoMechanic, Photoshop, PictureInfo,
    1475 PostScript, PrintIM, QuickTime, RAF, RAF2, RIFF, RMETA, Real, Real-CONT,
    1476 Real-MDPR, Real-PROP, Real-RA3, Real-RA4, Real-RA5, Real-RJMD, Ricoh, SPIFF,
    1477 SR2, SRF#, Sanyo, Sigma, SigmaRaw, Sony, SubIFD, Track#, Vorbis, XMP,
    1478 XMP-DICOM, XMP-PixelLive, XMP-aux, XMP-cc, XMP-crs, XMP-dc, XMP-dex,
    1479 XMP-exif, XMP-iptcCore, XMP-lr, XMP-mediapro, XMP-microsoft, XMP-pdf,
    1480 XMP-photomech, XMP-photoshop, XMP-tiff, XMP-xmp, XMP-xmpBJ, XMP-xmpDM,
    1481 XMP-xmpMM, XMP-xmpPLUS, XMP-xmpRights, XMP-xmpTPg
     1865AC3, AFCP, AIFF, APE, ASF, AVI1, Adobe, AdobeCM, CIFF, Canon, CanonCustom,
     1866CanonRaw, CanonVRD, Casio, Chapter#, Composite, DICOM, DNG, DV, DjVu,
     1867DjVu-Meta, Ducky, EPPIM, EXE, EXIF, ExifIFD, ExifTool, FLAC, File, Flash,
     1868FlashPix, Font, FotoStation, FujiFilm, GE, GIF, GIMP, GPS, GeoTiff,
     1869GlobParamIFD, GraphConv, H264, HP, HTML, HTML-dc, HTML-ncc, HTML-office,
     1870HTML-prod, HTML-vw96, HTTP-equiv, ICC-chrm, ICC-clrt, ICC-header, ICC-meas,
     1871ICC-meta, ICC-view, ICC_Profile, ICC_Profile#, ID3, ID3v1, ID3v1_Enh,
     1872ID3v2_2, ID3v2_3, ID3v2_4, IFD0, IFD1, IPTC, IPTC#, ITC, InteropIFD, JFIF,
     1873JPEG, JVC, Jpeg2000, KDC_IFD, Kodak, KodakBordersIFD, KodakEffectsIFD,
     1874KodakIFD, KyoceraRaw, LNK, Leaf, LeafSubIFD, Leica, M2TS, MAC, MIE-Audio,
     1875MIE-Camera, MIE-Canon, MIE-Doc, MIE-Extender, MIE-Flash, MIE-GPS, MIE-Geo,
     1876MIE-Image, MIE-Lens, MIE-Main, MIE-MakerNotes, MIE-Meta, MIE-Orient,
     1877MIE-Preview, MIE-Thumbnail, MIE-UTM, MIE-Unknown, MIE-Video, MIFF, MNG, MPC,
     1878MPEG, MPF0, MPImage, MXF, MakerNotes, MakerUnknown, Matroska, MetaIFD,
     1879Microsoft, Minolta, MinoltaRaw, NITF, Nikon, NikonCapture, NikonCustom,
     1880NikonScan, Olympus, PDF, PICT, PNG, PSP, Panasonic, Pentax, PhotoMechanic,
     1881Photoshop, PictureInfo, PostScript, PreviewIFD, PrintIM, ProfileIFD,
     1882QuickTime, RAF, RAF2, RIFF, RMETA, RSRC, RTF, Rawzor, Real, Real-CONT,
     1883Real-MDPR, Real-PROP, Real-RA3, Real-RA4, Real-RA5, Real-RJMD, Reconyx,
     1884Ricoh, SPIFF, SR2, SR2DataIFD, SR2SubIFD, SRF#, SVG, Samsung, Sanyo,
     1885Scalado, Sigma, SigmaRaw, Sony, SonyIDC, Stim, SubIFD, System, Track#,
     1886Version0, Vorbis, XML, XMP, XMP-DICOM, XMP-MP, XMP-MP1, XMP-PixelLive,
     1887XMP-acdsee, XMP-album, XMP-aux, XMP-cc, XMP-cell, XMP-crs, XMP-dc, XMP-dex,
     1888XMP-digiKam, XMP-exif, XMP-iptcCore, XMP-iptcExt, XMP-lr, XMP-mediapro,
     1889XMP-microsoft, XMP-mwg-coll, XMP-mwg-kw, XMP-mwg-rs, XMP-pdf, XMP-pdfx,
     1890XMP-photomech, XMP-photoshop, XMP-plus, XMP-prism, XMP-prl, XMP-pur,
     1891XMP-rdf, XMP-swf, XMP-tiff, XMP-x, XMP-xmp, XMP-xmpBJ, XMP-xmpDM, XMP-xmpMM,
     1892XMP-xmpNote, XMP-xmpPLUS, XMP-xmpRights, XMP-xmpTPg, ZIP
    14821893
    14831894=item Family 2 (Category):
     
    14851896Audio, Author, Camera, Document, ExifTool, Image, Location, Other, Printing,
    14861897Time, Unknown, Video
     1898
     1899=item Family 3 (Document Number):
     1900
     1901Doc#, Main
     1902
     1903=item Family 4 (Instance Number):
     1904
     1905Copy#
    14871906
    14881907=back
     
    153119500) [optional] File name (or just an extension)
    15321951
    1533 1) [optional]  Flag to return a description instead of a type
     19521) [optional] Flag to return a description instead of a type.  Set to 0 to
     1953return type for recognized but unsupported files (otherwise the return value
     1954for unsupported files is undef).
    15341955
    15351956=item Return Value:
    15361957
    1537 A string, based on the file extension, which represents the type of file.
    1538 Returns undefined value if file type is not supported by ExifTool.  In array
    1539 context, may return more than one file type if the file may be different
    1540 formats.  Returns a list of extensions for all recognized file types if no
    1541 input extension is specified.
     1958A string, based on the file extension, which indicates the basic format of
     1959the file.  Note that some files may be based on other formats (like many RAW
     1960image formats are based on TIFF).  In array context, may return more than
     1961one file type if the file may be based on different formats.  Returns undef
     1962if files with this extension are not yet supported by ExifTool.  Returns a
     1963list of extensions for all supported file types if no input extension is
     1964specified (or all recognized file types if the description flag is set to 0).
     1965Returns a more detailed description of the specific file format when the
     1966description flag is set.
    15421967
    15431968=back
     
    15451970=head2 CanWrite [static]
    15461971
    1547 Can the specified file or file type be written?
     1972Can the specified file be written?
    15481973
    15491974    my $writable = Image::ExifTool::CanWrite($filename);
     
    15531978=item Inputs:
    15541979
    1555 0) File name, file extension, or file type
     19800) File name or extension
    15561981
    15571982=item Return Value:
    15581983
    1559 True if the specified file type can be written (edited).
     1984True if ExifTool supports writing files of this type (based on the file
     1985extension).
    15601986
    15611987=back
     
    15631989=head2 CanCreate [static]
    15641990
    1565 Can the specified file or file type be created?
     1991Can the specified file be created?
    15661992
    15671993    my $creatable = Image::ExifTool::CanCreate($filename);
     
    15711997=item Inputs:
    15721998
    1573 0) File name, file extension, or file type
     19990) File name or extension
    15742000
    15752001=item Return Value:
    15762002
    1577 True if the specified file type can be created from scratch.  Currently,
    1578 this can only be done with XMP files.
    1579 
    1580 =back
     2003True if ExifTool can create files with this extension from scratch.
     2004Currently, this can only be done with XMP, MIE, ICC, VRD and EXIF files.
     2005
     2006=back
     2007
     2008=head1 CHARACTER ENCODINGS
     2009
     2010Certain meta information formats allow coded character sets other than plain
     2011ASCII.  When reading, 8-bit encodings are passed straight through ExifTool
     2012without re-coding unless specified otherwise below, and multi-byte encodings
     2013are converted according to the L</Charset> option ('UTF8' by default).  When
     2014writing, the inverse conversions are performed.  See the L</Charset> option
     2015for a list of valid character sets.
     2016
     2017More specific details are given below about how character coding is handled
     2018for EXIF, IPTC, XMP, PNG, ID3, PDF and MIE information:
     2019
     2020=head2 EXIF
     2021
     2022Most textual information in EXIF is stored in ASCII format, and ExifTool
     2023does not convert these tags.  However it is not uncommon for applications to
     2024write UTF-8 or other encodings where ASCII is expected, and ExifTool will
     2025quite happily read/write any encoding without conversion.  For a few EXIF
     2026tags (UserComment, GPSProcessingMethod and GPSAreaInformation) the stored
     2027text may be encoded either in ASCII, Unicode (UCS-2) or JIS.  When reading
     2028these tags, Unicode and JIS are converted to the character set specified by
     2029the L</Charset> option.  Other encodings are not converted.  When writing,
     2030text is stored as ASCII unless the string contains special characters, in
     2031which case it is converted from the specified character set and stored as
     2032Unicode.  ExifTool writes Unicode in native EXIF byte ordering by default,
     2033but this may be changed by setting the ExifUnicodeByteOrder tag.  The EXIF
     2034"XP" tags (XPTitle, XPComment, etc) are always stored as little-endian
     2035Unicode, and are read and written using the specified character set.
     2036
     2037=head2 IPTC
     2038
     2039The value of the IPTC:CodedCharacterSet tag determines how the internal IPTC
     2040string values are interpreted.  If CodedCharacterSet exists and has a value
     2041of 'UTF8' (or 'ESC % G') then string values are assumed to be stored as
     2042UTF-8, otherwise Windows Latin1 (cp1252, 'Latin') coding is assumed by
     2043default, but this can be changed with the L</CharsetIPTC> option.  When
     2044reading, these strings are converted to the character set specified by the
     2045L</Charset> option.  When writing, the inverse conversions are performed.
     2046No conversion is done if the internal (IPTC) and external (ExifTool)
     2047character sets are the same.  Note that ISO 2022 character set shifting is
     2048not supported.  Instead, a warning is issued and the string is not converted
     2049if an ISO 2022 shift code is found.  See L<http://www.iptc.org/IIM/> for the
     2050official IPTC specification.
     2051
     2052=head2 XMP
     2053
     2054Exiftool reads XMP encoded as UTF-8, UTF-16 or UTF-32, and converts them all
     2055to UTF-8 internally.  Also, all XML character entity references and numeric
     2056character references are converted.  When writing, ExifTool always encodes
     2057XMP as UTF-8, converting the following 5 characters to XML character
     2058references: E<amp> E<lt> E<gt> E<39> E<quot>.  By default no further
     2059conversion is performed, however if the L</Charset> option is other than
     2060'UTF8' then text is converted to/from a specified character set when
     2061reading/writing.
     2062
     2063=head2 PNG
     2064
     2065L<PNG TextualData tags|Image::ExifTool::TagNames/"PNG TextualData Tags"> are
     2066stored as tEXt, zTXt and iTXt chunks in PNG images.  The tEXt and zTXt
     2067chunks use ISO 8859-1 encoding, while iTXt uses UTF-8.  When reading,
     2068ExifTool converts all PNG textual data to the character set specified by the
     2069L</Charset> option.  When writing, ExifTool generates a tEXt chunk (or zTXt
     2070with the L</Compress> option) if the text doesn't contain special characters
     2071or if Latin encoding is specified; otherwise an iTXt chunk is used and the
     2072text is converted from the specified character set and stored as UTF-8.
     2073
     2074=head2 ID3
     2075
     2076The ID3v1 specification officially supports only ISO 8859-1 encoding (a
     2077subset of Windows Latin1), although some applications may incorrectly use
     2078other character sets.  By default ExifTool converts ID3v1 text from Latin to
     2079the character set specified by the </Charset> option.  However, the internal
     2080ID3v1 charset may be specified with the L</CharsetID3> option.  The encoding
     2081for ID3v2 information is stored in the file, so ExifTool converts ID3v2 text
     2082from this encoding to the character set specified by the L</Charset> option.
     2083ExifTool does not currently write ID3 information.
     2084
     2085=head2 PDF
     2086
     2087PDF text strings are stored in either PDFDocEncoding (similar to Windows
     2088Latin1) or Unicode (UCS-2).  When reading, ExifTool converts to the
     2089character set specified by the L</Charset> option.  When writing, ExifTool
     2090encodes input text from the specified character set as Unicode only if the
     2091string contains special characters, otherwise PDFDocEncoding is used.
     2092
     2093=head2 MIE
     2094
     2095MIE strings are stored as either UTF-8 or ISO 8859-1. When reading, UTF-8
     2096strings are converted according to the L</Charset> option, and ISO 8859-1
     2097strings are never converted.  When writing, input strings are converted from
     2098the specified character set to UTF-8.  The resulting strings are stored as
     2099UTF-8 if they contain multi-byte UTF-8 character sequences, otherwise they
     2100are stored as ISO 8859-1.
    15812101
    15822102=head1 AUTHOR
    15832103
    1584 Copyright 2003-2007, Phil Harvey
     2104Copyright 2003-2011, Phil Harvey
    15852105
    15862106This library is free software; you can redistribute it and/or modify it
    15872107under the same terms as Perl itself.
    15882108
    1589 =head1 CREDITS
     2109=head1 ACKNOWLEDGEMENTS
    15902110
    15912111Many people have helped in the development of ExifTool through their bug
    1592 reports, comments and suggestions, and/or additions to the code.  See
    1593 html/index.html in the Image::ExifTool distribution package for a list of
     2112reports, comments and suggestions, and/or additions to the code.  See the
     2113ACKNOWLEDGEMENTS in the individual Image::ExifTool modules and in
     2114html/index.html of the Image::ExifTool distribution package for a list of
    15942115people who have contributed to this project.
    15952116
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/AFCP.pm

    r16842 r24107  
    1515use Image::ExifTool qw(:DataAccess :Utils);
    1616
    17 $VERSION = '1.02';
     17$VERSION = '1.04';
    1818
    1919sub ProcessAFCP($$);
     
    2828
    2929ExifTool will read and write (but not create) AFCP IPTC information in JPEG
    30 images, but not other image formats.
     30and TIFF images.
    3131    },
    3232    IPTC => { SubDirectory => { TagTable => 'Image::ExifTool::IPTC::Main' } },
     
    3434    Nail => {
    3535        Name => 'ThumbnailImage',
    36         ValueConv => q{
    37             my $img = substr($val, 18);
    38             return $self->ValidateImage(\$img,$tag);
     36        # (the specification allows for a variable amount of padding before
     37        #  the image after a 10-byte header, so look for the JPEG SOI marker,
     38        #  otherwise assume a fixed 8 bytes of padding)
     39        RawConv => q{
     40            pos($val) = 10;
     41            my $start = ($val =~ /\xff\xd8\xff/g) ? pos($val) - 3 : 18;
     42            my $img = substr($val, $start);
     43            return $self->ValidateImage(\$img, $tag);
    3944        },
    4045    },
    4146    PrVw => {
    4247        Name => 'PreviewImage',
    43         ValueConv => q{
    44             my $img = substr($val, 18);
    45             return $self->ValidateImage(\$img,$tag);
     48        RawConv => q{
     49            pos($val) = 10;
     50            my $start = ($val =~ /\xff\xd8\xff/g) ? pos($val) - 3 : 18;
     51            my $img = substr($val, $start);
     52            return $self->ValidateImage(\$img, $tag);
    4653        },
    4754    },
     
    252259=head1 AUTHOR
    253260
    254 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     261Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    255262
    256263This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/AIFF.pm

    r16842 r24107  
    55#
    66# Revisions:    01/06/2006 - P. Harvey Created
     7#               09/22/2008 - PH Added DjVu support
    78#
    89# References:   1) http://developer.apple.com/documentation/QuickTime/INMAC/SOUND/imsoundmgr.30.htm#pgfId=3190
     
    1819use Image::ExifTool::ID3;
    1920
    20 $VERSION = '1.01';
     21$VERSION = '1.03';
    2122
    2223# information for time/date-based tags (time zero is Jan 1, 1904)
     
    2930# AIFF info
    3031%Image::ExifTool::AIFF::Main = (
    31     PROCESS_PROC => \&Image::ExifTool::AIFF::ProcessSubChunks,
    3232    GROUPS => { 2 => 'Audio' },
    3333    NOTES => 'Only the tags decoded by ExifTool are listed in this table.',
     
    137137    my ($exifTool, $dirInfo) = @_;
    138138    my $raf = $$dirInfo{RAF};
    139     my $verbose = $exifTool->Options('Verbose');
    140     my ($buff, $err);
     139    my ($buff, $err, $tagTablePtr, $page, $type);
    141140
    142141    # verify this is a valid AIFF file
    143142    return 0 unless $raf->Read($buff, 12) == 12;
    144     return 0 unless $buff =~ /^FORM....(AIF(F|C))/s;
    145     $exifTool->SetFileType($1);
     143    my $pos = 12;
     144    # check for DjVu image
     145    if ($buff =~ /^AT&TFORM/) {
     146        # http://www.djvu.org/
     147        # http://djvu.sourceforge.net/specs/djvu3changes.txt
     148        my $buf2;
     149        return 0 unless $raf->Read($buf2, 4) == 4 and $buf2 =~ /^(DJVU|DJVM)/;
     150        $pos += 4;
     151        $buff = substr($buff, 4) . $buf2;
     152        $tagTablePtr = GetTagTable('Image::ExifTool::DjVu::Main');
     153        $exifTool->SetFileType('DJVU');
     154        # modifiy FileType to indicate a multi-page document
     155        $exifTool->{VALUE}->{FileType} .= " (multi-page)" if $buf2 eq 'DJVM';
     156        $type = 'DjVu';
     157    } else {
     158        return 0 unless $buff =~ /^FORM....(AIF(F|C))/s;
     159        $exifTool->SetFileType($1);
     160        $tagTablePtr = GetTagTable('Image::ExifTool::AIFF::Main');
     161        $type = 'AIFF';
     162    }
    146163    SetByteOrder('MM');
    147     my $tagTablePtr = GetTagTable('Image::ExifTool::AIFF::Main');
    148     my $pos = 12;
    149 #
    150 # Read chunks in AIFF image
     164#
     165# Read through the IFF chunks
    151166#
    152167    for (;;) {
     
    159174        my $len2 = $len + ($len & 0x01);
    160175        if ($tagInfo) {
    161             $raf->Read($buff, $len2) == $len2 or $err=1, last;
     176            if ($$tagInfo{TypeOnly}) {
     177                $len = $len2 = 4;
     178                $page = ($page || 0) + 1;
     179                $exifTool->VPrint(0, $exifTool->{INDENT} . "Page $page:\n");
     180            }
     181            $raf->Read($buff, $len2) >= $len or $err=1, last;
     182            unless ($$tagInfo{SubDirectory} or $$tagInfo{Binary}) {
     183                $buff =~ s/\0+$//;  # remove trailing nulls
     184            }
    162185            $exifTool->HandleTag($tagTablePtr, $tag, $buff,
    163186                DataPt => \$buff,
     
    171194        $pos += $len2;
    172195    }
    173     $err and $exifTool->Warn('Error reading AIFF file (corrupted?)');
     196    $err and $exifTool->Warn("Error reading $type file (corrupted?)");
    174197    return 1;
    175198}
     
    194217=head1 AUTHOR
    195218
    196 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     219Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    197220
    198221This library is free software; you can redistribute it and/or modify it
     
    217240
    218241=cut
    219 
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/APE.pm

    r16842 r24107  
    9696
    9797    # must first check for leading/trailing ID3 information
    98     unless ($exifTool->{DONE_ID3}) {
     98    unless ($exifTool->{DoneID3}) {
    9999        require Image::ExifTool::ID3;
    100100        Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
     
    139139        my $footPos = -32;
    140140        # (...but before the ID3v1 trailer if it exists)
    141         $footPos -= 128 if $exifTool->{DONE_ID3} == 2;
     141        $footPos -= 128 if $exifTool->{DoneID3} == 2;
    142142        $raf->Seek($footPos, 2)     or return 1;
    143143        $raf->Read($buff, 32) == 32 or return 1;
     
    231231=head1 AUTHOR
    232232
    233 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     233Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    234234
    235235This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/APP12.pm

    r16842 r24107  
    1515use Image::ExifTool qw(:DataAccess);
    1616
    17 $VERSION = '1.06';
     17$VERSION = '1.08';
    1818
    1919sub ProcessAPP12($$$);
     
    114114        Avoid => 1,
    115115        # (ignore 4-byte character count at start of value)
    116         ValueConv => '$self->Unicode2Charset(substr($val,4),"MM")',
    117         ValueConvInv => 'pack("N",length $val) . $self->Charset2Unicode($val,"MM")',
     116        ValueConv => '$self->Decode(substr($val,4),"UCS2","MM")',
     117        ValueConvInv => 'pack("N",length $val) . $self->Encode($val,"UCS2","MM")',
    118118    },
    119119    3 => { #PH
     
    123123        Groups => { 2 => 'Author' },
    124124        # (ignore 4-byte character count at start of value)
    125         ValueConv => '$self->Unicode2Charset(substr($val,4),"MM")',
    126         ValueConvInv => 'pack("N",length $val) . $self->Charset2Unicode($val,"MM")',
     125        ValueConv => '$self->Decode(substr($val,4),"UCS2","MM")',
     126        ValueConvInv => 'pack("N",length $val) . $self->Encode($val,"UCS2","MM")',
    127127    },
    128128);
     
    140140    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
    141141    my @addTags = sort { $a <=> $b } keys(%$newTags);
    142     my $verbose = $exifTool->Options('Verbose');
    143     my $out = $exifTool->Options('TextOut');
    144142    my ($dirEnd, %doneTags);
    145143    if ($dataPt) {
     
    173171        my $tagInfo = $$newTags{$tag};
    174172        if ($tagInfo) {
    175             my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
     173            my $nvHash = $exifTool->GetNewValueHash($tagInfo);
    176174            my $isNew;
    177175            if (defined $val) {
    178                 if (Image::ExifTool::IsOverwriting($newValueHash, $val)) {
    179                     if ($verbose > 1) {
    180                         my $pval = $exifTool->Printable($val);
    181                         print $out "    - Ducky:$$tagInfo{Name} = '$pval'\n";
    182                     }
     176                if (Image::ExifTool::IsOverwriting($nvHash, $val)) {
     177                    $exifTool->VerboseValue("- Ducky:$$tagInfo{Name}", $val);
    183178                    $isNew = 1;
    184179                }
    185180            } else {
    186                 next unless Image::ExifTool::IsCreating($newValueHash);
     181                next unless Image::ExifTool::IsCreating($nvHash);
    187182                $isNew = 1;
    188183            }
    189184            if ($isNew) {
    190                 $val = Image::ExifTool::GetNewValues($newValueHash);
     185                $val = Image::ExifTool::GetNewValues($nvHash);
    191186                ++$exifTool->{CHANGED};
    192187                next unless defined $val;   # next if tag is being deleted
    193                 if ($verbose > 1) {
    194                     my $pval = $exifTool->Printable($val);
    195                     print $out "    + Ducky:$$tagInfo{Name} = '$pval'\n";
    196                 }
     188                $exifTool->VerboseValue("+ Ducky:$$tagInfo{Name}", $val);
    197189            }
    198190        }
     
    283275        unless ($tagInfo) {
    284276            # add new tag to table
    285             $tagInfo = { Name => $tag };
     277            $tagInfo = { Name => ucfirst $tag };
    286278            # put in Camera group if information in "Camera" section
    287279            $$tagInfo{Groups} = { 2 => 'Camera' } if $section =~ /camera/i;
     
    313305=head1 AUTHOR
    314306
    315 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     307Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    316308
    317309This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ASF.pm

    r16842 r24107  
    77#
    88# References:   1) http://www.microsoft.com/windows/windowsmedia/format/asfspec.aspx
     9#               2) http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart3.pdf (Oct 2008)
    910#------------------------------------------------------------------------------
    1011
     
    1516use Image::ExifTool qw(:DataAccess :Utils);
    1617use Image::ExifTool::Exif;
    17 
    18 $VERSION = '1.05';
     18use Image::ExifTool::RIFF;
     19
     20$VERSION = '1.17';
    1921
    2022sub ProcessMetadata($$$);
    2123sub ProcessContentDescription($$$);
    22 sub ProcessPreview($$$);
     24sub ProcessPicture($$$);
    2325sub ProcessCodecList($$$);
    2426
     
    6365    PROCESS_PROC => \&Image::ExifTool::ASF::ProcessASF,
    6466    NOTES => q{
    65         ASF format is used by Windows WMA and WMV files.  Tag ID's aren't listed
    66         because they are huge 128-bit GUID's that would ruin the formatting of this
    67         table.
     67        The ASF format is used by Windows WMA and WMV files, and DIVX videos.  Tag
     68        ID's aren't listed because they are huge 128-bit GUID's that would ruin the
     69        formatting of this table.
    6870    },
    6971    '75B22630-668E-11CF-A6D9-00AA0062CE6C' => {
     
    7678    'FEB103F8-12AD-4C64-840F-2A1D2F7AD48C' => 'MediaIndex',
    7779    '3CB73FD0-0C4A-4803-953D-EDF7B6228F0C' => 'TimecodeIndex',
     80    'BE7ACFCB-97A9-42E8-9C71-999491E3AFAC' => { #2
     81        Name => 'XMP',
     82        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     83    },
    7884);
    7985
     
    158164    BannerImageType => {},
    159165    BannerImageURL => {},
    160     Bitrate => {},
     166    Bitrate => { PrintConv => 'ConvertBitrate($val)' },
    161167    Broadcast => {},
    162168    BufferAverage => {},
     
    165171    Copyright => { Groups => { 2 => 'Author' } },
    166172    CopyrightURL => { Groups => { 2 => 'Author' } },
    167     CurrentBitrate => {},
     173    CurrentBitrate => { PrintConv => 'ConvertBitrate($val)' },
    168174    Description => {},
    169175    DRM_ContentID => {},
     
    183189    DRM_LicenseAcqURL => {},
    184190    DRM_V1LicenseAcqURL => {},
    185     Duration => {},
     191    Duration => { PrintConv => 'ConvertDuration($val)' },
    186192    FileSize => {},
    187193    HasArbitraryDataStream => {},
     
    201207    NSC_Phone => {},
    202208    NumberOfFrames => {},
    203     OptimalBitrate => {},
     209    OptimalBitrate => { PrintConv => 'ConvertBitrate($val)' },
    204210    PeakValue => {},
    205211    Rating => {},
     
    268274    ParentalRatingReason => {},
    269275    PartOfSet => {},
    270     PeakBitrate => {},
     276    PeakBitrate => { PrintConv => 'ConvertBitrate($val)' },
    271277    Period => {},
    272278    Picture => {
    273279        SubDirectory => {
    274             TagTable => 'Image::ExifTool::ASF::Preview',
     280            TagTable => 'Image::ExifTool::ASF::Picture',
    275281        },
    276282    },
     
    313319);
    314320
    315 %Image::ExifTool::ASF::Preview = (
    316     PROCESS_PROC => \&ProcessPreview,
    317     GROUPS => { 2 => 'Video' },
     321%Image::ExifTool::ASF::Picture = (
     322    PROCESS_PROC => \&ProcessPicture,
     323    GROUPS => { 2 => 'Image' },
    318324    0 => {
    319         Name => 'PreviewType',
    320         PrintConv => {
    321             0 => 'Other picture type',
    322             1 => '32x32 PNG file icon',
    323             2 => 'Other file icon',
    324             3 => 'Front album cover',
    325             4 => 'Back album cover',
    326             5 => 'Leaflet page',
    327             6 => 'Media label',
    328             7 => 'Lead artist, performer, or soloist',
    329             8 => 'Artists or performers',
     325        Name => 'PictureType',
     326        PrintConv => { # (Note: Duplicated in ID3, ASF and FLAC modules!)
     327            0 => 'Other',
     328            1 => '32x32 PNG Icon',
     329            2 => 'Other Icon',
     330            3 => 'Front Cover',
     331            4 => 'Back Cover',
     332            5 => 'Leaflet',
     333            6 => 'Media',
     334            7 => 'Lead Artist',
     335            8 => 'Artist',
    330336            9 => 'Conductor',
    331             10 => 'Band or orchestra',
     337            10 => 'Band',
    332338            11 => 'Composer',
    333             12 => 'Lyricist or writer',
    334             13 => 'Recording studio or location',
    335             14 => 'Recording session',
     339            12 => 'Lyricist',
     340            13 => 'Recording Studio or Location',
     341            14 => 'Recording Session',
    336342            15 => 'Performance',
    337             16 => 'Capture from movie or video',
    338             17 => 'A bright colored fish',
     343            16 => 'Capture from Movie or Video',
     344            17 => 'Bright(ly) Colored Fish',
    339345            18 => 'Illustration',
    340             19 => 'Band or artist logo',
    341             20 => 'Publisher or studio logo',
     346            19 => 'Band Logo',
     347            20 => 'Publisher Logo',
    342348        },
    343349    },
    344     1 => 'PreviewMimeType',
    345     2 => 'PreviewDescription',
     350    1 => 'PictureMimeType',
     351    2 => 'PictureDescription',
    346352    3 => {
    347         Name => 'PreviewImage',
    348         ValueConv => '$self->ValidateImage(\$val,$tag)',
     353        Name => 'Picture',
     354        Binary => 1,
    349355    },
    350356);
     
    358364        ValueConv => 'Image::ExifTool::ASF::GetGUID($val)',
    359365    },
    360     16 => { Name => 'FileSize',     Format => 'int64u' },
     366    16 => { Name => 'FileLength',   Format => 'int64u' },
    361367    24 => {
    362368        Name => 'CreationDate',
     
    374380        Format => 'int64u',
    375381        ValueConv => '$val / 1e7',
    376         PrintConv => '"$val sec"',
     382        PrintConv => 'ConvertDuration($val)',
    377383    },
    378384    48 => {
     
    380386        Format => 'int64u',
    381387        ValueConv => '$val / 1e7',
    382         PrintConv => '"$val sec"',
     388        PrintConv => 'ConvertDuration($val)',
    383389    },
    384390    56 => { Name => 'Preroll',      Format => 'int64u' },
     
    386392    68 => { Name => 'MinPacketSize',Format => 'int32u' },
    387393    72 => { Name => 'MaxPacketSize',Format => 'int32u' },
    388     76 => { Name => 'MaxBitrate',   Format => 'int32u' },
     394    76 => { Name => 'MaxBitrate',   Format => 'int32u', PrintConv => 'ConvertBitrate($val)' },
    389395);
    390396
     
    414420        Format => 'int64u',
    415421        ValueConv => '$val / 1e7',
    416         PrintConv => '"$val sec"',
     422        PrintConv => '"$val s"',
    417423    },
    418424    48 => {
     
    427433            Format => 'int16u',
    428434            PrintHex => 1,
    429             # from http://www.iana.org/assignments/wave-avi-codec-registry
    430             # and http://developers.videolan.org/vlc/vlc/doc/doxygen/html/codecs_8h-source.html
    431             PrintConv => {
    432                 0x0001 => 'Microsoft PCM',
    433                 0x0002 => 'Microsoft ADPCM',
    434                 0x0003 => 'IEEE Float',
    435                 0x0004 => 'Cmpaq VSELP',
    436                 0x0005 => 'IBM CVSD',
    437                 0x0006 => 'Microsoft A-Law',
    438                 0x0007 => 'Microsoft Mu-Law',
    439                 0x0008 => 'DTS Coherent Acoustics 1',
    440                 0x0010 => 'OKI ADPCM',
    441                 0x0011 => 'Intel DVI ADPCM',
    442                 0x0012 => 'Videologic MediaSpace ADPCM',
    443                 0x0013 => 'Sierra ADPCM',
    444                 0x0014 => 'G.723 ADPCM',
    445                 0x0015 => 'DSP Solution DIGISTD',
    446                 0x0016 => 'DSP Solution DIGIFIX',
    447                 0x0017 => 'Dialogic OKI ADPCM',
    448                 0x0018 => 'MediaVision ADPCM',
    449                 0x0019 => 'HP CU',
    450                 0x0020 => 'Yamaha ADPCM',
    451                 0x0021 => 'Speech Compression Sonarc',
    452                 0x0022 => 'DSP Group True Speech',
    453                 0x0023 => 'Echo Speech EchoSC1',
    454                 0x0024 => 'Audiofile AF36',
    455                 0x0025 => 'APTX',
    456                 0x0026 => 'AudioFile AF10',
    457                 0x0027 => 'Prosody 1612',
    458                 0x0028 => 'LRC',
    459                 0x0030 => 'Dolby AC2',
    460                 0x0031 => 'GSM610',
    461                 0x0032 => 'MSNAudio',
    462                 0x0033 => 'Antex ADPCME',
    463                 0x0034 => 'Control Res VQLPC',
    464                 0x0035 => 'Digireal',
    465                 0x0036 => 'DigiADPCM',
    466                 0x0037 => 'Control Res CR10',
    467                 0x0038 => 'NMS VBXADPCM',
    468                 0x0039 => 'Roland RDAC',
    469                 0x003a => 'EchoSC3',
    470                 0x003b => 'Rockwell ADPCM',
    471                 0x003c => 'Rockwell Digit LK',
    472                 0x003d => 'Xebec',
    473                 0x0040 => 'Antex Electronics G.721',
    474                 0x0041 => 'G.728 CELP',
    475                 0x0042 => 'MSG723',
    476                 0x0045 => 'G.726 ADPCM',
    477                 0x0050 => 'MPEG',
    478                 0x0052 => 'RT24',
    479                 0x0053 => 'PAC',
    480                 0x0055 => 'MPEG Layer 3',
    481                 0x0059 => 'Lucent G.723',
    482                 0x0060 => 'Cirrus',
    483                 0x0061 => 'ESPCM',
    484                 0x0062 => 'Voxware',
    485                 0x0063 => 'Canopus Atrac',
    486                 0x0064 => 'G.726 ADPCM',
    487                 0x0066 => 'DSAT',
    488                 0x0067 => 'DSAT Display',
    489                 0x0069 => 'Voxware Byte Aligned',
    490                 0x0070 => 'Voxware AC8',
    491                 0x0071 => 'Voxware AC10',
    492                 0x0072 => 'Voxware AC16',
    493                 0x0073 => 'Voxware AC20',
    494                 0x0074 => 'Voxware MetaVoice',
    495                 0x0075 => 'Voxware MetaSound',
    496                 0x0076 => 'Voxware RT29HW',
    497                 0x0077 => 'Voxware VR12',
    498                 0x0078 => 'Voxware VR18',
    499                 0x0079 => 'Voxware TQ40',
    500                 0x0080 => 'Softsound',
    501                 0x0081 => 'Voxware TQ60',
    502                 0x0082 => 'MSRT24',
    503                 0x0083 => 'G.729A',
    504                 0x0084 => 'MVI MV12',
    505                 0x0085 => 'DF G.726',
    506                 0x0086 => 'DF GSM610',
    507                 0x0088 => 'ISIAudio',
    508                 0x0089 => 'Onlive',
    509                 0x0091 => 'SBC24',
    510                 0x0092 => 'Dolby AC3 SPDIF',
    511                 0x0097 => 'ZyXEL ADPCM',
    512                 0x0098 => 'Philips LPCBB',
    513                 0x0099 => 'Packed',
    514                 0x00FF => 'MPEG-4',
    515                 0x0100 => 'Rhetorex ADPCM',
    516                 0x0101 => 'BeCubed Software IRAT',
    517                 0x0111 => 'Vivo G.723',
    518                 0x0112 => 'Vivo Siren',
    519                 0x0123 => 'Digital G.723',
    520                 0x0160 => 'Windows Media v1',
    521                 0x0161 => 'Windows Media v2',
    522                 0x0162 => 'Windows Media 9 Professional',
    523                 0x0163 => 'Windows Media 9 Lossless',
    524                 0x0200 => 'Creative ADPCM',
    525                 0x0202 => 'Creative FastSpeech8',
    526                 0x0203 => 'Creative FastSpeech10',
    527                 0x0220 => 'Quarterdeck',
    528                 0x0300 => 'FM Towns Snd',
    529                 0x0400 => 'BTV Digital',
    530                 0x0680 => 'VME VMPCM',
    531                 0x1000 => 'OLIGSM',
    532                 0x1001 => 'OLIADPCM',
    533                 0x1002 => 'OLICELP',
    534                 0x1003 => 'OLISBC',
    535                 0x1004 => 'OLIOPR',
    536                 0x1100 => 'LH Codec',
    537                 0x1400 => 'Norris',
    538                 0x1401 => 'ISIAudio',
    539                 0x1500 => 'Soundspace Music Compression',
    540                 0x2000 => 'DVM',
    541                 0x2001 => 'DTS Coherent Acoustics 2',
    542                 0x4143 => 'MPEG-4 (Divio)',
    543             },
     435            SeparateTable => 'RIFF AudioEncoding',
     436            PrintConv => \%Image::ExifTool::RIFF::audioEncoding,
    544437        },
    545438        {
     
    624517{
    625518    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    626     my $verbose = $exifTool->Options('Verbose');
    627519    my $dataPt = $$dirInfo{DataPt};
    628520    my $dirLen = $$dirInfo{DirLen};
     
    635527        next unless $len;
    636528        return 0 if $pos + $len > $dirLen;
    637         my $val = $exifTool->Unicode2Charset(substr($$dataPt,$pos,$len),'II');
     529        my $val = $exifTool->Decode(substr($$dataPt,$pos,$len),'UCS2','II');
    638530        $exifTool->HandleTag($tagTablePtr, $tag, $val);
    639531        $pos += $len;
     
    649541{
    650542    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    651     my $verbose = $exifTool->Options('Verbose');
    652543    my $dataPt = $$dirInfo{DataPt};
    653544    my $dirLen = $$dirInfo{DirLen};
     
    681572    my @vals;
    682573    if ($format == 0) { # unicode string
    683         $vals[0] = $exifTool->Unicode2Charset(substr($$dataPt,$pos,$size),'II');
     574        $vals[0] = $exifTool->Decode(substr($$dataPt,$pos,$size),'UCS2','II');
    684575    } elsif ($format == 2) { # 4-byte boolean
    685576        @vals = ReadValue($dataPt, $pos, 'int32u', undef, $size);
     
    706597{
    707598    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    708     my $verbose = $exifTool->Options('Verbose');
    709599    my $dataPt = $$dirInfo{DataPt};
    710600    my $dirLen = $$dirInfo{DirLen};
     
    719609        $pos += 2;
    720610        return 0 if $pos + $nameLen + 4 > $dirLen;
    721         my $tag = Image::ExifTool::Unicode2Latin(substr($$dataPt,$pos,$nameLen),'v');
     611        my $tag = Image::ExifTool::Decode(undef,substr($$dataPt,$pos,$nameLen),'UCS2','II','Latin');
    722612        $tag =~ s/^WM\///; # remove leading "WM/"
    723613        $pos += $nameLen;
     
    738628# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table reference
    739629# Returns: 1 on success
    740 sub ProcessPreview($$$)
     630sub ProcessPicture($$$)
    741631{
    742632    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    743     my $verbose = $exifTool->Options('Verbose');
    744633    my $dataPt = $$dirInfo{DataPt};
    745634    my $dirStart = $$dirInfo{DirStart};
     
    755644    if ($str =~ /^((?:..)*?)\0\0((?:..)*?)\0\0/) {
    756645        my ($mime, $desc) = ($1, $2);
    757         $exifTool->HandleTag($tagTablePtr, 1, $mime);
    758         $exifTool->HandleTag($tagTablePtr, 2, $desc) if length $desc;
     646        $exifTool->HandleTag($tagTablePtr, 1, $exifTool->Decode($mime,'UCS2','II'));
     647        $exifTool->HandleTag($tagTablePtr, 2, $exifTool->Decode($desc,'UCS2','II')) if length $desc;
    759648    }
    760649    $exifTool->HandleTag($tagTablePtr, 3, substr($$dataPt, $dirStart+5+$n, $picLen));
     
    769658{
    770659    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    771     my $verbose = $exifTool->Options('Verbose');
    772660    my $dataPt = $$dirInfo{DataPt};
    773661    my $dirLen = $$dirInfo{DirLen};
     
    785673        $pos += 4;
    786674        return 0 if $pos + $nameLen + 2 > $dirLen;
    787         my $name = $exifTool->Unicode2Charset(substr($$dataPt,$pos,$nameLen),'II');
     675        my $name = $exifTool->Decode(substr($$dataPt,$pos,$nameLen),'UCS2','II');
    788676        $exifTool->HandleTag($tagTablePtr, "${type}Name", $name);
    789677        my $descLen = Get16u($dataPt, $pos + $nameLen) * 2;
    790678        $pos += $nameLen + 2;
    791679        return 0 if $pos + $descLen + 2 > $dirLen;
    792         my $desc = $exifTool->Unicode2Charset(substr($$dataPt,$pos,$descLen),'II');
     680        my $desc = $exifTool->Decode(substr($$dataPt,$pos,$descLen),'UCS2','II');
    793681        $exifTool->HandleTag($tagTablePtr, "${type}Description", $desc);
    794682        my $infoLen = Get16u($dataPt, $pos + $descLen);
     
    805693{
    806694    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    807     my $verbose = $exifTool->Options('Verbose');
    808695    my $dataPt = $$dirInfo{DataPt};
    809696    my $dirLen = $$dirInfo{DirLen};
     
    818705        $pos += 12;
    819706        return 0 if $pos + $nameLen + $dLen > $dirLen;
    820         my $tag = Image::ExifTool::Unicode2Latin(substr($$dataPt,$pos,$nameLen),'v');
     707        my $tag = Image::ExifTool::Decode(undef,substr($$dataPt,$pos,$nameLen),'UCS2','II','Latin');
    821708        my $val = ReadASF($exifTool,$dataPt,$pos+$nameLen,$dType,$dLen);
    822709        $exifTool->HandleTag($tagTablePtr, $tag, $val,
     
    841728    my $rtnVal = 0;
    842729    my $pos = 0;
    843     my ($buff, $err, @parentTable, @childEnd, %dumpParms);
    844 
    845     if ($verbose > 2) {
    846         $dumpParms{MaxLen} = 96 unless $verbose > 3;
    847         $dumpParms{Prefix} = $$exifTool{INDENT};
    848         $dumpParms{Out} = $exifTool->Options('TextOut');
    849     }
     730    my ($buff, $err, @parentTable, @childEnd);
     731
    850732    for (;;) {
    851733        last unless $raf->Read($buff, 24) == 24;
     
    856738            last unless $tag eq '75B22630-668E-11CF-A6D9-00AA0062CE6C';
    857739            my $fileType = $exifTool->{FILE_EXT};
    858             $fileType = 'ASF' unless $fileType and $fileType =~ /^(ASF|WMV|WMA)$/;
     740            $fileType = 'ASF' unless $fileType and $fileType =~ /^(ASF|WMV|WMA|DIVX)$/;
    859741            $exifTool->SetFileType($fileType);
    860742            SetByteOrder('II');
     
    868750        }
    869751        if ($size > 0x7fffffff) {
    870             $err = 'Large ASF objects not supported';
     752            if ($size > 0x7fffffff * 4294967296) {
     753                $err = 'Invalid ASF object size';
     754            } elsif ($exifTool->Options('LargeFileSupport')) {
     755                if ($raf->Seek($size, 1)) {
     756                    $exifTool->VPrint(0, "  Skipped large ASF object ($size bytes)\n");
     757                    $pos += $size;
     758                    next;
     759                }
     760                $err = 'Error seeking past large ASF object';
     761            } else {
     762                $err = 'Large ASF objects not supported (LargeFileSupport not set)';
     763            }
    871764            last;
    872765        }
     
    876769            $tagTablePtr = pop @parentTable;
    877770            $exifTool->{INDENT} = substr($exifTool->{INDENT},0,-2);
    878             $dumpParms{Prefix} = $exifTool->{INDENT};
    879771        }
    880772        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
     
    889781                        if ($verbose > 2) {
    890782                            $raf->Read($buff, $s) == $s or $err = 'Truncated file', last;
    891                             Image::ExifTool::HexDump(\$buff, undef, %dumpParms);
     783                            $exifTool->VerboseDump(\$buff);
    892784                        } elsif (not $raf->Seek($s, 1)) {
    893785                            $err = 'Seek error';
     
    901793                        if ($verbose) {
    902794                            $exifTool->{INDENT} .= '| ';
    903                             $dumpParms{Prefix} = $exifTool->{INDENT};
    904795                            $exifTool->VerboseDir($$tagInfo{Name});
    905796                        }
     
    913804                        DirName => $$tagInfo{Name},
    914805                    );
    915                     if ($verbose > 2) {
    916                         Image::ExifTool::HexDump(\$buff, undef, %dumpParms);
    917                     }
     806                    $exifTool->VerboseDump(\$buff) if $verbose > 2;
    918807                    unless ($exifTool->ProcessDirectory(\%subdirInfo, $subTable)) {
    919808                        $exifTool->Warn("Error processing $$tagInfo{Name} directory");
     
    929818        if ($verbose > 2) {
    930819            $raf->Read($buff, $size) == $size or $err = 'Truncated file', last;
    931             Image::ExifTool::HexDump(\$buff, undef, %dumpParms);
     820            $exifTool->VerboseDump(\$buff);
    932821        } elsif (not $raf->Seek($size, 1)) { # skip the block
    933822            $err = 'Seek error';
     
    960849=head1 AUTHOR
    961850
    962 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     851Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    963852
    964853This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BMP.pm

    r16842 r24107  
    1616use Image::ExifTool qw(:DataAccess :Utils);
    1717
    18 $VERSION = '1.02';
     18$VERSION = '1.07';
    1919
    2020# BMP chunks
    2121%Image::ExifTool::BMP::Main = (
    2222    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    23     GROUPS => { 2 => 'Image' },
     23    GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
    2424    NOTES => q{
    2525        There really isn't much meta information in a BMP file as such, just a bit
    2626        of image related information.
    2727    },
     28    # 0 => size of bitmap structure:
     29    #        12  bytes => 'OS/2 V1',
     30    #        40  bytes => 'Windows V3',
     31    #        64  bytes => 'OS/2 V2',
     32    #        68  bytes => some bitmap structure in AVI videos
     33    #        108 bytes => 'Windows V4',
     34    #        124 bytes => 'Windows V5',
    2835    4 => {
    2936        Name => 'ImageWidth',
     
    3239    8 => {
    3340        Name => 'ImageHeight',
    34         Format => 'int32u',
     41        Format => 'int32s', # (negative when stored in top-to-bottom order)
     42        ValueConv => 'abs($val)',
    3543    },
    3644    12 => {
     
    5462            4 => 'JPEG', #2
    5563            5 => 'PNG', #2
     64            # pass through ASCII video compression codec ID's
     65            OTHER => sub {
     66                my $val = shift;
     67                # convert non-ascii characters
     68                $val =~ s/([\0-\x1f\x7f-\xff])/sprintf('\\x%.2x',ord $1)/eg;
     69                return $val;
     70            },
    5671        },
    5772    },
     
    8095);
    8196
     97# OS/2 12-byte bitmap header (ref http://www.fileformat.info/format/bmp/egff.htm)
     98%Image::ExifTool::BMP::OS2 = (
     99    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     100    GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
     101    NOTES => 'Information extracted from OS/2-format BMP images.',
     102    # 0 => size of bitmap structure (12)
     103    4  => { Name => 'ImageWidth',  Format => 'int16u' },
     104    6  => { Name => 'ImageHeight', Format => 'int16u' },
     105    8  => { Name => 'Planes',      Format => 'int16u' },
     106    10 => { Name => 'BitDepth',    Format => 'int16u' },
     107);
     108
    82109#------------------------------------------------------------------------------
    83110# Extract EXIF information from a BMP image
     
    88115    my ($exifTool, $dirInfo) = @_;
    89116    my $raf = $$dirInfo{RAF};
    90     my $buff;
     117    my ($buff, $tagTablePtr);
    91118
    92119    # verify this is a valid BMP file
    93     return 0 unless $raf->Read($buff, 14) == 14;
     120    return 0 unless $raf->Read($buff, 18) == 18;
    94121    return 0 unless $buff =~ /^BM/;
    95     return 0 unless $raf->Read($buff, 40) == 40;
    96122    SetByteOrder('II');
    97     return 0 unless Get32u(\$buff, 0) >= 40;    # make sure info is at least 40 bytes
     123    my $len = Get32u(\$buff, 14);
     124    return 0 unless $len == 12 or $len >= 40;
     125    return 0 unless $raf->Seek(-4, 1) and $raf->Read($buff, $len) == $len;
    98126    $exifTool->SetFileType();   # set the FileType tag
    99127    my %dirInfo = (
     
    102130        DirLen => length($buff),
    103131    );
    104     my $tagTablePtr = GetTagTable('Image::ExifTool::BMP::Main');
     132    if ($len == 12) {   # old OS/2 format BMP
     133        $tagTablePtr = GetTagTable('Image::ExifTool::BMP::OS2');
     134    } else {
     135        $tagTablePtr = GetTagTable('Image::ExifTool::BMP::Main');
     136    }
    105137    $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
    106138    return 1;
     
    126158=head1 AUTHOR
    127159
    128 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     160Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    129161
    130162This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BigTIFF.pm

    r16842 r24107  
    1616use Image::ExifTool::Exif;
    1717
    18 $VERSION = '1.00';
     18$VERSION = '1.05';
    1919
    2020my $maxOffset = 0x7fffffff; # currently supported maximum data offset/size
     
    3737    # loop through IFD chain
    3838    for (;;) {
    39         if ($dirStart > $maxOffset) {
    40             $exifTool->Warn('Huge offsets not yet supported');
     39        if ($dirStart > $maxOffset and not $exifTool->Options('LargeFileSupport')) {
     40            $exifTool->Warn('Huge offsets not supported (LargeFileSupport not set)');
    4141            last;
    4242        }
     
    6565        $raf->Read($nextIFD, 8) == 8 or undef $nextIFD; # try to read next IFD pointer
    6666        if ($htmlDump) {
    67             $exifTool->HtmlDump($bufPos-8, 8, "$dirName entries", "Entry count: $numEntries");
     67            $exifTool->HDump($bufPos-8, 8, "$dirName entries", "Entry count: $numEntries");
    6868            if (defined $nextIFD) {
    6969                my $tip = sprintf("Offset: 0x%.8x", Image::ExifTool::Get64u(\$nextIFD, 0));
    70                 $exifTool->HtmlDump($bufPos + 20 * $numEntries, 8, "Next IFD", $tip, 0);
     70                $exifTool->HDump($bufPos + 20 * $numEntries, 8, "Next IFD", $tip, 0);
    7171            }
    7272        }
     
    7979            my $formatSize = $Image::ExifTool::Exif::formatSize[$format];
    8080            unless (defined $formatSize) {
    81                 $exifTool->HtmlDump($bufPos+$entry,20,"[invalid IFD entry]",
     81                $exifTool->HDump($bufPos+$entry,20,"[invalid IFD entry]",
    8282                         "Bad format value: $format", 1);
    8383                # warn unless the IFD was just padded with zeros
     
    8888            my $size = $count * $formatSize;
    8989            my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
    90             next unless $tagInfo or $verbose;
     90            next unless defined $tagInfo or $verbose;
    9191            my $valuePtr = $entry + 12;
    9292            my ($valBuff, $valBase);
    9393            if ($size > 8) {
    9494                if ($size > $maxOffset) {
    95                     $exifTool->Warn("Can't yet handle $dirName entry $index (huge size)");
     95                    $exifTool->Warn("Can't handle $dirName entry $index (huge size)");
    9696                    next;
    9797                }
    9898                $valuePtr = Image::ExifTool::Get64u(\$dirBuff, $valuePtr);
    99                 if ($valuePtr > $maxOffset) {
    100                     $exifTool->Warn("Can't yet handle $dirName entry $index (huge offset)");
     99                if ($valuePtr > $maxOffset and not $exifTool->Options('LargeFileSupport')) {
     100                    $exifTool->Warn("Can't handle $dirName entry $index (LargeFileSupport not set)");
    101101                    next;
    102102                }
     
    110110                $valBase = $bufPos;
    111111            }
     112            if (defined $tagInfo and not $tagInfo) {
     113                # GetTagInfo() required the value for a Condition
     114                $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$valBuff);
     115            }
    112116            my $val = ReadValue(\$valBuff, 0, $formatStr, $count, $size);
    113117            if ($htmlDump) {
     118                my $tval = $val;
     119                if ($formatStr =~ /^rational64([su])$/) {
     120                    # show numerator/denominator separately
     121                    my $f = ReadValue(\$valBuff, 0, "int32$1", $count*2, $size);
     122                    $f =~ s/(-?\d+) (-?\d+)/$1\/$2/g;
     123                    $tval .= " ($f)";
     124                }
    114125                my ($tagName, $colName);
    115126                if ($tagID == 0x927c and $dirName eq 'ExifIFD') {
     
    122133                my $dname = sprintf("$dirName-%.2d", $index);
    123134                # build our tool tip
    124                 my $tip = sprintf("Tag ID: 0x%.4x\\n", $tagID) .
    125                           "Format: $formatStr\[$count]\\nSize: $size bytes\\n";
     135                my $tip = sprintf("Tag ID: 0x%.4x\n", $tagID) .
     136                          "Format: $formatStr\[$count]\nSize: $size bytes\n";
    126137                if ($size > 8) {
    127                     $tip .= sprintf("Value offset: 0x%.8x\\n", $valuePtr);
     138                    $tip .= sprintf("Value offset: 0x%.8x\n", $valuePtr);
    128139                    $colName = "<span class=H>$tagName</span>";
    129140                } else {
    130141                    $colName = $tagName;
    131142                }
    132                 my $tval = (length $val < 32) ? $val : substr($val,0,28) . '[...]';
     143                $tval = substr($tval,0,28) . '[...]' if length($tval) > 32;
    133144                if ($formatStr =~ /^(string|undef|binary)/) {
    134                     # translate all characters that could mess up JavaScript
    135                     $tval =~ tr/\\\x00-\x1f\x7f-\xff/./;
    136                     $tval =~ tr/"/'/;
    137                     $tval = "$tval";
     145                    # translate non-printable characters
     146                    $tval =~ tr/\x00-\x1f\x7f-\xff/./;
    138147                } elsif ($tagInfo and Image::ExifTool::IsInt($tval)) {
    139148                    if ($$tagInfo{IsOffset}) {
     
    144153                }
    145154                $tip .= "Value: $tval";
    146                 $exifTool->HtmlDump($entry+$bufPos, 20, "$dname $colName", $tip, 1);
     155                $exifTool->HDump($entry+$bufPos, 20, "$dname $colName", $tip, 1);
    147156                if ($size > 8) {
    148157                    # add value data block
    149158                    my $flg = ($tagInfo and $$tagInfo{SubDirectory} and $$tagInfo{MakerNotes}) ? 4 : 0;
    150                     $exifTool->HtmlDump($valuePtr,$size,"$tagName value",'SAME', $flg);
     159                    $exifTool->HDump($valuePtr,$size,"$tagName value",'SAME', $flg);
    151160                }
    152161            }
     
    189198                    RAF     => $raf,
    190199                );
    191                 $tagKey and $exifTool->SetGroup1($tagKey, $dirName);
     200                $tagKey and $exifTool->SetGroup($tagKey, $dirName);
    192201            }
    193202        }
     
    222231    if ($exifTool->{HTML_DUMP}) {
    223232        my $o = (GetByteOrder() eq 'II') ? 'Little' : 'Big';
    224         $exifTool->HtmlDump(0, 8, "BigTIFF header", "Byte order: $o endian", 0);
    225         $exifTool->HtmlDump(8, 8, "IFD0 pointer", sprintf("Offset: 0x%.8x",$offset), 0);
     233        $exifTool->HDump(0, 8, "BigTIFF header", "Byte order: $o endian", 0);
     234        $exifTool->HDump(8, 8, "IFD0 pointer", sprintf("Offset: 0x%.8x",$offset), 0);
    226235    }
    227236    my %dirInfo = (
     
    256265=head1 AUTHOR
    257266
    258 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     267Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    259268
    260269This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BuildTagLookup.pm

    r16842 r24107  
    1919BEGIN {
    2020    # prevent ExifTool from loading the user config file
    21     $Image::ExifTool::noConfig = 1;
     21    $Image::ExifTool::configFile = '';
     22    $Image::ExifTool::debug = 1; # enabled debug messages
    2223}
    2324
    2425use vars qw($VERSION @ISA);
    2526use Image::ExifTool qw(:Utils :Vars);
     27use Image::ExifTool::Exif;
    2628use Image::ExifTool::Shortcuts;
    2729use Image::ExifTool::HTML qw(EscapeHTML);
    2830use Image::ExifTool::IPTC;
     31use Image::ExifTool::XMP;
    2932use Image::ExifTool::Canon;
    3033use Image::ExifTool::Nikon;
    3134
    32 $VERSION = '1.59';
     35$VERSION = '2.28';
    3336@ISA = qw(Exporter);
    3437
    3538sub NumbersFirst;
     39
     40my $numbersFirst = 1;   # set to -1 to sort numbers last
     41
     42# list of all tables in plug-in modules
     43my @pluginTables = ('Image::ExifTool::MWG::Composite');
    3644
    3745# colors for html pages
     
    4351};
    4452
     53my $homePage = 'http://owl.phy.queensu.ca/~phil/exiftool';
     54
     55# list of all recognized Format strings
     56# (not a complete list, but this is all we use so far)
     57# (also, formats like "var_X[Y]" are allowed for any valid X)
     58my %formatOK = (
     59    %Image::ExifTool::Exif::formatNumber,
     60    0 => 1,
     61    1 => 1,
     62    real    => 1,
     63    integer => 1,
     64    date    => 1,
     65    boolean => 1,
     66    rational  => 1,
     67   'lang-alt' => 1,
     68    fixed16u => 1,
     69    fixed16s => 1,
     70    fixed32u => 1,
     71    fixed32s => 1,
     72    extended => 1,
     73    resize   => 1,
     74    digits   => 1,
     75    int16uRev => 1,
     76    rational32u => 1,
     77    rational32s => 1,
     78    var_string  => 1,
     79    var_int16u  => 1,
     80    var_pstr32  => 1,
     81    # Matroska
     82    signed      => 1,
     83    unsigned    => 1,
     84    utf8        => 1,
     85);
    4586
    4687my $caseInsensitive;    # flag to ignore case when sorting tag names
    4788
    4889# Descriptions for the TagNames documentation
     90# (descriptions may also be defined in tag table NOTES)
    4991# Note: POD headers in these descriptions start with '~' instead of '=' to keep
    5092# from confusing POD parsers which apparently parse inside quoted strings.
     
    58100
    59101This document contains a complete list of ExifTool tag names, organized into
    60 tables based on information type.  Tag names are used to indicate the
    61 specific meta information that is extracted or written in an image.
     102tables based on information type.  Tag names are used to reference specific
     103meta information extracted from or written to a file.
    62104
    63105~head1 TAG TABLES
     
    77119tag ID.  In these cases, the actual name used depends on the context in
    78120which the information is found.  Case is not significant for tag names.  A
    79 question mark after a tag name indicates that the information is either not
    80 understood, not verified, or not very useful -- these tags are not extracted
    81 by ExifTool unless the Unknown (-u) option is enabled.  Be aware that some
    82 tag names are different than the descriptions printed out by default when
    83 extracting information with exiftool.  To see the tag names instead of the
    84 descriptions, use C<exiftool -s>.
     121question mark (C<?>) after a tag name indicates that the information is
     122either not understood, not verified, or not very useful -- these tags are
     123not extracted by ExifTool unless the Unknown (-u) option is enabled.  Be
     124aware that some tag names are different than the descriptions printed out by
     125default when extracting information with exiftool.  To see the tag names
     126instead of the descriptions, use C<exiftool -s>.
    85127
    86128The B<Writable> column indicates whether the tag is writable by ExifTool.
     
    93135(including a null terminator which is added if required).
    94136
    95 An asterisk (C<*>) after an entry in the B<Writable> column indicates a
    96 "protected" tag which is not writable directly, but is set via a Composite
    97 tag.  A tilde (C<~>) indicates a tag this is only writable when print
    98 conversion is disabled (by setting PrintConv to 0, or using the -n option).
    99 A slash (C</>) indicates an "avoided" tag that is not created unless the
    100 group is specified (due to name conflicts with other tags).  An exclamation
    101 point (C<!>) indicates a tag that is considered unsafe to write under normal
    102 circumstances.  These "unsafe" tags are not set when calling
    103 SetNewValuesFromFile() or when using the exiftool -TagsFromFile option
    104 unless specified explicitly, and care should be taken when editing them
    105 manually since they may affect the way an image is rendered.  A plus sign
    106 (C<+>) indicates a "list" tag which supports multiple instances.
    107 
    108 The HTML version of these tables also list possible B<Values> for
    109 discrete-valued tags, as well as B<Notes> for some tags.
     137A plus sign (C<+>) after an entry in the B<Writable> column indicates a
     138"list" tag which supports multiple values and allows individual values to be
     139added and deleted.  A slash (C</>) indicates an "avoided" tag that is not
     140created when writing if another same-named tag may be created instead.  To
     141write these tags, the group should be specified.  A tilde (C<~>) indicates a
     142tag this is writable only when the print conversion is disabled (by setting
     143PrintConv to 0, using the -n option, or suffixing the tag name with a C<#>
     144character).  An exclamation point (C<!>) indicates a tag that is considered
     145unsafe to write under normal circumstances.  These "unsafe" tags are not set
     146when calling SetNewValuesFromFile() or copied with the exiftool
     147-tagsFromFile option unless specified explicitly, and care should be taken
     148when editing them manually since they may affect the way an image is
     149rendered.  An asterisk (C<*>) indicates a "protected" tag which is not
     150writable directly, but is written automatically by ExifTool (often when a
     151corresponding Composite or Extra tag is written).  A colon (C<:>) indicates
     152a mandatory tag which may be added automatically when writing.
     153
     154The HTML version of these tables also lists possible B<Values> for
     155discrete-valued tags, as well as B<Notes> for some tags.  The B<Values> are
     156listed as the computer-readable and human-readable values on the left and
     157right hand side of an equals sign (C<=>) respectively.  The human-readable
     158values are used by default when reading and writing, but the
     159computer-readable values may be accessed by disabling the value conversion
     160with the -n option on the command line, by setting the ValueConv option to 0
     161in the API, or or on a per-tag basis by appending a number symbol (C<#>) to
     162the tag name.
    110163
    111164B<Note>: If you are familiar with common meta-information tag names, you may
     
    119172EXIF stands for "Exchangeable Image File Format".  This type of information
    120173is formatted according to the TIFF specification, and may be found in JPG,
    121 TIFF, PNG, MIFF and WDP images, as well as many TIFF-based RAW images.
     174TIFF, PNG, PGF, MIFF, HDP, PSP and XCF images, as well as many TIFF-based
     175RAW images, and even some AVI and MOV videos.
    122176
    123177The EXIF meta information is organized into different Image File Directories
     
    126180B<Group> listed below is used unless another group is specified.
    127181
    128 Also listed in the table below are TIFF, DNG, WDP and other tags which are
    129 not part of the EXIF specification, but may co-exist with EXIF tags in some
    130 images.
     182The table below lists all EXIF tags.  Also listed are TIFF, DNG, HDP and
     183other tags which are not part of the EXIF specification, but may co-exist
     184with EXIF tags in some images.  Tags which are part of the EXIF 2.3
     185specification have an underlined B<Tag Name> in the HTML version of this
     186documentation.  See
     187L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-008-2010_E.pdf> for the
     188official EXIF 2.3 specification.
    131189},
    132190    GPS => q{
     
    144202automatically by ExifTool.  Remember that the descriptive values are used
    145203when writing (ie. 'Above Sea Level', not '0') unless the print conversion is
    146 disabled (with '-n' on the command line, or the PrintConv option in the
    147 API).
     204disabled (with '-n' on the command line or the PrintConv option in the API,
     205or by suffixing the tag name with a C<#> character).
     206
     207When adding GPS information to an image, it is important to set all of the
     208following tags: GPSLatitude, GPSLatitudeRef, GPSLongitude, GPSLongitudeRef,
     209GPSAltitude and GPSAltitudeRef.  ExifTool will write the required
     210GPSVersionID tag automatically if new a GPS IFD is added to an image.
    148211},
    149212    XMP => q{
    150213XMP stands for "Extensible Metadata Platform", an XML/RDF-based metadata
    151214format which is being pushed by Adobe.  Information in this format can be
    152 embedded in many different image file types including JPG, JP2, TIFF, PNG,
    153 MIFF, PS, PDF, PSD and DNG, as well as audio file formats supporting ID3v2
    154 information.
     215embedded in many different image file types including JPG, JP2, TIFF, GIF,
     216EPS, PDF, PSD, IND, PNG, DJVU, SVG, PGF, MIFF, XCF, CRW, DNG and a variety
     217of proprietary TIFF-based RAW images, as well as MOV, AVI, ASF, WMV, FLV,
     218SWF and MP4 videos, and WMA and audio formats supporting ID3v2 information.
    155219
    156220The XMP B<Tag ID>'s aren't listed because in most cases they are identical
    157 to the B<Tag Name>.
     221to the B<Tag Name> (aside from differences in case).  Tags with different
     222ID's are mentioned in the B<Notes> column of the HTML version of this
     223document.
    158224
    159225All XMP information is stored as character strings.  The B<Writable> column
    160 specifies the information format:  C<integer> is a string of digits
    161 (possibly beginning with a '+' or '-'), C<real> is a floating point number,
    162 C<rational> is two C<integer> strings separated by a '/' character, C<date>
    163 is a date/time string in the format "YYYY:MM:DD HH:MM:SS[+/-HH:MM]",
    164 C<boolean> is either "True" or "False", and C<lang-alt> is a list of string
    165 alternatives in different languages.
     226specifies the information format:  C<string> is an unformatted string,
     227C<integer> is a string of digits (possibly beginning with a '+' or '-'),
     228C<real> is a floating point number, C<rational> is entered as a floating
     229point number but stored as two C<integer> strings separated by a '/'
     230character, C<date> is a date/time string entered in the format "YYYY:mm:dd
     231HH:MM:SS[.ss][+/-HH:MM]", C<boolean> is either "True" or "False",
     232C<lang-alt> indicates that the tag supports alternate languages (see below),
     233and C<struct> is an XMP structure.  When reading, structures are extracted
     234only if the Struct (-struct) option is used.  Otherwise the corresponding
     235"flattened" tags, indicated by an underline (C<_>) after the B<Writable>
     236type, are extracted.  When copying information, the Struct option is in
     237effect by default.  When writing, the Struct option has no effect, and both
     238structured and flattened tags may be written.  See
     239L<http://owl.phy.queensu.ca/~phil/exiftool/struct.html> for more details.
    166240
    167241Individual languages for C<lang-alt> tags are accessed by suffixing the tag
    168242name with a '-', followed by an RFC 3066 language code (ie. "XMP:Title-fr",
    169 or "Rights-en-US").  A C<lang-alt> tag with no language code accesses the
    170 "x-default" language, but causes other languages to be deleted when writing.
    171 The "x-default" language code may be specified when writing a new value to
    172 write only the default language, but note that all languages are still
    173 deleted if "x-default" tag is deleted.  When reading, "x-default" is not
    174 specified.
     243or "Rights-en-US").  (See L<http://www.ietf.org/rfc/rfc3066.txt> for the RFC
     2443066 specification.)  A C<lang-alt> tag with no language code accesses the
     245"x-default" language, but causes other languages for this tag to be deleted
     246when writing.  The "x-default" language code may be specified when writing
     247to preserve other existing languages (ie. "XMP-dc:Description-x-default").
     248When reading, "x-default" is not specified.
    175249
    176250The XMP tags are organized according to schema B<Namespace> in the following
     
    180254more than one namespace, less common namespaces are avoided when writing.
    181255However, any namespace may be written by specifying a family 1 group name
    182 for the tag, ie) XMP-exif:Contrast or XMP-crs:Contrast.
     256for the tag, ie) XMP-exif:Contrast or XMP-crs:Contrast.  When deciding on
     257which tags to add to an image, using standard schemas such as
     258L<dc|/XMP dc Tags>, L<xmp|/XMP xmp Tags> or L<iptc|/XMP iptcCore Tags> is
     259recommended if possible.
     260
     261For structures, the heading of the first column is B<Field Name>.  Field
     262names are very similar to tag names, except they are used to identify fields
     263inside structures instead of stand-alone tags.  See
     264L<the Field Name section of the Structured Information documentation|http://owl.phy.queensu.ca/~phil/exiftool/struct.html#Fields> for more
     265details.
    183266
    184267ExifTool will extract XMP information even if it is not listed in these
    185268tables.  For example, the C<pdfx> namespace doesn't have a predefined set of
    186269tag names because it is used to store application-defined PDF information,
    187 but this information is extracted by ExifTool anyway.
     270but this information is extracted by ExifTool.
     271
     272See L<http://www.adobe.com/devnet/xmp/> for the official XMP specification.
    188273},
    189274    IPTC => q{
    190 IPTC stands for "International Press Telecommunications Council".  This is
    191 an older meta information format that is slowly being phased out in favor of
    192 XMP.  IPTC information may be embedded in JPG, TIFF, PNG, MIFF, PS, PDF, PSD
    193 and DNG images.
    194 
    195 The IPTC specification dictates a length for ASCII (C<string> or C<digits>)
    196 values.  These lengths are given in square brackets after the B<Writable>
    197 format name.  For tags where a range of lengths is allowed, the minimum and
    198 maximum lengths are separated by a comma within the brackets.  IPTC strings
    199 are not null terminated.
     275The tags listed below are part of the International Press Telecommunications
     276Council (IPTC) and the Newspaper Association of America (NAA) Information
     277Interchange Model (IIM).  This is an older meta information format, slowly
     278being phased out in favor of XMP.  (In fact, the newer IPTCCore
     279specification actually uses XMP format!)  IPTC information may be embedded
     280in JPG, TIFF, PNG, MIFF, PS, PDF, PSD, XCF and DNG images.
    200281
    201282IPTC information is separated into different records, each of which has its
    202 own set of tags.
     283own set of tags.  See
     284L<http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf> for the
     285official specification.
     286
     287This specification dictates a length for ASCII (C<string> or C<digits>) and
     288binary (C<undef>) values.  These lengths are given in square brackets after
     289the B<Writable> format name.  For tags where a range of lengths is allowed,
     290the minimum and maximum lengths are separated by a comma within the
     291brackets.  IPTC strings are not null terminated.  When writing, ExifTool
     292issues a minor warning and truncates the value if it is longer than allowed
     293by the IPTC specification. Minor errors may be ignored with the
     294IgnoreMinorErrors (-m) option, allowing longer values to be written, but
     295beware that values like this may cause problems for some other IPTC readers.
     296
     297Separate IPTC date and time tags may be written with a combined date/time
     298value and ExifTool automagically takes the appropriate part of the date/time
     299string depending on whether a date or time tag is being written.  This is
     300very useful when copying date/time values to IPTC from other metadata
     301formats.
     302
     303IPTC time values include a timezone offset.  If written with a value which
     304doesn't include a timezone then the current local timezone offset is used
     305(unless written with a combined date/time, in which case the local timezone
     306offset at the specified date/time is used, which may be different due to
     307changes in daylight savings time).
    203308},
    204309    Photoshop => q{
    205 Photoshop tags are found in PSD files, as well as inside embedded Photoshop
    206 information in many other file types (JPEG, TIFF, PDF, PNG to name a few).
     310Photoshop tags are found in PSD and PSB files, as well as inside embedded
     311Photoshop information in many other file types (JPEG, TIFF, PDF, PNG to name
     312a few).
    207313
    208314Many Photoshop tags are marked as Unknown (indicated by a question mark
    209315after the tag name) because the information they provide is not very useful
    210 under normal circumstances (and because Adobe denied my application for
     316under normal circumstances I<[and because Adobe denied my application for
    211317their file format documentation -- apparently open source software is too
    212 big a concept for them).  These unknown tags are not extracted unless the
     318big a concept for them]>.  These unknown tags are not extracted unless the
    213319Unknown (-u) option is used.
    214320},
     
    217323been decoded.  Use the Unknown (-u) option to extract PrintIM information.
    218324},
     325    GeoTiff => q{
     326ExifTool extracts the following tags from GeoTIFF images.  See
     327L<http://www.remotesensing.org/geotiff/spec/geotiffhome.html> for the
     328complete GeoTIFF specification.
     329},
     330    JFIF => q{
     331The following information is extracted from the JPEG JFIF header.  See
     332L<http://www.jpeg.org/public/jfif.pdf> for the JFIF 1.02 specification.
     333},
    219334    Kodak => q{
    220 The Kodak maker notes aren't in standard IFD format, and the format varies
    221 frequently with different models.  Some information has been decoded, but
    222 much of the Kodak information remains unknown.
     335Many Kodak models don't store the maker notes in standard IFD format, and
     336these formats vary with different models.  Some information has been
     337decoded, but much of the Kodak information remains unknown.
    223338},
    224339    'Kodak SpecialEffects' => q{
     
    227342},
    228343    Minolta => q{
    229 These tags are used by Minolta and Konica/Minolta cameras.  Minolta doesn't
    230 make things easy for decoders because the meaning of some tags and the
    231 location where some information is stored is different for different camera
    232 models.  (Take MinoltaQuality for example, which may be located in 5
    233 different places.)
     344These tags are used by Minolta, Konica/Minolta as well as some Sony cameras.
     345Minolta doesn't make things easy for decoders because the meaning of some
     346tags and the location where some information is stored is different for
     347different camera models.  (Take MinoltaQuality for example, which may be
     348located in 5 different places.)
    234349},
    235350    Olympus => q{
     
    239354},
    240355    Panasonic => q{
    241 Panasonic tags are also used for Leica cameras.
     356These tags are used in Panasonic/Leica cameras.
    242357},
    243358    Pentax => q{
    244 The Pentax tags are also used in Asahi cameras.
     359These tags are used in Pentax/Asahi cameras.
    245360},
    246361    Sigma => q{
     
    248363},
    249364    Sony => q{
    250 The maker notes in images from current Sony camera models contain a wealth
    251 of information, but very little is known about these tags.  Use the ExifTool
    252 Unknown (-u) or Verbose (-v) options to see information about the unknown
    253 tags.
     365The maker notes in images from most recent Sony camera models contain a
     366wealth of information, but for some models very little has been decoded.
     367Use the ExifTool Unknown (-u) or Verbose (-v) options to see information
     368about the unknown tags.  Also see the Minolta tags which are used by some
     369Sony models.
    254370},
    255371    CanonRaw => q{
     
    259375or padded as required) unless B<Writable> is C<resize>. Currently, only
    260376JpgFromRaw and ThumbnailImage are allowed to change size.
     377
     378CRW images also support the addition of a CanonVRD trailer, which in turn
     379supports XMP.  This trailer is created automatically if necessary when
     380ExifTool is used to write XMP to a CRW image.
    261381},
    262382    Unknown => q{
     
    267387The tags listed in the PDF tables below are those which are used by ExifTool
    268388to extract meta information, but they are only a small fraction of the total
    269 number of available PDF tags.
     389number of available PDF tags.  See
     390L<http://www.adobe.com/devnet/pdf/pdf_reference.html> for the official PDF
     391specification.
     392
     393ExifTool supports reading and writing PDF documents up to version 1.7
     394extension level 3, including support for RC4, AES-128 and AES-256
     395encryption.  A Password option is provided to allow processing of
     396password-protected PDF files.
     397
     398When writing PDF files, ExifTool uses an incremental update.  This has the
     399advantages of being fast and reversible.  The original PDF can be easily
     400recovered by deleting the C<PDF-update> pseudo-group (with
     401C<-PDF-update:all=> on the command line).  But there are two main
     402disadvantages to this technique:
     403
     4041) A linearized PDF file is no longer linearized after the update, so it
     405must be subsequently re-linearized if this is required.
     406
     4072) All metadata edits are reversible.  While this would normally be
     408considered an advantage, it is a potential security problem because old
     409information is never actually deleted from the file.
    270410},
    271411    DNG => q{
    272412The main DNG tags are found in the EXIF table.  The tables below define only
    273 information found within structures of these main DNG tag values.
     413information found within structures of these main DNG tag values.  See
     414L<http://www.adobe.com/products/dng/> for the official DNG specification.
    274415},
    275416    MPEG => q{
     
    284425},
    285426    Extra => q{
    286 The extra tags represent information found in the image but not associated
    287 with any other tag group.  The three writable "pseudo" tags (Filename,
    288 Directory and FileModifyDate) may be written without the need to rewrite the
    289 file since their values are not contained within the file data.
     427The extra tags represent extra information extracted or generated by
     428ExifTool that is not directly associated with another tag group.  The three
     429writable "pseudo" tags (FileName, Directory and FileModifyDate) may be
     430written without the need to rewrite the file since their values are not
     431contained within the file data.  These "pseudo" tags belong to the family 1
     432"System" group.
    290433},
    291434    Composite => q{
    292 The values of the composite tags are derived from the values of other tags.
    293 These are convenience tags which are calculated after all other information
    294 is extracted.
     435The values of the composite tags are B<Derived From> the values of other
     436tags.  These are convenience tags which are calculated after all other
     437information is extracted.
    295438},
    296439    Shortcuts => q{
     
    300443
    301444The shortcut tags below have been pre-defined, but user-defined shortcuts
    302 may be added via the %Image::ExifTool::Shortcuts::UserDefined lookup in the
     445may be added via the %Image::ExifTool::UserDefined::Shortcuts lookup in the
    303446~/.ExifTool_config file.  See the Image::ExifTool::Shortcuts documentation
    304447for more details.
     
    312455~head1 AUTHOR
    313456
    314 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     457Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    315458
    316459This library is free software; you can redistribute it and/or modify it
     
    325468);
    326469
     470# notes for Shortcuts tags
     471my %shortcutNotes = (
     472    MakerNotes => q{
     473        useful when copying tags between files to either copy the maker notes as a
     474        block or prevent it from being copied
     475    },
     476    CommonIFD0 => q{
     477        common metadata tags found in IFD0 of TIFF-format images.  Used to simpify
     478        deletion of all metadata from these images.  See FAQ number 7 for details
     479    },
     480    Unsafe => q{
     481        "unsafe" tags in JPEG images which are normally not copied.  Defined here
     482        as a shortcut to use when rebuilding JPEG EXIF from scratch
     483    },
     484);
     485
     486
     487
     488# EXIF table tag ID's which are part of the EXIF 2.3 specification
     489# (used only to add underlines in HTML version of EXIF Tag Table)
     490my %exifSpec = (
     491    0x100 => 1,  0x212 => 1,   0x9204 => 1,  0xa217 => 1,
     492    0x101 => 1,  0x213 => 1,   0x9205 => 1,  0xa300 => 1,
     493    0x102 => 1,  0x214 => 1,   0x9206 => 1,  0xa301 => 1,
     494    0x103 => 1,  0x8298 => 1,  0x9207 => 1,  0xa302 => 1,
     495    0x106 => 1,  0x829a => 1,  0x9208 => 1,  0xa401 => 1,
     496    0x10e => 1,  0x829d => 1,  0x9209 => 1,  0xa402 => 1,
     497    0x10f => 1,  0x8769 => 1,  0x920a => 1,  0xa403 => 1,
     498    0x110 => 1,  0x8822 => 1,  0x9214 => 1,  0xa404 => 1,
     499    0x111 => 1,  0x8824 => 1,  0x927c => 1,  0xa405 => 1,
     500    0x112 => 1,  0x8825 => 1,  0x9286 => 1,  0xa406 => 1,
     501    0x115 => 1,  0x8827 => 1,  0x9290 => 1,  0xa407 => 1,
     502    0x116 => 1,  0x8828 => 1,  0x9291 => 1,  0xa408 => 1,
     503    0x117 => 1,  0x8830 => 1,  0x9292 => 1,  0xa409 => 1,
     504    0x11a => 1,  0x8831 => 1,  0xa000 => 1,  0xa40a => 1,
     505    0x11b => 1,  0x8832 => 1,  0xa001 => 1,  0xa40b => 1,
     506    0x11c => 1,  0x8833 => 1,  0xa002 => 1,  0xa40c => 1,
     507    0x128 => 1,  0x8834 => 1,  0xa003 => 1,  0xa420 => 1,
     508    0x12d => 1,  0x8835 => 1,  0xa004 => 1,  0xa430 => 1,
     509    0x131 => 1,  0x9000 => 1,  0xa005 => 1,  0xa431 => 1,
     510    0x132 => 1,  0x9003 => 1,  0xa20b => 1,  0xa432 => 1,
     511    0x13b => 1,  0x9004 => 1,  0xa20c => 1,  0xa433 => 1,
     512    0x13e => 1,  0x9101 => 1,  0xa20e => 1,  0xa434 => 1,
     513    0x13f => 1,  0x9102 => 1,  0xa20f => 1,  0xa435 => 1,
     514    0x201 => 1,  0x9201 => 1,  0xa210 => 1,
     515    0x202 => 1,  0x9202 => 1,  0xa214 => 1,
     516    0x211 => 1,  0x9203 => 1,  0xa215 => 1,
     517);
     518# same thing for RIFF INFO tags found in the EXIF spec
     519my %riffSpec = (
     520    IARL => 1,  ICRD => 1,  IGNR => 1,  IPLT => 1,  ISRC => 1,
     521    IART => 1,  ICRP => 1,  IKEY => 1,  IPRD => 1,  ISRF => 1,
     522    ICMS => 1,  IDIM => 1,  ILGT => 1,  ISBJ => 1,  ITCH => 1,
     523    ICMT => 1,  IDPI => 1,  IMED => 1,  ISFT => 1,
     524    ICOP => 1,  IENG => 1,  INAM => 1,  ISHP => 1,
     525);
    327526
    328527#------------------------------------------------------------------------------
     
    335534    my $class = ref($that) || $that || 'Image::ExifTool::BuildTagLookup';
    336535    my $self = bless {}, $class;
    337     my (%subdirs, %isShortcut);
     536    my (%subdirs, %isShortcut, %allStructs);
    338537    my %count = (
    339538        'unique tag names' => 0,
     
    344543#
    345544    my (%tagNameInfo, %id, %longID, %longName, %shortName, %tableNum,
    346         %tagLookup, %tagExists, %tableWritable, %sepTable, %compositeModules);
     545        %tagLookup, %tagExists, %tableWritable, %sepTable, %structs,
     546        %compositeModules, %isPlugin, %flattened, %structLookup);
    347547    $self->{TAG_NAME_INFO} = \%tagNameInfo;
    348     $self->{TAG_ID} = \%id;
     548    $self->{ID_LOOKUP} = \%id;
    349549    $self->{LONG_ID} = \%longID;
    350550    $self->{LONG_NAME} = \%longName;
     
    353553    $self->{TAG_LOOKUP} = \%tagLookup;
    354554    $self->{TAG_EXISTS} = \%tagExists;
     555    $self->{FLATTENED} = \%flattened;
    355556    $self->{TABLE_WRITABLE} = \%tableWritable;
    356557    $self->{SEPARATE_TABLE} = \%sepTable;
     558    $self->{STRUCTURES} = \%structs;
     559    $self->{STRUCT_LOOKUP} = \%structLookup;  # lookup for Struct hash ref based on Struct name
    357560    $self->{COMPOSITE_MODULES} = \%compositeModules;
    358561    $self->{COUNT} = \%count;
     
    360563    Image::ExifTool::LoadAllTables();
    361564    my @tableNames = sort keys %allTables;
    362     push @tableNames, 'Image::ExifTool::Shortcuts::Main'; # add Shortcuts last
     565    # add Shortcuts after other tables
     566    push @tableNames, 'Image::ExifTool::Shortcuts::Main';
     567    # add plug-in modules last
     568    $Image::ExifTool::documentOnly = 1; # (don't really load them)
     569    foreach (@pluginTables) {
     570        push @tableNames, $_;
     571        $isPlugin{$_} = 1;
     572    }
     573
    363574    my $tableNum = 0;
    364     my $tableName;
     575    my $exifTool = new Image::ExifTool;
     576    my ($tableName, $tag);
    365577    # create lookup for short table names
    366578    foreach $tableName (@tableNames) {
     
    369581        $short =~ s/::Main$//;
    370582        $short =~ s/::/ /;
    371         $short =~ s/(.*)Tags$/\u$1/;
     583        $short =~ s/^(.+)Tags$/\u$1/ unless $short eq 'Nikon AVITags';
    372584        $short =~ s/^Exif\b/EXIF/;
    373585        $shortName{$tableName} = $short;    # remember short name
    374586        $tableNum{$tableName} = $tableNum++;
    375587    }
     588    # validate DICOM UID values
     589    foreach (values %Image::ExifTool::DICOM::uid) {
     590        next unless /[\0-\x1f\x7f-\xff]/;
     591        warn "Warning: Special characters in DICOM UID value ($_)\n";
     592    }
    376593    # make lookup table to check for shortcut tags
    377     my $tag;
    378594    foreach $tag (keys %Image::ExifTool::Shortcuts::Main) {
    379595        my $entry = $Image::ExifTool::Shortcuts::Main{$tag};
     
    386602        my $short = $shortName{$tableName};
    387603        my $info = $tagNameInfo{$tableName} = [ ];
    388         my ($table, $shortcut);
     604        my $isPlugin = $isPlugin{$tableName};
     605        my ($table, $shortcut, %isOffset, %datamember, %hasSubdir);
    389606        if ($short eq 'Shortcuts') {
    390607            # can't use GetTagTable() for Shortcuts (not a normal table)
    391608            $table = \%Image::ExifTool::Shortcuts::Main;
    392609            $shortcut = 1;
     610        } elsif ($isPlugin) {
     611            $table = GetTagTable($tableName);
     612            # don't add to allTables list because this messes our table order
     613            delete $allTables{$tableName};
     614            pop @tableOrder;
    393615        } else {
    394616            $table = GetTagTable($tableName);
    395617        }
    396618        my $tableNum = $tableNum{$tableName};
    397         my $writeProc = $table->{WRITE_PROC};
     619        my $writeProc = $$table{WRITE_PROC};
     620        my $vars = $$table{VARS} || { };
    398621        $longID{$tableName} = 0;
    399622        $longName{$tableName} = 0;
    400623        # save all tag names
    401         my ($tagID, $binaryTable, $noID, $isIPTC);
    402         $isIPTC = 1 if $$table{WRITE_PROC} and $$table{WRITE_PROC} eq \&Image::ExifTool::IPTC::WriteIPTC;
    403         $noID = 1 if $short =~ /^(Composite|XMP|Extra|Shortcuts|ASF.*)$/ or $table->{VARS}->{NO_ID};
    404         if (($table->{VARS} and $table->{VARS}->{INDEX}) or
    405             ($table->{PROCESS_PROC} and
    406              $table->{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData))
    407         {
     624        my ($tagID, $binaryTable, $noID, $isIPTC, $isXMP);
     625        $isIPTC = 1 if $writeProc and $writeProc eq \&Image::ExifTool::IPTC::WriteIPTC;
     626        # generate flattened tag names for structure fields if this is an XMP table
     627        if ($$table{GROUPS} and $$table{GROUPS}{0} eq 'XMP') {
     628            $isXMP = 1;
     629            foreach $tagID (TagTableKeys($table)) {
     630                my $tagInfo = $$table{$tagID};
     631                next unless ref $tagInfo eq 'HASH' and $$tagInfo{Struct};
     632                Image::ExifTool::XMP::AddFlattenedTags($table, $tagID);
     633            }
     634        }
     635        $noID = 1 if $isXMP or $short =~ /^(Shortcuts|ASF.*)$/ or $$vars{NO_ID};
     636        my $processBinaryData = ($$table{PROCESS_PROC} and (
     637            $$table{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData or
     638            $$table{PROCESS_PROC} eq \&Image::ExifTool::Nikon::ProcessNikonEncrypted));
     639        if ($$vars{ID_LABEL} or $processBinaryData) {
    408640            $binaryTable = 1;
    409             $id{$tableName} = 'Index';
    410         } elsif ($table->{PROCESS_PROC} and
    411             $table->{PROCESS_PROC} eq \&Image::ExifTool::Canon::ProcessSerialData)
    412         {
    413             $binaryTable = 1;
    414             $id{$tableName} = 'Sequence';
     641            $id{$tableName} = $$vars{ID_LABEL} || 'Index';
    415642        } elsif ($isIPTC and $$table{PROCESS_PROC}) { #only the main IPTC table has a PROCESS_PROC
    416643            $id{$tableName} = 'Record';
     
    418645            $id{$tableName} = 'Tag ID';
    419646        }
    420         $caseInsensitive = ($tableName =~ /::XMP::/);
     647        $caseInsensitive = $isXMP;
     648        $numbersFirst = -1 if $$table{VARS} and $$table{VARS}{ALPHA_FIRST};
    421649        my @keys = sort NumbersFirst TagTableKeys($table);
     650        $numbersFirst = 1;
    422651        my $defFormat = $table->{FORMAT};
    423         if (not $defFormat and $table->{PROCESS_PROC} and
    424             $table->{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData)
    425         {
    426             $defFormat = 'int8u';   # use default format for binary data tables
    427         }
     652        # use default format for binary data tables
     653        $defFormat = 'int8u' if not $defFormat and $binaryTable;
     654
    428655TagID:  foreach $tagID (@keys) {
    429656            my ($tagInfo, @tagNames, $subdir, $format, @values);
     
    431658            if ($shortcut) {
    432659                # must build a dummy tagInfo list since Shortcuts is not a normal table
    433                 $tagInfo = { Name => $tagID, Writable => 1, Require => { } };
     660                $tagInfo = {
     661                    Name => $tagID,
     662                    Notes => $shortcutNotes{$tagID},
     663                    Writable => 1,
     664                    Require => { },
     665                };
    434666                my $i;
    435667                for ($i=0; $i<@{$$table{$tagID}}; ++$i) {
     
    442674            $format = $defFormat;
    443675            foreach $tagInfo (@infoArray) {
     676                my $name = $$tagInfo{Name};
     677                # validate Name
     678                warn "Warning: Invalid tag name $short '$name'\n" if $name !~ /^[-\w]+$/;
     679                # accumulate information for consistency check of BinaryData tables
     680                if ($processBinaryData and $$table{WRITABLE}) {
     681                    $isOffset{$tagID} = $name if $$tagInfo{IsOffset};
     682                    $hasSubdir{$tagID} = $name if $$tagInfo{SubDirectory};
     683                    # require DATAMEMBER for writable var-format tags, Hook and DataMember tags
     684                    if ($$tagInfo{Format} and $$tagInfo{Format} =~ /^var_/) {
     685                        $datamember{$tagID} = $name;
     686                        unless (defined $$tagInfo{Writable} and not $$tagInfo{Writable}) {
     687                            warn "Warning: Var-format tag is writable - $short $name\n"
     688                        }
     689                    } elsif ($$tagInfo{Hook} or ($$tagInfo{RawConv} and
     690                             $$tagInfo{RawConv} =~ /\$self(->)?\{\w+\}\s*=(?!~)/))
     691                    {
     692                        $datamember{$tagID} = $name;
     693                    }
     694                }
     695                if ($$tagInfo{Hidden}) {
     696                    warn "Warning: Hidden tag in list - $short $name\n" if @infoArray > 1;
     697                    next TagID;
     698                }
     699                my $writable;
     700                if (defined $$tagInfo{Writable}) {
     701                    $writable = $$tagInfo{Writable};
     702                    # validate Writable
     703                    unless ($formatOK{$writable} or  ($writable =~ /(.*)\[/ and $formatOK{$1})) {
     704                        warn "Warning: Unknown Writable ($writable) for $short $name\n",
     705                    }
     706                } elsif (not $$tagInfo{SubDirectory}) {
     707                    $writable = $$table{WRITABLE};
     708                }
     709                # validate some characteristics of obvious date/time tags
     710                if ($$tagInfo{PrintConv} and $$tagInfo{PrintConv} eq '$self->ConvertDateTime($val)') {
     711                    my @g = $exifTool->GetGroup($tagInfo);
     712                    warn "$short $name should be in 'Time' group!\n" unless $g[2] eq 'Time';
     713                    if ($writable and not $$tagInfo{Shift} and $g[0] ne 'Composite' and
     714                        $short ne 'PostScript')
     715                    {
     716                        warn "$short $name is not shiftable!\n";
     717                    }
     718                } elsif ($name =~ /DateTime(?!Stamp)/ and (not $$tagInfo{Groups}{2} or
     719                    $$tagInfo{Groups}{2} ne 'Time') and $short ne 'DICOM') {
     720                    warn "$short $name should be in 'Time' group!\n";
     721                }
     722                # validate Description (can't contain special characters)
     723                if ($$tagInfo{Description} and
     724                    $$tagInfo{Description} ne EscapeHTML($$tagInfo{Description}))
     725                {
     726                    # this is a problem because the Escape option currently only
     727                    # escapes descriptions if the default Lang option isn't default
     728                    warn "$name description contains special characters!\n";
     729                }
     730                # validate SubIFD flag
     731                my $subdir = $$tagInfo{SubDirectory};
     732                my $struct = $$tagInfo{Struct};
     733                my $strTable;
     734                if (ref $struct) {
     735                    $strTable = $struct;
     736                    $struct = $$strTable{STRUCT_NAME};
     737                    if ($struct) {
     738                        my $oldTable = $structLookup{$struct};
     739                        if ($oldTable and $oldTable ne $strTable) {
     740                            warn "Duplicate XMP structure with name $struct\n";
     741                        } else {
     742                            $structLookup{$struct} = $strTable;
     743                        }
     744                    } else {
     745                        warn "Missing STRUCT_NAME for structure in $$tagInfo{Name}\n";
     746                        undef $strTable;
     747                    }
     748                } elsif ($struct) {
     749                    $strTable = $structLookup{$struct};
     750                    unless ($strTable) {
     751                        warn "Missing XMP $struct structure!\n";
     752                        undef $struct;
     753                    }
     754                }
     755                my $isSub = ($subdir and $$subdir{Start} and $$subdir{Start} eq '$val');
     756                if ($$tagInfo{SubIFD}) {
     757                    warn "Warning: Wrong SubDirectory Start for SubIFD tag - $short $name\n" unless $isSub;
     758                } else {
     759                    warn "Warning: SubIFD flag not set for $short $name\n" if $isSub;
     760                }
    444761                if ($$tagInfo{Notes}) {
    445762                    my $note = $$tagInfo{Notes};
     
    449766                    $note =~ s/(^[ \t]+|[ \t]+$)//mg;
    450767                    push @values, "($note)";
    451                 }
    452                 my $writable;
    453                 if (defined $$tagInfo{Writable}) {
    454                     $writable = $$tagInfo{Writable};
    455                 } elsif (not $$tagInfo{SubDirectory}) {
    456                     $writable = $$table{WRITABLE};
     768                } elsif ($isXMP and lc $tagID ne lc $name) {
     769                    # add note about different XMP Tag ID
     770                    if ($$tagInfo{RootTagInfo}) {
     771                        push @values, "($tagID)";
     772                    } else {
     773                        push @values,"(called $tagID by the spec)";
     774                    }
    457775                }
    458776                my $writeGroup;
     
    462780                    $writeGroup = '-' unless $writeGroup;
    463781                }
    464                 $format = $$tagInfo{Format} if defined $$tagInfo{Format};
    465                 if ($$tagInfo{SubDirectory}) {
    466                     # don't show XMP structure tags
    467                     next TagID if $short =~ /^XMP /;
    468                     $subdir = 1;
    469                     my $subTable = $tagInfo->{SubDirectory}->{TagTable} || $tableName;
     782                if (defined $$tagInfo{Format}) {
     783                    $format = $$tagInfo{Format};
     784                    # validate Format
     785                    unless ($formatOK{$format} or $short eq 'PICT' or
     786                        ($format =~ /^(var_)?(.*)\[/ and $formatOK{$2}))
     787                    {
     788                        warn "Warning: Unknown Format ($format) for $short $name\n";
     789                    }
     790                }
     791                if ($subdir) {
     792                    my $subTable = $$subdir{TagTable} || $tableName;
    470793                    push @values, $shortName{$subTable}
    471                 } else {
    472                     $subdir = 0;
     794                } elsif ($struct) {
     795                    push @values, $struct;
     796                    $structs{$struct} = 1;
    473797                }
    474798                my $type;
    475799                foreach $type ('Require','Desire') {
    476800                    my $require = $$tagInfo{$type};
    477                     if ($require) {
     801                    if (ref $require) {
    478802                        foreach (sort { $a <=> $b } keys %$require) {
    479803                            push @require, $$require{$_};
    480804                        }
     805                    } elsif ($require) {
     806                        push @require, $require;
    481807                    }
    482808                }
    483809                my $printConv = $$tagInfo{PrintConv};
     810                if ($$tagInfo{Mask}) {
     811                    my $val = $$tagInfo{Mask};
     812                    push @values, sprintf('[Mask 0x%.2x]',$val);
     813                    $$tagInfo{PrintHex} = 1 unless defined $$tagInfo{PrintHex};
     814                    # verify that all values are within the mask
     815                    if (ref $printConv eq 'HASH') {
     816                        # convert mask if necessary
     817                        if ($$tagInfo{ValueConv}) {
     818                            my $v = eval $$tagInfo{ValueConv};
     819                            $val = $v if defined $v;
     820                        }
     821                        foreach (keys %$printConv) {
     822                            next if $_ !~ /^\d+$/ or ($_ & $val) == $_;
     823                            my $hex = sprintf '0x%.2x', $_;
     824                            warn "$short $name PrintConv value $hex is not in Mask!\n";
     825                        }
     826                    }
     827                }
    484828                if (ref($printConv) =~ /^(HASH|ARRAY)$/) {
    485829                    my (@printConvList, @indexList, $index);
     
    487831                        for ($index=0; $index<@$printConv; ++$index) {
    488832                            next if ref $$printConv[$index] ne 'HASH';
     833                            next unless %{$$printConv[$index]};
    489834                            push @printConvList, $$printConv[$index];
    490835                            push @indexList, $index;
     836                            # collapse values with identical PrintConv's
     837                            if (@printConvList >= 2 and $printConvList[-1] eq $printConvList[-2]) {
     838                                if (ref $indexList[-2]) {
     839                                    push @{$indexList[-2]}, $indexList[-1];
     840                                } else {
     841                                    $indexList[-2] = [ $indexList[-2], $indexList[-1] ];
     842                                }
     843                                pop @printConvList;
     844                                pop @indexList;
     845                            }
    491846                        }
    492847                        $printConv = shift @printConvList;
     
    494849                    }
    495850                    while (defined $printConv) {
    496                         push @values, "[Value $index]" if defined $index;
     851                        if (defined $index) {
     852                            # (print indices of original values if reorganized)
     853                            my $s = '';
     854                            my $idx = $$tagInfo{Relist} ? $tagInfo->{Relist}->[$index] : $index;
     855                            if (ref $idx) {
     856                                $s = 's' if @$idx > 1;
     857                                # collapse consecutive number ranges
     858                                my ($i, @i, $rngStart);
     859                                for ($i=0; $i<@$idx; ++$i) {
     860                                    if ($i < @$idx - 1 and $$idx[$i+1] == $$idx[$i] + 1) {
     861                                        $rngStart = $i unless defined $rngStart;
     862                                        next;
     863                                    }
     864                                    push @i, defined($rngStart) ? "$rngStart-$i" : $i;
     865                                }
     866                                ($idx = join ', ', @i) =~ s/(.*),/$1 and/;
     867                            } elsif (not $$tagInfo{Relist}) {
     868                                while (@printConvList and $printConv eq $printConvList[0]) {
     869                                    shift @printConvList;
     870                                    $index = shift @indexList;
     871                                }
     872                                if ($idx != $index) {
     873                                    $idx = "$idx-$index";
     874                                    $s = 's';
     875                                }
     876                            }
     877                            push @values, "[Value$s $idx]";
     878                        }
    497879                        if ($$tagInfo{SeparateTable}) {
    498880                            $subdir = 1;
    499881                            my $s = $$tagInfo{SeparateTable};
    500                             $s = $$tagInfo{Name} if $s eq '1';
     882                            $s = $name if $s eq '1';
    501883                            # add module name if not specified
    502884                            $s =~ / / or ($short =~ /^(\w+)/ and $s = "$1 $s");
     
    505887                            # add PrintHex flag to PrintConv so we can check it later
    506888                            $$printConv{PrintHex} = 1 if $$tagInfo{PrintHex};
     889                            $$printConv{PrintString} = 1 if $$tagInfo{PrintString};
    507890                        } else {
    508891                            $caseInsensitive = 0;
    509892                            my @pk = sort NumbersFirst keys %$printConv;
    510                             my $bits;
     893                            my $n = scalar @values;
     894                            my ($bits, $cols, $i);
    511895                            foreach (@pk) {
    512896                                next if $_ eq '';
    513897                                $_ eq 'BITMASK' and $bits = $$printConv{$_}, next;
     898                                $_ eq 'OTHER' and next;
    514899                                my $index;
    515                                 if ($$tagInfo{PrintHex}) {
     900                                if (($$tagInfo{PrintHex} or $$printConv{BITMASK}) and /^\d+$/) {
    516901                                    $index = sprintf('0x%x',$_);
    517                                 } elsif (/^[-+]?\d+$/) {
     902                                } elsif (/^[+-]?(?=\d|\.\d)\d*(\.\d*)?$/ and not $$tagInfo{PrintString}) {
    518903                                    $index = $_;
    519904                                } else {
    520                                     # ignore unprintable values
    521                                     next if /[\x00-\x1f\x80-\xff]/;
    522                                     $index = "'$_'";
     905                                    $index = $_;
     906                                    # translate unprintable values
     907                                    if ($index =~ s/([\x00-\x1f\x80-\xff])/sprintf("\\x%.2x",ord $1)/eg) {
     908                                        $index = qq{"$index"};
     909                                    } else {
     910                                        $index = qq{'$index'};
     911                                    }
    523912                                }
    524913                                push @values, "$index = " . $$printConv{$_};
     914                                # validate all PrintConv values
     915                                if ($$printConv{$_} =~ /[\0-\x1f\x7f-\xff]/) {
     916                                    warn "Warning: Special characters in $short $name PrintConv ($$printConv{$_})\n";
     917                                }
    525918                            }
    526919                            if ($bits) {
     
    530923                                }
    531924                            }
     925                            # organize values into columns if specified
     926                            if (defined($cols = $$tagInfo{PrintConvColumns})) {
     927                                my @new = splice @values, $n;
     928                                my $v = '[!HTML]<table class=cols><tr>';
     929                                my $rows = int((scalar(@new) + $cols - 1) / $cols);
     930                                for ($n=0; $n<@new; $n+=$rows) {
     931                                    $v .= "\n  <td>";
     932                                    for ($i=0; $i<$rows and $n+$i<@new; ++$i) {
     933                                        $v .= "\n  <br>" if $i;
     934                                        $v .= EscapeHTML($new[$n+$i]);
     935                                    }
     936                                    $v .= '</td><td>&nbsp;&nbsp;</td>';
     937                                }
     938                                push @values, $v . "</tr></table>\n";
     939                            }
    532940                        }
    533941                        last unless @printConvList;
     
    536944                    }
    537945                } elsif ($printConv and $printConv =~ /DecodeBits\(\$val,\s*(\{.*\})\s*\)/s) {
     946                    $$self{Model} = '';   # needed for Nikon ShootingMode
    538947                    my $bits = eval $1;
     948                    delete $$self{Model};
    539949                    if ($@) {
    540950                        warn $@;
     
    548958                if ($subdir and not $$tagInfo{SeparateTable}) {
    549959                    # subdirectories are only writable if specified explicitly
    550                     $writable = '-' . ($$tagInfo{Writable} ? $writable : '');
     960                    my $tw = $$tagInfo{Writable};
     961                    $writable = '-' . ($tw ? $writable : '');
     962                    $writable .= '!' if $tw and ($$tagInfo{Protected} || 0) & 0x01;
    551963                } else {
    552964                    # not writable if we can't do the inverse conversions
     
    585997                        }
    586998                        $writable .= '~' if $noPrintConvInv;
    587                         # add a '*' if this tag is protected or a '~' for unsafe tags
     999                        # add a '*' if this tag is protected or a '!' for unsafe tags
    5881000                        if ($$tagInfo{Protected}) {
    5891001                            $writable .= '*' if $$tagInfo{Protected} & 0x02;
     
    5921004                        $writable .= '/' if $$tagInfo{Avoid};
    5931005                    }
     1006                    $writable = "=struct" if $struct;
     1007                    $writable .= '_' if defined $$tagInfo{Flat};
    5941008                    $writable .= '+' if $$tagInfo{List};
    595                     # Œseparate tables link like subdirectories (flagged with leading '-')
     1009                    $writable .= ':' if $$tagInfo{Mandatory};
     1010                    # separate tables link like subdirectories (flagged with leading '-')
    5961011                    $writable = "-$writable" if $subdir;
    5971012                }
    5981013                # don't duplicate a tag name unless an entry is different
    599                 my $name = $$tagInfo{Name};
    6001014                my $lcName = lc($name);
    6011015                # check for conflicts with shortcut names
     
    6141028                }
    6151029#
    616 # add this tag to the tag lookup unless PROCESS_PROC is 0 or shortcut tag
     1030# add this tag to the tag lookup unless PROCESS_PROC is 0 or shortcut or plug-in tag
    6171031#
    618                 next if $shortcut or (defined $$table{PROCESS_PROC} and not $$table{PROCESS_PROC});
     1032                next if $shortcut or $isPlugin;
     1033                next if defined $$table{PROCESS_PROC} and not $$table{PROCESS_PROC};
    6191034                # count our tags
    6201035                if ($$tagInfo{SubDirectory}) {
     
    6341049                    not defined $wflag and not $$tagInfo{SubDirectory}));
    6351050                $tagLookup{$lcName} or $tagLookup{$lcName} = { };
     1051                # add to lookup for flattened tags if necessary
     1052                if ($$tagInfo{RootTagInfo}) {
     1053                    $flattened{$lcName} or $flattened{$lcName} = { };
     1054                    $flattened{$lcName}{$tableNum} = $$tagInfo{RootTagInfo}{TagID};
     1055                }
    6361056                # remember number for this table
    6371057                my $tagIDs = $tagLookup{$lcName}->{$tableNum};
     
    6591079#
    6601080            my $tagIDstr;
    661             if ($tagID =~ /^\d+$/) {
    662                 if ($binaryTable or $isIPTC or ($short =~ /^CanonCustom/ and $tagID < 256)) {
    663                     $tagIDstr = $tagID;
     1081            if ($tagID =~ /^\d+(\.\d+)?$/) {
     1082                if ($1 or $binaryTable or $isIPTC or ($short =~ /^CanonCustom/ and $tagID < 256)) {
     1083                    if ($tagID < 0x10000) {
     1084                        $tagIDstr = $tagID;
     1085                    } else {
     1086                        $tagIDstr = sprintf('0x%.8x',$tagID);
     1087                    }
    6641088                } else {
    665                     $tagIDstr = sprintf("0x%.4x",$tagID);
     1089                    $tagIDstr = sprintf('0x%.4x',$tagID);
    6661090                }
    6671091            } elsif ($short eq 'DICOM') {
     
    6851109            push @$info, [ $tagIDstr, \@tagNames, \@writable, \@values, \@require, \@writeGroup ];
    6861110        }
     1111        # do consistency check of writable BinaryData tables
     1112        if ($processBinaryData and $$table{WRITABLE}) {
     1113            my %lookup = (
     1114                IS_OFFSET => \%isOffset,
     1115                IS_SUBDIR => \%hasSubdir,
     1116                DATAMEMBER => \%datamember,
     1117            );
     1118            my ($var, $tagID);
     1119            foreach $var (sort keys %lookup) {
     1120                my $hash = $lookup{$var};
     1121                if ($$table{$var}) {
     1122                    foreach $tagID (@{$$table{$var}}) {
     1123                        $$hash{$tagID} and delete($$hash{$tagID}), next;
     1124                        warn "Warning: Extra $var for $short tag $tagID\n";
     1125                    }
     1126                }
     1127                foreach $tagID (sort keys %$hash) {
     1128                    warn "Warning: Missing $var for $short $$hash{$tagID}\n";
     1129                }
     1130            }
     1131        }
     1132    }
     1133    # save information about structures
     1134    my $strName;
     1135    foreach $strName (keys %structs) {
     1136        my $struct = $structLookup{$strName};
     1137        my $info = $tagNameInfo{"XMP $strName Struct"} = [ ];
     1138        my $tag;
     1139        foreach $tag (sort keys %$struct) {
     1140            my $tagInfo = $$struct{$tag};
     1141            next unless ref $tagInfo eq 'HASH';
     1142            my $writable = $$tagInfo{Writable};
     1143            my @vals;
     1144            unless ($writable) {
     1145                $writable = $$tagInfo{Struct};
     1146                ref $writable and $writable = $$writable{STRUCT_NAME};
     1147                if ($writable) {
     1148                    push @vals, $writable;
     1149                    $structs{$writable} = 1;
     1150                    $writable = "=$writable";
     1151                } else {
     1152                    $writable = 'string';
     1153                }
     1154            }
     1155            $writable .= '+' if $$tagInfo{List};
     1156            push @$info, [
     1157                $tag,
     1158                [ $$tagInfo{Name} || ucfirst($tag) ],
     1159                [ $writable ],
     1160                \@vals,
     1161                [], []
     1162            ];
     1163        }
    6871164    }
    6881165    return $self;
     
    6961173sub WriteTagLookup($$)
    6971174{
    698     local $_;
     1175    local ($_, *INFILE, *OUTFILE);
    6991176    my ($self, $file) = @_;
    7001177    my $tagLookup = $self->{TAG_LOOKUP};
    7011178    my $tagExists = $self->{TAG_EXISTS};
     1179    my $flattened = $self->{FLATTENED};
    7021180    my $tableWritable = $self->{TABLE_WRITABLE};
    7031181#
     
    7051183#
    7061184    my $tmpFile = "${file}_tmp";
    707     open(INFILE,$file) or warn("Can't open $file\n"), return 0;
    708     unless (open(OUTFILE,">$tmpFile")) {
     1185    open(INFILE, $file) or warn("Can't open $file\n"), return 0;
     1186    unless (open(OUTFILE, ">$tmpFile")) {
    7091187        warn "Can't create temporary file $tmpFile\n";
    7101188        close(INFILE);
     
    7531231        my (@entries, $tableNum);
    7541232        foreach $tableNum (@tableNums) {
    755             my $tagID = $$tagLookup{$tag}->{$tableNum};
     1233            my $tagID = $$tagLookup{$tag}{$tableNum};
     1234            my $rootID = $$flattened{$tag}{$tableNum};
    7561235            my $entry;
    757             if (ref $tagID eq 'HASH') {
     1236            if (ref $tagID eq 'HASH' or $rootID) {
     1237                $tagID = { $tagID => 1 } unless ref $tagID eq 'HASH';
    7581238                my @tagIDs = sort keys %$tagID;
    7591239                foreach (@tagIDs) {
    7601240                    if (/^\d+$/) {
    761                         $_ = sprintf("0x%x",$_);
     1241                        $_ = sprintf('0x%x',$_);
    7621242                    } else {
    7631243                        my $quot = "'";
     
    7671247                    }
    7681248                }
     1249                # reference to root structure ID must come first in lookup
     1250                # (so we can generate the flattened tags just before we need them)
     1251                unshift @tagIDs, "\\'$rootID'" if $rootID;
    7691252                $entry = '[' . join(',', @tagIDs) . ']';
    7701253            } elsif ($tagID =~ /^\d+$/) {
    771                 $entry = sprintf("0x%x",$tagID);
     1254                $entry = sprintf('0x%x',$tagID);
    7721255            } else {
    7731256                $entry = "'$tagID'";
     
    8151298#
    8161299    if ($success) {
    817         rename($tmpFile, $file);
     1300        local (*ORG, *TMP);
     1301        # only rename the file if something changed
     1302        open ORG, $file or return 0;
     1303        open TMP, $tmpFile or return 0;
     1304        my ($buff, $buf2, $changed);
     1305        for (;;) {
     1306            my $n1 = read ORG, $buff, 65536;
     1307            my $n2 = read TMP, $buf2, 65536;
     1308            $n1 eq $n2 or $changed = 1, last;
     1309            last unless $n1;
     1310            $buff eq $buf2 or $changed = 1, last;
     1311        }
     1312        close ORG;
     1313        close TMP;
     1314        if ($changed) {
     1315            rename($tmpFile, $file) or warn("Error renaming $tmpFile\n"), $success = 0;
     1316        } else {
     1317            unlink($tmpFile);
     1318        }
    8181319    } else {
    8191320        unlink($tmpFile);
     
    8281329{
    8291330    my $rtnVal;
    830     my $bNum = ($b =~ /^-?[0-9]+$/);
    831     if ($a =~ /^-?[0-9]+$/) {
    832         $rtnVal = ($bNum ? $a <=> $b : -1);
     1331    my $bNum = ($b =~ /^-?[0-9]+(\.\d*)?$/);
     1332    if ($a =~ /^-?[0-9]+(\.\d*)?$/) {
     1333        $rtnVal = ($bNum ? $a <=> $b : -$numbersFirst);
    8331334    } elsif ($bNum) {
    834         $rtnVal = 1;
     1335        $rtnVal = $numbersFirst;
    8351336    } else {
    8361337        my ($a2, $b2) = ($a, $b);
    8371338        # expand numbers to 3 digits (with restrictions to avoid messing up ascii-hex tags)
    838         $a2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $a2 =~ /^(APP)?[0-9 ]*$/ and length($a2)<16;
    839         $b2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $b2 =~ /^(APP)?[0-9 ]*$/ and length($b2)<16;
     1339        $a2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $a2 =~ /^(APP)?[.0-9 ]*$/ and length($a2)<16;
     1340        $b2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $b2 =~ /^(APP)?[.0-9 ]*$/ and length($b2)<16;
    8401341        $caseInsensitive and $rtnVal = (lc($a2) cmp lc($b2));
    8411342        $rtnVal or $rtnVal = ($a2 cmp $b2);
     
    8481349# (funny, I know, but the pod headings must be hidden to prevent confusing
    8491350#  the pod parser)
    850 # Inputs: 0) string
    851 sub Doc2Pod($)
     1351# Inputs: 0-N) documentation strings
     1352sub Doc2Pod($;@)
    8521353{
    8531354    my $doc = shift;
     1355    local $_;
     1356    $doc .= shift while @_;
    8541357    $doc =~ s/\n~/\n=/g;
     1358    $doc =~ s/L<[^>]+?\|(http[^>]+)>/L<$1>/g; # POD doesn't support text for http links
    8551359    return $doc;
    8561360}
     
    8651369    $doc =~ s/B&lt;(.*?)&gt;/<b>$1<\/b>/sg;
    8661370    $doc =~ s/C&lt;(.*?)&gt;/<code>$1<\/code>/sg;
     1371    $doc =~ s/I&lt;(.*?)&gt;/<i>$1<\/i>/sg;
     1372    $doc =~ s{L&lt;([^&]+?)\|\Q$homePage\E/TagNames/(.*?)&gt;}{<a href="$2">$1<\/a>}sg;
     1373    $doc =~ s{L&lt;([^&]+?)\|\Q$homePage\E/(.*?)&gt;}{<a href="../$2">$1<\/a>}sg;
     1374    $doc =~ s{L&lt;\Q$homePage\E/TagNames/(.*?)&gt;}{<a href="$1">$1<\/a>}sg;
     1375    $doc =~ s{L&lt;\Q$homePage\E/(.*?)&gt;}{<a href="../$1">$1<\/a>}sg;
     1376    $doc =~ s{L&lt;([^&]+?)\|/\w+ ([^/&|]+) Tags&gt;}{<a href="#$2">$1</a>}sg;
     1377    $doc =~ s/L&lt;([^&]+?)\|(.+?)&gt;/<a href="$2">$1<\/a>/sg;
    8671378    $doc =~ s/L&lt;(.*?)&gt;/<a href="$1">$1<\/a>/sg;
    8681379    return $doc;
     
    8751386{
    8761387    my %gotTable;
    877     my $count = 0;
    8781388    my @tableNames = @tableOrder;
    8791389    my (@orderedTables, %mainTables, @outOfOrder);
     
    8941404        # recursively scan through tables in subdirectories
    8951405        my @moreTables;
    896         $caseInsensitive = ($tableName =~ /::XMP::/);
     1406        $caseInsensitive = ($$table{GROUPS} and $$table{GROUPS}{0} eq 'XMP');
     1407        $numbersFirst = -1 if $$table{VARS} and $$table{VARS}{ALPHA_FIRST};
    8971408        my @keys = sort NumbersFirst TagTableKeys($table);
     1409        $numbersFirst = 1;
    8981410        foreach (@keys) {
    8991411            my @infoArray = GetTagInfoList($table,$_);
     
    9321444    }
    9331445    # insert back in better order
    934     foreach $pos (reverse sort { $a <=> $b } keys %fixPos) {
     1446    foreach $pos (sort { $b <=> $a } keys %fixPos) { # (reverse sort)
    9351447        my $fix = $fixPos{$pos};
    9361448        foreach (@$fix) {
     
    9441456        GPS     => 'XMP',   # etc...
    9451457        GeoTiff => 'GPS',
     1458        CanonVRD=> 'CanonCustom',
     1459        Kodak   => 'JVC',
     1460       'Kodak::IFD' => 'Kodak::Unknown',
     1461       'Kodak::TextualInfo' => 'Kodak::IFD',
     1462       'Kodak::Processing' => 'Kodak::TextualInfo',
    9461463        Leaf    => 'Kodak',
    947         Unknown => 'Sony',
     1464        Minolta => 'Leaf',
     1465        SonyIDC => 'Sony',
     1466        Unknown => 'SonyIDC',
    9481467        DNG     => 'Unknown',
    9491468        PrintIM => 'ICC_Profile',
     1469        ID3     => 'PostScript',
     1470        MinoltaRaw => 'KyoceraRaw',
     1471        KyoceraRaw => 'CanonRaw',
     1472        SigmaRaw => 'PanasonicRaw',
    9501473        Olympus => 'NikonCapture',
    951         Pentax  => 'Panasonic',
    952         Ricoh   => 'Pentax',
    953         Sanyo   => 'Ricoh',
    9541474        PhotoMechanic => 'FotoStation',
     1475        Microsoft     => 'PhotoMechanic',
     1476       'Microsoft::MP'=> 'Microsoft::MP1',
     1477        GIMP    => 'Microsoft',
     1478       'Nikon::CameraSettingsD300' => 'Nikon::ShotInfoD300b',
     1479       'Pentax::LensData' => 'Pentax::LensInfo2',
     1480       'Sony::SRF2' => 'Sony::SRF',
     1481       'Samsung::INFO' => 'Samsung::Type2', # (necessary because Samsung doesn't have a main table)
     1482       'Samsung::MP4' => 'Samsung::INFO', # (necessary because Samsung doesn't have a main table)
    9551483    );
    9561484    my @tweak = sort keys %tweakOrder;
     
    9901518        $class = shift @names;
    9911519        $htmlFile = "$htmldir/TagNames/$class.html";
    992         $head = $category . ($sepTable ? ' Values' : ' Tags');
     1520        $head = $category;
     1521        if ($head =~ /^XMP .+ Struct$/) {
     1522            pop @names;
     1523        } else {
     1524            $head .= ($sepTable ? ' Values' : ' Tags');
     1525        }
    9931526        ($title = $head) =~ s/ .* / /;
    9941527        @names and $url = join '_', @names;
     
    9991532    }
    10001533    if ($createdFiles{$htmlFile}) {
    1001         open(HTMLFILE,">>${htmlFile}_tmp") or return 0;
     1534        open(HTMLFILE, ">>${htmlFile}_tmp") or return 0;
    10021535    } else {
    1003         open(HTMLFILE,">${htmlFile}_tmp") or return 0;
     1536        open(HTMLFILE, ">${htmlFile}_tmp") or return 0;
    10041537        print HTMLFILE "$docType<html>\n<head>\n<title>$title</title>\n";
    10051538        print HTMLFILE "<link rel=stylesheet type='text/css' href='style.css' title='Style'>\n";
     
    10431576            $fileDate = $1 if @lines and $lines[-1] =~ m{<i>Last revised (.*)</i>};
    10441577        }
    1045         open(HTMLFILE,">>$tmpFile") or $success = 0, next;
     1578        open(HTMLFILE, ">>$tmpFile") or $success = 0, next;
    10461579        # write the trailers
    10471580        print HTMLFILE "<hr>\n";
     
    11001633#         2) output html directory (ie. 'html')
    11011634# Returns: true on success
     1635# Notes: My apologies for the patchwork code, but this is only used to generate the docs.
    11021636sub WriteTagNames($$)
    11031637{
    11041638    my ($self, $podFile, $htmldir) = @_;
    1105     my ($tableName, $short, $url, @sepTables);
     1639    my ($tableName, $short, $url, @sepTables, @structs);
    11061640    my $tagNameInfo = $self->{TAG_NAME_INFO} or return 0;
    1107     my $idTitle = $self->{TAG_ID};
     1641    my $idLabel = $self->{ID_LOOKUP};
    11081642    my $shortName = $self->{SHORT_NAME};
    11091643    my $sepTable = $self->{SEPARATE_TABLE};
     1644    my $structs = $self->{STRUCTURES};
     1645    my $structLookup = $self->{STRUCT_LOOKUP};
    11101646    my $success = 1;
    1111     my %htmlFiles;
    11121647    my $columns = 6;    # number of columns in html index
    11131648    my $percent = int(100 / $columns);
    11141649
    11151650    # open the file and write the header
    1116     open(PODFILE,">$podFile") or return 0;
    1117     print PODFILE Doc2Pod($docs{PodHeader}), $docs{ExifTool}, $docs{ExifTool2};
     1651    open(PODFILE, ">$podFile") or return 0;
     1652    print PODFILE Doc2Pod($docs{PodHeader}, $docs{ExifTool}, $docs{ExifTool2});
    11181653    mkdir "$htmldir/TagNames";
    11191654    OpenHtmlFile($htmldir) or return 0;
     
    11251660    # write the index
    11261661    my @tableNames = GetTableOrder();
    1127     push @tableNames, 'Image::ExifTool::Shortcuts::Main';   # do Shortcuts last
     1662    # add shortcuts last
     1663    push @tableNames, 'Image::ExifTool::Shortcuts::Main';
     1664    push @tableNames, @pluginTables;
    11281665    # get list of headings and add any missing ones
    11291666    my $heading = 'xxx';
     
    11671704    print HTMLFILE '<p>',Doc2Html($docs{ExifTool2}),"</p>\n";
    11681705    # write all the tag tables
    1169     while (@tableNames or @sepTables) {
     1706    while (@tableNames or @sepTables or @structs) {
    11701707        while (@sepTables) {
    11711708            $tableName = shift @sepTables;
     
    11831720            close HTMLFILE;
    11841721            if (OpenHtmlFile($htmldir, $tableName, 1)) {
    1185                 print HTMLFILE Doc2Html($notes), "\n" if $notes;
     1722                print HTMLFILE '<p>', Doc2Html($notes), "</p>\n" if $notes;
    11861723                print HTMLFILE "<blockquote>\n";
    11871724                print HTMLFILE "<table class=frame><tr><td>\n";
     
    11911728                my @keys;
    11921729                foreach (sort NumbersFirst keys %$printConv) {
    1193                     next if /^(Notes|PrintHex)$/;
     1730                    next if /^(Notes|PrintHex|PrintString|OTHER)$/;
    11941731                    $align = '' if $align and /[^\d]/;
    11951732                    my $w = length($_) + length($$printConv{$_});
     
    12001737                # print in multiple columns if there is room
    12011738                my $cols = int(80 / ($wid + 4));
    1202                 $cols = 1 if $cols < 1 or $cols > @keys;
     1739                $cols = 1 if $cols < 1 or $cols > @keys or @keys < 4;
    12031740                my $rows = int((scalar(@keys) + $cols - 1) / $cols);
    12041741                my ($r, $c);
     
    12151752                        if (defined $key) {
    12161753                            $index = $key;
    1217                             $prt = "= $$printConv{$key}";
     1754                            $prt = '= ' . EscapeHTML($$printConv{$key});
    12181755                            if ($$printConv{PrintHex}) {
    12191756                                $index = sprintf('0x%x',$index);
    1220                             } elsif ($index !~ /^[-+]?\d+$/) {
     1757                            } elsif ($$printConv{PrintString} or
     1758                                $index !~ /^[+-]?(?=\d|\.\d)\d*(\.\d*)?$/)
     1759                            {
    12211760                                $index = "'" . EscapeHTML($index) . "'";
    12221761                            }
     
    12391778            }
    12401779        }
    1241         last unless @tableNames;
    1242         $tableName = shift @tableNames;
    1243         $short = $$shortName{$tableName};
    1244         unless ($short) {
    1245             # this is just an index heading
    1246             print PODFILE "\n=head2 $tableName Tags\n";
    1247             print PODFILE $docs{$tableName} if $docs{$tableName};
    1248             next;
    1249         }
     1780        last unless @tableNames or @structs;
     1781        my $isStruct;
     1782        if (@structs) {
     1783            $tableName = shift @structs;
     1784            next if $$structs{$tableName} == 2; # only list each structure once
     1785            $$structs{$tableName} = 2;
     1786            $isStruct = $$structLookup{$tableName};
     1787            $isStruct or warn("Missing structure $tableName\n"), next;
     1788            $short = $tableName = "XMP $tableName Struct";
     1789            my $maxLen = 0;
     1790            $maxLen < length and $maxLen = length foreach keys %$isStruct;
     1791            $$self{LONG_ID}{$tableName} = $maxLen;
     1792        } else {
     1793            $tableName = shift @tableNames;
     1794            $short = $$shortName{$tableName};
     1795            unless ($short) {
     1796                # this is just an index heading
     1797                print PODFILE "\n=head2 $tableName Tags\n";
     1798                print PODFILE Doc2Pod($docs{$tableName}) if $docs{$tableName};
     1799                next;
     1800            }
     1801        }
     1802        my $isExif = $tableName eq 'Image::ExifTool::Exif::Main' ? 1 : undef;
     1803        my $isRiff = $tableName eq 'Image::ExifTool::RIFF::Info' ? 1 : undef;
    12501804        my $info = $$tagNameInfo{$tableName};
    1251         my $id = $$idTitle{$tableName};
     1805        my $id = $$idLabel{$tableName};
    12521806        my ($hid, $showGrp);
    12531807        # widths of the different columns in the POD documentation
    12541808        my ($wID,$wTag,$wReq,$wGrp) = (8,36,24,10);
    1255         my $composite = $short eq 'Composite' ? 1 : 0;
    1256         my $derived = $composite ? '<th>Derived From</th>' : '';
     1809        my ($composite, $derived, $notes, $prefix);
    12571810        if ($short eq 'Shortcuts') {
    12581811            $derived = '<th>Refers To</th>';
    12591812            $composite = 2;
    1260         }
    1261         my $podIdLen = $self->{LONG_ID}->{$tableName};
    1262         my $notes;
    1263         unless ($composite == 2) {
     1813        } elsif ($isStruct) {
     1814            $derived = '';
     1815            $notes = $$isStruct{NOTES};
     1816        } else {
    12641817            my $table = GetTagTable($tableName);
    12651818            $notes = $$table{NOTES};
    1266         }
    1267         my $prefix;
     1819            if ($$table{GROUPS}{0} eq 'Composite') {
     1820                $composite = 1;
     1821                $derived = '<th>Derived From</th>';
     1822            } else {
     1823                $composite = 0;
     1824                $derived = '';
     1825            }
     1826        }
     1827        my $podIdLen = $self->{LONG_ID}->{$tableName};
    12681828        if ($notes) {
    12691829            # remove unnecessary whitespace
     
    12841844            $podIdLen = $col if $podIdLen < $col;
    12851845        }
    1286         $id = '' if $short =~ /^XMP/;
    12871846        if ($id) {
    12881847            ($hid = "<th>$id</th>") =~ s/ /&nbsp;/g;
     
    12911850            my $longTag = $self->{LONG_NAME}->{$tableName};
    12921851            if ($wTag < $longTag) {
    1293                 $wID -= $longTag - $wTag;
    1294                 $wTag = $longTag;
    12951852                warn "Notice: Long tags in $tableName table\n";
    1296             }
    1297         } elsif ($short !~ /^(Composite|Shortcuts)/) {
     1853                if ($wID - $longTag + $wTag >= 6) { # don't let ID column get too narrow
     1854                    $wID -= $longTag - $wTag;
     1855                    $wTag = $longTag;
     1856                }
     1857            }
     1858        } elsif ($composite) {
     1859            $wTag += $wID - $wReq;
     1860            $hid = '';
     1861        } else {
    12981862            $wTag += 9;
    12991863            $hid = '';
    1300         } else {
    1301             $hid = '';
    1302             $wTag += $wID - $wReq if $composite;
    13031864        }
    13041865        if ($short eq 'EXIF') {
     
    13081869        }
    13091870        my $head = ($short =~ / /) ? 'head3' : 'head2';
    1310         print PODFILE "\n=$head $short Tags\n";
    1311         print PODFILE $docs{$short} if $docs{$short};
    1312         print PODFILE "\n$notes\n" if $notes;
     1871        my $str = $isStruct ? '' : ' Tags';
     1872        print PODFILE "\n=$head $short$str\n";
     1873        print PODFILE Doc2Pod($docs{$short}) if $docs{$short};
     1874        print PODFILE "\n", Doc2Pod($notes), "\n" if $notes;
    13131875        my $line = "\n";
    13141876        if ($id) {
     
    13191881            $line .= ' ';
    13201882        }
    1321         my $tagNameHeading = ($short eq 'XMP') ? 'Namespace' : 'Tag Name';
     1883        my $tagNameHeading = ($short eq 'XMP') ? 'Namespace' : ($isStruct?'Field':'Tag').' Name';
    13221884        $line .= sprintf " %-${wTag}s", $tagNameHeading;
    13231885        $line .= sprintf " %-${wReq}s", $composite == 2 ? 'Refers To' : 'Derived From' if $composite;
     
    13251887        $line .= ' Writable';
    13261888        print PODFILE $line;
    1327         $line =~ s/Sequence /Sequence\t/;   # don't want an underline after 'Sequence'
     1889        $line =~ s/^(\s*\w.{6}\w) /$1\t/;   # change space to tab after long ID label (ie. "Sequence")
    13281890        $line =~ s/\S/-/g;
    13291891        $line =~ s/- -/---/g;
    1330         $line =~ tr/\t/ /;
     1892        $line =~ tr/\t/ /;                  # change tab back to space
    13311893        print PODFILE $line,"\n";
    13321894        close HTMLFILE;
     
    13441906            ++$infoCount;
    13451907            my ($tagIDstr, $tagNames, $writable, $values, $require, $writeGroup) = @$infoList;
    1346             my ($align, $idStr, $w);
     1908            my ($align, $idStr, $w, $tip);
     1909            my $wTag2 = $wTag;
    13471910            if (not $id) {
    13481911                $idStr = '  ';
    1349             } elsif ($tagIDstr =~ /^\d+$/) {
     1912            } elsif ($tagIDstr =~ /^\d+(\.\d+)?$/) {
    13501913                $w = $wID - 3;
    1351                 $idStr = sprintf "  %${w}d    ", $tagIDstr;
     1914                $idStr = sprintf "  %${w}g    ", $tagIDstr;
    13521915                $align = " class=r";
    13531916            } else {
    13541917                $tagIDstr =~ s/^'$prefix/'/ if $prefix;
    13551918                $w = $wID;
    1356                 if (length $tagIDstr > $w) {
    1357                     # put tag name on next line if ID is too long
    1358                     $idStr = "  $tagIDstr\n   " . (' ' x $w);
    1359                     warn "Notice: Split $$tagNames[0] line\n";
    1360                 } else {
    1361                     $idStr = sprintf "  %-${w}s ", $tagIDstr;
    1362                 }
     1919                my $over = length($tagIDstr) - $w;
     1920                if ($over > 0) {
     1921                    # shift over tag name if there is room
     1922                    if ($over <= $wTag - length($$tagNames[0])) {
     1923                        $wTag2 -= $over;
     1924                        $w += $over;
     1925                    } else {
     1926                        # put tag name on next line if ID is too long
     1927                        $idStr = "  $tagIDstr\n   " . (' ' x $w);
     1928                        warn "Notice: Split $$tagNames[0] line\n";
     1929                    }
     1930                }
     1931                $idStr = sprintf "  %-${w}s ", $tagIDstr unless defined $idStr;
    13631932                $align = '';
    13641933            }
     
    13691938            my $wrStr = shift @vals;
    13701939            my $subdir;
    1371             # if this is a subdirectory, print subdir name (from values) instead of writable
    1372             if ($wrStr =~ /^-/) {
     1940            my @masks = grep /^\[Mask 0x[\da-f]+\]/, @$values;
     1941            my $tag = shift @tags;
     1942            # if this is a subdirectory or structure, print subdir name (from values) instead of writable
     1943            if ($wrStr =~ /^[-=]/) {
    13731944                $subdir = 1;
    1374                 @vals = @$values;
     1945                if (@masks) {
     1946                    # combine any mask into the format string
     1947                    $wrStr .= " & $1" if $masks[0] =~ /(0x[\da-f]+)/;
     1948                    shift @masks;
     1949                    @vals = grep !/^\[Mask 0x[\da-f]+\]/, @$values;
     1950                } else {
     1951                    @vals = @$values;
     1952                }
    13751953                # remove Notes if subdir has Notes as well
    13761954                shift @vals if $vals[0] =~ /^\(/ and @vals >= @$writable;
     
    13791957                for ($i=0; $i<@$writable; ++$i) {
    13801958                    $vals[$i] = $$writable[$i] unless defined $vals[$i];
     1959                    if (@masks) {
     1960                        $vals[$i] .= " & $1" if $masks[0] =~ /(0x[\da-f]+)/;
     1961                        shift @masks;
     1962                    }
    13811963                }
    13821964                if ($$sepTable{$vals[0]}) {
    1383                     $wrStr =~ s/^-//;
     1965                    $wrStr =~ s/^[-=]//;
    13841966                    $wrStr = 'N' unless $wrStr;
     1967                } elsif ($$structs{$vals[0]}) {
     1968                    my $flags = $wrStr =~ /([+_]+)$/ ? $1 : '';
     1969                    $wrStr = "$vals[0] Struct$flags";
    13851970                } else {
    13861971                    $wrStr = $vals[0];
    13871972                }
    13881973                shift @vals;
    1389             }
    1390             my $tag = shift @tags;
    1391             printf PODFILE "%s%-${wTag}s", $idStr, $tag;
    1392             warn "Warning: Pushed $tag\n" if $id and length($tag) > $wTag;
     1974            } elsif ($wrStr and $wrStr ne 'N' and @masks) {
     1975                # fill in missing entries if masks are different
     1976                my $mask = shift @masks;
     1977                while (@masks > @vals) {
     1978                    last if $masks[@vals] eq $mask;
     1979                    push @vals, $wrStr;
     1980                    push @tags, $tag if @tags < @vals;
     1981                }
     1982                # add Mask to Writable column in POD doc
     1983                $wrStr .= " & $1" if $mask =~ /(0x[\da-f]+)/;
     1984            }
     1985            printf PODFILE "%s%-${wTag2}s", $idStr, $tag;
     1986            warn "Warning: Pushed $tag\n" if $id and length($tag) > $wTag2;
    13931987            printf PODFILE " %-${wGrp}s", shift(@wGrp) || '-' if $showGrp;
    13941988            if ($composite) {
    13951989                @reqs = @$require;
    13961990                $w = $wReq; # Keep writable column in line
    1397                 length($tag) > $wTag and $w -= length($tag) - $wTag;
     1991                length($tag) > $wTag2 and $w -= length($tag) - $wTag2;
    13981992                printf PODFILE " %-${w}s", shift(@reqs) || '';
    13991993            }
    14001994            printf PODFILE " $wrStr\n";
     1995            my $numTags = scalar @$tagNames;
    14011996            my $n = 0;
    14021997            while (@tags or @reqs or @vals) {
     
    14041999                $line = '  ';
    14052000                $line .= ' 'x($wID+1) if $id;
    1406                 $line .= sprintf("%-${wTag}s", shift(@tags) || '');
     2001                $line .= sprintf("%-${wTag2}s", shift(@tags) || '');
    14072002                $line .= sprintf(" %-${wReq}s", shift(@reqs) || '') if $composite;
    14082003                $line .= sprintf(" %-${wGrp}s", shift(@wGrp) || '-') if $showGrp;
     
    14122007                    # use writable if this is a note
    14132008                    my $wrStr = $$writable[$n];
    1414                     if ($subdir and ($val =~ /^\(/ or $val =~ /=/ or ($wrStr and $wrStr !~ /^-/))) {
     2009                    if ($subdir and ($val =~ /^\(/ or $val =~ /=/ or ($wrStr and $wrStr !~ /^[-=]/))) {
    14152010                        $val = $wrStr;
    14162011                        if (defined $val) {
    1417                             $val =~ s/^-//;
     2012                            $val =~ s/^[-=]//;
    14182013                        } else {
    14192014                            # done with tag if nothing else to print
     
    14212016                        }
    14222017                    }
    1423                     $line .= " $val" if defined $val;
     2018                    if (defined $val) {
     2019                        $line .= " $val";
     2020                        if (@masks) {
     2021                            $line .= " & $1" if $masks[0] =~ /(0x[\da-f]+)/;
     2022                            shift @masks;
     2023                        }
     2024                    }
    14242025                }
    14252026                $line =~ s/\s+$//;  # trim trailing white space
     
    14302031                push @htmlTags, EscapeHTML($_);
    14312032            }
     2033            if (($isExif and $exifSpec{hex $tagIDstr}) or
     2034                ($isRiff and $tagIDstr=~/(\w+)/ and $riffSpec{$1}))
     2035            {
     2036                # underline "unknown" makernote tags only
     2037                my $n = $tagIDstr eq '0x927c' ? -1 : 0;
     2038                $htmlTags[$n] = "<u>$htmlTags[$n]</u>";
     2039            }
    14322040            $rowClass = $rowClass ? '' : " class=b";
    14332041            my $isSubdir;
    1434             if ($$writable[0] =~ /^-/) {
     2042            if ($$writable[0] =~ /^[-=]/) {
    14352043                $isSubdir = 1;
    1436                 foreach (@$writable) {
    1437                     s/^-(.+)/$1/;
    1438                 }
    1439             }
     2044                s/^[-=](.+)/$1/ foreach @$writable;
     2045            }
     2046            # add tooltip for hex conversion of Tag ID
     2047            if ($tagIDstr =~ /^0x[0-9a-f]+$/i) {
     2048                $tip = sprintf(" title='$tagIDstr = %u'",hex $tagIDstr);
     2049            } elsif ($tagIDstr =~ /^(\d+)(\.\d*)?$/) {
     2050                $tip = sprintf(" title='%u = 0x%x'", $1, $1);
     2051            } else {
     2052                $tip = '';
     2053                # use copyright symbol in QuickTime UserData tags
     2054                $tagIDstr =~ s/^"\\xa9/"&copy;/;
     2055            }
     2056            # add tooltip for special writable attributes
     2057            my $wtip = '';
     2058            my %wattr = (
     2059                '_' => 'Flattened',
     2060                '+' => 'List',
     2061                '/' => 'Avoided',
     2062                '~' => 'Writable only with -n',
     2063                '!' => 'Unsafe',
     2064                '*' => 'Protected',
     2065                ':' => 'Mandatory',
     2066            );
     2067            my ($wstr, %hasAttr, @hasAttr);
     2068            foreach $wstr (@$writable) {
     2069                next unless $wstr =~ m{([+/~!*:_]+)$};
     2070                my @a = split //, $1;
     2071                foreach (@a) {
     2072                    next if $hasAttr{$_};
     2073                    push @hasAttr, $_;
     2074                    $hasAttr{$_} = 1;
     2075                }
     2076            }
     2077            if (@hasAttr) {
     2078                $wtip = " title='";
     2079                my $n = 0;
     2080                foreach (@hasAttr) {
     2081                    $wtip .= "\n" if $n;
     2082                    $wtip .= " $_ = $wattr{$_}";
     2083                    ++$n;
     2084                }
     2085                $wtip .= "'";
     2086            }
     2087            # print this row in the tag table
    14402088            print HTMLFILE "<tr$rowClass>\n";
    1441             print HTMLFILE "<td$align>$tagIDstr</td>\n" if $id;
     2089            print HTMLFILE "<td$align$tip>$tagIDstr</td>\n" if $id;
    14422090            print HTMLFILE "<td>", join("\n  <br>",@htmlTags), "</td>\n";
    1443             print HTMLFILE "<td class=c>",join('<br>',@$writable),"</td>\n";
    1444             print HTMLFILE '<td>',join("\n  <br>",@$require),"</td>\n" if $composite;
     2091            print HTMLFILE "<td class=c$wtip>",join('<br>',@$writable),"</td>\n";
     2092            print HTMLFILE '<td class=n>',join("\n  <br>",@$require),"</td>\n" if $composite;
    14452093            print HTMLFILE "<td class=c>",join('<br>',@$writeGroup),"</td>\n" if $showGrp;
    14462094            print HTMLFILE "<td>";
    1447             my $close = '';
    1448             my @values;
    14492095            if (@$values) {
    14502096                if ($isSubdir) {
    1451                     my $smallNote;
     2097                    my ($smallNote, @values);
    14522098                    foreach (@$values) {
    14532099                        if (/^\(/) {
    1454                             $smallNote = 1 if $n <= 1;
     2100                            # set the note font
     2101                            $smallNote = 1 if $numTags < 2;
    14552102                            push @values, ($smallNote ? $noteFontSmall : $noteFont) . "$_</span>";
    14562103                            next;
    14572104                        }
     2105                        # make text in square brackets small
     2106                        /^\[/ and push(@values, "<span class=s>$_</span>"), next;
    14582107                        /=/ and push(@values, $_), next;
    14592108                        my @names = split;
    1460                         $url = (shift @names) . '.html';
    1461                         @names and $url .= '#' . join '_', @names;
    14622109                        my $suffix = ' Tags';
    14632110                        if ($$sepTable{$_}) {
     
    14652112                            $suffix = ' Values';
    14662113                        }
     2114                        # currently all structures are in XMP documentation
     2115                        if ($$structs{$_} and $short =~ /^XMP/) {
     2116                            unshift @names, 'XMP';
     2117                            push @structs, $_;  # list this later
     2118                            $suffix = ' Struct';
     2119                        }
     2120                        $url = (shift @names) . '.html';
     2121                        @names and $url .= '#' . join '_', @names;
    14672122                        push @values, "--&gt; <a href='$url'>$_$suffix</a>";
    14682123                    }
    14692124                    # put small note last
    14702125                    $smallNote and push @values, shift @values;
     2126                    print HTMLFILE join("\n  <br>",@values);
    14712127                } else {
     2128                    my ($close, $br) = ('', '');
    14722129                    foreach (@$values) {
    1473                         $_ = EscapeHTML($_);
    1474                         /^\(/ and $_ = "$noteFont$_</span>";
    1475                         push @values, $_;
    1476                     }
    1477                     print HTMLFILE "<span class=s>";
    1478                     $close = '</span>';
     2130                        if (s/^\[!HTML\]//) {
     2131                            print HTMLFILE $close if $close;
     2132                            print HTMLFILE $_;
     2133                            $close = $br = '';
     2134                        } else {
     2135                            if (/^\(/) {
     2136                                # notes can use POD syntax
     2137                                $_ = $noteFont . Doc2Html($_) . "</span>";
     2138                            } else {
     2139                                $_ = EscapeHTML($_);
     2140                            }
     2141                            $close or $_ = "<span class=s>$_", $close = '</span>';
     2142                            print HTMLFILE $br, $_;
     2143                            $br = "\n  <br>";
     2144                        }
     2145                    }
     2146                    print HTMLFILE $close if $close;
    14792147                }
    14802148            } else {
    1481                 push @values, '&nbsp;';
    1482             }
    1483             print HTMLFILE join("\n  <br>",@values),"$close</td></tr>\n";
     2149                print HTMLFILE '&nbsp;';
     2150            }
     2151            print HTMLFILE "</td></tr>\n";
    14842152        }
    14852153        unless ($infoCount) {
     
    14882156            ++$cols if $hid;
    14892157            ++$cols if $derived;
    1490             print HTMLFILE "<tr><td colspan=$cols class=c>[no tags known]</td></tr>\n";
     2158            print HTMLFILE "<tr><td colspan=$cols class=c><i>[no tags known]</i></td></tr>\n";
    14912159        }
    14922160        print HTMLFILE "</table></td></tr></table></blockquote>\n\n";
     
    15142182Image::ExifTool::TagNames.pod, as well as HTML tag name documentation.  It
    15152183is used before each new ExifTool release to update the lookup tables and
    1516 documentation.
     2184documentation, but it is not used otherwise.
    15172185
    15182186=head1 SYNOPSIS
     
    15262194  $ok = $builder->WriteTagNames('lib/Image/ExifTool/TagNames.pod','html');
    15272195
     2196=head1 MEMBER VARIABLES
     2197
     2198=over 4
     2199
     2200=item PRESERVE_DATE
     2201
     2202Flag to preserve "Last revised" date in HTML files.  Set before calling
     2203WriteTagNames().
     2204
     2205=item COUNT
     2206
     2207Reference to hash containing counting statistics.  Keys are the
     2208descriptions, and values are the numerical counts.  Valid after
     2209BuildTagLookup object is created, but additional statistics are added by
     2210WriteTagNames().
     2211
     2212=back
     2213
    15282214=head1 AUTHOR
    15292215
    1530 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     2216Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    15312217
    15322218This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Canon.pm

    r16842 r24107  
    44# Description:  Canon EXIF maker notes tags
    55#
    6 # Revisions:    11/25/03 - P. Harvey Created
    7 #               12/03/03 - P. Harvey Figured out lots more tags and added
    8 #                            CanonAFInfo
    9 #               02/17/04 - Michael Rommel Added IxusAFPoint
    10 #               01/27/05 - P. Harvey Disable validation of CanonAFInfo
    11 #               01/30/05 - P. Harvey Added a few more tags (ref 4)
    12 #               02/10/06 - P. Harvey Decode a lot of new tags (ref 12)
     6# Revisions:    11/25/2003 - P. Harvey Created
     7#               12/03/2003 - P. Harvey Decode lots more tags and add CanonAFInfo
     8#               02/17/2004 - Michael Rommel Added IxusAFPoint
     9#               01/27/2005 - P. Harvey Disable validation of CanonAFInfo
     10#               01/30/2005 - P. Harvey Added a few more tags (ref 4)
     11#               02/10/2006 - P. Harvey Decode a lot of new tags (ref 12)
     12#               [ongoing]  - P. Harvey Constantly decoding new information
     13#
     14# Notes:        Must check FocalPlaneX/YResolution values for each new model!
    1315#
    1416# References:   1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
     
    1820#               5) Juha Eskelinen private communication (20D)
    1921#               6) Richard S. Smith private communication (20D)
    20 #               7) Denny Priebe private communication (1D MkII)
     22#               7) Denny Priebe private communication (1DmkII)
    2123#               8) Irwin Poche private communication
    22 #               9) Michael Tiemann private communication (1D MkII)
    23 #              10) Volker Gering private communication (1D MkII)
     24#               9) Michael Tiemann private communication (1DmkII)
     25#              10) Volker Gering private communication (1DmkII)
    2426#              11) "cip" private communication
    2527#              12) Rainer Honle private communication (5D)
    2628#              13) http://www.cybercom.net/~dcoffin/dcraw/
    2729#              14) (bozi) http://www.cpanforum.com/threads/2476 and /2563
    28 #              15) http://homepage3.nifty.com/kamisaka/makernote/makernote_canon.htm and
    29 #                  http://homepage3.nifty.com/kamisaka/makernote/CanonLens.htm (2006/07/04)
     30#              15) http://homepage3.nifty.com/kamisaka/makernote/makernote_canon.htm (2007/11/19)
     31#                + http://homepage3.nifty.com/kamisaka/makernote/CanonLens.htm (2007/11/19)
    3032#              16) Emil Sit private communication (30D)
    3133#              17) http://www.asahi-net.or.jp/~xp8t-ymzk/s10exif.htm
     
    3335#              19) Warren Stockton private communication
    3436#              20) Bogdan private communication
     37#              21) Heiko Hinrichs private communication
     38#              22) Dave Nicholson private communication (PowerShot S30)
     39#              23) Magne Nilsen private communication (400D)
     40#              24) Wolfgang Hoffmann private communication (40D)
     41#              26) Steve Balcombe private communication
     42#              27) Chris Huebsch private communication (40D)
     43#              28) Hal Williamson private communication (XTi)
     44#              29) Ger Vermeulen private communication
     45#              30) David Pitcher private communication (1DmkIII)
     46#              31) Darryl Zurn private communication (A590IS)
     47#              32) Rich Taylor private communication (5D)
     48#              33) D.J. Cristi private communication
     49#              34) Andreas Huggel and Pascal de Bruijn private communication
     50#              35) Jan Boelsma private communication
     51#              36) Karl-Heinz Klotz private communication (http://www.dslr-forum.de/showthread.php?t=430900)
     52#              37) Vesa Kivisto private communication (30D)
     53#              38) Kurt Garloff private communication (5DmkII)
     54#              39) Irwin Poche private communication (5DmkII)
     55#              40) Jose Oliver-Didier private communication
     56#              41) http://www.cpanforum.com/threads/10730
     57#              42) Norbert Wasser private communication
     58#              43) Karsten Sote private communication
     59#              44) Hugh Griffiths private communication (5DmkII)
     60#              45) Mark Berger private communication (5DmkII)
     61#              46) Dieter Steiner private communication (7D)
     62#              47) http://www.exiv2.org/
     63#              48) Tomasz A. Kawecki private communication (550D, firmware 1.0.6, 1.0.8)
     64#              49) http://www.listware.net/201101/digikam-users/49795-digikam-users-re-lens-recognition.html
     65#              JD) Jens Duttke private communication
    3566#------------------------------------------------------------------------------
    3667
     
    4475sub WriteCanon($$$);
    4576sub ProcessSerialData($$$);
    46 
    47 $VERSION = '1.77';
    48 
     77sub ProcessFilters($$$);
     78sub SwapWords($);
     79
     80$VERSION = '2.71';
     81
     82# Note: Removed 'USM' from 'L' lenses since it is redundant - PH
     83# (or is it?  Ref 32 shows 5 non-USM L-type lenses)
    4984my %canonLensTypes = ( #4
    50     1 => 'Canon EF 50mm f/1.8',
    51     2 => 'Canon EF 28mm f/2.8',
    52     3 => 'Canon EF 135mm f/2.8 Soft', #15
    53     4 => 'Sigma UC Zoom 35-135mm f/4-5.6',
    54     6 => 'Sigma 18-125mm F3.5-5.6 DC IF ASP or Tokina AF193-2 19-35mm f/3.5-4.5',
    55     7 => 'Canon EF 100-300mm F5.6L', #15
    56     # 10 can be 3 different Sigma lenses:
    57     # Sigma 50mm f/2.8 EX or Sigma 28mm f/1.8
    58     # or Sigma 105mm f/2.8 Macro EX (ref 15)
    59     10 => 'Canon EF 50mm f/2.5 Macro or Sigma', #10/4/15
     85     Notes => q{
     86        Decimal values differentiate lenses which would otherwise have the same
     87        LensType, and are used by the Composite LensID tag when attempting to
     88        identify the specific lens model.
     89     },
     90     1 => 'Canon EF 50mm f/1.8',
     91     2 => 'Canon EF 28mm f/2.8',
     92     # (3 removed in current Kamisaka list)
     93     3 => 'Canon EF 135mm f/2.8 Soft', #15/32
     94     4 => 'Canon EF 35-105mm f/3.5-4.5 or Sigma Lens', #28
     95     4.1 => 'Sigma UC Zoom 35-135mm f/4-5.6',
     96     5 => 'Canon EF 35-70mm f/3.5-4.5', #32
     97     6 => 'Canon EF 28-70mm f/3.5-4.5 or Sigma or Tokina Lens', #32
     98     6.1 => 'Sigma 18-50mm f/3.5-5.6 DC', #23
     99     6.2 => 'Sigma 18-125mm f/3.5-5.6 DC IF ASP',
     100     6.3 => 'Tokina AF193-2 19-35mm f/3.5-4.5',
     101     6.4 => 'Sigma 28-80mm f/3.5-5.6 II Macro', #47
     102     7 => 'Canon EF 100-300mm f/5.6L', #15
     103     8 => 'Canon EF 100-300mm f/5.6 or Sigma or Tokina Lens', #32
     104     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)
     105     8.2 => 'Tokina AT-X242AF 24-200mm f/3.5-5.6', #15
     106     9 => 'Canon EF 70-210mm f/4', #32
     107     9.1 => 'Sigma 55-200mm f/4-5.6 DC', #34
     108    10 => 'Canon EF 50mm f/2.5 Macro or Sigma Lens', #10 (+ LSC Life Size Converter --> 70mm - PH)
     109    10.1 => 'Sigma 50mm f/2.8 EX', #4
     110    10.2 => 'Sigma 28mm f/1.8',
     111    10.3 => 'Sigma 105mm f/2.8 Macro EX', #15
     112    10.4 => 'Sigma 70mm f/2.8 EX DG Macro EF', #Jean-Michel Dubois
    60113    11 => 'Canon EF 35mm f/2', #9
    61     13 => 'Canon EF 15mm f/2.8', #9
     114    13 => 'Canon EF 15mm f/2.8 Fisheye', #9
     115    14 => 'Canon EF 50-200mm f/3.5-4.5L', #32
     116    15 => 'Canon EF 50-200mm f/3.5-4.5', #32
     117    16 => 'Canon EF 35-135mm f/3.5-4.5', #32
     118    17 => 'Canon EF 35-70mm f/3.5-4.5A', #32
     119    18 => 'Canon EF 28-70mm f/3.5-4.5', #32
     120    20 => 'Canon EF 100-200mm f/4.5A', #32
    62121    21 => 'Canon EF 80-200mm f/2.8L',
    63     22 => 'Tokina AT-X280AF PRO 28-80mm F2.8 ASPHERICAL', #15
    64     # 26 can also be 2 Tamron lenses: (ref 15)
    65     # Tamron SP AF 90mm f/2.8 Di Macro or Tamron SP AF 180mm F3.5 Di Macro
    66     26 => 'Canon EF 100mm f/2.8 Macro or Cosina 100mm f/3.5 Macro AF or Tamron',
    67     # 28 can be: (ref 15)
    68     # - Tamron SP AF 28-105mm f/2.8 LD Aspherical IF
    69     # - Tamron SP AF 28-75mm F/2.8 XR Di LD Aspherical [ IF ] Macro
    70     28 => 'Tamron AF Aspherical 28-200mm f/3.8-5.6 or 28-75mm f/2.8 or 28-105mm f/2.8',#4/11/14/15
    71     29 => 'Canon EF 50mm f/1.8 MkII',
    72     31 => 'Tamron SP AF 300mm f/2.8 LD IF', #15
    73     32 => 'Canon EF 24mm f/2.8 or Sigma 15mm f/2.8 EX Fisheye', #10/11
     122    22 => 'Canon EF 20-35mm f/2.8L or Tokina Lens', #32
     123    22.1 => 'Tokina AT-X280AF PRO 28-80mm f/2.8 Aspherical', #15
     124    23 => 'Canon EF 35-105mm f/3.5-4.5', #32
     125    24 => 'Canon EF 35-80mm f/4-5.6 Power Zoom', #32
     126    25 => 'Canon EF 35-80mm f/4-5.6 Power Zoom', #32
     127    26 => 'Canon EF 100mm f/2.8 Macro or Other Lens',
     128    26.1 => 'Cosina 100mm f/3.5 Macro AF',
     129    26.2 => 'Tamron SP AF 90mm f/2.8 Di Macro', #15
     130    26.3 => 'Tamron SP AF 180mm f/3.5 Di Macro', #15
     131    26.4 => 'Carl Zeiss Planar T* 50mm f/1.4', #PH
     132    27 => 'Canon EF 35-80mm f/4-5.6', #32
     133    28 => 'Canon EF 80-200mm f/4.5-5.6 or Tamron Lens', #32
     134    28.1 => 'Tamron SP AF 28-105mm f/2.8 LD Aspherical IF', #15
     135    28.2 => 'Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical [IF] Macro', #4
     136    28.3 => 'Tamron AF 70-300mm f/4.5-5.6 Di LD 1:2 Macro Zoom', #11
     137    28.4 => 'Tamron AF Aspherical 28-200mm f/3.8-5.6', #14
     138    29 => 'Canon EF 50mm f/1.8 II',
     139    30 => 'Canon EF 35-105mm f/4.5-5.6', #32
     140    31 => 'Canon EF 75-300mm f/4-5.6 or Tamron Lens', #32
     141    31.1 => 'Tamron SP AF 300mm f/2.8 LD IF', #15
     142    32 => 'Canon EF 24mm f/2.8 or Sigma Lens', #10
     143    32.1 => 'Sigma 15mm f/2.8 EX Fisheye', #11
     144    33 => 'Voigtlander or Zeiss Lens',
     145    33.1 => 'Voigtlander Ultron 40mm f/2 SLII Aspherical', #45
     146    33.2 => 'Zeiss Distagon 35mm T* f/2 ZE', #PH
     147    35 => 'Canon EF 35-80mm f/4-5.6', #32
     148    36 => 'Canon EF 38-76mm f/4.5-5.6', #32
     149    37 => 'Canon EF 35-80mm f/4-5.6 or Tamron Lens', #32
     150    37.1 => 'Tamron 70-200mm f/2.8 Di LD IF Macro', #PH
     151    37.2 => 'Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical [IF] Macro Model A20', #38
     152    37.3 => 'Tamron SP AF 17-50mm f/2.8 XR Di II VC LD Aspherical [IF]', #34
     153    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
     154    38 => 'Canon EF 80-200mm f/4.5-5.6', #32
    74155    39 => 'Canon EF 75-300mm f/4-5.6',
    75156    40 => 'Canon EF 28-80mm f/3.5-5.6',
     157    41 => 'Canon EF 28-90mm f/4-5.6', #32
     158    42 => 'Canon EF 28-200mm f/3.5-5.6 or Tamron Lens', #32
     159    42.1 => 'Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical [IF] Macro Model A20', #15
    76160    43 => 'Canon EF 28-105mm f/4-5.6', #10
    77     45 => 'Canon EF-S 18-55mm f/3.5-5.6', #PH
     161    44 => 'Canon EF 90-300mm f/4.5-5.6', #32
     162    45 => 'Canon EF-S 18-55mm f/3.5-5.6 [II]', #PH (same ID for version II, ref 20)
     163    46 => 'Canon EF 28-90mm f/4-5.6', #32
     164    48 => 'Canon EF-S 18-55mm f/3.5-5.6 IS', #20
     165    49 => 'Canon EF-S 55-250mm f/4-5.6 IS', #23
     166    50 => 'Canon EF-S 18-200mm f/3.5-5.6 IS',
     167    51 => 'Canon EF-S 18-135mm f/3.5-5.6 IS', #PH
     168    52 => 'Canon EF-S 18-55mm f/3.5-5.6 IS II', #PH
     169    94 => 'Canon TS-E 17mm f/4L', #42
     170    95 => 'Canon TS-E 24.0mm f/3.5 L II', #43
    78171    124 => 'Canon MP-E 65mm f/2.8 1-5x Macro Photo', #9
    79172    125 => 'Canon TS-E 24mm f/3.5L',
    80173    126 => 'Canon TS-E 45mm f/2.8', #15
    81174    127 => 'Canon TS-E 90mm f/2.8', #15
     175    129 => 'Canon EF 300mm f/2.8L', #32
    82176    130 => 'Canon EF 50mm f/1.0L', #10/15
    83     131 => 'Sigma 17-35mm f2.8-4 EX Aspherical HSM',
     177    131 => 'Canon EF 28-80mm f/2.8-4L or Sigma Lens', #32
     178    131.1 => 'Sigma 8mm f/3.5 EX DG Circular Fisheye', #15
     179    131.2 => 'Sigma 17-35mm f/2.8-4 EX DG Aspherical HSM', #15
     180    131.3 => 'Sigma 17-70mm f/2.8-4.5 DC Macro', #PH (NC)
     181    131.4 => 'Sigma APO 50-150mm f/2.8 [II] EX DC HSM', #15 ([II] ref PH)
     182    131.5 => 'Sigma APO 120-300mm f/2.8 EX DG HSM', #15
     183           # 'Sigma APO 120-300mm f/2.8 EX DG HSM + 1.4x', #15
     184           # 'Sigma APO 120-300mm f/2.8 EX DG HSM + 2x', #15
     185    132 => 'Canon EF 1200mm f/5.6L', #32
    84186    134 => 'Canon EF 600mm f/4L IS', #15
    85187    135 => 'Canon EF 200mm f/1.8L',
    86188    136 => 'Canon EF 300mm f/2.8L',
    87     137 => 'Canon EF 85mm f/1.2L', #10
     189    137 => 'Canon EF 85mm f/1.2L or Sigma or Tamron Lens', #10
     190    137.1 => 'Sigma 18-50mm f/2.8-4.5 DC OS HSM', #PH
     191    137.2 => 'Sigma 50-200mm f/4-5.6 DC OS HSM', #PH
     192    137.3 => 'Sigma 18-250mm f/3.5-6.3 DC OS HSM', #PH
     193    137.4 => 'Sigma 24-70mm f/2.8 IF EX DG HSM', #PH
     194    137.5 => 'Sigma 18-125mm f/3.8-5.6 DC OS HSM', #PH
     195    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
     196    137.7 => 'Sigma 17-50mm f/2.8 OS HSM', #PH (from Exiv2)
     197    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
     198    138 => 'Canon EF 28-80mm f/2.8-4L', #32
    88199    139 => 'Canon EF 400mm f/2.8L',
     200    140 => 'Canon EF 500mm f/4.5L', #32
    89201    141 => 'Canon EF 500mm f/4.5L',
    90202    142 => 'Canon EF 300mm f/2.8L IS', #15
    91203    143 => 'Canon EF 500mm f/4L IS', #15
    92     149 => 'Canon EF 100mm f/2', #9
    93     # 150 can be: (ref 15)
    94     # Sigma 20mm EX F1.8/Sigma 30mm F1.4 DC HSM/Sigma 24mm F1.8 DG Macro EX
    95     150 => 'Canon EF 14mm f/2.8L or Sigma 20mm EX f/1.8', #10/4
     204    144 => 'Canon EF 35-135mm f/4-5.6 USM', #26
     205    145 => 'Canon EF 100-300mm f/4.5-5.6 USM', #32
     206    146 => 'Canon EF 70-210mm f/3.5-4.5 USM', #32
     207    147 => 'Canon EF 35-135mm f/4-5.6 USM', #32
     208    148 => 'Canon EF 28-80mm f/3.5-5.6 USM', #32
     209    149 => 'Canon EF 100mm f/2 USM', #9
     210    150 => 'Canon EF 14mm f/2.8L or Sigma Lens', #10
     211    150.1 => 'Sigma 20mm EX f/1.8', #4
     212    150.2 => 'Sigma 30mm f/1.4 DC HSM', #15
     213    150.3 => 'Sigma 24mm f/1.8 DG Macro EX', #15
    96214    151 => 'Canon EF 200mm f/2.8L',
    97     # 152 can be: (ref 15)
    98     # Sigma 12-24mm F4.5-5.6 EX DG ASPHERICAL HSM
    99     # Sigma 14mm F2.8 EX Aspherical HSM
    100     # Sigma 10-20mm F4-5.6 (ref 14)
    101     # Sigma 100-300 F4 (ref Bozi)
    102     152 => 'Sigma Lens (various models)',
    103     # 153 is Tamron AF 28-300mm, 18-200mm F3.5-6.3 Di II or
    104     #        Tamron 18-250mm F3.5-6.3 Di II_LD Aspherical (IF) Macro (ref PH)
    105     153 => 'Canon EF 35-350mm f/3.5-5.6L or Tamron or Sigma Bigma', #PH/15
     215    152 => 'Canon EF 300mm f/4L IS or Sigma Lens', #15
     216    152.1 => 'Sigma 12-24mm f/4.5-5.6 EX DG ASPHERICAL HSM', #15
     217    152.2 => 'Sigma 14mm f/2.8 EX Aspherical HSM', #15
     218    152.3 => 'Sigma 10-20mm f/4-5.6', #14
     219    152.4 => 'Sigma 100-300mm f/4', # (ref Bozi)
     220    153 => 'Canon EF 35-350mm f/3.5-5.6L or Sigma or Tamron Lens', #PH
     221    153.1 => 'Sigma 50-500mm f/4-6.3 APO HSM EX', #15
     222    153.2 => 'Tamron AF 28-300mm f/3.5-6.3 XR LD Aspherical [IF] Macro',
     223    153.3 => 'Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical [IF] Macro Model A14', #15
     224    153.4 => 'Tamron 18-250mm f/3.5-6.3 Di II LD Aspherical [IF] Macro', #PH
     225    154 => 'Canon EF 20mm f/2.8 USM', #15
    106226    155 => 'Canon EF 85mm f/1.8 USM',
    107     156 => 'Canon EF 28-105mm f/3.5-4.5 USM',
    108     160 => 'Canon EF 20-35mm f/3.5-4.5 USM',
    109     161 => 'Canon EF 28-70mm f/2.8L or Sigma 24-70mm EX f/2.8 or Tamron 90mm f/2.8',
     227    156 => 'Canon EF 28-105mm f/3.5-4.5 USM or Tamron Lens',
     228    156.1 => 'Tamron SP 70-300mm f/4.0-5.6 Di VC USD', #PH (model A005)
     229    160 => 'Canon EF 20-35mm f/3.5-4.5 USM or Tamron or Tokina Lens',
     230    160.1 => 'Tamron AF 19-35mm f/3.5-4.5', #44
     231    160.2 => 'Tokina AT-X 124 AF 12-24mm f/4 DX', #49 (not sure about specific model - PH)
     232    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)
     233    161 => 'Canon EF 28-70mm f/2.8L or Sigma or Tamron Lens',
     234    161.1 => 'Sigma 24-70mm f/2.8 EX',
     235    161.2 => 'Sigma 28-70mm f/2.8 EX', #PH (http://www.breezesys.com/forum/showthread.php?t=3718)
     236    161.3 => 'Tamron AF 17-50mm f/2.8 Di-II LD Aspherical', #40
     237    161.4 => 'Tamron 90mm f/2.8',
     238    162 => 'Canon EF 200mm f/2.8L', #32
     239    163 => 'Canon EF 300mm f/4L', #32
     240    164 => 'Canon EF 400mm f/5.6L', #32
    110241    165 => 'Canon EF 70-200mm f/2.8 L',
    111     166 => 'Canon EF 70-200mm f/2.8 L + x1.4',
    112     167 => 'Canon EF 70-200mm f/2.8 L + x2',
     242    166 => 'Canon EF 70-200mm f/2.8 L + 1.4x',
     243    167 => 'Canon EF 70-200mm f/2.8 L + 2x',
    113244    168 => 'Canon EF 28mm f/1.8 USM', #15
    114     169 => 'Canon EF17-35mm f/2.8L or Sigma 15-30mm f/3.5-4.5 EX DG Aspherical', #15/4
     245    169 => 'Canon EF 17-35mm f/2.8L or Sigma Lens', #15
     246    169.1 => 'Sigma 18-200mm f/3.5-6.3 DC OS', #23
     247    169.2 => 'Sigma 15-30mm f/3.5-4.5 EX DG Aspherical', #4
     248    169.3 => 'Sigma 18-50mm f/2.8 Macro', #26
     249    169.4 => 'Sigma 50mm f/1.4 EX DG HSM', #PH
     250    169.5 => 'Sigma 85mm f/1.4 EX DG HSM', #Rolando Ruzic
     251    169.6 => 'Sigma 30mm f/1.4 EX DC HSM', #Rodolfo Borges
    115252    170 => 'Canon EF 200mm f/2.8L II', #9
    116     # the following value is used by 2 different Sigma lenses (ref 14):
    117     # Sigma 180mm EX HSM Macro f/3.5 or Sigma APO Macro 150mm F3.5 EX DG IF HSM
    118     # 173 => 'Canon EF 180mm Macro f/3.5L or Sigma 180mm EX HSM Macro f/3.5', #9
    119     173 => 'Canon EF 180mm Macro f/3.5L or Sigma 180mm F3.5 or 150mm f/2.8 Macro',
    120     174 => 'Canon EF 135mm f/2L', #9
     253    171 => 'Canon EF 300mm f/4L', #15
     254    172 => 'Canon EF 400mm f/5.6L', #32
     255    173 => 'Canon EF 180mm Macro f/3.5L or Sigma Lens', #9
     256    173.1 => 'Sigma 180mm EX HSM Macro f/3.5', #14
     257    173.2 => 'Sigma APO Macro 150mm f/2.8 EX DG HSM', #14
     258    174 => 'Canon EF 135mm f/2L or Sigma Lens', #9
     259    174.1 => 'Sigma 70-200mm f/2.8 EX DG APO OS HSM', #PH (probably version II of this lens)
     260    175 => 'Canon EF 400mm f/2.8L', #32
    121261    176 => 'Canon EF 24-85mm f/3.5-4.5 USM',
    122262    177 => 'Canon EF 300mm f/4L IS', #9
    123263    178 => 'Canon EF 28-135mm f/3.5-5.6 IS',
     264    179 => 'Canon EF 24mm f/1.4L', #20
    124265    180 => 'Canon EF 35mm f/1.4L', #9
    125     181 => 'Canon EF 100-400mm f/4.5-5.6L IS + x1.4', #15
    126     182 => 'Canon EF 100-400mm f/4.5-5.6L IS + x2',
     266    181 => 'Canon EF 100-400mm f/4.5-5.6L IS + 1.4x', #15
     267    182 => 'Canon EF 100-400mm f/4.5-5.6L IS + 2x',
    127268    183 => 'Canon EF 100-400mm f/4.5-5.6L IS',
    128     184 => 'Canon EF 400mm f/2.8L + x2', #15
     269    184 => 'Canon EF 400mm f/2.8L + 2x', #15
     270    185 => 'Canon EF 600mm f/4L IS', #32
    129271    186 => 'Canon EF 70-200mm f/4L', #9
     272    187 => 'Canon EF 70-200mm f/4L + 1.4x', #26
     273    188 => 'Canon EF 70-200mm f/4L + 2x', #PH
     274    189 => 'Canon EF 70-200mm f/4L + 2.8x', #32
    130275    190 => 'Canon EF 100mm f/2.8 Macro',
    131276    191 => 'Canon EF 400mm f/4 DO IS', #9
    132     # 196 Canon 75-300mm F4? #15
    133     197 => 'Canon EF 75-300mm f/4-5.6 IS',
     277    193 => 'Canon EF 35-80mm f/4-5.6 USM', #32
     278    194 => 'Canon EF 80-200mm f/4.5-5.6 USM', #32
     279    195 => 'Canon EF 35-105mm f/4.5-5.6 USM', #32
     280    196 => 'Canon EF 75-300mm f/4-5.6 USM', #15/32
     281    197 => 'Canon EF 75-300mm f/4-5.6 IS USM',
    134282    198 => 'Canon EF 50mm f/1.4 USM', #9
    135     202 => 'Canon EF 28-80 f/3.5-5.6 USM IV',
    136     211 => 'Canon EF 28-200mm f/3.5-5.6', #15
    137     213 => 'Canon EF 90-300mm f/4.5-5.6',
    138     214 => 'Canon EF-S 18-55mm f/3.5-4.5 USM', #PH
    139     224 => 'Canon EF 70-200mm f/2.8L IS USM', #11
    140     225 => 'Canon EF 70-200mm f/2.8L IS USM + x1.4', #11
    141     226 => 'Canon EF 70-200mm f/2.8L IS USM + x2', #14
     283    199 => 'Canon EF 28-80mm f/3.5-5.6 USM', #32
     284    200 => 'Canon EF 75-300mm f/4-5.6 USM', #32
     285    201 => 'Canon EF 28-80mm f/3.5-5.6 USM', #32
     286    202 => 'Canon EF 28-80mm f/3.5-5.6 USM IV',
     287    208 => 'Canon EF 22-55mm f/4-5.6 USM', #32
     288    209 => 'Canon EF 55-200mm f/4.5-5.6', #32
     289    210 => 'Canon EF 28-90mm f/4-5.6 USM', #32
     290    211 => 'Canon EF 28-200mm f/3.5-5.6 USM', #15
     291    212 => 'Canon EF 28-105mm f/4-5.6 USM', #15
     292    213 => 'Canon EF 90-300mm f/4.5-5.6 USM',
     293    214 => 'Canon EF-S 18-55mm f/3.5-5.6 USM', #PH/34
     294    215 => 'Canon EF 55-200mm f/4.5-5.6 II USM',
     295    224 => 'Canon EF 70-200mm f/2.8L IS', #11
     296    225 => 'Canon EF 70-200mm f/2.8L IS + 1.4x', #11
     297    226 => 'Canon EF 70-200mm f/2.8L IS + 2x', #14
     298    227 => 'Canon EF 70-200mm f/2.8L IS + 2.8x', #32
     299    228 => 'Canon EF 28-105mm f/3.5-4.5 USM', #32
    142300    229 => 'Canon EF 16-35mm f/2.8L', #PH
    143301    230 => 'Canon EF 24-70mm f/2.8L', #9
    144302    231 => 'Canon EF 17-40mm f/4L',
    145303    232 => 'Canon EF 70-300mm f/4.5-5.6 DO IS USM', #15
     304    233 => 'Canon EF 28-300mm f/3.5-5.6L IS', #PH
    146305    234 => 'Canon EF-S 17-85mm f4-5.6 IS USM', #19
    147     235 => 'Canon EF-S10-22mm F3.5-4.5 USM', #15
    148     236 => 'Canon EF-S60mm F2.8 Macro USM', #15
     306    235 => 'Canon EF-S 10-22mm f/3.5-4.5 USM', #15
     307    236 => 'Canon EF-S 60mm f/2.8 Macro USM', #15
    149308    237 => 'Canon EF 24-105mm f/4L IS', #15
    150309    238 => 'Canon EF 70-300mm f/4-5.6 IS USM', #15
    151     239 => 'Canon EF 85mm f/1.2L II USM', #15
     310    239 => 'Canon EF 85mm f/1.2L II', #15
    152311    240 => 'Canon EF-S 17-55mm f/2.8 IS USM', #15
    153     241 => 'Canon EF 50mm f/1.2L USM', #15
    154     242 => 'Canon EF 70-200mm f/4L IS USM', #PH
     312    241 => 'Canon EF 50mm f/1.2L', #15
     313    242 => 'Canon EF 70-200mm f/4L IS', #PH
     314    243 => 'Canon EF 70-200mm f/4L IS + 1.4x', #15
     315    244 => 'Canon EF 70-200mm f/4L IS + 2x', #PH
     316    245 => 'Canon EF 70-200mm f/4L IS + 2.8x', #32
     317    246 => 'Canon EF 16-35mm f/2.8L II', #PH
     318    247 => 'Canon EF 14mm f/2.8L II USM', #32
     319    248 => 'Canon EF 200mm f/2L IS', #42
     320    249 => 'Canon EF 800mm f/5.6L IS', #35
     321    250 => 'Canon EF 24 f/1.4L II', #41
     322    251 => 'Canon EF 70-200mm f/2.8L IS II USM',
     323    254 => 'Canon EF 100mm f/2.8L Macro IS USM', #42
     324    # Note: LensType 488 (0x1e8) is reported as 232 (0xe8) in 7D CameraSettings
     325    488 => 'Canon EF-S 15-85mm f/3.5-5.6 IS USM', #PH
     326    489 => 'Canon EF 70-300mm f/4-5.6L IS USM', #Gerald Kapounek
    155327);
    156328
     
    202374    0x1590000 => 'PowerShot SD20 / Digital IXUS i5 / IXY Digital L2',
    203375    0x1640000 => 'PowerShot S2 IS',
    204     0x1650000 => 'PowerShot SD430 / IXUS Wireless / IXY Wireless',
     376    0x1650000 => 'PowerShot SD430 / Digital IXUS Wireless / IXY Digital Wireless',
    205377    0x1660000 => 'PowerShot SD500 / Digital IXUS 700 / IXY Digital 600',
    206378    0x1668000 => 'EOS D60',
    207     0x1700000 => 'PowerShot SD30 / Digital IXUS i zoom / IXY Digital L3',
     379    0x1700000 => 'PowerShot SD30 / Digital IXUS i Zoom / IXY Digital L3',
    208380    0x1740000 => 'PowerShot A430',
    209381    0x1750000 => 'PowerShot A410',
     
    245417    0x2300000 => 'PowerShot SD950 IS / Digital IXUS 960 IS / IXY Digital 2000 IS',
    246418    0x2310000 => 'PowerShot SD870 IS / Digital IXUS 860 IS / IXY Digital 910 IS',
     419    0x2320000 => 'PowerShot SD890 IS / Digital IXUS 970 IS / IXY Digital 820 IS',
     420    0x2360000 => 'PowerShot SD790 IS / Digital IXUS 90 IS / IXY Digital 95 IS',
     421    0x2370000 => 'PowerShot SD770 IS / Digital IXUS 85 IS / IXY Digital 25 IS',
     422    0x2380000 => 'PowerShot A590 IS',
     423    0x2390000 => 'PowerShot A580',
     424    0x2420000 => 'PowerShot A470',
     425    0x2430000 => 'PowerShot SD1100 IS / Digital IXUS 80 IS / IXY Digital 20 IS',
     426    0x2460000 => 'PowerShot SX1 IS',
     427    0x2470000 => 'PowerShot SX10 IS',
     428    0x2480000 => 'PowerShot A1000 IS',
     429    0x2490000 => 'PowerShot G10',
     430    0x2510000 => 'PowerShot A2000 IS',
     431    0x2520000 => 'PowerShot SX110 IS',
     432    0x2530000 => 'PowerShot SD990 IS / Digital IXUS 980 IS / IXY Digital 3000 IS',
     433    0x2540000 => 'PowerShot SD880 IS / Digital IXUS 870 IS / IXY Digital 920 IS',
     434    0x2550000 => 'PowerShot E1',
     435    0x2560000 => 'PowerShot D10',
     436    0x2570000 => 'PowerShot SD960 IS / Digital IXUS 110 IS / IXY Digital 510 IS',
     437    0x2580000 => 'PowerShot A2100 IS',
     438    0x2590000 => 'PowerShot A480',
     439    0x2600000 => 'PowerShot SX200 IS',
     440    0x2610000 => 'PowerShot SD970 IS / Digital IXUS 990 IS / IXY Digital 830 IS',
     441    0x2620000 => 'PowerShot SD780 IS / Digital IXUS 100 IS / IXY Digital 210 IS',
     442    0x2630000 => 'PowerShot A1100 IS',
     443    0x2640000 => 'PowerShot SD1200 IS / Digital IXUS 95 IS / IXY Digital 110 IS',
     444    0x2700000 => 'PowerShot G11',
     445    0x2710000 => 'PowerShot SX120 IS',
     446    0x2720000 => 'PowerShot S90',
     447    0x2750000 => 'PowerShot SX20 IS',
     448    0x2760000 => 'PowerShot SD980 IS / Digital IXUS 200 IS / IXY Digital 930 IS',
     449    0x2770000 => 'PowerShot SD940 IS / Digital IXUS 120 IS / IXY Digital 220 IS',
     450    0x2800000 => 'PowerShot A495',
     451    0x2810000 => 'PowerShot A490',
     452    0x2820000 => 'PowerShot A3100 IS',
     453    0x2830000 => 'PowerShot A3000 IS',
     454    0x2840000 => 'PowerShot SD1400 IS / IXUS 130 / IXY 400F',
     455    0x2850000 => 'PowerShot SD1300 IS / IXUS 105 / IXY 200F',
     456    0x2860000 => 'PowerShot SD3500 IS / IXUS 210 / IXY 10S',
     457    0x2870000 => 'PowerShot SX210 IS',
     458    0x2880000 => 'PowerShot SD4000 IS / IXUS 300 HS / IXY 30S',
     459    0x2890000 => 'PowerShot SD4500 IS / IXUS 1000 HS / IXY 50S',
     460    0x2920000 => 'PowerShot G12',
     461    0x2930000 => 'PowerShot SX30 IS',
     462    0x2940000 => 'PowerShot SX130 IS',
     463    0x2950000 => 'PowerShot S95',
     464    0x2980000 => 'PowerShot A3300 IS',
     465    0x2990000 => 'PowerShot A3200 IS',
     466    0x3000000 => 'PowerShot ELPH 500 HS / IXUS 310 HS / IXY 31 S',
    247467    0x3010000 => 'PowerShot Pro90 IS',
     468    0x3010001 => 'PowerShot A800',
     469    0x3020000 => 'PowerShot ELPH 100 HS / IXUS 115 HS / IXY 210F',
     470    0x3030000 => 'PowerShot SX230 HS',
     471    0x3040000 => 'PowerShot ELPH 300 HS / IXUS 220 HS / IXY 410F',
     472    0x3050000 => 'PowerShot A2200',
     473    0x3060000 => 'PowerShot A1200',
     474    0x3070000 => 'PowerShot SX220 HS',
    248475    0x4040000 => 'PowerShot G1',
    249476    0x6040000 => 'PowerShot S100 / Digital IXUS / IXY Digital',
     477    0x4007d673 => 'DC19/DC21/DC22',
     478    0x4007d674 => 'XH A1',
    250479    0x4007d675 => 'HV10',
    251     0x4007d777 => 'iVIS DC50',
    252     0x4007d778 => 'iVIS HV20',
     480    0x4007d676 => 'MD130/MD140/MD150/MD160/ZR850',
     481    0x4007d777 => 'DC50', # (iVIS)
     482    0x4007d778 => 'HV20', # (iVIS)
     483    0x4007d779 => 'DC211', #29
     484    0x4007d77a => 'HG10',
     485    0x4007d77b => 'HR10', #29 (iVIS)
     486    0x4007d77d => 'MD255/ZR950',
     487    0x4007d81c => 'HF11',
     488    0x4007d878 => 'HV30',
     489    0x4007d87e => 'DC301/DC310/DC311/DC320/DC330',
     490    0x4007d87f => 'FS100',
     491    0x4007d880 => 'HF10', #29 (iVIS/VIXIA)
     492    0x4007d882 => 'HG20/HG21', # (VIXIA)
     493    0x4007d925 => 'HF21', # (LEGRIA)
     494    0x4007d926 => 'HF S11', # (LEGRIA)
     495    0x4007d978 => 'HV40', # (LEGRIA)
     496    0x4007d987 => 'DC410/DC420',
     497    0x4007d988 => 'FS19/FS20/FS21/FS22/FS200', # (LEGRIA)
     498    0x4007d989 => 'HF20/HF200', # (LEGRIA)
     499    0x4007d98a => 'HF S10/S100', # (LEGRIA/VIXIA)
     500    0x4007da8e => 'HF R16/R17/R18/R100/R106', # (LEGRIA/VIXIA)
     501    0x4007da8f => 'HF M31/M36/M300', # (LEGRIA/VIXIA, probably also HF M30)
     502    0x4007da90 => 'HF S20/S21/S200', # (LEGRIA/VIXIA)
     503    0x4007da92 => 'FS36/FS37/FS305/FS306/FS307',
     504    # NOTE: some pre-production models may have a model name of
     505    # "Canon EOS Kxxx", where "xxx" is the last 3 digits of the model ID below.
     506    # This has been observed for the 1DSmkIII/K215 and 400D/K236.
    253507    0x80000001 => 'EOS-1D',
    254508    0x80000167 => 'EOS-1DS',
     
    258512    0x80000174 => 'EOS-1D Mark II',
    259513    0x80000175 => 'EOS 20D',
     514    0x80000176 => 'EOS Digital Rebel XSi / 450D / Kiss X2',
    260515    0x80000188 => 'EOS-1Ds Mark II',
    261516    0x80000189 => 'EOS Digital Rebel XT / 350D / Kiss Digital N',
     
    263518    0x80000213 => 'EOS 5D',
    264519    0x80000215 => 'EOS-1Ds Mark III',
     520    0x80000218 => 'EOS 5D Mark II',
    265521    0x80000232 => 'EOS-1D Mark II N',
    266522    0x80000234 => 'EOS 30D',
    267     0x80000236 => 'EOS Digital Rebel XTi / 400D / Kiss Digital X',
     523    0x80000236 => 'EOS Digital Rebel XTi / 400D / Kiss Digital X', # and K236
     524    0x80000250 => 'EOS 7D',
     525    0x80000252 => 'EOS Rebel T1i / 500D / Kiss X3',
     526    0x80000254 => 'EOS Rebel XS / 1000D / Kiss F',
     527    0x80000261 => 'EOS 50D',
     528    0x80000270 => 'EOS Rebel T2i / 550D / Kiss X4',
     529    0x80000281 => 'EOS-1D Mark IV',
     530    0x80000286 => 'EOS Rebel T3i / 600D / Kiss X5',
     531    0x80000287 => 'EOS 60D',
     532    0x80000288 => 'EOS Rebel T3 / 1100D / Kiss X50',
    268533);
    269534
     
    274539    4 => 'RAW',
    275540    5 => 'Superfine',
     541    130 => 'Normal Movie', #22
    276542);
    277543my %canonImageSize = (
     
    283549    7 => 'Medium 3', #PH
    284550    8 => 'Postcard', #PH (SD200 1600x1200 with DateStamp option)
    285     9 => 'Widescreen', #PH (SD900 3648x2048)
     551    9 => 'Widescreen', #PH (SD900 3648x2048), 22 (HFS200 3264x1840)
     552    10 => 'Medium Widescreen', #22 (HFS200 1920x1080)
     553    14 => 'Small 1', #PH
     554    15 => 'Small 2', #PH
     555    16 => 'Small 3', #PH
     556    128 => '640x480 Movie', #PH (7D 60fps)
     557    129 => 'Medium Movie', #22
     558    130 => 'Small Movie', #22
     559    137 => '1280x720 Movie', #PH (S95 24fps; D60 50fps)
     560    142 => '1920x1080 Movie', #PH (D60 25fps)
    286561);
    287562my %canonWhiteBalance = (
     563    # -1='Click", -2='Pasted' ?? - PH
    288564    0 => 'Auto',
    289565    1 => 'Daylight',
     
    303579    16 => 'Custom 2', #PH
    304580    17 => 'Underwater', #3
     581    18 => 'Custom 3', #PH
     582    19 => 'Custom 4', #PH
     583    20 => 'PC Set4', #PH
     584    21 => 'PC Set5', #PH
     585    # 22 - Custom 2?
     586    # 23 - Custom 3?
     587    # 30 - Click White Balance?
     588    # 31 - Shot Settings?
     589    # 137 - Tungsten?
     590    # 138 - White Fluorescent?
     591    # 139 - Fluorescent H?
     592    # 140 - Manual?
    305593);
    306594
    307595# picture styles used by the 5D
    308596# (styles 0x4X may be downloaded from Canon)
     597# (called "ColorMatrix" in 1D owner manual)
    309598my %pictureStyles = ( #12
    310599    0x00 => 'None', #PH
    311     0x01 => 'Standard', #PH guess (1D)
    312     0x02 => 'Set 1', #PH guess (1D)
    313     0x03 => 'Set 2', #PH guess (1D)
    314     0x04 => 'Set 3', #PH guess (1D)
     600    0x01 => 'Standard', #15
     601    0x02 => 'Portrait', #15
     602    0x03 => 'High Saturation', #15
     603    0x04 => 'Adobe RGB', #15
     604    0x05 => 'Low Saturation', #15
     605    0x06 => 'CM Set 1', #PH
     606    0x07 => 'CM Set 2', #PH
     607    # "ColorMatrix" values end here
    315608    0x21 => 'User Def. 1',
    316609    0x22 => 'User Def. 2',
     
    319612    # Twilight and Emerald.  The "User Def" styles change to these "External"
    320613    # codes when these styles are installed in the camera
    321     0x41 => 'External 1',
    322     0x42 => 'External 2',
    323     0x43 => 'External 3',
     614    0x41 => 'PC 1', #PH
     615    0x42 => 'PC 2', #PH
     616    0x43 => 'PC 3', #PH
    324617    0x81 => 'Standard',
    325618    0x82 => 'Portrait',
     
    328621    0x85 => 'Faithful',
    329622    0x86 => 'Monochrome',
    330 );
    331 my %userDefStyles = ( #12
    332     0x41 => 'Nostalgia',
    333     0x42 => 'Clear',
    334     0x43 => 'Twilight',
     623    0x87 => 'Auto', #PH
     624);
     625my %userDefStyles = ( #12/48
     626    Notes => q{
     627        Base style for user-defined picture styles.  PC values represent external
     628        picture styles which may be downloaded from Canon and installed in the
     629        camera.
     630    },
     631    0x41 => 'PC 1',
     632    0x42 => 'PC 2',
     633    0x43 => 'PC 3',
    335634    0x81 => 'Standard',
    336635    0x82 => 'Portrait',
     
    341640);
    342641
     642# picture style tag information for CameraInfo550D
     643my %psConv = (
     644    -559038737 => 'n/a', # = 0xdeadbeef ! LOL
     645    OTHER => sub { return shift },
     646);
     647my %psInfo = (
     648    Format => 'int32s',
     649    PrintHex => 1,
     650    PrintConv => \%psConv,
     651);
     652
    343653# ValueConv that makes long values binary type
    344654my %longBin = (
    345655    ValueConv => 'length($val) > 64 ? \$val : $val',
    346656    ValueConvInv => '$val',
     657);
     658
     659# conversions, etc for CameraColorCalibration tags
     660my %cameraColorCalibration = (
     661    Format => 'int16s[4]',
     662    Unknown => 1,
     663    PrintConv => 'sprintf("%4d %4d %4d (%dK)", split(" ",$val))',
     664    PrintConvInv => '$val=~s/\s+/ /g; $val=~tr/()K//d; $val',
     665);
     666
     667# conversions, etc for PowerShot CameraColorCalibration tags
     668my %cameraColorCalibration2 = (
     669    Format => 'int16s[5]',
     670    Unknown => 1,
     671    PrintConv => 'sprintf("%4d %4d %4d %4d (%dK)", split(" ",$val))',
     672    PrintConvInv => '$val=~s/\s+/ /g; $val=~tr/()K//d; $val',
     673);
     674# conversions, etc for byte-swapped FocusDistance tags
     675my %focusDistanceByteSwap = (
     676    # this is very odd (little-endian number on odd boundary),
     677    # but it does seem to work better with my sample images - PH
     678    Format => 'int16uRev',
     679    ValueConv => '$val / 100',
     680    ValueConvInv => '$val * 100',
     681    PrintConv => '$val > 655.345 ? "inf" : "$val m"',
     682    PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 655.35',
     683);
     684
     685# common attributes for writable BinaryData directories
     686my %binaryDataAttrs = (
     687    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     688    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     689    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     690    WRITABLE => 1,
    347691);
    348692
     
    386730        Name => 'CanonImageType',
    387731        Writable => 'string',
     732        Groups => { 2 => 'Image' },
    388733    },
    389734    0x7 => {
     
    394739        Name => 'FileNumber',
    395740        Writable => 'int32u',
     741        Groups => { 2 => 'Image' },
    396742        PrintConv => '$_=$val,s/(\d+)(\d{4})/$1-$2/,$_',
    397743        PrintConvInv => '$val=~s/-//g;$val',
     
    400746        Name => 'OwnerName',
    401747        Writable => 'string',
     748        # pad to 32 bytes (including null terminator which will be added)
     749        # to avoid bug which crashes DPP if length is 4 bytes
     750        ValueConvInv => '$val .= "\0" x (31 - length $val) if length $val < 31; $val',
    402751    },
    403752    0xa => {
    404         Name => 'ColorInfoD30',
     753        Name => 'UnknownD30',
    405754        SubDirectory => {
    406755            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
    407             TagTable => 'Image::ExifTool::Canon::ColorInfoD30',
     756            TagTable => 'Image::ExifTool::Canon::UnknownD30',
    408757        },
    409758    },
     
    412761            # D30
    413762            Name => 'SerialNumber',
    414             Description => 'Camera Body No.',
    415             Condition => '$$self{CameraModel} =~ /EOS D30\b/',
     763            Condition => '$$self{Model} =~ /EOS D30\b/',
    416764            Writable => 'int32u',
    417             PrintConv => 'sprintf("%x-%.5d",$val>>16,$val&0xffff)',
    418             PrintConvInv => '$val=~/(.*)-(\d+)/ ? (hex($1)<<16)+$2 : undef',
     765            PrintConv => 'sprintf("%.4x%.5d",$val>>16,$val&0xffff)',
     766            PrintConvInv => '$val=~/(.*)-?(\d{5})$/ ? (hex($1)<<16)+$2 : undef',
    419767        },
    420768        {
     
    422770            # displayed w/o leeding zeros (ref 7) (1D uses 6 digits - PH)
    423771            Name => 'SerialNumber',
    424             Description => 'Camera Body No.',
    425             Condition => '$$self{CameraModel} =~ /EOS-1D/',
     772            Condition => '$$self{Model} =~ /EOS-1D/',
    426773            Writable => 'int32u',
    427774            PrintConv => 'sprintf("%.6u",$val)',
     
    431778            # all other models (D60,300D,350D,REBEL,10D,20D,etc)
    432779            Name => 'SerialNumber',
    433             Description => 'Camera Body No.',
    434780            Writable => 'int32u',
    435781            PrintConv => 'sprintf("%.10u",$val)',
     
    439785    0xd => [
    440786        {
    441             Name => 'CanonCameraInfo',
    442             Condition => '$$self{CameraModel} =~ /\b(1D(?! Mark III)|5D)/',
     787            Name => 'CanonCameraInfo1D',
     788            # (save size of this record as "CameraInfoCount" for later tests)
     789            Condition => '($$self{CameraInfoCount} = $count) and $$self{Model} =~ /\b1DS?$/',
    443790            SubDirectory => {
    444                 TagTable => 'Image::ExifTool::Canon::CameraInfo',
     791                TagTable => 'Image::ExifTool::Canon::CameraInfo1D',
     792            },
     793        },
     794        {
     795            Name => 'CanonCameraInfo1DmkII',
     796            Condition => '$$self{Model} =~ /\b1Ds? Mark II$/',
     797            SubDirectory => {
     798                TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkII',
     799            },
     800        },
     801        {
     802            Name => 'CanonCameraInfo1DmkIIN',
     803            Condition => '$$self{Model} =~ /\b1Ds? Mark II N$/',
     804            SubDirectory => {
     805                TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIIN',
    445806            },
    446807        },
    447808        {
    448809            Name => 'CanonCameraInfo1DmkIII',
    449             Condition => '$$self{CameraModel} =~ /\b1D Mark III/',
     810            Condition => '$$self{Model} =~ /\b1Ds? Mark III$/',
    450811            SubDirectory => {
    451812                TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIII',
     
    453814        },
    454815        {
    455             Name => 'CanonCameraInfo2',
     816            Name => 'CanonCameraInfo1DmkIV',
     817            Condition => '$$self{Model} =~ /\b1D Mark IV$/',
     818            SubDirectory => {
     819                TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIV',
     820            },
     821        },
     822        {
     823            Name => 'CanonCameraInfo5D',
     824            Condition => '$$self{Model} =~ /EOS 5D$/',
     825            SubDirectory => {
     826                TagTable => 'Image::ExifTool::Canon::CameraInfo5D',
     827            },
     828        },
     829        {
     830            Name => 'CanonCameraInfo5DmkII',
     831            Condition => '$$self{Model} =~ /EOS 5D Mark II$/',
     832            SubDirectory => {
     833                TagTable => 'Image::ExifTool::Canon::CameraInfo5DmkII',
     834            },
     835        },
     836        {
     837            Name => 'CanonCameraInfo7D',
     838            Condition => '$$self{Model} =~ /EOS 7D$/',
     839            SubDirectory => {
     840                TagTable => 'Image::ExifTool::Canon::CameraInfo7D',
     841            },
     842        },
     843        {
     844            Name => 'CanonCameraInfo40D',
     845            Condition => '$$self{Model} =~ /EOS 40D$/',
     846            SubDirectory => {
     847                TagTable => 'Image::ExifTool::Canon::CameraInfo40D',
     848            },
     849        },
     850        {
     851            Name => 'CanonCameraInfo50D',
     852            Condition => '$$self{Model} =~ /EOS 50D$/',
     853            SubDirectory => {
     854                TagTable => 'Image::ExifTool::Canon::CameraInfo50D',
     855            },
     856        },
     857        {
     858            Name => 'CanonCameraInfo60D',
     859            Condition => '$$self{Model} =~ /EOS 60D$/',
     860            SubDirectory => {
     861                TagTable => 'Image::ExifTool::Canon::CameraInfo60D',
     862            },
     863        },
     864        {
     865            Name => 'CanonCameraInfo450D',
     866            Condition => '$$self{Model} =~ /\b(450D|REBEL XSi|Kiss X2)\b/',
     867            SubDirectory => {
     868                TagTable => 'Image::ExifTool::Canon::CameraInfo450D',
     869            },
     870        },
     871        {
     872            Name => 'CanonCameraInfo500D',
     873            Condition => '$$self{Model} =~ /\b(500D|REBEL T1i|Kiss X3)\b/',
     874            SubDirectory => {
     875                TagTable => 'Image::ExifTool::Canon::CameraInfo500D',
     876            },
     877        },
     878        {
     879            Name => 'CanonCameraInfo550D',
     880            Condition => '$$self{Model} =~ /\b(550D|REBEL T2i|Kiss X4)\b/',
     881            SubDirectory => {
     882                TagTable => 'Image::ExifTool::Canon::CameraInfo550D',
     883            },
     884        },
     885        {
     886            Name => 'CanonCameraInfo1000D',
     887            Condition => '$$self{Model} =~ /\b(1000D|REBEL XS|Kiss F)\b/',
     888            SubDirectory => {
     889                TagTable => 'Image::ExifTool::Canon::CameraInfo1000D',
     890            },
     891        },
     892        {
     893            Name => 'CanonCameraInfoPowerShot',
    456894            # valid if format is int32u[138] or int32u[148]
    457             Condition => q{ $format eq 'int32u' and ($count == 138 or $count == 148) },
     895            Condition => '$format eq "int32u" and ($count == 138 or $count == 148)',
    458896            SubDirectory => {
    459                 TagTable => 'Image::ExifTool::Canon::CameraInfo2',
     897                TagTable => 'Image::ExifTool::Canon::CameraInfoPowerShot',
     898            },
     899        },
     900        {
     901            Name => 'CanonCameraInfoPowerShot2',
     902            # valid if format is int32u[162], int32u[167], int32u[171] or int32u[264]
     903            Condition => q{
     904                $format eq "int32u" and ($count == 156 or $count == 162 or
     905                $count == 167 or $count == 171 or $count == 264)
     906            },
     907            SubDirectory => {
     908                TagTable => 'Image::ExifTool::Canon::CameraInfoPowerShot2',
    460909            },
    461910        },
    462911        {
    463912            Name => 'CanonCameraInfoUnknown32',
    464             Condition => q{ $format =~ /^int32/ },
     913            Condition => '$format =~ /^int32/',
     914            # (counts of 72, 85, 86, 93, 94, 96, 104) - PH
    465915            SubDirectory => {
    466916                TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown32',
     
    469919        {
    470920            Name => 'CanonCameraInfoUnknown16',
    471             Condition => q{ $format =~ /^int16/ },
     921            Condition => '$format =~ /^int16/',
    472922            SubDirectory => {
    473923                TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown16',
     
    475925        },
    476926        {
    477             Name => 'CanonCameraInfoUnknown8',
     927            Name => 'CanonCameraInfoUnknown',
    478928            SubDirectory => {
    479                 TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown8',
     929                TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown',
    480930            },
    481931        },
     
    487937    },
    488938    0xf => [
    489         {   # used by 1DmkII, 1DsMkII and 1DmkIIN
     939        {   # used by 1DmkII, 1DSmkII and 1DmkIIN
    490940            Name => 'CustomFunctions1D',
    491             Condition => '$$self{CameraModel} =~ /EOS-1D/',
     941            Condition => '$$self{Model} =~ /EOS-1D/',
    492942            SubDirectory => {
    493943                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     
    497947        {
    498948            Name => 'CustomFunctions5D',
    499             Condition => '$$self{CameraModel} =~ /EOS 5D/',
     949            Condition => '$$self{Model} =~ /EOS 5D/',
    500950            SubDirectory => {
    501951                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     
    505955        {
    506956            Name => 'CustomFunctions10D',
    507             Condition => '$$self{CameraModel} =~ /EOS 10D/',
     957            Condition => '$$self{Model} =~ /EOS 10D/',
    508958            SubDirectory => {
    509959                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     
    513963        {
    514964            Name => 'CustomFunctions20D',
    515             Condition => '$$self{CameraModel} =~ /EOS 20D/',
     965            Condition => '$$self{Model} =~ /EOS 20D/',
    516966            SubDirectory => {
    517967                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     
    521971        {
    522972            Name => 'CustomFunctions30D',
    523             Condition => '$$self{CameraModel} =~ /EOS 30D/',
     973            Condition => '$$self{Model} =~ /EOS 30D/',
    524974            SubDirectory => {
    525975                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     
    529979        {
    530980            Name => 'CustomFunctions350D',
    531             Condition => '$$self{CameraModel} =~ /\b(350D|REBEL XT|Kiss Digital N)\b/',
     981            Condition => '$$self{Model} =~ /\b(350D|REBEL XT|Kiss Digital N)\b/',
    532982            SubDirectory => {
    533983                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     
    537987        {
    538988            Name => 'CustomFunctions400D',
    539             Condition => '$$self{CameraModel} =~ /\b(400D|REBEL XTi|Kiss Digital X|K236)\b/',
     989            Condition => '$$self{Model} =~ /\b(400D|REBEL XTi|Kiss Digital X|K236)\b/',
    540990            SubDirectory => {
    541991                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     
    545995        {
    546996            Name => 'CustomFunctionsD30',
    547             Condition => '$$self{CameraModel} =~ /EOS D30\b/',
     997            Condition => '$$self{Model} =~ /EOS D30\b/',
    548998            SubDirectory => {
    549999                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     
    5531003        {
    5541004            Name => 'CustomFunctionsD60',
    555             Condition => '$$self{CameraModel} =~ /EOS D60\b/',
     1005            Condition => '$$self{Model} =~ /EOS D60\b/',
    5561006            SubDirectory => {
    5571007                # the stored size in the D60 apparently doesn't include the size word:
     
    5751025        SeparateTable => 1,
    5761026        PrintConv => \%canonModelID,
     1027    },
     1028    0x11 => { #PH
     1029        Name => 'MovieInfo',
     1030        SubDirectory => {
     1031            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     1032            TagTable => 'Image::ExifTool::Canon::MovieInfo',
     1033        },
    5771034    },
    5781035    0x12 => {
     
    5871044        },
    5881045    },
    589     # 0x13 - ('0 159 15 104' for widescreen image, '0 0 0 0' otherwise) - PH (A570IS)
     1046    0x13 => { #PH
     1047        Name => 'ThumbnailImageValidArea',
     1048        # left,right,top,bottom edges of image in thumbnail, or all zeros for full frame
     1049        Notes => 'all zeros for full frame',
     1050        Writable => 'int16u',
     1051        Count => 4,
     1052    },
    5901053    0x15 => { #PH
    5911054        # display format for serial number
     
    5981061        },
    5991062    },
     1063    0x1a => { #15
     1064        Name => 'SuperMacro',
     1065        Writable => 'int16u',
     1066        PrintConv => {
     1067            0 => 'Off',
     1068            1 => 'On (1)',
     1069            2 => 'On (2)',
     1070        },
     1071    },
    6001072    0x1c => { #PH (A570IS)
    6011073        Name => 'DateStampMode',
    6021074        Writable => 'int16u',
    603         Notes => 'only used in postcard mode',
     1075        Notes => 'used only in postcard mode',
    6041076        PrintConv => {
    6051077            0 => 'Off',
     
    6371109    # 0x1f - used for red-eye-corrected images - PH (A570IS)
    6381110    # 0x22 - values 1 and 2 are 2 and 1 for flash pics, 0 otherwise - PH (A570IS)
     1111    0x23 => { #31
     1112        Name => 'Categories',
     1113        Writable => 'int32u',
     1114        Format => 'int32u', # (necessary to perform conversion for Condition)
     1115        Notes => '2 values: 1. always 8, 2. Categories',
     1116        Count => '2',
     1117        Condition => '$$valPt =~ /^\x08\0\0\0/',
     1118        ValueConv => '$val =~ s/^8 //; $val',
     1119        ValueConvInv => '"8 $val"',
     1120        PrintConvColumns => 2,
     1121        PrintConv => { BITMASK => {
     1122            0 => 'People',
     1123            1 => 'Scenery',
     1124            2 => 'Events',
     1125            3 => 'User 1',
     1126            4 => 'User 2',
     1127            5 => 'User 3',
     1128            6 => 'To Do',
     1129        } },
     1130    },
    6391131    0x24 => { #PH
    6401132        Name => 'FaceDetect1',
     
    6521144    0x26 => { #PH (A570IS,1DmkIII)
    6531145        Name => 'CanonAFInfo2',
     1146        Condition => '$$valPt !~ /^\0\0\0\0/', # (data may be all zeros in thumbnail of 60D MOV video)
    6541147        SubDirectory => {
    6551148            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     
    6581151    },
    6591152    # 0x27 - value 1 is 1 for high ISO pictures, 0 otherwise
     1153    #        value 4 is 9 for Flexizone and FaceDetect AF, 1 for Centre AF, 0 otherwise (SX10IS)
     1154    0x28 => { #JD
     1155        # bytes 0-1=sequence number (encrypted), 2-5=date/time (encrypted) (ref JD)
     1156        Name => 'ImageUniqueID',
     1157        Format => 'undef',
     1158        Writable => 'int8u',
     1159        Groups => { 2 => 'Image' },
     1160        RawConv => '$val eq "\0" x 16 ? undef : $val',
     1161        ValueConv => 'unpack("H*", $val)',
     1162        ValueConvInv => 'pack("H*", $val)',
     1163    },
     1164    # 0x2d - changes with categories (ref 31)
     1165    # 0x44 - ShootInfo
     1166    # 0x62 - UserSetting
     1167    0x81 => { #13
     1168        Name => 'RawDataOffset',
     1169        # (can't yet write 1D raw files)
     1170        # Writable => 'int32u',
     1171        # Protected => 2,
     1172    },
    6601173    0x83 => { #PH
    661         Name => 'OriginalDecisionData',
     1174        Name => 'OriginalDecisionDataOffset',
    6621175        Writable => 'int32u',
     1176        OffsetPair => 1, # (just used as a flag, since this tag has no pair)
     1177        # this is an offset to the original decision data block
     1178        # (offset relative to start of file in JPEG images, but NOT DNG images!)
     1179        IsOffset => '$val and $$exifTool{FILE_TYPE} ne "JPEG"',
     1180        Protected => 2,
     1181        DataTag => 'OriginalDecisionData',
    6631182    },
    6641183    0x90 => {   # used by 1D and 1Ds
     
    6841203    },
    6851204    0x93 => {
    686         Name => 'CanonFileInfo',
     1205        Name => 'CanonFileInfo', # (ShootInfoEx)
    6871206        SubDirectory => {
    6881207            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     
    6971216    },
    6981217    0x95 => { #PH (observed in 5D sample image)
    699         Name => 'LensType',
     1218        Name => 'LensModel',
    7001219        Writable => 'string',
    7011220    },
    702     0x96 => { #PH
    703         Name => 'InternalSerialNumber',
    704         Writable => 'string',
    705     },
     1221    0x96 => [ #PH
     1222        {
     1223            Name => 'SerialInfo',
     1224            Condition => '$$self{Model} =~ /EOS 5D/',
     1225            SubDirectory => { TagTable => 'Image::ExifTool::Canon::SerialInfo' },
     1226        },
     1227        {
     1228            Name => 'InternalSerialNumber',
     1229            Writable => 'string',
     1230            # remove trailing 0xff's if they exist (Kiss X3)
     1231            ValueConv => '$val=~s/\xff+$//; $val',
     1232            ValueConvInv => '$val',
     1233        },
     1234    ],
    7061235    0x97 => { #PH
    7071236        Name => 'DustRemovalData',
    7081237        # some interesting stuff is stored in here, like LensType and InternalSerialNumber...
    709         Binary => 1,
     1238        Writable => 'undef',
     1239        Flags => [ 'Binary', 'Protected' ],
     1240    },
     1241    0x98 => { #PH
     1242        Name => 'CropInfo',
     1243        SubDirectory => {
     1244            TagTable => 'Image::ExifTool::Canon::CropInfo',
     1245        },
    7101246    },
    7111247    0x99 => { #PH (EOS 1D Mark III, 40D, etc)
     
    7161252        },
    7171253    },
    718     # 0x9a - 5 numbers, the 2nd and 3rd are imagewidth/height (EOS 1DmkIII and 40D)
     1254    0x9a => { #PH
     1255        Name => 'AspectInfo',
     1256        SubDirectory => {
     1257            TagTable => 'Image::ExifTool::Canon::AspectInfo',
     1258        },
     1259    },
    7191260    0xa0 => {
    720         Name => 'ProccessingInfo',
     1261        Name => 'ProcessingInfo',
    7211262        SubDirectory => {
    7221263            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     
    7381279        },
    7391280    },
    740     # 0xaa - looks like maybe measured color balance (inverse of RGGBLevels)? - PH
     1281    0xaa => {
     1282        Name => 'MeasuredColor',
     1283        SubDirectory => {
     1284            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     1285            TagTable => 'Image::ExifTool::Canon::MeasuredColor',
     1286        },
     1287    },
    7411288    0xae => {
    7421289        Name => 'ColorTemperature',
     
    7701317        Name => 'PreviewImageInfo',
    7711318        SubDirectory => {
    772             # Note: first word if this block is the total number of words, not bytes!
     1319            # Note: the first word of this block gives the correct block size in bytes, but
     1320            # the size is wrong by a factor of 2 in the IFD, so we must account for this
    7731321            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size/2)',
    7741322            TagTable => 'Image::ExifTool::Canon::PreviewImageInfo',
     
    7931341        {   # (int16u[582]) - 20D and 350D
    7941342            Condition => '$count == 582',
    795             Name => 'ColorBalance1',
     1343            Name => 'ColorData1',
    7961344            SubDirectory => {
    797                 TagTable => 'Image::ExifTool::Canon::ColorBalance1',
     1345                TagTable => 'Image::ExifTool::Canon::ColorData1',
    7981346            },
    7991347        },
    8001348        {   # (int16u[653]) - 1DmkII and 1DSmkII
    8011349            Condition => '$count == 653',
    802             Name => 'ColorBalance2',
     1350            Name => 'ColorData2',
    8031351            SubDirectory => {
    804                 TagTable => 'Image::ExifTool::Canon::ColorBalance2',
     1352                TagTable => 'Image::ExifTool::Canon::ColorData2',
    8051353            },
    8061354        },
    8071355        {   # (int16u[796]) - 1DmkIIN, 5D, 30D, 400D
    8081356            Condition => '$count == 796',
    809             Name => 'ColorBalance3',
     1357            Name => 'ColorData3',
    8101358            SubDirectory => {
    811                 TagTable => 'Image::ExifTool::Canon::ColorBalance3',
     1359                TagTable => 'Image::ExifTool::Canon::ColorData3',
    8121360            },
    8131361        },
     1362        {   # (int16u[692|674|702|1227|1250|1251|1337])
     1363            # 40D (692), 1DmkIII (674), 1DSmkIII (702), 450D/1000D (1227)
     1364            # 50D/5DmkII (1250), 500D/7D_pre-prod/1DmkIV_pre-prod (1251),
     1365            # 1DmkIV/7D/550D_pre-prod (1337), 550D (1338), 1100D (1346)
     1366            Condition => q{
     1367                $count == 692  or $count == 674  or $count == 702 or
     1368                $count == 1227 or $count == 1250 or $count == 1251 or
     1369                $count == 1337 or $count == 1338 or $count == 1346
     1370            },
     1371            Name => 'ColorData4',
     1372            SubDirectory => {
     1373                TagTable => 'Image::ExifTool::Canon::ColorData4',
     1374            },
     1375        },
     1376        {   # (int16u[5120]) - G10
     1377            Condition => '$count == 5120',
     1378            Name => 'ColorData5',
     1379            SubDirectory => {
     1380                TagTable => 'Image::ExifTool::Canon::ColorData5',
     1381            },
     1382        },
     1383        {   # (int16u[1273]) - 600D
     1384            Condition => '$count == 1273',
     1385            Name => 'ColorData6',
     1386            SubDirectory => {
     1387                TagTable => 'Image::ExifTool::Canon::ColorData6',
     1388            },
     1389        },
    8141390        {
    815             Name => 'ColorBalanceUnknown',
    816             %longBin,
     1391            Name => 'ColorDataUnknown',
     1392            SubDirectory => {
     1393                TagTable => 'Image::ExifTool::Canon::ColorDataUnknown',
     1394            },
    8171395        },
    8181396    ],
     
    8201398        # unknown data block in some JPEG and CR2 images
    8211399        # (5kB for most models, but 22kb for 5D and 30D)
    822         Name => 'UnknownBlock1',
     1400        Name => 'CRWParam',
    8231401        Format => 'undef',
    8241402        Flags => [ 'Unknown', 'Binary' ],
     
    8311409    },
    8321410    0x4005 => { #PH
    833         Name => 'UnknownBlock2',
     1411        Name => 'Flavor',
    8341412        Notes => 'unknown 49kB block, not copied to JPEG images',
    8351413        # 'Drop' because not found in JPEG images (too large for APP1 anyway)
     
    8371415    },
    8381416    0x4008 => { #PH guess (1DmkIII)
    839         Name => 'BlackLevel',
     1417        Name => 'BlackLevel', # (BasePictStyleOfUser)
    8401418        Unknown => 1,
     1419    },
     1420    0x4010 => { #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2933.0.html
     1421        Name => 'CustomPictureStyleFileName',
     1422        Writable => 'string',
     1423    },
     1424    0x4013 => { #PH
     1425        Name => 'AFMicroAdj',
     1426        SubDirectory => {
     1427            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     1428            TagTable => 'Image::ExifTool::Canon::AFMicroAdj',
     1429        },
     1430    },
     1431    0x4015 => {
     1432        Name => 'VignettingCorr',
     1433        Condition => '$$valPt !~ /^\0\0\0\0/', # (data may be all zeros for 60D)
     1434        SubDirectory => {
     1435            # (the size word is at byte 2 in this structure)
     1436            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart+2,$size)',
     1437            TagTable => 'Image::ExifTool::Canon::VignettingCorr',
     1438        },
     1439    },
     1440    0x4016 => {
     1441        Name => 'VignettingCorr2',
     1442        SubDirectory => {
     1443            # (the size word is actually 4 bytes, but it doesn't matter if little-endian)
     1444            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     1445            TagTable => 'Image::ExifTool::Canon::VignettingCorr2',
     1446        },
     1447    },
     1448    0x4018 => { #PH
     1449        Name => 'LightingOpt',
     1450        SubDirectory => {
     1451            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     1452            TagTable => 'Image::ExifTool::Canon::LightingOpt',
     1453        }
     1454    },
     1455    0x4019 => { #20
     1456        Name => 'LensInfo',
     1457        SubDirectory => {
     1458            TagTable => 'Image::ExifTool::Canon::LensInfo',
     1459        }
     1460    },
     1461    0x4020 => { #PH
     1462        Name => 'AmbienceInfo',
     1463        Condition => '$$valPt !~ /^\0\0\0\0/', # (data may be all zeros for 60D)
     1464        SubDirectory => {
     1465            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     1466            TagTable => 'Image::ExifTool::Canon::Ambience',
     1467        }
     1468    },
     1469    0x4024 => { #PH
     1470        Name => 'FilterInfo',
     1471        SubDirectory => {
     1472            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     1473            TagTable => 'Image::ExifTool::Canon::FilterInfo',
     1474        }
    8411475    },
    8421476);
     
    8461480# BinaryData (keys are indices into the int16s array)
    8471481%Image::ExifTool::Canon::CameraSettings = (
    848     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    849     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    850     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    851     WRITABLE => 1,
     1482    %binaryDataAttrs,
    8521483    FORMAT => 'int16s',
    8531484    FIRST_ENTRY => 1,
    854     DATAMEMBER => [ 25 ],   # FocalUnits necessary for writing
     1485    DATAMEMBER => [ 22, 25 ],   # necessary for writing
    8551486    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    8561487    1 => {
     
    8621493    },
    8631494    2 => {
    864         Name => 'Self-timer',
     1495        Name => 'SelfTimer',
    8651496        # Custom timer mode if bit 0x4000 is set - PH (A570IS)
    8661497        PrintConv => q{
    8671498            return 'Off' unless $val;
    868             return (($val&0xfff) / 10) . ' sec' . ($val & 0x4000 ? ', Custom' : '');
     1499            return (($val&0xfff) / 10) . ' s' . ($val & 0x4000 ? ', Custom' : '');
    8691500        },
    8701501        PrintConvInv => q{
    8711502            return 0 if $val =~ /^Off/i;
    872             $val =~ s/\s*sec$//i;
     1503            $val =~ s/\s*s(ec)?\b//i;
    8731504            $val =~ s/,?\s*Custom$//i ? ($val*10) | 0x4000 : $val*10;
    8741505        },
     
    9001531            4 => 'Continuous, Low', #PH
    9011532            5 => 'Continuous, High', #PH
     1533            6 => 'Silent Single', #PH
     1534            # 32-34 - Self-timer?
    9021535        },
    9031536    },
     
    9081541            1 => 'AI Servo AF',
    9091542            2 => 'AI Focus AF',
    910             3 => 'Manual Focus',
     1543            3 => 'Manual Focus (3)',
    9111544            4 => 'Single',
    9121545            5 => 'Continuous',
    913             6 => 'Manual Focus',
     1546            6 => 'Manual Focus (6)',
    9141547           16 => 'Pan Focus', #PH
     1548           # 137 - Single?
    9151549        },
    9161550    },
    9171551    9 => { #PH
    9181552        Name => 'RecordMode',
     1553        RawConv => '$val==-1 ? undef : $val', #22
    9191554        PrintConv => {
    9201555            1 => 'JPEG',
     
    9251560            6 => 'CR2', # +THM? (1D,30D,350D)
    9261561            7 => 'CR2+JPEG', # (S30)
     1562            9 => 'Video', # (S95 MOV)
    9271563        },
    9281564    },
    9291565    10 => {
    9301566        Name => 'CanonImageSize',
     1567        PrintConvColumns => 2,
    9311568        PrintConv => \%canonImageSize,
    9321569    },
    9331570    11 => {
    9341571        Name => 'EasyMode',
     1572        PrintConvColumns => 3,
    9351573        PrintConv => {
    9361574            0 => 'Full auto',
     
    9621600            26 => 'Digital Macro', #PH
    9631601            27 => 'My Colors', #PH
    964             28 => 'Still Image', #15 (animation frame?)
     1602            28 => 'Movie Snap', #PH
     1603            29 => 'Super Macro 2', #PH
    9651604            30 => 'Color Accent', #18
    9661605            31 => 'Color Swap', #18
    9671606            32 => 'Aquarium', #18
    9681607            33 => 'ISO 3200', #18
     1608            34 => 'ISO 6400', #PH
     1609            35 => 'Creative Light Effect', #PH
     1610            36 => 'Easy', #PH
     1611            37 => 'Quick Shot', #PH
     1612            38 => 'Creative Auto', #39
     1613            39 => 'Zoom Blur', #PH
     1614            40 => 'Low Light', #PH
     1615            41 => 'Nostalgic', #PH
     1616            42 => 'Super Vivid', #PH (SD4500)
     1617            43 => 'Poster Effect', #PH (SD4500)
     1618            44 => 'Face Self-timer', #PH
     1619            45 => 'Smile', #PH
     1620            46 => 'Wink Self-timer', #PH
     1621            47 => 'Fisheye Effect', #PH (SX30IS)
     1622            48 => 'Miniature Effect', #PH (SD4500)
     1623            49 => 'High-speed Burst', #PH
     1624            50 => 'Best Image Selection', #PH
     1625            51 => 'High Dynamic Range', #PH (S95)
     1626            52 => 'Handheld Night Scene', #PH
     1627            59 => 'Scene Intelligent Auto', #PH (T3i)
     1628            257 => 'Spotlight', #PH
     1629            258 => 'Night 2', #PH
     1630            259 => 'Night+',
     1631            260 => 'Super Night', #PH
     1632            261 => 'Sunset', #PH (SX10IS)
     1633            263 => 'Night Scene', #PH
     1634            264 => 'Surface', #PH
     1635            265 => 'Low Light 2', #PH
    9691636        },
    9701637    },
     
    9751642            1 => '2x',
    9761643            2 => '4x',
    977             3 => 'Other',  # value obtained from 2*#37/#36
     1644            3 => 'Other',  # value obtained from 2*$val[37]/$val[36]
    9781645        },
    9791646    },
     
    9811648        Name => 'Contrast',
    9821649        RawConv => '$val == 0x7fff ? undef : $val',
    983         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    984         PrintConvInv => '$val=~/normal/i ? 0 : $val',
     1650        %Image::ExifTool::Exif::printParameter,
    9851651    },
    9861652    14 => {
    9871653        Name => 'Saturation',
    9881654        RawConv => '$val == 0x7fff ? undef : $val',
    989         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    990         PrintConvInv => '$val=~/normal/i ? 0 : $val',
     1655        %Image::ExifTool::Exif::printParameter,
    9911656    },
    9921657    15 => {
    9931658        Name => 'Sharpness',
    9941659        RawConv => '$val == 0x7fff ? undef : $val',
    995         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    996         PrintConvInv => '$val=~/normal/i ? 0 : $val',
     1660        Notes => q{
     1661            some models use a range of -2 to +2 where 0 is normal sharpening, and
     1662            others use a range of 0 to 7 where 0 is no sharpening
     1663        },
     1664        PrintConv => '$val > 0 ? "+$val" : $val',
     1665        PrintConvInv => '$val',
    9971666    },
    9981667    16 => {
    9991668        Name => 'CameraISO',
    1000         RawConv => '$val != 0x7fff ? $val : undef',
     1669        RawConv => '$val == 0x7fff ? undef : $val',
    10011670        ValueConv => 'Image::ExifTool::Canon::CameraISO($val)',
    10021671        ValueConvInv => 'Image::ExifTool::Canon::CameraISO($val,1)',
     
    10101679            3 => 'Evaluative',
    10111680            4 => 'Partial',
    1012             5 => 'Center-weighted averaging',
     1681            5 => 'Center-weighted average',
    10131682        },
    10141683    },
     
    10551724            5 => 'Depth-of-field AE',
    10561725            6 => 'M-Dep', #PH
     1726            7 => 'Bulb', #30
    10571727        },
    10581728    },
    10591729    22 => { #4
    10601730        Name => 'LensType',
    1061         RawConv => '$val ? $val : undef', # don't use if value is zero
     1731        RawConv => '$val ? $$self{LensType}=$val : undef', # don't use if value is zero
     1732        Notes => 'this value is incorrect for EOS 7D images with lenses of type 256 or greater',
    10621733        SeparateTable => 1,
     1734        DataMember => 'LensType',
    10631735        PrintConv => \%canonLensTypes,
    10641736    },
     
    10701742        ValueConv => '$val / ($$self{FocalUnits} || 1)',
    10711743        ValueConvInv => '$val',
    1072         PrintConv => '"${val}mm"',
    1073         PrintConvInv => '$val=~s/mm//;$val',
     1744        PrintConv => '"$val mm"',
     1745        PrintConvInv => '$val=~s/\s*mm//;$val',
    10741746    },
    10751747    24 => {
     
    10791751        ValueConv => '$val / ($$self{FocalUnits} || 1)',
    10801752        ValueConvInv => '$val',
    1081         PrintConv => '"${val}mm"',
    1082         PrintConvInv => '$val=~s/mm//;$val',
     1753        PrintConv => '"$val mm"',
     1754        PrintConvInv => '$val=~s/\s*mm//;$val',
    10831755    },
    10841756    25 => {
    10851757        Name => 'FocalUnits',
     1758        # conversion from raw focal length values to mm
    10861759        DataMember => 'FocalUnits',
    10871760        RawConv => '$$self{FocalUnits} = $val',
     1761        PrintConv => '"$val/mm"',
     1762        PrintConvInv => '$val=~s/\s*\/?\s*mm//;$val',
    10881763    },
    10891764    26 => { #9
     
    11091784    29 => {
    11101785        Name => 'FlashBits',
     1786        PrintConvColumns => 2,
    11111787        PrintConv => { BITMASK => {
    11121788            0 => 'Manual', #PH
     
    11181794            11 => 'FP sync used',
    11191795            13 => 'Built-in',
    1120             14 => 'External',
     1796            14 => 'External', #(may not be set in manual mode - ref 37)
    11211797        } },
    11221798    },
     
    11271803            0 => 'Single',
    11281804            1 => 'Continuous',
     1805            8 => 'Manual', #22
    11291806        },
    11301807    },
     
    11461823            0 => 'Off',
    11471824            1 => 'On',
    1148             2 => 'On, Shot Only', #15
     1825            2 => 'On, Shot Only', #15 (panning for SX10IS)
    11491826            3 => 'On, Panning', #PH (A570IS)
     1827            4 => 'On, Video', #PH (SX30IS)
    11501828        },
    11511829    },
     
    11581836    36 => 'ZoomSourceWidth', #PH
    11591837    37 => 'ZoomTargetWidth', #PH
     1838    39 => { #22
     1839        Name => 'SpotMeteringMode',
     1840        RawConv => '$val==-1 ? undef : $val',
     1841        PrintConv => {
     1842            0 => 'Center',
     1843            1 => 'AF Point',
     1844        },
     1845    },
    11601846    40 => { #PH
    11611847        Name => 'PhotoEffect',
    11621848        RawConv => '$val==-1 ? undef : $val',
     1849        PrintConvColumns => 2,
    11631850        PrintConv => {
    11641851            0 => 'Off',
     
    11871874        Name => 'ColorTone',
    11881875        RawConv => '$val == 0x7fff ? undef : $val',
    1189         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    1190         PrintConvInv => '$val=~/normal/i ? 0 : $val',
     1876        %Image::ExifTool::Exif::printParameter,
     1877    },
     1878    46 => { #PH
     1879        Name => 'SRAWQuality',
     1880        RawConv => '$val==-1 ? undef : $val',
     1881        PrintConv => {
     1882            0 => 'n/a',
     1883            1 => 'sRAW1 (mRAW)',
     1884            2 => 'sRAW2 (sRAW)',
     1885        },
    11911886    },
    11921887);
     
    11941889# focal length information (MakerNotes tag 0x02)
    11951890%Image::ExifTool::Canon::FocalLength = (
    1196     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1197     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1198     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    1199     WRITABLE => 1,
     1891    %binaryDataAttrs,
    12001892    FORMAT => 'int16u',
    12011893    FIRST_ENTRY => 0,
     
    12041896        Name => 'FocalType',
    12051897        RawConv => '$val ? $val : undef', # don't use if value is zero
    1206         PrintConv => {
     1898        PrintConv => {
    12071899            1 => 'Fixed',
    12081900            2 => 'Zoom',
     
    12251917        ValueConv => '$val / ($$self{FocalUnits} || 1)',
    12261918        ValueConvInv => '$val',
    1227         PrintConv => '"${val}mm"',
    1228         PrintConvInv => '$val=~s/mm//;$val',
    1229     },
    1230     2 => { #4
    1231         Name => 'FocalPlaneXSize',
    1232         Notes => 'not valid for 1DmkIII',
    1233         Condition => '$$self{CameraModel} !~ /1D Mark III/',
    1234         # focal plane image dimensions in 1/1000 inch -- convert to mm
    1235         RawConv => '$val < 40 ? undef : $val',  # must be reasonable
    1236         ValueConv => '$val * 25.4 / 1000',
    1237         ValueConvInv => 'int($val * 1000 / 25.4 + 0.5)',
    1238         PrintConv => 'sprintf("%.2fmm",$val)',
    1239         PrintConvInv => '$val=~s/\s*mm$//;$val',
    1240     },
    1241     3 => {
    1242         Name => 'FocalPlaneYSize',
    1243         Notes => 'not valid for 1DmkIII',
    1244         Condition => '$$self{CameraModel} !~ /1D Mark III/',
    1245         RawConv => '$val < 40 ? undef : $val',  # must be reasonable
    1246         ValueConv => '$val * 25.4 / 1000',
    1247         ValueConvInv => 'int($val * 1000 / 25.4 + 0.5)',
    1248         PrintConv => 'sprintf("%.2fmm",$val)',
    1249         PrintConvInv => '$val=~s/\s*mm$//;$val',
    1250     },
     1919        PrintConv => '"$val mm"',
     1920        PrintConvInv => '$val=~s/\s*mm//;$val',
     1921    },
     1922    2 => [ #4
     1923        {
     1924            Name => 'FocalPlaneXSize',
     1925            Notes => q{
     1926                these focal plane sizes are only valid for some models, and are affected by
     1927                digital zoom if applied
     1928            },
     1929            # this conversion is valid only for PowerShot models and these EOS models:
     1930            # D30, D60, 1D, 1DS, 5D, 10D, 20D, 30D, 300D, 350D, and 400D
     1931            Condition => q{
     1932                $$self{Model} !~ /EOS/ or
     1933                $$self{Model} =~ /\b(1DS?|5D|D30|D60|10D|20D|30D|K236)$/ or
     1934                $$self{Model} =~ /\b((300D|350D|400D) DIGITAL|REBEL( XTi?)?|Kiss Digital( [NX])?)$/
     1935            },
     1936            # focal plane image dimensions in 1/1000 inch -- convert to mm
     1937            RawConv => '$val < 40 ? undef : $val',  # must be reasonable
     1938            ValueConv => '$val * 25.4 / 1000',
     1939            ValueConvInv => 'int($val * 1000 / 25.4 + 0.5)',
     1940            PrintConv => 'sprintf("%.2f mm",$val)',
     1941            PrintConvInv => '$val=~s/\s*mm$//;$val',
     1942        },{
     1943            Name => 'FocalPlaneXUnknown',
     1944            Unknown => 1,
     1945        },
     1946    ],
     1947    3 => [ #4
     1948        {
     1949            Name => 'FocalPlaneYSize',
     1950            Condition => q{
     1951                $$self{Model} !~ /EOS/ or
     1952                $$self{Model} =~ /\b(1DS?|5D|D30|D60|10D|20D|30D|K236)$/ or
     1953                $$self{Model} =~ /\b((300D|350D|400D) DIGITAL|REBEL( XTi?)?|Kiss Digital( [NX])?)$/
     1954            },
     1955            RawConv => '$val < 40 ? undef : $val',  # must be reasonable
     1956            ValueConv => '$val * 25.4 / 1000',
     1957            ValueConvInv => 'int($val * 1000 / 25.4 + 0.5)',
     1958            PrintConv => 'sprintf("%.2f mm",$val)',
     1959            PrintConvInv => '$val=~s/\s*mm$//;$val',
     1960        },{
     1961            Name => 'FocalPlaneYUnknown',
     1962            Unknown => 1,
     1963        },
     1964    ],
    12511965);
    12521966
     
    12541968# BinaryData (keys are indices into the int16s array)
    12551969%Image::ExifTool::Canon::ShotInfo = (
    1256     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1257     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1258     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    1259     WRITABLE => 1,
     1970    %binaryDataAttrs,
    12601971    FORMAT => 'int16s',
    12611972    FIRST_ENTRY => 1,
     1973    DATAMEMBER => [ 19 ],
    12621974    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
    12631975    1 => { #PH
     
    12811993        Name => 'MeasuredEV',
    12821994        Notes => q{
    1283             this the Canon name for what should properly be called MeasuredLV, and is
    1284             offset by about -5 EV from the calculated LV for most models
    1285         },
    1286         ValueConv => '$val / 32',
    1287         ValueConvInv => '$val * 32',
     1995            this is the Canon name for what could better be called MeasuredLV, and
     1996            should be close to the calculated LightValue for a proper exposure with most
     1997            models
     1998        },
     1999        # empirical offset of +5 seems to be good for EOS models, but maybe
     2000        # the offset should be less by up to 1 EV for some PowerShot models
     2001        ValueConv => '$val / 32 + 5',
     2002        ValueConvInv => '($val - 5) * 32',
    12882003        PrintConv => 'sprintf("%.2f",$val)',
    12892004        PrintConvInv => '$val',
     
    12992014    5 => { #2
    13002015        Name => 'TargetExposureTime',
    1301         RawConv => '$val > 0 ? $val : undef',
     2016        # ignore obviously bad values (also, -32768 may be used for n/a)
     2017        # (note that a few models always write 0: DC211, and video models)
     2018        RawConv => '($val > -1000 and ($val or $$self{Model}=~/(EOS|PowerShot|IXUS|IXY)/))? $val : undef',
    13022019        ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val)*log(2))',
    13032020        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val)/log(2))',
    13042021        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    1305         PrintConvInv => 'eval $val',
     2022        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    13062023    },
    13072024    6 => {
     
    13092026        ValueConv => 'Image::ExifTool::Canon::CanonEv($val)',
    13102027        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv($val)',
    1311         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    1312         PrintConvInv => 'eval $val',
     2028        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     2029        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    13132030    },
    13142031    7 => {
    13152032        Name => 'WhiteBalance',
    13162033        PrintConv => \%canonWhiteBalance,
     2034        SeparateTable => 1,
    13172035    },
    13182036    8 => { #PH
    13192037        Name => 'SlowShutter',
    13202038        PrintConv => {
     2039            -1 => 'n/a',
    13212040            0 => 'Off',
    13222041            1 => 'Night Scene',
     
    13352054        # (for many models, 0-6 represent 0-100% zoom, but it is always 8 for
    13362055        #  EOS models, and I have seen values of 16,20,28,32 and 39 too...)
     2056        # - set to 8 for "n/a" by Canon software (ref 22)
     2057        PrintConv => '$val == 8 ? "n/a" : $val',
     2058        PrintConvInv => '$val =~ /[a-z]/i ? 8 : $val',
    13372059    },
    13382060    # 11 - (8 for all EOS samples, [0,8] for other models - PH)
     2061    12 => { #37
     2062        Name => 'CameraTemperature',
     2063        Condition => '$$self{Model} =~ /EOS/ and $$self{Model} !~ /EOS-1DS?$/',
     2064        Groups => { 2 => 'Camera' },
     2065        Notes => 'newer EOS models only',
     2066        # usually zero if not valid for an EOS model (exceptions: 1D, 1DS)
     2067        RawConv => '$val ? $val : undef',
     2068        ValueConv => '$val - 128',
     2069        ValueConvInv => '$val + 128',
     2070        PrintConv => '"$val C"',
     2071        PrintConvInv => '$val=~s/ ?C//; $val',
     2072    },
    13392073    13 => { #PH
    13402074        Name => 'FlashGuideNumber',
    1341         RawConv => '$val == -1 ? undef : $val',
     2075        RawConv => '$val==-1 ? undef : $val',
    13422076        ValueConv => '$val / 32',
    13432077        ValueConvInv => '$val * 32',
     
    13502084        Flags => 'PrintHex',
    13512085        RawConv => '$val==0 ? undef : $val',
     2086        PrintConvColumns => 2,
    13522087        PrintConv => {
    13532088            0x3000 => 'None (MF)',
     
    13662101        ValueConv => 'Image::ExifTool::Canon::CanonEv($val)',
    13672102        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv($val)',
    1368         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    1369         PrintConvInv => 'eval $val',
     2103        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     2104        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    13702105    },
    13712106    16 => {
     
    13832118        ValueConv => 'Image::ExifTool::Canon::CanonEv($val)',
    13842119        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv($val)',
    1385         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    1386         PrintConvInv => 'eval $val',
     2120        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     2121        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     2122    },
     2123    18 => { #22
     2124        Name => 'ControlMode',
     2125        PrintConv => {
     2126            0 => 'n/a',
     2127            1 => 'Camera Local Control',
     2128            3 => 'Computer Remote Control',
     2129        },
    13872130    },
    13882131    19 => {
    13892132        Name => 'FocusDistanceUpper',
    1390         ValueConv => '$val * 0.01',
    1391         ValueConvInv => '$val / 0.01',
     2133        DataMember => 'FocusDistanceUpper',
     2134        Format => 'int16u',
     2135        Notes => 'FocusDistance tags are only extracted if FocusDistanceUpper is non-zero',
     2136        RawConv => '($$self{FocusDistanceUpper} = $val) || undef',
     2137        ValueConv => '$val / 100',
     2138        ValueConvInv => '$val * 100',
     2139        PrintConv => '$val > 655.345 ? "inf" : "$val m"',
     2140        PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 655.35',
    13922141    },
    13932142    20 => {
    1394         Name => 'FocusDistanceLower',
    1395         ValueConv => '$val * 0.01',
    1396         ValueConvInv => '$val / 0.01',
     2143        Name => 'FocusDistanceLower', # (seems to be the upper distance for the 400D)
     2144        Condition => '$$self{FocusDistanceUpper}',
     2145        Format => 'int16u',
     2146        ValueConv => '$val / 100',
     2147        ValueConvInv => '$val * 100',
     2148        PrintConv => '$val > 655.345 ? "inf" : "$val m"',
     2149        PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 655.35',
    13972150    },
    13982151    21 => {
     
    14112164            # encoding is different for 20D and 350D (darn!)
    14122165            # (but note that encoding is the same for TargetExposureTime - PH)
    1413             Condition => '$$self{CameraModel} =~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/',
     2166            Condition => '$$self{Model} =~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/',
    14142167            Priority => 0,
    1415             RawConv => '$val ? $val : undef',
     2168            # many models write 0 here in JPEG images (even though 0 is the
     2169            # value for an exposure time of 1 sec), but apparently a value of 0
     2170            # is valid in a CRW image (=1s, D60 sample)
     2171            RawConv => '($val or $$self{FILE_TYPE} eq "CRW") ? $val : undef',
    14162172            # approximate big translation table by simple calculation - PH
    14172173            ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val)*log(2))*1000/32',
    14182174            ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val*32/1000)/log(2))',
    14192175            PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    1420             PrintConvInv => 'eval $val',
     2176            PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    14212177        },
    14222178        {
    14232179            Name => 'ExposureTime',
    14242180            Priority => 0,
    1425             RawConv => '$val ? $val : undef',
     2181            # many models write 0 here in JPEG images (even though 0 is the
     2182            # value for an exposure time of 1 sec), but apparently a value of 0
     2183            # is valid in a CRW image (=1s, D60 sample)
     2184            RawConv => '($val or $$self{FILE_TYPE} eq "CRW") ? $val : undef',
    14262185            # approximate big translation table by simple calculation - PH
    14272186            ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val)*log(2))',
    14282187            ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val)/log(2))',
    14292188            PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    1430             PrintConvInv => 'eval $val',
     2189            PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    14312190        },
    14322191    ],
     2192    23 => { #37
     2193        Name => 'MeasuredEV2',
     2194        Description => 'Measured EV 2',
     2195        RawConv => '$val ? $val : undef',
     2196        ValueConv => '$val / 8 - 6',
     2197        ValueConvInv => 'int(($val + 6) * 8 + 0.5)',
     2198    },
    14332199    24 => {
    14342200        Name => 'BulbDuration',
     
    14422208        Groups => { 2 => 'Camera' },
    14432209        PrintConv => {
     2210            0 => 'n/a',
    14442211            248 => 'EOS High-end',
    14452212            250 => 'Compact',
     
    14502217    27 => {
    14512218        Name => 'AutoRotate',
    1452         PrintConv => {
    1453            -1 => 'Rotated by Software',
     2219        RawConv => '$val >= 0 ? $val : undef',
     2220        PrintConv => {
     2221           -1 => 'n/a', # (set to -1 when rotated by Canon software)
    14542222            0 => 'None',
    14552223            1 => 'Rotate 90 CW',
     
    14602228    28 => { #15
    14612229        Name => 'NDFilter',
    1462         PrintConv => { 0 => 'Off', 1 => 'On' },
     2230        PrintConv => { -1 => 'n/a', 0 => 'Off', 1 => 'On' },
    14632231    },
    14642232    29 => {
    1465         Name => 'Self-timer2',
     2233        Name => 'SelfTimer2',
    14662234        RawConv => '$val >= 0 ? $val : undef',
    14672235        ValueConv => '$val / 10',
     
    14702238    33 => { #PH (A570IS)
    14712239        Name => 'FlashOutput',
    1472         Notes => 'this has a maximum value of 500 for models like the A570IS',
    1473     },
    1474 );
    1475 
    1476 # Canon camera information (MakerNotes tag 0x0d)
    1477 # (ref 12 unless otherwise noted)
    1478 %Image::ExifTool::Canon::CameraInfo = (
    1479     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1480     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1481     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    1482     WRITABLE => 1,
    1483     FORMAT => 'int8s',
     2240        RawConv => '($$self{Model}=~/(PowerShot|IXUS|IXY)/ or $val) ? $val : undef',
     2241        Notes => q{
     2242            used only for PowerShot models, this has a maximum value of 500 for models
     2243            like the A570IS
     2244        },
     2245    },
     2246);
     2247
     2248# Canon panorama information (MakerNotes tag 0x05)
     2249%Image::ExifTool::Canon::Panorama = (
     2250    %binaryDataAttrs,
     2251    FORMAT => 'int16s',
    14842252    FIRST_ENTRY => 0,
     2253    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     2254    # 0 - values: always 1
     2255    # 1 - values: 0,256,512(3 sequential L->R images); 0,-256(2 R->L images)
     2256    2 => 'PanoramaFrameNumber', #(some models this is always 0)
     2257    # 3 - values: 160(SX10IS,A570IS); 871(S30)
     2258    # 4 - values: always 0
     2259    5 => {
     2260        Name => 'PanoramaDirection',
     2261        PrintConv => {
     2262            0 => 'Left to Right',
     2263            1 => 'Right to Left',
     2264            2 => 'Bottom to Top',
     2265            3 => 'Top to Bottom',
     2266            4 => '2x2 Matrix (Clockwise)',
     2267        },
     2268     },
     2269);
     2270
     2271# D30 color information (MakerNotes tag 0x0a)
     2272%Image::ExifTool::Canon::UnknownD30 = (
     2273    %binaryDataAttrs,
     2274    FORMAT => 'int16s',
     2275    FIRST_ENTRY => 1,
     2276    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2277);
     2278
     2279#..............................................................................
     2280# common CameraInfo tag definitions
     2281my %ciFNumber = (
     2282    Name => 'FNumber',
     2283    Format => 'int8u',
     2284    Groups => { 2 => 'Image' },
     2285    RawConv => '$val ? $val : undef',
     2286    ValueConv => 'exp(($val-8)/16*log(2))',
     2287    ValueConvInv => 'log($val)*16/log(2)+8',
     2288    PrintConv => 'sprintf("%.2g",$val)',
     2289    PrintConvInv => '$val',
     2290);
     2291my %ciExposureTime = (
     2292    Name => 'ExposureTime',
     2293    Format => 'int8u',
     2294    Groups => { 2 => 'Image' },
     2295    RawConv => '$val ? $val : undef',
     2296    ValueConv => 'exp(4*log(2)*(1-Image::ExifTool::Canon::CanonEv($val-24)))',
     2297    ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(1-log($val)/(4*log(2)))+24',
     2298    PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     2299    PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     2300);
     2301my %ciISO = (
     2302    Name => 'ISO',
     2303    Format => 'int8u',
     2304    Groups => { 2 => 'Image' },
     2305    ValueConv => '100*exp(($val/8-9)*log(2))',
     2306    ValueConvInv => '(log($val/100)/log(2)+9)*8',
     2307    PrintConv => 'sprintf("%.0f",$val)',
     2308    PrintConvInv => '$val',
     2309);
     2310my %ciCameraTemperature = (
     2311    Name => 'CameraTemperature',
     2312    Format => 'int8u',
     2313    ValueConv => '$val - 128',
     2314    ValueConvInv => '$val + 128',
     2315    PrintConv => '"$val C"',
     2316    PrintConvInv => '$val=~s/ ?C//; $val',
     2317);
     2318my %ciMacroMagnification = (
     2319    Name => 'MacroMagnification',
     2320    Notes => 'currently decoded only for the MP-E 65mm f/2.8 1-5x Macro Photo',
     2321    Condition => '$$self{LensType} and $$self{LensType} == 124',
     2322    # 75=1x, 44=5x, log relationship
     2323    ValueConv => 'exp((75-$val) * log(2) * 3 / 40)',
     2324    ValueConvInv => '$val > 0 ? 75 - log($val) / log(2) * 40 / 3 : undef',
     2325    PrintConv => 'sprintf("%.1fx",$val)',
     2326    PrintConvInv => '$val=~s/\s*x//; $val',
     2327);
     2328my %ciFocalLength = (
     2329    Name => 'FocalLength',
     2330    Format => 'int16uRev', # (just to make things confusing, the focal lengths are big-endian)
     2331    # ignore if zero
     2332    RawConv => '$val ? $val : undef',
     2333    PrintConv => '"$val mm"',
     2334    PrintConvInv => '$val=~s/\s*mm//;$val',
     2335);
     2336my %ciShortFocal = (
     2337    Name => 'ShortFocal',
     2338    Format => 'int16uRev', # byte order is big-endian
     2339    PrintConv => '"$val mm"',
     2340    PrintConvInv => '$val=~s/\s*mm//;$val',
     2341);
     2342my %ciLongFocal = (
     2343    Name => 'LongFocal',
     2344    Format => 'int16uRev', # byte order is big-endian
     2345    PrintConv => '"$val mm"',
     2346    PrintConvInv => '$val=~s/\s*mm//;$val',
     2347);
     2348
     2349#..............................................................................
     2350# Camera information for 1D and 1DS (MakerNotes tag 0x0d)
     2351# (ref 15 unless otherwise noted)
     2352%Image::ExifTool::Canon::CameraInfo1D = (
     2353    %binaryDataAttrs,
     2354    FORMAT => 'int8u',
     2355    FIRST_ENTRY => 0,
     2356    PRIORITY => 0,  # these tags are not reliable since they change with firmware version
    14852357    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    14862358    NOTES => q{
     
    14882360        encodings are very different than in other Canon records (even sometimes
    14892361        switching endianness between values within a single camera), plus there is
    1490         considerable variation in format from model to model. The table below is
    1491         common to the 1D, 1DS, 1DmkII, 1DSmkII and 5D, but individual tags may not
    1492         be valid for all these models.
    1493     },
    1494     0x03 => { #PH
    1495         Name => 'FNumber',
    1496         Groups => { 2 => 'Image' },
    1497         Condition => '$$self{CameraModel} =~ /EOS 5D/',
    1498         Format => 'int8u',
    1499         Notes => '5D only',
    1500         Priority => 0,
    1501         RawConv => '$val ? $val : undef',
    1502         ValueConv => 'exp(($val-8)/16*log(2))',
    1503         ValueConvInv => 'log($val)*16/log(2)+8',
    1504         PrintConv => 'sprintf("%.2g",$val)',
    1505         PrintConvInv => '$val',
    1506     },
    1507     0x04 => { #9
    1508         Name => 'ExposureTime',
    1509         Groups => { 2 => 'Image' },
    1510         Format => 'int8u',
    1511         Priority => 0,
    1512         RawConv => '$val ? $val : undef',
    1513         ValueConv => 'exp(4*log(2)*(1-Image::ExifTool::Canon::CanonEv($val-24)))',
    1514         ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(1-log($val)/(4*log(2)))+24',
    1515         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    1516         PrintConvInv => 'eval $val',
    1517     },
    1518     0x06 => { #PH
    1519         Name => 'ISO',
    1520         Groups => { 2 => 'Image' },
    1521         Condition => '$$self{CameraModel} =~ /EOS 5D/',
    1522         Format => 'int8u',
    1523         Notes => '5D only',
    1524         Priority => 0,
    1525         ValueConv => '100*exp(($val/8-9)*log(2))',
    1526         ValueConvInv => '(log($val/100)/log(2)+9)*8',
    1527         PrintConv => 'sprintf("%.0f",$val)',
    1528         PrintConvInv => '$val',
    1529     },
    1530     0x09 => { #9
     2362        considerable variation in format from model to model. The first table below
     2363        lists CameraInfo tags for the 1D and 1DS.
     2364    },
     2365    0x04 => { %ciExposureTime }, #9
     2366    0x0a => {
    15312367        Name => 'FocalLength',
    15322368        Format => 'int16u',
    1533         Condition => '$$self{CameraModel} =~ /\b1Ds? Mark II\b/',
    1534         Notes => '1DmkII and 1DsMkII only',
    1535         # the EXIF FocalLength is more reliable, so set this priority to zero
    1536         Priority => 0,
    1537         # ignore if zero and change to big-endian
    1538         RawConv => '$val ? unpack("n",pack("v",$val)) : undef',
    1539         PrintConv => '"${val}mm"',
    1540         PrintConvInv => '$val=~s/mm//;$val',
     2369        # ignore if zero
     2370        RawConv => '$val ? $val : undef',
     2371        PrintConv => '"$val mm"',
     2372        PrintConvInv => '$val=~s/\s*mm//;$val',
    15412373    },
    15422374    0x0d => { #9
    15432375        Name => 'LensType',
    1544         Format => 'int8u',
     2376        Format => 'int16uRev', # value is little-endian
    15452377        SeparateTable => 1,
    15462378        RawConv => '$val ? $val : undef', # don't use if value is zero
    15472379        PrintConv => \%canonLensTypes,
    15482380    },
    1549     0x11 => { #9
     2381    0x0e => {
    15502382        Name => 'ShortFocal',
    15512383        Format => 'int16u',
    1552         Condition => '$$self{CameraModel} =~ /\b1Ds? Mark II\b/',
    1553         Notes => '1DmkII and 1DsMkII only',
    1554         # the EXIF ShortFocal is more reliable, so set this priority to zero
    1555         Priority => 0,
    1556         ValueConv => 'unpack("n",pack("v",$val))',
    1557         ValueConvInv => 'unpack("v",pack("n",$val))',
    1558         PrintConv => '"${val}mm"',
    1559         PrintConvInv => '$val=~s/mm//;$val',
    1560     },
    1561     0x13 => { #9
     2384        PrintConv => '"$val mm"',
     2385        PrintConvInv => '$val=~s/\s*mm//;$val',
     2386    },
     2387    0x10 => {
    15622388        Name => 'LongFocal',
    15632389        Format => 'int16u',
    1564         Condition => '$$self{CameraModel} =~ /\b1Ds? Mark II\b/',
    1565         Notes => '1DmkII and 1DsMkII only',
    1566         # the EXIF LongFocal is more reliable, so set this priority to zero
    1567         Priority => 0,
    1568         ValueConv => 'unpack("n",pack("v",$val))',
    1569         ValueConvInv => 'unpack("v",pack("n",$val))',
    1570         PrintConv => '"${val}mm"',
    1571         PrintConvInv => '$val=~s/mm//;$val',
    1572     },
     2390        PrintConv => '"$val mm"',
     2391        PrintConvInv => '$val=~s/\s*mm//;$val',
     2392    },
     2393    0x41 => {
     2394        Name => 'SharpnessFrequency', # PatternSharpness?
     2395        Condition => '$$self{Model} =~ /\b1D$/',
     2396        Notes => '1D only',
     2397        PrintConvColumns => 2,
     2398        PrintConv => {
     2399            0 => 'n/a',
     2400            1 => 'Lowest',
     2401            2 => 'Low',
     2402            3 => 'Standard',
     2403            4 => 'High',
     2404            5 => 'Highest',
     2405        },
     2406    },
     2407    0x42 => {
     2408        Name => 'Sharpness',
     2409        Format => 'int8s',
     2410        Condition => '$$self{Model} =~ /\b1D$/',
     2411        Notes => '1D only',
     2412    },
     2413    0x44 => {
     2414        Name => 'WhiteBalance',
     2415        Condition => '$$self{Model} =~ /\b1D$/',
     2416        Notes => '1D only',
     2417        SeparateTable => 1,
     2418        PrintConv => \%canonWhiteBalance,
     2419    },
     2420    0x47 => {
     2421        Name => 'SharpnessFrequency', # PatternSharpness?
     2422        Condition => '$$self{Model} =~ /\b1DS$/',
     2423        Notes => '1DS only',
     2424        PrintConvColumns => 2,
     2425        PrintConv => {
     2426            0 => 'n/a',
     2427            1 => 'Lowest',
     2428            2 => 'Low',
     2429            3 => 'Standard',
     2430            4 => 'High',
     2431            5 => 'Highest',
     2432        },
     2433    },
     2434    0x48 => [
     2435        {
     2436            Name => 'ColorTemperature',
     2437            Format => 'int16u',
     2438            Condition => '$$self{Model} =~ /\b1D$/',
     2439            Notes => '1D only',
     2440        },
     2441        {
     2442            Name => 'Sharpness',
     2443            Format => 'int8s',
     2444            Condition => '$$self{Model} =~ /\b1DS$/',
     2445            Notes => '1DS only',
     2446        },
     2447    ],
     2448    0x4a => {
     2449        Name => 'WhiteBalance',
     2450        Condition => '$$self{Model} =~ /\b1DS$/',
     2451        Notes => '1DS only',
     2452        SeparateTable => 1,
     2453        PrintConv => \%canonWhiteBalance,
     2454    },
     2455    0x4b => {
     2456        Name => 'PictureStyle',
     2457        Condition => '$$self{Model} =~ /\b1D$/',
     2458        Notes => "1D only, called 'Color Matrix' in owner's manual",
     2459        Flags => ['PrintHex','SeparateTable'],
     2460        PrintConv => \%pictureStyles,
     2461    },
     2462    0x4e => {
     2463        Name => 'ColorTemperature',
     2464        Format => 'int16u',
     2465        Condition => '$$self{Model} =~ /\b1DS$/',
     2466        Notes => '1DS only',
     2467    },
     2468    0x51 => {
     2469        Name => 'PictureStyle',
     2470        Condition => '$$self{Model} =~ /\b1DS$/',
     2471        Notes => '1DS only',
     2472        Flags => ['PrintHex','SeparateTable'],
     2473        PrintConv => \%pictureStyles,
     2474    },
     2475);
     2476
     2477# Camera information for 1DmkII and 1DSmkII (MakerNotes tag 0x0d)
     2478# (ref 15 unless otherwise noted)
     2479%Image::ExifTool::Canon::CameraInfo1DmkII = (
     2480    %binaryDataAttrs,
     2481    FORMAT => 'int8u',
     2482    FIRST_ENTRY => 0,
     2483    PRIORITY => 0,
     2484    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2485    NOTES => 'CameraInfo tags for the 1DmkII and 1DSmkII.',
     2486    0x04 => { %ciExposureTime }, #9
     2487    0x09 => { %ciFocalLength }, #9
     2488    0x0c => { #9
     2489        Name => 'LensType',
     2490        Format => 'int16uRev', # value is big-endian
     2491        SeparateTable => 1,
     2492        RawConv => '$val ? $val : undef', # don't use if value is zero
     2493        PrintConv => \%canonLensTypes,
     2494    },
     2495    0x11 => { %ciShortFocal }, #9
     2496    0x13 => { %ciLongFocal }, #9
    15732497    0x2d => { #9
    15742498        Name => 'FocalType',
    1575         Format => 'int8u',
    1576         Condition => '$$self{CameraModel} =~ /\b1Ds? Mark II\b/',
    1577         Notes => '1DmkII and 1DSmkII only',
    1578         Priority => 0,
    15792499        PrintConv => {
    15802500           0 => 'Fixed',
     
    15822502        },
    15832503    },
     2504    0x36 => {
     2505        Name => 'WhiteBalance',
     2506        SeparateTable => 1,
     2507        PrintConv => \%canonWhiteBalance,
     2508    },
     2509    0x37 => {
     2510        Name => 'ColorTemperature',
     2511        Format => 'int16uRev',
     2512    },
     2513    0x39 => {
     2514        Name => 'CanonImageSize',
     2515        Format => 'int16u',
     2516        PrintConvColumns => 2,
     2517        PrintConv => \%canonImageSize,
     2518    },
     2519    0x66 => {
     2520        Name => 'JPEGQuality',
     2521        Notes => 'a number from 1 to 10',
     2522    },
     2523    0x6c => { #12
     2524        Name => 'PictureStyle',
     2525        Flags => ['PrintHex','SeparateTable'],
     2526        PrintConv => \%pictureStyles,
     2527    },
     2528    0x6e => {
     2529        Name => 'Saturation',
     2530        Format => 'int8s',
     2531        %Image::ExifTool::Exif::printParameter,
     2532    },
     2533    0x6f => {
     2534        Name => 'ColorTone',
     2535        Format => 'int8s',
     2536        %Image::ExifTool::Exif::printParameter,
     2537    },
     2538    0x72 => {
     2539        Name => 'Sharpness',
     2540        Format => 'int8s',
     2541    },
     2542    0x73 => {
     2543        Name => 'Contrast',
     2544        Format => 'int8s',
     2545        %Image::ExifTool::Exif::printParameter,
     2546    },
     2547    0x75 => {
     2548        Name => 'ISO',
     2549        Format => 'string[5]',
     2550    },
     2551);
     2552
     2553# Camera information for the 1DmkIIN (MakerNotes tag 0x0d)
     2554# (ref 9 unless otherwise noted)
     2555%Image::ExifTool::Canon::CameraInfo1DmkIIN = (
     2556    %binaryDataAttrs,
     2557    FORMAT => 'int8u',
     2558    FIRST_ENTRY => 0,
     2559    PRIORITY => 0,
     2560    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2561    NOTES => 'CameraInfo tags for the 1DmkIIN.',
     2562    0x04 => { %ciExposureTime },
     2563    0x09 => { %ciFocalLength },
     2564    0x0c => {
     2565        Name => 'LensType',
     2566        Format => 'int16uRev', # value is big-endian
     2567        SeparateTable => 1,
     2568        RawConv => '$val ? $val : undef', # don't use if value is zero
     2569        PrintConv => \%canonLensTypes,
     2570    },
     2571    0x11 => { %ciShortFocal },
     2572    0x13 => { %ciLongFocal },
     2573    0x36 => { #15
     2574        Name => 'WhiteBalance',
     2575        SeparateTable => 1,
     2576        PrintConv => \%canonWhiteBalance,
     2577    },
     2578    0x37 => { #15
     2579        Name => 'ColorTemperature',
     2580        Format => 'int16uRev',
     2581    },
     2582    0x73 => { #15
     2583        Name => 'PictureStyle',
     2584        Flags => ['PrintHex','SeparateTable'],
     2585        PrintConv => \%pictureStyles,
     2586    },
     2587    0x74 => { #15
     2588        Name => 'Sharpness',
     2589        Format => 'int8s',
     2590    },
     2591    0x75 => { #15
     2592        Name => 'Contrast',
     2593        Format => 'int8s',
     2594        %Image::ExifTool::Exif::printParameter,
     2595    },
     2596    0x76 => { #15
     2597        Name => 'Saturation',
     2598        Format => 'int8s',
     2599        %Image::ExifTool::Exif::printParameter,
     2600    },
     2601    0x77 => { #15
     2602        Name => 'ColorTone',
     2603        Format => 'int8s',
     2604        %Image::ExifTool::Exif::printParameter,
     2605    },
     2606    0x79 => { #15
     2607        Name => 'ISO',
     2608        Format => 'string[5]',
     2609    },
     2610);
     2611
     2612# Canon camera information for 1DmkIII and 1DSmkIII (MakerNotes tag 0x0d)
     2613# (ref PH unless otherwise noted)
     2614%Image::ExifTool::Canon::CameraInfo1DmkIII = (
     2615    %binaryDataAttrs,
     2616    FORMAT => 'int8u',
     2617    FIRST_ENTRY => 0,
     2618    PRIORITY => 0,
     2619    IS_SUBDIR => [ 0x2aa ],
     2620    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2621    NOTES => 'CameraInfo tags for the 1DmkIII and 1DSmkIII.',
     2622    0x03 => { %ciFNumber },
     2623    0x04 => { %ciExposureTime }, #9
     2624    0x06 => { %ciISO },
     2625    0x18 => { %ciCameraTemperature }, #36
     2626    0x1b => { %ciMacroMagnification }, #(NC)
     2627    0x1d => { %ciFocalLength },
     2628    0x30 => {
     2629        Name => 'CameraOrientation', # <-- (always 9th byte after 0xbbbb for all models - Dave Coffin)
     2630        PrintConv => {
     2631            0 => 'Horizontal (normal)',
     2632            1 => 'Rotate 90 CW',
     2633            2 => 'Rotate 270 CW',
     2634        },
     2635    },
     2636    0x43 => { #21/24
     2637        Name => 'FocusDistanceUpper',
     2638        # (it looks like the focus distances are also odd-byte big-endian)
     2639        %focusDistanceByteSwap,
     2640    },
     2641    0x45 => { #21/24
     2642        Name => 'FocusDistanceLower',
     2643        %focusDistanceByteSwap,
     2644    },
     2645    0x5e => { #15
     2646        Name => 'WhiteBalance',
     2647        Format => 'int16u',
     2648        PrintConv => \%canonWhiteBalance,
     2649        SeparateTable => 1,
     2650    },
     2651    0x62 => { #15
     2652        Name => 'ColorTemperature',
     2653        Format => 'int16u',
     2654    },
     2655    0x86 => {
     2656        Name => 'PictureStyle',
     2657        Flags => ['PrintHex','SeparateTable'],
     2658        PrintConv => \%pictureStyles,
     2659    },
     2660    0x111 => { #15
     2661        Name => 'LensType',
     2662        Format => 'int16uRev', # value is big-endian
     2663        SeparateTable => 1,
     2664        PrintConv => \%canonLensTypes,
     2665    },
     2666    0x113 => { %ciShortFocal },
     2667    0x115 => { %ciLongFocal },
     2668    0x136 => { #15
     2669        Name => 'FirmwareVersion',
     2670        Format => 'string[6]',
     2671    },
     2672    0x172 => {
     2673        Name => 'FileIndex',
     2674        Groups => { 2 => 'Image' },
     2675        Format => 'int32u',
     2676        ValueConv => '$val + 1',
     2677        ValueConvInv => '$val - 1',
     2678    },
     2679    0x176 => {
     2680        Name => 'ShutterCount',
     2681        Notes => 'may be valid only for some 1DmkIII copies, even running the same firmware',
     2682        Format => 'int32u',
     2683        ValueConv => '$val + 1',
     2684        ValueConvInv => '$val - 1',
     2685    },
     2686    0x17e => { #(NC)
     2687        Name => 'DirectoryIndex',
     2688        Groups => { 2 => 'Image' },
     2689        Format => 'int32u',
     2690        ValueConv => '$val - 1',
     2691        ValueConvInv => '$val + 1',
     2692    },
     2693    0x2aa => { #48
     2694        Name => 'PictureStyleInfo',
     2695        SubDirectory => {
     2696            TagTable => 'Image::ExifTool::Canon::PSInfo',
     2697        },
     2698    },
     2699    0x45a => { #29
     2700        Name => 'TimeStamp1',
     2701        Condition => '$$self{Model} =~ /\b1D Mark III$/',
     2702        Format => 'int32u',
     2703        Groups => { 2 => 'Time' },
     2704        # observed in 1DmkIII firmware 5.3.1 (pre-production), 1.0.3, 1.0.8
     2705        Notes => 'only valid for some versions of the 1DmkIII firmware',
     2706        Shift => 'Time',
     2707        RawConv => '$val ? $val : undef',
     2708        ValueConv => 'ConvertUnixTime($val)',
     2709        ValueConvInv => 'GetUnixTime($val)',
     2710        PrintConv => '$self->ConvertDateTime($val)',
     2711        PrintConvInv => '$self->InverseDateTime($val)',
     2712    },
     2713    0x45e => {
     2714        Name => 'TimeStamp',
     2715        Format => 'int32u',
     2716        Groups => { 2 => 'Time' },
     2717        # observed in 1DmkIII firmware 1.1.0, 1.1.3 and
     2718        # 1DSmkIII firmware 1.0.0, 1.0.4, 2.1.2, 2.7.1
     2719        Notes => 'valid for the 1DSmkIII and some versions of the 1DmkIII firmware',
     2720        Shift => 'Time',
     2721        RawConv => '$val ? $val : undef',
     2722        ValueConv => 'ConvertUnixTime($val)',
     2723        ValueConvInv => 'GetUnixTime($val)',
     2724        PrintConv => '$self->ConvertDateTime($val)',
     2725        PrintConvInv => '$self->InverseDateTime($val)',
     2726    },
     2727);
     2728
     2729# Canon camera information for 1DmkIV (MakerNotes tag 0x0d) (ref PH)
     2730%Image::ExifTool::Canon::CameraInfo1DmkIV = (
     2731    %binaryDataAttrs,
     2732    FIRST_ENTRY => 0,
     2733    PRIORITY => 0,
     2734    DATAMEMBER => [ 0x57 ],
     2735    IS_SUBDIR => [ 0x363, 0x368 ],
     2736    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2737    NOTES => 'CameraInfo tags for the 1DmkIV.',
     2738    0x03 => { %ciFNumber },
     2739    0x04 => { %ciExposureTime },
     2740    0x06 => { %ciISO },
     2741    0x07 => {
     2742        Name => 'HighlightTonePriority',
     2743        PrintConv => { 0 => 'Off', 1 => 'On' },
     2744    },
     2745    0x08 => {
     2746        Name => 'MeasuredEV2',
     2747        Description => 'Measured EV 2',
     2748        RawConv => '$val ? $val : undef',
     2749        ValueConv => '$val / 8 - 6',
     2750        ValueConvInv => 'int(($val + 6) * 8 + 0.5)',
     2751    },
     2752    0x09 => {
     2753        Name => 'MeasuredEV3',
     2754        Description => 'Measured EV 3',
     2755        RawConv => '$val ? $val : undef',
     2756        ValueConv => '$val / 8 - 6',
     2757        ValueConvInv => 'int(($val + 6) * 8 + 0.5)',
     2758    },
     2759    0x15 => {
     2760        Name => 'FlashMeteringMode',
     2761        PrintConv => {
     2762            0 => 'E-TTL',
     2763            3 => 'TTL',
     2764            4 => 'External Auto',
     2765            5 => 'External Manual',
     2766            6 => 'Off',
     2767        },
     2768    },
     2769    0x19 => { %ciCameraTemperature },
     2770    0x1e => { %ciFocalLength },
     2771    0x35 => {
     2772        Name => 'CameraOrientation',
     2773        PrintConv => {
     2774            0 => 'Horizontal (normal)',
     2775            1 => 'Rotate 90 CW',
     2776            2 => 'Rotate 270 CW',
     2777        },
     2778    },
     2779    0x54 => {
     2780        Name => 'FocusDistanceUpper',
     2781        %focusDistanceByteSwap,
     2782    },
     2783    0x56 => {
     2784        Name => 'FocusDistanceLower',
     2785        %focusDistanceByteSwap,
     2786    },
     2787    0x57 => {
     2788        Name => 'FirmwareVersionLookAhead',
     2789        Hidden => 1,
     2790        # must look ahead to check location of FirmwareVersion string
     2791        Format => 'undef[0x1a6]',
     2792        RawConv => q{
     2793            my $t = substr($val, 0x1e8 - 0x57, 6);
     2794            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirmA} = 1;
     2795            $t = substr($val, 0x1ed - 0x57, 6);
     2796            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirmB} = 1;
     2797            return undef;   # not a real tag
     2798        },
     2799    },
     2800    0x77 => {
     2801        Name => 'WhiteBalance',
     2802        Condition => '$$self{CanonFirmA}',
     2803        Notes => 'firmware 4.2.1',
     2804        Format => 'int16u',
     2805        SeparateTable => 1,
     2806        PrintConv => \%canonWhiteBalance,
     2807    },
     2808    0x78 => {
     2809        Name => 'WhiteBalance',
     2810        Condition => '$$self{CanonFirmB}',
     2811        Notes => 'firmware 1.0.4',
     2812        Format => 'int16u',
     2813        SeparateTable => 1,
     2814        PrintConv => \%canonWhiteBalance,
     2815    },
     2816    0x7b => {
     2817        Name => 'ColorTemperature',
     2818        Condition => '$$self{CanonFirmA}',
     2819        Format => 'int16u',
     2820    },
     2821    0x7c => {
     2822        Name => 'ColorTemperature',
     2823        Condition => '$$self{CanonFirmB}',
     2824        Format => 'int16u',
     2825    },
     2826    0x14e => {
     2827        Name => 'LensType',
     2828        Condition => '$$self{CanonFirmA}',
     2829        Format => 'int16uRev', # value is big-endian
     2830        SeparateTable => 1,
     2831        PrintConv => \%canonLensTypes,
     2832    },
     2833    0x14f => {
     2834        Name => 'LensType',
     2835        Condition => '$$self{CanonFirmB}',
     2836        Format => 'int16uRev', # value is big-endian
     2837        SeparateTable => 1,
     2838        PrintConv => \%canonLensTypes,
     2839    },
     2840    0x150 => {
     2841        %ciShortFocal,
     2842        Condition => '$$self{CanonFirmA}',
     2843    },
     2844    0x151 => {
     2845        %ciShortFocal,
     2846        Condition => '$$self{CanonFirmB}',
     2847    },
     2848    0x152 => {
     2849        %ciLongFocal,
     2850        Condition => '$$self{CanonFirmA}',
     2851    },
     2852    0x153 => {
     2853        %ciLongFocal,
     2854        Condition => '$$self{CanonFirmB}',
     2855    },
     2856    0x1e8 => { # firmware 4.2.1 (pre-production)
     2857        Name => 'FirmwareVersion',
     2858        Condition => '$$self{CanonFirmA}',
     2859        Format => 'string[6]',
     2860        Writable => 0,
     2861    },
     2862    0x1ed => { # firmware 1.0.4
     2863        Name => 'FirmwareVersion',
     2864        Condition => '$$self{CanonFirmB}',
     2865        Format => 'string[6]',
     2866        Writable => 0,
     2867    },
     2868    0x227 => { #(NC)
     2869        Name => 'FileIndex',
     2870        Condition => '$$self{CanonFirmA}',
     2871        Groups => { 2 => 'Image' },
     2872        Format => 'int32u',
     2873        ValueConv => '$val + 1',
     2874        ValueConvInv => '$val - 1',
     2875    },
     2876    0x22c => { #(NC)
     2877        Name => 'FileIndex',
     2878        Condition => '$$self{CanonFirmB}',
     2879        Groups => { 2 => 'Image' },
     2880        Format => 'int32u',
     2881        ValueConv => '$val + 1',
     2882        ValueConvInv => '$val - 1',
     2883    },
     2884    0x233 => { #(NC)
     2885        Name => 'DirectoryIndex',
     2886        Condition => '$$self{CanonFirmA}',
     2887        Groups => { 2 => 'Image' },
     2888        Format => 'int32u',
     2889        ValueConv => '$val - 1',
     2890        ValueConvInv => '$val + 1',
     2891    },
     2892    0x238 => { #(NC)
     2893        Name => 'DirectoryIndex',
     2894        Condition => '$$self{CanonFirmB}',
     2895        Groups => { 2 => 'Image' },
     2896        Format => 'int32u',
     2897        ValueConv => '$val - 1',
     2898        ValueConvInv => '$val + 1',
     2899    },
     2900    0x363 => {
     2901        Name => 'PictureStyleInfo',
     2902        Condition => '$$self{CanonFirmA}',
     2903        SubDirectory => {
     2904            TagTable => 'Image::ExifTool::Canon::PSInfo',
     2905        },
     2906    },
     2907    0x368 => {
     2908        Name => 'PictureStyleInfo',
     2909        Condition => '$$self{CanonFirmB}',
     2910        SubDirectory => {
     2911            TagTable => 'Image::ExifTool::Canon::PSInfo',
     2912        },
     2913    },
     2914);
     2915
     2916# Camera information for 5D (MakerNotes tag 0x0d)
     2917# (ref 12 unless otherwise noted)
     2918%Image::ExifTool::Canon::CameraInfo5D = (
     2919    %binaryDataAttrs,
     2920    FORMAT => 'int8s',
     2921    FIRST_ENTRY => 0,
     2922    PRIORITY => 0,
     2923    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2924    NOTES => 'CameraInfo tags for the EOS 5D.',
     2925    0x03 => { %ciFNumber }, #PH
     2926    0x04 => { %ciExposureTime }, #9
     2927    0x06 => { %ciISO }, #PH
     2928    0x0c => { #9
     2929        Name => 'LensType',
     2930        Format => 'int16uRev', # value is big-endian
     2931        SeparateTable => 1,
     2932        RawConv => '$val ? $val : undef', # don't use if value is zero
     2933        PrintConv => \%canonLensTypes,
     2934    },
     2935    0x17 => { %ciCameraTemperature }, #PH
     2936    0x1b => { %ciMacroMagnification }, #PH
     2937    0x27 => { #PH
     2938        Name => 'CameraOrientation',
     2939        PrintConv => {
     2940            0 => 'Horizontal (normal)',
     2941            1 => 'Rotate 90 CW',
     2942            2 => 'Rotate 270 CW',
     2943        },
     2944    },
     2945    0x28 => { %ciFocalLength }, #15
    15842946    0x38 => {
    15852947        Name => 'AFPointsInFocus5D',
    1586         Format => 'undef[2]',
    1587         Condition => '$$self{CameraModel} =~ /EOS 5D/',
    1588         Notes => 'EOS 5D, bit definitions are for big-endian int16u',
    1589         ValueConv => 'unpack("n",$val)',
    1590         ValueConvInv => 'pack("n",$val)',
     2948        Format => 'int16uRev',
     2949        PrintConvColumns => 2,
    15912950        PrintConv => { BITMASK => {
    15922951            0 => 'Center',
     
    16072966        } },
    16082967    },
     2968    0x54 => { #15
     2969        Name => 'WhiteBalance',
     2970        Format => 'int16u',
     2971        SeparateTable => 1,
     2972        PrintConv => \%canonWhiteBalance,
     2973    },
     2974    0x58 => { #15
     2975        Name => 'ColorTemperature',
     2976        Format => 'int16u',
     2977    },
    16092978    0x6c => {
    16102979        Name => 'PictureStyle',
    1611         Format => 'int16u',
    1612         Condition => '$$self{CameraModel} =~ /EOS(-1Ds? Mark II| 5D)$/',
    1613         Notes => '1DmkII, 1DSmkII and 5D only',
    1614         PrintHex => 1,
     2980        Format => 'int8u',
     2981        Flags => ['PrintHex','SeparateTable'],
    16152982        PrintConv => \%pictureStyles,
    16162983    },
    1617     0xa4 => { #PH (5D)
     2984    0x93 => { %ciShortFocal }, #15
     2985    0x95 => { %ciLongFocal }, #15
     2986    0x97 => { #15
     2987        Name => 'LensType',
     2988        Format => 'int16uRev', # value is big-endian
     2989        SeparateTable => 1,
     2990        PrintConv => \%canonLensTypes,
     2991    },
     2992    0xa4 => { #PH
    16182993        Name => 'FirmwareRevision',
    1619         Condition => '$$self{CameraModel} =~ /EOS 5D/',
    1620         Notes => '5D only',
    16212994        Format => 'string[8]',
    16222995    },
    1623     0xac => { #PH (5D)
     2996    0xac => { #PH
    16242997        Name => 'ShortOwnerName',
    16252998        Format => 'string[16]',
    1626         Condition => '$$self{CameraModel} =~ /EOS 5D/',
    1627         Notes => '5D only',
    16282999    },
    16293000    0xd0 => {
    16303001        Name => 'ImageNumber',
     3002        Format => 'int16u',
    16313003        Groups => { 2 => 'Image' },
    1632         Format => 'int16u',
    1633         Condition => '$$self{CameraModel} =~ /EOS 5D/',
    1634         Notes => '5D only',
    16353004        ValueConv => '$val + 1',
    16363005        ValueConvInv => '$val - 1',
    16373006    },
    1638     0xe8 => {
    1639         Name => 'ContrastStandard',
    1640         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    1641         PrintConvInv => '$val=~/normal/i ? 0 : $val',
    1642     },
    1643     0xe9 => {
    1644         Name => 'ContrastPortrait',
    1645         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    1646         PrintConvInv => '$val=~/normal/i ? 0 : $val',
    1647     },
    1648     0xea => {
    1649         Name => 'ContrastLandscape',
    1650         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    1651         PrintConvInv => '$val=~/normal/i ? 0 : $val',
    1652     },
    1653     0xeb => {
    1654         Name => 'ContrastNeutral',
    1655         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    1656         PrintConvInv => '$val=~/normal/i ? 0 : $val',
    1657     },
    1658     0xec => {
    1659         Name => 'ContrastFaithful',
    1660         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    1661         PrintConvInv => '$val=~/normal/i ? 0 : $val',
    1662     },
    1663     0xed => {
    1664         Name => 'ContrastMonochrome',
    1665         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    1666         PrintConvInv => '$val=~/normal/i ? 0 : $val',
    1667     },
    1668     0xee => {
    1669         Name => 'ContrastUserDef1',
    1670         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    1671         PrintConvInv => '$val=~/normal/i ? 0 : $val',
    1672     },
    1673     0xef => {
    1674         Name => 'ContrastUserDef2',
    1675         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    1676         PrintConvInv => '$val=~/normal/i ? 0 : $val',
    1677     },
    1678     0xf0 => {
    1679         Name => 'ContrastUserDef3',
    1680         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    1681         PrintConvInv => '$val=~/normal/i ? 0 : $val',
    1682     },
     3007    0xe8 => 'ContrastStandard',
     3008    0xe9 => 'ContrastPortrait',
     3009    0xea => 'ContrastLandscape',
     3010    0xeb => 'ContrastNeutral',
     3011    0xec => 'ContrastFaithful',
     3012    0xed => 'ContrastMonochrome',
     3013    0xee => 'ContrastUserDef1',
     3014    0xef => 'ContrastUserDef2',
     3015    0xf0 => 'ContrastUserDef3',
    16833016    # sharpness values are 0-7
    16843017    0xf1 => 'SharpnessStandard',
     
    17043037            3 => 'Red',
    17053038            4 => 'Green',
     3039            -559038737 => 'n/a', # (0xdeadbeef)
    17063040        },
    17073041    },
     
    17223056            3 => 'Purple',
    17233057            4 => 'Green',
     3058            -559038737 => 'n/a', # (0xdeadbeef)
    17243059        },
    17253060    },
     
    17303065        Name => 'UserDef1PictureStyle',
    17313066        Format => 'int16u',
    1732         PrintHex => 1,
     3067        PrintHex => 1, # (only needed for one tag)
     3068        SeparateTable => 'UserDefStyle',
    17333069        PrintConv => \%userDefStyles,
    17343070    },
     
    17363072        Name => 'UserDef2PictureStyle',
    17373073        Format => 'int16u',
    1738         PrintHex => 1,
     3074        SeparateTable => 'UserDefStyle',
    17393075        PrintConv => \%userDefStyles,
    17403076    },
     
    17423078        Name => 'UserDef3PictureStyle',
    17433079        Format => 'int16u',
    1744         PrintHex => 1,
     3080        SeparateTable => 'UserDefStyle',
    17453081        PrintConv => \%userDefStyles,
    17463082    },
     
    17543090        ValueConvInv => 'GetUnixTime($val)',
    17553091        PrintConv => '$self->ConvertDateTime($val)',
    1756         PrintConvInv => '$val',
    1757     },
    1758 );
    1759 
    1760 # Canon camera information for 1DmkIII (MakerNotes tag 0x0d) - PH
    1761 %Image::ExifTool::Canon::CameraInfo1DmkIII = (
    1762     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1763     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1764     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    1765     WRITABLE => 1,
    1766     FORMAT => 'int8s',
     3092        PrintConvInv => '$self->InverseDateTime($val)',
     3093    },
     3094);
     3095
     3096# Camera information for 5D Mark II (MakerNotes tag 0x0d)
     3097# (ref PH unless otherwise noted)
     3098%Image::ExifTool::Canon::CameraInfo5DmkII = (
     3099    %binaryDataAttrs,
     3100    FORMAT => 'int8u',
    17673101    FIRST_ENTRY => 0,
     3102    PRIORITY => 0,
     3103    IS_SUBDIR => [ 0x15a, 0x17e ],
    17683104    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    1769     NOTES => 'CameraInfo tags valid for the EOS 1D Mark III.',
    1770     0x03 => {
    1771         Name => 'FNumber',
    1772         Groups => { 2 => 'Image' },
    1773         Format => 'int8u',
    1774         Priority => 0,
    1775         RawConv => '$val ? $val : undef',
    1776         ValueConv => 'exp(($val-8)/16*log(2))',
    1777         ValueConvInv => 'log($val)*16/log(2)+8',
    1778         PrintConv => 'sprintf("%.2g",$val)',
    1779         PrintConvInv => '$val',
    1780     },
    1781     0x04 => { #9
    1782         Name => 'ExposureTime',
    1783         Groups => { 2 => 'Image' },
    1784         Format => 'int8u',
    1785         Priority => 0,
    1786         RawConv => '$val ? $val : undef',
    1787         ValueConv => 'exp(4*log(2)*(1-Image::ExifTool::Canon::CanonEv($val-24)))',
    1788         ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(1-log($val)/(4*log(2)))+24',
    1789         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    1790         PrintConvInv => 'eval $val',
    1791     },
    1792     0x06 => {
    1793         Name => 'ISO',
    1794         Groups => { 2 => 'Image' },
    1795         Format => 'int8u',
    1796         Priority => 0,
    1797         ValueConv => '100*exp(($val/8-9)*log(2))',
    1798         ValueConvInv => '(log($val/100)/log(2)+9)*8',
    1799         PrintConv => 'sprintf("%.0f",$val)',
    1800         PrintConvInv => '$val',
    1801     },
    1802     0x1d => {
    1803         Name => 'FocalLength',
     3105    NOTES => 'CameraInfo tags for the EOS 5D Mark II.',
     3106    0x03 => { %ciFNumber },
     3107    0x04 => { %ciExposureTime },
     3108    0x06 => { %ciISO },
     3109    0x07 => {
     3110        Name => 'HighlightTonePriority',
     3111        PrintConv => { 0 => 'Off', 1 => 'On' },
     3112    },
     3113    0x1b => { %ciMacroMagnification }, #PH
     3114    0x15 => { #PH (580 EX II)
     3115        Name => 'FlashMeteringMode',
     3116        PrintConv => {
     3117            0 => 'E-TTL',
     3118            3 => 'TTL',
     3119            4 => 'External Auto',
     3120            5 => 'External Manual',
     3121            6 => 'Off',
     3122        },
     3123    },
     3124    0x19 => { %ciCameraTemperature }, #36
     3125    # 0x1b, 0x1c, 0x1d - same as FileInfo 0x10 - PH
     3126    0x1e => { %ciFocalLength },
     3127    0x31 => {
     3128        Name => 'CameraOrientation',
     3129        PrintConv => {
     3130            0 => 'Horizontal (normal)',
     3131            1 => 'Rotate 90 CW',
     3132            2 => 'Rotate 270 CW',
     3133        },
     3134    },
     3135    0x50 => {
     3136        Name => 'FocusDistanceUpper',
     3137        %focusDistanceByteSwap,
     3138    },
     3139    0x52 => {
     3140        Name => 'FocusDistanceLower',
     3141        %focusDistanceByteSwap,
     3142    },
     3143    0x6f => {
     3144        Name => 'WhiteBalance',
    18043145        Format => 'int16u',
    1805         # the EXIF FocalLength is more reliable, so set this priority to zero
    1806         # (just to make things confusing, the focal lengths are big-endian,
    1807         #  while other values are stored little-endian)
    1808         Priority => 0,
    1809         # ignore if zero and change to big-endian
    1810         RawConv => '$val ? unpack("n",pack("v",$val)) : undef',
    1811         PrintConv => '"${val}mm"',
    1812         PrintConvInv => '$val=~s/mm//;$val',
    1813     },
    1814     0x86 => {
     3146        SeparateTable => 1,
     3147        PrintConv => \%canonWhiteBalance,
     3148    },
     3149    0x73 => {
     3150        Name => 'ColorTemperature',
     3151        Format => 'int16u',
     3152    },
     3153    0xa7 => {
    18153154        Name => 'PictureStyle',
    18163155        Format => 'int8u',
    1817         PrintHex => 1,
     3156        Flags => ['PrintHex','SeparateTable'],
    18183157        PrintConv => \%pictureStyles,
    18193158    },
    1820     0x113 => {
    1821         Name => 'ShortFocal',
    1822         Format => 'int16u',
    1823         # the EXIF ShortFocal is more reliable, so set this priority to zero
    1824         Priority => 0,
    1825         # byte order is big-endian
    1826         ValueConv => 'unpack("n",pack("v",$val))',
    1827         ValueConvInv => 'unpack("v",pack("n",$val))',
    1828         PrintConv => '"${val}mm"',
    1829         PrintConvInv => '$val=~s/mm//;$val',
    1830     },
    1831     0x115 => {
    1832         Name => 'LongFocal',
    1833         Format => 'int16u',
    1834         # the EXIF LongFocal is more reliable, so set this priority to zero
    1835         Priority => 0,
    1836         # byte order is big-endian
    1837         ValueConv => 'unpack("n",pack("v",$val))',
    1838         ValueConvInv => 'unpack("v",pack("n",$val))',
    1839         PrintConv => '"${val}mm"',
    1840         PrintConvInv => '$val=~s/mm//;$val',
    1841     },
    1842     0x172 => {
    1843         Name => 'FileNumber',
     3159    0xbd => {
     3160        Name => 'HighISONoiseReduction',
     3161        PrintConv => {
     3162            0 => 'Standard',
     3163            1 => 'Low',
     3164            2 => 'Strong',
     3165            3 => 'Off',
     3166        },
     3167    },
     3168    0xbf => {
     3169        Name => 'AutoLightingOptimizer',
     3170        PrintConv => {
     3171            0 => 'Standard',
     3172            1 => 'Low',
     3173            2 => 'Strong',
     3174            3 => 'Off',
     3175        },
     3176    },
     3177    0xe6 => {
     3178        Name => 'LensType',
     3179        Format => 'int16uRev', # value is big-endian
     3180        SeparateTable => 1,
     3181        PrintConv => \%canonLensTypes,
     3182    },
     3183    0xe8 => { %ciShortFocal },
     3184    0xea => { %ciLongFocal },
     3185    0x15a => {
     3186        Name => 'CameraInfo5DmkII_2a',
     3187        Condition => '$$valPt =~ /^\d+\.\d+\.\d+[\s\0]/',
     3188        Notes => 'at this location for firmware 3.4.6 and 3.6.1',
     3189        SubDirectory => {
     3190            TagTable => 'Image::ExifTool::Canon::CameraInfo5DmkII_2',
     3191        },
     3192    },
     3193    0x17e => {
     3194        Name => 'CameraInfo5DmkII_2b',
     3195        Condition => '$$valPt =~ /^\d+\.\d+\.\d+[\s\0]/',
     3196        Notes => 'at this location for firmware 1.0.6 and 4.1.1',
     3197        SubDirectory => {
     3198            TagTable => 'Image::ExifTool::Canon::CameraInfo5DmkII_2',
     3199        },
     3200    },
     3201);
     3202
     3203# variable-position Camera information for 5DmkII (ref PH)
     3204%Image::ExifTool::Canon::CameraInfo5DmkII_2 = (
     3205    %binaryDataAttrs,
     3206    FIRST_ENTRY => 0,
     3207    PRIORITY => 0,
     3208    IS_SUBDIR => [ 0x179 ],
     3209    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3210    NOTES => 'More CameraInfo tags for the EOS 5D Mark II.',
     3211    0 => {
     3212        Name => 'FirmwareVersion',
     3213        Format => 'string[6]',
     3214        Writable => 0, # not writable for logic reasons
     3215        # some firmwares have a null instead of a space after the version number
     3216        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
     3217    },
     3218    0x3d => {
     3219        Name => 'FileIndex',
    18443220        Groups => { 2 => 'Image' },
    18453221        Format => 'int32u',
     
    18473223        ValueConvInv => '$val - 1',
    18483224    },
    1849     0x176 => {
    1850         Name => 'ShutterCount',
    1851         Notes => 'may be valid only for some 1DmkIII copies, even running the same firmware',
     3225    0x49 => { #(NC)
     3226        Name => 'DirectoryIndex',
     3227        Groups => { 2 => 'Image' },
     3228        Format => 'int32u',
     3229        ValueConv => '$val - 1',
     3230        ValueConvInv => '$val + 1',
     3231    },
     3232    0x179 => { #48
     3233        Name => 'PictureStyleInfo',
     3234        SubDirectory => {
     3235            TagTable => 'Image::ExifTool::Canon::PSInfo',
     3236        },
     3237    },
     3238);
     3239
     3240# Camera information for 7D (MakerNotes tag 0x0d) (ref PH)
     3241%Image::ExifTool::Canon::CameraInfo7D = (
     3242    %binaryDataAttrs,
     3243    FORMAT => 'int8u',
     3244    FIRST_ENTRY => 0,
     3245    PRIORITY => 0,
     3246    IS_SUBDIR => [ 0x20, 0x24 ],
     3247    DATAMEMBER => [ 0x1f ],
     3248    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3249    NOTES => 'CameraInfo tags for the EOS 7D.',
     3250    0x03 => { %ciFNumber },
     3251    0x04 => { %ciExposureTime },
     3252    0x06 => { %ciISO },
     3253    0x07 => {
     3254        Name => 'HighlightTonePriority',
     3255        PrintConv => { 0 => 'Off', 1 => 'On' },
     3256    },
     3257    0x08 => { #37
     3258        Name => 'MeasuredEV2',
     3259        Description => 'Measured EV 2',
     3260        RawConv => '$val ? $val : undef',
     3261        ValueConv => '$val / 8 - 6',
     3262        ValueConvInv => 'int(($val + 6) * 8 + 0.5)',
     3263    },
     3264    0x09 => { #37
     3265        Name => 'MeasuredEV',
     3266        Description => 'Measured EV',
     3267        RawConv => '$val ? $val : undef',
     3268        ValueConv => '$val / 8 - 6',
     3269        ValueConvInv => 'int(($val + 6) * 8 + 0.5)',
     3270    },
     3271    0x15 => { #PH (580 EX II)
     3272        Name => 'FlashMeteringMode',
     3273        PrintConv => {
     3274            0 => 'E-TTL',
     3275            3 => 'TTL',
     3276            4 => 'External Auto',
     3277            5 => 'External Manual',
     3278            6 => 'Off',
     3279        },
     3280    },
     3281    0x19 => { %ciCameraTemperature },
     3282    0x1e => { %ciFocalLength },
     3283    0x1f => {
     3284        Name => 'FirmwareVersionLookAhead',
     3285        Hidden => 1,
     3286        # must look ahead to check location of FirmwareVersion string
     3287        Format => 'undef[0x1a0]',
     3288        RawConv => q{
     3289            my $t = substr($val, 0x1a8 - 0x1f, 6);
     3290            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirmA} = 1;
     3291            $t = substr($val, 0x1ac - 0x1f, 6);
     3292            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirmB} = 1;
     3293            return undef;   # not a real tag
     3294        },
     3295    },
     3296    0x20 => {
     3297        Name => 'CameraInfo7D_2a',
     3298        Condition => '$$self{CanonFirmA}',
     3299        Notes => 'at this location for pre-production firmware version 3.7.5',
     3300        SubDirectory => {
     3301            TagTable => 'Image::ExifTool::Canon::CameraInfo7D_2',
     3302        },
     3303    },
     3304    0x24 => {
     3305        Name => 'CameraInfo7D_2b',
     3306        Condition => '$$self{CanonFirmB}',
     3307        Notes => 'at this location for firmware 1.0.7, 1.0.8, 1.1.0, 1.2.1 and 1.2.2',
     3308        SubDirectory => {
     3309            TagTable => 'Image::ExifTool::Canon::CameraInfo7D_2',
     3310        },
     3311    },
     3312);
     3313
     3314# variable-position Camera information for 7D (ref PH)
     3315%Image::ExifTool::Canon::CameraInfo7D_2 = (
     3316    %binaryDataAttrs,
     3317    FORMAT => 'int8u',
     3318    FIRST_ENTRY => 0,
     3319    PRIORITY => 0,
     3320    IS_SUBDIR => [ 0x303 ],
     3321    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3322    NOTES => 'More CameraInfo tags for the EOS 7D.',
     3323    0x11 => {
     3324        Name => 'CameraOrientation',
     3325        PrintConv => {
     3326            0 => 'Horizontal (normal)',
     3327            1 => 'Rotate 90 CW',
     3328            2 => 'Rotate 270 CW',
     3329        },
     3330    },
     3331    0x30 => {
     3332        Name => 'FocusDistanceUpper',
     3333        %focusDistanceByteSwap,
     3334    },
     3335    0x32 => {
     3336        Name => 'FocusDistanceLower',
     3337        %focusDistanceByteSwap,
     3338    },
     3339    0x53 => {
     3340        Name => 'WhiteBalance',
     3341        Format => 'int16u',
     3342        SeparateTable => 1,
     3343        PrintConv => \%canonWhiteBalance,
     3344    },
     3345    0x57 => {
     3346        Name => 'ColorTemperature',
     3347        Format => 'int16u',
     3348    },
     3349    0xa5 => {
     3350        Name => 'HighISONoiseReduction',
     3351        PrintConv => {
     3352            0 => 'Standard',
     3353            1 => 'Low',
     3354            2 => 'Strong',
     3355            3 => 'Off',
     3356        },
     3357    },
     3358    0xee => {
     3359        Name => 'LensType',
     3360        Format => 'int16uRev', # value is big-endian
     3361        SeparateTable => 1,
     3362        PrintConv => \%canonLensTypes,
     3363    },
     3364    0xf0 => { %ciShortFocal },
     3365    0xf2 => { %ciLongFocal },
     3366    0x188 => {
     3367        Name => 'FirmwareVersion',
     3368        Format => 'string[6]',
     3369        Writable => 0, # not writable for logic reasons
     3370        # some firmwares have a null instead of a space after the version number
     3371        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
     3372    },
     3373    0x1c7 => {
     3374        Name => 'FileIndex',
     3375        Groups => { 2 => 'Image' },
    18523376        Format => 'int32u',
    18533377        ValueConv => '$val + 1',
    18543378        ValueConvInv => '$val - 1',
    18553379    },
    1856     0x45e => {
    1857         Name => 'TimeStamp',
     3380    0x1d3 => { #(NC)
     3381        Name => 'DirectoryIndex',
     3382        Groups => { 2 => 'Image' },
    18583383        Format => 'int32u',
    1859         Groups => { 2 => 'Time' },
    1860         Shift => 'Time',
    1861         RawConv => '$val ? $val : undef',
    1862         ValueConv => 'ConvertUnixTime($val)',
    1863         ValueConvInv => 'GetUnixTime($val)',
    1864         PrintConv => '$self->ConvertDateTime($val)',
    1865         PrintConvInv => '$val',
    1866     },
    1867 );
    1868 
    1869 # type 2 Canon camera information (MakerNotes tag 0x0d) - PH
    1870 %Image::ExifTool::Canon::CameraInfo2 = (
    1871     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1872     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1873     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    1874     WRITABLE => 1,
     3384        ValueConv => '$val - 1',
     3385        ValueConvInv => '$val + 1',
     3386    },
     3387    0x303 => { #48
     3388        Name => 'PictureStyleInfo',
     3389        SubDirectory => {
     3390            TagTable => 'Image::ExifTool::Canon::PSInfo',
     3391        },
     3392    },
     3393);
     3394
     3395# Canon camera information for 40D (MakerNotes tag 0x0d) (ref PH)
     3396%Image::ExifTool::Canon::CameraInfo40D = (
     3397    %binaryDataAttrs,
     3398    FORMAT => 'int8u',
     3399    FIRST_ENTRY => 0,
     3400    PRIORITY => 0,
     3401    IS_SUBDIR => [ 0x25b ],
     3402    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3403    NOTES => 'CameraInfo tags for the EOS 40D.',
     3404    0x03 => { %ciFNumber }, #PH
     3405    0x04 => { %ciExposureTime }, #PH
     3406    0x06 => { %ciISO }, #PH
     3407    0x15 => { #PH (580 EX II)
     3408        Name => 'FlashMeteringMode',
     3409        PrintConv => {
     3410            0 => 'E-TTL',
     3411            3 => 'TTL',
     3412            4 => 'External Auto',
     3413            5 => 'External Manual',
     3414            6 => 'Off',
     3415        },
     3416    },
     3417    0x18 => { %ciCameraTemperature }, #36
     3418    0x1b => { %ciMacroMagnification }, #PH
     3419    0x1d => { %ciFocalLength }, #PH
     3420    0x30 => { #20
     3421        Name => 'CameraOrientation',
     3422        PrintConv => {
     3423            0 => 'Horizontal (normal)',
     3424            1 => 'Rotate 90 CW',
     3425            2 => 'Rotate 270 CW',
     3426        },
     3427    },
     3428    0x43 => { #21/24
     3429        Name => 'FocusDistanceUpper',
     3430        # this is very odd (little-endian number on odd boundary),
     3431        # but it does seem to work better with my sample images - PH
     3432        %focusDistanceByteSwap,
     3433    },
     3434    0x45 => { #21/24
     3435        Name => 'FocusDistanceLower',
     3436        %focusDistanceByteSwap,
     3437    },
     3438    0x6f => { #15
     3439        Name => 'WhiteBalance',
     3440        Format => 'int16u',
     3441        PrintConv => \%canonWhiteBalance,
     3442        SeparateTable => 1,
     3443    },
     3444    0x73 => { #15
     3445        Name => 'ColorTemperature',
     3446        Format => 'int16u',
     3447    },
     3448    0xd6 => { #15
     3449        Name => 'LensType',
     3450        Format => 'int16uRev', # value is big-endian
     3451        SeparateTable => 1,
     3452        PrintConv => \%canonLensTypes,
     3453    },
     3454    0xd8 => { %ciShortFocal }, #15
     3455    0xda => { %ciLongFocal }, #15
     3456    0xff => { #15
     3457        Name => 'FirmwareVersion',
     3458        Format => 'string[6]',
     3459    },
     3460    0x133 => { #27
     3461        Name => 'FileIndex',
     3462        Groups => { 2 => 'Image' },
     3463        Format => 'int32u',
     3464        Notes => 'combined with DirectoryIndex to give the Composite FileNumber tag',
     3465        ValueConv => '$val + 1',
     3466        ValueConvInv => '$val - 1',
     3467    },
     3468    0x13f => { #27
     3469        Name => 'DirectoryIndex',
     3470        Groups => { 2 => 'Image' },
     3471        Format => 'int32u',
     3472        ValueConv => '$val - 1', # yes, minus (opposite to FileIndex)
     3473        ValueConvInv => '$val + 1',
     3474    },
     3475    0x25b => {
     3476        Name => 'PictureStyleInfo',
     3477        SubDirectory => {
     3478            TagTable => 'Image::ExifTool::Canon::PSInfo',
     3479        },
     3480    },
     3481    0x92b => { #33
     3482        Name => 'LensModel',
     3483        Format => 'string[64]',
     3484    },
     3485);
     3486
     3487# Canon camera information for 50D (MakerNotes tag 0x0d)
     3488# (ref PH unless otherwise noted)
     3489%Image::ExifTool::Canon::CameraInfo50D = (
     3490    %binaryDataAttrs,
     3491    FORMAT => 'int8u',
     3492    FIRST_ENTRY => 0,
     3493    PRIORITY => 0,
     3494    DATAMEMBER => [ 0x15a, 0x15e ],
     3495    IS_SUBDIR => [ 0x2d3, 0x2d7 ],
     3496    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3497    NOTES => 'CameraInfo tags for the EOS 50D.',
     3498    0x03 => { %ciFNumber },
     3499    0x04 => { %ciExposureTime },
     3500    0x06 => { %ciISO },
     3501    0x07 => {
     3502        Name => 'HighlightTonePriority',
     3503        PrintConv => { 0 => 'Off', 1 => 'On' },
     3504    },
     3505    0x15 => { #PH (580 EX II)
     3506        Name => 'FlashMeteringMode',
     3507        PrintConv => {
     3508            0 => 'E-TTL',
     3509            3 => 'TTL',
     3510            4 => 'External Auto',
     3511            5 => 'External Manual',
     3512            6 => 'Off',
     3513        },
     3514    },
     3515    0x19 => { %ciCameraTemperature }, #36
     3516    0x1e => { %ciFocalLength },
     3517    0x31 => {
     3518        Name => 'CameraOrientation',
     3519        PrintConv => {
     3520            0 => 'Horizontal (normal)',
     3521            1 => 'Rotate 90 CW',
     3522            2 => 'Rotate 270 CW',
     3523        },
     3524    },
     3525    0x50 => { #33
     3526        Name => 'FocusDistanceUpper',
     3527        %focusDistanceByteSwap,
     3528    },
     3529    0x52 => { #33
     3530        Name => 'FocusDistanceLower',
     3531        %focusDistanceByteSwap,
     3532    },
     3533    0x6f => {
     3534        Name => 'WhiteBalance',
     3535        Format => 'int16u',
     3536        SeparateTable => 1,
     3537        PrintConv => \%canonWhiteBalance,
     3538    },
     3539    0x73 => { #33
     3540        Name => 'ColorTemperature',
     3541        Format => 'int16u',
     3542    },
     3543    0xa7 => {
     3544        Name => 'PictureStyle',
     3545        Format => 'int8u',
     3546        Flags => ['PrintHex','SeparateTable'],
     3547        PrintConv => \%pictureStyles,
     3548    },
     3549    0xbd => {
     3550        Name => 'HighISONoiseReduction',
     3551        PrintConv => {
     3552            0 => 'Standard',
     3553            1 => 'Low',
     3554            2 => 'Strong',
     3555            3 => 'Off',
     3556        },
     3557    },
     3558    0xbf => {
     3559        Name => 'AutoLightingOptimizer',
     3560        PrintConv => {
     3561            0 => 'Standard',
     3562            1 => 'Low',
     3563            2 => 'Strong',
     3564            3 => 'Off',
     3565        },
     3566    },
     3567    0xea => { #33
     3568        Name => 'LensType',
     3569        Format => 'int16uRev', # value is big-endian
     3570        SeparateTable => 1,
     3571        PrintConv => \%canonLensTypes,
     3572    },
     3573    0xec => { %ciShortFocal },
     3574    0xee => { %ciLongFocal },
     3575    0x15a => {
     3576        Name => 'FirmwareVersion',
     3577        Format => 'string[6]',
     3578        Notes => 'at this location for firmware 2.6.1',
     3579        Writable => 0,
     3580        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $$self{CanonFirmA}=$val : undef',
     3581    },
     3582    0x15e => { #33
     3583        Name => 'FirmwareVersion',
     3584        Format => 'string[6]',
     3585        Notes => 'at this location for firmware 1.0.2, 1.0.3, 2.9.1 and 3.1.1',
     3586        Writable => 0,
     3587        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $$self{CanonFirmB}=$val : undef',
     3588    },
     3589    0x197 => {
     3590        Name => 'FileIndex',
     3591        Condition => '$$self{CanonFirmA}',
     3592        Groups => { 2 => 'Image' },
     3593        Format => 'int32u',
     3594        ValueConv => '$val + 1',
     3595        ValueConvInv => '$val - 1',
     3596    },
     3597    0x19b => {
     3598        Name => 'FileIndex',
     3599        Condition => '$$self{CanonFirmB}',
     3600        Groups => { 2 => 'Image' },
     3601        Format => 'int32u',
     3602        ValueConv => '$val + 1',
     3603        ValueConvInv => '$val - 1',
     3604    },
     3605    0x1a3 => { #(NC)
     3606        Name => 'DirectoryIndex',
     3607        Condition => '$$self{CanonFirmA}',
     3608        Groups => { 2 => 'Image' },
     3609        Format => 'int32u',
     3610        ValueConv => '$val - 1',
     3611        ValueConvInv => '$val + 1',
     3612    },
     3613    0x1a7 => { #(NC)
     3614        Name => 'DirectoryIndex',
     3615        Condition => '$$self{CanonFirmB}',
     3616        Groups => { 2 => 'Image' },
     3617        Format => 'int32u',
     3618        ValueConv => '$val - 1',
     3619        ValueConvInv => '$val + 1',
     3620    },
     3621    0x2d3 => {
     3622        Name => 'PictureStyleInfo',
     3623        Condition => '$$self{CanonFirmA}',
     3624        SubDirectory => {
     3625            TagTable => 'Image::ExifTool::Canon::PSInfo',
     3626        },
     3627    },
     3628    0x2d7 => {
     3629        Name => 'PictureStyleInfo',
     3630        Condition => '$$self{CanonFirmB}',
     3631        SubDirectory => {
     3632            TagTable => 'Image::ExifTool::Canon::PSInfo',
     3633        },
     3634    },
     3635);
     3636
     3637# Canon camera information for 60D (MakerNotes tag 0x0d)
     3638# (ref PH unless otherwise noted)
     3639# NOTE: Can probably borrow more 50D tags here, possibly with an offset
     3640%Image::ExifTool::Canon::CameraInfo60D = (
     3641    %binaryDataAttrs,
     3642    FORMAT => 'int8u',
     3643    FIRST_ENTRY => 0,
     3644    PRIORITY => 0,
     3645  #  DATAMEMBER => [ 0x199 ],
     3646    IS_SUBDIR => [ 0x321 ],
     3647    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3648    NOTES => 'CameraInfo tags for the EOS 60D.',
     3649    0x03 => { %ciFNumber },
     3650    0x04 => { %ciExposureTime },
     3651    0x06 => { %ciISO },
     3652    0x19 => { %ciCameraTemperature },
     3653    0x1e => { %ciFocalLength },
     3654    0x36 => {
     3655        Name => 'CameraOrientation',
     3656        PrintConv => {
     3657            0 => 'Horizontal (normal)',
     3658            1 => 'Rotate 90 CW',
     3659            2 => 'Rotate 270 CW',
     3660        },
     3661    },
     3662    0x55 => {
     3663        Name => 'FocusDistanceUpper',
     3664        %focusDistanceByteSwap,
     3665    },
     3666    0x57 => {
     3667        Name => 'FocusDistanceLower',
     3668        %focusDistanceByteSwap,
     3669    },
     3670    0x7d => {
     3671        Name => 'ColorTemperature',
     3672        Format => 'int16u',
     3673    },
     3674    0xe8 => {
     3675        Name => 'LensType',
     3676        Format => 'int16uRev', # value is big-endian
     3677        SeparateTable => 1,
     3678        PrintConv => \%canonLensTypes,
     3679    },
     3680    0xea => { %ciShortFocal },
     3681    0xec => { %ciLongFocal },
     3682    0x199 => {
     3683        Name => 'FirmwareVersion',
     3684        Format => 'string[6]',
     3685  #      Notes => 'at this location for firmware 2.8.1 and 1.0.5',
     3686        Writable => 0,
     3687  #      RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $$self{CanonFirmA}=$val : undef',
     3688    },
     3689    0x1d9 => {
     3690        Name => 'FileIndex',
     3691        Groups => { 2 => 'Image' },
     3692        Format => 'int32u',
     3693        ValueConv => '$val + 1',
     3694        ValueConvInv => '$val - 1',
     3695    },
     3696    0x1e5 => { #(NC)
     3697        Name => 'DirectoryIndex',
     3698        Groups => { 2 => 'Image' },
     3699        Format => 'int32u',
     3700        ValueConv => '$val - 1',
     3701        ValueConvInv => '$val + 1',
     3702    },
     3703    0x321 => {
     3704        Name => 'PictureStyleInfo2',
     3705        SubDirectory => {
     3706            TagTable => 'Image::ExifTool::Canon::PSInfo2',
     3707        },
     3708    },
     3709);
     3710
     3711# Canon camera information for 450D (MakerNotes tag 0x0d) (ref PH)
     3712%Image::ExifTool::Canon::CameraInfo450D = (
     3713    %binaryDataAttrs,
     3714    FORMAT => 'int8u',
     3715    FIRST_ENTRY => 0,
     3716    PRIORITY => 0,
     3717    IS_SUBDIR => [ 0x263 ],
     3718    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3719    NOTES => 'CameraInfo tags for the EOS 450D.',
     3720    0x03 => { %ciFNumber }, #PH
     3721    0x04 => { %ciExposureTime }, #PH
     3722    0x06 => { %ciISO }, #PH
     3723    0x15 => { #PH (580 EX II)
     3724        Name => 'FlashMeteringMode',
     3725        PrintConv => {
     3726            0 => 'E-TTL',
     3727            3 => 'TTL',
     3728            4 => 'External Auto',
     3729            5 => 'External Manual',
     3730            6 => 'Off',
     3731        },
     3732    },
     3733    0x18 => { %ciCameraTemperature }, #36
     3734    0x1b => { %ciMacroMagnification }, #PH
     3735    0x1d => { %ciFocalLength }, #PH
     3736    0x30 => { #20
     3737        Name => 'CameraOrientation',
     3738        PrintConv => {
     3739            0 => 'Horizontal (normal)',
     3740            1 => 'Rotate 90 CW',
     3741            2 => 'Rotate 270 CW',
     3742        },
     3743    },
     3744    0x43 => { #20
     3745        Name => 'FocusDistanceUpper',
     3746        # this is very odd (little-endian number on odd boundary),
     3747        # but it does seem to work better with my sample images - PH
     3748        %focusDistanceByteSwap,
     3749    },
     3750    0x45 => { #20
     3751        Name => 'FocusDistanceLower',
     3752        %focusDistanceByteSwap,
     3753    },
     3754    0x6f => { #PH
     3755        Name => 'WhiteBalance',
     3756        Format => 'int16u',
     3757        PrintConv => \%canonWhiteBalance,
     3758        SeparateTable => 1,
     3759    },
     3760    0x73 => { #PH
     3761        Name => 'ColorTemperature',
     3762        Format => 'int16u',
     3763    },
     3764    0xde => { #33
     3765        Name => 'LensType',
     3766        Format => 'int16uRev', # value is big-endian
     3767        SeparateTable => 1,
     3768        PrintConv => \%canonLensTypes,
     3769    },
     3770    0x107 => { #PH
     3771        Name => 'FirmwareVersion',
     3772        Format => 'string[6]',
     3773    },
     3774    0x10f => { #20
     3775        Name => 'OwnerName',
     3776        Format => 'string[32]',
     3777    },
     3778    0x133 => { #20
     3779        Name => 'DirectoryIndex',
     3780        Groups => { 2 => 'Image' },
     3781        Format => 'int32u',
     3782    },
     3783    0x13f => { #20
     3784        Name => 'FileIndex',
     3785        Groups => { 2 => 'Image' },
     3786        Format => 'int32u',
     3787        ValueConv => '$val + 1',
     3788        ValueConvInv => '$val - 1',
     3789    },
     3790    0x263 => { #PH
     3791        Name => 'PictureStyleInfo',
     3792        SubDirectory => {
     3793            TagTable => 'Image::ExifTool::Canon::PSInfo',
     3794        },
     3795    },
     3796    0x933 => { #33
     3797        Name => 'LensModel',
     3798        Format => 'string[64]',
     3799    },
     3800);
     3801
     3802# Canon camera information for 500D (MakerNotes tag 0x0d) (ref PH)
     3803%Image::ExifTool::Canon::CameraInfo500D = (
     3804    %binaryDataAttrs,
     3805    FORMAT => 'int8u',
     3806    FIRST_ENTRY => 0,
     3807    PRIORITY => 0,
     3808    IS_SUBDIR => [ 0x30b ],
     3809    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3810    NOTES => 'CameraInfo tags for the EOS 500D.',
     3811    0x03 => { %ciFNumber },
     3812    0x04 => { %ciExposureTime },
     3813    0x06 => { %ciISO },
     3814    0x07 => {
     3815        Name => 'HighlightTonePriority',
     3816        PrintConv => { 0 => 'Off', 1 => 'On' },
     3817    },
     3818    0x15 => { #PH (580 EX II)
     3819        Name => 'FlashMeteringMode',
     3820        PrintConv => {
     3821            0 => 'E-TTL',
     3822            3 => 'TTL',
     3823            4 => 'External Auto',
     3824            5 => 'External Manual',
     3825            6 => 'Off',
     3826        },
     3827    },
     3828    0x19 => { %ciCameraTemperature },
     3829    0x1e => { %ciFocalLength },
     3830    0x31 => {
     3831        Name => 'CameraOrientation',
     3832        PrintConv => {
     3833            0 => 'Horizontal (normal)',
     3834            1 => 'Rotate 90 CW',
     3835            2 => 'Rotate 270 CW',
     3836        },
     3837    },
     3838    0x50 => {
     3839        Name => 'FocusDistanceUpper',
     3840        %focusDistanceByteSwap,
     3841    },
     3842    0x52 => {
     3843        Name => 'FocusDistanceLower',
     3844        %focusDistanceByteSwap,
     3845    },
     3846    0x73 => { # (50D + 4)
     3847        Name => 'WhiteBalance',
     3848        Format => 'int16u',
     3849        SeparateTable => 1,
     3850        PrintConv => \%canonWhiteBalance,
     3851    },
     3852    0x77 => { # (50D + 4)
     3853        Name => 'ColorTemperature',
     3854        Format => 'int16u',
     3855    },
     3856    0xab => { # (50D + 4)
     3857        Name => 'PictureStyle',
     3858        Format => 'int8u',
     3859        Flags => ['PrintHex','SeparateTable'],
     3860        PrintConv => \%pictureStyles,
     3861    },
     3862    0xbc => {
     3863        Name => 'HighISONoiseReduction',
     3864        PrintConv => {
     3865            0 => 'Standard',
     3866            1 => 'Low',
     3867            2 => 'Strong',
     3868            3 => 'Off',
     3869        },
     3870    },
     3871    0xbe => {
     3872        Name => 'AutoLightingOptimizer',
     3873        PrintConv => {
     3874            0 => 'Standard',
     3875            1 => 'Low',
     3876            2 => 'Strong',
     3877            3 => 'Off',
     3878        },
     3879    },
     3880    0xf6 => {
     3881        Name => 'LensType',
     3882        Format => 'int16uRev', # value is big-endian
     3883        SeparateTable => 1,
     3884        PrintConv => \%canonLensTypes,
     3885    },
     3886    0xf8 => { %ciShortFocal },
     3887    0xfa => { %ciLongFocal },
     3888    0x190 => {
     3889        Name => 'FirmwareVersion',
     3890        Format => 'string[6]',
     3891        Writable => 0,
     3892        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
     3893    },
     3894    0x1d3 => {
     3895        Name => 'FileIndex',
     3896        Groups => { 2 => 'Image' },
     3897        Format => 'int32u',
     3898        ValueConv => '$val + 1',
     3899        ValueConvInv => '$val - 1',
     3900    },
     3901    0x1df => { #(NC)
     3902        Name => 'DirectoryIndex',
     3903        Groups => { 2 => 'Image' },
     3904        Format => 'int32u',
     3905        ValueConv => '$val - 1',
     3906        ValueConvInv => '$val + 1',
     3907    },
     3908    0x30b => {
     3909        Name => 'PictureStyleInfo',
     3910        SubDirectory => {
     3911            TagTable => 'Image::ExifTool::Canon::PSInfo',
     3912        },
     3913    },
     3914);
     3915
     3916# Canon camera information for 550D (MakerNotes tag 0x0d) (ref PH)
     3917%Image::ExifTool::Canon::CameraInfo550D = (
     3918    %binaryDataAttrs,
     3919    FORMAT => 'int8u',
     3920    FIRST_ENTRY => 0,
     3921    PRIORITY => 0,
     3922    IS_SUBDIR => [ 0x31c ],
     3923    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3924    NOTES => 'CameraInfo tags for the EOS 550D.',
     3925    0x03 => { %ciFNumber },
     3926    0x04 => { %ciExposureTime },
     3927    0x06 => { %ciISO },
     3928    0x07 => { #(NC)
     3929        Name => 'HighlightTonePriority',
     3930        PrintConv => { 0 => 'Off', 1 => 'On' },
     3931    },
     3932    0x15 => { #(NC)
     3933        Name => 'FlashMeteringMode',
     3934        PrintConv => {
     3935            0 => 'E-TTL',
     3936            3 => 'TTL',
     3937            4 => 'External Auto',
     3938            5 => 'External Manual',
     3939            6 => 'Off',
     3940        },
     3941    },
     3942    0x19 => { %ciCameraTemperature }, # (500D + 0)
     3943    0x1e => { %ciFocalLength }, # (500D + 0)
     3944    0x35 => { # (500D + 4)
     3945        Name => 'CameraOrientation',
     3946        PrintConv => {
     3947            0 => 'Horizontal (normal)',
     3948            1 => 'Rotate 90 CW',
     3949            2 => 'Rotate 270 CW',
     3950        },
     3951    },
     3952    0x54 => { # (500D + 4)
     3953        Name => 'FocusDistanceUpper',
     3954        %focusDistanceByteSwap,
     3955    },
     3956    0x56 => { # (500D + 4)
     3957        Name => 'FocusDistanceLower',
     3958        %focusDistanceByteSwap,
     3959    },
     3960    0x78 => { # (500D + 5) (NC)
     3961        Name => 'WhiteBalance',
     3962        Format => 'int16u',
     3963        SeparateTable => 1,
     3964        PrintConv => \%canonWhiteBalance,
     3965    },
     3966    0x7c => { # (500D + 5)
     3967        Name => 'ColorTemperature',
     3968        Format => 'int16u',
     3969    },
     3970    0xb0 => { # (500D + 5)
     3971        Name => 'PictureStyle',
     3972        Format => 'int8u',
     3973        Flags => ['PrintHex','SeparateTable'],
     3974        PrintConv => \%pictureStyles,
     3975    },
     3976    0xff => { # (500D + 9)
     3977        Name => 'LensType',
     3978        Format => 'int16uRev', # value is big-endian
     3979        SeparateTable => 1,
     3980        PrintConv => \%canonLensTypes,
     3981    },
     3982    0x101 => { %ciShortFocal }, # (500D + 9)
     3983    0x103 => { %ciLongFocal }, # (500D + 9)
     3984    0x1a4 => { # (500D + 0x11)
     3985        Name => 'FirmwareVersion',
     3986        Format => 'string[6]',
     3987        Writable => 0,
     3988        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
     3989    },
     3990    0x1e4 => { # (500D + 0x11)
     3991        Name => 'FileIndex',
     3992        Groups => { 2 => 'Image' },
     3993        Format => 'int32u',
     3994        ValueConv => '$val + 1',
     3995        ValueConvInv => '$val - 1',
     3996    },
     3997    0x1f0 => { # (500D + 0x11) (NC)
     3998        Name => 'DirectoryIndex',
     3999        Groups => { 2 => 'Image' },
     4000        Format => 'int32u',
     4001        ValueConv => '$val - 1',
     4002        ValueConvInv => '$val + 1',
     4003    },
     4004    0x31c => { #48
     4005        Name => 'PictureStyleInfo',
     4006        SubDirectory => {
     4007            TagTable => 'Image::ExifTool::Canon::PSInfo',
     4008        },
     4009    },
     4010);
     4011
     4012# Canon camera information for 1000D (MakerNotes tag 0x0d) (ref PH)
     4013%Image::ExifTool::Canon::CameraInfo1000D = (
     4014    %binaryDataAttrs,
     4015    FORMAT => 'int8u',
     4016    FIRST_ENTRY => 0,
     4017    PRIORITY => 0,
     4018    IS_SUBDIR => [ 0x267 ],
     4019    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4020    NOTES => 'CameraInfo tags for the EOS 1000D.',
     4021    0x03 => { %ciFNumber }, #PH
     4022    0x04 => { %ciExposureTime }, #PH
     4023    0x06 => { %ciISO }, #PH
     4024    0x15 => { #PH (580 EX II)
     4025        Name => 'FlashMeteringMode',
     4026        PrintConv => {
     4027            0 => 'E-TTL',
     4028            3 => 'TTL',
     4029            4 => 'External Auto',
     4030            5 => 'External Manual',
     4031            6 => 'Off',
     4032        },
     4033    },
     4034    0x18 => { %ciCameraTemperature }, #36
     4035    0x1b => { %ciMacroMagnification }, #PH (NC)
     4036    0x1d => { %ciFocalLength }, #PH
     4037    0x30 => { #20
     4038        Name => 'CameraOrientation',
     4039        PrintConv => {
     4040            0 => 'Horizontal (normal)',
     4041            1 => 'Rotate 90 CW',
     4042            2 => 'Rotate 270 CW',
     4043        },
     4044    },
     4045    0x43 => { #20
     4046        Name => 'FocusDistanceUpper',
     4047        %focusDistanceByteSwap,
     4048    },
     4049    0x45 => { #20
     4050        Name => 'FocusDistanceLower',
     4051        %focusDistanceByteSwap,
     4052    },
     4053    0x6f => { #PH
     4054        Name => 'WhiteBalance',
     4055        Format => 'int16u',
     4056        PrintConv => \%canonWhiteBalance,
     4057        SeparateTable => 1,
     4058    },
     4059    0x73 => { #PH
     4060        Name => 'ColorTemperature',
     4061        Format => 'int16u',
     4062    },
     4063    0xe2 => { #PH
     4064        Name => 'LensType',
     4065        Format => 'int16uRev', # value is big-endian
     4066        SeparateTable => 1,
     4067        PrintConv => \%canonLensTypes,
     4068    },
     4069    0x10b => { #PH
     4070        Name => 'FirmwareVersion',
     4071        Format => 'string[6]',
     4072    },
     4073    0x137 => { #PH (NC)
     4074        Name => 'DirectoryIndex',
     4075        Groups => { 2 => 'Image' },
     4076        Format => 'int32u',
     4077    },
     4078    0x143 => { #PH
     4079        Name => 'FileIndex',
     4080        Groups => { 2 => 'Image' },
     4081        Format => 'int32u',
     4082        ValueConv => '$val + 1',
     4083        ValueConvInv => '$val - 1',
     4084    },
     4085    0x267 => { #PH
     4086        Name => 'PictureStyleInfo',
     4087        SubDirectory => {
     4088            TagTable => 'Image::ExifTool::Canon::PSInfo',
     4089        },
     4090    },
     4091    0x937 => { #PH
     4092        Name => 'LensModel',
     4093        Format => 'string[64]',
     4094    },
     4095);
     4096
     4097# Canon camera information for PowerShot models (MakerNotes tag 0x0d) - PH
     4098%Image::ExifTool::Canon::CameraInfoPowerShot = (
     4099    %binaryDataAttrs,
    18754100    FORMAT => 'int32s',
    18764101    FIRST_ENTRY => 0,
     4102    PRIORITY => 0,
    18774103    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    1878     NOTES => 'These tags used by a number of newer PowerShot models.',
     4104    NOTES => q{
     4105        CameraInfo tags for PowerShot models such as the A450, A460, A550, A560,
     4106        A570, A630, A640, A650, A710, A720, G7, G9, S5, SD40, SD750, SD800, SD850,
     4107        SD870, SD900, SD950, SD1000, SX100 and TX1.
     4108    },
    18794109    0x00 => {
    18804110        Name => 'ISO',
    18814111        Groups => { 2 => 'Image' },
    1882         Priority => 0,
    1883         ValueConv => '100*exp(($val/100-4)*log(2))',
    1884         ValueConvInv => '(log($val/100)/log(2)+4)*100',
     4112        ValueConv => '100*exp((($val-411)/96)*log(2))',
     4113        ValueConvInv => 'log($val/100)/log(2)*96+411',
    18854114        PrintConv => 'sprintf("%.0f",$val)',
    18864115        PrintConvInv => '$val',
     
    18894118        Name => 'FNumber',
    18904119        Groups => { 2 => 'Image' },
    1891         Priority => 0,
    1892         ValueConv => 'exp(($val+16)/200*log(2))',
    1893         ValueConvInv => 'log($val)*200/log(2)-16',
     4120        ValueConv => 'exp($val/192*log(2))',
     4121        ValueConvInv => 'log($val)*192/log(2)',
    18944122        PrintConv => 'sprintf("%.2g",$val)',
    18954123        PrintConvInv => '$val',
     
    18984126        Name => 'ExposureTime',
    18994127        Groups => { 2 => 'Image' },
    1900         Priority => 0,
    1901         RawConv => '$val ? $val : undef',
    1902         ValueConv => 'exp(-($val+24)/100*log(2))',
    1903         ValueConvInv => '-log($val)*100/log(2)-24',
     4128        ValueConv => 'exp(-$val/96*log(2))',
     4129        ValueConvInv => '-log($val)*96/log(2)',
    19044130        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    1905         PrintConvInv => 'eval $val',
     4131        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    19064132    },
    19074133    0x17 => 'Rotation', # usually the same as Orientation (but not always! why?)
     4134    # 0x25 - flash fired/not fired (ref 37)
     4135    # 0x26 - related to flash mode? (ref 37)
     4136    # 0x37 - related to flash strength (ref 37)
     4137    # 0x38 - pre-flash fired/no fired or flash data collection (ref 37)
     4138    135 => { # [-3] <-- index relative to CameraInfoCount
     4139        Name => 'CameraTemperature',
     4140        Condition => '$$self{CameraInfoCount} == 138',
     4141        Notes => 'A450, A460, A550, A630, A640 and A710',
     4142        PrintConv => '"$val C"',
     4143        PrintConvInv => '$val=~s/ ?C//; $val',
     4144    },
     4145    145 => { #37 [-3]
     4146        Name => 'CameraTemperature',
     4147        Condition => '$$self{CameraInfoCount} == 148',
     4148        Notes => q{
     4149            A560, A570, A650, A720, G7, G9, S5, SD40, SD750, SD800, SD850, SD870, SD900,
     4150            SD950, SD1000, SX100 and TX1
     4151        },
     4152        PrintConv => '"$val C"',
     4153        PrintConvInv => '$val=~s/ ?C//; $val',
     4154    },
     4155);
     4156
     4157# Canon camera information for some PowerShot models (MakerNotes tag 0x0d) - PH
     4158%Image::ExifTool::Canon::CameraInfoPowerShot2 = (
     4159    %binaryDataAttrs,
     4160    FORMAT => 'int32s',
     4161    FIRST_ENTRY => 0,
     4162    PRIORITY => 0,
     4163    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4164    NOTES => q{
     4165        CameraInfo tags for PowerShot models such as the A470, A480, A490, A495,
     4166        A580, A590, A1000, A1100, A2000, A2100, A3000, A3100, D10, E1, G10, G11,
     4167        S90, S95, SD770, SD780, SD790, SD880, SD890, SD940, SD960, SD970, SD980,
     4168        SD990, SD1100, SD1200, SD1300, SD1400, SD3500, SD4000, SD4500, SX1, SX10,
     4169        SX20, SX110, SX120, SX130, SX200 and SX210.
     4170    },
     4171    0x01 => {
     4172        Name => 'ISO',
     4173        Groups => { 2 => 'Image' },
     4174        ValueConv => '100*exp((($val-411)/96)*log(2))',
     4175        ValueConvInv => 'log($val/100)/log(2)*96+411',
     4176        PrintConv => 'sprintf("%.0f",$val)',
     4177        PrintConvInv => '$val',
     4178    },
     4179    0x06 => {
     4180        Name => 'FNumber',
     4181        Groups => { 2 => 'Image' },
     4182        ValueConv => 'exp($val/192*log(2))',
     4183        ValueConvInv => 'log($val)*192/log(2)',
     4184        PrintConv => 'sprintf("%.2g",$val)',
     4185        PrintConvInv => '$val',
     4186    },
     4187    0x07 => {
     4188        Name => 'ExposureTime',
     4189        Groups => { 2 => 'Image' },
     4190        ValueConv => 'exp(-$val/96*log(2))',
     4191        ValueConvInv => '-log($val)*96/log(2)',
     4192        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     4193        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     4194    },
     4195    0x18 => 'Rotation',
     4196    153 => { # [-3] <-- index relative to CameraInfoCount
     4197        Name => 'CameraTemperature',
     4198        Condition => '$$self{CameraInfoCount} == 156',
     4199        Notes => 'A470, A580, A590, SD770, SD790, SD890 and SD1100',
     4200        PrintConv => '"$val C"',
     4201        PrintConvInv => '$val=~s/ ?C//; $val',
     4202    },
     4203    159 => { # [-3]
     4204        Name => 'CameraTemperature',
     4205        Condition => '$$self{CameraInfoCount} == 162',
     4206        Notes => 'A1000, A2000, E1, G10, SD880, SD990, SX1, SX10 and SX110',
     4207        PrintConv => '"$val C"',
     4208        PrintConvInv => '$val=~s/ ?C//; $val',
     4209    },
     4210    164 => { # [-3]
     4211        Name => 'CameraTemperature',
     4212        Condition => '$$self{CameraInfoCount} == 167',
     4213        Notes => 'A480, A1100, A2100, D10, SD780, SD960, SD970, SD1200 and SX200',
     4214        PrintConv => '"$val C"',
     4215        PrintConvInv => '$val=~s/ ?C//; $val',
     4216    },
     4217    168 => { # [-3]
     4218        Name => 'CameraTemperature',
     4219        Condition => '$$self{CameraInfoCount} == 171',
     4220        Notes => q{
     4221            A490, A495, A3000, A3100, G11, S90, SD940, SD980, SD1300, SD1400, SD3500,
     4222            SD4000, SX20, SX120 and SX210
     4223        },
     4224        PrintConv => '"$val C"',
     4225        PrintConvInv => '$val=~s/ ?C//; $val',
     4226    },
     4227    261 => { # [-3]
     4228        Name => 'CameraTemperature',
     4229        Condition => '$$self{CameraInfoCount} == 264',
     4230        Notes => 'S95, SD4500 and SX130',
     4231        PrintConv => '"$val C"',
     4232        PrintConvInv => '$val=~s/ ?C//; $val',
     4233    },
    19084234);
    19094235
    19104236# unknown Canon camera information (MakerNotes tag 0x0d) - PH
    19114237%Image::ExifTool::Canon::CameraInfoUnknown32 = (
    1912     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1913     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1914     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    1915     WRITABLE => 1,
     4238    %binaryDataAttrs,
    19164239    FORMAT => 'int32s',
    19174240    FIRST_ENTRY => 0,
     4241    PRIORITY => 0,
    19184242    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    19194243    NOTES => 'Unknown CameraInfo tags are divided into 3 tables based on format size.',
     4244    71 => { # [-1] <-- index relative to CameraInfoCount
     4245        Name => 'CameraTemperature',
     4246        Condition => '$$self{CameraInfoCount} == 72',
     4247        Notes => 'S1',
     4248        PrintConv => '"$val C"',
     4249        PrintConvInv => '$val=~s/ ?C//; $val',
     4250    },
     4251    83 => { # [-2]
     4252        Name => 'CameraTemperature',
     4253        Condition => '$$self{CameraInfoCount} == 85',
     4254        Notes => 'S2',
     4255        PrintConv => '"$val C"',
     4256        PrintConvInv => '$val=~s/ ?C//; $val',
     4257    },
     4258    91 => { # [-2 or -3]
     4259        Name => 'CameraTemperature',
     4260        Condition => '$$self{CameraInfoCount} == 93 or $$self{CameraInfoCount} == 94',
     4261        Notes => 'A410, A610, A620, S80, SD30, SD400, SD430, SD450, SD500 and SD550',
     4262        PrintConv => '"$val C"',
     4263        PrintConvInv => '$val=~s/ ?C//; $val',
     4264    },
     4265    92 => { # [-4]
     4266        Name => 'CameraTemperature',
     4267        Condition => '$$self{CameraInfoCount} == 96',
     4268        Notes => 'S3',
     4269        PrintConv => '"$val C"',
     4270        PrintConvInv => '$val=~s/ ?C//; $val',
     4271    },
     4272    100 => { # [-4]
     4273        Name => 'CameraTemperature',
     4274        Condition => '$$self{CameraInfoCount} == 104',
     4275        Notes => 'A420, A430, A530, A540, A700, SD600, SD630 and SD700',
     4276        PrintConv => '"$val C"',
     4277        PrintConvInv => '$val=~s/ ?C//; $val',
     4278    },
     4279    466 => { # [-3]
     4280        Name => 'CameraTemperature',
     4281        Condition => '$$self{CameraInfoCount} == 469',
     4282        Notes => 'A1200, A2200, A3200, A3300, 100HS, 300HS and 500HS',
     4283        PrintConv => '"$val C"',
     4284        PrintConvInv => '$val=~s/ ?C//; $val',
     4285    },
     4286    503 => { # [-3]
     4287        Name => 'CameraTemperature',
     4288        Condition => '$$self{CameraInfoCount} == 506',
     4289        Notes => 'A800',
     4290        PrintConv => '"$val C"',
     4291        PrintConvInv => '$val=~s/ ?C//; $val',
     4292    },
     4293    506 => { # [-3]
     4294        Name => 'CameraTemperature',
     4295        Condition => '$$self{CameraInfoCount} == 509',
     4296        Notes => 'SX230HS',
     4297        PrintConv => '"$val C"',
     4298        PrintConvInv => '$val=~s/ ?C//; $val',
     4299    },
    19204300);
    19214301
    19224302# unknown Canon camera information (MakerNotes tag 0x0d) - PH
    19234303%Image::ExifTool::Canon::CameraInfoUnknown16 = (
    1924     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1925     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1926     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    1927     WRITABLE => 1,
     4304    %binaryDataAttrs,
    19284305    FORMAT => 'int16s',
    19294306    FIRST_ENTRY => 0,
     4307    PRIORITY => 0,
    19304308    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    19314309);
    19324310
    19334311# unknown Canon camera information (MakerNotes tag 0x0d) - PH
    1934 %Image::ExifTool::Canon::CameraInfoUnknown8 = (
    1935     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1936     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1937     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    1938     WRITABLE => 1,
     4312%Image::ExifTool::Canon::CameraInfoUnknown = (
     4313    %binaryDataAttrs,
    19394314    FORMAT => 'int8s',
    19404315    FIRST_ENTRY => 0,
     4316    PRIORITY => 0,
    19414317    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    19424318);
    19434319
    1944 # Canon panorama information (MakerNotes tag 0x05)
    1945 %Image::ExifTool::Canon::Panorama = (
    1946     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1947     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1948     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    1949     WRITABLE => 1,
    1950     FORMAT => 'int16s',
     4320# Picture Style information for various cameras (ref 48)
     4321%Image::ExifTool::Canon::PSInfo = (
     4322    %binaryDataAttrs,
    19514323    FIRST_ENTRY => 0,
    1952     GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
    1953     2 => 'PanoramaFrame',
    1954     5 => {
    1955         Name => 'PanoramaDirection',
    1956         PrintConv => {
    1957             0 => 'Left to Right',
    1958             1 => 'Right to Left',
    1959             2 => 'Bottom to Top',
    1960             3 => 'Top to Bottom',
    1961             4 => '2x2 Matrix (Clockwise)',
    1962         },
    1963      },
     4324    PRIORITY => 0,
     4325    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4326    NOTES => 'Custom picture style information for various models.',
     4327    # (values expected to be "n/a" are flagged as Unknown)
     4328    0x00 => { Name => 'ContrastStandard',      %psInfo },
     4329    0x04 => { Name => 'SharpnessStandard',     %psInfo },
     4330    0x08 => { Name => 'SaturationStandard',    %psInfo },
     4331    0x0c => { Name => 'ColorToneStandard',     %psInfo },
     4332    0x10 => { Name => 'FilterEffectStandard',  %psInfo, Unknown => 1 },
     4333    0x14 => { Name => 'ToningEffectStandard',  %psInfo, Unknown => 1 },
     4334    0x18 => { Name => 'ContrastPortrait',      %psInfo },
     4335    0x1c => { Name => 'SharpnessPortrait',     %psInfo },
     4336    0x20 => { Name => 'SaturationPortrait',    %psInfo },
     4337    0x24 => { Name => 'ColorTonePortrait',     %psInfo },
     4338    0x28 => { Name => 'FilterEffectPortrait',  %psInfo, Unknown => 1 },
     4339    0x2c => { Name => 'ToningEffectPortrait',  %psInfo, Unknown => 1 },
     4340    0x30 => { Name => 'ContrastLandscape',     %psInfo },
     4341    0x34 => { Name => 'SharpnessLandscape',    %psInfo },
     4342    0x38 => { Name => 'SaturationLandscape',   %psInfo },
     4343    0x3c => { Name => 'ColorToneLandscape',    %psInfo },
     4344    0x40 => { Name => 'FilterEffectLandscape', %psInfo, Unknown => 1 },
     4345    0x44 => { Name => 'ToningEffectLandscape', %psInfo, Unknown => 1 },
     4346    0x48 => { Name => 'ContrastNeutral',       %psInfo },
     4347    0x4c => { Name => 'SharpnessNeutral',      %psInfo },
     4348    0x50 => { Name => 'SaturationNeutral',     %psInfo },
     4349    0x54 => { Name => 'ColorToneNeutral',      %psInfo },
     4350    0x58 => { Name => 'FilterEffectNeutral',   %psInfo, Unknown => 1 },
     4351    0x5c => { Name => 'ToningEffectNeutral',   %psInfo, Unknown => 1 },
     4352    0x60 => { Name => 'ContrastFaithful',      %psInfo },
     4353    0x64 => { Name => 'SharpnessFaithful',     %psInfo },
     4354    0x68 => { Name => 'SaturationFaithful',    %psInfo },
     4355    0x6c => { Name => 'ColorToneFaithful',     %psInfo },
     4356    0x70 => { Name => 'FilterEffectFaithful',  %psInfo, Unknown => 1 },
     4357    0x74 => { Name => 'ToningEffectFaithful',  %psInfo, Unknown => 1 },
     4358    0x78 => { Name => 'ContrastMonochrome',    %psInfo },
     4359    0x7c => { Name => 'SharpnessMonochrome',   %psInfo },
     4360    0x80 => { Name => 'SaturationMonochrome',  %psInfo, Unknown => 1 },
     4361    0x84 => { Name => 'ColorToneMonochrome',   %psInfo, Unknown => 1 },
     4362    0x88 => { Name => 'FilterEffectMonochrome',%psInfo,
     4363        PrintConv => {
     4364            0 => 'None',
     4365            1 => 'Yellow',
     4366            2 => 'Orange',
     4367            3 => 'Red',
     4368            4 => 'Green',
     4369            -559038737 => 'n/a', # (0xdeadbeef)
     4370        },
     4371    },
     4372    0x8c => { Name => 'ToningEffectMonochrome',%psInfo,
     4373        PrintConv => {
     4374            0 => 'None',
     4375            1 => 'Sepia',
     4376            2 => 'Blue',
     4377            3 => 'Purple',
     4378            4 => 'Green',
     4379            -559038737 => 'n/a', # (0xdeadbeef)
     4380        },
     4381    },
     4382    0x90 => { Name => 'ContrastUserDef1',      %psInfo },
     4383    0x94 => { Name => 'SharpnessUserDef1',     %psInfo },
     4384    0x98 => { Name => 'SaturationUserDef1',    %psInfo },
     4385    0x9c => { Name => 'ColorToneUserDef1',     %psInfo },
     4386    0xa0 => { Name => 'FilterEffectUserDef1',  %psInfo,
     4387        PrintConv => {
     4388            0 => 'None',
     4389            1 => 'Yellow',
     4390            2 => 'Orange',
     4391            3 => 'Red',
     4392            4 => 'Green',
     4393            -559038737 => 'n/a', # (0xdeadbeef)
     4394        },
     4395    },
     4396    0xa4 => { Name => 'ToningEffectUserDef1',  %psInfo,
     4397        PrintConv => {
     4398            0 => 'None',
     4399            1 => 'Sepia',
     4400            2 => 'Blue',
     4401            3 => 'Purple',
     4402            4 => 'Green',
     4403            -559038737 => 'n/a', # (0xdeadbeef)
     4404        },
     4405    },
     4406    0xa8 => { Name => 'ContrastUserDef2',      %psInfo },
     4407    0xac => { Name => 'SharpnessUserDef2',     %psInfo },
     4408    0xb0 => { Name => 'SaturationUserDef2',    %psInfo },
     4409    0xb4 => { Name => 'ColorToneUserDef2',     %psInfo },
     4410    0xb8 => { Name => 'FilterEffectUserDef2',  %psInfo,
     4411        PrintConv => {
     4412            0 => 'None',
     4413            1 => 'Yellow',
     4414            2 => 'Orange',
     4415            3 => 'Red',
     4416            4 => 'Green',
     4417            -559038737 => 'n/a', # (0xdeadbeef)
     4418        },
     4419    },
     4420    0xbc => { Name => 'ToningEffectUserDef2',  %psInfo,
     4421        PrintConv => {
     4422            0 => 'None',
     4423            1 => 'Sepia',
     4424            2 => 'Blue',
     4425            3 => 'Purple',
     4426            4 => 'Green',
     4427            -559038737 => 'n/a', # (0xdeadbeef)
     4428        },
     4429    },
     4430    0xc0 => { Name => 'ContrastUserDef3',      %psInfo },
     4431    0xc4 => { Name => 'SharpnessUserDef3',     %psInfo },
     4432    0xc8 => { Name => 'SaturationUserDef3',    %psInfo },
     4433    0xcc => { Name => 'ColorToneUserDef3',     %psInfo },
     4434    0xd0 => { Name => 'FilterEffectUserDef3',  %psInfo,
     4435        PrintConv => {
     4436            0 => 'None',
     4437            1 => 'Yellow',
     4438            2 => 'Orange',
     4439            3 => 'Red',
     4440            4 => 'Green',
     4441            -559038737 => 'n/a', # (0xdeadbeef)
     4442        },
     4443    },
     4444    0xd4 => { Name => 'ToningEffectUserDef3',  %psInfo,
     4445        PrintConv => {
     4446            0 => 'None',
     4447            1 => 'Sepia',
     4448            2 => 'Blue',
     4449            3 => 'Purple',
     4450            4 => 'Green',
     4451            -559038737 => 'n/a', # (0xdeadbeef)
     4452        },
     4453    },
     4454    # base picture style names:
     4455    0xd8 => {
     4456        Name => 'UserDef1PictureStyle',
     4457        Format => 'int16u',
     4458        SeparateTable => 'UserDefStyle',
     4459        PrintConv => \%userDefStyles,
     4460    },
     4461    0xda => {
     4462        Name => 'UserDef2PictureStyle',
     4463        Format => 'int16u',
     4464        SeparateTable => 'UserDefStyle',
     4465        PrintConv => \%userDefStyles,
     4466    },
     4467    0xdc => {
     4468        Name => 'UserDef3PictureStyle',
     4469        Format => 'int16u',
     4470        SeparateTable => 'UserDefStyle',
     4471        PrintConv => \%userDefStyles,
     4472    },
     4473);
     4474
     4475# Picture Style information for the 60D (ref 48)
     4476%Image::ExifTool::Canon::PSInfo2 = (
     4477    %binaryDataAttrs,
     4478    FIRST_ENTRY => 0,
     4479    PRIORITY => 0,
     4480    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4481    NOTES => 'Custom picture style information for the EOS 60D.',
     4482    # (values expected to be "n/a" are flagged as Unknown)
     4483    0x00 => { Name => 'ContrastStandard',      %psInfo },
     4484    0x04 => { Name => 'SharpnessStandard',     %psInfo },
     4485    0x08 => { Name => 'SaturationStandard',    %psInfo },
     4486    0x0c => { Name => 'ColorToneStandard',     %psInfo },
     4487    0x10 => { Name => 'FilterEffectStandard',  %psInfo, Unknown => 1 },
     4488    0x14 => { Name => 'ToningEffectStandard',  %psInfo, Unknown => 1 },
     4489    0x18 => { Name => 'ContrastPortrait',      %psInfo },
     4490    0x1c => { Name => 'SharpnessPortrait',     %psInfo },
     4491    0x20 => { Name => 'SaturationPortrait',    %psInfo },
     4492    0x24 => { Name => 'ColorTonePortrait',     %psInfo },
     4493    0x28 => { Name => 'FilterEffectPortrait',  %psInfo, Unknown => 1 },
     4494    0x2c => { Name => 'ToningEffectPortrait',  %psInfo, Unknown => 1 },
     4495    0x30 => { Name => 'ContrastLandscape',     %psInfo },
     4496    0x34 => { Name => 'SharpnessLandscape',    %psInfo },
     4497    0x38 => { Name => 'SaturationLandscape',   %psInfo },
     4498    0x3c => { Name => 'ColorToneLandscape',    %psInfo },
     4499    0x40 => { Name => 'FilterEffectLandscape', %psInfo, Unknown => 1 },
     4500    0x44 => { Name => 'ToningEffectLandscape', %psInfo, Unknown => 1 },
     4501    0x48 => { Name => 'ContrastNeutral',       %psInfo },
     4502    0x4c => { Name => 'SharpnessNeutral',      %psInfo },
     4503    0x50 => { Name => 'SaturationNeutral',     %psInfo },
     4504    0x54 => { Name => 'ColorToneNeutral',      %psInfo },
     4505    0x58 => { Name => 'FilterEffectNeutral',   %psInfo, Unknown => 1 },
     4506    0x5c => { Name => 'ToningEffectNeutral',   %psInfo, Unknown => 1 },
     4507    0x60 => { Name => 'ContrastFaithful',      %psInfo },
     4508    0x64 => { Name => 'SharpnessFaithful',     %psInfo },
     4509    0x68 => { Name => 'SaturationFaithful',    %psInfo },
     4510    0x6c => { Name => 'ColorToneFaithful',     %psInfo },
     4511    0x70 => { Name => 'FilterEffectFaithful',  %psInfo, Unknown => 1 },
     4512    0x74 => { Name => 'ToningEffectFaithful',  %psInfo, Unknown => 1 },
     4513    0x78 => { Name => 'ContrastMonochrome',    %psInfo },
     4514    0x7c => { Name => 'SharpnessMonochrome',   %psInfo },
     4515    0x80 => { Name => 'SaturationMonochrome',  %psInfo, Unknown => 1 },
     4516    0x84 => { Name => 'ColorToneMonochrome',   %psInfo, Unknown => 1 },
     4517    0x88 => { Name => 'FilterEffectMonochrome',%psInfo,
     4518        PrintConv => {
     4519            0 => 'None',
     4520            1 => 'Yellow',
     4521            2 => 'Orange',
     4522            3 => 'Red',
     4523            4 => 'Green',
     4524            -559038737 => 'n/a', # (0xdeadbeef)
     4525        },
     4526    },
     4527    0x8c => { Name => 'ToningEffectMonochrome',%psInfo,
     4528        PrintConv => {
     4529            0 => 'None',
     4530            1 => 'Sepia',
     4531            2 => 'Blue',
     4532            3 => 'Purple',
     4533            4 => 'Green',
     4534            -559038737 => 'n/a', # (0xdeadbeef)
     4535        },
     4536    },
     4537    0x90 => { Name => 'ContrastUnknown',        %psInfo, Unknown => 1 },
     4538    0x94 => { Name => 'SharpnessUnknown',       %psInfo, Unknown => 1 },
     4539    0x98 => { Name => 'SaturationUnknown',      %psInfo, Unknown => 1 },
     4540    0x9c => { Name => 'ColorToneUnknown',       %psInfo, Unknown => 1 },
     4541    0xa0 => { Name => 'FilterEffectUnknown',    %psInfo, Unknown => 1,
     4542        PrintConv => {
     4543            0 => 'None',
     4544            1 => 'Yellow',
     4545            2 => 'Orange',
     4546            3 => 'Red',
     4547            4 => 'Green',
     4548            -559038737 => 'n/a', # (0xdeadbeef)
     4549        },
     4550    },
     4551    0xa4 => { Name => 'ToningEffectUnknown',    %psInfo, Unknown => 1,
     4552        PrintConv => {
     4553            0 => 'None',
     4554            1 => 'Sepia',
     4555            2 => 'Blue',
     4556            3 => 'Purple',
     4557            4 => 'Green',
     4558            -559038737 => 'n/a', # (0xdeadbeef)
     4559        },
     4560    },
     4561    0xa8 => { Name => 'ContrastUserDef1',      %psInfo },
     4562    0xac => { Name => 'SharpnessUserDef1',     %psInfo },
     4563    0xb0 => { Name => 'SaturationUserDef1',    %psInfo },
     4564    0xb4 => { Name => 'ColorToneUserDef1',     %psInfo },
     4565    0xb8 => { Name => 'FilterEffectUserDef1',  %psInfo,
     4566        PrintConv => {
     4567            0 => 'None',
     4568            1 => 'Yellow',
     4569            2 => 'Orange',
     4570            3 => 'Red',
     4571            4 => 'Green',
     4572            -559038737 => 'n/a', # (0xdeadbeef)
     4573        },
     4574    },
     4575    0xbc => { Name => 'ToningEffectUserDef1',  %psInfo,
     4576        PrintConv => {
     4577            0 => 'None',
     4578            1 => 'Sepia',
     4579            2 => 'Blue',
     4580            3 => 'Purple',
     4581            4 => 'Green',
     4582            -559038737 => 'n/a', # (0xdeadbeef)
     4583        },
     4584    },
     4585    0xc0 => { Name => 'ContrastUserDef2',      %psInfo },
     4586    0xc4 => { Name => 'SharpnessUserDef2',     %psInfo },
     4587    0xc8 => { Name => 'SaturationUserDef2',    %psInfo },
     4588    0xcc => { Name => 'ColorToneUserDef2',     %psInfo },
     4589    0xd0 => { Name => 'FilterEffectUserDef2',  %psInfo,
     4590        PrintConv => {
     4591            0 => 'None',
     4592            1 => 'Yellow',
     4593            2 => 'Orange',
     4594            3 => 'Red',
     4595            4 => 'Green',
     4596            -559038737 => 'n/a', # (0xdeadbeef)
     4597        },
     4598    },
     4599    0xd4 => { Name => 'ToningEffectUserDef2',  %psInfo,
     4600        PrintConv => {
     4601            0 => 'None',
     4602            1 => 'Sepia',
     4603            2 => 'Blue',
     4604            3 => 'Purple',
     4605            4 => 'Green',
     4606            -559038737 => 'n/a', # (0xdeadbeef)
     4607        },
     4608    },
     4609    0xd8 => { Name => 'ContrastUserDef3',      %psInfo },
     4610    0xdc => { Name => 'SharpnessUserDef3',     %psInfo },
     4611    0xe0 => { Name => 'SaturationUserDef3',    %psInfo },
     4612    0xe4 => { Name => 'ColorToneUserDef3',     %psInfo },
     4613    0xe8 => { Name => 'FilterEffectUserDef3',  %psInfo,
     4614        PrintConv => {
     4615            0 => 'None',
     4616            1 => 'Yellow',
     4617            2 => 'Orange',
     4618            3 => 'Red',
     4619            4 => 'Green',
     4620            -559038737 => 'n/a', # (0xdeadbeef)
     4621        },
     4622    },
     4623    0xec => { Name => 'ToningEffectUserDef3',  %psInfo,
     4624        PrintConv => {
     4625            0 => 'None',
     4626            1 => 'Sepia',
     4627            2 => 'Blue',
     4628            3 => 'Purple',
     4629            4 => 'Green',
     4630            -559038737 => 'n/a', # (0xdeadbeef)
     4631        },
     4632    },
     4633    # base picture style names:
     4634    0xf0 => {
     4635        Name => 'UserDef1PictureStyle',
     4636        Format => 'int16u',
     4637        SeparateTable => 'UserDefStyle',
     4638        PrintConv => \%userDefStyles,
     4639    },
     4640    0xf2 => {
     4641        Name => 'UserDef2PictureStyle',
     4642        Format => 'int16u',
     4643        SeparateTable => 'UserDefStyle',
     4644        PrintConv => \%userDefStyles,
     4645    },
     4646    0xf4 => {
     4647        Name => 'UserDef3PictureStyle',
     4648        Format => 'int16u',
     4649        SeparateTable => 'UserDefStyle',
     4650        PrintConv => \%userDefStyles,
     4651    },
     4652);
     4653
     4654# Movie information (MakerNotes tag 0x11) (ref PH)
     4655%Image::ExifTool::Canon::MovieInfo = (
     4656    %binaryDataAttrs,
     4657    FORMAT => 'int16u',
     4658    FIRST_ENTRY => 1,
     4659    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
     4660    NOTES => 'Tags written by some Canon cameras when recording video.',
     4661    1 => { # (older PowerShot AVI)
     4662        Name => 'FrameRate',
     4663        RawConv => '$val == 65535 ? undef: $val',
     4664        ValueConvInv => '$val > 65535 ? 65535 : $val',
     4665    },
     4666    2 => { # (older PowerShot AVI)
     4667        Name => 'FrameCount',
     4668        RawConv => '$val == 65535 ? undef: $val',
     4669        ValueConvInv => '$val > 65535 ? 65535 : $val',
     4670    },
     4671    # 3 - values: 0x0001 (older PowerShot AVI), 0x4004, 0x4005
     4672    4 => {
     4673        Name => 'FrameCount',
     4674        Format => 'int32u',
     4675    },
     4676    6 => {
     4677        Name => 'FrameRate',
     4678        Format => 'rational32u',
     4679        PrintConv => 'int($val * 1000 + 0.5) / 1000',
     4680        PrintConvInv => '$val',
     4681    },
     4682    # 9/10 - same as 6/7 (FrameRate)
     4683    106 => {
     4684        Name => 'Duration',
     4685        Format => 'int32u',
     4686        ValueConv => '$val / 1000',
     4687        ValueConvInv => '$val * 1000',
     4688        PrintConv => 'ConvertDuration($val)',
     4689        PrintConvInv => q{
     4690            my @a = ($val =~ /\d+(?:\.\d*)?/g);
     4691            $val  = pop(@a) || 0;         # seconds
     4692            $val += pop(@a) *   60 if @a; # minutes
     4693            $val += pop(@a) * 3600 if @a; # hours
     4694            return $val;
     4695        },
     4696    },
     4697    108 => {
     4698        Name => 'AudioBitrate',
     4699        Groups => { 2 => 'Audio' },
     4700        Format => 'int32u',
     4701        PrintConv => 'ConvertBitrate($val)',
     4702        PrintConvInv => q{
     4703            $val =~ /^(\d+(?:\.\d*)?) ?([kMG]?bps)?$/ or return undef;
     4704            return $1 * {bps=>1,kbps=>1000,Mbps=>1000000,Gbps=>1000000000}->{$2 || 'bps'};
     4705        },
     4706    },
     4707    110 => {
     4708        Name => 'AudioSampleRate',
     4709        Groups => { 2 => 'Audio' },
     4710        Format => 'int32u',
     4711    },
     4712    112 => { # (guess)
     4713        Name => 'AudioChannels',
     4714        Groups => { 2 => 'Audio' },
     4715        Format => 'int32u',
     4716    },
     4717    # 114 - values: 0 (60D), 1 (S95)
     4718    116 => {
     4719        Name => 'VideoCodec',
     4720        Format => 'undef[4]',
     4721        # swap bytes if little endian
     4722        RawConv => 'GetByteOrder() eq "MM" ? $val : pack("N",unpack("V",$val))',
     4723        RawConvInv => 'GetByteOrder() eq "MM" ? $val : pack("N",unpack("V",$val))',
     4724    },
     4725    # 125 - same as 10
    19644726);
    19654727
     
    19674729%Image::ExifTool::Canon::AFInfo = (
    19684730    PROCESS_PROC => \&ProcessSerialData,
     4731    VARS => { ID_LABEL => 'Sequence' },
    19694732    FORMAT => 'int16u',
    19704733    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     
    20174780            Name => 'PrimaryAFPoint',
    20184781            Condition => q{
    2019                 $$self{CameraModel} !~ /EOS/ and
     4782                $$self{Model} !~ /EOS/ and
    20204783                (not $$self{AFInfoCount} or $$self{AFInfoCount} != 36)
    20214784            },
     
    20244787            # (some PowerShot 9-point systems put PrimaryAFPoint after 8 unknown values)
    20254788            Name => 'Canon_AFInfo_0x000b',
    2026             Condition => '$$self{CameraModel} !~ /EOS/',
     4789            Condition => '$$self{Model} !~ /EOS/',
    20274790            Format => 'int16u[8]',
    20284791            Unknown => 1,
     
    20374800%Image::ExifTool::Canon::AFInfo2 = (
    20384801    PROCESS_PROC => \&ProcessSerialData,
     4802    VARS => { ID_LABEL => 'Sequence' },
    20394803    FORMAT => 'int16u',
    20404804    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     
    20494813    },
    20504814    1 => {
    2051         Name => 'AFMode',
     4815        Name => 'AFAreaMode',
    20524816        PrintConv => {
    20534817            0 => 'Off (Manual Focus)',
    20544818            2 => 'Single-point AF',
    2055             4 => 'Multi-point AF', # AiAF on A570IS
     4819            4 => 'Multi-point AF or AI AF', # AiAF on A570IS
    20564820            5 => 'Face Detect AF',
     4821            7 => 'Zone AF', #46
     4822            8 => 'AF Point Expansion', #46
     4823            9 => 'Spot AF', #46
    20574824        },
    20584825    },
     
    20704837    },
    20714838    5 => {
    2072         Name => 'CanonImageWidth',
     4839        Name => 'CanonImageHeight',
    20734840        Groups => { 2 => 'Image' },
    20744841    },
     
    21024869        {
    21034870            Name => 'AFPointsSelected',
    2104             Condition => '$$self{CameraModel} =~ /EOS/',
     4871            Condition => '$$self{Model} =~ /EOS/',
    21054872            Format => 'int16s[int(($val{2}+15)/16)]',
    21064873            PrintConv => 'Image::ExifTool::DecodeBits($val, undef, 16)',
     
    21154882        # usually, but not always, the lowest number AF point in focus
    21164883        Name => 'PrimaryAFPoint',
    2117         Condition => '$$self{CameraModel} !~ /EOS/',
    2118     },       
     4884        Condition => '$$self{Model} !~ /EOS/',
     4885    },
    21194886);
    21204887
    21214888# my color mode information (MakerNotes tag 0x1d) - PH (A570IS)
    21224889%Image::ExifTool::Canon::MyColors = (
    2123     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2124     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2125     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2126     WRITABLE => 1,
     4890    %binaryDataAttrs,
    21274891    FORMAT => 'int16u',
    21284892    FIRST_ENTRY => 0,
     
    21304894    0x02 => {
    21314895        Name => 'MyColorMode',
     4896        PrintConvColumns => 2,
    21324897        PrintConv => {
    21334898            0 => 'Off',
     4899            1 => 'Positive Film', #15 (SD600)
     4900            2 => 'Light Skin Tone', #15
     4901            3 => 'Dark Skin Tone', #15
     4902            4 => 'Vivid Blue', #15
     4903            5 => 'Vivid Green', #15
     4904            6 => 'Vivid Red', #15
     4905            7 => 'Color Accent', #15 (A610) (NC)
     4906            8 => 'Color Swap', #15 (A610)
    21344907            9 => 'Custom',
    21354908            12 => 'Vivid',
     
    21434916# face detect information (MakerNotes tag 0x24) - PH (A570IS)
    21444917%Image::ExifTool::Canon::FaceDetect1 = (
    2145     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2146     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2147     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2148     WRITABLE => 1,
     4918    %binaryDataAttrs,
    21494919    FORMAT => 'int16u',
    21504920    FIRST_ENTRY => 0,
     
    21564926        RawConv => '$$self{FacesDetected} = $val',
    21574927    },
    2158     0x03 => 'FaceDetectFrameWidth',
    2159     0x04 => 'FaceDetectFrameHeight',
     4928    0x03 => {
     4929        Name => 'FaceDetectFrameSize',
     4930        Format => 'int16u[2]',
     4931    },
    21604932    0x08 => {
    2161         Name => 'Face0Position',
     4933        Name => 'Face1Position',
    21624934        Format => 'int16s[2]',
    21634935        RawConv => '$$self{FacesDetected} < 1 ? undef: $val',
     
    21694941    },
    21704942    0x0a => {
    2171         Name => 'Face1Position',
     4943        Name => 'Face2Position',
    21724944        Format => 'int16s[2]',
    21734945        RawConv => '$$self{FacesDetected} < 2 ? undef : $val',
    21744946    },
    21754947    0x0c => {
    2176         Name => 'Face2Position',
     4948        Name => 'Face3Position',
    21774949        Format => 'int16s[2]',
    21784950        RawConv => '$$self{FacesDetected} < 3 ? undef : $val',
    21794951    },
    21804952    0x0e => {
    2181         Name => 'Face3Position',
     4953        Name => 'Face4Position',
    21824954        Format => 'int16s[2]',
    21834955        RawConv => '$$self{FacesDetected} < 4 ? undef : $val',
    21844956    },
    21854957    0x10 => {
    2186         Name => 'Face4Position',
     4958        Name => 'Face5Position',
    21874959        Format => 'int16s[2]',
    21884960        RawConv => '$$self{FacesDetected} < 5 ? undef : $val',
    21894961    },
    21904962    0x12 => {
    2191         Name => 'Face5Position',
     4963        Name => 'Face6Position',
    21924964        Format => 'int16s[2]',
    21934965        RawConv => '$$self{FacesDetected} < 6 ? undef : $val',
    21944966    },
    21954967    0x14 => {
    2196         Name => 'Face6Position',
     4968        Name => 'Face7Position',
    21974969        Format => 'int16s[2]',
    21984970        RawConv => '$$self{FacesDetected} < 7 ? undef : $val',
    21994971    },
    22004972    0x16 => {
    2201         Name => 'Face7Position',
     4973        Name => 'Face8Position',
    22024974        Format => 'int16s[2]',
    22034975        RawConv => '$$self{FacesDetected} < 8 ? undef : $val',
    22044976    },
    22054977    0x18 => {
    2206         Name => 'Face8Position',
     4978        Name => 'Face9Position',
    22074979        Format => 'int16s[2]',
    22084980        RawConv => '$$self{FacesDetected} < 9 ? undef : $val',
     
    22124984# more face detect information (MakerNotes tag 0x25) - PH (A570IS)
    22134985%Image::ExifTool::Canon::FaceDetect2 = (
    2214     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2215     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2216     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2217     WRITABLE => 1,
     4986    %binaryDataAttrs,
    22184987    FORMAT => 'int8u',
    22194988    FIRST_ENTRY => 0,
    22204989    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     4990    0x01 => 'FaceWidth',
    22214991    0x02 => 'FacesDetected',
    2222 );
    2223 
    2224 # Preview image information (MakerNotes tag 0xb6)
    2225 # - The 300D writes a 1536x1024 preview image that is accessed
    2226 #   through this information - decoded by PH 12/14/03
    2227 %Image::ExifTool::Canon::PreviewImageInfo = (
    2228     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2229     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2230     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2231     WRITABLE => 1,
    2232     FORMAT => 'int32u',
    2233     FIRST_ENTRY => 1,
    2234     IS_OFFSET => [ 5 ],   # tag 5 is 'IsOffset'
    2235     GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
    2236 # the size of the preview block in 2-byte increments
    2237 #    0 => {
    2238 #        Name => 'PreviewImageInfoWords',
    2239 #    },
    2240     1 => {
    2241         Name => 'PreviewQuality',
    2242         PrintConv => \%canonQuality,
    2243     },
    2244     2 => {
    2245         Name => 'PreviewImageLength',
    2246         OffsetPair => 5,   # point to associated offset
    2247         DataTag => 'PreviewImage',
    2248         Protected => 2,
    2249     },
    2250     3 => 'PreviewImageWidth',
    2251     4 => 'PreviewImageHeight',
    2252     5 => {
    2253         Name => 'PreviewImageStart',
    2254         Flags => 'IsOffset',
    2255         OffsetPair => 2,  # associated byte count tagID
    2256         DataTag => 'PreviewImage',
    2257         Protected => 2,
    2258     },
    2259     6 => {
    2260         Name => 'PreviewFocalPlaneXResolution',
    2261         Format => 'rational64s',
    2262         PrintConv => 'sprintf("%.1f",$val)',
    2263         PrintConvInv => '$val',
    2264     },
    2265     8 => {
    2266         Name => 'PreviewFocalPlaneYResolution',
    2267         Format => 'rational64s',
    2268         PrintConv => 'sprintf("%.1f",$val)',
    2269         PrintConvInv => '$val',
    2270     },
    2271 # the following 2 values look like they are really 4 shorts
    2272 # taking the values of 1,4,4 and 2 respectively - don't know what they are though
    2273 #    10 => {
    2274 #        Name => 'PreviewImageUnknown1',
    2275 #        PrintConv => 'sprintf("0x%x",$val)',
    2276 #    },
    2277 #    11 => {
    2278 #        Name => 'PreviewImageUnknown2',
    2279 #        PrintConv => 'sprintf("0x%x",$val)',
    2280 #    },
    2281 );
    2282 
    2283 # Sensor information (MakerNotes tag 0xe0) (ref 12)
    2284 %Image::ExifTool::Canon::SensorInfo = (
    2285     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2286     FORMAT => 'int16s',
    2287     FIRST_ENTRY => 1,
    2288     GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
    2289     # Note: Don't make these writable because it confuses Canon decoding software
    2290     # if these are changed
    2291     1 => 'SensorWidth',
    2292     2 => 'SensorHeight',
    2293     5 => 'SensorLeftBorder', #2
    2294     6 => 'SensorTopBorder', #2
    2295     7 => 'SensorRightBorder', #2
    2296     8 => 'SensorBottomBorder', #2
    22974992);
    22984993
    22994994# File number information (MakerNotes tag 0x93)
    23004995%Image::ExifTool::Canon::FileInfo = (
    2301     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2302     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2303     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2304     WRITABLE => 1,
     4996    %binaryDataAttrs,
    23054997    FORMAT => 'int16s',
    23064998    FIRST_ENTRY => 1,
     
    23095001        { #5
    23105002            Name => 'FileNumber',
    2311             Condition => '$$self{CameraModel} =~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/',
     5003            Condition => '$$self{Model} =~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/',
    23125004            Format => 'int32u',
    23135005            # Thanks to Juha Eskelinen for figuring this out:
     
    23355027        { #16
    23365028            Name => 'FileNumber',
    2337             Condition => '$$self{CameraModel} =~ /\b(30D|400D|REBEL XTi|Kiss Digital X|K236)\b/',
     5029            Condition => '$$self{Model} =~ /\b(30D|400D|REBEL XTi|Kiss Digital X|K236)\b/',
    23385030            Format => 'int32u',
    23395031            Notes => q{
     
    23715063            Format => 'int32u',
    23725064        },
    2373         { #7 (1DmkII, 1DsMkII, 1DsMkIIN)
     5065        { #7 (1DmkII, 1DSmkII, 1DSmkIIN)
    23745066            Name => 'ShutterCount',
    2375             Condition => '$$self{CameraModel} =~ /\b1Ds? Mark II\b/',
     5067            Condition => '$$self{Model} =~ /\b1Ds? Mark II\b/',
    23765068            Format => 'int32u',
    23775069            ValueConv => '($val>>16)|(($val&0xffff)<<16)',
     
    24045096    },
    24055097    8 => { #PH
    2406         Name => 'NoiseReduction',
     5098        Name => 'LongExposureNoiseReduction2',
     5099        Notes => q{
     5100            for some modules this gives the long exposure noise reduction applied to the
     5101            image, but for other models this just reflects the setting independent of
     5102            whether or not it was applied
     5103        },
    24075104        RawConv => '$val<0 ? undef : $val',
    24085105        PrintConv => {
    24095106            0 => 'Off',
    2410             # what do these modes mean?:
    2411             1 => 'On (mode 1)',
    2412             2 => 'On (mode 2)',
    2413             3 => 'On (mode 3)', # (1DmkII,5D)
    2414             4 => 'On (mode 4)', # (30D)
     5107            1 => 'On (1D)',
     5108            3 => 'On',
     5109            4 => 'Auto',
    24155110        },
    24165111    },
     
    24475142        },
    24485143    },
    2449 );
    2450 
    2451 # color information (MakerNotes tag 0xa0)
     5144    16 => { #PH
     5145        %ciMacroMagnification,
     5146        # MP-E 65mm on 5DmkII: 44=5x,52~=3.9x,56~=3.3x,62~=2.6x,75=1x
     5147        # ME-E 65mm on 40D/450D: 72 for all samples (not valid)
     5148        Condition => q{
     5149            $$self{LensType} and $$self{LensType} == 124 and
     5150            $$self{Model} !~ /\b(40D|450D|REBEL XSi|Kiss X2)\b/
     5151        },
     5152        Notes => q{
     5153            currently decoded only for the MP-E 65mm f/2.8 1-5x Macro Photo, and not
     5154            valid for all camera models
     5155        },
     5156    },
     5157    # 17 - values: 0, 3, 4
     5158    # 18 - same as LiveViewShooting for all my samples (5DmkII, 50D) - PH
     5159    19 => { #PH
     5160        # Note: this value is not displayed by Canon ImageBrowser for the following
     5161        # models with the live view feature:  1DmkIII, 1DSmkIII, 40D, 450D, 1000D
     5162        # (this tag could be valid only for some firmware versions:
     5163        # http://www.breezesys.com/forum/showthread.php?p=16980)
     5164        Name => 'LiveViewShooting',
     5165        PrintConv => { 0 => 'Off', 1 => 'On' },
     5166    },
     5167    # 22 - values: 0, 1
     5168    # 23 - values: 0, 21, 22
     5169    25 => { #PH
     5170        Name => 'FlashExposureLock',
     5171        PrintConv => { 0 => 'Off', 1 => 'On' },
     5172    },
     5173);
     5174
     5175# Internal serial number information (MakerNotes tag 0x96) (ref PH)
     5176%Image::ExifTool::Canon::SerialInfo = (
     5177    %binaryDataAttrs,
     5178    FIRST_ENTRY => 0,
     5179    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5180    9 => {
     5181        Name => 'InternalSerialNumber',
     5182        Format => 'string',
     5183    },
     5184);
     5185
     5186# Cropping information (MakerNotes tag 0x98) (ref PH)
     5187%Image::ExifTool::Canon::CropInfo = (
     5188    %binaryDataAttrs,
     5189    FORMAT => 'int16u',
     5190    FIRST_ENTRY => 0,
     5191    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5192    0 => 'CropLeftMargin',  # (NC, may be right)
     5193    1 => 'CropRightMargin',
     5194    2 => 'CropTopMargin',   # (NC, may be bottom)
     5195    3 => 'CropBottomMargin',
     5196);
     5197
     5198# Aspect ratio information (MakerNotes tag 0x9a) (ref PH)
     5199%Image::ExifTool::Canon::AspectInfo = (
     5200    %binaryDataAttrs,
     5201    FORMAT => 'int32u',
     5202    FIRST_ENTRY => 0,
     5203    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5204    0 => {
     5205        Name => 'AspectRatio',
     5206        PrintConv => {
     5207            0 => '3:2',
     5208            1 => '1:1',
     5209            2 => '4:3',
     5210            7 => '16:9',
     5211            8 => '4:5',
     5212        },
     5213    },
     5214    1 => 'CroppedImageWidth', # (could use a better name for these)
     5215    2 => 'CroppedImageHeight',
     5216);
     5217
     5218# Color information (MakerNotes tag 0xa0)
    24525219%Image::ExifTool::Canon::Processing = (
    2453     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2454     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2455     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2456     WRITABLE => 1,
     5220    %binaryDataAttrs,
    24575221    FORMAT => 'int16s',
    24585222    FIRST_ENTRY => 1,
     
    24685232    2 => { #12
    24695233        Name => 'Sharpness',
    2470         Notes => '1D and 5D only',
    2471         Condition => '$$self{CameraModel} =~ /\b(1D|5D)/',
     5234        Notes => 'all models except the 20D and 350D',
     5235        Condition => '$$self{Model} !~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/',
     5236        Priority => 0,  # (maybe not as reliable as other sharpness values)
    24725237    },
    24735238    3 => { #PH
    2474         Name => 'SharpnessFrequency',
     5239        Name => 'SharpnessFrequency', # PatternSharpness?
     5240        PrintConvColumns => 2,
    24755241        PrintConv => {
    24765242            0 => 'n/a',
     
    24905256        RawConv => '$val < 0 ? undef : $val',
    24915257        PrintConv => \%canonWhiteBalance,
     5258        SeparateTable => 1,
    24925259    },
    24935260    9 => 'ColorTemperature', #6
    24945261    10 => { #12
    24955262        Name => 'PictureStyle',
    2496         PrintHex => 1,
     5263        Flags => ['PrintHex','SeparateTable'],
    24975264        PrintConv => \%pictureStyles,
    24985265    },
     
    25045271    12 => { #PH
    25055272        Name => 'WBShiftAB',
    2506         Notes => 'positive is a shift toward red',
     5273        Notes => 'positive is a shift toward amber',
    25075274    },
    25085275    13 => { #PH
    25095276        Name => 'WBShiftGM',
    2510         Notes => 'positive is a shift toward yellow/green',
    2511     },
    2512 );
    2513 
    2514 # D30 color information (MakerNotes tag 0x0a)
    2515 %Image::ExifTool::Canon::ColorInfoD30 = (
    2516     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2517     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2518     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2519     WRITABLE => 1,
    2520     FORMAT => 'int16s',
    2521     FIRST_ENTRY => 1,
    2522     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    2523     9 => 'ColorTemperature',
    2524     10 => 'ColorMatrix',
     5277        Notes => 'positive is a shift toward green',
     5278    },
    25255279);
    25265280
    25275281# Color balance information (MakerNotes tag 0xa9) (ref PH)
    25285282%Image::ExifTool::Canon::ColorBalance = (
    2529     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2530     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2531     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2532     NOTES => 'This table is used by the 10D and 300D.',
    2533     FORMAT => 'int16u',
     5283    %binaryDataAttrs,
     5284    NOTES => 'These tags are used by the 10D and 300D.',
     5285    FORMAT => 'int16s',
    25345286    FIRST_ENTRY => 0,
    2535     WRITABLE => 1,
    25365287    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    25375288    # red,green1,green2,blue (ref 2)
    2538     0  => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16u[4]' },
    2539     4  => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16u[4]' },
    2540     8  => { Name => 'WB_RGGBLevelsShade',      Format => 'int16u[4]' },
    2541     12 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16u[4]' },
    2542     16 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16u[4]' },
    2543     20 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16u[4]' },
    2544     24 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16u[4]' },
    2545     28 => { Name => 'WB_RGGBLevelsCustom',     Format => 'int16u[4]' },
    2546     32 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16u[4]' },
    2547 );
    2548 
    2549 # Color balance (MakerNotes tag 0x4001) (ref 12)
    2550 %Image::ExifTool::Canon::ColorBalance1 = (
    2551     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2552     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2553     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2554     NOTES => 'This table is used by the 20D and 350D.',
     5289    0  => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
     5290    4  => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
     5291    8  => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
     5292    12 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
     5293    16 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
     5294    20 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
     5295    24 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
     5296    28 => { Name => 'WB_RGGBLevelsCustom',     Format => 'int16s[4]' },
     5297    32 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
     5298);
     5299
     5300# Measured color levels (MakerNotes tag 0xaa) (ref 37)
     5301%Image::ExifTool::Canon::MeasuredColor = (
     5302    %binaryDataAttrs,
    25555303    FORMAT => 'int16u',
    2556     FIRST_ENTRY => 0,
    2557     WRITABLE => 1,
    2558     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    2559     25 => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16u[4]' },
    2560     29 => 'ColorTempAsShot',
    2561     30 => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16u[4]' },
    2562     34 => 'ColorTempAuto',
    2563     35 => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16u[4]' },
    2564     39 => 'ColorTempDaylight',
    2565     40 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16u[4]' },
    2566     44 => 'ColorTempShade',
    2567     45 => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16u[4]' },
    2568     49 => 'ColorTempCloudy',
    2569     50 => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16u[4]' },
    2570     54 => 'ColorTempTungsten',
    2571     55 => { Name => 'WB_RGGBLevelsFluorescent', Format => 'int16u[4]' },
    2572     59 => 'ColorTempFluorescent',
    2573     60 => { Name => 'WB_RGGBLevelsFlash',       Format => 'int16u[4]' },
    2574     64 => 'ColorTempFlash',
    2575     65 => { Name => 'WB_RGGBLevelsCustom1',     Format => 'int16u[4]' },
    2576     69 => 'ColorTempCustom1',
    2577     70 => { Name => 'WB_RGGBLevelsCustom2',     Format => 'int16u[4]' },
    2578     74 => 'ColorTempCustom2',
    2579 );
    2580 
    2581 # Color balance (MakerNotes tag 0x4001) (ref 12)
    2582 %Image::ExifTool::Canon::ColorBalance2 = (
    2583     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2584     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2585     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2586     NOTES => 'This table is used by the 1DmkII and 1DSmkII.',
    2587     FORMAT => 'int16u',
    2588     FIRST_ENTRY => 0,
    2589     WRITABLE => 1,
    2590     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    2591     24 => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16u[4]' },
    2592     28 => 'ColorTempAsShot',
    2593     29 => { Name => 'WB_RGGBLevelsUnknown',     Format => 'int16u[4]', Unknown => 1 },
    2594     33 => { Name => 'ColorTempUnknown', Unknown => 1 },
    2595     34 => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16u[4]' },
    2596     38 => 'ColorTempAuto',
    2597     39 => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16u[4]' },
    2598     43 => 'ColorTempDaylight',
    2599     44 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16u[4]' },
    2600     48 => 'ColorTempShade',
    2601     49 => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16u[4]' },
    2602     53 => 'ColorTempCloudy',
    2603     54 => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16u[4]' },
    2604     58 => 'ColorTempTungsten',
    2605     59 => { Name => 'WB_RGGBLevelsFluorescent', Format => 'int16u[4]' },
    2606     63 => 'ColorTempFluorescent',
    2607     64 => { Name => 'WB_RGGBLevelsKelvin',      Format => 'int16u[4]' },
    2608     68 => 'ColorTempKelvin',
    2609     69 => { Name => 'WB_RGGBLevelsFlash',       Format => 'int16u[4]' },
    2610     73 => 'ColorTempFlash',
    2611     74 => { Name => 'WB_RGGBLevelsUnknown2',    Format => 'int16u[4]', Unknown => 1 },
    2612     78 => { Name => 'ColorTempUnknown2', Unknown => 1 },
    2613     79 => { Name => 'WB_RGGBLevelsUnknown3',    Format => 'int16u[4]', Unknown => 1 },
    2614     83 => { Name => 'ColorTempUnknown3', Unknown => 1 },
    2615     84 => { Name => 'WB_RGGBLevelsUnknown4',    Format => 'int16u[4]', Unknown => 1 },
    2616     88 => { Name => 'ColorTempUnknown4', Unknown => 1 },
    2617     89 => { Name => 'WB_RGGBLevelsUnknown5',    Format => 'int16u[4]', Unknown => 1 },
    2618     93 => { Name => 'ColorTempUnknown5', Unknown => 1 },
    2619     94 => { Name => 'WB_RGGBLevelsUnknown6',    Format => 'int16u[4]', Unknown => 1 },
    2620     98 => { Name => 'ColorTempUnknown6', Unknown => 1 },
    2621     99 => { Name => 'WB_RGGBLevelsUnknown7',    Format => 'int16u[4]', Unknown => 1 },
    2622     103 => { Name => 'ColorTempUnknown7', Unknown => 1 },
    2623     104 => { Name => 'WB_RGGBLevelsUnknown8',   Format => 'int16u[4]', Unknown => 1 },
    2624     108 => { Name => 'ColorTempUnknown8', Unknown => 1 },
    2625     109 => { Name => 'WB_RGGBLevelsUnknown9',   Format => 'int16u[4]', Unknown => 1 },
    2626     113 => { Name => 'ColorTempUnknown9', Unknown => 1 },
    2627     114 => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16u[4]', Unknown => 1 },
    2628     118 => { Name => 'ColorTempUnknown10', Unknown => 1 },
    2629     119 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16u[4]', Unknown => 1 },
    2630     123 => { Name => 'ColorTempUnknown11', Unknown => 1 },
    2631     124 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16u[4]', Unknown => 1 },
    2632     128 => { Name => 'ColorTempUnknown12', Unknown => 1 },
    2633     129 => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16u[4]', Unknown => 1 },
    2634     133 => { Name => 'ColorTempUnknown13', Unknown => 1 },
    2635     134 => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16u[4]', Unknown => 1 },
    2636     138 => { Name => 'ColorTempUnknown14', Unknown => 1 },
    2637     139 => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16u[4]', Unknown => 1 },
    2638     143 => { Name => 'ColorTempUnknown15', Unknown => 1 },
    2639     144 => { Name => 'WB_RGGBLevelsPC1',        Format => 'int16u[4]' },
    2640     148 => 'ColorTempPC1',
    2641     149 => { Name => 'WB_RGGBLevelsPC2',        Format => 'int16u[4]' },
    2642     153 => 'ColorTempPC2',
    2643     154 => { Name => 'WB_RGGBLevelsPC3',        Format => 'int16u[4]' },
    2644     158 => 'ColorTempPC3',
    2645     159 => { Name => 'WB_RGGBLevelsUnknown16',  Format => 'int16u[4]', Unknown => 1 },
    2646     163 => { Name => 'ColorTempUnknown16', Unknown => 1 },
    2647 );
    2648 
    2649 # Color balance (MakerNotes tag 0x4001) (ref 12)
    2650 %Image::ExifTool::Canon::ColorBalance3 = (
    2651     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2652     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2653     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2654     NOTES => 'This table is used by the 1DmkIIN, 5D, 30D and 400D.',
    2655     FORMAT => 'int16u',
    2656     FIRST_ENTRY => 0,
    2657     WRITABLE => 1,
    2658     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    2659     63 => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16u[4]' },
    2660     67 => 'ColorTempAsShot',
    2661     68 => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16u[4]' },
    2662     72 => 'ColorTempAuto',
    2663     # not sure exactly what 'Measured' values mean...
    2664     73 => { Name => 'WB_RGGBLevelsMeasured',    Format => 'int16u[4]' },
    2665     77 => 'ColorTempMeasured',
    2666     78 => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16u[4]' },
    2667     82 => 'ColorTempDaylight',
    2668     83 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16u[4]' },
    2669     87 => 'ColorTempShade',
    2670     88 => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16u[4]' },
    2671     92 => 'ColorTempCloudy',
    2672     93 => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16u[4]' },
    2673     97 => 'ColorTempTungsten',
    2674     98 => { Name => 'WB_RGGBLevelsFluorescent', Format => 'int16u[4]' },
    2675     102 => 'ColorTempFluorescent',
    2676     103 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16u[4]' },
    2677     107 => 'ColorTempKelvin',
    2678     108 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16u[4]' },
    2679     112 => 'ColorTempFlash',
    2680     113 => { Name => 'WB_RGGBLevelsPC1',        Format => 'int16u[4]' },
    2681     117 => 'ColorTempPC1',
    2682     118 => { Name => 'WB_RGGBLevelsPC2',        Format => 'int16u[4]' },
    2683     122 => 'ColorTempPC2',
    2684     123 => { Name => 'WB_RGGBLevelsPC3',        Format => 'int16u[4]' },
    2685     127 => 'ColorTempPC3',
    2686     128 => { Name => 'WB_RGGBLevelsCustom',     Format => 'int16u[4]' },
    2687     132 => 'ColorTempCustom',
    2688 );
    2689 
    2690 # Color information (MakerNotes tag 0x4003) (ref PH)
    2691 %Image::ExifTool::Canon::ColorInfo = (
    2692     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2693     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2694     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2695     WRITABLE => 1,
    2696     FORMAT => 'int16s',
    26975304    FIRST_ENTRY => 1,
    26985305    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    26995306    1 => {
    2700         Condition => '$$self{CameraMake} =~ /EOS-1D/',
    2701         Name => 'Saturation',
    2702     },
    2703     2 => 'ColorHue',
    2704     3 => {
    2705         Name => 'ColorSpace',
    2706         RawConv => '$val ? $val : undef', # ignore tag if zero
    2707         PrintConv => {
    2708             1 => 'sRGB',
    2709             2 => 'Adobe RGB',
    2710         },
    2711     },
     5307        # this is basically the inverse of WB_RGGBLevelsMeasured (ref 37)
     5308        Name => 'MeasuredRGGB',
     5309        Format => 'int16u[4]',
     5310    },
     5311    # 5 - observed values: 0, 1 - PH
    27125312);
    27135313
    27145314# Flags information (MakerNotes tag 0xb0) (ref PH)
    27155315%Image::ExifTool::Canon::Flags = (
    2716     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2717     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2718     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2719     WRITABLE => 1,
     5316    %binaryDataAttrs,
    27205317    FORMAT => 'int16s',
    27215318    FIRST_ENTRY => 1,
     
    27265323# Modified information (MakerNotes tag 0xb1) (ref PH)
    27275324%Image::ExifTool::Canon::ModifiedInfo = (
    2728     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    2729     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    2730     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    2731     WRITABLE => 1,
     5325    %binaryDataAttrs,
    27325326    FORMAT => 'int16s',
    27335327    FIRST_ENTRY => 1,
     
    27445338        Name => 'ModifiedSharpness',
    27455339        Notes => '1D and 5D only',
    2746         Condition => '$$self{CameraModel} =~ /\b(1D|5D)/',
     5340        Condition => '$$self{Model} =~ /\b(1D|5D)/',
    27475341    },
    27485342    3 => {
    2749         Name => 'ModifiedSharpnessFreq',
     5343        Name => 'ModifiedSharpnessFreq', # ModifiedPatternSharpness?
    27505344        PrintConv => {
    27515345            0 => 'n/a',
    2752             1 => 'Smoothest',
    2753             2 => 'Smooth',
     5346            1 => 'Lowest',
     5347            2 => 'Low',
    27545348            3 => 'Standard',
    2755             4 => 'Sharp',
    2756             5 => 'Sharpest',
     5349            4 => 'High',
     5350            5 => 'Highest',
    27575351        },
    27585352    },
     
    27645358        Name => 'ModifiedWhiteBalance',
    27655359        PrintConv => \%canonWhiteBalance,
     5360        SeparateTable => 'WhiteBalance',
    27665361    },
    27675362    9 => 'ModifiedColorTemp',
     
    27695364        Name => 'ModifiedPictureStyle',
    27705365        PrintHex => 1,
     5366        SeparateTable => 'PictureStyle',
    27715367        PrintConv => \%pictureStyles,
    27725368    },
     
    27785374);
    27795375
    2780 # canon composite tags
     5376# Preview image information (MakerNotes tag 0xb6)
     5377# - The 300D writes a 1536x1024 preview image that is accessed
     5378#   through this information - decoded by PH 12/14/03
     5379%Image::ExifTool::Canon::PreviewImageInfo = (
     5380    %binaryDataAttrs,
     5381    FORMAT => 'int32u',
     5382    FIRST_ENTRY => 1,
     5383    IS_OFFSET => [ 5 ],   # tag 5 is 'IsOffset'
     5384    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     5385# the size of the preview block in 2-byte increments
     5386#    0 => {
     5387#        Name => 'PreviewImageInfoWords',
     5388#    },
     5389    1 => {
     5390        Name => 'PreviewQuality',
     5391        PrintConv => \%canonQuality,
     5392    },
     5393    2 => {
     5394        Name => 'PreviewImageLength',
     5395        OffsetPair => 5,   # point to associated offset
     5396        DataTag => 'PreviewImage',
     5397        Protected => 2,
     5398    },
     5399    3 => 'PreviewImageWidth',
     5400    4 => 'PreviewImageHeight',
     5401    5 => {
     5402        Name => 'PreviewImageStart',
     5403        Flags => 'IsOffset',
     5404        OffsetPair => 2,  # associated byte count tagID
     5405        DataTag => 'PreviewImage',
     5406        Protected => 2,
     5407    },
     5408    # NOTE: The size of the PreviewImageInfo structure is incorrectly
     5409    # written as 48 bytes (Count=12, Format=int32u), but only the first
     5410    # 6 int32u values actually exist
     5411);
     5412
     5413# Sensor information (MakerNotes tag 0xe0) (ref 12)
     5414%Image::ExifTool::Canon::SensorInfo = (
     5415    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     5416    FORMAT => 'int16s',
     5417    FIRST_ENTRY => 1,
     5418    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     5419    # Note: Don't make these writable because it confuses Canon decoding software
     5420    # if these are changed
     5421    1 => 'SensorWidth',
     5422    2 => 'SensorHeight',
     5423    5 => 'SensorLeftBorder', #2
     5424    6 => 'SensorTopBorder', #2
     5425    7 => 'SensorRightBorder', #2
     5426    8 => 'SensorBottomBorder', #2
     5427    9 => { #22
     5428        Name => 'BlackMaskLeftBorder',
     5429        Notes => q{
     5430            coordinates for the area to the left or right of the image used to calculate
     5431            the average black level
     5432        },
     5433    },
     5434    10 => 'BlackMaskTopBorder', #22
     5435    11 => 'BlackMaskRightBorder', #22
     5436    12 => 'BlackMaskBottomBorder', #22
     5437);
     5438
     5439# Color data (MakerNotes tag 0x4001, count=582) (ref 12)
     5440%Image::ExifTool::Canon::ColorData1 = (
     5441    %binaryDataAttrs,
     5442    NOTES => 'These tags are used by the 20D and 350D.',
     5443    FORMAT => 'int16s',
     5444    FIRST_ENTRY => 0,
     5445    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5446    IS_SUBDIR => [ 0x4b ],
     5447    # 0x00: size of record in bytes - PH
     5448    # (dcraw 8.81 uses index 0x19 for WB)
     5449    0x19 => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16s[4]' },
     5450    0x1d => 'ColorTempAsShot',
     5451    0x1e => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16s[4]' },
     5452    0x22 => 'ColorTempAuto',
     5453    0x23 => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16s[4]' },
     5454    0x27 => 'ColorTempDaylight',
     5455    0x28 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16s[4]' },
     5456    0x2c => 'ColorTempShade',
     5457    0x2d => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16s[4]' },
     5458    0x31 => 'ColorTempCloudy',
     5459    0x32 => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16s[4]' },
     5460    0x36 => 'ColorTempTungsten',
     5461    0x37 => { Name => 'WB_RGGBLevelsFluorescent', Format => 'int16s[4]' },
     5462    0x3b => 'ColorTempFluorescent',
     5463    0x3c => { Name => 'WB_RGGBLevelsFlash',       Format => 'int16s[4]' },
     5464    0x40 => 'ColorTempFlash',
     5465    0x41 => { Name => 'WB_RGGBLevelsCustom1',     Format => 'int16s[4]' },
     5466    0x45 => 'ColorTempCustom1',
     5467    0x46 => { Name => 'WB_RGGBLevelsCustom2',     Format => 'int16s[4]' },
     5468    0x4a => 'ColorTempCustom2',
     5469    0x4b => { #PH
     5470        Name => 'ColorCalib',
     5471        Format => 'undef[120]',
     5472        Unknown => 1, # (all tags are unknown, so we can avoid processing entire directory)
     5473        Notes => 'A, B, C, Temperature',
     5474        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
     5475    },
     5476);
     5477
     5478# Color data (MakerNotes tag 0x4001, count=653) (ref 12)
     5479%Image::ExifTool::Canon::ColorData2 = (
     5480    %binaryDataAttrs,
     5481    NOTES => 'These tags are used by the 1DmkII and 1DSmkII.',
     5482    FORMAT => 'int16s',
     5483    FIRST_ENTRY => 0,
     5484    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5485    IS_SUBDIR => [ 0xa4 ],
     5486    0x18 => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
     5487    0x1c => 'ColorTempAuto',
     5488    0x1d => { Name => 'WB_RGGBLevelsUnknown',    Format => 'int16s[4]', Unknown => 1 },
     5489    0x21 => { Name => 'ColorTempUnknown', Unknown => 1 },
     5490    # (dcraw 8.81 uses index 0x22 for WB)
     5491    0x22 => { Name => 'WB_RGGBLevelsAsShot',     Format => 'int16s[4]' },
     5492    0x26 => 'ColorTempAsShot',
     5493    0x27 => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
     5494    0x2b => 'ColorTempDaylight',
     5495    0x2c => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
     5496    0x30 => 'ColorTempShade',
     5497    0x31 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
     5498    0x35 => 'ColorTempCloudy',
     5499    0x36 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
     5500    0x3a => 'ColorTempTungsten',
     5501    0x3b => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
     5502    0x3f => 'ColorTempFluorescent',
     5503    0x40 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
     5504    0x44 => 'ColorTempKelvin',
     5505    0x45 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
     5506    0x49 => 'ColorTempFlash',
     5507    0x4a => { Name => 'WB_RGGBLevelsUnknown2',   Format => 'int16s[4]', Unknown => 1 },
     5508    0x4e => { Name => 'ColorTempUnknown2', Unknown => 1 },
     5509    0x4f => { Name => 'WB_RGGBLevelsUnknown3',   Format => 'int16s[4]', Unknown => 1 },
     5510    0x53 => { Name => 'ColorTempUnknown3', Unknown => 1 },
     5511    0x54 => { Name => 'WB_RGGBLevelsUnknown4',   Format => 'int16s[4]', Unknown => 1 },
     5512    0x58 => { Name => 'ColorTempUnknown4', Unknown => 1 },
     5513    0x59 => { Name => 'WB_RGGBLevelsUnknown5',   Format => 'int16s[4]', Unknown => 1 },
     5514    0x5d => { Name => 'ColorTempUnknown5', Unknown => 1 },
     5515    0x5e => { Name => 'WB_RGGBLevelsUnknown6',   Format => 'int16s[4]', Unknown => 1 },
     5516    0x62 => { Name => 'ColorTempUnknown6', Unknown => 1 },
     5517    0x63 => { Name => 'WB_RGGBLevelsUnknown7',   Format => 'int16s[4]', Unknown => 1 },
     5518    0x67 => { Name => 'ColorTempUnknown7', Unknown => 1 },
     5519    0x68 => { Name => 'WB_RGGBLevelsUnknown8',   Format => 'int16s[4]', Unknown => 1 },
     5520    0x6c => { Name => 'ColorTempUnknown8', Unknown => 1 },
     5521    0x6d => { Name => 'WB_RGGBLevelsUnknown9',   Format => 'int16s[4]', Unknown => 1 },
     5522    0x71 => { Name => 'ColorTempUnknown9', Unknown => 1 },
     5523    0x72 => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
     5524    0x76 => { Name => 'ColorTempUnknown10', Unknown => 1 },
     5525    0x77 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
     5526    0x7b => { Name => 'ColorTempUnknown11', Unknown => 1 },
     5527    0x7c => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
     5528    0x80 => { Name => 'ColorTempUnknown12', Unknown => 1 },
     5529    0x81 => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
     5530    0x85 => { Name => 'ColorTempUnknown13', Unknown => 1 },
     5531    0x86 => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16s[4]', Unknown => 1 },
     5532    0x8a => { Name => 'ColorTempUnknown14', Unknown => 1 },
     5533    0x8b => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16s[4]', Unknown => 1 },
     5534    0x8f => { Name => 'ColorTempUnknown15', Unknown => 1 },
     5535    0x90 => { Name => 'WB_RGGBLevelsPC1',        Format => 'int16s[4]' },
     5536    0x94 => 'ColorTempPC1',
     5537    0x95 => { Name => 'WB_RGGBLevelsPC2',        Format => 'int16s[4]' },
     5538    0x99 => 'ColorTempPC2',
     5539    0x9a => { Name => 'WB_RGGBLevelsPC3',        Format => 'int16s[4]' },
     5540    0x9e => 'ColorTempPC3',
     5541    0x9f => { Name => 'WB_RGGBLevelsUnknown16',  Format => 'int16s[4]', Unknown => 1 },
     5542    0xa3 => { Name => 'ColorTempUnknown16', Unknown => 1 },
     5543    0xa4 => { #PH
     5544        Name => 'ColorCalib',
     5545        Format => 'undef[120]',
     5546        Unknown => 1,
     5547        Notes => 'A, B, C, Temperature',
     5548        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
     5549    },
     5550    0x26a => { #PH
     5551        Name => 'RawMeasuredRGGB',
     5552        Format => 'int32u[4]',
     5553        Notes => 'raw MeasuredRGGB values, before normalization',
     5554        # swap words because the word ordering is big-endian, opposite to the byte ordering
     5555        ValueConv => \&SwapWords,
     5556        ValueConvInv => \&SwapWords,
     5557    },
     5558);
     5559
     5560# Color data (MakerNotes tag 0x4001, count=796) (ref 12)
     5561%Image::ExifTool::Canon::ColorData3 = (
     5562    %binaryDataAttrs,
     5563    NOTES => 'These tags are used by the 1DmkIIN, 5D, 30D and 400D.',
     5564    FORMAT => 'int16s',
     5565    FIRST_ENTRY => 0,
     5566    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5567    IS_SUBDIR => [ 0x85 ],
     5568    0x00 => { #PH
     5569        Name => 'ColorDataVersion',
     5570        PrintConv => {
     5571            1 => '1 (1DmkIIN/5D/30D/400D)',
     5572        },
     5573    },
     5574    # 0x01-0x3e: RGGB coefficients, apparently specific to the
     5575    # individual camera and possibly used for color calibration (ref 37)
     5576    # (dcraw 8.81 uses index 0x3f for WB)
     5577    0x3f => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16s[4]' },
     5578    0x43 => 'ColorTempAsShot',
     5579    0x44 => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16s[4]' },
     5580    0x48 => 'ColorTempAuto',
     5581    # not sure exactly what 'Measured' values mean...
     5582    0x49 => { Name => 'WB_RGGBLevelsMeasured',    Format => 'int16s[4]' },
     5583    0x4d => 'ColorTempMeasured',
     5584    0x4e => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16s[4]' },
     5585    0x52 => 'ColorTempDaylight',
     5586    0x53 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16s[4]' },
     5587    0x57 => 'ColorTempShade',
     5588    0x58 => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16s[4]' },
     5589    0x5c => 'ColorTempCloudy',
     5590    0x5d => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16s[4]' },
     5591    0x61 => 'ColorTempTungsten',
     5592    0x62 => { Name => 'WB_RGGBLevelsFluorescent', Format => 'int16s[4]' },
     5593    0x66 => 'ColorTempFluorescent',
     5594    0x67 => { Name => 'WB_RGGBLevelsKelvin',      Format => 'int16s[4]' },
     5595    0x6b => 'ColorTempKelvin',
     5596    0x6c => { Name => 'WB_RGGBLevelsFlash',       Format => 'int16s[4]' },
     5597    0x70 => 'ColorTempFlash',
     5598    0x71 => { Name => 'WB_RGGBLevelsPC1',         Format => 'int16s[4]' },
     5599    0x75 => 'ColorTempPC1',
     5600    0x76 => { Name => 'WB_RGGBLevelsPC2',         Format => 'int16s[4]' },
     5601    0x7a => 'ColorTempPC2',
     5602    0x7b => { Name => 'WB_RGGBLevelsPC3',         Format => 'int16s[4]' },
     5603    0x7f => 'ColorTempPC3',
     5604    0x80 => { Name => 'WB_RGGBLevelsCustom',      Format => 'int16s[4]' },
     5605    0x84 => 'ColorTempCustom',
     5606    0x85 => { #37
     5607        Name => 'ColorCalib',
     5608        Format => 'undef[120]',
     5609        Unknown => 1,
     5610        Notes => 'B, C, A, Temperature',
     5611        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
     5612    },
     5613    # 0xc5-0xc7: looks like black levels (ref 37)
     5614    # 0xc8-0x1c7: some sort of color table (ref 37)
     5615    0x248 => { #37
     5616        Name => 'FlashOutput',
     5617        ValueConv => '$val >= 255 ? 255 : exp(($val-200)/16*log(2))',
     5618        ValueConvInv => '$val == 255 ? 255 : 200 + log($val)*16/log(2)',
     5619        PrintConv => '$val == 255 ? "Strobe or Misfire" : sprintf("%.0f%%", $val * 100)',
     5620        PrintConvInv => '$val =~ /^(\d(\.?\d*))/ ? $1 / 100 : 255',
     5621    },
     5622    0x249 => { #37
     5623        Name => 'FlashBatteryLevel',
     5624        # calibration points for external flash: 144=3.76V (almost empty), 192=5.24V (full)
     5625        # - have seen a value of 201 with internal flash
     5626        PrintConv => '$val ? sprintf("%.2fV", $val * 5 / 186) : "n/a"',
     5627        PrintConvInv => '$val=~/^(\d+\.\d+)\s*V?$/i ? int($val*186/5+0.5) : 0',
     5628    },
     5629    0x24a => { #37
     5630        Name => 'ColorTempFlashData',
     5631        # 0 for no external flash, 35980 for 'Strobe or Misfire'
     5632        # (lower than ColorTempFlash by up to 200 degrees)
     5633        RawConv => '($val < 2000 or $val > 12000) ? undef : $val',
     5634    },
     5635    # 0x24b: inverse relationship with flash power (ref 37)
     5636    # 0x286: has value 256 for correct exposure, less for under exposure (seen 96 minimum) (ref 37)
     5637    0x287 => { #37
     5638        Name => 'MeasuredRGGBData',
     5639        Format => 'int32u[4]',
     5640        Notes => 'MeasuredRGGB may be derived from these data values',
     5641        # swap words because the word ordering is big-endian, opposite to the byte ordering
     5642        ValueConv => \&SwapWords,
     5643        ValueConvInv => \&SwapWords,
     5644    },
     5645    # 0x297: ranges from -10 to 30, higher for high ISO (ref 37)
     5646);
     5647
     5648# Color data (MakerNotes tag 0x4001, count=674|692|702|1227|1250|1251|1337|1338|1346) (ref PH)
     5649%Image::ExifTool::Canon::ColorData4 = (
     5650    %binaryDataAttrs,
     5651    NOTES => q{
     5652        These tags are used by the 1DmkIII, 1DSmkIII, 1DmkIV, 5DmkII, 7D, 40D, 50D,
     5653        450D, 500D, 550D, 1000D and 1100D.
     5654    },
     5655    FORMAT => 'int16s',
     5656    FIRST_ENTRY => 0,
     5657    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5658    IS_SUBDIR => [ 0x3f, 0xa8 ],
     5659    0x00 => {
     5660        Name => 'ColorDataVersion',
     5661        PrintConv => {
     5662            2 => '2 (1DmkIII)',
     5663            3 => '3 (40D)',
     5664            4 => '4 (1DSmkIII)',
     5665            5 => '5 (450D/1000D)',
     5666            6 => '6 (50D/5DmkII)',
     5667            7 => '7 (500D/550D/7D/1DmkIV)',
     5668            9 => '9 (1100D)',
     5669        },
     5670    },
     5671    # 0x01-0x18: unknown RGGB coefficients (int16s[4]) (50D)
     5672    # (dcraw 8.81 uses index 0x3f for WB)
     5673    0x3f => {
     5674        Name => 'ColorCoefs',
     5675        Format => 'undef[210]', # ColorTempUnknown11 is last entry
     5676        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCoefs' }
     5677    },
     5678    0xa8 => {
     5679        Name => 'ColorCalib',
     5680        Format => 'undef[120]',
     5681        Unknown => 1,
     5682        Notes => 'B, C, A, Temperature',
     5683        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
     5684    },
     5685    0x280 => { #PH
     5686        Name => 'RawMeasuredRGGB',
     5687        Format => 'int32u[4]',
     5688        Notes => 'raw MeasuredRGGB values, before normalization',
     5689        # swap words because the word ordering is big-endian, opposite to the byte ordering
     5690        ValueConv => \&SwapWords,
     5691        ValueConvInv => \&SwapWords,
     5692    },
     5693);
     5694
     5695# color coefficients (ref PH)
     5696%Image::ExifTool::Canon::ColorCoefs = (
     5697    %binaryDataAttrs,
     5698    FORMAT => 'int16s',
     5699    FIRST_ENTRY => 0,
     5700    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5701    0x00 => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16s[4]' },
     5702    0x04 => 'ColorTempAsShot',
     5703    0x05 => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16s[4]' },
     5704    0x09 => 'ColorTempAuto',
     5705    0x0a => { Name => 'WB_RGGBLevelsMeasured',    Format => 'int16s[4]' },
     5706    0x0e => 'ColorTempMeasured',
     5707    # the following Unknown values are set for the 50D and 5DmkII, and the
     5708    # SRAW images of the 40D, and affect thumbnail display for the 50D/5DmkII
     5709    # and conversion for all modes of the 40D
     5710    0x0f => { Name => 'WB_RGGBLevelsUnknown',     Format => 'int16s[4]', Unknown => 1 },
     5711    0x13 => { Name => 'ColorTempUnknown', Unknown => 1 },
     5712    0x14 => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16s[4]' },
     5713    0x18 => 'ColorTempDaylight',
     5714    0x19 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16s[4]' },
     5715    0x1d => 'ColorTempShade',
     5716    0x1e => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16s[4]' },
     5717    0x22 => 'ColorTempCloudy',
     5718    0x23 => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16s[4]' },
     5719    0x27 => 'ColorTempTungsten',
     5720    0x28 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
     5721    0x2c => 'ColorTempFluorescent',
     5722    # (changing the Kelvin values has no effect on image in DPP... why not?)
     5723    0x2d => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
     5724    0x31 => 'ColorTempKelvin',
     5725    0x32 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
     5726    0x36 => 'ColorTempFlash',
     5727    0x37 => { Name => 'WB_RGGBLevelsUnknown2',   Format => 'int16s[4]', Unknown => 1 },
     5728    0x3b => { Name => 'ColorTempUnknown2', Unknown => 1 },
     5729    0x3c => { Name => 'WB_RGGBLevelsUnknown3',   Format => 'int16s[4]', Unknown => 1 },
     5730    0x40 => { Name => 'ColorTempUnknown3', Unknown => 1 },
     5731    0x41 => { Name => 'WB_RGGBLevelsUnknown4',   Format => 'int16s[4]', Unknown => 1 },
     5732    0x45 => { Name => 'ColorTempUnknown4', Unknown => 1 },
     5733    0x46 => { Name => 'WB_RGGBLevelsUnknown5',   Format => 'int16s[4]', Unknown => 1 },
     5734    0x4a => { Name => 'ColorTempUnknown5', Unknown => 1 },
     5735    0x4b => { Name => 'WB_RGGBLevelsUnknown6',   Format => 'int16s[4]', Unknown => 1 },
     5736    0x4f => { Name => 'ColorTempUnknown6', Unknown => 1 },
     5737    0x50 => { Name => 'WB_RGGBLevelsUnknown7',   Format => 'int16s[4]', Unknown => 1 },
     5738    0x54 => { Name => 'ColorTempUnknown7', Unknown => 1 },
     5739    0x55 => { Name => 'WB_RGGBLevelsUnknown8',   Format => 'int16s[4]', Unknown => 1 },
     5740    0x59 => { Name => 'ColorTempUnknown8', Unknown => 1 },
     5741    0x5a => { Name => 'WB_RGGBLevelsUnknown9',   Format => 'int16s[4]', Unknown => 1 },
     5742    0x5e => { Name => 'ColorTempUnknown9', Unknown => 1 },
     5743    0x5f => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
     5744    0x63 => { Name => 'ColorTempUnknown10', Unknown => 1 },
     5745    0x64 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
     5746    0x68 => { Name => 'ColorTempUnknown11', Unknown => 1 },
     5747    0x69 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
     5748    0x6d => { Name => 'ColorTempUnknown12', Unknown => 1 },
     5749    0x6e => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
     5750    0x72 => { Name => 'ColorTempUnknown13', Unknown => 1 },
     5751);
     5752
     5753# color calibration (ref 37)
     5754%Image::ExifTool::Canon::ColorCalib = (
     5755    %binaryDataAttrs,
     5756    FORMAT => 'int16s',
     5757    FIRST_ENTRY => 0,
     5758    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5759    # these coefficients are in a different order compared to older
     5760    # models (A,B,C in ColorData1/2 vs. C,A,B in ColorData3/4) - PH
     5761    # Coefficient A most closely matches the blue curvature, and
     5762    # coefficient B most closely matches the red curvature, but the match
     5763    # is not perfect, and I don't know what coefficient C is for (certainly
     5764    # not a green coefficient) - PH
     5765    NOTES => q{
     5766        Camera color calibration data.  For the 20D, 350D, 1DmkII and 1DSmkII the
     5767        order of the cooefficients is A, B, C, Temperature, but for newer models it
     5768        is B, C, A, Temperature.  These tags are extracted only when the Unknown
     5769        option is used.
     5770    },
     5771    0x00 => { Name => 'CameraColorCalibration01', %cameraColorCalibration },
     5772    0x04 => { Name => 'CameraColorCalibration02', %cameraColorCalibration },
     5773    0x08 => { Name => 'CameraColorCalibration03', %cameraColorCalibration },
     5774    0x0c => { Name => 'CameraColorCalibration04', %cameraColorCalibration },
     5775    0x10 => { Name => 'CameraColorCalibration05', %cameraColorCalibration },
     5776    0x14 => { Name => 'CameraColorCalibration06', %cameraColorCalibration },
     5777    0x18 => { Name => 'CameraColorCalibration07', %cameraColorCalibration },
     5778    0x1c => { Name => 'CameraColorCalibration08', %cameraColorCalibration },
     5779    0x20 => { Name => 'CameraColorCalibration09', %cameraColorCalibration },
     5780    0x24 => { Name => 'CameraColorCalibration10', %cameraColorCalibration },
     5781    0x28 => { Name => 'CameraColorCalibration11', %cameraColorCalibration },
     5782    0x2c => { Name => 'CameraColorCalibration12', %cameraColorCalibration },
     5783    0x30 => { Name => 'CameraColorCalibration13', %cameraColorCalibration },
     5784    0x34 => { Name => 'CameraColorCalibration14', %cameraColorCalibration },
     5785    0x38 => { Name => 'CameraColorCalibration15', %cameraColorCalibration },
     5786);
     5787
     5788# Color data (MakerNotes tag 0x4001, count=5120) (ref PH)
     5789%Image::ExifTool::Canon::ColorData5 = (
     5790    %binaryDataAttrs,
     5791    NOTES => 'These tags are used by the PowerShot G10.',
     5792    FORMAT => 'int16s',
     5793    FIRST_ENTRY => 0,
     5794    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5795    IS_SUBDIR => [ 0x47 ],
     5796    # 0x00 - oddly, this isn't ColorDataVersion (probably should have been version 8)
     5797    0x47 => {
     5798        Name => 'ColorCoefs',
     5799        Format => 'undef[230]', # ColorTempUnknown13 is last entry
     5800        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCoefs' }
     5801    },
     5802    0xba => { Name => 'CameraColorCalibration01', %cameraColorCalibration2,
     5803              Notes => 'B, C, A, D, Temperature' },
     5804    0xbf => { Name => 'CameraColorCalibration02', %cameraColorCalibration2 },
     5805    0xc4 => { Name => 'CameraColorCalibration03', %cameraColorCalibration2 },
     5806    0xc9 => { Name => 'CameraColorCalibration04', %cameraColorCalibration2 },
     5807    0xce => { Name => 'CameraColorCalibration05', %cameraColorCalibration2 },
     5808    0xd3 => { Name => 'CameraColorCalibration06', %cameraColorCalibration2 },
     5809    0xd8 => { Name => 'CameraColorCalibration07', %cameraColorCalibration2 },
     5810    0xdd => { Name => 'CameraColorCalibration08', %cameraColorCalibration2 },
     5811    0xe2 => { Name => 'CameraColorCalibration09', %cameraColorCalibration2 },
     5812    0xe7 => { Name => 'CameraColorCalibration10', %cameraColorCalibration2 },
     5813    0xec => { Name => 'CameraColorCalibration11', %cameraColorCalibration2 },
     5814    0xf1 => { Name => 'CameraColorCalibration12', %cameraColorCalibration2 },
     5815    0xf6 => { Name => 'CameraColorCalibration13', %cameraColorCalibration2 },
     5816    0xfb => { Name => 'CameraColorCalibration14', %cameraColorCalibration2 },
     5817    0x100=> { Name => 'CameraColorCalibration15', %cameraColorCalibration2 },
     5818);
     5819
     5820# Color data (MakerNotes tag 0x4001, count=1273) (ref PH)
     5821%Image::ExifTool::Canon::ColorData6 = (
     5822    %binaryDataAttrs,
     5823    NOTES => 'These tags are used by the EOS 600D.',
     5824    FORMAT => 'int16s',
     5825    FIRST_ENTRY => 0,
     5826    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5827    IS_SUBDIR => [ 0xbc ],
     5828    0x00 => {
     5829        Name => 'ColorDataVersion',
     5830        PrintConv => {
     5831            10 => '10 (600D)',
     5832        },
     5833    },
     5834    0x3f => { Name => 'WB_RGGBLevelsAsShot',     Format => 'int16s[4]' },
     5835    0x43 => 'ColorTempAsShot',
     5836    0x44 => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
     5837    0x48 => 'ColorTempAuto',
     5838    0x49 => { Name => 'WB_RGGBLevelsMeasured',   Format => 'int16s[4]' },
     5839    0x4d => 'ColorTempMeasured',
     5840    0x4e => { Name => 'WB_RGGBLevelsUnknown',    Format => 'int16s[4]', Unknown => 1 },
     5841    0x52 => { Name => 'ColorTempUnknown', Unknown => 1 },
     5842    0x53 => { Name => 'WB_RGGBLevelsUnknown2',   Format => 'int16s[4]', Unknown => 1 },
     5843    0x57 => { Name => 'ColorTempUnknown2', Unknown => 1 },
     5844    0x58 => { Name => 'WB_RGGBLevelsUnknown3',   Format => 'int16s[4]', Unknown => 1 },
     5845    0x5c => { Name => 'ColorTempUnknown3', Unknown => 1 },
     5846    0x5d => { Name => 'WB_RGGBLevelsUnknown4',   Format => 'int16s[4]', Unknown => 1 },
     5847    0x61 => { Name => 'ColorTempUnknown4', Unknown => 1 },
     5848    0x62 => { Name => 'WB_RGGBLevelsUnknown5',   Format => 'int16s[4]', Unknown => 1 },
     5849    0x66 => { Name => 'ColorTempUnknown5', Unknown => 1 },
     5850    0x67 => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
     5851    0x6b => 'ColorTempDaylight',
     5852    0x6c => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
     5853    0x70 => 'ColorTempShade',
     5854    0x71 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
     5855    0x75 => 'ColorTempCloudy',
     5856    0x76 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
     5857    0x7a => 'ColorTempTungsten',
     5858    0x7b => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
     5859    0x7f => 'ColorTempFluorescent',
     5860    0x80 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
     5861    0x84 => 'ColorTempKelvin',
     5862    0x85 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
     5863    0x89 => 'ColorTempFlash',
     5864    0x8a => { Name => 'WB_RGGBLevelsUnknown6',   Format => 'int16s[4]', Unknown => 1 },
     5865    0x8e => { Name => 'ColorTempUnknown6', Unknown => 1 },
     5866    0x8f => { Name => 'WB_RGGBLevelsUnknown7',   Format => 'int16s[4]', Unknown => 1 },
     5867    0x93 => { Name => 'ColorTempUnknown7', Unknown => 1 },
     5868    0x94 => { Name => 'WB_RGGBLevelsUnknown8',   Format => 'int16s[4]', Unknown => 1 },
     5869    0x98 => { Name => 'ColorTempUnknown8', Unknown => 1 },
     5870    0x99 => { Name => 'WB_RGGBLevelsUnknown9',   Format => 'int16s[4]', Unknown => 1 },
     5871    0x9d => { Name => 'ColorTempUnknown9', Unknown => 1 },
     5872    0x9e => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
     5873    0xa2 => { Name => 'ColorTempUnknown10', Unknown => 1 },
     5874    0xa3 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
     5875    0xa7 => { Name => 'ColorTempUnknown11', Unknown => 1 },
     5876    0xa8 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
     5877    0xac => { Name => 'ColorTempUnknown12', Unknown => 1 },
     5878    0xad => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
     5879    0xb1 => { Name => 'ColorTempUnknown13', Unknown => 1 },
     5880    0xb2 => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16s[4]', Unknown => 1 },
     5881    0xb6 => { Name => 'ColorTempUnknown14', Unknown => 1 },
     5882    0xb7 => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16s[4]', Unknown => 1 },
     5883    0xbb => { Name => 'ColorTempUnknown15', Unknown => 1 },
     5884    0xbc => {
     5885        Name => 'ColorCalib',
     5886        Format => 'undef[120]',
     5887        Unknown => 1,
     5888        Notes => 'B, C, A, Temperature',
     5889        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
     5890    },
     5891    0x194 => { #PH
     5892        Name => 'RawMeasuredRGGB',
     5893        Format => 'int32u[4]',
     5894        Notes => 'raw MeasuredRGGB values, before normalization',
     5895        # swap words because the word ordering is big-endian, opposite to the byte ordering
     5896        ValueConv => \&SwapWords,
     5897        ValueConvInv => \&SwapWords,
     5898    },
     5899);
     5900
     5901# Unknown color data (MakerNotes tag 0x4001)
     5902%Image::ExifTool::Canon::ColorDataUnknown = (
     5903    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     5904    FORMAT => 'int16s',
     5905    FIRST_ENTRY => 0,
     5906    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5907);
     5908
     5909# Color information (MakerNotes tag 0x4003) (ref PH)
     5910%Image::ExifTool::Canon::ColorInfo = (
     5911    %binaryDataAttrs,
     5912    FORMAT => 'int16s',
     5913    FIRST_ENTRY => 1,
     5914    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5915    1 => {
     5916        Condition => '$$self{Model} =~ /EOS-1D/',
     5917        Name => 'Saturation',
     5918        %Image::ExifTool::Exif::printParameter,
     5919    },
     5920    2 => {
     5921        Name => 'ColorTone',
     5922        %Image::ExifTool::Exif::printParameter,
     5923    },
     5924    3 => {
     5925        Name => 'ColorSpace',
     5926        RawConv => '$val ? $val : undef', # ignore tag if zero
     5927        PrintConv => {
     5928            1 => 'sRGB',
     5929            2 => 'Adobe RGB',
     5930        },
     5931    },
     5932);
     5933
     5934# AF micro-adjustment information (MakerNotes tag 0x4013) (ref PH)
     5935%Image::ExifTool::Canon::AFMicroAdj = (
     5936    %binaryDataAttrs,
     5937    FORMAT => 'int32s',
     5938    FIRST_ENTRY => 1,
     5939    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5940    1 => {
     5941        Name => 'AFMicroAdjActive',
     5942        PrintConv => {
     5943            0 => 'No',
     5944            1 => 'Yes',
     5945        },
     5946    },
     5947    2 => {
     5948        Name => 'AFMicroAdjValue',
     5949        Format => 'rational64s',
     5950    },
     5951);
     5952
     5953# Vignetting correction information (MakerNotes tag 0x4015)
     5954%Image::ExifTool::Canon::VignettingCorr = (
     5955    %binaryDataAttrs,
     5956    FORMAT => 'int16s',
     5957    FIRST_ENTRY => 1,
     5958    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5959    NOTES => q{
     5960        This information is found in images from the 1DmkIV, 5DmkII, 7D, 50D, 500D
     5961        and 550D.
     5962    },
     5963    # 0 => 'PeripheralLightingVersion', value = 0x1000
     5964    2 => {
     5965        Name => 'PeripheralLighting',
     5966        PrintConv => { 0 => 'Off', 1 => 'On' },
     5967    },
     5968    6 => 'PeripheralLightingValue',
     5969    # 10 - flags?
     5970    11 => {
     5971        Name => 'OriginalImageWidth',
     5972        Notes => 'full size of original image before being rotated or scaled in camera',
     5973    },
     5974    12 => 'OriginalImageHeight',
     5975);
     5976
     5977# More Vignetting correction information (MakerNotes tag 0x4016)
     5978%Image::ExifTool::Canon::VignettingCorr2 = (
     5979    %binaryDataAttrs,
     5980    FORMAT => 'int32s',
     5981    FIRST_ENTRY => 1,
     5982    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5983    5 => {
     5984        Name => 'PeripheralLightingSetting',
     5985        PrintConv => { 0 => 'Off', 1 => 'On' },
     5986    },
     5987);
     5988
     5989# Auto Lighting Optimizater information (MakerNotes tag 0x4018) (ref PH)
     5990%Image::ExifTool::Canon::LightingOpt = (
     5991    %binaryDataAttrs,
     5992    FORMAT => 'int32s',
     5993    FIRST_ENTRY => 1,
     5994    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     5995    NOTES => 'This information is new in images from the EOS 7D.',
     5996    2 => {
     5997        Name => 'AutoLightingOptimizer',
     5998        PrintConv => {
     5999            0 => 'Standard',
     6000            1 => 'Low',
     6001            2 => 'Strong',
     6002            3 => 'Off',
     6003        },
     6004    },
     6005);
     6006
     6007# Lens information (MakerNotes tag 0x4019) (ref 20)
     6008%Image::ExifTool::Canon::LensInfo = (
     6009    %binaryDataAttrs,
     6010    FIRST_ENTRY => 0,
     6011    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     6012    0 => { # this doesn't seem to be valid for some models (ie. 550D, 7D?, 1DmkIV?)
     6013        Name => 'LensSerialNumber',
     6014        Notes => q{
     6015            apparently this is an internal serial number because it doesn't correspond
     6016            to the one printed on the lens
     6017        },
     6018        Condition => '$$valPt !~ /^\0\0\0\0/', # (rules out 550D and older lenses)
     6019        Format => 'undef[5]',
     6020        ValueConv => 'unpack("H*", $val)',
     6021        ValueConvInv => 'pack("H*", $val)',
     6022    },
     6023);
     6024
     6025# Subject mode ambience information (MakerNotes tag 0x4020) (ref PH)
     6026%Image::ExifTool::Canon::Ambience = (
     6027    %binaryDataAttrs,
     6028    FORMAT => 'int32s',
     6029    FIRST_ENTRY => 1,
     6030    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     6031    1 => {
     6032        Name => 'AmbienceSelection',
     6033        PrintConv => {
     6034            0 => 'Standard',
     6035            1 => 'Vivid',
     6036            2 => 'Warm',
     6037            3 => 'Soft',
     6038            4 => 'Cool',
     6039            5 => 'Intense',
     6040            6 => 'Brighter',
     6041            7 => 'Darker',
     6042            8 => 'Monochrome',
     6043        },
     6044    },
     6045);
     6046
     6047# Creative filter information (MakerNotes tag 0x4024) (ref PH)
     6048%Image::ExifTool::Canon::FilterInfo = (
     6049    PROCESS_PROC => \&ProcessFilters,
     6050    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     6051    NOTES => 'Information about creative filter settings.',
     6052    0x101 => {
     6053        Name => 'GrainyBWFilter',
     6054        Description => 'Grainy B/W Filter',
     6055        PrintConv => '$val == -1 ? "Off" : "On ($val)"',
     6056        PrintConvInv => '$val =~ /([-+]?\d+)/ ? $1 : -1',
     6057    },
     6058    0x201 => {
     6059        Name => 'SoftFocusFilter',
     6060        PrintConv => '$val == -1 ? "Off" : "On ($val)"',
     6061        PrintConvInv => '$val =~ /([-+]?\d+)/ ? $1 : -1',
     6062    },
     6063    0x301 => {
     6064        Name => 'ToyCameraFilter',
     6065        PrintConv => '$val == -1 ? "Off" : "On ($val)"',
     6066        PrintConvInv => '$val =~ /([-+]?\d+)/ ? $1 : -1',
     6067    },
     6068    0x401 => {
     6069        Name => 'MiniatureFilter',
     6070        PrintConv => '$val == -1 ? "Off" : "On ($val)"',
     6071        PrintConvInv => '$val =~ /([-+]?\d+)/ ? $1 : -1',
     6072    },
     6073    0x0402 => {
     6074        Name => 'MiniatureFilterOrientation',
     6075        PrintConv => {
     6076            0 => 'Horizontal',
     6077            1 => 'Vertical',
     6078        },
     6079    },
     6080    0x403=> 'MiniatureFilterPosition',
     6081    # 0x404 - value: 0, 345, 518, ... (miniature filter width maybe?)
     6082);
     6083
     6084# Canon CNTH atoms (ref PH)
     6085%Image::ExifTool::Canon::CNTH = (
     6086    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Video' },
     6087    NOTES => q{
     6088        Canon-specific QuickTime tags found in the CNTH atom of MOV videos from some
     6089        cameras such as the PowerShot S95.
     6090    },
     6091    CNDA => {
     6092        Name => 'ThumbnailImage',
     6093        Format => 'undef',
     6094        Notes => 'the full THM image, embedded metadata is extracted as the first sub-document',
     6095        RawConv => q{
     6096            $$self{DOC_NUM} = ++$$self{DOC_COUNT};
     6097            $self->ExtractInfo(\$val, { ReEntry => 1 });
     6098            $$self{DOC_NUM} = 0;
     6099            return \$val;
     6100        },
     6101    },
     6102);
     6103
     6104# Canon composite tags
    27816105%Image::ExifTool::Canon::Composite = (
    27826106    GROUPS => { 2 => 'Camera' },
     
    27846108        Require => {
    27856109            0 => 'ContinuousDrive',
    2786             1 => 'Self-timer',
     6110            1 => 'SelfTimer',
    27876111        },
    27886112        ValueConv => '$val[0] ? 0 : ($val[1] ? 1 : 2)',
    27896113        PrintConv => {
    2790             0 => 'Continuous shooting',
     6114            0 => 'Continuous Shooting',
    27916115            1 => 'Self-timer Operation',
    2792             2 => 'Single-frame shooting',
     6116            2 => 'Single-frame Shooting',
    27936117        },
    27946118    },
     
    28126136        },
    28136137        ValueConv => '$val[3] * ($val[2] ? $val[2] : 1)',
    2814         PrintConv => '$prt[3] . ($val[2] ? sprintf(" (35mm equivalent: %s)",Image::ExifTool::Canon::PrintFocalRange(@val)) : "")',
     6138        PrintConv => '$prt[3] . ($val[2] ? sprintf(" (35 mm equivalent: %s)",Image::ExifTool::Canon::PrintFocalRange(@val)) : "")',
    28156139    },
    28166140    ShootingMode => {
     
    28196143            1 => 'EasyMode',
    28206144        },
    2821         ValueConv => '$val[0] ? $val[0] : $val[1] + 10',
    2822         PrintConv => '$val[0] ? $prt[0] : $prt[1]',
     6145        Desire => {
     6146            2 => 'BulbDuration',
     6147        },
     6148        # most Canon models set CanonExposureMode to Manual (4) for Bulb shots,
     6149        # but the 1DmkIII uses a value of 7 for Bulb, so use this for other
     6150        # models too (Note that Canon DPP reports "Manual Exposure" here)
     6151        ValueConv => '$val[0] ? (($val[0] eq "4" and $val[2]) ? 7 : $val[0]) : $val[1] + 10',
     6152        PrintConv => '$val eq "7" ? "Bulb" : ($val[0] ? $prt[0] : $prt[1])',
    28236153    },
    28246154    FlashType => {
     6155        Notes => q{
     6156            may report "Built-in Flash" for some Canon cameras with external flash in
     6157            manual mode
     6158        },
    28256159        Require => {
    28266160            0 => 'FlashBits',
     
    28406174        RawConv => '$val[1] ? $val : undef',
    28416175        ValueConv => '($val[0]==3 or $val[0]==4 or $val[0]==6) ? 1 : 0',
    2842         PrintConv => {
    2843             0 => 'Off',
    2844             1 => 'On',
    2845         },
    2846     },
    2847     # fudge to display simple Flash On/Off for Canon cameras only
    2848     FlashOn => {
    2849         Description => 'Flash',
    2850         Desire => {
    2851             0 => 'FlashBits',
    2852             1 => 'Flash',
    2853         },
    2854         ValueConv => 'Image::ExifTool::Canon::FlashOn(@val)',
    28556176        PrintConv => {
    28566177            0 => 'Off',
     
    29266247        },
    29276248        RawConv => q{
    2928             return undef unless $val[2] == 3 and $val[0];
     6249            ToFloat(@val);
     6250            return undef unless $val[2] and $val[2] == 3 and $val[0] and $val[1];
    29296251            return $val[1] / $val[0];
    29306252        },
    29316253        PrintConv => 'sprintf("%.2fx",$val)',
    2932     }
     6254    },
     6255    OriginalDecisionData => {
     6256        Flags => ['Writable','Protected'],
     6257        WriteGroup => 'MakerNotes',
     6258        Require => 'OriginalDecisionDataOffset',
     6259        RawConv => 'Image::ExifTool::Canon::ReadODD($self,$val[0])',
     6260    },
     6261    FileNumber => {
     6262        Groups => { 2 => 'Image' },
     6263        Writable => 1,
     6264        WriteCheck => '$val=~/\d+-\d+/ ? undef : "Invalid format"',
     6265        DelCheck => '"Can\'t delete"',
     6266        Require => {
     6267            0 => 'DirectoryIndex',
     6268            1 => 'FileIndex',
     6269        },
     6270        WriteAlso => {
     6271            DirectoryIndex => '$val=~/(\d+)-(\d+)/; $1',
     6272            FileIndex => '$val=~/(\d+)-(\d+)/; $2',
     6273        },
     6274        ValueConv => 'sprintf("%.3d-%.4d",@val)',
     6275    },
    29336276);
    29346277
     
    29366279Image::ExifTool::AddCompositeTags('Image::ExifTool::Canon');
    29376280
     6281#------------------------------------------------------------------------------
     6282# Return lens name with teleconverter if applicable
     6283# Inputs: 0) lens name string, 1) short focal length
     6284# Returns: lens string with tc if appropriate
     6285sub LensWithTC($$)
     6286{
     6287    my ($lens, $shortFocal) = @_;
     6288
     6289    # add teleconverter multiplication factor if applicable
     6290    # (and if the LensType doesn't already include one)
     6291    if (not $lens =~ /x$/ and $lens =~ /(\d+)/) {
     6292        my $sf = $1;    # short focal length
     6293        my $tc;
     6294        foreach $tc (1, 1.4, 2, 2.8) {
     6295            next if abs($shortFocal - $sf * $tc) > 0.9;
     6296            $lens .= " + ${tc}x" if $tc > 1;
     6297            last;
     6298        }
     6299    }
     6300    return $lens;
     6301}
     6302
     6303#------------------------------------------------------------------------------
     6304# Attempt to identify the specific lens if multiple lenses have the same LensType
     6305# Inputs: 0) PrintConv hash ref, 1) LensType, 2) ShortFocal, 3) LongFocal
     6306#         4) MaxAperture, 5) LensModel
     6307# Notes: PrintConv, LensType, ShortFocal and LongFocal must be defined.
     6308#        Other inputs are optional.
     6309sub PrintLensID(@)
     6310{
     6311    my ($printConv, $lensType, $shortFocal, $longFocal, $maxAperture, $lensModel) = @_;
     6312    my $lens = $$printConv{$lensType};
     6313    if ($lens) {
     6314        # return this lens unless other lenses have the same LensType
     6315        return LensWithTC($lens, $shortFocal) unless $$printConv{"$lensType.1"};
     6316        $lens =~ s/ or .*//s;    # remove everything after "or"
     6317        # make list of all possible matching lenses
     6318        my @lenses = ( $lens );
     6319        my $i;
     6320        for ($i=1; $$printConv{"$lensType.$i"}; ++$i) {
     6321            push @lenses, $$printConv{"$lensType.$i"};
     6322        }
     6323        # look for lens in user-defined lenses
     6324        foreach $lens (@lenses) {
     6325            next unless $Image::ExifTool::userLens{$lens};
     6326            return LensWithTC($lens, $shortFocal);
     6327        }
     6328        # attempt to determine actual lens
     6329        my ($tc, @maybe, @likely, @matches);
     6330        foreach $tc (1, 1.4, 2, 2.8) {  # loop through teleconverter scaling factors
     6331            foreach $lens (@lenses) {
     6332                next unless $lens =~ /(\d+)(?:-(\d+))?mm.*?(?:[fF]\/?)(\d+(?:\.\d+)?)(?:-(\d+(?:\.\d+)?))?/;
     6333                # ($1=short focal, $2=long focal, $3=max aperture wide, $4=max aperture tele)
     6334                my ($sf, $lf, $sa, $la) = ($1, $2, $3, $4);
     6335                # see if we can rule out this lens by focal length or aperture
     6336                $lf = $sf if $sf and not $lf;
     6337                $la = $sa if $sa and not $la;
     6338                next if abs($shortFocal - $sf * $tc) > 0.9;
     6339                my $tclens = $lens;
     6340                $tclens .= " + ${tc}x" if $tc > 1;
     6341                push @maybe, $tclens;
     6342                next if abs($longFocal  - $lf * $tc) > 0.9;
     6343                push @likely, $tclens;
     6344                if ($maxAperture) {
     6345                    # (not 100% sure that TC affects MaxAperture, but it should!)
     6346                    next if $maxAperture < $sa * $tc - 0.15;
     6347                    next if $maxAperture > $la * $tc + 0.15;
     6348                }
     6349                push @matches, $tclens;
     6350            }
     6351            last if @maybe;
     6352        }
     6353        return join(' or ', @matches) if @matches;
     6354        return join(' or ', @likely) if @likely;
     6355        return join(' or ', @maybe) if @maybe;
     6356    } elsif ($lensModel and $lensModel =~ /\d/) {
     6357        # use lens model as written by the camera (add "Canon" to the start
     6358        # since the camera only understands Canon lenses anyway)
     6359        return "Canon $lensModel";
     6360    }
     6361    my $str = '';
     6362    if ($shortFocal) {
     6363        $str .= sprintf(' %d', $shortFocal);
     6364        $str .= sprintf('-%d', $longFocal) if $longFocal and $longFocal != $shortFocal;
     6365        $str .= 'mm';
     6366    }
     6367    return "Unknown$str" if $lensType eq '-1'; # (careful because Sigma LensType's may not be integer)
     6368    return "Unknown ($lensType)$str";
     6369}
     6370
     6371#------------------------------------------------------------------------------
     6372# Swap 16-bit words in 32-bit integers
     6373# Inputs: 0) string of integers
     6374# Returns: string of word-swapped integers
     6375sub SwapWords($)
     6376{
     6377    my @a = split(' ', shift);
     6378    $_ = (($_ >> 16) | ($_ << 16)) & 0xffffffff foreach @a;
     6379    return "@a";
     6380}
    29386381
    29396382#------------------------------------------------------------------------------
     
    29816424    return 1 if abs(1-$f1*$f2) < 0.01;
    29826425    return 0;
     6426}
     6427
     6428#------------------------------------------------------------------------------
     6429# Read original decision data from file (variable length)
     6430# Inputs: 0) ExifTool object ref, 1) offset in file
     6431# Returns: reference to original decision data (or undef if no data)
     6432sub ReadODD($$)
     6433{
     6434    my ($exifTool, $offset) = @_;
     6435    return undef unless $offset;
     6436    my ($raf, $buff, $buf2, $i, $warn);
     6437    return undef unless defined($raf = $$exifTool{RAF});
     6438    # the data block is a variable length and starts with 0xffffffff
     6439    # followed a 4-byte (int32u) version number
     6440    my $pos = $raf->Tell();
     6441    if ($raf->Seek($offset, 0) and $raf->Read($buff, 8)==8 and $buff=~/^\xff{4}.\0\0/s) {
     6442        my $err = 1;
     6443        # must set byte order in case it is different than current byte order
     6444        # (we could be reading this after byte order was changed)
     6445        my $oldOrder = GetByteOrder();
     6446        my $version = Get32u(\$buff, 4);
     6447        if ($version > 20) {
     6448            ToggleByteOrder();
     6449            $version = unpack('N',pack('V',$version));
     6450        }
     6451        if ($version == 1 or   # 1Ds (big endian)
     6452            $version == 2)     # 5D/20D (little endian)
     6453        {
     6454            # this data is structured as follows:
     6455            #  4 bytes: all 0xff
     6456            #  4 bytes: version number (=1 or 2)
     6457            # 20 bytes: sha1
     6458            #  4 bytes: record count
     6459            # for each record:
     6460            # |  4 bytes: record number (beginning at 0)
     6461            # |  4 bytes: block offset
     6462            # |  4 bytes: block length
     6463            # | 20 bytes: block sha1
     6464            if ($raf->Read($buf2, 24) == 24) {
     6465                $buff .= $buf2;
     6466                my $count = Get32u(\$buf2, 20);
     6467                # read all records if the count is reasonable
     6468                if ($count and $count < 20 and
     6469                    $raf->Read($buf2, $count * 32) == $count * 32)
     6470                {
     6471                    $buff .= $buf2;
     6472                    undef $err;
     6473                }
     6474            }
     6475        } elsif ($version == 3) { # newer models (little endian)
     6476            # this data is structured as follows:
     6477            #  4 bytes: all 0xff
     6478            #  4 bytes: version number (=3)
     6479            # 24 bytes: sha1 A length (=20) + sha1 A
     6480            # 24 bytes: sha1 B length (=20) + sha1 B
     6481            #  4 bytes: length of remaining data (including this length word!)
     6482            #  8 bytes: salt length (=4) + salt ?
     6483            #  4 bytes: unknown (=3)
     6484            #  4 bytes: size of file
     6485            #  4 bytes: unknown (=1 for most models, 2 for 5DmkII)
     6486            #  4 bytes: unknown (=1)
     6487            #  4 bytes: unknown (always the same for a given firmware version)
     6488            #  4 bytes: unknown (random)
     6489            #  4 bytes: record count
     6490            # for each record:
     6491            # |  4 bytes: record number (beginning at 1)
     6492            # |  8 bytes: salt length (=4) + salt ?
     6493            # | 24 bytes: sha1 length (=20) + sha1
     6494            # |  4 bytes: block count
     6495            # | for each block:
     6496            # | |  4 bytes: block offset
     6497            # | |  4 bytes: block length
     6498            # followed by zero padding to end of ODD data (~72 bytes)
     6499            for ($i=0; ; ++$i) {
     6500                $i == 3 and undef $err, last; # success!
     6501                $raf->Read($buf2, 4) == 4 or last;
     6502                $buff .= $buf2;
     6503                my $len = Get32u(\$buf2, 0);
     6504                # (the data length includes the length word itself - doh!)
     6505                $len -= 4 if $i == 2 and $len >= 4;
     6506                # make sure records are a reasonable size (<= 64kB)
     6507                $len <= 0x10000 and $raf->Read($buf2, $len) == $len or last;
     6508                $buff .= $buf2;
     6509            }
     6510        } else {
     6511            $warn = "Unsupported original decision data version $version";
     6512        }
     6513        SetByteOrder($oldOrder);
     6514        unless ($err) {
     6515            if ($exifTool->Options('HtmlDump')) {
     6516                $exifTool->HDump($offset, length $buff, '[OriginalDecisionData]', undef);
     6517            }
     6518            $raf->Seek($pos, 0);    # restore original file position
     6519            return \$buff;
     6520        }
     6521    }
     6522    $exifTool->Warn($warn || 'Invalid original decision data');
     6523    $raf->Seek($pos, 0);    # restore original file position
     6524    return undef;
    29836525}
    29846526
     
    30246566    $scale or $scale = 1;
    30256567    if ($short == $long) {
    3026         return sprintf("%.1fmm", $short * $scale);
     6568        return sprintf("%.1f mm", $short * $scale);
    30276569    } else {
    3028         return sprintf("%.1f - %.1fmm", $short * $scale, $long * $scale);
     6570        return sprintf("%.1f - %.1f mm", $short * $scale, $long * $scale);
    30296571    }
    30306572}
    30316573
    30326574#------------------------------------------------------------------------------
    3033 # process a serial stream of binary data
     6575# Process a serial stream of binary data
    30346576# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
    30356577# Returns: 1 on success
     
    31216663# Inputs: 0) value to convert
    31226664# Focus point pattern:
    3123 #          A1  A2  A3  A4  A5  A6  A7
    3124 #    B1  B2  B3  B4  B5  B6  B7  B8  B9  B10
    3125 C1  C2  C3  C4  C5  C6  C7  C9  C9  C10  C11
    3126 #    D1  D2  D3  D4  D5  D6  D7  D8  D9  D10
    3127 #          E1  E2  E3  E4  E5  E6  E7
     6665#            A1  A2  A3  A4  A5  A6  A7
     6666#      B1  B2  B3  B4  B5  B6  B7  B8  B9  B10
     6667  C1  C2  C3  C4  C5  C6  C7  C9  C9  C10  C11
     6668#      D1  D2  D3  D4  D5  D6  D7  D8  D9  D10
     6669#            E1  E2  E3  E4  E5  E6  E7
    31286670sub PrintAFPoints1D($)
    31296671{
    31306672    my $val = shift;
    31316673    return 'Unknown' unless length $val == 8;
    3132     # these are the x/y positions of each bit in the AF point mask
    3133     # (x is upper 3 bits / y is lower 5 bits)
     6674    # list of focus point values for decoding the first byte of the 8-byte record.
     6675    # they are the x/y positions of each bit in the AF point mask
     6676    # (y is upper 3 bits / x is lower 5 bits)
    31346677    my @focusPts = (0,0,
    31356678              0x04,0x06,0x08,0x0a,0x0c,0x0e,0x10,         0,0,
     
    31546697    $focusing or $focusing = ($focus eq 0xff) ? 'Auto' : sprintf('Unknown (0x%.2x)',$focus);
    31556698    return "$focusing (" . join(',',@points) . ')';
    3156 }
    3157 
    3158 #------------------------------------------------------------------------------
    3159 # Decide whether flash was on or off
    3160 sub FlashOn(@)
    3161 {
    3162     my @val = @_;
    3163 
    3164     if (defined $val[0]) {
    3165         return $val[0] ? 1 : 0;
    3166     }
    3167     if (defined $val[1]) {
    3168         return $val[1]&0x07 ? 1 : 0;
    3169     }
    3170     return undef;
    31716699}
    31726700
     
    32296757
    32306758#------------------------------------------------------------------------------
     6759# Process a creative filter data
     6760# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     6761# Returns: 1 on success
     6762sub ProcessFilters($$$)
     6763{
     6764    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     6765    my $dataPt = $$dirInfo{DataPt};
     6766    my $pos = $$dirInfo{DirStart};
     6767    my $dirLen = $$dirInfo{DirLen};
     6768    my $dataPos = $$dirInfo{DataPos} || 0;
     6769    my $end = $pos + $dirLen;
     6770    my $verbose = $exifTool->Options('Verbose');
     6771
     6772    return 0 if $dirLen < 8;
     6773    my $numFilters = Get32u($dataPt, $pos + 4);
     6774    $verbose and $exifTool->VerboseDir('Creative Filter', $numFilters);
     6775    $pos += 8;
     6776    my ($i, $j, $err);
     6777    for ($i=0; $i<$numFilters; ++$i) {
     6778        # read filter structure:
     6779        # 4 bytes - filter number
     6780        # 4 bytes - filter data length
     6781        # 4 bytes - number of parameters:
     6782        # |  4 bytes - paramter ID
     6783        # |  4 bytes - paramter value count
     6784        # |  4 bytes * count - paramter values (NC)
     6785        $pos + 12 > $end and $err = "Truncated data for filter $i", last;
     6786        my $fnum = Get32u($dataPt, $pos); # (is this an index or an ID?)
     6787        my $size = Get32u($dataPt, $pos + 4);
     6788        my $nparm = Get32u($dataPt, $pos + 8);
     6789        my $nxt = $pos + 4 + $size;
     6790        $nxt > $end and $err = "Invalid size ($size) for filter $i", last;
     6791        $verbose and $exifTool->VerboseDir("Filter $fnum", $nparm, $size);
     6792        $pos += 12;
     6793        for ($j=0; $j<$nparm; ++$j) {
     6794            $pos + 12 > $end and $err = "Truncated data for filter $i param $j", last;
     6795            my $tag = Get32u($dataPt, $pos);
     6796            my $count = Get32u($dataPt, $pos + 4);
     6797            $pos += 8;
     6798            $pos + 4 * $count > $end and $err = "Truncated value for filter $i param $j", last;
     6799            my $val = ReadValue($dataPt, $pos, 'int32s', $count, 4 * $count);
     6800            $exifTool->HandleTag($tagTablePtr, $tag, $val,
     6801                DataPt  => $dataPt,
     6802                DataPos => $dataPos,
     6803                Start   => $pos,
     6804                Size    => 4 * $count,
     6805            );
     6806            $pos += 4 * $count;
     6807        }
     6808        $pos = $nxt;    # step to next filter
     6809    }
     6810    $err and $exifTool->Warn($err, 1);
     6811    return 1;
     6812}
     6813
     6814#------------------------------------------------------------------------------
    32316815# Write Canon maker notes
    32326816# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table ref
     
    32376821    $exifTool or return 1;    # allow dummy access to autoload this package
    32386822    my $dirData = Image::ExifTool::Exif::WriteExif($exifTool, $dirInfo, $tagTablePtr);
    3239     # add trailer which is written by some Canon models (it's a TIFF header)
     6823    # add footer which is written by some Canon models (format of a TIFF header)
    32406824    if (defined $dirData and length $dirData and $$dirInfo{Fixup}) {
    32416825        $dirData .= GetByteOrder() . Set16u(42) . Set32u(0);
     
    32656849=head1 AUTHOR
    32666850
    3267 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     6851Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    32686852
    32696853This library is free software; you can redistribute it and/or modify it
     
    32916875the Digital Ixus and PowerShot S70 cameras, Juha Eskelinen and Emil Sit for
    32926876figuring out the 20D and 30D FileNumber, Denny Priebe for figuring out a
    3293 couple of 1D tags, and Michael Tiemann and Rainer Honle for decoding a
    3294 number of new tags.  Also thanks to everyone who made contributions to the
    3295 LensType lookup list or the meanings of other tag values.
     6877couple of 1D tags, and Michael Tiemann, Rainer Honle, Dave Nicholson, Chris
     6878Huebsch, Ger Vermeulen, Darryl Zurn, D.J. Cristi, Bogdan and Vesa Kivisto for
     6879decoding a number of new tags.  Also thanks to everyone who made contributions
     6880to the LensType lookup list or the meanings of other tag values.
    32966881
    32976882=head1 SEE ALSO
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonCustom.pm

    r16842 r24107  
    77#
    88# References:   1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
    9 #               2) Christian Koller private communication (tests with the 20D)
    10 #               3) Rainer Honle private communication (tests with the 5D)
     9#               2) Christian Koller private communication (20D)
     10#               3) Rainer Honle private communication (5D)
     11#               4) David Pitcher private communication (1DmkIII firmware upgrade)
    1112#------------------------------------------------------------------------------
    1213
     
    1920use Image::ExifTool::Exif;
    2021
    21 $VERSION = '1.17';
     22$VERSION = '1.40';
    2223
    2324sub ProcessCanonCustom($$$);
     
    122123    },
    123124    9 => {
    124         Name => 'AEBSequence',
     125        Name => 'AEBSequenceAutoCancel',
     126        Description => 'AEB Sequence/Auto Cancel',
    125127        PrintConv => {
    126128            0 => '0,-,+/Enabled',
     
    212214            3 => 'Moderately fast',
    213215            4 => 'Fast',
     216        },
     217    },
     218    21 => {
     219        Name => 'AIServoContinuousShooting',
     220        PrintConv => {
     221            0 => 'Shooting not possible without focus',
     222            1 => 'Shooting possible without focus',
    214223        },
    215224    },
     
    291300    },
    292301    9 => {
    293         Name => 'AEBSequence',
     302        Name => 'AEBSequenceAutoCancel',
     303        Description => 'AEB Sequence/Auto Cancel',
    294304        PrintConv => {
    295305            0 => '0,-,+/Enabled',
     
    381391    WRITABLE => 'int8u',
    382392    1 => {
    383         Name => 'SetButtonFunction',
    384         PrintConv => {
    385             0 => 'Not assigned',
    386             1 => 'Change quality',
     393        Name => 'SetButtonWhenShooting',
     394        PrintConv => {
     395            0 => 'Normal (disabled)',
     396            1 => 'Image quality',
    387397            2 => 'Change parameters',
    388398            3 => 'Menu display',
    389             4 => 'Image replay',
     399            4 => 'Image playback',
    390400        },
    391401    },
     
    456466    },
    457467    9 => {
    458         Name => 'AEBSequence',
     468        Name => 'AEBSequenceAutoCancel',
     469        Description => 'AEB Sequence/Auto Cancel',
    459470        PrintConv => {
    460471            0 => '0,-,+/Enabled',
     
    508519        Name => 'LensAFStopButton',
    509520        PrintConv => {
    510             0 => 'AF Stop',
    511             1 => 'Operate AF',
    512             2 => 'Lock AE and start timer',
     521            0 => 'AF stop',
     522            1 => 'AF start',
     523            2 => 'AE lock while metering',
     524            3 => 'AF point: M->Auto/Auto->ctr',
     525            4 => 'One Shot <-> AI servo',
     526            5 => 'IS start',
    513527        },
    514528    },
     
    579593    },
    580594    8 => {
    581         Name => 'AEBSequence',
     595        Name => 'AEBSequenceAutoCancel',
     596        Description => 'AEB Sequence/Auto Cancel',
    582597        PrintConv => {
    583598            0 => '0,-,+/Enabled',
     
    715730    },
    716731    9 => {
    717         Name => 'AEBSequence',
     732        Name => 'AEBSequenceAutoCancel',
     733        Description => 'AEB Sequence/Auto Cancel',
    718734        PrintConv => {
    719735            0 => '0,-,+/Enabled',
     
    960976    WRITE_PROC => \&WriteCanonCustom,
    961977    CHECK_PROC => \&CheckCanonCustom,
    962     NOTES => 'Custom functions for the EOS-D30 and D60.',
     978    NOTES => 'Custom functions for the EOS D30 and D60.',
    963979    WRITABLE => 'int8u',
    964980    1 => {
     
    10031019    },
    10041020    7 => {
    1005         Name => 'AEBSequence',
     1021        Name => 'AEBSequenceAutoCancel',
     1022        Description => 'AEB Sequence/Auto Cancel',
    10061023        PrintConv => {
    10071024            0 => '0,-,+/Enabled',
     
    10391056    },
    10401057    12 => {
    1041         Name => 'SetButtonFunction',
    1042         PrintConv => {
    1043             0 => 'Not assigned',
    1044             1 => 'Change quality',
     1058        Name => 'SetButtonWhenShooting',
     1059        PrintConv => {
     1060            0 => 'Default (no function)',
     1061            1 => 'Image quality',
    10451062            2 => 'Change ISO speed',
    1046             3 => 'Select parameters',
     1063            3 => 'Change parameters',
    10471064        },
    10481065    },
     
    11331150        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val*8/1000)/log(2))/4',
    11341151        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    1135         PrintConvInv => 'eval $val',
     1152        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    11361153    },
    11371154    5 => {
     
    11411158        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val*8/1000)/log(2))/4',
    11421159        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    1143         PrintConvInv => 'eval $val',
     1160        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    11441161    },
    11451162    6 => {
     
    11871204    NOTES => q{
    11881205        Beginning with the EOS 1D Mark III, Canon finally created a set of custom
    1189         function tags which are consistent across models.  The EOS 1D Mark III has
    1190         57 custom function tags divided into four main groups: 1. Exposure
    1191         (0x0101-0x010f), 2. Image (0x0201-0x0203), Flash Exposure (0x0304-0x0306)
    1192         and Display (0x0407-0x0409), 3. Auto Focus (0x0501-0x050e) and Drive
    1193         (0x060f-0x0611), and 4. Operation (0x0701-0x070a) and Others
     1206        function tags which are (reasonably) consistent across models.  The EOS 1D
     1207        Mark III has 57 custom function tags divided into four main groups: 1.
     1208        Exposure (0x0101-0x010f), 2. Image (0x0201-0x0203), Flash Exposure
     1209        (0x0304-0x0306) and Display (0x0407-0x0409), 3. Auto Focus (0x0501-0x050e)
     1210        and Drive (0x060f-0x0611), and 4. Operation (0x0701-0x070a) and Others
    11941211        (0x080b-0x0810).  The table below lists tags used by the EOS 1D Mark III, as
    1195         well as newer values and tags used by the EOS 40D.  It is expected that
    1196         future models will re-use some of these tags (possibly with minor value
    1197         changes), as well as defining additional new tags of their own.
     1212        well as newer tags and values added by later models.
    11981213    },
    11991214    # grouped in 4 groups:
     
    12021217        {
    12031218            Name => 'ExposureLevelIncrements',
    1204             Condition => '$$self{CameraModel} =~ /\b40D\b/',
    1205             Notes => '40D',
    1206             PrintConv => {
    1207                 0 => '1/3 Stop',
    1208                 1 => '1/2 Stop',
    1209             },
    1210         },
    1211         {
    1212             Name => 'ExposureLevelIncrements',
    1213             Notes => '1D Mark III',
     1219            Condition => '$$self{Model} =~ /\b1Ds?\b/',
     1220            Notes => '1DmkIII and 1DmkIV',
    12141221            PrintConv => {
    12151222                0 => '1/3-stop set, 1/3-stop comp.',
     
    12181225            },
    12191226        },
     1227        {
     1228            Name => 'ExposureLevelIncrements',
     1229            Notes => 'other models',
     1230            PrintConv => {
     1231                0 => '1/3 Stop',
     1232                1 => '1/2 Stop',
     1233            },
     1234        },
    12201235    ],
    12211236    0x0102 => {
    12221237        Name => 'ISOSpeedIncrements',
    12231238        PrintConv => {
    1224             0 => '1/3-stop',
    1225             1 => '1-stop',
     1239            0 => '1/3 Stop',
     1240            1 => '1 Stop',
    12261241        },
    12271242    },
    12281243    0x0103 => [
    12291244        {
    1230             Name => 'ISOExpansion',
    1231             Condition => '$$self{CameraModel} =~ /\b40D\b/',
    1232             Notes => '40D',
    1233             PrintConv => {
    1234                 0 => 'Off',
    1235                 1 => 'On',
    1236             },
    1237         },
    1238         {
    12391245            Name => 'ISOSpeedRange',
    1240             Notes => '1D Mark III',
     1246            Condition => '$$self{Model} =~ /\b1D/',
     1247            Notes => '1DmkIII and 1DmkIV',
    12411248            Count => 3,
    12421249            # (this decoding may not be valid for CR2 images?)
    12431250            ValueConv => [
    12441251                undef,
    1245                 '$val < 1000 ? exp(($val/8-9)*log(2))*100 : 0', # (educated guess)
    1246                 '$val < 1000 ? exp(($val/8-9)*log(2))*100 : 0', # (educated guess)
     1252                # this may also be set to "H" (Hi6400) -- is this the -1 value I see? - PH
     1253                '$val < 2 ? $val : ($val < 1000 ? exp(($val/8-9)*log(2))*100 : 0)', # (educated guess)
     1254                # this may also be set to "L" (Lo50) -- is this the 1 value I see? - PH
     1255                '$val < 2 ? $val : ($val < 1000 ? exp(($val/8-9)*log(2))*100 : 0)', # (educated guess)
    12471256            ],
    12481257            ValueConvInv => [
    12491258                undef,
    1250                 '$val ? int(8*(log($val/100)/log(2)+9) + 0.5) : 0xffffffff',
    1251                 '$val ? int(8*(log($val/100)/log(2)+9) + 0.5) : 0xffffffff',
     1259                '$val < 2 ? $val : int(8*(log($val/100)/log(2)+9) + 0.5)',
     1260                '$val < 2 ? $val : int(8*(log($val/100)/log(2)+9) + 0.5)',
    12521261            ],
    12531262            PrintConv => [
     
    12581267            PrintConvInv => [
    12591268                undef,
    1260                 '$val=~/([\d.]+)/ ? $1 : 0',
    1261                 '$val=~/([\d.]+)/ ? $1 : 0',
     1269                '$val=~/(-?[\d.]+)/ ? $1 : 0',
     1270                '$val=~/(-?[\d.]+)/ ? $1 : 0',
    12621271            ],
     1272        },
     1273        {
     1274            Name => 'ISOExpansion',
     1275            Notes => 'other models',
     1276            PrintConv => {
     1277                0 => 'Off',
     1278                1 => 'On',
     1279            },
    12631280        },
    12641281    ],
     
    12691286    0x0105 => {
    12701287        Name => 'AEBSequence',
    1271         Notes => 'value of 2 not used by 40D',
     1288        Notes => 'value of 2 not used by 40D, 50D, 60D, 5DmkII and 7D',
    12721289        PrintConv => {
    12731290            0 => '0,-,+',
     
    12781295    0x0106 => {
    12791296        Name => 'AEBShotCount',
    1280         PrintConv => {
     1297        Count => -1,
     1298        Notes => '1 value for the 1DmkIII, 2 for the 1DmkIV',
     1299        PrintConv => [{
    12811300            0 => 3,
    12821301            1 => 2,
    12831302            2 => 5,
    12841303            3 => 7,
    1285         },
     1304        }],
    12861305    },
    12871306    0x0107 => {
     
    12941313    0x0108 => {
    12951314        Name => 'SafetyShift',
    1296         Notes => 'value of 2 not used by 40D',
     1315        Notes => 'value of 2 not used by 40D, 50D, 60D, 5DmkII and 7D',
    12971316        PrintConv => {
    12981317            0 => 'Disable',
     
    13861405        Name => 'ApplyShootingMeteringMode',
    13871406        Count => 8,
    1388         PrintConv => [
    1389             \%disableEnable,
    1390         ],
     1407        PrintConv => [ \%disableEnable ],
    13911408    },
    13921409    0x010f => [
    13931410        {
    13941411            Name => 'FlashSyncSpeedAv',
    1395             Condition => '$$self{CameraModel} =~ /\b40D\b/',
     1412            Condition => '$$self{Model} =~ /\b40D\b/',
    13961413            Notes => '40D',
    13971414            PrintConv => {
     
    14021419        {
    14031420            Name => 'FlashSyncSpeedAv',
     1421            Condition => '$$self{Model} =~ /\b(50D|60D|7D)\b/',
     1422            Notes => '50D, 60D and 7D',
     1423            PrintConv => {
     1424                0 => 'Auto',
     1425                1 => '1/250-1/60 Auto',
     1426                2 => '1/250 Fixed',
     1427            },
     1428        },
     1429        {
     1430            Name => 'FlashSyncSpeedAv',
     1431            Condition => '$$self{Model} =~ /\b(450D|XSi|Kiss X2|1000D|XS|Kiss F)\b/',
     1432            Notes => '450D and 1000D',
     1433            PrintConv => {
     1434                0 => 'Auto',
     1435                1 => '1/200 Fixed',
     1436            },
     1437        },
     1438        {
     1439            Name => 'FlashSyncSpeedAv',
     1440            Condition => '$$self{Model} =~ /\b(5D Mark II|500D|T1i|Kiss X3|550D|T2i|Kiss X4)\b/',
     1441            Notes => '5D Mark II, 500D and 550D',
     1442            PrintConv => {
     1443                0 => 'Auto',
     1444                1 => '1/200-1/60 Auto',
     1445                2 => '1/200 Fixed',
     1446            },
     1447        },
     1448        {
     1449            Name => 'FlashSyncSpeedAv',
     1450            Condition => '$$self{Model} =~ /\b(EOS-1D Mark IV)\b/',
     1451            Notes => '1D Mark IV',
     1452            PrintConv => {
     1453                0 => 'Auto',
     1454                1 => '1/300-1/60 Auto',
     1455                2 => '1/300 Fixed',
     1456            },
     1457        },
     1458        {
     1459            Name => 'FlashSyncSpeedAv',
    14041460            Notes => '1D Mark III',
    14051461            PrintConv => {
     
    14091465        },
    14101466    ],
     1467    0x0110 => { # new for 1DmkIV
     1468        Name => 'FEMicroadjustment',
     1469        Count => 3,
     1470        PrintConv => [ \%disableEnable ],
     1471    },
     1472    0x0111 => { # new for 1DmkIV
     1473        Name => 'AEMicroadjustment',
     1474        Count => 3,
     1475        PrintConv => [ \%disableEnable ],
     1476    },
    14111477    #### 2a) Image
    14121478    0x0201 => {
     
    14181484        },
    14191485    },
    1420     0x0202 => {
    1421         Name => 'HighISONoiseReduction',
    1422         PrintConv => \%offOn,
    1423     },
     1486    0x0202 => [
     1487        {
     1488            Name => 'HighISONoiseReduction',
     1489            Condition => '$$self{Model} =~ /\b(50D|60D|5D Mark II|7D|500D|T1i|Kiss X3|550D|T2i|Kiss X4)\b/',
     1490            Notes => '50D, 60D, 500D, 550D, 5DmkII and 7D',
     1491            PrintConv => {
     1492                0 => 'Standard',
     1493                1 => 'Low',
     1494                2 => 'Strong',
     1495                3 => 'Off',
     1496            },
     1497        },
     1498        {
     1499            Name => 'HighISONoiseReduction',
     1500            Notes => 'other models',
     1501            PrintConv => \%offOn,
     1502        },
     1503    ],
    14241504    0x0203 => {
    14251505        Name => 'HighlightTonePriority',
    14261506        PrintConv => \%disableEnable
    14271507    },
     1508    0x0204 => [
     1509        {
     1510            Name => 'AutoLightingOptimizer',
     1511            Condition => '$$self{Model} =~ /\b(50D|5D Mark II|500D|T1i|Kiss X3|1D Mark IV)\b/',
     1512            Notes => '50D, 500D, 5DmkII and 1DmkIV',
     1513            PrintConv => {
     1514                0 => 'Standard',
     1515                1 => 'Low',
     1516                2 => 'Strong',
     1517                3 => 'Disable',
     1518            },
     1519        },
     1520        {
     1521            Name => 'AutoLightingOptimizer',
     1522            Notes => 'other models',
     1523            PrintConv => \%enableDisable,
     1524        },
     1525    ],
    14281526    #### 2b) Flash exposure
    14291527    0x0304 => {
     
    14581556        PrintConv => \%offOn,
    14591557    },
    1460     0x0409 => {
    1461         Name => 'InfoButtonWhenShooting',
    1462         PrintConv => {
    1463             0 => 'Displays camera settings',
    1464             1 => 'Displays shooting functions',
    1465         },
    1466     },
     1558    0x0409 => [
     1559        {
     1560            Name => 'InfoButtonWhenShooting',
     1561            Condition => '$$self{Model} =~ /\b1Ds? Mark III\b/',
     1562            Notes => '1D Mark III',
     1563            PrintConv => {
     1564                0 => 'Displays camera settings',
     1565                1 => 'Displays shooting functions',
     1566            },
     1567        },
     1568        {
     1569            Name => 'InfoButtonWhenShooting',
     1570            Notes => '1D Mark IV',
     1571            PrintConv => {
     1572                # reversed from earlier models. grr...
     1573                0 => 'Displays shooting functions',
     1574                1 => 'Displays camera settings',
     1575            },
     1576        },
     1577    ],
    14671578    #### 3a) Auto focus
    14681579    0x0501 => {
     
    14901601            1 => '1: AF, 2: Drive speed',
    14911602            2 => '1: Release, 2: Drive speed',
     1603            3 => '1: Release, 2: Tracking', # 7D/1DmkIV
    14921604        },
    14931605    },
     
    15081620    0x0506 => {
    15091621        Name => 'LensAFStopButton',
    1510         Notes => 'value of 6 not used by 40D',
     1622        Notes => 'value of 6 not used by 40D, 50D and 5DmkII',
    15111623        PrintConv => {
    15121624            0 => 'AF stop',
     
    15171629            5 => 'IS start',
    15181630            6 => 'Switch to registered AF point',
     1631            7 => 'Spot AF', # 1DmkIV
    15191632        },
    15201633    },
     
    15311644        ],
    15321645    },
    1533     0x0508 => {
    1534         Name => 'AFExpansionWithSelectedPoint',
    1535         PrintConv => {
    1536             0 => 'Disable',
    1537             1 => 'Enable (left/right assist points)',
    1538             2 => 'Enable (surrounding assist points)',
    1539         },
    1540     },
    1541     0x0509 => {
    1542         Name => 'SelectableAFPoint',
    1543         PrintConv => {
    1544             0 => '19 points',
    1545             1 => 'Inner 9 points',
    1546             2 => 'Outer 9 points',
    1547         },
    1548     },
    1549     0x050a => {
    1550         Name => 'SwitchToRegisteredAFPoint',
    1551         PrintConv => \%disableEnable,
    1552     },
     1646    0x0508 => [
     1647        {
     1648            Name => 'AFPointAreaExpansion',
     1649            Condition => '$$self{Model} =~ /\b5D Mark II\b/',
     1650            Notes => '5D Mark II',
     1651            PrintConv => {
     1652                0 => 'Disable',
     1653                1 => 'Enable',
     1654            },
     1655        },
     1656        {
     1657            Name => 'AFPointAreaExpansion',
     1658            PrintConv => {
     1659                0 => 'Disable',
     1660                1 => 'Left/right AF points',
     1661                2 => 'Surrounding AF points',
     1662                3 => 'All 45 points area', # 1DmkIV
     1663            },
     1664        },
     1665    ],
     1666    0x0509 => [
     1667        {
     1668            Name => 'SelectableAFPoint',
     1669            Condition => '$$self{Model} =~ /\b1D Mark IV\b/',
     1670            Notes => '1D Mark IV',
     1671            PrintConv => {
     1672                 0 => '45 points',
     1673                 1 => '19 points',
     1674                 2 => '11 points',
     1675                 3 => 'Inner 9 points',
     1676                 4 => 'Outer 9 points',
     1677            },
     1678        },
     1679        {
     1680            Name => 'SelectableAFPoint',
     1681            Notes => 'other models',
     1682            PrintConv => {
     1683                0 => '19 points',
     1684                1 => 'Inner 9 points',
     1685                2 => 'Outer 9 points',
     1686                3 => '19 Points, Multi-controller selectable', #4
     1687                4 => 'Inner 9 Points, Multi-controller selectable', #4
     1688                5 => 'Outer 9 Points, Multi-controller selectable', #4
     1689            },
     1690        },
     1691    ],
     1692    0x050a => [
     1693        {
     1694            Name => 'SwitchToRegisteredAFPoint',
     1695            Condition => '$$self{Model} =~ /\b1D Mark IV\b/',
     1696            Notes => '1D Mark IV',
     1697            PrintConv => {
     1698                0 => 'Disable',
     1699                1 => 'Switch with multi-controller',
     1700                2 => 'Only while AEL is pressed',
     1701            },
     1702        },
     1703        {
     1704            Name => 'SwitchToRegisteredAFPoint',
     1705            Notes => 'other models',
     1706            PrintConv => \%disableEnable,
     1707        },
     1708    ],
    15531709    0x050b => {
    15541710        Name => 'AFPointAutoSelection',
     
    15741730        },
    15751731    },
    1576     0x050e => {
    1577         Name => 'AFAssistBeam',
    1578         Notes => 'value of 2 not used by 1D Mark III',
    1579         PrintConv => {
    1580             0 => 'Emits',
    1581             1 => 'Does not emit',
    1582             2 => 'Only ext. flash emits',
    1583         },
    1584     },
    1585     0x050f => { # new for 40D
    1586         Name => 'AFPointSelectionMethod',
    1587         PrintConv => {
    1588             0 => 'Normal',
    1589             1 => 'Multi-controller direct',
    1590             2 => 'Quick Control Dial direct',
    1591         },
    1592     },
    1593     0x0510 => { # new for 40D
    1594         Name => 'SuperimposedDisplay',
    1595         PrintConv => \%onOff,
    1596     },
    1597     0x0511 => { # new for 40D
    1598         Name => 'AFDuringLiveView',
    1599         PrintConv => \%disableEnable,
     1732    0x050e => [
     1733        {
     1734            Name => 'AFAssistBeam',
     1735            Condition => '$$self{Model} =~ /\b1D Mark IV\b/',
     1736            Notes => '1D Mark IV',
     1737            PrintConv => {
     1738                0 => 'Emits',
     1739                1 => 'Does not emit',
     1740                2 => 'IR AF assist beam only',
     1741            },
     1742        },
     1743        {
     1744            Name => 'AFAssistBeam',
     1745            Notes => 'other models; values 2-3 not used by 1DmkIII or 5DmkII, value 3 new for 7D',
     1746            PrintConv => {
     1747                0 => 'Emits',
     1748                1 => 'Does not emit',
     1749                2 => 'Only ext. flash emits',
     1750                3 => 'IR AF assist beam only', # new for 7D
     1751            },
     1752        },
     1753    ],
     1754    0x050f => [ # new for 40D
     1755        {
     1756            Name => 'AFPointSelectionMethod',
     1757            Condition => '$$self{Model} !~ /\b60D\b/',
     1758            Notes => '40D, 50D and 5DmkII',
     1759            PrintConv => {
     1760                0 => 'Normal',
     1761                1 => 'Multi-controller direct',
     1762                2 => 'Quick Control Dial direct',
     1763            },
     1764        },
     1765        {
     1766            Name => 'AFPointSelectionMethod',
     1767            Notes => '60D',
     1768            PrintConv => {
     1769                0 => 'AF point button: Activate AF Sel; Rear dial: Select AF points',
     1770                1 => 'AF point button: Auto selection; Rear dial: Manual selection',
     1771            },
     1772        },
     1773    ],
     1774    0x0510 => [ # new for 40D
     1775        {
     1776            Name => 'VFDisplayIllumination',
     1777            Condition => '$$self{Model} =~ /\b7D\b/',
     1778            Notes => '7D',
     1779            PrintConv => {
     1780                0 => 'Auto',
     1781                1 => 'Enable',
     1782                2 => 'Disable',
     1783            },
     1784        },
     1785        {
     1786            Name => 'SuperimposedDisplay',
     1787            Notes => 'other models',
     1788            PrintConv => \%onOff,
     1789        },
     1790    ],
     1791    0x0511 => [ # new for 40D
     1792        {
     1793            Name => 'AFDuringLiveView',
     1794            Condition => '$$self{Model} =~ /\b40D\b/',
     1795            Notes => '40D',
     1796            PrintConv => \%disableEnable,
     1797        },
     1798        {
     1799            Name => 'AFDuringLiveView',
     1800            Notes => '450D and 1000D',
     1801            PrintConv => {
     1802                0 => 'Disable',
     1803                1 => 'Quick mode',
     1804                2 => 'Live mode',
     1805            },
     1806        },
     1807    ],
     1808    0x0512 => { # new for 7D
     1809        Name => 'SelectAFAreaSelectMode',
     1810        PrintConv => [
     1811            {
     1812                0 => 'Disable',
     1813                1 => 'Enable',
     1814                2 => 'Register',
     1815                3 => 'Select AF-modes',
     1816            },
     1817            # must decode 2nd value
     1818        ],
     1819    },
     1820    0x0513 => { # new for 7D
     1821        Name => 'ManualAFPointSelectPattern',
     1822        PrintConv => {
     1823            0 => 'Stops at AF area edges',
     1824            1 => 'Continuous',
     1825        },
     1826    },
     1827    0x0514 => { # new for 7D
     1828        Name => 'DisplayAllAFPoints',
     1829        PrintConv => \%enableDisable,
     1830    },
     1831    0x0515 => { # new for 7D
     1832        Name => 'FocusDisplayAIServoAndMF',
     1833        PrintConv => \%enableDisable,
     1834    },
     1835    0x0516 => { # new for 7D and 1DmkIV
     1836        Name => 'OrientationLinkedAFPoint',
     1837        PrintConv => {
     1838            0 => 'Same for verical and horizontal',
     1839            1 => 'Select different AF points',
     1840        },
     1841    },
     1842    0x0517 => { # new for 1DmkIV
     1843        Name => 'MultiControllerWhileMetering',
     1844        PrintConv => {
     1845            0 => 'Off',
     1846            1 => 'AF point selection',
     1847        },
    16001848    },
    16011849    #### 3b) Drive
    16021850    0x060f => {
    16031851        Name => 'MirrorLockup',
    1604         Notes => 'value of 2 not used by 40D',
     1852        Notes => 'value of 2 not used by some models',
    16051853        PrintConv => {
    16061854            0 => 'Disable',
     
    16361884    },
    16371885    #### 4a) Operation
    1638     0x0701 => {
    1639         Name => 'ShutterButtonAFOnButton',
    1640         PrintConv => {
    1641             0 => 'Metering + AF start',
    1642             1 => 'Metering + AF start/AF stop',
    1643             2 => 'Metering start/Meter + AF start',
    1644             3 => 'AE lock/Metering + AF start',
    1645             4 => 'Metering + AF start / disable',
    1646         },
    1647     },
     1886    0x0701 => [
     1887        {
     1888            Name => 'Shutter-AELock',
     1889            Condition => '$$self{Model} =~ /\b(1000D|XS|Kiss F|500D|T1i|Kiss X3|550D|T2i|Kiss X4)\b/',
     1890            Notes => '500D, 550D and 1000D',
     1891            PrintConv => {
     1892                0 => 'AF/AE lock',
     1893                1 => 'AE lock/AF',
     1894                2 => 'AF/AF lock, No AE lock',
     1895                3 => 'AE/AF, No AE lock',
     1896            },
     1897        },
     1898        {
     1899            Name => 'AFAndMeteringButtons',
     1900            Condition => '$$self{Model} =~ /\b60D\b/',
     1901            Notes => '60D',
     1902            PrintConv => {
     1903                0 => 'Metering start',
     1904                1 => 'Metering + AF start',
     1905                2 => 'AE lock',
     1906                3 => 'AF stop',
     1907                4 => 'No function',
     1908            },
     1909        },
     1910        {
     1911            Name => 'ShutterButtonAFOnButton',
     1912            Notes => 'other models',
     1913            PrintConv => {
     1914                0 => 'Metering + AF start',
     1915                1 => 'Metering + AF start/AF stop',
     1916                2 => 'Metering start/Meter + AF start',
     1917                3 => 'AE lock/Metering + AF start',
     1918                4 => 'Metering + AF start/disable',
     1919            },
     1920        },
     1921    ],
    16481922    0x0702 => {
    16491923        Name => 'AFOnAELockButtonSwitch',
     
    16561930            1 => 'AF point selection',
    16571931            2 => 'ISO speed',
     1932            3 => 'AF point selection swapped with Exposure comp', #4
     1933            4 => 'ISO speed swapped with Exposure comp', #4
    16581934        },
    16591935    },
     
    16611937        {
    16621938            Name => 'SetButtonWhenShooting',
    1663             Condition => '$$self{CameraModel} =~ /\b40D\b/',
    1664             Notes => '40D',
     1939            Condition => '$$self{Model} =~ /\b(40D|50D|5D Mark II)\b/',
     1940            Notes => '40D, 50D and 5DmkII; value of 5 is new for 50D, and 6 is new for 5DmkII',
    16651941            PrintConv => {
    16661942                0 => 'Normal (disabled)',
     
    16691945                3 => 'Menu display',
    16701946                4 => 'Image playback',
     1947                5 => 'Quick control screen', #50D
     1948                6 => 'Record movie (Live View)', #5DmkII
    16711949            },
    16721950        },
    16731951        {
    16741952            Name => 'SetButtonWhenShooting',
    1675             Notes => '1D Mark III',
     1953            Condition => '$$self{Model} =~ /\b60D\b/',
     1954            Notes => '60D',
     1955            PrintConv => {
     1956                0 => 'Normal (disabled)',
     1957                1 => 'Image quality',
     1958                2 => 'Picture style',
     1959                3 => 'White balance',
     1960                4 => 'Flash exposure compensation',
     1961                5 => 'Viewfinder leveling gauge',
     1962            },
     1963        },
     1964        {
     1965            Name => 'SetButtonWhenShooting',
     1966            Condition => '$$self{Model} =~ /\b(450D|XSi|Kiss X2|550D|T2i|Kiss X4)\b/',
     1967            Notes => '450D and 550D; value of 5 is new for 550D',
     1968            PrintConv => {
     1969                0 => 'Normal (disabled)',
     1970                1 => 'Image quality',
     1971                2 => 'Flash exposure compensation',
     1972                3 => 'LCD monitor On/Off',
     1973                4 => 'Menu display',
     1974                5 => 'ISO speed',
     1975            },
     1976        },
     1977        {
     1978            Name => 'SetButtonWhenShooting',
     1979            Condition => '$$self{Model} =~ /\b(1000D|XS|Kiss F)\b/',
     1980            Notes => '1000D',
     1981            PrintConv => {
     1982                0 => 'LCD monitor On/Off',
     1983                1 => 'Image quality',
     1984                2 => 'Flash exposure compensation',
     1985                3 => 'Menu display',
     1986                4 => 'Disabled',
     1987            },
     1988        },
     1989        {
     1990            Name => 'SetButtonWhenShooting',
     1991            Condition => '$$self{Model} =~ /\b(500D|T1i|Kiss X3)\b/',
     1992            Notes => '500D',
     1993            PrintConv => {
     1994                0 => 'Quick control screen',
     1995                1 => 'Image quality',
     1996                2 => 'Flash exposure compensation',
     1997                3 => 'LCD monitor On/Off',
     1998                4 => 'Menu display',
     1999                5 => 'Disabled',
     2000            },
     2001        },
     2002        {
     2003            Name => 'SetButtonWhenShooting',
     2004            Notes => '1DmkIII and 1DmkIV',
    16762005            PrintConv => {
    16772006                0 => 'Normal (disabled)',
     
    17152044        Name => 'LockMicrophoneButton',
    17162045        PrintConv => {
    1717             0 => 'Protect (holding:sound rec.)',
    1718             1 => 'Sound rec. (protect:disable)',
     2046            # called "sound" in 1DmkIII manual, and "memo" in 1DmkIV manual
     2047            0 => 'Protect (hold:record memo)',
     2048            1 => 'Record memo (protect:disable)',
     2049            2 => 'Play memo (hold:record memo)', # new with 1DmkIV
    17192050        },
    17202051    },
     
    17262057        },
    17272058    },
     2059    0x070b => { # 50D (also, 5DmkII writes this but it isn't in user guide)
     2060        Name => 'AssignFuncButton',
     2061        PrintConv => {
     2062            0 => 'LCD brightness',
     2063            1 => 'Image quality',
     2064            2 => 'Exposure comp./AEB setting',
     2065            3 => 'Image jump with main dial',
     2066            4 => 'Live view function settings',
     2067        },
     2068    },
     2069    0x070c => { # new for 7D
     2070        Name => 'CustomControls',
     2071        # (too much stuff to decode)
     2072    },
     2073    0x070d => { # new for 1DmkIV
     2074        Name => 'StartMovieShooting',
     2075        PrintConv => {
     2076            0 => 'Default (from LV)',
     2077            1 => 'Quick start (FEL button)',
     2078        },
     2079    },
    17282080    #### 4b) Others
    17292081    0x080b => [
    17302082        {
    17312083            Name => 'FocusingScreen',
    1732             Condition => '$$self{CameraModel} =~ /\b40D\b/',
    1733             Notes => '40D',
     2084            Condition => '$$self{Model} =~ /\b(40D|50D|60D)\b/',
     2085            Notes => '40D, 50D and 60D',
    17342086            PrintConv => {
    17352087                0 => 'Ef-A',
     
    17402092        {
    17412093            Name => 'FocusingScreen',
    1742             Notes => '1D Mark III',
     2094            Condition => '$$self{Model} =~ /\b5D Mark II\b/',
     2095            Notes => '5D Mark II',
     2096            PrintConv => {
     2097                0 => 'Eg-A',
     2098                1 => 'Eg-D',
     2099                2 => 'Eg-S',
     2100            },
     2101        },
     2102        {
     2103            Name => 'FocusingScreen',
     2104            Notes => '1DmkIII and 1DmkIV',
    17432105            PrintConv => {
    17442106                0 => 'Ec-CIV',
     
    17542116        PrintConv => [
    17552117            \%disableEnable,
    1756             '"6 sec: $val"',
    1757             '"16 sec: $val"',
     2118            '"6 s: $val"',
     2119            '"16 s: $val"',
    17582120            '"After release: $val"',
    17592121        ],
     
    17822144    },
    17832145    0x080f => {
    1784         Name => 'AddOriginalDecisionData',
     2146        Name => 'AddOriginalDecisionData', # called ("image verification" in 1DmkIV manual)
    17852147        PrintConv => \%offOn,
    17862148    },
     
    17902152            0 => 'Disable (LCD auto adjust)',
    17912153            1 => 'Enable (simulates exposure)',
     2154        },
     2155    },
     2156    0x0811 => {
     2157        Name => 'LCDDisplayAtPowerOn',
     2158        PrintConv => {
     2159            0 => 'Display',
     2160            1 => 'Retain power off status',
    17922161        },
    17932162    },
     
    18352204    if ($write) {
    18362205        $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
    1837         $exifTool->VPrint(0, "  Rewriting CanonCustom2\n") if $verbose;
     2206        $exifTool->VPrint(0, "  Rewriting CanonCustom2\n");
    18382207    } elsif ($verbose) {
    18392208        $exifTool->VerboseDir('CanonCustom2', $count);
     
    18652234                my $tagInfo = $$newTags{$tag};
    18662235                next unless $tagInfo;
    1867                 my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
    1868                 next unless Image::ExifTool::IsOverwriting($newValueHash, $val);
    1869                 my $newVal = Image::ExifTool::GetNewValues($newValueHash);
     2236                my $nvHash = $exifTool->GetNewValueHash($tagInfo);
     2237                next unless Image::ExifTool::IsOverwriting($nvHash, $val);
     2238                my $newVal = Image::ExifTool::GetNewValues($nvHash);
    18702239                next unless defined $newVal;    # can't delete from a custom table
    18712240                WriteValue($newVal, 'int32s', $num, $dataPt, $recPos);
    1872                 if ($verbose > 1) {
    1873                     $exifTool->VPrint(0, "    - CanonCustom:$$tagInfo{Name} = '$val'\n",
    1874                                          "    + CanonCustom:$$tagInfo{Name} = '$newVal'\n");
    1875                 }
     2241                $exifTool->VerboseValue("- CanonCustom:$$tagInfo{Name}", $val);
     2242                $exifTool->VerboseValue("+ CanonCustom:$$tagInfo{Name}", $newVal);
    18762243                ++$exifTool->{CHANGED};
    18772244            } else {
    1878                 # extract the value
     2245                # save extracted tag
    18792246                my $oldInfo = $$tagTablePtr{$tag};
    18802247                $exifTool->HandleTag($tagTablePtr, $tag, $val,
     
    19362303    # first entry in array must be the size
    19372304    my $len = Get16u($dataPt,$offset);
    1938     unless ($len == $size or ($$exifTool{CameraModel}=~/\bD60\b/ and $len+2 == $size)) {
     2305    unless ($len == $size or ($$exifTool{Model}=~/\bD60\b/ and $len+2 == $size)) {
    19392306        $exifTool->Warn("Invalid CanonCustom data");
    19402307        return 0;
     
    19792346    my $dirLen = $$dirInfo{DirLen} || length($$dataPt) - $dirStart;
    19802347    my $dirName = $$dirInfo{DirName};
    1981     my $verbose = $exifTool->Options('Verbose');
    19822348    my $newData = substr($$dataPt, $dirStart, $dirLen) or return undef;
    19832349    $dataPt = \$newData;
     
    19852351    # first entry in array must be the size
    19862352    my $len = Get16u($dataPt, 0);
    1987     unless ($len == $dirLen or ($$exifTool{CameraModel}=~/\bD60\b/ and $len+2 == $dirLen)) {
     2353    unless ($len == $dirLen or ($$exifTool{Model}=~/\bD60\b/ and $len+2 == $dirLen)) {
    19882354        $exifTool->Warn("Invalid CanonCustom data");
    19892355        return undef;
     
    19962362        my $tagInfo = $$newTags{$tag};
    19972363        next unless $tagInfo;
    1998         my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
     2364        my $nvHash = $exifTool->GetNewValueHash($tagInfo);
    19992365        $val = ($val & 0xff);
    2000         next unless Image::ExifTool::IsOverwriting($newValueHash, $val);
    2001         my $newVal = Image::ExifTool::GetNewValues($newValueHash);
     2366        next unless Image::ExifTool::IsOverwriting($nvHash, $val);
     2367        my $newVal = Image::ExifTool::GetNewValues($nvHash);
    20022368        next unless defined $newVal;    # can't delete from a custom table
    20032369        Set16u(($newVal & 0xff) + ($tag << 8), $dataPt, $pos);
    2004         if ($verbose > 1) {
    2005             $exifTool->VPrint(0, "    - $dirName:$$tagInfo{Name} = '$val'\n",
    2006                                  "    + $dirName:$$tagInfo{Name} = '$newVal'\n");
    2007         }
     2370        $exifTool->VerboseValue("- $dirName:$$tagInfo{Name}", $val);
     2371        $exifTool->VerboseValue("+ $dirName:$$tagInfo{Name}", $newVal);
    20082372        ++$exifTool->{CHANGED};
    20092373    }
     
    20332397=head1 AUTHOR
    20342398
    2035 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     2399Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    20362400
    20372401This library is free software; you can redistribute it and/or modify it
     
    20492413
    20502414Thanks to Christian Koller for his work in decoding the 20D custom
    2051 functions, and Rainer Honle for decoding the 5D custom functions.
     2415functions, Rainer Honle for decoding the 5D custom functions and David
     2416Pitcher for adding a few undocumented 1DmkIII settings.
    20522417
    20532418=head1 SEE ALSO
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonRaw.pm

    r16842 r24107  
    1212#               2) http://www.wonderland.org/crw/
    1313#               3) http://xyrion.org/ciff/CIFFspecV1R04.pdf
     14#               4) Dave Nicholson private communication (PowerShot S30)
    1415#------------------------------------------------------------------------------
    1516
     
    1819use strict;
    1920use vars qw($VERSION $AUTOLOAD %crwTagFormat);
    20 use Image::ExifTool qw(:DataAccess);
     21use Image::ExifTool qw(:DataAccess :Utils);
    2122use Image::ExifTool::Exif;
    2223use Image::ExifTool::Canon;
    2324
    24 $VERSION = '1.42';
     25$VERSION = '1.54';
    2526
    2627sub WriteCRW($$);
     
    132133        },
    133134    },
    134     0x102c => { Name => 'CanonColorInfo2', Writable => 0 },
     135    0x102c => {
     136        Name => 'CanonColorInfo2',
     137        Writable => 0,
     138        # for the S30, the following information has been decoded: (ref 4)
     139        # offset 66: int32u - shutter half press time in ms
     140        # offset 70: int32u - image capture time in ms
     141        # offset 74: int16u - custom white balance flag (0=Off, 512=On)
     142    },
    135143    0x102d => {
    136144        Name => 'CanonCameraSettings',
     
    138146        SubDirectory => {
    139147            TagTable => 'Image::ExifTool::Canon::CameraSettings',
     148        },
     149    },
     150    0x1030 => { #4
     151        Name => 'WhiteSample',
     152        Writable => 0,
     153        SubDirectory => {
     154            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     155            TagTable => 'Image::ExifTool::CanonRaw::WhiteSample',
    140156        },
    141157    },
     
    152168        {
    153169            Name => 'CustomFunctions10D',
    154             Condition => '$self->{CameraModel} =~ /EOS 10D/',
     170            Condition => '$self->{Model} =~ /EOS 10D/',
    155171            SubDirectory => {
    156172                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     
    160176        {
    161177            Name => 'CustomFunctionsD30',
    162             Condition => '$self->{CameraModel} =~ /EOS D30\b/',
     178            Condition => '$self->{Model} =~ /EOS D30\b/',
    163179            SubDirectory => {
    164180                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
     
    168184        {
    169185            Name => 'CustomFunctionsD60',
    170             Condition => '$self->{CameraModel} =~ /EOS D60\b/',
     186            Condition => '$self->{Model} =~ /EOS D60\b/',
    171187            SubDirectory => {
    172188                # the stored size in the D60 apparently doesn't include the size word:
     
    241257        ValueConv => '$val / 1000',
    242258        ValueConvInv => '$val * 1000',
    243         PrintConv => '"$val sec"',
    244         PrintConvInv => '$val=~s/\s*sec.*//;$val',
     259        PrintConv => '"$val s"',
     260        PrintConvInv => '$val=~s/\s*s.*//;$val',
    245261    },
    246262    0x1807 => {
     
    250266        PrintConvInv => '$val=~s/\s*mm$//;$val',
    251267    },
    252     0x180b => {
    253         Name => 'SerialNumber',
    254         Writable => 'int32u',
    255         Description => 'Camera Body No.',
    256         PrintConv => 'sprintf("%.10d",$val)',
    257         PrintConvInv => '$val',
    258     },
     268    0x180b => [
     269        {
     270            # D30
     271            Name => 'SerialNumber',
     272            Condition => '$$self{Model} =~ /EOS D30\b/',
     273            Writable => 'int32u',
     274            PrintConv => 'sprintf("%x-%.5d",$val>>16,$val&0xffff)',
     275            PrintConvInv => '$val=~/(.*)-(\d+)/ ? (hex($1)<<16)+$2 : undef',
     276        },
     277        {
     278            # all EOS models (D30, 10D, 300D)
     279            Name => 'SerialNumber',
     280            Condition => '$$self{Model} =~ /EOS/',
     281            Writable => 'int32u',
     282            PrintConv => 'sprintf("%.10d",$val)',
     283            PrintConvInv => '$val',
     284        },
     285        {
     286            # this is not SerialNumber for PowerShot models (but what is it?) - PH
     287            Name => 'UnknownNumber',
     288            Unknown => 1,
     289        },
     290    ],
    259291    0x180e => {
    260292        Name => 'TimeStamp',
     
    281313        Name => 'MeasuredEV',
    282314        Notes => q{
    283             this the Canon name for what should properly be called MeasuredLV, and is
    284             offset by about -5 EV from the calculated LV for most models
     315            this is the Canon name for what could better be called MeasuredLV, and
     316            should be close to the calculated LightValue for a proper exposure with most
     317            models
    285318        },
    286319        Format => 'float',
     320        ValueConv => '$val + 5',
     321        ValueConvInv => '$val - 5',
    287322    },
    288323    0x1817 => {
     
    295330    0x1818 => { #3
    296331        Name => 'ExposureInfo',
     332        Groups => { 1 => 'CIFF' }, # (only so CIFF shows up in group lists)
    297333        Writable => 0,
    298334        SubDirectory => {
     
    314350        Name => 'DecoderTable',
    315351        Writable => 0,
     352        SubDirectory => {
     353            TagTable => 'Image::ExifTool::CanonRaw::DecoderTable',
     354        },
    316355    },
    317356    0x183b => { #PH
     
    334373        Writable => 'resize',  # 'resize' allows this value to change size
    335374        Permanent => 0,
    336         ValueConv => '$self->ValidateImage(\$val,$tag)',
    337         ValueConvInv => '$val',
     375        RawConv => '$self->ValidateImage(\$val,$tag)',
    338376    },
    339377    0x2008 => {
     
    342380        WriteCheck => '$self->CheckImage(\$val)',
    343381        Permanent => 0,
    344         ValueConv => '$self->ValidateImage(\$val,$tag)',
    345         ValueConvInv => '$val',
     382        RawConv => '$self->ValidateImage(\$val,$tag)',
    346383    },
    347384    # the following entries are subdirectories
     
    398435        Name => 'Make',
    399436        Format => 'string[6]',  # "Canon\0"
    400         DataMember => 'CameraMake',
    401         RawConv => '$self->{CameraMake} = $val',
     437        DataMember => 'Make',
     438        RawConv => '$self->{Make} = $val',
    402439    },
    403440    6 => {
    404441        Name => 'Model',
    405         Format => 'string[$size-6]',
     442        Format => 'string', # no size = to the end of the data
    406443        Description => 'Camera Model Name',
    407         DataMember => 'CameraModel',
    408         RawConv => '$self->{CameraModel} = $val',
     444        DataMember => 'Model',
     445        RawConv => '$self->{Model} = $val',
    409446    },
    410447);
     
    425462        ValueConvInv => 'GetUnixTime($val)',
    426463        PrintConv => '$self->ConvertDateTime($val)',
    427         PrintConvInv => '$val',
     464        PrintConvInv => '$self->InverseDateTime($val)',
    428465    },
    429466    1 => { #3
     
    514551    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
    515552    0 => 'ExposureCompensation',
    516     1 => 'TvValue',
    517     2 => 'AvValue',
     553    1 => {
     554        Name => 'ShutterSpeedValue',
     555        ValueConv => 'abs($val)<100 ? 1/(2**$val) : 0',
     556        ValueConvInv => '$val>0 ? -log($val)/log(2) : -100',
     557        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     558        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     559    },
     560    2 => {
     561        Name => 'ApertureValue',
     562        ValueConv => '2 ** ($val / 2)',
     563        ValueConvInv => '$val>0 ? 2*log($val)/log(2) : 0',
     564        PrintConv => 'sprintf("%.1f",$val)',
     565        PrintConvInv => '$val',
     566    },
    518567);
    519568
     
    523572    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    524573    FORMAT => 'int32u',
    525     FIRST_ENTRY => 1,
     574    FIRST_ENTRY => 0,
    526575    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
    527576    # Note: Don't make these writable (except rotation) because it confuses
     
    541590    5 => 'ColorBitDepth', #3
    542591    6 => 'ColorBW', #3
     592);
     593
     594# ref 4
     595%Image::ExifTool::CanonRaw::DecoderTable = (
     596    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     597    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     598    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     599    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     600    FORMAT => 'int32u',
     601    FIRST_ENTRY => 0,
     602    0 => 'DecoderTableNumber',
     603    2 => 'CompressedDataOffset',
     604    3 => 'CompressedDataLength',
     605);
     606
     607# ref 1/4
     608%Image::ExifTool::CanonRaw::WhiteSample = (
     609    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     610    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     611    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     612    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     613    FORMAT => 'int16u',
     614    FIRST_ENTRY => 1,
     615    1 => 'WhiteSampleWidth',
     616    2 => 'WhiteSampleHeight',
     617    3 => 'WhiteSampleLeftBorder',
     618    4 => 'WhiteSampleTopBorder',
     619    5 => 'WhiteSampleBits',
     620    # this is followed by the encrypted white sample values (ref 1)
    543621);
    544622
     
    576654    $raf->Read($buff, 10 * $entries) == 10 * $entries or return 0;
    577655
    578     $verbose and $exifTool->VerboseDir('Raw', $entries);
     656    $verbose and $exifTool->VerboseDir('CIFF', $entries);
    579657    my $index;
    580658    for ($index=0; $index<$entries; ++$index) {
     
    649727                $value = "Binary data $size bytes";
    650728                if ($tagInfo) {
    651                     if ($exifTool->Options('Binary')) {
     729                    if ($exifTool->Options('Binary') or $verbose) {
    652730                        # read the value anyway
    653731                        unless ($raf->Seek($ptr, 0) and $raf->Read($value, $size) == $size) {
     
    695773            my $newTagTable;
    696774            if ($$subdir{TagTable}) {
    697                 $newTagTable = Image::ExifTool::GetTagTable($$subdir{TagTable});
     775                $newTagTable = GetTagTable($$subdir{TagTable});
    698776                unless ($newTagTable) {
    699777                    warn "Unknown tag table $$subdir{TagTable}\n";
     
    761839
    762840    # set the FileType tag unless already done (ie. APP0 CIFF record in JPEG image)
    763     $exifTool->SetFileType() unless $exifTool->GetValue('FileType');
     841    $exifTool->SetFileType();
    764842
    765843    # build directory information for main raw directory
     
    774852
    775853    # process the raw directory
    776     my $rawTagTable = Image::ExifTool::GetTagTable('Image::ExifTool::CanonRaw::Main');
     854    my $rawTagTable = GetTagTable('Image::ExifTool::CanonRaw::Main');
    777855    unless ($exifTool->ProcessDirectory(\%dirInfo, $rawTagTable)) {
    778856        $exifTool->Warn('CRW file format error');
     
    782860    $buildMakerNotes and SaveMakerNotes($exifTool);
    783861
    784     # process trailers if they exist
    785     my $trailInfo = Image::ExifTool::IdentifyTrailer($raf);
    786     $exifTool->ProcessTrailers($trailInfo) if $trailInfo;
     862    # process trailers if they exist in CRW file (not in CIFF information!)
     863    if ($$exifTool{FILE_TYPE} eq 'CRW') {
     864        my $trailInfo = Image::ExifTool::IdentifyTrailer($raf);
     865        $exifTool->ProcessTrailers($trailInfo) if $trailInfo;
     866    }
    787867
    788868    return 1;
     
    816896=head1 AUTHOR
    817897
    818 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     898Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    819899
    820900This library is free software; you can redistribute it and/or modify it
     
    834914
    835915=back
     916
     917=head1 ACKNOWLEDGEMENTS
     918
     919Thanks to Dave Nicholson for decoding a number of new tags.
    836920
    837921=head1 SEE ALSO
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonVRD.pm

    r16842 r24107  
    44# Description:  Read/write Canon VRD information
    55#
    6 # Revisions:    10/30/2006 - P. Harvey Created
     6# Revisions:    2006/10/30 - P. Harvey Created
     7#               2007/10/23 - PH Added new VRD 3.0 tags
     8#               2008/08/29 - PH Added new VRD 3.4 tags
     9#               2008/12/02 - PH Added new VRD 3.5 tags
     10#               2010/06/18 - PH Support variable-length CustomPictureStyle data
     11#               2010/09/14 - PH Added r/w support for XMP in VRD
     12#
     13# References:   1) Bogdan private communication (Canon DPP v3.4.1.1)
     14#               2) Gert Kello private communiation (DPP 3.8)
    715#------------------------------------------------------------------------------
    816
     
    1321use Image::ExifTool qw(:DataAccess :Utils);
    1422
    15 $VERSION = '1.05';
    16 
    17 sub ProcessCanonVRD($$);
    18 
    19 my $debug;  # set this to 1 for offsets relative to binary data start
     23$VERSION = '1.12';
     24
     25sub ProcessCanonVRD($$;$);
     26sub WriteCanonVRD($$;$);
     27sub ProcessEditData($$$);
     28sub ProcessIHL($$$);
     29sub ProcessIHLExif($$$);
     30
     31# map for adding directories to VRD
     32my %vrdMap = (
     33    XMP      => 'CanonVRD',
     34    CanonVRD => 'VRD',
     35);
    2036
    2137my %noYes = ( 0 => 'No', 1 => 'Yes' );
    2238
    23 # main tag table IPTC-format records in CanonVRD trailer
     39# main tag table blocks in CanonVRD trailer (ref PH)
    2440%Image::ExifTool::CanonVRD::Main = (
    25     VARS => { INDEX => 1 },
     41    WRITE_PROC => \&WriteCanonVRD,
     42    PROCESS_PROC => \&ProcessCanonVRD,
    2643    NOTES => q{
    2744        Canon Digital Photo Professional writes VRD (Recipe Data) information as a
    2845        trailer record to JPEG, TIFF, CRW and CR2 images, or as a stand-alone VRD
    29         file. The tags listed below represent information found in this record.  The
    30         complete VRD data record may be accessed as a block using the Extra
     46        file.  The tags listed below represent information found in this record.
     47        The complete VRD data record may be accessed as a block using the Extra
    3148        'CanonVRD' tag, but this tag is not extracted or copied unless specified
    3249        explicitly.
    3350    },
     51    0xffff00f4 => {
     52        Name => 'EditData',
     53        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::Edit' },
     54    },
     55    0xffff00f5 => {
     56        Name => 'IHLData',
     57        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::IHL' },
     58    },
     59    0xffff00f6 => {
     60        Name => 'XMP',
     61        Flags => [ 'Binary', 'Protected' ],
     62        Writable => 'undef',    # allow writing/deleting as a block
     63        SubDirectory => {
     64            DirName => 'XMP',
     65            TagTable => 'Image::ExifTool::XMP::Main',
     66        },
     67    },
     68);
     69
     70# the VRD edit information is divided into sections
     71%Image::ExifTool::CanonVRD::Edit = (
     72    WRITE_PROC => \&ProcessEditData,
     73    PROCESS_PROC => \&ProcessEditData,
     74    VARS => { ID_LABEL => 'Index' }, # change TagID label in documentation
     75    NOTES => 'Canon VRD edit information.',
    3476    0 => {
    3577        Name => 'VRD1',
     
    5092);
    5193
    52 # VRD version 1 tags
     94# "IHL Created Optional Item Data" tags (not yet writable)
     95%Image::ExifTool::CanonVRD::IHL = (
     96    PROCESS_PROC => \&ProcessIHL,
     97    TAG_PREFIX => 'VRD_IHL',
     98    GROUPS => { 2 => 'Image' },
     99    1 => [
     100        # this contains edited TIFF-format data, with an original IFD at 0x0008
     101        # and an edited IFD with offset given in the TIFF header.
     102        {
     103            Name => 'IHL_EXIF',
     104            Condition => '$self->Options("ExtractEmbedded")',
     105            SubDirectory => {
     106                TagTable => 'Image::ExifTool::Exif::Main',
     107                ProcessProc => \&ProcessIHLExif,
     108            },
     109        },{
     110            Name => 'IHL_EXIF',
     111            Notes => q{
     112                extracted as a block if the Unknown option is used, or processed as the
     113                first sub-document with the ExtractEmbedded option
     114            },
     115            Binary => 1,
     116            Unknown => 1,
     117        },
     118    ],
     119    # 2 - written by DPP 3.0.2.6, and it looks something like edit data,
     120    #     but I haven't decoded it yet - PH
     121    3 => {
     122        # (same size as the PreviewImage with DPP 3.0.2.6)
     123        Name => 'ThumbnailImage',
     124        Binary => 1,
     125    },
     126    4 => {
     127        Name => 'PreviewImage',
     128        Binary => 1,
     129    },
     130    5 => {
     131        Name => 'RawCodecVersion',
     132        ValueConv => '$val =~ s/\0.*//; $val',  # truncate string at null
     133    },
     134    6 => {
     135        Name => 'CRCDevelParams',
     136        Binary => 1,
     137        Unknown => 1,
     138    },
     139);
     140
     141# VRD version 1 tags (ref PH)
    53142%Image::ExifTool::CanonVRD::Ver1 = (
    54143    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     
    56145    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    57146    WRITABLE => 1,
     147    FIRST_ENTRY => 0,
    58148    GROUPS => { 2 => 'Image' },
     149    DATAMEMBER => [ 0x002 ],   # necessary for writing
    59150#
    60151# RAW image adjustment
     
    64155        Format => 'int16u',
    65156        Writable => 0,
     157        DataMember => 'VRDVersion',
     158        RawConv => '$$self{VRDVersion} = $val',
    66159        PrintConv => 'sprintf("%.2f", $val / 100)',
    67160    },
     
    162255        PrintConv => \%noYes,
    163256    },
     257    0x113 => {
     258        Name => 'ToneCurveMode',
     259        PrintConv => { 0 => 'RGB', 1 => 'Luminance' },
     260    },
    164261    0x114 => {
    165262        Name => 'BrightnessAdj',
     
    178275        Notes => 'in degrees, so -1 is the same as 359',
    179276        Format => 'int32s',
     277    },
     278    0x126 => {
     279        Name => 'LuminanceCurvePoints',
     280        Format => 'int16u[21]',
     281        PrintConv => 'Image::ExifTool::CanonVRD::ToneCurvePrint($val)',
     282        PrintConvInv => 'Image::ExifTool::CanonVRD::ToneCurvePrintInv($val)',
     283    },
     284    0x150 => {
     285        Name => 'LuminanceCurveLimits',
     286        Notes => '4 numbers: input and output highlight and shadow points',
     287        Format => 'int16u[4]',
     288    },
     289    0x159 => {
     290        Name => 'ToneCurveInterpolation',
     291        PrintConv => { 0 => 'Curve', 1 => 'Straight' },
    180292    },
    181293    0x160 => {
     
    185297        PrintConvInv => 'Image::ExifTool::CanonVRD::ToneCurvePrintInv($val)',
    186298    },
     299    # 0x193 same as 0x159
    187300    0x19a => {
    188301        Name => 'GreenCurvePoints',
     
    191304        PrintConvInv => 'Image::ExifTool::CanonVRD::ToneCurvePrintInv($val)',
    192305    },
     306    # 0x1cd same as 0x159
    193307    0x1d4 => {
    194308        Name => 'BlueCurvePoints',
     
    199313    0x18a => {
    200314        Name => 'RedCurveLimits',
    201         Notes => '4 numbers: input and output highlight and shadow points',
    202315        Format => 'int16u[4]',
    203316    },
     
    210323        Format => 'int16u[4]',
    211324    },
     325    # 0x207 same as 0x159
    212326    0x20e => {
    213327        Name => 'RGBCurvePoints',
     
    220334        Format => 'int16u[4]',
    221335    },
     336    # 0x241 same as 0x159
    222337    0x244 => {
    223338        Name => 'CropActive',
     
    240355    0x24c => {
    241356        Name => 'CropHeight',
     357        Format => 'int16u',
     358    },
     359    0x25a => {
     360        Name => 'SharpnessAdj',
    242361        Format => 'int16u',
    243362    },
     
    303422        },
    304423    },
    305     # (VRD 1.0 edit data ends here -- 0x272 bytes long)
     424    # (VRD 1.0 edit data ends here -- 0x272 bytes)
    306425);
    307426
    308 # VRD Stamp Tool tags
     427# VRD Stamp Tool tags (ref PH)
    309428%Image::ExifTool::CanonVRD::StampTool = (
    310429    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     
    316435);
    317436
    318 # VRD version 2 and 3 tags
     437# VRD version 2 and 3 tags (ref PH)
    319438%Image::ExifTool::CanonVRD::Ver2 = (
    320439    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     
    322441    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    323442    WRITABLE => 1,
     443    FIRST_ENTRY => 0,
     444    FORMAT => 'int16s',
     445    DATAMEMBER => [ 0x58 ], # (required for writable var-format tags)
    324446    GROUPS => { 2 => 'Image' },
    325447    NOTES => 'Tags added in DPP version 2.0 and later.',
    326     0x04 => {
     448    0x02 => {
    327449        Name => 'PictureStyle',
    328         Format => 'int16u',
    329450        PrintConv => {
    330451            0 => 'Standard',
     
    334455            4 => 'Faithful',
    335456            5 => 'Monochrome',
    336         },
    337     },
    338     0x1a => {
    339         Name => 'RawColorToneAdj',
    340         Format => 'int16s',
    341     },
    342     0x1c => {
    343         Name => 'RawSaturationAdj',
    344         Format => 'int16s',
    345     },
    346     0x1e => {
    347         Name => 'RawContrastAdj',
    348         Format => 'int16s',
    349     },
    350     0x20 => {
    351         Name => 'RawLinear',
    352         Format => 'int16u',
     457            6 => 'Unknown?', # PH (maybe in-camera custom picture style?)
     458            7 => 'Custom',
     459        },
     460    },
     461    0x03 => {
     462        Name => 'IsCustomPictureStyle',
    353463        PrintConv => \%noYes,
    354464    },
     465    0x0d => 'StandardRawColorTone',
     466    0x0e => 'StandardRawSaturation',
     467    0x0f => 'StandardRawContrast',
     468    0x10 => {
     469        Name => 'StandardRawLinear',
     470        PrintConv => \%noYes,
     471    },
     472    0x11 => 'StandardRawSharpness',
     473    0x12 => 'StandardRawHighlightPoint',
     474    0x13 => 'StandardRawShadowPoint',
     475    0x14 => 'StandardOutputHighlightPoint', #2
     476    0x15 => 'StandardOutputShadowPoint', #2
     477    0x16 => 'PortraitRawColorTone',
     478    0x17 => 'PortraitRawSaturation',
     479    0x18 => 'PortraitRawContrast',
     480    0x19 => {
     481        Name => 'PortraitRawLinear',
     482        PrintConv => \%noYes,
     483    },
     484    0x1a => 'PortraitRawSharpness',
     485    0x1b => 'PortraitRawHighlightPoint',
     486    0x1c => 'PortraitRawShadowPoint',
     487    0x1d => 'PortraitOutputHighlightPoint',
     488    0x1e => 'PortraitOutputShadowPoint',
     489    0x1f => 'LandscapeRawColorTone',
     490    0x20 => 'LandscapeRawSaturation',
     491    0x21 => 'LandscapeRawContrast',
    355492    0x22 => {
    356         Name => 'RawSharpnessAdj',
    357         Format => 'int16s',
    358     },
    359     0x24 => {
    360         Name => 'RawHighlightPoint',
    361         Format => 'int16s',
    362     },
    363     0x26 => {
    364         Name => 'RawShadowPoint',
    365         Format => 'int16s',
    366     },
    367     0x74 => {
     493        Name => 'LandscapeRawLinear',
     494        PrintConv => \%noYes,
     495    },
     496    0x23 => 'LandscapeRawSharpness',
     497    0x24 => 'LandscapeRawHighlightPoint',
     498    0x25 => 'LandscapeRawShadowPoint',
     499    0x26 => 'LandscapeOutputHighlightPoint',
     500    0x27 => 'LandscapeOutputShadowPoint',
     501    0x28 => 'NeutralRawColorTone',
     502    0x29 => 'NeutralRawSaturation',
     503    0x2a => 'NeutralRawContrast',
     504    0x2b => {
     505        Name => 'NeutralRawLinear',
     506        PrintConv => \%noYes,
     507    },
     508    0x2c => 'NeutralRawSharpness',
     509    0x2d => 'NeutralRawHighlightPoint',
     510    0x2e => 'NeutralRawShadowPoint',
     511    0x2f => 'NeutralOutputHighlightPoint',
     512    0x30 => 'NeutralOutputShadowPoint',
     513    0x31 => 'FaithfulRawColorTone',
     514    0x32 => 'FaithfulRawSaturation',
     515    0x33 => 'FaithfulRawContrast',
     516    0x34 => {
     517        Name => 'FaithfulRawLinear',
     518        PrintConv => \%noYes,
     519    },
     520    0x35 => 'FaithfulRawSharpness',
     521    0x36 => 'FaithfulRawHighlightPoint',
     522    0x37 => 'FaithfulRawShadowPoint',
     523    0x38 => 'FaithfulOutputHighlightPoint',
     524    0x39 => 'FaithfulOutputShadowPoint',
     525    0x3a => {
    368526        Name => 'MonochromeFilterEffect',
    369         Format => 'int16s',
    370527        PrintConv => {
    371528            -2 => 'None',
     
    376533        },
    377534    },
    378     0x76 => {
     535    0x3b => {
    379536        Name => 'MonochromeToningEffect',
    380         Format => 'int16s',
    381537        PrintConv => {
    382538            -2 => 'None',
     
    387543        },
    388544    },
    389     0x78 => {
    390         Name => 'MonochromeContrast',
    391         Format => 'int16s',
    392     },
    393     0x7a => {
     545    0x3c => 'MonochromeContrast',
     546    0x3d => {
    394547        Name => 'MonochromeLinear',
    395         Format => 'int16u',
    396548        PrintConv => \%noYes,
    397549    },
    398     0x7c => {
    399         Name => 'MonochromeSharpness',
    400         Format => 'int16s',
    401     },
    402     # (VRD 2.0 edit data ends here -- offset 0xb2)
    403     0xbc => {
     550    0x3e => 'MonochromeSharpness',
     551    0x3f => 'MonochromeRawHighlightPoint',
     552    0x40 => 'MonochromeRawShadowPoint',
     553    0x41 => 'MonochromeOutputHighlightPoint',
     554    0x42 => 'MonochromeOutputShadowPoint',
     555    0x45 => { Name => 'UnknownContrast',            Unknown => 1 },
     556    0x46 => {
     557        Name => 'UnknownLinear',
     558        Unknown => 1,
     559        PrintConv => \%noYes,
     560    },
     561    0x47 => { Name => 'UnknownSharpness',           Unknown => 1 },
     562    0x48 => { Name => 'UnknownRawHighlightPoint',   Unknown => 1 },
     563    0x49 => { Name => 'UnknownRawShadowPoint',      Unknown => 1 },
     564    0x4a => { Name => 'UnknownOutputHighlightPoint',Unknown => 1 },
     565    0x4b => { Name => 'UnknownOutputShadowPoint',   Unknown => 1 },
     566    0x4e => 'CustomContrast',
     567    0x4f => {
     568        Name => 'CustomLinear',
     569        PrintConv => \%noYes,
     570    },
     571    0x50 => 'CustomSharpness',
     572    0x51 => 'CustomRawHighlightPoint',
     573    0x52 => 'CustomRawShadowPoint',
     574    0x53 => 'CustomOutputHighlightPoint',
     575    0x54 => 'CustomOutputShadowPoint',
     576    0x58 => {
     577        Name => 'CustomPictureStyleData',
     578        Format => 'var_int16u',
     579        Binary => 1,
     580        Notes => 'variable-length data structure',
     581        Writable => 0,
     582        RawConv => 'length($val) == 2 ? undef : $val', # ignore if no data
     583    },
     584    # (VRD 2.0 edit data ends here: 178 bytes, index 0x59)
     585    0x5e => [{
    404586        Name => 'ChrominanceNoiseReduction',
    405         Format => 'int16u',
     587        Condition => '$$self{VRDVersion} < 330',
     588        Notes => 'VRDVersion prior to 3.30',
    406589        PrintConv => {
    407590            0   => 'Off',
     
    409592            100 => 'High',
    410593        },
    411     },
    412     0xbe => {
     594    },{ #1
     595        Name => 'ChrominanceNoiseReduction',
     596        Notes => 'VRDVersion 3.30 or later',
     597        PrintHex => 1,
     598        PrintConvColumns => 4,
     599        PrintConv => {
     600            0x00 => 0,
     601            0x10 => 1,
     602            0x21 => 2,
     603            0x32 => 3,
     604            0x42 => 4,
     605            0x53 => 5,
     606            0x64 => 6,
     607            0x74 => 7,
     608            0x85 => 8,
     609            0x96 => 9,
     610            0xa6 => 10,
     611            0xa7 => 11,
     612            0xa8 => 12,
     613            0xa9 => 13,
     614            0xaa => 14,
     615            0xab => 15,
     616            0xac => 16,
     617            0xad => 17,
     618            0xae => 18,
     619            0xaf => 19,
     620            0xb0 => 20,
     621        },
     622    }],
     623    0x5f => [{
    413624        Name => 'LuminanceNoiseReduction',
    414         Format => 'int16u',
     625        Condition => '$$self{VRDVersion} < 330',
     626        Notes => 'VRDVersion prior to 3.30',
    415627        PrintConv => {
    416628            0   => 'Off',
     
    418630            100 => 'High',
    419631        },
    420     },
    421     0xc0 => {
     632    },{ #1
     633        Name => 'LuminanceNoiseReduction',
     634        Notes => 'VRDVersion 3.30 or later',
     635        PrintHex => 1,
     636        PrintConvColumns => 4,
     637        PrintConv => {
     638            0x00 => 0,
     639            0x41 => 1,
     640            0x64 => 2,
     641            0x6e => 3,
     642            0x78 => 4,
     643            0x82 => 5,
     644            0x8c => 6,
     645            0x96 => 7,
     646            0xa0 => 8,
     647            0xaa => 9,
     648            0xb4 => 10,
     649            0xb5 => 11,
     650            0xb6 => 12,
     651            0xb7 => 13,
     652            0xb8 => 14,
     653            0xb9 => 15,
     654            0xba => 16,
     655            0xbb => 17,
     656            0xbc => 18,
     657            0xbd => 19,
     658            0xbe => 20,
     659        },
     660    }],
     661    0x60 => [{
    422662        Name => 'ChrominanceNR_TIFF_JPEG',
    423         Format => 'int16u',
     663        Condition => '$$self{VRDVersion} < 330',
     664        Notes => 'VRDVersion prior to 3.30',
    424665        PrintConv => {
    425666            0   => 'Off',
     
    427668            100 => 'High',
    428669        },
    429     }
    430     # (VRD 3.0 edit data ends here -- offset 0xc4)
     670    },{ #1
     671        Name => 'ChrominanceNR_TIFF_JPEG',
     672        Notes => 'VRDVersion 3.30 or later',
     673        PrintHex => 1,
     674        PrintConvColumns => 4,
     675        PrintConv => {
     676            0x00 => 0,
     677            0x10 => 1,
     678            0x21 => 2,
     679            0x32 => 3,
     680            0x42 => 4,
     681            0x53 => 5,
     682            0x64 => 6,
     683            0x74 => 7,
     684            0x85 => 8,
     685            0x96 => 9,
     686            0xa6 => 10,
     687            0xa7 => 11,
     688            0xa8 => 12,
     689            0xa9 => 13,
     690            0xaa => 14,
     691            0xab => 15,
     692            0xac => 16,
     693            0xad => 17,
     694            0xae => 18,
     695            0xaf => 19,
     696            0xb0 => 20,
     697        },
     698    }],
     699    # (VRD 3.0 edit data ends here: 196 bytes, index 0x62)
     700    0x62 => {
     701        Name => 'ChromaticAberrationOn',
     702        ValueConv => \%noYes,
     703    },
     704    0x63 => {
     705        Name => 'DistortionCorrectionOn',
     706        ValueConv => \%noYes,
     707    },
     708    0x64 => {
     709        Name => 'PeripheralIlluminationOn',
     710        ValueConv => \%noYes,
     711    },
     712    0x65 => {
     713        Name => 'ColorBlur',
     714        ValueConv => \%noYes,
     715    },
     716    0x66 => {
     717        Name => 'ChromaticAberration',
     718        ValueConv => '$val / 0x400',
     719        ValueConvInv => 'int($val * 0x400 + 0.5)',
     720        PrintConv => 'sprintf("%.0f%%", $val * 100)',
     721        PrintConvInv => 'ToFloat($val) / 100',
     722    },
     723    0x67 => {
     724        Name => 'DistortionCorrection',
     725        ValueConv => '$val / 0x400',
     726        ValueConvInv => 'int($val * 0x400 + 0.5)',
     727        PrintConv => 'sprintf("%.0f%%", $val * 100)',
     728        PrintConvInv => 'ToFloat($val) / 100',
     729    },
     730    0x68 => {
     731        Name => 'PeripheralIllumination',
     732        ValueConv => '$val / 0x400',
     733        ValueConvInv => 'int($val * 0x400 + 0.5)',
     734        PrintConv => 'sprintf("%.0f%%", $val * 100)',
     735        PrintConvInv => 'ToFloat($val) / 100',
     736    },
     737    0x69 => {
     738        Name => 'AberrationCorrectionDistance',
     739        Notes => '100% = infinity',
     740        RawConv => '$val == 0x7fff ? undef : $val',
     741        ValueConv => '1 - $val / 0x400',
     742        ValueConvInv => 'int((1 - $val) * 0x400 + 0.5)',
     743        PrintConv => 'sprintf("%.0f%%", $val * 100)',
     744        PrintConvInv => 'ToFloat($val) / 100',
     745    },
     746    0x6a => 'ChromaticAberrationRed',
     747    0x6b => 'ChromaticAberrationBlue',
     748    0x6d => { #1
     749        Name => 'LuminanceNR_TIFF_JPEG',
     750        Notes => 'val = raw / 10',
     751        ValueConv => '$val / 10',
     752        ValueConvInv => 'int($val * 10 + 0.5)',
     753    },
     754    # (VRD 3.4 edit data ends here: 220 bytes, index 0x6e)
     755    0x6e => {
     756        Name => 'AutoLightingOptimizerOn',
     757        PrintConv => \%noYes,
     758    },
     759    0x6f => {
     760        Name => 'AutoLightingOptimizer',
     761        PrintConv => {
     762            100 => 'Low',
     763            200 => 'Standard',
     764            300 => 'Strong',
     765            0x7fff => 'n/a', #1
     766        },
     767    },
     768    # (VRD 3.5 edit data ends here: 232 bytes, index 0x74)
     769    0x75 => {
     770        Name => 'StandardRawHighlight',
     771        ValueConv => '$val / 10',
     772        ValueConvInv => '$val * 10',
     773    },
     774    0x76 => {
     775        Name => 'PortraitRawHighlight',
     776        ValueConv => '$val / 10',
     777        ValueConvInv => '$val * 10',
     778    },
     779    0x77 => {
     780        Name => 'LandscapeRawHighlight',
     781        ValueConv => '$val / 10',
     782        ValueConvInv => '$val * 10',
     783    },
     784    0x78 => {
     785        Name => 'NeutralRawHighlight',
     786        ValueConv => '$val / 10',
     787        ValueConvInv => '$val * 10',
     788    },
     789    0x79 => {
     790        Name => 'FaithfulRawHighlight',
     791        ValueConv => '$val / 10',
     792        ValueConvInv => '$val * 10',
     793    },
     794    0x7a => {
     795        Name => 'MonochromeRawHighlight',
     796        ValueConv => '$val / 10',
     797        ValueConvInv => '$val * 10',
     798    },
     799    0x7b => {
     800        Name => 'UnknownRawHighlight',
     801        Unknown => 1,
     802        ValueConv => '$val / 10',
     803        ValueConvInv => '$val * 10',
     804    },
     805    0x7c => {
     806        Name => 'CustomRawHighlight',
     807        ValueConv => '$val / 10',
     808        ValueConvInv => '$val * 10',
     809    },
     810    0x7e => {
     811        Name => 'StandardRawShadow',
     812        ValueConv => '$val / 10',
     813        ValueConvInv => '$val * 10',
     814    },
     815    0x7f => {
     816        Name => 'PortraitRawShadow',
     817        ValueConv => '$val / 10',
     818        ValueConvInv => '$val * 10',
     819    },
     820    0x80 => {
     821        Name => 'LandscapeRawShadow',
     822        ValueConv => '$val / 10',
     823        ValueConvInv => '$val * 10',
     824    },
     825    0x81 => {
     826        Name => 'NeutralRawShadow',
     827        ValueConv => '$val / 10',
     828        ValueConvInv => '$val * 10',
     829    },
     830    0x82 => {
     831        Name => 'FaithfulRawShadow',
     832        ValueConv => '$val / 10',
     833        ValueConvInv => '$val * 10',
     834    },
     835    0x83 => {
     836        Name => 'MonochromeRawShadow',
     837        ValueConv => '$val / 10',
     838        ValueConvInv => '$val * 10',
     839    },
     840    0x84 => {
     841        Name => 'UnknownRawShadow',
     842        Unknown => 1,
     843        ValueConv => '$val / 10',
     844        ValueConvInv => '$val * 10',
     845    },
     846    0x85 => {
     847        Name => 'CustomRawShadow',
     848        ValueConv => '$val / 10',
     849        ValueConvInv => '$val * 10',
     850    },
     851    0x8b => { #2
     852        Name => 'AngleAdj',
     853        Format => 'int32s',
     854        ValueConv => '$val / 100',
     855        ValueConvInv => '$val * 100',
     856    },
     857    0x8e => {
     858        Name => 'CheckMark2',
     859        Format => 'int16u',
     860        PrintConv => {
     861            0 => 'Clear',
     862            1 => 1,
     863            2 => 2,
     864            3 => 3,
     865            4 => 4,
     866            5 => 5,
     867        },
     868    },
     869    # (VRD 3.8 edit data ends here: 286 bytes, index 0x8f)
     870    0x90 => {
     871        Name => 'UnsharpMask',
     872        PrintConv => { 0 => 'Off', 1 => 'On' },
     873    },
     874    0x92 => 'UnsharpMaskStrength',
     875    0x94 => 'UnsharpMaskFineness',
     876    0x96 => 'UnsharpMaskThreshold',
     877    # (VRD 3.91 edit data ends here: 392 bytes, index 0xc4)
    431878);
    432879
     
    461908
    462909#------------------------------------------------------------------------------
     910# Read/Write VRD edit data
     911# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     912# Returns: Reading: 1 on success; Writing: modified edit data, or undef if nothing changed
     913sub ProcessEditData($$$)
     914{
     915    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     916    $exifTool or return 1;    # allow dummy access
     917    my $dataPt = $$dirInfo{DataPt};
     918    my $pos = $$dirInfo{DirStart};
     919    my $dataPos = $$dirInfo{DataPos};
     920    my $outfile = $$dirInfo{OutFile};
     921    my $dirLen = $$dirInfo{DirLen};
     922    my $dirEnd = $pos + $dirLen;
     923    my $verbose = $exifTool->Options('Verbose');
     924    my $out = $exifTool->Options('TextOut');
     925    my $oldChanged = $$exifTool{CHANGED};
     926
     927    $exifTool->VerboseDir('VRD Edit Data', 0, $dirLen);
     928
     929    # loop through all records in the edit data
     930    my ($recNum, $recLen, $err);
     931    for ($recNum=0;; ++$recNum, $pos+=$recLen) {
     932        if ($pos + 4 > $dirEnd) {
     933            last if $pos == $dirEnd;    # all done if we arrived at end
     934            $recLen = 0;    # just reset record size (will exit loop on test below)
     935        } else {
     936            $recLen = Get32u($dataPt, $pos);
     937        }
     938        $pos += 4;          # move to start of record
     939        if ($pos + $recLen > $dirEnd) {
     940            $exifTool->Warn('Possibly corrupt CanonVRD Edit record');
     941            $err = 1;
     942            last;
     943        }
     944        if ($verbose > 1 and not $outfile) {
     945            printf $out "$$exifTool{INDENT}CanonVRD Edit record ($recLen bytes at offset 0x%x)\n",
     946                   $pos + $dataPos;
     947        }
     948
     949        # our edit information is the 0th record, so don't process the others
     950        next if $recNum;
     951
     952        # process VRD edit information
     953        my $subTablePtr = GetTagTable('Image::ExifTool::CanonVRD::Edit');
     954        my $index;
     955        my $editData = substr($$dataPt, $pos, $recLen);
     956        my %subdirInfo = (
     957            DataPt => \$editData,
     958            DataPos => $dataPos + $pos,
     959        );
     960        my $start = 0;
     961        # loop through various sections of the VRD edit data
     962        for ($index=0; ; ++$index) {
     963            my $tagInfo = $$subTablePtr{$index} or last;
     964            my $dirLen;
     965            my $maxLen = $recLen - $start;
     966            if ($$tagInfo{Size}) {
     967                $dirLen = $$tagInfo{Size};
     968            } elsif (defined $$tagInfo{Size}) {
     969                # get size from int32u at $start
     970                last unless $start + 4 <= $recLen;
     971                $dirLen = Get32u(\$editData, $start);
     972                $start += 4; # skip the length word
     973            } else {
     974                $dirLen = $maxLen;
     975            }
     976            $dirLen > $maxLen and $dirLen = $maxLen;
     977            if ($dirLen) {
     978                my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
     979                my $subName = $$tagInfo{Name};
     980                $subdirInfo{DirStart} = $start;
     981                $subdirInfo{DirLen} = $dirLen;
     982                $subdirInfo{DirName} = $subName;
     983                if ($outfile) {
     984                    # rewrite this section of the VRD edit information
     985                    $verbose and print $out "  Rewriting Canon $subName\n";
     986                    my $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
     987                    substr($$dataPt, $pos+$start, $dirLen) = $newVal if $newVal;
     988                } else {
     989                    $exifTool->VPrint(0, "$$exifTool{INDENT}$subName (SubDirectory) -->\n");
     990                    $exifTool->VerboseDump(\$editData,
     991                        Start => $start,
     992                        Addr  => $dataPos + $pos + $start,
     993                        Len   => $dirLen,
     994                    );
     995                    # extract tags from this section of the VRD edit information
     996                    $exifTool->ProcessDirectory(\%subdirInfo, $subTable);
     997                }
     998            }
     999            # next section starts at the end of this one
     1000            $start += $dirLen;
     1001        }
     1002    }
     1003    if ($outfile) {
     1004        return undef if $oldChanged == $$exifTool{CHANGED};
     1005        return substr($$dataPt, $$dirInfo{DirStart}, $dirLen);
     1006    }
     1007    return $err ? 0 : 1;
     1008}
     1009
     1010#------------------------------------------------------------------------------
     1011# Process VRD IHL data
     1012# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     1013# Returns: 1 on success
     1014sub ProcessIHL($$$)
     1015{
     1016    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     1017    my $dataPt = $$dirInfo{DataPt};
     1018    my $dataPos = $$dirInfo{DataPos};
     1019    my $pos = $$dirInfo{DirStart};
     1020    my $dirLen = $$dirInfo{DirLen};
     1021    my $dirEnd = $pos + $dirLen;
     1022
     1023    $exifTool->VerboseDir('VRD IHL', 0, $dirLen);
     1024
     1025    SetByteOrder('II'); # (make up your mind, Canon!)
     1026    while ($pos + 48 <= $dirEnd) {
     1027        my $hdr = substr($$dataPt, $pos, 48);
     1028        unless ($hdr =~ /^IHL Created Optional Item Data\0\0/) {
     1029            $exifTool->Warn('Possibly corrupted VRD IHL data');
     1030            last;
     1031        }
     1032        my $tag  = Get32u($dataPt, $pos + 36);
     1033        my $size = Get32u($dataPt, $pos + 40); # size of data in IHL record
     1034        my $next = Get32u($dataPt, $pos + 44); # size of complete IHL record
     1035        if ($size > $next or $pos + 48 + $next > $dirEnd) {
     1036            $exifTool->Warn(sprintf('Bad size for VRD IHL tag 0x%.4x', $tag));
     1037            last;
     1038        }
     1039        $pos += 48;
     1040        $exifTool->HandleTag($tagTablePtr, $tag, substr($$dataPt, $pos, $size),
     1041            DataPt  => $dataPt,
     1042            DataPos => $dataPos,
     1043            Start   => $pos,
     1044            Size    => $size
     1045        );
     1046        $pos += $next;
     1047    }
     1048    return 1;
     1049}   
     1050   
     1051#------------------------------------------------------------------------------
     1052# Process VRD IHL EXIF data
     1053# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     1054# Returns: 1 on success
     1055sub ProcessIHLExif($$$)
     1056{
     1057    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     1058    $$exifTool{DOC_NUM} = 1;
     1059    # the IHL-edited maker notes may look messed up, but the offsets should be OK
     1060    my $oldFix = $exifTool->Options(FixBase => 0);
     1061    my $rtnVal = $exifTool->ProcessTIFF($dirInfo, $tagTablePtr);
     1062    $exifTool->Options(FixBase => $oldFix);
     1063    delete $$exifTool{DOC_NUM};
     1064    return $rtnVal;
     1065}
     1066
     1067#------------------------------------------------------------------------------
    4631068# Read/write Canon VRD file
    4641069# Inputs: 0) ExifTool object reference, 1) dirInfo reference
     
    4701075    my $buff;
    4711076    my $num = $raf->Read($buff, 0x1c);
     1077
     1078    # initialize write directories if necessary
     1079    $exifTool->InitWriteDirs(\%vrdMap, 'XMP') if $$dirInfo{OutFile};
     1080
    4721081    if (not $num and $$dirInfo{OutFile}) {
    4731082        # create new VRD file from scratch
     
    4781087            ++$exifTool->{CHANGED};
    4791088        } else {
     1089            # allow VRD to be created from individual tags
     1090            if ($$exifTool{ADD_DIRS}{CanonVRD}) {
     1091                my $newVal = '';
     1092                if (ProcessCanonVRD($exifTool, { OutFile => \$newVal }) > 0) {
     1093                    Write($$dirInfo{OutFile}, $newVal) or return -1;
     1094                    ++$exifTool->{CHANGED};
     1095                    return 1;
     1096                }
     1097            }
    4801098            $exifTool->Error('No CanonVRD information to write');
    4811099        }
     
    4931111
    4941112#------------------------------------------------------------------------------
     1113# Write VRD data record as a block
     1114# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     1115# Returns: VRD data block (may be empty if no VRD data)
     1116# Notes: Increments ExifTool CHANGED flag if changed
     1117sub WriteCanonVRD($$;$)
     1118{
     1119    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     1120    $exifTool or return 1;    # allow dummy access
     1121    my $nvHash = $exifTool->GetNewValueHash($Image::ExifTool::Extra{CanonVRD});
     1122    return undef unless Image::ExifTool::IsOverwriting($nvHash);
     1123    my $val = Image::ExifTool::GetNewValues($nvHash);
     1124    $val = '' unless defined $val;
     1125    ++$exifTool->{CHANGED};
     1126    return $val;
     1127}
     1128
     1129#------------------------------------------------------------------------------
    4951130# Read/write CanonVRD information
    4961131# Inputs: 0) ExifTool object reference, 1) dirInfo reference
     
    4981133# - updates DataPos to point to start of CanonVRD information
    4991134# - updates DirLen to trailer length
    500 sub ProcessCanonVRD($$)
     1135sub ProcessCanonVRD($$;$)
    5011136{
    502     my ($exifTool, $dirInfo) = @_;
     1137    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    5031138    my $raf = $$dirInfo{RAF};
    5041139    my $offset = $$dirInfo{Offset} || 0;
     
    5061141    my $verbose = $exifTool->Options('Verbose');
    5071142    my $out = $exifTool->Options('TextOut');
    508     my ($buff, $footer, $header, $err);
    509     my ($blockLen, $blockType, $recLen, $size);
    510 
     1143    my ($buff, $footer, $header, $created, $err);
     1144    my ($blockLen, $blockType, $size, %didDir);
     1145
     1146    if (not $raf) {
     1147        my $vrdPt = $$dirInfo{DataPt};
     1148        unless ($vrdPt) {
     1149            return 1 unless $outfile;
     1150            # create blank VRD data from scratch
     1151            my $blank = "CANON OPTIONAL DATA\0\0\x01\0\0\0\0\0\0" .
     1152                        "CANON OPTIONAL DATA\0" . ("\0" x 42) . "\xff\xd9";
     1153            $vrdPt = \$blank;
     1154            $verbose and printf $out "  Creating CanonVRD trailer\n";
     1155            $created = 1;
     1156        }
     1157        $raf = new File::RandomAccess($vrdPt);
     1158    }
    5111159    # read and validate the trailer footer
    5121160    $raf->Seek(-64-$offset, 2)    or return 0;
     
    5171165    # read and validate the header too
    5181166    # (header is 0x1c bytes and footer is 0x40 bytes)
    519     unless ($size > 12 and ($size & 0x80000000) == 0 and
     1167    unless (($size & 0x80000000) == 0 and
    5201168            $raf->Seek(-$size-0x5c, 1) and
    5211169            $raf->Read($header, 0x1c) == 0x1c and
     
    5351183
    5361184    if ($outfile) {
     1185        $verbose and not $created and printf $out "  Rewriting CanonVRD trailer\n";
    5371186        # delete CanonVRD information if specified
    5381187        if ($exifTool->{DEL_GROUP}->{CanonVRD} or $exifTool->{DEL_GROUP}->{Trailer} or
     
    5641213        }
    5651214    } elsif ($verbose or $exifTool->{HTML_DUMP}) {
    566         $exifTool->DumpTrailer($dirInfo);
     1215        $exifTool->DumpTrailer($dirInfo) if $$dirInfo{RAF};
    5671216    }
     1217
     1218    $tagTablePtr = GetTagTable('Image::ExifTool::CanonVRD::Main');
    5681219
    5691220    # validate VRD trailer and get position and length of edit record
     
    5711222    my $pos = 0;
    5721223    my $vrdPos = $$dirInfo{DataPos} + length($header);
    573 Block: for (;;) {
     1224    my $dataPt = \$buff;
     1225
     1226    # loop through the VRD blocks
     1227    for (;;) {
    5741228        if ($pos + 8 > $size) {
    5751229            last if $pos == $size;
    5761230            $blockLen = $size;  # mark as invalid
    5771231        } else {
    578             $blockType = Get32u(\$buff, $pos);
    579             $blockLen = Get32u(\$buff, $pos + 4);
     1232            $blockType = Get32u($dataPt, $pos);
     1233            $blockLen = Get32u($dataPt, $pos + 4);
    5801234        }
    5811235        $pos += 8;          # move to start of block
     
    5841238            last;
    5851239        }
    586         printf $out "  CanonVRD block %x ($blockLen bytes at offset 0x%x)\n",
    587             $blockType, $pos + $vrdPos if $verbose > 1 and not $outfile;
    588         # process edit-data block
    589         if ($blockType == 0xffff00f4) {
    590             my $blockEnd = $pos + $blockLen;
    591             my $recNum;
    592             for ($recNum=0;; ++$recNum, $pos+=$recLen) {
    593                 if ($pos + 4 > $blockEnd) {
    594                     last Block if $pos == $blockEnd;  # all done if we arrived at end
    595                     $recLen = $blockEnd;    # mark as invalid
     1240        if ($verbose > 1 and not $outfile) {
     1241            printf $out "  CanonVRD block 0x%.8x ($blockLen bytes at offset 0x%x)\n",
     1242                $blockType, $pos + $vrdPos;
     1243            if ($verbose > 2) {
     1244                my %parms = (
     1245                    Start  => $pos,
     1246                    Addr   => $pos + $vrdPos,
     1247                    Out    => $out,
     1248                    Prefix => $$exifTool{INDENT},
     1249                );
     1250                $parms{MaxLen} = $verbose == 3 ? 96 : 2048 if $verbose < 5;
     1251                Image::ExifTool::HexDump($dataPt, $blockLen, %parms);
     1252            }
     1253        }
     1254        my $tagInfo = $$tagTablePtr{$blockType};
     1255        unless ($tagInfo) {
     1256            unless ($exifTool->Options('Unknown')) {
     1257                $pos += $blockLen;  # step to next block
     1258                next;
     1259            }
     1260            my $name = sprintf('CanonVRD_0x%.8x', $blockType);
     1261            my $desc = $name;
     1262            $desc =~ tr/_/ /;
     1263            $tagInfo = {
     1264                Name        => $name,
     1265                Description => $desc,
     1266                Binary      => 1,
     1267            };
     1268            Image::ExifTool::AddTagToTable($tagTablePtr, $blockType, $tagInfo);
     1269        }
     1270        if ($$tagInfo{SubDirectory}) {
     1271            my $subTablePtr = GetTagTable($$tagInfo{SubDirectory}{TagTable});
     1272            my %subdirInfo = (
     1273                DataPt   => $dataPt,
     1274                DataLen  => length $$dataPt,
     1275                DataPos  => $vrdPos,
     1276                DirStart => $pos,
     1277                DirLen   => $blockLen,
     1278                DirName  => $$tagInfo{Name},
     1279                Parent   => 'CanonVRD',
     1280                OutFile  => $outfile,
     1281            );
     1282            if ($outfile) {
     1283                # set flag indicating we did this directory
     1284                $didDir{$$tagInfo{Name}} = 1;
     1285                my $dat;
     1286                if ($$exifTool{NEW_VALUE}{$tagInfo}) {
     1287                    # write as a block
     1288                    $exifTool->VPrint(0, "Writing $$tagInfo{Name} as a block\n");
     1289                    $dat = $exifTool->GetNewValues($tagInfo);
     1290                    $dat = '' unless defined $dat;
     1291                    ++$$exifTool{CHANGED};
    5961292                } else {
    597                     $recLen = Get32u(\$buff, $pos);
     1293                    $dat = $exifTool->WriteDirectory(\%subdirInfo, $subTablePtr);
    5981294                }
    599                 $pos += 4;      # move to start of record
    600                 if ($pos + $recLen > $blockEnd) {
    601                     $exifTool->Warn('Possibly corrupt CanonVRD record');
    602                     last Block;
     1295                # update data with new directory
     1296                if (defined $dat) {
     1297                    my $buf2;
     1298                    if (length $dat or $$exifTool{FILE_TYPE} !~ /^(CRW|VRD)$/) {
     1299                        # replace with new block (updating the block length word)
     1300                        $buf2 = substr($$dataPt, 0, $pos - 4) . Set32u(length $dat) . $dat;
     1301                    } else {
     1302                        # remove block totally (CRW/VRD files only)
     1303                        $buf2 = substr($$dataPt, 0, $pos - 8);
     1304                    }
     1305                    my $oldBlockEnd = $pos + $blockLen;
     1306                    $pos = length $$dataPt; # set to start of next block
     1307                    $buf2 .= substr($$dataPt, $oldBlockEnd);
     1308                    undef $$dataPt;         # free the memory
     1309                    $dataPt = \$buf2;
     1310                    # update the new VRD length in the header/footer
     1311                    Set32u(length($buf2), \$header, 0x18);
     1312                    Set32u(length($buf2), \$footer, 0x14);
     1313                    next;
    6031314                }
    604                 printf $out "  CanonVRD record ($recLen bytes at offset 0x%x)\n",
    605                     $pos + $vrdPos if $verbose > 1 and not $outfile;
    606 
    607                 # our edit information is the first record
    608                 # (don't process if simply deleting VRD)
    609                 next if $recNum;
    610 
    611                 # process VRD edit information
    612                 my $tagTablePtr = GetTagTable('Image::ExifTool::CanonVRD::Main');
    613                 my $index;
    614                 my $editData = substr($buff, $pos, $recLen);
    615                 my %subdirInfo = (
    616                     DataPt => \$editData,
    617                     DataPos => $debug ? 0 : $vrdPos + $pos,
    618                 );
    619                 my $start = 0;
    620                 for ($index=0; ; ++$index) {
    621                     my $tagInfo = $$tagTablePtr{$index} or last;
    622                     my $dirLen;
    623                     my $maxLen = $recLen - $start;
    624                     if ($$tagInfo{Size}) {
    625                         $dirLen = $$tagInfo{Size};
    626                     } elsif (defined $$tagInfo{Size}) {
    627                         # get size from int32u at $start
    628                         last unless $start + 4 <= $recLen;
    629                         $dirLen = Get32u(\$editData, $start);
    630                         $start += 4; # skip the length word
    631                     } else {
    632                         $dirLen = $maxLen;
    633                     }
    634                     $dirLen > $maxLen and $dirLen = $maxLen;
    635                     if ($dirLen) {
    636                         my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
    637                         my $subName = $$tagInfo{Name};
    638                         $subdirInfo{DirStart} = $start;
    639                         $subdirInfo{DirLen} = $dirLen;
    640                         $subdirInfo{DirName} = $subName;
    641                         if ($outfile) {
    642                             # rewrite CanonVRD information
    643                             $verbose and print $out "  Rewriting Canon $subName\n";
    644                             my $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
    645                             substr($buff, $pos+$start, $dirLen) = $newVal if $newVal;
    646                         } else {
    647                             Image::ExifTool::HexDump(\$editData, $dirLen,
    648                                 Start  => $start,
    649                                 Addr   => 0,
    650                                 Prefix => $$tagInfo{Name}
    651                             ) if $debug;
    652                             # extract CanonVRD information
    653                             $exifTool->ProcessDirectory(\%subdirInfo, $subTable);
    654                         }
    655                     }
    656                     # next directory starts at the end of this one
    657                     $start += $dirLen;
    658                 }
     1315            } else {
     1316                # extract as a block if requested
     1317                $exifTool->ProcessDirectory(\%subdirInfo, $subTablePtr);
    6591318            }
    6601319        } else {
    661             $pos += $blockLen;  # skip other blocks
    662         }
     1320            $exifTool->HandleTag($tagTablePtr, $blockType, substr($$dataPt, $pos, $blockLen));
     1321        }
     1322        $pos += $blockLen;  # step to next block
    6631323    }
    664     # write CanonVRD trailer
    665     Write($outfile, $header, $buff, $footer) or $err = 1 if $outfile;
    666 
    667     undef $buff;
     1324    if ($outfile) {
     1325        # create XMP block if necessary (CRW/VRD files only)
     1326        if ($$exifTool{ADD_DIRS}{CanonVRD} and not $didDir{XMP}) {
     1327            my $subTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
     1328            my $dat = $exifTool->WriteDirectory({ Parent => 'CanonVRD' }, $subTablePtr);
     1329            if ($dat) {
     1330                $$dataPt .= Set32u(0xffff00f6) . Set32u(length $dat) . $dat;
     1331                # update the new VRD length in the header/footer
     1332                Set32u(length($$dataPt), \$header, 0x18);
     1333                Set32u(length($$dataPt), \$footer, 0x14);
     1334            }
     1335        }
     1336        # write CanonVRD trailer unless it is empty
     1337        if (length $$dataPt) {
     1338            Write($outfile, $header, $$dataPt, $footer) or $err = 1;
     1339        } else {
     1340            $verbose and printf $out "  Deleting CanonVRD trailer\n";
     1341        }
     1342    }
     1343    undef $$dataPt;
    6681344    return $err ? -1 : 1;
    6691345}
     
    6861362write VRD Recipe Data information as written by the Canon Digital Photo
    6871363Professional software.  This information is written to VRD files, and as a
    688 trailer in JPEG, CRW and CR2 images.
     1364trailer in JPEG, CRW, CR2 and TIFF images.
    6891365
    6901366=head1 AUTHOR
    6911367
    692 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1368Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    6931369
    6941370This library is free software; you can redistribute it and/or modify it
    6951371under the same terms as Perl itself.
    6961372
     1373=head1 ACKNOWLEDGEMENTS
     1374
     1375Thanks to Bogdan and Gert Kello for decoding some tags.
     1376
    6971377=head1 SEE ALSO
    6981378
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Casio.pm

    r16842 r24107  
    1111#               3) http://homepage3.nifty.com/kamisaka/makernote/makernote_casio.htm
    1212#               4) http://www.gvsoft.homedns.org/exif/makernote-casio.html
     13#               5) Robert Chi private communication (EX-F1)
     14#               JD) Jens Duttke private communication
    1315#------------------------------------------------------------------------------
    1416
     
    1921use Image::ExifTool::Exif;
    2022
    21 $VERSION = '1.21';
     23$VERSION = '1.32';
    2224
    2325# older Casio maker notes (ref 1)
     
    6163        {
    6264            Name => 'FlashMode',
    63             Condition => '$self->{CameraModel} =~ /^QV-(3500EX|8000SX)/',
     65            Condition => '$self->{Model} =~ /^QV-(3500EX|8000SX)/',
    6466            Writable => 'int16u',
    6567            PrintConv => {
     
    168170        Priority => 0,
    169171    },
     172    0x0015 => { #JD (Similar to Type2 0x2001)
     173        Name => 'FirmwareDate',
     174        Writable => 'string',
     175        Format => 'undef', # the 'string' contains nulls
     176        Count => 18,
     177        PrintConv => q{
     178            $_ = $val;
     179            if (/^(\d{2})(\d{2})\0\0(\d{2})(\d{2})\0\0(\d{2})(.{2})\0{2}$/) {
     180                my $yr = $1 + ($1 < 70 ? 2000 : 1900);
     181                my $sec = $6;
     182                $val = "$yr:$2:$3 $4:$5";
     183                $val .= ":$sec" if $sec=~/^\d{2}$/;
     184                return $val;
     185            }
     186            tr/\0/./;  s/\.+$//;
     187            return "Unknown ($_)";
     188        },
     189        PrintConvInv => q{
     190            $_ = $val;
     191            if (/^(19|20)(\d{2}):(\d{2}):(\d{2}) (\d{2}):(\d{2})$/) {
     192                return "$2$3\0\0$4$5\0\0$6\0\0\0\0";
     193            } elsif (/^Unknown\s*\((.*)\)$/i) {
     194                $_ = $1;  tr/./\0/;
     195                return $_;
     196            } else {
     197                return undef;
     198            }
     199        },
     200    },
    170201    0x0016 => { #4
    171202        Name => 'Enhancement',
     
    197228        Name => 'AFPoint',
    198229        Writable => 'int16u',
     230        Notes => 'may not be valid for all models', #JD
    199231        PrintConv => {
    200232            1 => 'Center',
     
    327359        Name => 'FocalLength',
    328360        Writable => 'rational64u',
    329         PrintConv => 'sprintf("%.1fmm",$val)',
    330         PrintConvInv => '$val=~s/mm$//;$val',
     361        PrintConv => 'sprintf("%.1f mm",$val)',
     362        PrintConvInv => '$val=~s/\s*mm$//;$val',
    331363    },
    332364    0x001f => {
     
    413445           4 => 'Flash?',
    414446           6 => 'Fluorescent', #3
     447           9 => 'Tungsten?', #PH (EX-Z77)
    415448           10 => 'Tungsten', #3
    416449           12 => 'Flash',
     450        },
     451    },
     452    0x2021 => { #JD (guess)
     453        Name => 'AFPointPosition',
     454        Writable => 'int16u',
     455        Count => 4,
     456        PrintConv => q{
     457            my @v = split ' ', $val;
     458            return 'n/a' if $v[0] == 65535 or not $v[1] or not $v[3];
     459            sprintf "%.2g %.2g", $v[0]/$v[1], $v[2]/$v[3];
    417460        },
    418461    },
     
    426469    },
    427470    # 0x2023 looks interesting (values 0,1,2,3,5 in samples) - PH
     471    #        - 1 for makeup mode shots (portrait?) (EX-Z450)
    428472    0x2034 => {
    429473        Name => 'FlashDistance',
    430474        Writable => 'int16u',
     475    },
     476    # 0x203e - normally 62000, but 62001 for anti-shake mode - PH
     477    0x2076 => { #PH (EX-Z450)
     478        # ("Enhancement" was taken already, so call this "SpecialEffect" for lack of a better name)
     479        Name => 'SpecialEffectMode',
     480        Writable => 'int8u',
     481        Count => 3,
     482        PrintConv => {
     483            '0 0 0' => 'Off',
     484            '1 0 0' => 'Makeup',
     485            '2 0 0' => 'Mist Removal',
     486            '3 0 0' => 'Vivid Landscape',
     487            # have also seen '1 1 1', '2 2 4', '4 3 3', '4 4 4'
     488            # '0 0 14' and '0 0 42' - premium auto night shot (EX-Z2300)
     489        },
     490    },
     491    0x2089 => [ #PH
     492        {
     493            Name => 'FaceInfo1',
     494            Condition => '$$valPt =~ /^(\0\0|.\x02\x80\x01\xe0)/s', # (EX-H5)
     495            SubDirectory => {
     496                TagTable => 'Image::ExifTool::Casio::FaceInfo1',
     497                ByteOrder => 'BigEndian',
     498            },
     499        },{
     500            Name => 'FaceInfo2',
     501            Condition => '$$valPt =~ /^\x02\x01/', # (EX-H20G,EX-ZR100)
     502            SubDirectory => {
     503                TagTable => 'Image::ExifTool::Casio::FaceInfo2',
     504                ByteOrder => 'LittleEndian',
     505            },
     506        },{
     507            Name => 'FaceInfoUnknown',
     508            Unknown => 1,
     509        },
     510    ],
     511    # 0x208a - also some sort of face detection information - PH
     512    0x211c => { #PH
     513        Name => 'FacesDetected',
     514        Format => 'int8u',
    431515    },
    432516    0x3000 => {
     
    439523            5 => 'Manual', #3
    440524            6 => 'Best Shot', #3
    441         },
    442     },
    443     # 0x3001 is ShutterMode according to ref 3!
    444     0x3001 => {
    445         Name => 'SelfTimer',
    446         Writable => 'int16u',
    447         PrintConv => { 1 => 'Off' },
     525            17 => 'Movie', #PH (UHQ?)
     526            19 => 'Movie (19)', #PH (HQ?, EX-P505)
     527            20 => 'YouTube Movie', #PH
     528            '2 0' => 'Program AE', #PH (NC)
     529            '3 0' => 'Shutter Priority', #PH (NC)
     530            '4 0' => 'Aperture Priority', #PH (NC)
     531            '5 0' => 'Manual', #PH (NC)
     532            '6 0' => 'Best Shot', #PH (NC)
     533        },
     534    },
     535    0x3001 => { #3
     536        Name => 'ReleaseMode',
     537        Writable => 'int16u',
     538        PrintConv => {
     539            1 => 'Normal',
     540            3 => 'AE Bracketing',
     541            11 => 'WB Bracketing',
     542            13 => 'Contrast Bracketing', #(not sure about translation - PH)
     543            19 => 'High Speed Burst', #PH (EX-FH25, 40fps)
     544            # have also seen: 2, 7(common), 14, 18 - PH
     545        },
    448546    },
    449547    0x3002 => {
     
    460558        Writable => 'int16u',
    461559        PrintConv => {
    462            0 => 'Manual?',
    463            1 => 'Fixation?',
     560           0 => 'Manual', #(guess at translation)
     561           1 => 'Focus Lock', #(guess at translation)
    464562           2 => 'Macro', #3
    465563           3 => 'Single-Area Auto Focus',
     564           5 => 'Infinity', #PH
    466565           6 => 'Multi-Area Auto Focus',
     566           8 => 'Super Macro', #PH (EX-Z2300)
    467567        },
    468568    },
     
    474574        Name => 'BestShotMode',
    475575        Writable => 'int16u',
    476         PrintConv => {
    477            0 => 'Off',
    478            1 => 'On?',
    479         },
     576        # unfortunately these numbers are model-dependent,
     577        # so we can't use a lookup as usual - PH
     578        PrintConv => '$val ? $val : "Off"',
     579        PrintConvInv => '$val=~/(\d+)/ ? $1 : 0',
    480580    },
    481581    0x3008 => { #3
    482582        Name => 'AutoISO',
    483583        Writable => 'int16u',
    484         PrintConv => { 1 => 'On', 2 => 'Off' },
     584        PrintConv => {
     585            1 => 'On',
     586            2 => 'Off',
     587            7 => 'On (high sensitivity)', #PH
     588            8 => 'On (anti-shake)', #PH
     589            10 => 'High Speed', #PH (EX-FC150)
     590        },
     591    },
     592    0x3009 => { #PH (EX-Z77)
     593        Name => 'AFMode',
     594        Writable => 'int16u',
     595        PrintConv => {
     596            0 => 'Off',
     597            1 => 'On',
     598            # have seen 2(EX-Z35 macro/portrait), 3(portrait) and 5(auto mode)
     599            4 => 'Face Recognition', # "Family First"
     600        },
    485601    },
    486602    0x3011 => { #3
     
    507623        Name => 'ColorMode',
    508624        Writable => 'int16u',
    509         PrintConv => { 0 => 'Off' },
     625        PrintConv => { 
     626            0 => 'Off',
     627            2 => 'Black & White', #PH (EX-Z400,FH20)
     628            3 => 'Sepia', #PH (EX-Z400)
     629        },
    510630    },
    511631    0x3016 => {
    512632        Name => 'Enhancement',
    513633        Writable => 'int16u',
    514         PrintConv => { 0 => 'Off' },
     634        PrintConv => {
     635            0 => 'Off',
     636            1 => 'Scenery', #PH (NC) (EX-Z77)
     637            3 => 'Green', #PH (EX-Z77)
     638            5 => 'Underwater', #PH (NC) (EX-Z77)
     639            9 => 'Flesh Tones', #PH (EX-Z77)
     640        },
    515641    },
    516642    0x3017 => {
    517         Name => 'Filter',
    518         Writable => 'int16u',
    519         PrintConv => { 0 => 'Off' },
     643        Name => 'ColorFilter',
     644        Writable => 'int16u',
     645        PrintConv => {
     646            0 => 'Off',
     647            1 => 'Blue', #PH (FH20,Z400)
     648            3 => 'Green', #PH (FH20)
     649            4 => 'Yellow', #PH (FH20)
     650            5 => 'Red', #PH (FH20,Z77)
     651            6 => 'Purple', #PH (FH20,Z77,Z400)
     652            7 => 'Pink', #PH (FH20)
     653        },
     654    },
     655    0x301b => { #PH
     656        Name => 'UnknownMode',
     657        Writable => 'int16u',
     658        Unknown => 1,
     659        PrintConv => {
     660            0 => 'Normal',
     661            8 => 'Silent Movie',
     662            39 => 'HDR', # (EX-ZR10)
     663            45 => 'Premium Auto', # (EX-2300)
     664            47 => 'Painting', # (EX-2300)
     665            49 => 'Crayon Drawing', # (EX-2300)
     666            51 => 'Panorama', # (EX-ZR10)
     667            52 => 'Art HDR', # (EX-ZR10)
     668        },
    520669    },
    521670    0x301c => { #3
     
    536685            1 => 'On',
    537686            2 => 'Best Shot',
     687            # 3 observed in MOV videos (EX-V7)
     688            # (newer models write 2 numbers here - PH)
     689            '0 0' => 'Off', #PH
     690            # have seen '0 1' for EX-Z2000 which has 5 modes: Auto, Camera AS, Image AS, DEMO, Off
     691            '16 0' => 'Slow Shutter', #PH (EX-Z77)
     692            '18 0' => 'Anti-Shake', #PH (EX-Z77)
     693            '20 0' => 'High Sensitivity', #PH (EX-Z77)
     694            '0 3' => 'CCD Shift', #PH (guess)
     695            '2 3' => 'High Speed Anti-Shake', #PH (EX-FC150)
     696        },
     697    },
     698    0x302a => { #PH (EX-Z450)
     699        Name => 'LightingMode', #(just guessing here)
     700        Writable => 'int16u',
     701        PrintConv => {
     702            0 => 'Off',
     703            1 => 'High Dynamic Range', # (EX-Z77 anti-blur shot)
     704            5 => 'Shadow Enhance Low', #(NC)
     705            6 => 'Shadow Enhance High', #(NC)
     706        },
     707    },
     708    0x302b => { #PH (EX-Z77)
     709        Name => 'PortraitRefiner',
     710        Writable => 'int16u',
     711        PrintConv => {
     712            0 => 'Off',
     713            1 => '+1',
     714            2 => '+2',
     715        },
     716    },
     717    0x3030 => { #PH (EX-Z450)
     718        Name => 'SpecialEffectLevel',
     719        Writable => 'int16u',
     720    },
     721    0x3031 => { #PH (EX-Z450)
     722        Name => 'SpecialEffectSetting',
     723        Writable => 'int16u',
     724        PrintConv => {
     725            0 => 'Off',
     726            1 => 'Makeup',
     727            2 => 'Mist Removal',
     728            3 => 'Vivid Landscape',
     729            16 => 'Art Shot', # (EX-Z2300)
     730        },
     731    },
     732    0x3103 => { #5
     733        Name => 'DriveMode',
     734        Writable => 'int16u',
     735        PrintConvColumns => 2,
     736        PrintConv => {
     737            OTHER => sub {
     738                # handle new values of future models
     739                my ($val, $inv) = @_;
     740                return $val =~ /(\d+)/ ? $1 : undef if $inv;
     741                return "Continuous ($val fps)";
     742            },
     743            0 => 'Single Shot', #PH (NC)
     744            1 => 'Continuous Shooting', # (1 fps for the EX-F1)
     745            2 => 'Continuous (2 fps)',
     746            3 => 'Continuous (3 fps)',
     747            4 => 'Continuous (4 fps)',
     748            5 => 'Continuous (5 fps)',
     749            6 => 'Continuous (6 fps)',
     750            7 => 'Continuous (7 fps)',
     751            10 => 'Continuous (10 fps)',
     752            12 => 'Continuous (12 fps)',
     753            15 => 'Continuous (15 fps)',
     754            20 => 'Continuous (20 fps)',
     755            30 => 'Continuous (30 fps)',
     756            40 => 'Continuous (40 fps)', #PH (EX-FH25)
     757            60 => 'Continuous (60 fps)',
     758            240 => 'Auto-N',
     759        },
     760    },
     761    0x4001 => { #PH (AVI videos)
     762        Name => 'CaptureFrameRate',
     763        Writable => 'int16u',
     764        Count => -1,
     765        ValueConv => q{
     766            my @v=split(" ",$val);
     767            return $val / 1000 if @v == 1;
     768            return $v[1] ? "$v[1]-$v[0]" : ($v[0] > 10000 ? $v[0] / 1000 : $v[0]);
     769        },
     770        ValueConvInv => '$val <= 60 ? $val * 1000 : int($val) . " 0"',
     771    },
     772    # 0x4002 - AVI videos, related to video quality or size - PH
     773    0x4003 => { #PH (AVI and MOV videos)
     774        Name => 'VideoQuality',
     775        Writable => 'int16u',
     776        PrintConv => {
     777            1 => 'Standard',
     778            # 2 - could this be LP?
     779            3 => 'HD (720p)',
     780            4 => 'Full HD (1080p)', # (EX-ZR10, 30fps 1920x1080)
     781            5 => 'Low', # used in High Speed modes
    538782        },
    539783    },
    540784);
     785
     786# face detection information (ref PH) (EX-H5)
     787%Image::ExifTool::Casio::FaceInfo1 = (
     788    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     789    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     790    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     791    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     792    WRITABLE => 1,
     793    FIRST_ENTRY => 0,
     794    DATAMEMBER => [ 0 ],
     795    NOTES => 'Face-detect tags extracted from models such as the EX-H5.',
     796    0x00 => { # (NC)
     797        Name => 'FacesDetected',
     798        DataMember => 'FacesDetected',
     799        RawConv => '$$self{FacesDetected} = $val',
     800    },
     801    0x01 => {
     802        Name => 'FaceDetectFrameSize',
     803        Condition => '$$self{FacesDetected} >= 1', # (otherwise zeros)
     804        Format => 'int16u[2]',
     805    },
     806    0x0d => {
     807        Name => 'Face1Position',
     808        Condition => '$$self{FacesDetected} >= 1',
     809        Format => 'int16u[4]',
     810        Notes => q{
     811            left, top, right and bottom of detected face in coordinates of
     812            FaceDetectFrameSize, with increasing Y downwards
     813        },
     814    },
     815    # decoding NOT CONFIRMED (NC) for faces 2-10!
     816    0x7c => {
     817        Name => 'Face2Position',
     818        Condition => '$$self{FacesDetected} >= 2',
     819        Format => 'int16u[4]',
     820    },
     821    0xeb => {
     822        Name => 'Face3Position',
     823        Condition => '$$self{FacesDetected} >= 3',
     824        Format => 'int16u[4]',
     825    },
     826    0x15a => {
     827        Name => 'Face4Position',
     828        Condition => '$$self{FacesDetected} >= 4',
     829        Format => 'int16u[4]',
     830    },
     831    0x1c9 => {
     832        Name => 'Face5Position',
     833        Condition => '$$self{FacesDetected} >= 5',
     834        Format => 'int16u[4]',
     835    },
     836    0x238 => {
     837        Name => 'Face6Position',
     838        Condition => '$$self{FacesDetected} >= 6',
     839        Format => 'int16u[4]',
     840    },
     841    0x2a7 => {
     842        Name => 'Face7Position',
     843        Condition => '$$self{FacesDetected} >= 7',
     844        Format => 'int16u[4]',
     845    },
     846    0x316 => {
     847        Name => 'Face8Position',
     848        Condition => '$$self{FacesDetected} >= 8',
     849        Format => 'int16u[4]',
     850    },
     851    0x385 => {
     852        Name => 'Face9Position',
     853        Condition => '$$self{FacesDetected} >= 9',
     854        Format => 'int16u[4]',
     855    },
     856    0x3f4 => {
     857        Name => 'Face10Position',
     858        Condition => '$$self{FacesDetected} >= 10',
     859        Format => 'int16u[4]',
     860    },
     861);
     862
     863# face detection information (ref PH) (EX-ZR100)
     864%Image::ExifTool::Casio::FaceInfo2 = (
     865    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     866    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     867    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     868    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     869    WRITABLE => 1,
     870    FIRST_ENTRY => 0,
     871    DATAMEMBER => [ 2 ],
     872    NOTES => 'Face-detect tags extracted from models such as the EX-H20G and EX-ZR100.',
     873    0x02 => {
     874        Name => 'FacesDetected',
     875        DataMember => 'FacesDetected',
     876        RawConv => '$$self{FacesDetected} = $val',
     877    },
     878    0x04 => {
     879        Name => 'FaceDetectFrameSize',
     880        Condition => '$$self{FacesDetected} >= 1',
     881        Format => 'int16u[2]',
     882    },
     883    0x08 => {
     884        Name => 'FaceOrientation',
     885        Condition => '$$self{FacesDetected} >= 1',
     886        PrintConv => {
     887            0 => 'Horizontal (normal)',
     888            1 => 'Rotate 90 CW',
     889            2 => 'Rotate 270 CW',
     890            3 => 'Rotate 180', # (NC)
     891        },
     892        Notes => 'orientation of face relative to unrotated image',
     893    },
     894    # 0x0a - FaceDetectFrameSize again
     895    # 0x11 - Face1Detected flag (1=detected)
     896    0x18 => {
     897        Name => 'Face1Position',
     898        Condition => '$$self{FacesDetected} >= 1',
     899        Format => 'int16u[4]',
     900        Notes => q{
     901            left, top, right and bottom of detected face in coordinates of
     902            FaceDetectFrameSize, with increasing Y downwards
     903        },
     904    },
     905    # 0x45 - Face2Detected, etc...
     906    0x4c => {
     907        Name => 'Face2Position',
     908        Condition => '$$self{FacesDetected} >= 2',
     909        Format => 'int16u[4]',
     910    },
     911    0x80 => {
     912        Name => 'Face3Position',
     913        Condition => '$$self{FacesDetected} >= 3',
     914        Format => 'int16u[4]',
     915    },
     916    0xb4 => {
     917        Name => 'Face4Position',
     918        Condition => '$$self{FacesDetected} >= 4',
     919        Format => 'int16u[4]',
     920    },
     921    0xe8 => {
     922        Name => 'Face5Position',
     923        Condition => '$$self{FacesDetected} >= 5',
     924        Format => 'int16u[4]',
     925    },
     926    0x11c => {
     927        Name => 'Face6Position',
     928        Condition => '$$self{FacesDetected} >= 6',
     929        Format => 'int16u[4]',
     930    },
     931    0x150 => {
     932        Name => 'Face7Position',
     933        Condition => '$$self{FacesDetected} >= 7',
     934        Format => 'int16u[4]',
     935    },
     936    0x184 => {
     937        Name => 'Face8Position',
     938        Condition => '$$self{FacesDetected} >= 8',
     939        Format => 'int16u[4]',
     940    },
     941    0x1b8 => {
     942        Name => 'Face9Position',
     943        Condition => '$$self{FacesDetected} >= 9',
     944        Format => 'int16u[4]',
     945    },
     946    0x1ec => {
     947        Name => 'Face10Position',
     948        Condition => '$$self{FacesDetected} >= 10',
     949        Format => 'int16u[4]',
     950    },
     951);
     952
     953# Casio APP1 QVCI segment found in QV-7000SX images (ref PH)
     954%Image::ExifTool::Casio::QVCI = (
     955    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     956    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     957    FIRST_ENTRY => 0,
     958    NOTES => q{
     959        This information is found in the APP1 QVCI segment of JPEG images from the
     960        Casio QV-7000SX.
     961    },
     962    0x2c => {
     963        Name => 'CasioQuality',
     964        PrintConv => {
     965            1 => 'Economy',
     966            2 => 'Normal',
     967            3 => 'Fine',
     968            4 => 'Super Fine',
     969        },
     970    },
     971    0x37 => {
     972        Name => 'FocalRange',
     973        Unknown => 1,
     974    },
     975    0x4d => {
     976        Name => 'DateTimeOriginal',
     977        Description => 'Date/Time Original',
     978        Format => 'string[20]',
     979        Groups => { 2 => 'Time' },
     980        ValueConv => '$val=~tr/./:/; $val=~s/(\d+:\d+:\d+):/$1 /; $val',
     981        PrintConv => '$self->ConvertDateTime($val)',
     982    },
     983    0x62 => {
     984        Name => 'ModelType',
     985        Format => 'string[7]',
     986    },
     987    0x72 => { # could be serial number or manufacture date in form YYMMDDxx ?
     988        Name => 'ManufactureIndex',
     989        Format => 'string[9]',
     990    },
     991    0x7c => {
     992        Name => 'ManufactureCode',
     993        Format => 'string[9]',
     994    },
     995);
     996
     997# tags in Casio AVI videos (ref PH)
     998%Image::ExifTool::Casio::AVI = (
     999    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1000    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     1001    FIRST_ENTRY => 0,
     1002    NOTES => 'This information is found in Casio GV-10 AVI videos.',
     1003    0 => {
     1004        Name => 'Software', # (equivalent to RIFF Software tag)
     1005        Format => 'string',
     1006    },
     1007);
     1008
    5411009
    54210101;  # end
     
    5591027=head1 AUTHOR
    5601028
    561 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1029Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    5621030
    5631031This library is free software; you can redistribute it and/or modify it
     
    5741042=head1 ACKNOWLEDGEMENTS
    5751043
    576 Thanks to Joachim Loehr for adding support for the type 2 maker notes.
     1044Thanks to Joachim Loehr for adding support for the type 2 maker notes, and
     1045Jens Duttke and Robert Chi for decoding some tags.
    5771046
    5781047=head1 SEE ALSO
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DICOM.pm

    r16842 r24107  
    44# Description:  Read DICOM and ACR-NEMA medical images
    55#
    6 # Revisions:    11/09/2005 - P. Harvey Created
     6# Revisions:    2005/11/09 - P. Harvey Created
     7#               2009/11/19 - P. Harvey Added private GE tags from ref 4
     8#               2009/12/11 - P. Harvey Updated to DICOM 2008 spec
     9#               2010/04/08 - P. Harvey Updated to DICOM 2009 spec
    710#
    8 # References:   1) http://medical.nema.org/dicom/2004.html
     11# References:   1) http://medical.nema.org/
    912#               2) http://www.sph.sc.edu/comd/rorden/dicom.html
    1013#               3) http://www.dclunie.com/
     14#               4) http://www.gehealthcare.com/usen/interoperability/dicom/docs/2258357r3.pdf
    1115#------------------------------------------------------------------------------
    1216
     
    1418
    1519use strict;
    16 use vars qw($VERSION);
     20use vars qw($VERSION %uid);
    1721use Image::ExifTool qw(:DataAccess :Utils);
    1822
    19 $VERSION = '1.06';
     23$VERSION = '1.11';
    2024
    2125# DICOM VR (Value Representation) format conversions
     
    5155        header and a number of new tags.  ExifTool will extract information from
    5256        either type of file.  The Tag ID's in the following table are the tag group
    53         and element numbers in hexadecimal, as given in the DICOM specification.
     57        and element numbers in hexadecimal, as given in the DICOM specification (see
     58        L<http://medical.nema.org/>).  The table below contains tags from the DICOM
     59        2009 and earlier specifications plus some vendor-specific private tags.
    5460    },
    5561    # file meta information group (names end with VR)
     
    8692    # identifying group
    8793    '0008,0000' => { VR => 'UL', Name => 'IdentifyingGroupLength' },
    88     '0008,0001' => { VR => 'RET',Name => 'LengthToEnd' },
     94    '0008,0001' => { VR => 'UL', Name => 'LengthToEnd' },
    8995    '0008,0005' => { VR => 'CS', Name => 'SpecificCharacterSet' },
     96    '0008,0006' => { VR => 'SQ', Name => 'LanguageCodeSequence' },
    9097    '0008,0008' => { VR => 'CS', Name => 'ImageType' },
    91     '0008,0010' => { VR => 'RET',Name => 'RecognitionCode' },
     98    '0008,0010' => { VR => 'CS', Name => 'RecognitionCode' },
    9299    '0008,0012' => { VR => 'DA', Name => 'InstanceCreationDate' },
    93100    '0008,0013' => { VR => 'TM', Name => 'InstanceCreationTime' },
     
    103110    '0008,0024' => { VR => 'DA', Name => 'OverlayDate' },
    104111    '0008,0025' => { VR => 'DA', Name => 'CurveDate' },
    105     '0008,002A' => { VR => 'DT', Name => 'AcquisitionDatetime' },
     112    '0008,002A' => { VR => 'DT', Name => 'AcquisitionDateTime' },
    106113    '0008,0030' => { VR => 'TM', Name => 'StudyTime' },
    107114    '0008,0031' => { VR => 'TM', Name => 'SeriesTime' },
     
    110117    '0008,0034' => { VR => 'TM', Name => 'OverlayTime' },
    111118    '0008,0035' => { VR => 'TM', Name => 'CurveTime' },
    112     '0008,0040' => { VR => 'RET',Name => 'DataSetType' },
    113     '0008,0041' => { VR => 'RET',Name => 'DataSetSubtype' },
    114     '0008,0042' => { VR => 'RET',Name => 'NuclearMedicineSeriesType' },
     119    '0008,0040' => { VR => 'US', Name => 'DataSetType' },
     120    '0008,0041' => { VR => 'LO', Name => 'DataSetSubtype' },
     121    '0008,0042' => { VR => 'CS', Name => 'NuclearMedicineSeriesType' },
    115122    '0008,0050' => { VR => 'SH', Name => 'AccessionNumber' },
    116     '0008,0052' => { VR => 'CS', Name => 'Query-RetrieveLevel' },
     123    '0008,0052' => { VR => 'CS', Name => 'QueryRetrieveLevel' },
    117124    '0008,0054' => { VR => 'AE', Name => 'RetrieveAETitle' },
    118125    '0008,0056' => { VR => 'CS', Name => 'InstanceAvailability' },
     
    127134    '0008,0081' => { VR => 'ST', Name => 'InstitutionAddress' },
    128135    '0008,0082' => { VR => 'SQ', Name => 'InstitutionCodeSequence' },
    129     '0008,0090' => { VR => 'PN', Name => 'ReferringPhysiciansName' },
    130     '0008,0092' => { VR => 'ST', Name => 'ReferringPhysiciansAddress' },
    131     '0008,0094' => { VR => 'SH', Name => 'ReferringPhysiciansTelephoneNumber' },
     136    '0008,0090' => { VR => 'PN', Name => 'ReferringPhysicianName' },
     137    '0008,0092' => { VR => 'ST', Name => 'ReferringPhysicianAddress' },
     138    '0008,0094' => { VR => 'SH', Name => 'ReferringPhysicianTelephoneNumber' },
    132139    '0008,0096' => { VR => 'SQ', Name => 'ReferringPhysicianIDSequence' },
    133140    '0008,0100' => { VR => 'SH', Name => 'CodeValue' },
     
    147154    '0008,0115' => { VR => 'ST', Name => 'CodingSchemeName' },
    148155    '0008,0116' => { VR => 'ST', Name => 'ResponsibleOrganization' },
     156    '0008,0117' => { VR => 'UI', Name => 'ContextUID' },
    149157    '0008,0201' => { VR => 'SH', Name => 'TimezoneOffsetFromUTC' },
    150     '0008,1000' => { VR => 'RET',Name => 'NetworkID' },
     158    '0008,1000' => { VR => 'AE', Name => 'NetworkID' },
    151159    '0008,1010' => { VR => 'SH', Name => 'StationName' },
    152160    '0008,1030' => { VR => 'LO', Name => 'StudyDescription' },
     
    154162    '0008,103E' => { VR => 'LO', Name => 'SeriesDescription' },
    155163    '0008,1040' => { VR => 'LO', Name => 'InstitutionalDepartmentName' },
    156     '0008,1048' => { VR => 'PN', Name => 'PhysicianOfRecord' },
    157     '0008,1049' => { VR => 'SQ', Name => 'PhysicianOfRecordIDSequence' },
    158     '0008,1050' => { VR => 'PN', Name => 'PerformingPhysiciansName' },
     164    '0008,1048' => { VR => 'PN', Name => 'PhysiciansOfRecord' },
     165    '0008,1049' => { VR => 'SQ', Name => 'PhysiciansOfRecordIDSequence' },
     166    '0008,1050' => { VR => 'PN', Name => 'PerformingPhysicianName' },
    159167    '0008,1052' => { VR => 'SQ', Name => 'PerformingPhysicianIDSequence' },
    160168    '0008,1060' => { VR => 'PN', Name => 'NameOfPhysicianReadingStudy' },
     
    180188    '0008,115A' => { VR => 'UI', Name => 'SOPClassesSupported' },
    181189    '0008,1160' => { VR => 'IS', Name => 'ReferencedFrameNumber' },
     190    '0008,1161' => { VR => 'UL', Name => 'SimpleFrameList' },
     191    '0008,1162' => { VR => 'UL', Name => 'CalculatedFrameList' },
     192    '0008,1163' => { VR => 'FD', Name => 'TimeRange' },
     193    '0008,1164' => { VR => 'SQ', Name => 'FrameExtractionSequence' },
    182194    '0008,1195' => { VR => 'UI', Name => 'TransactionUID' },
    183195    '0008,1197' => { VR => 'US', Name => 'FailureReason' },
     
    186198    '0008,1200' => { VR => 'SQ', Name => 'OtherReferencedStudiesSequence' },
    187199    '0008,1250' => { VR => 'SQ', Name => 'RelatedSeriesSequence' },
    188     '0008,2110' => { VR => 'RET',Name => 'LossyImageCompression' },
     200    '0008,2110' => { VR => 'CS', Name => 'LossyImageCompression' },
    189201    '0008,2111' => { VR => 'ST', Name => 'DerivationDescription' },
    190202    '0008,2112' => { VR => 'SQ', Name => 'SourceImageSequence' },
     
    196208    '0008,2129' => { VR => 'IS', Name => 'NumberOfEventTimers' },
    197209    '0008,212A' => { VR => 'IS', Name => 'NumberOfViewsInStage' },
    198     '0008,2130' => { VR => 'DS', Name => 'EventElapsedTime' },
    199     '0008,2132' => { VR => 'LO', Name => 'EventTimerName' },
     210    '0008,2130' => { VR => 'DS', Name => 'EventElapsedTimes' },
     211    '0008,2132' => { VR => 'LO', Name => 'EventTimerNames' },
     212    '0008,2133' => { VR => 'SQ', Name => 'EventTimerSequence' },
     213    '0008,2134' => { VR => 'FD', Name => 'EventTimeOffset' },
     214    '0008,2135' => { VR => 'SQ', Name => 'EventCodeSequence' },
    200215    '0008,2142' => { VR => 'IS', Name => 'StartTrim' },
    201216    '0008,2143' => { VR => 'IS', Name => 'StopTrim' },
    202217    '0008,2144' => { VR => 'IS', Name => 'RecommendedDisplayFrameRate' },
    203     '0008,2200' => { VR => 'RET',Name => 'TransducerPosition' },
    204     '0008,2204' => { VR => 'RET',Name => 'TransducerOrientation' },
    205     '0008,2208' => { VR => 'RET',Name => 'AnatomicStructure' },
     218    '0008,2200' => { VR => 'CS', Name => 'TransducerPosition' },
     219    '0008,2204' => { VR => 'CS', Name => 'TransducerOrientation' },
     220    '0008,2208' => { VR => 'CS', Name => 'AnatomicStructure' },
    206221    '0008,2218' => { VR => 'SQ', Name => 'AnatomicRegionSequence' },
    207222    '0008,2220' => { VR => 'SQ', Name => 'AnatomicRegionModifierSequence' },
     
    213228    '0008,2244' => { VR => 'SQ', Name => 'TransducerOrientationSequence' },
    214229    '0008,2246' => { VR => 'SQ', Name => 'TransducerOrientationModifierSeq' },
     230    '0008,2253' => { VR => 'SQ', Name => 'AnatomicEntrancePortalCodeSeqTrial' },
     231    '0008,2255' => { VR => 'SQ', Name => 'AnatomicApproachDirCodeSeqTrial' },
     232    '0008,2256' => { VR => 'ST', Name => 'AnatomicPerspectiveDescrTrial' },
     233    '0008,2257' => { VR => 'SQ', Name => 'AnatomicPerspectiveCodeSeqTrial' },
    215234    '0008,3001' => { VR => 'SQ', Name => 'AlternateRepresentationSequence' },
    216     '0008,4000' => { VR => 'RET',Name => 'IdentifyingComments' },
     235    '0008,3010' => { VR => 'UI', Name => 'IrradiationEventUID' },
     236    '0008,4000' => { VR => 'LT', Name => 'IdentifyingComments' },
    217237    '0008,9007' => { VR => 'CS', Name => 'FrameType' },
    218238    '0008,9092' => { VR => 'SQ', Name => 'ReferencedImageEvidenceSequence' },
     
    228248    '0008,9215' => { VR => 'SQ', Name => 'DerivationCodeSequence' },
    229249    '0008,9237' => { VR => 'SQ', Name => 'GrayscalePresentationStateSequence' },
     250    '0008,9410' => { VR => 'SQ', Name => 'ReferencedOtherPlaneSequence' },
     251    '0008,9458' => { VR => 'SQ', Name => 'FrameDisplaySequence' },
     252    '0008,9459' => { VR => 'FL', Name => 'RecommendedDisplayFrameRateInFloat' },
     253    '0008,9460' => { VR => 'CS', Name => 'SkipFrameRangeFlag' },
     254    # GEMS_IDEN_01 (ref 4)
     255    '0009,1001' => { VR => 'LO', Name => 'FullFidelity' },
     256    '0009,1002' => { VR => 'SH', Name => 'SuiteID' },
     257    '0009,1004' => { VR => 'SH', Name => 'ProductID' },
     258    '0009,1027' => { VR => 'SL', Name => 'ImageActualDate' },
     259    '0009,1030' => { VR => 'SH', Name => 'ServiceID' },
     260    '0009,1031' => { VR => 'SH', Name => 'MobileLocationNumber' },
     261    '0009,10E3' => { VR => 'UI', Name => 'EquipmentUID' },
     262    '0009,10E6' => { VR => 'SH', Name => 'GenesisVersionNow' },
     263    '0009,10E7' => { VR => 'UL', Name => 'ExamRecordChecksum' },
     264    '0009,10E9' => { VR => 'SL', Name => 'ActualSeriesDataTimeStamp' },
    230265    # patient group
    231266    '0010,0000' => { VR => 'UL', Name => 'PatientGroupLength' },
    232     '0010,0010' => { VR => 'PN', Name => 'PatientsName' },
     267    '0010,0010' => { VR => 'PN', Name => 'PatientName' },
    233268    '0010,0020' => { VR => 'LO', Name => 'PatientID' },
    234269    '0010,0021' => { VR => 'LO', Name => 'IssuerOfPatientID' },
    235     '0010,0030' => { VR => 'DA', Name => 'PatientsBirthDate' },
    236     '0010,0032' => { VR => 'TM', Name => 'PatientsBirthTime' },
    237     '0010,0040' => { VR => 'CS', Name => 'PatientsSex' },
    238     '0010,0050' => { VR => 'SQ', Name => 'PatientsInsurancePlanCodeSequence' },
    239     '0010,0101' => { VR => 'SQ', Name => 'PatientsPrimaryLanguageCodeSeq' },
    240     '0010,0102' => { VR => 'SQ', Name => 'PatientsPrimaryLanguageCodeModSeq' },
     270    '0010,0022' => { VR => 'CS', Name => 'TypeOfPatientID' },
     271    '0010,0030' => { VR => 'DA', Name => 'PatientBirthDate' },
     272    '0010,0032' => { VR => 'TM', Name => 'PatientBirthTime' },
     273    '0010,0040' => { VR => 'CS', Name => 'PatientSex' },
     274    '0010,0050' => { VR => 'SQ', Name => 'PatientInsurancePlanCodeSequence' },
     275    '0010,0101' => { VR => 'SQ', Name => 'PatientPrimaryLanguageCodeSeq' },
     276    '0010,0102' => { VR => 'SQ', Name => 'PatientPrimaryLanguageCodeModSeq' },
    241277    '0010,1000' => { VR => 'LO', Name => 'OtherPatientIDs' },
    242278    '0010,1001' => { VR => 'PN', Name => 'OtherPatientNames' },
    243     '0010,1005' => { VR => 'PN', Name => 'PatientsBirthName' },
    244     '0010,1010' => { VR => 'AS', Name => 'PatientsAge' },
    245     '0010,1020' => { VR => 'DS', Name => 'PatientsSize' },
    246     '0010,1030' => { VR => 'DS', Name => 'PatientsWeight' },
    247     '0010,1040' => { VR => 'LO', Name => 'PatientsAddress' },
    248     '0010,1050' => { VR => 'RET',Name => 'InsurancePlanIdentification' },
    249     '0010,1060' => { VR => 'PN', Name => 'PatientsMothersBirthName' },
     279    '0010,1002' => { VR => 'SQ', Name => 'OtherPatientIDsSequence' },
     280    '0010,1005' => { VR => 'PN', Name => 'PatientBirthName' },
     281    '0010,1010' => { VR => 'AS', Name => 'PatientAge' },
     282    '0010,1020' => { VR => 'DS', Name => 'PatientSize' },
     283    '0010,1030' => { VR => 'DS', Name => 'PatientWeight' },
     284    '0010,1040' => { VR => 'LO', Name => 'PatientAddress' },
     285    '0010,1050' => { VR => 'LO', Name => 'InsurancePlanIdentification' },
     286    '0010,1060' => { VR => 'PN', Name => 'PatientMotherBirthName' },
    250287    '0010,1080' => { VR => 'LO', Name => 'MilitaryRank' },
    251288    '0010,1081' => { VR => 'LO', Name => 'BranchOfService' },
    252289    '0010,1090' => { VR => 'LO', Name => 'MedicalRecordLocator' },
    253290    '0010,2000' => { VR => 'LO', Name => 'MedicalAlerts' },
    254     '0010,2110' => { VR => 'LO', Name => 'ContrastAllergies' },
     291    '0010,2110' => { VR => 'LO', Name => 'Allergies' },
    255292    '0010,2150' => { VR => 'LO', Name => 'CountryOfResidence' },
    256293    '0010,2152' => { VR => 'LO', Name => 'RegionOfResidence' },
    257     '0010,2154' => { VR => 'SH', Name => 'PatientsTelephoneNumbers' },
     294    '0010,2154' => { VR => 'SH', Name => 'PatientTelephoneNumbers' },
    258295    '0010,2160' => { VR => 'SH', Name => 'EthnicGroup' },
    259296    '0010,2180' => { VR => 'SH', Name => 'Occupation' },
     
    262299    '0010,21C0' => { VR => 'US', Name => 'PregnancyStatus' },
    263300    '0010,21D0' => { VR => 'DA', Name => 'LastMenstrualDate' },
    264     '0010,21F0' => { VR => 'LO', Name => 'PatientsReligiousPreference' },
     301    '0010,21F0' => { VR => 'LO', Name => 'PatientReligiousPreference' },
     302    '0010,2201' => { VR => 'LO', Name => 'PatientSpeciesDescription' },
     303    '0010,2202' => { VR => 'SQ', Name => 'PatientSpeciesCodeSequence' },
     304    '0010,2203' => { VR => 'CS', Name => 'PatientSexNeutered' },
     305    '0010,2210' => { VR => 'CS', Name => 'AnatomicalOrientationType' },
     306    '0010,2292' => { VR => 'LO', Name => 'PatientBreedDescription' },
     307    '0010,2293' => { VR => 'SQ', Name => 'PatientBreedCodeSequence' },
     308    '0010,2294' => { VR => 'SQ', Name => 'BreedRegistrationSequence' },
     309    '0010,2295' => { VR => 'LO', Name => 'BreedRegistrationNumber' },
     310    '0010,2296' => { VR => 'SQ', Name => 'BreedRegistryCodeSequence' },
     311    '0010,2297' => { VR => 'PN', Name => 'ResponsiblePerson' },
     312    '0010,2298' => { VR => 'CS', Name => 'ResponsiblePersonRole' },
     313    '0010,2299' => { VR => 'LO', Name => 'ResponsibleOrganization' },
    265314    '0010,4000' => { VR => 'LT', Name => 'PatientComments' },
     315    '0010,9431' => { VR => 'FL', Name => 'ExaminedBodyThickness' },
     316    # GEMS_PATI_01 (ref 4)
     317    '0011,1010' => { VR => 'SS', Name => 'PatientStatus' },
     318    # clinical trial group
    266319    '0012,0010' => { VR => 'LO', Name => 'ClinicalTrialSponsorName' },
    267320    '0012,0020' => { VR => 'LO', Name => 'ClinicalTrialProtocolID' },
     
    274327    '0012,0051' => { VR => 'ST', Name => 'ClinicalTrialTimePointDescription' },
    275328    '0012,0060' => { VR => 'LO', Name => 'ClinicalTrialCoordinatingCenter' },
     329    '0012,0062' => { VR => 'CS', Name => 'PatientIdentityRemoved' },
     330    '0012,0063' => { VR => 'LO', Name => 'DeidentificationMethod' },
     331    '0012,0064' => { VR => 'SQ', Name => 'DeidentificationMethodCodeSequence' },
     332    '0012,0071' => { VR => 'LO', Name => 'ClinicalTrialSeriesID' },
     333    '0012,0072' => { VR => 'LO', Name => 'ClinicalTrialSeriesDescription' },
     334    '0012,0084' => { VR => 'CS', Name => 'DistributionType' },
     335    '0012,0085' => { VR => 'CS', Name => 'ConsentForDistributionFlag' },
    276336    # acquisition group
    277337    '0018,0000' => { VR => 'UL', Name => 'AcquisitionGroupLength' },
    278     '0018,0010' => { VR => 'LO', Name => 'Contrast-BolusAgent' },
    279     '0018,0012' => { VR => 'SQ', Name => 'Contrast-BolusAgentSequence' },
    280     '0018,0014' => { VR => 'SQ', Name => 'Contrast-BolusAdministrationRoute' },
     338    '0018,0010' => { VR => 'LO', Name => 'ContrastBolusAgent' },
     339    '0018,0012' => { VR => 'SQ', Name => 'ContrastBolusAgentSequence' },
     340    '0018,0014' => { VR => 'SQ', Name => 'ContrastBolusAdministrationRoute' },
    281341    '0018,0015' => { VR => 'CS', Name => 'BodyPartExamined' },
    282342    '0018,0020' => { VR => 'CS', Name => 'ScanningSequence' },
     
    291351    '0018,0029' => { VR => 'SQ', Name => 'InterventionDrugSequence' },
    292352    '0018,002A' => { VR => 'SQ', Name => 'AdditionalDrugSequence' },
    293     '0018,0030' => { VR => 'RET',Name => 'Radionuclide' },
     353    '0018,0030' => { VR => 'LO', Name => 'Radionuclide' },
    294354    '0018,0031' => { VR => 'LO', Name => 'Radiopharmaceutical' },
    295     '0018,0032' => { VR => 'RET',Name => 'EnergyWindowCenterline' },
    296     '0018,0033' => { VR => 'RET',Name => 'EnergyWindowTotalWidth' },
     355    '0018,0032' => { VR => 'DS', Name => 'EnergyWindowCenterline' },
     356    '0018,0033' => { VR => 'DS', Name => 'EnergyWindowTotalWidth' },
    297357    '0018,0034' => { VR => 'LO', Name => 'InterventionDrugName' },
    298358    '0018,0035' => { VR => 'TM', Name => 'InterventionDrugStartTime' },
    299359    '0018,0036' => { VR => 'SQ', Name => 'InterventionSequence' },
    300     '0018,0037' => { VR => 'RET',Name => 'TherapyType' },
     360    '0018,0037' => { VR => 'CS', Name => 'TherapyType' },
    301361    '0018,0038' => { VR => 'CS', Name => 'InterventionStatus' },
    302     '0018,0039' => { VR => 'RET',Name => 'TherapyDescription' },
     362    '0018,0039' => { VR => 'CS', Name => 'TherapyDescription' },
    303363    '0018,003A' => { VR => 'ST', Name => 'InterventionDescription' },
    304364    '0018,0040' => { VR => 'IS', Name => 'CineRate' },
     365    '0018,0042' => { VR => 'CS', Name => 'InitialCineRunState' },
    305366    '0018,0050' => { VR => 'DS', Name => 'SliceThickness' },
    306367    '0018,0060' => { VR => 'DS', Name => 'KVP' },
     
    327388    '0018,0095' => { VR => 'DS', Name => 'PixelBandwidth' },
    328389    '0018,1000' => { VR => 'LO', Name => 'DeviceSerialNumber' },
     390    '0018,1002' => { VR => 'UI', Name => 'DeviceUID' },
     391    '0018,1003' => { VR => 'LO', Name => 'DeviceID' },
    329392    '0018,1004' => { VR => 'LO', Name => 'PlateID' },
     393    '0018,1005' => { VR => 'LO', Name => 'GeneratorID' },
     394    '0018,1006' => { VR => 'LO', Name => 'GridID' },
     395    '0018,1007' => { VR => 'LO', Name => 'CassetteID' },
     396    '0018,1008' => { VR => 'LO', Name => 'GantryID' },
    330397    '0018,1010' => { VR => 'LO', Name => 'SecondaryCaptureDeviceID' },
    331398    '0018,1011' => { VR => 'LO', Name => 'HardcopyCreationDeviceID' },
     
    342409    '0018,1023' => { VR => 'LO', Name => 'DigitalImageFormatAcquired' },
    343410    '0018,1030' => { VR => 'LO', Name => 'ProtocolName' },
    344     '0018,1040' => { VR => 'LO', Name => 'Contrast-BolusRoute' },
    345     '0018,1041' => { VR => 'DS', Name => 'Contrast-BolusVolume' },
    346     '0018,1042' => { VR => 'TM', Name => 'Contrast-BolusStartTime' },
    347     '0018,1043' => { VR => 'TM', Name => 'Contrast-BolusStopTime' },
    348     '0018,1044' => { VR => 'DS', Name => 'Contrast-BolusTotalDose' },
     411    '0018,1040' => { VR => 'LO', Name => 'ContrastBolusRoute' },
     412    '0018,1041' => { VR => 'DS', Name => 'ContrastBolusVolume' },
     413    '0018,1042' => { VR => 'TM', Name => 'ContrastBolusStartTime' },
     414    '0018,1043' => { VR => 'TM', Name => 'ContrastBolusStopTime' },
     415    '0018,1044' => { VR => 'DS', Name => 'ContrastBolusTotalDose' },
    349416    '0018,1045' => { VR => 'IS', Name => 'SyringeCounts' },
    350417    '0018,1046' => { VR => 'DS', Name => 'ContrastFlowRate' },
    351418    '0018,1047' => { VR => 'DS', Name => 'ContrastFlowDuration' },
    352     '0018,1048' => { VR => 'CS', Name => 'Contrast-BolusIngredient' },
    353     '0018,1049' => { VR => 'DS', Name => 'Contrast-BolusConcentration' },
     419    '0018,1048' => { VR => 'CS', Name => 'ContrastBolusIngredient' },
     420    '0018,1049' => { VR => 'DS', Name => 'ContrastBolusConcentration' },
    354421    '0018,1050' => { VR => 'DS', Name => 'SpatialResolution' },
    355422    '0018,1060' => { VR => 'DS', Name => 'TriggerTime' },
     
    357424    '0018,1062' => { VR => 'IS', Name => 'NominalInterval' },
    358425    '0018,1063' => { VR => 'DS', Name => 'FrameTime' },
    359     '0018,1064' => { VR => 'LO', Name => 'FramingType' },
     426    '0018,1064' => { VR => 'LO', Name => 'CardiacFramingType' },
    360427    '0018,1065' => { VR => 'DS', Name => 'FrameTimeVector' },
    361428    '0018,1066' => { VR => 'DS', Name => 'FrameDelay' },
     
    374441    '0018,1076' => { VR => 'DS', Name => 'RadionuclidePositronFraction' },
    375442    '0018,1077' => { VR => 'DS', Name => 'RadiopharmaceuticalSpecActivity' },
     443    '0018,1078' => { VR => 'DT', Name => 'RadiopharmaceuticalStartDateTime' },
     444    '0018,1079' => { VR => 'DT', Name => 'RadiopharmaceuticalStopDateTime' },
    376445    '0018,1080' => { VR => 'CS', Name => 'BeatRejectionFlag' },
    377446    '0018,1081' => { VR => 'IS', Name => 'LowRRValue' },
     
    388457    '0018,1111' => { VR => 'DS', Name => 'DistanceSourceToPatient' },
    389458    '0018,1114' => { VR => 'DS', Name => 'EstimatedRadiographicMagnification' },
    390     '0018,1120' => { VR => 'DS', Name => 'Gantry-DetectorTilt' },
    391     '0018,1121' => { VR => 'DS', Name => 'Gantry-DetectorSlew' },
     459    '0018,1120' => { VR => 'DS', Name => 'GantryDetectorTilt' },
     460    '0018,1121' => { VR => 'DS', Name => 'GantryDetectorSlew' },
    392461    '0018,1130' => { VR => 'DS', Name => 'TableHeight' },
    393462    '0018,1131' => { VR => 'DS', Name => 'TableTraverse' },
     
    404473    '0018,1144' => { VR => 'DS', Name => 'AngularStep' },
    405474    '0018,1145' => { VR => 'DS', Name => 'CenterOfRotationOffset' },
    406     '0018,1146' => { VR => 'RET',Name => 'RotationOffset' },
     475    '0018,1146' => { VR => 'DS', Name => 'RotationOffset' },
    407476    '0018,1147' => { VR => 'CS', Name => 'FieldOfViewShape' },
    408477    '0018,1149' => { VR => 'IS', Name => 'FieldOfViewDimensions' },
     
    422491    '0018,1166' => { VR => 'CS', Name => 'Grid' },
    423492    '0018,1170' => { VR => 'IS', Name => 'GeneratorPower' },
    424     '0018,1180' => { VR => 'SH', Name => 'Collimator-GridName' },
     493    '0018,1180' => { VR => 'SH', Name => 'CollimatorGridName' },
    425494    '0018,1181' => { VR => 'CS', Name => 'CollimatorType' },
    426495    '0018,1182' => { VR => 'IS', Name => 'FocalDistance' },
    427496    '0018,1183' => { VR => 'DS', Name => 'XFocusCenter' },
    428497    '0018,1184' => { VR => 'DS', Name => 'YFocusCenter' },
    429     '0018,1190' => { VR => 'DS', Name => 'FocalSpot' },
     498    '0018,1190' => { VR => 'DS', Name => 'FocalSpots' },
    430499    '0018,1191' => { VR => 'CS', Name => 'AnodeTargetMaterial' },
    431500    '0018,11A0' => { VR => 'DS', Name => 'BodyPartThickness' },
     
    434503    '0018,1201' => { VR => 'TM', Name => 'TimeOfLastCalibration' },
    435504    '0018,1210' => { VR => 'SH', Name => 'ConvolutionKernel' },
    436     '0018,1240' => { VR => 'RET',Name => 'Upper-LowerPixelValues' },
     505    '0018,1240' => { VR => 'IS', Name => 'UpperLowerPixelValues' },
    437506    '0018,1242' => { VR => 'IS', Name => 'ActualFrameDuration' },
    438507    '0018,1243' => { VR => 'IS', Name => 'CountRate' },
     
    455524    '0018,1402' => { VR => 'CS', Name => 'CassetteOrientation' },
    456525    '0018,1403' => { VR => 'CS', Name => 'CassetteSize' },
    457     '0018,1404' => { VR => 'US', Name => 'ExposuresonPlate' },
     526    '0018,1404' => { VR => 'US', Name => 'ExposuresOnPlate' },
    458527    '0018,1405' => { VR => 'IS', Name => 'RelativeXRayExposure' },
    459528    '0018,1450' => { VR => 'DS', Name => 'ColumnAngulation' },
     
    482551    '0018,1622' => { VR => 'US', Name => 'ShutterPresentationValue' },
    483552    '0018,1623' => { VR => 'US', Name => 'ShutterOverlayGroup' },
     553    '0018,1624' => { VR => 'US', Name => 'ShutterPresentationColorCIELabVal' },
    484554    '0018,1700' => { VR => 'CS', Name => 'CollimatorShape' },
    485555    '0018,1702' => { VR => 'IS', Name => 'CollimatorLeftVerticalEdge' },
     
    509579    '0018,3104' => { VR => 'IS', Name => 'IVUSPullbackStopFrameNumber' },
    510580    '0018,3105' => { VR => 'IS', Name => 'LesionNumber' },
    511     '0018,4000' => { VR => 'RET',Name => 'AcquisitionComments' },
     581    '0018,4000' => { VR => 'LT', Name => 'AcquisitionComments' },
    512582    '0018,5000' => { VR => 'SH', Name => 'OutputPower' },
    513583    '0018,5010' => { VR => 'LO', Name => 'TransducerData' },
     
    521591    '0018,5028' => { VR => 'DS', Name => 'SoftTissueFocusThermalIndex' },
    522592    '0018,5029' => { VR => 'DS', Name => 'SoftTissueSurfaceThermalIndex' },
    523     '0018,5030' => { VR => 'RET',Name => 'DynamicRange' },
    524     '0018,5040' => { VR => 'RET',Name => 'TotalGain' },
     593    '0018,5030' => { VR => 'DS', Name => 'DynamicRange' },
     594    '0018,5040' => { VR => 'DS', Name => 'TotalGain' },
    525595    '0018,5050' => { VR => 'IS', Name => 'DepthOfScanField' },
    526596    '0018,5100' => { VR => 'CS', Name => 'PatientPosition' },
    527597    '0018,5101' => { VR => 'CS', Name => 'ViewPosition' },
    528598    '0018,5104' => { VR => 'SQ', Name => 'ProjectionEponymousNameCodeSeq' },
    529     '0018,5210' => { VR => 'RET',Name => 'ImageTransformationMatrix' },
    530     '0018,5212' => { VR => 'RET',Name => 'ImageTranslationVector' },
     599    '0018,5210' => { VR => 'DS', Name => 'ImageTransformationMatrix' },
     600    '0018,5212' => { VR => 'DS', Name => 'ImageTranslationVector' },
    531601    '0018,6000' => { VR => 'DS', Name => 'Sensitivity' },
    532602    '0018,6011' => { VR => 'SQ', Name => 'SequenceOfUltrasoundRegions' },
     
    551621    '0018,6034' => { VR => 'FD', Name => 'DopplerCorrectionAngle' },
    552622    '0018,6036' => { VR => 'FD', Name => 'SteeringAngle' },
    553     '0018,6038' => { VR => 'RET',Name => 'DopplerSampleVolumeXPositionUL' },
     623    '0018,6038' => { VR => 'UL', Name => 'DopplerSampleVolumeXPosRetired' },
    554624    '0018,6039' => { VR => 'SL', Name => 'DopplerSampleVolumeXPosition' },
    555     '0018,603A' => { VR => 'RET',Name => 'DopplerSampleVolumeYPositionUL' },
     625    '0018,603A' => { VR => 'UL', Name => 'DopplerSampleVolumeYPosRetired' },
    556626    '0018,603B' => { VR => 'SL', Name => 'DopplerSampleVolumeYPosition' },
    557     '0018,603C' => { VR => 'RET',Name => 'TMLinePositionX0UL' },
     627    '0018,603C' => { VR => 'UL', Name => 'TMLinePositionX0Retired' },
    558628    '0018,603D' => { VR => 'SL', Name => 'TMLinePositionX0' },
    559     '0018,603E' => { VR => 'RET',Name => 'TMLinePositionY0UL' },
     629    '0018,603E' => { VR => 'UL', Name => 'TMLinePositionY0Retired' },
    560630    '0018,603F' => { VR => 'SL', Name => 'TMLinePositionY0' },
    561     '0018,6040' => { VR => 'RET',Name => 'TMLinePositionX1UL' },
     631    '0018,6040' => { VR => 'UL', Name => 'TMLinePositionX1Retired' },
    562632    '0018,6041' => { VR => 'SL', Name => 'TMLinePositionX1' },
    563     '0018,6042' => { VR => 'RET',Name => 'TMLinePositionY1UL' },
     633    '0018,6042' => { VR => 'UL', Name => 'TMLinePositionY1Retired' },
    564634    '0018,6043' => { VR => 'SL', Name => 'TMLinePositionY1' },
    565635    '0018,6044' => { VR => 'US', Name => 'PixelComponentOrganization' },
     
    638708    '0018,9025' => { VR => 'CS', Name => 'SpectrallySelectedSuppression' },
    639709    '0018,9026' => { VR => 'CS', Name => 'SpectrallySelectedExcitation' },
    640     '0018,9027' => { VR => 'CS', Name => 'SpatialPreSaturation' },
     710    '0018,9027' => { VR => 'CS', Name => 'SpatialPresaturation' },
    641711    '0018,9028' => { VR => 'CS', Name => 'Tagging' },
    642712    '0018,9029' => { VR => 'CS', Name => 'OversamplingPhase' },
     
    675745    '0018,9070' => { VR => 'FD', Name => 'CardiacRRIntervalSpecified' },
    676746    '0018,9073' => { VR => 'FD', Name => 'AcquisitionDuration' },
    677     '0018,9074' => { VR => 'DT', Name => 'FrameAcquisitionDatetime' },
     747    '0018,9074' => { VR => 'DT', Name => 'FrameAcquisitionDateTime' },
    678748    '0018,9075' => { VR => 'CS', Name => 'DiffusionDirectionality' },
    679749    '0018,9076' => { VR => 'SQ', Name => 'DiffusionGradientDirectionSequence' },
     
    694764    '0018,9094' => { VR => 'CS', Name => 'CoverageOfKSpace' },
    695765    '0018,9095' => { VR => 'UL', Name => 'SpectroscopyAcquisitionPhaseRows' },
     766    '0018,9096' => { VR => 'FD', Name => 'ParallelReductFactorInPlaneRetired' },
    696767    '0018,9098' => { VR => 'FD', Name => 'TransmitterFrequency' },
    697768    '0018,9100' => { VR => 'CS', Name => 'ResonantNucleus' },
     
    712783    '0018,9127' => { VR => 'UL', Name => 'SpectroscopyAcquisitionDataColumns' },
    713784    '0018,9147' => { VR => 'CS', Name => 'DiffusionAnisotropyType' },
    714     '0018,9151' => { VR => 'DT', Name => 'FrameReferenceDatetime' },
     785    '0018,9151' => { VR => 'DT', Name => 'FrameReferenceDateTime' },
    715786    '0018,9152' => { VR => 'SQ', Name => 'MRMetaboliteMapSequence' },
    716787    '0018,9155' => { VR => 'FD', Name => 'ParallelReductionFactorOutOfPlane' },
     
    734805    '0018,9183' => { VR => 'CS', Name => 'FlowCompensationDirection' },
    735806    '0018,9184' => { VR => 'FD', Name => 'TaggingDelay' },
     807    '0018,9185' => { VR => 'ST', Name => 'RespiratoryMotionCompTechDescr' },
     808    '0018,9186' => { VR => 'SH', Name => 'RespiratorySignalSourceID' },
    736809    '0018,9195' => { VR => 'FD', Name => 'ChemicalShiftsMinIntegrateLimitHz' },
    737810    '0018,9196' => { VR => 'FD', Name => 'ChemicalShiftsMaxIntegrateLimitHz' },
     
    790863    '0018,9334' => { VR => 'CS', Name => 'FluoroscopyFlag' },
    791864    '0018,9335' => { VR => 'FD', Name => 'SourceToDataCollectionCenterDist' },
    792     '0018,9337' => { VR => 'US', Name => 'Contrast-BolusAgentNumber' },
    793     '0018,9338' => { VR => 'SQ', Name => 'Contrast-BolusIngredientCodeSeq' },
     865    '0018,9337' => { VR => 'US', Name => 'ContrastBolusAgentNumber' },
     866    '0018,9338' => { VR => 'SQ', Name => 'ContrastBolusIngredientCodeSeq' },
    794867    '0018,9340' => { VR => 'SQ', Name => 'ContrastAdministrationProfileSeq' },
    795     '0018,9341' => { VR => 'SQ', Name => 'Contrast-BolusUsageSequence' },
    796     '0018,9342' => { VR => 'CS', Name => 'Contrast-BolusAgentAdministered' },
    797     '0018,9343' => { VR => 'CS', Name => 'Contrast-BolusAgentDetected' },
    798     '0018,9344' => { VR => 'CS', Name => 'Contrast-BolusAgentPhase' },
     868    '0018,9341' => { VR => 'SQ', Name => 'ContrastBolusUsageSequence' },
     869    '0018,9342' => { VR => 'CS', Name => 'ContrastBolusAgentAdministered' },
     870    '0018,9343' => { VR => 'CS', Name => 'ContrastBolusAgentDetected' },
     871    '0018,9344' => { VR => 'CS', Name => 'ContrastBolusAgentPhase' },
    799872    '0018,9345' => { VR => 'FD', Name => 'CTDIvol' },
     873    '0018,9346' => { VR => 'SQ', Name => 'CTDIPhantomTypeCodeSequence' },
     874    '0018,9351' => { VR => 'FL', Name => 'CalciumScoringMassFactorPatient' },
     875    '0018,9352' => { VR => 'FL', Name => 'CalciumScoringMassFactorDevice' },
     876    '0018,9353' => { VR => 'FL', Name => 'EnergyWeightingFactor' },
     877    '0018,9360' => { VR => 'SQ', Name => 'CTAdditionalXRaySourceSequence' },
     878    '0018,9401' => { VR => 'SQ', Name => 'ProjectionPixelCalibrationSequence' },
     879    '0018,9402' => { VR => 'FL', Name => 'DistanceSourceToIsocenter' },
     880    '0018,9403' => { VR => 'FL', Name => 'DistanceObjectToTableTop' },
     881    '0018,9404' => { VR => 'FL', Name => 'ObjectPixelSpacingInCenterOfBeam' },
     882    '0018,9405' => { VR => 'SQ', Name => 'PositionerPositionSequence' },
     883    '0018,9406' => { VR => 'SQ', Name => 'TablePositionSequence' },
     884    '0018,9407' => { VR => 'SQ', Name => 'CollimatorShapeSequence' },
     885    '0018,9412' => { VR => 'SQ', Name => 'XA-XRFFrameCharacteristicsSequence' },
     886    '0018,9417' => { VR => 'SQ', Name => 'FrameAcquisitionSequence' },
     887    '0018,9420' => { VR => 'CS', Name => 'XRayReceptorType' },
     888    '0018,9423' => { VR => 'LO', Name => 'AcquisitionProtocolName' },
     889    '0018,9424' => { VR => 'LT', Name => 'AcquisitionProtocolDescription' },
     890    '0018,9425' => { VR => 'CS', Name => 'ContrastBolusIngredientOpaque' },
     891    '0018,9426' => { VR => 'FL', Name => 'DistanceReceptorPlaneToDetHousing' },
     892    '0018,9427' => { VR => 'CS', Name => 'IntensifierActiveShape' },
     893    '0018,9428' => { VR => 'FL', Name => 'IntensifierActiveDimensions' },
     894    '0018,9429' => { VR => 'FL', Name => 'PhysicalDetectorSize' },
     895    '0018,9430' => { VR => 'US', Name => 'PositionOfIsocenterProjection' },
     896    '0018,9432' => { VR => 'SQ', Name => 'FieldOfViewSequence' },
     897    '0018,9433' => { VR => 'LO', Name => 'FieldOfViewDescription' },
     898    '0018,9434' => { VR => 'SQ', Name => 'ExposureControlSensingRegionsSeq' },
     899    '0018,9435' => { VR => 'CS', Name => 'ExposureControlSensingRegionShape' },
     900    '0018,9436' => { VR => 'SS', Name => 'ExposureControlSensRegionLeftEdge' },
     901    '0018,9437' => { VR => 'SS', Name => 'ExposureControlSensRegionRightEdge' },
     902    '0018,9440' => { VR => 'SS', Name => 'CenterOfCircExposControlSensRegion' },
     903    '0018,9441' => { VR => 'US', Name => 'RadiusOfCircExposControlSensRegion' },
     904    '0018,9447' => { VR => 'FL', Name => 'ColumnAngulationPatient' },
     905    '0018,9449' => { VR => 'FL', Name => 'BeamAngle' },
     906    '0018,9451' => { VR => 'SQ', Name => 'FrameDetectorParametersSequence' },
     907    '0018,9452' => { VR => 'FL', Name => 'CalculatedAnatomyThickness' },
     908    '0018,9455' => { VR => 'SQ', Name => 'CalibrationSequence' },
     909    '0018,9456' => { VR => 'SQ', Name => 'ObjectThicknessSequence' },
     910    '0018,9457' => { VR => 'CS', Name => 'PlaneIdentification' },
     911    '0018,9461' => { VR => 'FL', Name => 'FieldOfViewDimensionsInFloat' },
     912    '0018,9462' => { VR => 'SQ', Name => 'IsocenterReferenceSystemSequence' },
     913    '0018,9463' => { VR => 'FL', Name => 'PositionerIsocenterPrimaryAngle' },
     914    '0018,9464' => { VR => 'FL', Name => 'PositionerIsocenterSecondaryAngle' },
     915    '0018,9465' => { VR => 'FL', Name => 'PositionerIsocenterDetRotAngle' },
     916    '0018,9466' => { VR => 'FL', Name => 'TableXPositionToIsocenter' },
     917    '0018,9467' => { VR => 'FL', Name => 'TableYPositionToIsocenter' },
     918    '0018,9468' => { VR => 'FL', Name => 'TableZPositionToIsocenter' },
     919    '0018,9469' => { VR => 'FL', Name => 'TableHorizontalRotationAngle' },
     920    '0018,9470' => { VR => 'FL', Name => 'TableHeadTiltAngle' },
     921    '0018,9471' => { VR => 'FL', Name => 'TableCradleTiltAngle' },
     922    '0018,9472' => { VR => 'SQ', Name => 'FrameDisplayShutterSequence' },
     923    '0018,9473' => { VR => 'FL', Name => 'AcquiredImageAreaDoseProduct' },
     924    '0018,9474' => { VR => 'CS', Name => 'CArmPositionerTabletopRelationship' },
     925    '0018,9476' => { VR => 'SQ', Name => 'XRayGeometrySequence' },
     926    '0018,9477' => { VR => 'SQ', Name => 'IrradiationEventIDSequence' },
     927    '0018,9504' => { VR => 'SQ', Name => 'XRay3DFrameTypeSequence' },
     928    '0018,9506' => { VR => 'SQ', Name => 'ContributingSourcesSequence' },
     929    '0018,9507' => { VR => 'SQ', Name => 'XRay3DAcquisitionSequence' },
     930    '0018,9508' => { VR => 'FL', Name => 'PrimaryPositionerScanArc' },
     931    '0018,9509' => { VR => 'FL', Name => 'SecondaryPositionerScanArc' },
     932    '0018,9510' => { VR => 'FL', Name => 'PrimaryPositionerScanStartAngle' },
     933    '0018,9511' => { VR => 'FL', Name => 'SecondaryPositionerScanStartAngle' },
     934    '0018,9514' => { VR => 'FL', Name => 'PrimaryPositionerIncrement' },
     935    '0018,9515' => { VR => 'FL', Name => 'SecondaryPositionerIncrement' },
     936    '0018,9516' => { VR => 'DT', Name => 'StartAcquisitionDateTime' },
     937    '0018,9517' => { VR => 'DT', Name => 'EndAcquisitionDateTime' },
     938    '0018,9524' => { VR => 'LO', Name => 'ApplicationName' },
     939    '0018,9525' => { VR => 'LO', Name => 'ApplicationVersion' },
     940    '0018,9526' => { VR => 'LO', Name => 'ApplicationManufacturer' },
     941    '0018,9527' => { VR => 'CS', Name => 'AlgorithmType' },
     942    '0018,9528' => { VR => 'LO', Name => 'AlgorithmDescription' },
     943    '0018,9530' => { VR => 'SQ', Name => 'XRay3DReconstructionSequence' },
     944    '0018,9531' => { VR => 'LO', Name => 'ReconstructionDescription' },
     945    '0018,9538' => { VR => 'SQ', Name => 'PerProjectionAcquisitionSequence' },
     946    '0018,9601' => { VR => 'SQ', Name => 'DiffusionBMatrixSequence' },
     947    '0018,9602' => { VR => 'FD', Name => 'DiffusionBValueXX' },
     948    '0018,9603' => { VR => 'FD', Name => 'DiffusionBValueXY' },
     949    '0018,9604' => { VR => 'FD', Name => 'DiffusionBValueXZ' },
     950    '0018,9605' => { VR => 'FD', Name => 'DiffusionBValueYY' },
     951    '0018,9606' => { VR => 'FD', Name => 'DiffusionBValueYZ' },
     952    '0018,9607' => { VR => 'FD', Name => 'DiffusionBValueZZ' },
     953    '0018,9701' => { VR => 'DT', Name => 'DecayCorrectionDateTime' },
     954    '0018,9715' => { VR => 'FD', Name => 'StartDensityThreshold' },
     955    '0018,9722' => { VR => 'FD', Name => 'TerminationTimeThreshold' },
     956    '0018,9725' => { VR => 'CS', Name => 'DetectorGeometry' },
     957    '0018,9727' => { VR => 'FD', Name => 'AxialDetectorDimension' },
     958    '0018,9735' => { VR => 'SQ', Name => 'PETPositionSequence' },
     959    '0018,9739' => { VR => 'US', Name => 'NumberOfIterations' },
     960    '0018,9740' => { VR => 'US', Name => 'NumberOfSubsets' },
     961    '0018,9751' => { VR => 'SQ', Name => 'PETFrameTypeSequence' },
     962    '0018,9756' => { VR => 'CS', Name => 'ReconstructionType' },
     963    '0018,9758' => { VR => 'CS', Name => 'DecayCorrected' },
     964    '0018,9759' => { VR => 'CS', Name => 'AttenuationCorrected' },
     965    '0018,9760' => { VR => 'CS', Name => 'ScatterCorrected' },
     966    '0018,9761' => { VR => 'CS', Name => 'DeadTimeCorrected' },
     967    '0018,9762' => { VR => 'CS', Name => 'GantryMotionCorrected' },
     968    '0018,9763' => { VR => 'CS', Name => 'PatientMotionCorrected' },
     969    '0018,9765' => { VR => 'CS', Name => 'RandomsCorrected' },
     970    '0018,9767' => { VR => 'CS', Name => 'SensitivityCalibrated' },
     971    '0018,9801' => { VR => 'FD', Name => 'DepthsOfFocus' },
     972    '0018,9804' => { VR => 'DT', Name => 'ExclusionStartDatetime' },
     973    '0018,9805' => { VR => 'FD', Name => 'ExclusionDuration' },
     974    '0018,9807' => { VR => 'SQ', Name => 'ImageDataTypeSequence' },
     975    '0018,9808' => { VR => 'CS', Name => 'DataType' },
     976    '0018,980B' => { VR => 'CS', Name => 'AliasedDataType' },
    800977    '0018,A001' => { VR => 'SQ', Name => 'ContributingEquipmentSequence' },
    801978    '0018,A002' => { VR => 'DT', Name => 'ContributionDateTime' },
    802979    '0018,A003' => { VR => 'ST', Name => 'ContributionDescription' },
     980    # GEMS_ACQU_01 (ref 4)
     981    '0019,1002' => { VR => 'SL', Name => 'NumberOfCellsIInDetector' },
     982    '0019,1003' => { VR => 'DS', Name => 'CellNumberAtTheta' },
     983    '0019,1004' => { VR => 'DS', Name => 'CellSpacing' },
     984    '0019,100F' => { VR => 'DS', Name => 'HorizFrameOfRef' },
     985    '0019,1011' => { VR => 'SS', Name => 'SeriesContrast' },
     986    '0019,1012' => { VR => 'SS', Name => 'LastPseq' },
     987    '0019,1013' => { VR => 'SS', Name => 'StartNumberForBaseline' },
     988    '0019,1014' => { VR => 'SS', Name => 'EndNumberForBaseline' },
     989    '0019,1015' => { VR => 'SS', Name => 'StartNumberForEnhancedScans' },
     990    '0019,1016' => { VR => 'SS', Name => 'EndNumberForEnhancedScans' },
     991    '0019,1017' => { VR => 'SS', Name => 'SeriesPlane' },
     992    '0019,1018' => { VR => 'LO', Name => 'FirstScanRas' },
     993    '0019,1019' => { VR => 'DS', Name => 'FirstScanLocation' },
     994    '0019,101A' => { VR => 'LO', Name => 'LastScanRas' },
     995    '0019,101B' => { VR => 'DS', Name => 'LastScanLoc' },
     996    '0019,101E' => { VR => 'DS', Name => 'DisplayFieldOfView' },
     997    '0019,1023' => { VR => 'DS', Name => 'TableSpeed' },
     998    '0019,1024' => { VR => 'DS', Name => 'MidScanTime' },
     999    '0019,1025' => { VR => 'SS', Name => 'MidScanFlag' },
     1000    '0019,1026' => { VR => 'SL', Name => 'DegreesOfAzimuth' },
     1001    '0019,1027' => { VR => 'DS', Name => 'GantryPeriod' },
     1002    '0019,102A' => { VR => 'DS', Name => 'XRayOnPosition' },
     1003    '0019,102B' => { VR => 'DS', Name => 'XRayOffPosition' },
     1004    '0019,102C' => { VR => 'SL', Name => 'NumberOfTriggers' },
     1005    '0019,102E' => { VR => 'DS', Name => 'AngleOfFirstView' },
     1006    '0019,102F' => { VR => 'DS', Name => 'TriggerFrequency' },
     1007    '0019,1039' => { VR => 'SS', Name => 'ScanFOVType' },
     1008    '0019,1040' => { VR => 'SS', Name => 'StatReconFlag' },
     1009    '0019,1041' => { VR => 'SS', Name => 'ComputeType' },
     1010    '0019,1042' => { VR => 'SS', Name => 'SegmentNumber' },
     1011    '0019,1043' => { VR => 'SS', Name => 'TotalSegmentsRequested' },
     1012    '0019,1044' => { VR => 'DS', Name => 'InterscanDelay' },
     1013    '0019,1047' => { VR => 'SS', Name => 'ViewCompressionFactor' },
     1014    '0019,104A' => { VR => 'SS', Name => 'TotalNoOfRefChannels' },
     1015    '0019,104B' => { VR => 'SL', Name => 'DataSizeForScanData' },
     1016    '0019,1052' => { VR => 'SS', Name => 'ReconPostProcflag' },
     1017    '0019,1057' => { VR => 'SS', Name => 'CTWaterNumber' },
     1018    '0019,1058' => { VR => 'SS', Name => 'CTBoneNumber' },
     1019    '0019,105A' => { VR => 'FL', Name => 'AcquisitionDuration' },
     1020    '0019,105E' => { VR => 'SL', Name => 'NumberOfChannels' },
     1021    '0019,105F' => { VR => 'SL', Name => 'IncrementBetweenChannels' },
     1022    '0019,1060' => { VR => 'SL', Name => 'StartingView' },
     1023    '0019,1061' => { VR => 'SL', Name => 'NumberOfViews' },
     1024    '0019,1062' => { VR => 'SL', Name => 'IncrementBetweenViews' },
     1025    '0019,106A' => { VR => 'SS', Name => 'DependantOnNoViewsProcessed' },
     1026    '0019,106B' => { VR => 'SS', Name => 'FieldOfViewInDetectorCells' },
     1027    '0019,1070' => { VR => 'SS', Name => 'ValueOfBackProjectionButton' },
     1028    '0019,1071' => { VR => 'SS', Name => 'SetIfFatqEstimatesWereUsed' },
     1029    '0019,1072' => { VR => 'DS', Name => 'ZChanAvgOverViews' },
     1030    '0019,1073' => { VR => 'DS', Name => 'AvgOfLeftRefChansOverViews' },
     1031    '0019,1074' => { VR => 'DS', Name => 'MaxLeftChanOverViews' },
     1032    '0019,1075' => { VR => 'DS', Name => 'AvgOfRightRefChansOverViews' },
     1033    '0019,1076' => { VR => 'DS', Name => 'MaxRightChanOverViews' },
     1034    '0019,107D' => { VR => 'DS', Name => 'SecondEcho' },
     1035    '0019,107E' => { VR => 'SS', Name => 'NumberOfEchoes' },
     1036    '0019,107F' => { VR => 'DS', Name => 'TableDelta' },
     1037    '0019,1081' => { VR => 'SS', Name => 'Contiguous' },
     1038    '0019,1084' => { VR => 'DS', Name => 'PeakSAR' },
     1039    '0019,1085' => { VR => 'SS', Name => 'MonitorSAR' },
     1040    '0019,1087' => { VR => 'DS', Name => 'CardiacRepetitionTime' },
     1041    '0019,1088' => { VR => 'SS', Name => 'ImagesPerCardiacCycle' },
     1042    '0019,108A' => { VR => 'SS', Name => 'ActualReceiveGainAnalog' },
     1043    '0019,108B' => { VR => 'SS', Name => 'ActualReceiveGainDigital' },
     1044    '0019,108D' => { VR => 'DS', Name => 'DelayAfterTrigger' },
     1045    '0019,108F' => { VR => 'SS', Name => 'Swappf' },
     1046    '0019,1090' => { VR => 'SS', Name => 'PauseInterval' },
     1047    '0019,1091' => { VR => 'DS', Name => 'PulseTime' },
     1048    '0019,1092' => { VR => 'SL', Name => 'SliceOffsetOnFreqAxis' },
     1049    '0019,1093' => { VR => 'DS', Name => 'CenterFrequency' },
     1050    '0019,1094' => { VR => 'SS', Name => 'TransmitGain' },
     1051    '0019,1095' => { VR => 'SS', Name => 'AnalogReceiverGain' },
     1052    '0019,1096' => { VR => 'SS', Name => 'DigitalReceiverGain' },
     1053    '0019,1097' => { VR => 'SL', Name => 'BitmapDefiningCVs' },
     1054    '0019,1098' => { VR => 'SS', Name => 'CenterFreqMethod' },
     1055    '0019,109B' => { VR => 'SS', Name => 'PulseSeqMode' },
     1056    '0019,109C' => { VR => 'LO', Name => 'PulseSeqName' },
     1057    '0019,109D' => { VR => 'DT', Name => 'PulseSeqDate' },
     1058    '0019,109E' => { VR => 'LO', Name => 'InternalPulseSeqName' },
     1059    '0019,109F' => { VR => 'SS', Name => 'TransmittingCoil' },
     1060    '0019,10A0' => { VR => 'SS', Name => 'SurfaceCoilType' },
     1061    '0019,10A1' => { VR => 'SS', Name => 'ExtremityCoilFlag' },
     1062    '0019,10A2' => { VR => 'SL', Name => 'RawDataRunNumber' },
     1063    '0019,10A3' => { VR => 'UL', Name => 'CalibratedFieldStrength' },
     1064    '0019,10A4' => { VR => 'SS', Name => 'SATFatWaterBone' },
     1065    '0019,10A5' => { VR => 'DS', Name => 'ReceiveBandwidth' },
     1066    '0019,10A7' => { VR => 'DS', Name => 'UserData01' },
     1067    '0019,10A8' => { VR => 'DS', Name => 'UserData02' },
     1068    '0019,10A9' => { VR => 'DS', Name => 'UserData03' },
     1069    '0019,10AA' => { VR => 'DS', Name => 'UserData04' },
     1070    '0019,10AB' => { VR => 'DS', Name => 'UserData05' },
     1071    '0019,10AC' => { VR => 'DS', Name => 'UserData06' },
     1072    '0019,10AD' => { VR => 'DS', Name => 'UserData07' },
     1073    '0019,10AE' => { VR => 'DS', Name => 'UserData08' },
     1074    '0019,10AF' => { VR => 'DS', Name => 'UserData09' },
     1075    '0019,10B0' => { VR => 'DS', Name => 'UserData10' },
     1076    '0019,10B1' => { VR => 'DS', Name => 'UserData11' },
     1077    '0019,10B2' => { VR => 'DS', Name => 'UserData12' },
     1078    '0019,10B3' => { VR => 'DS', Name => 'UserData13' },
     1079    '0019,10B4' => { VR => 'DS', Name => 'UserData14' },
     1080    '0019,10B5' => { VR => 'DS', Name => 'UserData15' },
     1081    '0019,10B6' => { VR => 'DS', Name => 'UserData16' },
     1082    '0019,10B7' => { VR => 'DS', Name => 'UserData17' },
     1083    '0019,10B8' => { VR => 'DS', Name => 'UserData18' },
     1084    '0019,10B9' => { VR => 'DS', Name => 'UserData19' },
     1085    '0019,10BA' => { VR => 'DS', Name => 'UserData20' },
     1086    '0019,10BB' => { VR => 'DS', Name => 'UserData21' },
     1087    '0019,10BC' => { VR => 'DS', Name => 'UserData22' },
     1088    '0019,10BD' => { VR => 'DS', Name => 'UserData23' },
     1089    '0019,10BE' => { VR => 'DS', Name => 'ProjectionAngle' },
     1090    '0019,10C0' => { VR => 'SS', Name => 'SaturationPlanes' },
     1091    '0019,10C1' => { VR => 'SS', Name => 'SurfaceCoilIntensity' },
     1092    '0019,10C2' => { VR => 'SS', Name => 'SATLocationR' },
     1093    '0019,10C3' => { VR => 'SS', Name => 'SATLocationL' },
     1094    '0019,10C4' => { VR => 'SS', Name => 'SATLocationA' },
     1095    '0019,10C5' => { VR => 'SS', Name => 'SATLocationP' },
     1096    '0019,10C6' => { VR => 'SS', Name => 'SATLocationH' },
     1097    '0019,10C7' => { VR => 'SS', Name => 'SATLocationF' },
     1098    '0019,10C8' => { VR => 'SS', Name => 'SATThicknessR-L' },
     1099    '0019,10C9' => { VR => 'SS', Name => 'SATThicknessA-P' },
     1100    '0019,10CA' => { VR => 'SS', Name => 'SATThicknessH-F' },
     1101    '0019,10CB' => { VR => 'SS', Name => 'PrescribedFlowAxis' },
     1102    '0019,10CC' => { VR => 'SS', Name => 'VelocityEncoding' },
     1103    '0019,10CD' => { VR => 'SS', Name => 'ThicknessDisclaimer' },
     1104    '0019,10CE' => { VR => 'SS', Name => 'PrescanType' },
     1105    '0019,10CF' => { VR => 'SS', Name => 'PrescanStatus' },
     1106    '0019,10D0' => { VR => 'SH', Name => 'RawDataType' },
     1107    '0019,10D2' => { VR => 'SS', Name => 'ProjectionAlgorithm' },
     1108    '0019,10D3' => { VR => 'SH', Name => 'ProjectionAlgorithm' },
     1109    '0019,10D5' => { VR => 'SS', Name => 'FractionalEcho' },
     1110    '0019,10D6' => { VR => 'SS', Name => 'PrepPulse' },
     1111    '0019,10D7' => { VR => 'SS', Name => 'CardiacPhases' },
     1112    '0019,10D8' => { VR => 'SS', Name => 'VariableEchoflag' },
     1113    '0019,10D9' => { VR => 'DS', Name => 'ConcatenatedSAT' },
     1114    '0019,10DA' => { VR => 'SS', Name => 'ReferenceChannelUsed' },
     1115    '0019,10DB' => { VR => 'DS', Name => 'BackProjectorCoefficient' },
     1116    '0019,10DC' => { VR => 'SS', Name => 'PrimarySpeedCorrectionUsed' },
     1117    '0019,10DD' => { VR => 'SS', Name => 'OverrangeCorrectionUsed' },
     1118    '0019,10DE' => { VR => 'DS', Name => 'DynamicZAlphaValue' },
     1119    '0019,10DF' => { VR => 'DS', Name => 'UserData' },
     1120    '0019,10E0' => { VR => 'DS', Name => 'UserData' },
     1121    '0019,10E2' => { VR => 'DS', Name => 'VelocityEncodeScale' },
     1122    '0019,10F2' => { VR => 'SS', Name => 'FastPhases' },
     1123    '0019,10F9' => { VR => 'DS', Name => 'TransmissionGain' },
    8031124    # relationship group
    8041125    '0020,0000' => { VR => 'UL', Name => 'RelationshipGroupLength' },
     
    8091130    '0020,0012' => { VR => 'IS', Name => 'AcquisitionNumber' },
    8101131    '0020,0013' => { VR => 'IS', Name => 'InstanceNumber' },
    811     '0020,0014' => { VR => 'RET',Name => 'IsotopeNumber' },
    812     '0020,0015' => { VR => 'RET',Name => 'PhaseNumber' },
    813     '0020,0016' => { VR => 'RET',Name => 'IntervalNumber' },
    814     '0020,0017' => { VR => 'RET',Name => 'TimeSlotNumber' },
    815     '0020,0018' => { VR => 'RET',Name => 'AngleNumber' },
     1132    '0020,0014' => { VR => 'IS', Name => 'IsotopeNumber' },
     1133    '0020,0015' => { VR => 'IS', Name => 'PhaseNumber' },
     1134    '0020,0016' => { VR => 'IS', Name => 'IntervalNumber' },
     1135    '0020,0017' => { VR => 'IS', Name => 'TimeSlotNumber' },
     1136    '0020,0018' => { VR => 'IS', Name => 'AngleNumber' },
    8161137    '0020,0019' => { VR => 'IS', Name => 'ItemNumber' },
    8171138    '0020,0020' => { VR => 'CS', Name => 'PatientOrientation' },
     
    8231144    '0020,0035' => { VR => 'DS', Name => 'ImageOrientation' },
    8241145    '0020,0037' => { VR => 'DS', Name => 'ImageOrientationPatient' },
    825     '0020,0050' => { VR => 'RET',Name => 'Location' },
     1146    '0020,0050' => { VR => 'DS', Name => 'Location' },
    8261147    '0020,0052' => { VR => 'UI', Name => 'FrameOfReferenceUID' },
    8271148    '0020,0060' => { VR => 'CS', Name => 'Laterality' },
    8281149    '0020,0062' => { VR => 'CS', Name => 'ImageLaterality' },
    829     '0020,0070' => { VR => 'RET',Name => 'ImageGeometryType' },
    830     '0020,0080' => { VR => 'RET',Name => 'MaskingImage' },
     1150    '0020,0070' => { VR => 'LO', Name => 'ImageGeometryType' },
     1151    '0020,0080' => { VR => 'CS', Name => 'MaskingImage' },
    8311152    '0020,0100' => { VR => 'IS', Name => 'TemporalPositionIdentifier' },
    8321153    '0020,0105' => { VR => 'IS', Name => 'NumberOfTemporalPositions' },
     
    8341155    '0020,0200' => { VR => 'UI', Name => 'SynchronizationFrameOfReferenceUID' },
    8351156    '0020,1000' => { VR => 'IS', Name => 'SeriesInStudy' },
    836     '0020,1001' => { VR => 'RET',Name => 'AcquisitionsInSeries' },
     1157    '0020,1001' => { VR => 'IS', Name => 'AcquisitionsInSeries' },
    8371158    '0020,1002' => { VR => 'IS', Name => 'ImagesInAcquisition' },
     1159    '0020,1003' => { VR => 'IS', Name => 'ImagesInSeries' },
    8381160    '0020,1004' => { VR => 'IS', Name => 'AcquisitionsInStudy' },
    839     '0020,1020' => { VR => 'RET',Name => 'Reference' },
     1161    '0020,1005' => { VR => 'IS', Name => 'ImagesInStudy' },
     1162    '0020,1020' => { VR => 'CS', Name => 'Reference' },
    8401163    '0020,1040' => { VR => 'LO', Name => 'PositionReferenceIndicator' },
    8411164    '0020,1041' => { VR => 'DS', Name => 'SliceLocation' },
     
    8461169    '0020,1206' => { VR => 'IS', Name => 'NumberOfStudyRelatedSeries' },
    8471170    '0020,1208' => { VR => 'IS', Name => 'NumberOfStudyRelatedInstances' },
    848     '0020,1209' => { VR => 'RET',Name => 'NumberOfSeriesRelatedInstances' },
    849     '0020,31xx' => { VR => 'RET',Name => 'SourceImageIDs' },
    850     '0020,3401' => { VR => 'RET',Name => 'ModifyingDeviceID' },
    851     '0020,3402' => { VR => 'RET',Name => 'ModifiedImageID' },
    852     '0020,3403' => { VR => 'RET',Name => 'ModifiedImageDate' },
    853     '0020,3404' => { VR => 'RET',Name => 'ModifyingDeviceManufacturer' },
    854     '0020,3405' => { VR => 'RET',Name => 'ModifiedImageTime' },
    855     '0020,3406' => { VR => 'RET',Name => 'ModifiedImageDescription' },
     1171    '0020,1209' => { VR => 'IS', Name => 'NumberOfSeriesRelatedInstances' },
     1172    '0020,31xx' => { VR => 'CS', Name => 'SourceImageIDs' },
     1173    '0020,3401' => { VR => 'CS', Name => 'ModifyingDeviceID' },
     1174    '0020,3402' => { VR => 'CS', Name => 'ModifiedImageID' },
     1175    '0020,3403' => { VR => 'DA', Name => 'ModifiedImageDate' },
     1176    '0020,3404' => { VR => 'LO', Name => 'ModifyingDeviceManufacturer' },
     1177    '0020,3405' => { VR => 'TM', Name => 'ModifiedImageTime' },
     1178    '0020,3406' => { VR => 'LO', Name => 'ModifiedImageDescription' },
    8561179    '0020,4000' => { VR => 'LT', Name => 'ImageComments' },
    857     '0020,5000' => { VR => 'US', Name => 'OriginalImageIdentification' },
    858     '0020,5002' => { VR => 'RET',Name => 'OriginalImageIdentNomenclature' },
     1180    '0020,5000' => { VR => 'AT', Name => 'OriginalImageIdentification' },
     1181    '0020,5002' => { VR => 'CS', Name => 'OriginalImageIdentNomenclature' },
    8591182    '0020,9056' => { VR => 'SH', Name => 'StackID' },
    8601183    '0020,9057' => { VR => 'UL', Name => 'InStackPositionNumber' },
     
    8701193    '0020,9158' => { VR => 'LT', Name => 'FrameComments' },
    8711194    '0020,9161' => { VR => 'UI', Name => 'ConcatenationUID' },
    872     '0020,9162' => { VR => 'US', Name => 'InconcatenationNumber' },
    873     '0020,9163' => { VR => 'US', Name => 'InconcatenationTotalNumber' },
     1195    '0020,9162' => { VR => 'US', Name => 'InConcatenationNumber' },
     1196    '0020,9163' => { VR => 'US', Name => 'InConcatenationTotalNumber' },
    8741197    '0020,9164' => { VR => 'UI', Name => 'DimensionOrganizationUID' },
    8751198    '0020,9165' => { VR => 'AT', Name => 'DimensionIndexPointer' },
     
    8801203    '0020,9228' => { VR => 'UL', Name => 'ConcatenationFrameOffsetNumber' },
    8811204    '0020,9238' => { VR => 'LO', Name => 'FunctionalGroupPrivateCreator' },
     1205    '0020,9241' => { VR => 'FL', Name => 'NominalPercentageOfCardiacPhase' },
     1206    '0020,9245' => { VR => 'FL', Name => 'NominalPercentOfRespiratoryPhase' },
     1207    '0020,9246' => { VR => 'FL', Name => 'StartingRespiratoryAmplitude' },
     1208    '0020,9247' => { VR => 'CS', Name => 'StartingRespiratoryPhase' },
     1209    '0020,9248' => { VR => 'FL', Name => 'EndingRespiratoryAmplitude' },
     1210    '0020,9249' => { VR => 'CS', Name => 'EndingRespiratoryPhase' },
     1211    '0020,9250' => { VR => 'CS', Name => 'RespiratoryTriggerType' },
     1212    '0020,9251' => { VR => 'FD', Name => 'RRIntervalTimeNominal' },
     1213    '0020,9252' => { VR => 'FD', Name => 'ActualCardiacTriggerDelayTime' },
     1214    '0020,9253' => { VR => 'SQ', Name => 'RespiratorySynchronizationSequence' },
     1215    '0020,9254' => { VR => 'FD', Name => 'RespiratoryIntervalTime' },
     1216    '0020,9255' => { VR => 'FD', Name => 'NominalRespiratoryTriggerDelayTime' },
     1217    '0020,9256' => { VR => 'FD', Name => 'RespiratoryTriggerDelayThreshold' },
     1218    '0020,9257' => { VR => 'FD', Name => 'ActualRespiratoryTriggerDelayTime' },
     1219    '0020,9301' => { VR => 'FD', Name => 'ImagePositionVolume' },
     1220    '0020,9302' => { VR => 'FD', Name => 'ImageOrientationVolume' },
     1221    '0020,9308' => { VR => 'FD', Name => 'ApexPosition' },
     1222    '0020,9421' => { VR => 'LO', Name => 'DimensionDescriptionLabel' },
     1223    '0020,9450' => { VR => 'SQ', Name => 'PatientOrientationInFrameSequence' },
     1224    '0020,9453' => { VR => 'LO', Name => 'FrameLabel' },
     1225    '0020,9518' => { VR => 'US', Name => 'AcquisitionIndex' },
     1226    '0020,9529' => { VR => 'SQ', Name => 'ContributingSOPInstancesRefSeq' },
     1227    '0020,9536' => { VR => 'US', Name => 'ReconstructionIndex' },
     1228    # GEMS_RELA_01 (ref 4)
     1229    '0021,1003' => { VR => 'SS', Name => 'SeriesFromWhichPrescribed' },
     1230    '0021,1005' => { VR => 'SH', Name => 'GenesisVersionNow' },
     1231    '0021,1005' => { VR => 'SH', Name => 'GenesisVersionNow' },
     1232    '0021,1007' => { VR => 'UL', Name => 'SeriesRecordChecksum' },
     1233    '0021,1018' => { VR => 'SH', Name => 'GenesisVersionNow' },
     1234    '0021,1018' => { VR => 'SH', Name => 'GenesisVersionNow' },
     1235    '0021,1019' => { VR => 'UL', Name => 'AcqReconRecordChecksum' },
     1236    '0021,1019' => { VR => 'UL', Name => 'AcqreconRecordChecksum' },
     1237    '0021,1020' => { VR => 'DS', Name => 'TableStartLocation' },
     1238    '0021,1035' => { VR => 'SS', Name => 'SeriesFromWhichPrescribed' },
     1239    '0021,1036' => { VR => 'SS', Name => 'ImageFromWhichPrescribed' },
     1240    '0021,1037' => { VR => 'SS', Name => 'ScreenFormat' },
     1241    '0021,104A' => { VR => 'LO', Name => 'AnatomicalReferenceForScout' },
     1242    '0021,104F' => { VR => 'SS', Name => 'LocationsInAcquisition' },
     1243    '0021,1050' => { VR => 'SS', Name => 'GraphicallyPrescribed' },
     1244    '0021,1051' => { VR => 'DS', Name => 'RotationFromSourceXRot' },
     1245    '0021,1052' => { VR => 'DS', Name => 'RotationFromSourceYRot' },
     1246    '0021,1053' => { VR => 'DS', Name => 'RotationFromSourceZRot' },
     1247    '0021,1054' => { VR => 'SH', Name => 'ImagePosition' },
     1248    '0021,1055' => { VR => 'SH', Name => 'ImageOrientation' },
     1249    '0021,1056' => { VR => 'SL', Name => 'IntegerSlop' },
     1250    '0021,1057' => { VR => 'SL', Name => 'IntegerSlop' },
     1251    '0021,1058' => { VR => 'SL', Name => 'IntegerSlop' },
     1252    '0021,1059' => { VR => 'SL', Name => 'IntegerSlop' },
     1253    '0021,105A' => { VR => 'SL', Name => 'IntegerSlop' },
     1254    '0021,105B' => { VR => 'DS', Name => 'FloatSlop' },
     1255    '0021,105C' => { VR => 'DS', Name => 'FloatSlop' },
     1256    '0021,105D' => { VR => 'DS', Name => 'FloatSlop' },
     1257    '0021,105E' => { VR => 'DS', Name => 'FloatSlop' },
     1258    '0021,105F' => { VR => 'DS', Name => 'FloatSlop' },
     1259    '0021,1081' => { VR => 'DS', Name => 'AutoWindowLevelAlpha' },
     1260    '0021,1082' => { VR => 'DS', Name => 'AutoWindowLevelBeta' },
     1261    '0021,1083' => { VR => 'DS', Name => 'AutoWindowLevelWindow' },
     1262    '0021,1084' => { VR => 'DS', Name => 'ToWindowLevelLevel' },
     1263    '0021,1090' => { VR => 'SS', Name => 'TubeFocalSpotPosition' },
     1264    '0021,1091' => { VR => 'SS', Name => 'BiopsyPosition' },
     1265    '0021,1092' => { VR => 'FL', Name => 'BiopsyTLocation' },
     1266    '0021,1093' => { VR => 'FL', Name => 'BiopsyRefLocation' },
     1267    # ?
    8821268    '0022,0001' => { VR => 'US', Name => 'LightPathFilterPassThroughWavelen' },
    8831269    '0022,0002' => { VR => 'US', Name => 'LightPathFilterPassBand' },
     
    9111297    '0022,0021' => { VR => 'SQ', Name => 'LeftImageSequence' },
    9121298    '0022,0022' => { VR => 'SQ', Name => 'RightImageSequence' },
     1299    '0022,0030' => { VR => 'FL', Name => 'AxialLengthOfTheEye' },
     1300    '0022,0031' => { VR => 'SQ', Name => 'OphthalmicFrameLocationSequence' },
     1301    '0022,0032' => { VR => 'FL', Name => 'ReferenceCoordinates' },
     1302    '0022,0035' => { VR => 'FL', Name => 'DepthSpatialResolution' },
     1303    '0022,0036' => { VR => 'FL', Name => 'MaximumDepthDistortion' },
     1304    '0022,0037' => { VR => 'FL', Name => 'AlongScanSpatialResolution' },
     1305    '0022,0038' => { VR => 'FL', Name => 'MaximumAlongScanDistortion' },
     1306    '0022,0039' => { VR => 'CS', Name => 'OphthalmicImageOrientation' },
     1307    '0022,0041' => { VR => 'FL', Name => 'DepthOfTransverseImage' },
     1308    '0022,0042' => { VR => 'SQ', Name => 'MydriaticAgentConcUnitsSeq' },
     1309    '0022,0048' => { VR => 'FL', Name => 'AcrossScanSpatialResolution' },
     1310    '0022,0049' => { VR => 'FL', Name => 'MaximumAcrossScanDistortion' },
     1311    '0022,004E' => { VR => 'DS', Name => 'MydriaticAgentConcentration' },
     1312    '0022,0055' => { VR => 'FL', Name => 'IlluminationWaveLength' },
     1313    '0022,0056' => { VR => 'FL', Name => 'IlluminationPower' },
     1314    '0022,0057' => { VR => 'FL', Name => 'IlluminationBandwidth' },
     1315    '0022,0058' => { VR => 'SQ', Name => 'MydriaticAgentSequence' },
     1316    # GEMS_STDY_01 (ref 4)
     1317    '0023,1001' => { VR => 'SL', Name => 'NumberOfSeriesInStudy' },
     1318    '0023,1002' => { VR => 'SL', Name => 'NumberOfUnarchivedSeries' },
     1319    '0023,1010' => { VR => 'SS', Name => 'ReferenceImageField' },
     1320    '0023,1050' => { VR => 'SS', Name => 'SummaryImage' },
     1321    '0023,1070' => { VR => 'FD', Name => 'StartTimeSecsInFirstAxial' },
     1322    '0023,1074' => { VR => 'SL', Name => 'NoofUpdatesToHeader' },
     1323    '0023,107D' => { VR => 'SS', Name => 'IndicatesIfStudyHasCompleteInfo' },
     1324    '0023,107D' => { VR => 'SS', Name => 'IndicatesIfTheStudyHasCompleteInfo' },
     1325    # GEMS_SERS_01 (ref 4)
     1326    '0025,1006' => { VR => 'SS', Name => 'LastPulseSequenceUsed' },
     1327    '0025,1007' => { VR => 'SL', Name => 'ImagesInSeries' },
     1328    '0025,1010' => { VR => 'SL', Name => 'LandmarkCounter' },
     1329    '0025,1011' => { VR => 'SS', Name => 'NumberOfAcquisitions' },
     1330    '0025,1014' => { VR => 'SL', Name => 'IndicatesNoofUpdatesToHeader' },
     1331    '0025,1017' => { VR => 'SL', Name => 'SeriesCompleteFlag' },
     1332    '0025,1018' => { VR => 'SL', Name => 'NumberOfImagesArchived' },
     1333    '0025,1019' => { VR => 'SL', Name => 'LastImageNumberUsed' },
     1334    '0025,101A' => { VR => 'SH', Name => 'PrimaryReceiverSuiteAndHost' },
     1335    # GEMS_IMAG_01 (ref 4)
     1336    '0027,1006' => { VR => 'SL', Name => 'ImageArchiveFlag' },
     1337    '0027,1010' => { VR => 'SS', Name => 'ScoutType' },
     1338    '0027,101C' => { VR => 'SL', Name => 'VmaMamp' },
     1339    '0027,101D' => { VR => 'SS', Name => 'VmaPhase' },
     1340    '0027,101E' => { VR => 'SL', Name => 'VmaMod' },
     1341    '0027,101F' => { VR => 'SL', Name => 'VmaClip' },
     1342    '0027,1020' => { VR => 'SS', Name => 'SmartScanOnOffFlag' },
     1343    '0027,1030' => { VR => 'SH', Name => 'ForeignImageRevision' },
     1344    '0027,1031' => { VR => 'SS', Name => 'ImagingMode' },
     1345    '0027,1032' => { VR => 'SS', Name => 'PulseSequence' },
     1346    '0027,1033' => { VR => 'SL', Name => 'ImagingOptions' },
     1347    '0027,1035' => { VR => 'SS', Name => 'PlaneType' },
     1348    '0027,1036' => { VR => 'SL', Name => 'ObliquePlane' },
     1349    '0027,1040' => { VR => 'SH', Name => 'RASLetterOfImageLocation' },
     1350    '0027,1041' => { VR => 'FL', Name => 'ImageLocation' },
     1351    '0027,1042' => { VR => 'FL', Name => 'CenterRCoordOfPlaneImage' },
     1352    '0027,1043' => { VR => 'FL', Name => 'CenterACoordOfPlaneImage' },
     1353    '0027,1044' => { VR => 'FL', Name => 'CenterSCoordOfPlaneImage' },
     1354    '0027,1045' => { VR => 'FL', Name => 'NormalRCoord' },
     1355    '0027,1046' => { VR => 'FL', Name => 'NormalACoord' },
     1356    '0027,1047' => { VR => 'FL', Name => 'NormalSCoord' },
     1357    '0027,1048' => { VR => 'FL', Name => 'RCoordOfTopRightCorner' },
     1358    '0027,1049' => { VR => 'FL', Name => 'ACoordOfTopRightCorner' },
     1359    '0027,104A' => { VR => 'FL', Name => 'SCoordOfTopRightCorner' },
     1360    '0027,104B' => { VR => 'FL', Name => 'RCoordOfBottomRightCorner' },
     1361    '0027,104C' => { VR => 'FL', Name => 'ACoordOfBottomRightCorner' },
     1362    '0027,104D' => { VR => 'FL', Name => 'SCoordOfBottomRightCorner' },
     1363    '0027,1050' => { VR => 'FL', Name => 'TableStartLocation' },
     1364    '0027,1051' => { VR => 'FL', Name => 'TableEndLocation' },
     1365    '0027,1052' => { VR => 'SH', Name => 'RASLetterForSideOfImage' },
     1366    '0027,1053' => { VR => 'SH', Name => 'RASLetterForAnteriorPosterior' },
     1367    '0027,1054' => { VR => 'SH', Name => 'RASLetterForScoutStartLoc' },
     1368    '0027,1055' => { VR => 'SH', Name => 'RASLetterForScoutEndLoc' },
     1369    '0027,1060' => { VR => 'FL', Name => 'ImageDimensionX' },
     1370    '0027,1061' => { VR => 'FL', Name => 'ImageDimensionY' },
     1371    '0027,1062' => { VR => 'FL', Name => 'NumberOfExcitations' },
    9131372    # image presentation group
    9141373    '0028,0000' => { VR => 'UL', Name => 'ImagePresentationGroupLength' },
     
    9291388    '0028,0032' => { VR => 'DS', Name => 'ZoomCenter' },
    9301389    '0028,0034' => { VR => 'IS', Name => 'PixelAspectRatio' },
    931     '0028,0040' => { VR => 'RET',Name => 'ImageFormat' },
    932     '0028,0050' => { VR => 'RET',Name => 'ManipulatedImage' },
     1390    '0028,0040' => { VR => 'CS', Name => 'ImageFormat' },
     1391    '0028,0050' => { VR => 'LO', Name => 'ManipulatedImage' },
    9331392    '0028,0051' => { VR => 'CS', Name => 'CorrectedImage' },
    934     '0028,0060' => { VR => 'RET',Name => 'CompressionCode' },
     1393    '0028,005F' => { VR => 'LO', Name => 'CompressionRecognitionCode' },
     1394    '0028,0060' => { VR => 'CS', Name => 'CompressionCode' },
     1395    '0028,0061' => { VR => 'SH', Name => 'CompressionOriginator' },
     1396    '0028,0062' => { VR => 'LO', Name => 'CompressionLabel' },
     1397    '0028,0063' => { VR => 'SH', Name => 'CompressionDescription' },
     1398    '0028,0065' => { VR => 'CS', Name => 'CompressionSequence' },
     1399    '0028,0066' => { VR => 'AT', Name => 'CompressionStepPointers' },
     1400    '0028,0068' => { VR => 'US', Name => 'RepeatInterval' },
     1401    '0028,0069' => { VR => 'US', Name => 'BitsGrouped' },
     1402    '0028,0070' => { VR => 'US', Name => 'PerimeterTable' },
     1403    '0028,0071' => { VR => 'US', Name => 'PerimeterValue' },
     1404    '0028,0080' => { VR => 'US', Name => 'PredictorRows' },
     1405    '0028,0081' => { VR => 'US', Name => 'PredictorColumns' },
     1406    '0028,0082' => { VR => 'US', Name => 'PredictorConstants' },
     1407    '0028,0090' => { VR => 'CS', Name => 'BlockedPixels' },
     1408    '0028,0091' => { VR => 'US', Name => 'BlockRows' },
     1409    '0028,0092' => { VR => 'US', Name => 'BlockColumns' },
     1410    '0028,0093' => { VR => 'US', Name => 'RowOverlap' },
     1411    '0028,0094' => { VR => 'US', Name => 'ColumnOverlap' },
    9351412    '0028,0100' => { VR => 'US', Name => 'BitsAllocated' },
    9361413    '0028,0101' => { VR => 'US', Name => 'BitsStored' },
    9371414    '0028,0102' => { VR => 'US', Name => 'HighBit' },
    938     '0028,0103' => { VR => 'US', Name => 'PixelRepresentation' },
    939     '0028,0104' => { VR => 'RET',Name => 'SmallestValidPixelValue' },
    940     '0028,0105' => { VR => 'RET',Name => 'LargestValidPixelValue' },
    941     '0028,0106' => { VR => 'SS', Name => 'SmallestImagePixelValue' },
    942     '0028,0107' => { VR => 'SS', Name => 'LargestImagePixelValue' },
    943     '0028,0108' => { VR => 'SS', Name => 'SmallestPixelValueInSeries' },
    944     '0028,0109' => { VR => 'SS', Name => 'LargestPixelValueInSeries' },
    945     '0028,0110' => { VR => 'SS', Name => 'SmallestImagePixelValueInPlane' },
    946     '0028,0111' => { VR => 'SS', Name => 'LargestImagePixelValueInPlane' },
    947     '0028,0120' => { VR => 'SS', Name => 'PixelPaddingValue' },
    948     '0028,0200' => { VR => 'SS', Name => 'ImageLocation' },
     1415    '0028,0103' => { VR => 'US', Name => 'PixelRepresentation', PrintConv => { 0 => 'Unsigned', 1 => 'Signed' } },
     1416    '0028,0104' => { VR => 'US', Name => 'SmallestValidPixelValue' },
     1417    '0028,0105' => { VR => 'US', Name => 'LargestValidPixelValue' },
     1418    '0028,0106' => { VR => 'US', Name => 'SmallestImagePixelValue' },
     1419    '0028,0107' => { VR => 'US', Name => 'LargestImagePixelValue' },
     1420    '0028,0108' => { VR => 'US', Name => 'SmallestPixelValueInSeries' },
     1421    '0028,0109' => { VR => 'US', Name => 'LargestPixelValueInSeries' },
     1422    '0028,0110' => { VR => 'US', Name => 'SmallestImagePixelValueInPlane' },
     1423    '0028,0111' => { VR => 'US', Name => 'LargestImagePixelValueInPlane' },
     1424    '0028,0120' => { VR => 'US', Name => 'PixelPaddingValue' },
     1425    '0028,0121' => { VR => 'US', Name => 'PixelPaddingRangeLimit' },
     1426    '0028,0200' => { VR => 'US', Name => 'ImageLocation' },
    9491427    '0028,0300' => { VR => 'CS', Name => 'QualityControlImage' },
    9501428    '0028,0301' => { VR => 'CS', Name => 'BurnedInAnnotation' },
     1429    '0028,0400' => { VR => 'LO', Name => 'TransformLabel' },
     1430    '0028,0401' => { VR => 'LO', Name => 'TransformVersionNumber' },
     1431    '0028,0402' => { VR => 'US', Name => 'NumberOfTransformSteps' },
     1432    '0028,0403' => { VR => 'LO', Name => 'SequenceOfCompressedData' },
     1433    '0028,0404' => { VR => 'AT', Name => 'DetailsOfCoefficients' },
     1434    '0028,04x2' => { VR => 'LO', Name => 'CoefficientCoding' },
     1435    '0028,04x3' => { VR => 'AT', Name => 'CoefficientCodingPointers' },
     1436    '0028,0700' => { VR => 'LO', Name => 'DCTLabel' },
     1437    '0028,0701' => { VR => 'CS', Name => 'DataBlockDescription' },
     1438    '0028,0702' => { VR => 'AT', Name => 'DataBlock' },
     1439    '0028,0710' => { VR => 'US', Name => 'NormalizationFactorFormat' },
     1440    '0028,0720' => { VR => 'US', Name => 'ZonalMapNumberFormat' },
     1441    '0028,0721' => { VR => 'AT', Name => 'ZonalMapLocation' },
     1442    '0028,0722' => { VR => 'US', Name => 'ZonalMapFormat' },
     1443    '0028,0730' => { VR => 'US', Name => 'AdaptiveMapFormat' },
     1444    '0028,0740' => { VR => 'US', Name => 'CodeNumberFormat' },
     1445    '0028,08x0' => { VR => 'CS', Name => 'CodeLabel' },
     1446    '0028,08x2' => { VR => 'US', Name => 'NumberOfTables' },
     1447    '0028,08x3' => { VR => 'AT', Name => 'CodeTableLocation' },
     1448    '0028,08x4' => { VR => 'US', Name => 'BitsForCodeWord' },
     1449    '0028,08x8' => { VR => 'AT', Name => 'ImageDataLocation' },
     1450    '0028,1040' => { VR => 'CS', Name => 'PixelIntensityRelationship' },
     1451    '0028,0A02' => { VR => 'CS', Name => 'PixelSpacingCalibrationType' },
     1452    '0028,0A04' => { VR => 'LO', Name => 'PixelSpacingCalibrationDescription' },
    9511453    '0028,1040' => { VR => 'CS', Name => 'PixelIntensityRelationship' },
    9521454    '0028,1041' => { VR => 'SS', Name => 'PixelIntensityRelationshipSign' },
     
    9571459    '0028,1054' => { VR => 'LO', Name => 'RescaleType' },
    9581460    '0028,1055' => { VR => 'LO', Name => 'WindowCenterAndWidthExplanation' },
    959     '0028,1080' => { VR => 'RET',Name => 'GrayScale' },
     1461    '0028,1056' => { VR => 'CS', Name => 'VOI_LUTFunction' },
     1462    '0028,1080' => { VR => 'CS', Name => 'GrayScale' },
    9601463    '0028,1090' => { VR => 'CS', Name => 'RecommendedViewingMode' },
    961     '0028,1100' => { VR => 'RET',Name => 'GrayLookupTableDescriptor' },
     1464    '0028,1100' => { VR => 'SS', Name => 'GrayLookupTableDescriptor' },
    9621465    '0028,1101' => { VR => 'SS', Name => 'RedPaletteColorTableDescriptor' },
    9631466    '0028,1102' => { VR => 'SS', Name => 'GreenPaletteColorTableDescriptor' },
    9641467    '0028,1103' => { VR => 'SS', Name => 'BluePaletteColorTableDescriptor' },
     1468    '0028,1111' => { VR => 'SS', Name => 'LargeRedPaletteColorTableDescr' },
     1469    '0028,1112' => { VR => 'SS', Name => 'LargeGreenPaletteColorTableDescr' },
     1470    '0028,1113' => { VR => 'SS', Name => 'LargeBluePaletteColorTableDescr' },
    9651471    '0028,1199' => { VR => 'UI', Name => 'PaletteColorTableUID' },
    966     '0028,1200' => { VR => 'RET',Name => 'GrayLookupTableData' },
     1472    '0028,1200' => { VR => 'US', Name => 'GrayLookupTableData' },
    9671473    '0028,1201' => { VR => 'OW', Name => 'RedPaletteColorTableData' },
    9681474    '0028,1202' => { VR => 'OW', Name => 'GreenPaletteColorTableData' },
    9691475    '0028,1203' => { VR => 'OW', Name => 'BluePaletteColorTableData' },
     1476    '0028,1211' => { VR => 'OW', Name => 'LargeRedPaletteColorTableData', Binary => 1 },
     1477    '0028,1212' => { VR => 'OW', Name => 'LargeGreenPaletteColorTableData', Binary => 1 },
     1478    '0028,1213' => { VR => 'OW', Name => 'LargeBluePaletteColorTableData', Binary => 1 },
     1479    '0028,1214' => { VR => 'UI', Name => 'LargePaletteColorLookupTableUID' },
    9701480    '0028,1221' => { VR => 'OW', Name => 'SegmentedRedColorTableData' },
    9711481    '0028,1222' => { VR => 'OW', Name => 'SegmentedGreenColorTableData' },
    9721482    '0028,1223' => { VR => 'OW', Name => 'SegmentedBlueColorTableData' },
    973     '0028,1300' => { VR => 'CS', Name => 'ImplantPresent' },
     1483    '0028,1300' => { VR => 'CS', Name => 'BreastImplantPresent' },
    9741484    '0028,1350' => { VR => 'CS', Name => 'PartialView' },
    9751485    '0028,1351' => { VR => 'ST', Name => 'PartialViewDescription' },
     1486    '0028,1352' => { VR => 'SQ', Name => 'PartialViewCodeSequence' },
     1487    '0028,135A' => { VR => 'CS', Name => 'SpatialLocationsPreserved' },
     1488    '0028,1402' => { VR => 'CS', Name => 'DataPathAssignment' },
     1489    '0028,1404' => { VR => 'SQ', Name => 'BlendingLUT1Sequence' },
     1490    '0028,1406' => { VR => 'FD', Name => 'BlendingWeightConstant' },
     1491    '0028,1408' => { VR => 'OW', Name => 'BlendingLookupTableData' },
     1492    '0028,140C' => { VR => 'SQ', Name => 'BlendingLUT2Sequence' },
     1493    '0028,140E' => { VR => 'CS', Name => 'DataPathID' },
     1494    '0028,140F' => { VR => 'CS', Name => 'RGBLUTTransferFunction' },
     1495    '0028,1410' => { VR => 'CS', Name => 'AlphaLUTTransferFunction' },
     1496    '0028,2000' => { VR => 'OB', Name => 'ICCProfile' },
    9761497    '0028,2110' => { VR => 'CS', Name => 'LossyImageCompression' },
    9771498    '0028,2112' => { VR => 'DS', Name => 'LossyImageCompressionRatio' },
    9781499    '0028,2114' => { VR => 'CS', Name => 'LossyImageCompressionMethod' },
    9791500    '0028,3000' => { VR => 'SQ', Name => 'ModalityLUTSequence' },
    980     '0028,3002' => { VR => 'SS', Name => 'LUTDescriptor' },
     1501    '0028,3002' => { VR => 'US', Name => 'LUTDescriptor' },
    9811502    '0028,3003' => { VR => 'LO', Name => 'LUTExplanation' },
    9821503    '0028,3004' => { VR => 'LO', Name => 'ModalityLUTType' },
     
    9841505    '0028,3010' => { VR => 'SQ', Name => 'VOILUTSequence' },
    9851506    '0028,3110' => { VR => 'SQ', Name => 'SoftcopyVOILUTSequence' },
    986     '0028,4000' => { VR => 'RET',Name => 'ImagePresentationComments' },
     1507    '0028,4000' => { VR => 'LT', Name => 'ImagePresentationComments' },
    9871508    '0028,5000' => { VR => 'SQ', Name => 'BiPlaneAcquisitionSequence' },
    9881509    '0028,6010' => { VR => 'US', Name => 'RepresentativeFrameNumber' },
    989     '0028,6020' => { VR => 'US', Name => 'FrameNumbersOfInterestFOI' },
     1510    '0028,6020' => { VR => 'US', Name => 'FrameNumbersOfInterest' },
    9901511    '0028,6022' => { VR => 'LO', Name => 'FrameOfInterestDescription' },
    9911512    '0028,6023' => { VR => 'CS', Name => 'FrameOfInterestType' },
    992     '0028,6030' => { VR => 'RET',Name => 'MaskPointers' },
     1513    '0028,6030' => { VR => 'US', Name => 'MaskPointers' },
    9931514    '0028,6040' => { VR => 'US', Name => 'RWavePointer' },
    9941515    '0028,6100' => { VR => 'SQ', Name => 'MaskSubtractionSequence' },
     
    10001521    '0028,6120' => { VR => 'SS', Name => 'TIDOffset' },
    10011522    '0028,6190' => { VR => 'ST', Name => 'MaskOperationExplanation' },
     1523    '0028,7FE0' => { VR => 'UT', Name => 'PixelDataProviderURL' },
    10021524    '0028,9001' => { VR => 'UL', Name => 'DataPointRows' },
    10031525    '0028,9002' => { VR => 'UL', Name => 'DataPointColumns' },
     
    10091531    '0028,9145' => { VR => 'SQ', Name => 'PixelValueTransformationSequence' },
    10101532    '0028,9235' => { VR => 'CS', Name => 'SignalDomainRows' },
     1533    '0028,9411' => { VR => 'FL', Name => 'DisplayFilterPercentage' },
     1534    '0028,9415' => { VR => 'SQ', Name => 'FramePixelShiftSequence' },
     1535    '0028,9416' => { VR => 'US', Name => 'SubtractionItemID' },
     1536    '0028,9422' => { VR => 'SQ', Name => 'PixelIntensityRelationshipLUTSeq' },
     1537    '0028,9443' => { VR => 'SQ', Name => 'FramePixelDataPropertiesSequence' },
     1538    '0028,9444' => { VR => 'CS', Name => 'GeometricalProperties' },
     1539    '0028,9445' => { VR => 'FL', Name => 'GeometricMaximumDistortion' },
     1540    '0028,9446' => { VR => 'CS', Name => 'ImageProcessingApplied' },
     1541    '0028,9454' => { VR => 'CS', Name => 'MaskSelectionMode' },
     1542    '0028,9474' => { VR => 'CS', Name => 'LUTFunction' },
     1543    '0028,9478' => { VR => 'FL', Name => 'MaskVisibilityPercentage' },
     1544    '0028,9501' => { VR => 'SQ', Name => 'PixelShiftSequence' },
     1545    '0028,9502' => { VR => 'SQ', Name => 'RegionPixelShiftSequence' },
     1546    '0028,9503' => { VR => 'SS', Name => 'VerticesOfTheRegion' },
     1547    '0028,9506' => { VR => 'US', Name => 'PixelShiftFrameRange' },
     1548    '0028,9507' => { VR => 'US', Name => 'LUTFrameRange' },
     1549    '0028,9520' => { VR => 'DS', Name => 'ImageToEquipmentMappingMatrix' },
     1550    '0028,9537' => { VR => 'CS', Name => 'EquipmentCoordinateSystemID' },
     1551    # GEMS_IMPS_01 (ref 4)
     1552    '0029,1004' => { VR => 'SL', Name => 'LowerRangeOfPixels1a' },
     1553    '0029,1005' => { VR => 'DS', Name => 'LowerRangeOfPixels1b' },
     1554    '0029,1006' => { VR => 'DS', Name => 'LowerRangeOfPixels1c' },
     1555    '0029,1007' => { VR => 'SL', Name => 'LowerRangeOfPixels1d' },
     1556    '0029,1008' => { VR => 'SH', Name => 'LowerRangeOfPixels1e' },
     1557    '0029,1009' => { VR => 'SH', Name => 'LowerRangeOfPixels1f' },
     1558    '0029,100A' => { VR => 'SS', Name => 'LowerRangeOfPixels1g' },
     1559    '0029,1015' => { VR => 'SL', Name => 'LowerRangeOfPixels1h' },
     1560    '0029,1016' => { VR => 'SL', Name => 'LowerRangeOfPixels1i' },
     1561    '0029,1017' => { VR => 'SL', Name => 'LowerRangeOfPixels2' },
     1562    '0029,1018' => { VR => 'SL', Name => 'UpperRangeOfPixels2' },
     1563    '0029,101A' => { VR => 'SL', Name => 'LenOfTotHdrInBytes' },
     1564    '0029,1026' => { VR => 'SS', Name => 'VersionOfTheHdrStruct' },
     1565    '0029,1034' => { VR => 'SL', Name => 'AdvantageCompOverflow' },
     1566    '0029,1035' => { VR => 'SL', Name => 'AdvantageCompUnderflow' },
    10111567    # study group
    10121568    '0032,0000' => { VR => 'UL', Name => 'StudyGroupLength' },
     
    10551611    '0038,0044' => { VR => 'SQ', Name => 'DischargeDiagnosisCodeSequence' },
    10561612    '0038,0050' => { VR => 'LO', Name => 'SpecialNeeds' },
     1613    '0038,0060' => { VR => 'LO', Name => 'ServiceEpisodeID' },
     1614    '0038,0061' => { VR => 'LO', Name => 'IssuerOfServiceEpisodeID' },
     1615    '0038,0062' => { VR => 'LO', Name => 'ServiceEpisodeDescription' },
     1616    '0038,0100' => { VR => 'SQ', Name => 'PertinentDocumentsSequence' },
    10571617    '0038,0300' => { VR => 'LO', Name => 'CurrentPatientLocation' },
    1058     '0038,0400' => { VR => 'LO', Name => 'PatientsInstitutionResidence' },
     1618    '0038,0400' => { VR => 'LO', Name => 'PatientInstitutionResidence' },
    10591619    '0038,0500' => { VR => 'LO', Name => 'PatientState' },
     1620    '0038,0502' => { VR => 'SQ', Name => 'PatientClinicalTrialParticipSeq' },
    10601621    '0038,4000' => { VR => 'LT', Name => 'VisitComments' },
    10611622    '003A,0004' => { VR => 'CS', Name => 'WaveformOriginality' },
     
    10841645    '003A,0222' => { VR => 'DS', Name => 'NotchFilterFrequency' },
    10851646    '003A,0223' => { VR => 'DS', Name => 'NotchFilterBandwidth' },
     1647    '003A,0230' => { VR => 'FL', Name => 'WaveformDataDisplayScale' },
     1648    '003A,0231' => { VR => 'US', Name => 'WaveformDisplayBkgCIELabValue' },
     1649    '003A,0240' => { VR => 'SQ', Name => 'WaveformPresentationGroupSequence' },
     1650    '003A,0241' => { VR => 'US', Name => 'PresentationGroupNumber' },
     1651    '003A,0242' => { VR => 'SQ', Name => 'ChannelDisplaySequence' },
     1652    '003A,0244' => { VR => 'US', Name => 'ChannelRecommendDisplayCIELabValue' },
     1653    '003A,0245' => { VR => 'FL', Name => 'ChannelPosition' },
     1654    '003A,0246' => { VR => 'CS', Name => 'DisplayShadingFlag' },
     1655    '003A,0247' => { VR => 'FL', Name => 'FractionalChannelDisplayScale' },
     1656    '003A,0248' => { VR => 'FL', Name => 'AbsoluteChannelDisplayScale' },
    10861657    '003A,0300' => { VR => 'SQ', Name => 'MultiplexAudioChannelsDescrCodeSeq' },
    10871658    '003A,0301' => { VR => 'IS', Name => 'ChannelIdentificationCode' },
     
    11021673    '0040,0012' => { VR => 'LO', Name => 'PreMedication' },
    11031674    '0040,0020' => { VR => 'CS', Name => 'ScheduledProcedureStepStatus' },
     1675    '0040,0031' => { VR => 'UT', Name => 'LocalNamespaceEntityID' },
     1676    '0040,0032' => { VR => 'UT', Name => 'UniversalEntityID' },
     1677    '0040,0033' => { VR => 'CS', Name => 'UniversalEntityIDType' },
     1678    '0040,0035' => { VR => 'CS', Name => 'IdentifierTypeCode' },
     1679    '0040,0036' => { VR => 'SQ', Name => 'AssigningFacilitySequence' },
    11041680    '0040,0100' => { VR => 'SQ', Name => 'ScheduledProcedureStepSequence' },
    11051681    '0040,0220' => { VR => 'SQ', Name => 'ReferencedNonImageCompositeSOPSeq' },
     
    11161692    '0040,0255' => { VR => 'LO', Name => 'PerformedProcedureTypeDescription' },
    11171693    '0040,0260' => { VR => 'SQ', Name => 'PerformedProtocolCodeSequence' },
     1694    '0040,0261' => { VR => 'CS', Name => 'PerformedProtocolType' },
    11181695    '0040,0270' => { VR => 'SQ', Name => 'ScheduledStepAttributesSequence' },
    11191696    '0040,0275' => { VR => 'SQ', Name => 'RequestAttributesSequence' },
     
    11291706    '0040,0303' => { VR => 'US', Name => 'ExposedArea' },
    11301707    '0040,0306' => { VR => 'DS', Name => 'DistanceSourceToEntrance' },
    1131     '0040,0307' => { VR => 'RET',Name => 'DistanceSourceToSupport' },
     1708    '0040,0307' => { VR => 'DS', Name => 'DistanceSourceToSupport' },
    11321709    '0040,030E' => { VR => 'SQ', Name => 'ExposureDoseSequence' },
    11331710    '0040,0310' => { VR => 'ST', Name => 'CommentsOnRadiationDose' },
     
    11391716    '0040,0321' => { VR => 'SQ', Name => 'FilmConsumptionSequence' },
    11401717    '0040,0324' => { VR => 'SQ', Name => 'BillingSuppliesAndDevicesSequence' },
    1141     '0040,0330' => { VR => 'RET',Name => 'ReferencedProcedureStepSequence' },
     1718    '0040,0330' => { VR => 'SQ', Name => 'ReferencedProcedureStepSequence' },
    11421719    '0040,0340' => { VR => 'SQ', Name => 'PerformedSeriesSequence' },
    11431720    '0040,0400' => { VR => 'LT', Name => 'CommentsOnScheduledProcedureStep' },
     
    11451722    '0040,0441' => { VR => 'SQ', Name => 'ContentItemModifierSequence' },
    11461723    '0040,050A' => { VR => 'LO', Name => 'SpecimenAccessionNumber' },
     1724    '0040,0512' => { VR => 'LO', Name => 'ContainerIdentifier' },
     1725    '0040,051A' => { VR => 'LO', Name => 'ContainerDescription' },
    11471726    '0040,0550' => { VR => 'SQ', Name => 'SpecimenSequence' },
    11481727    '0040,0551' => { VR => 'LO', Name => 'SpecimenIdentifier' },
     1728    '0040,0552' => { VR => 'SQ', Name => 'SpecimenDescriptionSequenceTrial' },
     1729    '0040,0553' => { VR => 'ST', Name => 'SpecimenDescriptionTrial' },
     1730    '0040,0554' => { VR => 'UI', Name => 'SpecimenUID' },
    11491731    '0040,0555' => { VR => 'SQ', Name => 'AcquisitionContextSequence' },
    11501732    '0040,0556' => { VR => 'ST', Name => 'AcquisitionContextDescription' },
    11511733    '0040,059A' => { VR => 'SQ', Name => 'SpecimenTypeCodeSequence' },
     1734    '0040,0600' => { VR => 'LO', Name => 'SpecimenShortDescription' },
    11521735    '0040,06FA' => { VR => 'LO', Name => 'SlideIdentifier' },
    11531736    '0040,071A' => { VR => 'SQ', Name => 'ImageCenterPointCoordinatesSeq' },
     
    11581741    '0040,08DA' => { VR => 'SQ', Name => 'CoordinateSystemAxisCodeSequence' },
    11591742    '0040,08EA' => { VR => 'SQ', Name => 'MeasurementUnitsCodeSequence' },
     1743    '0040,09F8' => { VR => 'SQ', Name => 'VitalStainCodeSequenceTrial' },
    11601744    '0040,1001' => { VR => 'SH', Name => 'RequestedProcedureID' },
    11611745    '0040,1002' => { VR => 'LO', Name => 'ReasonForRequestedProcedure' },
     
    11631747    '0040,1004' => { VR => 'LO', Name => 'PatientTransportArrangements' },
    11641748    '0040,1005' => { VR => 'LO', Name => 'RequestedProcedureLocation' },
    1165     '0040,1006' => { VR => 'RET',Name => 'PlacerOrderNumber-Procedure' },
    1166     '0040,1007' => { VR => 'RET',Name => 'FillerOrderNumber-Procedure' },
     1749    '0040,1006' => { VR => 'SH', Name => 'PlacerOrderNumber-Procedure' },
     1750    '0040,1007' => { VR => 'SH', Name => 'FillerOrderNumber-Procedure' },
    11671751    '0040,1008' => { VR => 'LO', Name => 'ConfidentialityCode' },
    11681752    '0040,1009' => { VR => 'SH', Name => 'ReportingPriority' },
     
    11711755    '0040,1011' => { VR => 'SQ', Name => 'IntendedRecipientsOfResultsIDSeq' },
    11721756    '0040,1101' => { VR => 'SQ', Name => 'PersonIdentificationCodeSequence' },
    1173     '0040,1102' => { VR => 'ST', Name => 'PersonsAddress' },
    1174     '0040,1103' => { VR => 'LO', Name => 'PersonsTelephoneNumbers' },
     1757    '0040,1102' => { VR => 'ST', Name => 'PersonAddress' },
     1758    '0040,1103' => { VR => 'LO', Name => 'PersonTelephoneNumbers' },
    11751759    '0040,1400' => { VR => 'LT', Name => 'RequestedProcedureComments' },
    1176     '0040,2001' => { VR => 'RET',Name => 'ReasonForImagingServiceRequest' },
     1760    '0040,2001' => { VR => 'LO', Name => 'ReasonForImagingServiceRequest' },
    11771761    '0040,2004' => { VR => 'DA', Name => 'IssueDateOfImagingServiceRequest' },
    11781762    '0040,2005' => { VR => 'TM', Name => 'IssueTimeOfImagingServiceRequest' },
    1179     '0040,2006' => { VR => 'RET',Name => 'PlacerOrderNum-ImagingServiceReq' },
    1180     '0040,2007' => { VR => 'RET',Name => 'FillerOrderNum-ImagingServiceReq' },
     1763    '0040,2006' => { VR => 'SH', Name => 'PlacerOrderNum-ImagingServiceReq' },
     1764    '0040,2007' => { VR => 'SH', Name => 'FillerOrderNum-ImagingServiceReq' },
    11811765    '0040,2008' => { VR => 'PN', Name => 'OrderEnteredBy' },
    1182     '0040,2009' => { VR => 'SH', Name => 'OrderEnterersLocation' },
     1766    '0040,2009' => { VR => 'SH', Name => 'OrderEntererLocation' },
    11831767    '0040,2010' => { VR => 'SH', Name => 'OrderCallbackPhoneNumber' },
    11841768    '0040,2016' => { VR => 'LO', Name => 'PlacerOrderNum-ImagingServiceReq' },
     
    12161800    '0040,4035' => { VR => 'SQ', Name => 'ActualHumanPerformersSequence' },
    12171801    '0040,4036' => { VR => 'LO', Name => 'HumanPerformersOrganization' },
    1218     '0040,4037' => { VR => 'PN', Name => 'HumanPerformersName' },
     1802    '0040,4037' => { VR => 'PN', Name => 'HumanPerformerName' },
     1803    '0040,4040' => { VR => 'CS', Name => 'RawDataHandling' },
    12191804    '0040,8302' => { VR => 'DS', Name => 'EntranceDoseInMilliGy' },
     1805    '0040,9094' => { VR => 'SQ', Name => 'RefImageRealWorldValueMappingSeq' },
    12201806    '0040,9096' => { VR => 'SQ', Name => 'RealWorldValueMappingSequence' },
     1807    '0040,9098' => { VR => 'SQ', Name => 'PixelValueMappingCodeSequence' },
    12211808    '0040,9210' => { VR => 'SH', Name => 'LUTLabel' },
    12221809    '0040,9211' => { VR => 'SS', Name => 'RealWorldValueLastValueMapped' },
     
    12341821    '0040,A073' => { VR => 'SQ', Name => 'VerifyingObserverSequence' },
    12351822    '0040,A075' => { VR => 'PN', Name => 'VerifyingObserverName' },
     1823    '0040,A078' => { VR => 'SQ', Name => 'AuthorObserverSequence' },
     1824    '0040,A07A' => { VR => 'SQ', Name => 'ParticipantSequence' },
     1825    '0040,A07C' => { VR => 'SQ', Name => 'CustodialOrganizationSequence' },
     1826    '0040,A080' => { VR => 'CS', Name => 'ParticipationType' },
     1827    '0040,A082' => { VR => 'DT', Name => 'ParticipationDateTime' },
     1828    '0040,A084' => { VR => 'CS', Name => 'ObserverType' },
    12361829    '0040,A088' => { VR => 'SQ', Name => 'VerifyingObserverIdentCodeSequence' },
     1830    '0040,A090' => { VR => 'SQ', Name => 'EquivalentCDADocumentSequence' },
    12371831    '0040,A0B0' => { VR => 'US', Name => 'ReferencedWaveformChannels' },
    12381832    '0040,A120' => { VR => 'DT', Name => 'DateTime' },
     
    12451839    '0040,A136' => { VR => 'US', Name => 'ReferencedFrameNumbers' },
    12461840    '0040,A138' => { VR => 'DS', Name => 'ReferencedTimeOffsets' },
    1247     '0040,A13A' => { VR => 'DT', Name => 'ReferencedDatetime' },
     1841    '0040,A13A' => { VR => 'DT', Name => 'ReferencedDateTime' },
    12481842    '0040,A160' => { VR => 'UT', Name => 'TextValue' },
    12491843    '0040,A168' => { VR => 'SQ', Name => 'ConceptCodeSequence' },
     
    12541848    '0040,A301' => { VR => 'SQ', Name => 'NumericValueQualifierCodeSequence' },
    12551849    '0040,A30A' => { VR => 'DS', Name => 'NumericValue' },
     1850    '0040,A353' => { VR => 'ST', Name => 'AddressTrial' },
     1851    '0040,A354' => { VR => 'LO', Name => 'TelephoneNumberTrial' },
    12561852    '0040,A360' => { VR => 'SQ', Name => 'PredecessorDocumentsSequence' },
    12571853    '0040,A370' => { VR => 'SQ', Name => 'ReferencedRequestSequence' },
     
    12591855    '0040,A375' => { VR => 'SQ', Name => 'CurrentRequestedProcEvidenceSeq' },
    12601856    '0040,A385' => { VR => 'SQ', Name => 'PertinentOtherEvidenceSequence' },
     1857    '0040,A390' => { VR => 'SQ', Name => 'HL7StructuredDocumentRefSeq' },
    12611858    '0040,A491' => { VR => 'CS', Name => 'CompletionFlag' },
    12621859    '0040,A492' => { VR => 'LO', Name => 'CompletionFlagDescription' },
    12631860    '0040,A493' => { VR => 'CS', Name => 'VerificationFlag' },
     1861    '0040,A494' => { VR => 'CS', Name => 'ArchiveRequested' },
     1862    '0040,A496' => { VR => 'CS', Name => 'PreliminaryFlag' },
    12641863    '0040,A504' => { VR => 'SQ', Name => 'ContentTemplateSequence' },
    12651864    '0040,A525' => { VR => 'SQ', Name => 'IdenticalDocumentsSequence' },
     
    12671866    '0040,B020' => { VR => 'SQ', Name => 'AnnotationSequence' },
    12681867    '0040,DB00' => { VR => 'CS', Name => 'TemplateIdentifier' },
    1269     '0040,DB06' => { VR => 'RET',Name => 'TemplateVersion' },
    1270     '0040,DB07' => { VR => 'RET',Name => 'TemplateLocalVersion' },
    1271     '0040,DB0B' => { VR => 'RET',Name => 'TemplateExtensionFlag' },
    1272     '0040,DB0C' => { VR => 'RET',Name => 'TemplateExtensionOrganizationUID' },
    1273     '0040,DB0D' => { VR => 'RET',Name => 'TemplateExtensionCreatorUID' },
     1868    '0040,DB06' => { VR => 'DT', Name => 'TemplateVersion' },
     1869    '0040,DB07' => { VR => 'DT', Name => 'TemplateLocalVersion' },
     1870    '0040,DB0B' => { VR => 'CS', Name => 'TemplateExtensionFlag' },
     1871    '0040,DB0C' => { VR => 'UI', Name => 'TemplateExtensionOrganizationUID' },
     1872    '0040,DB0D' => { VR => 'UI', Name => 'TemplateExtensionCreatorUID' },
    12741873    '0040,DB73' => { VR => 'UL', Name => 'ReferencedContentItemIdentifier' },
     1874    '0040,E001' => { VR => 'ST', Name => 'HL7InstanceIdentifier' },
     1875    '0040,E004' => { VR => 'DT', Name => 'HL7DocumentEffectiveTime' },
     1876    '0040,E006' => { VR => 'SQ', Name => 'HL7DocumentTypeCodeSequence' },
     1877    '0040,E010' => { VR => 'UT', Name => 'RetrieveURI' },
     1878    '0040,E011' => { VR => 'UI', Name => 'RetrieveLocationUID' },
     1879    '0042,0010' => { VR => 'ST', Name => 'DocumentTitle' },
     1880    '0042,0011' => { VR => 'OB', Name => 'EncapsulatedDocument' },
     1881    '0042,0012' => { VR => 'LO', Name => 'MIMETypeOfEncapsulatedDocument' },
     1882    '0042,0013' => { VR => 'SQ', Name => 'SourceInstanceSequence' },
     1883    '0042,0014' => { VR => 'LO', Name => 'ListOfMIMETypes' },
     1884    # GEMS_PARM_01 (ref 4)
     1885    '0043,1001' => { VR => 'SS', Name => 'BitmapOfPrescanOptions' },
     1886    '0043,1002' => { VR => 'SS', Name => 'GradientOffsetInX' },
     1887    '0043,1003' => { VR => 'SS', Name => 'GradientOffsetInY' },
     1888    '0043,1004' => { VR => 'SS', Name => 'GradientOffsetInZ' },
     1889    '0043,1005' => { VR => 'SS', Name => 'ImgIsOriginalOrUnoriginal' },
     1890    '0043,1006' => { VR => 'SS', Name => 'NumberOfEPIShots' },
     1891    '0043,1007' => { VR => 'SS', Name => 'ViewsPerSegment' },
     1892    '0043,1008' => { VR => 'SS', Name => 'RespiratoryRateBpm' },
     1893    '0043,1009' => { VR => 'SS', Name => 'RespiratoryTriggerPoint' },
     1894    '0043,100A' => { VR => 'SS', Name => 'TypeOfReceiverUsed' },
     1895    '0043,100B' => { VR => 'DS', Name => 'PeakRateOfChangeOfGradientField' },
     1896    '0043,100C' => { VR => 'DS', Name => 'LimitsInUnitsOfPercent' },
     1897    '0043,100D' => { VR => 'DS', Name => 'PSDEstimatedLimit' },
     1898    '0043,100E' => { VR => 'DS', Name => 'PSDEstimatedLimitInTeslaPerSecond' },
     1899    '0043,100F' => { VR => 'DS', Name => 'Saravghead' },
     1900    '0043,1010' => { VR => 'US', Name => 'WindowValue' },
     1901    '0043,1011' => { VR => 'US', Name => 'TotalInputViews' },
     1902    '0043,1012' => { VR => 'SS', Name => 'X-RayChain' },
     1903    '0043,1013' => { VR => 'SS', Name => 'DeconKernelParameters' },
     1904    '0043,1014' => { VR => 'SS', Name => 'CalibrationParameters' },
     1905    '0043,1015' => { VR => 'SS', Name => 'TotalOutputViews' },
     1906    '0043,1016' => { VR => 'SS', Name => 'NumberOfOverranges' },
     1907    '0043,1017' => { VR => 'DS', Name => 'IBHImageScaleFactors' },
     1908    '0043,1018' => { VR => 'DS', Name => 'BBHCoefficients' },
     1909    '0043,1019' => { VR => 'SS', Name => 'NumberOfBBHChainsToBlend' },
     1910    '0043,101A' => { VR => 'SL', Name => 'StartingChannelNumber' },
     1911    '0043,101B' => { VR => 'SS', Name => 'PpscanParameters' },
     1912    '0043,101C' => { VR => 'SS', Name => 'GEImageIntegrity' },
     1913    '0043,101D' => { VR => 'SS', Name => 'LevelValue' },
     1914    '0043,101E' => { VR => 'DS', Name => 'DeltaStartTime' },
     1915    '0043,101F' => { VR => 'SL', Name => 'MaxOverrangesInAView' },
     1916    '0043,1020' => { VR => 'DS', Name => 'AvgOverrangesAllViews' },
     1917    '0043,1021' => { VR => 'SS', Name => 'CorrectedAfterGlowTerms' },
     1918    '0043,1025' => { VR => 'SS', Name => 'ReferenceChannels' },
     1919    '0043,1026' => { VR => 'US', Name => 'NoViewsRefChansBlocked' },
     1920    '0043,1027' => { VR => 'SH', Name => 'ScanPitchRatio' },
     1921    '0043,1028' => { VR => 'OB', Name => 'UniqueImageIden' },
     1922    '0043,1029' => { VR => 'OB', Name => 'HistogramTables' },
     1923    '0043,102A' => { VR => 'OB', Name => 'UserDefinedData' },
     1924    '0043,102B' => { VR => 'SS', Name => 'PrivateScanOptions' },
     1925    '0043,102C' => { VR => 'SS', Name => 'EffectiveEchoSpacing' },
     1926    '0043,102D' => { VR => 'SH', Name => 'StringSlopField1' },
     1927    '0043,102E' => { VR => 'SH', Name => 'StringSlopField2' },
     1928    '0043,102F' => { VR => 'SS', Name => 'RawDataType' },
     1929    '0043,1030' => { VR => 'SS', Name => 'RawDataType' },
     1930    '0043,1031' => { VR => 'DS', Name => 'RACordOfTargetReconCenter' },
     1931    '0043,1032' => { VR => 'SS', Name => 'RawDataType' },
     1932    '0043,1033' => { VR => 'FL', Name => 'NegScanspacing' },
     1933    '0043,1034' => { VR => 'IS', Name => 'OffsetFrequency' },
     1934    '0043,1035' => { VR => 'UL', Name => 'UserUsageTag' },
     1935    '0043,1036' => { VR => 'UL', Name => 'UserFillMapMSW' },
     1936    '0043,1037' => { VR => 'UL', Name => 'UserFillMapLSW' },
     1937    '0043,1038' => { VR => 'FL', Name => 'User25-48' },
     1938    '0043,1039' => { VR => 'IS', Name => 'SlopInt6-9' },
     1939    '0043,1040' => { VR => 'FL', Name => 'TriggerOnPosition' },
     1940    '0043,1041' => { VR => 'FL', Name => 'DegreeOfRotation' },
     1941    '0043,1042' => { VR => 'SL', Name => 'DASTriggerSource' },
     1942    '0043,1043' => { VR => 'SL', Name => 'DASFpaGain' },
     1943    '0043,1044' => { VR => 'SL', Name => 'DASOutputSource' },
     1944    '0043,1045' => { VR => 'SL', Name => 'DASAdInput' },
     1945    '0043,1046' => { VR => 'SL', Name => 'DASCalMode' },
     1946    '0043,1047' => { VR => 'SL', Name => 'DASCalFrequency' },
     1947    '0043,1048' => { VR => 'SL', Name => 'DASRegXm' },
     1948    '0043,1049' => { VR => 'SL', Name => 'DASAutoZero' },
     1949    '0043,104A' => { VR => 'SS', Name => 'StartingChannelOfView' },
     1950    '0043,104B' => { VR => 'SL', Name => 'DASXmPattern' },
     1951    '0043,104C' => { VR => 'SS', Name => 'TGGCTriggerMode' },
     1952    '0043,104D' => { VR => 'FL', Name => 'StartScanToXrayOnDelay' },
     1953    '0043,104E' => { VR => 'FL', Name => 'DurationOfXrayOn' },
     1954    '0043,1060' => { VR => 'IS', Name => 'SlopInt10-17' },
     1955    '0043,1061' => { VR => 'UI', Name => 'ScannerStudyEntityUID' },
     1956    '0043,1062' => { VR => 'SH', Name => 'ScannerStudyID' },
     1957    '0043,106f' => { VR => 'DS', Name => 'ScannerTableEntry' },
     1958    # ?
     1959    '0044,0001' => { VR => 'ST', Name => 'ProductPackageIdentifier' },
     1960    '0044,0002' => { VR => 'CS', Name => 'SubstanceAdministrationApproval' },
     1961    '0044,0003' => { VR => 'LT', Name => 'ApprovalStatusFurtherDescription' },
     1962    '0044,0004' => { VR => 'DT', Name => 'ApprovalStatusDateTime' },
     1963    '0044,0007' => { VR => 'SQ', Name => 'ProductTypeCodeSequence' },
     1964    '0044,0008' => { VR => 'LO', Name => 'ProductName' },
     1965    '0044,0009' => { VR => 'LT', Name => 'ProductDescription' },
     1966    '0044,000A' => { VR => 'LO', Name => 'ProductLotIdentifier' },
     1967    '0044,000B' => { VR => 'DT', Name => 'ProductExpirationDateTime' },
     1968    '0044,0010' => { VR => 'DT', Name => 'SubstanceAdministrationDateTime' },
     1969    '0044,0011' => { VR => 'LO', Name => 'SubstanceAdministrationNotes' },
     1970    '0044,0012' => { VR => 'LO', Name => 'SubstanceAdministrationDeviceID' },
     1971    '0044,0013' => { VR => 'SQ', Name => 'ProductParameterSequence' },
     1972    '0044,0019' => { VR => 'SQ', Name => 'SubstanceAdminParameterSeq' },
     1973    # GEMS_HELIOS_01 (ref 4)
     1974    '0045,1001' => { VR => 'LO', Name => 'NumberOfMacroRowsInDetector' },
     1975    '0045,1002' => { VR => 'FL', Name => 'MacroWidthAtISOCenter' },
     1976    '0045,1003' => { VR => 'SS', Name => 'DASType' },
     1977    '0045,1004' => { VR => 'SS', Name => 'DASGain' },
     1978    '0045,1005' => { VR => 'SS', Name => 'DASTemperature' },
     1979    '0045,1006' => { VR => 'CS', Name => 'TableDirectionInOrOut' },
     1980    '0045,1007' => { VR => 'FL', Name => 'ZSmoothingFactor' },
     1981    '0045,1008' => { VR => 'SS', Name => 'ViewWeightingMode' },
     1982    '0045,1009' => { VR => 'SS', Name => 'SigmaRowNumberWhichRowsWereUsed' },
     1983    '0045,100A' => { VR => 'FL', Name => 'MinimumDasValueFoundInTheScanData' },
     1984    '0045,100B' => { VR => 'FL', Name => 'MaximumOffsetShiftValueUsed' },
     1985    '0045,100C' => { VR => 'SS', Name => 'NumberOfViewsShifted' },
     1986    '0045,100D' => { VR => 'SS', Name => 'ZTrackingFlag' },
     1987    '0045,100E' => { VR => 'FL', Name => 'MeanZError' },
     1988    '0045,100F' => { VR => 'FL', Name => 'ZTrackingMaximumError' },
     1989    '0045,1010' => { VR => 'SS', Name => 'StartingViewForRow2a' },
     1990    '0045,1011' => { VR => 'SS', Name => 'NumberOfViewsInRow2a' },
     1991    '0045,1012' => { VR => 'SS', Name => 'StartingViewForRow1a' },
     1992    '0045,1013' => { VR => 'SS', Name => 'SigmaMode' },
     1993    '0045,1014' => { VR => 'SS', Name => 'NumberOfViewsInRow1a' },
     1994    '0045,1015' => { VR => 'SS', Name => 'StartingViewForRow2b' },
     1995    '0045,1016' => { VR => 'SS', Name => 'NumberOfViewsInRow2b' },
     1996    '0045,1017' => { VR => 'SS', Name => 'StartingViewForRow1b' },
     1997    '0045,1018' => { VR => 'SS', Name => 'NumberOfViewsInRow1b' },
     1998    '0045,1019' => { VR => 'SS', Name => 'AirFilterCalibrationDate' },
     1999    '0045,101A' => { VR => 'SS', Name => 'AirFilterCalibrationTime' },
     2000    '0045,101B' => { VR => 'SS', Name => 'PhantomCalibrationDate' },
     2001    '0045,101C' => { VR => 'SS', Name => 'PhantomCalibrationTime' },
     2002    '0045,101D' => { VR => 'SS', Name => 'ZSlopeCalibrationDate' },
     2003    '0045,101E' => { VR => 'SS', Name => 'ZSlopeCalibrationTime' },
     2004    '0045,101F' => { VR => 'SS', Name => 'CrosstalkCalibrationDate' },
     2005    '0045,1020' => { VR => 'SS', Name => 'CrosstalkCalibrationTime' },
     2006    '0045,1021' => { VR => 'SS', Name => 'IterboneOptionFlag' },
     2007    '0045,1022' => { VR => 'SS', Name => 'PeristalticFlagOption' },
     2008    '0046,0012' => { VR => 'LO', Name => 'LensDescription' },
     2009    '0046,0014' => { VR => 'SQ', Name => 'RightLensSequence' },
     2010    '0046,0015' => { VR => 'SQ', Name => 'LeftLensSequence' },
     2011    '0046,0018' => { VR => 'SQ', Name => 'CylinderSequence' },
     2012    '0046,0028' => { VR => 'SQ', Name => 'PrismSequence' },
     2013    '0046,0030' => { VR => 'FD', Name => 'HorizontalPrismPower' },
     2014    '0046,0032' => { VR => 'CS', Name => 'HorizontalPrismBase' },
     2015    '0046,0034' => { VR => 'FD', Name => 'VerticalPrismPower' },
     2016    '0046,0036' => { VR => 'CS', Name => 'VerticalPrismBase' },
     2017    '0046,0038' => { VR => 'CS', Name => 'LensSegmentType' },
     2018    '0046,0040' => { VR => 'FD', Name => 'OpticalTransmittance' },
     2019    '0046,0042' => { VR => 'FD', Name => 'ChannelWidth' },
     2020    '0046,0044' => { VR => 'FD', Name => 'PupilSize' },
     2021    '0046,0046' => { VR => 'FD', Name => 'CornealSize' },
     2022    '0046,0060' => { VR => 'FD', Name => 'DistancePupillaryDistance' },
     2023    '0046,0062' => { VR => 'FD', Name => 'NearPupillaryDistance' },
     2024    '0046,0064' => { VR => 'FD', Name => 'OtherPupillaryDistance' },
     2025    '0046,0075' => { VR => 'FD', Name => 'RadiusOfCurvature' },
     2026    '0046,0076' => { VR => 'FD', Name => 'KeratometricPower' },
     2027    '0046,0077' => { VR => 'FD', Name => 'KeratometricAxis' },
     2028    '0046,0092' => { VR => 'CS', Name => 'BackgroundColor' },
     2029    '0046,0094' => { VR => 'CS', Name => 'Optotype' },
     2030    '0046,0095' => { VR => 'CS', Name => 'OptotypePresentation' },
     2031    '0046,0100' => { VR => 'SQ', Name => 'AddNearSequence' },
     2032    '0046,0101' => { VR => 'SQ', Name => 'AddIntermediateSequence' },
     2033    '0046,0102' => { VR => 'SQ', Name => 'AddOtherSequence' },
     2034    '0046,0104' => { VR => 'FD', Name => 'AddPower' },
     2035    '0046,0106' => { VR => 'FD', Name => 'ViewingDistance' },
     2036    '0046,0125' => { VR => 'CS', Name => 'ViewingDistanceType' },
     2037    '0046,0135' => { VR => 'SS', Name => 'VisualAcuityModifiers' },
     2038    '0046,0137' => { VR => 'FD', Name => 'DecimalVisualAcuity' },
     2039    '0046,0139' => { VR => 'LO', Name => 'OptotypeDetailedDefinition' },
     2040    '0046,0146' => { VR => 'FD', Name => 'SpherePower' },
     2041    '0046,0147' => { VR => 'FD', Name => 'CylinderPower' },
    12752042    # calibration group
    12762043    '0050,0004' => { VR => 'CS', Name => 'CalibrationImage' },
    12772044    '0050,0010' => { VR => 'SQ', Name => 'DeviceSequence' },
    12782045    '0050,0014' => { VR => 'DS', Name => 'DeviceLength' },
     2046    '0050,0015' => { VR => 'FD', Name => 'ContainerComponentWidth' },
    12792047    '0050,0016' => { VR => 'DS', Name => 'DeviceDiameter' },
    12802048    '0050,0017' => { VR => 'CS', Name => 'DeviceDiameterUnits' },
    12812049    '0050,0018' => { VR => 'DS', Name => 'DeviceVolume' },
    12822050    '0050,0019' => { VR => 'DS', Name => 'InterMarkerDistance' },
     2051    '0050,001B' => { VR => 'LO', Name => 'ContainerComponentID' },
    12832052    '0050,0020' => { VR => 'LO', Name => 'DeviceDescription' },
    12842053    # nuclear acquisition group
     
    13642133    '0060,3000' => { VR => 'SQ', Name => 'HistogramSequence' },
    13652134    '0060,3002' => { VR => 'US', Name => 'HistogramNumberOfBins' },
    1366     '0060,3004' => { VR => 'SS', Name => 'HistogramFirstBinValue' },
    1367     '0060,3006' => { VR => 'SS', Name => 'HistogramLastBinValue' },
     2135    '0060,3004' => { VR => 'US', Name => 'HistogramFirstBinValue' },
     2136    '0060,3006' => { VR => 'US', Name => 'HistogramLastBinValue' },
    13682137    '0060,3008' => { VR => 'US', Name => 'HistogramBinWidth' },
    13692138    '0060,3010' => { VR => 'LO', Name => 'HistogramExplanation' },
    13702139    '0060,3020' => { VR => 'UL', Name => 'HistogramData' },
     2140    '0062,0001' => { VR => 'CS', Name => 'SegmentationType' },
     2141    '0062,0002' => { VR => 'SQ', Name => 'SegmentSequence' },
     2142    '0062,0003' => { VR => 'SQ', Name => 'SegmentedPropertyCategoryCodeSeq' },
     2143    '0062,0004' => { VR => 'US', Name => 'SegmentNumber' },
     2144    '0062,0005' => { VR => 'LO', Name => 'SegmentLabel' },
     2145    '0062,0006' => { VR => 'ST', Name => 'SegmentDescription' },
     2146    '0062,0008' => { VR => 'CS', Name => 'SegmentAlgorithmType' },
     2147    '0062,0009' => { VR => 'LO', Name => 'SegmentAlgorithmName' },
     2148    '0062,000A' => { VR => 'SQ', Name => 'SegmentIdentificationSequence' },
     2149    '0062,000B' => { VR => 'US', Name => 'ReferencedSegmentNumber' },
     2150    '0062,000C' => { VR => 'US', Name => 'RecommendedDisplayGrayscaleValue' },
     2151    '0062,000D' => { VR => 'US', Name => 'RecommendedDisplayCIELabValue' },
     2152    '0062,000E' => { VR => 'US', Name => 'MaximumFractionalValue' },
     2153    '0062,000F' => { VR => 'SQ', Name => 'SegmentedPropertyTypeCodeSequence' },
     2154    '0062,0010' => { VR => 'CS', Name => 'SegmentationFractionalType' },
     2155    '0064,0002' => { VR => 'SQ', Name => 'DeformableRegistrationSequence' },
     2156    '0064,0003' => { VR => 'UI', Name => 'SourceFrameOfReferenceUID' },
     2157    '0064,0005' => { VR => 'SQ', Name => 'DeformableRegistrationGridSequence' },
     2158    '0064,0007' => { VR => 'UL', Name => 'GridDimensions' },
     2159    '0064,0008' => { VR => 'FD', Name => 'GridResolution' },
     2160    '0064,0009' => { VR => 'OF', Name => 'VectorGridData' },
     2161    '0064,000F' => { VR => 'SQ', Name => 'PreDeformationMatrixRegistSeq' },
     2162    '0064,0010' => { VR => 'SQ', Name => 'PostDeformationMatrixRegistSeq' },
     2163    '0066,0001' => { VR => 'UL', Name => 'NumberOfSurfaces' },
     2164    '0066,0002' => { VR => 'SQ', Name => 'SurfaceSequence' },
     2165    '0066,0003' => { VR => 'UL', Name => 'SurfaceNumber' },
     2166    '0066,0004' => { VR => 'LT', Name => 'SurfaceComments' },
     2167    '0066,0009' => { VR => 'CS', Name => 'SurfaceProcessing' },
     2168    '0066,000A' => { VR => 'FL', Name => 'SurfaceProcessingRatio' },
     2169    '0066,000E' => { VR => 'CS', Name => 'FiniteVolume' },
     2170    '0066,0010' => { VR => 'CS', Name => 'Manifold' },
     2171    '0066,0011' => { VR => 'SQ', Name => 'SurfacePointsSequence' },
     2172    '0066,0015' => { VR => 'UL', Name => 'NumberOfSurfacePoints' },
     2173    '0066,0016' => { VR => 'OF', Name => 'PointCoordinatesData' },
     2174    '0066,0017' => { VR => 'FL', Name => 'PointPositionAccuracy' },
     2175    '0066,0018' => { VR => 'FL', Name => 'MeanPointDistance' },
     2176    '0066,0019' => { VR => 'FL', Name => 'MaximumPointDistance' },
     2177    '0066,001B' => { VR => 'FL', Name => 'AxisOfRotation' },
     2178    '0066,001C' => { VR => 'FL', Name => 'CenterOfRotation' },
     2179    '0066,001E' => { VR => 'UL', Name => 'NumberOfVectors' },
     2180    '0066,001F' => { VR => 'US', Name => 'VectorDimensionality' },
     2181    '0066,0020' => { VR => 'FL', Name => 'VectorAccuracy' },
     2182    '0066,0021' => { VR => 'OF', Name => 'VectorCoordinateData' },
     2183    '0066,0023' => { VR => 'OW', Name => 'TrianglePointIndexList' },
     2184    '0066,0024' => { VR => 'OW', Name => 'EdgePointIndexList' },
     2185    '0066,0025' => { VR => 'OW', Name => 'VertexPointIndexList' },
     2186    '0066,0026' => { VR => 'SQ', Name => 'TriangleStripSequence' },
     2187    '0066,0027' => { VR => 'SQ', Name => 'TriangleFanSequence' },
     2188    '0066,0028' => { VR => 'SQ', Name => 'LineSequence' },
     2189    '0066,0029' => { VR => 'OW', Name => 'PrimitivePointIndexList' },
     2190    '0066,002A' => { VR => 'UL', Name => 'SurfaceCount' },
     2191    '0066,002F' => { VR => 'SQ', Name => 'AlgorithmFamilyCodeSequ' },
     2192    '0066,0031' => { VR => 'LO', Name => 'AlgorithmVersion' },
     2193    '0066,0032' => { VR => 'LT', Name => 'AlgorithmParameters' },
     2194    '0066,0034' => { VR => 'SQ', Name => 'FacetSequence' },
     2195    '0066,0036' => { VR => 'LO', Name => 'AlgorithmName' },
    13712196    '0070,0001' => { VR => 'SQ', Name => 'GraphicAnnotationSequence' },
    13722197    '0070,0002' => { VR => 'CS', Name => 'GraphicLayer' },
     
    13872212    '0070,0023' => { VR => 'CS', Name => 'GraphicType' },
    13882213    '0070,0024' => { VR => 'CS', Name => 'GraphicFilled' },
     2214    '0070,0040' => { VR => 'IS', Name => 'ImageRotationRetired' },
    13892215    '0070,0041' => { VR => 'CS', Name => 'ImageHorizontalFlip' },
    13902216    '0070,0042' => { VR => 'US', Name => 'ImageRotation' },
    1391     '0070,0052' => { VR => 'SL', Name => 'DisplayedAreaTopLeftHandCorner' },
    1392     '0070,0053' => { VR => 'SL', Name => 'DisplayedAreaBottomRightHandCorner' },
     2217    '0070,0050' => { VR => 'US', Name => 'DisplayedAreaTopLeftTrial' },
     2218    '0070,0051' => { VR => 'US', Name => 'DisplayedAreaBottomRightTrial' },
     2219    '0070,0052' => { VR => 'SL', Name => 'DisplayedAreaTopLeft' },
     2220    '0070,0053' => { VR => 'SL', Name => 'DisplayedAreaBottomRight' },
    13932221    '0070,005A' => { VR => 'SQ', Name => 'DisplayedAreaSelectionSequence' },
    13942222    '0070,0060' => { VR => 'SQ', Name => 'GraphicLayerSequence' },
     
    14012229    '0070,0082' => { VR => 'DA', Name => 'PresentationCreationDate' },
    14022230    '0070,0083' => { VR => 'TM', Name => 'PresentationCreationTime' },
    1403     '0070,0084' => { VR => 'PN', Name => 'ContentCreatorsName' },
     2231    '0070,0084' => { VR => 'PN', Name => 'ContentCreatorName' },
     2232    '0070,0086' => { VR => 'SQ', Name => 'ContentCreatorIDCodeSequence' },
    14042233    '0070,0100' => { VR => 'CS', Name => 'PresentationSizeMode' },
    14052234    '0070,0101' => { VR => 'DS', Name => 'PresentationPixelSpacing' },
     
    14212250    '0070,031C' => { VR => 'SQ', Name => 'FiducialSetSequence' },
    14222251    '0070,031E' => { VR => 'SQ', Name => 'FiducialSequence' },
     2252    '0070,0401' => { VR => 'US', Name => 'GraphicLayerRecomDisplayCIELabVal' },
     2253    '0070,0402' => { VR => 'SQ', Name => 'BlendingSequence' },
     2254    '0070,0403' => { VR => 'FL', Name => 'RelativeOpacity' },
     2255    '0070,0404' => { VR => 'SQ', Name => 'ReferencedSpatialRegistrationSeq' },
     2256    '0070,0405' => { VR => 'CS', Name => 'BlendingPosition' },
     2257    '0072,0002' => { VR => 'SH', Name => 'HangingProtocolName' },
     2258    '0072,0004' => { VR => 'LO', Name => 'HangingProtocolDescription' },
     2259    '0072,0006' => { VR => 'CS', Name => 'HangingProtocolLevel' },
     2260    '0072,0008' => { VR => 'LO', Name => 'HangingProtocolCreator' },
     2261    '0072,000A' => { VR => 'DT', Name => 'HangingProtocolCreationDateTime' },
     2262    '0072,000C' => { VR => 'SQ', Name => 'HangingProtocolDefinitionSequence' },
     2263    '0072,000E' => { VR => 'SQ', Name => 'HangingProtocolUserIDCodeSequence' },
     2264    '0072,0010' => { VR => 'LO', Name => 'HangingProtocolUserGroupName' },
     2265    '0072,0012' => { VR => 'SQ', Name => 'SourceHangingProtocolSequence' },
     2266    '0072,0014' => { VR => 'US', Name => 'NumberOfPriorsReferenced' },
     2267    '0072,0020' => { VR => 'SQ', Name => 'ImageSetsSequence' },
     2268    '0072,0022' => { VR => 'SQ', Name => 'ImageSetSelectorSequence' },
     2269    '0072,0024' => { VR => 'CS', Name => 'ImageSetSelectorUsageFlag' },
     2270    '0072,0026' => { VR => 'AT', Name => 'SelectorAttribute' },
     2271    '0072,0028' => { VR => 'US', Name => 'SelectorValueNumber' },
     2272    '0072,0030' => { VR => 'SQ', Name => 'TimeBasedImageSetsSequence' },
     2273    '0072,0032' => { VR => 'US', Name => 'ImageSetNumber' },
     2274    '0072,0034' => { VR => 'CS', Name => 'ImageSetSelectorCategory' },
     2275    '0072,0038' => { VR => 'US', Name => 'RelativeTime' },
     2276    '0072,003A' => { VR => 'CS', Name => 'RelativeTimeUnits' },
     2277    '0072,003C' => { VR => 'SS', Name => 'AbstractPriorValue' },
     2278    '0072,003E' => { VR => 'SQ', Name => 'AbstractPriorCodeSequence' },
     2279    '0072,0040' => { VR => 'LO', Name => 'ImageSetLabel' },
     2280    '0072,0050' => { VR => 'CS', Name => 'SelectorAttributeVR' },
     2281    '0072,0052' => { VR => 'AT', Name => 'SelectorSequencePointer' },
     2282    '0072,0054' => { VR => 'LO', Name => 'SelectorSeqPointerPrivateCreator' },
     2283    '0072,0056' => { VR => 'LO', Name => 'SelectorAttributePrivateCreator' },
     2284    '0072,0060' => { VR => 'AT', Name => 'SelectorATValue' },
     2285    '0072,0062' => { VR => 'CS', Name => 'SelectorCSValue' },
     2286    '0072,0064' => { VR => 'IS', Name => 'SelectorISValue' },
     2287    '0072,0066' => { VR => 'LO', Name => 'SelectorLOValue' },
     2288    '0072,0068' => { VR => 'LT', Name => 'SelectorLTValue' },
     2289    '0072,006A' => { VR => 'PN', Name => 'SelectorPNValue' },
     2290    '0072,006C' => { VR => 'SH', Name => 'SelectorSHValue' },
     2291    '0072,006E' => { VR => 'ST', Name => 'SelectorSTValue' },
     2292    '0072,0070' => { VR => 'UT', Name => 'SelectorUTValue' },
     2293    '0072,0072' => { VR => 'DS', Name => 'SelectorDSValue' },
     2294    '0072,0074' => { VR => 'FD', Name => 'SelectorFDValue' },
     2295    '0072,0076' => { VR => 'FL', Name => 'SelectorFLValue' },
     2296    '0072,0078' => { VR => 'UL', Name => 'SelectorULValue' },
     2297    '0072,007A' => { VR => 'US', Name => 'SelectorUSValue' },
     2298    '0072,007C' => { VR => 'SL', Name => 'SelectorSLValue' },
     2299    '0072,007E' => { VR => 'SS', Name => 'SelectorSSValue' },
     2300    '0072,0080' => { VR => 'SQ', Name => 'SelectorCodeSequenceValue' },
     2301    '0072,0100' => { VR => 'US', Name => 'NumberOfScreens' },
     2302    '0072,0102' => { VR => 'SQ', Name => 'NominalScreenDefinitionSequence' },
     2303    '0072,0104' => { VR => 'US', Name => 'NumberOfVerticalPixels' },
     2304    '0072,0106' => { VR => 'US', Name => 'NumberOfHorizontalPixels' },
     2305    '0072,0108' => { VR => 'FD', Name => 'DisplayEnvironmentSpatialPosition' },
     2306    '0072,010A' => { VR => 'US', Name => 'ScreenMinimumGrayscaleBitDepth' },
     2307    '0072,010C' => { VR => 'US', Name => 'ScreenMinimumColorBitDepth' },
     2308    '0072,010E' => { VR => 'US', Name => 'ApplicationMaximumRepaintTime' },
     2309    '0072,0200' => { VR => 'SQ', Name => 'DisplaySetsSequence' },
     2310    '0072,0202' => { VR => 'US', Name => 'DisplaySetNumber' },
     2311    '0072,0203' => { VR => 'LO', Name => 'DisplaySetLabel' },
     2312    '0072,0204' => { VR => 'US', Name => 'DisplaySetPresentationGroup' },
     2313    '0072,0206' => { VR => 'LO', Name => 'DisplaySetPresentationGroupDescr' },
     2314    '0072,0208' => { VR => 'CS', Name => 'PartialDataDisplayHandling' },
     2315    '0072,0210' => { VR => 'SQ', Name => 'SynchronizedScrollingSequence' },
     2316    '0072,0212' => { VR => 'US', Name => 'DisplaySetScrollingGroup' },
     2317    '0072,0214' => { VR => 'SQ', Name => 'NavigationIndicatorSequence' },
     2318    '0072,0216' => { VR => 'US', Name => 'NavigationDisplaySet' },
     2319    '0072,0218' => { VR => 'US', Name => 'ReferenceDisplaySets' },
     2320    '0072,0300' => { VR => 'SQ', Name => 'ImageBoxesSequence' },
     2321    '0072,0302' => { VR => 'US', Name => 'ImageBoxNumber' },
     2322    '0072,0304' => { VR => 'CS', Name => 'ImageBoxLayoutType' },
     2323    '0072,0306' => { VR => 'US', Name => 'ImageBoxTileHorizontalDimension' },
     2324    '0072,0308' => { VR => 'US', Name => 'ImageBoxTileVerticalDimension' },
     2325    '0072,0310' => { VR => 'CS', Name => 'ImageBoxScrollDirection' },
     2326    '0072,0312' => { VR => 'CS', Name => 'ImageBoxSmallScrollType' },
     2327    '0072,0314' => { VR => 'US', Name => 'ImageBoxSmallScrollAmount' },
     2328    '0072,0316' => { VR => 'CS', Name => 'ImageBoxLargeScrollType' },
     2329    '0072,0318' => { VR => 'US', Name => 'ImageBoxLargeScrollAmount' },
     2330    '0072,0320' => { VR => 'US', Name => 'ImageBoxOverlapPriority' },
     2331    '0072,0330' => { VR => 'FD', Name => 'CineRelativeToRealTime' },
     2332    '0072,0400' => { VR => 'SQ', Name => 'FilterOperationsSequence' },
     2333    '0072,0402' => { VR => 'CS', Name => 'FilterByCategory' },
     2334    '0072,0404' => { VR => 'CS', Name => 'FilterByAttributePresence' },
     2335    '0072,0406' => { VR => 'CS', Name => 'FilterByOperator' },
     2336    '0072,0432' => { VR => 'US', Name => 'SynchronizedImageBoxList' },
     2337    '0072,0434' => { VR => 'CS', Name => 'TypeOfSynchronization' },
     2338    '0072,0500' => { VR => 'CS', Name => 'BlendingOperationType' },
     2339    '0072,0510' => { VR => 'CS', Name => 'ReformattingOperationType' },
     2340    '0072,0512' => { VR => 'FD', Name => 'ReformattingThickness' },
     2341    '0072,0514' => { VR => 'FD', Name => 'ReformattingInterval' },
     2342    '0072,0516' => { VR => 'CS', Name => 'ReformattingOpInitialViewDir' },
     2343    '0072,0520' => { VR => 'CS', Name => '3DRenderingType' },
     2344    '0072,0600' => { VR => 'SQ', Name => 'SortingOperationsSequence' },
     2345    '0072,0602' => { VR => 'CS', Name => 'SortByCategory' },
     2346    '0072,0604' => { VR => 'CS', Name => 'SortingDirection' },
     2347    '0072,0700' => { VR => 'CS', Name => 'DisplaySetPatientOrientation' },
     2348    '0072,0702' => { VR => 'CS', Name => 'VOIType' },
     2349    '0072,0704' => { VR => 'CS', Name => 'PseudoColorType' },
     2350    '0072,0706' => { VR => 'CS', Name => 'ShowGrayscaleInverted' },
     2351    '0072,0710' => { VR => 'CS', Name => 'ShowImageTrueSizeFlag' },
     2352    '0072,0712' => { VR => 'CS', Name => 'ShowGraphicAnnotationFlag' },
     2353    '0072,0714' => { VR => 'CS', Name => 'ShowPatientDemographicsFlag' },
     2354    '0072,0716' => { VR => 'CS', Name => 'ShowAcquisitionTechniquesFlag' },
     2355    '0072,0717' => { VR => 'CS', Name => 'DisplaySetHorizontalJustification' },
     2356    '0072,0718' => { VR => 'CS', Name => 'DisplaySetVerticalJustification' },
     2357    '0074,1000' => { VR => 'CS', Name => 'UnifiedProcedureStepState' },
     2358    '0074,1002' => { VR => 'SQ', Name => 'UPSProgressInformationSequence' },
     2359    '0074,1004' => { VR => 'DS', Name => 'UnifiedProcedureStepProgress' },
     2360    '0074,1006' => { VR => 'ST', Name => 'UnifiedProcedureStepProgressDescr' },
     2361    '0074,1008' => { VR => 'SQ', Name => 'UnifiedProcedureStepComURISeq' },
     2362    '0074,100a' => { VR => 'ST', Name => 'ContactURI' },
     2363    '0074,100c' => { VR => 'LO', Name => 'ContactDisplayName' },
     2364    '0074,1020' => { VR => 'SQ', Name => 'BeamTaskSequence' },
     2365    '0074,1022' => { VR => 'CS', Name => 'BeamTaskType' },
     2366    '0074,1024' => { VR => 'IS', Name => 'BeamOrderIndex' },
     2367    '0074,1030' => { VR => 'SQ', Name => 'DeliveryVerificationImageSequence' },
     2368    '0074,1032' => { VR => 'CS', Name => 'VerificationImageTiming' },
     2369    '0074,1034' => { VR => 'CS', Name => 'DoubleExposureFlag' },
     2370    '0074,1036' => { VR => 'CS', Name => 'DoubleExposureOrdering' },
     2371    '0074,1038' => { VR => 'DS', Name => 'DoubleExposureMeterset' },
     2372    '0074,103A' => { VR => 'DS', Name => 'DoubleExposureFieldDelta' },
     2373    '0074,1040' => { VR => 'SQ', Name => 'RelatedReferenceRTImageSequence' },
     2374    '0074,1042' => { VR => 'SQ', Name => 'GeneralMachineVerificationSequence' },
     2375    '0074,1044' => { VR => 'SQ', Name => 'ConventionalMachineVerificationSeq' },
     2376    '0074,1046' => { VR => 'SQ', Name => 'IonMachineVerificationSequence' },
     2377    '0074,1048' => { VR => 'SQ', Name => 'FailedAttributesSequence' },
     2378    '0074,104A' => { VR => 'SQ', Name => 'OverriddenAttributesSequence' },
     2379    '0074,104C' => { VR => 'SQ', Name => 'ConventionalControlPointVerifySeq' },
     2380    '0074,104E' => { VR => 'SQ', Name => 'IonControlPointVerificationSeq' },
     2381    '0074,1050' => { VR => 'SQ', Name => 'AttributeOccurrenceSequence' },
     2382    '0074,1052' => { VR => 'AT', Name => 'AttributeOccurrencePointer' },
     2383    '0074,1054' => { VR => 'UL', Name => 'AttributeItemSelector' },
     2384    '0074,1056' => { VR => 'LO', Name => 'AttributeOccurrencePrivateCreator' },
     2385    '0074,1200' => { VR => 'CS', Name => 'ScheduledProcedureStepPriority' },
     2386    '0074,1202' => { VR => 'LO', Name => 'WorklistLabel' },
     2387    '0074,1204' => { VR => 'LO', Name => 'ProcedureStepLabel' },
     2388    '0074,1210' => { VR => 'SQ', Name => 'ScheduledProcessingParametersSeq' },
     2389    '0074,1212' => { VR => 'SQ', Name => 'PerformedProcessingParametersSeq' },
     2390    '0074,1216' => { VR => 'SQ', Name => 'UPSPerformedProcedureSequence' },
     2391    '0074,1220' => { VR => 'SQ', Name => 'RelatedProcedureStepSequence' },
     2392    '0074,1222' => { VR => 'LO', Name => 'ProcedureStepRelationshipType' },
     2393    '0074,1230' => { VR => 'LO', Name => 'DeletionLock' },
     2394    '0074,1234' => { VR => 'AE', Name => 'ReceivingAE' },
     2395    '0074,1236' => { VR => 'AE', Name => 'RequestingAE' },
     2396    '0074,1238' => { VR => 'LT', Name => 'ReasonForCancellation' },
     2397    '0074,1242' => { VR => 'CS', Name => 'SCPStatus' },
     2398    '0074,1244' => { VR => 'CS', Name => 'SubscriptionListStatus' },
     2399    '0074,1246' => { VR => 'CS', Name => 'UPSListStatus' },
    14232400    # storage group
    14242401    '0088,0130' => { VR => 'SH', Name => 'StorageMediaFileSetID' },
     
    14282405    '0088,0906' => { VR => 'ST', Name => 'TopicSubject' },
    14292406    '0088,0910' => { VR => 'LO', Name => 'TopicAuthor' },
    1430     '0088,0912' => { VR => 'LO', Name => 'TopicKeyWords' },
     2407    '0088,0912' => { VR => 'LO', Name => 'TopicKeywords' },
    14312408    '0100,0410' => { VR => 'CS', Name => 'SOPInstanceStatus' },
    14322409    '0100,0420' => { VR => 'DT', Name => 'SOPAuthorizationDateAndTime' },
     
    14442421    '0400,0305' => { VR => 'CS', Name => 'CertifiedTimestampType' },
    14452422    '0400,0310' => { VR => 'OB', Name => 'CertifiedTimestamp' },
     2423    '0400,0401' => { VR => 'SQ', Name => 'DigitalSignaturePurposeCodeSeq' },
     2424    '0400,0402' => { VR => 'SQ', Name => 'ReferencedDigitalSignatureSeq' },
     2425    '0400,0403' => { VR => 'SQ', Name => 'ReferencedSOPInstanceMACSeq' },
     2426    '0400,0404' => { VR => 'OB', Name => 'MAC' },
    14462427    '0400,0500' => { VR => 'SQ', Name => 'EncryptedAttributesSequence' },
    14472428    '0400,0510' => { VR => 'UI', Name => 'EncryptedContentTransferSyntaxUID' },
    14482429    '0400,0520' => { VR => 'OB', Name => 'EncryptedContent' },
    14492430    '0400,0550' => { VR => 'SQ', Name => 'ModifiedAttributesSequence' },
     2431    '0400,0561' => { VR => 'SQ', Name => 'OriginalAttributesSequence' },
     2432    '0400,0562' => { VR => 'DT', Name => 'AttributeModificationDateTime' },
     2433    '0400,0563' => { VR => 'LO', Name => 'ModifyingSystem' },
     2434    '0400,0564' => { VR => 'LO', Name => 'SourceOfPreviousValues' },
     2435    '0400,0565' => { VR => 'CS', Name => 'ReasonForTheAttributeModification' },
     2436    '1000,xxx0' => { VR => 'US', Name => 'EscapeTriplet' },
     2437    '1000,xxx1' => { VR => 'US', Name => 'RunLengthTriplet' },
     2438    '1000,xxx2' => { VR => 'US', Name => 'HuffmanTableSize' },
     2439    '1000,xxx3' => { VR => 'US', Name => 'HuffmanTableTriplet' },
     2440    '1000,xxx4' => { VR => 'US', Name => 'ShiftTableSize' },
     2441    '1000,xxx5' => { VR => 'US', Name => 'ShiftTableTriplet' },
     2442    '1010,xxxx' => { VR => 'US', Name => 'ZonalMap' },
    14502443    '2000,0010' => { VR => 'IS', Name => 'NumberOfCopies' },
    14512444    '2000,001E' => { VR => 'SQ', Name => 'PrinterConfigurationSequence' },
     
    14672460    '2000,00A4' => { VR => 'SQ', Name => 'OtherMediaAvailableSequence' },
    14682461    '2000,00A8' => { VR => 'SQ', Name => 'SupportedImageDisplayFormatSeq' },
    1469     # film box group
    14702462    '2000,0500' => { VR => 'SQ', Name => 'ReferencedFilmBoxSequence' },
    14712463    '2000,0510' => { VR => 'SQ', Name => 'ReferencedStoredPrintSequence' },
     2464    # film box group
    14722465    '2010,0010' => { VR => 'ST', Name => 'ImageDisplayFormat' },
    14732466    '2010,0030' => { VR => 'CS', Name => 'AnnotationDisplayFormatID' },
     
    14972490    '2010,0520' => { VR => 'SQ', Name => 'ReferencedBasicAnnotationBoxSeq' },
    14982491    # image box group
    1499     '2020,0010' => { VR => 'US', Name => 'ImagePosition' },
     2492    '2020,0010' => { VR => 'US', Name => 'ImageBoxPosition' },
    15002493    '2020,0020' => { VR => 'CS', Name => 'Polarity' },
    15012494    '2020,0030' => { VR => 'DS', Name => 'RequestedImageSize' },
     
    15032496    '2020,0050' => { VR => 'CS', Name => 'RequestedResolutionID' },
    15042497    '2020,00A0' => { VR => 'CS', Name => 'RequestedImageSizeFlag' },
    1505     '2020,00A2' => { VR => 'CS', Name => 'Decimate-CropResult' },
     2498    '2020,00A2' => { VR => 'CS', Name => 'DecimateCropResult' },
    15062499    '2020,0110' => { VR => 'SQ', Name => 'BasicGrayscaleImageSequence' },
    15072500    '2020,0111' => { VR => 'SQ', Name => 'BasicColorImageSequence' },
    1508     '2020,0130' => { VR => 'RET',Name => 'ReferencedImageOverlayBoxSequence' },
    1509     '2020,0140' => { VR => 'RET',Name => 'ReferencedVOILUTBoxSequence' },
     2501    '2020,0130' => { VR => 'SQ', Name => 'ReferencedImageOverlayBoxSequence' },
     2502    '2020,0140' => { VR => 'SQ', Name => 'ReferencedVOILUTBoxSequence' },
    15102503    # annotation group
    15112504    '2030,0010' => { VR => 'US', Name => 'AnnotationPosition' },
     
    15212514    '2040,0080' => { VR => 'CS', Name => 'OverlayForegroundDensity' },
    15222515    '2040,0082' => { VR => 'CS', Name => 'OverlayBackgroundDensity' },
    1523     '2040,0090' => { VR => 'RET',Name => 'OverlayMode' },
    1524     '2040,0100' => { VR => 'RET',Name => 'ThresholdDensity' },
    1525     '2040,0500' => { VR => 'RET',Name => 'ReferencedImageBoxSequence' },
     2516    '2040,0090' => { VR => 'CS', Name => 'OverlayMode' },
     2517    '2040,0100' => { VR => 'CS', Name => 'ThresholdDensity' },
     2518    '2040,0500' => { VR => 'SQ', Name => 'ReferencedImageBoxSequence' },
    15262519    '2050,0010' => { VR => 'SQ', Name => 'PresentationLUTSequence' },
    15272520    '2050,0020' => { VR => 'CS', Name => 'PresentationLUTShape' },
     
    15332526    '2100,0050' => { VR => 'TM', Name => 'CreationTime' },
    15342527    '2100,0070' => { VR => 'AE', Name => 'Originator' },
    1535     '2100,0140' => { VR => 'AE', Name => 'Destination' },
     2528    '2100,0140' => { VR => 'AE', Name => 'DestinationAE' },
    15362529    '2100,0160' => { VR => 'SH', Name => 'OwnerID' },
    15372530    '2100,0170' => { VR => 'IS', Name => 'NumberOfFilms' },
     
    15932586    '3002,0041' => { VR => 'CS', Name => 'FluenceDataSource' },
    15942587    '3002,0042' => { VR => 'DS', Name => 'FluenceDataScale' },
     2588    '3002,0051' => { VR => 'CS', Name => 'FluenceMode' },
     2589    '3002,0052' => { VR => 'SH', Name => 'FluenceModeID' },
    15952590    '3004,0001' => { VR => 'CS', Name => 'DVHType' },
    15962591    '3004,0002' => { VR => 'CS', Name => 'DoseUnits' },
     
    16572652    '3006,00B2' => { VR => 'CS', Name => 'ROIPhysicalProperty' },
    16582653    '3006,00B4' => { VR => 'DS', Name => 'ROIPhysicalPropertyValue' },
     2654    '3006,00B6' => { VR => 'SQ', Name => 'ROIElementalCompositionSequence' },
     2655    '3006,00B7' => { VR => 'US', Name => 'ROIElementalCompAtomicNumber' },
     2656    '3006,00B8' => { VR => 'FL', Name => 'ROIElementalCompAtomicMassFraction' },
    16592657    '3006,00C0' => { VR => 'SQ', Name => 'FrameOfReferenceRelationshipSeq' },
    16602658    '3006,00C2' => { VR => 'UI', Name => 'RelatedFrameOfReferenceUID' },
     
    16672665    '3008,0016' => { VR => 'DS', Name => 'MeasuredDoseValue' },
    16682666    '3008,0020' => { VR => 'SQ', Name => 'TreatmentSessionBeamSequence' },
     2667    '3008,0021' => { VR => 'SQ', Name => 'TreatmentSessionIonBeamSequence' },
    16692668    '3008,0022' => { VR => 'IS', Name => 'CurrentFractionNumber' },
    16702669    '3008,0024' => { VR => 'DA', Name => 'TreatmentControlPointDate' },
     
    16812680    '3008,003B' => { VR => 'DS', Name => 'DeliveredTreatmentTime' },
    16822681    '3008,0040' => { VR => 'SQ', Name => 'ControlPointDeliverySequence' },
     2682    '3008,0041' => { VR => 'SQ', Name => 'IonControlPointDeliverySequence' },
    16832683    '3008,0042' => { VR => 'DS', Name => 'SpecifiedMeterset' },
    16842684    '3008,0044' => { VR => 'DS', Name => 'DeliveredMeterset' },
     2685    '3008,0045' => { VR => 'FL', Name => 'MetersetRateSet' },
     2686    '3008,0046' => { VR => 'FL', Name => 'MetersetRateDelivered' },
     2687    '3008,0047' => { VR => 'FL', Name => 'ScanSpotMetersetsDelivered' },
    16852688    '3008,0048' => { VR => 'DS', Name => 'DoseRateDelivered' },
    16862689    '3008,0050' => { VR => 'SQ', Name => 'TreatmentSummaryCalcDoseRefSeq' },
     
    16902693    '3008,005A' => { VR => 'IS', Name => 'NumberOfFractionsDelivered' },
    16912694    '3008,0060' => { VR => 'SQ', Name => 'OverrideSequence' },
     2695    '3008,0061' => { VR => 'AT', Name => 'ParameterSequencePointer' },
    16922696    '3008,0062' => { VR => 'AT', Name => 'OverrideParameterPointer' },
     2697    '3008,0063' => { VR => 'IS', Name => 'ParameterItemIndex' },
    16932698    '3008,0064' => { VR => 'IS', Name => 'MeasuredDoseReferenceNumber' },
     2699    '3008,0065' => { VR => 'AT', Name => 'ParameterPointer' },
    16942700    '3008,0066' => { VR => 'ST', Name => 'OverrideReason' },
     2701    '3008,0068' => { VR => 'SQ', Name => 'CorrectedParameterSequence' },
     2702    '3008,006A' => { VR => 'FL', Name => 'CorrectionValue' },
    16952703    '3008,0070' => { VR => 'SQ', Name => 'CalculatedDoseReferenceSequence' },
    16962704    '3008,0072' => { VR => 'IS', Name => 'CalculatedDoseReferenceNumber' },
     
    17082716    '3008,00D0' => { VR => 'SQ', Name => 'RecordedBlockSequence' },
    17092717    '3008,00E0' => { VR => 'SQ', Name => 'TreatmentSummaryMeasuredDoseRefSeq' },
     2718    '3008,00F0' => { VR => 'SQ', Name => 'RecordedSnoutSequence' },
     2719    '3008,00F2' => { VR => 'SQ', Name => 'RecordedRangeShifterSequence' },
     2720    '3008,00F4' => { VR => 'SQ', Name => 'RecordedLateralSpreadingDeviceSeq' },
     2721    '3008,00F6' => { VR => 'SQ', Name => 'RecordedRangeModulatorSequence' },
    17102722    '3008,0100' => { VR => 'SQ', Name => 'RecordedSourceSequence' },
    17112723    '3008,0105' => { VR => 'LO', Name => 'SourceSerialNumber' },
     
    17452757    '300A,0007' => { VR => 'TM', Name => 'RTPlanTime' },
    17462758    '300A,0009' => { VR => 'LO', Name => 'TreatmentProtocols' },
    1747     '300A,000A' => { VR => 'CS', Name => 'TreatmentIntent' },
     2759    '300A,000A' => { VR => 'CS', Name => 'PlanIntent' },
    17482760    '300A,000B' => { VR => 'LO', Name => 'TreatmentSites' },
    17492761    '300A,000C' => { VR => 'CS', Name => 'RTPlanGeometry' },
     
    17762788    '300A,0048' => { VR => 'SQ', Name => 'BeamLimitingDeviceToleranceSeq' },
    17772789    '300A,004A' => { VR => 'DS', Name => 'BeamLimitingDevicePositionTol' },
     2790    '300A,004B' => { VR => 'FL', Name => 'SnoutPositionTolerance' },
    17782791    '300A,004C' => { VR => 'DS', Name => 'PatientSupportAngleTolerance' },
    17792792    '300A,004E' => { VR => 'DS', Name => 'TableTopEccentricAngleTolerance' },
     2793    '300A,004F' => { VR => 'FL', Name => 'TableTopPitchAngleTolerance' },
     2794    '300A,0050' => { VR => 'FL', Name => 'TableTopRollAngleTolerance' },
    17802795    '300A,0051' => { VR => 'DS', Name => 'TableTopVerticalPositionTolerance' },
    17812796    '300A,0052' => { VR => 'DS', Name => 'TableTopLongitudinalPositionTol' },
     
    17932808    '300A,0084' => { VR => 'DS', Name => 'BeamDose' },
    17942809    '300A,0086' => { VR => 'DS', Name => 'BeamMeterset' },
     2810    '300A,0088' => { VR => 'FL', Name => 'BeamDosePointDepth' },
     2811    '300A,0089' => { VR => 'FL', Name => 'BeamDosePointEquivalentDepth' },
     2812    '300A,008A' => { VR => 'FL', Name => 'BeamDosePointSSD' },
    17952813    '300A,00A0' => { VR => 'IS', Name => 'NumberOfBrachyApplicationSetups' },
    17962814    '300A,00A2' => { VR => 'DS', Name => 'BrachyAppSetupDoseSpecPoint' },
     
    18032821    '300A,00B8' => { VR => 'CS', Name => 'RTBeamLimitingDeviceType' },
    18042822    '300A,00BA' => { VR => 'DS', Name => 'SourceToBeamLimitingDeviceDistance' },
    1805     '300A,00BC' => { VR => 'IS', Name => 'NumberOfLeaf-JawPairs' },
     2823    '300A,00BB' => { VR => 'FL', Name => 'IsocenterToBeamLimitingDeviceDist' },
     2824    '300A,00BC' => { VR => 'IS', Name => 'NumberOfLeafJawPairs' },
    18062825    '300A,00BE' => { VR => 'DS', Name => 'LeafPositionBoundaries' },
    18072826    '300A,00C0' => { VR => 'IS', Name => 'BeamNumber' },
     
    18222841    '300A,00D5' => { VR => 'IS', Name => 'WedgeAngle' },
    18232842    '300A,00D6' => { VR => 'DS', Name => 'WedgeFactor' },
     2843    '300A,00D7' => { VR => 'FL', Name => 'TotalWedgeTrayWaterEquivThickness' },
    18242844    '300A,00D8' => { VR => 'DS', Name => 'WedgeOrientation' },
     2845    '300A,00D9' => { VR => 'FL', Name => 'IsocenterToWedgeTrayDistance' },
    18252846    '300A,00DA' => { VR => 'DS', Name => 'SourceToWedgeTrayDistance' },
     2847    '300A,00DB' => { VR => 'FL', Name => 'WedgeThinEdgePosition' },
     2848    '300A,00DC' => { VR => 'SH', Name => 'BolusID' },
     2849    '300A,00DD' => { VR => 'ST', Name => 'BolusDescription' },
    18262850    '300A,00E0' => { VR => 'IS', Name => 'NumberOfCompensators' },
    18272851    '300A,00E1' => { VR => 'SH', Name => 'MaterialID' },
     
    18412865    '300A,00F0' => { VR => 'IS', Name => 'NumberOfBlocks' },
    18422866    '300A,00F2' => { VR => 'DS', Name => 'TotalBlockTrayFactor' },
     2867    '300A,00F3' => { VR => 'FL', Name => 'TotalBlockTrayWaterEquivThickness' },
    18432868    '300A,00F4' => { VR => 'SQ', Name => 'BlockSequence' },
    18442869    '300A,00F5' => { VR => 'SH', Name => 'BlockTrayID' },
    18452870    '300A,00F6' => { VR => 'DS', Name => 'SourceToBlockTrayDistance' },
     2871    '300A,00F7' => { VR => 'FL', Name => 'IsocenterToBlockTrayDistance' },
    18462872    '300A,00F8' => { VR => 'CS', Name => 'BlockType' },
    18472873    '300A,00F9' => { VR => 'LO', Name => 'AccessoryCode' },
     
    18682894    '300A,0118' => { VR => 'CS', Name => 'WedgePosition' },
    18692895    '300A,011A' => { VR => 'SQ', Name => 'BeamLimitingDevicePositionSequence' },
    1870     '300A,011C' => { VR => 'DS', Name => 'Leaf-JawPositions' },
     2896    '300A,011C' => { VR => 'DS', Name => 'LeafJawPositions' },
    18712897    '300A,011E' => { VR => 'DS', Name => 'GantryAngle' },
    18722898    '300A,011F' => { VR => 'CS', Name => 'GantryRotationDirection' },
     
    18852911    '300A,0130' => { VR => 'DS', Name => 'SourceToSurfaceDistance' },
    18862912    '300A,0134' => { VR => 'DS', Name => 'CumulativeMetersetWeight' },
     2913    '300A,0140' => { VR => 'FL', Name => 'TableTopPitchAngle' },
     2914    '300A,0142' => { VR => 'CS', Name => 'TableTopPitchRotationDirection' },
     2915    '300A,0144' => { VR => 'FL', Name => 'TableTopRollAngle' },
     2916    '300A,0146' => { VR => 'CS', Name => 'TableTopRollRotationDirection' },
     2917    '300A,0148' => { VR => 'FL', Name => 'HeadFixationAngle' },
     2918    '300A,014A' => { VR => 'FL', Name => 'GantryPitchAngle' },
     2919    '300A,014C' => { VR => 'CS', Name => 'GantryPitchRotationDirection' },
     2920    '300A,014E' => { VR => 'FL', Name => 'GantryPitchAngleTolerance' },
    18872921    '300A,0180' => { VR => 'SQ', Name => 'PatientSetupSequence' },
    18882922    '300A,0182' => { VR => 'IS', Name => 'PatientSetupNumber' },
     2923    '300A,0183' => { VR => 'LO', Name => 'PatientSetupLabel' },
    18892924    '300A,0184' => { VR => 'LO', Name => 'PatientAdditionalPosition' },
    18902925    '300A,0190' => { VR => 'SQ', Name => 'FixationDeviceSequence' },
     
    18932928    '300A,0196' => { VR => 'ST', Name => 'FixationDeviceDescription' },
    18942929    '300A,0198' => { VR => 'SH', Name => 'FixationDevicePosition' },
     2930    '300A,0199' => { VR => 'FL', Name => 'FixationDevicePitchAngle' },
     2931    '300A,019A' => { VR => 'FL', Name => 'FixationDeviceRollAngle' },
    18952932    '300A,01A0' => { VR => 'SQ', Name => 'ShieldingDeviceSequence' },
    18962933    '300A,01A2' => { VR => 'CS', Name => 'ShieldingDeviceType' },
     
    19222959    '300A,0226' => { VR => 'LO', Name => 'SourceIsotopeName' },
    19232960    '300A,0228' => { VR => 'DS', Name => 'SourceIsotopeHalfLife' },
     2961    '300A,0229' => { VR => 'CS', Name => 'SourceStrengthUnits' },
    19242962    '300A,022A' => { VR => 'DS', Name => 'ReferenceAirKermaRate' },
    1925     '300A,022C' => { VR => 'DA', Name => 'AirKermaRateReferenceDate' },
    1926     '300A,022E' => { VR => 'TM', Name => 'AirKermaRateReferenceTime' },
     2963    '300A,022B' => { VR => 'DS', Name => 'SourceStrength' },
     2964    '300A,022C' => { VR => 'DA', Name => 'SourceStrengthReferenceDate' },
     2965    '300A,022E' => { VR => 'TM', Name => 'SourceStrengthReferenceTime' },
    19272966    '300A,0230' => { VR => 'SQ', Name => 'ApplicationSetupSequence' },
    19282967    '300A,0232' => { VR => 'CS', Name => 'ApplicationSetupType' },
     
    19733012    '300A,02E1' => { VR => 'CS', Name => 'CompensatorMountingPosition' },
    19743013    '300A,02E2' => { VR => 'DS', Name => 'SourceToCompensatorDistance' },
     3014    '300A,02E3' => { VR => 'FL', Name => 'TotalCompTrayWaterEquivThickness' },
     3015    '300A,02E4' => { VR => 'FL', Name => 'IsocenterToCompensatorTrayDistance' },
     3016    '300A,02E5' => { VR => 'FL', Name => 'CompensatorColumnOffset' },
     3017    '300A,02E6' => { VR => 'FL', Name => 'IsocenterToCompensatorDistances' },
     3018    '300A,02E7' => { VR => 'FL', Name => 'CompensatorRelStoppingPowerRatio' },
     3019    '300A,02E8' => { VR => 'FL', Name => 'CompensatorMillingToolDiameter' },
     3020    '300A,02EA' => { VR => 'SQ', Name => 'IonRangeCompensatorSequence' },
     3021    '300A,02EB' => { VR => 'LT', Name => 'CompensatorDescription' },
     3022    '300A,0302' => { VR => 'IS', Name => 'RadiationMassNumber' },
     3023    '300A,0304' => { VR => 'IS', Name => 'RadiationAtomicNumber' },
     3024    '300A,0306' => { VR => 'SS', Name => 'RadiationChargeState' },
     3025    '300A,0308' => { VR => 'CS', Name => 'ScanMode' },
     3026    '300A,030A' => { VR => 'FL', Name => 'VirtualSourceAxisDistances' },
     3027    '300A,030C' => { VR => 'SQ', Name => 'SnoutSequence' },
     3028    '300A,030D' => { VR => 'FL', Name => 'SnoutPosition' },
     3029    '300A,030F' => { VR => 'SH', Name => 'SnoutID' },
     3030    '300A,0312' => { VR => 'IS', Name => 'NumberOfRangeShifters' },
     3031    '300A,0314' => { VR => 'SQ', Name => 'RangeShifterSequence' },
     3032    '300A,0316' => { VR => 'IS', Name => 'RangeShifterNumber' },
     3033    '300A,0318' => { VR => 'SH', Name => 'RangeShifterID' },
     3034    '300A,0320' => { VR => 'CS', Name => 'RangeShifterType' },
     3035    '300A,0322' => { VR => 'LO', Name => 'RangeShifterDescription' },
     3036    '300A,0330' => { VR => 'IS', Name => 'NumberOfLateralSpreadingDevices' },
     3037    '300A,0332' => { VR => 'SQ', Name => 'LateralSpreadingDeviceSequence' },
     3038    '300A,0334' => { VR => 'IS', Name => 'LateralSpreadingDeviceNumber' },
     3039    '300A,0336' => { VR => 'SH', Name => 'LateralSpreadingDeviceID' },
     3040    '300A,0338' => { VR => 'CS', Name => 'LateralSpreadingDeviceType' },
     3041    '300A,033A' => { VR => 'LO', Name => 'LateralSpreadingDeviceDescription' },
     3042    '300A,033C' => { VR => 'FL', Name => 'LateralSpreadingDevWaterEquivThick' },
     3043    '300A,0340' => { VR => 'IS', Name => 'NumberOfRangeModulators' },
     3044    '300A,0342' => { VR => 'SQ', Name => 'RangeModulatorSequence' },
     3045    '300A,0344' => { VR => 'IS', Name => 'RangeModulatorNumber' },
     3046    '300A,0346' => { VR => 'SH', Name => 'RangeModulatorID' },
     3047    '300A,0348' => { VR => 'CS', Name => 'RangeModulatorType' },
     3048    '300A,034A' => { VR => 'LO', Name => 'RangeModulatorDescription' },
     3049    '300A,034C' => { VR => 'SH', Name => 'BeamCurrentModulationID' },
     3050    '300A,0350' => { VR => 'CS', Name => 'PatientSupportType' },
     3051    '300A,0352' => { VR => 'SH', Name => 'PatientSupportID' },
     3052    '300A,0354' => { VR => 'LO', Name => 'PatientSupportAccessoryCode' },
     3053    '300A,0356' => { VR => 'FL', Name => 'FixationLightAzimuthalAngle' },
     3054    '300A,0358' => { VR => 'FL', Name => 'FixationLightPolarAngle' },
     3055    '300A,035A' => { VR => 'FL', Name => 'MetersetRate' },
     3056    '300A,0360' => { VR => 'SQ', Name => 'RangeShifterSettingsSequence' },
     3057    '300A,0362' => { VR => 'LO', Name => 'RangeShifterSetting' },
     3058    '300A,0364' => { VR => 'FL', Name => 'IsocenterToRangeShifterDistance' },
     3059    '300A,0366' => { VR => 'FL', Name => 'RangeShifterWaterEquivThickness' },
     3060    '300A,0370' => { VR => 'SQ', Name => 'LateralSpreadingDeviceSettingsSeq' },
     3061    '300A,0372' => { VR => 'LO', Name => 'LateralSpreadingDeviceSetting' },
     3062    '300A,0374' => { VR => 'FL', Name => 'IsocenterToLateralSpreadingDevDist' },
     3063    '300A,0380' => { VR => 'SQ', Name => 'RangeModulatorSettingsSequence' },
     3064    '300A,0382' => { VR => 'FL', Name => 'RangeModulatorGatingStartValue' },
     3065    '300A,0384' => { VR => 'FL', Name => 'RangeModulatorGatingStopValue' },
     3066    '300A,038A' => { VR => 'FL', Name => 'IsocenterToRangeModulatorDistance' },
     3067    '300A,0390' => { VR => 'SH', Name => 'ScanSpotTuneID' },
     3068    '300A,0392' => { VR => 'IS', Name => 'NumberOfScanSpotPositions' },
     3069    '300A,0394' => { VR => 'FL', Name => 'ScanSpotPositionMap' },
     3070    '300A,0396' => { VR => 'FL', Name => 'ScanSpotMetersetWeights' },
     3071    '300A,0398' => { VR => 'FL', Name => 'ScanningSpotSize' },
     3072    '300A,039A' => { VR => 'IS', Name => 'NumberOfPaintings' },
     3073    '300A,03A0' => { VR => 'SQ', Name => 'IonToleranceTableSequence' },
     3074    '300A,03A2' => { VR => 'SQ', Name => 'IonBeamSequence' },
     3075    '300A,03A4' => { VR => 'SQ', Name => 'IonBeamLimitingDeviceSequence' },
     3076    '300A,03A6' => { VR => 'SQ', Name => 'IonBlockSequence' },
     3077    '300A,03A8' => { VR => 'SQ', Name => 'IonControlPointSequence' },
     3078    '300A,03AA' => { VR => 'SQ', Name => 'IonWedgeSequence' },
     3079    '300A,03AC' => { VR => 'SQ', Name => 'IonWedgePositionSequence' },
     3080    '300A,0401' => { VR => 'SQ', Name => 'ReferencedSetupImageSequence' },
     3081    '300A,0402' => { VR => 'ST', Name => 'SetupImageComment' },
     3082    '300A,0410' => { VR => 'SQ', Name => 'MotionSynchronizationSequence' },
     3083    '300A,0412' => { VR => 'FL', Name => 'ControlPointOrientation' },
     3084    '300A,0420' => { VR => 'SQ', Name => 'GeneralAccessorySequence' },
     3085    '300A,0421' => { VR => 'SH', Name => 'GeneralAccessoryID' },
     3086    '300A,0422' => { VR => 'ST', Name => 'GeneralAccessoryDescription' },
     3087    '300A,0423' => { VR => 'CS', Name => 'GeneralAccessoryType' },
     3088    '300A,0424' => { VR => 'IS', Name => 'GeneralAccessoryNumber' },
    19753089    '300C,0002' => { VR => 'SQ', Name => 'ReferencedRTPlanSequence' },
    19763090    '300C,0004' => { VR => 'SQ', Name => 'ReferencedBeamSequence' },
     
    19983112    '300C,00E0' => { VR => 'IS', Name => 'ReferencedBlockNumber' },
    19993113    '300C,00F0' => { VR => 'IS', Name => 'ReferencedControlPointIndex' },
     3114    '300C,00F2' => { VR => 'SQ', Name => 'ReferencedControlPointSequence' },
     3115    '300C,00F4' => { VR => 'IS', Name => 'ReferencedStartControlPointIndex' },
     3116    '300C,00F6' => { VR => 'IS', Name => 'ReferencedStopControlPointIndex' },
     3117    '300C,0100' => { VR => 'IS', Name => 'ReferencedRangeShifterNumber' },
     3118    '300C,0102' => { VR => 'IS', Name => 'ReferencedLateralSpreadingDevNum' },
     3119    '300C,0104' => { VR => 'IS', Name => 'ReferencedRangeModulatorNumber' },
    20003120    '300E,0002' => { VR => 'CS', Name => 'ApprovalStatus' },
    20013121    '300E,0004' => { VR => 'DA', Name => 'ReviewDate' },
     
    20043124    # text group
    20053125    '4000,0000' => { VR => 'UL', Name => 'TextGroupLength' },
    2006     '4000,0010' => { VR => 'RET',Name => 'Arbitrary' },
    2007     '4000,4000' => { VR => 'RET',Name => 'TextComments' },
     3126    '4000,0010' => { VR => 'LT', Name => 'Arbitrary' },
     3127    '4000,4000' => { VR => 'LT', Name => 'TextComments' },
    20083128    # results group
    20093129    '4008,0040' => { VR => 'SH', Name => 'ResultsID' },
     
    20563176    '50xx,2008' => { VR => 'UL', Name => 'SampleRate' },
    20573177    '50xx,200A' => { VR => 'UL', Name => 'TotalTime' },
    2058     '50xx,200C' => { VR => 'OB', Name => 'AudioSampleData' },
     3178    '50xx,200C' => { VR => 'OW', Name => 'AudioSampleData' },
    20593179    '50xx,200E' => { VR => 'LT', Name => 'AudioComments' },
    20603180    '50xx,2500' => { VR => 'LO', Name => 'CurveLabel' },
    20613181    '50xx,2600' => { VR => 'SQ', Name => 'ReferencedOverlaySequence' },
    20623182    '50xx,2610' => { VR => 'US', Name => 'ReferencedOverlayGroup' },
    2063     '50xx,3000' => { VR => 'OB', Name => 'CurveData' },
     3183    '50xx,3000' => { VR => 'OW', Name => 'CurveData' },
    20643184    '5200,9229' => { VR => 'SQ', Name => 'SharedFunctionalGroupsSequence' },
    20653185    '5200,9230' => { VR => 'SQ', Name => 'PerFrameFunctionalGroupsSequence' },
    20663186    '5400,0100' => { VR => 'SQ', Name => 'WaveformSequence' },
    2067     '5400,0110' => { VR => 'OW', Name => 'ChannelMinimumValue' },
    2068     '5400,0112' => { VR => 'OW', Name => 'ChannelMaximumValue' },
     3187    '5400,0110' => { VR => 'OB', Name => 'ChannelMinimumValue' },
     3188    '5400,0112' => { VR => 'OB', Name => 'ChannelMaximumValue' },
    20693189    '5400,1004' => { VR => 'US', Name => 'WaveformBitsAllocated' },
    20703190    '5400,1006' => { VR => 'CS', Name => 'WaveformSampleInterpretation' },
    2071     '5400,100A' => { VR => 'OW', Name => 'WaveformPaddingValue' },
    2072     '5400,1010' => { VR => 'OW', Name => 'WaveformData' },
     3191    '5400,100A' => { VR => 'OB', Name => 'WaveformPaddingValue' },
     3192    '5400,1010' => { VR => 'OB', Name => 'WaveformData' },
    20733193    '5600,0010' => { VR => 'OF', Name => 'FirstOrderPhaseCorrectionAngle' },
    20743194    '5600,0020' => { VR => 'OF', Name => 'SpectroscopyData' },
     
    20853205    '60xx,0051' => { VR => 'US', Name => 'ImageFrameOrigin' },
    20863206    '60xx,0052' => { VR => 'US', Name => 'OverlayPlaneOrigin' },
    2087     '60xx,0060' => { VR => 'RET',Name => 'CompressionCode' },
     3207    '60xx,0060' => { VR => 'CS', Name => 'OverlayCompressionCode' },
     3208    '60xx,0061' => { VR => 'SH', Name => 'OverlayCompressionOriginator' },
     3209    '60xx,0062' => { VR => 'SH', Name => 'OverlayCompressionLabel' },
     3210    '60xx,0063' => { VR => 'CS', Name => 'OverlayCompressionDescription' },
     3211    '60xx,0066' => { VR => 'AT', Name => 'OverlayCompressionStepPointers' },
     3212    '60xx,0068' => { VR => 'US', Name => 'OverlayRepeatInterval' },
     3213    '60xx,0069' => { VR => 'US', Name => 'OverlayBitsGrouped' },
    20883214    '60xx,0100' => { VR => 'US', Name => 'OverlayBitsAllocated' },
    20893215    '60xx,0102' => { VR => 'US', Name => 'OverlayBitPosition' },
    2090     '60xx,0110' => { VR => 'RET',Name => 'OverlayFormat' },
    2091     '60xx,0200' => { VR => 'RET',Name => 'OverlayLocation' },
     3216    '60xx,0110' => { VR => 'CS', Name => 'OverlayFormat' },
     3217    '60xx,0200' => { VR => 'US', Name => 'OverlayLocation' },
     3218    '60xx,0800' => { VR => 'CS', Name => 'OverlayCodeLabel' },
     3219    '60xx,0802' => { VR => 'US', Name => 'OverlayNumberOfTables' },
     3220    '60xx,0803' => { VR => 'AT', Name => 'OverlayCodeTableLocation' },
     3221    '60xx,0804' => { VR => 'US', Name => 'OverlayBitsForCodeWord' },
    20923222    '60xx,1001' => { VR => 'CS', Name => 'OverlayActivationLayer' },
    2093     '60xx,1100' => { VR => 'RET',Name => 'OverlayDescriptorGray' },
    2094     '60xx,1101' => { VR => 'RET',Name => 'OverlayDescriptorRed' },
    2095     '60xx,1102' => { VR => 'RET',Name => 'OverlayDescriptorGreen' },
    2096     '60xx,1103' => { VR => 'RET',Name => 'OverlayDescriptorBlue' },
    2097     '60xx,1200' => { VR => 'RET',Name => 'OverlaysGray' },
    2098     '60xx,1201' => { VR => 'RET',Name => 'OverlaysRed' },
    2099     '60xx,1202' => { VR => 'RET',Name => 'OverlaysGreen' },
    2100     '60xx,1203' => { VR => 'RET',Name => 'OverlaysBlue' },
     3223    '60xx,1100' => { VR => 'US', Name => 'OverlayDescriptorGray' },
     3224    '60xx,1101' => { VR => 'US', Name => 'OverlayDescriptorRed' },
     3225    '60xx,1102' => { VR => 'US', Name => 'OverlayDescriptorGreen' },
     3226    '60xx,1103' => { VR => 'US', Name => 'OverlayDescriptorBlue' },
     3227    '60xx,1200' => { VR => 'US', Name => 'OverlaysGray' },
     3228    '60xx,1201' => { VR => 'US', Name => 'OverlaysRed' },
     3229    '60xx,1202' => { VR => 'US', Name => 'OverlaysGreen' },
     3230    '60xx,1203' => { VR => 'US', Name => 'OverlaysBlue' },
    21013231    '60xx,1301' => { VR => 'IS', Name => 'ROIArea' },
    21023232    '60xx,1302' => { VR => 'DS', Name => 'ROIMean' },
    21033233    '60xx,1303' => { VR => 'DS', Name => 'ROIStandardDeviation' },
    21043234    '60xx,1500' => { VR => 'LO', Name => 'OverlayLabel' },
    2105     '60xx,3000' => { VR => 'OW', Name => 'OverlayData' },
    2106     '60xx,4000' => { VR => 'RET',Name => 'OverlayComments' },
     3235    '60xx,3000' => { VR => 'OB', Name => 'OverlayData' },
     3236    '60xx,4000' => { VR => 'LT',Name => 'OverlayComments' },
    21073237    # pixel data group
    2108     '7FE0,0000' => { VR => 'UL', Name => 'PixelDataGroupLength' },
    2109     '7FE0,0010' => { VR => 'OB', Name => 'PixelData' },
     3238    '7Fxx,0000' => { VR => 'UL', Name => 'PixelDataGroupLength' },
     3239    '7Fxx,0010' => { VR => 'OB', Name => 'PixelData', Binary => 1 },
     3240    '7Fxx,0011' => { VR => 'US', Name => 'VariableNextDataGroup' },
     3241    '7Fxx,0020' => { VR => 'OW', Name => 'VariableCoefficientsSDVN' },
     3242    '7Fxx,0030' => { VR => 'OW', Name => 'VariableCoefficientsSDHN' },
     3243    '7Fxx,0040' => { VR => 'OW', Name => 'VariableCoefficientsSDDN' },
    21103244    'FFFA,FFFA' => { VR => 'SQ', Name => 'DigitalSignaturesSequence' },
    2111     'FFFC,FFFC' => { VR => 'OB', Name => 'DataSetTrailingPadding' },
     3245    'FFFC,FFFC' => { VR => 'OB', Name => 'DataSetTrailingPadding', Binary => 1 },
    21123246    # the sequence delimiters have no VR:
    21133247    'FFFE,E000' => 'StartOfItem',
     
    21173251
    21183252# table to translate registered UID values to readable strings
    2119 my %uid = (
     3253# (the PrintConv is added dynamically when a 'UI' format tag is extracted)
     3254%uid = (
    21203255    '1.2.840.10008.1.1' => 'Verification SOP Class',
    21213256    '1.2.840.10008.1.2' => 'Implicit VR Little Endian',
     
    21453280    '1.2.840.10008.1.2.4.90' => 'JPEG 2000 Image Compression (Lossless Only)',
    21463281    '1.2.840.10008.1.2.4.91' => 'JPEG 2000 Image Compression',
     3282    '1.2.840.10008.1.2.4.92' => 'JPEG 2000 Part 2 Multi-component Image Compression (Lossless Only)',
     3283    '1.2.840.10008.1.2.4.93' => 'JPEG 2000 Part 2 Multi-component Image Compression',
     3284    '1.2.840.10008.1.2.4.94' => 'JPIP Referenced',
     3285    '1.2.840.10008.1.2.4.95' => 'JPIP Referenced Deflate',
    21473286    '1.2.840.10008.1.2.4.100' => 'MPEG2 Main Profile @ Main Level',
    21483287    '1.2.840.10008.1.2.5' => 'RLE Lossless',
     3288    '1.2.840.10008.1.2.6.1' => 'RFC 2557 MIME encapsulation',
     3289    '1.2.840.10008.1.2.6.2' => 'XML Encoding',
    21493290    '1.2.840.10008.1.3.10' => 'Media Storage Directory Storage',
    21503291    '1.2.840.10008.1.4.1.1' => 'Talairach Brain Atlas Frame of Reference',
     
    21753316    '1.2.840.10008.1.40' => 'Procedural Event Logging SOP Class',
    21763317    '1.2.840.10008.1.40.1' => 'Procedural Event Logging SOP Instance',
    2177     '1.2.840.10008.2.16.4' => 'DICOM Controlled Terminology Coding Scheme PS 3.16',
     3318    '1.2.840.10008.1.42' => 'Substance Administration Logging SOP Class',
     3319    '1.2.840.10008.1.42.1' => 'Substance Administration Logging SOP Instance',
     3320    '1.2.840.10008.2.6.1' => 'DICOM UID Registry',
     3321    '1.2.840.10008.2.16.4' => 'DICOM Controlled Terminology',
    21783322    '1.2.840.10008.3.1.1.1' => 'DICOM Application Context Name',
    21793323    '1.2.840.10008.3.1.2.1.1' => 'Detached Patient Management SOP Class',
     
    22183362    '1.2.840.10008.5.1.1.33' => 'Media Creation Management SOP Class',
    22193363    '1.2.840.10008.5.1.4.1.1.1' => 'Computed Radiography Image Storage',
    2220     '1.2.840.10008.5.1.4.1.1.1.1' => 'Digital X-Ray Image Storage Ð For Presentation',
    2221     '1.2.840.10008.5.1.4.1.1.1.1.1' => 'Digital X-Ray Image Storage Ð For Processing',
    2222     '1.2.840.10008.5.1.4.1.1.1.2' => 'Digital Mammography X-Ray Image Storage Ð For Presentation',
    2223     '1.2.840.10008.5.1.4.1.1.1.2.1' => 'Digital Mammography X-Ray Image Storage Ð For Processing',
    2224     '1.2.840.10008.5.1.4.1.1.1.3' => 'Digital Intra-oral X-Ray Image Storage Ð For Presentation',
    2225     '1.2.840.10008.5.1.4.1.1.1.3.1' => 'Digital Intra-oral X-Ray Image Storage Ð For Processing',
     3364    '1.2.840.10008.5.1.4.1.1.1.1' => 'Digital X-Ray Image Storage - For Presentation',
     3365    '1.2.840.10008.5.1.4.1.1.1.1.1' => 'Digital X-Ray Image Storage - For Processing',
     3366    '1.2.840.10008.5.1.4.1.1.1.2' => 'Digital Mammography X-Ray Image Storage - For Presentation',
     3367    '1.2.840.10008.5.1.4.1.1.1.2.1' => 'Digital Mammography X-Ray Image Storage - For Processing',
     3368    '1.2.840.10008.5.1.4.1.1.1.3' => 'Digital Intra-oral X-Ray Image Storage - For Presentation',
     3369    '1.2.840.10008.5.1.4.1.1.1.3.1' => 'Digital Intra-oral X-Ray Image Storage - For Processing',
    22263370    '1.2.840.10008.5.1.4.1.1.2' => 'CT Image Storage',
    22273371    '1.2.840.10008.5.1.4.1.1.2.1' => 'Enhanced CT Image Storage',
     
    22413385    '1.2.840.10008.5.1.4.1.1.8' => 'Standalone Overlay Storage',
    22423386    '1.2.840.10008.5.1.4.1.1.9' => 'Standalone Curve Storage',
     3387    '1.2.840.10008.5.1.4.1.1.9.1' => 'Waveform Storage - Trial (Retired)',
    22433388    '1.2.840.10008.5.1.4.1.1.9.1.1' => '12-lead ECG Waveform Storage',
    22443389    '1.2.840.10008.5.1.4.1.1.9.1.2' => 'General ECG Waveform Storage',
     
    22503395    '1.2.840.10008.5.1.4.1.1.11' => 'Standalone VOI LUT Storage',
    22513396    '1.2.840.10008.5.1.4.1.1.11.1' => 'Grayscale Softcopy Presentation State Storage SOP Class',
     3397    '1.2.840.10008.5.1.4.1.1.11.2' => 'Color Softcopy Presentation State Storage SOP Class',
     3398    '1.2.840.10008.5.1.4.1.1.11.3' => 'Pseudo-Color Softcopy Presentation State Storage SOP Class',
     3399    '1.2.840.10008.5.1.4.1.1.11.4' => 'Blending Softcopy Presentation State Storage SOP Class',
    22523400    '1.2.840.10008.5.1.4.1.1.12.1' => 'X-Ray Angiographic Image Storage',
     3401    '1.2.840.10008.5.1.4.1.1.12.1.1' => 'Enhanced XA Image Storage',
    22533402    '1.2.840.10008.5.1.4.1.1.12.2' => 'X-Ray Radiofluoroscopic Image Storage',
     3403    '1.2.840.10008.5.1.4.1.1.12.2.1' => 'Enhanced XRF Image Storage',
    22543404    '1.2.840.10008.5.1.4.1.1.12.3' => 'X-Ray Angiographic Bi-Plane Image Storage ',
     3405    '1.2.840.10008.5.1.4.1.1.13.1.1' => 'X-Ray 3D Angiographic Image Storage',
     3406    '1.2.840.10008.5.1.4.1.1.13.1.2' => 'X-Ray 3D Craniofacial Image Storage',
    22553407    '1.2.840.10008.5.1.4.1.1.20' => 'Nuclear Medicine Image Storage',
    22563408    '1.2.840.10008.5.1.4.1.1.66' => 'Raw Data Storage',
    22573409    '1.2.840.10008.5.1.4.1.1.66.1' => 'Spatial Registration Storage',
    22583410    '1.2.840.10008.5.1.4.1.1.66.2' => 'Spatial Fiducials Storage',
     3411    '1.2.840.10008.5.1.4.1.1.66.3' => 'Deformable Spatial Registration Storage',
     3412    '1.2.840.10008.5.1.4.1.1.66.4' => 'Segmentation Storage',
     3413    '1.2.840.10008.5.1.4.1.1.67' => 'Real World Value Mapping Storage',
    22593414    '1.2.840.10008.5.1.4.1.1.77.1' => 'VL Image Storage ',
    22603415    '1.2.840.10008.5.1.4.1.1.77.2' => 'VL Multi-frame Image Storage',
     
    22693424    '1.2.840.10008.5.1.4.1.1.77.1.5.2' => 'Ophthalmic Photography 16 Bit Image Storage',
    22703425    '1.2.840.10008.5.1.4.1.1.77.1.5.3' => 'Stereometric Relationship Storage',
     3426    '1.2.840.10008.5.1.4.1.1.77.1.5.4' => 'Ophthalmic Tomography Image Storage',
     3427    '1.2.840.10008.5.1.4.1.1.88.1' => 'Text SR Storage - Trial (Retired)',
     3428    '1.2.840.10008.5.1.4.1.1.88.2' => 'Audio SR Storage - Trial (Retired)',
     3429    '1.2.840.10008.5.1.4.1.1.88.3' => 'Detail SR Storage - Trial (Retired)',
     3430    '1.2.840.10008.5.1.4.1.1.88.4' => 'Comprehensive SR Storage - Trial (Retired)',
    22713431    '1.2.840.10008.5.1.4.1.1.88.11' => 'Basic Text SR',
    22723432    '1.2.840.10008.5.1.4.1.1.88.22' => 'Enhanced SR',
     
    22763436    '1.2.840.10008.5.1.4.1.1.88.59' => 'Key Object Selection Document',
    22773437    '1.2.840.10008.5.1.4.1.1.88.65' => 'Chest CAD SR',
     3438    '1.2.840.10008.5.1.4.1.1.88.67' => 'X-Ray Radiation Dose SR Storage',
     3439    '1.2.840.10008.5.1.4.1.1.104.1' => 'Encapsulated PDF Storage',
     3440    '1.2.840.10008.5.1.4.1.1.104.2' => 'Encapsulated CDA Storage',
    22783441    '1.2.840.10008.5.1.4.1.1.128' => 'Positron Emission Tomography Image Storage',
    22793442    '1.2.840.10008.5.1.4.1.1.129' => 'Standalone PET Curve Storage',
     
    22853448    '1.2.840.10008.5.1.4.1.1.481.6' => 'RT Brachy Treatment Record Storage',
    22863449    '1.2.840.10008.5.1.4.1.1.481.7' => 'RT Treatment Summary Record Storage',
    2287     '1.2.840.10008.5.1.4.1.2.1.1' => 'Patient Root Query/Retrieve Information Model Ð FIND',
    2288     '1.2.840.10008.5.1.4.1.2.1.2' => 'Patient Root Query/Retrieve Information Model Ð MOVE',
    2289     '1.2.840.10008.5.1.4.1.2.1.3' => 'Patient Root Query/Retrieve Information Model Ð GET',
    2290     '1.2.840.10008.5.1.4.1.2.2.1' => 'Study Root Query/Retrieve Information Model Ð FIND',
    2291     '1.2.840.10008.5.1.4.1.2.2.2' => 'Study Root Query/Retrieve Information Model Ð MOVE',
    2292     '1.2.840.10008.5.1.4.1.2.2.3' => 'Study Root Query/Retrieve Information Model Ð GET',
     3450    '1.2.840.10008.5.1.4.1.1.481.8' => 'RT Ion Plan Storage',
     3451    '1.2.840.10008.5.1.4.1.1.481.9' => 'RT Ion Beams Treatment Record Storage',
     3452    '1.2.840.10008.5.1.4.1.2.1.1' => 'Patient Root Query/Retrieve Information Model - FIND',
     3453    '1.2.840.10008.5.1.4.1.2.1.2' => 'Patient Root Query/Retrieve Information Model - MOVE',
     3454    '1.2.840.10008.5.1.4.1.2.1.3' => 'Patient Root Query/Retrieve Information Model - GET',
     3455    '1.2.840.10008.5.1.4.1.2.2.1' => 'Study Root Query/Retrieve Information Model - FIND',
     3456    '1.2.840.10008.5.1.4.1.2.2.2' => 'Study Root Query/Retrieve Information Model - MOVE',
     3457    '1.2.840.10008.5.1.4.1.2.2.3' => 'Study Root Query/Retrieve Information Model - GET',
    22933458    '1.2.840.10008.5.1.4.1.2.3.1' => 'Patient/Study Only Query/Retrieve Information Model - FIND',
    22943459    '1.2.840.10008.5.1.4.1.2.3.2' => 'Patient/Study Only Query/Retrieve Information Model - MOVE',
    22953460    '1.2.840.10008.5.1.4.1.2.3.3' => 'Patient/Study Only Query/Retrieve Information Model - GET',
    2296     '1.2.840.10008.5.1.4.31' => 'Modality Worklist Information Model Ð FIND',
    2297     '1.2.840.10008.5.1.4.32.1' => 'General Purpose Worklist Information Model Ð FIND',
     3461    '1.2.840.10008.5.1.4.31' => 'Modality Worklist Information Model - FIND',
     3462    '1.2.840.10008.5.1.4.32.1' => 'General Purpose Worklist Information Model - FIND',
    22983463    '1.2.840.10008.5.1.4.32.2' => 'General Purpose Scheduled Procedure Step SOP Class',
    22993464    '1.2.840.10008.5.1.4.32.3' => 'General Purpose Performed Procedure Step SOP Class',
    23003465    '1.2.840.10008.5.1.4.32' => 'General Purpose Worklist Management Meta SOP Class',
    23013466    '1.2.840.10008.5.1.4.33' => 'Instance Availability Notification SOP Class',
     3467    '1.2.840.10008.5.1.4.34.1' => 'RT Beams Delivery Instruction Storage',
     3468    '1.2.840.10008.5.1.4.34.2' => 'RT Conventional Machine Verification',
     3469    '1.2.840.10008.5.1.4.34.3' => 'RT Ion Machine Verification',
     3470    '1.2.840.10008.5.1.4.34.4' => 'Unified Worklist and Procedure Step Service Class',
     3471    '1.2.840.10008.5.1.4.34.4.1' => 'Unified Procedure Step - Push SOP Class',
     3472    '1.2.840.10008.5.1.4.34.4.2' => 'Unified Procedure Step - Watch SOP Class',
     3473    '1.2.840.10008.5.1.4.34.4.3' => 'Unified Procedure Step - Pull SOP Class',
     3474    '1.2.840.10008.5.1.4.34.4.4' => 'Unified Procedure Step - Event SOP Class',
     3475    '1.2.840.10008.5.1.4.34.5' => 'Unified Worklist and Procedure Step SOP Instance',
    23023476    '1.2.840.10008.5.1.4.37.1' => 'General Relevant Patient Information Query',
    23033477    '1.2.840.10008.5.1.4.37.2' => 'Breast Imaging Relevant Patient Information Query',
    23043478    '1.2.840.10008.5.1.4.37.3' => 'Cardiac Relevant Patient Information Query',
     3479    '1.2.840.10008.5.1.4.38.1' => 'Hanging Protocol Storage',
     3480    '1.2.840.10008.5.1.4.38.2' => 'Hanging Protocol Information Model - FIND',
     3481    '1.2.840.10008.5.1.4.38.3' => 'Hanging Protocol Information Model - MOVE',
     3482    '1.2.840.10008.5.1.4.41' => 'Product Characteristics Query SOP Class',
     3483    '1.2.840.10008.5.1.4.42' => 'Substance Approval Query SOP Class',
    23053484    '1.2.840.10008.15.0.3.1' => 'dicomDeviceName',
    23063485    '1.2.840.10008.15.0.3.2' => 'dicomDescription',
     
    25033682        my $tagInfo = $$tagTablePtr{$tag};
    25043683        unless ($tagInfo) {
    2505             # look for a tag like '60xx,1203' or '0020,31xx' in table
     3684            # accept tag ID's with "x" for a wildcard in the following patterns:
     3685            # '60xx,1203', '0020,31xx', '0028,04x2', '1000,xxx0', '1010,xxxx'
    25063686            my $xx;
    2507             if ((($xx = $tag) =~ s/^(..)../$1xx/ and $$tagTablePtr{$xx}) or
    2508                 (($xx = $tag) =~ s/(..)$/xx/ and $$tagTablePtr{$xx}))
     3687            if ((($xx = $tag) =~ s/^(..)../$1xx/  and $$tagTablePtr{$xx}) or
     3688                (($xx = $tag) =~ s/..$/xx/        and $$tagTablePtr{$xx}) or
     3689                (($xx = $tag) =~ s/.(.)$/x$1/     and $$tagTablePtr{$xx}) or
     3690                (($xx = $tag) =~ s/...(.)$/xxx$1/ and $$tagTablePtr{$xx}) or
     3691                (($xx = $tag) =~ s/....$/xxxx/    and $$tagTablePtr{$xx}))
    25093692            {
    25103693                $tag = $xx;
     
    26143797=head1 NOTES
    26153798
    2616 Values of retired elements in implicit VR format files are intepreted as
    2617 strings, hence they may not be displayed properly.  This is because the
    2618 specification no longer lists these VR's, but simply lists 'RET' for these
    2619 elements.  (Doh. Who's idea was that? :P)
    2620 
    26213799Images compressed using the DICOM deflated transfer syntax will be decoded
    26223800if Compress::Zlib is installed.
     
    26263804=head1 AUTHOR
    26273805
    2628 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     3806Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    26293807
    26303808This library is free software; you can redistribute it and/or modify it
     
    26353813=over 4
    26363814
    2637 =item L<http://medical.nema.org/dicom/2004.html>
     3815=item L<http://medical.nema.org/>
    26383816
    26393817=item L<http://www.sph.sc.edu/comd/rorden/dicom.html>
    26403818
    26413819=item L<http://www.dclunie.com/>
     3820
     3821=item L<http://www.gehealthcare.com/usen/interoperability/dicom/docs/2258357r3.pdf>
    26423822
    26433823=back
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DNG.pm

    r16842 r24107  
    66# Revisions:    01/09/2006 - P. Harvey Created
    77#
    8 # References:   1) http://www.adobe.com/products/dng/pdfs/dng_spec.pdf
     8# References:   1) http://www.adobe.com/products/dng/
    99#------------------------------------------------------------------------------
    1010
     
    1818use Image::ExifTool::CanonRaw;
    1919
    20 $VERSION = '1.07';
     20$VERSION = '1.15';
    2121
    2222sub ProcessOriginalRaw($$$);
     
    2424sub ProcessAdobeMakN($$$);
    2525sub ProcessAdobeCRW($$$);
     26sub ProcessAdobeRAF($$$);
    2627sub ProcessAdobeMRW($$$);
    2728sub ProcessAdobeSR2($$$);
     29sub ProcessAdobeIFD($$$);
    2830sub WriteAdobeStuff($$$);
    2931
     
    5557        The maker notes ('MakN') are processed by ExifTool, but some information may
    5658        have been lost by the Adobe DNG Converter.  This is because the Adobe DNG
    57         Converter (as of version 3.3) doesn't properly handle information referenced
     59        Converter (as of version 6.3) doesn't properly handle information referenced
    5860        from inside the maker notes that lies outside the original maker notes
    59         block, and this information is lost when only the maker note block is copied
    60         to the DNG image.   While this isn't a big problem for most camera makes, it
    61         is serious for some makes like Olympus.
    62 
    63         The CRW data is from DNG-converted CRW images, but it has been restructured
    64         to a proprietary Adobe format (which results in a loss of the original
    65         hierarchical information structure, and creates extra work for everyone else
    66         who wants to use this information).
     61        block.  This information is lost when only the maker note block is copied to
     62        the DNG image.   While this doesn't effect all makes of cameras, it is a
     63        problem for some major brands such as Olympus and Sony.
     64
     65        Other entries in this table represent proprietary information that is
     66        extracted from the original RAW image and restructured to a different (but
     67        still proprietary) Adobe format.
    6768    },
    6869    MakN  => [ ],   # (filled in later)
     
    9293   'RAF ' => {
    9394        Name => 'AdobeRAF',
    94         Flags => [qw(Binary Unknown)],
     95        SubDirectory => {
     96            TagTable => 'Image::ExifTool::FujiFilm::RAF',
     97            ProcessProc => \&ProcessAdobeRAF,
     98        },
     99    },
     100    'Pano' => {
     101        Name => 'AdobePano',
     102        SubDirectory => {
     103            TagTable => 'Image::ExifTool::PanasonicRaw::Main',
     104            ProcessProc => \&ProcessAdobeIFD,
     105        },
     106    },
     107    'Koda' => {
     108        Name => 'AdobeKoda',
     109        SubDirectory => {
     110            TagTable => 'Image::ExifTool::Kodak::IFD',
     111            ProcessProc => \&ProcessAdobeIFD,
     112        },
     113    },
     114    'Leaf' => {
     115        Name => 'AdobeLeaf',
     116        SubDirectory => {
     117            TagTable => 'Image::ExifTool::Leaf::SubIFD',
     118            ProcessProc => \&ProcessAdobeIFD,
     119        },
    95120    },
    96121);
     
    107132        my %copy = %$tagInfo;
    108133        delete $copy{Groups};
     134        delete $copy{GotGroups};
    109135        delete $copy{Table};
    110136        push @$list, \%copy;
     
    124150    my $pos = $start;
    125151    my ($index, $err);
     152
    126153    SetByteOrder('MM'); # pointers are always big-endian in this structure
    127154    for ($index=0; $index<8; ++$index) {
     
    205232    unless ($outfile) {
    206233        $exifTool->VerboseDir($dirInfo);
    207     }
    208     $htmlDump and $exifTool->HtmlDump($dataPos, 6, 'Adobe DNGPrivateData header');
     234        # don't parse makernotes if FastScan > 1
     235        my $fast = $exifTool->Options('FastScan');
     236        return 1 if $fast and $fast > 1;
     237    }
     238    $htmlDump and $exifTool->HDump($dataPos, 6, 'Adobe DNGPrivateData header');
    209239    SetByteOrder('MM'); # always big endian
    210240    $pos += 6;
     
    217247            my $name = "Adobe$tag";
    218248            $name =~ tr/ //d;
    219             $exifTool->HtmlDump($dataPos + $pos - 8, 8, "$name header", "Data Size: $size bytes");
     249            $exifTool->HDump($dataPos + $pos - 8, 8, "$name header", "Data Size: $size bytes");
    220250            # dump non-EXIF format data
    221251            unless ($tag =~ /^(MakN|SR2 )$/) {
    222                 $exifTool->HtmlDump($dataPos + $pos, $size, "$name data");
     252                $exifTool->HDump($dataPos + $pos, $size, "$name data");
    223253            }
    224254        }
    225         $verbose and not $outfile and $exifTool->VerboseInfo($tag,
    226             ref $tagInfo eq 'HASH' ? $tagInfo : undef,
    227             DataPt => $dataPt,
    228             DataPos => $dataPos,
    229             Start => $pos,
    230             Size => $size,
    231         );
     255        if ($verbose and not $outfile) {
     256            $tagInfo or $exifTool->VPrint(0, "$$exifTool{INDENT}Unsupported DNGAdobeData record: ($tag)\n");
     257            $exifTool->VerboseInfo($tag,
     258                ref $tagInfo eq 'HASH' ? $tagInfo : undef,
     259                DataPt => $dataPt,
     260                DataPos => $dataPos,
     261                Start => $pos,
     262                Size => $size,
     263            );
     264        }
    232265        my $value;
    233266        while ($tagInfo) {
     
    356389                if ($subdir and $$subdir{TagTable}) {
    357390                    my $name = $$tagInfo{Name};
    358                     my $newTagTable = Image::ExifTool::GetTagTable($$subdir{TagTable});
     391                    my $newTagTable = GetTagTable($$subdir{TagTable});
    359392                    return 0 unless $newTagTable;
    360393                    my $subdirStart = 0;
     
    385418                    }
    386419                } elsif ($$newTags{$tagID}) {
    387                     my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
    388                     if (Image::ExifTool::IsOverwriting($newValueHash, $val)) {
    389                         my $newVal = Image::ExifTool::GetNewValues($newValueHash);
     420                    my $nvHash = $exifTool->GetNewValueHash($tagInfo);
     421                    if (Image::ExifTool::IsOverwriting($nvHash, $val)) {
     422                        my $newVal = Image::ExifTool::GetNewValues($nvHash);
    390423                        my $verboseVal;
    391424                        $verboseVal = $newVal if $verbose > 1;
     
    395428                        }
    396429                        if (defined $newVal) {
    397                             if ($verbose > 1) {
    398                                 my $oldStr = $exifTool->Printable($value);
    399                                 my $newStr = $exifTool->Printable($verboseVal);
    400                                 my $out = $exifTool->Options('TextOut');
    401                                 print $out "    - CanonRaw:$$tagInfo{Name} = '$oldStr'\n";
    402                                 print $out "    + CanonRaw:$$tagInfo{Name} = '$newStr'\n";
    403                             }
     430                            $exifTool->VerboseValue("- CanonRaw:$$tagInfo{Name}", $value);
     431                            $exifTool->VerboseValue("+ CanonRaw:$$tagInfo{Name}", $verboseVal);
    404432                            $value = $newVal;
    405433                            ++$exifTool->{CHANGED};
     
    464492    my $dirStart = $$dirInfo{DirStart};
    465493    my $outfile = $$dirInfo{OutFile};
     494
    466495    # construct fake MRW file
    467496    my $buff = "\0MRM" . pack('N', $dirLen - 4);
     
    479508
    480509#------------------------------------------------------------------------------
     510# Process Adobe RAF directory
     511# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     512# Returns: 1 on success, otherwise returns 0 and sets a Warning
     513sub ProcessAdobeRAF($$$)
     514{
     515    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     516    return 0 if $$dirInfo{OutFile}; # (can't write this yet)
     517    my $dataPt = $$dirInfo{DataPt};
     518    my $pos = $$dirInfo{DirStart};
     519    my $dirEnd = $$dirInfo{DirLen} + $pos;
     520    my ($readIt, $warn);
     521
     522    # set byte order according to first 2 bytes of Adobe RAF data
     523    if ($pos + 2 <= $dirEnd and SetByteOrder(substr($$dataPt, $pos, 2))) {
     524        $pos += 2;
     525    } else {
     526        $exifTool->Warn('Invalid DNG RAF data');
     527        return 0;
     528    }
     529    $exifTool->VerboseDir($dirInfo);
     530    # make fake RAF object for processing (same acronym, different meaning)
     531    my $raf = new File::RandomAccess($dataPt);
     532    my $num = '';
     533    # loop through all records in Adobe RAF data:
     534    # 0 - RAF table (not processed)
     535    # 1 - first RAF directory
     536    # 2 - second RAF directory (if available)
     537    for (;;) {
     538        last if $pos + 4 > $dirEnd;
     539        my $len = Get32u($dataPt, $pos);
     540        $pos += 4 + $len;   # step to next entry in Adobe RAF record
     541        $len or last;       # ends with an empty entry
     542        $readIt or $readIt = 1, next;   # ignore first entry (RAF table)
     543        my %dirInfo = (
     544            RAF      => $raf,
     545            DirStart => $pos - $len,
     546        );
     547        $$exifTool{SET_GROUP1} = "RAF$num";
     548        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr) or $warn = 1;
     549        delete $$exifTool{SET_GROUP1};
     550        $num = ($num || 1) + 1;
     551    }
     552    $warn and $exifTool->Warn('Possibly corrupt RAF information');
     553    return 1;
     554}
     555
     556#------------------------------------------------------------------------------
    481557# Process Adobe SR2 directory
    482558# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     
    486562{
    487563    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     564    return 0 if $$dirInfo{OutFile}; # (can't write this yet)
    488565    my $dataPt = $$dirInfo{DataPt};
    489566    my $start = $$dirInfo{DirStart};
    490567    my $len = $$dirInfo{DirLen};
    491     return 0 if $$dirInfo{OutFile}; # (can't write this yet)
    492568
    493569    return 0 if $len < 6;
     
    514590    );
    515591    if ($exifTool->Options('HtmlDump')) {
    516         $exifTool->HtmlDump($dataPos + $start, 6, 'Adobe SR2 data');
     592        $exifTool->HDump($dataPos + $start, 6, 'Adobe SR2 data');
    517593    }
    518594    # parse the SR2 directory
    519595    $exifTool->ProcessDirectory(\%subdirInfo, $tagTablePtr);
     596    return 1;
     597}
     598
     599#------------------------------------------------------------------------------
     600# Process Adobe-mutilated IFD directory
     601# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     602# Returns: 1 on success, otherwise returns 0 and sets a Warning
     603# Notes: data has 2 byte header (byte order of the data)
     604sub ProcessAdobeIFD($$$)
     605{
     606    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     607    return 0 if $$dirInfo{OutFile}; # (can't write this yet)
     608    my $dataPt = $$dirInfo{DataPt};
     609    my $pos = $$dirInfo{DirStart};
     610    my $dataPos = $$dirInfo{DataPos};
     611
     612    return 0 if $$dirInfo{DirLen} < 4;
     613    my $dataOrder = substr($$dataPt, $pos, 2);
     614    return 0 unless SetByteOrder($dataOrder);   # validate byte order of data
     615
     616    # parse the mutilated IFD.  This is similar to a TIFF IFD, except:
     617    # - data follows directly after Count entry in IFD
     618    # - byte order of IFD entires is always big-endian, but byte order of data changes
     619    SetByteOrder('MM');     # IFD structure is always big-endian
     620    my $entries = Get16u($dataPt, $pos + 2);
     621    $exifTool->VerboseDir($dirInfo, $entries);
     622    $pos += 4;
     623
     624    my $end = $pos + $$dirInfo{DirLen};
     625    my $index;
     626    for ($index=0; $index<$entries; ++$index) {
     627        last if $pos + 8 > $end;
     628        SetByteOrder('MM'); # directory entries always big-endian (doh!)
     629        my $tagID = Get16u($dataPt, $pos);
     630        my $format = Get16u($dataPt, $pos+2);
     631        my $count = Get32u($dataPt, $pos+4);
     632        if ($format < 1 or $format > 13) {
     633            # warn unless the IFD was just padded with zeros
     634            $format and $exifTool->Warn(
     635                sprintf("Unknown format ($format) for $$dirInfo{DirName} tag 0x%x",$tagID));
     636            return 0; # must be corrupted
     637        }
     638        my $size = $Image::ExifTool::Exif::formatSize[$format] * $count;
     639        last if $pos + 8 + $size > $end;
     640        my $formatStr = $Image::ExifTool::Exif::formatName[$format];
     641        SetByteOrder($dataOrder);   # data stored in native order
     642        my $val = ReadValue($dataPt, $pos + 8, $formatStr, $count, $size);
     643        $exifTool->HandleTag($tagTablePtr, $tagID, $val,
     644            Index   => $index,
     645            DataPt  => $dataPt,
     646            DataPos => $dataPos,
     647            Start   => $pos + 8,
     648            Size    => $size
     649        );
     650        $pos += 8 + $size;
     651    }
     652    if ($index < $entries) {
     653        $exifTool->Warn("Truncated $$dirInfo{DirName} directory");
     654        return 0;
     655    }
    520656    return 1;
    521657}
     
    571707    }
    572708    if ($exifTool->Options('HtmlDump')) {
    573         $exifTool->HtmlDump($dataPos + $start, 6, 'Adobe MakN data');
    574         $exifTool->HtmlDump($dataPos + $dirStart, $loc, "$$tagInfo{Name} header") if $loc;
     709        $exifTool->HDump($dataPos + $start, 6, 'Adobe MakN data');
     710        $exifTool->HDump($dataPos + $dirStart, $loc, "$$tagInfo{Name} header") if $loc;
    575711    }
    576712
     
    606742            $fixup->{Shift} += $originalPos;
    607743        }
     744        # if we wrote the directory as a block the header is already included
     745        $loc = 0 if $subdirInfo{BlockWrite};
    608746        $fixup->{Shift} += $loc;    # adjust for makernotes header
    609747        $fixup->ApplyFixup(\$buff); # fix up pointer offsets
     
    673811=head1 AUTHOR
    674812
    675 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     813Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    676814
    677815This library is free software; you can redistribute it and/or modify it
     
    682820=over 4
    683821
    684 =item L<http://www.adobe.com/products/dng/pdfs/dng_spec.pdf>
     822=item L<http://www.adobe.com/products/dng/>
    685823
    686824=back
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Exif.pm

    r16842 r24107  
    22# File:         Exif.pm
    33#
    4 # Description:  Read EXIF meta information
     4# Description:  Read EXIF/TIFF meta information
    55#
    66# Revisions:    11/25/2003 - P. Harvey Created
     
    1212# References:   0) http://www.exif.org/Exif2-2.PDF
    1313#               1) http://partners.adobe.com/asn/developer/pdfs/tn/TIFF6.pdf
    14 #               2) http://www.adobe.com/products/dng/pdfs/dng_spec.pdf
     14#               2) http://www.adobe.com/products/dng/pdfs/dng_spec_1_3_0_0.pdf
    1515#               3) http://www.awaresystems.be/imaging/tiff/tifftags.html
    1616#               4) http://www.remotesensing.org/libtiff/TIFFTechNote2.html
    17 #               5) http://www.asmail.be/msg0054681802.html
     17#               5) http://www.exif.org/dcf.PDF
    1818#               6) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
    1919#               7) http://www.fine-view.com/jp/lab/doc/ps6ffspecsv2.pdf
     
    2424#              12) http://www.broomscloset.com/closet/photo/exif/TAG2000-22_DIS12234-2.PDF
    2525#              13) http://www.microsoft.com/whdc/xps/wmphoto.mspx
     26#              14) http://www.asmail.be/msg0054681802.html
     27#              15) http://crousseau.free.fr/imgfmt_raw.htm
     28#              16) http://www.cybercom.net/~dcoffin/dcraw/
     29#              17) http://www.digitalpreservation.gov/formats/content/tiff_tags.shtml
     30#              18) http://www.asmail.be/msg0055568584.html
     31#              19) http://libpsd.graphest.com/files/Photoshop%20File%20Formats.pdf
     32#              20) http://tiki-lounge.com/~raf/tiff/fields.html
     33#              21) http://community.roxen.com/developers/idocs/rfc/rfc3949.html
     34#              22) http://tools.ietf.org/html/draft-ietf-fax-tiff-fx-extension1-01
     35#              23) MetaMorph Stack (STK) Image File Format:
     36#                  --> ftp://ftp.meta.moleculardevices.com/support/stack/STK.doc
     37#              24) http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-008-2010_E.pdf (Exif 2.3)
     38#              25) Vesa Kivisto private communication (7D)
     39#              26) Jeremy Brown private communication
     40#              JD) Jens Duttke private communication
    2641#------------------------------------------------------------------------------
    2742
     
    2944
    3045use strict;
    31 use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber
    32             %lightSource %compression %photometricInterpretation %orientation);
     46use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
     47            %lightSource %flash %compression %photometricInterpretation %orientation
     48            %subfileType);
    3349use Image::ExifTool qw(:DataAccess :Utils);
    3450use Image::ExifTool::MakerNotes;
    3551
    36 $VERSION = '2.42';
     52$VERSION = '3.21';
    3753
    3854sub ProcessExif($$$);
     
    4258sub EncodeExifText($$);
    4359sub ValidateIFD($;$);
     60sub ProcessTiffIFD($$$);
     61sub PrintParameter($$$);
     62sub GetOffList($$$$$);
     63sub PrintLensInfo($);
     64sub ConvertLensInfo($);
     65
     66# size limit for loading binary data block into memory
     67sub BINARY_DATA_LIMIT { return 10 * 1024 * 1024; }
    4468
    4569# byte sizes for the various EXIF format types below
    46 @formatSize = (undef,1,1,2,4,8,1,1,2,4,8,4,8,4,undef,undef,8,8,8);
     70@formatSize = (undef,1,1,2,4,8,1,1,2,4,8,4,8,4,2,8,8,8,8);
    4771
    4872@formatName = (
     
    5074    'int32u', 'rational64u', 'int8s', 'undef',
    5175    'int16s', 'int32s', 'rational64s', 'float',
    52     'double', 'ifd', undef, undef, # (14 is unicode, 15 is complex? http://remotesensing.org/libtiff/bigtiffdesign.html)
    53     'int64u', 'int64s', 'ifd8', # (new BigTIFF formats)
     76    'double', 'ifd', 'unicode', 'complex',
     77    'int64u', 'int64s', 'ifd64', # (new BigTIFF formats)
    5478);
    5579
     
    5781# (format types are all lower case)
    5882%formatNumber = (
    59     'int8u'         => 1,   # BYTE
    60     'string'        => 2,   # ASCII
    61     'int16u'        => 3,   # SHORT
    62     'int32u'        => 4,   # LONG
    63     'rational64u'   => 5,   # RATIONAL
    64     'int8s'         => 6,   # SBYTE
    65     'undef'         => 7,   # UNDEFINED
    66     'binary'        => 7,   # (treat binary data as undef)
    67     'int16s'        => 8,   # SSHORT
    68     'int32s'        => 9,   # SLONG
    69     'rational64s'   => 10,  # SRATIONAL
    70     'float'         => 11,  # FLOAT
    71     'double'        => 12,  # DOUBLE
    72     'ifd'           => 13,  # IFD (with int32u format)
    73     'int64u'        => 16,  # LONG8 [BigTIFF]
    74     'int64s'        => 17,  # SLONG8 [BigTIFF]
    75     'ifd8'          => 18,  # IFD8 (with int64u format) [BigTIFF]
     83    'int8u'       => 1,  # BYTE
     84    'string'      => 2,  # ASCII
     85    'int16u'      => 3,  # SHORT
     86    'int32u'      => 4,  # LONG
     87    'rational64u' => 5,  # RATIONAL
     88    'int8s'       => 6,  # SBYTE
     89    'undef'       => 7,  # UNDEFINED
     90    'binary'      => 7,  # (treat binary data as undef)
     91    'int16s'      => 8,  # SSHORT
     92    'int32s'      => 9,  # SLONG
     93    'rational64s' => 10, # SRATIONAL
     94    'float'       => 11, # FLOAT
     95    'double'      => 12, # DOUBLE
     96    'ifd'         => 13, # IFD (with int32u format)
     97    'unicode'     => 14, # UNICODE [see Note below]
     98    'complex'     => 15, # COMPLEX [see Note below]
     99    'int64u'      => 16, # LONG8 [BigTIFF]
     100    'int64s'      => 17, # SLONG8 [BigTIFF]
     101    'ifd64'       => 18, # IFD8 (with int64u format) [BigTIFF]
     102    # Note: unicode and complex types are not yet properly supported by ExifTool.
     103    # These are types which have been observed in the Adobe DNG SDK code, but
     104    # aren't fully supported there either.  We know the sizes, but that's about it.
     105    # We don't know if the unicode is null terminated, or the format for complex
     106    # (although I suspect it would be two 4-byte floats, real and imaginary).
     107);
     108
     109# lookup for integer format strings
     110%intFormat = (
     111    'int8u'  => 1,
     112    'int16u' => 3,
     113    'int32u' => 4,
     114    'int8s'  => 6,
     115    'int16s' => 8,
     116    'int32s' => 9,
     117    'ifd'    => 13,
     118    'int64u' => 16,
     119    'int64s' => 17,
     120    'ifd64'  => 18,
    76121);
    77122
    78123# EXIF LightSource PrintConv values
    79124%lightSource = (
     125    0 => 'Unknown',
    80126    1 => 'Daylight',
    81127    2 => 'Fluorescent',
    82     3 => 'Tungsten',
     128    3 => 'Tungsten (Incandescent)',
    83129    4 => 'Flash',
    84130    9 => 'Fine Weather',
    85131    10 => 'Cloudy',
    86132    11 => 'Shade',
    87     12 => 'Daylight Fluorescent',
    88     13 => 'Day White Fluorescent',
    89     14 => 'Cool White Fluorescent',
    90     15 => 'White Fluorescent',
     133    12 => 'Daylight Fluorescent',   # (D 5700 - 7100K)
     134    13 => 'Day White Fluorescent',  # (N 4600 - 5500K)
     135    14 => 'Cool White Fluorescent', # (W 3800 - 4500K)
     136    15 => 'White Fluorescent',      # (WW 3250 - 3800K)
     137    16 => 'Warm White Fluorescent', # (L 2600 - 3250K)
    91138    17 => 'Standard Light A',
    92139    18 => 'Standard Light B',
     
    100147);
    101148
     149# EXIF Flash values
     150%flash = (
     151    OTHER => sub {
     152        # translate "Off" and "On" when writing
     153        my ($val, $inv) = @_;
     154        return undef unless $inv and $val =~ /^(off|on)$/i;
     155        return lc $val eq 'off' ? 0x00 : 0x01;
     156    },
     157    0x00 => 'No Flash',
     158    0x01 => 'Fired',
     159    0x05 => 'Fired, Return not detected',
     160    0x07 => 'Fired, Return detected',
     161    0x08 => 'On, Did not fire', # not charged up?
     162    0x09 => 'On, Fired',
     163    0x0d => 'On, Return not detected',
     164    0x0f => 'On, Return detected',
     165    0x10 => 'Off, Did not fire',
     166    0x14 => 'Off, Did not fire, Return not detected',
     167    0x18 => 'Auto, Did not fire',
     168    0x19 => 'Auto, Fired',
     169    0x1d => 'Auto, Fired, Return not detected',
     170    0x1f => 'Auto, Fired, Return detected',
     171    0x20 => 'No flash function',
     172    0x30 => 'Off, No flash function',
     173    0x41 => 'Fired, Red-eye reduction',
     174    0x45 => 'Fired, Red-eye reduction, Return not detected',
     175    0x47 => 'Fired, Red-eye reduction, Return detected',
     176    0x49 => 'On, Red-eye reduction',
     177    0x4d => 'On, Red-eye reduction, Return not detected',
     178    0x4f => 'On, Red-eye reduction, Return detected',
     179    0x50 => 'Off, Red-eye reduction',
     180    0x58 => 'Auto, Did not fire, Red-eye reduction',
     181    0x59 => 'Auto, Fired, Red-eye reduction',
     182    0x5d => 'Auto, Fired, Red-eye reduction, Return not detected',
     183    0x5f => 'Auto, Fired, Red-eye reduction, Return detected',
     184);
     185
     186# TIFF Compression values
     187# (values with format "Xxxxx XXX Compressed" are used to identify RAW file types)
    102188%compression = (
    103189    1 => 'Uncompressed',
     
    111197    9 => 'JBIG B&W', #3
    112198    10 => 'JBIG Color', #3
     199    99 => 'JPEG', #16
     200    262 => 'Kodak 262', #16
    113201    32766 => 'Next', #3
    114     32769 => 'Epson ERF Compressed', #PH
     202    32767 => 'Sony ARW Compressed', #16
     203    32769 => 'Packed RAW', #PH (used by Epson, Nikon, Samsung)
     204    32770 => 'Samsung SRW Compressed', #PH
    115205    32771 => 'CCIRLEW', #3
    116206    32773 => 'PackBits',
    117207    32809 => 'Thunderscan', #3
     208    32867 => 'Kodak KDC Compressed', #PH
    118209    32895 => 'IT8CTPAD', #3
    119210    32896 => 'IT8LW', #3
     
    129220    34712 => 'JPEG 2000', #3
    130221    34713 => 'Nikon NEF Compressed', #PH
     222    34715 => 'JBIG2 TIFF FX', #20
     223    34718 => 'Microsoft Document Imaging (MDI) Binary Level Codec', #18
     224    34719 => 'Microsoft Document Imaging (MDI) Progressive Transform Codec', #18
     225    34720 => 'Microsoft Document Imaging (MDI) Vector', #18
    131226    65000 => 'Kodak DCR Compressed', #PH
    132227    65535 => 'Pentax PEF Compressed', #Jens
    133    
    134228);
    135229
     
    162256);
    163257
     258%subfileType = (
     259    0 => 'Full-resolution Image',
     260    1 => 'Reduced-resolution image',
     261    2 => 'Single page of multi-page image',
     262    3 => 'Single page of multi-page reduced-resolution image',
     263    4 => 'Transparency mask',
     264    5 => 'Transparency mask of reduced-resolution image',
     265    6 => 'Transparency mask of multi-page image',
     266    7 => 'Transparency mask of reduced-resolution multi-page image',
     267    0xffffffff => 'invalid', #(found in E5700 NEF's)
     268    BITMASK => {
     269        0 => 'Reduced resolution',
     270        1 => 'Single page',
     271        2 => 'Transparency mask',
     272        3 => 'TIFF/IT final page', #20
     273        4 => 'TIFF-FX mixed raster content', #20
     274    },
     275);
     276
     277# PrintConv for parameter tags
     278%Image::ExifTool::Exif::printParameter = (
     279    PrintConv => {
     280        0 => 'Normal',
     281        OTHER => \&Image::ExifTool::Exif::PrintParameter,
     282    },
     283);
     284
    164285# ValueConv that makes long values binary type
    165286my %longBin = (
     
    168289);
    169290
     291# PrintConv for SampleFormat (0x153)
     292my %sampleFormat = (
     293    1 => 'Unsigned',        # unsigned integer
     294    2 => 'Signed',          # two's complement signed integer
     295    3 => 'Float',           # IEEE floating point
     296    4 => 'Undefined',
     297    5 => 'Complex int',     # complex integer (ref 3)
     298    6 => 'Complex float',   # complex IEEE floating point (ref 3)
     299);
     300
    170301# main EXIF tag table
    171302%Image::ExifTool::Exif::Main = (
     
    173304    WRITE_PROC => \&WriteExif,
    174305    WRITE_GROUP => 'ExifIFD',   # default write group
     306    SET_GROUP1 => 1, # set group1 name to directory name for all tags in table
    175307    0x1 => {
    176308        Name => 'InteropIndex',
     
    182314        },
    183315    },
    184     0x2 => {
     316    0x2 => { #5
    185317        Name => 'InteropVersion',
    186318        Description => 'Interoperability Version',
     319        RawConv => '$val=~s/\0+$//; $val',  # (some idiots add null terminators)
    187320    },
    188321    0x0b => { #PH
     
    193326        Name => 'SubfileType',
    194327        # set priority directory if this is the full resolution image
    195         RawConv => '$self->SetPriorityDir() if $val == 0; $val',
    196         PrintConv => {
    197             0 => 'Full-resolution Image',
    198             1 => 'Reduced-resolution image',
    199             2 => 'Single page of multi-page image',
    200             3 => 'Single page of multi-page reduced-resolution image',
    201             4 => 'Transparency mask',
    202             5 => 'Transparency mask of reduced-resolution image',
    203             6 => 'Transparency mask of multi-page image',
    204             7 => 'Transparency mask of reduced-resolution multi-page image',
    205         },
     328        DataMember => 'SubfileType',
     329        RawConv => '$self->SetPriorityDir() if $val eq "0"; $$self{SubfileType} = $val',
     330        PrintConv => \%subfileType,
    206331    },
    207332    0xff => {
    208333        Name => 'OldSubfileType',
    209334        # set priority directory if this is the full resolution image
    210         RawConv => '$self->SetPriorityDir() if $val == 1; $val',
     335        RawConv => '$self->SetPriorityDir() if $val eq "1"; $val',
    211336        PrintConv => {
    212337            1 => 'Full-resolution image',
     
    220345        # so it will show up in the group lists
    221346        Groups => { 1 => 'IFD1' },
    222         # set Priority to zero so the value found in the first IFD (IFD0) doesn't
    223         # get overwritten by subsequent IFD's (same for ImageHeight below)
     347        # Note: priority 0 tags automatically have their priority increased for the
     348        # priority direcory (the directory with a SubfileType of "Full-resolution image")
    224349        Priority => 0,
    225350    },
    226351    0x101 => {
    227352        Name => 'ImageHeight',
     353        Notes => 'called ImageLength by the EXIF spec.',
    228354        Priority => 0,
    229355    },
     
    234360    0x103 => {
    235361        Name => 'Compression',
     362        DataMember => 'Compression',
     363        SeparateTable => 'Compression',
     364        RawConv => q{
     365            Image::ExifTool::Exif::IdentifyRawFile($self, $val);
     366            return $$self{Compression} = $val;
     367        },
    236368        PrintConv => \%compression,
    237369        Priority => 0,
     
    267399        Name => 'Make',
    268400        Groups => { 2 => 'Camera' },
    269         DataMember => 'CameraMake',
    270         # save this value as an ExifTool member variable
    271         RawConv => '$self->{CameraMake} = $val',
     401        DataMember => 'Make',
     402        # remove trailing blanks and save as an ExifTool member variable
     403        RawConv => '$val =~ s/\s+$//; $$self{Make} = $val',
     404        # NOTE: trailing "blanks" (spaces) are removed from all EXIF tags which
     405        # may be "unknown" (filled with spaces) according to the EXIF spec.
     406        # This allows conditional replacement with "exiftool -TAG-= -TAG=VALUE".
     407        # - also removed are any other trailing whitespace characters
    272408    },
    273409    0x110 => {
     
    275411        Description => 'Camera Model Name',
    276412        Groups => { 2 => 'Camera' },
    277         DataMember => 'CameraModel',
    278         # save this value as an ExifTool member variable
    279         RawConv => '$self->{CameraModel} = $val',
     413        DataMember => 'Model',
     414        # remove trailing blanks and save as an ExifTool member variable
     415        RawConv => '$val =~ s/\s+$//; $$self{Model} = $val',
    280416    },
    281417    0x111 => [
    282418        {
    283419            Condition => q[
    284                 ($self->{TIFF_TYPE} ne "CR2" or $self->{DIR_NAME} ne "IFD0") and
    285                 ($self->{TIFF_TYPE} ne "DNG" or $self->{DIR_NAME} !~ /^SubIFD[12]$/)
     420                $$self{TIFF_TYPE} eq 'MRW' and $$self{DIR_NAME} eq 'IFD0' and
     421                $$self{Model} =~ /^DiMAGE A200/
     422            ],
     423            Name => 'StripOffsets',
     424            IsOffset => 1,
     425            OffsetPair => 0x117,  # point to associated byte counts
     426            # A200 stores this information in the wrong byte order!!
     427            ValueConv => '$val=join(" ",unpack("N*",pack("V*",split(" ",$val))));\$val',
     428            ByteOrder => 'LittleEndian',
     429        },
     430        {
     431            Condition => q[
     432                ($$self{TIFF_TYPE} ne 'CR2' or $$self{DIR_NAME} ne 'IFD0') and
     433                ($$self{TIFF_TYPE} ne 'DNG' or $$self{DIR_NAME} !~ /^SubIFD[12]$/)
    286434            ],
    287435            Name => 'StripOffsets',
     
    291439        },
    292440        {
    293             Condition => '$self->{DIR_NAME} eq "IFD0"',
     441            Condition => '$$self{DIR_NAME} eq "IFD0"',
    294442            Name => 'PreviewImageStart',
    295443            IsOffset => 1,
     
    302450            Writable => 'int32u',
    303451            WriteGroup => 'IFD0',
    304             WriteCondition => '$self->{TIFF_TYPE} eq "CR2"',
     452            WriteCondition => '$$self{TIFF_TYPE} eq "CR2"',
    305453            Protected => 2,
    306454        },
    307455        {
    308             Condition => '$self->{DIR_NAME} eq "SubIFD1"',
     456            Condition => '$$self{DIR_NAME} eq "SubIFD1"',
    309457            Name => 'PreviewImageStart',
    310458            IsOffset => 1,
     
    313461            Writable => 'int32u',
    314462            WriteGroup => 'SubIFD1',
    315             WriteCondition => '$self->{TIFF_TYPE} eq "DNG"',
     463            WriteCondition => '$$self{TIFF_TYPE} eq "DNG"',
    316464            Protected => 2,
    317465        },
     
    323471            Writable => 'int32u',
    324472            WriteGroup => 'SubIFD2',
    325             WriteCondition => '$self->{TIFF_TYPE} eq "DNG"',
     473            WriteCondition => '$$self{TIFF_TYPE} eq "DNG"',
    326474            Protected => 2,
    327475        },
     
    330478        Name => 'Orientation',
    331479        PrintConv => \%orientation,
    332         Priority => 0,  # so IFD1 doesn't take precedence
     480        Priority => 0,  # so PRIORITY_DIR takes precedence
    333481    },
    334482    0x115 => {
     
    343491        {
    344492            Condition => q[
    345                 ($self->{TIFF_TYPE} ne "CR2" or $self->{DIR_NAME} ne "IFD0") and
    346                 ($self->{TIFF_TYPE} ne "DNG" or $self->{DIR_NAME} !~ /^SubIFD[12]$/)
     493                $$self{TIFF_TYPE} eq 'MRW' and $$self{DIR_NAME} eq 'IFD0' and
     494                $$self{Model} =~ /^DiMAGE A200/
     495            ],
     496            Name => 'StripByteCounts',
     497            OffsetPair => 0x111,   # point to associated offset
     498            # A200 stores this information in the wrong byte order!!
     499            ValueConv => '$val=join(" ",unpack("N*",pack("V*",split(" ",$val))));\$val',
     500            ByteOrder => 'LittleEndian',
     501        },
     502        {
     503            Condition => q[
     504                ($$self{TIFF_TYPE} ne 'CR2' or $$self{DIR_NAME} ne 'IFD0') and
     505                ($$self{TIFF_TYPE} ne 'DNG' or $$self{DIR_NAME} !~ /^SubIFD[12]$/)
    347506            ],
    348507            Name => 'StripByteCounts',
     
    351510        },
    352511        {
    353             Condition => '$self->{DIR_NAME} eq "IFD0"',
     512            Condition => '$$self{DIR_NAME} eq "IFD0"',
    354513            Name => 'PreviewImageLength',
    355514            OffsetPair => 0x111,
     
    361520            Writable => 'int32u',
    362521            WriteGroup => 'IFD0',
    363             WriteCondition => '$self->{TIFF_TYPE} eq "CR2"',
     522            WriteCondition => '$$self{TIFF_TYPE} eq "CR2"',
    364523            Protected => 2,
    365524        },
    366525        {
    367             Condition => '$self->{DIR_NAME} eq "SubIFD1"',
     526            Condition => '$$self{DIR_NAME} eq "SubIFD1"',
    368527            Name => 'PreviewImageLength',
    369528            OffsetPair => 0x111,
     
    371530            Writable => 'int32u',
    372531            WriteGroup => 'SubIFD1',
    373             WriteCondition => '$self->{TIFF_TYPE} eq "DNG"',
     532            WriteCondition => '$$self{TIFF_TYPE} eq "DNG"',
    374533            Protected => 2,
    375534        },
     
    380539            Writable => 'int32u',
    381540            WriteGroup => 'SubIFD2',
    382             WriteCondition => '$self->{TIFF_TYPE} eq "DNG"',
     541            WriteCondition => '$$self{TIFF_TYPE} eq "DNG"',
    383542            Protected => 2,
    384543        },
     
    388547    0x11a => {
    389548        Name => 'XResolution',
    390         Priority => 0,  # so IFD0 takes priority over IFD1
     549        Priority => 0,  # so PRIORITY_DIR takes precedence
    391550    },
    392551    0x11b => {
     
    446605    0x128 => {
    447606        Name => 'ResolutionUnit',
     607        Notes => 'the value 1 is not standard EXIF',
    448608        PrintConv => {
    449609            1 => 'None',
     
    461621    0x131 => {
    462622        Name => 'Software',
     623        RawConv => '$val =~ s/\s+$//; $val', # trim trailing blanks
    463624    },
    464625    0x132 => {
    465626        Name => 'ModifyDate',
    466627        Groups => { 2 => 'Time' },
     628        Notes => 'called DateTime by the EXIF spec.',
    467629        PrintConv => '$self->ConvertDateTime($val)',
    468630    },
     
    470632        Name => 'Artist',
    471633        Groups => { 2 => 'Author' },
     634        Notes => 'becomes a list-type tag when the MWG module is loaded',
     635        RawConv => '$val =~ s/\s+$//; $val', # trim trailing blanks
    472636    },
    473637    0x13c => 'HostComputer',
     
    516680    },
    517681    0x148 => 'ConsecutiveBadFaxLines', #3
    518     0x14a => {
    519         Name => 'SubIFD',
    520         Groups => { 1 => 'SubIFD' },
    521         Flags => 'SubIFD',
    522         SubDirectory => {
    523             Start => '$val',
    524             MaxSubdirs => 3,
    525         },
    526     },
     682    0x14a => [
     683        {
     684            Name => 'SubIFD',
     685            # use this opportunity to identify an ARW image, and if so we
     686            # must decide if this is a SubIFD or the A100 raw data
     687            # (use SubfileType, Compression and FILE_TYPE to identify ARW/SR2,
     688            # then call SetARW to finish the job)
     689            Condition => q{
     690                $$self{DIR_NAME} ne 'IFD0' or $$self{FILE_TYPE} ne 'TIFF' or
     691                $$self{Make} !~ /^SONY/ or
     692                not $$self{SubfileType} or $$self{SubfileType} != 1 or
     693                not $$self{Compression} or $$self{Compression} != 6 or
     694                not require Image::ExifTool::Sony or
     695                Image::ExifTool::Sony::SetARW($self, $valPt)
     696            },
     697            Groups => { 1 => 'SubIFD' },
     698            Flags => 'SubIFD',
     699            SubDirectory => {
     700                Start => '$val',
     701                MaxSubdirs => 3,
     702            },
     703        },
     704        { #16
     705            Name => 'A100DataOffset',
     706            Notes => 'the data offset in original Sony DSLR-A100 ARW images',
     707            DataMember => 'A100DataOffset',
     708            RawConv => '$$self{A100DataOffset} = $val',
     709            IsOffset => 1,
     710        },
     711    ],
    527712    0x14c => {
    528713        Name => 'InkSet',
     
    536721    0x150 => 'DotRange',
    537722    0x151 => 'TargetPrinter',
    538     0x152 => 'ExtraSamples',
     723    0x152 => {
     724        Name => 'ExtraSamples',
     725        PrintConv => { #20
     726            0 => 'Unspecified',
     727            1 => 'Associated Alpha',
     728            2 => 'Unassociated Alpha',
     729        },
     730    },
    539731    0x153 => {
    540732        Name => 'SampleFormat',
    541         PrintConv => {
    542             1 => 'Unsigned integer',
    543             2 => "Two's complement signed integer",
    544             3 => 'IEEE floating point',
    545             4 => 'Undefined',
    546             5 => 'Complex integer', #3
    547             6 => 'IEEE floating point', #3
    548         },
     733        Notes => 'SamplesPerPixel values',
     734        PrintConvColumns => 2,
     735        PrintConv => [ \%sampleFormat, \%sampleFormat, \%sampleFormat, \%sampleFormat ],
    549736    },
    550737    0x154 => 'SMinSampleValue',
     
    569756        },
    570757    },
     758    # 0x181 => 'Decode', #20 (typo! - should be 0x1b1, ref 21)
     759    # 0x182 => 'DefaultImageColor', #20 (typo! - should be 0x1b2, ref 21)
    571760    0x190 => { #3
    572761        Name => 'GlobalParametersIFD',
     
    592781            5 => 'Lossless color and grayscale, L',
    593782            6 => 'Mixed raster content, M',
     783            7 => 'Profile T', #20
     784            255 => 'Multi Profiles', #20
    594785        },
    595786    },
     
    609800    0x195 => 'ModeNumber', #3
    610801    0x1b1 => 'Decode', #3
    611     0x1b2 => 'DefaultImageColor', #3
     802    0x1b2 => 'DefaultImageColor', #3 (changed to ImageBaseColor, ref 21)
     803    0x1b3 => 'T82Options', #20
     804    0x1b5 => { #19
     805        Name => 'JPEGTables',
     806        Binary => 1,
     807    },
    612808    0x200 => {
    613809        Name => 'JPEGProc',
     
    620816        {
    621817            Name => 'ThumbnailOffset',
     818            Notes => q{
     819                ThumbnailOffset in IFD1 of JPEG and some TIFF-based images, IFD0 of MRW
     820                images and AVI videos, and the SubIFD in IFD1 of SRW images;
     821                PreviewImageStart in MakerNotes and IFD0 of ARW and SR2 images;
     822                JpgFromRawStart in SubIFD of NEF images and IFD2 of PEF images; and
     823                OtherImageStart in everything else
     824            },
    622825            # thumbnail is found in IFD1 of JPEG and TIFF images, and
    623826            # IFD0 of EXIF information in FujiFilm AVI (RIFF) videos
    624827            Condition => q{
    625                 $self->{DIR_NAME} eq 'IFD1' or
    626                 ($self->{FILE_TYPE} eq 'RIFF' and $self->{DIR_NAME} eq 'IFD0')
     828                $$self{DIR_NAME} eq 'IFD1' or
     829                ($$self{FILE_TYPE} eq 'RIFF' and $$self{DIR_NAME} eq 'IFD0')
    627830            },
    628831            IsOffset => 1,
     
    631834            Writable => 'int32u',
    632835            WriteGroup => 'IFD1',
    633             WriteCondition => '$$self{FILE_TYPE} ne "TIFF"',
     836            # according to the EXIF spec. a JPEG-compressed thumbnail image may not
     837            # be stored in a TIFF file, but these TIFF-based RAW image formats
     838            # use IFD1 for a JPEG-compressed thumbnail:  CR2, ARW, SR2 and PEF.
     839            # (SRF also stores a JPEG image in IFD1, but it is actually a preview
     840            # and we don't yet write SRF anyway)
     841            WriteCondition => q{
     842                $$self{FILE_TYPE} ne "TIFF" or
     843                $$self{TIFF_TYPE} =~ /^(CR2|ARW|SR2|PEF)$/
     844            },
     845            Protected => 2,
     846        },
     847        {
     848            Name => 'ThumbnailOffset',
     849            # thumbnail in IFD0 of MRW images (Minolta A200)
     850            Condition => '$$self{DIR_NAME} eq "IFD0" and $$self{TIFF_TYPE} eq "MRW"',
     851            IsOffset => 1,
     852            OffsetPair => 0x202,
     853            # A200 uses the wrong base offset for this pointer!!
     854            WrongBase => '$$self{Model} =~ /^DiMAGE A200/ ? $$self{MRW_WrongBase} : undef',
     855            DataTag => 'ThumbnailImage',
     856            Writable => 'int32u',
     857            WriteGroup => 'IFD0',
     858            WriteCondition => '$$self{FILE_TYPE} eq "MRW"',
     859            Protected => 2,
     860        },
     861        {
     862            Name => 'ThumbnailOffset',
     863            # in SubIFD of IFD1 in Samsung SRW images
     864            Condition => q{
     865                $$self{TIFF_TYPE} eq 'SRW' and $$self{DIR_NAME} eq 'SubIFD' and
     866                $$self{PATH}[-2] eq 'IFD1'
     867            },
     868            IsOffset => 1,
     869            OffsetPair => 0x202,
     870            DataTag => 'ThumbnailImage',
     871            Writable => 'int32u',
     872            WriteGroup => 'SubIFD',
     873            WriteCondition => '$$self{TIFF_TYPE} eq "SRW"',
    634874            Protected => 2,
    635875        },
    636876        {
    637877            Name => 'PreviewImageStart',
    638             Condition => '$self->{DIR_NAME} eq "MakerNotes"',
     878            Condition => '$$self{DIR_NAME} eq "MakerNotes"',
    639879            IsOffset => 1,
    640880            OffsetPair => 0x202,
     
    642882            Writable => 'int32u',
    643883            WriteGroup => 'MakerNotes',
     884            # (no WriteCondition necessary because MakerNotes won't be created)
     885            Protected => 2,
     886        },
     887        {
     888            Name => 'PreviewImageStart',
     889            # PreviewImage in IFD0 of ARW and SR2 files for all models
     890            Condition => '$$self{DIR_NAME} eq "IFD0" and $$self{TIFF_TYPE} =~ /^(ARW|SR2)$/',
     891            IsOffset => 1,
     892            OffsetPair => 0x202,
     893            DataTag => 'PreviewImage',
     894            Writable => 'int32u',
     895            WriteGroup => 'IFD0',
     896            WriteCondition => '$$self{TIFF_TYPE} =~ /^(ARW|SR2)$/',
    644897            Protected => 2,
    645898        },
    646899        {
    647900            Name => 'JpgFromRawStart',
    648             Condition => '$self->{DIR_NAME} eq "SubIFD"',
     901            Condition => '$$self{DIR_NAME} eq "SubIFD"',
    649902            IsOffset => 1,
    650903            OffsetPair => 0x202,
     
    652905            Writable => 'int32u',
    653906            WriteGroup => 'SubIFD',
    654             # JpgFromRaw is in SubIFD of NEF files
    655             WriteCondition => '$self->{TIFF_TYPE} eq "NEF"',
     907            # JpgFromRaw is in SubIFD of NEF, NRW and SRW files
     908            WriteCondition => '$$self{TIFF_TYPE} =~ /^(NEF|NRW|SRW)$/',
    656909            Protected => 2,
    657910        },
    658911        {
    659912            Name => 'JpgFromRawStart',
    660             Condition => '$self->{DIR_NAME} eq "IFD2"',
     913            Condition => '$$self{DIR_NAME} eq "IFD2"',
    661914            IsOffset => 1,
    662915            OffsetPair => 0x202,
     
    665918            WriteGroup => 'IFD2',
    666919            # JpgFromRaw is in IFD2 of PEF files
    667             WriteCondition => '$self->{TIFF_TYPE} eq "PEF"',
     920            WriteCondition => '$$self{TIFF_TYPE} eq "PEF"',
    668921            Protected => 2,
    669922        },
     
    677930        {
    678931            Name => 'ThumbnailLength',
     932            Notes => q{
     933                ThumbnailLength in IFD1 of JPEG and some TIFF-based images, IFD0 of MRW
     934                images and AVI videos, and the SubIFD in IFD1 of SRW images;
     935                PreviewImageLength in MakerNotes and IFD0 of ARW and SR2 images;
     936                JpgFromRawLength in SubIFD of NEF images, and IFD2 of PEF images; and
     937                OtherImageLength in everything else
     938            },
    679939            Condition => q{
    680                 $self->{DIR_NAME} eq 'IFD1' or
    681                 ($self->{FILE_TYPE} eq 'RIFF' and $self->{DIR_NAME} eq 'IFD0')
     940                $$self{DIR_NAME} eq 'IFD1' or
     941                ($$self{FILE_TYPE} eq 'RIFF' and $$self{DIR_NAME} eq 'IFD0')
    682942            },
    683943            OffsetPair => 0x201,
     
    685945            Writable => 'int32u',
    686946            WriteGroup => 'IFD1',
    687             WriteCondition => '$$self{FILE_TYPE} ne "TIFF"',
     947            WriteCondition => q{
     948                $$self{FILE_TYPE} ne "TIFF" or
     949                $$self{TIFF_TYPE} =~ /^(CR2|ARW|SR2|PEF)$/
     950            },
     951            Protected => 2,
     952        },
     953        {
     954            Name => 'ThumbnailLength',
     955            # thumbnail in IFD0 of MRW images (Minolta A200)
     956            Condition => '$$self{DIR_NAME} eq "IFD0" and $$self{TIFF_TYPE} eq "MRW"',
     957            OffsetPair => 0x201,
     958            DataTag => 'ThumbnailImage',
     959            Writable => 'int32u',
     960            WriteGroup => 'IFD0',
     961            WriteCondition => '$$self{FILE_TYPE} eq "MRW"',
     962            Protected => 2,
     963        },
     964        {
     965            Name => 'ThumbnailLength',
     966            # in SubIFD of IFD1 in Samsung SRW images
     967            Condition => q{
     968                $$self{TIFF_TYPE} eq 'SRW' and $$self{DIR_NAME} eq 'SubIFD' and
     969                $$self{PATH}[-2] eq 'IFD1'
     970            },
     971            OffsetPair => 0x201,
     972            DataTag => 'ThumbnailImage',
     973            Writable => 'int32u',
     974            WriteGroup => 'SubIFD',
     975            WriteCondition => '$$self{TIFF_TYPE} eq "SRW"',
    688976            Protected => 2,
    689977        },
    690978        {
    691979            Name => 'PreviewImageLength',
    692             Condition => '$self->{DIR_NAME} eq "MakerNotes"',
     980            Condition => '$$self{DIR_NAME} eq "MakerNotes"',
    693981            OffsetPair => 0x201,
    694982            DataTag => 'PreviewImage',
    695983            Writable => 'int32u',
    696984            WriteGroup => 'MakerNotes',
     985            # (no WriteCondition necessary because MakerNotes won't be created)
     986            Protected => 2,
     987        },
     988        {
     989            Name => 'PreviewImageLength',
     990            # PreviewImage in IFD0 of ARW and SR2 files for all models
     991            Condition => '$$self{DIR_NAME} eq "IFD0" and $$self{TIFF_TYPE} =~ /^(ARW|SR2)$/',
     992            OffsetPair => 0x201,
     993            DataTag => 'PreviewImage',
     994            Writable => 'int32u',
     995            WriteGroup => 'IFD0',
     996            WriteCondition => '$$self{TIFF_TYPE} =~ /^(ARW|SR2)$/',
    697997            Protected => 2,
    698998        },
    699999        {
    7001000            Name => 'JpgFromRawLength',
    701             Condition => '$self->{DIR_NAME} eq "SubIFD"',
     1001            Condition => '$$self{DIR_NAME} eq "SubIFD"',
    7021002            OffsetPair => 0x201,
    7031003            DataTag => 'JpgFromRaw',
    7041004            Writable => 'int32u',
    7051005            WriteGroup => 'SubIFD',
    706             WriteCondition => '$self->{TIFF_TYPE} eq "NEF"',
     1006            WriteCondition => '$$self{TIFF_TYPE} =~ /^(NEF|NRW|SRW)$/',
    7071007            Protected => 2,
    7081008        },
    7091009        {
    7101010            Name => 'JpgFromRawLength',
    711             Condition => '$self->{DIR_NAME} eq "IFD2"',
     1011            Condition => '$$self{DIR_NAME} eq "IFD2"',
    7121012            OffsetPair => 0x201,
    7131013            DataTag => 'JpgFromRaw',
    7141014            Writable => 'int32u',
    7151015            WriteGroup => 'IFD2',
    716             WriteCondition => '$self->{TIFF_TYPE} eq "PEF"',
     1016            WriteCondition => '$$self{TIFF_TYPE} eq "PEF"',
    7171017            Protected => 2,
    7181018        },
     
    7251025    0x205 => 'JPEGLosslessPredictors',
    7261026    0x206 => 'JPEGPointTransforms',
    727     0x207 => 'JPEGQTables',
    728     0x208 => 'JPEGDCTables',
    729     0x209 => 'JPEGACTables',
     1027    0x207 => {
     1028        Name => 'JPEGQTables',
     1029        IsOffset => 1,
     1030        # this tag is not supported for writing, so define an
     1031        # invalid offset pair to cause a "No size tag" error to be
     1032        # generated if we try to write a file containing this tag
     1033        OffsetPair => -1,
     1034    },
     1035    0x208 => {
     1036        Name => 'JPEGDCTables',
     1037        IsOffset => 1,
     1038        OffsetPair => -1, # (see comment for JPEGQTables)
     1039    },
     1040    0x209 => {
     1041        Name => 'JPEGACTables',
     1042        IsOffset => 1,
     1043        OffsetPair => -1, # (see comment for JPEGQTables)
     1044    },
    7301045    0x211 => {
    7311046        Name => 'YCbCrCoefficients',
     
    7341049    0x212 => {
    7351050        Name => 'YCbCrSubSampling',
    736         PrintConv => {
    737             '1 1' => 'YCbCr4:4:4 (1 1)', #PH
    738             '2 1' => 'YCbCr4:2:2 (2 1)', #6
    739             '2 2' => 'YCbCr4:2:0 (2 2)', #6
    740             '4 1' => 'YCbCr4:1:1 (4 1)', #6
    741             '4 2' => 'YCbCr4:1:0 (4 2)', #PH
    742             '1 2' => 'YCbCr4:4:0 (1 2)', #PH
    743         },
     1051        PrintConvColumns => 2,
     1052        PrintConv => \%Image::ExifTool::JPEG::yCbCrSubSampling,
    7441053        Priority => 0,
    7451054    },
     
    7581067    0x22f => 'StripRowCounts',
    7591068    0x2bc => {
    760         Name => 'ApplicationNotes',
     1069        Name => 'ApplicationNotes', # (writable directory!)
     1070        Writable => 'int8u',
     1071        Format => 'undef',
     1072        Flags => [ 'Binary', 'Protected' ],
    7611073        # this could be an XMP block
    7621074        SubDirectory => {
     
    7651077        },
    7661078    },
    767     0x1000 => 'RelatedImageFileFormat',
    768     0x1001 => 'RelatedImageWidth',
    769     0x1002 => 'RelatedImageLength',
     1079    0x3e7 => 'USPTOMiscellaneous', #20
     1080    0x1000 => 'RelatedImageFileFormat', #5
     1081    0x1001 => 'RelatedImageWidth', #5
     1082    0x1002 => { #5
     1083        Name => 'RelatedImageHeight',
     1084        Notes => 'called RelatedImageLength by the DCF spec.',
     1085    },
    7701086    # (0x474x tags written by MicrosoftPhoto)
    7711087    0x4746 => 'Rating', #PH
     1088    0x4747 => { # (written by Digital Image Pro)
     1089        Name => 'XP_DIP_XML',
     1090        Format => 'undef',
     1091        # the following reference indicates this is Unicode:
     1092        # http://social.msdn.microsoft.com/Forums/en-US/isvvba/thread/ce6edcbb-8fc2-40c6-ad98-85f5d835ddfb
     1093        ValueConv => '$self->Decode($val,"UCS2","II")',
     1094    },
     1095    0x4748 => {
     1096        Name => 'StitchInfo',
     1097        SubDirectory => {
     1098            TagTable => 'Image::ExifTool::Microsoft::Stitch',
     1099            ByteOrder => 'LittleEndian', #PH (NC)
     1100        },
     1101    },
    7721102    0x4749 => 'RatingPercent', #PH
    7731103    0x800d => 'ImageID', #10
    774     0x80a4 => 'WangAnnotation',
     1104    0x80a3 => { Name => 'WangTag1', Binary => 1 }, #20
     1105    0x80a4 => { Name => 'WangAnnotation', Binary => 1 },
     1106    0x80a5 => { Name => 'WangTag3', Binary => 1 }, #20
     1107    0x80a6 => { #20
     1108        Name => 'WangTag4',
     1109        PrintConv => 'length($val) <= 64 ? $val : \$val',
     1110    },
    7751111    0x80e3 => 'Matteing', #9
    7761112    0x80e4 => 'DataType', #9
     
    7781114    0x80e6 => 'TileDepth', #9
    7791115    0x827d => 'Model2',
    780     0x828d => 'CFARepeatPatternDim',
    781     0x828e => 'CFAPattern2',
    782     0x828f => {
     1116    0x828d => 'CFARepeatPatternDim', #12
     1117    0x828e => {
     1118        Name => 'CFAPattern2', #12
     1119        Format => 'int8u',  # (written incorrectly as 'undef' in Nikon NRW images)
     1120    },
     1121    0x828f => { #12
    7831122        Name => 'BatteryLevel',
    7841123        Groups => { 2 => 'Camera' },
     1124    },
     1125    0x8290 => {
     1126        Name => 'KodakIFD',
     1127        Groups => { 1 => 'KodakIFD' },
     1128        Flags => 'SubIFD',
     1129        Notes => 'used in various types of Kodak images',
     1130        SubDirectory => {
     1131            TagTable => 'Image::ExifTool::Kodak::IFD',
     1132            DirName => 'KodakIFD',
     1133            Start => '$val',
     1134        },
    7851135    },
    7861136    0x8298 => {
    7871137        Name => 'Copyright',
    7881138        Groups => { 2 => 'Author' },
     1139        Format => 'undef',
     1140        Notes => q{
     1141            may contain copyright notices for photographer and editor, separated by a
     1142            newline in ExifTool
     1143        },
     1144        # internally the strings are separated by a null character in this format:
     1145        # Photographer only: photographer + NULL
     1146        # Both:              photographer + NULL + editor + NULL
     1147        # Editor only:       SPACE + NULL + editor + NULL
     1148        # 1) translate first NULL to a newline, removing trailing blanks
     1149        # 2) truncate at second NULL and remove trailing blanks
     1150        # 3) remove trailing newline if it exists
     1151        # (this is done as a RawConv so conditional replaces will work properly)
     1152        RawConv => '$_=$val; s/ *\0/\n/; s/ *\0.*//s; s/\n$//; $_',
    7891153    },
    7901154    0x829a => {
     
    8081172    0x82ac => 'MDFileUnits', #3
    8091173    0x830e => 'PixelScale',
    810     0x83bb => {
    811         Name => 'IPTC-NAA',
     1174    0x8335 => 'AdventScale', #20
     1175    0x8336 => 'AdventRevision', #20
     1176    0x835c => 'UIC1Tag', #23
     1177    0x835d => 'UIC2Tag', #23
     1178    0x835e => 'UIC3Tag', #23
     1179    0x835f => 'UIC4Tag', #23
     1180    0x83bb => { #12
     1181        Name => 'IPTC-NAA', # (writable directory!)
     1182        # this should actually be written as 'undef' (see
     1183        # http://www.awaresystems.be/imaging/tiff/tifftags/iptc.html),
     1184        # but Photoshop writes it as int32u and Nikon Capture won't read
     1185        # anything else, so we do the same thing here...  Doh!
     1186        Format => 'undef',      # convert binary values as undef
     1187        Writable => 'int32u',   # but write int32u format code in IFD
     1188        WriteGroup => 'IFD0',
     1189        Flags => [ 'Binary', 'Protected' ],
    8121190        SubDirectory => {
    8131191            DirName => 'IPTC',
     
    8181196    0x847f => 'IntergraphFlagRegisters', #3
    8191197    0x8480 => 'IntergraphMatrix',
     1198    0x8481 => 'INGRReserved', #20
    8201199    0x8482 => {
    8211200        Name => 'ModelTiePoint',
     
    8251204    0x84e1 => 'ColorSequence', #9
    8261205    0x84e2 => 'IT8Header', #9
    827     0x84e3 => 'RasterPadding', #9
     1206    0x84e3 => { #9
     1207        Name => 'RasterPadding',
     1208        PrintConv => { #20
     1209            0 => 'Byte',
     1210            1 => 'Word',
     1211            2 => 'Long Word',
     1212            9 => 'Sector',
     1213            10 => 'Long Sector',
     1214        },
     1215    },
    8281216    0x84e4 => 'BitsPerRunLength', #9
    8291217    0x84e5 => 'BitsPerExtendedRunLength', #9
    8301218    0x84e6 => 'ColorTable', #9
    831     0x84e7 => 'ImageColorIndicator', #9
    832     0x84e8 => 'BackgroundColorIndicator', #9
     1219    0x84e7 => { #9
     1220        Name => 'ImageColorIndicator',
     1221        PrintConv => { #20
     1222            0 => 'Unspecified Image Color',
     1223            1 => 'Specified Image Color',
     1224        },
     1225    },
     1226    0x84e8 => { #9
     1227        Name => 'BackgroundColorIndicator',
     1228        PrintConv => { #20
     1229            0 => 'Unspecified Background Color',
     1230            1 => 'Specified Background Color',
     1231        },
     1232    },
    8331233    0x84e9 => 'ImageColorValue', #9
    8341234    0x84ea => 'BackgroundColorValue', #9
     
    8361236    0x84ec => 'TransparencyIndicator', #9
    8371237    0x84ed => 'ColorCharacterization', #9
    838     0x84ee => 'HCUsage', #9
     1238    0x84ee => { #9
     1239        Name => 'HCUsage',
     1240        PrintConv => { #20
     1241            0 => 'CT',
     1242            1 => 'Line Art',
     1243            2 => 'Trap',
     1244        },
     1245    },
     1246    0x84ef => 'TrapIndicator', #17
     1247    0x84f0 => 'CMYKEquivalent', #17
    8391248    0x8546 => { #11
    8401249        Name => 'SEMInfo',
     
    8441253        Name => 'AFCP_IPTC',
    8451254        SubDirectory => {
    846             DirName => 'IPTC2', # change name because this isn't the IPTC we want to write
     1255            # must change directory name so we don't create this directory
     1256            DirName => 'AFCP_IPTC',
    8471257            TagTable => 'Image::ExifTool::IPTC::Main',
    8481258        },
    8491259    },
     1260    0x85b8 => 'PixelMagicJBIGOptions', #20
    8501261    0x85d8 => {
    8511262        Name => 'ModelTransform',
    8521263        Groups => { 2 => 'Location' },
    8531264    },
     1265    0x8602 => { #16
     1266        Name => 'WB_GRGBLevels',
     1267        Notes => 'found in IFD0 of Leaf MOS images',
     1268    },
     1269    # 0x8603 - Leaf CatchLight color matrix (ref 16)
    8541270    0x8606 => {
    8551271        Name => 'LeafData',
     
    8601276        },
    8611277    },
    862     0x8649 => {
     1278    0x8649 => { #19
    8631279        Name => 'PhotoshopSettings',
    8641280        Format => 'binary',
     
    8711287        Name => 'ExifOffset',
    8721288        Groups => { 1 => 'ExifIFD' },
    873         Flags => 'SubIFD',
     1289        SubIFD => 2,
    8741290        SubDirectory => {
    8751291            DirName => 'ExifIFD',
     
    8831299        },
    8841300    },
     1301    0x877f => { #20
     1302        Name => 'TIFF_FXExtensions',
     1303        PrintConv => { BITMASK => {
     1304            0 => 'Resolution/Image Width',
     1305            1 => 'N Layer Profile M',
     1306            2 => 'Shared Data',
     1307            3 => 'B&W JBIG2',
     1308            4 => 'JBIG2 Profile M',
     1309        }},
     1310    },
     1311    0x8780 => { #20
     1312        Name => 'MultiProfiles',
     1313        PrintConv => { BITMASK => {
     1314            0 => 'Profile S',
     1315            1 => 'Profile F',
     1316            2 => 'Profile J',
     1317            3 => 'Profile C',
     1318            4 => 'Profile L',
     1319            5 => 'Profile M',
     1320            6 => 'Profile T',
     1321            7 => 'Resolution/Image Width',
     1322            8 => 'N Layer Profile M',
     1323            9 => 'Shared Data',
     1324            10 => 'JBIG2 Profile M',
     1325        }},
     1326    },
     1327    0x8781 => { #22
     1328        Name => 'SharedData',
     1329        IsOffset => 1,
     1330        # this tag is not supported for writing, so define an
     1331        # invalid offset pair to cause a "No size tag" error to be
     1332        # generated if we try to write a file containing this tag
     1333        OffsetPair => -1,
     1334    },
     1335    0x8782 => 'T88Options', #20
    8851336    0x87ac => 'ImageLayer',
    8861337    0x87af => {
     
    9011352        Name => 'ExposureProgram',
    9021353        Groups => { 2 => 'Camera' },
     1354        Notes => 'the value of 9 is not standard EXIF, but is used by the Canon EOS 7D',
    9031355        PrintConv => {
     1356            0 => 'Not Defined',
    9041357            1 => 'Manual',
    9051358            2 => 'Program AE',
     
    9101363            7 => 'Portrait',
    9111364            8 => 'Landscape',
     1365            9 => 'Bulb', #25
    9121366        },
    9131367    },
     
    9261380        },
    9271381    },
    928     0x8827 => 'ISO',
     1382    0x8827 => {
     1383        Name => 'ISO',
     1384        Notes => q{
     1385            called ISOSpeedRatings by EXIF 2.2, then PhotographicSensitivity by the EXIF
     1386            2.3 spec.
     1387        },
     1388        PrintConv => '$val=~s/\s+/, /g; $val',
     1389    },
    9291390    0x8828 => {
    9301391        Name => 'Opto-ElectricConvFactor',
     1392        Notes => 'called OECF by the EXIF spec.',
    9311393        Binary => 1,
    9321394    },
    933     0x8829 => 'Interlace',
    934     0x882a => 'TimeZoneOffset',
    935     0x882b => 'SelfTimerMode',
     1395    0x8829 => 'Interlace', #12
     1396    0x882a => 'TimeZoneOffset', #12
     1397    0x882b => 'SelfTimerMode', #12
     1398    0x8830 => { #24
     1399        Name => 'SensitivityType',
     1400        Notes => 'applies to EXIF:ISO tag',
     1401        PrintConv => {
     1402            0 => 'Unknown',
     1403            1 => 'Standard Output Sensitivity',
     1404            2 => 'Recommended Exposure Index',
     1405            3 => 'ISO Speed',
     1406            4 => 'Standard Output Sensitivity and Recommended Exposure Index',
     1407            5 => 'Standard Output Sensitivity and ISO Speed',
     1408            6 => 'Recommended Exposure Index and ISO Speed',
     1409            7 => 'Standard Output Sensitivity, Recommended Exposure Index and ISO Speed',
     1410        },
     1411    },
     1412    0x8831 => 'StandardOutputSensitivity', #24
     1413    0x8832 => 'RecommendedExposureIndex', #24
     1414    0x8833 => 'ISOSpeed', #24
     1415    0x8834 => { #24
     1416        Name => 'ISOSpeedLatitudeyyy',
     1417        Description => 'ISO Speed Latitude yyy',
     1418    },
     1419    0x8835 => { #24
     1420        Name => 'ISOSpeedLatitudezzz',
     1421        Description => 'ISO Speed Latitude zzz',
     1422    },
    9361423    0x885c => 'FaxRecvParams', #9
    9371424    0x885d => 'FaxSubAddress', #9
     
    9471434        },
    9481435    },
    949     0x9000 => 'ExifVersion',
     1436    0x9000 => {
     1437        Name => 'ExifVersion',
     1438        RawConv => '$val=~s/\0+$//; $val',  # (some idiots add null terminators)
     1439    },
    9501440    0x9003 => {
    9511441        Name => 'DateTimeOriginal',
    9521442        Description => 'Date/Time Original',
    9531443        Groups => { 2 => 'Time' },
     1444        Notes => 'date/time when original image was taken',
    9541445        PrintConv => '$self->ConvertDateTime($val)',
    9551446    },
     
    9571448        Name => 'CreateDate',
    9581449        Groups => { 2 => 'Time' },
     1450        Notes => 'called DateTimeDigitized by the EXIF spec.',
    9591451        PrintConv => '$self->ConvertDateTime($val)',
    9601452    },
    9611453    0x9101 => {
    9621454        Name => 'ComponentsConfiguration',
    963         PrintConv => '$_=$val;s/\0.*//s;tr/\x01-\x06/YbrRGB/;s/b/Cb/g;s/r/Cr/g;$_',
     1455        Format => 'int8u',
     1456        PrintConvColumns => 2,
     1457        PrintConv => {
     1458            0 => '-',
     1459            1 => 'Y',
     1460            2 => 'Cb',
     1461            3 => 'Cr',
     1462            4 => 'R',
     1463            5 => 'G',
     1464            6 => 'B',
     1465            OTHER => sub {
     1466                my ($val, $inv, $conv) = @_;
     1467                my @a = split /,?\s+/, $val;
     1468                if ($inv) {
     1469                    my %invConv;
     1470                    $invConv{lc $$conv{$_}} = $_ foreach keys %$conv;
     1471                    # strings like "YCbCr" and "RGB" still work for writing
     1472                    @a = $a[0] =~ /(Y|Cb|Cr|R|G|B)/g if @a == 1;
     1473                    foreach (@a) {
     1474                        $_ = $invConv{lc $_};
     1475                        return undef unless defined $_;
     1476                    }
     1477                    push @a, 0 while @a < 4;
     1478                } else {
     1479                    foreach (@a) {
     1480                        $_ = $$conv{$_} || "Err ($_)";
     1481                    }
     1482                }
     1483                return join ', ', @a;
     1484            },
     1485        },
    9641486    },
    9651487    0x9102 => 'CompressedBitsPerPixel',
    9661488    0x9201 => {
    9671489        Name => 'ShutterSpeedValue',
    968         ValueConv => 'abs($val)<100 ? 1/(2**$val) : 0',
     1490        Format => 'rational64s', # Leica M8 patch (incorrectly written as rational64u)
     1491        ValueConv => 'abs($val)<100 ? 2**(-$val) : 0',
    9691492        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    9701493    },
     
    9771500    0x9204 => {
    9781501        Name => 'ExposureCompensation',
    979         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     1502        Format => 'rational64s', # Leica M8 patch (incorrectly written as rational64u)
     1503        Notes => 'called ExposureBiasValue by the EXIF spec.',
     1504        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
    9801505    },
    9811506    0x9205 => {
     
    9881513        Name => 'SubjectDistance',
    9891514        Groups => { 2 => 'Camera' },
    990         PrintConv => '$val eq "inf" ? $val : "${val} m"',
     1515        PrintConv => '$val =~ /^(inf|undef)$/ ? $val : "${val} m"',
    9911516    },
    9921517    0x9207 => {
     
    9941519        Groups => { 2 => 'Camera' },
    9951520        PrintConv => {
     1521            0 => 'Unknown',
    9961522            1 => 'Average',
    9971523            2 => 'Center-weighted average',
     
    10061532        Name => 'LightSource',
    10071533        Groups => { 2 => 'Camera' },
     1534        SeparateTable => 'LightSource',
    10081535        PrintConv => \%lightSource,
    10091536    },
     
    10121539        Groups => { 2 => 'Camera' },
    10131540        Flags => 'PrintHex',
    1014         PrintConv => {
    1015             0x00 => 'No Flash',
    1016             0x01 => 'Fired',
    1017             0x05 => 'Fired, Return not detected',
    1018             0x07 => 'Fired, Return detected',
    1019             0x08 => 'On, Did not fire', # not charged up?
    1020             0x09 => 'On',
    1021             0x0d => 'On, Return not detected',
    1022             0x0f => 'On, Return detected',
    1023             0x10 => 'Off',
    1024             0x14 => 'Off, Did not fire, Return not detected',
    1025             0x18 => 'Auto, Did not fire',
    1026             0x19 => 'Auto, Fired',
    1027             0x1d => 'Auto, Fired, Return not detected',
    1028             0x1f => 'Auto, Fired, Return detected',
    1029             0x20 => 'No flash function',
    1030             0x30 => 'Off, No flash function',
    1031             0x41 => 'Fired, Red-eye reduction',
    1032             0x45 => 'Fired, Red-eye reduction, Return not detected',
    1033             0x47 => 'Fired, Red-eye reduction, Return detected',
    1034             0x49 => 'On, Red-eye reduction',
    1035             0x4d => 'On, Red-eye reduction, Return not detected',
    1036             0x4f => 'On, Red-eye reduction, Return detected',
    1037             0x50 => 'Off, Red-eye reduction',
    1038             0x58 => 'Auto, Did not fire, Red-eye reduction',
    1039             0x59 => 'Auto, Fired, Red-eye reduction',
    1040             0x5d => 'Auto, Fired, Red-eye reduction, Return not detected',
    1041             0x5f => 'Auto, Fired, Red-eye reduction, Return detected',
    1042         },
     1541        SeparateTable => 'Flash',
     1542        PrintConv => \%flash,
    10431543    },
    10441544    0x920a => {
    10451545        Name => 'FocalLength',
    10461546        Groups => { 2 => 'Camera' },
    1047         PrintConv => 'sprintf("%.1fmm",$val)',
     1547        PrintConv => 'sprintf("%.1f mm",$val)',
    10481548    },
    10491549    # Note: tags 0x920b-0x9217 are duplicates of 0xa20b-0xa217
    10501550    # (The TIFF standard uses 0xa2xx, but you'll find both in images)
    1051     0x920b => {
     1551    0x920b => { #12
    10521552        Name => 'FlashEnergy',
    10531553        Groups => { 2 => 'Camera' },
    10541554    },
    1055     0x920c => 'SpatialFrequencyResponse',   # ?? (not in Fuji images - PH)
    1056     0x920d => 'Noise',
    1057     0x920e => 'FocalPlaneXResolution',
    1058     0x920f => 'FocalPlaneYResolution',
    1059     0x9210 => {
     1555    0x920c => 'SpatialFrequencyResponse', #12 (not in Fuji images - PH)
     1556    0x920d => 'Noise', #12
     1557    0x920e => 'FocalPlaneXResolution', #12
     1558    0x920f => 'FocalPlaneYResolution', #12
     1559    0x9210 => { #12
    10601560        Name => 'FocalPlaneResolutionUnit',
    10611561        Groups => { 2 => 'Camera' },
     
    10681568        },
    10691569    },
    1070     0x9211 => 'ImageNumber',
     1570    0x9211 => 'ImageNumber', #12
    10711571    0x9212 => { #12
    10721572        Name => 'SecurityClassification',
     
    10791579        },
    10801580    },
    1081     0x9213 => 'ImageHistory',
     1581    0x9213 => 'ImageHistory', #12
    10821582    0x9214 => {
    1083         Name => 'SubjectLocation',
     1583        Name => 'SubjectArea',
    10841584        Groups => { 2 => 'Camera' },
    10851585    },
    1086     0x9215 => 'ExposureIndex',
    1087     0x9216 => 'TIFF-EPStandardID',
    1088     0x9217 => {
     1586    0x9215 => 'ExposureIndex', #12
     1587    0x9216 => 'TIFF-EPStandardID', #12
     1588    0x9217 => { #12
    10891589        Name => 'SensingMethod',
    10901590        Groups => { 2 => 'Camera' },
     1591        Notes => 'values 1 and 6 are not standard EXIF',
    10911592        PrintConv => {
    1092             1 => 'Monochrome area', #12
     1593            1 => 'Monochrome area', #12 (not standard EXIF)
    10931594            2 => 'One-chip color area',
    10941595            3 => 'Two-chip color area',
    10951596            4 => 'Three-chip color area',
    10961597            5 => 'Color sequential area',
    1097             6 => 'Monochrome linear', #12
     1598            6 => 'Monochrome linear', #12 (not standard EXIF)
    10981599            7 => 'Trilinear',
    10991600            8 => 'Color sequential linear',
     
    11011602    },
    11021603    0x9213 => 'ImageHistory',
     1604    0x923a => 'CIP3DataFile', #20
     1605    0x923b => 'CIP3Sheet', #20
     1606    0x923c => 'CIP3Side', #20
    11031607    0x923f => 'StoNits', #9
    11041608    # handle maker notes as a conditional list
     
    11061610    0x9286 => {
    11071611        Name => 'UserComment',
    1108         PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
     1612        # may consider forcing a Format of 'undef' for this tag because I have
     1613        # seen other applications write it incorrectly as 'string' or 'int8u'
     1614        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
    11091615    },
    11101616    0x9290 => {
    11111617        Name => 'SubSecTime',
    11121618        Groups => { 2 => 'Time' },
     1619        ValueConv => '$val=~s/ +$//; $val', # trim trailing blanks
    11131620    },
    11141621    0x9291 => {
    11151622        Name => 'SubSecTimeOriginal',
    11161623        Groups => { 2 => 'Time' },
     1624        ValueConv => '$val=~s/ +$//; $val', # trim trailing blanks
    11171625    },
    11181626    0x9292 => {
    11191627        Name => 'SubSecTimeDigitized',
    11201628        Groups => { 2 => 'Time' },
    1121     },
    1122     0x935c => { #3
     1629        ValueConv => '$val=~s/ +$//; $val', # trim trailing blanks
     1630    },
     1631    # The following 3 tags are found in MSOffice TIFF images
     1632    # References:
     1633    # http://social.msdn.microsoft.com/Forums/en-US/os_standocs/thread/03086d55-294a-49d5-967a-5303d34c40f8/
     1634    # http://blogs.msdn.com/openspecification/archive/2009/12/08/details-of-three-tiff-tag-extensions-that-microsoft-office-document-imaging-modi-software-may-write-into-the-tiff-files-it-generates.aspx
     1635    # http://www.microsoft.com/downloads/details.aspx?FamilyID=0dbc435d-3544-4f4b-9092-2f2643d64a39&displaylang=en#filelist
     1636    0x932f => 'MSDocumentText',
     1637    0x9330 => {
     1638        Name => 'MSPropertySetStorage',
     1639        Binary => 1,
     1640    },
     1641    0x9331 => {
     1642        Name => 'MSDocumentTextPosition',
     1643        Binary => 1, # (just in case -- don't know what format this is)
     1644    },
     1645    0x935c => { #3/19
    11231646        Name => 'ImageSourceData',
    11241647        Binary => 1,
     
    11271650        Name => 'XPTitle',
    11281651        Format => 'undef',
    1129         ValueConv => '$self->Unicode2Charset($val,"II")',
     1652        ValueConv => '$self->Decode($val,"UCS2","II")',
    11301653    },
    11311654    0x9c9c => {
    11321655        Name => 'XPComment',
    11331656        Format => 'undef',
    1134         ValueConv => '$self->Unicode2Charset($val,"II")',
     1657        ValueConv => '$self->Decode($val,"UCS2","II")',
    11351658    },
    11361659    0x9c9d => {
     
    11381661        Groups => { 2 => 'Author' },
    11391662        Format => 'undef',
    1140         ValueConv => '$self->Unicode2Charset($val,"II")',
     1663        ValueConv => '$self->Decode($val,"UCS2","II")',
    11411664    },
    11421665    0x9c9e => {
    11431666        Name => 'XPKeywords',
    11441667        Format => 'undef',
    1145         ValueConv => '$self->Unicode2Charset($val,"II")',
     1668        ValueConv => '$self->Decode($val,"UCS2","II")',
    11461669    },
    11471670    0x9c9f => {
    11481671        Name => 'XPSubject',
    11491672        Format => 'undef',
    1150         ValueConv => '$self->Unicode2Charset($val,"II")',
    1151     },
    1152     0xa000 => 'FlashpixVersion',
     1673        ValueConv => '$self->Decode($val,"UCS2","II")',
     1674    },
     1675    0xa000 => {
     1676        Name => 'FlashpixVersion',
     1677        RawConv => '$val=~s/\0+$//; $val',  # (some idiots add null terminators)
     1678    },
    11531679    0xa001 => {
    11541680        Name => 'ColorSpace',
    11551681        Notes => q{
    1156             the value of 2 is not standard EXIF.  Instead, an Adobe RGB image is
    1157             indicated by "Uncalibrated" with an InteropIndex of "R03"'
    1158         },
     1682            the value of 0x2 is not standard EXIF.  Instead, an Adobe RGB image is
     1683            indicated by "Uncalibrated" with an InteropIndex of "R03".  The values
     1684            0xfffd and 0xfffe are also non-standard, and are used by some Sony cameras
     1685        },
     1686        PrintHex => 1,
    11591687        PrintConv => {
    11601688            1 => 'sRGB',
    11611689            2 => 'Adobe RGB',
    11621690            0xffff => 'Uncalibrated',
    1163         },
    1164     },
    1165     0xa002 => 'ExifImageWidth',
    1166     0xa003 => 'ExifImageLength',
     1691            # Sony uses these definitions: (ref JD)
     1692            # 0xffff => 'Adobe RGB', (conflicts with Uncalibrated)
     1693            0xfffe => 'ICC Profile',
     1694            0xfffd => 'Wide Gamut RGB',
     1695        },
     1696    },
     1697    0xa002 => {
     1698        Name => 'ExifImageWidth',
     1699        Notes => 'called PixelXDimension by the EXIF spec.',
     1700    },
     1701    0xa003 => {
     1702        Name => 'ExifImageHeight',
     1703        Notes => 'called PixelYDimension by the EXIF spec.',
     1704    },
    11671705    0xa004 => 'RelatedSoundFile',
    11681706    0xa005 => {
     
    11901728        Name => 'FocalPlaneResolutionUnit',
    11911729        Groups => { 2 => 'Camera' },
     1730        Notes => 'values 1, 4 and 5 are not standard EXIF',
    11921731        PrintConv => {
    11931732            1 => 'None', # (not standard EXIF)
     
    12541793            1 => 'Manual',
    12551794            2 => 'Auto bracket',
     1795            # have seen 3 for Samsung EX1 images - PH
    12561796        },
    12571797    },
     
    12741814    0xa405 => {
    12751815        Name => 'FocalLengthIn35mmFormat',
     1816        Notes => 'called FocalLengthIn35mmFilm by the EXIF spec.',
    12761817        Groups => { 2 => 'Camera' },
    1277         PrintConv => '"${val}mm"',
     1818        PrintConv => '"$val mm"',
    12781819    },
    12791820    0xa406 => {
     
    13281869        Name => 'DeviceSettingDescription',
    13291870        Groups => { 2 => 'Camera' },
     1871        Binary => 1,
    13301872    },
    13311873    0xa40c => {
     
    13331875        Groups => { 2 => 'Camera' },
    13341876        PrintConv => {
     1877            0 => 'Unknown',
    13351878            1 => 'Macro',
    13361879            2 => 'Close',
     
    13381881        },
    13391882    },
     1883    # 0xa40d - int16u: 0 (GE E1486 TW)
     1884    # 0xa40e - int16u: 1 (GE E1486 TW)
    13401885    0xa420 => 'ImageUniqueID',
     1886    0xa430 => { #24
     1887        Name => 'OwnerName',
     1888        Notes => 'called CameraOwnerName by the EXIF spec.',
     1889    },
     1890    0xa431 => { #24
     1891        Name => 'SerialNumber',
     1892        Notes => 'called BodySerialNumber by the EXIF spec.',
     1893    },
     1894    0xa432 => { #24
     1895        Name => 'LensInfo',
     1896        Notes => q{
     1897            4 rational values giving focal and aperture ranges, called LensSpecification
     1898            by the EXIF spec.
     1899        },
     1900        # convert to the form "12-20mm f/3.8-4.5" or "50mm f/1.4"
     1901        PrintConv => \&Image::ExifTool::Exif::PrintLensInfo,
     1902    },
     1903    0xa433 => 'LensMake', #24
     1904    0xa434 => 'LensModel', #24
     1905    0xa435 => 'LensSerialNumber', #24
    13411906    0xa480 => 'GDALMetadata', #3
    13421907    0xa481 => 'GDALNoData', #3
    13431908    0xa500 => 'Gamma',
     1909    0xafc0 => 'ExpandSoftware', #JD (Opanda)
     1910    0xafc1 => 'ExpandLens', #JD (Opanda)
     1911    0xafc2 => 'ExpandFilm', #JD (Opanda)
     1912    0xafc3 => 'ExpandFilterLens', #JD (Opanda)
     1913    0xafc4 => 'ExpandScanner', #JD (Opanda)
     1914    0xafc5 => 'ExpandFlashLamp', #JD (Opanda)
    13441915#
    1345 # Windows Media Photo WDP tags
     1916# Windows Media Photo / HD Photo (WDP/HDP) tags
    13461917#
    13471918    0xbc01 => { #13
     
    13501921        Format => 'undef',
    13511922        Notes => q{
    1352             tags 0xbc** are used in Windows Media Photo WDP images. The actual
     1923            tags 0xbc** are used in Windows HD Photo (HDP and WDP) images. The actual
    13531924            PixelFormat values are 16-byte GUID's but the leading 15 bytes,
    13541925            '6fddc324-4e03-4bfe-b1853-d77768dc9', have been removed below to avoid
     
    14211992        },
    14221993    },
    1423     0xbc04 => { #13
    1424         Name => 'ImageType',
    1425         PrintConv => { BITMASK => {
    1426             0 => 'Preview',
    1427             1 => 'Page',
    1428         } },
    1429     },
    14301994    0xbc02 => { #13
    1431         Name => 'Transfomation',
     1995        Name => 'Transformation',
    14321996        PrintConv => {
    14331997            0 => 'Horizontal (normal)',
     
    14452009        PrintConv => { 0 => 'No', 1 => 'Yes' },
    14462010    },
     2011    0xbc04 => { #13
     2012        Name => 'ImageType',
     2013        PrintConv => { BITMASK => {
     2014            0 => 'Preview',
     2015            1 => 'Page',
     2016        } },
     2017    },
     2018    0xbc80 => 'ImageWidth', #13
     2019    0xbc81 => 'ImageHeight', #13
     2020    0xbc82 => 'WidthResolution', #13
     2021    0xbc83 => 'HeightResolution', #13
    14472022    0xbcc0 => { #13
    14482023        Name => 'ImageOffset',
     
    14812056        },
    14822057    },
    1483     0xbc80 => 'ImageWidth', #13
    1484     0xbc81 => 'ImageHeight', #13
    1485     0xbc82 => 'WidthResolution', #13
    1486     0xbc83 => 'HeightResolution', #13
    14872058#
    14882059    0xc427 => 'OceScanjobDesc', #3
     
    14902061    0xc429 => 'OceIDNumber', #3
    14912062    0xc42a => 'OceImageLogic', #3
    1492     0xc44f => 'Annotations', #7
     2063    0xc44f => { Name => 'Annotations', Binary => 1 }, #7/19
    14932064    0xc4a5 => {
    1494         Name => 'PrintIM',
     2065        Name => 'PrintIM', # (writable directory!)
    14952066        # must set Writable here so this tag will be saved with MakerNotes option
    14962067        Writable => 'undef',
     2068        WriteGroup => 'IFD0',
    14972069        Description => 'Print Image Matching',
    14982070        SubDirectory => {
     
    15002072        },
    15012073    },
     2074    0xc580 => { #20
     2075        Name => 'USPTOOriginalContentType',
     2076        PrintConv => {
     2077            0 => 'Text or Drawing',
     2078            1 => 'Grayscale',
     2079            2 => 'Color',
     2080        },
     2081    },
    15022082#
    1503 # DNG tags 0xc6XX (ref 2 unless otherwise stated)
     2083# DNG tags 0xc6XX and 0xc7XX (ref 2 unless otherwise stated)
    15042084#
    15052085    0xc612 => {
    15062086        Name => 'DNGVersion',
    1507         Notes => 'tags 0xc612-0xc65d are used in DNG images',
     2087        Notes => 'tags 0xc612-0xc761 are used in DNG images unless otherwise noted',
     2088        DataMember => 'DNGVersion',
     2089        RawConv => '$$self{DNGVersion} = $val',
     2090        PrintConv => '$val =~ tr/ /./; $val',
    15082091    },
    15092092    0xc613 => 'DNGBackwardVersion',
     
    15122095        Name => 'LocalizedCameraModel',
    15132096        Format => 'string',
    1514         PrintConv => '$self->Printable($val)',
     2097        PrintConv => '$self->Printable($val, 0)',
    15152098    },
    15162099    0xc616 => {
     
    15302113            4 => 'Even rows offset right 1/2 column',
    15312114            5 => 'Even rows offset left 1/2 column',
    1532         },
    1533     },
    1534     0xc618 => {
    1535         Name => 'LinearizationTable',
    1536         Binary => 1,
    1537     },
     2115            # the following are new for DNG 1.3:
     2116            6 => 'Even rows offset up by 1/2 row, even columns offset left by 1/2 column',
     2117            7 => 'Even rows offset up by 1/2 row, even columns offset right by 1/2 column',
     2118            8 => 'Even rows offset down by 1/2 row, even columns offset left by 1/2 column',
     2119            9 => 'Even rows offset down by 1/2 row, even columns offset right by 1/2 column',
     2120        },
     2121    },
     2122    0xc618 => { Name => 'LinearizationTable', Binary => 1 },
    15382123    0xc619 => 'BlackLevelRepeatDim',
    15392124    0xc61a => 'BlackLevel',
     
    15652150        Name => 'DNGLensInfo',
    15662151        Groups => { 2 => 'Camera' },
    1567         PrintConv => '$_=$val;s/(\S+) (\S+) (\S+) (\S+)/$1-$2mm f\/$3-$4/;$_',
     2152        PrintConv =>\&PrintLensInfo,
    15682153    },
    15692154    0xc631 => 'ChromaBlurRadius',
     
    15722157    0xc634 => [
    15732158        {
    1574             Condition => '$self->{TIFF_TYPE} eq "SR2"',
     2159            Condition => '$$self{TIFF_TYPE} =~ /^(ARW|SR2)$/',
    15752160            Name => 'SR2Private',
    15762161            Groups => { 1 => 'SR2' },
    15772162            Flags => 'SubIFD',
    15782163            Format => 'int32u',
     2164            # some utilites have problems unless this is int8u format:
     2165            # - Adobe Camera Raw 5.3 gives an error
     2166            # - Apple Preview 10.5.8 gets the wrong white balance
     2167            FixFormat => 'int8u', # (stupid Sony)
    15792168            SubDirectory => {
    15802169                DirName => 'SR2Private',
     
    15862175            Condition => '$$valPt =~ /^Adobe\0/',
    15872176            Name => 'DNGAdobeData',
    1588             DNGMakerNotes => 1,
     2177            NestedHtmlDump => 1,
    15892178            SubDirectory => { TagTable => 'Image::ExifTool::DNG::AdobeData' },
    15902179            Format => 'undef',  # written incorrectly as int8u (change to undef for speed)
    15912180        },
    15922181        {
    1593             Condition => '$$valPt =~ /^PENTAX \0/',
    1594             Name => 'DNGPentaxData',
    1595             DNGMakerNotes => 1,
     2182            Condition => '$$valPt =~ /^(PENTAX |SAMSUNG)\0/',
     2183            Name => 'MakerNotePentax',
     2184            MakerNotes => 1,    # (causes "MakerNotes header" to be identified in HtmlDump output)
     2185            Binary => 1,
     2186            # Note: Don't make this block-writable for a few reasons:
     2187            # 1) It would be dangerous (possibly confusing Pentax software)
     2188            # 2) It is a different format from the JPEG version of MakerNotePentax
     2189            # 3) It is converted to JPEG format by RebuildMakerNotes() when copying
    15962190            SubDirectory => {
    15972191                TagTable => 'Image::ExifTool::Pentax::Main',
     
    16152209        },
    16162210    },
     2211    0xc640 => { #15
     2212        Name => 'RawImageSegmentation',
     2213        # (int16u[3], not writable)
     2214        Notes => q{
     2215            used in segmented Canon CR2 images.  3 numbers: 1. Number of segments minus
     2216            one; 2. Pixel width of segments except last; 3. Pixel width of last segment
     2217        },
     2218    },
    16172219    0xc65a => {
    16182220        Name => 'CalibrationIlluminant1',
     2221        SeparateTable => 'LightSource',
    16192222        PrintConv => \%lightSource,
    16202223    },
    16212224    0xc65b => {
    16222225        Name => 'CalibrationIlluminant2',
     2226        SeparateTable => 'LightSource',
    16232227        PrintConv => \%lightSource,
    16242228    },
     
    16312235    0xc660 => { #3
    16322236        Name => 'AliasLayerMetadata',
    1633         Notes => 'used by Alias Sketchbook Pro, not a DNG tag',
     2237        Notes => 'used by Alias Sketchbook Pro',
    16342238    },
    16352239    0xc68b => {
     
    16382242    },
    16392243    0xc68c => {
    1640         Name => 'OriginalRawFileData',
     2244        Name => 'OriginalRawFileData', # (writable directory!)
     2245        Writable => 'undef', # must be defined here so tag will be extracted if specified
     2246        WriteGroup => 'IFD0',
     2247        Flags => [ 'Binary', 'Protected' ],
    16412248        SubDirectory => {
    16422249            TagTable => 'Image::ExifTool::DNG::OriginalRaw',
     
    16652272    },
    16662273    0xc692 => 'CurrentPreProfileMatrix',
    1667     # 0xea1c - unknown tag written by MicrosoftPhoto (undef)
    1668     #  observed: 1720 bytes in IFD0 or 1988 bytes in ExifIFD, in both cases
    1669     #  the data starts with "1c ea 00 00 00 08" followed by all 00's
     2274    0xc6bf => 'ColorimetricReference',
     2275    0xc6d2 => { #JD (Panasonic DMC-TZ5)
     2276        # this text is UTF-8 encoded (hooray!) - PH (TZ5)
     2277        Name => 'PanasonicTitle',
     2278        Format => 'string', # written incorrectly as 'undef'
     2279        Notes => 'proprietary Panasonic tag used for baby/pet name, etc',
     2280        # panasonic always records this tag (64 zero bytes),
     2281        # so ignore it unless it contains valid information
     2282        RawConv => 'length($val) ? $val : undef',
     2283        ValueConv => '$self->Decode($val, "UTF8")',
     2284    },
     2285    0xc6d3 => { #PH (Panasonic DMC-FS7)
     2286        Name => 'PanasonicTitle2',
     2287        Format => 'string', # written incorrectly as 'undef'
     2288        Notes => 'proprietary Panasonic tag used for baby/pet name with age',
     2289        # panasonic always records this tag (128 zero bytes),
     2290        # so ignore it unless it contains valid information
     2291        RawConv => 'length($val) ? $val : undef',
     2292        ValueConv => '$self->Decode($val, "UTF8")',
     2293    },
     2294    0xc6f3 => 'CameraCalibrationSig',
     2295    0xc6f4 => 'ProfileCalibrationSig',
     2296    0xc6f5 => {
     2297        Name => 'ProfileIFD', # (ExtraCameraProfiles)
     2298        Groups => { 1 => 'ProfileIFD' },
     2299        Flags => 'SubIFD',
     2300        SubDirectory => {
     2301            ProcessProc => \&ProcessTiffIFD,
     2302            WriteProc => \&ProcessTiffIFD,
     2303            DirName => 'ProfileIFD',
     2304            Start => '$val',
     2305            Base => '$start',   # offsets relative to start of TIFF-like header
     2306            MaxSubdirs => 10,
     2307            Magic => 0x4352,    # magic number for TIFF-like header
     2308        },
     2309    },
     2310    0xc6f6 => 'AsShotProfileName',
     2311    0xc6f7 => 'NoiseReductionApplied',
     2312    0xc6f8 => 'ProfileName',
     2313    0xc6f9 => 'ProfileHueSatMapDims',
     2314    0xc6fa => 'ProfileHueSatMapData1',
     2315    0xc6fb => 'ProfileHueSatMapData2',
     2316    0xc6fc => {
     2317        Name => 'ProfileToneCurve',
     2318        Binary => 1,
     2319    },
     2320    0xc6fd => {
     2321        Name => 'ProfileEmbedPolicy',
     2322        PrintConv => {
     2323            0 => 'Allow Copying',
     2324            1 => 'Embed if Used',
     2325            2 => 'Never Embed',
     2326            3 => 'No Restrictions',
     2327        },
     2328    },
     2329    0xc6fe => 'ProfileCopyright',
     2330    0xc714 => 'ForwardMatrix1',
     2331    0xc715 => 'ForwardMatrix2',
     2332    0xc716 => 'PreviewApplicationName',
     2333    0xc717 => 'PreviewApplicationVersion',
     2334    0xc718 => 'PreviewSettingsName',
     2335    0xc719 => {
     2336        Name => 'PreviewSettingsDigest',
     2337        Format => 'undef',
     2338        ValueConv => 'unpack("H*", $val)',
     2339    },
     2340    0xc71a => 'PreviewColorSpace',
     2341    0xc71b => {
     2342        Name => 'PreviewDateTime',
     2343        Groups => { 2 => 'Time' },
     2344        ValueConv => q{
     2345            require Image::ExifTool::XMP;
     2346            return Image::ExifTool::XMP::ConvertXMPDate($val);
     2347        },
     2348    },
     2349    0xc71c => {
     2350        Name => 'RawImageDigest',
     2351        Format => 'undef',
     2352        ValueConv => 'unpack("H*", $val)',
     2353    },
     2354    0xc71d => {
     2355        Name => 'OriginalRawFileDigest',
     2356        Format => 'undef',
     2357        ValueConv => 'unpack("H*", $val)',
     2358    },
     2359    0xc71e => 'SubTileBlockSize',
     2360    0xc71f => 'RowInterleaveFactor',
     2361    0xc725 => 'ProfileLookTableDims',
     2362    0xc726 => {
     2363        Name => 'ProfileLookTableData',
     2364        Binary => 1,
     2365    },
     2366    0xc740 => { # DNG 1.3
     2367        Name => 'OpcodeList1',
     2368        Binary => 1,
     2369        # opcodes:
     2370        # 1 => 'WarpRectilinear',
     2371        # 2 => 'WarpFisheye',
     2372        # 3 => 'FixVignetteRadial',
     2373        # 4 => 'FixBadPixelsConstant',
     2374        # 5 => 'FixBadPixelsList',
     2375        # 6 => 'TrimBounds',
     2376        # 7 => 'MapTable',
     2377        # 8 => 'MapPolynomial',
     2378        # 9 => 'GainMap',
     2379        # 10 => 'DeltaPerRow',
     2380        # 11 => 'DeltaPerColumn',
     2381        # 12 => 'ScalePerRow',
     2382        # 13 => 'ScalePerColumn',
     2383    },
     2384    0xc741 => { # DNG 1.3
     2385        Name => 'OpcodeList2',
     2386        Binary => 1,
     2387    },
     2388    0xc74e => { # DNG 1.3
     2389        Name => 'OpcodeList3',
     2390        Binary => 1,
     2391    },
     2392    0xc761 => 'NoiseProfile', # DNG 1.3
     2393    0xea1c => { #13
     2394        Name => 'Padding',
     2395        Binary => 1,
     2396        Writable => 'undef',
     2397        # must start with 0x1c 0xea by the WM Photo specification
     2398        # (not sure what should happen if padding is only 1 byte)
     2399        # (why does MicrosoftPhoto write "1c ea 00 00 00 08"?)
     2400        RawConvInv => '$val=~s/^../\x1c\xea/s; $val',
     2401    },
    16702402    0xea1d => {
    16712403        Name => 'OffsetSchema',
    16722404        Notes => "Microsoft's ill-conceived maker note offset difference",
     2405        # From the Microsoft documentation:
     2406        #
     2407        #     Any time the "Maker Note" is relocated by Windows, the Exif MakerNote
     2408        #     tag (37500) is updated automatically to reference the new location. In
     2409        #     addition, Windows records the offset (or difference) between the old and
     2410        #     new locations in the Exif OffsetSchema tag (59933). If the "Maker Note"
     2411        #     contains relative references, the developer can add the value in
     2412        #     OffsetSchema to the original references to find the correct information.
     2413        #
     2414        # My recommendation is for other developers to ignore this tag because the
     2415        # information it contains is unreliable. It will be wrong if the image has
     2416        # been subsequently edited by another application that doesn't recognize the
     2417        # new Microsoft tag.
     2418        #
     2419        # The new tag unfortunately only gives the difference between the new maker
     2420        # note offset and the original offset. Instead, it should have been designed
     2421        # to store the original offset. The new offset may change if the image is
     2422        # edited, which will invalidate the tag as currently written. If instead the
     2423        # original offset had been stored, the new difference could be easily
     2424        # calculated because the new maker note offset is known.
     2425        #
     2426        # I exchanged emails with a Microsoft technical representative, pointing out
     2427        # this problem shortly after they released the update (Feb 2007), but so far
     2428        # they have taken no steps to address this.
    16732429    },
    16742430
     
    16782434    # of tags, all tags with values above 0xf000 are handled specially
    16792435    # by ProcessExif().
     2436
     2437    0xfe00 => {
     2438        Name => 'KDC_IFD',
     2439        Groups => { 1 => 'KDC_IFD' },
     2440        Flags => 'SubIFD',
     2441        Notes => 'used in some Kodak KDC images',
     2442        SubDirectory => {
     2443            TagTable => 'Image::ExifTool::Kodak::KDC_IFD',
     2444            DirName => 'KDC_IFD',
     2445            Start => '$val',
     2446        },
     2447    },
    16802448);
    16812449
    1682 # the Composite tags are evaluated last, and are used
    1683 # to calculate values based on the other tags
    1684 # (the main script looks for the special 'Composite' hash)
     2450# EXIF Composite tags (plus other more general Composite tags)
    16852451%Image::ExifTool::Exif::Composite = (
    16862452    GROUPS => { 2 => 'Image' },
     
    16902456            1 => 'ImageHeight',
    16912457        },
    1692         ValueConv => '"$val[0]x$val[1]"',
     2458        Desire => {
     2459            2 => 'ExifImageWidth',
     2460            3 => 'ExifImageHeight',
     2461        },
     2462        # use ExifImageWidth/Height only for Canon and Phase One TIFF-base RAW images
     2463        ValueConv => q{
     2464            return "$val[2]x$val[3]" if $val[2] and $val[3] and
     2465                    $$self{TIFF_TYPE} =~ /^(CR2|Canon 1D RAW|IIQ|EIP)$/;
     2466            return "$val[0]x$val[1]";
     2467        },
    16932468    },
    16942469    # pick the best shutter speed value
     
    17212496        PrintConv => 'sprintf("%.1f",$val)',
    17222497    },
    1723     FocalLength35efl => {
     2498    FocalLength35efl => { #26/PH
    17242499        Description => 'Focal Length',
    17252500        Notes => 'this value may be incorrect if the image has been resized',
     
    17312506            1 => 'ScaleFactor35efl',
    17322507        },
    1733         ValueConv => '$val[0] * ($val[1] ? $val[1] : 1)',
    1734         PrintConv => '$val[1] ? sprintf("%.1fmm (35mm equivalent: %.1fmm)", $val[0], $val) : sprintf("%.1fmm", $val)',
    1735     },
    1736     ScaleFactor35efl => {
    1737         Description => 'Scale Factor To 35mm Equivalent',
     2508        ValueConv => 'ToFloat(@val); ($val[0] || 0) * ($val[1] || 1)',
     2509        PrintConv => '$val[1] ? sprintf("%.1f mm (35 mm equivalent: %.1f mm)", $val[0], $val) : sprintf("%.1f mm", $val)',
     2510    },
     2511    ScaleFactor35efl => { #26/PH
     2512        Description => 'Scale Factor To 35 mm Equivalent',
    17382513        Notes => 'this value and any derived values may be incorrect if image has been resized',
    17392514        Groups => { 2 => 'Camera' },
     
    17482523            7 => 'FocalPlaneXResolution',
    17492524            8 => 'FocalPlaneYResolution',
    1750             9 => 'CanonImageWidth',
    1751            10 => 'CanonImageHeight',
    1752            11 => 'ExifImageWidth',
    1753            12 => 'ExifImageLength',
     2525            9 => 'ExifImageWidth',
     2526           10 => 'ExifImageHeight',
     2527           11 => 'CanonImageWidth',
     2528           12 => 'CanonImageHeight',
    17542529           13 => 'ImageWidth',
    17552530           14 => 'ImageHeight',
     
    17772552        },
    17782553        ValueConv => q{
    1779             return undef unless $val[1] and $val[2];
     2554            ToFloat(@val);
     2555            return 'inf' unless $val[1] and $val[2];
    17802556            return $val[0] * $val[0] / ($val[1] * $val[2] * 1000);
    17812557        },
     
    17832559    },
    17842560    DOF => {
    1785         Description => 'Depth of Field',
     2561        Description => 'Depth Of Field',
    17862562        Notes => 'this value may be incorrect if the image has been resized',
    17872563        Require => {
    1788             0 => 'FocusDistance', # FocusDistance in meters, 0 means 'inf'
    1789             1 => 'FocalLength',
    1790             2 => 'Aperture',
    1791             3 => 'CircleOfConfusion',
     2564            0 => 'FocalLength',
     2565            1 => 'Aperture',
     2566            2 => 'CircleOfConfusion',
     2567        },
     2568        Desire => {
     2569            3 => 'FocusDistance',   # focus distance in metres (0 is infinity)
     2570            4 => 'SubjectDistance',
     2571            5 => 'ObjectDistance',
    17922572        },
    17932573        ValueConv => q{
    1794             return undef unless $val[1] and $val[3];
    1795             $val[0] or $val[0] = 1e10;  # use a large number for 'inf'
    1796             my ($s, $f) = ($val[0], $val[1]);
    1797             my $t = $val[2] * $val[3] * ($s * 1000 - $f) / ($f * $f);
    1798             my @v = ($s / (1 + $t), $s / (1 - $t));
     2574            ToFloat(@val);
     2575            my ($d, $f) = ($val[3], $val[0]);
     2576            if (defined $d) {
     2577                $d or $d = 1e10;    # (use large number for infinity)
     2578            } else {
     2579                $d = $val[4] || $val[5];
     2580                return undef unless defined $d;
     2581            }
     2582            return 0 unless $f and $val[2];
     2583            my $t = $val[1] * $val[2] * ($d * 1000 - $f) / ($f * $f);
     2584            my @v = ($d / (1 + $t), $d / (1 - $t));
    17992585            $v[1] < 0 and $v[1] = 0; # 0 means 'inf'
    18002586            return join(' ',@v);
     
    18072593        },
    18082594    },
    1809     DateTimeCreated => { # used by IPTC, XMP, WAV, etc
    1810         Description => 'Date/Time Created',
    1811         Groups => { 2 => 'Time' },
     2595    FOV => {
     2596        Description => 'Field Of View',
     2597        Notes => q{
     2598            calculated for the long image dimension, this value may be incorrect for
     2599            fisheye lenses, or if the image has been resized
     2600        },
    18122601        Require => {
    1813             0 => 'DateCreated',
    1814             1 => 'TimeCreated',
    1815         },
    1816         ValueConv => '"$val[0] $val[1]"',
    1817         PrintConv => '$self->ConvertDateTime($val)',
    1818     },
    1819     # create DateTimeOriginal from DateTimeCreated if not set already
     2602            0 => 'FocalLength',
     2603            1 => 'ScaleFactor35efl',
     2604        },
     2605        Desire => {
     2606            2 => 'FocusDistance', # (multiply by 1000 to convert to mm)
     2607        },
     2608        # ref http://www.bobatkins.com/photography/technical/field_of_view.html
     2609        # (calculations below apply to rectilinear lenses only, not fisheye)
     2610        ValueConv => q{
     2611            ToFloat(@val);
     2612            return undef unless $val[0] and $val[1];
     2613            my $corr = 1;
     2614            if ($val[2]) {
     2615                my $d = 1000 * $val[2] - $val[0];
     2616                $corr += $val[0]/$d if $d > 0;
     2617            }
     2618            my $fd2 = atan2(36, 2*$val[0]*$val[1]*$corr);
     2619            my @fov = ( $fd2 * 360 / 3.14159 );
     2620            if ($val[2] and $val[2] > 0 and $val[2] < 10000) {
     2621                push @fov, 2 * $val[2] * sin($fd2) / cos($fd2);
     2622            }
     2623            return join(' ', @fov);
     2624        },
     2625        PrintConv => q{
     2626            my @v = split(' ',$val);
     2627            my $str = sprintf("%.1f deg", $v[0]);
     2628            $str .= sprintf(" (%.2f m)", $v[1]) if $v[1];
     2629            return $str;
     2630        },
     2631    },
     2632    # generate DateTimeOriginal from Date and Time Created if not extracted already
    18202633    DateTimeOriginal => {
    1821         Condition => 'not defined($oldVal)',
     2634        Condition => 'not defined $$self{VALUE}{DateTimeOriginal}',
    18222635        Description => 'Date/Time Original',
    18232636        Groups => { 2 => 'Time' },
    1824         Require => 'DateTimeCreated',
    1825         ValueConv => '$val[0]',
    1826         PrintConv => '$prt[0]',
     2637        Desire => {
     2638            0 => 'DateTimeCreated',
     2639            1 => 'DateCreated',
     2640            2 => 'TimeCreated',
     2641        },
     2642        ValueConv => q{
     2643            return $val[0] if $val[0] and $val[0]=~/ /;
     2644            return undef unless $val[1] and $val[2];
     2645            return "$val[1] $val[2]";
     2646        },
     2647        PrintConv => '$self->ConvertDateTime($val)',
    18272648    },
    18282649    ThumbnailImage => {
     
    18442665        Writable => 1,
    18452666        WriteCheck => '$self->CheckImage(\$val)',
     2667        DelCheck => '$val = ""; return undef', # can't delete, so set to empty string
    18462668        WriteAlso => {
    18472669            PreviewImageStart  => 'defined $val ? 0xfeedfeed : undef',
     
    18552677        Desire => {
    18562678            2 => 'PreviewImageValid',
    1857             # (DNG may be have 2 preview images)
     2679            # (DNG and A100 ARW may be have 2 preview images)
    18582680            3 => 'PreviewImageStart (1)',
    18592681            4 => 'PreviewImageLength (1)',
    18602682        },
     2683        # note: extract 2nd preview, but ignore double-referenced preview
     2684        # (in A100 ARW images, the 2nd PreviewImageLength from IFD0 may be wrong anyway)
    18612685        RawConv => q{
    1862             if ($val[3] and $val[4]) {
     2686            if ($val[3] and $val[4] and $val[0] ne $val[3]) {
    18632687                my %val = (
    18642688                    0 => 'PreviewImageStart (1)',
     
    19022726    SubSecDateTimeOriginal => {
    19032727        Description => 'Date/Time Original',
     2728        Groups => { 2 => 'Time' },
    19042729        Require => {
    1905             0 => 'DateTimeOriginal',
     2730            0 => 'EXIF:DateTimeOriginal',
    19062731            1 => 'SubSecTimeOriginal',
    19072732        },
    1908         # be careful here in case there is a timezone following the seconds
    1909         ValueConv => '$_=$val[0];s/(.*:\d{2})/$1\.$val[1]/;$_',
     2733        # be careful here just in case there is a timezone following the seconds
     2734        ValueConv => q{
     2735            return undef if $val[1] eq '';
     2736            $_ = $val[0]; s/( \d{2}:\d{2}:\d{2})/$1\.$val[1]/; $_;
     2737        },
     2738        PrintConv => '$self->ConvertDateTime($val)',
     2739    },
     2740    SubSecCreateDate => {
     2741        Description => 'Create Date',
     2742        Groups => { 2 => 'Time' },
     2743        Require => {
     2744            0 => 'EXIF:CreateDate',
     2745            1 => 'SubSecTimeDigitized',
     2746        },
     2747        ValueConv => q{
     2748            return undef if $val[1] eq '';
     2749            $_ = $val[0]; s/( \d{2}:\d{2}:\d{2})/$1\.$val[1]/; $_;
     2750        },
     2751        PrintConv => '$self->ConvertDateTime($val)',
     2752    },
     2753    SubSecModifyDate => {
     2754        Description => 'Modify Date',
     2755        Groups => { 2 => 'Time' },
     2756        Require => {
     2757            0 => 'EXIF:ModifyDate',
     2758            1 => 'SubSecTime',
     2759        },
     2760        ValueConv => q{
     2761            return undef if $val[1] eq '';
     2762            $_ = $val[0]; s/( \d{2}:\d{2}:\d{2})/$1\.$val[1]/; $_;
     2763        },
    19102764        PrintConv => '$self->ConvertDateTime($val)',
    19112765    },
     
    19192773            my @a = split / /, $val[0];
    19202774            my @b = split / /, $val[1];
    1921             return undef unless @a==2 and @b==$a[0]*$a[1];
     2775            return '?' unless @a==2 and @b==$a[0]*$a[1];
    19222776            return Set16u($a[0]) . Set16u($a[1]) . pack('C*', @b);
    19232777        },
     
    19322786            3 => 'WB_GRBGLevels',
    19332787            4 => 'WB_GRGBLevels',
    1934             5 => 'WB_RBLevels',
    1935             6 => 'WBRedLevel',
    1936             7 => 'WBGreenLevel',
     2788            5 => 'WB_GBRGLevels',
     2789            6 => 'WB_RGBLevels',
     2790            7 => 'WB_RBLevels',
     2791            8 => 'WBRedLevel', # red
     2792            9 => 'WBGreenLevel',
    19372793        },
    19382794        ValueConv => 'Image::ExifTool::Exif::RedBlueBalance(0,@val)',
     
    19472803            3 => 'WB_GRBGLevels',
    19482804            4 => 'WB_GRGBLevels',
    1949             5 => 'WB_RBLevels',
    1950             6 => 'WBBlueLevel',
    1951             7 => 'WBGreenLevel',
     2805            5 => 'WB_GBRGLevels',
     2806            6 => 'WB_RGBLevels',
     2807            7 => 'WB_RBLevels',
     2808            8 => 'WBBlueLevel', # blue
     2809            9 => 'WBGreenLevel',
    19522810        },
    19532811        ValueConv => 'Image::ExifTool::Exif::RedBlueBalance(1,@val)',
     
    19552813    },
    19562814    GPSPosition => {
     2815        Groups => { 2 => 'Location' },
    19572816        Require => {
    19582817            0 => 'GPSLatitude',
     
    19612820        ValueConv => '"$val[0] $val[1]"',
    19622821        PrintConv => '"$prt[0], $prt[1]"',
     2822    },
     2823    LensID => {
     2824        Groups => { 2 => 'Camera' },
     2825        Require => {
     2826            0 => 'LensType',
     2827        },
     2828        Desire => {
     2829            1 => 'FocalLength',
     2830            2 => 'MaxAperture',
     2831            3 => 'MaxApertureValue',
     2832            4 => 'ShortFocal',
     2833            5 => 'LongFocal',
     2834            6 => 'LensModel',
     2835            7 => 'LensFocalRange',
     2836        },
     2837        Notes => q{
     2838            attempt to identify the actual lens from all lenses with a given LensType.
     2839            Applies only to LensType values with a lookup table.  May be configured
     2840            by adding user-defined lenses
     2841        },
     2842        # this LensID is only valid if the LensType has a PrintConv or is a model name
     2843        ValueConv => q{
     2844            return $val[0] if ref $$self{TAG_INFO}{LensType}{PrintConv} eq "HASH" or
     2845                              $prt[0] =~ /(mm|\d\/F)/;
     2846            return undef;
     2847        },
     2848        PrintConv => 'Image::ExifTool::Exif::PrintLensID($self, $prt[0], @val)',
    19632849    },
    19642850);
     
    19832869
    19842870#------------------------------------------------------------------------------
     2871# Identify RAW file type for some TIFF-based formats using Compression value
     2872# Inputs: 0) ExifTool object reference, 1) Compression value
     2873# - sets TIFF_TYPE and FileType if identified
     2874sub IdentifyRawFile($$)
     2875{
     2876    my ($exifTool, $comp) = @_;
     2877    if ($$exifTool{FILE_TYPE} eq 'TIFF' and not $$exifTool{IdentifiedRawFile}) {
     2878        if ($compression{$comp} and $compression{$comp} =~ /^\w+ ([A-Z]{3}) Compressed$/) {
     2879            $exifTool->OverrideFileType($$exifTool{TIFF_TYPE} = $1);
     2880            $$exifTool{IdentifiedRawFile} = 1;
     2881        }
     2882    }
     2883}
     2884
     2885#------------------------------------------------------------------------------
    19852886# Calculate LV (Light Value)
    19862887# Inputs: 0) Aperture, 1) ShutterSpeed, 2) ISO
    1987 # Returns: LV value
     2888# Returns: LV value (and converts input values to floating point if necessary)
    19882889sub CalculateLV($$$)
    19892890{
     
    19922893    return undef unless @_ >= 3;
    19932894    foreach (@_) {
    1994         return undef unless defined $_ and Image::ExifTool::IsFloat($_) and $_ > 0;
     2895        return undef unless $_ and /([+-]?(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?)/ and $1 > 0;
     2896        $_ = $1;    # extract float from any other garbage
    19952897    }
    19962898    # (A light value of 0 is defined as f/1.0 at 1 second with ISO 100)
     
    19992901
    20002902#------------------------------------------------------------------------------
    2001 # Calculate scale factor for 35mm effective focal length
     2903# Calculate scale factor for 35mm effective focal length (ref 26/PH)
    20022904# Inputs: 0) Focal length
    20032905#         1) Focal length in 35mm format
     
    20112913sub CalcScaleFactor35efl
    20122914{
     2915    my $res = $_[6];    # save resolution units (in case they have been converted to string)
     2916    Image::ExifTool::ToFloat(@_);
    20132917    my $focal = shift;
    20142918    my $foc35 = shift;
     
    20192923    my $diag = shift;
    20202924    unless ($diag and Image::ExifTool::IsFloat($diag)) {
     2925        undef $diag;
    20212926        my $xsize = shift;
    20222927        my $ysize = shift;
    20232928        if ($xsize and $ysize) {
    2024             $diag = sqrt($xsize * $xsize + $ysize * $ysize);
    2025         } else {
     2929            # validate by checking aspect ratio because FocalPlaneX/YSize is not reliable
     2930            my $a = $xsize / $ysize;
     2931            if (abs($a-1.3333) < .1 or abs($a-1.5) < .1) {
     2932                $diag = sqrt($xsize * $xsize + $ysize * $ysize);
     2933            }
     2934        }
     2935        unless ($diag) {
    20262936            # get number of mm in units (assume inches unless otherwise specified)
    2027             my $units = { 3=>10, 4=>1, 5=>0.001 }->{ shift() || '' } || 25.4;
     2937            my %lkup = ( 3=>10, 4=>1, 5=>0.001 , cm=>10, mm=>1, um=>0.001 );
     2938            my $units = $lkup{ shift() || $res || '' } || 25.4;
    20282939            my $x_res = shift || return undef;
    20292940            my $y_res = shift || return undef;
     
    20512962
    20522963#------------------------------------------------------------------------------
    2053 # Convert exposure compensation fraction
    2054 sub ConvertFraction($)
     2964# Print exposure compensation fraction
     2965sub PrintFraction($)
    20552966{
    20562967    my $val = shift;
     
    20672978            $str = sprintf("%+d/3", int($val * 3));
    20682979        } else {
    2069             $str = sprintf("%.3g", $val);
     2980            $str = sprintf("%+.3g", $val);
    20702981        }
    20712982    }
     
    20742985
    20752986#------------------------------------------------------------------------------
     2987# Convert fraction or number to floating point value (or 'undef' or 'inf')
     2988sub ConvertFraction($)
     2989{
     2990    my $val = shift;
     2991    if ($val =~ m{([-+]?\d+)/(\d+)}) {
     2992        $val = $2 ? $1 / $2 : ($1 ? 'inf' : 'undef');
     2993    }
     2994    return $val;
     2995}
     2996
     2997#------------------------------------------------------------------------------
    20762998# Convert EXIF text to something readable
    20772999# Inputs: 0) ExifTool object reference, 1) EXIF text
    2078 # Returns: UTF8 or Latin text
     3000# Returns: text encoded according to Charset option (with trailing spaces removed)
    20793001sub ConvertExifText($$)
    20803002{
     
    20833005    my $id = substr($val, 0, 8);
    20843006    my $str = substr($val, 8);
    2085     # by the EXIF spec, the string should be "UNICODE\0", but apparently Kodak
    2086     # sometimes uses "Unicode\0" in the APP3 "Meta" information.  But unfortunately
    2087     # Ricoh uses "Unicode\0" in the RR30 EXIF UserComment when the text is actually
    2088     # ASCII, so only recognize uppercase "UNICODE\0" here.
    2089     if ($id eq "UNICODE\0") {
     3007    # Note: allow spaces instead of nulls in the ID codes because
     3008    # it is fairly common for camera manufacturers to get this wrong
     3009    if ($id =~ /^(ASCII)?[\0 ]+$/) {
     3010        # truncate at null terminator (shouldn't have a null based on the
     3011        # EXIF spec, but it seems that few people actually read the spec)
     3012        $str =~ s/\0.*//s;
     3013    # by the EXIF spec, the following string should be "UNICODE\0", but
     3014    # apparently Kodak sometimes uses "Unicode\0" in the APP3 "Meta" information.
     3015    # However, unfortunately Ricoh uses "Unicode\0" in the RR30 EXIF UserComment
     3016    # when the text is actually ASCII, so only recognize uppercase "UNICODE\0".
     3017    } elsif ($id =~ /^UNICODE[\0 ]$/) {
    20903018        # MicrosoftPhoto writes as little-endian even in big-endian EXIF,
    20913019        # so we must guess at the true byte ordering
    2092         my ($ii, $mm) = (0, 0);
    2093         foreach (unpack('n*', $str)) {
    2094             ++$mm unless $_ & 0xff00;
    2095             ++$ii unless $_ & 0x00ff;
    2096         }
    2097         my $order;
    2098         $order = ($ii > $mm) ? 'II' : 'MM' if $ii != $mm;
    2099         # convert from unicode
    2100         $str = $exifTool->Unicode2Charset($str, $order);
     3020        $str = $exifTool->Decode($str, 'UCS2', 'Unknown');
     3021    } elsif ($id =~ /^JIS[\0 ]{5}$/) {
     3022        $str = $exifTool->Decode($str, 'JIS', 'Unknown');
    21013023    } else {
    2102         # assume everything else is ASCII (Don't convert JIS... yet)
    2103         $str =~ s/\0.*//s;   # truncate at null terminator
     3024        $exifTool->Warn("Invalid EXIF text encoding");
     3025        $str = $id . $str;
    21043026    }
     3027    $str =~ s/ +$//;    # trim trailing blanks
    21053028    return $str;
    21063029}
     
    21303053#------------------------------------------------------------------------------
    21313054# Print numerical parameter value (with sign, or 'Normal' for zero)
    2132 sub PrintParameter($)
     3055# Inputs: 0) value, 1) flag for inverse conversion, 2) conversion hash reference
     3056sub PrintParameter($$$)
    21333057{
    2134     my $val = shift;
     3058    my ($val, $inv, $conv) = @_;
     3059    return $val if $inv;
    21353060    if ($val > 0) {
    21363061        if ($val > 0xfff0) {    # a negative value in disguise?
     
    21393064            $val = "+$val";
    21403065        }
    2141     } elsif ($val == 0) {
    2142         $val = 'Normal';
    21433066    }
    21443067    return $val;
     
    21473070#------------------------------------------------------------------------------
    21483071# Convert parameter back to standard EXIF value
    2149 #   0 or "Normal" => 0
     3072#   0,0.00,etc or "Normal" => 0
    21503073#   -1,-2,etc or "Soft" or "Low" => 1
    21513074#   +1,+2,1,2,etc or "Hard" or "High" => 2
     
    21533076{
    21543077    my $val = shift;
     3078    my $isFloat = Image::ExifTool::IsFloat($val);
    21553079    # normal is a value of zero
    2156     return 0 if $val =~ /\bn/i or not $val;
     3080    return 0 if $val =~ /\bn/i or ($isFloat and $val == 0);
    21573081    # "soft", "low" or any negative number is a value of 1
    2158     return 1 if $val =~ /\b(s|l|-)/i;
    2159     # "hard", "high" or any positive number is a vail of 2
    2160     return 2 if $val =~ /\b(h|\+|\d)/i;
     3082    return 1 if $val =~ /\b(s|l)/i or ($isFloat and $val < 0);
     3083    # "hard", "high" or any positive number is a value of 2
     3084    return 2 if $val =~ /\bh/i or $isFloat;
    21613085    return undef;
    21623086}
     
    21643088#------------------------------------------------------------------------------
    21653089# Calculate Red/BlueBalance
    2166 # Inputs: 0) 0=red, 1=blue, 1-6) WB_RGGB/RGBG/RBGG/GRBG/GRGB/RBLevels,
    2167 #         7) red or blue level, 8) green level
     3090# Inputs: 0) 0=red, 1=blue, 1-7) WB_RGGB/RGBG/RBGG/GRBG/GRGB/RGB/RBLevels,
     3091#         8) red or blue level, 9) green level
    21683092my @rggbLookup = (
    2169     [ 0, 1, 2, 3 ], # RGGB
    2170     [ 0, 1, 3, 2 ], # RGBG
    2171     [ 0, 2, 3, 1 ], # RBGG
    2172     [ 1, 0, 3, 2 ], # GRBG
    2173     [ 1, 0, 2, 3 ], # GRGB
    2174     [ 0, 256, 256, 1 ], # RB (green level is 256)
     3093    # indices for R, G, G and B components in input value
     3094    [ 0, 1, 2, 3 ], # 0 RGGB
     3095    [ 0, 1, 3, 2 ], # 1 RGBG
     3096    [ 0, 2, 3, 1 ], # 2 RBGG
     3097    [ 1, 0, 3, 2 ], # 3 GRBG
     3098    [ 1, 0, 2, 3 ], # 4 GRGB
     3099    [ 2, 3, 0, 1 ], # 5 GBRG
     3100    [ 0, 1, 1, 2 ], # 6 RGB
     3101    [ 0, 256, 256, 1 ], # 7 RB (green level is 256)
    21753102);
    21763103sub RedBlueBalance($@)
     
    21853112        my $g = $$lookup[1];    # get green level or index
    21863113        if ($g < 4) {
    2187             next if @levels < 4;
     3114            next if @levels < 3;
    21883115            $g = ($levels[$g] + $levels[$$lookup[2]]) / 2 or next;
     3116        } elsif ($levels[$$lookup[$blue * 3]] < 4) {
     3117            $g = 1; # Some Nikon cameras use a scaling factor of 1 (E5700)
    21893118        }
    21903119        $val = $levels[$$lookup[$blue * 3]] / $g;
     
    22373166
    22383167#------------------------------------------------------------------------------
     3168# Print conversion for lens info
     3169# Inputs: 0) string of values (min focal, max focal, min F, max F)
     3170# Returns: string in the form "12-20mm f/3.8-4.5" or "50mm f/1.4"
     3171sub PrintLensInfo($)
     3172{
     3173    my $val = shift;
     3174    my @vals = split ' ', $val;
     3175    return $val unless @vals == 4;
     3176    my $c = 0;
     3177    foreach (@vals) {
     3178        Image::ExifTool::IsFloat($_) and ++$c, next;
     3179        $_ eq 'inf' and $_ = '?', ++$c, next;
     3180        $_ eq 'undef' and $_ = '?', ++$c, next;
     3181    }
     3182    return $val unless $c == 4;
     3183    $val = "$vals[1]mm f/$vals[2]";
     3184    $val = "$vals[0]-$val" if $vals[0] ne $vals[1];
     3185    $val .= "-$vals[3]" if $vals[3] ne $vals[2];
     3186    return $val;
     3187}
     3188
     3189#------------------------------------------------------------------------------
     3190# Get lens info from lens model string
     3191# Inputs: 0) lens string, 1) flag to allow unknown "?" values
     3192# Returns: 0) min focal, 1) max focal, 2) min aperture, 3) max aperture
     3193# Notes: returns empty list if lens string could not be parsed
     3194sub GetLensInfo($;$)
     3195{
     3196    my ($lens, $unk) = @_;
     3197    # extract focal length and aperture ranges for this lens
     3198    my $pat = '\\d+(?:\\.\\d+)?';
     3199    $pat .= '|\\?' if $unk;
     3200    return () unless $lens =~ /($pat)(?:-($pat))?\s*mm.*?(?:[fF]\/?\s*)($pat)(?:-($pat))?/;
     3201    # ($1=short focal, $2=long focal, $3=max aperture wide, $4=max aperture tele)
     3202    my @a = ($1, $2, $3, $4);
     3203    $a[1] or $a[1] = $a[0];
     3204    $a[3] or $a[3] = $a[2];
     3205    if ($unk) {
     3206        local $_;
     3207        $_ eq '?' and $_ = 'undef' foreach @a;
     3208    }
     3209    return @a;
     3210}
     3211
     3212#------------------------------------------------------------------------------
     3213# Attempt to identify the specific lens if multiple lenses have the same LensType
     3214# Inputs: 0) ExifTool object ref, 1) LensType string, 2) LensType value,
     3215#         3) FocalLength, 4) MaxAperture, 5) MaxApertureValue, 6) ShortFocal,
     3216#         7) LongFocal, 8) LensModel, 9) LensFocalRange
     3217sub PrintLensID($$@)
     3218{
     3219    my ($exifTool, $lensTypePrt, $lensType, $focalLength, $maxAperture,
     3220        $maxApertureValue, $shortFocal, $longFocal, $lensModel, $lensFocalRange) = @_;
     3221    # the rest of the logic relies on the LensType lookup:
     3222    return undef unless defined $lensType;
     3223    my $printConv = $exifTool->{TAG_INFO}{LensType}{PrintConv};
     3224    # just copy LensType PrintConv value if it was a lens name
     3225    # (Olympus or Panasonic -- just exclude things like Nikon and Leaf LensType)
     3226    unless (ref $printConv eq 'HASH') {
     3227        return $lensTypePrt if $lensTypePrt =~ /mm/;
     3228        return $lensTypePrt if $lensTypePrt =~ s/(\d)\/F/$1mm F/;
     3229        return undef;
     3230    }
     3231    # use MaxApertureValue if MaxAperture is not available
     3232    $maxAperture = $maxApertureValue unless $maxAperture;
     3233    if ($lensFocalRange and $lensFocalRange =~ /^(\d+)(?: to (\d+))?$/) {
     3234        ($shortFocal, $longFocal) = ($1, $2 || $1);
     3235    }
     3236    if ($shortFocal and $longFocal) {
     3237        # Canon includes makernote information which allows better lens identification
     3238        require Image::ExifTool::Canon;
     3239        return Image::ExifTool::Canon::PrintLensID($printConv, $lensType,
     3240                    $shortFocal, $longFocal, $maxAperture, $lensModel);
     3241    }
     3242    my $lens = $$printConv{$lensType};
     3243    return ($lensModel || $lensTypePrt) unless $lens;
     3244    return $lens unless $$printConv{"$lensType.1"};
     3245    $lens =~ s/ or .*//s;    # remove everything after "or"
     3246    # make list of all possible matching lenses
     3247    my @lenses = ( $lens );
     3248    my $i;
     3249    for ($i=1; $$printConv{"$lensType.$i"}; ++$i) {
     3250        push @lenses, $$printConv{"$lensType.$i"};
     3251    }
     3252    # attempt to determine actual lens
     3253    my (@matches, @best, @user, $diff);
     3254    foreach $lens (@lenses) {
     3255        if ($Image::ExifTool::userLens{$lens}) {
     3256            push @user, $lens;
     3257            next;
     3258        }
     3259        my ($sf, $lf, $sa, $la) = GetLensInfo($lens);
     3260        next unless $sf;
     3261        # see if we can rule out this lens using FocalLength and MaxAperture
     3262        if ($focalLength) {
     3263            next if $focalLength < $sf - 0.5;
     3264            next if $focalLength > $lf + 0.5;
     3265        }
     3266        if ($maxAperture) {
     3267            # it seems that most manufacturers set MaxAperture and MaxApertureValue
     3268            # to the maximum aperture (smallest F number) for the current focal length
     3269            # of the lens, so assume that MaxAperture varies with focal length and find
     3270            # the closest match (this is somewhat contrary to the EXIF specification which
     3271            # states "The smallest F number of the lens", without mention of focal length)
     3272            next if $maxAperture < $sa - 0.15;  # (0.15 is arbitrary)
     3273            next if $maxAperture > $la + 0.15;
     3274            # now determine the best match for this aperture
     3275            my $aa; # approximate maximum aperture at this focal length
     3276            if ($sf == $lf or $sa == $la) {
     3277                $aa = $sa;
     3278            } else {
     3279                # assume a log-log variation of max aperture with focal length
     3280                # (see http://regex.info/blog/2006-10-05/263)
     3281                $aa = exp(log($sa) + (log($la)-log($sa)) / (log($lf)-log($sf)) *
     3282                                     (log($focalLength)-log($sf)));
     3283            }
     3284            my $d = abs($maxAperture - $aa);
     3285            if (defined $diff) {
     3286                $d > $diff + 0.15 and next;     # (0.15 is arbitrary)
     3287                $d < $diff - 0.15 and undef @best;
     3288            }
     3289            $diff = $d;
     3290            push @best, $lens;
     3291        }
     3292        push @matches, $lens;
     3293    }
     3294    return join(' or ', @user) if @user;
     3295    return join(' or ', @best) if @best;
     3296    return join(' or ', @matches) if @matches;
     3297    return $$printConv{$lensType};
     3298}
     3299
     3300#------------------------------------------------------------------------------
    22393301# translate date into standard EXIF format
    22403302# Inputs: 0) date
     
    22823344    my $image;
    22833345
    2284     return undef unless $len;   # no image if length is zero
     3346    # no image if length is zero, and don't try to extract binary from XMP file
     3347    return undef if not $len or $$exifTool{FILE_TYPE} eq 'XMP';
    22853348
    22863349    # take data from EXIF block if possible
     
    22903353        $image = $exifTool->ExtractBinary($offset, $len, $tag);
    22913354        return undef unless defined $image;
     3355        # patch for incorrect ThumbnailOffset in some Sony DSLR-A100 ARW images
     3356        if ($tag and $tag eq 'ThumbnailImage' and $$exifTool{TIFF_TYPE} eq 'ARW' and
     3357            $$exifTool{Model} eq 'DSLR-A100' and $offset < 0x10000 and
     3358            $image !~ /^(Binary data|\xff\xd8\xff)/)
     3359        {
     3360            my $try = $exifTool->ExtractBinary($offset + 0x10000, $len, $tag);
     3361            if (defined $try and $try =~ /^\xff\xd8\xff/) {
     3362                $image = $try;
     3363                $exifTool->{VALUE}->{ThumbnailOffset} += 0x10000;
     3364                $exifTool->Warn('Adjusted incorrect A100 ThumbnailOffset', 1);
     3365            }
     3366        }
    22923367    }
    22933368    return $exifTool->ValidateImage(\$image, $tag);
     
    23153390    my $htmlDump = $exifTool->{HTML_DUMP};
    23163391    my $success = 1;
    2317     my ($tagKey, $name, $dirSize, $makerAddr);
    2318 
     3392    my ($tagKey, $dirSize, $makerAddr);
     3393    my $inMakerNotes = $tagTablePtr->{GROUPS}{0} eq 'MakerNotes';
     3394
     3395    # ignore non-standard EXIF while in strict MWG compatibility mode
     3396    if ($Image::ExifTool::MWG::strict and $dirName eq 'IFD0' and
     3397        $tagTablePtr eq \%Image::ExifTool::Exif::Main and
     3398        $$exifTool{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/)
     3399    {
     3400        my $path = $exifTool->MetadataPath();
     3401        unless ($path =~ /^(JPEG-APP1-IFD0|TIFF-IFD0|PSD-EXIFInfo-IFD0)$/) {
     3402            $exifTool->Warn("Ignored non-standard EXIF at $path");
     3403            return 1;
     3404        }
     3405    }
    23193406    $verbose = -1 if $htmlDump; # mix htmlDump into verbose so we can test for both at once
    23203407    $dirName eq 'EXIF' and $dirName = $$dirInfo{DirName} = 'IFD0';
    2321     $$dirInfo{Multi} = 1 if $dirName eq 'IFD0' or $dirName eq 'SubIFD';
    2322     $htmlDump and $name = ($dirName eq 'MakerNotes') ? $$dirInfo{Name} : $dirName;
     3408    $$dirInfo{Multi} = 1 if $dirName =~ /^(IFD0|SubIFD)$/ and not defined $$dirInfo{Multi};
     3409    # get a more descriptive name for MakerNote sub-directories
     3410    my $name = $$dirInfo{Name};
     3411    $name = $dirName unless $name and $inMakerNotes and $name !~ /^MakerNote/;
    23233412
    23243413    my ($numEntries, $dirEnd);
     
    23563445                    $dataLen = $$dirInfo{DataLen} = length $buff;
    23573446                    $dirStart = $$dirInfo{DirStart} = 0;
     3447                    $dirLen = $$dirInfo{DirLen} = length $buff;
    23583448                    $success = 1;
    23593449                }
     
    23613451        }
    23623452        unless ($success) {
    2363             $exifTool->Warn("Bad $dirName directory");
     3453            $exifTool->Warn("Bad $name directory");
    23643454            return 0;
    23653455        }
     
    23723462    if ($bytesFromEnd < 4) {
    23733463        unless ($bytesFromEnd==2 or $bytesFromEnd==0) {
    2374             $exifTool->Warn(sprintf"Illegal $dirName directory size (0x%x entries)",$numEntries);
     3464            $exifTool->Warn(sprintf"Illegal $name directory size (0x%x entries)",$numEntries);
    23753465            return 0;
    23763466        }
     
    23863476    }
    23873477    if ($htmlDump) {
     3478        my $longName = $name eq 'MakerNotes' ? ($$dirInfo{Name} || $name) : $name;
    23883479        if (defined $makerAddr) {
    23893480            my $hdrLen = $dirStart + $dataPos + $base - $makerAddr;
    2390             $exifTool->HtmlDump($makerAddr, $hdrLen, "MakerNotes header", $name) if $hdrLen > 0;
     3481            $exifTool->HDump($makerAddr, $hdrLen, "MakerNotes header", $longName) if $hdrLen > 0;
    23913482        }
    2392         $exifTool->HtmlDump($dirStart + $dataPos + $base, 2, "$name entries",
     3483        $exifTool->HDump($dirStart + $dataPos + $base, 2, "$longName entries",
    23933484                 "Entry count: $numEntries");
    23943485        my $tip;
    23953486        if ($bytesFromEnd >= 4) {
    2396             my $nxt = ($name =~ /^IFD(\d+)/) ? "IFD" . ($1 + 1) : 'Next IFD';
     3487            my $nxt = ($name =~ /^(.*?)(\d+)$/) ? $1 . ($2 + 1) : 'Next IFD';
    23973488            $tip = sprintf("$nxt offset: 0x%.4x", Get32u($dataPt, $dirEnd));
    23983489        }
    2399         $exifTool->HtmlDump($dirEnd + $dataPos + $base, 4, "Next IFD", $tip, 0);
    2400         $name = $dirName if $name =~ /^MakerNote/;
     3490        $exifTool->HDump($dirEnd + $dataPos + $base, 4, "Next IFD", $tip, 0);
    24013491    }
    24023492
     3493    # patch for Canon EOS 40D firmware 1.0.4 bug (incorrect directory counts)
     3494    # (must do this before parsing directory or CameraSettings offset will be suspicious)
     3495    if ($inMakerNotes and $$exifTool{Model} eq 'Canon EOS 40D') {
     3496        my $entry = $dirStart + 2 + 12 * ($numEntries - 1);
     3497        my $fmt = Get16u($dataPt, $entry + 2);
     3498        if ($fmt < 1 or $fmt > 13) {
     3499            $exifTool->HDump($entry+$dataPos+$base,12,"[invalid IFD entry]",
     3500                     "Bad format type: $fmt", 1);
     3501            # adjust the number of directory entries
     3502            --$numEntries;
     3503            $dirEnd -= 12;
     3504        }
     3505    }
     3506
    24033507    # loop through all entries in an EXIF directory (IFD)
    2404     my ($index, $valEnd);
     3508    my ($index, $valEnd, $offList, $offHash);
     3509    my $warnCount = 0;
    24053510    for ($index=0; $index<$numEntries; ++$index) {
     3511        if ($warnCount > 10) {
     3512            $exifTool->Warn("Too many warnings -- $name parsing aborted", 1) and return 0;
     3513        }
    24063514        my $entry = $dirStart + 2 + 12 * $index;
    24073515        my $tagID = Get16u($dataPt, $entry);
     
    24093517        my $count = Get32u($dataPt, $entry+4);
    24103518        if ($format < 1 or $format > 13) {
    2411             $exifTool->HtmlDump($entry+$dataPos+$base,12,"[invalid IFD entry]",
     3519            $exifTool->HDump($entry+$dataPos+$base,12,"[invalid IFD entry]",
    24123520                     "Bad format type: $format", 1);
    24133521            # warn unless the IFD was just padded with zeros
    2414             $format and $exifTool->Warn(
    2415                 sprintf("Unknown format ($format) for $dirName tag 0x%x",$tagID));
     3522            if ($format) {
     3523                $exifTool->Warn(sprintf("Unknown format ($format) for $name tag 0x%x",$tagID));
     3524                ++$warnCount;
     3525            }
    24163526            return 0 unless $index; # assume corrupted IFD if this is our first entry
    24173527            next;
    24183528        }
    24193529        my $formatStr = $formatName[$format];   # get name of this format
    2420         my $size = $count * $formatSize[$format];
    24213530        my $valueDataPt = $dataPt;
    24223531        my $valueDataPos = $dataPos;
     
    24243533        my $valuePtr = $entry + 8;      # pointer to value within $$dataPt
    24253534        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
     3535        my $origFormStr;
     3536        # hack to patch incorrect count in Kodak SubIFD3 tags
     3537        if ($count < 2 and ref $$tagTablePtr{$tagID} eq 'HASH' and $$tagTablePtr{$tagID}{FixCount}) {
     3538            $offList or ($offList, $offHash) = GetOffList($dataPt, $dirStart, $dataPos,
     3539                                                          $numEntries, $tagTablePtr);
     3540            my $i = $$offHash{Get32u($dataPt, $valuePtr)};
     3541            if (defined $i and $i < $#$offList) {
     3542                my $oldCount = $count;
     3543                $count = int(($$offList[$i+1] - $$offList[$i]) / $formatSize[$format]);
     3544                $origFormStr = $formatName[$format] . '[' . $oldCount . ']' if $oldCount != $count;
     3545            }
     3546        }
     3547        my $size = $count * $formatSize[$format];
     3548        my $readSize = $size;
    24263549        if ($size > 4) {
    24273550            if ($size > 0x7fffffff) {
    2428                 $exifTool->Warn(sprintf("Invalid size ($size) for $dirName tag 0x%x",$tagID));
     3551                $exifTool->Warn(sprintf("Invalid size ($size) for $name tag 0x%x",$tagID));
     3552                ++$warnCount;
    24293553                next;
    24303554            }
     
    24343558                my $wFlag;
    24353559                $valEnd or $valEnd = $dataPos + $dirEnd + 4;
    2436                 #### eval FixOffsets($valuePtr, $valEnd, $size, $tagID, $wFlag)
     3560                #### eval FixOffsets ($valuePtr, $valEnd, $size, $tagID, $wFlag)
    24373561                eval $$dirInfo{FixOffsets};
    24383562            }
     3563            my $suspect;
     3564            # offset shouldn't point into TIFF header
     3565            $valuePtr < 8 and $suspect = $warnCount;
    24393566            # convert offset to pointer in $$dataPt
    24403567            if ($$dirInfo{EntryBased} or (ref $$tagTablePtr{$tagID} eq 'HASH' and
    2441                 $tagTablePtr->{$tagID}->{EntryBased}))
     3568                $tagTablePtr->{$tagID}{EntryBased}))
    24423569            {
    24433570                $valuePtr += $entry;
     
    24453572                $valuePtr -= $dataPos;
    24463573            }
     3574            # value shouldn't overlap our directory
     3575            $suspect = $warnCount if $valuePtr < $dirEnd and $valuePtr+$size > $dirStart;
     3576            # load value from file if necessary
    24473577            if ($valuePtr < 0 or $valuePtr+$size > $dataLen) {
    24483578                # get value by seeking in file if we are allowed
    24493579                my $buff;
    24503580                if ($raf) {
    2451                     if ($raf->Seek($base + $valuePtr + $dataPos,0) and
    2452                         $raf->Read($buff,$size) == $size)
     3581                    # avoid loading large binary data unless necessary
     3582                    # (ie. ImageSourceData -- layers in Photoshop TIFF image)
     3583                    while ($size > BINARY_DATA_LIMIT) {
     3584                        if ($tagInfo) {
     3585                            # make large unknown blocks binary data
     3586                            $$tagInfo{Binary} = 1 if $$tagInfo{Unknown};
     3587                            last unless $$tagInfo{Binary};      # must read non-binary data
     3588                            last if $$tagInfo{SubDirectory};    # must read SubDirectory data
     3589                            if ($exifTool->{OPTIONS}{Binary}) {
     3590                                # read binary data if specified unless tagsFromFile won't use it
     3591                                last unless $$exifTool{TAGS_FROM_FILE} and $$tagInfo{Protected};
     3592                            }
     3593                            # must read if tag is specified by name
     3594                            last if $exifTool->{REQ_TAG_LOOKUP}{lc($$tagInfo{Name})};
     3595                        } else {
     3596                            # must read value if needed for a condition
     3597                            last if defined $tagInfo;
     3598                        }
     3599                        # (note: changing the value without changing $size will cause
     3600                        # a warning in the verbose output, but we need to maintain the
     3601                        # proper size for the htmlDump, so we can't change this)
     3602                        $buff = "Binary data $size bytes";
     3603                        $readSize = length $buff;
     3604                        last;
     3605                    }
     3606                    # read from file if necessary
     3607                    unless (defined $buff or
     3608                            ($raf->Seek($base + $valuePtr + $dataPos,0) and
     3609                             $raf->Read($buff,$size) == $size))
    24533610                    {
    2454                         $valueDataPt = \$buff;
    2455                         $valueDataPos = $valuePtr + $dataPos;
    2456                         $valueDataLen = $size;
    2457                         $valuePtr = 0;
    2458                     } else {
    2459                         $exifTool->Warn("Error reading value for $dirName entry $index");
    2460                         return 0;
     3611                        $exifTool->Warn("Error reading value for $name entry $index", $inMakerNotes);
     3612                        return 0 unless $inMakerNotes;
     3613                        ++$warnCount;
     3614                        $buff = '' unless defined $buff;
     3615                        $readSize = length $buff;
    24613616                    }
     3617                    $valueDataPt = \$buff;
     3618                    $valueDataPos = $valuePtr + $dataPos;
     3619                    $valueDataLen = length $buff;
     3620                    $valuePtr = 0;
    24623621                } else {
    2463                     my $tagStr;
     3622                    my ($tagStr, $tmpInfo);
    24643623                    if ($tagInfo) {
    24653624                        $tagStr = $$tagInfo{Name};
    24663625                    } elsif (defined $tagInfo) {
    2467                         my $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \ '', $formatStr, $count);
     3626                        $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \ '', $formatStr, $count);
    24683627                        $tagStr = $$tmpInfo{Name} if $tmpInfo;
     3628                    }
     3629                    if ($tagInfo and $$tagInfo{ChangeBase}) {
     3630                        # adjust base offset for this tag only
     3631                        #### eval ChangeBase ($dirStart,$dataPos)
     3632                        my $newBase = eval $$tagInfo{ChangeBase};
     3633                        $valuePtr += $newBase;
    24693634                    }
    24703635                    $tagStr or $tagStr = sprintf("tag 0x%x",$tagID);
     
    24783643                        $valueDataLen = $size;
    24793644                        $valuePtr = 0;
     3645                    } elsif ($tagStr eq 'MakerNoteLeica6' and $exifTool->{RAF}) {
     3646                        if ($verbose > 0) {
     3647                            $exifTool->VPrint(0, "$$exifTool{INDENT}$index) $tagStr --> (outside APP1 segment)\n");
     3648                        }
     3649                        if ($exifTool->Options('FastScan')) {
     3650                            $exifTool->Warn('Ignored Leica MakerNote trailer');
     3651                        } else {
     3652                            $$exifTool{LeicaTrailer} = {
     3653                                TagInfo => $tagInfo || $tmpInfo,
     3654                                Offset  => $base + $valuePtr + $dataPos,
     3655                                Size    => $size,
     3656                            };
     3657                        }
    24803658                    } else {
    2481                         $exifTool->Warn("Bad $dirName directory pointer for $tagStr");
     3659                        $exifTool->Warn("Bad $name offset for $tagStr");
     3660                        ++$warnCount;
    24823661                    }
    24833662                    unless (defined $buff) {
     
    24903669                }
    24913670            }
     3671            # warn about suspect offsets if they didn't already cause another warning
     3672            if (defined $suspect and $suspect == $warnCount) {
     3673                my $tagStr = $tagInfo ? $$tagInfo{Name} : sprintf('tag 0x%.4x', $tagID);
     3674                if ($exifTool->Warn("Suspicious $name offset for $tagStr", $inMakerNotes)) {
     3675                    ++$warnCount;
     3676                    next unless $verbose;
     3677                }
     3678            }
    24923679        }
    24933680        # treat single unknown byte as int8u
    24943681        $formatStr = 'int8u' if $format == 7 and $count == 1;
    24953682
    2496         my $val;
    2497         if ($tagID > 0xf000 and not $$tagTablePtr{$tagID}
    2498             and $tagTablePtr eq \%Image::ExifTool::Exif::Main)
    2499         {
    2500             # handle special case of Photoshop RAW tags (0xfde8-0xfe58)
    2501             # --> generate tags from the value if possible
    2502             $val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$size);
    2503             if (defined $val and $val =~ /(.*): (.*)/) {
    2504                 my $tag = $1;
    2505                 $val = $2;
    2506                 $tag =~ s/'s//; # remove 's (so "Owner's Name" becomes "OwnerName")
    2507                 $tag =~ tr/a-zA-Z0-9_//cd; # remove unknown characters
    2508                 if ($tag) {
    2509                     $tagInfo = {
    2510                         Name => $tag,
    2511                         ValueConv => '$_=$val;s/.*: //;$_', # remove descr
    2512                     };
    2513                     Image::ExifTool::AddTagToTable($tagTablePtr, $tagID, $tagInfo);
     3683        my ($val, $subdir, $wrongFormat);
     3684        if ($tagID > 0xf000 and $tagTablePtr eq \%Image::ExifTool::Exif::Main) {
     3685            my $oldInfo = $$tagTablePtr{$tagID};
     3686            if (not $oldInfo or (ref $oldInfo eq 'HASH' and $$oldInfo{Condition})) {
     3687                # handle special case of Photoshop RAW tags (0xfde8-0xfe58)
     3688                # --> generate tags from the value if possible
     3689                $val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$readSize);
     3690                if (defined $val and $val =~ /(.*): (.*)/) {
     3691                    my $tag = $1;
     3692                    $val = $2;
     3693                    $tag =~ s/'s//; # remove 's (so "Owner's Name" becomes "OwnerName")
     3694                    $tag =~ tr/a-zA-Z0-9_//cd; # remove unknown characters
     3695                    if ($tag) {
     3696                        $tagInfo = {
     3697                            Name => $tag,
     3698                            ValueConv => '$_=$val;s/.*: //;$_', # remove descr
     3699                        };
     3700                        Image::ExifTool::AddTagToTable($tagTablePtr, $tagID, $tagInfo);
     3701                        # generate conditional list if a conditional tag already existed
     3702                        $$tagTablePtr{$tagID} = [ $oldInfo, $tagInfo ] if $oldInfo;
     3703                    }
    25143704                }
    25153705            }
     
    25173707        if (defined $tagInfo and not $tagInfo) {
    25183708            # GetTagInfo() required the value for a Condition
    2519             my $tmpVal = substr($$valueDataPt, $valuePtr, $size < 48 ? $size : 48);
    2520             $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$tmpVal, $formatStr, $count);
     3709            my $tmpVal = substr($$valueDataPt, $valuePtr, $readSize < 128 ? $readSize : 128);
     3710            # (use original format name in this call -- $formatStr may have been changed to int8u)
     3711            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$tmpVal,
     3712                                             $formatName[$format], $count);
    25213713        }
    2522         # override EXIF format if specified
    2523         my $origFormStr;
     3714        # make sure we are handling the 'ifd' format properly
     3715        if (($format == 13 or $format == 18) and (not $tagInfo or not $$tagInfo{SubIFD})) {
     3716            my $str = sprintf('%s tag 0x%.4x IFD format not handled', $dirName, $tagID);
     3717            $exifTool->Warn($str, $inMakerNotes);
     3718        }
    25243719        if (defined $tagInfo) {
     3720            $subdir = $$tagInfo{SubDirectory};
     3721            # override EXIF format if specified
    25253722            if ($$tagInfo{Format}) {
    25263723                $formatStr = $$tagInfo{Format};
    2527                 # must adjust number of items for new format size
    25283724                my $newNum = $formatNumber{$formatStr};
    2529                 if ($newNum) {
     3725                if ($newNum and $newNum != $format) {
    25303726                    $origFormStr = $formatName[$format] . '[' . $count . ']';
    25313727                    $format = $newNum;
    2532                     $count = $size / $formatSize[$format];
     3728                    # adjust number of items for new format size
     3729                    $count = int($size / $formatSize[$format]);
    25333730                }
     3731            }
     3732            # verify that offset-type values are integral
     3733            if (($$tagInfo{IsOffset} or $$tagInfo{SubIFD}) and not $intFormat{$formatStr}) {
     3734                $exifTool->Warn("Wrong format ($formatStr) for $name $$tagInfo{Name}");
     3735                next unless $verbose;
     3736                $wrongFormat = 1;
    25343737            }
    25353738        } else {
     
    25373740        }
    25383741        # convert according to specified format
    2539         $val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$size);
     3742        $val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$readSize);
    25403743
    25413744        if ($verbose) {
     3745            my $tval = $val;
     3746            if ($formatStr =~ /^rational64([su])$/ and defined $tval) {
     3747                # show numerator/denominator separately
     3748                my $f = ReadValue($valueDataPt,$valuePtr,"int32$1",$count*2,$readSize);
     3749                $f =~ s/(-?\d+) (-?\d+)/$1\/$2/g;
     3750                $tval .= " ($f)";
     3751            }
    25423752            if ($htmlDump) {
    25433753                my ($tagName, $colName);
     
    25523762                # build our tool tip
    25533763                $size < 0 and $size = $count * $formatSize[$format];
    2554                 my $tip = sprintf("Tag ID: 0x%.4x\\n", $tagID) .
    2555                           "Format: $formatName[$format]\[$count]\\nSize: $size bytes\\n";
     3764                my $fstr = "$formatName[$format]\[$count]";
     3765                $fstr = "$origFormStr read as $fstr" if $origFormStr and $origFormStr ne $fstr;
     3766                $fstr .= ' <-- WRONG' if $wrongFormat;
     3767                my $tip = sprintf("Tag ID: 0x%.4x\n", $tagID) .
     3768                          "Format: $fstr\nSize: $size bytes\n";
    25563769                if ($size > 4) {
    25573770                    my $offPt = Get32u($dataPt,$entry+8);
    2558                     $tip .= sprintf("Value offset: 0x%.4x\\n", $offPt);
    25593771                    my $actPt = $valuePtr + $valueDataPos + $base - ($$exifTool{EXIF_POS} || 0);
     3772                    $tip .= sprintf("Value offset: 0x%.4x\n", $offPt);
    25603773                    # highlight tag name (red for bad size)
    2561                     my $style = ($valueDataLen < 0) ? 'V' : 'H';
     3774                    my $style = ($valueDataLen < 0 or not defined $tval) ? 'V' : 'H';
    25623775                    if ($actPt != $offPt) {
    2563                         $tip .= sprintf("Actual offset: 0x%.4x\\n", $actPt);
     3776                        $tip .= sprintf("Actual offset: 0x%.4x\n", $actPt);
     3777                        my $sign = $actPt < $offPt ? '-' : '';
     3778                        $tip .= sprintf("Offset base: ${sign}0x%.4x\n", abs($actPt - $offPt));
    25643779                        $style = 'F' if $style eq 'H';  # purple for different offsets
    25653780                    }
    25663781                    $colName = "<span class=$style>$tagName</span>";
     3782                    $colName .= ' <span class=V>(odd)</span>' if $offPt & 0x01;
    25673783                } else {
    25683784                    $colName = $tagName;
    25693785                }
    2570                 my $tval;
    2571                 if ($valueDataLen < 0) {
     3786                $colName .= ' <span class=V>(err)</span>' if $wrongFormat;
     3787                if ($valueDataLen < 0 or not defined $tval) {
    25723788                    $tval = '<bad offset>';
    25733789                } else {
    2574                     $tval = (length $val < 32) ? $val : substr($val,0,28) . '[...]';
     3790                    $tval = substr($tval,0,28) . '[...]' if length($tval) > 32;
    25753791                    if ($formatStr =~ /^(string|undef|binary)/) {
    2576                         # translate all characters that could mess up JavaScript
    2577                         $tval =~ tr/\\\x00-\x1f\x7f-\xff/./;
    2578                         $tval =~ tr/"/'/;
    2579                         $tval = "$tval";
     3792                        # translate non-printable characters
     3793                        $tval =~ tr/\x00-\x1f\x7f-\xff/./;
    25803794                    } elsif ($tagInfo and Image::ExifTool::IsInt($tval)) {
    2581                         if ($$tagInfo{IsOffset}) {
     3795                        if ($$tagInfo{IsOffset} or $$tagInfo{SubIFD}) {
    25823796                            $tval = sprintf('0x%.4x', $tval);
     3797                            my $actPt = $val + $base - ($$exifTool{EXIF_POS} || 0);
     3798                            if ($actPt != $val) {
     3799                                $tval .= sprintf("\nActual offset: 0x%.4x", $actPt);
     3800                                my $sign = $actPt < $val ? '-' : '';
     3801                                $tval .= sprintf("\nOffset base: ${sign}0x%.4x", abs($actPt - $val));
     3802                            }
    25833803                        } elsif ($$tagInfo{PrintHex}) {
    25843804                            $tval = sprintf('0x%x', $tval);
     
    25873807                }
    25883808                $tip .= "Value: $tval";
    2589                 $exifTool->HtmlDump($entry+$dataPos+$base, 12, "$dname $colName", $tip, 1);
     3809                $exifTool->HDump($entry+$dataPos+$base, 12, "$dname $colName", $tip, 1);
    25903810                next if $valueDataLen < 0;  # don't process bad pointer entry
    25913811                if ($size > 4) {
    25923812                    my $exifDumpPos = $valuePtr + $valueDataPos + $base;
     3813                    my $flag = 0;
     3814                    if ($subdir) {
     3815                        if ($$tagInfo{MakerNotes}) {
     3816                            $flag = 0x04;
     3817                        } elsif ($$tagInfo{NestedHtmlDump}) {
     3818                            $flag = $$tagInfo{NestedHtmlDump} == 2 ? 0x10 : 0x04;
     3819                        }
     3820                    }
    25933821                    # add value data block (underlining maker notes data)
    2594                     $exifTool->HtmlDump($exifDumpPos,$size,"$tagName value",'SAME',
    2595                         ($tagInfo and $$tagInfo{SubDirectory} and
    2596                         ($$tagInfo{MakerNotes} or $$tagInfo{DNGMakerNotes})) ? 4 : 0);
     3822                    $exifTool->HDump($exifDumpPos,$size,"$tagName value",'SAME', $flag);
    25973823                }
    25983824            } else {
    25993825                my $fstr = $formatName[$format];
    2600                 $origFormStr and $fstr = "$origFormStr read as $fstr";
     3826                $fstr = "$origFormStr read as $fstr" if $origFormStr;
    26013827                $exifTool->VerboseInfo($tagID, $tagInfo,
    26023828                    Table   => $tagTablePtr,
    26033829                    Index   => $index,
    2604                     Value   => $val,
     3830                    Value   => $tval,
    26053831                    DataPt  => $valueDataPt,
    26063832                    DataPos => $valueDataPos + $base,
     
    26113837                );
    26123838            }
    2613             next unless $tagInfo;
     3839            next if not $tagInfo or $wrongFormat;
    26143840        }
     3841        next unless defined $val;
    26153842#..............................................................................
    26163843# Handle SubDirectory tag types
    26173844#
    2618         my $subdir = $$tagInfo{SubDirectory};
    26193845        if ($subdir) {
     3846            # don't process empty subdirectories
     3847            unless ($size) {
     3848                unless ($$tagInfo{MakerNotes} or $inMakerNotes) {
     3849                    $exifTool->Warn("Empty $$tagInfo{Name} data", 1);
     3850                }
     3851                next;
     3852            }
    26203853            my (@values, $newTagTable, $dirNum, $newByteOrder, $invalid);
    26213854            my $tagStr = $$tagInfo{Name};
     
    26913924                    # calculate subdirectory start relative to $base for eval
    26923925                    my $start = $subdirStart + $subdirDataPos;
    2693                     #### eval Base ($start)
     3926                    #### eval Base ($start,$base)
    26943927                    $subdirBase = eval($$subdir{Base}) + $base;
    26953928                }
     
    27013934                        $exifTool->Warn("Bad $tagStr OffsetPt");
    27023935                        last;
    2703                     }                   
     3936                    }
    27043937                    SetByteOrder($newByteOrder);
    27053938                    $subdirStart += Get32u($subdirDataPt, $pos);
     
    27083941                if ($subdirStart < 0 or $subdirStart + 2 > $subdirDataLen) {
    27093942                    # convert $subdirStart back to a file offset
    2710                     $subdirStart += $subdirDataPos;
    2711                     my $dirOK;
    27123943                    if ($raf) {
    2713                         # read the directory from the file
    2714                         if ($raf->Seek($subdirStart + $base,0)) {
    2715                             my ($buff, $buf2);
    2716                             if ($raf->Read($buff,2) == 2) {
    2717                                 # get no. dir entries
    2718                                 $size = 12 * Get16u(\$buff, 0);
    2719                                 # read dir (plus next IFD pointer)
    2720                                 if ($raf->Read($buf2,$size+4) >= $size) {
    2721                                     # set up variables to process new subdir data
    2722                                     $buff .= $buf2;
    2723                                     $size = length $buff;
    2724                                     $subdirDataPt = \$buff;
    2725                                     $subdirDataPos = $subdirStart;
    2726                                     $subdirDataLen = $size;
    2727                                     $subdirStart = 0;
    2728                                     $dirOK = 1;
    2729                                 }
    2730                             }
    2731                         }
    2732                     }
    2733                     unless ($dirOK) {
     3944                        # reset SubDirectory buffer (we will load it later)
     3945                        my $buff = '';
     3946                        $subdirDataPt = \$buff;
     3947                        $subdirDataLen = $size = length $buff;
     3948                    } else {
    27343949                        my $msg = "Bad $tagStr SubDirectory start";
    27353950                        if ($verbose > 0) {
     
    27603975                    RAF        => $raf,
    27613976                    Parent     => $dirName,
     3977                    DirName    => $$subdir{DirName},
    27623978                    FixBase    => $$subdir{FixBase},
    27633979                    FixOffsets => $$subdir{FixOffsets},
     
    27653981                    TagInfo    => $tagInfo,
    27663982                    SubIFD     => $$tagInfo{SubIFD},
     3983                    Subdir     => $subdir,
    27673984                );
     3985                # (remember: some cameras incorrectly write maker notes in IFD0)
    27683986                if ($$tagInfo{MakerNotes}) {
     3987                    # don't parse makernotes if FastScan > 1
     3988                    my $fast = $exifTool->Options('FastScan');
     3989                    last if $fast and $fast > 1;
    27693990                    $subdirInfo{MakerNoteAddr} = $valuePtr + $valueDataPos + $base;
    2770                     $subdirInfo{NoFixBase} = 1 if $$subdir{Base};
     3991                    $subdirInfo{NoFixBase} = 1 if defined $$subdir{Base};
    27713992                }
    2772                 # some Pentax cameras (Optio 330) write maker notes in IFD0
    2773                 # set directory IFD name from group name of family 1 in tag information if it exists
    2774                 if ($$tagInfo{Groups}) {
    2775                     $subdirInfo{DirName} = $tagInfo->{Groups}->{1};
     3993                # set directory IFD name from group name of family 1 if it exists,
     3994                # unless the tag is extracted as a block in which case group 1 may
     3995                # have been set automatically if the block was previously extracted
     3996                if ($$tagInfo{Groups} and not $$tagInfo{BlockExtract}) {
     3997                    $subdirInfo{DirName} = $tagInfo->{Groups}{1};
    27763998                    # number multiple subdirectories
    2777                     $dirNum and $subdirInfo{DirName} .= $dirNum;
     3999                    $subdirInfo{DirName} =~ s/\d*$/$dirNum/ if $dirNum;
    27784000                }
    27794001                SetByteOrder($newByteOrder);    # set byte order for this subdir
     
    28004022            }
    28014023            my $doMaker = $exifTool->Options('MakerNotes');
    2802             next unless $doMaker or $exifTool->{REQ_TAG_LOOKUP}->{lc($tagStr)};
     4024            next unless $doMaker or $exifTool->{REQ_TAG_LOOKUP}{lc($tagStr)} or
     4025                        $$tagInfo{BlockExtract};
    28034026            # extract as a block if specified
    28044027            if ($$tagInfo{MakerNotes}) {
    28054028                # save maker note byte order (if it was significant and valid)
    28064029                if ($$subdir{ByteOrder} and not $invalid) {
    2807                     $exifTool->{MAKER_NOTE_BYTE_ORDER} = 
    2808                         defined ($exifTool->{UnknownByteOrder}) ? 
     4030                    $exifTool->{MAKER_NOTE_BYTE_ORDER} =
     4031                        defined ($exifTool->{UnknownByteOrder}) ?
    28094032                                 $exifTool->{UnknownByteOrder} : $newByteOrder;
    28104033                }
     
    28454068 #..............................................................................
    28464069        # convert to absolute offsets if this tag is an offset
    2847         if ($$tagInfo{IsOffset}) {
     4070        #### eval IsOffset ($val, $exifTool)
     4071        if ($$tagInfo{IsOffset} and eval $$tagInfo{IsOffset}) {
    28484072            my $offsetBase = $$tagInfo{IsOffset} eq '2' ? $firstBase : $base;
    28494073            $offsetBase += $$exifTool{BASE};
     4074            # handle offsets which use a wrong base (Minolta A200)
     4075            if ($$tagInfo{WrongBase}) {
     4076                my $self = $exifTool;
     4077                #### eval WrongBase ($self)
     4078                $offsetBase += eval $$tagInfo{WrongBase} || 0;
     4079            }
    28504080            my @vals = split(' ',$val);
    28514081            foreach $val (@vals) {
     
    28564086        # save the value of this tag
    28574087        $tagKey = $exifTool->FoundTag($tagInfo, $val);
    2858         # set the group 1 name for tags in main table
    2859         if (defined $tagKey and $tagTablePtr eq \%Image::ExifTool::Exif::Main) {
    2860             $exifTool->SetGroup1($tagKey, $dirName);
     4088        # set the group 1 name for tags in specified tables
     4089        if (defined $tagKey and $$tagTablePtr{SET_GROUP1}) {
     4090            $exifTool->SetGroup($tagKey, $dirName);
    28614091        }
    28624092    }
     
    28734103            $newDirInfo{DirStart} = $subdirStart;
    28744104            # increment IFD number
    2875             $newDirInfo{DirName} =~ s/(\d+)$//;
    2876             $newDirInfo{DirName} .= ($1 || 0) + 1;
     4105            my $ifdNum = $newDirInfo{DirName} =~ s/(\d+)$// ? $1 : 0;
     4106            $newDirInfo{DirName} .= $ifdNum + 1;
    28774107            # must validate SubIFD1 because the nextIFD pointer is invalid for some RAW formats
    28784108            if ($newDirInfo{DirName} ne 'SubIFD1' or ValidateIFD(\%newDirInfo)) {
    28794109                $exifTool->{INDENT} =~ s/..$//; # keep indent the same
     4110                my $cur = pop @{$$exifTool{PATH}};
    28804111                $exifTool->ProcessDirectory(\%newDirInfo, $tagTablePtr) or $success = 0;
     4112                push @{$$exifTool{PATH}}, $cur;
    28814113            } elsif ($verbose or $exifTool->{TIFF_TYPE} eq 'TIFF') {
    28824114                $exifTool->Warn('Ignored bad IFD linked from SubIFD');
     
    28934125=head1 NAME
    28944126
    2895 Image::ExifTool::Exif - Read EXIF meta information
     4127Image::ExifTool::Exif - Read EXIF/TIFF meta information
    28964128
    28974129=head1 SYNOPSIS
     
    29024134
    29034135This module contains routines required by Image::ExifTool for processing
    2904 EXIF meta information.
     4136EXIF and TIFF meta information.
    29054137
    29064138=head1 AUTHOR
    29074139
    2908 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     4140Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    29094141
    29104142This library is free software; you can redistribute it and/or modify it
     
    29174149=item L<http://www.exif.org/Exif2-2.PDF>
    29184150
     4151=item L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-008-2010_E.pdf>
     4152
    29194153=item L<http://partners.adobe.com/asn/developer/pdfs/tn/TIFF6.pdf>
    29204154
     
    29274161=item L<http://www.remotesensing.org/libtiff/TIFFTechNote2.html>
    29284162
     4163=item L<http://www.exif.org/dcf.PDF>
     4164
     4165=item L<http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html>
     4166
     4167=item L<http://www.fine-view.com/jp/lab/doc/ps6ffspecsv2.pdf>
     4168
     4169=item L<http://www.ozhiker.com/electronics/pjmt/jpeg_info/meta.html>
     4170
     4171=item L<http://hul.harvard.edu/jhove/tiff-tags.html>
     4172
     4173=item L<http://www.microsoft.com/whdc/xps/wmphoto.mspx>
     4174
    29294175=item L<http://www.asmail.be/msg0054681802.html>
    29304176
    2931 =item L<http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html>
    2932 
    2933 =item L<http://www.fine-view.com/jp/lab/doc/ps6ffspecsv2.pdf>
    2934 
    2935 =item L<http://www.ozhiker.com/electronics/pjmt/jpeg_info/meta.html>
    2936 
    2937 =item L<http://hul.harvard.edu/jhove/tiff-tags.html>
    2938 
    2939 =item L<http://www.microsoft.com/whdc/xps/wmphoto.mspx>
     4177=item L<http://crousseau.free.fr/imgfmt_raw.htm>
     4178
     4179=item L<http://www.cybercom.net/~dcoffin/dcraw/>
     4180
     4181=item L<http://www.digitalpreservation.gov/formats/content/tiff_tags.shtml>
     4182
     4183=item L<http://community.roxen.com/developers/idocs/rfc/rfc3949.html>
     4184
     4185=item L<http://tools.ietf.org/html/draft-ietf-fax-tiff-fx-extension1-01>
    29404186
    29414187=back
     
    29434189=head1 ACKNOWLEDGEMENTS
    29444190
    2945 Thanks to Matt Madrid for his help with the XP character code conversions.
     4191Thanks to Jeremy Brown for the 35efl tags, and Matt Madrid for his help with
     4192the XP character code conversions.
    29464193
    29474194=head1 SEE ALSO
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FLAC.pm

    r16842 r24107  
    1515use Image::ExifTool qw(:DataAccess :Utils);
    1616
    17 $VERSION = '1.00';
     17$VERSION = '1.03';
    1818
    1919sub ProcessBitStream($$$);
     
    3232        Name => 'VorbisComment',
    3333        SubDirectory => { TagTable => 'Image::ExifTool::Vorbis::Comments' },
     34    },
     35    6 => {
     36        Name => 'Picture',
     37        SubDirectory => { TagTable => 'Image::ExifTool::FLAC::Picture' },
    3438    },
    3539);
     
    5559);
    5660
     61%Image::ExifTool::FLAC::Picture = (
     62    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     63    GROUPS => { 2 => 'Image' },
     64    FORMAT => 'int32u',
     65    0 => {
     66        Name => 'PictureType',
     67        PrintConv => { # (Note: Duplicated in ID3, ASF and FLAC modules!)
     68            0 => 'Other',
     69            1 => '32x32 PNG Icon',
     70            2 => 'Other Icon',
     71            3 => 'Front Cover',
     72            4 => 'Back Cover',
     73            5 => 'Leaflet',
     74            6 => 'Media',
     75            7 => 'Lead Artist',
     76            8 => 'Artist',
     77            9 => 'Conductor',
     78            10 => 'Band',
     79            11 => 'Composer',
     80            12 => 'Lyricist',
     81            13 => 'Recording Studio or Location',
     82            14 => 'Recording Session',
     83            15 => 'Performance',
     84            16 => 'Capture from Movie or Video',
     85            17 => 'Bright(ly) Colored Fish',
     86            18 => 'Illustration',
     87            19 => 'Band Logo',
     88            20 => 'Publisher Logo',
     89        },
     90    },
     91    1 => {
     92        Name => 'PictureMIMEType',
     93        Format => 'var_pstr32',
     94    },
     95    2 => {
     96        Name => 'PictureDescription',
     97        Format => 'var_pstr32',
     98        ValueConv => '$self->Decode($val, "UTF8")',
     99    },
     100    3 => 'PictureWidth',
     101    4 => 'PictureHeight',
     102    5 => 'PictureBitsPerPixel',
     103    6 => 'PictureIndexedColors',
     104    7 => 'PictureLength',
     105    8 => {
     106        Name => 'Picture',
     107        Format => 'undef[$val{7}]',
     108        Binary => 1,
     109    },
     110);
     111
    57112# FLAC composite tags
    58113%Image::ExifTool::FLAC::Composite = (
     
    60115        Require => {
    61116            0 => 'FLAC:SampleRate',
    62             1 => 'FLAC:Channels',
    63             2 => 'FLAC:TotalSamples',
     117            1 => 'FLAC:TotalSamples',
    64118        },
    65         ValueConv => '$val[0] and $val[1] and $val[2] ? $val[2] / ($val[0] * $val[1]) : undef',
    66         PrintConv => 'sprintf("%.2fs",$val)',
     119        ValueConv => '$val[0] and $val[1] ? $val[1] / $val[0] : undef',
     120        PrintConv => 'ConvertDuration($val)',
    67121    },
    68122);
     
    159213
    160214    # must first check for leading/trailing ID3 information
    161     unless ($exifTool->{DONE_ID3}) {
     215    unless ($exifTool->{DoneID3}) {
    162216        require Image::ExifTool::ID3;
    163217        Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
     
    170224    # check FLAC signature
    171225    $raf->Read($buff, 4) == 4 and $buff eq 'fLaC' or return 0;
    172     $exifTool->SetFileType() unless $exifTool->{VALUE}->{FileType};
     226    $exifTool->SetFileType();
    173227    SetByteOrder('MM');
    174228    my $tagTablePtr = GetTagTable('Image::ExifTool::FLAC::Main');
     
    214268=head1 AUTHOR
    215269
    216 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     270Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    217271
    218272This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Fixup.pm

    r16842 r24107  
    322322=head1 AUTHOR
    323323
    324 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     324Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    325325
    326326This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Flash.pm

    r16842 r24107  
    66# Revisions:    05/16/2006 - P. Harvey Created
    77#               06/07/2007 - PH Added support for FLV (Flash Video) files
     8#               10/23/2008 - PH Added support for XMP in FLV and SWF
    89#
    910# References:   1) http://www.the-labs.com/MacromediaFlash/SWF-Spec/SWFfileformat.html
    1011#               2) http://sswf.sourceforge.net/SWFalexref.html
    1112#               3) http://osflash.org/flv/
     13#               4) http://www.irisa.fr/texmex/people/dufouil/ffmpegdoxy/flv_8h.html
     14#               5) http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart3.pdf (Oct 2008)
     15#               6) http://www.adobe.com/devnet/swf/pdf/swf_file_format_spec_v9.pdf
     16#               7) http://help.adobe.com/en_US/FlashMediaServer/3.5_Deving/WS5b3ccc516d4fbf351e63e3d11a0773d56e-7ff6.html
     17#               8) http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v10.pdf
    1218#
    1319# Notes:        I'll add AMF3 support if someone sends me a FLV with AMF3 data
     
    2127use Image::ExifTool::FLAC;
    2228
    23 $VERSION = '1.02';
     29$VERSION = '1.09';
    2430
    2531sub ProcessMeta($$$;$);
     32
     33# Meta packets that we process
     34my %processMetaPacket = ( onMetaData => 1, onXMPData => 1 );
    2635
    2736# information extracted from SWF header
    2837%Image::ExifTool::Flash::Main = (
    2938    GROUPS => { 2 => 'Video' },
     39    VARS => { ALPHA_FIRST => 1 },
    3040    NOTES => q{
    31         The information below is extracted from the header of SWF (Shockwave Flash)
    32         files.
     41        The information below is extracted from SWF (Shockwave Flash) files.  Tags
     42        with string ID's represent information extracted from the file header.
    3343    },
    3444    FlashVersion => { },
     
    4050    Duration => {
    4151        Notes => 'calculated from FrameRate and FrameCount',
    42         PrintConv => 'sprintf("%.2f sec",$val)',
     52        PrintConv => 'ConvertDuration($val)',
     53    },
     54    69 => {
     55        Name => 'FileAttributes',
     56        PrintConv => { BITMASK => {
     57            0 => 'UseNetwork',
     58            3 => 'ActionScript3',
     59            4 => 'HasMetadata',
     60        } },
     61    },
     62    77 => {
     63        Name => 'XMP',
     64        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
    4365    },
    4466);
     
    7496        Name => 'AudioEncoding',
    7597        PrintConv => {
    76             0 => 'Uncompressed',
     98            0 => 'PCM-BE (uncompressed)', # PCM-BE according to ref 4
    7799            1 => 'ADPCM',
    78100            2 => 'MP3',
    79             5 => 'Nellymoser 8kHz mono',
     101            3 => 'PCM-LE (uncompressed)', #4
     102            4 => 'Nellymoser 16kHz Mono', #8
     103            5 => 'Nellymoser 8kHz Mono',
    80104            6 => 'Nellymoser',
     105            7 => 'G.711 A-law logarithmic PCM', #8
     106            8 => 'G.711 mu-law logarithmic PCM', #8
     107            # (9 is reserved, ref 8)
     108            10 => 'AAC', #8
     109            11 => 'Speex', #8
     110            13 => 'MP3 8-Khz', #8
     111            15 => 'Device-specific sound', #8
    81112        },
    82113    },
     
    91122    },
    92123    'Bit6' => {
    93         Name => 'AudioSampleBits',
     124        Name => 'AudioBitsPerSample',
    94125        ValueConv => '8 * ($val + 1)',
    95126    },
     
    112143        Name => 'VideoEncoding',
    113144        PrintConv => {
     145            1 => 'JPEG', #8
    114146            2 => 'Sorensen H.263',
    115             3 => 'Screen video',
     147            3 => 'Screen Video',
    116148            4 => 'On2 VP6',
     149            5 => 'On2 VP6 Alpha', #3
     150            6 => 'Screen Video 2', #3
     151            7 => 'H.264', #7 (called "AVC" by ref 8)
    117152        },
    118153    },
     
    132167        Groups => { 2 => 'Audio' },
    133168        ValueConv => '$val * 1000',
    134         PrintConv => 'int($val + 0.5)',
     169        PrintConv => 'ConvertBitrate($val)',
    135170    },
    136171    'audiodelay'    => { Name => 'AudioDelay',      Groups => { 2 => 'Audio' } },
     
    138173    'audiosamplesize'=>{ Name => 'AudioSampleSize', Groups => { 2 => 'Audio' } },
    139174    'audiosize'     => { Name => 'AudioSize',       Groups => { 2 => 'Audio' } },
     175    'bytelength'    => 'ByteLength', # (youtube)
     176    'canseekontime' => 'CanSeekOnTime', # (youtube)
    140177    'canSeekToEnd'  => 'CanSeekToEnd',
    141178    'creationdate'  => {
     
    145182        ValueConv => '$val=~s/\s+$//; $val',    # trim trailing whitespace
    146183    },
     184    'createdby'     => 'CreatedBy', #7
    147185    'cuePoints'     => {
    148186        Name => 'CuePoint',
     
    152190    'duration' => {
    153191        Name => 'Duration',
    154         PrintConv => 'sprintf("%.3fs",$val)',
     192        PrintConv => 'ConvertDuration($val)',
    155193    },
    156194    'filesize'      => 'FileSizeBytes',
     
    165203    'hasVideo'      => 'HasVideo',
    166204    'height'        => 'ImageHeight',
     205    'httphostheader'=> 'HTTPHostHeader', # (youtube)
    167206    'keyframesTimes'=> 'KeyFramesTimes',
    168207    'keyframesFilepositions' => 'KeyFramePositions',
     
    175214        PrintConv => '$self->ConvertDateTime($val)',
    176215    },
     216    'purl'          => 'URL', # (youtube) (what does P mean?)
     217    'pmsg'          => 'Message', # (youtube) (what does P mean?)
     218    'sourcedata'    => 'SourceData', # (youtube)
     219    'starttime'     => { # (youtube)
     220        Name => 'StartTime',
     221        PrintConv => 'ConvertDuration($val)',
     222    },
    177223    'stereo'        => { Name => 'Stereo',          Groups => { 2 => 'Audio' } },
     224    'totalduration' => { # (youtube)
     225        Name => 'TotalDuration',
     226        PrintConv => 'ConvertDuration($val)',
     227    },
     228    'totaldatarate' => { # (youtube)
     229        Name => 'TotalDataRate',
     230        ValueConv => '$val * 1000',
     231        PrintConv => 'int($val + 0.5)',
     232    },
     233    'totalduration' => 'TotalDuration',
    178234    'videocodecid'  => 'VideoCodecID',
    179235    'videodatarate' => {
    180236        Name => 'VideoBitrate',
    181237        ValueConv => '$val * 1000',
    182         PrintConv => 'int($val + 0.5)',
     238        PrintConv => 'ConvertBitrate($val)',
    183239    },
    184240    'videosize'     => 'VideoSize',
    185241    'width'         => 'ImageWidth',
     242    # tags in 'onXMPData' packets
     243    'liveXML'       => { #5
     244        Name => 'XMP',
     245        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     246    },
    186247);
    187248
     
    234295    my $dirLen = $$dirInfo{DirLen} || length($$dataPt);
    235296    my $pos = $$dirInfo{Pos} || 0;
    236     my $verbose = $exifTool->Options('Verbose');
    237297    my ($type, $val, $rec);
    238298
     
    312372                # switch to subdirectory table if necessary
    313373                if ($tagInfo and $$tagInfo{SubDirectory}) {
    314                     $tag = $$tagInfo{Name}; # use our name for the tag
    315                     $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
     374                    my $subTable = $tagInfo->{SubDirectory}->{TagTable};
     375                    # descend into Flash SubDirectory
     376                    if ($subTable =~ /^Image::ExifTool::Flash::/) {
     377                        $tag = $$tagInfo{Name}; # use our name for the tag
     378                        $subTablePtr = GetTagTable($subTable);
     379                    }
    316380                }
    317381                # get object value
     
    332396                if (not $$subTablePtr{$tag} and $tag =~ /^\w+$/) {
    333397                    Image::ExifTool::AddTagToTable($subTablePtr, $tag, { Name => ucfirst($tag) });
    334                     $verbose > 1 and $exifTool->VPrint(1, "  | (adding $tag)\n");
     398                    $exifTool->VPrint(1, "  | (adding $tag)\n");
    335399                }
    336400                $exifTool->HandleTag($subTablePtr, $tag, $v,
     
    383447        last if $single;        # all done if extracting single value
    384448        unless ($isStruct{$type}) {
    385             # only process "onMetaData" Meta packets
     449            # only process certain Meta packets
    386450            if ($type == 0x02 and not $rec) {
    387                 my $verb = ($val eq 'onMetaData') ? 'processing' : 'ignoring';
     451                my $verb = $processMetaPacket{$val} ? 'processing' : 'ignoring';
    388452                $exifTool->VPrint(0, "  | ($verb $val information)\n");
    389                 last unless $val eq 'onMetaData';
     453                last unless $processMetaPacket{$val};
    390454            } else {
    391455                # give verbose indication if we ignore a lone value
     
    477541
    478542#------------------------------------------------------------------------------
     543# Read data from possibly compressed file
     544# Inputs: 0) RAF reference, 1) data buffer, 2) bytes to read, 2) compressed flag
     545# Returns: number of bytes read (may be greater than requested bytes if compressed)
     546# - concatenates data to current buffer
     547# - updates compressed flag with reference to inflate object for future calls
     548#   (or sets to error message and returns zero on error)
     549sub ReadCompressed($$$$)
     550{
     551    my ($raf, $len, $inflate) = ($_[0], $_[2], $_[3]);
     552    my $buff;
     553    unless ($raf->Read($buff, $len)) {
     554        $_[3] = 'Error reading file';
     555        return 0;
     556    }
     557    # uncompress if necessary
     558    if ($inflate) {
     559        unless (ref $inflate) {
     560            unless (eval 'require Compress::Zlib') {
     561                $_[3] = 'Install Compress::Zlib to extract compressed information';
     562                return 0;
     563            }
     564            $inflate = Compress::Zlib::inflateInit();
     565            unless ($inflate) {
     566                $_[3] = 'Error initializing inflate for Flash data';
     567                return 0;
     568            }
     569            $_[3] = $inflate;   # pass inflate object back to caller
     570        }
     571        my $tmp = $buff;
     572        $buff = '';
     573        # read 64 more bytes at a time and inflate until we get enough uncompressed data
     574        for (;;) {
     575            my ($dat, $stat) = $inflate->inflate($tmp);
     576            if ($stat == Compress::Zlib::Z_STREAM_END() or
     577                $stat == Compress::Zlib::Z_OK())
     578            {
     579                $buff .= $dat;  # add inflated data to buffer
     580                last if length $buff >= $len or $stat == Compress::Zlib::Z_STREAM_END();
     581                $raf->Read($tmp,64) or last;    # must read a bit more data
     582            } else {
     583                $buff = '';
     584                last;
     585            }
     586        }
     587        $_[3] = 'Error inflating compressed Flash data' unless length $buff;
     588    }
     589    $_[1] = defined $_[1] ? $_[1] . $buff : $buff;
     590    return length $buff;
     591}
     592
     593#------------------------------------------------------------------------------
    479594# Read information frame a Flash file
    480595# Inputs: 0) ExifTool object reference, 1) Directory information reference
     
    483598{
    484599    my ($exifTool, $dirInfo) = @_;
    485     my $verbose = $exifTool->Options('Verbose');
    486600    my $raf = $$dirInfo{RAF};
    487     my $buff;
     601    my ($buff, $hasMeta);
    488602
    489603    $raf->Read($buff, 8) == 8 or return 0;
     
    491605    my ($compressed, $vers) = ($1 eq 'C' ? 1 : 0, ord($2));
    492606
    493     # read the first bit of the file
    494     $raf->Read($buff, 64) or return 0;
    495 
     607    SetByteOrder('II');
    496608    $exifTool->SetFileType();
    497609    GetTagTable('Image::ExifTool::Flash::Main');  # make sure table is initialized
     
    500612    FoundFlashTag($exifTool, Compressed => $compressed);
    501613
    502     # uncompress if necessary
    503     if ($compressed) {
    504         unless (eval 'require Compress::Zlib') {
    505             $exifTool->Warn('Install Compress::Zlib to extract compressed information');
    506             return 1;
    507         }
    508         my $inflate = Compress::Zlib::inflateInit();
    509         my $tmp = $buff;
    510         $buff = '';
    511         # read file 64 bytes at a time and inflate until we get enough uncompressed data
    512         for (;;) {
    513             unless ($inflate) {
    514                 $exifTool->Warn('Error inflating compressed Flash data');
    515                 return 1;
    516             }
    517             my ($dat, $stat) = $inflate->inflate($tmp);
    518             if ($stat == Compress::Zlib::Z_STREAM_END() or
    519                 $stat == Compress::Zlib::Z_OK())
    520             {
    521                 $buff .= $dat;  # add inflated data to buffer
    522                 last if length $buff >= 64 or $stat == Compress::Zlib::Z_STREAM_END();
    523                 $raf->Read($tmp,64) or last;    # read some more data
    524             } else {
    525                 undef $inflate; # issue warning the next time around
    526             }
    527         }
     614    # read the next 64 bytes of the file (and inflate if necessary)
     615    $buff = '';
     616    unless (ReadCompressed($raf, $buff, 64, $compressed)) {
     617        $exifTool->Warn($compressed) if $compressed;
     618        return 1;
    528619    }
     620
    529621    # unpack elements of bit-packed Flash Rect structure
    530     my ($nBits, $totBits, $nBytes);
    531     for (;;) {
    532         if (length($buff)) {
    533             $nBits = unpack('C', $buff) >> 3;    # bits in x1,x2,y1,y2 elements
    534             $totBits = 5 + $nBits * 4;           # total bits in Rect structure
    535             $nBytes = int(($totBits + 7) / 8);   # byte length of Rect structure
    536             last if length $buff >= $nBytes + 4; # make sure header is long enough
    537         }
     622    my $nBits = unpack('C', $buff) >> 3;    # bits in x1,x2,y1,y2 elements
     623    my $totBits = 5 + $nBits * 4;           # total bits in Rect structure
     624    my $nBytes = int(($totBits + 7) / 8);   # byte length of Rect structure
     625    if (length $buff < $nBytes + 4) {
    538626        $exifTool->Warn('Truncated Flash file');
    539627        return 1;
     
    555643    FoundFlashTag($exifTool, Duration => $vals[1] * 256 / $vals[0]) if $vals[0];
    556644
     645    # scan through the tags to find FileAttributes and XMP
     646    $buff = substr($buff, $nBytes + 4);
     647    for (;;) {
     648        my $buffLen = length $buff;
     649        last if $buffLen < 2;
     650        my $code = Get16u(\$buff, 0);
     651        my $pos = 2;
     652        my $tag = $code >> 6;
     653        my $size = $code & 0x3f;
     654        $exifTool->VPrint(1, "SWF tag $tag ($size bytes):\n");
     655        last unless $tag == 69 or $tag == 77 or $hasMeta;
     656        # read enough to get a complete short record
     657        if ($pos + $size > $buffLen) {
     658            # (read 2 extra bytes if available to get next tag word)
     659            unless (ReadCompressed($raf, $buff, $size + 2, $compressed)) {
     660                $exifTool->Warn($compressed) if $compressed;
     661                return 1;
     662            }
     663            $buffLen = length $buff;
     664            last if $pos + $size > $buffLen;
     665        }
     666        # read extended record if necessary
     667        if ($size == 0x3f) {
     668            last if $pos + 4 > $buffLen;
     669            $size = Get32u(\$buff, $pos);
     670            $pos += 4;
     671            last if $size > 1000000; # don't read anything huge
     672            if ($pos + $size > $buffLen) {
     673                unless (ReadCompressed($raf, $buff, $size + 2, $compressed)) {
     674                    $exifTool->Warn($compressed) if $compressed;
     675                    return 1;
     676                }
     677                $buffLen = length $buff;
     678                last if $pos + $size > $buffLen;
     679            }
     680            $exifTool->VPrint(1, "  [extended size $size bytes]\n");
     681        }
     682        if ($tag == 69) {       # FileAttributes
     683            last unless $size;
     684            my $flags = Get8u(\$buff, $pos);
     685            FoundFlashTag($exifTool, $tag => $flags);
     686            last unless $flags & 0x10;  # only continue if we have metadata (XMP)
     687            $hasMeta = 1;
     688        } elsif ($tag == 77) {  # Metadata
     689            my $val = substr($buff, $pos, $size);
     690            FoundFlashTag($exifTool, $tag => $val);
     691            last;
     692        }
     693        last if $pos + 2 > $buffLen;
     694        $buff = substr($buff, $pos);    # remove everything before the next tag
     695    }
    557696    return 1;
    558697}
     
    583722=head1 AUTHOR
    584723
    585 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     724Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    586725
    587726This library is free software; you can redistribute it and/or modify it
     
    598737=item L<http://osflash.org/flv/>
    599738
     739=item L<http://www.irisa.fr/texmex/people/dufouil/ffmpegdoxy/flv_8h.html>
     740
     741=item L<http://help.adobe.com/en_US/FlashMediaServer/3.5_Deving/WS5b3ccc516d4fbf351e63e3d11a0773d56e-7ff6.html>
     742
     743=item L<http://www.adobe.com/devnet/swf/pdf/swf_file_format_spec_v9.pdf>
     744
     745=item L<http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v10.pdf>
     746
    600747=back
    601748
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FlashPix.pm

    r16842 r24107  
    99#               2) http://www.graphcomp.com/info/specs/livepicture/fpx.pdf
    1010#               3) http://search.cpan.org/~jdb/libwin32/
    11 #               4) http://msdn2.microsoft.com/en-us/library/aa380374.aspx
     11#               4) http://msdn.microsoft.com/en-us/library/aa380374.aspx
    1212#------------------------------------------------------------------------------
    1313
     
    2020use Image::ExifTool::ASF;   # for GetGUID()
    2121
    22 $VERSION = '1.04';
     22$VERSION = '1.19';
    2323
    2424sub ProcessFPX($$);
    2525sub ProcessFPXR($$$);
    2626sub ProcessProperties($$$);
    27 sub ReadFPXValue($$$$$;$);
    28 sub ConvertTimeSpan($);
     27sub ReadFPXValue($$$$$;$$);
    2928sub ProcessHyperlinks($$);
     29sub ProcessContents($$$);
     30sub SetDocNum($$;$$$);
    3031
    3132# sector type constants
     
    115116my @dirEntryType = qw(INVALID STORAGE STREAM LOCKBYTES PROPERTY ROOT);
    116117
     118# list of code pages used by Microsoft
     119# (ref http://msdn.microsoft.com/en-us/library/dd317756(VS.85).aspx)
     120my %codePage = (
     121    037 => 'IBM EBCDIC US-Canada',
     122    437 => 'DOS United States',
     123    500 => 'IBM EBCDIC International',
     124    708 => 'Arabic (ASMO 708)',
     125    709 => 'Arabic (ASMO-449+, BCON V4)',
     126    710 => 'Arabic - Transparent Arabic',
     127    720 => 'DOS Arabic (Transparent ASMO)',
     128    737 => 'DOS Greek (formerly 437G)',
     129    775 => 'DOS Baltic',
     130    850 => 'DOS Latin 1 (Western European)',
     131    852 => 'DOS Latin 2 (Central European)',
     132    855 => 'DOS Cyrillic (primarily Russian)',
     133    857 => 'DOS Turkish',
     134    858 => 'DOS Multilingual Latin 1 with Euro',
     135    860 => 'DOS Portuguese',
     136    861 => 'DOS Icelandic',
     137    862 => 'DOS Hebrew',
     138    863 => 'DOS French Canadian',
     139    864 => 'DOS Arabic',
     140    865 => 'DOS Nordic',
     141    866 => 'DOS Russian (Cyrillic)',
     142    869 => 'DOS Modern Greek',
     143    870 => 'IBM EBCDIC Multilingual/ROECE (Latin 2)',
     144    874 => 'Windows Thai (same as 28605, ISO 8859-15)',
     145    875 => 'IBM EBCDIC Greek Modern',
     146    932 => 'Windows Japanese (Shift-JIS)',
     147    936 => 'Windows Simplified Chinese (PRC, Singapore)',
     148    949 => 'Windows Korean (Unified Hangul Code)',
     149    950 => 'Windows Traditional Chinese (Taiwan)',
     150    1026 => 'IBM EBCDIC Turkish (Latin 5)',
     151    1047 => 'IBM EBCDIC Latin 1/Open System',
     152    1140 => 'IBM EBCDIC US-Canada with Euro',
     153    1141 => 'IBM EBCDIC Germany with Euro',
     154    1142 => 'IBM EBCDIC Denmark-Norway with Euro',
     155    1143 => 'IBM EBCDIC Finland-Sweden with Euro',
     156    1144 => 'IBM EBCDIC Italy with Euro',
     157    1145 => 'IBM EBCDIC Latin America-Spain with Euro',
     158    1146 => 'IBM EBCDIC United Kingdom with Euro',
     159    1147 => 'IBM EBCDIC France with Euro',
     160    1148 => 'IBM EBCDIC International with Euro',
     161    1149 => 'IBM EBCDIC Icelandic with Euro',
     162    1200 => 'Unicode UTF-16, little endian',
     163    1201 => 'Unicode UTF-16, big endian',
     164    1250 => 'Windows Latin 2 (Central European)',
     165    1251 => 'Windows Cyrillic',
     166    1252 => 'Windows Latin 1 (Western European)',
     167    1253 => 'Windows Greek',
     168    1254 => 'Windows Turkish',
     169    1255 => 'Windows Hebrew',
     170    1256 => 'Windows Arabic',
     171    1257 => 'Windows Baltic',
     172    1258 => 'Windows Vietnamese',
     173    1361 => 'Korean (Johab)',
     174    10000 => 'Mac Roman (Western European)',
     175    10001 => 'Mac Japanese',
     176    10002 => 'Mac Traditional Chinese',
     177    10003 => 'Mac Korean',
     178    10004 => 'Mac Arabic',
     179    10005 => 'Mac Hebrew',
     180    10006 => 'Mac Greek',
     181    10007 => 'Mac Cyrillic',
     182    10008 => 'Mac Simplified Chinese',
     183    10010 => 'Mac Romanian',
     184    10017 => 'Mac Ukrainian',
     185    10021 => 'Mac Thai',
     186    10029 => 'Mac Latin 2 (Central European)',
     187    10079 => 'Mac Icelandic',
     188    10081 => 'Mac Turkish',
     189    10082 => 'Mac Croatian',
     190    12000 => 'Unicode UTF-32, little endian',
     191    12001 => 'Unicode UTF-32, big endian',
     192    20000 => 'CNS Taiwan',
     193    20001 => 'TCA Taiwan',
     194    20002 => 'Eten Taiwan',
     195    20003 => 'IBM5550 Taiwan',
     196    20004 => 'TeleText Taiwan',
     197    20005 => 'Wang Taiwan',
     198    20105 => 'IA5 (IRV International Alphabet No. 5, 7-bit)',
     199    20106 => 'IA5 German (7-bit)',
     200    20107 => 'IA5 Swedish (7-bit)',
     201    20108 => 'IA5 Norwegian (7-bit)',
     202    20127 => 'US-ASCII (7-bit)',
     203    20261 => 'T.61',
     204    20269 => 'ISO 6937 Non-Spacing Accent',
     205    20273 => 'IBM EBCDIC Germany',
     206    20277 => 'IBM EBCDIC Denmark-Norway',
     207    20278 => 'IBM EBCDIC Finland-Sweden',
     208    20280 => 'IBM EBCDIC Italy',
     209    20284 => 'IBM EBCDIC Latin America-Spain',
     210    20285 => 'IBM EBCDIC United Kingdom',
     211    20290 => 'IBM EBCDIC Japanese Katakana Extended',
     212    20297 => 'IBM EBCDIC France',
     213    20420 => 'IBM EBCDIC Arabic',
     214    20423 => 'IBM EBCDIC Greek',
     215    20424 => 'IBM EBCDIC Hebrew',
     216    20833 => 'IBM EBCDIC Korean Extended',
     217    20838 => 'IBM EBCDIC Thai',
     218    20866 => 'Russian/Cyrillic (KOI8-R)',
     219    20871 => 'IBM EBCDIC Icelandic',
     220    20880 => 'IBM EBCDIC Cyrillic Russian',
     221    20905 => 'IBM EBCDIC Turkish',
     222    20924 => 'IBM EBCDIC Latin 1/Open System with Euro',
     223    20932 => 'Japanese (JIS 0208-1990 and 0121-1990)',
     224    20936 => 'Simplified Chinese (GB2312)',
     225    20949 => 'Korean Wansung',
     226    21025 => 'IBM EBCDIC Cyrillic Serbian-Bulgarian',
     227    21027 => 'Extended Alpha Lowercase (deprecated)',
     228    21866 => 'Ukrainian/Cyrillic (KOI8-U)',
     229    28591 => 'ISO 8859-1 Latin 1 (Western European)',
     230    28592 => 'ISO 8859-2 (Central European)',
     231    28593 => 'ISO 8859-3 Latin 3',
     232    28594 => 'ISO 8859-4 Baltic',
     233    28595 => 'ISO 8859-5 Cyrillic',
     234    28596 => 'ISO 8859-6 Arabic',
     235    28597 => 'ISO 8859-7 Greek',
     236    28598 => 'ISO 8859-8 Hebrew (Visual)',
     237    28599 => 'ISO 8859-9 Turkish',
     238    28603 => 'ISO 8859-13 Estonian',
     239    28605 => 'ISO 8859-15 Latin 9',
     240    29001 => 'Europa 3',
     241    38598 => 'ISO 8859-8 Hebrew (Logical)',
     242    50220 => 'ISO 2022 Japanese with no halfwidth Katakana (JIS)',
     243    50221 => 'ISO 2022 Japanese with halfwidth Katakana (JIS-Allow 1 byte Kana)',
     244    50222 => 'ISO 2022 Japanese JIS X 0201-1989 (JIS-Allow 1 byte Kana - SO/SI)',
     245    50225 => 'ISO 2022 Korean',
     246    50227 => 'ISO 2022 Simplified Chinese',
     247    50229 => 'ISO 2022 Traditional Chinese',
     248    50930 => 'EBCDIC Japanese (Katakana) Extended',
     249    50931 => 'EBCDIC US-Canada and Japanese',
     250    50933 => 'EBCDIC Korean Extended and Korean',
     251    50935 => 'EBCDIC Simplified Chinese Extended and Simplified Chinese',
     252    50936 => 'EBCDIC Simplified Chinese',
     253    50937 => 'EBCDIC US-Canada and Traditional Chinese',
     254    50939 => 'EBCDIC Japanese (Latin) Extended and Japanese',
     255    51932 => 'EUC Japanese',
     256    51936 => 'EUC Simplified Chinese',
     257    51949 => 'EUC Korean',
     258    51950 => 'EUC Traditional Chinese',
     259    52936 => 'HZ-GB2312 Simplified Chinese',
     260    54936 => 'Windows XP and later: GB18030 Simplified Chinese (4 byte)',
     261    57002 => 'ISCII Devanagari',
     262    57003 => 'ISCII Bengali',
     263    57004 => 'ISCII Tamil',
     264    57005 => 'ISCII Telugu',
     265    57006 => 'ISCII Assamese',
     266    57007 => 'ISCII Oriya',
     267    57008 => 'ISCII Kannada',
     268    57009 => 'ISCII Malayalam',
     269    57010 => 'ISCII Gujarati',
     270    57011 => 'ISCII Punjabi',
     271    65000 => 'Unicode (UTF-7)',
     272    65001 => 'Unicode (UTF-8)',
     273);
     274
     275# test for file extensions which may be variants of the FPX format
     276# (have seen one password-protected DOCX file that is FPX-like, so assume
     277#  that all the rest could be as well)
     278my %fpxFileType = (
     279    DOC => 1,  DOCX => 1,  DOCM => 1,
     280    DOT => 1,  DOTX => 1,  DOTM => 1,
     281    POT => 1,  POTX => 1,  POTM => 1,
     282    PPS => 1,  PPSX => 1,  PPSM => 1,
     283    PPT => 1,  PPTX => 1,  PPTM => 1,  THMX => 1,
     284    XLA => 1,  XLAM => 1,
     285    XLS => 1,  XLSX => 1,  XLSM => 1,  XLSB => 1,
     286    XLT => 1,  XLTX => 1,  XLTM => 1,
     287    # non MSOffice types
     288    FLA => 1,  VSD  => 1,
     289);
     290
    117291%Image::ExifTool::FlashPix::Main = (
    118292    PROCESS_PROC => \&ProcessFPXR,
     
    122296        Hewlett-Packard and Microsoft.  Internally the FPX file structure mimics
    123297        that of an old DOS disk with fixed-sized "sectors" (usually 512 bytes) and a
    124         "file allocation table" (FAT).  No wonder the format never became popular.
    125 
    126         However, some of the structures used in FlashPix streams are part of the
    127         EXIF specification, and are still being used in the APP2 FPXR segment of
    128         JPEG images by some Kodak and Hewlett-Packard digital cameras.
     298        "file allocation table" (FAT).  No wonder this image format never became
     299        popular.  However, some of the structures used in FlashPix streams are part
     300        of the EXIF specification, and are still being used in the APP2 FPXR segment
     301        of JPEG images by some Kodak and Hewlett-Packard digital cameras.
    129302
    130303        ExifTool extracts FlashPix information from both FPX images and the APP2
    131304        FPXR segment of JPEG images.  As well, FlashPix information is extracted
    132         from DOC, XLS and PPT (Microsoft Word, Excel and PowerPoint) documents since
    133         the FlashPix file format is closely related to the formats of these files.
     305        from DOC, PPT, XLS (Microsoft Word, PowerPoint and Excel) documents, VSD
     306        (Microsoft Visio) drawings, and FLA (Macromedia/Adobe Flash project) files
     307        since these are based on the same file format as FlashPix (the Windows
     308        Compound Binary File format).  See
     309        L<http://graphcomp.com/info/specs/livepicture/fpx.pdf> for the FlashPix
     310        specification.
    134311    },
    135312    "\x05SummaryInformation" => {
     
    165342        },
    166343    },
     344    "Contents" => {
     345        Name => 'Contents',
     346        Notes => 'found in FLA files; may contain XMP',
     347        SubDirectory => {
     348            TagTable => 'Image::ExifTool::XMP::Main',
     349            ProcessProc => \&ProcessContents,
     350        },
     351    },
    167352    "ICC Profile 0001" => {
    168353        Name => 'ICC_Profile',
     
    229414        ValueConv => 'length($val) > 0x1c and $val = substr($val, 0x1c); \$val',
    230415    },
    231     "Current User" => { #PH
     416    'Current User' => { #PH
    232417        Name => 'CurrentUser',
    233418        # not sure what the rest of this data is, but extract ASCII name from it - PH
     
    245430%Image::ExifTool::FlashPix::SummaryInfo = (
    246431    PROCESS_PROC => \&ProcessProperties,
    247     GROUPS => { 2 => 'Image' },
     432    GROUPS => { 2 => 'Document' },
    248433    NOTES => q{
    249434        The Dictionary, CodePage and LocalIndicator tags are common to all FlashPix
    250435        property tables, even though they are only listed in the SummaryInfo table.
    251436    },
    252     0x00 => { Name => 'Dictionary', Groups => { 2 => 'Other' }, Binary => 1 },
    253     0x01 => { Name => 'CodePage',   Groups => { 2 => 'Other' } },
     437    0x00 => { Name => 'Dictionary',     Groups => { 2 => 'Other' }, Binary => 1 },
     438    0x01 => {
     439        Name => 'CodePage',
     440        Groups => { 2 => 'Other' },
     441        PrintConv => \%codePage,
     442    },
    254443    0x02 => 'Title',
    255444    0x03 => 'Subject',
    256     0x04 => { Name => 'Author',     Groups => { 2 => 'Author' } },
     445    0x04 => { Name => 'Author',         Groups => { 2 => 'Author' } },
    257446    0x05 => 'Keywords',
    258447    0x06 => 'Comments',
    259448    0x07 => 'Template',
    260     0x08 => { Name => 'LastSavedBy',Groups => { 2 => 'Author' } },
     449    0x08 => { Name => 'LastModifiedBy', Groups => { 2 => 'Author' } },
    261450    0x09 => 'RevisionNumber',
    262     0x0a => { Name => 'TotalEditTime', PrintConv => \&ConvertTimeSpan },
    263     0x0b => 'LastPrinted',
    264     0x0c => { Name => 'CreateDate', Groups => { 2 => 'Time' } },
    265     0x0d => { Name => 'ModifyDate', Groups => { 2 => 'Time' } },
    266     0x0e => 'PageCount',
    267     0x0f => 'WordCount',
    268     0x10 => 'CharCount',
    269     0x11 => { Name => 'ThumbnailClip', Binary => 1 },
    270     0x12 => 'Software',
    271     0x13 => 'Security',
     451    0x0a => { Name => 'TotalEditTime',  PrintConv => 'ConvertTimeSpan($val)' }, # (in sec)
     452    0x0b => { Name => 'LastPrinted',    Groups => { 2 => 'Time' } },
     453    0x0c => {
     454        Name => 'CreateDate',
     455        Groups => { 2 => 'Time' },
     456        PrintConv => '$self->ConvertDateTime($val)',
     457    },
     458    0x0d => {
     459        Name => 'ModifyDate',
     460        Groups => { 2 => 'Time' },
     461        PrintConv => '$self->ConvertDateTime($val)',
     462    },
     463    0x0e => 'Pages',
     464    0x0f => 'Words',
     465    0x10 => 'Characters',
     466    0x11 => { Name => 'ThumbnailClip',  Binary => 1 },
     467    0x12 => {
     468        Name => 'Software',
     469        RawConv => '$$self{Software} = $val', # (use to determine file type)
     470    },
     471    0x13 => {
     472        Name => 'Security',
     473        # see http://msdn.microsoft.com/en-us/library/aa379255(VS.85).aspx
     474        PrintConv => {
     475            0 => 'None',
     476            1 => 'Password protected',
     477            2 => 'Read-only recommended',
     478            4 => 'Read-only enforced',
     479            8 => 'Locked for annotations',
     480        },
     481    },
    272482    0x80000000 => { Name => 'LocaleIndicator', Groups => { 2 => 'Other' } },
    273483);
     
    279489    NOTES => q{
    280490        The DocumentSummaryInformation property set includes a UserDefined property
    281         set for which only the Hyperlinks and HyperlinkBase tags are pre-defined. 
     491        set for which only the Hyperlinks and HyperlinkBase tags are pre-defined.
    282492        However, ExifTool will also extract any other information found in the
    283493        UserDefined properties.
     
    292502    0x09 => 'HiddenSlides',
    293503    0x0a => 'MMClips',
    294     0x0b => 'ScaleCrop',
     504    0x0b => {
     505        Name => 'ScaleCrop',
     506        PrintConv => { 0 => 'No', 1 => 'Yes' },
     507    },
    295508    0x0c => 'HeadingPairs',
    296509    0x0d => 'TitleOfParts',
    297510    0x0e => 'Manager',
    298511    0x0f => 'Company',
    299     0x10 => 'LinksUpToDate',
     512    0x10 => {
     513        Name => 'LinksUpToDate',
     514        PrintConv => { 0 => 'No', 1 => 'Yes' },
     515    },
    300516    0x11 => 'CharCountWithSpaces',
    301517  # 0x12 ?
    302     0x13 => 'SharedDoc', #PH (unconfirmed)
     518    0x13 => { #PH (unconfirmed)
     519        Name => 'SharedDoc',
     520        PrintConv => { 0 => 'No', 1 => 'Yes' },
     521    },
    303522  # 0x14 ?
    304523  # 0x15 ?
    305     0x16 => 'HyperlinksChanged',
    306     0x17 => { #PH (unconfirmed)
     524    0x16 => {
     525        Name => 'HyperlinksChanged',
     526        PrintConv => { 0 => 'No', 1 => 'Yes' },
     527    },
     528    0x17 => { #PH (unconfirmed handling of lower 16 bits)
    307529        Name => 'AppVersion',
    308         # (not sure what the lower 16 bits mean, so print them in hex inside brackets)
    309         ValueConv => 'sprintf("%d (%.4x)",$val >> 16, $val & 0xffff)',
    310     },
    311    '_PID_LINKBASE' => 'HyperlinkBase',
     530        ValueConv => 'sprintf("%d.%.4d",$val >> 16, $val & 0xffff)',
     531    },
     532   '_PID_LINKBASE' => {
     533        Name => 'HyperlinkBase',
     534        ValueConv => '$self->Decode($val, "UCS2","II")',
     535    },
    312536   '_PID_HLINKS' => {
    313537        Name => 'Hyperlinks',
     
    364588    0x23000004 => 'People',
    365589    0x23000007 => 'Things',
    366     0x2300000A => { Name => 'DateTimeOriginal', Groups => { 2 => 'Time' } },
     590    0x2300000A => {
     591        Name => 'DateTimeOriginal',
     592        Description => 'Date/Time Original',
     593        Groups => { 2 => 'Time' },
     594        PrintConv => '$self->ConvertDateTime($val)',
     595    },
    367596    0x2300000B => 'Events',
    368597    0x2300000C => 'Places',
     
    375604    },
    376605    0x24000002 => { Name => 'SerialNumber',     Groups => { 2 => 'Camera' } },
    377     0x25000000 => { Name => 'CreateDate',       Groups => { 2 => 'Time' } },
     606    0x25000000 => {
     607        Name => 'CreateDate',
     608        Groups => { 2 => 'Time' },
     609        PrintConv => '$self->ConvertDateTime($val)',
     610    },
    378611    0x25000001 => {
    379612        Name => 'ExposureTime',
     
    410643        Name => 'FocalLength',
    411644        Groups => { 2 => 'Camera' },
    412         PrintConv => 'sprintf("%.1fmm",$val)',
     645        PrintConv => 'sprintf("%.1f mm",$val)',
    413646    },
    414647    0x2500000A => {
     
    520753    0x28000005 => 'ServiceOrganizationName',
    521754    0x28000006 => 'ScanOperatorID',
    522     0x28000008 => { Name => 'ScanDate',   Groups => { 2 => 'Time' } },
    523     0x28000009 => { Name => 'ModifyDate', Groups => { 2 => 'Time' } },
     755    0x28000008 => {
     756        Name => 'ScanDate',
     757        Groups => { 2 => 'Time' },
     758        PrintConv => '$self->ConvertDateTime($val)',
     759    },
     760    0x28000009 => {
     761        Name => 'ModifyDate',
     762        Groups => { 2 => 'Time' },
     763        PrintConv => '$self->ConvertDateTime($val)',
     764    },
    524765    0x2800000A => 'ScannerPixelSize',
    525766);
     
    725966);
    726967
     968# MacroMedia flash contents
     969%Image::ExifTool::FlashPix::Contents = (
     970    PROCESS_PROC => \&ProcessProperties,
     971    GROUPS => { 2 => 'Image' },
     972);
     973
    727974# CompObj tags
    728975%Image::ExifTool::FlashPix::CompObj = (
     
    731978    FORMAT => 'int32u',
    732979    0 => { Name => 'CompObjUserTypeLen' },
    733     1 => { Name => 'CompObjUserType', Format => 'string[$val{0}]' },
     980    1 => {
     981        Name => 'CompObjUserType',
     982        Format => 'string[$val{0}]',
     983        RawConv => '$$self{CompObjUserType} = $val', # (use to determine file type)
     984    },
    734985);
    735986
     
    7841035
    7851036#------------------------------------------------------------------------------
    786 # Print conversion for time span value
    787 sub ConvertTimeSpan($)
    788 {
    789     my $val = shift;
    790     if (Image::ExifTool::IsFloat($val) and $val != 0) {
    791         if ($val < 60) {
    792             $val = "$val seconds";
    793         } elsif ($val < 3600) {
    794             $val = sprintf("%.1f minutes", $val / 60);
    795         } elsif ($val < 24 * 3600) {
    796             $val = sprintf("%.1f hours", $val / 3600);
    797         } else {
    798             $val = sprintf("%.1f days", $val / (24 * 3600));
    799         }
    800     }
    801     return $val;
    802 }
    803 
    804 #------------------------------------------------------------------------------
    8051037# Read FlashPix value
    8061038# Inputs: 0) ExifTool ref, 1) data ref, 2) value offset, 3) FPX format number,
    807 #         4) end offset, 5) options: 0x01=no padding, 0x02=translate to UTF8
     1039#         4) end offset, 5) flag for no padding, 6) code page
    8081040# Returns: converted value (or list of values in list context) and updates
    8091041#          value offset to end of value if successful, or returns undef on error
    810 sub ReadFPXValue($$$$$;$)
     1042sub ReadFPXValue($$$$$;$$)
    8111043{
    812     my ($exifTool, $dataPt, $valPos, $type, $dirEnd, $opts) = @_;
    813     $opts = 0 unless defined $opts;
     1044    my ($exifTool, $dataPt, $valPos, $type, $dirEnd, $noPad, $codePage) = @_;
    8141045    my @vals;
    8151046
     
    8211052        if ($flags) {
    8221053            if ($flags == VT_VECTOR) {
    823                 $opts |= 0x01;  # values don't seem to be padded inside vectors
     1054                $noPad = 1;     # values don't seem to be padded inside vectors
    8241055                my $size = $oleFormatSize{VT_VECTOR};
    8251056                last if $valPos + $size > $dirEnd;
     
    8471078                my $subType = Get32u($dataPt, $valPos);
    8481079                $valPos += $size;
    849                 $val = ReadFPXValue($exifTool, $dataPt, $valPos, $subType, $dirEnd, $opts);
     1080                $val = ReadFPXValue($exifTool, $dataPt, $valPos, $subType, $dirEnd, $noPad, $codePage);
    8501081                last unless defined $val;
    8511082                push @vals, $val;
     
    8721103                if ($format eq 'VT_LPWSTR') {
    8731104                    # convert wide string from Unicode
    874                     $val = $exifTool->Unicode2Charset($val);
    875                 } elsif ($opts & 0x02) {
    876                     # convert from Latin1 to UTF-8
    877                     $val = Image::ExifTool::Latin2Unicode($val,'v');
    878                     $val = Image::ExifTool::Unicode2UTF8($val,'v');
     1105                    $val = $exifTool->Decode($val, 'UCS2');
     1106                } elsif ($codePage) {
     1107                    my $charset = $Image::ExifTool::charsetName{"cp$codePage"};
     1108                    if ($charset) {
     1109                        $val = $exifTool->Decode($val, $charset);
     1110                    } elsif ($codePage eq 1200) {   # UTF-16, little endian
     1111                        $val = $exifTool->Decode(undef, 'UCS2', 'II');
     1112                    }
    8791113                }
    8801114                $val =~ s/\0.*//s;  # truncate at null terminator
     
    8821116                # (the spec states that strings should be padded to align
    8831117                #  on even 32-bit boundaries, but this isn't always the case)
    884                 $valPos += ($opts & 0x01) ? $len : ($len + 3) & 0xfffffffc;
     1118                $valPos += $noPad ? $len : ($len + 3) & 0xfffffffc;
    8851119            } elsif ($format eq 'VT_BLOB' or $format eq 'VT_CF') {
    8861120                my $len = Get32u($dataPt, $valPos);
     
    8971131        }
    8981132        # join VT_ values with commas unless we want an array
    899         @vals = ( join ', ', @vals ) if @vals > 1 and not wantarray;
     1133        @vals = ( join $exifTool->Options('ListSep'), @vals ) if @vals > 1 and not wantarray;
    9001134        last;   # didn't really want to loop
    9011135    }
     
    9091143        return $vals[0];
    9101144    }
     1145}
     1146
     1147#------------------------------------------------------------------------------
     1148# Scan for XMP in FLA Contents (ref PH)
     1149# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     1150# Returns: 1 on success
     1151# Notes: FLA format is proprietary and I couldn't find any documentation,
     1152#        so this routine is entirely based on observations from sample files
     1153sub ProcessContents($$$)
     1154{
     1155    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     1156    my $dataPt = $$dirInfo{DataPt};
     1157    my $isFLA;
     1158
     1159    # all of my FLA samples contain "Contents" data, an no other FPX-like samples have
     1160    # this, but check the data for a familiar pattern to be sure this is FLA: the
     1161    # Contents of all of my FLA samples start with two bytes (0x29,0x38,0x3f,0x43 or 0x47,
     1162    # then 0x01) followed by a number of zero bytes (from 0x18 to 0x26 of them, related
     1163    # somehow to the value of the first byte), followed by the string "DocumentPage"
     1164    $isFLA = 1 if $$dataPt =~ /^..\0+\xff\xff\x01\0\x0d\0CDocumentPage/;
     1165   
     1166    # do a brute-force scan of the "Contents" for UTF-16 XMP
     1167    # (this may always be little-endian, but allow for either endianness)
     1168    if ($$dataPt =~ /<\0\?\0x\0p\0a\0c\0k\0e\0t\0 \0b\0e\0g\0i\0n\0=\0['"](\0\xff\xfe|\xfe\xff)/g) {
     1169        $$dirInfo{DirStart} = pos($$dataPt) - 36;
     1170        if ($$dataPt =~ /<\0\?\0x\0p\0a\0c\0k\0e\0t\0 \0e\0n\0d\0=\0['"]\0[wr]\0['"]\0\?\0>\0?/g) {
     1171            $$dirInfo{DirLen} = pos($$dataPt) - $$dirInfo{DirStart};
     1172            Image::ExifTool::XMP::ProcessXMP($exifTool, $dirInfo, $tagTablePtr);
     1173            # override format if not already FLA but XMP-dc:Format indicates it is
     1174            $isFLA = 1 if $$exifTool{FILE_TYPE} ne 'FLA' and $$exifTool{VALUE}{Format} and
     1175                          $$exifTool{VALUE}{Format} eq 'application/vnd.adobe.fla';
     1176        }
     1177    }
     1178    $exifTool->OverrideFileType('FLA') if $isFLA;
     1179    return 1;
    9111180}
    9121181
     
    9371206    my $dirEnd = $pos + $dirLen;
    9381207    my $verbose = $exifTool->Options('Verbose');
    939     my ($out, $n);
     1208    my $n;
    9401209
    9411210    if ($dirLen < 48) {
     
    9561225    for ($n=0; $n<2; ++$n) {
    9571226        my %dictionary;     # dictionary to translate user-defined properties
    958         my $opts = 0;       # option flags for converting values
     1227        my $codePage;
    9591228        last if $pos + 8 > $dirEnd;
    9601229        # read property section header
     
    9911260                    next if $$tagTablePtr{$name};
    9921261                    $tag = $name;
    993                     $name =~ tr/a-zA-Z0-9//dc;
     1262                    $name =~ s/(^| )([a-z])/\U$2/g; # start with uppercase
     1263                    $name =~ tr/-_a-zA-Z0-9//dc;    # remove illegal characters
    9941264                    next unless length $name;
    995                     Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => ucfirst($name) });
     1265                    $exifTool->VPrint(0, "$$exifTool{INDENT}\[adding $name]\n") if $verbose;
     1266                    Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name });
    9961267                }
    9971268                next;
     
    10031274                $custom = 1;
    10041275            }
    1005             my @vals = ReadFPXValue($exifTool, $dataPt, $valPos, $type, $dirEnd, $opts);
     1276            my @vals = ReadFPXValue($exifTool, $dataPt, $valPos, $type, $dirEnd, undef, $codePage);
    10061277            @vals or $exifTool->Warn('Error reading property value');
    10071278            $val = @vals > 1 ? \@vals : $vals[0];
     
    10171288                my $summaryTable = GetTagTable('Image::ExifTool::FlashPix::SummaryInfo');
    10181289                $tagInfo = $exifTool->GetTagInfo($summaryTable, $tag);
    1019                 if ($tag == 1 and $val == 1252 and $exifTool->Options('Charset') eq 'UTF8') {
    1020                     # set flag to translate 8-bit text only if
    1021                     # code page is cp1252 and Charset is UTF8
    1022                     $opts |= 0x02;
     1290                if ($tag == 1) {
     1291                    $val += 0x10000 if $val < 0; # (may be incorrectly stored as int16s)
     1292                    $codePage = $val;            # save code page for translating values
    10231293                }
    10241294            } elsif ($$tagTablePtr{$tag}) {
     
    10361306            }
    10371307            $exifTool->HandleTag($tagTablePtr, $tag, $val,
    1038                 DataPt => $dataPt,
    1039                 Start => $valStart,
    1040                 Size => $valPos - $valStart,
    1041                 Format => $formStr,
    1042                 Index => $index,
     1308                DataPt  => $dataPt,
     1309                Start   => $valStart,
     1310                Size    => $valPos - $valStart,
     1311                Format  => $formStr,
     1312                Index   => $index,
    10431313                TagInfo => $tagInfo,
    1044                 Extra => ", type=$type",
     1314                Extra   => ", type=$type",
    10451315            );
    10461316        }
     
    10641334    my ($buff, %loadedSect);
    10651335    for (;;) {
    1066         last if $sect == END_OF_CHAIN;
     1336        last if $sect >= END_OF_CHAIN;
    10671337        return undef if $loadedSect{$sect}; # avoid infinite loop
    10681338        $loadedSect{$sect} = 1;
    10691339        my $offset = $sect * $sectSize + $hdrSize;
    1070         return undef unless $offset <= 0x7fffffff and
     1340        return undef unless ($offset <= 0x7fffffff or $$raf{LargeFileSupport}) and
    10711341                            $raf->Seek($offset, 0) and
    10721342                            $raf->Read($buff, $sectSize) == $sectSize;
     
    11261396            }
    11271397            # convert stream pathname to ascii
    1128             my $name = Image::ExifTool::Unicode2Latin($1, 'v');
     1398            my $name = Image::ExifTool::Decode(undef, $1, 'UCS2', 'II', 'Latin');
    11291399            if ($verbose) {
    11301400                my $psize = ($size == 0xffffffff) ? 'storage' : "$size bytes";
     
    11821452                        }
    11831453                    }
    1184                     # concatinate data with this stream
     1454                    # concatenate data with this stream
    11851455                    $$obj{Stream} .= substr($$dataPt, $dirStart+13);
    11861456                } else {
     
    12141484                delete $$obj{Stream}; # done with this stream
    12151485            }
     1486        # hack for improperly stored FujiFilm PreviewImage (stored with no contents list)
     1487        } elsif ($index == 512 and $dirLen > 60 and ($$exifTool{FujiPreview} or
     1488            ($dirLen > 64 and substr($$dataPt, $dirStart+60, 4) eq "\xff\xd8\xff\xdb")))
     1489        {
     1490            # recombine PreviewImage, skipping unknown 60 byte header
     1491            if ($$exifTool{FujiPreview}) {
     1492                $$exifTool{FujiPreview} .= substr($$dataPt, $dirStart+60);
     1493            } else {
     1494                $$exifTool{FujiPreview} = substr($$dataPt, $dirStart+60);
     1495            }
    12161496        } else {
    1217             $exifTool->Warn("Unlisted FPXR segment (index $index)");
     1497            # (Kodak uses index 255 for a free segment in images from some cameras)
     1498            $exifTool->Warn("Unlisted FPXR segment (index $index)") if $index != 255;
    12181499        }
    12191500
     
    12251506
    12261507    # clean up if this was the last FPXR segment
    1227     if ($$dirInfo{LastFPXR} and $$exifTool{FPXR}) {
    1228         my $obj;
    1229         my $i = 0;
    1230         foreach $obj (@{$$exifTool{FPXR}}) {
    1231             $exifTool->Warn("Missing stream for FPXR object $i") if defined $$obj{Stream};
    1232             ++$i;
    1233         }
    1234         delete $$exifTool{FPXR};    # delete our temporary variables
     1508    if ($$dirInfo{LastFPXR}) {
     1509        if ($$exifTool{FPXR}) {
     1510            my $obj;
     1511            my $i = 0;
     1512            foreach $obj (@{$$exifTool{FPXR}}) {
     1513                $exifTool->Warn("Missing stream for FPXR object $i") if defined $$obj{Stream};
     1514                ++$i;
     1515            }
     1516            delete $$exifTool{FPXR};    # delete our temporary variables
     1517        }
     1518        if ($$exifTool{FujiPreview}) {
     1519            $exifTool->FoundTag('PreviewImage', $$exifTool{FujiPreview});
     1520            delete $$exifTool{FujiPreview};
     1521        }
    12351522    }
    12361523    return 1;
     1524}
     1525
     1526#------------------------------------------------------------------------------
     1527# Set document number for objects
     1528# Inputs: 0) object hierarchy hash ref, 1) object index, 2) doc number list ref,
     1529#         3) doc numbers used at each level, 4) flag set for metadata levels
     1530sub SetDocNum($$;$$$)
     1531{
     1532    my ($hier, $index, $doc, $used, $meta) = @_;
     1533    my $obj = $$hier{$index} or return;
     1534    return if exists $$obj{DocNum};
     1535    $$obj{DocNum} = $doc;
     1536    SetDocNum($hier, $$obj{Left}, $doc, $used, $meta) if $$obj{Left};
     1537    SetDocNum($hier, $$obj{Right}, $doc, $used, $meta) if $$obj{Right};
     1538    if (defined $$obj{Child}) {
     1539        $used or $used = [ ];
     1540        my @subDoc;
     1541        push @subDoc, @$doc if $doc;
     1542        # we must dive down 2 levels for each sub-document, so use the
     1543        # $meta flag to add a sub-document level only for every 2nd generation
     1544        if ($meta) {
     1545            my $subNum = ($$used[scalar @subDoc] || 0);
     1546            $$used[scalar @subDoc] = $subNum;
     1547            push @subDoc, $subNum;
     1548        } elsif (@subDoc) {
     1549            $subDoc[-1] = ++$$used[$#subDoc];
     1550        }
     1551        SetDocNum($hier, $$obj{Child}, \@subDoc, $used, not $meta)
     1552    }
    12371553}
    12381554
     
    12401556# Extract information from a FlashPix (FPX) file
    12411557# Inputs: 0) ExifTool object ref, 1) dirInfo ref
    1242 # Returns: 1 on success, 0 if this wasn't a valid FPX image
     1558# Returns: 1 on success, 0 if this wasn't a valid FPX-format file
    12431559sub ProcessFPX($$)
    12441560{
     
    12461562    my $raf = $$dirInfo{RAF};
    12471563    my ($buff, $out, %dumpParms, $oldIndent, $miniStreamBuff);
     1564    my ($tag, %hier, %objIndex);
    12481565
    12491566    # read header
     
    12521569    return 0 unless $buff =~ /^\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1/;
    12531570
     1571    # set FileType initially based on file extension (we may override this later)
    12541572    my $fileType = $exifTool->{FILE_EXT};
    1255     $fileType = 'FPX' unless $fileType and $fileType =~ /^(DOC|XLS|PPT)$/;
     1573    $fileType = 'FPX' unless $fileType and $fpxFileType{$fileType};
    12561574    $exifTool->SetFileType($fileType);
    12571575    SetByteOrder(substr($buff, 0x1c, 2) eq "\xff\xfe" ? 'MM' : 'II');
    12581576    my $tagTablePtr = GetTagTable('Image::ExifTool::FlashPix::Main');
    12591577    my $verbose = $exifTool->Options('Verbose');
     1578    # copy LargeFileSupport option to RAF for use in LoadChain
     1579    $$raf{LargeFileSupport} = $exifTool->Options('LargeFileSupport');
    12601580
    12611581    my $sectSize = 1 << Get16u(\$buff, 0x1e);
     
    12711591    if ($verbose) {
    12721592        $out = $exifTool->Options('TextOut');
     1593        $dumpParms{Out} = $out;
    12731594        $dumpParms{MaxLen} = 96 if $verbose == 3;
    12741595        print $out "  Sector size=$sectSize\n  FAT: Count=$fatCount\n";
     
    13001621            ++$fatCountCheck;
    13011622        }
    1302         last if $difStart == END_OF_CHAIN;
     1623        last if $difStart >= END_OF_CHAIN;
    13031624        # read next DIF (Dual Indirect FAT) sector
    13041625        my $offset = $difStart * $sectSize + HDR_SIZE;
     
    13081629        }
    13091630        # set end of sector information in this DIF
     1631        $pos = 0;
    13101632        $endPos = $sectSize - 4;
    13111633        # next time around we want to read next DIF in chain
     
    13441666    my $index = 0;
    13451667
    1346     for ($pos=0; $pos<=$endPos-128; $pos+=128) {
     1668    for ($pos=0; $pos<=$endPos-128; $pos+=128, ++$index) {
    13471669
    13481670        # get directory entry type
     
    13591681        my $len = Get16u(\$dir, $pos + 0x40);
    13601682        $len > 32 and $len = 32;
    1361         my $tag = Image::ExifTool::Unicode2Latin(substr($dir, $pos, $len * 2), 'v');
     1683        $tag = Image::ExifTool::Decode(undef, substr($dir,$pos,$len*2), 'UCS2', 'II', 'Latin');
    13621684        $tag =~ s/\0.*//s;  # truncate at null (in case length was wrong)
    13631685
     
    13831705                ($tag =~ /(.*) \d{6}$/s and $$tagTablePtr{$1}) or
    13841706                ($tag =~ /(.*)_[0-9a-f]{16}$/s and $$tagTablePtr{$1});
     1707        }
     1708
     1709        my $lSib = Get32u(\$dir, $pos + 0x44);  # left sibling
     1710        my $rSib = Get32u(\$dir, $pos + 0x48);  # right sibling
     1711        my $chld = Get32u(\$dir, $pos + 0x4c);  # child directory
     1712
     1713        # save information about object hierachy
     1714        my ($obj, $sub);
     1715        $obj = $hier{$index} or $obj = $hier{$index} = { };
     1716        $$obj{Left} = $lSib unless $lSib == FREE_SECT;
     1717        $$obj{Right} = $rSib unless $rSib == FREE_SECT;
     1718        unless ($chld == FREE_SECT) {
     1719            $$obj{Child} = $chld;
     1720            $sub = $hier{$chld} or $sub = $hier{$chld} = { };
     1721            $$sub{Parent} = $index;
    13851722        }
    13861723
     
    14141751        if ($verbose) {
    14151752            my $flags = Get8u(\$dir, $pos + 0x43);  # 0=red, 1=black
    1416             my $lSib = Get32u(\$dir, $pos + 0x44);  # left sibling
    1417             my $rSib = Get32u(\$dir, $pos + 0x48);  # right sibling
    1418             my $chld = Get32u(\$dir, $pos + 0x4c);  # child directory
    14191753            my $col = { 0 => 'Red', 1 => 'Black' }->{$flags} || $flags;
    14201754            $extra .= " Type=$typeStr Flags=$col";
     
    14231757            $extra .= " Child=$chld" unless $chld == FREE_SECT;
    14241758            $exifTool->VerboseInfo($tag, $tagInfo,
    1425                 Index => $index++,
    1426                 Value => $buff,
     1759                Index  => $index,
     1760                Value  => $buff,
    14271761                DataPt => \$buff,
    1428                 Extra => $extra,
    1429                 Size => $size,
     1762                Extra  => $extra,
     1763                Size   => $size,
    14301764            );
    14311765        }
    14321766        if ($tagInfo and $buff) {
    1433             if ($$tagInfo{SubDirectory}) {
     1767            my $num = $$exifTool{NUM_FOUND};
     1768            my $subdir = $$tagInfo{SubDirectory};
     1769            if ($subdir) {
    14341770                my %dirInfo = (
    1435                     DataPt => \$buff,
    1436                     DirStart => $tagInfo->{SubDirectory}->{DirStart},
    1437                     DirLen => length $buff,
    1438                     Multi => $$tagInfo{Multi},
     1771                    DataPt   => \$buff,
     1772                    DirStart => $$subdir{DirStart},
     1773                    DirLen   => length $buff,
     1774                    Multi    => $$tagInfo{Multi},
    14391775                );
    1440                 my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
    1441                 $exifTool->ProcessDirectory(\%dirInfo, $subTablePtr);
     1776                my $subTablePtr = GetTagTable($$subdir{TagTable});
     1777                $exifTool->ProcessDirectory(\%dirInfo, $subTablePtr,  $$subdir{ProcessProc});
    14421778            } else {
    14431779                $exifTool->FoundTag($tagInfo, $buff);
    14441780            }
     1781            # save object index number for all found tags
     1782            my $num2 = $$exifTool{NUM_FOUND};
     1783            $objIndex{++$num} = $index while $num < $num2;
     1784        }
     1785    }
     1786    # set document numbers for tags extracted from embedded documents
     1787    unless ($$exifTool{DOC_NUM}) {
     1788        # initialize document number for all objects, beginning at root (index 0)
     1789        SetDocNum(\%hier, 0);
     1790        # set family 3 group name for all tags in embedded documents
     1791        my $order = $$exifTool{FILE_ORDER};
     1792        my (@pri, $copy, $member);
     1793        foreach $tag (keys %$order) {
     1794            my $num = $$order{$tag};
     1795            next unless defined $num and $objIndex{$num};
     1796            my $obj = $hier{$objIndex{$num}} or next;
     1797            my $docNums = $$obj{DocNum};
     1798            next unless $docNums and @$docNums;
     1799            $$exifTool{TAG_EXTRA}{$tag}{G3} = join '-', @$docNums;
     1800            push @pri, $tag unless $tag =~ / /; # save keys for priority sub-doc tags
     1801        }
     1802        # swap priority sub-document tags with main document tags if they exist
     1803        foreach $tag (@pri) {
     1804            for ($copy=1; ;++$copy) {
     1805                my $key = "$tag ($copy)";
     1806                last unless defined $$exifTool{VALUE}{$key};
     1807                my $extra = $$exifTool{TAG_EXTRA}{$key};
     1808                next if $extra and $$extra{G3}; # not Main if family 3 group is set
     1809                foreach $member ('PRIORITY','VALUE','FILE_ORDER','TAG_INFO','TAG_EXTRA') {
     1810                    my $pHash = $$exifTool{$member};
     1811                    my $t = $$pHash{$tag};
     1812                    $$pHash{$tag} = $$pHash{$key};
     1813                    $$pHash{$key} = $t;
     1814                }
     1815                last;
     1816            }
    14451817        }
    14461818    }
    14471819    $exifTool->{INDENT} = $oldIndent if $verbose;
     1820    # try to better identify the file type
     1821    if ($$exifTool{VALUE}{FileType} eq 'FPX') {
     1822        my $val = $$exifTool{CompObjUserType} || $$exifTool{Software};
     1823        if ($val) {
     1824            my %type = ( Word => 'DOC', PowerPoint => 'PPT', Excel => 'XLS' );
     1825            my $pat;
     1826            foreach $pat (sort keys %type) {
     1827                next unless $val =~ /$pat/;
     1828                $exifTool->OverrideFileType($type{$pat});
     1829                last;
     1830            }
     1831        }
     1832    }
    14481833    return 1;
    14491834}
     
    14691854=head1 AUTHOR
    14701855
    1471 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1856Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    14721857
    14731858This library is free software; you can redistribute it and/or modify it
     
    14841869=item L<http://search.cpan.org/~jdb/libwin32/>
    14851870
     1871=item L<http://msdn.microsoft.com/en-us/library/aa380374.aspx>
     1872
    14861873=back
    14871874
     
    14891876
    14901877L<Image::ExifTool::TagNames/FlashPix Tags>,
     1878L<Image::ExifTool::TagNames/OOXML Tags>,
    14911879L<Image::ExifTool(3pm)|Image::ExifTool>
    14921880
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FotoStation.pm

    r16842 r24107  
    4040        Name => 'ThumbnailImage',
    4141        Writable => 1,
    42         ValueConv => '$self->ValidateImage(\$val,$tag)',
    43         ValueConvInv => '$val',
     42        RawConv => '$self->ValidateImage(\$val,$tag)',
    4443    },
    4544    0x04 => {
    4645        Name => 'PreviewImage',
    4746        Writable => 1,
    48         ValueConv => '$self->ValidateImage(\$val,$tag)',
    49         ValueConvInv => '$val',
     47        RawConv => '$self->ValidateImage(\$val,$tag)',
    5048    },
    5149);
     
    193191                $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
    194192            } else {
    195                 my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
    196                 if (Image::ExifTool::IsOverwriting($newValueHash) > 0) {
    197                     $newVal = Image::ExifTool::GetNewValues($newValueHash);
     193                my $nvHash = $exifTool->GetNewValueHash($tagInfo);
     194                if (Image::ExifTool::IsOverwriting($nvHash) > 0) {
     195                    $newVal = Image::ExifTool::GetNewValues($nvHash);
    198196                    $newVal = '' unless defined $newVal;
    199197                    if ($verbose > 1) {
     
    243241=head1 AUTHOR
    244242
    245 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     243Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    246244
    247245This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FujiFilm.pm

    r16842 r24107  
    22# File:         FujiFilm.pm
    33#
    4 # Description:  FujiFilm EXIF maker notes tags
     4# Description:  Read/write FujiFilm maker notes and RAF images
    55#
    6 # Revisions:    11/25/2003  - P. Harvey Created
     6# Revisions:    11/25/2003 - P. Harvey Created
     7#               11/14/2007 - PH Added abilty to write RAF images
    78#
    89# References:   1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
    9 #               2) http://homepage3.nifty.com/kamisaka/makernote/makernote_fuji.htm
     10#               2) http://homepage3.nifty.com/kamisaka/makernote/makernote_fuji.htm (2007/09/11)
    1011#               3) Michael Meissner private communication
    1112#               4) Paul Samuelson private communication (S5)
    1213#               5) http://www.cybercom.net/~dcoffin/dcraw/
     14#               6) http://forums.dpreview.com/forums/readflat.asp?forum=1012&thread=31350384
     15#                  and http://forum.photome.de/viewtopic.php?f=2&t=353&p=742#p740
     16#               JD) Jens Duttke private communication
    1317#------------------------------------------------------------------------------
    1418
     
    2024use Image::ExifTool::Exif;
    2125
    22 $VERSION = '1.14';
    23 
     26$VERSION = '1.31';
     27
     28sub ProcessFujiDir($$$);
     29sub ProcessFaceRec($$$);
     30
     31# the following RAF version numbers have been tested for writing:
     32my %testedRAF = (
     33    '0100' => 'E550, E900, S5600, S6000fd, S6500fd, HS10/HS11, S200EXR, X100 (all Ver1.00)',
     34    '0102' => 'S100FS Ver1.02',
     35    '0104' => 'S5Pro Ver1.04',
     36    '0106' => 'S5Pro Ver1.06',
     37    '0111' => 'S5Pro Ver1.11',
     38    '0114' => 'S9600 Ver1.00',
     39    '0159' => 'S2Pro Ver1.00',
     40    '0212' => 'S3Pro Ver2.12',
     41    '0216' => 'S3Pro Ver2.16', # (NC)
     42    '0218' => 'S3Pro Ver2.18',
     43    '0264' => 'F700  Ver2.00',
     44    '0266' => 'S9500 Ver1.01',
     45    '0269' => 'S9500 Ver1.02',
     46    '0271' => 'S3Pro Ver2.71', # UV/IR model?
     47    '0712' => 'S5000 Ver3.00',
     48    '0716' => 'S5000 Ver3.00', # (yes, 2 RAF versions with the same firmware version)
     49);
     50
     51my %faceCategories = (
     52    Format => 'int8u',
     53    PrintConv => { BITMASK => {
     54        1 => 'Partner',
     55        2 => 'Family',
     56        3 => 'Friend',
     57    }},
     58);
     59
     60# FujiFilm MakerNotes tags
    2461%Image::ExifTool::FujiFilm::Main = (
    2562    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     
    5491    0x1001 => {
    5592        Name => 'Sharpness',
    56         Writable => 'int16u',
    57         PrintConv => {
    58             1 => 'Soft',
    59             2 => 'Soft2',
    60             3 => 'Normal',
    61             4 => 'Hard',
    62             5 => 'Hard2',
     93        Flags => 'PrintHex',
     94        Writable => 'int16u',
     95        PrintConv => {
     96            0x01 => 'Soft',
     97            0x02 => 'Soft2',
     98            0x03 => 'Normal',
     99            0x04 => 'Hard',
     100            0x05 => 'Hard2',
     101            0x82 => 'Medium Soft', #2
     102            0x84 => 'Medium Hard', #2
     103            0x8000 => 'Film Simulation', #2
     104            0xffff => 'n/a', #2
    63105        },
    64106    },
     
    74116            0x301 => 'Day White Fluorescent',
    75117            0x302 => 'White Fluorescent',
     118            0x303 => 'Warm White Fluorescent', #2/PH (S5)
     119            0x304 => 'Living Room Warm White Fluorescent', #2/PH (S5)
    76120            0x400 => 'Incandescent',
    77121            0x500 => 'Flash', #4
    78122            0xf00 => 'Custom',
     123            0xf01 => 'Custom2', #2
     124            0xf02 => 'Custom3', #2
     125            0xf03 => 'Custom4', #2
     126            0xf04 => 'Custom5', #2
     127            # 0xfe0 => 'Gray Point?', #2
    79128            0xff0 => 'Kelvin', #4
    80129        },
     
    86135        PrintConv => {
    87136            0x0   => 'Normal',
     137            0x080 => 'Medium High', #2
    88138            0x100 => 'High',
     139            0x180 => 'Medium Low', #2
    89140            0x200 => 'Low',
    90141            0x300 => 'None (B&W)', #2
     142            0x301 => 'B&W Green Filter', #PH (X100)
     143            0x302 => 'B&W Yellow Filter', #PH (X100)
     144            0x303 => 'B&W Blue Filter', #PH (X100)
     145            0x310 => 'B&W Sepia', #PH (X100)
     146            0x8000 => 'Film Simulation', #2
    91147        },
    92148    },
     
    97153        PrintConv => {
    98154            0x0   => 'Normal',
     155            0x080 => 'Medium High', #2
    99156            0x100 => 'High',
     157            0x180 => 'Medium Low', #2
    100158            0x200 => 'Low',
     159            0x8000 => 'Film Simulation', #2
    101160        },
    102161    },
     
    104163        Name => 'ColorTemperature',
    105164        Writable => 'int16u',
     165    },
     166    0x1006 => { #JD
     167        Name => 'Contrast',
     168        Flags => 'PrintHex',
     169        Writable => 'int16u',
     170        PrintConv => {
     171            0x0   => 'Normal',
     172            0x100 => 'High',
     173            0x300 => 'Low',
     174        },
     175    },
     176    0x100a => { #2
     177        Name => 'WhiteBalanceFineTune',
     178        Writable => 'int32s',
     179        Count => 2,
     180        PrintConv => 'sprintf("Red %+d, Blue %+d", split(" ", $val))',
     181        PrintConvInv => 'my @v=($val=~/-?\d+/g);"@v"',
     182    },
     183    0x100b => { #2
     184        Name => 'NoiseReduction',
     185        Flags => 'PrintHex',
     186        Writable => 'int16u',
     187        PrintConv => {
     188            0x40 => 'Low',
     189            0x80 => 'Normal',
     190            0x100 => 'n/a', #PH (NC) (all X100 samples)
     191        },
     192    },
     193    0x100e => { #PH (X100)
     194        Name => 'HighISONoiseReduction',
     195        Flags => 'PrintHex',
     196        Writable => 'int16u',
     197        PrintConv => {
     198            0x000 => 'Normal',
     199            0x100 => 'Strong',
     200            0x200 => 'Weak',
     201        },
    106202    },
    107203    0x1010 => {
     
    113209            2 => 'Off',
    114210            3 => 'Red-eye reduction',
     211            4 => 'External', #JD
    115212        },
    116213    },
    117214    0x1011 => {
    118         Name => 'FlashStrength',
     215        Name => 'FlashExposureComp', #JD
    119216        Writable => 'rational64s',
    120217    },
     
    156253            0x1 => 'Portrait',
    157254            0x2 => 'Landscape',
     255            0x3 => 'Macro', #JD
    158256            0x4 => 'Sports',
    159257            0x5 => 'Night Scene',
     
    161259            0x7 => 'Natural Light', #3
    162260            0x8 => 'Anti-blur', #3
     261            0x9 => 'Beach & Snow', #JD
    163262            0xa => 'Sunset', #3
    164263            0xb => 'Museum', #3
     
    171270            0x12 => 'Fireworks', #3
    172271            0x13 => 'Underwater', #3
     272            0x16 => 'Panorama', #PH (X100)
    173273            0x100 => 'Aperture-priority AE',
    174274            0x200 => 'Shutter speed priority AE',
     
    181281#        Writable => 'int16u',
    182282#    },
     283    0x1033 => { #6
     284        Name => 'EXRAuto',
     285        Writable => 'int16u',
     286        PrintConv => {
     287            0 => 'Auto',
     288            1 => 'Manual',
     289        },
     290    },
     291    0x1034 => { #6
     292        Name => 'EXRMode',
     293        Writable => 'int16u',
     294        PrintHex => 1,
     295        PrintConv => {
     296            0x100 => 'HR (High Resolution)',
     297            0x200 => 'SN (Signal to Noise priority)',
     298            0x300 => 'DR (Dynamic Range priority)',
     299        },
     300    },
    183301    0x1100 => {
    184302        Name => 'AutoBracketing',
     
    228346        },
    229347    },
     348    0x1304 => { #PH
     349        Name => 'GEImageSize',
     350        Condition => '$$self{Make} =~ /^GENERAL IMAGING/',
     351        Format => 'string',
     352        Notes => 'GE models only',
     353    },
    230354    0x1400 => { #2
    231355        Name => 'DynamicRange',
     
    234358            1 => 'Standard',
    235359            3 => 'Wide',
    236         },
    237     },
    238     0x1401 => { #2
     360            # the S5Pro has 100%(STD),130%,170%,230%(W1),300%,400%(W2) - PH
     361        },
     362    },
     363    0x1401 => { #2 (this doesn't seem to work for the X100 - PH)
    239364        Name => 'FilmMode',
    240365        Writable => 'int16u',
     
    243368            0x000 => 'F0/Standard',
    244369            0x100 => 'F1/Studio Portrait',
     370            0x110 => 'F1a/Studio Portrait Enhanced Saturation',
     371            0x120 => 'F1b/Studio Portrait Smooth Skin Tone',
     372            0x130 => 'F1c/Studio Portrait Increased Sharpness',
    245373            0x200 => 'F2/Fujichrome',
    246374            0x300 => 'F3/Studio Portrait Ex',
     
    254382        PrintConv => {
    255383            0x000 => 'Auto (100-400%)',
    256             0x001 => 'RAW',
     384            0x001 => 'Manual', #(ref http://forum.photome.de/viewtopic.php?f=2&t=353)
    257385            0x100 => 'Standard (100%)',
    258386            0x200 => 'Wide1 (230%)',
    259387            0x201 => 'Wide2 (400%)',
    260             0x8000 => 'Film Simulation Mode',
    261         },
    262     },
    263     0x1403 => { #2
     388            0x8000 => 'Film Simulation',
     389        },
     390    },
     391    0x1403 => { #2 (only valid for manual DR, ref 6)
    264392        Name => 'DevelopmentDynamicRange',
    265393        Writable => 'int16u',
     
    281409        Writable => 'rational64s',
    282410    },
     411    # 0x1408 - values: '0100', 'S100', 'VQ10'
     412    # 0x1409 - values: same as 0x1408
     413    # 0x140a - values: 0, 1, 3, 5, 7
     414    0x140b => { #6
     415        Name => 'AutoDynamicRange',
     416        Writable => 'int16u',
     417        PrintConv => '"$val%"',
     418        PrintConvInv => '$val=~s/\s*\%$//; $val',
     419    },
     420    # 0x140b - DR value for AutoDR???? (ref 6) - values: 100
     421    # 0x3820 - int16u video frame rate? - PH (HS20EXR)
     422    # 0x3821 - int16u video frame width? - PH (HS20EXR)
     423    # 0x3822 - int16u video frame height? - PH (HS20EXR)
     424    0x4100 => { #PH
     425        Name => 'FacesDetected',
     426        Writable => 'int16u',
     427    },
     428    0x4103 => { #PH
     429        Name => 'FacePositions',
     430        Writable => 'int16u',
     431        Count => -1,
     432        Notes => q{
     433            left, top, right and bottom coordinates in full-sized image for each face
     434            detected
     435        },
     436    },
     437    # 0x4104 - also related to face detection (same number of entries as FacePositions)
     438    # 0x4203 - same as 0x4103
     439    # 0x4204 - same as 0x4104
     440    0x4282 => { #PH
     441        Name => 'FaceRecInfo',
     442        SubDirectory => { TagTable => 'Image::ExifTool::FujiFilm::FaceRecInfo' },
     443    },
    283444    0x8000 => { #2
    284445        Name => 'FileSource',
     
    293454        Writable => 'int16u',
    294455    },
     456    0xb211 => { #PH
     457        Name => 'Parallax',
     458        # (value set in camera is -0.5 times this value in MPImage2... why?)
     459        Writable => 'rational64s',
     460        Notes => 'only found in MPImage2 of .MPO images',
     461    },
     462    # 0xb212 - also found in MPIMage2 images - PH
     463);
     464
     465# Face recognition information from FinePix F550EXR (ref PH)
     466%Image::ExifTool::FujiFilm::FaceRecInfo = (
     467    PROCESS_PROC => \&ProcessFaceRec,
     468    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     469    VARS => { NO_ID => 1 },
     470    NOTES => 'Face recognition information.',
     471    Face1Name => { },
     472    Face2Name => { },
     473    Face3Name => { },
     474    Face4Name => { },
     475    Face5Name => { },
     476    Face6Name => { },
     477    Face7Name => { },
     478    Face8Name => { },
     479    Face1Category => { %faceCategories },
     480    Face2Category => { %faceCategories },
     481    Face3Category => { %faceCategories },
     482    Face4Category => { %faceCategories },
     483    Face5Category => { %faceCategories },
     484    Face6Category => { %faceCategories },
     485    Face7Category => { %faceCategories },
     486    Face8Category => { %faceCategories },
     487    Face1Birthday => { },
     488    Face2Birthday => { },
     489    Face3Birthday => { },
     490    Face4Birthday => { },
     491    Face5Birthday => { },
     492    Face6Birthday => { },
     493    Face7Birthday => { },
     494    Face8Birthday => { },
    295495);
    296496
    297497# tags in RAF images (ref 5)
    298498%Image::ExifTool::FujiFilm::RAF = (
     499    PROCESS_PROC => \&ProcessFujiDir,
    299500    GROUPS => { 0 => 'RAF', 1 => 'RAF', 2 => 'Image' },
    300     NOTES => 'Tags extracted from FujiFilm RAF-format information.',
     501    PRIORITY => 0, # so the first RAF directory takes precedence
     502    NOTES => q{
     503        FujiFilm RAF images contain meta information stored in a proprietary
     504        FujiFilm RAF format, as well as EXIF information stored inside an embedded
     505        JPEG preview image.  The table below lists tags currently decoded from the
     506        RAF-format information.
     507    },
    301508    0x100 => {
    302509        Name => 'RawImageFullSize',
     
    311518        {
    312519            Name => 'RawImageSize',
    313             Condition => '$$self{CameraModel} eq "FinePixS2Pro"',
     520            Condition => '$$self{Model} eq "FinePixS2Pro"',
    314521            Format => 'int16u',
    315522            Count => 2,
     
    350557);
    351558
     559# information found in FFMV atom of MOV videos
     560%Image::ExifTool::FujiFilm::FFMV = (
     561    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     562    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     563    FIRST_ENTRY => 0,
     564    NOTES => 'Information found in the FFMV atom of MOV videos.',
     565    0 => {
     566        Name => 'MovieStreamName',
     567        Format => 'string[34]',
     568    },
     569);
     570
     571#------------------------------------------------------------------------------
     572# decode information from FujiFilm face recognition information
     573# Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) tag table ref
     574# Returns: 1
     575sub ProcessFaceRec($$$)
     576{
     577    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     578    my $dataPt = $$dirInfo{DataPt};
     579    my $dataPos = $$dirInfo{DataPos} + ($$dirInfo{Base} || 0);
     580    my $dirStart = $$dirInfo{DirStart};
     581    my $dirLen = $$dirInfo{DirLen};
     582    my $pos = $dirStart;
     583    my $end = $dirStart + $dirLen;
     584    my ($i, $n, $p, $val);
     585    $exifTool->VerboseDir('FaceRecInfo');
     586    for ($i=1; ; ++$i) {
     587        last if $pos + 8 > $end;
     588        my $off = Get32u($dataPt, $pos) + $dirStart;
     589        my $len = Get32u($dataPt, $pos + 4);
     590        last if $len==0 or $off>$end or $off+$len>$end or $len < 62;
     591        # values observed for each offset (always zero if not listed):
     592        # 0=5; 3=1; 4=4; 6=1; 10-13=numbers(constant for a given registered face)
     593        # 15=16; 16=3; 18=1; 22=nameLen; 26=1; 27=16; 28=7; 30-33=nameLen(int32u)
     594        # 34-37=nameOffset(int32u); 38=32; 39=16; 40=4; 42=1; 46=0,2,4,8(category)
     595        # 50=33; 51=16; 52=7; 54-57=dateLen(int32u); 58-61=dateOffset(int32u)
     596        $n = Get32u($dataPt, $off + 30);
     597        $p = Get32u($dataPt, $off + 34) + $dirStart;
     598        last if $p < $dirStart or $p + $n > $end;
     599        $val = substr($$dataPt, $p, $n);
     600        $exifTool->HandleTag($tagTablePtr, "Face${i}Name", $val,
     601            DataPt  => $dataPt,
     602            DataPos => $dataPos,
     603            Start   => $p,
     604            Size    => $n,
     605        );
     606        $n = Get32u($dataPt, $off + 54);
     607        $p = Get32u($dataPt, $off + 58) + $dirStart;
     608        last if $p < $dirStart or $p + $n > $end;
     609        $val = substr($$dataPt, $p, $n);
     610        $val =~ s/(\d{4})(\d{2})(\d{2})/$1:$2:$2/;
     611        $exifTool->HandleTag($tagTablePtr, "Face${i}Birthday", $val,
     612            DataPt  => $dataPt,
     613            DataPos => $dataPos,
     614            Start   => $p,
     615            Size    => $n,
     616        );
     617        $exifTool->HandleTag($tagTablePtr, "Face${i}Category", undef,
     618            DataPt  => $dataPt,
     619            DataPos => $dataPos,
     620            Start   => $off + 46,
     621            Size    => 1,
     622        );
     623        $pos += 8;
     624    }
     625    return 1;
     626}
     627
    352628#------------------------------------------------------------------------------
    353629# get information from FujiFilm RAF directory
     
    360636    my $offset = $$dirInfo{DirStart};
    361637    $raf->Seek($offset, 0) or return 0;
    362     my $buff;
     638    my ($buff, $index);
    363639    $raf->Read($buff, 4) or return 0;
    364640    my $entries = unpack 'N', $buff;
    365641    $entries < 256 or return 0;
     642    $exifTool->Options('Verbose') and $exifTool->VerboseDir('Fuji', $entries);
    366643    SetByteOrder('MM');
    367     while ($entries--) {
     644    my $pos = $offset + 4;
     645    for ($index=0; $index<$entries; ++$index) {
    368646        $raf->Read($buff,4) or return 0;
     647        $pos += 4;
    369648        my ($tag, $len) = unpack 'nn', $buff;
    370649        my ($val, $vbuf);
     
    374653            $val = ReadValue(\$vbuf, 0, $$tagInfo{Format}, $$tagInfo{Count}, $len);
    375654            next unless defined $val;
     655        } elsif ($len == 4) {
     656            # interpret unknown 4-byte values as int32u
     657            $val = Get32u(\$vbuf, 0);
    376658        } else {
     659            # treat other unknown values as binary data
    377660            $val = \$vbuf;
    378661        }
    379         $exifTool->HandleTag($tagTablePtr, $tag, $val);
     662        $exifTool->HandleTag($tagTablePtr, $tag, $val,
     663            Index   => $index,
     664            DataPt  => \$vbuf,
     665            DataPos => $pos,
     666            Size    => $len,
     667            TagInfo => $tagInfo,
     668        );
     669        $pos += $len;
    380670    }
    381671    return 1;
     
    383673
    384674#------------------------------------------------------------------------------
    385 # get information from FujiFilm RAW file
     675# write information to FujiFilm RAW file (RAF)
    386676# Inputs: 0) ExifTool object reference, 1) dirInfo reference
    387 # Returns: 1 if this was a valid FujiFilm RAW file
     677# Returns: 1 on success, 0 if this wasn't a valid RAF file, or -1 on write error
     678sub WriteRAF($$)
     679{
     680    my ($exifTool, $dirInfo) = @_;
     681    my $raf = $$dirInfo{RAF};
     682    my ($hdr, $jpeg, $outJpeg, $offset, $err, $buff);
     683
     684    $raf->Read($hdr,0x94) == 0x94  or return 0;
     685    $hdr =~ /^FUJIFILM/            or return 0;
     686    my $ver = substr($hdr, 0x3c, 4);
     687    $ver =~ /^\d{4}$/              or return 0;
     688
     689    # get the position and size of embedded JPEG
     690    my ($jpos, $jlen) = unpack('x84NN', $hdr);
     691    # check to be sure the JPEG starts in the expected location
     692    if ($jpos > 0x94 or $jpos < 0x68 or $jpos & 0x03) {
     693        $exifTool->Error("Unsupported or corrupted RAF image (version $ver)");
     694        return 1;
     695    }
     696    # check to make sure this version of RAF has been tested
     697    unless ($testedRAF{$ver}) {
     698        $exifTool->Error("RAF version $ver not yet tested", 1) and return 1;
     699    }
     700    # read the embedded JPEG
     701    unless ($raf->Seek($jpos, 0) and $raf->Read($jpeg, $jlen) == $jlen) {
     702        $exifTool->Error('Error reading RAF meta information');
     703        return 1;
     704    }
     705    # use same write directories as JPEG
     706    $exifTool->InitWriteDirs('JPEG');
     707    # rewrite the embedded JPEG in memory
     708    my %jpegInfo = (
     709        Parent  => 'RAF',
     710        RAF     => new File::RandomAccess(\$jpeg),
     711        OutFile => \$outJpeg,
     712    );
     713    $$exifTool{FILE_TYPE} = 'JPEG';
     714    my $success = $exifTool->WriteJPEG(\%jpegInfo);
     715    $$exifTool{FILE_TYPE} = 'RAF';
     716    unless ($success and $outJpeg) {
     717        $exifTool->Error("Invalid RAF format");
     718        return 1;
     719    }
     720    return -1 if $success < 0;
     721
     722    # rewrite the RAF image
     723    SetByteOrder('MM');
     724    my $jpegLen = length $outJpeg;
     725    # pad JPEG to an even 4 bytes (ALWAYS use padding as Fuji does)
     726    my $pad = "\0" x (4 - ($jpegLen % 4));
     727    # update JPEG size in header (size without padding)
     728    Set32u(length($outJpeg), \$hdr, 0x58);
     729    # get pointer to start of the next RAF block
     730    my $nextPtr = Get32u(\$hdr, 0x5c);
     731    # determine the length of padding at the end of the original JPEG
     732    my $oldPadLen = $nextPtr - ($jpos + $jlen);
     733    if ($oldPadLen) {
     734        if ($oldPadLen > 1000000 or $oldPadLen < 0 or
     735            not $raf->Seek($jpos+$jlen, 0) or
     736            $raf->Read($buff, $oldPadLen) != $oldPadLen)
     737        {
     738            $exifTool->Error('Bad RAF pointer at 0x5c');
     739            return 1;
     740        }
     741        # make sure padding is only zero bytes (can be >100k for HS10)
     742        if ($buff =~ /[^\0]/) {
     743            $exifTool->Error('Non-null bytes found in padding');
     744            return 1;
     745        }
     746    }
     747    # calculate offset difference due to change in JPEG size
     748    my $ptrDiff = length($outJpeg) + length($pad) - ($jlen + $oldPadLen);
     749    # update necessary pointers in header
     750    foreach $offset (0x5c, 0x64, 0x78, 0x80) {
     751        last if $offset >= $jpos;    # some versions have a short header
     752        my $oldPtr = Get32u(\$hdr, $offset);
     753        next unless $oldPtr;        # don't update if pointer is zero
     754        Set32u($oldPtr + $ptrDiff, \$hdr, $offset);
     755    }
     756    # write the new header
     757    my $outfile = $$dirInfo{OutFile};
     758    Write($outfile, substr($hdr, 0, $jpos)) or $err = 1;
     759    # write the updated JPEG plus padding
     760    Write($outfile, $outJpeg, $pad) or $err = 1;
     761    # copy over the rest of the RAF image
     762    unless ($raf->Seek($nextPtr, 0)) {
     763        $exifTool->Error('Error reading RAF image');
     764        return 1;
     765    }
     766    while ($raf->Read($buff, 65536)) {
     767        Write($outfile, $buff) or $err = 1, last;
     768    }
     769    return $err ? -1 : 1;
     770}
     771
     772#------------------------------------------------------------------------------
     773# get information from FujiFilm RAW file (RAF)
     774# Inputs: 0) ExifTool object reference, 1) dirInfo reference
     775# Returns: 1 if this was a valid RAF file
    388776sub ProcessRAF($$)
    389777{
    390778    my ($exifTool, $dirInfo) = @_;
    391     my ($buff, $warn);
     779    my ($buff, $jpeg, $warn, $offset);
    392780
    393781    my $raf = $$dirInfo{RAF};
    394     $raf->Read($buff,8) == 8        or return 0;
    395     $buff eq 'FUJIFILM'             or return 0;
    396     $raf->Seek(84, 0)               or return 0;
    397     $raf->Read($buff, 8) == 8       or return 0;
    398     my ($pos, $len) = unpack('NN', $buff);
    399     $pos & 0x8000                  and return 0;
    400     $raf->Seek($pos, 0)             or return 0;
    401     $raf->Read($buff, $len) == $len or return 0;
     782    $raf->Read($buff,0x5c) == 0x5c    or return 0;
     783    $buff =~ /^FUJIFILM/              or return 0;
     784    my ($jpos, $jlen) = unpack('x84NN', $buff);
     785    $jpos & 0x8000                   and return 0;
     786    $raf->Seek($jpos, 0)              or return 0;
     787    $raf->Read($jpeg, $jlen) == $jlen or return 0;
     788
     789    $exifTool->FoundTag('RAFVersion', substr($buff, 0x3c, 4));
     790
     791    # extract information from embedded JPEG
    402792    my %dirInfo = (
    403793        Parent => 'RAF',
    404         RAF    => new File::RandomAccess(\$buff),
     794        RAF    => new File::RandomAccess(\$jpeg),
    405795    );
    406     $$exifTool{BASE} += $pos;
     796    $$exifTool{BASE} += $jpos;
    407797    my $rtnVal = $exifTool->ProcessJPEG(\%dirInfo);
    408     $$exifTool{BASE} -= $pos;
    409     $exifTool->FoundTag('PreviewImage', \$buff) if $rtnVal;
    410 
    411     if ($raf->Seek(92, 0) and $raf->Read($buff, 4)) {
     798    $$exifTool{BASE} -= $jpos;
     799    $exifTool->FoundTag('PreviewImage', \$jpeg) if $rtnVal;
     800
     801    # extract information from Fuji RAF directories
     802    my $num = '';
     803    foreach $offset (0x5c, 0x78) {
     804        last if $offset >= $jpos;
     805        unless ($raf->Seek($offset, 0) and $raf->Read($buff, 4)) {
     806            $warn = 1;
     807            last;
     808        }
     809        my $start = unpack('N',$buff);
     810        next unless $start;
     811
     812        %dirInfo = (
     813            RAF      => $raf,
     814            DirStart => $start,
     815        );
     816        $$exifTool{SET_GROUP1} = "RAF$num";
    412817        my $tagTablePtr = GetTagTable('Image::ExifTool::FujiFilm::RAF');
    413         %dirInfo = (
    414             RAF => $raf,
    415             DirStart => unpack('N', $buff),
    416         );
    417         $$exifTool{SET_GROUP1} = 'RAF';
    418         ProcessFujiDir($exifTool, \%dirInfo, $tagTablePtr) or $warn = 1;
    419    
    420         # extract information from 2nd image if available
    421         if ($pos > 120) {
    422             $raf->Seek(120, 0) or return 0;
    423             $raf->Read($buff, 4) or return 0;
    424             my $start = unpack('N',$buff);
    425             if ($start) {
    426                 $$dirInfo{DirStart} = $start;
    427                 $$exifTool{SET_GROUP1} = 'RAF2';
    428                 ProcessFujiDir($exifTool, \%dirInfo, $tagTablePtr) or $warn = 1;
    429             }
    430         }
     818        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr) or $warn = 1;
    431819        delete $$exifTool{SET_GROUP1};
    432     } else {
    433         $warn = 1;
     820
     821        $num = ($num || 1) + 1;
    434822    }
    435823    $warn and $exifTool->Warn('Possibly corrupt RAF information');
     
    444832=head1 NAME
    445833
    446 Image::ExifTool::FujiFilm - FujiFilm EXIF maker notes tags
     834Image::ExifTool::FujiFilm - Read/write FujiFilm maker notes and RAF images
    447835
    448836=head1 SYNOPSIS
     
    453841
    454842This module contains definitions required by Image::ExifTool to interpret
    455 FujiFilm maker notes in EXIF information, and to read FujiFilm RAW (RAF)
    456 images.
     843FujiFilm maker notes in EXIF information, and to read/write FujiFilm RAW
     844(RAF) images.
    457845
    458846=head1 AUTHOR
    459847
    460 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     848Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    461849
    462850This library is free software; you can redistribute it and/or modify it
     
    479867=head1 ACKNOWLEDGEMENTS
    480868
    481 Thanks to Michael Meissner for decoding some new PictureMode and
    482 AutoBracketing values, and to Paul Samuelson for decoding some WhiteBalance
    483 values and the ColorTemperature tag.
     869Thanks to Michael Meissner, Paul Samuelson and Jens Duttke for help decoding
     870some FujiFilm information.
    484871
    485872=head1 SEE ALSO
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GIF.pm

    r16842 r24107  
    66# Revisions:    10/18/2005 - P. Harvey Separated from ExifTool.pm
    77#
    8 # References:   http://www.w3.org/Graphics/GIF/spec-gif89a.txt
    9 #
    10 # Notes:        GIF really doesn't have much meta information, except for
    11 #               comments which are allowed in GIF89a images
     8# References:   1) http://www.w3.org/Graphics/GIF/spec-gif89a.txt
     9#               2) http://www.adobe.com/devnet/xmp/
     10#               3) http://graphcomp.com/info/specs/ani_gif.html
    1211#------------------------------------------------------------------------------
    1312
     
    1615use strict;
    1716use vars qw($VERSION);
    18 use Image::ExifTool qw(:DataAccess);
    19 
    20 $VERSION = '1.04';
     17use Image::ExifTool qw(:DataAccess :Utils);
     18
     19$VERSION = '1.06';
     20
     21# road map of directory locations in GIF images
     22my %gifMap = (
     23    XMP => 'GIF',
     24);
     25
     26%Image::ExifTool::GIF::Main = (
     27    GROUPS => { 2 => 'Image' },
     28    VARS => { NO_ID => 1 },
     29    NOTES => q{
     30        This table lists information extracted from GIF images. See
     31        L<http://www.w3.org/Graphics/GIF/spec-gif89a.txt> for the official GIF89a
     32        specification.
     33    },
     34    GIFVersion => { },
     35    FrameCount => { Notes => 'number of animated images' },
     36    Text       => { Notes => 'text displayed in image' },
     37    Comment    => {
     38        # for documentation only -- flag as writable for the docs, but
     39        # it won't appear in the TagLookup because there is no WRITE_PROC
     40        Writable => 1,
     41    },
     42    Duration   => {
     43        Notes => 'duration of a single animation iteration',
     44        PrintConv => 'sprintf("%.2f s",$val)',
     45    },
     46    ScreenDescriptor => {
     47        SubDirectory => { TagTable => 'Image::ExifTool::GIF::Screen' },
     48    },
     49    AnimationExtension => {
     50        SubDirectory => { TagTable => 'Image::ExifTool::GIF::Animate' },
     51    },
     52    XMPExtension => { # (for documentation only)
     53        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     54    },
     55);
     56
     57# GIF locical screen descriptor
     58%Image::ExifTool::GIF::Screen = (
     59    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     60    GROUPS => { 2 => 'Image' },
     61    NOTES => 'Information extracted from the GIF logical screen descriptor.',
     62    0 => {
     63        Name => 'ImageWidth',
     64        Format => 'int16u',
     65    },
     66    2 => {
     67        Name => 'ImageHeight',
     68        Format => 'int16u',
     69    },
     70    4.1 => {
     71        Name => 'HasColorMap',
     72        Mask => 0x80,
     73        PrintConv => { 0x00 => 'No', 0x80 => 'Yes' },
     74    },
     75    4.2 => {
     76        Name => 'ColorResolutionDepth',
     77        Mask => 0x70,
     78        ValueConv => '($val >> 4) + 1',
     79    },
     80    4.3 => {
     81        Name => 'BitsPerPixel',
     82        Mask => 0x07,
     83        ValueConv => '$val + 1',
     84    },
     85    5 => 'BackgroundColor',
     86);
     87
     88# GIF Netscape 2.0 animation extension
     89%Image::ExifTool::GIF::Animate = (
     90    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     91    GROUPS => { 2 => 'Image' },
     92    NOTES => 'Information extracted from the "NETSCAPE2.0" animation extension.',
     93    2 => {
     94        Name => 'AnimationIterations',
     95        Format => 'int16u',
     96        PrintConv => '$val ? $val : "Infinite"',
     97    },
     98);
    2199
    22100#------------------------------------------------------------------------------
     
    28106{
    29107    my ($exifTool, $dirInfo) = @_;
    30     my ($type, $a, $s, $ch, $length, $buff);
    31     my ($err, $newComment, $setComment);
     108    my $outfile = $$dirInfo{OutFile};
     109    my $raf = $$dirInfo{RAF};
    32110    my $verbose = $exifTool->Options('Verbose');
    33111    my $out = $exifTool->Options('TextOut');
    34     my $outfile = $$dirInfo{OutFile};
    35     my $raf = $$dirInfo{RAF};
     112    my ($a, $s, $ch, $length, $buff, $comment);
     113    my ($err, $newComment, $setComment);
     114    my ($addDirs, %doneDir);
     115    my ($frameCount, $delayTime) = (0, 0);
     116
     117    # verify this is a valid GIF file
     118    return 0 unless $raf->Read($buff, 6) == 6
     119        and $buff =~ /^GIF(8[79]a)$/
     120        and $raf->Read($s, 7) == 7;
     121
     122    my $ver = $1;
    36123    my $rtnVal = 0;
    37 
    38     # verify this is a valid GIF file
    39     # (must do a RAF read until we know the file is ours)
    40     return 0 unless $raf->Read($type, 6) == 6
    41         and $type =~ /^GIF8[79]a$/
    42         and $raf->Read($s, 4) == 4;
    43 
    44     $verbose and print $out "GIF file version $type\n";
     124    my $tagTablePtr = GetTagTable('Image::ExifTool::GIF::Main');
     125    SetByteOrder('II');
     126
    45127    if ($outfile) {
    46         Write($outfile, $type, $s) or $err = 1;
    47         if ($exifTool->{DEL_GROUP}->{File}) {
     128        $exifTool->InitWriteDirs(\%gifMap, 'XMP'); # make XMP the preferred group for GIF
     129        $addDirs = $exifTool->{ADD_DIRS};
     130        # determine if we are editing the File:Comment tag
     131        my $delGroup = $exifTool->{DEL_GROUP};
     132        if ($$delGroup{File}) {
    48133            $setComment = 1;
    49             if ($exifTool->{DEL_GROUP}->{File} == 2) {
     134            if ($$delGroup{File} == 2) {
    50135                $newComment = $exifTool->GetNewValues('Comment');
    51136            }
    52137        } else {
    53             my $newValueHash;
    54             $newComment = $exifTool->GetNewValues('Comment', \$newValueHash);
    55             $setComment = 1 if $newValueHash;
    56         }
     138            my $nvHash;
     139            $newComment = $exifTool->GetNewValues('Comment', \$nvHash);
     140            $setComment = 1 if $nvHash;
     141        }
     142        # change to GIF 89a if adding comment or XMP
     143        $buff = 'GIF89a' if $$addDirs{XMP} or defined $newComment;
     144        Write($outfile, $buff, $s) or $err = 1;
     145    } else {
     146        $exifTool->SetFileType();   # set file type
     147        $exifTool->HandleTag($tagTablePtr, 'GIFVersion', $ver);
     148        $exifTool->HandleTag($tagTablePtr, 'ScreenDescriptor', $s);
    57149    }
    58     $exifTool->SetFileType();   # set file type
    59     my ($w, $h) = unpack("v"x2, $s);
    60     $exifTool->FoundTag('ImageWidth', $w);
    61     $exifTool->FoundTag('ImageHeight', $h);
    62     if ($raf->Read($s, 3) == 3) {
    63         Write($outfile, $s) or $err = 1 if $outfile;
    64         if (ord($s) & 0x80) { # does this image contain a color table?
    65             # calculate color table size
    66             $length = 3 * (2 << (ord($s) & 0x07));
    67             $raf->Read($buff, $length) == $length or return 0; # skip color table
    68             Write($outfile, $buff) or $err = 1 if $outfile;
    69         }
    70         # write the comment first if necessary
    71         if ($outfile and defined $newComment) {
    72             if ($type ne 'GIF87a') {
    73                 # write comment marker
    74                 Write($outfile, "\x21\xfe") or $err = 1;
    75                 my $len = length($newComment);
    76                 # write out the comment in 255-byte chunks, each
    77                 # chunk beginning with a length byte
    78                 my $n;
    79                 for ($n=0; $n<$len; $n+=255) {
    80                     my $size = $len - $n;
    81                     $size > 255 and $size = 255;
    82                     my $str = substr($newComment,$n,$size);
    83                     Write($outfile, pack('C',$size), $str) or $err = 1;
    84                 }
    85                 Write($outfile, "\0") or $err = 1;  # empty chunk as terminator
    86                 undef $newComment;
    87                 ++$exifTool->{CHANGED};     # increment file changed flag
    88             } else {
    89                 $exifTool->Warn("The GIF87a format doesn't support comments");
    90             }
    91         }
    92         my $comment;
    93         for (;;) {
    94             last unless $raf->Read($ch, 1);
    95             if (ord($ch) == 0x2c) {
     150    my $flags = Get8u(\$s, 4);
     151    if ($flags & 0x80) { # does this image contain a color table?
     152        # calculate color table size
     153        $length = 3 * (2 << ($flags & 0x07));
     154        $raf->Read($buff, $length) == $length or return 0; # skip color table
     155        Write($outfile, $buff) or $err = 1 if $outfile;
     156    }
     157    # write the comment first if necessary
     158    if ($outfile and defined $newComment) {
     159        # write comment marker
     160        Write($outfile, "\x21\xfe") or $err = 1;
     161        $verbose and print $out "  + Comment = $newComment\n";
     162        my $len = length($newComment);
     163        # write out the comment in 255-byte chunks, each
     164        # chunk beginning with a length byte
     165        my $n;
     166        for ($n=0; $n<$len; $n+=255) {
     167            my $size = $len - $n;
     168            $size > 255 and $size = 255;
     169            my $str = substr($newComment,$n,$size);
     170            Write($outfile, pack('C',$size), $str) or $err = 1;
     171        }
     172        Write($outfile, "\0") or $err = 1;  # empty chunk as terminator
     173        undef $newComment;
     174        ++$exifTool->{CHANGED};     # increment file changed flag
     175    }
     176#
     177# loop through GIF blocks
     178#
     179Block:
     180    for (;;) {
     181        last unless $raf->Read($ch, 1);
     182        if ($outfile and ord($ch) != 0x21) {
     183            # add application extension containing XMP block if necessary
     184            # (this will place XMP before the first non-extension block)
     185            if (exists $$addDirs{XMP} and not defined $doneDir{XMP}) {
     186                $doneDir{XMP} = 1;
     187                # write new XMP data
     188                my $xmpTable = GetTagTable('Image::ExifTool::XMP::Main');
     189                my %dirInfo = ( Parent => 'GIF' );
     190                $verbose and print $out "Creating XMP application extension block:\n";
     191                $buff = $exifTool->WriteDirectory(\%dirInfo, $xmpTable);
     192                if (defined $buff and length $buff) {
     193                    my $lz = pack('C*',1,reverse(0..255),0);
     194                    Write($outfile, "\x21\xff\x0bXMP DataXMP", $buff, $lz) or $err = 1;
     195                    ++$doneDir{XMP};    # set to 2 to indicate we added XMP
     196                } else {
     197                    $verbose and print $out "  -> no XMP to add\n";
     198                }
     199            }
     200        }
     201        if (ord($ch) == 0x2c) {
     202            ++$frameCount;
     203            Write($outfile, $ch) or $err = 1 if $outfile;
     204            # image descriptor
     205            last unless $raf->Read($buff, 8) == 8 and $raf->Read($ch, 1);
     206            Write($outfile, $buff, $ch) or $err = 1 if $outfile;
     207            if ($verbose) {
     208                my ($left, $top, $w, $h) = unpack('v*', $buff);
     209                print $out "Image: left=$left top=$top width=$w height=$h\n";
     210            }
     211            if (ord($ch) & 0x80) { # does color table exist?
     212                $length = 3 * (2 << (ord($ch) & 0x07));
     213                # skip the color table
     214                last unless $raf->Read($buff, $length) == $length;
     215                Write($outfile, $buff) or $err = 1 if $outfile;
     216            }
     217            # skip "LZW Minimum Code Size" byte
     218            last unless $raf->Read($buff, 1);
     219            Write($outfile,$buff) or $err = 1 if $outfile;
     220            # skip image blocks
     221            for (;;) {
     222                last unless $raf->Read($ch, 1);
    96223                Write($outfile, $ch) or $err = 1 if $outfile;
    97                 # image descriptor
    98                 last unless $raf->Read($buff, 8) == 8;
    99                 last unless $raf->Read($ch, 1);
    100                 Write($outfile, $buff, $ch) or $err = 1 if $outfile;
    101                 if (ord($ch) & 0x80) { # does color table exist?
    102                     $length = 3 * (2 << (ord($ch) & 0x07));
    103                     # skip the color table
    104                     last unless $raf->Read($buff, $length) == $length;
    105                     Write($outfile, $buff) or $err = 1 if $outfile;
    106                 }
    107                 # skip "LZW Minimum Code Size" byte
    108                 last unless $raf->Read($buff, 1);
     224                last unless ord($ch);
     225                last unless $raf->Read($buff, ord($ch));
    109226                Write($outfile,$buff) or $err = 1 if $outfile;
    110                 # skip image blocks
    111                 for (;;) {
    112                     last unless $raf->Read($ch, 1);
    113                     Write($outfile, $ch) or $err = 1 if $outfile;
    114                     last unless ord($ch);
    115                     last unless $raf->Read($buff, ord($ch));
    116                     Write($outfile,$buff) or $err = 1 if $outfile;
    117                 }
    118                 next;  # continue with next field
    119             }
     227            }
     228            next;  # continue with next field
     229        }
    120230#               last if ord($ch) == 0x3b;  # normal end of GIF marker
    121             unless (ord($ch) == 0x21) {
    122                 if ($outfile) {
    123                     Write($outfile, $ch) or $err = 1;
    124                     # copy the rest of the file
    125                     while ($raf->Read($buff, 65536)) {
    126                         Write($outfile, $buff) or $err = 1;
    127                     }
    128                 }
    129                 $rtnVal = 1;
    130                 last;
    131             }
    132             # get extension block type/size
    133             last unless $raf->Read($s, 2) == 2;
    134             # get marker and block size
    135             ($a,$length) = unpack("C"x2, $s);
    136             if ($a == 0xfe) {  # is this a comment?
    137                 if ($setComment) {
    138                     ++$exifTool->{CHANGED}; # increment the changed flag
    139                 } else {
    140                     Write($outfile, $ch, $s) or $err = 1 if $outfile;
    141                 }
    142                 while ($length) {
    143                     last unless $raf->Read($buff, $length) == $length;
    144                     $verbose > 2 and Image::ExifTool::HexDump(\$buff, undef, Out => $out);
    145                     if (defined $comment) {
    146                         $comment .= $buff;  # add to comment string
    147                     } else {
    148                         $comment = $buff;
    149                     }
    150                     last unless $raf->Read($ch, 1);  # read next block header
    151                     unless ($setComment) {
    152                         Write($outfile, $buff, $ch) or $err = 1 if $outfile;
    153                     }
    154                     $length = ord($ch);  # get next block size
    155                 }
    156                 last if $length;    # was a read error if length isn't zero
    157                 unless ($outfile) {
    158                     $rtnVal = 1;
    159                     $exifTool->FoundTag('Comment', $comment) if $comment;
    160                     undef $comment;
    161                     # assume no more than one comment in FastScan mode
    162                     last if $exifTool->Options('FastScan');
    163                 }
     231        unless (ord($ch) == 0x21) {
     232            if ($outfile) {
     233                Write($outfile, $ch) or $err = 1;
     234                # copy the rest of the file
     235                while ($raf->Read($buff, 65536)) {
     236                    Write($outfile, $buff) or $err = 1;
     237                }
     238            }
     239            $rtnVal = 1;
     240            last;
     241        }
     242        # get extension block type/size
     243        last unless $raf->Read($s, 2) == 2;
     244        # get marker and block size
     245        ($a,$length) = unpack("C"x2, $s);
     246
     247        if ($a == 0xfe) {                           # comment extension
     248
     249            if ($setComment) {
     250                ++$exifTool->{CHANGED}; # increment the changed flag
    164251            } else {
    165252                Write($outfile, $ch, $s) or $err = 1 if $outfile;
    166                 # skip the block
    167                 while ($length) {
    168                     last unless $raf->Read($buff, $length) == $length;
    169                     Write($outfile, $buff) or $err = 1 if $outfile;
    170                     last unless $raf->Read($ch, 1);  # read next block header
    171                     Write($outfile, $ch) or $err = 1 if $outfile;
    172                     $length = ord($ch);  # get next block size
    173                 }
    174             }
    175         }
     253            }
     254            while ($length) {
     255                last unless $raf->Read($buff, $length) == $length;
     256                if ($verbose > 2 and not $outfile) {
     257                    Image::ExifTool::HexDump(\$buff, undef, Out => $out);
     258                }
     259                # add buffer to comment string
     260                $comment = defined $comment ? $comment . $buff : $buff;
     261                last unless $raf->Read($ch, 1);  # read next block header
     262                $length = ord($ch);  # get next block size
     263
     264                # write or delete comment
     265                next unless $outfile;
     266                if ($setComment) {
     267                    $verbose and print $out "  - Comment = $buff\n";
     268                } else {
     269                    Write($outfile, $buff, $ch) or $err = 1;
     270                }
     271            }
     272            last if $length;    # was a read error if length isn't zero
     273            unless ($outfile) {
     274                $rtnVal = 1;
     275                $exifTool->FoundTag('Comment', $comment) if $comment;
     276                undef $comment;
     277                # assume no more than one comment in FastScan mode
     278                last if $exifTool->Options('FastScan');
     279            }
     280            next;
     281
     282        } elsif ($a == 0xff and $length == 0x0b) {  # application extension
     283
     284            last unless $raf->Read($buff, $length) == $length;
     285            if ($verbose) {
     286                my @a = unpack('a8a3', $buff);
     287                s/\0.*//s foreach @a;
     288                print $out "Application Extension: @a\n";
     289            }
     290            if ($buff eq 'XMP DataXMP') {   # XMP data (ref 2)
     291                my $hdr = "$ch$s$buff";
     292                # read XMP data
     293                my $xmp = '';
     294                for (;;) {
     295                    $raf->Read($ch, 1) or last Block;   # read next block header
     296                    $length = ord($ch) or last;         # get next block size
     297                    $raf->Read($buff, $length) == $length or last Block;
     298                    $xmp .= $ch . $buff;
     299                }
     300                # get length of XMP without landing zone data
     301                # (note that LZ data may not be exactly the same as what we use)
     302                my $xmpLen;
     303                if ($xmp =~ /<\?xpacket end=['"][wr]['"]\?>/g) {
     304                    $xmpLen = pos($xmp);
     305                } else {
     306                    $xmpLen = length($xmp);
     307                }
     308                my %dirInfo = (
     309                    DataPt  => \$xmp,
     310                    DataLen => length $xmp,
     311                    DirLen  => $xmpLen,
     312                    Parent  => 'GIF',
     313                );
     314                my $xmpTable = GetTagTable('Image::ExifTool::XMP::Main');
     315                if ($outfile) {
     316                    if ($doneDir{XMP} and $doneDir{XMP} > 1) {
     317                        $exifTool->Warn('Duplicate XMP block created');
     318                    }
     319                    my $newXMP = $exifTool->WriteDirectory(\%dirInfo, $xmpTable);
     320                    if (not defined $newXMP) {
     321                        Write($outfile, $hdr, $xmp) or $err = 1;  # write original XMP
     322                        $doneDir{XMP} = 1;
     323                    } elsif (length $newXMP) {
     324                        if ($newXMP =~ /\0/) { # (check just to be safe)
     325                            $exifTool->Error('XMP contained NULL character');
     326                        } else {
     327                            # write new XMP and landing zone
     328                            my $lz = pack('C*',1,reverse(0..255),0);
     329                            Write($outfile, $hdr, $newXMP, $lz) or $err = 1;
     330                        }
     331                        $doneDir{XMP} = 1;
     332                    } # else we are deleting the XMP
     333                } else {
     334                    $exifTool->ProcessDirectory(\%dirInfo, $xmpTable);
     335                }
     336                next;
     337            } elsif ($buff eq 'NETSCAPE2.0') {      # animated GIF extension (ref 3)
     338                $raf->Read($buff, 5) == 5 or last;
     339                # make sure this contains the expected data
     340                if ($buff =~ /^\x03\x01(..)\0$/) {
     341                    $exifTool->HandleTag($tagTablePtr, 'AnimationExtension', $buff);
     342                }
     343                $raf->Seek(-$length-5, 1) or last;  # seek back to start of block
     344            } else {
     345                $raf->Seek(-$length, 1) or last;
     346            }
     347
     348        } elsif ($a == 0xf9 and $length == 4) {     # graphic control extension
     349
     350            last unless $raf->Read($buff, $length) == $length;
     351            # sum the indivual delay times
     352            my $delay = Get16u(\$buff, 1);
     353            $delayTime += $delay;
     354            $verbose and printf $out "Graphic Control: delay=%.2f\n", $delay / 100;
     355            $raf->Seek(-$length, 1) or last;
     356
     357        } elsif ($a == 0x01 and $length == 12) {    # plain text extension
     358
     359            last unless $raf->Read($buff, $length) == $length;
     360            Write($outfile, $ch, $s, $buff) or $err = 1 if $outfile;
     361            if ($verbose) {
     362                my ($left, $top, $w, $h) = unpack('v4', $buff);
     363                print $out "Text: left=$left top=$top width=$w height=$h\n";
     364            }
     365            my $text = '';
     366            for (;;) {
     367                last unless $raf->Read($ch, 1);
     368                $length = ord($ch) or last;
     369                last unless $raf->Read($buff, $length) == $length;
     370                Write($outfile, $ch, $buff) or $err = 1 if $outfile; # write block
     371                $text .= $buff;
     372            }
     373            Write($outfile, "\0") or $err = 1 if $outfile;  # write terminator block
     374            $exifTool->HandleTag($tagTablePtr, 'Text', $text);
     375            next;
     376        }
     377        Write($outfile, $ch, $s) or $err = 1 if $outfile;
     378        # skip the block
     379        while ($length) {
     380            last unless $raf->Read($buff, $length) == $length;
     381            Write($outfile, $buff) or $err = 1 if $outfile;
     382            last unless $raf->Read($ch, 1);  # read next block header
     383            Write($outfile, $ch) or $err = 1 if $outfile;
     384            $length = ord($ch);  # get next block size
     385        }
     386    }
     387    unless ($outfile) {
     388        $exifTool->HandleTag($tagTablePtr, 'FrameCount', $frameCount) if $frameCount > 1;
     389        $exifTool->HandleTag($tagTablePtr, 'Duration', $delayTime/100) if $delayTime;
     390        # for historical reasons, the GIF Comment tag is in the Extra table
    176391        $exifTool->FoundTag('Comment', $comment) if $comment;
    177392    }
     393
    178394    # set return value to -1 if we only had a write error
    179395    $rtnVal = -1 if $rtnVal and $err;
     
    197413
    198414This module contains definitions required by Image::ExifTool to read and
    199 write GIF meta information.  GIF87a images contain no meta information, and
    200 only the Comment tag is currently supported in GIF89a images.
     415write GIF meta information.
    201416
    202417=head1 AUTHOR
    203418
    204 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     419Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    205420
    206421This library is free software; you can redistribute it and/or modify it
     
    213428=item L<http://www.w3.org/Graphics/GIF/spec-gif89a.txt>
    214429
     430=item L<http://www.adobe.com/devnet/xmp/>
     431
     432=item L<http://graphcomp.com/info/specs/ani_gif.html>
     433
    215434=back
    216435
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GPS.pm

    r16842 r24107  
    1313use Image::ExifTool::Exif;
    1414
    15 $VERSION = '1.17';
     15$VERSION = '1.34';
    1616
    1717my %coordConv = (
     
    2828    WRITABLE => 1,
    2929    WRITE_GROUP => 'GPS',
    30     NOTES => q{
    31         When adding GPS information to an image, it is important to set all of the
    32         following tags: GPSLatitude, GPSLatitudeRef, GPSLongitude, GPSLongitudeRef,
    33         GPSAltitude and GPSAltitudeRef.  ExifTool will write the required
    34         GPSVersionID tag automatically if new a GPS IFD is added to an image.
    35     },
    3630    0x0000 => {
    3731        Name => 'GPSVersionID',
    3832        Writable => 'int8u',
     33        Mandatory => 1,
    3934        Count => 4,
    4035        PrintConv => '$val =~ tr/ /./; $val',
     
    4641        Count => 2,
    4742        PrintConv => {
     43            # extract N/S if written from Composite:GPSLatitude
     44            # (also allow writing from a signed number)
     45            OTHER => sub {
     46                my ($val, $inv) = @_;
     47                return undef unless $inv;
     48                return uc $1 if $val =~ /\b([NS])$/i;
     49                return $1 eq '-' ? 'S' : 'N' if $val =~ /^([-+]?)\d+(\.\d*)?$/;
     50                return undef;
     51            },
    4852            N => 'North',
    4953            S => 'South',
     
    6165        Count => 2,
    6266        PrintConv => {
     67            # extract E/W if written from Composite:GPSLongitude
     68            # (also allow writing from a signed number)
     69            OTHER => sub {
     70                my ($val, $inv) = @_;
     71                return undef unless $inv;
     72                return uc $1 if $val =~ /\b([EW])$/i;
     73                return $1 eq '-' ? 'W' : 'E' if $val =~ /^([-+]?)\d+(\.\d*)?$/;
     74                return undef;
     75            },
    6376            E => 'East',
    6477            W => 'West',
     
    8295        Name => 'GPSAltitude',
    8396        Writable => 'rational64u',
    84         PrintConv => '$val eq "inf" ? $val : "$val m"',
     97        # extricate unsigned decimal number from string
     98        ValueConvInv => '$val=~/((?=\d|\.\d)\d*(?:\.\d*)?)/ ? $1 : undef',
     99        PrintConv => '$val =~ /^(inf|undef)$/ ? $val : "$val m"',
    85100        PrintConvInv => '$val=~s/\s*m$//;$val',
    86101    },
     
    91106        Count => 3,
    92107        Shift => 'Time',
    93         ValueConv => sub {
    94             my $val = shift;
    95             my ($h,$m,$s) = split ' ', $val;
    96             my $f = (($h || 0) * 60 + ($m || 0)) * 60 + ($s || 0);
    97             $h = int($f / 3600); $f -= $h * 3600;
    98             $m = int($f / 60);   $f -= $m * 60;
    99             $s = int($f);        $f -= $s;
    100             $f = int($f * 1000000 + 0.5);
    101             if ($f) {
    102                 ($f = sprintf(".%.6d", $f)) =~ s/0+$//;
    103             } else {
    104                 $f = ''
    105             }
    106             return sprintf("%.2d:%.2d:%.2d$f",$h,$m,$s);
    107         },
     108        Notes => q{
     109            when writing, date is stripped off if present, and time is adjusted to UTC
     110            if it includes a timezone
     111        },
     112        ValueConv => 'Image::ExifTool::GPS::ConvertTimeStamp($val)',
    108113        ValueConvInv => '$val=~tr/:/ /;$val',
    109114        # pull time out of any format date/time string
    110         # (eventually handle timezones? -- timestamp should be UTC)
     115        # (converting to UTC if a timezone is given)
    111116        PrintConvInv => sub {
    112117            my $v = shift;
    113             $v =~ s/[-+].*//s; # remove timezone
     118            my @tz;
     119            if ($v =~ s/([-+])(.*)//s) {    # remove timezone
     120                my $s = $1 eq '-' ? 1 : -1; # opposite sign to convert back to UTC
     121                my $t = $2;
     122                @tz = ($s*$1, $s*$2) if $t =~ /^(\d{2}):?(\d{2})\s*$/;
     123            }
    114124            my @a = ($v =~ /((?=\d|\.\d)\d*(?:\.\d*)?)/g);
    115125            push @a, '00' while @a < 3;
     126            if (@tz) {
     127                # adjust to UTC
     128                $a[-2] += $tz[1];
     129                $a[-3] += $tz[0];
     130                while ($a[-2] >= 60) { $a[-2] -= 60; ++$a[-3] }
     131                while ($a[-2] < 0)   { $a[-2] += 60; --$a[-3] }
     132                $a[-3] = ($a[-3] + 24) % 24;
     133            }
    116134            return "$a[-3]:$a[-2]:$a[-1]";
    117135        },
     
    126144        Count => 2,
    127145        PrintConv => {
    128             A => 'Measurement In Progress',
    129             V => 'Measurement Interoperability',
    130         },
    131     },
    132     0x000A => {
     146            A => 'Measurement Active', # Exif2.2 "Measurement in progress"
     147            V => 'Measurement Void',   # Exif2.2 "Measurement Interoperability" (WTF?)
     148            # (meaning for 'V' taken from status code in NMEA GLL and RMC sentences)
     149        },
     150    },
     151    0x000a => {
    133152        Name => 'GPSMeasureMode',
    134153        Writable => 'string',
     
    139158        },
    140159    },
    141     0x000B => {
     160    0x000b => {
    142161        Name => 'GPSDOP',
    143162        Description => 'GPS Dilution Of Precision',
    144163        Writable => 'rational64u',
    145164    },
    146     0x000C => {
     165    0x000c => {
    147166        Name => 'GPSSpeedRef',
    148167        Writable => 'string',
     
    154173        },
    155174    },
    156     0x000D => {
     175    0x000d => {
    157176        Name => 'GPSSpeed',
    158177        Writable => 'rational64u',
    159178    },
    160     0x000E => {
     179    0x000e => {
    161180        Name => 'GPSTrackRef',
    162181        Writable => 'string',
     
    167186        },
    168187    },
    169     0x000F => {
     188    0x000f => {
    170189        Name => 'GPSTrack',
    171190        Writable => 'rational64u',
     
    241260        },
    242261    },
    243     0x001A => {
     262    0x001a => {
    244263        Name => 'GPSDestDistance',
    245264        Writable => 'rational64u',
    246265    },
    247     0x001B => {
     266    0x001b => {
    248267        Name => 'GPSProcessingMethod',
    249268        Writable => 'undef',
    250         PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
    251         PrintConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
    252     },
    253     0x001C => {
     269        Notes => 'values of "GPS", "CELLID", "WLAN" or "MANUAL" by the EXIF spec.',
     270        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
     271        RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
     272    },
     273    0x001c => {
    254274        Name => 'GPSAreaInformation',
    255275        Writable => 'undef',
    256         PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
    257         PrintConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
    258     },
    259     0x001D => {
     276        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
     277        RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
     278    },
     279    0x001d => {
    260280        Name => 'GPSDateStamp',
    261281        Groups => { 2 => 'Time' },
    262282        Writable => 'string',
    263         Notes => 'YYYY:MM:DD',
     283        Notes => 'YYYY:mm:dd',
    264284        Count => 11,
    265285        Shift => 'Time',
     286        Notes => q{
     287            when writing, time is stripped off if present, after adjusting date/time to
     288            UTC if time includes a timezone
     289        },
    266290        ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
    267291        ValueConvInv => '$val',
    268292        # pull date out of any format date/time string
    269         PrintConvInv => '$val=~/(\d{4}).*?(\d{2}).*?(\d{2})/ ? "$1:$2:$3" : $val',
    270     },
    271     0x001E => {
     293        # (and adjust to UTC if this is a full date/time/timezone value)
     294        PrintConvInv => q{
     295            my $secs;
     296            if ($val =~ /[-+]/ and ($secs = Image::ExifTool::GetUnixTime($val, 1))) {
     297                $val = Image::ExifTool::ConvertUnixTime($secs);
     298            }
     299            return $val =~ /(\d{4}).*?(\d{2}).*?(\d{2})/ ? "$1:$2:$3" : undef;
     300        },
     301    },
     302    0x001e => {
    272303        Name => 'GPSDifferential',
    273304        Writable => 'int16u',
     
    277308        },
    278309    },
     310    0x001f => {
     311        Name => 'GPSHPositioningError',
     312        Description => 'GPS Horizontal Positioning Error',
     313        PrintConv => '"$val m"',
     314        PrintConvInv => '$val=~s/\s*m$//; $val',
     315        Writable => 'rational64u',
     316    },
    279317);
    280318
    281319# Composite GPS tags
    282320%Image::ExifTool::GPS::Composite = (
     321    GROUPS => { 2 => 'Location' },
    283322    GPSDateTime => {
    284323        Description => 'GPS Date/Time',
    285324        Groups => { 2 => 'Time' },
     325        SubDoc => 1,    # generate for all sub-documents
    286326        Require => {
    287             0 => 'GPSDateStamp',
    288             1 => 'GPSTimeStamp',
    289         },
    290         ValueConv => '"$val[0] $val[1]"',
     327            0 => 'GPS:GPSDateStamp',
     328            1 => 'GPS:GPSTimeStamp',
     329        },
     330        ValueConv => '"$val[0] $val[1]Z"',
    291331        PrintConv => '$self->ConvertDateTime($val)',
    292332    },
     333    # Note: The following tags are used by other modules
     334    # which must therefore require this module as necessary
    293335    GPSLatitude => {
     336        SubDoc => 1,    # generate for all sub-documents
    294337        Require => {
    295338            0 => 'GPS:GPSLatitude',
     
    300343    },
    301344    GPSLongitude => {
     345        SubDoc => 1,    # generate for all sub-documents
    302346        Require => {
    303347            0 => 'GPS:GPSLongitude',
     
    307351        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
    308352    },
     353    GPSAltitude => {
     354        SubDoc => 1,    # generate for all sub-documents
     355        Desire => {
     356            0 => 'GPS:GPSAltitude',
     357            1 => 'GPS:GPSAltitudeRef',
     358            2 => 'XMP:GPSAltitude',
     359            3 => 'XMP:GPSAltitudeRef',
     360        },
     361        # Require either GPS:GPSAltitudeRef or XMP:GPSAltitudeRef
     362        RawConv => '(defined $val[1] or defined $val[3]) ? $val : undef',
     363        ValueConv => q{
     364            my $alt = $val[0];
     365            $alt = $val[2] unless defined $alt;
     366            return undef unless defined $alt;
     367            return ($val[1] || $val[3]) ? -$alt : $alt;
     368        },
     369        PrintConv => q{
     370            $val = int($val * 10) / 10;
     371            return ($val =~ s/^-// ? "$val m Below" : "$val m Above") . " Sea Level";
     372        },
     373    },
    309374);
    310375
    311376# add our composite tags
    312377Image::ExifTool::AddCompositeTags('Image::ExifTool::GPS');
     378
     379#------------------------------------------------------------------------------
     380# Convert GPS timestamp value
     381# Inputs: 0) raw timestamp value string
     382# Returns: EXIF-formatted time string
     383sub ConvertTimeStamp($)
     384{
     385    my $val = shift;
     386    my ($h,$m,$s) = split ' ', $val;
     387    my $f = (($h || 0) * 60 + ($m || 0)) * 60 + ($s || 0);
     388    $h = int($f / 3600); $f -= $h * 3600;
     389    $m = int($f / 60);   $f -= $m * 60;
     390    $s = int($f);        $f -= $s;
     391    $f = int($f * 1000000 + 0.5);
     392    if ($f) {
     393        ($f = sprintf(".%.6d", $f)) =~ s/0+$//;
     394    } else {
     395        $f = ''
     396    }
     397    return sprintf("%.2d:%.2d:%.2d$f",$h,$m,$s);
     398}
    313399
    314400#------------------------------------------------------------------------------
     
    330416        $ref = " $ref" unless $doPrintConv and $doPrintConv eq '2';
    331417    } else {
     418        $val = abs($val);
    332419        $ref = '';
    333420    }
     
    364451{
    365452    my ($val, $doSign) = @_;
    366     # extract decimal values out of any other garbage
    367     my ($d, $m, $s) = ($val =~ /((?:[+-]?)(?=\d|\.\d)\d*(?:\.\d*)?)/g);
     453    # extract decimal or floating point values out of any other garbage
     454    my ($d, $m, $s) = ($val =~ /((?:[+-]?)(?=\d|\.\d)\d*(?:\.\d*)?(?:[Ee][+-]\d+)?)/g);
    368455    my $deg = ($d || 0) + (($m || 0) + ($s || 0)/60) / 60;
    369456    # make negative if S or W coordinate
     
    392479=head1 AUTHOR
    393480
    394 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     481Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    395482
    396483This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GeoTiff.pm

    r16842 r24107  
    44# Description:  Read GeoTiff meta information
    55#
    6 # Revisions:    02/23/04 - P. Harvey Created
    7 #               02/25/04 - P. Harvey Added new codes from libgeotiff-1.2.1
    8 #               02/01/07 - P. Harvey Added new codes from libgeotiff-1.2.3
     6# Revisions:    02/23/2004 - P. Harvey Created
     7#               02/25/2004 - P. Harvey Added new codes from libgeotiff-1.2.1
     8#               02/01/2007 - P. Harvey Added new codes from libgeotiff-1.2.3
    99#
    1010# Reference:    ftp://ftp.remotesensing.org/geotiff/libgeotiff/libgeotiff-1.1.4.tar.gz
     
    1515use strict;
    1616use vars qw($VERSION);
    17 use Image::ExifTool qw(:DataAccess);
    18 
    19 $VERSION = '1.06';
     17use Image::ExifTool qw(:DataAccess :Utils);
     18
     19$VERSION = '1.07';
    2020
    2121# format codes for geoTiff directory entries
     
    20652065
    20662066#------------------------------------------------------------------------------
    2067 # Inputs: 0) ExifTool object reference
    2068 #         1) tag table reference
     2067# Inputs: 0) ExifTool object ref
     2068# Notes: byte order must be set before calling this routine
    20692069sub ProcessGeoTiff($)
    20702070{
    2071     my ($exifTool) = @_;
     2071    my $exifTool = shift;
    20722072    my $dirData = $exifTool->GetValue('GeoTiffDirectory', 'ValueConv') or return;
    20732073    my $doubleData = $exifTool->GetValue('GeoTiffDoubleParams', 'ValueConv');
    20742074    my $asciiData = $exifTool->GetValue('GeoTiffAsciiParams', 'ValueConv');
    20752075    my $verbose = $exifTool->Options('Verbose');
    2076     my @double;
    20772076
    20782077    # restore or original EXIF byte order setting
    2079     my $byteOrder = $exifTool->{EXIF_BYTE_ORDER};
    2080     $byteOrder and SetByteOrder($byteOrder);
    20812078    if (length($$dirData) >= 8 and
    20822079        length($$dirData) >= 8 * (Get16u($dirData,6) + 1))
     
    20862083        my $minorRev   = Get16u($dirData,4);
    20872084        my $numEntries = Get16u($dirData,6);
    2088    
     2085
    20892086        if ($verbose) {
    20902087            $exifTool->{INDENT} .= '| ';
     
    20922089        }
    20932090        # generate version number tag (not a real GeoTiff tag)
    2094         my $tagTable = Image::ExifTool::GetTagTable("Image::ExifTool::GeoTiff::Main");
     2091        my $tagTable = GetTagTable("Image::ExifTool::GeoTiff::Main");
    20952092        my $tagInfo = $exifTool->GetTagInfo($tagTable, 1);
    20962093        $tagInfo and $exifTool->FoundTag($tagInfo,"$version.$revision.$minorRev");
    2097    
     2094
    20982095        my $i;
    20992096        for ($i=0; $i<$numEntries; ++$i) {
     
    21702167=head1 AUTHOR
    21712168
    2172 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     2169Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    21732170
    21742171This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HP.pm

    r16842 r24107  
    1313use Image::ExifTool qw(:DataAccess :Utils);
    1414
    15 $VERSION = '1.01';
     15$VERSION = '1.02';
    1616
    1717sub ProcessHP($$$);
     18sub ProcessTDHD($$$);
    1819
    1920# HP EXIF-format maker notes (or is it Vivitar?)
     
    2324        These tables list tags found in the maker notes of some Hewlett-Packard
    2425        camera models.
    25        
     26
    2627        The first table lists tags found in the EXIF-format maker notes of the
    2728        PhotoSmart 720 (also used by the Vivitar ViviCam 3705, 3705B and 3715).
     
    4344   'PreviewImage' => {
    4445        Name => 'PreviewImage',
    45         ValueConv => '$self->ValidateImage(\$val,$tag)',
     46        RawConv => '$self->ValidateImage(\$val,$tag)',
    4647    },
    4748   'Serial Number' => 'SerialNumber',
     
    110111    },
    111112);
     113
     114# proprietary format TDHD data written by Photosmart R837 (ref PH)
     115%Image::ExifTool::HP::TDHD = (
     116    PROCESS_PROC => \&ProcessTDHD,
     117    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     118    NOTES => q{
     119        These tags are extracted from the APP6 "TDHD" segment of Photosmart R837
     120        JPEG images.  Many other unknown tags exist in is data, and can be seen with
     121        the Unknown (-u) option.
     122    },
     123    # (all subdirectories except TDHD and LSLV are automatically recognized
     124    # by their "type" word of 0x10001)
     125    TDHD => {
     126        Name => 'TDHD',
     127        SubDirectory => { TagTable => 'Image::ExifTool::HP::TDHD' },
     128    },
     129    LSLV => {
     130        Name => 'LSLV',
     131        SubDirectory => { TagTable => 'Image::ExifTool::HP::TDHD' },
     132    },
     133    FWRV => 'FirmwareVersion',
     134    CMSN => 'SerialNumber', # (unverified)
     135    # LTEM - some temperature?
     136);
     137
     138#------------------------------------------------------------------------------
     139# Process HP APP6 TDHD metadata (ref PH)
     140# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     141# Returns: 1 on success
     142sub ProcessTDHD($$$)
     143{
     144    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     145    my $dataPt = $$dirInfo{DataPt};
     146    my $dataPos = $$dirInfo{DataPos};
     147    my $pos = $$dirInfo{DirStart};
     148    my $dirEnd = $pos + $$dirInfo{DirLen};
     149    my $unknown = $exifTool->Options('Unknown') || $exifTool->Options('Verbose');
     150    $exifTool->VerboseDir('TDHD', undef, $$dirInfo{DirLen});
     151    SetByteOrder('II');
     152    while ($pos + 12 < $dirEnd) {
     153        my $tag = substr($$dataPt, $pos, 4);
     154        my $type = Get32u($dataPt, $pos + 4);
     155        my $size = Get32u($dataPt, $pos + 8);
     156        $pos += 12;
     157        last if $size < 0 or $pos + $size > $dirEnd;
     158        if ($type == 0x10001) {
     159            # this is a subdirectory containing more tags
     160            my %dirInfo = (
     161                DataPt   => $dataPt,
     162                DataPos  => $dataPos,
     163                DirStart => $pos,
     164                DirLen   => $size,
     165            );
     166            $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
     167        } else {
     168            if (not $$tagTablePtr{$tag} and $unknown) {
     169                my $name = $tag;
     170                $name =~ tr/-_A-Za-z0-9//dc;    # remove invalid characters
     171                my %tagInfo = (
     172                    Name => "HP_TDHD_$name",
     173                    Unknown => 1,
     174                );
     175                # guess format based on data size
     176                if ($size == 1) {
     177                    $tagInfo{Format} = 'int8u';
     178                } elsif ($size == 2) {
     179                    $tagInfo{Format} = 'int16u';
     180                } elsif ($size == 4) {
     181                    $tagInfo{Format} = 'int32s';
     182                } elsif ($size > 80) {
     183                    $tagInfo{Binary} = 1;
     184                }
     185                Image::ExifTool::AddTagToTable($tagTablePtr, $tag, \%tagInfo);
     186            }
     187            $exifTool->HandleTag($tagTablePtr, $tag, undef,
     188                DataPt  => $dataPt,
     189                DataPos => $dataPos,
     190                Start   => $pos,
     191                Size    => $size,
     192            );
     193        }
     194        $pos += $size;
     195    }
     196    return 1;
     197}
    112198
    113199#------------------------------------------------------------------------------
     
    164250=head1 AUTHOR
    165251
    166 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     252Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    167253
    168254This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HTML.pm

    r16842 r24107  
    2121require Exporter;
    2222
    23 $VERSION = '1.03';
     23$VERSION = '1.11';
    2424@ISA = qw(Exporter);
    2525@EXPORT_OK = qw(EscapeHTML UnescapeHTML);
     26
     27sub SetHTMLCharset($$);
     28
     29# convert HTML charset (lower case) to ExifTool Charset name
     30my %htmlCharset = (
     31    macintosh     => 'MacRoman',
     32   'iso-8859-1'   => 'Latin',
     33   'utf-8'        => 'UTF8',
     34   'windows-1252' => 'Latin',
     35);
    2636
    2737# HTML 4 character entity references
     
    121131    NOTES => q{
    122132        Meta information extracted from the header of HTML and XHTML files.  This is
    123         a mix of information found in the C<META> elements and the C<TITLE> element.
     133        a mix of information found in the C<META> elements, C<XML> element, and the
     134        C<TITLE> element.
    124135    },
    125136    dc => {
     
    142153        Name => 'HTTP-equiv',
    143154        SubDirectory => { TagTable => 'Image::ExifTool::HTML::equiv' },
     155    },
     156    o => {
     157        Name => 'Office',
     158        SubDirectory => { TagTable => 'Image::ExifTool::HTML::Office' },
    144159    },
    145160    abstract        => { },
     
    157172    keywords        => { List => 1 },
    158173    mssmarttagspreventparsing => { Name => 'NoMSSmartTags' },
     174    originator      => { },
    159175    owner           => { },
    160176    progid          => { Name => 'ProgID' },
     
    195211%Image::ExifTool::HTML::ncc = (
    196212    GROUPS => { 1 => 'HTML-ncc', 2 => 'Document' },
    197     charset         => { },
     213    charset         => { Name => 'CharacterSet' }, # name changed to avoid conflict with -charset option
    198214    depth           => { },
    199215    files           => { },
     
    209225    prodnotes       => { Name => 'ProdNotes' },
    210226    producer        => { },
    211     produceddate    => { Name => 'ProducedDate', Groups => { 2 => 'Time' } }, # yyyy-mm-dd
     227    produceddate    => { Name => 'ProducedDate', Groups => { 2 => 'Time' } }, # YYYY-mm-dd
    212228    revision        => { },
    213229    revisiondate    => { Name => 'RevisionDate', Groups => { 2 => 'Time' } },
     
    220236    sourcetitle     => { Name => 'SourceTitle' },
    221237    tocitems        => { Name => 'TOCItems' },
    222     totaltime       => { Name => 'Duration' }, # hh:mm:ss
     238    totaltime       => { Name => 'Duration' }, # HH:MM:SS
    223239);
    224240
     
    245261   'content-script-type' => { Name => 'ContentScriptType' },
    246262   'content-style-type'  => { Name => 'ContentStyleType' },
    247    'content-type'        => { Name => 'ContentType' },
     263    # note: setting the HTMLCharset like this will miss any tags which come earlier
     264   'content-type'        => { Name => 'ContentType', RawConv => \&SetHTMLCharset },
    248265   'default-style'       => { Name => 'DefaultStyle' },
    249266    expires              => { },
     
    264281);
    265282
     283# MS Office namespace (ref PH)
     284%Image::ExifTool::HTML::Office = (
     285    GROUPS => { 1 => 'HTML-office', 2 => 'Document' },
     286    NOTES => 'Tags written by Microsoft Office applications.',
     287    Subject     => { },
     288    Author      => { Groups => { 2 => 'Author' } },
     289    Keywords    => { },
     290    Description => { },
     291    Template    => { },
     292    LastAuthor  => { Groups => { 2 => 'Author' } },
     293    Revision    => { Name => 'RevisionNumber' },
     294    TotalTime   => { Name => 'TotalEditTime',   PrintConv => 'ConvertTimeSpan($val, 60)' },
     295    Created     => {
     296        Name => 'CreateDate',
     297        Groups => { 2 => 'Time' },
     298        ValueConv => 'Image::ExifTool::XMP::ConvertXMPDate($val)',
     299        PrintConv => '$self->ConvertDateTime($val)',
     300    },
     301    LastSaved   => {
     302        Name => 'ModifyDate',
     303        Groups => { 2 => 'Time' },
     304        ValueConv => 'Image::ExifTool::XMP::ConvertXMPDate($val)',
     305        PrintConv => '$self->ConvertDateTime($val)',
     306    },
     307    LastSaved   => {
     308        Name => 'ModifyDate',
     309        Groups => { 2 => 'Time' },
     310        ValueConv => 'Image::ExifTool::XMP::ConvertXMPDate($val)',
     311        PrintConv => '$self->ConvertDateTime($val)',
     312    },
     313    LastPrinted => {
     314        Name => 'LastPrinted',
     315        Groups => { 2 => 'Time' },
     316        ValueConv => 'Image::ExifTool::XMP::ConvertXMPDate($val)',
     317        PrintConv => '$self->ConvertDateTime($val)',
     318    },
     319    Pages       => { },
     320    Words       => { },
     321    Characters  => { },
     322    Category    => { },
     323    Manager     => { },
     324    Company     => { },
     325    Lines       => { },
     326    Paragraphs  => { },
     327    CharactersWithSpaces => { },
     328    Version     => { Name => 'RevisionNumber' },
     329);
     330
     331#------------------------------------------------------------------------------
     332# Set HTMLCharset member based on content type
     333# Inputs: 0) content type string, 1) ExifTool ref
     334# Returns: original string
     335sub SetHTMLCharset($$)
     336{
     337    my ($val, $exifTool) = @_;
     338    $$exifTool{HTMLCharset} = $htmlCharset{lc $1} if $val =~ /charset=['"]?([-\w]+)/;
     339    return $val;
     340}
     341
    266342#------------------------------------------------------------------------------
    267343# Convert single UTF-8 character to HTML character reference
    268344# Inputs: 0) UTF-8 character sequence
    269 # Returns: HML character reference (ie. "&quot;");
     345# Returns: HTML character reference (ie. "&quot;");
    270346# Note: Must be called via EscapeHTML to load name lookup
    271347sub EscapeChar($)
    272348{
    273349    my $ch = shift;
    274     my ($val) = ($] >= 5.006001) ? unpack('U0U',$ch) : UnpackUTF8($ch);
     350    my $val;
     351    if ($] < 5.006001) {
     352        ($val) = Image::ExifTool::UnpackUTF8($ch);
     353    } else {
     354        # the meaning of "U0" is reversed as of Perl 5.10.0!
     355        ($val) = unpack($] < 5.010000 ? 'U0U' : 'C0U', $ch);
     356    }
    275357    return '?' unless defined $val;
    276358    return "&$entityName{$val};" if $entityName{$val};
     
    297379            delete $entityName{39};  # 'apos' is not valid HTML
    298380        }
    299         # supress warnings
     381        # suppress warnings
    300382        local $SIG{'__WARN__'} = sub { 1 };
    301383        # escape any non-ascii characters for HTML
     
    322404    my ($exifTool, $dirInfo) = @_;
    323405    my $raf = $$dirInfo{RAF};
    324     my $verbose = $exifTool->Options('Verbose');
    325     my ($buff, $err);
     406    my $buff;
    326407
    327408    # validate HTML or XHTML file
    328409    $raf->Read($buff, 256) or return 0;
    329     $buff =~ /^<(!DOCTYPE HTML|HTML|\?xml)/i or return 0;
    330     $buff =~ /<(!DOCTYPE )?HTML/i or return 0 if $1 eq '?xml';
     410    $buff =~ /^<(!DOCTYPE\s+HTML|HTML|\?xml)/i or return 0;
     411    $buff =~ /<(!DOCTYPE\s+)?HTML/i or return 0 if $1 eq '?xml';
    331412    $exifTool->SetFileType();
    332413
    333414    $raf->Seek(0,0) or $exifTool->Warn('Seek error'), return 1;
    334415
    335     my $oldsep = Image::ExifTool::PostScript::SetInputRecordSeparator($raf);
    336     $oldsep or $exifTool->Warn('Invalid HTML data'), return 1;
     416    local $/ = Image::ExifTool::PostScript::GetInputRecordSeparator($raf);
     417    $/ or $exifTool->Warn('Invalid HTML data'), return 1;
    337418
    338419    # extract header information
     
    348429        last if $buff =~ m{</head>}i;
    349430    }
     431    return 1 unless defined $doc;
    350432
    351433    # process all elements in header
     
    371453        }
    372454        my $table = $tagTablePtr;
    373         # parse HTML META element
    374455        if ($tag eq 'meta') {
     456            # parse HTML META element
    375457            undef $tag;
    376458            # tag name is in NAME or HTTP-EQUIV attribute
     
    396478                }
    397479            }
     480        } elsif ($tag eq 'xml') {
     481            $exifTool->VPrint(0, "Parsing XML\n");
     482            # parse XML tags (quick-and-dirty)
     483            my $xml = $val;
     484            while ($xml =~ /<([\w-]+):([\w-]+)(\s.*?)?>([^<]*?)<\/\1:\2>/g) {
     485                ($grp, $tag, $val) = ($1, $2, $4);
     486                my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $grp);
     487                next unless $tagInfo and $$tagInfo{SubDirectory};
     488                $table = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
     489                unless ($$table{$tag}) {
     490                    my $name = ucfirst $tag;
     491                    $name =~ s/_x([0-9a-f]{4})_/chr(hex($1))/gie; # convert hex codes
     492                    $name =~ s/\s(.)/\U$1/g;     # capitalize all words in tag name
     493                    $name =~ tr/-_a-zA-Z0-9//dc; # remove illegal characters (also hex code wide chars)
     494                    Image::ExifTool::AddTagToTable($table, $tag, { Name => $name });
     495                    $exifTool->VPrint(0, "  [adding $tag '$name']\n");
     496                }
     497                $val = $exifTool->Decode($val, $$exifTool{HTMLCharset}) if $$exifTool{HTMLCharset};
     498                $exifTool->HandleTag($table, $tag, UnescapeXML($val));
     499            }
     500            next;
    398501        } else {
    399             # the only non-META element we process is TITLE
     502            # the only other element we process is TITLE
    400503            next unless $tag eq 'title';
    401504        }
     
    408511            $exifTool->VPrint(0, "  [adding $tag '$tagName']\n");
    409512        }
     513        # recode if necessary
     514        $val = $exifTool->Decode($val, $$exifTool{HTMLCharset}) if $$exifTool{HTMLCharset};
    410515        $val =~ s{\s*$/\s*}{ }sg;   # replace linefeeds and indenting spaces
    411516        $val = UnescapeHTML($val);  # unescape HTML character references
    412517        $exifTool->HandleTag($table, $tag, $val);
    413518    }
    414     $/ = $oldsep;   # restore original separator
    415519    return 1;
    416520}
     
    435539=head1 AUTHOR
    436540
    437 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     541Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    438542
    439543This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HtmlDump.pm

    r16842 r24107  
    1212use vars qw($VERSION);
    1313use Image::ExifTool;    # only for FinishTiffDump()
    14 
    15 $VERSION = '1.17';
    16 
    17 sub DumpTable($$$;$$$$);
     14use Image::ExifTool::HTML qw(EscapeHTML);
     15
     16$VERSION = '1.30';
     17
     18sub DumpTable($$$;$$$$$);
    1819sub Open($$$;@);
    1920sub Write($@);
    2021
    21 my ($bkgStart, $bkgEnd, $bkgSpan);
     22my ($bkgStart, $bkgEnd, @bkgSpan);
    2223
    2324my $htmlHeader1 = <<_END_PART_1_;
     
    4445.F { color: #aa00dd } /* actual offset differs */
    4546.M { text-decoration: underline } /* maker notes data */
     47.tt { /* tooltip text */
     48    visibility: hidden;
     49    position: absolute;
     50    white-space: nowrap;
     51    top: 0;
     52    left: 0;
     53    font-family: Verdana, sans-serif;
     54    font-size: .7em;
     55    padding: 2px 4px;
     56    border: 1px solid gray;
     57    z-index: 3;
     58}
     59.tb { /* tooltip background */
     60    visibility: hidden;
     61    position: absolute;
     62    background: #ffffdd;
     63    opacity: 0.8;
     64    -moz-opacity: 0.8;
     65    filter: alpha(opacity=80);
     66    -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)';
     67    z-index: 2;
     68}
    4669/* table styles */
    4770table.dump {
     
    6184<script language="JavaScript" type="text/JavaScript">
    6285<!-- Begin
    63 var t = new Array;
     86// tooltip positioning constants
     87var TMAR = 4;   // top/left margins
     88var BMAR = 16;  // bottom/right margins (scrollbars may overhang inner dimensions)
     89var XOFF = 10;  // x offset from cursor
     90var YOFF = 40;  // y offset
     91var YMIN = 10;  // minimum y offset
     92var YTOP = 20;  // y offset when above cursor
     93// common variables
     94var safari1 = navigator.userAgent.indexOf("Safari/312.6") >= 0;
     95var ie6 = navigator.userAgent.toLowerCase().indexOf('msie 6') >= 0;
    6496var mspan = new Array;
     97var hlist, tt, tb;
     98
    6599function GetElementsByClass(classname, tagname) {
    66100  var found = new Array();
     
    79113  return found;
    80114}
     115
     116// move tooltip
     117function move(e)
     118{
     119  if (!tt) return;
     120  if (ie6 && (tt.style.top  == '' || tt.style.top  == 0) &&
     121             (tt.style.left == '' || tt.style.left == 0))
     122  {
     123    tt.style.width  = tt.offsetWidth  + 'px';
     124    tt.style.height = tt.offsetHeight + 'px';
     125  }
     126  var w, h;
     127  // browser inconsistencies make getting window size more complex than it should be,
     128  // and even then we don't know if it is smaller due to scrollbar width
     129  if (typeof(window.innerWidth) == 'number') {
     130    w = window.innerWidth;
     131    h = window.innerHeight;
     132  } else if (document.documentElement && document.documentElement.clientWidth) {
     133    w = document.documentElement.clientWidth;
     134    h = document.documentElement.clientHeight;
     135  } else {
     136    w = document.body.clientWidth;
     137    h = document.body.clientHeight;
     138  }
     139  var x = e.clientX + XOFF;
     140  var y = e.clientY + YOFF;
     141  if (safari1) { // patch for people still using OS X 10.3.9
     142    x -= document.body.scrollLeft + document.documentElement.scrollLeft;
     143    y -= document.body.scrollTop  + document.documentElement.scrollTop;
     144  }
     145  var mx = w - BMAR - tt.offsetWidth;
     146  var my = h - BMAR - tt.offsetHeight;
     147  if (y > my + YOFF - YMIN) y = e.clientY - YTOP - tt.offsetHeight;
     148  if (x > mx) x = mx;
     149  if (y > my) y = my;
     150  if (x < TMAR) x = TMAR;
     151  if (y < TMAR) y = TMAR;
     152  x += document.body.scrollLeft + document.documentElement.scrollLeft;
     153  y += document.body.scrollTop  + document.documentElement.scrollTop;
     154  tb.style.width  = tt.offsetWidth  + 'px';
     155  tb.style.height = tt.offsetHeight + 'px';
     156  tt.style.top  = tb.style.top  = y + 'px';
     157  tt.style.left = tb.style.left = x + 'px';
     158  tt.style.visibility = tb.style.visibility = 'visible';
     159}
     160
     161// highlight/unhighlight text
    81162function high(e,on) {
    82163  var targ;
     
    86167  if (!targ.name) targ = targ.parentNode; // go up another level if necessary
    87168  if (targ.name && document.getElementsByName) {
    88     var col;
    89     var tip;
     169    // un-highlight current objects
     170    if (hlist) {
     171      for (var i=0; i<hlist.length; ++i) {
     172        hlist[i].style.background = 'transparent';
     173      }
     174      hlist = null;
     175    }
     176    if (tt) {
     177      // hide old tooltip
     178      tt.style.visibility = tb.style.visibility = 'hidden';
     179      tt = null;
     180    }
    90181    if (on) {
    91       col = "#ffcc99";
    92182      if (targ.name.substring(0,1) == 't') {
    93         var index = parseInt(targ.name.substring(1));
    94         tip = t[index];
    95         if (tip) delete t[index];
     183        // show our tooltip (ID is different than name to avoid confusing IE)
     184        tt = document.getElementById('p' + targ.name.substring(1));
     185        if (tt) {
     186          tb = document.getElementById('tb');
     187          move(e);
     188        }
    96189      }
    97     } else {
    98       col = "transparent";
    99     }
    100     // highlight anchor elements with the same name and add tool tip
    101     var list = document.getElementsByName(targ.name);
    102     for (var i=0; i<list.length; ++i) {
    103       list[i].style.background = col;
    104       if (tip) list[i].title += tip;
    105     }
    106     // use class name to highlight span elements if necessary
    107     for (var i=0; i<mspan.length; ++i) {
    108       if (mspan[i] != targ.name) continue;
    109       list = GetElementsByClass(targ.name, 'span');
    110       for (var j=0; j<list.length; ++j) {
    111         list[j].style.background = col;
     190      // highlight anchor elements with the same name
     191      hlist = document.getElementsByName(targ.name);
     192      // use class name to highlight span elements if necessary
     193      for (var i=0; i<mspan.length; ++i) {
     194        if (mspan[i] != targ.name) continue;
     195        var slist = GetElementsByClass(targ.name, 'span');
     196        // add elements from hlist collection to our array
     197        for (var j=0; j<hlist.length; ++j) {
     198            slist[slist.length] = hlist[j];
     199        }
     200        hlist = slist;
     201        break;
    112202      }
    113       break;
     203      for (var j=0; j<hlist.length; ++j) {
     204        hlist[j].style.background = '#ffcc99';
     205      }
    114206    }
    115207  }
     
    122214<body><noscript><b class=V>--&gt;
    123215Enable JavaScript for active highlighting and information tool tips!
    124 </b></noscript><table class=dump cellspacing=0 cellpadding=2>
     216</b></noscript>
     217<table class=dump cellspacing=0 cellpadding=2>
    125218<tr><td valign='top'><pre>];
    126219
    127 my $preMouse = q(<pre onmouseover="high(event,1)" onmouseout="high(event,0)">);
     220my $preMouse = q(<pre onmouseover="high(event,1)" onmouseout="high(event,0)" onmousemove="move(event)">);
    128221
    129222#------------------------------------------------------------------------------
     
    142235# Inputs: 0) HTML dump hash ref, 1) absolute offset in file, 2) data size,
    143236#         3) comment string, 4) tool tip (or SAME to use previous tip),
    144 #         5) bit flags (see below), 6) true to use same tooltip as last call
     237#         5) bit flags (see below)
    145238# Bits: 0x01 - print at start of line
    146239#       0x02 - print red address
    147240#       0x04 - maker notes data ('M'-class span)
    148241#       0x08 - limit block length
     242#       0x10 - allow double references
     243#       0x100 - (reserved)
    149244# Notes: Block will be shown in 'unused' color if comment string begins with '['
    150 sub Add($$$$;$$)
     245sub Add($$$$;$)
    151246{
    152     my ($self, $start, $size, $msg, $tip, $flag, $sameTip) = @_;
     247    my ($self, $start, $size, $msg, $tip, $flag) = @_;
    153248    my $block = $$self{Block};
    154249    $$block{$start} or $$block{$start} = [ ];
     250    my $htip;
    155251    if ($tip and $tip eq 'SAME') {
    156         $tip = '';
     252        $htip = '';
    157253    } else {
    158         $tip = defined $tip ? '\n' . $tip : '';
    159         my $m = $msg;
    160         $m =~ s/<.*?>//g;       # remove html format codes
    161         $tip = "$m$tip";        # add msg as first line in tooltip
     254        # use message as first line of tip, and make bold unless in brackets
     255        $htip = ($msg =~ /^[[(]/) ? $msg : "<b>$msg</b>";
     256        if (defined $tip) {
     257            ($tip = EscapeHTML($tip)) =~ s/\n/<br>/g;   # HTML-ize tooltip text
     258            $htip .= '<br>' . $tip;
     259        }
    162260        # add size if not already done
    163         $tip .= "\\n($size bytes)" unless $tip =~ /\\nSize:/;
     261        $htip .= "<br>($size bytes)" unless $htip =~ /<br>Size:/;
    164262        ++$self->{TipNum};
    165263    }
    166     push @{$$block{$start}}, [ $size, $msg, $tip, $flag, $self->{TipNum} ];
     264    push @{$$block{$start}}, [ $size, $msg, $htip, $flag, $self->{TipNum} ];
    167265}
    168266
     
    172270#         2) data pointer, 3) data position, 4) output file or scalar reference,
    173271#         5) limit level (1-3), 6) title
    174 # Returns: non-zero if useful output was generated
     272# Returns: non-zero if useful output was generated,
     273#          or -1 on error loading data and "ERROR" is set to offending data name
     274# Note: The "Error" member may be set externally to print a specific error
     275#       message instead of doing the dump.
    175276sub Print($$;$$$$$)
    176277{
    177278    local $_;
    178279    my ($self, $raf, $dataPt, $dataPos, $outfile, $level, $title) = @_;
    179     my ($i, $buff, $rtnVal);
     280    my ($i, $buff, $rtnVal, $limit, $err);
    180281    my $block = $$self{Block};
    181282    $dataPos = 0 unless $dataPos;
     
    184285    $level or $level = 0;
    185286    my $tell = $raf->Tell();
    186     my @starts = sort { $a <=> $b } keys %$block;
    187287    my $pos = 0;
    188288    my $dataEnd = $dataPos + ($dataPt ? length($$dataPt) : 0);
     
    195295    # set dump size limits (limits are 4x smaller if bit 0x08 set in flags)
    196296    if ($level <= 1) {
    197         $$self{Limit} = 1024;
     297        $limit = 1024;
    198298    } elsif ($level <= 2) {
    199         $$self{Limit} = 16384;
     299        $limit = 16384;
    200300    } else {
    201         delete $$self{Limit};   # no limit
    202     }
     301        $limit = 256 * 1024 * 1024; # never dump bigger than 256 MB
     302    }
     303    $$self{Limit} = $limit;
    203304    # pre-initialize open/closed hashes for all columns
    204305    for ($i=0; $i<4; ++$i) {
     
    207308    }
    208309    $bkgStart = $bkgEnd = 0;
    209     $bkgSpan = '';
     310    undef @bkgSpan;
    210311    my $index = 0;  # initialize tooltip index
    211     my @names;
     312    my (@names, $wasUnused, @starts);
     313    # only do dump if we didn't have a serious error
     314    @starts = sort { $a <=> $b } keys %$block unless $$self{Error};
    212315    for ($i=0; $i<@starts; ++$i) {
    213316        my $start = $starts[$i];
    214         my $bytes = $start - $pos;
    215         if ($bytes > 0) {
    216             if ($pos >= $dataPos and $pos + $bytes <= $dataEnd) {
    217                 $buff = substr($$dataPt, $pos-$dataPos, $bytes);
     317        my $parmList = $$block{$start};
     318        my $len = $start - $pos;
     319        if ($len > 0 and not $wasUnused) {
     320            # we have an unused bytes before this data block
     321            --$i;           # dump the data block next time around
     322            # split unused data into 2 blocks if it spans end of a bkg block
     323            my ($nextBkgEnd, $bkg);
     324            if (not defined $wasUnused and $bkgEnd) {
     325                foreach $bkg (@bkgSpan) {
     326                    next if $pos >= $$bkg{End} + $dataPos or $pos + $len <= $$bkg{End} + $dataPos;
     327                    $nextBkgEnd = $$bkg{End} unless $nextBkgEnd and $nextBkgEnd < $$bkg{End};
     328                }
     329            }
     330            if ($nextBkgEnd) {
     331                $start = $pos;
     332                $len = $nextBkgEnd + $dataPos - $pos;
     333                $wasUnused = 0;
    218334            } else {
    219                 $buff = '';
    220                 $raf->Seek($pos, 0) and $raf->Read($buff, $bytes);
    221             }
    222             if (length $buff) {
    223                 my $str = ($bytes > 1) ? "unused $bytes bytes" : 'pad byte';
    224                 $self->DumpTable($pos-$dataPos, \$buff, "[$str]", "t$index", 0x108);
    225                 ++$index;
    226             }
    227             $pos = $start;  # dumped unused data up to the start of this block
     335                $start = $pos;  # dump the unused bytes now
     336                $wasUnused = 1; # avoid re-dumping unused bytes if we get a read error
     337            }
     338            my $str = ($len > 1) ? "unused $len bytes" : 'pad byte';
     339            $parmList = [ [ $len, "[$str]", undef, 0x108 ] ];
     340        } else {
     341            undef $wasUnused;
    228342        }
    229343        my $parms;
    230         my $parmList = $$block{$start};
    231344        foreach $parms (@$parmList) {
    232345            my ($len, $msg, $tip, $flag, $tipNum) = @$parms;
     
    234347            $flag = 0 unless defined $flag;
    235348            # generate same name for all blocks indexed by this tooltip
    236             my $name = $names[$tipNum];
     349            my $name;
     350            $name = $names[$tipNum] if defined $tipNum;
    237351            my $idx = $index;
    238352            if ($name) {
     
    240354                $idx = substr($name, 1);
    241355            } else {
    242                 $name = $names[$tipNum] = "t$index";
     356                $name = "t$index";
     357                $names[$tipNum] = $name if defined $tipNum;
    243358                ++$index;
    244359            }
    245             if ($flag == 4) {
    246                 $bkgStart = $start - $dataPos;
    247                 $bkgEnd = $bkgStart + $len;
    248                 $bkgSpan = "<span class='$name M'>";
     360            if ($flag & 0x14) {
     361                my %bkg = (
     362                    Class => $flag & 0x04 ? "$name M" : $name,
     363                    Start => $start - $dataPos,
     364                    End   => $start - $dataPos + $len,
     365                );
     366                push @bkgSpan, \%bkg;
     367                $bkgStart = $bkg{Start} unless $bkgStart and $bkgStart < $bkg{Start};
     368                $bkgEnd = $bkg{End} unless $bkgEnd and $bkgEnd > $bkg{End};
    249369                push @{$self->{MSpanList}}, $name;
    250370                next;
    251371            }
     372            # loop until we read the value properly
     373            my ($end, $try);
     374            for ($try=0; $try<2; ++$try) {
     375                $end = $start + $len;
     376                # only load as much of the block as we are going to dump
     377                my $size = ($len > $limit) ? $limit / 2 : $len;
     378                if ($start >= $dataPos and $end <= $dataEnd) {
     379                    $buff = substr($$dataPt, $start-$dataPos, $size);
     380                    if ($len != $size) {
     381                        $buff .= substr($$dataPt, $start-$dataPos+$len-$size, $size);
     382                    }
     383                } else {
     384                    $buff = '';
     385                    if ($raf->Seek($start, 0) and $raf->Read($buff, $size) == $size) {
     386                        # read end of block
     387                        if ($len != $size) {
     388                            my $buf2 = '';
     389                            unless ($raf->Seek($start+$len-$size, 0) and
     390                                    $raf->Read($buf2, $size) == $size)
     391                            {
     392                                $err = $msg;
     393                                # reset $len to the actual length of available data
     394                                $raf->Seek(0, 2);
     395                                $len = $raf->Tell() - $start;
     396                                $tip .= "<br>Error: Only $len bytes available!" if $tip;
     397                                next;
     398                            }
     399                            $buff .= $buf2;
     400                            undef $buf2;
     401                        }
     402                    } else {
     403                        $err = $msg;
     404                        $len = length $buff;
     405                        $tip .= "<br>Error: Only $len bytes available!" if $tip;
     406                    }
     407                }
     408                last;
     409            }
    252410            $tip and $self->{TipList}->[$idx] = $tip;
    253             my $end = $start + $len;
    254             if ($start >= $dataPos and $end <= $dataEnd) {
    255                 $buff = substr($$dataPt, $start-$dataPos, $len);
    256             } else {
    257                 $buff = '';
    258                 $raf->Seek($start, 0) and $raf->Read($buff, $len);
    259             }
    260411            next unless length $buff;
    261412            # set flag to continue this line if next block is contiguous
     
    267418            }
    268419            $self->DumpTable($start-$dataPos, \$buff, $msg, $name,
    269                              $flag, $pos-$dataPos);
     420                             $flag, $len, $pos-$dataPos);
     421            undef $buff;
    270422            $pos = $end if $pos < $end;
    271423        }
     
    282434            Write($outfile, qq(mspan[$i] = "$$mspan[$i]";\n));
    283435        }
    284         my $tips = \@{$$self{TipList}};
    285         for ($i=0; $i<@$tips; ++$i) {
    286             Write($outfile, qq(t[$i] = "$$tips[$i]";\n)) if defined $$tips[$i];
    287         }
    288         delete $$self{TipList};
    289436        Write($outfile, $htmlHeader3, $self->{Cols}->[0]);
    290437        Write($outfile, '</pre></td><td valign="top">',
     
    294441        Write($outfile, '</pre></td><td valign="top">',
    295442                        $preMouse, $self->{Cols}->[3]);
    296         Write($outfile, "</pre></td></tr></table>\n");
     443        Write($outfile, "</pre></td></tr></table>\n<div id=tb class=tb> </div>\n");
     444        my $tips = \@{$$self{TipList}};
     445        for ($i=0; $i<@$tips; ++$i) {
     446            my $tip = $$tips[$i];
     447            Write($outfile, "<div id=p$i class=tt>$tip</div>\n") if defined $tip;
     448        }
     449        delete $$self{TipList};
    297450        $rtnVal = 1;
    298451    } else {
    299         Write($outfile, "$title</title></head><body>\n",
    300                         "No EXIF or TIFF information found in image\n");
     452        my $err = $$self{Error} || 'No EXIF or TIFF information found in image';
     453        Write($outfile, "$title</title></head><body>\n$err\n");
     454        $rtnVal = 0;
    301455    }
    302456    Write($outfile, "</body></html>\n");
    303457    for ($i=0; $i<4; ++$i) {
    304458        $self->{Cols}->[$i] = '';   # free memory
     459    }
     460    if ($err) {
     461        $err =~ tr/()//d;
     462        $$self{ERROR} = $err;
     463        return -1;
    305464    }
    306465    return $rtnVal;
     
    388547# Dump a block of data in HTML table form
    389548# Inputs: 0) HtmlDump object ref, 1) data position, 2) block pointer,
    390 #         3) message, 4) object name, 5) flag, 6) data end position
    391 sub DumpTable($$$;$$$$)
     549#         3) message, 4) object name, 5) flag, 6) full block length (actual
     550#         data may be shorter), 7) data end position
     551sub DumpTable($$$;$$$$$)
    392552{
    393     my ($self, $pos, $blockPt, $msg, $name, $flag, $endPos) = @_;
    394     my $len = length $$blockPt;
     553    my ($self, $pos, $blockPt, $msg, $name, $flag, $len, $endPos) = @_;
     554    $len = length $$blockPt unless defined $len;
    395555    $endPos = 0 unless $endPos;
    396556    my ($f0, $dblRef, $id);
     557    my $skipped = 0;
    397558    if (($endPos and $pos < $endPos) or $flag & 0x02) {
    398559        # display double-reference addresses in red
     
    417578            ++$id unless $dblRef;
    418579        }
    419         $name = qq{<a name=$name class=$id>};
     580        $name = "<a name=$name class=$id>";
    420581        $msg and $msg = "$name$msg</a>";
    421582    } else {
     
    446607    # loop through each column of hex numbers
    447608    for (;;) {
    448         $self->Open('bkg', ($p>=$bkgStart and $p<$bkgEnd) ? $bkgSpan : '', 1, 2);
     609        my (@spanClass, @spanCont, $spanClose, $bkg);
     610        if ($p >= $bkgStart and $p < $bkgEnd) {
     611            foreach $bkg (@bkgSpan) {
     612                next unless $p >= $$bkg{Start} and $p < $$bkg{End};
     613                push @spanClass, $$bkg{Class};
     614                if ($p + 1 == $$bkg{End}) {
     615                    $spanClose = 1;
     616                } else {
     617                    push @spanCont, $$bkg{Class};   # this span continues
     618                }
     619            }
     620            $self->Open('bkg', @spanClass ? "<span class='@spanClass'>" : '', 1, 2);
     621        } else {
     622            $self->Open('bkg', '', 1, 2);
     623        }
    449624        $self->Open('a', $name, 1, 2);
    450         my $ch = substr($$blockPt,$p-$pos,1);
     625        my $ch = substr($$blockPt,$p-$pos-$skipped,1);
    451626        $c[1] .= sprintf("%.2x", ord($ch));
    452627        # make the character HTML-friendly
     
    459634        ++$cols;
    460635        # close necessary elements
    461         if ($p >= $bkgEnd) {
     636        if ($spanClose) {
     637            my $spanCont = @spanCont ? "<span class='@spanCont'>" : '';
    462638            # close without reopening if closing anchor later
    463             my $arg = ($p - $pos >= $len) ? 0 : '';
     639            my $arg = ($p - $pos >= $len) ? 0 : $spanCont;
    464640            $self->Open('bkg', $arg, 1, 2);
    465641        }
     
    496672                if ($n > 16) { # (no use just cutting out one line)
    497673                    $self->Open('bkg', '', 1, 2); # no underline
    498                     my $note = "[snip $n bytes]";
     674                    my $note = sprintf "[snip %d lines]", $n / 16;
    499675                    $note = (' ' x (24-length($note)/2)) . $note;
    500676                    $c[0] .= "  ...\n";
     
    503679                    $c[3] .= "\n";
    504680                    $p += $n;
     681                    $skipped += $len - length $$blockPt;
    505682                }
    506683            }
     
    550727        ImageOffset       => 'ImageByteCount',
    551728        AlphaOffset       => 'AlphaByteCount',
     729        MPImageStart      => 'MPImageLength',
     730        IDCPreviewStart   => 'IDCPreviewLength',
    552731    );
    553732
     
    556735        my $info = $exifTool->GetInfo($tag);
    557736        next unless %$info;
    558         foreach $key (%$info) {
     737        # Panasonic hack: StripOffsets is not valid for Panasonic RW2 files,
     738        # and StripRowBytes is not valid for some RAW images
     739        if ($tag eq 'StripOffsets' and $exifTool->{TAG_INFO}{$tag}{PanasonicHack}) {
     740            # use RawDataOffset instead if available since it is valid in RW2
     741            my $info2 = $exifTool->GetInfo('RawDataOffset');
     742            $info2 = $info unless %$info2;
     743            my @keys = keys %$info2;
     744            my $offset = $$info2{$keys[0]};
     745            my $raf = $$exifTool{RAF};
     746            # ignore StripByteCounts and assume raw data runs to the end of file
     747            if (@keys == 1 and $offset =~ /^\d+$/ and $raf) {
     748                my $pos = $raf->Tell();
     749                $raf->Seek(0, 2);   # seek to end
     750                my $len = $raf->Tell() - $offset;
     751                $raf->Seek($pos, 0);
     752                if ($len > 0) {
     753                    $self->Add($offset, $len, "(Panasonic raw data)", "Size: $len bytes", 0x08);
     754                    next;
     755                }
     756            }
     757        }
     758        # loop through all offsets tags
     759        foreach $key (keys %$info) {
    559760            my $name = Image::ExifTool::GetTagName($key);
    560761            my $grp1 = $exifTool->GetGroup($key, 1);
    561762            my $info2 = $exifTool->GetInfo($offsetPair{$tag}, { Group1 => $grp1 });
    562             next unless %$info2;
    563             my ($key2) = keys %$info2;
     763            my $key2 = $offsetPair{$tag};
     764            $key2 .= $1 if $key =~ /( .*)/; # use same instance number as $tag
     765            next unless $$info2{$key2};
    564766            my $offsets = $$info{$key};
    565767            my $byteCounts = $$info2{$key2};
     768            # ignore primary MPImage (this is the whole JPEG)
     769            next if $tag eq 'MPImageStart' and $offsets eq '0';
    566770            # (long lists may be SCALAR references)
    567771            my @offsets = split ' ', (ref $offsets ? $$offsets : $offsets);
     
    657861ExifTool 'HtmlDump' option is used.
    658862
    659 Currently, only EXIF and TIFF information is dumped.
     863Currently, only EXIF/TIFF and JPEG information is dumped.
    660864
    661865=head1 BUGS
     
    666870
    667871An HTML 4 compliant browser is needed to properly display the generated HTML
    668 page, but note that some of these browsers (like Mozilla) may not properly
    669 display linefeeds in the tool tips.
     872page.
    670873
    671874=head1 AUTHOR
    672875
    673 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     876Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    674877
    675878This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ICC_Profile.pm

    r16842 r24107  
    44# Description:  Read ICC Profile meta information
    55#
    6 # Revisions:    11/16/04 - P. Harvey Created
     6# Revisions:    11/16/2004 - P. Harvey Created
    77#
    88# References:   1) http://www.color.org/icc_specs2.html (ICC.1:2003-09)
     
    1010#               3) http://developer.apple.com/documentation/GraphicsImaging/Reference/ColorSync_Manager/ColorSync_Manager.pdf
    1111#               4) http://www.color.org/privatetag2007-01.pdf
     12#               5) http://www.color.org/icc_specs2.xalter (approved revisions, 2010-07-16)
    1213#
    1314# Notes:        The ICC profile information is different: the format of each
     
    2324use Image::ExifTool qw(:DataAccess :Utils);
    2425
    25 $VERSION = '1.13';
     26$VERSION = '1.22';
    2627
    2728sub ProcessICC($$);
    2829sub ProcessICC_Profile($$$);
    2930sub WriteICC_Profile($$;$);
     31sub ProcessMetadata($$$);
    3032sub ValidateICC($);
    3133
     
    4951    abst => 'Abstract Profile',
    5052    nmcl => 'NamedColor Profile',
     53    nkpf => 'Nikon Input Device Profile (NON-STANDARD!)', # (written by Nikon utilities)
    5154);
    5255
     
    5861    NOTES => q{
    5962        ICC profile information is used in many different file types including JPEG,
    60         TIFF, PDF, PostScript, Photoshop, PNG, MIFF, PICT, QuickTime and some RAW
    61         formats.  While the tags listed below are not individually writable, the
     63        TIFF, PDF, PostScript, Photoshop, PNG, MIFF, PICT, QuickTime, XCF and some
     64        RAW formats.  While the tags listed below are not individually writable, the
    6265        entire profile itself can be accessed via the extra 'ICC_Profile' tag, but
    63         this tag is neither extracted nor written unless specified explicitly.
     66        this tag is neither extracted nor written unless specified explicitly.  See
     67        L<http://www.color.org/icc_specs2.xalter> for the official ICC
     68        specification.
    6469    },
    6570    A2B0 => 'AToB0',
     
    7984        PrintConv => '$self->ConvertDateTime($val)',
    8085    },
    81     targ => 'CharTarget',
     86    targ => {
     87        Name => 'CharTarget',
     88        ValueConv => 'length $val > 128 ? \$val : $val',
     89    },
    8290    chad => 'ChromaticAdaptation',
    8391    chrm => {
    8492        Name => 'Chromaticity',
     93        Groups => { 1 => 'ICC_Profile#' }, #(just for the group list)
    8594        SubDirectory => {
    8695            TagTable => 'Image::ExifTool::ICC_Profile::Chromaticity',
     
    96105        },
    97106    },
    98     cprt => 'ProfileCopyright',
     107    clot => { # new in version 4.2
     108        Name => 'ColorantTableOut',
     109        Binary => 1,
     110    },
     111    cprt => {
     112        Name => 'ProfileCopyright',
     113        ValueConv => '$val=~s/\0.*//; $val', # may be null terminated
     114    },
    99115    crdi => 'CRDInfo', #2
    100116    dmnd => {
     
    142158    psd2 => 'PostScript2CRD2', #2
    143159    ps2s => 'PostScript2CSA', #2
    144     ps2i => 'PS2RenteringIntent', #2
     160    ps2i => 'PS2RenderingIntent', #2
    145161    rXYZ => 'RedMatrixColumn', # (called RedColorant in ref 2)
    146162    rTRC => {
     
    152168   'bfd '=> {
    153169        Name => 'UCRBG',
    154         Description => 'Under Color Removal & Black Gen.',
     170        Description => 'Under Color Removal and Black Gen.',
    155171    },
    156172    tech => {
     
    179195            silk => 'Silkscreen',
    180196            flex => 'Flexography',
     197            mpfs => 'Motion Picture Film Scanner', #5
     198            mpfr => 'Motion Picture Film Recorder', #5
     199            dmpc => 'Digital Motion Picture Camera', #5
     200            dcpj => 'Digital Cinema Projector', #5
    181201        },
    182202    },
     
    189209        },
    190210    },
     211    ciis => 'ColorimetricIntentImageState', #5
     212    scoe => 'SceneColorimetryEstimates', #5
     213    sape => 'SceneAppearanceEstimates', #5
     214    fpce => 'FocalPlaneColorimetryEstimates', #5
     215    rhoc => 'ReflectionHardcopyOrigColorimetry', #5
     216    rpoc => 'ReflectionPrintOutputColorimetry', #5
     217    psid => { #5
     218        Name => 'ProfileSequenceIdentifier',
     219        Binary => 1,
     220    },
     221    B2D0 => { Name => 'BToD0', Binary => 1 }, #5
     222    B2D1 => { Name => 'BToD1', Binary => 1 }, #5
     223    B2D2 => { Name => 'BToD2', Binary => 1 }, #5
     224    B2D3 => { Name => 'BToD3', Binary => 1 }, #5
     225    D2B0 => { Name => 'DToB0', Binary => 1 }, #5
     226    D2B1 => { Name => 'DToB1', Binary => 1 }, #5
     227    D2B2 => { Name => 'DToB2', Binary => 1 }, #5
     228    D2B3 => { Name => 'DToB3', Binary => 1 }, #5
     229    rig0 => { #5
     230        Name => 'PerceptualRenderingIntentGamut',
     231        PrintConv => {
     232            prmg => 'Perceptual Reference Medium Gamut',
     233        },
     234    },
     235    rig2 => { #5
     236        Name => 'SaturationRenderingIntentGamut',
     237        PrintConv => {
     238            prmg => 'Perceptual Reference Medium Gamut',
     239        },
     240    },
     241    meta => { #5 (EVENTUALLY DECODE THIS ONCE WE HAVE A SAMPLE!!)
     242        Name => 'Metadata',
     243        SubDirectory => {
     244            TagTable => 'Image::ExifTool::ICC_Profile::Metadata',
     245            Validate => '$type eq "meta"',
     246        },
     247    },
     248
    191249    # ColorSync custom tags (ref 3)
    192250    psvm => 'PS2CRDVMSize',
     
    195253    dscm => 'ProfileDescriptionML',
    196254    ndin => 'NativeDisplayInfo',
    197    
     255
    198256    # Microsoft custom tags (ref http://msdn2.microsoft.com/en-us/library/ms536870.aspx)
    199257    MS00 => 'WCSProfiles',
     
    269327        Name => 'DeviceManufacturer',
    270328        Format => 'string[4]',
     329        # KODA = Kodak
    271330    },
    272331    52 => {
    273332        Name => 'DeviceModel',
    274333        Format => 'string[4]',
     334        # ROMM = Refrence Output Medium Metric
    275335    },
    276336    56 => {
     
    302362        Name => 'ProfileCreator',
    303363        Format => 'string[4]',
     364        # KODA = Kodak
    304365    },
    305366    84 => {
     
    441502);
    442503
     504# metadata (meta) tags
     505%Image::ExifTool::ICC_Profile::Metadata = (
     506    PROCESS_PROC => \&ProcessMetadata,
     507    GROUPS => { 0 => 'ICC_Profile', 1 => 'ICC-meta', 2 => 'Image' },
     508    VARS => { NO_ID => 1 },
     509    NOTES => q{
     510        Only these few tags have been pre-defined, but ExifTool will extract any
     511        Metadata tags that exist.
     512    },
     513    ManufacturerName => { },
     514    MediaColor       => { },
     515    MediaWeight      => { },
     516);
    443517
    444518#------------------------------------------------------------------------------
     
    466540#  curveType, lut16Type, lut8Type, lutAtoBType, lutBtoAType, namedColor2Type,
    467541#  parametricCurveType, profileSeqDescType, responseCurveSet16Type
     542# The multiLocalizedUnicodeType must be handled by the calling routine.
    468543sub FormatICCTag($$$)
    469544{
     
    498573               Get16u($dataPt, $offset+12), Get16u($dataPt, $offset+14),
    499574               Get16u($dataPt, $offset+16), Get16u($dataPt, $offset+18));
    500     }
    501     # multiLocalizedUnicodeType (replaces textDescriptionType of ref 2)
    502     if ($type eq 'mluc' and $size >= 28) {
    503         # take first language in list (pray that it is ascii)
    504         my $len = Get32u($dataPt, $offset + 20);
    505         my $pos = Get32u($dataPt, $offset + 24);
    506         if ($size >= $pos + $len) {
    507             my $str = substr($$dataPt, $offset + $pos, $len);
    508             $str =~ tr/\x00-\x1f\x80-\xff//d; # remove control characters and non-ascii
    509             return $str;
    510         }
    511575    }
    512576    # s15Fixed16ArrayType
     
    556620    }
    557621    return undef;   # data type is not supported
     622}
     623
     624#------------------------------------------------------------------------------
     625# Process ICC metadata record (ref 5) (UNTESTED!)
     626# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
     627# Returns: 1 on success
     628sub ProcessMetadata($$$)
     629{
     630    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     631    my $dataPt = $$dirInfo{DataPt};
     632    my $dirStart = $$dirInfo{DirStart};
     633    my $dirLen = $$dirInfo{DirLen};
     634    my $dirEnd = $dirStart + $dirLen;
     635   
     636    if ($dirLen < 16 or substr($$dataPt, $dirStart, 4) ne 'dict') {
     637        $exifTool->Warn('Invalid ICC meta dictionary');
     638        return 0;
     639    }
     640    my $num = Get32u($dataPt, $dirStart + 8);
     641    $exifTool->VerboseDir('Metadata', $num);
     642    my $size = Get32u($dataPt, $dirStart + 12);
     643    $size < 16 and $exifTool->Warn('Invalid ICC meta record size'), return 0;
     644    # NOTE: In the example the minimum offset is 20,
     645    # but this doesn't jive with the table (both in ref 5)
     646    my $minPtr = 16 + $size * $num;
     647    my $index;
     648    for ($index=0; $index<$num; ++$index) {
     649        my $entry = $dirStart + 16 + $size * $index;
     650        if ($entry + $size > $dirEnd) {
     651            $exifTool->Warn('Truncated ICC meta dictionary');
     652            last;
     653        }
     654        my $namePtr = Get32u($dataPt, $entry);
     655        my $nameLen = Get32u($dataPt, $entry + 4);
     656        my $valuePtr = Get32u($dataPt, $entry + 8);
     657        my $valueLen = Get32u($dataPt, $entry + 16);
     658        next unless $namePtr and $valuePtr;   # ignore if offsets are zero
     659        if ($namePtr < $minPtr or $namePtr + $nameLen > $dirLen or
     660            $valuePtr < $minPtr or $valuePtr + $valueLen > $dirLen)
     661        {
     662            $exifTool->Warn('Corrupted ICC meta dictionary');
     663            last;
     664        }
     665        my $tag = substr($dataPt, $dirStart + $namePtr, $nameLen);
     666        my $val = substr($dataPt, $dirStart + $valuePtr, $valueLen);
     667        $tag = $exifTool->Decode($tag, 'UTF16', 'MM', 'UTF8');
     668        $val = $exifTool->Decode($val, 'UTF16', 'MM');
     669        # generate tagInfo if it doesn't exist
     670        unless ($$tagTablePtr{$tag}) {
     671            my $name = ucfirst $tag;
     672            $name =~ s/\s+(.)/\u$1/g;
     673            $name =~ tr/-_a-zA-Z0-9//dc;
     674            next unless length $name;
     675            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name });
     676        }
     677        $exifTool->HandleTag($tagTablePtr, $tag, $val);
     678    }
     679    return 1;
    558680}
    559681
     
    581703
    582704#------------------------------------------------------------------------------
    583 # Write ICC data record
     705# Write ICC data as a block
    584706# Inputs: 0) ExifTool object reference, 1) source dirInfo reference,
    585707#         2) tag table reference
     
    593715    # (don't write AsShotICCProfile or CurrentICCProfile here)
    594716    return undef unless $dirName eq 'ICC_Profile';
    595     my $newValueHash = $exifTool->GetNewValueHash($Image::ExifTool::Extra{$dirName});
    596     return undef unless Image::ExifTool::IsOverwriting($newValueHash);
    597     my $val = Image::ExifTool::GetNewValues($newValueHash);
     717    my $nvHash = $exifTool->GetNewValueHash($Image::ExifTool::Extra{$dirName});
     718    return undef unless Image::ExifTool::IsOverwriting($nvHash);
     719    my $val = Image::ExifTool::GetNewValues($nvHash);
    598720    $val = '' unless defined $val;
    599721    ++$exifTool->{CHANGED};
     
    665787    my $dirLen = $$dirInfo{DirLen};
    666788    my $verbose = $exifTool->Options('Verbose');
    667     my $raf;
     789
     790    return 0 if $dirLen < 4;
    668791
    669792    # extract binary ICC_Profile data block if binary mode or requested
     
    736859        my $subdir = $$tagInfo{SubDirectory};
    737860        # format the value unless this is a subdirectory
    738         my $value;
     861        my ($value, $fmt);
     862        if ($size > 4) {
     863            $fmt = substr($$dataPt, $valuePtr, 4);
     864            # handle multiLocalizedUnicodeType
     865            if ($fmt eq 'mluc' and not $subdir) {
     866                next if $size < 28;
     867                my $count = Get32u($dataPt, $valuePtr + 8);
     868                my $recLen = Get32u($dataPt, $valuePtr + 12);
     869                next if $recLen < 12;
     870                my $i;
     871                for ($i=0; $i<$count; ++$i) {
     872                    my $recPos = $valuePtr + 16 + $i * $recLen;
     873                    last if $recPos + $recLen > $valuePtr + $size;
     874                    my $lang = substr($$dataPt, $recPos, 4);
     875                    my $langInfo;
     876                    # validate language code and change to standard case (just in case)
     877                    if ($lang =~ s/^([a-z]{2})([A-Z]{2})$/\L$1-\U$2/i and $lang ne 'en-US') {
     878                        $langInfo = Image::ExifTool::GetLangInfo($tagInfo, $lang);
     879                    }
     880                    my $strLen = Get32u($dataPt, $recPos + 4);
     881                    my $strPos = Get32u($dataPt, $recPos + 8);
     882                    last if $strPos + $strLen > $size;
     883                    my $str = substr($$dataPt, $valuePtr + $strPos, $strLen);
     884                    $str = $exifTool->Decode($str, 'UTF16');
     885                    $exifTool->HandleTag($tagTablePtr, $tagID, $str,
     886                        TagInfo => $langInfo || $tagInfo,
     887                        Table  => $tagTablePtr,
     888                        Index  => $index,
     889                        Value  => $str,
     890                        DataPt => $dataPt,
     891                        Size   => $strLen,
     892                        Start  => $valuePtr + $strPos,
     893                        Format => "type '$fmt'",
     894                    );
     895                }
     896                $exifTool->Warn("Corrupted $$tagInfo{Name} data") if $i < $count;
     897                next;
     898            }
     899        } else {
     900            $fmt = 'err ';
     901        }
    739902        $value = FormatICCTag($dataPt, $valuePtr, $size) unless $subdir;
    740         my $fmt;
    741         $fmt = substr($$dataPt, $valuePtr, 4) if $size > 4;
    742903        $verbose and $exifTool->VerboseInfo($tagID, $tagInfo,
    743904            Table  => $tagTablePtr,
     
    783944            $value = substr($$dataPt, $valuePtr, $size);
    784945            # treat unsupported formats as binary data
    785             my $oldValueConv = $$tagInfo{ValueConv};
    786946            $$tagInfo{ValueConv} = '\$val' unless defined $$tagInfo{ValueConv};
    787947            $exifTool->FoundTag($tagInfo, $value);
     
    814974=head1 AUTHOR
    815975
    816 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     976Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    817977
    818978This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ID3.pm

    r16842 r24107  
    88# References:   1) http://www.id3.org/
    99#               2) http://www.mp3-tech.org/
     10#               3) http://www.fortunecity.com/underworld/sonic/3/id3tag.html
    1011#------------------------------------------------------------------------------
    1112
     
    1617use Image::ExifTool qw(:DataAccess :Utils);
    1718
    18 $VERSION = '1.11';
     19$VERSION = '1.28';
    1920
    2021sub ProcessID3v2($$$);
    2122sub ProcessPrivate($$$);
     23sub ConvertID3v1Text($$);
    2224
    2325# audio formats that we process after an ID3v2 header (in order)
     
    3032);
    3133
    32 my %warnedOnce;     # hash of warnings we issued
     34# picture types for 'PIC' and 'APIC' tags
     35# (Note: Duplicated in ID3, ASF and FLAC modules!)
     36my %pictureType = (
     37    0 => 'Other',
     38    1 => '32x32 PNG Icon',
     39    2 => 'Other Icon',
     40    3 => 'Front Cover',
     41    4 => 'Back Cover',
     42    5 => 'Leaflet',
     43    6 => 'Media',
     44    7 => 'Lead Artist',
     45    8 => 'Artist',
     46    9 => 'Conductor',
     47    10 => 'Band',
     48    11 => 'Composer',
     49    12 => 'Lyricist',
     50    13 => 'Recording Studio or Location',
     51    14 => 'Recording Session',
     52    15 => 'Performance',
     53    16 => 'Capture from Movie or Video',
     54    17 => 'Bright(ly) Colored Fish',
     55    18 => 'Illustration',
     56    19 => 'Band Logo',
     57    20 => 'Publisher Logo',
     58);
     59
     60my %dateTimeConv = (
     61    ValueConv => 'require Image::ExifTool::XMP; Image::ExifTool::XMP::ConvertXMPDate($val)',
     62    PrintConv => '$self->ConvertDateTime($val)',
     63);
    3364
    3465# This table is just for documentation purposes
    3566%Image::ExifTool::ID3::Main = (
    36     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, # (not really)
     67    VARS => { NO_ID => 1 },
    3768    NOTES => q{
    3869        ExifTool extracts ID3 information from MP3, MPEG, AIFF, OGG, FLAC, APE and
    39         RealAudio files.
     70        RealAudio files.  ID3v2 tags which support multiple languages (ie. Comment
     71        and Lyrics) are extracted by specifying the tag name, followed by a dash
     72        ('-'), then a 3-character
     73        ISO 639-2
     74        language code (ie. "Comment-spa"). See L<http://www.id3.org/> for the
     75        official ID3 specification and
     76        L<http://www.loc.gov/standards/iso639-2/php/code_list.php> for a list of ISO
     77        639-2 language codes.
    4078    },
    4179    ID3v1 => {
    4280        Name => 'ID3v1',
    4381        SubDirectory => { TagTable => 'Image::ExifTool::ID3::v1' },
     82    },
     83    ID3v1Enh => {
     84        Name => 'ID3v1_Enh',
     85        SubDirectory => { TagTable => 'Image::ExifTool::ID3::v1_Enh' },
    4486    },
    4587    ID3v22 => {
     
    186228    124 => 'Euro-House',
    187229    125 => 'Dance Hall',
     230    # ref http://yar.hole.ru/MP3Tech/lamedoc/id3.html
     231    126 => 'Goa',
     232    127 => 'Drum & Bass',
     233    128 => 'Club-House',
     234    129 => 'Hardcore',
     235    130 => 'Terror',
     236    131 => 'Indie',
     237    132 => 'BritPop',
     238    133 => 'Negerpunk',
     239    134 => 'Polsk Punk',
     240    135 => 'Beat',
     241    136 => 'Christian Gangsta',
     242    137 => 'Heavy Metal',
     243    138 => 'Black Metal',
     244    139 => 'Crossover',
     245    140 => 'Contemporary C',
     246    141 => 'Christian Rock',
     247    142 => 'Merengue',
     248    143 => 'Salsa',
     249    144 => 'Thrash Metal',
     250    145 => 'Anime',
     251    146 => 'JPop',
     252    147 => 'SynthPop',
    188253    255 => 'None',
    189254    # ID3v2 adds some text short forms...
     
    200265        Name => 'Title',
    201266        Format => 'string[30]',
    202         ValueConv => 'Image::ExifTool::Latin2Charset($self,$val)',
     267        ValueConv => 'Image::ExifTool::ID3::ConvertID3v1Text($self,$val)',
    203268    },
    204269    33 => {
     
    206271        Groups => { 2 => 'Author' },
    207272        Format => 'string[30]',
    208         ValueConv => 'Image::ExifTool::Latin2Charset($self,$val)',
     273        ValueConv => 'Image::ExifTool::ID3::ConvertID3v1Text($self,$val)',
    209274    },
    210275    63 => {
    211276        Name => 'Album',
    212277        Format => 'string[30]',
    213         ValueConv => 'Image::ExifTool::Latin2Charset($self,$val)',
     278        ValueConv => 'Image::ExifTool::ID3::ConvertID3v1Text($self,$val)',
    214279    },
    215280    93 => {
     
    221286        Name => 'Comment',
    222287        Format => 'string[30]',
    223         ValueConv => 'Image::ExifTool::Latin2Charset($self,$val)',
     288        ValueConv => 'Image::ExifTool::ID3::ConvertID3v1Text($self,$val)',
     289    },
     290    125 => { # ID3v1.1 (ref http://en.wikipedia.org/wiki/ID3#Layout)
     291        Name => 'Track',
     292        Format => 'int8u[2]',
     293        Notes => 'v1.1 addition -- last 2 bytes of v1.0 Comment field',
     294        RawConv => '($val =~ s/^0 // and $val) ? $val : undef',
    224295    },
    225296    127 => {
     
    228299        Format => 'int8u',
    229300        PrintConv => \%genre,
     301        PrintConvColumns => 3,
     302    },
     303);
     304
     305# ID3v1 "Enhanced TAG" information (ref 3)
     306%Image::ExifTool::ID3::v1_Enh = (
     307    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     308    GROUPS => { 1 => 'ID3v1_Enh', 2 => 'Audio' },
     309    NOTES => 'ID3 version 1 "Enhanced TAG" information (not part of the official spec).',
     310    PRIORITY => 0,  # let ID3v2 tags replace these if they come later
     311    4 => {
     312        Name => 'Title2',
     313        Format => 'string[60]',
     314        ValueConv => 'Image::ExifTool::ID3::ConvertID3v1Text($self,$val)',
     315    },
     316    64 => {
     317        Name => 'Artist2',
     318        Groups => { 2 => 'Author' },
     319        Format => 'string[60]',
     320        ValueConv => 'Image::ExifTool::ID3::ConvertID3v1Text($self,$val)',
     321    },
     322    124 => {
     323        Name => 'Album2',
     324        Format => 'string[60]',
     325        ValueConv => 'Image::ExifTool::ID3::ConvertID3v1Text($self,$val)',
     326    },
     327    184 => {
     328        Name => 'Speed',
     329        Format => 'int8u',
     330        PrintConv => {
     331            1 => 'Slow',
     332            2 => 'Medium',
     333            3 => 'Fast',
     334            4 => 'Hardcore',
     335        },
     336    },
     337    185 => {
     338        Name => 'Genre',
     339        Format => 'string[30]',
     340        ValueConv => 'Image::ExifTool::ID3::ConvertID3v1Text($self,$val)',
     341    },
     342    215 => {
     343        Name => 'StartTime',
     344        Format => 'string[6]',
     345    },
     346    221 => {
     347        Name => 'EndTime',
     348        Format => 'string[6]',
    230349    },
    231350);
     
    236355    GROUPS => { 1 => 'ID3v2_2', 2 => 'Audio' },
    237356    NOTES => q{
    238 ExifTool extracts mainly text-based tags from ID3v2 information.  The tags
    239 in the tables below are those extracted by ExifTool, and don't represent a
    240 complete list of available ID3v2 tags.
    241 
    242 ID3 version 2.2 tags.  (These are the tags written by iTunes 5.0.)
     357        ExifTool extracts mainly text-based tags from ID3v2 information.  The tags
     358        in the tables below are those extracted by ExifTool, and don't represent a
     359        complete list of available ID3v2 tags.
     360       
     361        ID3 version 2.2 tags.  (These are the tags written by iTunes 5.0.)
    243362    },
    244363    CNT => 'PlayCounter',
     
    247366    PIC => {
    248367        Name => 'Picture',
     368        Groups => { 2 => 'Image' },
    249369        Binary => 1,
    250     },
     370        Notes => 'the 3 tags below are also extracted from this PIC frame',
     371    },
     372    'PIC-1' => { Name => 'PictureFormat',      Groups => { 2 => 'Image' } },
     373    'PIC-2' => {
     374        Name => 'PictureType',
     375        Groups => { 2 => 'Image' },
     376        PrintConv => \%pictureType,
     377        SeparateTable => 1,
     378    },
     379    'PIC-3' => { Name => 'PictureDescription', Groups => { 2 => 'Image' } },
    251380  # POP => 'Popularimeter',
     381    SLT => {
     382        Name => 'SynchronizedLyricText',
     383        Binary => 1,
     384    },
    252385    TAL => 'Album',
    253386    TBP => 'BeatsPerMinute',
     
    292425    TYE => { Name => 'Year', Groups => { 2 => 'Time' } },
    293426    ULT => 'Lyrics',
    294     WAF => 'FileRUL',
     427    WAF => 'FileURL',
    295428    WAR => { Name => 'ArtistURL', Groups => { 2 => 'Author' } },
    296429    WAS => 'SourceURL',
     
    306439    APIC => {
    307440        Name => 'Picture',
     441        Groups => { 2 => 'Image' },
    308442        Binary => 1,
    309     },
     443        Notes => 'the 3 tags below are also extracted from this PIC frame',
     444    },
     445    'APIC-1' => { Name => 'PictureMimeType',    Groups => { 2 => 'Image' } },
     446    'APIC-2' => {
     447        Name => 'PictureType',
     448        Groups => { 2 => 'Image' },
     449        PrintConv => \%pictureType,
     450        SeparateTable => 1,
     451    },
     452    'APIC-3' => { Name => 'PictureDescription', Groups => { 2 => 'Image' } },
    310453    COMM => 'Comment',
    311454  # COMR => 'Commercial',
     
    327470  # RBUF => 'RecommendedBufferSize',
    328471  # RVRB => 'Reverb',
    329   # SYLT => 'SynchronizedLyricText',
     472    SYLT => {
     473        Name => 'SynchronizedLyricText',
     474        Binary => 1,
     475    },
    330476  # SYTC => 'SynchronizedTempoCodes',
    331477    TALB => 'Album',
    332478    TBPM => 'BeatsPerMinute',
     479    TCMP => { Name => 'Compilation', PrintConv => { 0 => 'No', 1 => 'Yes' } }, #PH (iTunes)
    333480    TCOM => 'Composer',
    334481    TCON =>{
     
    350497        Name => 'Length',
    351498        ValueConv => '$val / 1000',
    352         PrintConv => '"$val sec"',
     499        PrintConv => '"$val s"',
    353500    },
    354501    TMED => 'Media',
     
    375522    WCOM => 'CommercialURL',
    376523    WCOP => 'CopyrightURL',
    377     WOAF => 'FileRUL',
     524    WOAF => 'FileURL',
    378525    WOAR => { Name => 'ArtistURL', Groups => { 2 => 'Author' } },
    379526    WOAS => 'SourceURL',
     
    411558  # SEEK => 'Seek',
    412559  # SIGN => 'Signature',
    413     TDEN => { Name => 'EncodingTime',       Groups => { 2 => 'Time' } },
    414     TDOR => { Name => 'OriginalReleaseTime',Groups => { 2 => 'Time' } },
    415     TDRC => { Name => 'RecordingTime',      Groups => { 2 => 'Time' } },
    416     TDRL => { Name => 'ReleaseTime',        Groups => { 2 => 'Time' } },
    417     TDTG => { Name => 'TaggingTime',        Groups => { 2 => 'Time' } },
     560    TDEN => { Name => 'EncodingTime',       Groups => { 2 => 'Time' }, %dateTimeConv },
     561    TDOR => { Name => 'OriginalReleaseTime',Groups => { 2 => 'Time' }, %dateTimeConv },
     562    TDRC => { Name => 'RecordingTime',      Groups => { 2 => 'Time' }, %dateTimeConv },
     563    TDRL => { Name => 'ReleaseTime',        Groups => { 2 => 'Time' }, %dateTimeConv },
     564    TDTG => { Name => 'TaggingTime',        Groups => { 2 => 'Time' }, %dateTimeConv },
    418565    TIPL => 'InvolvedPeople',
    419566    TMCL => 'MusicianCredits',
     
    445592);
    446593
     594# ID3 Composite tags
     595%Image::ExifTool::ID3::Composite = (
     596    GROUPS => { 2 => 'Image' },
     597    DateTimeOriginal => {
     598        Description => 'Date/Time Original',
     599        Groups => { 2 => 'Time' },
     600        Priority => 0,
     601        Desire => {
     602            0 => 'ID3:RecordingTime',
     603            1 => 'ID3:Year',
     604            2 => 'ID3:Date',
     605            3 => 'ID3:Time',
     606        },
     607        ValueConv => q{
     608            return $val[0] if $val[0];
     609            return undef unless $val[1];
     610            return $val[1] unless $val[2] and $val[2] =~ /^(\d{2})(\d{2})$/;
     611            $val[1] .= ":$1:$2";
     612            return $val[1] unless $val[3] and $val[3] =~ /^(\d{2})(\d{2})$/;
     613            return "$val[1] $1:$2";
     614        },
     615        PrintConv => '$self->ConvertDateTime($val)',
     616    },
     617);
     618
     619# add our composite tags
     620Image::ExifTool::AddCompositeTags('Image::ExifTool::ID3');
     621
    447622# can't share tagInfo hashes between two tables, so we must make
    448623# copies of the necessary hashes
     
    452627        next unless ref $id3v2_common{$tag} eq 'HASH';
    453628        my %tagInfo = %{$id3v2_common{$tag}};
     629        # must also copy Groups hash if it exists
     630        my $groups = $tagInfo{Groups};
     631        $tagInfo{Groups} = { %$groups } if $groups;
    454632        $Image::ExifTool::ID3::v2_4{$tag} = \%tagInfo;
    455633    }
     634}
     635
     636#------------------------------------------------------------------------------
     637# Convert ID3v1 text to exiftool character set
     638# Inputs: 0) ExifTool object ref, 1) text string
     639# Returns: converted text
     640sub ConvertID3v1Text($$)
     641{
     642    my ($exifTool, $val) = @_;
     643    return $exifTool->Decode($val, $exifTool->Options('CharsetID3'));
    456644}
    457645
     
    485673    );
    486674    # set group1 name
    487     $exifTool->SetGroup1($key, $$exifTool{ID3_Ver}) if $key;
     675    $exifTool->SetGroup($key, $$exifTool{ID3_Ver}) if $key;
    488676}
    489677
     
    507695    $val =~ s/\((\d+)\)/\($genre{$1}\)/g;
    508696    $val =~ s/(^|\/)(\d+)/$1$genre{$2}/g;
     697    $val =~ s/^\(([^)]+)\)\1?$/$1/; # clean up by removing brackets and duplicates
    509698    return $val;
    510699}
     
    512701#------------------------------------------------------------------------------
    513702# Decode ID3 string
    514 # Inputs: 0) ExifTool object reference, 1) string beginning with encoding byte
     703# Inputs: 0) ExifTool object reference
     704#         1) string beginning with encoding byte unless specified as argument
     705#         2) optional encoding (0=ISO-8859-1, 1=UTF-16 BOM, 2=UTF-16BE, 3=UTF-8)
    515706# Returns: Decoded string in scalar context, or list of strings in list context
    516 sub DecodeString($$)
     707sub DecodeString($$;$)
    517708{
    518     my ($exifTool, $val) = @_;
     709    my ($exifTool, $val, $enc) = @_;
    519710    return '' unless length $val;
    520     my $enc = unpack('C', $val);
    521     $val = substr($val, 1); # remove encoding byte
     711    unless (defined $enc) {
     712        $enc = unpack('C', $val);
     713        $val = substr($val, 1); # remove encoding byte
     714    }
    522715    my @vals;
    523     if ($enc == 0) {        # ISO 8859-1
     716    if ($enc == 0 or $enc == 3) { # ISO 8859-1 or UTF-8
    524717        $val =~ s/\0+$//;   # remove any null padding
    525         $val = $exifTool->Latin2Charset($val);
     718        # (must split before converting because conversion routines truncate at null)
    526719        @vals = split "\0", $val;
    527     } elsif ($enc == 3) {   # UTF-8
    528         $val =~ s/\0+$//;
    529         $val = $exifTool->UTF82Charset($val);
    530         @vals = split "\0", $val;
     720        foreach $val (@vals) {
     721            $val = $exifTool->Decode($val, $enc ? 'UTF8' : 'Latin');
     722        }
    531723    } elsif ($enc == 1 or $enc == 2) {  # UTF-16 with BOM, or UTF-16BE
    532724        my $bom = "\xfe\xff";
     
    543735            }
    544736            $bom = $1 if $v =~ s/^(\xfe\xff|\xff\xfe)//;
    545             push @vals, $exifTool->Unicode2Charset($v, $order{$bom});
     737            push @vals, $exifTool->Decode($v, 'UCS2', $order{$bom});
    546738        }
    547739    } else {
     
    554746
    555747#------------------------------------------------------------------------------
    556 # Issue one warning of each type
    557 # Inputs: 0) ExifTool object reference, 1) warning
    558 sub WarnOnce($$)
     748# Convert sync-safe integer to a number we can use
     749# Inputs: 0) int32u sync-safe value
     750# Returns: actual number or undef on invalid value
     751sub UnSyncSafe($)
    559752{
    560     my ($exifTool, $warn) = @_;
    561     unless ($warnedOnce{$warn}) {
    562         $warnedOnce{$warn} = 1;
    563         $exifTool->Warn($warn);
    564     }
     753    my $val = shift;
     754    return undef if $val & 0x80808080;
     755    return ($val & 0x0000007f) |
     756          (($val & 0x00007f00) >> 1) |
     757          (($val & 0x007f0000) >> 2) |
     758          (($val & 0x7f000000) >> 3);
    565759}
     760
    566761#------------------------------------------------------------------------------
    567762# Process ID3v2 information
     
    578773
    579774    $verbose and $exifTool->VerboseDir($tagTablePtr->{GROUPS}->{1}, 0, $size);
    580     undef %warnedOnce;
    581775
    582776    for (;;$offset+=$len) {
     
    595789            last if $id eq "\0\0\0\0";
    596790            $offset += 10;
     791            # length is a "sync-safe" integer by the ID3v2.4 specification, but
     792            # reportedly some versions of iTunes write this as a normal integer
     793            # (ref http://www.id3.org/iTunes)
     794            while ($vers >= 0x0400 and $len > 0x7f and not $len & 0x80808080) {
     795                my $oldLen = $len;
     796                $len =  UnSyncSafe($len);
     797                if (not defined $len or $offset + $len + 10 > $size) {
     798                    $exifTool->Warn('Invalid ID3 frame size');
     799                    last;
     800                }
     801                # check next ID to see if it makes sense
     802                my $nextID = substr($$dataPt, $offset + $len, 4);
     803                last if $$tagTablePtr{$nextID};
     804                # try again with the incorrect length word (patch for iTunes bug)
     805                last if $offset + $oldLen + 10 > $size;
     806                $nextID = substr($$dataPt, $offset + $len, 4);
     807                $len = $oldLen if $$tagTablePtr{$nextID};
     808                last; # yes, "while" was really a "goto" in disguise
     809            }
    597810        }
    598811        last if $offset + $len > $size;
     
    625838        }
    626839        if ($flags{Encrypt}) {
    627             WarnOnce($exifTool, 'Encrypted frames currently not supported');
     840            $exifTool->WarnOnce('Encrypted frames currently not supported');
    628841            next;
    629842        }
     
    631844        my $val = substr($$dataPt, $offset, $len);
    632845
    633         # handle the flags
    634         if ($flags{Unsync}) {
    635             # reverse the unsynchronization
    636             $val =~ s/\xff\x00/\xff/g;
    637         }
     846        # reverse the unsynchronization
     847        $val =~ s/\xff\x00/\xff/g if $flags{Unsync};
     848
     849        # read grouping identity
    638850        if ($flags{GroupID}) {
    639851            length($val) >= 1 or $exifTool->Warn("Short $id frame"), next;
    640             # ignore the grouping identity byte
    641             $val = substr($val, 1);
    642         }
     852            $val = substr($val, 1); # (ignore it)
     853        }
     854        # read data length
     855        my $dataLen;
    643856        if ($flags{DataLen} or $flags{Compress}) {
    644857            length($val) >= 4 or $exifTool->Warn("Short $id frame"), next;
    645             # ignore data length word
     858            $dataLen = unpack('N', $val);   # save the data length word
    646859            $val = substr($val, 4);
    647860        }
     861        # uncompress data
    648862        if ($flags{Compress}) {
    649863            if (eval 'require Compress::Zlib') {
     
    658872                }
    659873            } else {
    660                 WarnOnce($exifTool,'Install Compress::Zlib to decode compressed frames');
     874                $exifTool->WarnOnce('Install Compress::Zlib to decode compressed frames');
    661875                next;
    662876            }
     877        }
     878        # validate data length
     879        if (defined $dataLen) {
     880            $dataLen = UnSyncSafe($dataLen);
     881            defined $dataLen or $exifTool->Warn("Invalid length for $id frame"), next;
     882            $dataLen == length($val) or $exifTool->Warn("Wrong length for $id frame"), next;
    663883        }
    664884        $verbose and $exifTool->VerboseInfo($id, $tagInfo,
     
    674894# decode data in this frame
    675895#
     896        my $lang;
    676897        my $valLen = length($val);  # actual value length (after decompression, etc)
    677898        if ($id =~ /^(TXX|TXXX)$/) {
     
    694915                $exifTool->Warn("Invalid $id frame value");
    695916                next;
    696             }               
     917            }
    697918            $val = DecodeString($exifTool, $val);
    698919            $url =~ s/\0.*//;
     
    702923        } elsif ($id =~ /^(COM|COMM|ULT|USLT)$/) {
    703924            $valLen > 4 or $exifTool->Warn("Short $id frame"), next;
    704             substr($val, 1, 3) = '';    # remove language code
    705             my @vals = DecodeString($exifTool, $val);
     925            $lang = substr($val,1,3);
     926            my @vals = DecodeString($exifTool, substr($val,4), Get8u(\$val,0));
    706927            foreach (0..1) { $vals[$_] = '' unless defined $vals[$_]; }
    707928            $val = length($vals[0]) ? "($vals[0]) $vals[1]" : $vals[1];
    708929        } elsif ($id eq 'USER') {
    709930            $valLen > 4 or $exifTool->Warn('Short USER frame'), next;
    710             substr($val, 1, 3) = '';    # remove language code
    711             $val = DecodeString($exifTool, $val);
     931            $lang = substr($val,1,3);
     932            $val = DecodeString($exifTool, substr($val,4), Get8u(\$val,0));
    712933        } elsif ($id =~ /^(CNT|PCNT)$/) {
    713934            $valLen >= 4 or $exifTool->Warn("Short $id frame"), next;
     
    720941        } elsif ($id =~ /^(PIC|APIC)$/) {
    721942            $valLen >= 4 or $exifTool->Warn("Short $id frame"), next;
     943            my ($hdr, $attr);
    722944            my $enc = unpack('C', $val);
    723             my $hdr = ($id eq 'PIC') ? '.{5}.*?\0' : '..*?\0..*?\0';
     945            if ($enc == 1 or $enc == 2) {
     946                $hdr = ($id eq 'PIC') ? ".(...)(.)((?:..)*?)\0\0" : ".(.*?)\0(.)((?:..)*?)\0\0";
     947            } else {
     948                $hdr = ($id eq 'PIC') ? ".(...)(.)(.*?)\0"        : ".(.*?)\0(.)(.*?)\0";
     949            }
    724950            # remove header (encoding, image format or MIME type, picture type, description)
    725             $val =~ s/$hdr//s or $exifTool->Warn("Invalid $id frame"), next;
    726             $enc and $val =~ s/^\0//;   # remove 2nd terminator if Unicode encoding
     951            $val =~ s/^$hdr//s or $exifTool->Warn("Invalid $id frame"), next;
     952            my @attrs = ($1, ord($2), DecodeString($exifTool, $3, $enc));
     953            my $i = 1;
     954            foreach $attr (@attrs) {
     955                # must store descriptions even if they are empty to maintain
     956                # sync between copy numbers when multiple images
     957                $exifTool->HandleTag($tagTablePtr, "$id-$i", $attr);
     958                ++$i;
     959            }
    727960        } elsif ($id eq 'PRIV') {
    728961            # save version number to set group1 name for tag later
     
    734967            next;
    735968        }
     969        if ($lang and $lang =~ /^[a-z]{3}$/i and $lang ne 'eng') {
     970            $tagInfo = Image::ExifTool::GetLangInfo($tagInfo, lc $lang);
     971        }
    736972        $exifTool->FoundTag($tagInfo, $val);
    737973    }
    738     undef %warnedOnce;
    739974}
    740975
     
    744979# Returns: 1 on success, 0 if this file didn't contain ID3 information
    745980# - also processes audio data if any ID3 information was found
    746 # - sets ExifTool DONE_ID3 to 1 when called, or to 2 if an ID3v1 trailer exists
     981# - sets ExifTool DoneID3 to 1 when called, or to 2 if an ID3v1 trailer exists
    747982sub ProcessID3($$)
    748983{
    749984    my ($exifTool, $dirInfo) = @_;
    750    
    751     return 0 if $exifTool->{DONE_ID3};  # avoid infinite recursion
    752     $exifTool->{DONE_ID3} = 1;
     985
     986    return 0 if $exifTool->{DoneID3};  # avoid infinite recursion
     987    $exifTool->{DoneID3} = 1;
    753988
    754989    # allow this to be called with either RAF or DataPt
    755990    my $raf = $$dirInfo{RAF} || new File::RandomAccess($$dirInfo{DataPt});
    756     my ($buff, %id3Header, %id3Trailer, $hBuff, $tBuff, $tBuffPos, $tagTablePtr);
     991    my ($buff, %id3Header, %id3Trailer, $hBuff, $tBuff, $eBuff, $tagTablePtr);
    757992    my $rtnVal = 0;
    758993    my $hdrEnd = 0;
     994    my $id3Len = 0;
    759995
    760996    # read first 3 bytes of file
     
    7681004        $raf->Read($hBuff, 7) == 7 or $exifTool->Warn('Short ID3 header'), last;
    7691005        my ($vers, $flags, $size) = unpack('nCN', $hBuff);
    770         $size & 0x80808080 and $exifTool->Warn('Invalid ID3 header'), last;
     1006        $size = UnSyncSafe($size);
     1007        defined $size or $exifTool->Warn('Invalid ID3 header'), last;
    7711008        my $verStr = sprintf("2.%d.%d", $vers >> 8, $vers & 0xff);
    7721009        if ($vers >= 0x0500) {
     
    7741011            last;
    7751012        }
    776         $size =  ($size & 0x0000007f) |
    777                 (($size & 0x00007f00) >> 1) |
    778                 (($size & 0x007f0000) >> 2) |
    779                 (($size & 0x7f000000) >> 3);
    7801013        unless ($raf->Read($hBuff, $size) == $size) {
    7811014            $exifTool->Warn('Truncated ID3 data');
    7821015            last;
    7831016        }
    784         if ($flags & 0x80) {
     1017        # this flag only indicates use of unsynchronized frames in ID3v2.4
     1018        if ($flags & 0x80 and $vers < 0x0400) {
    7851019            # reverse the unsynchronization
    7861020            $hBuff =~ s/\xff\x00/\xff/g;
     
    8101044            DirName  => "ID3v$verStr",
    8111045        );
     1046        $id3Len += length($hBuff) + 10;
    8121047        if ($vers >= 0x0400) {
    8131048            $tagTablePtr = GetTagTable('Image::ExifTool::ID3::v2_4');
     
    8241059#
    8251060    if ($raf->Seek(-128, 2) and $raf->Read($tBuff, 128) == 128 and $tBuff =~ /^TAG/) {
    826         $exifTool->{DONE_ID3} = 2;  # set to 2 as flag that trailer exists
     1061        $exifTool->{DoneID3} = 2;  # set to 2 as flag that trailer exists
    8271062        %id3Trailer = (
    8281063            DataPt   => \$tBuff,
     
    8311066            DirLen   => length($tBuff),
    8321067        );
     1068        $id3Len += length($tBuff);
    8331069        $rtnVal = 1;
     1070        # load 'Enhanced TAG' information if available
     1071        if ($raf->Seek(-355, 2) and $raf->Read($eBuff, 227) == 227 and $eBuff =~ /^TAG+/) {
     1072            $id3Trailer{EnhancedTAG} = \$eBuff;
     1073        }
    8341074    }
    8351075#
     
    8391079        # first process audio data if it exists
    8401080        if ($$dirInfo{RAF}) {
    841             my $type = $exifTool->{FILE_TYPE};  # save file type
     1081            my $oldType = $exifTool->{FILE_TYPE};   # save file type
    8421082            # check current file type first
    843             my @types = grep /^$type$/, @audioFormats;
    844             push @types, grep(!/^$type$/, @audioFormats);
    845             my $oldType = $exifTool->{FILE_TYPE};
     1083            my @types = grep /^$oldType$/, @audioFormats;
     1084            push @types, grep(!/^$oldType$/, @audioFormats);
     1085            my $type;
    8461086            foreach $type (@types) {
    8471087                # seek to end of ID3 header
     
    8571097                use strict 'refs';
    8581098            }
    859             $exifTool->{FILE_TYPE} = $type;     # restore original file type
     1099            $exifTool->{FILE_TYPE} = $oldType;      # restore original file type
    8601100        }
    8611101        # set file type to MP3 if we didn't find audio data
    862         $exifTool->SetFileType('MP3') unless $exifTool->{VALUE}->{FileType};
     1102        $exifTool->SetFileType('MP3');
     1103        # record the size if the ID3 metadata
     1104        $exifTool->FoundTag('ID3Size', $id3Len);
    8631105        # process ID3v2 header if it exists
    8641106        if (%id3Header) {
     
    8721114            $tagTablePtr = GetTagTable('Image::ExifTool::ID3::v1');
    8731115            $exifTool->ProcessDirectory(\%id3Trailer, $tagTablePtr);
     1116            # process "Enhanced TAG" information if available
     1117            if ($id3Trailer{EnhancedTAG}) {
     1118                $exifTool->VPrint(0, "ID3v1 Enhanced TAG:\n");
     1119                $tagTablePtr = GetTagTable('Image::ExifTool::ID3::v1_Enh');
     1120                $id3Trailer{DataPt} = $id3Trailer{EnhancedTAG};
     1121                $id3Trailer{DataPos} -= 227; # (227 = length of Enhanced TAG block)
     1122                $id3Trailer{DirLen} = 227;
     1123                $exifTool->ProcessDirectory(\%id3Trailer, $tagTablePtr);
     1124            }
    8741125        }
    8751126    }
     
    8881139
    8891140    # must first check for leading/trailing ID3 information
    890     unless ($exifTool->{DONE_ID3}) {
    891         require Image::ExifTool::ID3;
    892         Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
     1141    unless ($exifTool->{DoneID3}) {
     1142        ProcessID3($exifTool, $dirInfo) and return 1;
    8931143    }
    8941144    my $raf = $$dirInfo{RAF};
     
    8971147#
    8981148# extract information from first audio/video frame headers
    899 # (if found in the first 256 bytes)
     1149# (if found in the first $scanLen bytes)
    9001150#
    901     if ($raf->Read($buff, 256)) {
     1151    # scan further into a file that should be an MP3
     1152    my $scanLen = ($$exifTool{FILE_EXT} and $$exifTool{FILE_EXT} eq 'MP3') ? 8192 : 256;
     1153    if ($raf->Read($buff, $scanLen)) {
    9021154        require Image::ExifTool::MPEG;
    9031155        if ($buff =~ /\0\0\x01(\xb3|\xc0)/) {
    9041156            # look for A/V headers in first 64kB
    9051157            my $buf2;
    906             $raf->Read($buf2, 65280) and $buff .= $buf2;
    907             $rtnVal = 1 if Image::ExifTool::MPEG::ProcessMPEGAudioVideo($exifTool, \$buff);
     1158            $raf->Read($buf2, 0x10000 - $scanLen) and $buff .= $buf2;
     1159            $rtnVal = 1 if Image::ExifTool::MPEG::ParseMPEGAudioVideo($exifTool, \$buff);
    9081160        } else {
    909             # look for audio frame sync in first 256 bytes
    910             $rtnVal = 1 if Image::ExifTool::MPEG::ProcessMPEGAudio($exifTool, \$buff);
     1161            # look for audio frame sync in first $scanLen bytes
     1162            $rtnVal = 1 if Image::ExifTool::MPEG::ParseMPEGAudio($exifTool, \$buff);
    9111163        }
    9121164    }
     
    9341186=head1 AUTHOR
    9351187
    936 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1188Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    9371189
    9381190This library is free software; you can redistribute it and/or modify it
     
    9471199=item L<http://www.mp3-tech.org/>
    9481200
     1201=item L<http://www.fortunecity.com/underworld/sonic/3/id3tag.html>
     1202
    9491203=back
    9501204
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/IPTC.pm

    r16842 r24107  
    44# Description:  Read IPTC meta information
    55#
    6 # Revisions:    Jan. 08/03 - P. Harvey Created
    7 #               Feb. 05/04 - P. Harvey Added support for records other than 2
     6# Revisions:    Jan. 08/2003 - P. Harvey Created
     7#               Feb. 05/2004 - P. Harvey Added support for records other than 2
    88#
    99# References:   1) http://www.iptc.org/IIM/
     
    1515use vars qw($VERSION $AUTOLOAD %iptcCharset);
    1616
    17 $VERSION = '1.23';
     17$VERSION = '1.42';
    1818
    1919%iptcCharset = (
    2020    "\x1b%G"  => 'UTF8',
    2121   # don't translate these (at least until we handle ISO 2022 shift codes)
    22    # because the sets are only designated and not invoked 
     22   # because the sets are only designated and not invoked
    2323   # "\x1b,A"  => 'Latin',  # G0 = ISO 8859-1 (similar to Latin1, but codes 0x80-0x9f are missing)
    2424   # "\x1b-A"  => 'Latin',  # G1     "
     
    105105    9 => {
    106106        Name => 'IPTCPostObjectData',
     107        Groups => { 1 => 'IPTC#' }, #(just so this shows up in group list)
    107108        SubDirectory => {
    108109            TagTable => 'Image::ExifTool::IPTC::PostObjectData',
     110        },
     111    },
     112    240 => {
     113        Name => 'IPTCFotoStation',
     114        SubDirectory => {
     115            TagTable => 'Image::ExifTool::IPTC::FotoStation',
    109116        },
    110117    },
     
    120127        Name => 'EnvelopeRecordVersion',
    121128        Format => 'int16u',
     129        Mandatory => 1,
    122130    },
    123131    5 => {
     
    154162        Name => 'EnvelopePriority',
    155163        Format => 'digits[1]',
     164        PrintConv => {
     165            0 => '0 (reserved)',
     166            1 => '1 (most urgent)',
     167            2 => 2,
     168            3 => 3,
     169            4 => 4,
     170            5 => '5 (normal urgency)',
     171            6 => 6,
     172            7 => 7,
     173            8 => '8 (least urgent)',
     174            9 => '9 (user-defined priority)',
     175        },
    156176    },
    157177    70 => {
     
    178198            convenience.  Either string may be used when writing.  The value of this tag
    179199            affects the decoding of string values in the Application and NewsPhoto
    180             records
    181         },
     200            records.  This tag is marked as "unsafe" to prevent it from being copied by
     201            default in a group operation because existing tags in the destination image
     202            may use a different encoding.  When creating a new IPTC record from scratch,
     203            it is suggested that this be set to "UTF8" if special characters are a
     204            possibility
     205        },
     206        Protected => 1,
    182207        Format => 'string[0,32]',
    183208        # convert ISO 2022 escape sequences to a more readable format
     
    208233        Name => 'ApplicationRecordVersion',
    209234        Format => 'int16u',
     235        Mandatory => 1,
    210236    },
    211237    3 => {
     
    229255        Name => 'EditorialUpdate',
    230256        Format => 'digits[2]',
     257        PrintConv => {
     258            '01' => 'Additional language',
     259        },
    231260    },
    232261    10 => {
    233262        Name => 'Urgency',
    234263        Format => 'digits[1]',
     264        PrintConv => {
     265            0 => '0 (reserved)',
     266            1 => '1 (most urgent)',
     267            2 => 2,
     268            3 => 3,
     269            4 => 4,
     270            5 => '5 (normal urgency)',
     271            6 => 6,
     272            7 => 7,
     273            8 => '8 (least urgent)',
     274            9 => '9 (user-defined priority)',
     275        },
    235276    },
    236277    12 => {
     
    454495        Format => 'string[0,2000]',
    455496    },
    456     121 => { # (format not certain)
     497    121 => {
    457498        Name => 'LocalCaption',
    458         Format => 'string[0,256]',
     499        Format => 'string[0,256]', # (guess)
    459500        Notes => q{
    460501            I haven't found a reference for the format of tags 121, 184-188 and
    461502            225-232, so I have just make them writable as strings with
    462503            reasonable length.  Beware that if this is wrong, other utilities
    463             won't be able to read these tags as written by ExifTool.
     504            won't be able to read these tags as written by ExifTool
    464505        },
    465506    },
     
    472513    125 => {
    473514        Name => 'RasterizedCaption',
    474         Format => 'string[7360]',
     515        Format => 'undef[7360]',
    475516        Binary => 1,
    476517    },
     
    533574        Format => 'string[0,64]',
    534575    },
    535     184 => { # (format not certain)
     576    184 => {
    536577        Name => 'JobID',
    537         Format => 'string[0,64]',
    538     },
    539     185 => { # (format not certain)
     578        Format => 'string[0,64]', # (guess)
     579    },
     580    185 => {
    540581        Name => 'MasterDocumentID',
    541         Format => 'string[0,256]',
    542     },
    543     186 => { # (format not certain)
     582        Format => 'string[0,256]', # (guess)
     583    },
     584    186 => {
    544585        Name => 'ShortDocumentID',
    545         Format => 'string[0,64]',
    546     },
    547     187 => { # (format not certain)
     586        Format => 'string[0,64]', # (guess)
     587    },
     588    187 => {
    548589        Name => 'UniqueDocumentID',
    549         Format => 'string[0,128]',
    550     },
    551     188 => { # (format not certain)
     590        Format => 'string[0,128]', # (guess)
     591    },
     592    188 => {
    552593        Name => 'OwnerID',
    553         Format => 'string[0,128]',
     594        Format => 'string[0,128]', # (guess)
    554595    },
    555596    200 => {
     
    567608        Name => 'ObjectPreviewData',
    568609        Groups => { 2 => 'Image' },
    569         Format => 'string[0,256000]',
     610        Format => 'undef[0,256000]',
    570611        Binary => 1,
    571612    },
     
    586627        },
    587628    },
    588     225 => { # (format not certain)
     629    225 => {
    589630        Name => 'ClassifyState',
    590         Format => 'string[0,64]',
    591     },
    592     228 => { # (format not certain)
     631        Format => 'string[0,64]', # (guess)
     632    },
     633    228 => {
    593634        Name => 'SimilarityIndex',
    594         Format => 'string[0,32]',
    595     },
    596     230 => { # (format not certain)
     635        Format => 'string[0,32]', # (guess)
     636    },
     637    230 => {
    597638        Name => 'DocumentNotes',
    598         Format => 'string[0,1024]',
    599     },
    600     231 => { # (format not certain)
     639        Format => 'string[0,1024]', # (guess)
     640    },
     641    231 => {
    601642        Name => 'DocumentHistory',
    602         Format => 'string[0,256]',
    603     },
    604     232 => { # (format not certain)
     643        Format => 'string[0,256]', # (guess)
     644    },
     645    232 => {
    605646        Name => 'ExifCameraInfo',
    606         Format => 'string[0,4096]',
     647        Format => 'string[0,4096]', # (guess)
     648    },
     649    255 => { #PH
     650        Name => 'CatalogSets',
     651        List => 1,
     652        Format => 'string[0,256]', # (guess)
     653        Notes => 'written by iView MediaPro',
    607654    },
    608655);
     
    617664        Name => 'NewsPhotoVersion',
    618665        Format => 'int16u',
     666        Mandatory => 1,
    619667    },
    620668    10 => {
     
    842890);
    843891
     892# Record 240 -- FotoStation proprietary data (ref PH)
     893%Image::ExifTool::IPTC::FotoStation = (
     894    GROUPS => { 2 => 'Other' },
     895    WRITE_PROC => \&WriteIPTC,
     896    CHECK_PROC => \&CheckIPTC,
     897    WRITABLE => 1,
     898);
     899
     900# IPTC Composite tags
     901%Image::ExifTool::IPTC::Composite = (
     902    GROUPS => { 2 => 'Image' },
     903    DateTimeCreated => {
     904        Description => 'Date/Time Created',
     905        Groups => { 2 => 'Time' },
     906        Require => {
     907            0 => 'IPTC:DateCreated',
     908            1 => 'IPTC:TimeCreated',
     909        },
     910        ValueConv => '"$val[0] $val[1]"',
     911        PrintConv => '$self->ConvertDateTime($val)',
     912    },
     913    DigitalCreationDateTime => {
     914        Description => 'Digital Creation Date/Time',
     915        Groups => { 2 => 'Time' },
     916        Require => {
     917            0 => 'IPTC:DigitalCreationDate',
     918            1 => 'IPTC:DigitalCreationTime',
     919        },
     920        ValueConv => '"$val[0] $val[1]"',
     921        PrintConv => '$self->ConvertDateTime($val)',
     922    },
     923);
     924
     925# add our composite tags
     926Image::ExifTool::AddCompositeTags('Image::ExifTool::IPTC');
     927
    844928
    845929#------------------------------------------------------------------------------
     
    863947    return $val;
    864948}
    865        
     949
    866950#------------------------------------------------------------------------------
    867951# Handle CodedCharacterSet
    868952# Inputs: 0) ExifTool ref, 1) CodedCharacterSet value
    869 # Returns: external character set if translation required (or 'bad' if unknown)
     953# Returns: IPTC character set if translation required (or 'bad' if unknown)
    870954sub HandleCodedCharset($$)
    871955{
    872956    my ($exifTool, $val) = @_;
    873     my $xlat = $exifTool->Options('Charset');
    874     if ($iptcCharset{$val}) {
    875         # no need to translate if destination is the same
    876         undef $xlat if $xlat eq $iptcCharset{$val};
    877     } elsif ($val =~ /^\x1b\x25/) {
    878         # some unknown character set involked
    879         $xlat = 'bad';  # flag unsupported coding
    880     } else {
    881         # translate all other codes as Latin
    882         undef $xlat if $xlat eq 'Latin';
     957    my $xlat = $iptcCharset{$val};
     958    unless ($xlat) {
     959        if ($val =~ /^\x1b\x25/) {
     960            # some unknown character set invoked
     961            $xlat = 'bad';  # flag unsupported coding
     962        } else {
     963            $xlat = $exifTool->Options('CharsetIPTC');
     964        }
    883965    }
     966    # no need to translate if Charset is the same
     967    undef $xlat if $xlat eq $exifTool->Options('Charset');
    884968    return $xlat;
    885969}
     
    887971#------------------------------------------------------------------------------
    888972# Encode or decode coded string
    889 # Inputs: 0) ExifTool ref, 1) value ptr, 2) destination charset ('Latin','UTF8' or 'bad')
     973# Inputs: 0) ExifTool ref, 1) value ptr, 2) IPTC charset (or 'bad') ref
    890974#         3) flag set to decode (read) value from IPTC
    891975# Updates value on return
     
    893977{
    894978    my ($exifTool, $valPtr, $xlatPtr, $read) = @_;
    895     my $escaped;
    896979    if ($$xlatPtr eq 'bad') {
    897980        $exifTool->Warn('Some IPTC characters not converted (unsupported CodedCharacterSet)');
    898981        undef $$xlatPtr;
    899     } elsif ($$xlatPtr eq 'Latin' xor $read) {
     982    } elsif (not $read) {
     983        $$valPtr = $exifTool->Decode($$valPtr, undef, undef, $$xlatPtr);
     984    } elsif ($$valPtr !~ /[\x14\x15\x1b]/) {
     985        $$valPtr = $exifTool->Decode($$valPtr, $$xlatPtr);
     986    } else {
    900987        # don't yet support reading ISO 2022 shifted character sets
    901         if (not $read or $$valPtr !~ /[\x14\x15\x1b]/) {
    902             # convert from Latin to UTF-8
    903             my $val = Image::ExifTool::Latin2Unicode($$valPtr,'n');
    904             $$valPtr = Image::ExifTool::Unicode2UTF8($val,'n');
    905         } elsif (not $$exifTool{WarnShift2022}) {
    906             $exifTool->Warn('Some IPTC characters not converted (ISO 2022 shifting not supported)');
    907             $$exifTool{WarnShift2022} = 1;
    908         }
    909     } else {
    910         # convert from UTF-8 to Latin
    911         my $val = Image::ExifTool::UTF82Unicode($$valPtr,'n',$exifTool);
    912         $$valPtr = Image::ExifTool::Unicode2Latin($val,'n',$exifTool);
     988        $exifTool->WarnOnce('Some IPTC characters not converted (ISO 2022 shifting not supported)');
    913989    }
     990}
     991
     992#------------------------------------------------------------------------------
     993# Is this IPTC in a standard location?
     994# Inputs: 0) Current metadata path string
     995# Returns: true if path is standard
     996sub IsStandardIPTC($)
     997{
     998    my $path = shift;
     999    return $path =~ /^(JPEG-APP13-Photoshop-IPTC|TIFF-IFD0-IPTC|PSD-IPTC|MIE-IPTC)$/
    9141000}
    9151001
     
    9281014    my $verbose = $exifTool->Options('Verbose');
    9291015    my $success = 0;
    930     my (%listTags, $lastRec, $recordPtr, $recordName);
    931 
    932     # begin by assuming IPTC is Latin (so no translation if Charset is Latin)
    933     my $xlat = $exifTool->Options('Charset');
    934     undef $xlat if $xlat eq 'Latin';
    935    
     1016    my ($lastRec, $recordPtr, $recordName);
     1017
    9361018    $verbose and $dirInfo and $exifTool->VerboseDir('IPTC', 0, $$dirInfo{DirLen});
     1019
    9371020    if ($tagTablePtr eq \%Image::ExifTool::IPTC::Main) {
     1021        # calculate MD5 if Digest::MD5 is available (for standard IPTC only)
     1022        my $path = $exifTool->MetadataPath();
     1023        if (IsStandardIPTC($path)) {
     1024            my $md5;
     1025            if (eval 'require Digest::MD5') {
     1026                if ($pos or $dirLen != length($$dataPt)) {
     1027                    $md5 = Digest::MD5::md5(substr $$dataPt, $pos, $dirLen);
     1028                } else {
     1029                    $md5 = Digest::MD5::md5($$dataPt);
     1030                }
     1031            } else {
     1032                # a zero digest indicates IPTC exists but we don't have Digest::MD5
     1033                $md5 = "\0" x 16;
     1034            }
     1035            $exifTool->FoundTag('CurrentIPTCDigest', $md5);
     1036        } elsif ($Image::ExifTool::MWG::strict and $$exifTool{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/) {
     1037            # ignore non-standard IPTC while in strict MWG compatibility mode
     1038            $exifTool->Warn("Ignored non-standard IPTC at $path");
     1039            return 1;
     1040        }
     1041        # set family 1 group name if multiple IPTC directories
    9381042        my $dirCount = ($exifTool->{DIR_COUNT}->{IPTC} || 0) + 1;
    9391043        $exifTool->{DIR_COUNT}->{IPTC} = $dirCount;
    9401044        $exifTool->{SET_GROUP1} = '+' . $dirCount if $dirCount > 1;
    9411045    }
     1046    # begin by assuming default IPTC encoding
     1047    my $xlat = $exifTool->Options('CharsetIPTC');
     1048    undef $xlat if $xlat eq $exifTool->Options('Charset');
     1049
    9421050    # quick check for improperly byte-swapped IPTC
    9431051    if ($dirLen >= 4 and substr($$dataPt, $pos, 1) ne "\x1c" and
     
    9671075            my $tableInfo = $tagTablePtr->{$rec};
    9681076            unless ($tableInfo) {
    969                 $exifTool->Warn("Unrecognized IPTC record: $rec");
     1077                $exifTool->Warn("Unrecognized IPTC record $rec, subsequent records ignored");
    9701078                last;   # stop now because we're probably reading garbage
    9711079            }
     
    10101118        my $tagInfo = $exifTool->GetTagInfo($recordPtr, $tag);
    10111119        my $format;
     1120        # (could use $$recordPtr{FORMAT} if no Format below, but don't do this to
     1121        #  be backward compatible with improperly written PhotoMechanic tags)
    10121122        $format = $$tagInfo{Format} if $tagInfo;
    10131123        # use logic to determine format if not specified
     
    10251135                }
    10261136            } elsif ($format =~ /^string/) {
     1137                $val =~ s/\0+$//;   # some braindead softwares add null terminators
    10271138                if ($rec == 1) {
    10281139                    # handle CodedCharacterSet tag
     
    10331144                    TranslateCodedString($exifTool, \$val, \$xlat, 1);
    10341145                }
    1035             } elsif ($format !~ /^digits/) {
     1146            } elsif ($format =~ /^digits/) {
     1147                $val =~ s/\0+$//;
     1148            } elsif ($format !~ /^undef/) {
    10361149                warn("Invalid IPTC format: $format");
    10371150            }
     
    10451158            Start   => $pos,
    10461159            Extra   => ", $recordName record",
     1160            Format  => $format,
    10471161        );
    1048         # prevent adding tags to list from another IPTC directory
    1049         if ($tagInfo) {
    1050             if ($$tagInfo{List}) {
    1051                 $exifTool->{NO_LIST} = 1 unless $listTags{$tagInfo};
    1052                 $listTags{$tagInfo} = 1;    # list the next one we see
    1053             }
    1054             $exifTool->FoundTag($tagInfo, $val);
    1055         }
    1056         delete $exifTool->{NO_LIST};
     1162        $exifTool->FoundTag($tagInfo, $val) if $tagInfo;
    10571163        $success = 1;
    10581164
     
    10841190=head1 AUTHOR
    10851191
    1086 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1192Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    10871193
    10881194This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JPEG.pm

    r16842 r24107  
    1010use strict;
    1111use vars qw($VERSION);
    12 
    13 $VERSION = '1.07';
     12use Image::ExifTool qw(:DataAccess :Utils);
     13
     14$VERSION = '1.13';
     15
     16sub ProcessScalado($$$);
     17sub ProcessOcad($$$);
    1418
    1519# (this main JPEG table is for documentation purposes only)
     
    2832        Condition => '$$valPt =~ /^(II|MM).{4}HEAPJPGM/s',
    2933        SubDirectory => { TagTable => 'Image::ExifTool::CanonRaw::Main' },
     34      }, {
     35        Name => 'AVI1',
     36        Condition => '$$valPt =~ /^AVI1/',
     37        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::AVI1' },
     38      }, {
     39        Name => 'Ocad',
     40        Condition => '$$valPt =~ /^Ocad/',
     41        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::Ocad' },
    3042    }],
    3143    APP1 => [{
     
    3446        SubDirectory => { TagTable => 'Image::ExifTool::Exif::Main' },
    3547      }, {
     48        Name => 'ExtendedXMP',
     49        Condition => '$$valPt =~ m{^http://ns.adobe.com/xmp/extension/\0}',
     50        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     51      }, {
    3652        Name => 'XMP',
    3753        Condition => '$$valPt =~ /^http/ or $$valPt =~ /<exif:/',
    3854        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     55      }, {
     56        Name => 'QVCI',
     57        Condition => '$$valPt =~ /^QVCI\0/',
     58        SubDirectory => { TagTable => 'Image::ExifTool::Casio::QVCI' },
    3959    }],
    4060    APP2 => [{
     
    4666        Condition => '$$valPt =~ /^FPXR\0/',
    4767        SubDirectory => { TagTable => 'Image::ExifTool::FlashPix::Main' },
    48     }],
    49     APP3 => {
     68      }, {
     69        Name => 'MPF',
     70        Condition => '$$valPt =~ /^MPF\0/',
     71        SubDirectory => { TagTable => 'Image::ExifTool::MPF::Main' },
     72      }, {
     73        Name => 'PreviewImage',
     74        Condition => '$$valPt =~ /^\xff\xd8\xff\xdb/',
     75        Notes => 'Samsung large preview',
     76    }],
     77    APP3 => [{
    5078        Name => 'Meta',
    5179        Condition => '$$valPt =~ /^(Meta|META|Exif)\0\0/',
    5280        SubDirectory => { TagTable => 'Image::ExifTool::Kodak::Meta' },
    53     },
     81      }, {
     82        Name => 'Stim',
     83        Condition => '$$valPt =~ /^Stim\0/',
     84        SubDirectory => { TagTable => 'Image::ExifTool::Stim::Main' },
     85      }, {
     86        Name => 'PreviewImage', # (written by HP R837 and Samsung S1060)
     87        Condition => '$$valPt =~ /^\xff\xd8\xff\xdb/',
     88        Notes => 'Hewlett-Packard or Samsung preview image',
     89    }],
     90    APP4 => [{
     91        Name => 'Scalado',
     92        Condition => '$$valPt =~ /^SCALADO\0/',
     93        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::Scalado' },
     94      }, {
     95        Name => 'FPXR', # (non-standard location written by some HP models)
     96        Condition => '$$valPt =~ /^FPXR\0/',
     97        SubDirectory => { TagTable => 'Image::ExifTool::FlashPix::Main' },
     98      }, {
     99        Name => 'PreviewImage', # (written by S1060)
     100        Notes => 'Continued Samsung preview from APP3',
     101    }],
    54102    APP5 => {
    55103        Name => 'RMETA',
     
    57105        SubDirectory => { TagTable => 'Image::ExifTool::Ricoh::RMETA' },
    58106    },
    59     APP6 => {
     107    APP6 => [{
    60108        Name => 'EPPIM',
    61109        Condition => '$$valPt =~ /^EPPIM\0/',
    62110        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::EPPIM' },
    63     },
     111      }, {
     112        Name => 'NITF',
     113        Condition => '$$valPt =~ /^NTIF\0/',
     114        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::NITF' },
     115      }, {
     116        Name => 'HP_TDHD', # (written by R837)
     117        Condition => '$$valPt =~ /^TDHD\x01\0\0\0/',
     118        SubDirectory => { TagTable => 'Image::ExifTool::HP::TDHD' },
     119    }],
    64120    APP8 => {
    65121        Name => 'SPIFF',
     
    104160        # note: flag as writable for documentation, but it won't show up
    105161        # in the TagLookup as writable because there is no WRITE_PROC
    106         Writable => '1',
     162        Writable => 1,
    107163    },
    108164    SOF => {
    109165        Name => 'StartOfFrame',
    110166        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::SOF' },
     167    },
     168    DQT => {
     169        Name => 'DefineQuantizationTable',
     170        Notes => 'used to calculate the Extra:JPEGDigest tag value',
    111171    },
    112172    Trailer => [{
     
    167227        This information is found in APP8 of SPIFF-style JPEG images (the "official"
    168228        yet rarely used JPEG file format standard: Still Picture Interchange File
    169         Format).
     229        Format).  See L<http://www.jpeg.org/public/spiff.pdf> for the official
     230        specification.
    170231    },
    171232    0 => {
     
    294355);
    295356
     357# AVI1 APP0 segment (ref http://www.schnarff.com/file-formats/bmp/BMPDIB.TXT)
     358%Image::ExifTool::JPEG::AVI1 = (
     359    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     360    GROUPS => { 0 => 'APP0', 1 => 'AVI1', 2 => 'Image' },
     361    NOTES => 'This information may be found in APP0 of JPEG image data from AVI videos.',
     362    FIRST_ENTRY => 0,
     363    0 => {
     364        Name => 'InterleavedField',
     365        PrintConv => {
     366            0 => 'Not Interleaved',
     367            1 => 'Odd',
     368            2 => 'Even',
     369        },
     370    },   
     371);
     372
     373# Ocad APP0 segment (ref PH)
     374%Image::ExifTool::JPEG::Ocad = (
     375    PROCESS_PROC => \&ProcessOcad,
     376    GROUPS => { 0 => 'APP0', 1 => 'Ocad', 2 => 'Image' },
     377    FIRST_ENTRY => 0,
     378    NOTES => q{
     379        Tags extracted from the JPEG APP0 "Ocad" segment (found in Photobucket
     380        images).
     381    },
     382    Rev => {
     383        Name => 'OcadRevision',
     384        Format => 'string[6]',
     385    }
     386);
     387
     388# NITF APP6 segment (National Imagery Transmission Format)
     389# ref http://www.gwg.nga.mil/ntb/baseline/docs/n010697/bwcguide25aug98.pdf
     390%Image::ExifTool::JPEG::NITF = (
     391    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     392    GROUPS => { 0 => 'APP6', 1 => 'NITF', 2 => 'Image' },
     393    NOTES => q{
     394        Information in APP6 used by the National Imagery Transmission Format.  See
     395        L<http://www.gwg.nga.mil/ntb/baseline/docs/n010697/bwcguide25aug98.pdf> for
     396        the official specification.
     397    },
     398    0 => {
     399        Name => 'NITFVersion',
     400        Format => 'int8u[2]',
     401        ValueConv => 'sprintf("%d.%.2d", split(" ",$val))',
     402    },
     403    2 => {
     404        Name => 'ImageFormat',
     405        ValueConv => 'chr($val)',
     406        PrintConv => { B => 'IMode B' },
     407    },
     408    3 => {
     409        Name => 'BlocksPerRow',
     410        Format => 'int16u',
     411    },
     412    5 => {
     413        Name => 'BlocksPerColumn',
     414        Format => 'int16u',
     415    },
     416    7 => {
     417        Name => 'ImageColor',
     418        PrintConv => { 0 => 'Monochrome' },
     419    },
     420    8 => 'BitDepth',
     421    9 => {
     422        Name => 'ImageClass',
     423        PrintConv => {
     424            0 => 'General Purpose',
     425            4 => 'Tactical Imagery',
     426        },
     427    },
     428    10 => {
     429        Name => 'JPEGProcess',
     430        PrintConv => {
     431            1 => 'Baseline sequential DCT, Huffman coding, 8-bit samples',
     432            4 => 'Extended sequential DCT, Huffman coding, 12-bit samples',
     433        },
     434    },
     435    11 => 'Quality',
     436    12 => {
     437        Name => 'StreamColor',
     438        PrintConv => { 0 => 'Monochrome' },
     439    },
     440    13 => 'StreamBitDepth',
     441    14 => {
     442        Name => 'Flags',
     443        Format => 'int32u',
     444        PrintConv => 'sprintf("0x%x", $val)',
     445    },
     446);
     447
     448# information written by Scalado software (PhotoFusion maybe?)
     449%Image::ExifTool::JPEG::Scalado = (
     450    GROUPS => { 0 => 'APP4', 1 => 'Scalado', 2 => 'Image' },
     451    PROCESS_PROC => \&ProcessScalado,
     452    TAG_PREFIX => 'Scalado',
     453    FORMAT => 'int32s',
     454    # I presume this was written by
     455    NOTES => q{
     456        Tags extracted from the JPEG APP4 "SCALADO" segment (presumably written by
     457        Scalado mobile software, L<http://www.scalado.com/>).
     458    },
     459    SPMO => {
     460        Name => 'DataLength',
     461        Unkown => 1,
     462    },
     463    WDTH => {
     464        Name => 'PreviewImageWidth',
     465        ValueConv => '$val ? abs($val) : undef',
     466    },
     467    HGHT => {
     468        Name => 'PreviewImageHeight',
     469        ValueConv => '$val ? abs($val) : undef',
     470    },
     471    QUAL => {
     472        Name => 'PreviewQuality',
     473        ValueConv => '$val ? abs($val) : undef',
     474    },
     475    # tags not yet decoded with observed values:
     476    # CHKH: 0, -9010
     477    # CHKL: -2664, -12852
     478    # CLEN: -1024
     479    # CSPC: -2232593
     480    # DATA: (+ve data length)
     481    # HDEC: 0
     482    # MAIN: 0
     483    # SCI0: (+ve data length)
     484    # SCX1: (+ve data length)
     485    # WDEC: 0
     486);
     487
     488#------------------------------------------------------------------------------
     489# Extract information from the JPEG APP0 Ocad segment
     490# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     491# Returns: 1 on success
     492sub ProcessOcad($$$)
     493{
     494    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     495    my $dataPt = $$dirInfo{DataPt};
     496    $exifTool->VerboseDir('APP0 Ocad', undef, length $$dataPt);
     497    for (;;) {
     498        last unless $$dataPt =~ /\$(\w+):([^\0\$]+)/g;
     499        my ($tag, $val) = ($1, $2);
     500        $val =~ s/(^\s+|\s+$)//g;   # remove leading/trailing spaces
     501        unless ($$tagTablePtr{$tag}) {
     502            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => "Ocad_$tag" });
     503        }
     504        $exifTool->HandleTag($tagTablePtr, $tag, $val);
     505    }
     506    return 1;
     507}
     508
     509#------------------------------------------------------------------------------
     510# Extract information from the JPEG APP4 SCALADO segment
     511# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     512# Returns: 1 on success
     513sub ProcessScalado($$$)
     514{
     515    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     516    my $dataPt = $$dirInfo{DataPt};
     517    my $pos = 0;
     518    my $end = length $$dataPt;
     519    SetByteOrder('MM');
     520    $exifTool->VerboseDir('APP4 SCALADO', undef, $end);
     521    for (;;) {
     522        last if $pos + 12 > $end;
     523        my $tag = substr($$dataPt, $pos, 4);
     524        my $unk = Get32u($dataPt, $pos + 4); # (what is this?)
     525        $exifTool->HandleTag($tagTablePtr, $tag, undef,
     526            DataPt  => $dataPt,
     527            Start   => $pos + 8,
     528            Size    => 4,
     529            Extra   => ", unk $unk",
     530        );
     531        # shorten directory size by length of SPMO
     532        $end -= Get32u($dataPt, $pos + 8) if $tag eq 'SPMO';
     533        $pos += 12;
     534    }
     535    return 1;
     536}
     537
    2965381;  # end
    297539
     
    314556=head1 AUTHOR
    315557
    316 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     558Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    317559
    318560This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JVC.pm

    r16842 r24107  
    1313use Image::ExifTool::Exif;
    1414
    15 $VERSION = '1.01';
     15$VERSION = '1.02';
    1616
    1717sub ProcessJVCText($$$);
     
    2424    NOTES => 'JVC EXIF maker note tags.',
    2525    #0x0001 - almost always '2', but '3' for GR-DV700 samples
    26     0x0002 => 'CPUVersions', #PH
     26    0x0002 => { #PH
     27        Name => 'CPUVersions',
     28        # remove trailing nulls/spaces and split at remaining nulls/spaces
     29        ValueConv => '$_=$val; s/(\s*\0)+$//; s/(\s*\0)+/, /g; $_',
     30    },
    2731    0x0003 => { #PH
    2832        Name => 'Quality',
     
    7276        return 0;
    7377    }
    74     my $pos = 0;
    7578    while ($data =~ m/([A-Z]+):(.{3,4})/sg) {
    7679        my ($tag, $val) = ($1, $2);
     
    114117=head1 AUTHOR
    115118
    116 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     119Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    117120
    118121This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Jpeg2000.pm

    r16842 r24107  
    1717use Image::ExifTool qw(:DataAccess :Utils);
    1818
    19 $VERSION = '1.12';
     19$VERSION = '1.16';
    2020
    2121sub ProcessJpeg2000Box($$$);
     
    3939    IFD0         => 'UUID-EXIF',
    4040    XMP          => 'UUID-XMP',
     41   'UUID-IPTC'   => 'JP2',
     42   'UUID-EXIF'   => 'JP2',
     43   'UUID-XMP'    => 'JP2',
    4144  # jp2h         => 'JP2',  (not yet functional)
    4245  # ICC_Profile  => 'jp2h', (not yet functional)
     
    6164);
    6265
    63 # JPEG 2000 "box" (ie. segment) names
     66# JPEG 2000 "box" (ie. atom) names
    6467%Image::ExifTool::Jpeg2000::Main = (
    6568    GROUPS => { 2 => 'Image' },
     
    7376   "jP\x1a\x1a" => 'JP2Signature', # (ref 2)
    7477    prfl => 'Profile',
    75     ftyp => { Name => 'FileType', Priority => 0 },
     78    ftyp => {
     79        Name => 'FileType',
     80        SubDirectory => { TagTable => 'Image::ExifTool::Jpeg2000::FileType' },
     81    },
    7682    rreq => 'ReaderRequirements',
    7783    jp2h => {
     
    192198                ProcessProc => \&Image::ExifTool::ProcessTIFF,
    193199                WriteProc => \&Image::ExifTool::WriteTIFF,
     200                DirName => 'EXIF',
    194201                Start => '$valuePtr + 16',
    195202            },
     
    274281            8 => 'JBIG2',
    275282        },
     283    },
     284);
     285
     286# (ref fcd15444-1/2/6.pdf)
     287# (also see http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html)
     288%Image::ExifTool::Jpeg2000::FileType = (
     289    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     290    GROUPS => { 2 => 'Video' },
     291    FORMAT => 'int32u',
     292    0 => {
     293        Name => 'MajorBrand',
     294        Format => 'undef[4]',
     295        PrintConv => {
     296            'jp2 ' => 'JPEG 2000 Image (.JP2)',           # image/jp2
     297            'jpm ' => 'JPEG 2000 Compound Image (.JPM)',  # image/jpm
     298            'jpx ' => 'JPEG 2000 with extensions (.JPX)', # image/jpx
     299        },
     300    },
     301    1 => {
     302        Name => 'MinorVersion',
     303        Format => 'undef[4]',
     304        ValueConv => 'sprintf("%x.%x.%x", unpack("nCC", $val))',
     305    },
     306    2 => {
     307        Name => 'CompatibleBrands',
     308        Format => 'undef[$size-8]',
     309        # ignore any entry with a null, and return others as a list
     310        ValueConv => 'my @a=($val=~/.{4}/sg); @a=grep(!/\0/,@a); \@a',
    276311    },
    277312);
     
    344379            my $tagTable = GetTagTable($$subdir{TagTable});
    345380            my %dirInfo = (
    346                 DirName => $dirName,
     381                DirName => $$subdir{DirName} || $dirName,
    347382                Parent => 'JP2',
    348383            );
     
    464499        if (defined $tagInfo and not $tagInfo) {
    465500            # GetTagInfo() required the value for a Condition
    466             my $tmpVal = substr($$dataPt, $valuePtr, $boxLen < 48 ? $boxLen : 48);
     501            my $tmpVal = substr($$dataPt, $valuePtr, $boxLen < 128 ? $boxLen : 128);
    467502            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $boxID, \$tmpVal);
    468503        }
     
    497532                DirStart => $subdirStart,
    498533                DirLen => $subdirLen,
    499                 DirName => $$tagInfo{Name},
     534                DirName => $$subdir{DirName} || $$tagInfo{Name},
    500535                OutFile => $outfile,
    501536                Base => $dataPos + $subdirStart,
     
    555590    my $raf = $$dirInfo{RAF};
    556591    my $outfile = $$dirInfo{OutFile};
    557     my $rtnVal = 0;
    558592    my $hdr;
    559593
     
    570604        $$exifTool{AddJp2Dirs} = \%addDirs;
    571605    } else {
    572         $exifTool->SetFileType();
     606        my ($buff, $fileType);
     607        # recognize JPX and JPM as unique types of JP2
     608        if ($raf->Read($buff, 12) == 12 and $buff =~ /^.{4}ftyp(.{4})/s) {
     609            $fileType = 'JPX' if $1 eq 'jpx ';
     610            $fileType = 'JPM' if $1 eq 'jpm ';
     611        }
     612        $raf->Seek(-length($buff), 1) if defined $buff;
     613        $exifTool->SetFileType($fileType);
    573614    }
    574615    SetByteOrder('MM'); # JPEG 2000 files are big-endian
     
    601642=head1 AUTHOR
    602643
    603 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     644Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    604645
    605646This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Kodak.pm

    r16842 r24107  
    88# References:   1) http://search.cpan.org/dist/Image-MetaData-JPEG/
    99#               2) http://www.ozhiker.com/electronics/pjmt/jpeg_info/meta.html
     10#               3) http://www.cybercom.net/~dcoffin/dcraw/
    1011#
    1112# Notes:        There really isn't much public information about Kodak formats.
     
    2223use Image::ExifTool::Exif;
    2324
    24 $VERSION = '1.10';
     25$VERSION = '1.27';
    2526
    2627sub ProcessKodakIFD($$$);
     28sub ProcessKodakText($$$);
    2729sub WriteKodakIFD($$$);
    2830
     
    103105        Name => 'MeteringMode',
    104106        PrintConv => { #PH
    105             0 => 'Multi-pattern',
    106             1 => 'Center-Weighted',
     107            0 => 'Multi-segment',
     108            1 => 'Center-weighted average',
    107109            2 => 'Spot',
    108110        },
     
    121123        ValueConvInv => '$val * 1e5',
    122124        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    123         PrintConvInv => 'eval $val',
     125        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    124126    },
    125127    0x24 => {
     
    129131        ValueConvInv => '$val * 1000',
    130132        PrintConv => '$val > 0 ? "+$val" : $val',
    131         PrintConvInv => 'eval $val',
     133        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    132134    },
    133135    0x26 => {
     
    255257        Name => 'Sharpness',
    256258        Format => 'int8s',
    257         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    258         PrintConvInv => '$val=~/normal/i ? 0 : $val',
     259        %Image::ExifTool::Exif::printParameter,
    259260    },
    260261);
     
    329330        Name => 'Sharpness',
    330331        Format => 'int8s',
    331         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    332         PrintConvInv => '$val=~/normal/i ? 0 : $val',
     332        %Image::ExifTool::Exif::printParameter,
    333333    },
    334334    0x38 => {
     
    338338        ValueConvInv => '$val * 1e5',
    339339        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    340         PrintConvInv => 'eval $val',
     340        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    341341    },
    342342    0x3c => {
     
    383383        ValueConvInv => '$val * 1e5',
    384384        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    385         PrintConvInv => 'eval $val',
     385        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    386386    },
    387387    0x1a => {
     
    447447        ValueConvInv => '$val * 1e5',
    448448        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    449         PrintConvInv => 'eval $val',
     449        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    450450    },
    451451    0x14 => {
     
    511511
    512512# Kodak IFD-format maker notes (ref PH)
    513 %Image::ExifTool::Kodak::IFD = (
     513%Image::ExifTool::Kodak::Type8 = (
    514514    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
    515515    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
    516516    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    517517    NOTES => q{
    518         Newer Kodak models such as the P712, P850, P880, Z612 and Z712 use standard
    519         TIFF IFD format for the maker notes.  There is a large amount of information
    520         stored in these maker notes (with apparently much duplication), but
    521         relatively few tags have so far been decoded.
    522     },
    523     0xfc00 => {
     518        Kodak models such as the ZD710, P712, P850, P880, V1233, V1253, V1275,
     519        V1285, Z612, Z712, Z812, Z885 use standard TIFF IFD format for the maker
     520        notes.  In keeping with Kodak's strategy of inconsistent makernotes, models
     521        such as the M380, M1033, M1093, V1073, V1273, Z1012, Z1085 and Z8612
     522        also use these tags, but these makernotes begin with a TIFF header instead
     523        of an IFD entry count and use relative instead of absolute offsets.  There
     524        is a large amount of information stored in these maker notes (apparently
     525        with much duplication), but relatively few tags have so far been decoded.
     526    },
     527    0xfc00 => [{
    524528        Name => 'SubIFD0',
    525         Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
     529        Condition => '$format eq "undef"',
     530        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
     531        NestedHtmlDump => 2, # (so HtmlDump doesn't show these as double-referenced)
     532        SubDirectory => {
     533            TagTable => 'Image::ExifTool::Kodak::SubIFD0',
     534            Base => '$start',
     535            ProcessProc => \&ProcessKodakIFD,
     536            WriteProc => \&WriteKodakIFD,
     537        },
     538    },{
     539        Name => 'SubIFD0',
     540        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
    526541        Flags => 'SubIFD',
    527542        SubDirectory => {
    528543            TagTable => 'Image::ExifTool::Kodak::SubIFD0',
    529544            Start => '$val',
    530         },
    531     },
     545            # (odd but true: the Base for this SubIFD is different than 0xfc01-0xfc06)
     546        },
     547    }],
    532548    # SubIFD1 and higher data is preceded by a TIFF byte order mark to indicate
    533     # the byte ordering used
    534     0xfc01 => {
     549    # the byte ordering used.  Beginning with the M580, these subdirectories are
     550    # stored as 'undef' data rather than as a standard EXIF SubIFD.
     551    0xfc01 => [{
    535552        Name => 'SubIFD1',
    536         Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
     553        Condition => '$format eq "undef"',
     554        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
     555        NestedHtmlDump => 2,
     556        SubDirectory => {
     557            TagTable => 'Image::ExifTool::Kodak::SubIFD1',
     558            Base => '$start',
     559        },
     560    },{
     561        Name => 'SubIFD1',
     562        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
     563        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
    537564        Flags => 'SubIFD',
    538565        SubDirectory => {
     
    541568            Base => '$start',
    542569        },
    543     },
    544     0xfc02 => {
     570    }],
     571    0xfc02 => [{
    545572        Name => 'SubIFD2',
    546         Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
     573        Condition => '$format eq "undef"',
     574        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
     575        NestedHtmlDump => 2,
     576        SubDirectory => {
     577            TagTable => 'Image::ExifTool::Kodak::SubIFD2',
     578            Base => '$start',
     579        },
     580    },{
     581        Name => 'SubIFD2',
     582        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
     583        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
    547584        Flags => 'SubIFD',
    548585        SubDirectory => {
     
    551588            Base => '$start',
    552589        },
    553     },
    554     0xfc03 => {
     590    }],
     591    0xfc03 => [{
    555592        Name => 'SubIFD3',
    556         Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
     593        Condition => '$format eq "undef"',
     594        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
     595        NestedHtmlDump => 2,
     596        SubDirectory => {
     597            TagTable => 'Image::ExifTool::Kodak::SubIFD3',
     598            Base => '$start',
     599        },
     600    },{
     601        Name => 'SubIFD3',
     602        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
     603        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
    557604        Flags => 'SubIFD',
    558605        SubDirectory => {
     
    561608            Base => '$start',
    562609        },
    563     },
     610    }],
    564611    # (SubIFD4 has the pointer zeroed in my samples, but support it
    565612    # in case it is used by future models -- ignored if pointer is zero)
    566     0xfc04 => {
     613    0xfc04 => [{
    567614        Name => 'SubIFD4',
    568         Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
     615        Condition => '$format eq "undef"',
     616        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
     617        NestedHtmlDump => 2,
     618        SubDirectory => {
     619            TagTable => 'Image::ExifTool::Kodak::SubIFD4',
     620            Base => '$start',
     621        },
     622    },{
     623        Name => 'SubIFD4',
     624        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
     625        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
    569626        Flags => 'SubIFD',
    570627        SubDirectory => {
     
    573630            Base => '$start',
    574631        },
    575     },
    576     0xfc05 => {
     632    }],
     633    0xfc05 => [{
    577634        Name => 'SubIFD5',
    578         Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
     635        Condition => '$format eq "undef"',
     636        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
     637        NestedHtmlDump => 2,
     638        SubDirectory => {
     639            TagTable => 'Image::ExifTool::Kodak::SubIFD5',
     640            Base => '$start',
     641        },
     642    },{
     643        Name => 'SubIFD5',
     644        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
     645        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
    579646        Flags => 'SubIFD',
    580647        SubDirectory => {
     
    583650            Base => '$start',
    584651        },
     652    }],
     653    0xfc06 => [{ # new for the M580
     654        Name => 'SubIFD6',
     655        Condition => '$format eq "undef"',
     656        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
     657        NestedHtmlDump => 2,
     658        SubDirectory => {
     659            TagTable => 'Image::ExifTool::Kodak::SubIFD6',
     660            Base => '$start',
     661        },
     662    },{
     663        Name => 'SubIFD6',
     664        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
     665        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
     666        Flags => 'SubIFD',
     667        SubDirectory => {
     668            TagTable => 'Image::ExifTool::Kodak::SubIFD6',
     669            Start => '$val',
     670            Base => '$start',
     671        },
     672    }],
     673    0xfcff => {
     674        Name => 'SubIFD255',
     675        Condition => '$format eq "undef"',
     676        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
     677        NestedHtmlDump => 2,
     678        SubDirectory => {
     679            TagTable => 'Image::ExifTool::Kodak::SubIFD0',
     680            # (uses the same Base as the main MakerNote IFD)
     681        },
    585682    },
    586683    0xff00 => {
    587684        Name => 'CameraInfo',
    588         Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
     685        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
     686        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
    589687        Flags => 'SubIFD',
    590688        SubDirectory => {
    591689            TagTable => 'Image::ExifTool::Kodak::CameraInfo',
    592690            Start => '$val',
    593         },
    594     },
     691            # (uses the same Base as the main MakerNote IFD)
     692        },
     693    },
     694);
     695
     696# Kodak type 9 maker notes (ref PH)
     697%Image::ExifTool::Kodak::Type9 = (
     698    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     699    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     700    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     701    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     702    WRITABLE => 1,
     703    FIRST_ENTRY => 0,
     704    NOTES => q{
     705        These tags are used by the Kodak C140, C180, C913, C1013, M320, M340 and
     706        M550, as well as various cameras marketed by other manufacturers.
     707    },
     708    0x0c => [
     709        {
     710            Name => 'FNumber',
     711            Condition => '$$self{Make} =~ /Kodak/i',
     712            Format => 'int16u',
     713            ValueConv => '$val / 100',
     714            ValueConvInv => 'int($val * 100 + 0.5)',
     715        },{
     716            Name => 'FNumber',
     717            Format => 'int16u',
     718            ValueConv => '$val / 10',
     719            ValueConvInv => 'int($val * 10 + 0.5)',
     720        },
     721    ],
     722    0x10 => {
     723        Name => 'ExposureTime',
     724        Format => 'int32u',
     725        ValueConv => '$val / 1e6',
     726        ValueConvInv => '$val * 1e6',
     727        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     728        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     729    },
     730    0x14 => {
     731        Name => 'DateTimeOriginal',
     732        Description => 'Date/Time Original',
     733        Groups => { 2 => 'Time' },
     734        Format => 'string[20]',
     735        Shift => 'Time',
     736        ValueConv => '$val=~s{/}{:}g; $val',
     737        ValueConvInv => '$val=~s{^(\d{4}):(\d{2}):}{$1/$2/}; $val',
     738        PrintConv => '$self->ConvertDateTime($val)',
     739        PrintConvInv => '$self->InverseDateTime($val,0)',
     740    },
     741    0x34 => {
     742        Name => 'ISO',
     743        Format => 'int16u',
     744    },
     745    0x57 => {
     746        Name => 'FirmwareVersion',
     747        Condition => '$$self{Make} =~ /Kodak/i',
     748        Format => 'string[16]',
     749        Notes => 'Kodak only',
     750    },
     751    0xa8 => { # (not confirmed)
     752        Name => 'SerialNumber',
     753        Condition => '$$self{Make} =~ /Kodak/i',
     754        Format => 'string[12]',
     755        Notes => 'Kodak only',
     756    },
     757);
     758
     759# more Kodak IFD-format maker notes (ref PH)
     760%Image::ExifTool::Kodak::Type10 = (
     761    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     762    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     763    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     764    PRIORITY => 0,
     765    NOTES => q{
     766        Another variation of the IFD-format type, this time with just a byte order
     767        indicator instead of a full TIFF header.  These tags are used by the Z980.
     768    },
     769    # 0x01 int16u - always 0
     770    0x02 => {
     771        Name => 'PreviewImageSize',
     772        Writable => 'int16u',
     773        Count => 2,
     774    },
     775    # 0x03 int32u - ranges from about 33940 to 40680
     776    # 0x04 int32u - always 18493
     777    # 0x06 undef[4] - 07 d9 04 11
     778    # 0x07 undef[3] - varies
     779    # 0x08 int16u - 1 (mostly), 2
     780    # 0x09 int16u - 255
     781    # 0x0b int16u[2] - '0 0' (mostly), '20 0', '21 0', '1 0'
     782    # 0x0c int16u - 1 (mostly), 3, 259, 260
     783    # 0x0d int16u - 0
     784    # 0x0e int16u - 0, 1, 2 (MeteringMode? 0=Partial, 1,2=Multi)
     785    # 0x0f int16u - 0, 5 (MeteringMode? 0=Multi, 5=Partial)
     786    # 0x10 int16u - ranges from about 902 to 2308
     787    0x12 => {
     788        Name => 'ExposureTime',
     789        Writable => 'int32u',
     790        ValueConv => '$val / 1e5',
     791        ValueConvInv => '$val * 1e5',
     792        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     793        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     794    },
     795    0x13 => {
     796        Name => 'FNumber',
     797        Writable => 'int16u',
     798        ValueConv => '$val / 10',
     799        ValueConvInv => '$val * 10',
     800    },
     801    0x14 => {
     802        Name => 'ISO',
     803        Writable => 'int16u',
     804        ValueConv => 'exp($val/3*log(2))*25',
     805        ValueConvInv => '3*log($val/25)/log(2)',
     806        PrintConv => 'int($val + 0.5)',
     807        PrintConvInv => '$val',
     808    },
     809    # 0x15 int16u - 18-25 (SceneMode? 21=auto, 24=Aperture Priority, 19=high speed)
     810    # 0x16 int16u - 50
     811    # 0x17 int16u - 0, 65535 (MeteringMode? 0=Multi, 65535=Partial)
     812    # 0x19 int16u - 0, 4 (WhiteBalance? 0=Auto, 4=Manual)
     813    # 0x1a int16u - 0, 65535
     814    # 0x1b int16u - 416-696
     815    # 0x1c int16u - 251-439 (low when 0x1b is high)
     816    0x1d => {
     817        Name => 'FocalLength',
     818        Writable => 'int32u',
     819        ValueConv => '$val / 100',
     820        ValueConvInv => '$val * 100',
     821        PrintConv => '"$val mm"',
     822        PrintConvInv => '$val=~s/\s*mm//;$val',
     823    },
     824    # 0x1e int16u - 100
     825    # 0x1f int16u - 0, 1
     826    # 0x20,0x21 int16u - 1
     827    # 0x27 undef[4] - fe ff ff ff
     828    # 0x32 undef[4] - 00 00 00 00
     829    # 0x61 int32u[2] - '0 0' or '34050 0'
     830    # 0x62 int8u - 0, 1
     831    # 0x63 int8u - 1
     832    # 0x64,0x65 int8u - 0, 1, 2
     833    # 0x66 int32u - 0
     834    # 0x67 int32u - 3
     835    # 0x68 int32u - 0
     836    # 0x3fe undef[2540]
    595837);
    596838
     
    600842    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
    601843    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    602     NOTES => 'SubIFD0 through SubIFD5 tags are used by the Z612 and Z712.',
     844    NOTES => 'SubIFD0 through SubIFD5 tags are written a number of newer Kodak models.',
    603845    0xfa02 => {
    604846        Name => 'SceneMode',
    605847        Writable => 'int16u',
     848        Notes => 'may not be valid for some models', # ie. M580?
    606849        PrintConv => {
    607850            1 => 'Sport',
     
    667910        ValueConvInv => '$val * 1e5',
    668911        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    669         PrintConvInv => 'eval $val',
     912        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    670913    },
    671914    0xfa2e => {
     
    8101053        ValueConvInv => '$val * 1e6',
    8111054        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    812         PrintConvInv => 'eval $val',
     1055        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    8131056    },
    8141057    0xf105 => {
     
    8371080    # 0x1002 - related to focal length (1=wide, 32=full zoom)
    8381081    # 0x1006 - pictures remaining? (gradually decreases as pictures are taken)
     1082#
     1083# the following unknown Kodak tags in subIFD3 may store an IFD count of 0 or 1 instead
     1084# of the correct value (which changes from model to model).  This bad count is fixed
     1085# with the "FixCount" patch.  Models known to have this problem include:
     1086# M380, M1033, M1093IS, V1073, V1233, V1253, V1273, V1275, V1285, Z612, Z712,
     1087# Z812, Z885, Z915, Z950, Z1012IS, Z1085IS, ZD710
     1088#
     1089    0x2007 => {
     1090        Name => 'Kodak_SubIFD3_0x2007',
     1091        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1092    },
     1093    0x2008 => {
     1094        Name => 'Kodak_SubIFD3_0x2008',
     1095        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1096    },
     1097    0x2009 => {
     1098        Name => 'Kodak_SubIFD3_0x2009',
     1099        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1100    },
     1101    0x200a => {
     1102        Name => 'Kodak_SubIFD3_0x200a',
     1103        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1104    },
     1105    0x200b => {
     1106        Name => 'Kodak_SubIFD3_0x200b',
     1107        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1108    },
     1109    0x3020 => {
     1110        Name => 'Kodak_SubIFD3_0x3020',
     1111        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1112    },
     1113    0x3030 => {
     1114        Name => 'Kodak_SubIFD3_0x3030',
     1115        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1116    },
     1117    0x3040 => {
     1118        Name => 'Kodak_SubIFD3_0x3040',
     1119        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1120    },
     1121    0x3050 => {
     1122        Name => 'Kodak_SubIFD3_0x3050',
     1123        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1124    },
     1125    0x3060 => {
     1126        Name => 'Kodak_SubIFD3_0x3060',
     1127        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1128    },
     1129    0x8001 => {
     1130        Name => 'Kodak_SubIFD3_0x8001',
     1131        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1132    },
     1133    0x8002 => {
     1134        Name => 'Kodak_SubIFD3_0x8002',
     1135        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1136    },
     1137    0x8003 => {
     1138        Name => 'Kodak_SubIFD3_0x8003',
     1139        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1140    },
     1141    0x8004 => {
     1142        Name => 'Kodak_SubIFD3_0x8004',
     1143        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1144    },
     1145    0x8005 => {
     1146        Name => 'Kodak_SubIFD3_0x8005',
     1147        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1148    },
     1149    0x8006 => {
     1150        Name => 'Kodak_SubIFD3_0x8006',
     1151        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1152    },
     1153    0x8007 => {
     1154        Name => 'Kodak_SubIFD3_0x8007',
     1155        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1156    },
     1157    0x8008 => {
     1158        Name => 'Kodak_SubIFD3_0x8008',
     1159        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1160    },
     1161    0x8009 => {
     1162        Name => 'Kodak_SubIFD3_0x8009',
     1163        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1164    },
     1165    0x800a => {
     1166        Name => 'Kodak_SubIFD3_0x800a',
     1167        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1168    },
     1169    0x800b => {
     1170        Name => 'Kodak_SubIFD3_0x800b',
     1171        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1172    },
     1173    0x800c => {
     1174        Name => 'Kodak_SubIFD3_0x800c',
     1175        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
     1176    },
    8391177);
    8401178
     
    8611199        PrintConvInv => '$val=~s/ ?x//; $val',
    8621200    },
     1201);
     1202
     1203# Kodak SubIFD6 tags (ref PH)
     1204%Image::ExifTool::Kodak::SubIFD6 = (
     1205    PROCESS_PROC => \&ProcessKodakIFD,
     1206    WRITE_PROC => \&WriteKodakIFD,
     1207    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     1208    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     1209    NOTES => 'SubIFD6 is written by the M580.',
    8631210);
    8641211
     
    9211268        ValueConvInv => '$val * 1e6',
    9221269        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    923         PrintConvInv => 'eval $val',
     1270        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    9241271    },
    9251272    0xfd06 => {
     
    9351282    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    9361283    FIRST_ENTRY => 0,
     1284);
     1285
     1286# tags found in the KodakIFD (in IFD0 of KDC, DCR, TIFF and JPEG images) (ref PH)
     1287%Image::ExifTool::Kodak::IFD = (
     1288    GROUPS => { 0 => 'MakerNotes', 1 => 'KodakIFD', 2 => 'Image'},
     1289    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     1290    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     1291    WRITE_GROUP => 'KodakIFD',
     1292    SET_GROUP1 => 1,
     1293    NOTES => q{
     1294        These tags are found in a separate IFD of JPEG, TIFF, DCR and KDC images
     1295        from some older Kodak models such as the DC50, DC120, DCS760C, DCS Pro 14N,
     1296        14nx, SLR/n, Pro Back and Canon EOS D2000.
     1297    },
     1298    # 0x0000: int8u[4]    - values: "1 0 0 0" (DC50), "1 1 0 0" (DC120)
     1299    0x0001 => {
     1300        # (related to EV but exact meaning unknown)
     1301        Name => 'UnknownEV',
     1302        Writable => 'rational64u',
     1303        Unknown => 1,
     1304    },
     1305    # 0x0002: int8u       - values: 0
     1306    0x0003 => {
     1307        Name => 'ExposureValue',
     1308        Writable => 'rational64u',
     1309    },
     1310    # 0x0004: rational64u - values: 2.875,3.375,3.625,4,4.125,7.25
     1311    # 0x0005: int8u       - values: 0
     1312    # 0x0006: int32u[12]  - ?
     1313    # 0x0007: int32u[3]   - values: "65536 67932 69256"
     1314    0x03e9 => { Name => 'OriginalFileName', Writable => 'string' },
     1315    0x03eb => 'SensorLeftBorder',
     1316    0x03ec => 'SensorTopBorder',
     1317    0x03ed => 'SensorImageWidth',
     1318    0x03ee => 'SensorImageHeight',
     1319    0x03f1 => {
     1320        Name => 'TextualInfo',
     1321        SubDirectory => {
     1322            TagTable => 'Image::ExifTool::Kodak::TextualInfo',
     1323        },
     1324    },
     1325    0x03fc => { #3
     1326        Name => 'WhiteBalance',
     1327        Writable => 'int16u',
     1328        Priority => 0,
     1329        PrintConv => { },   # no values yet known
     1330    },
     1331    0x03fd => { #3
     1332        Name => 'Processing',
     1333        Condition => '$count == 72',
     1334        SubDirectory => {
     1335            TagTable => 'Image::ExifTool::Kodak::Processing',
     1336        },
     1337    },
     1338    0x0401 => {
     1339        Name => 'Time',
     1340        Groups => { 2 => 'Time' },
     1341        Writable => 'string',
     1342    },
     1343    0x0414 => { Name => 'NCDFileInfo',      Writable => 'string' },
     1344    0x0846 => { #3
     1345        Name => 'ColorTemperature',
     1346        Writable => 'int16u',
     1347    },
     1348    0x0852 => 'WB_RGBMul0', #3
     1349    0x0853 => 'WB_RGBMul1', #3
     1350    0x0854 => 'WB_RGBMul2', #3
     1351    0x0855 => 'WB_RGBMul3', #3
     1352    0x085c => { Name => 'WB_RGBCoeffs0', Binary => 1 }, #3
     1353    0x085d => { Name => 'WB_RGBCoeffs1', Binary => 1 }, #3
     1354    0x085e => { Name => 'WB_RGBCoeffs2', Binary => 1 }, #3
     1355    0x085f => { Name => 'WB_RGBCoeffs3', Binary => 1 }, #3
     1356    # 0x090d: linear table (ref 3)
     1357    # 0x0c81: some sort of date (manufacture date?) - PH
     1358    0x0ce5 => { Name => 'FirmwareVersion',  Writable => 'string' },
     1359    # 0x1390: value: "DCSProSLRn" (tone curve name?) - PH
     1360    0x1391 => { Name => 'ToneCurveFileName',Writable => 'string' },
     1361    0x1784 => { Name => 'ISO',              Writable => 'int32u' }, #3
     1362);
     1363
     1364# contains WB adjust set in software (ref 3)
     1365%Image::ExifTool::Kodak::Processing = (
     1366    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     1367    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1368    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     1369    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     1370    FORMAT => 'int16u',
     1371    FIRST_ENTRY => 0,
     1372    20 => {
     1373        Name => 'WB_RGBLevels',
     1374        Format => 'int16u[3]',
     1375        ValueConv => q{
     1376            my @a = split ' ',$val;
     1377            foreach (@a) {
     1378                $_ = 2048 / $_ if $_;
     1379            }
     1380            return join ' ', @a;
     1381        }
     1382    },
     1383);
     1384
     1385# tags found in the Kodak KDC_IFD (in IFD0 of KDC images) (ref 3)
     1386%Image::ExifTool::Kodak::KDC_IFD = (
     1387    GROUPS => { 0 => 'MakerNotes', 1 => 'KDC_IFD', 2 => 'Image'},
     1388    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     1389    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     1390    WRITE_GROUP => 'KDC_IFD',
     1391    SET_GROUP1 => 1,
     1392    NOTES => q{
     1393        These tags are found in a separate IFD of KDC images from some newer Kodak
     1394        models such as the P880 and Z1015IS.
     1395    },
     1396    0xfa00 => {
     1397        Name => 'SerialNumber', #PH (unverified)
     1398        Writable => 'string',
     1399    },
     1400    0xfa0d => {
     1401        Name => 'WhiteBalance',
     1402        Writable => 'int8u',
     1403        PrintConv => { #PH
     1404            0 => 'Auto',
     1405            1 => 'Fluorescent', # (NC)
     1406            2 => 'Tungsten', # (NC)
     1407            3 => 'Daylight', # (NC)
     1408            6 => 'Shade', # (NC, called "Open Shade" by Kodak)
     1409        },
     1410    },
     1411    # the following tags are numbered for use in the Composite tag lookup
     1412    0xfa25 => 'WB_RGBLevelsAuto',
     1413    0xfa27 => 'WB_RGBLevelsTungsten', # (NC)
     1414    0xfa28 => 'WB_RGBLevelsFluorescent', # (NC)
     1415    0xfa29 => 'WB_RGBLevelsDaylight', # (NC)
     1416    0xfa2a => 'WB_RGBLevelsShade', # (NC)
     1417);
     1418
     1419# textual-based Kodak TextualInfo tags (not found in KDC images) (ref PH)
     1420%Image::ExifTool::Kodak::TextualInfo = (
     1421    GROUPS => { 0 => 'MakerNotes', 1 => 'Kodak', 2 => 'Image'},
     1422    PROCESS_PROC => \&ProcessKodakText,
     1423    NOTES => q{
     1424        Below is a list of tags which have been observed in the Kodak TextualInfo
     1425        data, however ExifTool will extract information from any tags found here.
     1426    },
     1427    'Actual Compensation' => 'ActualCompensation',
     1428    'AF Function'   => 'AFMode', # values: "S" (=Single?, then maybe C for Continuous, M for Manual?) - PH
     1429    'Aperture'      => {
     1430        Name => 'Aperture',
     1431        ValueConv => '$val=~s/^f//i; $val',
     1432    },
     1433    'Auto Bracket'  => 'AutoBracket',
     1434    'Brightness Value' => 'BrightnessValue',
     1435    'Camera'        => 'CameraModel',
     1436    'Camera body'   => 'CameraBody',
     1437    'Compensation'  => 'ExposureCompensation',
     1438    'Date'          => {
     1439        Name => 'Date',
     1440        Groups => { 2 => 'Time' },
     1441    },
     1442    'Exposure Bias' => 'ExposureBias',
     1443    'Exposure Mode' => {
     1444        Name => 'ExposureMode',
     1445        PrintConv => {
     1446            'M' => 'Manual',
     1447            'A' => 'Aperture Priority', #(NC -- I suppose this could be "Auto" too)
     1448            'S' => 'Shutter Priority', #(NC)
     1449            'P' => 'Program', #(NC)
     1450            'B' => 'Bulb', #(NC)
     1451            # have seen "Manual (M)" written by DCS760C - PH
     1452        },
     1453    },
     1454    'Firmware Version' => 'FirmwareVersion',
     1455    'Flash Compensation' => 'FlashExposureComp',
     1456    'Flash Fired'   => 'FlashFired',
     1457    'Flash Sync Mode' => 'FlashSyncMode',
     1458    'Focal Length'  => {
     1459        Name => 'FocalLength',
     1460        PrintConv => '"$val mm"',
     1461    },
     1462    'Height'        => 'KodakImageHeight',
     1463    'Image Number'  => 'ImageNumber',
     1464    'ISO'           => 'ISO',
     1465    'ISO Speed'     => 'ISO',
     1466    'Max Aperture'  => {
     1467        Name => 'MaxAperture',
     1468        ValueConv => '$val=~s/^f//i; $val',
     1469    },
     1470    'Meter Mode'    => 'MeterMode',
     1471    'Min Aperture'  => {
     1472        Name => 'MinAperture',
     1473        ValueConv => '$val=~s/^f//i; $val',
     1474    },
     1475    'Popup Flash'   => 'PopupFlash',
     1476    'Serial Number' => 'SerialNumber',
     1477    'Shooting Mode' => 'ShootingMode',
     1478    'Shutter'       => 'ShutterSpeed',
     1479    'Temperature'   => 'Temperature', # with a value of 15653, what could this be? - PH
     1480    'Time'          => {
     1481        Name => 'Time',
     1482        Groups => { 2 => 'Time' },
     1483    },
     1484    'White balance' => 'WhiteBalance',
     1485    'Width'         => 'KodakImageWidth',
     1486    '_other_info'   => {
     1487        Name => 'OtherInfo',
     1488        Notes => 'any other information without a tag name',
     1489    },
    9371490);
    9381491
     
    9401493%Image::ExifTool::Kodak::Meta = (
    9411494    GROUPS => { 0 => 'Meta', 1 => 'MetaIFD', 2 => 'Image'},
     1495    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     1496    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     1497    WRITE_GROUP => 'MetaIFD',   # default write group
    9421498    NOTES => q{
    9431499        These tags are found in the APP3 "Meta" segment of JPEG images from Kodak
    944         cameras such as the DC280, DC3400, DC5000 and MC3.  The structure of this
    945         segment is similar to the APP1 "Exif" segment, but a different set of tags
    946         is used.
     1500        cameras such as the DC280, DC3400, DC5000, MC3, M580, Z950 and Z981.  The
     1501        structure of this segment is similar to the APP1 "Exif" segment, but a
     1502        different set of tags is used.
    9471503    },
    9481504    0xc350 => 'FilmProductCode',
     
    9511507    0xc353 => {
    9521508        Name => 'CameraOwner',
    953         PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
     1509        Writable => 'undef',
     1510        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
     1511        RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
    9541512    },
    9551513    0xc354 => {
    9561514        Name => 'SerialNumber',
     1515        Writable => 'undef',
    9571516        Groups => { 2 => 'Camera' },
     1517        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)', #PH
     1518        RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
    9581519    },
    9591520    0xc355 => 'UserSelectGroupTitle',
     
    9691530    0xc35f => 'SBAInputImageColorspace',
    9701531    0xc360 => 'SBAInputImageBitDepth',
    971     0xc361 => 'SBAExposureRecord',
    972     0xc362 => 'UserAdjSBA_RGBShifts',
     1532    0xc361 => {
     1533        Name => 'SBAExposureRecord',
     1534        Binary => 1,
     1535    },
     1536    0xc362 => {
     1537        Name => 'UserAdjSBA_RGBShifts',
     1538        Binary => 1,
     1539    },
    9731540    0xc363 => 'ImageRotationStatus',
    9741541    0xc364 => 'RollGuidElements',
     
    9811548        Name => 'KodakEffectsIFD',
    9821549        Flags => 'SubIFD',
     1550        Groups => { 1 => 'KodakEffectsIFD' },
    9831551        SubDirectory => {
    9841552            TagTable => 'Image::ExifTool::Kodak::SpecialEffects',
     
    9891557        Name => 'KodakBordersIFD',
    9901558        Flags => 'SubIFD',
     1559        Groups => { 1 => 'KodakBordersIFD' },
    9911560        SubDirectory => {
    9921561            TagTable => 'Image::ExifTool::Kodak::Borders',
     
    10051574%Image::ExifTool::Kodak::SpecialEffects = (
    10061575    GROUPS => { 0 => 'Meta', 1 => 'KodakEffectsIFD', 2 => 'Image'},
     1576    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
    10071577    0 => 'DigitalEffectsVersion',
    10081578    1 => {
     
    10161586%Image::ExifTool::Kodak::Borders = (
    10171587    GROUPS => { 0 => 'Meta', 1 => 'KodakBordersIFD', 2 => 'Image'},
     1588    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
    10181589    0 => 'BordersVersion',
    10191590    1 => {
     
    10271598);
    10281599
     1600# tags in Kodak MOV videos (ref PH)
     1601# (similar information in Kodak,Minolta,Nikon,Olympus,Pentax and Sanyo videos)
     1602%Image::ExifTool::Kodak::MOV = (
     1603    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1604    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     1605    FIRST_ENTRY => 0,
     1606    NOTES => 'This information is found in Kodak MOV videos from models such as the P880.',
     1607    0 => {
     1608        Name => 'Make',
     1609        Format => 'string[21]',
     1610    },
     1611    0x16 => {
     1612        Name => 'Model',
     1613        Format => 'string[42]',
     1614    },
     1615    0x40 => {
     1616        Name => 'ModelType',
     1617        Format => 'string[8]',
     1618    },
     1619    # (01 00 at offset 0x48)
     1620    0x4e => {
     1621        Name => 'ExposureTime',
     1622        Format => 'int32u',
     1623        ValueConv => '$val ? 10 / $val : 0',
     1624        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     1625    },
     1626    0x52 => {
     1627        Name => 'FNumber',
     1628        Format => 'rational64u',
     1629        PrintConv => 'sprintf("%.1f",$val)',
     1630    },
     1631    0x5a => {
     1632        Name => 'ExposureCompensation',
     1633        Format => 'rational64s',
     1634        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     1635    },
     1636    # 0x6c => 'WhiteBalance', ?
     1637    0x70 => {
     1638        Name => 'FocalLength',
     1639        Format => 'rational64u',
     1640        PrintConv => 'sprintf("%.1f mm",$val)',
     1641    },
     1642);
     1643
    10291644# Kodak composite tags
    10301645%Image::ExifTool::Kodak::Composite = (
     1646    GROUPS => { 2 => 'Camera' },
    10311647    DateCreated => {
    10321648        Groups => { 2 => 'Time' },
     
    10371653        ValueConv => '"$val[0]:$val[1]"',
    10381654    },
     1655    WB_RGBLevels => {
     1656        Require => {
     1657            0 => 'KDC_IFD:WhiteBalance',
     1658        },
     1659        # indices of the following entries are KDC_IFD:WhiteBalance + 1
     1660        Desire => {
     1661            1 => 'WB_RGBLevelsAuto',
     1662            2 => 'WB_RGBLevelsFluorescent',
     1663            3 => 'WB_RGBLevelsTungsten',
     1664            4 => 'WB_RGBLevelsDaylight',
     1665            5 => 'WB_RGBLevels4',
     1666            6 => 'WB_RGBLevels5',
     1667            7 => 'WB_RGBLevelsShade',
     1668        },
     1669        ValueConv => '$val[$val[0] + 1]',
     1670    },
     1671    WB_RGBLevels2 => {
     1672        Name => 'WB_RGBLevels',
     1673        Require => {
     1674            0 => 'KodakIFD:WhiteBalance',
     1675            1 => 'WB_RGBMul0',
     1676            2 => 'WB_RGBMul1',
     1677            3 => 'WB_RGBMul2',
     1678            4 => 'WB_RGBMul3',
     1679            5 => 'WB_RGBCoeffs0',
     1680            6 => 'WB_RGBCoeffs1',
     1681            7 => 'WB_RGBCoeffs2',
     1682            8 => 'WB_RGBCoeffs3',
     1683        },
     1684        # indices of the following entries are KDC_IFD:WhiteBalance + 1
     1685        Desire => {
     1686            9 => 'KodakIFD:ColorTemperature',
     1687            10 => 'Kodak:WB_RGBLevels',
     1688        },
     1689        ValueConv => 'Image::ExifTool::Kodak::CalculateRGBLevels(@val)',
     1690    },
    10391691);
    10401692
    10411693# add our composite tags
    10421694Image::ExifTool::AddCompositeTags('Image::ExifTool::Kodak');
     1695
     1696#------------------------------------------------------------------------------
     1697# Calculate RGB levels from associated tags (ref 3)
     1698# Inputs: 0) KodakIFD:WhiteBalance, 1-4) WB_RGBMul0-3, 5-8) WB_RGBCoeffs0-3
     1699#         9) (optional) KodakIFD:ColorTemperature, 10) (optional) Kodak:WB_RGBLevels
     1700# Returns: WB_RGBLevels or undef
     1701sub CalculateRGBLevels(@)
     1702{
     1703    return undef if $_[10]; # use existing software levels if they exist
     1704    my $wbi = $_[0];
     1705    return undef if $wbi < 0 or $wbi > 3;
     1706    my @mul = split ' ', $_[$wbi + 1], 13; # (only use the first 12 coeffs)
     1707    my @coefs = split ' ', ${$_[$wbi + 5]}; # (extra de-reference for Binary data)
     1708    my $wbtemp100 = ($_[9] || 6500) / 100;
     1709    return undef unless @mul >= 3 and @coefs >= 12;
     1710    my ($i, $c, $n, $num, @cam_mul);
     1711    for ($c=$n=0; $c<3; ++$c) {
     1712        for ($num=$i=0; $i<4; ++$i) {
     1713            $num += $coefs[$n++] * ($wbtemp100 ** $i);
     1714        }
     1715        $cam_mul[$c] = 2048 / ($num * $mul[$c]);
     1716    }
     1717    return join(' ', @cam_mul);
     1718}
     1719
     1720#------------------------------------------------------------------------------
     1721# Process Kodak textual TextualInfo
     1722# Inputs: 0) ExifTool object ref, 1) dirInfo hash ref, 2) tag table ref
     1723# Returns: 1 on success
     1724sub ProcessKodakText($$$)
     1725{
     1726    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     1727    my $dataPt = $$dirInfo{DataPt};
     1728    my $dirStart = $$dirInfo{DirStart} || 0;
     1729    my $dirLen = $$dirInfo{DirLen} || length($$dataPt) - $dirStart;
     1730    my $data = substr($$dataPt, $dirStart, $dirLen);
     1731    $data =~ s/\0.*//s;     # truncate at null if it exists
     1732    my @lines = split /[\n\r]+/, $data;
     1733    my ($line, $success, @other, $tagInfo);
     1734    $exifTool->VerboseDir('Kodak Text');
     1735    foreach $line (@lines) {
     1736        if ($line =~ /(.*?):\s*(.*)/) {
     1737            my ($tag, $val) = ($1, $2);
     1738            if ($$tagTablePtr{$tag}) {
     1739                $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
     1740            } else {
     1741                my $tagName = $tag;
     1742                $tagName =~ s/([A-Z])\s+([A-Za-z])/${1}_\U$2/g;
     1743                $tagName =~ s/([a-z])\s+([A-Za-z0-9])/${1}\U$2/g;
     1744                $tagName =~ s/\s+//g;
     1745                $tagName =~ s/[^-\w]+//g;   # delete remaining invalid characters
     1746                $tagName = 'NoName' unless $tagName;
     1747                $tagInfo = { Name => $tagName };
     1748                Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
     1749            }
     1750            $exifTool->HandleTag($tagTablePtr, $tag, $val, TagInfo => $tagInfo);
     1751            $success = 1;
     1752        } else {
     1753            # strip off leading/trailing white space and ignore blank lines
     1754            push @other, $1 if $line =~ /^\s*(\S.*?)\s*$/;
     1755        }
     1756    }
     1757    if ($success) {
     1758        if (@other) {
     1759            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, '_other_info');
     1760            $exifTool->FoundTag($tagInfo, \@other);
     1761        }
     1762    } else {
     1763        $exifTool->Warn("Can't parse Kodak TextualInfo data", 1);
     1764    }
     1765    return $success;
     1766}
    10431767
    10441768#------------------------------------------------------------------------------
     
    10521776    return 1 if $dirStart <= 0 or $dirStart + 2 > $$dirInfo{DataLen};
    10531777    my $byteOrder = substr(${$$dirInfo{DataPt}}, $dirStart, 2);
    1054     return 1 unless Image::ExifTool::SetByteOrder($byteOrder);
     1778    unless (Image::ExifTool::SetByteOrder($byteOrder)) {
     1779        $exifTool->Warn("Invalid Kodak $$dirInfo{Name} directory");
     1780        return 1;
     1781    }
    10551782    $$dirInfo{DirStart} += 2;   # skip byte order mark
    10561783    $$dirInfo{DirLen} -= 2;
    10571784    if ($exifTool->{HTML_DUMP}) {
    10581785        my $base = $$dirInfo{Base} + $$dirInfo{DataPos};
    1059         $exifTool->HtmlDump($dirStart+$base, 2, "Byte Order Mark");
     1786        $exifTool->HDump($dirStart+$base, 2, "Byte Order Mark");
    10601787    }
    10611788    return Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
     
    11051832=head1 AUTHOR
    11061833
    1107 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1834Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    11081835
    11091836This library is free software; you can redistribute it and/or modify it
     
    11181845=item L<http://www.ozhiker.com/electronics/pjmt/jpeg_info/meta.html>
    11191846
     1847=item L<http://www.cybercom.net/~dcoffin/dcraw/>
     1848
    11201849=item (...plus lots of testing with my daughter's CX4200!)
    11211850
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/KyoceraRaw.pm

    r16842 r24107  
    1313use strict;
    1414use vars qw($VERSION);
    15 use Image::ExifTool qw(:DataAccess);
     15use Image::ExifTool qw(:DataAccess :Utils);
    1616
    17 $VERSION = '1.00';
     17$VERSION = '1.02';
    1818
    1919sub ProcessRAW($$);
     
    4444    0x21 => { #1
    4545        Name => 'DateTimeOriginal',
     46        Description => 'Date/Time Original',
    4647        Groups => { 2 => 'Time' },
    4748        Format => 'string[20]',
    4849        ValueConv => \&ReverseString,
     50        PrintConv => '$self->ConvertDateTime($val)',
    4951    },
    5052    0x34 => {
     
    9698        Name => 'FocalLength',
    9799        Format => 'int32u',
    98         PrintConv => '"${val}mm"',
     100        PrintConv => '"$val mm"',
    99101    },
    100102    0x7c => {
     
    127129        DirLen => $size,
    128130    );
    129     my $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::KyoceraRaw::Main');
     131    my $tagTablePtr = GetTagTable('Image::ExifTool::KyoceraRaw::Main');
    130132    $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
    131133    return 1;
     
    151153=head1 AUTHOR
    152154
    153 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     155Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    154156
    155157This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Leaf.pm

    r16842 r24107  
    1414use Image::ExifTool::Exif;
    1515
    16 $VERSION = '1.01';
     16$VERSION = '1.03';
    1717
    1818sub ProcessLeaf($$$);
     
    2222    GROUPS => { 0 => 'Leaf', 2 => 'Camera' },
    2323    NOTES => q{
    24 These tags are found in .MOS images from Leaf digital camera backs as
    25 written by Creo Leaf Capture.  They exist within the Leaf-specific directory
    26 structure of EXIF tag 0x8606. The tables below list observed Leaf tags,
    27 however ExifTool will extract any tags found in the Leaf directories even if
    28 they don't appear in these tables.
     24        These tags are found in .MOS images from Leaf digital camera backs as
     25        written by Creo Leaf Capture.  They exist within the Leaf-specific directory
     26        structure of EXIF tag 0x8606. The tables below list observed Leaf tags,
     27        however ExifTool will extract any tags found in the Leaf directories even if
     28        they don't appear in these tables.
    2929    },
    3030    icc_camera_profile => {
     
    336336# table for Leaf SubIFD entries
    337337%Image::ExifTool::Leaf::SubIFD = (
    338     GROUPS => { 0 => 'EXIF', 1 => 'LeafSubIFD', 2 => 'Image'},
     338    GROUPS => { 0 => 'MakerNotes', 1 => 'LeafSubIFD', 2 => 'Image'},
    339339    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
    340340    NOTES => q{
    341 Leaf also writes a TIFF-format sub-IFD inside IFD0 of a MOS image.  No tags
    342 in this sub-IFD are currently known, except for tag 0x8606 which really
    343 shouldn't be here anyway (so it doesn't appear in the table below) because
    344 it duplicates a reference to the same data of tag 0x8606 in IFD0.
     341        Leaf writes a TIFF-format sub-IFD inside IFD0 of a MOS image.  No tags in
     342        this sub-IFD are currently known, except for tag 0x8606 which really
     343        shouldn't be here anyway (so it doesn't appear in the table below) because
     344        it duplicates a reference to the same data of tag 0x8606 in IFD0.
    345345    },
    346346);
     
    472472                $exifTool->ProcessDirectory(\%subdirInfo, $subTable);
    473473            } else {
    474                 $val =~ tr/\n/ /;   # remove newlines from value
     474                $val =~ tr/\n/ /;   # translate newlines to spaces
     475                $val =~ s/\0+$//;   # remove null terminators
    475476                $exifTool->FoundTag($tagInfo, $val);
    476477            }
     
    502503=head1 AUTHOR
    503504
    504 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     505Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    505506
    506507This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIE.pm

    r16842 r24107  
    1515use Image::ExifTool::GPS;
    1616
    17 $VERSION = '1.15';
     17$VERSION = '1.34';
    1818
    1919sub ProcessMIE($$);
     
    8080   'MIE-GPS'        => 'MIE-Geo',
    8181   'MIE-UTM'        => 'MIE-Geo',
     82   'MIE-Canon'      => 'MIE-MakerNotes',
    8283    EXIF            => 'MIE-Meta',
    8384    XMP             => 'MIE-Meta',
     
    8586    ICC_Profile     => 'MIE-Meta',
    8687    ID3             => 'MIE-Meta',
     88    CanonVRD        => 'MIE-Canon',
    8789    IFD0            => 'EXIF',
    8890    IFD1            => 'IFD0',
     
    102104);
    103105my %dateInfo = (
    104     Groups => { 2 => 'Time' },
    105106    Shift => 'Time',
    106107    PrintConv => '$self->ConvertDateTime($val)',
    107     PrintConvInv => '$val',
     108    PrintConvInv => '$self->InverseDateTime($val)',
    108109);
    109110my %noYes = ( 0 => 'No', 1 => 'Yes' );
     
    155156        Name => 'SubfileType',
    156157        Notes => q{
    157             Currently defined types are ACR, AI, AIFF, APE, ARW, ASF, AVI, BMP, CR2,
    158             CRW, DCM, DNG, EPS, ERF, FLAC, FPX, GIF, ICC, JNG, JP2, JPEG, MIE, MIFF MNG,
    159             MOS, MOV, MP3, MP4, MPC, MPEG, MRW, NEF, OGG, ORF, PBM, PDF, PEF, PGM, PICT,
    160             PNG, PPM, PS, PSD, QTIF, RA, RAF, RAW, RIFF, RM, SR2, SRF, SWF, TIFF, VRD,
    161             WAV, WDP, WMA, WMV, X3F and XMP.  Other types should use the common file
    162             extension.
     158            the capitalized common extension for this type of file.  If the extension
     159            has a dot-3 abbreviation, then the longer version is used here. For
     160            instance, JPEG and TIFF are used, not JPG and TIF
    163161        },
    164162    },
     
    167165        Notes => 'version 1.1 is assumed if not specified',
    168166    },
    169    '1Directory' => { Name => 'SubfileDirectory' },
    170    '1Name'      => { Name => 'SubfileName' },
     167   '1Directory' => {
     168        Name => 'SubfileDirectory',
     169        Notes => 'original directory for the file',
     170    },
     171   '1Name'      => {
     172        Name => 'SubfileName',
     173        Notes => 'the file name, including extension if it exists',
     174    },
    171175   '2MIME'      => { Name => 'SubfileMIMEType' },
    172176    Meta => {
     
    291295    Contributors=> { Groups => { 2 => 'Author' }, List => 1 },
    292296    Copyright   => { Groups => { 2 => 'Author' } },
    293     CreateDate  => { %dateInfo },
     297    CreateDate  => { Groups => { 2 => 'Time' }, %dateInfo },
    294298    EMail       => { Groups => { 2 => 'Author' } },
    295299    Keywords    => { List => 1 },
    296     ModifyDate  => { %dateInfo },
    297     OriginalDate=> { Name => 'DateTimeOriginal', %dateInfo },
     300    ModifyDate  => { Groups => { 2 => 'Time' }, %dateInfo },
     301    OriginalDate=> {
     302        Name => 'DateTimeOriginal',
     303        Description => 'Date/Time Original',
     304        Groups => { 2 => 'Time' },
     305        %dateInfo,
     306    },
    298307    Phone       => { Name => 'PhoneNumber', Groups => { 2 => 'Author' } },
    299308    References  => { List => 1 },
     
    406415        Notes => q{'km/h' unless 'mi/h', 'm/s' or 'kn' specified},
    407416    },
    408     DateTime => { Name => 'GPSDateTime', %dateInfo },
     417    DateTime => { Name => 'GPSDateTime', Groups => { 2 => 'Time' }, %dateInfo },
    409418);
    410419
     
    456465        Name => 'FullSizeImage',
    457466        %binaryConv,
    458         ValueConv => '$self->ValidateImage(\$val,$tag)',
    459         ValueConvInv => '$val',
     467        RawConv => '$self->ValidateImage(\$val,$tag)',
    460468    },
    461469);
     
    479487        Name => 'PreviewImage',
    480488        %binaryConv,
    481         ValueConv => '$self->ValidateImage(\$val,$tag)',
    482         ValueConvInv => '$val',
     489        RawConv => '$self->ValidateImage(\$val,$tag)',
    483490    },
    484491);
     
    502509        Name => 'ThumbnailImage',
    503510        %binaryConv,
    504         ValueConv => '$self->ValidateImage(\$val,$tag)',
    505         ValueConvInv => '$val',
     511        RawConv => '$self->ValidateImage(\$val,$tag)',
    506512    },
    507513);
     
    523529    Channels    => { Writable => 'int8u' },
    524530    Compression => { Name => 'AudioCompression' },
    525     Duration    => { Writable => 'rational64u' },
     531    Duration    => { Writable => 'rational64u', PrintConv => 'ConvertDuration($val)' },
    526532    SampleRate  => { Writable => 'int32u' },
    527533    data        => { Name => 'RelatedAudioFile', %binaryConv },
     
    536542   '1Name'      => { Name => 'RelatedVideoFileName' },
    537543    Codec       => { },
    538     Duration    => { Writable => 'rational64u' },
     544    Duration    => { Writable => 'rational64u', PrintConv => 'ConvertDuration($val)' },
    539545    data        => { Name => 'RelatedVideoFile', %binaryConv },
    540546);
     
    559565        Writable => 'rational64u',
    560566        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    561         PrintConvInv => 'eval $val',
     567        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    562568    },
    563569    Flash => {
     
    690696    NOTES => q{
    691697        MIE maker notes are contained within separate groups for each manufacturer
    692         to avoid name conflicts.  Currently no specific manufacturer information has
    693         been defined.
    694     },
    695     Canon       => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
     698        to avoid name conflicts.
     699    },
     700    Canon => {
     701        SubDirectory => {
     702            TagTable => 'Image::ExifTool::MIE::Canon',
     703            DirName => 'MIE-Canon',
     704        },
     705    },
    696706    Casio       => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
    697707    FujiFilm    => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
     
    705715    Sigma       => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
    706716    Sony        => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
     717);
     718
     719# MIE Canon-specific information
     720%Image::ExifTool::MIE::Canon = (
     721    %tableDefaults,
     722    GROUPS => { 1 => 'MIE-Canon' },
     723    WRITE_GROUP => 'MIE-Canon',
     724    VRD => {
     725        Name => 'CanonVRD',
     726        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::Main' },
     727    },
    707728);
    708729
     
    803824
    804825#------------------------------------------------------------------------------
    805 # Does a string contain valid UTF-8 characters?
    806 # Inputs: 0) string
    807 # Returns: 0=regular ASCII, -1=invalid UTF-8, 1=valid UTF-8 with maximum 16-bit
    808 #          wide characters, 2=valid UTF-8 requiring 32-bit wide characters
    809 # Notes: Changes current string position
    810 sub IsUTF8($)
    811 {
    812     my $rtnVal = 0;
    813     pos($_[0]) = 0; # start at beginning of string
    814     for (;;) {
    815         last unless $_[0] =~ /([\x80-\xff])/g;
    816         my $ch = ord($1);
    817         # minimum lead byte for 2-byte sequence is 0xc2 (overlong sequences
    818         # not allowed), 0xf8-0xfd are restricted by RFC 3629 (no 5 or 6 byte
    819         # sequences), and 0xfe and 0xff are not valid in UTF-8 strings
    820         return -1 if $ch < 0xc2 or $ch >= 0xf8;
    821         # determine number of bytes remaining in sequence
    822         my $n = 1;
    823         $n += ($ch >= 0xf0) ? 2 : 1 if $ch >= 0xe0;
    824         return -1 unless $_[0] =~ /\G[\x80-\xbf]{$n}/g;
    825         # character code is greater than 0xffff if more than 2 extra bytes were
    826         # required in the UTF-8 character
    827         $rtnVal |= ($n > 2) ? 2 : 1;
    828     }
    829     return $rtnVal;
    830 }
    831 
    832 #------------------------------------------------------------------------------
    833826# ReadValue() with added support for UTF formats (utf8, utf16 and utf32)
    834827# Inputs: 0) data reference, 1) value offset, 2) format string,
     
    837830# Returns: converted value, or undefined if data isn't there
    838831#          or list of values in list context
     832# Notes: all string formats are converted to UTF8
    839833sub ReadMIEValue($$$$$)
    840834{
    841835    my ($dataPt, $offset, $format, $count, $size) = @_;
    842836    my $val;
    843     if ($format =~ /^utf(8|16|32)/) {
    844         if ($1 == 8) {
    845             # return UTF8 string
     837    if ($format =~ /^(utf(8|16|32)|string)/) {
     838        if ($1 eq 'utf8' or $1 eq 'string') {
     839            # read the 8-bit string
    846840            $val = substr($$dataPt, $offset, $size);
     841            # (as of ExifTool 7.62, leave string values unconverted)
    847842        } else {
    848843            # convert to UTF8
    849844            my $fmt;
    850845            if (GetByteOrder() eq 'MM') {
    851                 $fmt = ($1 == 16) ? 'n' : 'N';
     846                $fmt = ($1 eq 'utf16') ? 'n' : 'N';
    852847            } else {
    853                 $fmt = ($1 == 16) ? 'v' : 'V';
     848                $fmt = ($1 eq 'utf16') ? 'v' : 'V';
    854849            }
    855850            my @unpk = unpack("x$offset$fmt$size",$$dataPt);
     
    861856        }
    862857        # truncate at null unless this is a list
     858        # (strings shouldn't have a null, but just in case)
    863859        $val =~ s/\0.*//s unless $format =~ /_list$/;
    864         return $val;
    865860    } else {
    866         # don't modify string lists
    867         $format = 'undef' if $format eq 'string_list' or $format eq 'free';
     861        $format = 'undef' if $format eq 'free'; # read 'free' as 'undef'
    868862        return ReadValue($dataPt, $offset, $format, $count, $size);
    869863    }
     864    return $val;
    870865}
    871866
     
    893888        return 'Units not supported';
    894889    } else {
     890        if ($format eq 'string' and $exifTool->{OPTIONS}->{Charset} ne 'UTF8' and
     891            $$valPtr =~ /[\x80-\xff]/)
     892        {
     893            # convert from Charset to UTF-8
     894            $$valPtr = $exifTool->Encode($$valPtr,'UTF8');
     895        }
    895896        $err = Image::ExifTool::CheckValue($valPtr, $format, $$tagInfo{Count});
    896897    }
     
    11001101                        }
    11011102                        %subdirInfo = (
    1102                             DataPt => \$oldVal,
     1103                            DataPt  => \$oldVal,
    11031104                            DataLen => $valLen,
    11041105                            DirName => $$newInfo{Name},
    11051106                            DataPos => $raf->Tell() - $valLen,
    1106                             DirStart => 0,
    1107                             DirLen => $valLen,
     1107                            DirStart=> 0,
     1108                            DirLen  => $valLen,
    11081109                        );
     1110                        # write Compact subdirectories if we will compress the data
     1111                        if (($compress or $optCompress or $$dirInfo{IsCompressed}) and
     1112                            eval 'require Compress::Zlib')
     1113                        {
     1114                            $subdirInfo{Compact} = 1;
     1115                        }
    11091116                    }
    11101117                    $subdirInfo{Parent} = $dirName;
    11111118                    my $writeProc = $newInfo->{SubDirectory}->{WriteProc};
     1119                    # reset processed lookup to avoid errors in case of multiple EXIF blocks
     1120                    $exifTool->{PROCESSED} = { };
    11121121                    $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTablePtr, $writeProc);
    11131122                    if (defined $newVal) {
     
    11271136                # get the new tag information
    11281137                $newInfo = $$newTags{$newTag};
    1129                 my $newValueHash = $exifTool->GetNewValueHash($newInfo);
     1138                my $nvHash = $exifTool->GetNewValueHash($newInfo);
    11301139                my @newVals;
    11311140
    11321141                # write information only to specified group
    1133                 my $writeGroup = $$newValueHash{WriteGroup};
     1142                my $writeGroup = $$nvHash{WriteGroup};
    11341143                last unless $isWriting{$writeGroup};
    11351144
     
    11411150                        $isOverwriting = -1;    # force processing list elements individually
    11421151                    } else {
    1143                         $isOverwriting = Image::ExifTool::IsOverwriting($newValueHash);
     1152                        $isOverwriting = Image::ExifTool::IsOverwriting($nvHash);
    11441153                        last unless $isOverwriting;
    11451154                    }
     
    11781187                                # keep any list items that we aren't overwriting
    11791188                                foreach $v (@vals) {
    1180                                     next if Image::ExifTool::IsOverwriting($newValueHash, $v);
     1189                                    next if Image::ExifTool::IsOverwriting($nvHash, $v);
    11811190                                    push @newVals, $v;
    11821191                                }
    11831192                            } else {
    11841193                                # test to see if we really want to overwrite the value
    1185                                 $isOverwriting = Image::ExifTool::IsOverwriting($newValueHash, $val);
     1194                                $isOverwriting = Image::ExifTool::IsOverwriting($nvHash, $val);
    11861195                            }
    11871196                        }
     
    11941203                        if ($verbose > 1) {
    11951204                            $val .= "($units)" if defined $units;
    1196                             $val = $exifTool->Printable($val);
    1197                             print $out "    - $grp1:$$newInfo{Name} = '$val'\n";
     1205                            $exifTool->VerboseValue("- $grp1:$$newInfo{Name}", $val);
    11981206                        }
    11991207                        $deletedTag = $tag;     # remember that we deleted this tag
     
    12181226                    # write new value if creating, or if List and list existed, or
    12191227                    # if tag was previously deleted
    1220                     next unless Image::ExifTool::IsCreating($newValueHash) or
     1228                    next unless Image::ExifTool::IsCreating($nvHash) or
    12211229                        ($newTag eq $lastTag and ($$newInfo{List} or $deletedTag eq $lastTag));
    12221230                }
    12231231                # get the new value to write (undef to delete)
    1224                 push @newVals, Image::ExifTool::GetNewValues($newValueHash);
     1232                push @newVals, Image::ExifTool::GetNewValues($nvHash);
    12251233                next unless @newVals;
    12261234                $writable = $$newInfo{Writable} || $$tagTablePtr{WRITABLE};
     
    12291237                    $newVal = join "\0", @newVals;
    12301238                    # write string as UTF-8,16 or 32 if value contains valid UTF-8 codes
    1231                     my $isUTF8 = IsUTF8($newVal);
     1239                    require Image::ExifTool::XMP;
     1240                    my $isUTF8 = Image::ExifTool::XMP::IsUTF8(\$newVal);
    12321241                    if ($isUTF8 > 0) {
    12331242                        $writable = 'utf8';
    12341243                        # write UTF-16 or UTF-32 if it is more compact
    1235                         # (only if Perl version is 5.6.1 or greater)
    1236                         if ($] >= 5.006001) {
    1237                             # pack with current byte order
    1238                             my $pk = (GetByteOrder() eq 'MM') ? 'n' : 'v';
    1239                             $pk = uc($pk) if $isUTF8 > 1;
    1240                             # translate to utf16 or utf32
    1241                             my $tmp = pack("$pk*",unpack('U0U*',$newVal));
    1242                             if (length $tmp < length $newVal) {
    1243                                 $newVal = $tmp;
    1244                                 $writable = ($isUTF8 > 1) ? 'utf32' : 'utf16';
    1245                             }
     1244                        my $to = $isUTF8 > 1 ? 'UCS4' : 'UCS2';
     1245                        my $tmp = Image::ExifTool::Decode(undef,$newVal,'UTF8',undef,$to);
     1246                        if (length $tmp < length $newVal) {
     1247                            $newVal = $tmp;
     1248                            $writable = ($isUTF8 > 1) ? 'utf32' : 'utf16';
    12461249                        }
    12471250                    }
     
    13281331                Write($outfile, $hdr, chr($len), $newTag, $extLen, $$valPt) or $err = 1;
    13291332                $toWrite = '';
    1330                 if ($verbose > 1 and not $$editDirs{$newTag}) {
    1331                     $newVal = $exifTool->Printable($newVal);
    1332                     print $out "    + $grp1:$$newInfo{Name} = '$newVal'\n";
     1333                # we changed a tag unless just editing a subdirectory
     1334                unless ($$editDirs{$newTag}) {
     1335                    $exifTool->VerboseValue("+ $grp1:$$newInfo{Name}", $newVal);
     1336                    ++$exifTool->{CHANGED};
    13331337                }
    1334                 ++$exifTool->{CHANGED};
    13351338                last;   # didn't want to loop anyway
    13361339            }
     
    14261429    my $verbose = $exifTool->Options('Verbose');
    14271430    my $out = $exifTool->Options('TextOut');
     1431    my $notUTF8 = ($exifTool->{OPTIONS}->{Charset} ne 'UTF8');
    14281432    my ($msg, $buff, $ok, $oldIndent, $mime);
    14291433    my $lastTag = '';
     
    14501454        $exifTool->VerboseDir($grp1);
    14511455    }
     1456    my $wasCompressed = $$dirInfo{WasCompressed};
    14521457
    14531458    # process all MIE elements
     
    15321537                }
    15331538                $valLen = length $value;
     1539                $wasCompressed = 1;
    15341540            }
    15351541        }
     
    15521558            my %subdirInfo = (
    15531559                DirName => $dirName || $tag,
    1554                 RAF => $raf,
    1555                 Parent => $$dirInfo{DirName},
     1560                RAF     => $raf,
     1561                Parent  => $$dirInfo{DirName},
     1562                WasCompressed => $wasCompressed,
    15561563            );
    15571564            # read from uncompressed data instead if necessary
     
    15821589                    }
    15831590                    $exifTool->VerboseInfo($lastTag, $tagInfo,
    1584                         DataPt => \$value,
     1591                        DataPt  => \$value,
    15851592                        DataPos => $raf->Tell() - $valLen,
    1586                         Size => $valLen,
    1587                         Format => $formatStr,
    1588                         Value => $val,
    1589                         Count => $count,
     1593                        Size    => $valLen,
     1594                        Format  => $formatStr,
     1595                        Value   => $val,
     1596                        Count   => $count,
    15901597                    );
    15911598                }
     
    15941601                    my %subdirInfo = (
    15951602                        DirName => $$tagInfo{Name},
    1596                         DataPt => \$value,
    1597                         DataPos => $raf->Tell() - $valLen,
     1603                        DataPt  => \$value,
    15981604                        DataLen => $valLen,
    1599                         DirStart => 0,
    1600                         DirLen => $valLen,
     1605                        DirStart=> 0,
     1606                        DirLen  => $valLen,
     1607                        Parent  => $$dirInfo{DirName},
     1608                        WasCompressed => $wasCompressed,
    16011609                    );
     1610                    # set DataPos and Base for uncompressed information only
     1611                    unless ($wasCompressed) {
     1612                        $subdirInfo{DataPos} = $raf->Tell() - $valLen;
     1613                        $subdirInfo{Base}    = $raf->Tell() - $valLen;
     1614                    }
     1615                    # reset PROCESSED lookup for each MIE directory
     1616                    # (there is no possibility of double-processing a MIE directory)
     1617                    $exifTool->{PROCESSED} = { };
    16021618                    my $processProc = $tagInfo->{SubDirectory}->{ProcessProc};
    16031619                    delete $exifTool->{SET_GROUP1};
     1620                    delete $exifTool->{NO_LIST};
    16041621                    $exifTool->ProcessDirectory(\%subdirInfo, $subTablePtr, $processProc);
    16051622                    $exifTool->{SET_GROUP1} = $grp1;
    1606                 } elsif ($formatStr =~ /_list$/) {
    1607                     # split list value into separate strings
    1608                     my @vals = split "\0", $val;
    1609                     $exifTool->FoundTag($tagInfo, \@vals);
     1623                    $exifTool->{NO_LIST} = 1;
    16101624                } else {
    1611                     # add units to value if specified
    1612                     $val .= "($units)" if defined $units;
     1625                    # convert to specified character set if necessary
     1626                    if ($notUTF8 and $formatStr =~ /^(utf|string)/) {
     1627                        $val = $exifTool->Decode($val, 'UTF8');
     1628                    }
     1629                    if ($formatStr =~ /_list$/) {
     1630                        # split list value into separate strings
     1631                        my @vals = split "\0", $val;
     1632                        $val = \@vals;
     1633                    }
     1634                    if (defined $units) {
     1635                        $val = "@$val" if ref $val; # convert string list to number list
     1636                        # add units to value if specified
     1637                        $val .= "($units)" if defined $units;
     1638                    }
    16131639                    $exifTool->FoundTag($tagInfo, $val);
    16141640                }
     
    16531679                        $buff =~ /(\x10|\x18)(\x08)$/s;
    16541680            SetByteOrder($1 eq "\x10" ? 'MM' : 'II');
    1655             my $len = ($2 eq "\x04") ? Get32u(\$buff, 4) : Get64u(\$buff);
     1681            my $len = ($2 eq "\x04") ? Get32u(\$buff, 4) : Get64u(\$buff, 0);
    16561682            my $curPos = $raf->Tell() or last;
    16571683            last if $len < 12 or $len > $curPos;
     
    17131739            # we have the ability to create a MIE file from scratch
    17141740            $buff = ''; # start from nothing
    1715             SetByteOrder('MM'); # write big-endian
     1741            # set byte order according to preferences
     1742            $exifTool->SetPreferredByteOrder();
    17161743            $isCreating = 1;
    17171744        }
     
    17281755        unless ($numDocs) {
    17291756            # this is a valid MIE file (unless a trailer on another file)
    1730             $exifTool->SetFileType() unless $exifTool->{VALUE}->{FileType};
     1757            $exifTool->SetFileType();
    17311758            $exifTool->{NO_LIST} = 1;   # handle lists ourself
    17321759            $exifTool->{MIE_COUNT} = { };
     
    17541781            UpdateMieMap() unless $doneMieMap;
    17551782            # initialize write directories, with MIE tags taking priority
     1783            # (note that this may re-initialize directories when writing trailer
     1784            #  to another type of image, but this is OK because we are done writing
     1785            #  the other format by the time we start writing the trailer)
    17561786            $exifTool->InitWriteDirs(\%mieMap, 'MIE');
    17571787            $subdirInfo{ToWrite} = '~' . MIEGroupFormat(1) . "\x04\xfe0MIE\0\0\0\0";
     
    17621792                last;
    17631793            } elsif (defined $msg and $isCreating) {
    1764                 $exifTool->Error('Nothing to write');
    17651794                last;
    17661795            }
     
    20672096comes first regardless of the byte ordering.  In a signed rational value,
    20682097only the numerator is signed.  The denominator of all rational values is
    2069 unsigned (ie. a signed 32-bit rational of 0x80000000/0x80000000 evaluates to
     2098unsigned (ie. a signed 64-bit rational of 0x80000000/0x80000000 evaluates to
    20702099-1, not +1).
    20712100
     
    24822511=head1 REVISIONS
    24832512
     2513  2010-04-05 - Fixed ÒFormat SizeÓ Note 7 to give the correct number of bits
     2514               in the example rational value
    24842515  2007-01-21 - Specified LF character (0x0a) for text newline sequence
    24852516  2007-01-19 - Specified ISO 8859-1 character set for extended ASCII codes
     
    24962527=head1 AUTHOR
    24972528
    2498 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     2529Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    24992530
    25002531This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIEUnits.pod

    r16842 r24107  
    357357=head1 AUTHOR
    358358
    359 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     359Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    360360
    361361This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIFF.pm

    r16842 r24107  
    1616use Image::ExifTool qw(:DataAccess :Utils);
    1717
    18 $VERSION = '1.03';
     18$VERSION = '1.05';
    1919
    2020# MIFF chunks
     
    2222    GROUPS => { 2 => 'Image' },
    2323    NOTES => q{
    24 The MIFF format allows aribrary tag names to be used.  Only the standard tag
    25 names are listed below, however ExifTool will decode any tags found in the
    26 image.
     24        The MIFF (Magick Image File Format) format allows aribrary tag names to be
     25        used.  Only the standard tag names are listed below, however ExifTool will
     26        decode any tags found in the image.
    2727    },
    2828   'background-color' => 'BackgroundColor',
     
    120120    # slurp those entire files, which will be slower, but will work
    121121    # OK except that the profile information won't be decoded
    122     my $oldsep = $/;
    123     $/ = ":\x1a";
     122    local $/ = ":\x1a";
    124123
    125124    my $mode = '';
     
    175174        }
    176175    }
    177     $/ = $oldsep;   # restore separator to original value
    178176
    179177    # process profile information
     
    232230            if ($verbose) {
    233231                $exifTool->VerboseDir($type, 0, $len);
    234                 Image::ExifTool::HexDump(\$buff, undef,
    235                     Out => $exifTool->Options('TextOut')
    236                 ) if $verbose > 2;
    237              }
     232                $exifTool->VerboseDump(\$buff);
     233            }
    238234         }
    239235    }
     
    260256=head1 AUTHOR
    261257
    262 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     258Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    263259
    264260This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MNG.pm

    r16842 r24107  
    662662=head1 AUTHOR
    663663
    664 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     664Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    665665
    666666This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPC.pm

    r16842 r24107  
    8282
    8383    # must first check for leading ID3 information
    84     unless ($exifTool->{DONE_ID3}) {
     84    unless ($exifTool->{DoneID3}) {
    8585        require Image::ExifTool::ID3;
    8686        Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
     
    107107    } else {
    108108        $exifTool->Warn('Audio info not currently extracted from this version MPC file');
    109     } 
     109    }
    110110
    111111    # process APE trailer if it exists
     
    135135=head1 AUTHOR
    136136
    137 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     137Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    138138
    139139This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPEG.pm

    r16842 r24107  
    88# References:   1) http://www.mp3-tech.org/
    99#               2) http://www.getid3.org/
     10#               3) http://dvd.sourceforge.net/dvdinfo/dvdmpeg.html
     11#               4) http://ffmpeg.org/
     12#               5) http://sourceforge.net/projects/mediainfo/
    1013#------------------------------------------------------------------------------
    1114
     
    1619use Image::ExifTool qw(:DataAccess :Utils);
    1720
    18 $VERSION = '1.04';
     21$VERSION = '1.13';
    1922
    2023%Image::ExifTool::MPEG::Audio = (
     
    4447            Condition => '$self->{MPEG_Vers} == 3 and $self->{MPEG_Layer} == 3',
    4548            Notes => 'version 1, layer 1',
    46             PrintConv => {
     49            PrintConvColumns => 3,
     50            ValueConv => {
    4751                0 => 'free',
    4852                1 => 32000,
     
    6165                14 => 448000,
    6266            },
     67            PrintConv => 'ConvertBitrate($val)',
    6368        },
    6469        {
     
    6671            Condition => '$self->{MPEG_Vers} == 3 and $self->{MPEG_Layer} == 2',
    6772            Notes => 'version 1, layer 2',
    68             PrintConv => {
     73            PrintConvColumns => 3,
     74            ValueConv => {
    6975                0 => 'free',
    7076                1 => 32000,
     
    8389                14 => 384000,
    8490            },
     91            PrintConv => 'ConvertBitrate($val)',
    8592        },
    8693        {
     
    8895            Condition => '$self->{MPEG_Vers} == 3 and $self->{MPEG_Layer} == 1',
    8996            Notes => 'version 1, layer 3',
    90             PrintConv => {
     97            PrintConvColumns => 3,
     98            ValueConv => {
    9199                0 => 'free',
    92100                1 => 32000,
     
    105113                14 => 320000,
    106114            },
     115            PrintConv => 'ConvertBitrate($val)',
    107116        },
    108117        {
     
    110119            Condition => '$self->{MPEG_Vers} != 3 and $self->{MPEG_Layer} == 3',
    111120            Notes => 'version 2 or 2.5, layer 1',
    112             PrintConv => {
     121            PrintConvColumns => 3,
     122            ValueConv => {
    113123                0 => 'free',
    114124                1 => 32000,
     
    127137                14 => 256000,
    128138            },
     139            PrintConv => 'ConvertBitrate($val)',
    129140        },
    130141        {
     
    132143            Condition => '$self->{MPEG_Vers} != 3 and $self->{MPEG_Layer}',
    133144            Notes => 'version 2 or 2.5, layer 2 or 3',
    134             PrintConv => {
     145            PrintConvColumns => 3,
     146            ValueConv => {
    135147                0 => 'free',
    136148                1 => 8000,
     
    149161                14 => 160000,
    150162            },
     163            PrintConv => 'ConvertBitrate($val)',
    151164        },
    152165    ],
     
    187200    'Bit24-25' => {
    188201        Name => 'ChannelMode',
     202        RawConv => '$self->{MPEG_Mode} = $val',
    189203        PrintConv => {
    190204            0 => 'Stereo',
     
    298312        Name => 'VideoBitrate',
    299313        ValueConv => '$val eq 0x3ffff ? "Variable" : $val * 400',
     314        PrintConv => 'ConvertBitrate($val)',
    300315    },
    301316    # these tags not very interesting
     
    306321);
    307322
     323%Image::ExifTool::MPEG::Xing = (
     324    GROUPS => { 2 => 'Audio' },
     325    VARS => { NO_ID => 1 },
     326    NOTES => 'These tags are extracted from the Xing/Info frame.',
     327    1 => { Name => 'VBRFrames' },
     328    2 => { Name => 'VBRBytes' },
     329    3 => { Name => 'VBRScale' },
     330    4 => { Name => 'Encoder' },
     331    5 => { Name => 'LameVBRQuality' },
     332    6 => { Name => 'LameQuality' },
     333    7 => { # (for documentation only)
     334        Name => 'LameHeader',
     335        SubDirectory => { TagTable => 'Image::ExifTool::MPEG::Lame' },
     336    },
     337);
     338
     339# Lame header tags (ref 5)
     340%Image::ExifTool::MPEG::Lame = (
     341    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     342    GROUPS => { 2 => 'Audio' },
     343    NOTES => 'Tags extracted from Lame 3.90 or later header.',
     344    9 => {
     345        Name => 'LameMethod',
     346        Mask => 0x0f,
     347        PrintConv => {
     348            1 => 'CBR',
     349            2 => 'ABR',
     350            3 => 'VBR (old/rh)',
     351            4 => 'VBR (new/mtrh)',
     352            5 => 'VBR (old/rh)',
     353            6 => 'VBR',
     354            8 => 'CBR (2-pass)',
     355            9 => 'ABR (2-pass)',
     356        },
     357    },
     358    10 => {
     359        Name => 'LameLowPassFilter',
     360        ValueConv => '$val * 100',
     361        PrintConv => '($val / 1000) . " kHz"',
     362    },
     363    # 19 - EncodingFlags
     364    20 => {
     365        Name => 'LameBitrate',
     366        ValueConv => '$val * 1000',
     367        PrintConv => 'ConvertBitrate($val)',
     368    },
     369    24 => {
     370        Name => 'LameStereoMode',
     371        Mask => 0x1c,
     372        ValueConv => '$val >> 2',
     373        PrintConv => {
     374            0 => 'Mono',
     375            1 => 'Stereo',
     376            2 => 'Dual Channels',
     377            3 => 'Joint Stereo',
     378            4 => 'Forced Joint Stereo',
     379            6 => 'Auto',
     380            7 => 'Intensity Stereo',
     381        },
     382    },
     383);
     384
    308385# composite tags
    309386%Image::ExifTool::MPEG::Composite = (
     
    314391        },
    315392        Desire => {
    316             1 => 'MPEG:AudioBitrate',
    317             2 => 'MPEG:VideoBitrate',
    318         },
    319         # calculate duration as file size divided by total bitrate
    320         # (note: this is only approximate!)
     393            1 => 'ID3Size',
     394            2 => 'MPEG:AudioBitrate',
     395            3 => 'MPEG:VideoBitrate',
     396            4 => 'MPEG:VBRFrames',
     397            5 => 'MPEG:SampleRate',
     398            6 => 'MPEG:MPEGAudioVersion',
     399        },
     400        Priority => -1, # (don't want to replace any other Duration tag)
    321401        ValueConv => q{
    322             return undef unless $val[1] or $val[2];
    323             return undef if $prt[1] and not $prt[1] =~ /^\d+$/;
     402            if ($val[4] and defined $val[5] and defined $val[6]) {
     403                # calculate from number of VBR audio frames
     404                my $mfs = $prt[5] / ($val[6] == 3 ? 144 : 72);
     405                # calculate using VBR length
     406                return 8 * $val[4] / $mfs;
     407            }
     408            # calculate duration as file size divided by total bitrate
     409            # (note: this is only approximate!)
     410            return undef unless $val[2] or $val[3];
    324411            return undef if $val[2] and not $val[2] =~ /^\d+$/;
    325             return (8 * $val[0]) / (($prt[1]||0) + ($val[2]||0));
    326         },
    327         PrintConv => q{
    328             my $h = int($val / 3600);
    329             my $m = int($val / 60 - $h * 60);
    330             my $s = $val - $h * 3600 - $m * 60;
    331             return sprintf("%d:%.2d:%05.2f (approx)",$h,$m,$s);
    332         },
     412            return undef if $val[3] and not $val[3] =~ /^\d+$/;
     413            return (8 * ($val[0] - ($val[1]||0))) / (($val[2]||0) + ($val[3]||0));
     414        },
     415        PrintConv => 'ConvertDuration($val) . " (approx)"',
     416    },
     417    AudioBitrate => {
     418        Groups => { 2 => 'Audio' },
     419        Notes => 'calculated for variable-bitrate MPEG audio',
     420        Require => {
     421            0 => 'MPEG:MPEGAudioVersion',
     422            1 => 'MPEG:SampleRate',
     423            2 => 'MPEG:VBRBytes',
     424            3 => 'MPEG:VBRFrames',
     425        },
     426        ValueConv => q{
     427            return undef unless $val[3];
     428            my $mfs = $prt[1] / ($val[0] == 3 ? 144 : 72);
     429            return $mfs * $val[2] / $val[3];
     430        },
     431        PrintConv => 'ConvertBitrate($val)',
    333432    },
    334433);
     
    363462# Inputs: 0) ExifTool object reference, 1) Reference to audio data
    364463# Returns: 1 on success, 0 if no audio header was found
    365 sub ProcessMPEGAudio($$)
     464sub ParseMPEGAudio($$)
    366465{
    367466    my ($exifTool, $buffPt) = @_;
    368     my $word;
     467    my ($word, $pos);
     468    my $ext = $$exifTool{FILE_EXT} || '';
    369469
    370470    for (;;) {
     
    379479        if (($word & 0x180000) == 0x080000 or   # 01 is a reserved version ID
    380480            ($word & 0x060000) == 0x000000 or   # 00 is a reserved layer description
     481            ($word & 0x00f000) == 0x000000 or   # 0000 is the "free" bitrate index
    381482            ($word & 0x00f000) == 0x00f000 or   # 1111 is a bad bitrate index
    382             ($word & 0x000600) == 0x000600 or   # 11 is a reserved sampling frequency
     483            ($word & 0x000c00) == 0x000c00 or   # 11 is a reserved sampling frequency
    383484            ($word & 0x000003) == 0x000002)     # 10 is a reserved emphasis
    384485        {
    385             return 0;   # invalid frame header
    386         }
     486            # give up easily unless this really should be an MP3 file
     487            return 0 unless $ext eq 'MP3';
     488            pos($$buffPt) = pos($$buffPt) - 1;
     489            next;
     490        }
     491        $pos = pos($$buffPt);
    387492        last;
    388493    }
    389494    # set file type if not done already
    390     $exifTool->SetFileType() unless $exifTool->{VALUE}->{FileType};
     495    $exifTool->SetFileType();
    391496
    392497    my $tagTablePtr = GetTagTable('Image::ExifTool::MPEG::Audio');
    393498    ProcessFrameHeader($exifTool, $tagTablePtr, $word);
     499
     500    # extract the VBR information (ref MP3::Info)
     501    my ($v, $m) = ($$exifTool{MPEG_Vers}, $$exifTool{MPEG_Mode});
     502    while (defined $v and defined $m) {
     503        my $len = length $$buffPt;
     504        $pos += $v == 3 ? ($m == 3 ? 17 : 32) : ($m == 3 ?  9 : 17);
     505        last if $pos + 8 > $len;
     506        my $buff = substr($$buffPt, $pos, 8);
     507        last unless $buff =~ /^(Xing|Info)/;
     508        my $xingTable = GetTagTable('Image::ExifTool::MPEG::Xing');
     509        my $vbrScale;
     510        my $flags = unpack('x4N', $buff);
     511        my $isVBR = ($buff !~ /^Info/);     # Info frame is not VBR (ref 5)
     512        $pos += 8;
     513        if ($flags & 0x01) {    # VBRFrames
     514            last if $pos + 4 > $len;
     515            $exifTool->HandleTag($xingTable, 1, unpack("x${pos}N", $$buffPt)) if $isVBR;
     516            $pos += 4;
     517        }
     518        if ($flags & 0x02) {    # VBRBytes
     519            last if $pos + 4 > $len;
     520            $exifTool->HandleTag($xingTable, 2, unpack("x${pos}N", $$buffPt)) if $isVBR;
     521            $pos += 4;
     522        }
     523        if ($flags & 0x04) {    # VBR_TOC
     524            last if $pos + 100 > $len;
     525            # (ignore toc for now)
     526            $pos += 100;
     527        }
     528        if ($flags & 0x08) {    # VBRScale
     529            last if $pos + 4 > $len;
     530            $vbrScale = unpack("x${pos}N", $$buffPt);
     531            $exifTool->HandleTag($xingTable, 3, $vbrScale) if $isVBR;
     532            $pos += 4;
     533        }
     534        # process Lame header (ref 5)
     535        if ($flags & 0x10) {    # Lame
     536            last if $pos + 348 > $len;
     537        } elsif ($pos + 4 <= $len) {
     538            my $lib = substr($$buffPt, $pos, 4);
     539            unless ($lib eq 'LAME' or $lib eq 'GOGO') {
     540                # attempt to identify other encoders
     541                my $n;
     542                if (index($$buffPt, 'RCA mp3PRO Encoder') >= 0) {
     543                    $lib = 'RCA mp3PRO';
     544                } elsif (($n = index($$buffPt, 'THOMSON mp3PRO Encoder')) >= 0) {
     545                    $lib = 'Thomson mp3PRO';
     546                    $n += 22;
     547                    $lib .= ' ' . substr($$buffPt, $n, 6) if length($$buffPt) - $n >= 6;
     548                } elsif (index($$buffPt, 'MPGE') >= 0) {
     549                    $lib = 'Gogo (<3.0)';
     550                } else {
     551                    last;
     552                }
     553                $exifTool->HandleTag($xingTable, 4, $lib);
     554                last;
     555            }
     556        }
     557        my $lameLen = $len - $pos;
     558        last if $lameLen < 9;
     559        my $enc = substr($$buffPt, $pos, 9);
     560        if ($enc ge 'LAME3.90') {
     561            $exifTool->HandleTag($xingTable, 4, $enc);
     562            if ($vbrScale <= 100) {
     563                $exifTool->HandleTag($xingTable, 5, int((100 - $vbrScale) / 10));
     564                $exifTool->HandleTag($xingTable, 6, (100 - $vbrScale) % 10);
     565            }
     566            my %dirInfo = (
     567                DataPt   => $buffPt,
     568                DirStart => $pos,
     569                DirLen   => length($$buffPt) - $pos,
     570            );
     571            my $subTablePtr = GetTagTable('Image::ExifTool::MPEG::Lame');
     572            $exifTool->ProcessDirectory(\%dirInfo, $subTablePtr);
     573        } else {
     574            $exifTool->HandleTag($xingTable, 4, substr($$buffPt, $pos, 20));
     575        }
     576        last;   # (didn't want to loop anyway)
     577    }
     578
    394579    return 1;
    395580}
     
    425610# Inputs: 0) ExifTool object reference, 1) Reference to audio/video data
    426611# Returns: 1 on success, 0 if no video header was found
    427 sub ProcessMPEGAudioVideo($$)
     612# To Do: Properly parse MPEG streams:
     613#   0xb7 - sequence end
     614#   0xb9 - end code
     615#   0xba - pack start code
     616#   0xbb - system header
     617#   0xbc - program map <-- should parse this
     618#   0xbd - private stream 1 --> for VOB, this contains sub-streams:
     619#           0x20-0x3f - pictures
     620#           0x80-0x87 - audio (AC3,DTS,SDDS)
     621#           0xa0-0xa7 - audio (LPCM)
     622#   0xbe - padding
     623#   0xbf - private stream 2
     624#   0xc0-0xdf - audio stream
     625#   0xe0-0xef - video stream
     626sub ParseMPEGAudioVideo($$)
    428627{
    429628    my ($exifTool, $buffPt) = @_;
    430     my %found;
     629    my (%found, $didHdr);
    431630    my $rtnVal = 0;
    432     my %proc = ( audio => \&ProcessMPEGAudio, video => \&ProcessMPEGVideo );
     631    my %proc = ( audio => \&ParseMPEGAudio, video => \&ProcessMPEGVideo );
    433632
    434633    delete $exifTool->{AudioBitrate};
     
    437636    while ($$buffPt =~ /\0\0\x01(\xb3|\xc0)/g) {
    438637        my $type = $1 eq "\xb3" ? 'video' : 'audio';
     638        unless ($didHdr) {
     639            # make sure we didn't miss an audio frame sync before this (ie. MP3 file)
     640            # (the last byte of the 4-byte MP3 audio frame header word may be zero,
     641            # but the 2nd last must be non-zero, so we need only check to pos-3)
     642            my $buff = substr($$buffPt, 0, pos($$buffPt) - 3);
     643            $found{audio} = 1 if ParseMPEGAudio($exifTool, \$buff);
     644            $didHdr = 1;
     645        }
    439646        next if $found{$type};
    440647        my $len = length($$buffPt) - pos($$buffPt);
     
    454661
    455662#------------------------------------------------------------------------------
    456 # Read information frame an MPEG file
     663# Read information from an MPEG file
    457664# Inputs: 0) ExifTool object reference, 1) Directory information reference
    458665# Returns: 1 on success, 0 if this wasn't a valid MPEG file
     
    470677    $raf->Read($buff, 65536*4) or return 0;
    471678
    472     return ProcessMPEGAudioVideo($exifTool, \$buff);
     679    return ParseMPEGAudioVideo($exifTool, \$buff);
    473680}
    474681
     
    497704=head1 AUTHOR
    498705
    499 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     706Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    500707
    501708This library is free software; you can redistribute it and/or modify it
     
    510717=item L<http://www.getid3.org/>
    511718
     719=item L<http://dvd.sourceforge.net/dvdinfo/dvdmpeg.html>
     720
     721=item L<http://ffmpeg.org/>
     722
     723=item L<http://sourceforge.net/projects/mediainfo/>
     724
    512725=back
    513726
     
    515728
    516729L<Image::ExifTool::TagNames/MPEG Tags>,
     730L<MP3::Info(3pm)|MP3::Info>,
    517731L<Image::ExifTool(3pm)|Image::ExifTool>
    518732
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MakerNotes.pm

    r16842 r24107  
    1515
    1616sub ProcessUnknown($$$);
    17 
    18 $VERSION = '1.34';
    19 
    20 my $debug;          # set to 1 to enabled debugging code
     17sub ProcessUnknownOrPreview($$$);
     18sub ProcessCanon($$$);
     19sub ProcessGE2($$$);
     20sub WriteUnknownOrPreview($$$);
     21sub FixLeicaBase($$;$);
     22
     23$VERSION = '1.66';
     24
     25my $debug;          # set to 1 to enable debugging code
    2126
    2227# conditional list of maker notes
     
    3136        Name => 'MakerNoteCanon',
    3237        # (starts with an IFD)
    33         Condition => '$self->{CameraMake} =~ /^Canon/',
     38        Condition => '$$self{Make} =~ /^Canon/',
    3439        SubDirectory => {
    3540            TagTable => 'Image::ExifTool::Canon::Main',
     41            ProcessProc => \&ProcessCanon,
    3642            ByteOrder => 'Unknown',
    3743        },
     
    4248        # in a nice order for documentation
    4349        # (starts with an IFD)
    44         Condition => '$self->{CameraMake}=~/^CASIO(?! COMPUTER CO.,LTD)/',
     50        Condition => '$$self{Make}=~/^CASIO/ and $$valPt!~/^(QVC|DCI)\0/',
    4551        SubDirectory => {
    4652            TagTable => 'Image::ExifTool::Casio::Main',
     
    5056    {
    5157        Name => 'MakerNoteCasio2',
    52         # (starts with "QVC\0")
    53         Condition => '$self->{CameraMake}=~/^CASIO COMPUTER CO.,LTD/',
     58        # (starts with "QVC\0" [Casio] or "DCI\0" [Concord])
     59        # (also found in AVI and MOV videos)
     60        Condition => '$$valPt =~ /^(QVC|DCI)\0/',
    5461        SubDirectory => {
    5562            TagTable => 'Image::ExifTool::Casio::Type2',
    5663            Start => '$valuePtr + 6',
    5764            ByteOrder => 'Unknown',
    58         },
    59     },
    60     {
    61         # The Fuji programmers really botched this one up,
    62         # but with a bit of work we can still read this directory
     65            FixBase => 1, # necessary for AVI and MOV videos
     66        },
     67    },
     68    {
     69        # The Fuji maker notes use a structure similar to a self-contained
     70        # TIFF file, but with "FUJIFILM" instead of the standard TIFF header
    6371        Name => 'MakerNoteFujiFilm',
    6472        # (starts with "FUJIFILM" -- also used by some Leica, Minolta and Sharp models)
    65         Condition => '$$valPt =~ /^FUJIFILM/',
     73        # (GE FujiFilm models start with "GENERALE")
     74        Condition => '$$valPt =~ /^(FUJIFILM|GENERALE)/',
    6675        SubDirectory => {
    6776            TagTable => 'Image::ExifTool::FujiFilm::Main',
     
    7584    },
    7685    {
     86        Name => 'MakerNoteGE',
     87        Condition => '$$valPt =~ /^GE(\0\0|NIC\0)/',
     88        SubDirectory => {
     89            TagTable => 'Image::ExifTool::GE::Main',
     90            Start => '$valuePtr + 18',
     91            FixBase => 1,
     92            AutoFix => 1,
     93            ByteOrder => 'Unknown',
     94       },
     95    },
     96    {
     97        Name => 'MakerNoteGE2',
     98        Condition => '$$valPt =~ /^GE\x0c\0\0\0\x16\0\0\0/',
     99        # Note: we will get a "Maker notes could not be parsed" warning when writing
     100        #       these maker notes because they aren't currently supported for writing
     101        SubDirectory => {
     102            TagTable => 'Image::ExifTool::FujiFilm::Main',
     103            ProcessProc => \&ProcessGE2,
     104            Start => '$valuePtr + 12',
     105            Base => '$start - 6',
     106            ByteOrder => 'LittleEndian',
     107            # hard patch for crazy offsets
     108            FixOffsets => '$valuePtr -= 210 if $tagID >= 0x1303',
     109       },
     110    },
     111    # (the GE X5 has really messed up EXIF-like maker notes starting with
     112    #  "GENIC\x0c\0" --> currently not decoded)
     113    {
    77114        Name => 'MakerNoteHP',  # PhotoSmart 720 (also Vivitar 3705, 3705B and 3715)
    78115        Condition => '$$valPt =~ /^(Hewlett-Packard|Vivitar)/',
     
    85122    {
    86123        Name => 'MakerNoteHP2', # PhotoSmart E427
    87         Condition => q{
    88             $self->{CameraMake} =~ /^Hewlett-Packard/ and
    89             $$valPt !~ /^.{8}Hewlett-Packard/s and
    90             $$valPt !~ /^IIII/ and $$valPt =~ /^\d{3}.\0/s
    91         },
     124        # (this type of maker note also used by BenQ, Mustek, Sanyo, Traveler and Vivitar)
     125        Condition => '$$valPt =~ /^610[\0-\4]/',
    92126        NotIFD => 1,
    93127        SubDirectory => {
     
    118152    },
    119153    {
     154        Name => 'MakerNoteISL', # (used in Samsung GX20 samples)
     155        Condition => '$$valPt =~ /^ISLMAKERNOTE000\0/',
     156        # this maker notes starts with a TIFF-like header at offset 0x10
     157        SubDirectory => {
     158            TagTable => 'Image::ExifTool::Unknown::Main',
     159            Start => '$valuePtr + 24',
     160            Base => '$start - 8',
     161            ByteOrder => 'Unknown',
     162        },
     163    },
     164    {
    120165        Name => 'MakerNoteJVC',
    121166        Condition => '$$valPt=~/^JVC /',
     
    128173    {
    129174        Name => 'MakerNoteJVCText',
    130         Condition => '$self->{CameraMake}=~/^(JVC|Victor)/ and $$valPt=~/^VER:/',
     175        Condition => '$$self{Make}=~/^(JVC|Victor)/ and $$valPt=~/^VER:/',
    131176        NotIFD => 1,
    132177        SubDirectory => {
     
    136181    {
    137182        Name => 'MakerNoteKodak1a',
    138         Condition => '$self->{CameraMake}=~/^EASTMAN KODAK/ and $$valPt=~/^KDK INFO/',
     183        Condition => '$$self{Make}=~/^EASTMAN KODAK/ and $$valPt=~/^KDK INFO/',
    139184        NotIFD => 1,
    140185        SubDirectory => {
     
    146191    {
    147192        Name => 'MakerNoteKodak1b',
    148         Condition => '$self->{CameraMake}=~/^EASTMAN KODAK/ and $$valPt=~/^KDK/',
     193        Condition => '$$self{Make}=~/^EASTMAN KODAK/ and $$valPt=~/^KDK/',
    149194        NotIFD => 1,
    150195        SubDirectory => {
     
    171216        # upper byte of the year should be 0x07:
    172217        Name => 'MakerNoteKodak3',
    173         Condition => '$self->{CameraMake}=~/^EASTMAN KODAK/ and $$valPt=~/^.{12}\x07/s',
     218        Condition => q{
     219            $$self{Make} =~ /^EASTMAN KODAK/ and
     220            $$valPt =~ /^(?!MM|II).{12}\x07/s and
     221            $$valPt !~ /^(MM|II|AOC)/
     222        },
    174223        NotIFD => 1,
    175224        SubDirectory => {
     
    180229    {
    181230        Name => 'MakerNoteKodak4',
    182         Condition => '$self->{CameraMake}=~/^Eastman Kodak/ and $$valPt=~/^.{41}JPG/s',
     231        Condition => q{
     232            $$self{Make} =~ /^Eastman Kodak/ and
     233            $$valPt =~ /^.{41}JPG/s and
     234            $$valPt !~ /^(MM|II|AOC)/
     235        },
    183236        NotIFD => 1,
    184237        SubDirectory => {
     
    190243        Name => 'MakerNoteKodak5',
    191244        Condition => q{
    192             $self->{CameraMake}=~/^EASTMAN KODAK/ and
    193             ($self->{CameraModel}=~/CX(4200|4230|4300|4310|6200|6230)/ or
     245            $$self{Make}=~/^EASTMAN KODAK/ and
     246            ($$self{Model}=~/CX(4200|4230|4300|4310|6200|6230)/ or
    194247            # try to pick up similar models we haven't tested yet
    195248            $$valPt=~/^\0(\x1a\x18|\x3a\x08|\x59\xf8|\x14\x80)\0/)
     
    204257        Name => 'MakerNoteKodak6a',
    205258        Condition => q{
    206             $self->{CameraMake}=~/^EASTMAN KODAK/ and
    207             $self->{CameraModel}=~/DX3215/
     259            $$self{Make}=~/^EASTMAN KODAK/ and
     260            $$self{Model}=~/DX3215/
    208261        },
    209262        NotIFD => 1,
     
    216269        Name => 'MakerNoteKodak6b',
    217270        Condition => q{
    218             $self->{CameraMake}=~/^EASTMAN KODAK/ and
    219             $self->{CameraModel}=~/DX3700/
     271            $$self{Make}=~/^EASTMAN KODAK/ and
     272            $$self{Model}=~/DX3700/
    220273        },
    221274        NotIFD => 1,
     
    231284        #  accept other strings from sample images that may be serial numbers)
    232285        Condition => q{
    233             $self->{CameraMake}=~/Kodak/i and
     286            $$self{Make}=~/Kodak/i and
    234287            $$valPt =~ /^[CK][A-Z\d]{3} ?[A-Z\d]{1,2}\d{2}[A-Z\d]\d{4}[ \0]/
    235288        },
     
    241294    },
    242295    {
    243         Name => 'MakerNoteKodakIFD',
    244         # look for reasonable number of entries and check
    245         # format and count of first IFD entry
     296        Name => 'MakerNoteKodak8a',
     297        # IFD-format maker notes: look for reasonable number of
     298        # entries and check format and count of first IFD entry
    246299        Condition => q{
    247             $self->{CameraMake}=~/Kodak/i and
     300            $$self{Make}=~/Kodak/i and
    248301            ($$valPt =~ /^\0[\x02-\x7f]..\0[\x01-\x0c]\0\0/s or
    249302             $$valPt =~ /^[\x02-\x7f]\0..[\x01-\x0c]\0..\0\0/s)
    250303        },
    251304        SubDirectory => {
    252             TagTable => 'Image::ExifTool::Kodak::IFD',
     305            TagTable => 'Image::ExifTool::Kodak::Type8',
    253306            ProcessProc => \&ProcessUnknown,
    254307            ByteOrder => 'Unknown',
     
    256309    },
    257310    {
     311        Name => 'MakerNoteKodak8b',
     312        # TIFF-format maker notes
     313        Condition => q{
     314            $$self{Make}=~/Kodak/i and
     315            $$valPt =~ /^(MM\0\x2a\0\0\0\x08|II\x2a\0\x08\0\0\0)/
     316        },
     317        SubDirectory => {
     318            TagTable => 'Image::ExifTool::Kodak::Type8',
     319            ProcessProc => \&ProcessUnknown,
     320            ByteOrder => 'Unknown',
     321            Start => '$valuePtr + 8',
     322            Base => '$start - 8',
     323        },
     324    },
     325    {
     326        Name => 'MakerNoteKodak9',
     327        # test header and Kodak:DateTimeOriginal
     328        Condition => '$$valPt =~ m{^IIII[\x02\x03]\0.{14}\d{4}/\d{2}/\d{2} }s',
     329        NotIFD => 1,
     330        SubDirectory => {
     331            TagTable => 'Image::ExifTool::Kodak::Type9',
     332            ByteOrder => 'LittleEndian',
     333        },
     334    },
     335    {
     336        Name => 'MakerNoteKodak10',
     337        # yet another type of Kodak IFD-format maker notes:
     338        # this type begins with a byte order indicator,
     339        # followed immediately by the IFD
     340        Condition => q{
     341            $$self{Make}=~/Kodak/i and
     342            $$valPt =~ /^(MM\0[\x02-\x7f]|II[\x02-\x7f]\0)/
     343        },
     344        SubDirectory => {
     345            TagTable => 'Image::ExifTool::Kodak::Type10',
     346            ProcessProc => \&ProcessUnknown,
     347            ByteOrder => 'Unknown',
     348            Start => '$valuePtr + 2',
     349        },
     350    },
     351    {
    258352        Name => 'MakerNoteKodakUnknown',
    259         Condition => '$self->{CameraMake}=~/Kodak/i',
     353        Condition => '$$self{Make}=~/Kodak/i and $$valPt!~/^AOC\0/',
    260354        NotIFD => 1,
    261355        SubDirectory => {
     
    267361        Name => 'MakerNoteKyocera',
    268362        # (starts with "KYOCERA")
    269         Condition => '$self->{CameraMake}=~/^KYOCERA/',
     363        Condition => '$$valPt =~ /^KYOCERA/',
    270364        SubDirectory => {
    271365            TagTable => 'Image::ExifTool::Unknown::Main',
     
    279373        Name => 'MakerNoteMinolta',
    280374        Condition => q{
    281             $self->{CameraMake}=~/^(Konica Minolta|Minolta)/i and
     375            $$self{Make}=~/^(Konica Minolta|Minolta)/i and
    282376            $$valPt !~ /^(MINOL|CAMER|MLY0|KC|\+M\+M|\xd7)/
    283377        },
     
    305399        # /^\xd7/ - DiMAGE RD3000
    306400        Name => 'MakerNoteMinolta3',
    307         Condition => '$self->{CameraMake} =~ /^(Konica Minolta|Minolta)/i',
     401        Condition => '$$self{Make} =~ /^(Konica Minolta|Minolta)/i',
     402        Binary => 1,
    308403        Notes => 'not EXIF-based',
    309         Binary => 1,
    310         NotIFD => 1,
    311404    },
    312405    {
    313406        # this maker notes starts with a standard TIFF header at offset 0x0a
    314407        Name => 'MakerNoteNikon',
    315         Condition => '$self->{CameraMake}=~/^NIKON/i and $$valPt=~/^Nikon\x00\x02/',
     408        Condition => '$$self{Make}=~/^NIKON/i and $$valPt=~/^Nikon\x00\x02/',
    316409        SubDirectory => {
    317410            TagTable => 'Image::ExifTool::Nikon::Main',
     
    324417        # older Nikon maker notes
    325418        Name => 'MakerNoteNikon2',
    326         Condition => '$self->{CameraMake}=~/^NIKON/ and $$valPt=~/^Nikon\x00\x01/',
     419        Condition => '$$self{Make}=~/^NIKON/ and $$valPt=~/^Nikon\x00\x01/',
    327420        SubDirectory => {
    328421            TagTable => 'Image::ExifTool::Nikon::Type2',
     
    334427        # headerless Nikon maker notes
    335428        Name => 'MakerNoteNikon3',
    336         Condition => '$self->{CameraMake}=~/^NIKON/i',
     429        Condition => '$$self{Make}=~/^NIKON/i',
    337430        SubDirectory => {
    338431            TagTable => 'Image::ExifTool::Nikon::Main',
     
    355448        Name => 'MakerNoteOlympus2',
    356449        # new Olympus maker notes start with "OLYMPUS\0"
    357         Condition => '$$valPt =~ /^OLYMPUS\0/ and $$self{OlympusType2} = 1',
     450        Condition => '$$valPt =~ /^OLYMPUS\0/',
    358451        SubDirectory => {
    359452            TagTable => 'Image::ExifTool::Olympus::Main',
     
    365458    {
    366459        Name => 'MakerNoteLeica',
    367         # (starts with "LEICA\0")
    368         Condition => '$self->{CameraMake} =~ /^LEICA/',
    369         SubDirectory => {
    370             # Leica uses the same format as Panasonic
     460        # (starts with "LEICA\0\0\0")
     461        Condition => '$$self{Make} eq "LEICA"',
     462        SubDirectory => {
     463            # many Leica models use the same format as Panasonic
    371464            TagTable => 'Image::ExifTool::Panasonic::Main',
    372465            Start => '$valuePtr + 8',
     
    375468    },
    376469    {
     470        Name => 'MakerNoteLeica2', # used by the M8
     471        # (starts with "LEICA\0\0\0")
     472        Condition => '$$self{Make} =~ /^Leica Camera AG/ and $$valPt =~ /^LEICA\0\0\0/',
     473        SubDirectory => {
     474            TagTable => 'Image::ExifTool::Panasonic::Leica2',
     475            # (the offset base is different in JPEG and DNG images, but we
     476            # can copy makernotes from one to the other, so we need special
     477            # logic to decide which base to apply)
     478            ProcessProc => \&FixLeicaBase,
     479            Start => '$valuePtr + 8',
     480            Base => '$start', # (- 8 for DNG images!)
     481            ByteOrder => 'Unknown',
     482        },
     483    },
     484    {
     485        Name => 'MakerNoteLeica3', # used by the R8 and R9
     486        # (starts with IFD)
     487        Condition => '$$self{Make} =~ /^Leica Camera AG/ and $$valPt !~ /^LEICA/ and $$self{Model} ne "S2"',
     488        SubDirectory => {
     489            TagTable => 'Image::ExifTool::Panasonic::Leica3',
     490            Start => '$valuePtr',
     491            ByteOrder => 'Unknown',
     492        },
     493    },
     494    {
     495        Name => 'MakerNoteLeica4', # used by the M9
     496        # (M9 starts with "LEICA0\x03\0")
     497        Condition => '$$self{Make} =~ /^Leica Camera AG/ and $$valPt =~ /^LEICA0/',
     498        SubDirectory => {
     499            TagTable => 'Image::ExifTool::Panasonic::Leica4',
     500            Start => '$valuePtr + 8',
     501            Base => '$start - 8', # (yay! Leica fixed the M8 problem)
     502            ByteOrder => 'Unknown',
     503        },
     504    },
     505    {
     506        Name => 'MakerNoteLeica5', # used by the X1
     507        # (X1 starts with "LEICA\0\x01\0", Make is "LEICA CAMERA AG")
     508        Condition => '$$valPt =~ /^LEICA\0\x01\0/',
     509        SubDirectory => {
     510            TagTable => 'Image::ExifTool::Panasonic::Leica5',
     511            Start => '$valuePtr + 8',
     512            Base => '$start - 8',
     513            ByteOrder => 'Unknown',
     514        },
     515    },
     516    {
     517        Name => 'MakerNoteLeica6', # used by the S2 (CAUTION: this tag name is special cased in the code)
     518        # (S2 starts with "LEICA\0\x02\xff", Make is "LEICA CAMERA AG",
     519        #  but maker notes aren't loaded at the time this is tested)
     520        Condition => '$$self{Model} eq "S2"',
     521        DataTag => 'LeicaTrailer',  # (generates fixup name for this tag)
     522        SubDirectory => {
     523            TagTable => 'Image::ExifTool::Panasonic::Leica6',
     524            Start => '$valuePtr + 8',
     525            ByteOrder => 'Unknown',
     526            # NOTE: Leica uses absolute file offsets when this maker note is stored
     527            # as a JPEG trailer -- this case is handled by ProcessLeicaTrailer in
     528            # Panasonic.pm, and any "Base" defined here is ignored for this case.
     529            # ExifTool may also create S2 maker notes inside the APP1 segment when
     530            # copying from other files, and for this the normal EXIF offsets are used,
     531            # Base should not be defined!
     532        },
     533    },
     534    {
    377535        Name => 'MakerNotePanasonic',
    378536        # (starts with "Panasonic\0")
    379         Condition => '$self->{CameraMake} =~ /^Panasonic/ and $$valPt!~/^MKE/',
     537        Condition => '$$valPt=~/^Panasonic/',
    380538        SubDirectory => {
    381539            TagTable => 'Image::ExifTool::Panasonic::Main',
     
    387545        Name => 'MakerNotePanasonic2',
    388546        # (starts with "Panasonic\0")
    389         Condition => '$self->{CameraMake} =~ /^Panasonic/',
     547        Condition => '$$self{Make}=~/^Panasonic/ and $$valPt=~/^MKE/',
    390548        SubDirectory => {
    391549            TagTable => 'Image::ExifTool::Panasonic::Type2',
     
    399557        Condition => q{
    400558            $$valPt=~/^AOC\0/ and
    401             $self->{CameraModel} !~ /^PENTAX Optio ?[34]30RS\s*$/
     559            $$self{Model} !~ /^PENTAX Optio ?[34]30RS\s*$/
    402560        },
    403561        SubDirectory => {
     
    416574        # (starts with an IFD)
    417575        # Casio-like maker notes used only by the Optio 330 and 430
    418         Condition => '$self->{CameraMake}=~/^Asahi/ and $$valPt!~/^AOC\0/',
     576        Condition => '$$self{Make}=~/^Asahi/ and $$valPt!~/^AOC\0/',
    419577        SubDirectory => {
    420578            TagTable => 'Image::ExifTool::Pentax::Type2',
     
    428586        # (starts with "AOC\0", like the more common Pentax maker notes)
    429587        # Casio maker notes used only by the Optio 330RS and 430RS
    430         Condition => '$self->{CameraMake}=~/^Asahi/',
     588        Condition => '$$self{Make}=~/^Asahi/',
    431589        SubDirectory => {
    432590            TagTable => 'Image::ExifTool::Casio::Type2',
     
    440598        # (starts with 3 or 4 digits)
    441599        # HP2-like text-based maker notes used by Optio E20
    442         Condition => '$self->{CameraMake}=~/^PENTAX/ and $$valPt=~/^\d{3}/',
     600        Condition => '$$self{Make}=~/^PENTAX/ and $$valPt=~/^\d{3}/',
    443601        NotIFD => 1,
    444602        SubDirectory => {
     
    449607    },
    450608    {
     609        Name => 'MakerNotePentax5',
     610        # (starts with "PENTAX \0")
     611        Condition => '$$valPt=~/^PENTAX \0/',
     612        SubDirectory => {
     613            TagTable => 'Image::ExifTool::Pentax::Main',
     614            Start => '$valuePtr + 10',
     615            Base => '$start - 10',
     616            ByteOrder => 'Unknown',
     617        },
     618    },
     619    {
     620        Name => 'MakerNotePhaseOne',
     621        # Starts with: 'IIIITwaR' or 'IIIICwaR' (have seen both written by P25)
     622        # (have also seen code which expects 'MMMMRawT')
     623        Condition => q{
     624            return undef unless $$valPt =~ /^(IIII.waR|MMMMRaw.)/s;
     625            $self->OverrideFileType($$self{TIFF_TYPE} = 'IIQ') if $count > 1000000;
     626            return 1;
     627        },
     628        NotIFD => 1,
     629        Binary => 1,
     630        PutFirst => 1, # place immediately after TIFF header
     631        Notes => 'the raw image data in PhaseOne IIQ images',
     632    },
     633    {
     634        Name => 'MakerNoteReconyx',
     635        Condition => '$$valPt =~ /^\x01\xf1[\x02\x03]\x00/',
     636        SubDirectory => {
     637            TagTable => 'Image::ExifTool::Reconyx::Main',
     638            ByteOrder => 'Little-endian',
     639        },
     640    },
     641    {
    451642        Name => 'MakerNoteRicoh',
    452         Condition => '$self->{CameraMake}=~/^RICOH/ and $$valPt=~/^Ricoh/i',
     643        # (my test R50 image starts with "      \x02\x01" - PH)
     644        Condition => '$$self{Make}=~/^RICOH/ and $$valPt=~/^(Ricoh|      )/i',
    453645        SubDirectory => {
    454646            TagTable => 'Image::ExifTool::Ricoh::Main',
     
    459651    {
    460652        Name => 'MakerNoteRicohText',
    461         Condition => '$self->{CameraMake}=~/^RICOH/',
     653        Condition => '$$self{Make}=~/^RICOH/',
    462654        NotIFD => 1,
    463655        SubDirectory => {
     
    467659    },
    468660    {
    469         # PreviewImage (Samsung Digimax plus some other types of cameras)
    470         %Image::ExifTool::previewImageTagInfo,
    471         Condition => '$$valPt =~ /^\xff\xd8\xff\xdb/',
    472         Notes => 'Samsung preview image',
     661        Name => 'MakerNoteSamsung1a',
     662        # Samsung STMN maker notes WITHOUT PreviewImage
     663        Condition => '$$valPt =~ /^STMN\d{3}.\0{4}/s',
     664        Binary => 1,
     665        Notes => 'Samsung "STMN" maker notes without PreviewImage',
     666    },
     667    {
     668        Name => 'MakerNoteSamsung1b',
     669        # Samsung STMN maker notes WITH PreviewImage
     670        Condition => '$$valPt =~ /^STMN\d{3}/',
     671        SubDirectory => {
     672            TagTable => 'Image::ExifTool::Samsung::Type1',
     673        },
     674    },
     675    {
     676        Name => 'MakerNoteSamsung2',
     677        # Samsung EXIF-format maker notes
     678        Condition => q{
     679            $$self{Make} eq 'SAMSUNG' and ($$self{TIFF_TYPE} eq 'SRW' or
     680            $$valPt=~/^(\0.\0\x01\0\x07\0{3}\x04|.\0\x01\0\x07\0\x04\0{3})0100/s)
     681        },
     682        SubDirectory => {
     683            TagTable => 'Image::ExifTool::Samsung::Type2',
     684            # Samsung is very inconsistent here, and uses absolute offsets for some
     685            # models and relative offsets for others, so process as Unknown
     686            ProcessProc => \&ProcessUnknown,
     687            FixBase => 1,
     688            ByteOrder => 'Unknown',
     689        },
    473690    },
    474691    {
    475692        Name => 'MakerNoteSanyo',
    476693        # (starts with "SANYO\0")
    477         Condition => '$self->{CameraMake}=~/^SANYO/ and $self->{CameraModel} !~ /^(C4|J\d|S\d)\b/',
     694        Condition => '$$self{Make}=~/^SANYO/ and $$self{Model}!~/^(C4|J\d|S\d)\b/',
    478695        SubDirectory => {
    479696            TagTable => 'Image::ExifTool::Sanyo::Main',
     
    486703        Name => 'MakerNoteSanyoC4',
    487704        # The C4 offsets are wrong by 12, so they must be fixed
    488         Condition => '$self->{CameraMake}=~/^SANYO/ and $self->{CameraModel} =~ /^C4\b/',
     705        Condition => '$$self{Make}=~/^SANYO/ and $$self{Model}=~/^C4\b/',
    489706        SubDirectory => {
    490707            TagTable => 'Image::ExifTool::Sanyo::Main',
     
    498715        Name => 'MakerNoteSanyoPatch',
    499716        # The J1, J2, J4, S1, S3 and S4 offsets are completely screwy
    500         Condition => '$self->{CameraMake}=~/^SANYO/',
     717        Condition => '$$self{Make}=~/^SANYO/',
    501718        SubDirectory => {
    502719            TagTable => 'Image::ExifTool::Sanyo::Main',
     
    510727        Name => 'MakerNoteSigma',
    511728        # (starts with "SIGMA\0")
    512         Condition => '$self->{CameraMake}=~/^(SIGMA|FOVEON)/',
     729        Condition => '$$self{Make}=~/^(SIGMA|FOVEON)/',
    513730        SubDirectory => {
    514731            TagTable => 'Image::ExifTool::Sigma::Main',
     
    521738        Name => 'MakerNoteSony',
    522739        # (starts with "SONY DSC \0" or "SONY CAM \0")
    523         Condition => '$self->{CameraMake}=~/^SONY/ and $self->{TIFF_TYPE}!~/^(SRF|SR2|DNG)$/',
     740        Condition => '$$self{Make}=~/^SONY/ and $$valPt=~/^SONY (DSC|CAM)/',
    524741        SubDirectory => {
    525742            TagTable => 'Image::ExifTool::Sony::Main',
    526             # validate the maker note because this is sometimes garbage
    527             Validate => 'defined($val) and $val =~ /^SONY (DSC|CAM)/',
    528743            Start => '$valuePtr + 12',
    529744            ByteOrder => 'Unknown',
     
    531746    },
    532747    {
     748        Name => 'MakerNoteSony2',
     749        # (starts with "SONY PI\0" -- DSC-S650/S700/S750)
     750        Condition => '$$self{Make}=~/^SONY/ and $$valPt=~/^SONY PI\0/ and $$self{OlympusCAMER}=1',
     751        SubDirectory => {
     752            TagTable => 'Image::ExifTool::Olympus::Main',
     753            Start => '$valuePtr + 12',
     754            ByteOrder => 'Unknown',
     755        },
     756    },
     757    {
     758        Name => 'MakerNoteSony3',
     759        # (starts with "PREMI\0" -- DSC-S45/S500)
     760        Condition => '$$self{Make}=~/^SONY/ and $$valPt=~/^(PREMI)\0/ and $$self{OlympusCAMER}=1',
     761        SubDirectory => {
     762            TagTable => 'Image::ExifTool::Olympus::Main',
     763            Start => '$valuePtr + 8',
     764            ByteOrder => 'Unknown',
     765        },
     766    },
     767    {
     768        Name => 'MakerNoteSony4', # used in SR2 and ARW images
     769        Condition => '$$self{Make}=~/^SONY/ and $$valPt!~/^\x01\x00/',
     770        SubDirectory => {
     771            TagTable => 'Image::ExifTool::Sony::Main',
     772            Start => '$valuePtr',
     773            ByteOrder => 'Unknown',
     774        },
     775    },
     776    {
     777        Name => 'MakerNoteSonyEricsson',
     778        Condition => '$$valPt =~ /^SEMC MS\0/',
     779        SubDirectory => {
     780            TagTable => 'Image::ExifTool::Sony::Ericsson',
     781            Start => '$valuePtr + 20',
     782            Base => '$start - 8',
     783            ByteOrder => 'Unknown',
     784        },
     785    },
     786    {
    533787        Name => 'MakerNoteSonySRF',
    534         Condition => '$self->{CameraMake}=~/^SONY/ and $$valPt =~ /^\x01\x00/',
     788        Condition => '$$self{Make}=~/^SONY/',
    535789        SubDirectory => {
    536790            TagTable => 'Image::ExifTool::Sony::SRF',
     
    540794    },
    541795    {
    542         Name => 'MakerNoteSonySR2',
    543         Condition => '$self->{CameraMake}=~/^SONY/',
    544         SubDirectory => {
    545             TagTable => 'Image::ExifTool::Sony::Main',
    546             Start => '$valuePtr',
    547             ByteOrder => 'Unknown',
    548         },
     796        Name => 'MakerNoteUnknownText',
     797        Condition => '$$valPt =~ /^[\x09\x0d\x0a\x20-\x7e]+\0*$/',
     798        Notes => 'unknown text-based maker notes',
     799        # show as binary if it is too long
     800        ValueConv => 'length($val) > 64 ? \$val : $val',
     801        ValueConvInv => '$val',
    549802    },
    550803    {
    551804        Name => 'MakerNoteUnknown',
     805        PossiblePreview => 1,
    552806        SubDirectory => {
    553807            TagTable => 'Image::ExifTool::Unknown::Main',
    554             ProcessProc => \&ProcessUnknown,
    555             ByteOrder => 'Unknown',
    556         },
     808            ProcessProc => \&ProcessUnknownOrPreview,
     809            WriteProc => \&WriteUnknownOrPreview,
     810            ByteOrder => 'Unknown',
     811            FixBase => 2,
     812       },
    557813    },
    558814);
     
    565821    $$tagInfo{Groups} = { 1 => 'MakerNotes' };
    566822    next unless $$tagInfo{SubDirectory};
    567     # set up this tag so we can write it
    568     $$tagInfo{ValueConv} = '\$val';
    569     $$tagInfo{ValueConvInv} = '$val';
     823    # make all SubDirectory tags block-writable
     824    $$tagInfo{Binary} = 1,
    570825    $$tagInfo{MakerNotes} = 1;
    571826}
     
    582837    my $exifTool = shift;
    583838    # figure out where we expect the value data based on camera type
    584     my $make = $exifTool->{CameraMake};
    585     my $model = $exifTool->{CameraModel};
     839    my $make = $exifTool->{Make};
     840    my $model = $exifTool->{Model};
    586841    my ($relative, @offsets);
    587842
    588     # normally value data starts 4 bytes after end of directory, so this is the default
     843    # normally value data starts 4 bytes after end of directory, so this is the default.
     844    # offsets of 0 and 4 are always allowed even if not specified,
     845    # but the first offset specified is the one used when writing
    589846    if ($make =~ /^Canon/) {
    590847        push @offsets, ($model =~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/) ? 6 : 4;
     
    592849        # at the end of the IFD (2 spare IFD entries?)
    593850        push @offsets, 28 if $model =~ /\b(FV\b|OPTURA)/;
     851        # some Canon PowerShot models leave 12 unused bytes
     852        push @offsets, 16 if $model =~ /(PowerShot|IXUS|IXY)/;
     853    } elsif ($make =~ /^CASIO/) {
     854        # Casio AVI and MOV images use no padding, and their JPEG's use 4,
     855        # except some models like the EX-S770,Z65,Z70,Z75 and Z700 which use 16,
     856        # and the EX-Z35 which uses 2 (grrrr...)
     857        push @offsets, $$exifTool{FILE_TYPE} =~ /^(RIFF|MOV)$/ ? 0 : (4, 16, 2);
     858    } elsif ($make =~ /^(General Imaging Co.|GEDSC IMAGING CORP.)/i) {
     859        push @offsets, 0;
    594860    } elsif ($make =~ /^KYOCERA/) {
    595861        push @offsets, 12;
     862    } elsif ($make =~ /^Leica Camera AG/) {
     863        if ($model eq 'S2') {
     864            # lots of empty space before first value in S2 images
     865            push @offsets, 4, ($$exifTool{FILE_TYPE} eq 'JPEG' ? 286 : 274);
     866        } elsif ($model =~ /^(R8|R9|M8)\b/) {
     867            push @offsets, 6;
     868        } else {
     869            push @offsets, 4;
     870        }
    596871    } elsif ($make =~ /^OLYMPUS/ and $model =~ /^E-(1|300|330)\b/) {
    597872        push @offsets, 16;
     
    601876    {
    602877        # no expected offset --> determine offset empirically via FixBase()
    603     } elsif ($make =~ /^(Panasonic|SONY|JVC)\b/) {
     878    } elsif ($make =~ /^(Panasonic|JVC)\b/) {
    604879        push @offsets, 0;
     880    } elsif ($make =~ /^SONY/) {
     881        # DSLR and "PREMI" models use an offset of 4
     882        if ($model =~ /DSLR/ or $$exifTool{OlympusCAMER}) {
     883            push @offsets, 4;
     884        } else {
     885            push @offsets, 0;
     886        }
    605887    } elsif ($make eq 'FUJIFILM') {
    606888        # some models have offset of 6, so allow that too (A345,A350,A360,A370)
     
    629911#------------------------------------------------------------------------------
    630912# Get hash of value offsets / block sizes
    631 # Inputs: 0) Data pointer, 1) offset to start of directory
     913# Inputs: 0) Data pointer, 1) offset to start of directory,
     914#         2) hash ref to return value pointers based on tag ID
    632915# Returns: 0) hash reference: keys are offsets, values are block sizes
    633916#          1) same thing, but with keys adjusted for value-based offsets
    634917# Notes: Directory size should be validated before calling this routine
    635918# - calculates MIN and MAX offsets in entry-based hash
    636 sub GetValueBlocks($$)
     919sub GetValueBlocks($$;$)
    637920{
    638     my ($dataPt, $dirStart) = @_;
     921    my ($dataPt, $dirStart, $tagPtr) = @_;
    639922    my $numEntries = Get16u($dataPt, $dirStart);
    640923    my ($index, $valPtr, %valBlock, %valBlkAdj, $end);
     
    647930        next if $size <= 4;
    648931        $valPtr = Get32u($dataPt, $entry+8);
     932        $tagPtr and $$tagPtr{Get16u($dataPt, $entry)} = $valPtr;
    649933        # save location and size of longest block at this offset
    650934        unless (defined $valBlock{$valPtr} and $valBlock{$valPtr} > $size) {
     
    688972    my $fixBase = $exifTool->Options('FixBase');
    689973    my $setBase = (defined $fixBase and $fixBase ne '') ? 1 : 0;
    690     my ($fix, $fixedBy);
    691 #
    692 # handle special case of Canon maker notes with TIFF trailer containing original offset
    693 #
    694     if ($$exifTool{CameraMake} =~ /^Canon/ and $$dirInfo{DirLen} > 8) {
    695         my $trailerPos = $dirStart + $$dirInfo{DirLen} - 8;
    696         my $trailer = substr($$dataPt, $trailerPos, 8);
    697         if ($trailer =~ /^(II\x2a\0|MM\0\x2a)/ and  # check for TIFF trailer
    698             substr($trailer,0,2) eq GetByteOrder()) # validate byte ordering
     974    my ($fix, $fixedBy, %tagPtr);
     975
     976    # get hash of value block positions
     977    my ($valBlock, $valBlkAdj) = GetValueBlocks($dataPt, $dirStart, \%tagPtr);
     978    return 0 unless %$valBlock;
     979    # get sorted list of value offsets
     980    my @valPtrs = sort { $a <=> $b } keys %$valBlock;
     981#
     982# handle special case of Canon maker notes with TIFF footer containing original offset
     983#
     984    if ($$exifTool{Make} =~ /^Canon/ and $$dirInfo{DirLen} > 8) {
     985        my $footerPos = $dirStart + $$dirInfo{DirLen} - 8;
     986        my $footer = substr($$dataPt, $footerPos, 8);
     987        if ($footer =~ /^(II\x2a\0|MM\0\x2a)/ and  # check for TIFF footer
     988            substr($footer,0,2) eq GetByteOrder()) # validate byte ordering
    699989        {
    700             if ($$exifTool{HTML_DUMP}) {
    701                 my $filePos = ($$dirInfo{Base} || 0) + $dataPos + $trailerPos;
    702                 $exifTool->HtmlDump($filePos, 8, '[Canon MakerNote trailer]')
    703             }
     990            my $oldOffset = Get32u(\$footer, 4);
     991            my $newOffset = $dirStart + $dataPos;
    704992            if ($setBase) {
    705993                $fix = $fixBase;
    706994            } else {
    707                 my $oldOffset = Get32u(\$trailer, 4);
    708                 my $newOffset = $dirStart + $dataPos;
    709995                $fix = $newOffset - $oldOffset;
    710996                return 0 unless $fix;
     997                # Picasa and ACDSee have a bug where they update other offsets without
     998                # updating the TIFF footer (PH - 2009/02/25), so test for this case:
     999                # validate Canon maker note footer fix by checking offset of last value
     1000                my $maxPt = $valPtrs[-1] + $$valBlock{$valPtrs[-1]};
     1001                # compare to end of maker notes, taking 8-byte footer into account
     1002                my $endDiff = $dirStart + $$dirInfo{DirLen} - ($maxPt - $dataPos) - 8;
     1003                # ignore footer offset only if end difference is exactly correct
     1004                # (allow for possible padding byte, although I have never seen this)
     1005                if (not $endDiff or $endDiff == 1) {
     1006                    $exifTool->Warn('Canon maker note footer may be invalid (ignored)',1);
     1007                    return 0;
     1008                }
    7111009            }
    712             $exifTool->Warn("Adjusted $dirName base by $fix", 1);
     1010            $exifTool->Warn("Adjusted $dirName base by $fix",1);
    7131011            $$dirInfo{FixedBy} = $fix;
    7141012            $$dirInfo{Base} += $fix;
     
    7181016    }
    7191017#
    720 # analyze value offsets to see if they need fixing.  The first task is to
    721 # determine the minimum valid offset used (this is tricky, because we have
    722 # to weed out bad offsets written by some cameras)
    723 #
    724     # get hash of value block positions
    725     my ($valBlock, $valBlkAdj) = GetValueBlocks($dataPt, $dirStart);
    726     return 0 unless %$valBlock;
    727 
     1018# analyze value offsets to see if they need fixing.  The first task is to determine
     1019# the minimum valid offset used (this is tricky, because we have to weed out bad
     1020# offsets written by some cameras)
     1021#
     1022    my $minPt = $$dirInfo{MinOffset} = $valPtrs[0]; # if life were simple, this would be it
    7281023    my $ifdLen = 2 + 12 * Get16u($$dirInfo{DataPt}, $dirStart);
    7291024    my $ifdEnd = $dirStart + $ifdLen;
     
    7361031    my $expected = $dataPos + $ifdEnd + (defined $makeDiff ? $makeDiff : 4);
    7371032    $debug and print "$expected expected\n";
    738 
    739     # get sorted list of value offsets
    740     my @valPtrs = sort { $a <=> $b } keys %$valBlock;
    741     my $minPt = $valPtrs[0];    # if life were simple, this would be it
    7421033
    7431034    # zero our counters
     
    7481039               $valPtr - ($last || 0)) if $debug;
    7491040        if (defined $last) {
    750             my $diff = $valPtr - $last;
    751             if ($diff == 0 or $diff == 1) {
     1041            my $gap = $valPtr - $last;
     1042            if ($gap == 0 or $gap == 1) {
    7521043                ++$countZero;
    753             } elsif ($diff == -12 and not $entryBased) {
     1044            } elsif ($gap == -12 and not $entryBased) {
    7541045                # you get this when value offsets are relative to the IFD entry
    7551046                ++$countNeg12;
    756             } elsif ($diff < 0) {
     1047            } elsif ($gap < 0) {
    7571048                # any other negative difference indicates overlapping values
    7581049                ++$countOverlap if $valPtr; # (but ignore zero value pointers)
    759             } elsif ($diff >= $ifdLen) {
     1050            } elsif ($gap >= $ifdLen) {
    7601051                # ignore previous minimum if we took a jump to near the expected value
    7611052                # (some values can be stored before the IFD)
     
    7751066        # which have been correcting for individual entry position
    7761067        $entryBased = 1;
    777         $verbose and $exifTool->Warn("$dirName offsets are entry-based");
     1068        $verbose and $exifTool->Warn("$dirName offsets are entry-based",1);
    7781069    } else {
    779         # calculate difference from normal
     1070        # calculate offset difference from end of IFD to first value
    7801071        $diff = ($minPt - $dataPos) - $ifdEnd;
    7811072        $shift = 0;
    7821073        $countOverlap and $exifTool->Warn("Overlapping $dirName values",1);
    7831074        if ($entryBased) {
    784             $exifTool->Warn("$dirName offsets do NOT look entry-based");
     1075            $exifTool->Warn("$dirName offsets do NOT look entry-based",1);
    7851076            undef $entryBased;
    7861077            undef $relative;
    7871078        }
     1079        # use PrintIM tag to do special check for correct absolute offsets
     1080        if ($tagPtr{0xe00}) {
     1081            my $ptr = $tagPtr{0xe00} - $dataPos;
     1082            return 0 if $ptr > 0 and $ptr <= length($$dataPt) - 8 and
     1083                        substr($$dataPt, $ptr, 8) eq "PrintIM\0";
     1084        }
     1085        # allow a range of reasonable differences for Unknown maker notes
     1086        if ($$dirInfo{FixBase} and $$dirInfo{FixBase} == 2) {
     1087            return 0 if $diff >=0 and $diff <= 24;
     1088        }
     1089        # (used for testing to extract differences)
     1090        # $exifTool->FoundTag('Diff', $diff);
    7881091    }
    7891092#
     
    8711174    my $dataPt = $$dirInfo{DataPt};
    8721175    my $dirStart = $$dirInfo{DirStart} || 0;
    873     my $size = $$dirInfo{DirLen} || ($$dirInfo{DataLen} - $dirStart);
     1176    # (ignore MakerNotes DirLen since sometimes this is incorrect)
     1177    my $size = $$dirInfo{DataLen} - $dirStart;
     1178    my $dirLen = $$dirInfo{DirLen} || $size;
    8741179    my $tagInfo = $$dirInfo{TagInfo};
    8751180    my $ifdOffsetPos;
     
    8861191    if ($tagInfo and $$tagInfo{SubDirectory}) {
    8871192        my $subdir = $$tagInfo{SubDirectory};
    888         unless ($$subdir{ProcessProc} and $$subdir{ProcessProc} eq \&ProcessUnknown) {
     1193        unless ($$subdir{ProcessProc} and
     1194               ($$subdir{ProcessProc} eq \&ProcessUnknown or
     1195                $$subdir{ProcessProc} eq \&ProcessUnknownOrPreview))
     1196        {
    8891197            # look for the IFD at the "Start" specified in our SubDirectory information
    8901198            my $valuePtr = $dirStart;
     
    8971205                # calculate subdirectory start relative to $base for eval
    8981206                my $start = $newStart + $$dirInfo{DataPos};
    899                 #### eval Base ($start)
     1207                my $base = $$dirInfo{Base} || 0;
     1208                #### eval Base ($start,$base)
    9001209                my $baseShift = eval($$subdir{Base});
    9011210                # shift directory base (note: we may do this again below
     
    9051214                $$dirInfo{DataPos} -= $baseShift;
    9061215                # this is a relative directory if Base depends on $start
    907                 $$dirInfo{Relative} = 1 if $$subdir{Base} =~ /\$start\b/;
     1216                if ($$subdir{Base} =~ /\$start\b/) {
     1217                    $$dirInfo{Relative} = 1;
     1218                    # hack to fix Leica quirk
     1219                    if ($$subdir{ProcessProc} and $$subdir{ProcessProc} eq \&FixLeicaBase) {
     1220                        my $oldStart = $$dirInfo{DirStart};
     1221                        $$dirInfo{DirStart} = $newStart;
     1222                        FixLeicaBase($exifTool, $dirInfo);
     1223                        $$dirInfo{DirStart} = $oldStart;
     1224                    }
     1225                }
    9081226            }
    9091227            # add offset to the start of the directory if necessary
     
    9271245# scan for something that looks like an IFD
    9281246#
    929     if ($size >= 14 + $firstTry) {  # minimum size for an IFD
     1247    if ($dirLen >= 14 + $firstTry) {  # minimum size for an IFD
    9301248        my $offset;
    9311249IFD_TRY: for ($offset=$firstTry; $offset<=$lastTry; $offset+=2) {
    932             last if $offset + 14 > $size;    # 14 bytes is minimum size for an IFD
     1250            last if $offset + 14 > $dirLen;    # 14 bytes is minimum size for an IFD
    9331251            my $pos = $dirStart + $offset;
    9341252#
     
    9431261                # get pointer to IFD
    9441262                my $ptr = Get32u($dataPt, $pos + $ifdOffsetPos);
    945                 if ($ptr >= $ifdOffsetPos + 4 and $ptr + $offset + 14 <= $size) {
     1263                if ($ptr >= $ifdOffsetPos + 4 and $ptr + $offset + 14 <= $dirLen) {
    9461264                    # shift directory start and shorten dirLen accordingly
    9471265                    $$dirInfo{DirStart} += $ptr + $offset;
     
    9831301                # because some manufacturers pad with null entries
    9841302                next unless $format or $count or $index == 0;
     1303                # patch for Canon EOS 40D firmware 1.0.4 bug: allow zero format for last entry
     1304                next if $format==0 and $index==$num-1 and $$exifTool{Model}=~/EOS 40D/;
    9851305                # (would like to verify tag ID, but some manufactures don't
    9861306                #  sort entries in order of tag ID so we don't have much of
     
    9911311                # cameras like the 1DmkIII use this value)
    9921312                next IFD_TRY if $count & 0xff000000;
     1313                # extra tests to avoid mis-identifying Samsung makernotes (GT-I9000, etc)
     1314                next unless $num == 1;
     1315                my $valueSize = $count * $Image::ExifTool::Exif::formatSize[$format];
     1316                if ($valueSize > 4) {
     1317                    next IFD_TRY if $valueSize > $size;
     1318                    my $valuePtr = Get32u($dataPt, $entry+8);
     1319                    next IFD_TRY if $valuePtr > 0x10000;
     1320                }
    9931321            }
    9941322            $$dirInfo{DirStart} += $offset;    # update directory start
     
    10011329
    10021330#------------------------------------------------------------------------------
     1331# Fix base offset for Leica maker notes
     1332# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     1333# Returns: 1 on success, and updates $dirInfo if necessary for new directory
     1334sub FixLeicaBase($$;$)
     1335{
     1336    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     1337    my $dataPt = $$dirInfo{DataPt};
     1338    my $dirStart = $$dirInfo{DirStart} || 0;
     1339    # get hash of value block positions
     1340    my ($valBlock, $valBlkAdj) = GetValueBlocks($dataPt, $dirStart);
     1341    if (%$valBlock) {
     1342        # get sorted list of value offsets
     1343        my @valPtrs = sort { $a <=> $b } keys %$valBlock;
     1344        my $numEntries = Get16u($dataPt, $dirStart);
     1345        my $diff = $valPtrs[0] - ($numEntries * 12 + 4);
     1346        if ($diff > 8) {
     1347            $$dirInfo{Base} -= 8;
     1348            $$dirInfo{DataPos} += 8;
     1349        }
     1350    }
     1351    my $success = 1;
     1352    if ($tagTablePtr) {
     1353        $success = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
     1354    }
     1355    return $success;
     1356}
     1357
     1358#------------------------------------------------------------------------------
     1359# Process Canon maker notes
     1360# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     1361# Returns: 1 on success
     1362sub ProcessCanon($$$)
     1363{
     1364    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     1365    # identify Canon MakerNote footer in HtmlDump
     1366    # (this code moved from FixBase so it also works for Adobe MakN in DNG images)
     1367    if ($$exifTool{HTML_DUMP} and $$dirInfo{DirLen} > 8) {
     1368        my $dataPos = $$dirInfo{DataPos};
     1369        my $dirStart = $$dirInfo{DirStart} || 0;
     1370        my $footerPos = $dirStart + $$dirInfo{DirLen} - 8;
     1371        my $footer = substr(${$$dirInfo{DataPt}}, $footerPos, 8);
     1372        if ($footer =~ /^(II\x2a\0|MM\0\x2a)/ and substr($footer,0,2) eq GetByteOrder()) {
     1373            my $oldOffset = Get32u(\$footer, 4);
     1374            my $newOffset = $dirStart + $dataPos;
     1375            my $str = sprintf('Original maker note offset: 0x%.4x', $oldOffset);
     1376            if ($oldOffset != $newOffset) {
     1377                $str .= sprintf("\nCurrent maker note offset: 0x%.4x", $newOffset);
     1378            }
     1379            my $filePos = ($$dirInfo{Base} || 0) + $dataPos + $footerPos;
     1380            $exifTool->HDump($filePos, 8, '[Canon MakerNotes footer]', $str);
     1381        }
     1382    }
     1383    # process as normal
     1384    return Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
     1385}
     1386
     1387#------------------------------------------------------------------------------
     1388# Process GE type 2 maker notes
     1389# Inputs: 0) ExifTool object ref, 1) DirInfo ref, 2) tag table ref
     1390# Returns: 1 on success
     1391sub ProcessGE2($$$)
     1392{
     1393    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     1394    my $dataPt = $$dirInfo{DataPt} or return 0;
     1395    my $dirStart = $$dirInfo{DirStart} || 0;
     1396
     1397    # these maker notes are missing the IFD entry count, but they
     1398    # always have 25 entries, so write the entry count manually
     1399    Set16u(25, $dataPt, $dirStart);
     1400    return Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
     1401}
     1402
     1403#------------------------------------------------------------------------------
     1404# Process unknown maker notes or PreviewImage
     1405# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     1406# Returns: 1 on success, and updates $dirInfo if necessary for new directory
     1407sub ProcessUnknownOrPreview($$$)
     1408{
     1409    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     1410    my $dataPt = $$dirInfo{DataPt};
     1411    my $dirStart = $$dirInfo{DirStart};
     1412    my $dirLen = $$dirInfo{DirLen};
     1413    # check to see if this is a preview image
     1414    if ($dirLen > 6 and substr($$dataPt, $dirStart, 3) eq "\xff\xd8\xff") {
     1415        $exifTool->VerboseDir('PreviewImage');
     1416        if ($$exifTool{HTML_DUMP}) {
     1417            my $pos = $$dirInfo{DataPos} + $$dirInfo{Base} + $dirStart;
     1418            $exifTool->HDump($pos, $dirLen, '(MakerNotes:PreviewImage data)', "Size: $dirLen bytes")
     1419        }
     1420        $exifTool->FoundTag('PreviewImage', substr($$dataPt, $dirStart, $dirLen));
     1421        return 1;
     1422    }
     1423    return ProcessUnknown($exifTool, $dirInfo, $tagTablePtr);
     1424}
     1425
     1426#------------------------------------------------------------------------------
     1427# Write unknown maker notes or PreviewImage
     1428# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     1429# Returns: directory data, '' to delete, or undef on error
     1430sub WriteUnknownOrPreview($$$)
     1431{
     1432    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     1433    my $dataPt = $$dirInfo{DataPt};
     1434    my $dirStart = $$dirInfo{DirStart};
     1435    my $dirLen = $$dirInfo{DirLen};
     1436    my $newVal;
     1437    # check to see if this is a preview image
     1438    if ($dirLen > 6 and substr($$dataPt, $dirStart, 3) eq "\xff\xd8\xff") {
     1439        if ($$exifTool{NEW_VALUE}{$Image::ExifTool::Extra{PreviewImage}}) {
     1440            # write or delete new preview (if deleted, it can't currently be added back again)
     1441            $newVal = $exifTool->GetNewValues('PreviewImage') || '';
     1442            if ($exifTool->Options('Verbose') > 1) {
     1443                $exifTool->VerboseValue("- MakerNotes:PreviewImage", substr($$dataPt, $dirStart, $dirLen));
     1444                $exifTool->VerboseValue("+ MakerNotes:PreviewImage", $newVal) if $newVal;
     1445            }
     1446            ++$$exifTool{CHANGED};
     1447        } else {
     1448            $newVal = substr($$dataPt, $dirStart, $dirLen);
     1449        }
     1450    } else {
     1451        # rewrite MakerNote IFD
     1452        $newVal = Image::ExifTool::Exif::WriteExif($exifTool, $dirInfo, $tagTablePtr);
     1453    }
     1454    return $newVal;
     1455}
     1456
     1457#------------------------------------------------------------------------------
    10031458# Process unknown maker notes assuming it is in EXIF IFD format
    1004 # Inputs: 0) ExifTool object reference, 1) reference to directory information
    1005 #         2) pointer to tag table
     1459# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
    10061460# Returns: 1 on success, and updates $dirInfo if necessary for new directory
    10071461sub ProcessUnknown($$$)
     
    10231477    } else {
    10241478        $exifTool->{UnknownByteOrder} = ''; # indicates we tried but didn't set byte order
    1025         $exifTool->Warn("Unrecognized $$dirInfo{DirName}");
     1479        $exifTool->Warn("Unrecognized $$dirInfo{DirName}", 1);
    10261480    }
    10271481    return $success;
     
    10481502=head1 AUTHOR
    10491503
    1050 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1504Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    10511505
    10521506This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Minolta.pm

    r16842 r24107  
    1919#              11) http://www.dyxum.com/dforum/forum_posts.asp?TID=6371&PN=1 and
    2020#                  http://www.dyxum.com/dAdmin/lenses/MakerNoteList_Public.asp?stro=makr
     21#                  http://dyxum.com/dforum/forum_posts.asp?TID=23435&PN=2
    2122#              12) http://www.minolta-forum.de/forum/index.php?showtopic=14914
    2223#              13) http://www.mhohner.de/minolta/lenses.php
    2324#              14) Jeffery Small private communication (tests with 7D)
    2425#              15) http://homepage3.nifty.com/kamisaka/makernote/makernote_sony.htm
     26#              16) Thomas Kassner private communication
     27#              17) Mladen Sever private communication
     28#              18) Olaf Ulrich private communication
     29#              19) Lukasz Stelmach private communication
     30#              20) Igal Milchtaich private communication (A100 firmware 1.04)
     31#              21) Jean-Michel Dubois private communication
     32#              22) http://www.mi-fo.de/forum/index.php?act=attach&type=post&id=6024
     33#              23) Marcin Krol private communication
     34#              24) http://cpanforum.com/threads/12291
     35#              JD) Jens Duttke private communication
    2536#------------------------------------------------------------------------------
    2637
     
    2839
    2940use strict;
    30 use vars qw($VERSION %minoltaLensIDs %minoltaColorMode);
     41use vars qw($VERSION %minoltaLensTypes %minoltaColorMode %sonyColorMode %minoltaSceneMode);
    3142use Image::ExifTool qw(:DataAccess :Utils);
    3243use Image::ExifTool::Exif;
    3344
    34 $VERSION = '1.33';
     45$VERSION = '1.76';
    3546
    3647# lens ID numbers (ref 3)
    37 %minoltaLensIDs = (
    38     0 => 'Minolta AF 28-85mm F3.5-4.5',
     48# ("New" and "II" appear in brackets if original version also has this LensType)
     49%minoltaLensTypes = (
     50    Notes => q{
     51        Decimal values differentiate lenses which would otherwise have the same
     52        LensType, and are used by the Composite LensID tag when attempting to
     53        identify the specific lens model.  "New" or "II" appear in brackets if the
     54        original version of the lens has the same LensType.
     55    },
     56    0 => 'Minolta AF 28-85mm F3.5-4.5 New', # New added (ref 13/18)
    3957    1 => 'Minolta AF 80-200mm F2.8 HS-APO G',
    4058    2 => 'Minolta AF 28-70mm F2.8 G',
    4159    3 => 'Minolta AF 28-80mm F4-5.6',
    42     5 => 'Minolta AF 35-70mm F3.5-4.5',
    43     6 => 'Minolta AF 24-85mm F3.5-4.5 [New]',
    44     # 7 => 'AF 100-400mm F4.5-6.7 (D)', ??
    45     7 => 'Minolta AF 100-300mm F4.5-5.6 APO [New]',
    46     8 => 'Minolta AF 70-210mm F4.5-5.6',
     60    5 => 'Minolta AF 35-70mm F3.5-4.5 [II]', # (original and II, ref 13)
     61    6 => 'Minolta AF 24-85mm F3.5-4.5 [New]', # (original and New, ref 13)
     62  # 7 => 'AF 100-400mm F4.5-6.7 (D)', ??
     63    7 => 'Minolta AF 100-300mm F4.5-5.6 APO [New] or 100-400mm or Sigma Lens',
     64    7.1 => 'Minolta AF 100-400mm F4.5-6.7 APO', #JD
     65    7.2 => 'Sigma AF 100-300mm F4 EX DG IF', #JD
     66    8 => 'Minolta AF 70-210mm F4.5-5.6 [II]', # (original and II, ref 13)
    4767    9 => 'Minolta AF 50mm F3.5 Macro',
    48     10 => 'Minolta AF 28-105mm F3.5-4.5 [New]',
     68    10 => 'Minolta AF 28-105mm F3.5-4.5 [New]', # (original and New, ref 13)
    4969    11 => 'Minolta AF 300mm F4 HS-APO G',
    5070    12 => 'Minolta AF 100mm F2.8 Soft Focus',
    51     13 => 'Minolta AF 75-300mm F4.5-5.6',
     71    13 => 'Minolta AF 75-300mm F4.5-5.6 (New or II)', # (II and New, ref 13)
    5272    14 => 'Minolta AF 100-400mm F4.5-6.7 APO',
    5373    15 => 'Minolta AF 400mm F4.5 HS-APO G',
     
    5575    17 => 'Minolta AF 20-35mm F3.5-4.5',
    5676    18 => 'Minolta AF 28-80mm F3.5-5.6 II',
    57     19 => 'Minolta AF 35mm F1.4',
    58     20 => 'Minolta STF 135mm F2.8 [T4.5]',
    59     22 => 'Minolta AF 35-80mm F4-5.6',
    60     23 => 'Minolta AF 200mm F4 G APO Macro',
    61     24 => 'Minolta AF 24-105mm F3.5-4.5 (D)', # or Sigma 18-50mm F2.8 or Sigma 17-70mm F2.8-4.5 (D)',
    62     25 => 'Minolta AF 100-300mm F4.5-5.6 (D)',
    63     27 => 'Minolta AF 85mm F1.4 G',
    64     28 => 'Minolta AF 100mm F2.8 Macro (D)',
    65     29 => 'Minolta AF 75-300mm F4.5-5.6 (D)',
    66     30 => 'Minolta AF 28-80mm F3.5-5.6 (D)', # or Sigma AF 12-24mm F4.5-5.6 EX DG',
    67     31 => 'Minolta AF 50mm F2.8 Macro (D) or AF 50mm F3.5 Macro',
    68     # 32 => 'AF 100-400mm F4.5-6.7 (D) x1.5', ??
    69     32 => 'Minolta AF 300mm F2.8 G',
    70     33 => 'Minolta AF 70-200mm F2.8 G (D) SSM',
     77    19 => 'Minolta AF 35mm F1.4 G', # G added (ref 18), but not New as per ref 13
     78    20 => 'Minolta/Sony 135mm F2.8 [T4.5] STF',
     79    22 => 'Minolta AF 35-80mm F4-5.6 II', # II added (ref 13)
     80    23 => 'Minolta AF 200mm F4 Macro APO G',
     81    24 => 'Minolta/Sony AF 24-105mm F3.5-4.5 (D) or Sigma or Tamron Lens',
     82    24.1 => 'Sigma 18-50mm F2.8',
     83    24.2 => 'Sigma 17-70mm F2.8-4.5 (D)',
     84    24.3 => 'Sigma 20-40mm F2.8 EX DG Aspherical IF', #JD
     85    24.4 => 'Sigma 18-200mm F3.5-6.3 DC', #22
     86    24.5 => 'Sigma 20-40mm F2.8 EX DG Aspherical IF', #22
     87    24.6 => 'Tamron SP AF 28-75mm F2.8 XR Di (IF) Macro', #JD
     88    25 => 'Minolta AF 100-300mm F4.5-5.6 APO (D) or Sigma Lens',
     89    25.1 => 'Sigma 100-300mm F4 EX (APO (D) or D IF)', #JD
     90    25.2 => 'Sigma 70mm F2.8 EX DG Macro', #JD
     91    25.3 => 'Sigma 20mm F1.8 EX DG Aspherical RF', #19
     92    25.4 => 'Sigma 30mm F1.4 DG EX', #21
     93    27 => 'Minolta AF 85mm F1.4 G (D)', # added (D) (ref 13)
     94    28 => 'Minolta/Sony AF 100mm F2.8 Macro (D) or Tamron Lens',
     95    # 28 => 'Sony 100mm F2.8 Macro (SAL-100M28)' (ref 18)
     96    28.1 => 'Tamron SP AF 90mm F2.8 Di Macro', #JD
     97    29 => 'Minolta/Sony AF 75-300mm F4.5-5.6 (D)', # Sony added (ref 13)
     98    30 => 'Minolta AF 28-80mm F3.5-5.6 (D) or Sigma Lens',
     99    30.1 => 'Sigma AF 10-20mm F4-5.6 EX DC', #JD
     100    30.2 => 'Sigma AF 12-24mm F4.5-5.6 EX DG',
     101    30.3 => 'Sigma 28-70mm EX DG F2.8', #16
     102    30.4 => 'Sigma 55-200mm F4-5.6 DC', #JD
     103    31 => 'Minolta/Sony AF 50mm F2.8 Macro (D) or F3.5',
     104    31.1 => 'Minolta/Sony AF 50mm F3.5 Macro',
     105    32 => 'Minolta/Sony AF 300mm F2.8 G or 1.5x Teleconverter', #13/18
     106    # 32 => 'Minolta AF 300mm F2.8 G (D) SSM' (ref 13)
     107    # 32 => 'Sony 300mm F2.8 G (SAL-300F28G)' (ref 18)
     108    33 => 'Minolta/Sony AF 70-200mm F2.8 G',
     109    # 33 => 'Minolta AF 70-200mm F2.8 G (D) SSM' (ref 13)
    71110    35 => 'Minolta AF 85mm F1.4 G (D) Limited',
    72111    36 => 'Minolta AF 28-100mm F3.5-5.6 (D)',
    73     38 => 'KonicaMinolta AF 17-35mm F2.8-4 (D)',
    74     39 => 'Minolta AF 28-75mm F2.8 (D)',
    75     40 => 'KonicaMinolta or Sony AF DT 18-70mm F3.5-5.6 (D)',
    76     41 => 'Minolta AF DT 11-18mm F4.5-5.6 (D)',
    77     42 => 'Minolta AF DT 18-200mm F3.5-6.3 (D)',
    78     43 => 'Minolta AF 35mm F1.4 G',
    79     44 => 'Minolta AF 50mm F1.4',
     112    38 => 'Minolta AF 17-35mm F2.8-4 (D)', # (Konica Minolta, ref 13)
     113    39 => 'Minolta AF 28-75mm F2.8 (D)', # (Konica Minolta, ref 13)
     114    40 => 'Minolta/Sony AF DT 18-70mm F3.5-5.6 (D) or 18-200m F3.5-6.3', # (Konica Minolta, ref 13)
     115    40.1 => 'Sony AF DT 18-200mm F3.5-6.3', #11
     116    41 => 'Minolta/Sony AF DT 11-18mm F4.5-5.6 (D) or Tamron Lens', # (Konica Minolta, ref 13)
     117    41.1 => 'Tamron SP AF 11-18mm F4.5-5.6 Di II LD Aspherical IF', #JD
     118    42 => 'Minolta/Sony AF DT 18-200mm F3.5-6.3 (D)', # Sony added (ref 13) (Konica Minolta, ref 13)
     119    43 => 'Sony 35mm F1.4 G (SAL-35F14G)', # changed from Minolta to Sony (ref 13/18) (but ref 11 shows both!)
     120    44 => 'Sony 50mm F1.4 (SAL-50F14)', # changed from Minolta to Sony (ref 13/18)
    80121    45 => 'Carl Zeiss Planar T* 85mm F1.4 ZA',
    81122    46 => 'Carl Zeiss Vario-Sonnar T* DT 16-80mm F3.5-4.5 ZA',
    82123    47 => 'Carl Zeiss Sonnar T* 135mm F1.8 ZA',
    83     128 => 'Tamron 18-200, 28-300 or 80-300mm F3.5-6.3',
    84     129 => 'Tamron 200-400mm F5.6 LD', #12
     124    48 => 'Carl Zeiss Vario-Sonnar T* 24-70mm F2.8 ZA SSM (SAL-2470Z)', #11
     125    49 => 'Sony AF DT 55-200mm F4-5.6', #JD
     126    50 => 'Sony AF DT 18-250mm F3.5-6.3', #11
     127    51 => 'Sony AF DT 16-105mm F3.5-5.6 or 55-200mm F4-5.5', #11
     128    51.1 => 'Sony AF DT 55-200mm F4-5.5', #11
     129    52 => 'Sony 70-300mm F4.5-5.6 G SSM', #JD
     130    53 => 'Sony AF 70-400mm F4-5.6 G SSM (SAL-70400G)', #17 (/w correction by Stephen Bishop)
     131    54 => 'Carl Zeiss Vario-Sonnar T* 16-35mm F2.8 ZA SSM (SAL-1635Z)', #17
     132    55 => 'Sony DT 18-55mm F3.5-5.6 SAM (SAL-1855)', #PH
     133    56 => 'Sony AF DT 55-200mm F4-5.6 SAM', #22
     134    57 => 'Sony AF DT 50mm F1.8 SAM', #22
     135    58 => 'Sony AF DT 30mm F2.8 SAM Macro', #22
     136    59 => 'Sony 28-75/2.8 SAM', #21
     137    60 => 'Carl Zeiss Distagon T* 24mm F2 SSM', #17
     138    61 => 'Sony 85mm F2.8 SAM (SAL-85F28)', #17
     139    62 => 'Sony DT 35mm F1.8 SAM (SAL-35F18)', #PH
     140    128 => 'Tamron or Sigma Lens (128)',
     141    128.1 => 'Tamron 18-200mm F3.5-6.3',
     142    128.2 => 'Tamron 28-300mm F3.5-6.3',
     143    128.3 => 'Tamron 80-300mm F3.5-6.3',
     144    128.4 => 'Tamron AF 28-200mm F3.8-5.6 XR Di Aspherical [IF] MACRO', #JD
     145    128.5 => 'Tamron SP AF 17-35mm F2.8-4 Di LD Aspherical IF', #JD
     146    128.6 => 'Sigma AF 50-150mm F2.8 EX DC APO HSM II', #JD
     147    128.7 => 'Sigma 10-20mm F3.5 EX DC HSM', #11 (model 202-205)
     148    128.8 => 'Sigma 70-200mm F2.8 II EX DG APO MACRO HSM', #24
     149    129 => 'Tamron Lens (129)',
     150    129.1 => 'Tamron 200-400mm F5.6 LD', #12 (LD ref 23)
     151    129.2 => 'Tamron 70-300mm F4-5.6 LD', #12
     152    131 => 'Tamron 20-40mm F2.7-3.5 SP Aspherical IF', #23
     153    135 => 'Vivitar 28-210mm F3.5-5.6', #16
     154    136 => 'Tokina EMZ M100 AF 100mm F3.5', #JD
     155    137 => 'Cosina 70-210mm F2.8-4 AF', #11
    85156    138 => 'Soligor 19-35mm F3.5-4.5', #11
     157    142 => 'Voigtlander 70-300mm F4.5-5.6', #JD
     158    146 => 'Voigtlander Macro APO-Lanthar 125mm F2.5 SL', #JD
     159    255 => 'Tamron Lens (255)',
     160    255.1 => 'Tamron SP AF 17-50mm F2.8 XR Di II LD Aspherical',
     161    255.2 => 'Tamron AF 18-250mm F3.5-6.3 XR Di II LD', #JD
     162    255.3 => 'Tamron AF 55-200mm F4-5.6 Di II',
     163    255.4 => 'Tamron AF 70-300mm F4-5.6 Di LD MACRO 1:2',
     164    255.5 => 'Tamron SP AF 200-500mm F5.0-6.3 Di LD IF',
     165    255.6 => 'Tamron SP AF 10-24mm F3.5-4.5 Di II LD Aspherical IF', #22
     166    255.7 => 'Tamron SP AF 70-200mm F2.8 Di LD IF Macro', #22
     167    255.8 => 'Tamron SP AF 28-75mm F2.8 XR Di LD Aspherical IF', #24
    86168    25501 => 'Minolta AF 50mm F1.7', #7
    87     25511 => 'Minolta AF 35-70mm F4', # or Sigma UC AF 28-70mm F3.5-4.5 or Sigma M-AF 70-200mm F2.8 EX Aspherical', #/12/12
    88     25521 => 'Minolta AF 28-85mm F3.5-4.5 [New]', # or Tokina 19-35mm F3.5-4.5 or Tokina 28-70mm F2.8 AT-X', #3/7
    89     25531 => 'Minolta AF 28-135mm F4-4.5',
     169    25511 => 'Minolta AF 35-70mm F4 or Other Lens',
     170    25511.1 => 'Sigma UC AF 28-70mm F3.5-4.5', #12/16(HighSpeed-AF)
     171    25511.2 => 'Sigma AF 28-70mm F2.8', #JD
     172    25511.3 => 'Sigma M-AF 70-200mm F2.8 EX Aspherical', #12
     173    25511.4 => 'Quantaray M-AF 35-80mm F4-5.6', #JD
     174    25521 => 'Minolta AF 28-85mm F3.5-4.5 or Other Lens', # not New (ref 18)
     175    25521.1 => 'Tokina 19-35mm F3.5-4.5', #3
     176    25521.2 => 'Tokina 28-70mm F2.8 AT-X', #7
     177    25521.3 => 'Tokina 80-400mm F4.5-5.6 AT-X AF II 840', #JD
     178    25521.4 => 'Tokina AF PRO 28-80mm F2.8 AT-X 280', #JD
     179    25521.5 => 'Tokina AT-X PRO II AF 28-70mm F2.6-2.8 270', #24
     180    25521.6 => 'Tamron AF 19-35mm F3.5-4.5', #JD
     181    25521.7 => 'Angenieux AF 28-70mm F2.6', #JD
     182    25531 => 'Minolta AF 28-135mm F4-4.5 or Sigma Lens',
     183    25531.1 => 'Sigma ZOOM-alpha 35-135mm F3.5-4.5', #16
     184    25531.2 => 'Sigma 28-105mm F2.8-4 Aspherical', #JD
    90185    25541 => 'Minolta AF 35-105mm F3.5-4.5', #13
    91     25551 => 'Minolta AF 70-210mm F4 Macro', # or Sigma 70-210mm F4-5.6 APO or Sigma M-AF 70-200mm F2.8 EX APO', #7/6
     186    25551 => 'Minolta AF 70-210mm F4 Macro or Sigma Lens',
     187    25551.1 => 'Sigma 70-210mm F4-5.6 APO', #7
     188    25551.2 => 'Sigma M-AF 70-200mm F2.8 EX APO', #6
     189    25551.3 => 'Sigma 75-200mm F2.8-3.5', #22
    92190    25561 => 'Minolta AF 135mm F2.8',
    93     25571 => 'Minolta AF 28mm F2.8',
     191    25571 => 'Minolta/Sony AF 28mm F2.8', # Sony added (ref 18)
     192    # 25571 => 'Sony 28mm F2.8 (SAL-28F28)' (ref 18)
    94193    25581 => 'Minolta AF 24-50mm F4',
    95194    25601 => 'Minolta AF 100-200mm F4.5',
    96     25611 => 'Minolta AF 75-300mm F4.5-5.6', #13 # or Sigma 70-300mm F4-5.6 or Sigma 300mm F4 APO Macro', #12/3/7
    97     25621 => 'Minolta AF 50mm F1.4 [New]', #13
    98     25631 => 'Minolta AF 300mm F2.8 G',
    99     25641 => 'Minolta AF 50mm F2.8 Macro',
     195    25611 => 'Minolta AF 75-300mm F4.5-5.6 or Sigma Lens', #13
     196    25611.1 => 'Sigma 70-300mm F4-5.6 DL Macro', #12
     197    25611.2 => 'Sigma 300mm F4 APO Macro', #3/7
     198    25611.3 => 'Sigma AF 500mm F4.5 APO', #JD
     199    25611.4 => 'Sigma AF 170-500mm F5-6.3 APO Aspherical', #JD
     200    25611.5 => 'Tokina AT-X AF 300mm F4', #JD
     201    25611.6 => 'Tokina AT-X AF 400mm F5.6 SD', #22
     202    25611.7 => 'Tokina AF 730 II 75-300mm F4.5-5.6', #JD
     203    25621 => 'Minolta AF 50mm F1.4 [New]', # original and New, not Sony (ref 13/18)
     204    25631 => 'Minolta AF 300mm F2.8 APO or Sigma Lens', # changed G to APO (ref 13)
     205    25631.1 => 'Sigma AF 50-500mm F4-6.3 EX DG APO', #JD
     206    25631.2 => 'Sigma AF 170-500mm F5-6.3 APO Aspherical', #JD
     207    25631.3 => 'Sigma AF 500mm F4.5 EX DG APO', #JD
     208    25631.4 => 'Sigma 400mm F5.6 APO', #22
     209    25641 => 'Minolta AF 50mm F2.8 Macro or Sigma Lens',
     210    25641.1 => 'Sigma 50mm F2.8 EX Macro', #11
    100211    25651 => 'Minolta AF 600mm F4',
    101212    25661 => 'Minolta AF 24mm F2.8',
    102     25721 => 'Minolta AF 500mm F8 Reflex',
    103     25781 => 'Minolta AF 16mm F2.8 Fisheye', # or Sigma 8mm F4 Fisheye or Sigma 14mm F3.5',
    104     25791 => 'Minolta AF 20mm F2.8',
    105     25811 => 'Minolta AF 100mm F2.8 Macro New', # or Tamron 90mm F2.8 Macro or Sigma 180mm F5.6 Macro',
    106     25858 => 'Minolta AF 35-105mm F3.5-4.5 New', # or Tamron 24-135mm F3.5-5.6',
     213    25721 => 'Minolta/Sony AF 500mm F8 Reflex',
     214    25781 => 'Minolta/Sony AF 16mm F2.8 Fisheye or Sigma Lens', # Sony added (ref 13/18)
     215    # 25781 => 'Sony 16mm F2.8 Fisheye (SAL-16F28)' (ref 18)
     216    25781.1 => 'Sigma 8mm F4 EX [DG] Fisheye',
     217    25781.2 => 'Sigma 14mm F3.5',
     218    25781.3 => 'Sigma 15mm F2.8 Fisheye', #JD (writes 16mm to EXIF)
     219    25791 => 'Minolta/Sony AF 20mm F2.8', # Sony added (ref 11)
     220    25811 => 'Minolta AF 100mm F2.8 Macro [New] or Sigma or Tamron Lens', # not Sony (ref 13/18)
     221    25811.1 => 'Sigma AF 90mm F2.8 Macro', #JD
     222    25811.2 => 'Sigma AF 105mm F2.8 EX [DG] Macro', #JD
     223    25811.3 => 'Sigma 180mm F5.6 Macro',
     224    25811.4 => 'Tamron 90mm F2.8 Macro',
     225    25851 => 'Beroflex 35-135mm F3.5-4.5', #16
     226    25858 => 'Minolta AF 35-105mm F3.5-4.5 New or Tamron Lens',
     227    25858.1 => 'Tamron 24-135mm F3.5-5.6',
    107228    25881 => 'Minolta AF 70-210mm F3.5-4.5',
    108     25891 => 'Minolta AF 80-200 F2.8 APO', # or Tokina 80-200mm F2.8',
    109     25911 => 'Minolta AF 35mm F1.4', #(from Sony list)
     229    25891 => 'Minolta AF 80-200mm F2.8 APO or Tokina Lens',
     230    25891.1 => 'Tokina 80-200mm F2.8',
     231    25911 => 'Minolta AF 35mm F1.4', #(from Sony list) (not G as per ref 13)
    110232    25921 => 'Minolta AF 85mm F1.4 G (D)',
    111233    25931 => 'Minolta AF 200mm F2.8 G APO',
    112     25941 => 'Minolta AF 3X-1X F1.7-2.8 Macro',
     234    25941 => 'Minolta AF 3x-1x F1.7-2.8 Macro',
    113235    25961 => 'Minolta AF 28mm F2',
    114     25971 => 'Minolta AF 35mm F2',
     236    25971 => 'Minolta AF 35mm F2 [New]', #13
    115237    25981 => 'Minolta AF 100mm F2',
    116238    26041 => 'Minolta AF 80-200mm F4.5-5.6',
    117239    26051 => 'Minolta AF 35-80mm F4-5.6', #(from Sony list)
    118     26061 => 'Minolta AF 100-300mm F4.5-5.6 (D)',
     240    26061 => 'Minolta AF 100-300mm F4.5-5.6', # not (D) (ref 13/18)
    119241    26071 => 'Minolta AF 35-80mm F4-5.6', #13
    120     26081 => 'Minolta AF 300mm F2.8 G',
     242    26081 => 'Minolta AF 300mm F2.8 HS-APO G', # HS-APO added (ref 13/18)
    121243    26091 => 'Minolta AF 600mm F4 HS-APO G',
    122     26121 => 'Minolta AF 200mm F2.8 G HS-APO',
     244    26121 => 'Minolta AF 200mm F2.8 HS-APO G',
    123245    26131 => 'Minolta AF 50mm F1.7 New',
    124     26151 => 'Minolta AF 28-105mm F3.5-4.5 Power Zoom',
    125     26161 => 'Minolta AF 35-200mm F4.5-5.6 Power Zoom',
    126     26181 => 'Minolta AF 28-80mm F4-5.6 Power Zoom',
    127     26191 => 'Minolta AF 80-200mm F4.5-5.6 Power Zoom',
     246    26151 => 'Minolta AF 28-105mm F3.5-4.5 xi', # xi, not Power Zoom (ref 13/18)
     247    26161 => 'Minolta AF 35-200mm F4.5-5.6 xi', # xi, not Power Zoom (ref 13/18)
     248    26181 => 'Minolta AF 28-80mm F4-5.6 xi', # xi, not Power Zoom (ref 13/18)
     249    26191 => 'Minolta AF 80-200mm F4.5-5.6 xi', # xi, not Power Zoom (ref 13/18)
    128250    26201 => 'Minolta AF 28-70mm F2.8 G', #11
    129     26211 => 'Minolta AF 100-300mm F4.5-5.6 Power Zoom',
     251    26211 => 'Minolta AF 100-300mm F4.5-5.6 xi', # xi, not Power Zoom (ref 13/18)
    130252    26241 => 'Minolta AF 35-80mm F4-5.6 Power Zoom',
    131253    26281 => 'Minolta AF 80-200mm F2.8 G', #11
    132254    26291 => 'Minolta AF 85mm F1.4 New',
    133     26311 => 'Minolta AF 100-300mm F4.5-5.6 APO', #11
     255    26311 => 'Minolta/Sony AF 100-300mm F4.5-5.6 APO', #11
    134256    26321 => 'Minolta AF 24-50mm F4 New',
    135257    26381 => 'Minolta AF 50mm F2.8 Macro New',
    136258    26391 => 'Minolta AF 100mm F2.8 Macro',
    137     26411 => 'Minolta AF 20mm F2.8 New',
     259    26411 => 'Minolta/Sony AF 20mm F2.8 New', # Sony added (ref 13)
    138260    26421 => 'Minolta AF 24mm F2.8 New',
    139261    26441 => 'Minolta AF 100-400mm F4.5-6.7 APO', #11
     
    142264    26681 => 'Minolta AF 28mm F2 New',
    143265    26721 => 'Minolta AF 24-105mm F3.5-4.5 (D)', #11
    144     45741 => 'Minolta AF 200mm F2.8 G x2', # or Tokina 300mm F2.8 x2',
     266    45671 => 'Tokina 70-210mm F4-5.6', #22
     267    45741 => '2x Teleconverter or Tamron or Tokina Lens', #18
     268    45741.1 => 'Tamron SP AF 90mm F2.5', #JD
     269    45741.2 => 'Tokina RF 500mm F8.0 x2', #JD
     270    45741.3 => 'Tokina 300mm F2.8 x2',
     271    45751 => '1.4x Teleconverter', #18
     272    45851 => 'Tamron SP AF 300mm F2.8 LD IF', #11
     273    # all M42-type lenses give a value of 65535 (and FocalLength=0, FNumber=1)
     274    65535 => 'T-Mount or Other Lens or no lens', #JD
     275    65535.1 => 'Arax MC 35mm F2.8 Tilt+Shift', #JD
     276    65535.2 => 'Arax MC 80mm F2.8 Tilt+Shift', #JD
     277    65535.3 => 'Zenitar MF 16mm F2.8 Fisheye M42', #JD
     278    65535.4 => 'Samyang 500mm Mirror F8.0', #19
     279    65535.5 => 'Pentacon Auto 135mm F2.8', #19
     280    65535.6 => 'Pentacon Auto 29mm F2.8', #19
     281    65535.7 => 'Helios 44-2 58mm F2.0', #19
    145282);
    146283
     
    160297    17 => 'Night Scene', #10
    161298    18 => 'Night Portrait', #10
     299    0x84 => 'Embed Adobe RGB',
    162300);
     301
     302%sonyColorMode = ( #15
     303    0 => 'Standard',
     304    1 => 'Vivid', #PH
     305    2 => 'Portrait',
     306    3 => 'Landscape',
     307    4 => 'Sunset',
     308    5 => 'Night View/Portrait', #(portrait if flash is on)
     309    6 => 'B&W',
     310    7 => 'Adobe RGB',
     311    12 => 'Neutral', # Sony
     312    100 => 'Neutral', #JD
     313    101 => 'Clear', #JD
     314    102 => 'Deep', #JD
     315    103 => 'Light', #JD
     316    104 => 'Night View', #JD
     317    105 => 'Autumn Leaves', #JD
     318    0xffffffff => 'n/a', #PH
     319);
     320
     321%minoltaSceneMode = (
     322    0 => 'Standard',
     323    1 => 'Portrait',
     324    2 => 'Text',
     325    3 => 'Night Scene',
     326    4 => 'Sunset',
     327    5 => 'Sports',
     328    6 => 'Landscape',
     329    7 => 'Night Portrait', #JD
     330    8 => 'Macro',
     331    9 => 'Super Macro',
     332    16 => 'Auto',
     333    17 => 'Night View/Portrait',
     334    18 => 'Sweep Panorama', #PH (SLT-A55V)
     335    19 => 'Handheld Night Shot', #PH
     336    20 => 'Anti Motion Blur', #PH
     337    21 => 'Cont. Priority AE', #PH
     338    22 => 'Auto+',
     339    23 => '3D Sweep Panorama', #PH (SLT-A55V)
     340    0xffff => 'n/a', #PH
     341);
     342
     343my %exposureIndicator = (
     344    0 => 'Not Indicated',
     345    1 => 'Under Scale',
     346    119 => 'Bottom of Scale',
     347    120 => '-2.0',
     348    121 => '-1.7',
     349    122 => '-1.5',
     350    123 => '-1.3',
     351    124 => '-1.0',
     352    125 => '-0.7',
     353    126 => '-0.5',
     354    127 => '-0.3',
     355    128 => '0',
     356    129 => '+0.3',
     357    130 => '+0.5',
     358    131 => '+0.7',
     359    132 => '+1.0',
     360    133 => '+1.3',
     361    134 => '+1.5',
     362    135 => '+1.7',
     363    136 => '+2.0',
     364    253 => 'Top of Scale',
     365    254 => 'Over Scale',
     366);
     367
     368my %onOff = ( 0 => 'On', 1 => 'Off' );
     369my %offOn = ( 0 => 'Off', 1 => 'On' );
    163370
    164371# Minolta tag table
     
    183390        Name => 'MinoltaCameraSettings',
    184391        # These camera settings are different for the DiMAGE X31
    185         Condition => '$self->{CameraModel} ne "DiMAGE X31"',
     392        Condition => '$self->{Model} ne "DiMAGE X31"',
    186393        SubDirectory => {
    187394            TagTable => 'Image::ExifTool::Minolta::CameraSettings',
     
    200407    0x0018 => {
    201408        Name => 'ImageStabilization',
    202         Condition => '$self->{CameraModel} =~ /^DiMAGE (A1|A2|X1)$/',
     409        Condition => '$self->{Model} =~ /^DiMAGE (A1|A2|X1)$/',
    203410        Notes => q{
    204411            a block of binary data which exists in DiMAGE A2 (and A1/X1?) images only if
     
    206413        },
    207414        ValueConv => '"On"',
     415    },
     416    0x0020 => {
     417        Name => 'WBInfoA100',
     418        Condition => '$$self{Model} eq "DSLR-A100"',
     419        Notes => 'currently decoded only for the Sony A100',
     420        SubDirectory => {
     421            TagTable => 'Image::ExifTool::Minolta::WBInfoA100',
     422            ByteOrder => 'BigEndian',
     423        },
    208424    },
    209425    0x0040 => {
     
    223439        Writable => 'int32u',
    224440        Protected => 2,
     441        # Note: Sony also uses this tag in A100 ARW images, but it points
     442        #       to the same data as JpgFromRaw
    225443    },
    226444    0x0089 => {
     
    231449        Protected => 2,
    232450    },
    233     0x0100 => { #10 (needs verification - PH)
     451    0x0100 => { #10
    234452        Name => 'SceneMode',
    235         PrintConv => {
    236             0 => 'Standard',
    237             1 => 'Portrait',
    238             2 => 'Text',
    239             3 => 'Night Scene',
    240             4 => 'Evening Scene',
    241             5 => 'Sports',
    242             6 => 'Landscape',
    243             9 => 'Super Macro',
    244         },
     453        Writable => 'int32u',
     454        PrintConv => \%minoltaSceneMode,
    245455    },
    246456    0x0101 => [
    247457        {
    248458            Name => 'ColorMode',
    249             Condition => '$self->{CameraMake} !~ /^SONY/',
     459            Condition => '$self->{Make} !~ /^SONY/',
    250460            Priority => 0, # Other ColorMode is more reliable for A2
    251461            Writable => 'int32u',
     
    255465            Name => 'ColorMode',
    256466            Writable => 'int32u',
    257             Notes => 'Sony DSLR-A100',
    258             PrintConv => {
    259                 0 => 'Standard',
    260                 1 => 'Vivid', #PH
    261                 2 => 'Portrait',
    262                 3 => 'Landscape',
    263                 4 => 'Sunset',
    264                 5 => 'Night Scene',
    265                 6 => 'B&W',
    266                 7 => 'Adobe RGB',
    267             },
     467            Notes => 'Sony models',
     468            PrintConv => \%sonyColorMode,
    268469        },
    269470    ],
     
    288489            Name => 'MinoltaQuality',
    289490            Writable => 'int32u',
    290             Condition => '$self->{CameraModel} =~ /^DiMAGE (A2|7Hi)$/',
     491            Condition => '$self->{Model} =~ /^DiMAGE (A2|7Hi)$/',
    291492            Notes => 'quality for DiMAGE A2/7Hi',
    292493            Priority => 0, # lower priority because this doesn't work for A200
     
    303504            Name => 'MinoltaImageSize',
    304505            Writable => 'int32u',
    305             Condition => '$self->{CameraModel} !~ /^DiMAGE A200$/',
     506            Condition => '$self->{Model} !~ /^DiMAGE A200$/',
    306507            Notes => 'image size for other models except A200',
    307508            PrintConv => {
     
    320521        Writable => 'rational64s',
    321522    },
    322 # needs verification:
    323 #    0x0105 => { #10
    324 #        Name => 'Teleconverter',
    325 #        PrintConv => {
    326 #            0 => 'None',
    327 #            72 => 'Minolta AF 2x APO (D)',
    328 #            80 => 'Minolta AF 2x APO II',
    329 #            136 => 'Minolta AF 1.4x APO (D)',
    330 #            144 => 'Minolta AF 1.4x APO II',
    331 #        },
    332 #    },
     523    0x0105 => { #10
     524        Name => 'Teleconverter',
     525        Writable => 'int32u',
     526        PrintHex => 1,
     527        PrintConv => {
     528            0x00 => 'None',
     529            0x48 => 'Minolta AF 2x APO (D)',
     530            0x50 => 'Minolta AF 2x APO II',
     531            0x88 => 'Minolta AF 1.4x APO (D)',
     532            0x90 => 'Minolta AF 1.4x APO II',
     533        },
     534    },
    333535    0x0107 => { #8
    334536        Name => 'ImageStabilization',
     
    339541        },
    340542    },
     543    0x0109 => { #20
     544        Name => 'RawAndJpgRecording',
     545        Writable => 'int32u',
     546        PrintConv => \%offOn,
     547    },
    341548    0x010a => {
    342549        Name => 'ZoneMatching',
     
    353560    },
    354561    0x010c => { #3 (Alpha 7)
    355         Name => 'LensID',
     562        Name => 'LensType',
    356563        Writable => 'int32u',
    357         PrintConv => \%minoltaLensIDs,
     564        SeparateTable => 1,
     565        PrintConv => \%minoltaLensTypes,
    358566    },
    359567    # 0x010e - WhiteBalance according to ref #10
     568    0x0111 => { #20
     569        Name => 'ColorCompensationFilter',
     570        Writable => 'int32s',
     571        Notes => 'ranges from -2 for green to +2 for magenta',
     572    },
     573    0x0112 => { #PH (from Sony tags, NC)
     574        Name => 'WhiteBalanceFineTune',
     575        Format => 'int32s',
     576        Writable => 'int32u',
     577    },
    360578    0x0113 => { #PH
    361579        Name => 'ImageStabilization',
    362         Condition => '$self->{CameraModel} eq "DSLR-A100"',
     580        Condition => '$self->{Model} eq "DSLR-A100"',
    363581        Notes => 'valid for Sony A100 only',
    364582        Writable => 'int32u',
    365         PrintConv => { 0 => 'Off', 1 => 'On' },
     583        PrintConv => \%offOn,
    366584    },
    367585    0x0114 => [
    368586        { #8
    369587            Name => 'MinoltaCameraSettings5D',
    370             Condition => '$self->{CameraModel} =~ /^(DYNAX 5D|MAXXUM 5D|ALPHA SWEET)/',
     588            Condition => '$self->{Model} =~ /^(DYNAX 5D|MAXXUM 5D|ALPHA SWEET)/',
    371589            SubDirectory => {
    372590                TagTable => 'Image::ExifTool::Minolta::CameraSettings5D',
     
    375593        },
    376594        { #PH
    377             Name => 'MinoltaCameraSettingsA100',
    378             Condition => '$self->{CameraModel} eq "DSLR-A100"',
     595            Name => 'CameraSettingsA100',
     596            Condition => '$self->{Model} eq "DSLR-A100"',
    379597            SubDirectory => {
    380598                TagTable => 'Image::ExifTool::Minolta::CameraSettingsA100',
     
    383601        },
    384602    ],
     603    0x0115 => { #20
     604        Name => 'WhiteBalance',
     605        Writable => 'int32u',
     606        PrintHex => 1,
     607        PrintConv => {
     608            0x00 => 'Auto',
     609            0x01 => 'Color Temperature/Color Filter',
     610            0x10 => 'Daylight',
     611            0x20 => 'Cloudy',
     612            0x30 => 'Shade',
     613            0x40 => 'Tungsten',
     614            0x50 => 'Flash',
     615            0x60 => 'Fluorescent',
     616            0x70 => 'Custom',
     617        },
     618    },
    385619    0x0e00 => {
    386620        Name => 'PrintIM',
     
    394628        Name => 'MinoltaCameraSettings2',
    395629        Writable => 0,
     630        Binary => 1,
    396631    },
    397632);
     
    411646        information may not be as reliable as it should be.  Because of this, tags
    412647        in the following tables are set to lower priority to prevent them from
    413         superceeding the values of same-named tags in other locations when duplicate
     648        superceding the values of same-named tags in other locations when duplicate
    414649        tags are disabled.
    415650    },
     
    430665            2 => 'Rear flash sync',
    431666            3 => 'Wireless',
     667            4 => 'Off?', #PH
    432668        },
    433669    },
     
    475711        PrintConv => {
    476712            0 => 'Multi-segment',
    477             1 => 'Center weighted',
     713            1 => 'Center-weighted average',
    478714            2 => 'Spot',
    479715        },
     
    491727        ValueConvInv => '48 - 8*log($val)/log(2)',
    492728        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    493         PrintConvInv => 'eval $val',
     729        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    494730    },
    495731    10 => {
     
    519755        ValueConv => '$val/3 - 2',
    520756        ValueConvInv => '($val + 2) * 3',
    521         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    522         PrintConvInv => 'eval $val',
     757        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     758        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    523759    },
    524760    14 => {
     
    536772        ValueConv => '$val / 256',
    537773        ValueConvInv => '$val * 256',
    538         PrintConv => 'sprintf("%.1fmm",$val)',
    539         PrintConvInv => '$val=~s/mm$//;$val',
     774        PrintConv => 'sprintf("%.1f mm",$val)',
     775        PrintConvInv => '$val=~s/\s*mm$//;$val',
    540776    },
    541777    19 => {
     
    576812    26 => {
    577813        Name => 'FileNumberMemory',
    578         PrintConv => {
    579             0 => 'Off',
    580             1 => 'On',
    581         },
     814        PrintConv => \%offOn,
    582815    },
    583816    27 => 'LastFileNumber',
     
    599832    31 => {
    600833        Name => 'Saturation',
    601         ValueConv => '$val - ($self->{CameraModel}=~/DiMAGE A2/ ? 5 : 3)',
    602         ValueConvInv => '$val + ($self->{CameraModel}=~/DiMAGE A2/ ? 5 : 3)',
    603         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    604         PrintConvInv => '$val=~/normal/i ? 0 : $val',
     834        ValueConv => '$val - ($self->{Model}=~/DiMAGE A2/ ? 5 : 3)',
     835        ValueConvInv => '$val + ($self->{Model}=~/DiMAGE A2/ ? 5 : 3)',
     836        %Image::ExifTool::Exif::printParameter,
    605837    },
    606838    32 => {
    607839        Name => 'Contrast',
    608         ValueConv => '$val - ($self->{CameraModel}=~/DiMAGE A2/ ? 5 : 3)',
    609         ValueConvInv => '$val + ($self->{CameraModel}=~/DiMAGE A2/ ? 5 : 3)',
    610         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    611         PrintConvInv => '$val=~/normal/i ? 0 : $val',
     840        ValueConv => '$val - ($self->{Model}=~/DiMAGE A2/ ? 5 : 3)',
     841        ValueConvInv => '$val + ($self->{Model}=~/DiMAGE A2/ ? 5 : 3)',
     842        %Image::ExifTool::Exif::printParameter,
    612843    },
    613844    33 => {
     
    635866        ValueConv => '($val - 6) / 3',
    636867        ValueConvInv => '$val * 3 + 6',
    637         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    638         PrintConvInv => 'eval $val',
     868        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     869        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    639870    },
    640871    36 => {
     
    688919    41 => {
    689920        Name => 'ColorFilter',
    690         ValueConv => '$val - ($self->{CameraModel}=~/DiMAGE A2/ ? 5 : 3)',
    691         ValueConvInv => '$val + ($self->{CameraModel}=~/DiMAGE A2/ ? 5 : 3)',
     921        ValueConv => '$val - ($self->{Model}=~/DiMAGE A2/ ? 5 : 3)',
     922        ValueConvInv => '$val + ($self->{Model}=~/DiMAGE A2/ ? 5 : 3)',
    692923    },
    693924    42 => 'BWFilter',
     
    742973    51 => {
    743974        Name => 'ColorProfile',
    744         Condition => '$self->{CameraModel} eq "DiMAGE 7Hi"',
     975        Condition => '$self->{Model} eq "DiMAGE 7Hi"',
    745976        Notes => 'DiMAGE 7Hi only',
    746977        PrintConv => {
     
    752983    52 => {
    753984        Name => 'DataImprint',
    754         Condition => '$self->{CameraModel} eq "DiMAGE 7Hi"',
     985        Condition => '$self->{Model} eq "DiMAGE 7Hi"',
    755986        Notes => 'DiMAGE 7Hi only',
    756987        PrintConv => {
     
    7891020            2 => 'Shutter Priority',
    7901021            3 => 'Manual',
    791             4 => 'Auto?',
     1022            4 => 'Auto',
    7921023            5 => 'Program-shift A',
    7931024            6 => 'Program-shift S',
     
    8281059        Name => 'FocusMode',
    8291060        PrintConv => {
    830             0 => 'Single-shot AF',
    831             1 => 'Continuous AF',
    832             3 => 'Automatic AF',
    833             4 => 'Manual',
     1061            0 => 'AF-S',
     1062            1 => 'AF-C',
     1063            # Note: these two are reversed in ref 8
     1064            3 => 'Manual', #JD
     1065            4 => 'AF-A', #JD
    8341066        },
    8351067    },
     
    8501082    0x15 => {
    8511083        Name => 'Flash',
    852         PrintConv => { 0 => 'Off', 1 => 'On' },
    853     },
    854 # needs verification:
    855 #    0x16 => { #10
    856 #        Name => 'FlashMode',
    857 #        PrintConv => {
    858 #            0 => 'Normal',
    859 #            1 => 'Red-eye reduction',
    860 #            2 => 'Rear flash sync',
    861 #        },
    862 #    },
     1084        PrintConv => \%offOn,
     1085    },
     1086    0x16 => { #10
     1087        Name => 'FlashMode',
     1088        PrintConv => {
     1089            0 => 'Normal',
     1090            1 => 'Red-eye reduction',
     1091            2 => 'Rear flash sync',
     1092        },
     1093    },
    8631094    0x1c => {
    8641095        Name => 'ISOSetting',
     
    8781109        ValueConv => '$val / 24',
    8791110        ValueConvInv => '$val * 24',
    880         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    881         PrintConvInv => 'eval $val',
     1111        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     1112        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    8821113    },
    8831114    0x25 => {
     
    9111142        ValueConvInv => '$val / 100',
    9121143    },
    913 # needs verification:
    914 #    0x40 => { #10
    915 #        Name => 'HueAdjustment',
    916 #        Unknown => 1,
    917 #        ValueConv => '$val - 10',
    918 #        ValueConvInv => '$val + 10',
    919 #    },
     1144    0x40 => { #10
     1145        Name => 'HueAdjustment',
     1146        ValueConv => '$val - 10',
     1147        ValueConvInv => '$val + 10',
     1148    },
    9201149    0x46 => {
    9211150        Name => 'Rotation',
     
    9381167        ValueConvInv => '48 - 8*log($val)/log(2)',
    9391168        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    940         PrintConvInv => 'eval $val',
     1169        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    9411170    },
    9421171    0x4a => 'FreeMemoryCardImages',
     
    9521181    0x60 => {
    9531182        Name => 'NoiseReduction',
    954         PrintConv => { 0 => 'Off', 1 => 'On' },
     1183        PrintConv => \%offOn,
    9551184    },
    9561185    0x62 => {
     
    9611190    0x71 => {
    9621191        Name => 'ImageStabilization',
    963         PrintConv => { 0 => 'Off', 1 => 'On' },
     1192        PrintConv => \%offOn,
    9641193    },
    9651194    0x75 => {
    9661195        Name => 'ZoneMatchingOn',
    967         PrintConv => { 0 => 'Off', 1 => 'On' },
     1196        PrintConv => \%offOn,
    9681197    },
    9691198);
     
    10311260        },
    10321261    },
    1033 # needs verification:
    1034 #    0x20 => { #10
    1035 #        Name => 'FlashMode',
    1036 #        PrintConv => {
    1037 #            0 => 'Normal',
    1038 #            1 => 'Red-eye reduction',
    1039 #            2 => 'Rear flash sync',
    1040 #        },
    1041 #    },
     1262    0x20 => { #10
     1263        Name => 'FlashMode',
     1264        PrintConv => {
     1265            0 => 'Normal',
     1266            1 => 'Red-eye reduction',
     1267            2 => 'Rear flash sync',
     1268        },
     1269    },
    10421270    0x25 => {
    10431271        Name => 'MeteringMode',
    10441272        PrintConv => {
    10451273            0 => 'Multi-segment',
    1046             1 => 'Center weighted',
     1274            1 => 'Center-weighted average',
    10471275            2 => 'Spot',
    10481276        },
     
    10681296#        ValueConvInv => '$val * 24',
    10691297#    },
    1070 # needs verification:
    1071 #    0x2f => { #10
    1072 #        Name => 'ColorSpace',
    1073 #        PrintConv => {
    1074 #            0 => 'Natural sRGB',
    1075 #            1 => 'Natural+ sRGB',
    1076 #            2 => 'Monochrome',
    1077 #            4 => 'Adobe RGB (ICC)',
    1078 #            5 => 'Adobe RGB',
    1079 #        },
    1080 #    },
     1298    0x2f => { #10
     1299        Name => 'ColorSpace',
     1300        PrintConv => {
     1301            0 => 'Natural sRGB',
     1302            1 => 'Natural+ sRGB',
     1303            2 => 'Monochrome',
     1304            4 => 'Adobe RGB (ICC)',
     1305            5 => 'Adobe RGB',
     1306        },
     1307    },
    10811308    0x30 => {
    10821309        Name => 'Sharpness',
     
    10991326        ValueConvInv => '48 - 8*log($val)/log(2)',
    11001327        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    1101         PrintConvInv => 'eval $val',
     1328        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    11021329    },
    11031330    0x36 => { #PH
     
    11161343        ValueConvInv => '$val / 100',
    11171344    },
    1118 # needs verification:
    1119 #    0x4a => { #10
    1120 #        Name => 'HueAdjustment',
    1121 #        ValueConv => '$val - 10',
    1122 #        ValueConvInv => '$val + 10',
    1123 #    },
     1345    0x4a => { #10
     1346        Name => 'HueAdjustment',
     1347        ValueConv => '$val - 10',
     1348        ValueConvInv => '$val + 10',
     1349    },
    11241350    0x50 => {
    11251351        Name => 'Rotation',
     
    11341360        ValueConv => '$val / 100 - 3',
    11351361        ValueConvInv => '($val + 3) * 100',
    1136         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    1137         PrintConvInv => 'eval $val',
     1362        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     1363        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    11381364    },
    11391365    0x54 => 'FreeMemoryCardImages',
    1140 # needs verification:
    1141 #    0x65 => { #10
    1142 #        Name => 'Rotation',
    1143 #        PrintConv => {
    1144 #            0 => 'Horizontal (normal)',
    1145 #            1=> 'Rotate 90 CW',
    1146 #            2 => 'Rotate 270 CW',
    1147 #        },
    1148 #    },
     1366    0x65 => { #10
     1367        Name => 'Rotation',
     1368        PrintConv => {
     1369            0 => 'Horizontal (normal)',
     1370            1 => 'Rotate 90 CW',
     1371            2 => 'Rotate 270 CW',
     1372        },
     1373    },
    11491374    # 0x66 maybe program mode or some setting like this? (PH)
    11501375    0x6e => { #10
     
    11541379        ValueConvInv => '$val / 100',
    11551380    },
    1156 # needs verification:
    1157 #    0x71 => { #10
    1158 #        Name => 'PictureFinish',
    1159 #        PrintConv => {
    1160 #            0 => 'Natural',
    1161 #            1 => 'Natural+',
    1162 #            2 => 'Portrait',
    1163 #            3 => 'Wind Scene',
    1164 #            4 => 'Evening Scene',
    1165 #            5 => 'Night Scene',
    1166 #            6 => 'Night Portrait',
    1167 #            7 => 'Monochrome',
    1168 #            8 => 'Adobe RGB',
    1169 #            9 => 'Adobe RGB (ICC)',
    1170 #        },
    1171 #    },
     1381    0x71 => { #10
     1382        Name => 'PictureFinish',
     1383        PrintConv => {
     1384            0 => 'Natural',
     1385            1 => 'Natural+',
     1386            2 => 'Portrait',
     1387            3 => 'Wind Scene',
     1388            4 => 'Evening Scene',
     1389            5 => 'Night Scene',
     1390            6 => 'Night Portrait',
     1391            7 => 'Monochrome',
     1392            8 => 'Adobe RGB',
     1393            9 => 'Adobe RGB (ICC)',
     1394        },
     1395    },
    11721396    # 0x95 FlashStrength? (PH)
    11731397    # 0xa4 similar information to 0x27, except with different values
     
    11791403    0xb0 => {
    11801404        Name => 'NoiseReduction',
    1181         PrintConv => { 0 => 'Off', 1 => 'On' },
     1405        PrintConv => \%offOn,
    11821406    },
    11831407    0xbd => {
    11841408        Name => 'ImageStabilization',
    1185         PrintConv => { 0 => 'Off', 1 => 'On' },
     1409        PrintConv => \%offOn,
    11861410    },
    11871411);
     
    11941418    NOTES => 'Camera settings information for the Sony DSLR-A100.',
    11951419    WRITABLE => 1,
    1196     PRIORITY => 0,
     1420    PRIORITY => 0, # may not be as reliable as other information
    11971421    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    11981422    FORMAT => 'int16u',
     
    12071431            3 => 'Manual',
    12081432            4 => 'Auto',
     1433            5 => 'Program Shift A', #20
     1434            6 => 'Program Shift S', #20
    12091435            0x1013 => 'Portrait',
     1436            0x1023 => 'Sports', #20
     1437            0x1033 => 'Sunset', #20
     1438            0x1043 => 'Night View/Portrait', #20
    12101439            0x1053 => 'Landscape',
     1440            0x1083 => 'Macro', #20
    12111441        },
    12121442    },
    12131443    0x01 => { #15
    1214         Name => 'ExposureCompensation',
     1444        Name => 'ExposureCompensationSetting',
     1445        # (differs from ExposureCompensation for exposure bracketing shots, ref 20)
    12151446        ValueConv => '$val / 100 - 3',
    12161447        ValueConvInv => 'int(($val + 3) * 100 + 0.5)',
    12171448    },
    1218     # 0x09 some sort of APEX value (ref 15)
     1449    0x05 => { #20 (requires external flash)
     1450        Name => 'HighSpeedSync',
     1451        PrintConv => \%offOn,
     1452    },
     1453    0x06 => { #20
     1454        Name => 'ManualExposureTime',
     1455        Notes => 'the most recent exposure time set manually by the user',
     1456        ValueConv => '$val ? 2 ** ((48-$val)/8) : $val',
     1457        ValueConvInv => '$val ? 48 - 8*log($val)/log(2) : $val',
     1458        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
     1459        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
     1460    },
     1461    0x07 => { #20
     1462        Name => 'ManualFNumber',
     1463        Notes => 'the most recent aperture set manually by the user',
     1464        ValueConv => '2 ** (($val-8)/16)',
     1465        ValueConvInv => '8 + 16*log($val)/log(2)',
     1466        PrintConv => 'sprintf("%.1f",$val)',
     1467        PrintConvInv => '$val',
     1468    },
     1469    0x08 => { #20
     1470        Name => 'ExposureTime',
     1471        ValueConv => '$val ? 2 ** ((48-$val)/8) : $val',
     1472        ValueConvInv => '$val ? 48 - 8*log($val)/log(2) : $val',
     1473        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
     1474        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
     1475    },
     1476    0x09 => { #15/20
     1477        Name => 'FNumber',
     1478        ValueConv => '2 ** (($val / 8 - 1) / 2)',
     1479        ValueConvInv => '$val>0 ? (2*log($val)/log(2)+1) * 8 : undef',
     1480        PrintConv => 'sprintf("%.1f",$val)',
     1481        PrintConvInv => '$val',
     1482    },
     1483    0x0a => { #20
     1484        Name => 'DriveMode2',
     1485        PrintConv => {
     1486            0 => 'Self-timer 10 sec',
     1487            1 => 'Continuous',
     1488            4 => 'Self-timer 2 sec',
     1489            5 => 'Single Frame',
     1490            8 => 'White Balance Bracketing Low',
     1491            9 => 'White Balance Bracketing High',
     1492            770 => 'Single-frame Bracketing Low',
     1493            771 => 'Continous Bracketing Low',
     1494            1794 => 'Single-frame Bracketing High',
     1495            1795 => 'Continuous Bracketing High',
     1496        },
     1497    },
    12191498    0x0b => { #15
    12201499        Name => 'WhiteBalance',
     
    12321511        },
    12331512    },
    1234     # 0x12 => 'MeteringMode' (ref 15)
    1235     # 0x13 => 'ISO' (ref 15)
    1236     # 0x14 => 'ZoneMatching' (ref 15)
    1237     # 0x15 => 'DynamicRangeOptimizer' (ref 15)
     1513    0x0c => { #20
     1514        Name => 'FocusMode',
     1515        PrintConv => {
     1516            0 => 'AF-S',
     1517            1 => 'AF-C',
     1518            4 => 'AF-A',
     1519            5 => 'Manual',
     1520            6 => 'DMF',
     1521        },
     1522    },
     1523    0x0d => { #20
     1524        Name => 'LocalAFAreaPoint',
     1525        PrintConv => {
     1526            1 => 'Center',
     1527            2 => 'Top',
     1528            3 => 'Top-Right',
     1529            4 => 'Right',
     1530            5 => 'Bottom-Right',
     1531            6 => 'Bottom',
     1532            7 => 'Bottom-Left',
     1533            8 => 'Left',
     1534            9 => 'Top-Left',
     1535        },
     1536    },
     1537    0x0e => { #20
     1538        Name => 'AFAreaMode',
     1539        PrintConv => {
     1540            0 => 'Wide',
     1541            1 => 'Local',
     1542            2 => 'Spot',
     1543        },
     1544    },
     1545    0x0f => { #20
     1546        Name => 'FlashMode',
     1547        PrintConv => {
     1548            0 => 'Auto',
     1549            2 => 'Rear Sync',
     1550            3 => 'Wireless',
     1551            4 => 'Fill Flash',
     1552        },
     1553    },
     1554    0x10 => { #20
     1555        Name => 'FlashExposureCompSetting',
     1556        Description => 'Flash Exposure Comp. Setting',
     1557        # (may differ from FlashExposureComp for flash bracketing shots)
     1558        ValueConv => '$val / 100 - 3',
     1559        ValueConvInv => 'int(($val + 3) * 100 + 0.5)',
     1560    },
     1561    0x12 => { #15/20
     1562        Name => 'MeteringMode',
     1563        PrintConv => {
     1564            0 => 'Multi-segment',
     1565            1 => 'Center-weighted average',
     1566            2 => 'Spot',
     1567        },
     1568    },
     1569    0x13 => { #15/20
     1570        Name => 'ISOSetting',
     1571        PrintConv => {
     1572            0 => 'Auto',
     1573            48 => 100,
     1574            56 => 200,
     1575            64 => 400,
     1576            72 => 800,
     1577            80 => 1600,
     1578            174 => '80 (Zone Matching Low)',
     1579            184 => '200 (Zone Matching High)',
     1580        },
     1581    },
     1582    0x14 => { #15/20
     1583        Name => 'ZoneMatchingMode',
     1584        PrintConv => {
     1585            0 => 'Off',
     1586            1 => 'Standard',
     1587            2 => 'Advanced',
     1588        },
     1589    },
     1590    0x15 => { #15/20
     1591        Name => 'DynamicRangeOptimizer',
     1592        # this and the Sony tag 0xb025 DynamicRangeOptimizer give the actual mode
     1593        # applied to the image. The Minolta CameraSettingsA100 0x0027 tag gives
     1594        # the setting. There is a longish list of scenarios in which, regardless
     1595        # of the latter, DRO is not applied (ref 20)
     1596        Notes => 'as applied to image',
     1597        PrintConv => {
     1598            0 => 'Off',
     1599            1 => 'Standard',
     1600            2 => 'Advanced',
     1601        },
     1602    },
    12381603    0x16 => { #15
    12391604        Name => 'ColorMode',
     
    12491614        },
    12501615    },
    1251     # 0x17 => 'ColorSpace' (ref 15)
     1616    0x17 => { # 15/20
     1617        Name => 'ColorSpace',
     1618        PrintConv => {
     1619            0 => 'sRGB',
     1620            5 => 'Adobe RGB',
     1621        },
     1622    },
    12521623    0x18 => { #15
    12531624        Name => 'Sharpness',
    12541625        ValueConv => '$val - 10',
    12551626        ValueConvInv => '$val + 10',
    1256         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    1257         PrintConvInv => '$val=~/normal/i ? 0 : $val',
     1627        %Image::ExifTool::Exif::printParameter,
    12581628    },
    12591629    0x19 => { #15
     
    12611631        ValueConv => '$val - 10',
    12621632        ValueConvInv => '$val + 10',
    1263         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    1264         PrintConvInv => '$val=~/normal/i ? 0 : $val',
     1633        %Image::ExifTool::Exif::printParameter,
    12651634    },
    12661635    0x1a => { #15
     
    12681637        ValueConv => '$val - 10',
    12691638        ValueConvInv => '$val + 10',
    1270         PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
    1271         PrintConvInv => '$val=~/normal/i ? 0 : $val',
     1639        %Image::ExifTool::Exif::printParameter,
     1640    },
     1641    0x1c => { #20
     1642        Name => 'FlashMetering',
     1643        PrintConv => {
     1644            0 => 'ADI (Advanced Distance Integration)',
     1645            1 => 'Pre-flash TTL',
     1646        },
     1647    },
     1648    0x1d => { #20
     1649        Name => 'PrioritySetupShutterRelease',
     1650        PrintConv => {
     1651            0 => 'AF',
     1652            1 => 'Release',
     1653        },
    12721654    },
    12731655    0x1e => { #PH
     
    12761658            0 => 'Single Frame',
    12771659            1 => 'Continuous',
    1278             2 => 'Self-Timer',
     1660            2 => 'Self-timer',
    12791661            3 => 'Continuous Bracketing',
    12801662            4 => 'Single-Frame Bracketing',
     
    12821664        },
    12831665    },
     1666    0x1f => { #20
     1667        Name => 'SelfTimerTime',
     1668        PrintConv => {
     1669            0 => '10 s',
     1670            4 => '2 s',
     1671        },
     1672    },
     1673    0x20 => { #20
     1674        Name => 'ContinuousBracketing',
     1675        PrintHex => 1,
     1676        PrintConv => {
     1677            0x303 => 'Low',
     1678            0x703 => 'High',
     1679        },
     1680    },
     1681    0x21 => { #20
     1682        Name => 'SingleFrameBracketing',
     1683        PrintHex => 1,
     1684        PrintConv => {
     1685            0x302 => 'Low',
     1686            0x702 => 'High',
     1687        },
     1688    },
     1689    0x22 => { #20
     1690        Name => 'WhiteBalanceBracketing',
     1691        PrintHex => 1,
     1692        PrintConv => {
     1693            0x08 => 'Low',
     1694            0x09 => 'High',
     1695        },
     1696    },
     1697    0x023 => { #20
     1698        Name => 'WhiteBalanceSetting',
     1699        PrintHex => 1,
     1700        # (not sure what bit 0x8000 indicates)
     1701        PrintConv => {
     1702            0 => 'Auto',
     1703            1 => 'Preset',
     1704            2 => 'Custom',
     1705            3 => 'Color Temperature/Color Filter',
     1706            0x8001 => 'Preset',
     1707            0x8002 => 'Custom',
     1708            0x8003 => 'Color Temperature/Color Filter',
     1709        },
     1710    },
     1711    0x24 => { #20
     1712        Name => 'PresetWhiteBalance',
     1713        PrintConv => {
     1714            1 => 'Daylight',
     1715            2 => 'Cloudy',
     1716            3 => 'Shade',
     1717            4 => 'Tungsten',
     1718            5 => 'Fluorescent',
     1719            6 => 'Flash',
     1720        },
     1721    },
     1722    0x25 => { #20
     1723        Name => 'ColorTemperatureSetting',
     1724        PrintConv => {
     1725            0 => 'Temperature',
     1726            2 => 'Color Filter',
     1727        },
     1728    },
     1729    0x26 => { #20
     1730        Name => 'CustomWBSetting',
     1731        PrintConv => {
     1732            0 => 'Setup',
     1733            1 => 'Recall',
     1734        },
     1735    },
     1736    0x27 => { #20
     1737        Name => 'DynamicRangeOptimizerSetting',
     1738        Notes => 'as set in camera',
     1739        PrintConv => {
     1740            0 => 'Off',
     1741            1 => 'Standard',
     1742            2 => 'Advanced',
     1743        },
     1744    },
     1745    0x32 => 'FreeMemoryCardImages', #20
     1746    0x34 => 'CustomWBRedLevel', #20
     1747    0x35 => 'CustomWBGreenLevel', #20
     1748    0x36 => 'CustomWBBlueLevel', #20
     1749    0x37 => { #20
     1750        Name => 'CustomWBError',
     1751        PrintConv => {
     1752            0 => 'OK',
     1753            1 => 'Error',
     1754        },
     1755    },
     1756    0x38 => { #20
     1757        Name => 'WhiteBalanceFineTune',
     1758        Format => 'int16s',
     1759    },
     1760    0x39 => { #20
     1761        Name => 'ColorTemperature',
     1762        ValueConv => '$val * 100',
     1763        ValueConvInv => '$val / 100',
     1764    },
     1765    0x3a => { #20
     1766        Name => 'ColorCompensationFilter',
     1767        Format => 'int16s',
     1768        Notes => 'ranges from -2 for green to +2 for magenta',
     1769    },
     1770    0x3b => { #20
     1771        Name => 'SonyImageSize',
     1772        PrintConv => {
     1773            0 => 'Standard',
     1774            1 => 'Medium',
     1775            2 => 'Small',
     1776        },
     1777    },
     1778    0x3c => { #20
     1779        Name => 'SonyQuality',
     1780        PrintConv => {
     1781            0 => 'RAW',
     1782            32 => 'Fine',
     1783            34 => 'RAW + JPEG',
     1784            48 => 'Standard',
     1785        },
     1786    },
     1787    0x3d => { #20
     1788        Name => 'InstantPlaybackTime',
     1789        PrintConv => '"$val s"',
     1790        PrintConvInv => '$val=~s/\s*s//; $val',
     1791    },
     1792    0x3e => { #20
     1793        Name => 'InstantPlaybackSetup',
     1794        PrintConv => {
     1795            0 => 'Image and Information',
     1796            1 => 'Image Only',
     1797            # 2 appears to be unused
     1798            3 => 'Image and Histogram',
     1799        },
     1800    },
    12841801    0x3f => { #PH
    12851802        Name => 'NoiseReduction',
    1286         PrintConv => { 0 => 'Off', 1 => 'On' },
     1803        PrintConv => \%offOn,
     1804    },
     1805    0x40 => { #20
     1806        Name => 'EyeStartAF',
     1807        PrintConv => \%onOff,
     1808    },
     1809    0x41 => { #20
     1810        Name => 'RedEyeReduction',
     1811        PrintConv => \%offOn,
     1812    },
     1813    0x42 => { #20
     1814        Name => 'FlashDefault',
     1815        PrintConv => {
     1816            0 => 'Auto',
     1817            1 => 'Fill Flash',
     1818        },
     1819    },
     1820    0x43 => { #20
     1821        Name => 'AutoBracketOrder',
     1822        PrintConv => {
     1823            0 => '0 - +',
     1824            1 => '- 0 +',
     1825        },
     1826    },
     1827    0x44 => { #20
     1828        Name => 'FocusHoldButton',
     1829        PrintConv => {
     1830            0 => 'Focus Hold',
     1831            1 => 'DOF Preview',
     1832        },
     1833    },
     1834    0x45 => { #20
     1835        Name => 'AELButton',
     1836        PrintConv => {
     1837            0 => 'Hold',
     1838            1 => 'Toggle',
     1839            2 => 'Spot Hold',
     1840            3 => 'Spot Toggle',
     1841        },
     1842    },
     1843    0x46 => { #20
     1844        Name => 'ControlDialSet',
     1845        PrintConv => {
     1846            0 => 'Shutter Speed',
     1847            1 => 'Aperture',
     1848        },
     1849    },
     1850    0x47 => { #20
     1851        Name => 'ExposureCompensationMode',
     1852        PrintConv => {
     1853            0 => 'Ambient and Flash',
     1854            1 => 'Ambient Only',
     1855        },
     1856    },
     1857    0x48 => { #20
     1858        Name => 'AFAssist',
     1859        PrintConv => \%onOff,
     1860    },
     1861    0x49 => { #20
     1862        Name => 'CardShutterLock',
     1863        PrintConv => \%onOff,
     1864    },
     1865    0x4a => { #20
     1866        Name => 'LensShutterLock',
     1867        PrintConv => \%onOff,
     1868    },
     1869    0x4b => { #20
     1870        Name => 'AFAreaIllumination',
     1871        PrintConv => {
     1872            0 => '0.3 s',
     1873            1 => '0.6 s',
     1874            2 => 'Off',
     1875        },
     1876    },
     1877    0x4c => { #20
     1878        Name => 'MonitorDisplayOff',
     1879        PrintConv => {
     1880            0 => 'Automatic',
     1881            1 => 'Manual',
     1882        },
     1883    },
     1884    0x4d => { #20
     1885        Name => 'RecordDisplay',
     1886        PrintConv => {
     1887            0 => 'Auto Rotate',
     1888            1 => 'Horizontal',
     1889        },
     1890    },
     1891    0x4e => { #20
     1892        Name => 'PlayDisplay',
     1893        PrintConv => {
     1894            0 => 'Auto Rotate',
     1895            1 => 'Manual Rotate',
     1896        },
     1897    },
     1898    0x50 => { #20
     1899        Name => 'ExposureIndicator',
     1900        SeparateTable => 'ExposureIndicator',
     1901        PrintConv => \%exposureIndicator,
     1902    },
     1903    0x51 => { #20
     1904        Name => 'AELExposureIndicator',
     1905        Notes => 'also indicates exposure for next shot when bracketing',
     1906        SeparateTable => 'ExposureIndicator',
     1907        PrintConv => \%exposureIndicator,
     1908    },
     1909    0x52 => { #20
     1910        Name => 'ExposureBracketingIndicatorLast',
     1911        Notes => 'indicator for last shot when bracketing',
     1912        SeparateTable => 'ExposureIndicator',
     1913        PrintConv => \%exposureIndicator,
     1914    },
     1915    0x53 => { #20
     1916        Name => 'MeteringOffScaleIndicator',
     1917        Notes => 'two flashing triangles when under or over metering scale',
     1918        PrintConv => {
     1919            0 => 'Within Range',
     1920            1 => 'Under/Over Range',
     1921            255 => 'Out of Range',
     1922        },
     1923    },
     1924    0x54 => { #20
     1925        Name => 'FlashExposureIndicator',
     1926        SeparateTable => 'ExposureIndicator',
     1927        PrintConv => \%exposureIndicator,
     1928    },
     1929    0x55 => { #20
     1930        Name => 'FlashExposureIndicatorNext',
     1931        Notes => 'indicator for next shot when bracketing',
     1932        SeparateTable => 'ExposureIndicator',
     1933        PrintConv => \%exposureIndicator,
     1934    },
     1935    0x56 => { #20
     1936        Name => 'FlashExposureIndicatorLast',
     1937        Notes => 'indicator for last shot when bracketing',
     1938        SeparateTable => 'ExposureIndicator',
     1939        PrintConv => \%exposureIndicator,
     1940    },
     1941    0x58 => { #20
     1942        Name => 'FocusModeSwitch',
     1943        PrintConv => {
     1944            0 => 'AF',
     1945            1 => 'MF',
     1946        },
     1947    },
     1948    0x59 => { #20
     1949        Name => 'FlashType',
     1950        PrintConv => {
     1951            0 => 'Off',
     1952            1 => 'Built-in', # (also when built-in flash is a trigger in wireless mode)
     1953            2 => 'External',
     1954        },
    12871955    },
    12881956    0x5a => { #15
     
    12931961            2 => 'Rotate 90 CW',
    12941962        },
     1963    },
     1964    0x5b => { #20
     1965        Name => 'AELock',
     1966        PrintConv => \%offOn,
     1967    },
     1968    0x57 => { #15
     1969        Name => 'ImageStabilization',
     1970        PrintConv => \%offOn,
    12951971    },
    12961972    0x5e => { #15
     
    12991975        ValueConvInv => '$val / 100',
    13001976    },
    1301     0x87 => { #15
    1302         Name => 'ImageStabilization',
    1303         Writable => 'int32u',
    1304         PrintConv => { 0 => 'Off', 1 => 'On' },
     1977    0x5f => { #20
     1978        Name => 'ColorCompensationFilter',
     1979        Format => 'int16s',
     1980        Notes => 'ranges from -2 for green to +2 for magenta',
     1981    },
     1982    0x60 => { #20
     1983        Name => 'BatteryLevel',
     1984        PrintConv => {
     1985            3 => 'Very Low',
     1986            4 => 'Low',
     1987            5 => 'Half Full',
     1988            6 => 'Sufficient Power Remaining',
     1989        },
     1990    },
     1991);
     1992
     1993# white balance information stored by the Sony DSLR-A100 (ref 20)
     1994%Image::ExifTool::Minolta::WBInfoA100 = (
     1995    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1996    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     1997    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     1998    NOTES => 'White balance information for the Sony DSLR-A100.',
     1999    WRITABLE => 1,
     2000    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2001    FIRST_ENTRY => 0,
     2002    0x96  => { Name => 'WB_RGBLevels',          Format => 'int16u[3]' },
     2003    0xae  => { Name => 'WB_GBRGLevels',         Format => 'int16u[4]' },
     2004    0x304 => { Name => 'WB_RBPresetFlash',      Format => 'int16u[2]' },
     2005    0x308 => { Name => 'WB_RBPresetCoolWhiteF', Format => 'int16u[2]' },
     2006    0x3e8 => { Name => 'WB_RBPresetTungsten',   Format => 'int16u[2]' },
     2007    0x3ec => { Name => 'WB_RBPresetDaylight',   Format => 'int16u[2]' },
     2008    0x3f0 => { Name => 'WB_RBPresetCloudy',     Format => 'int16u[2]' },
     2009    0x3f4 => { Name => 'WB_RBPresetFlash',      Format => 'int16u[2]' },
     2010    0x3fc => {
     2011        Name => 'WB_RedPresetsFluorescent',
     2012        Format => 'int16u[7]',
     2013        Notes => q{
     2014            white balance red presets for fluorescent -2 through +4.  -2=Fluorescent,
     2015            -1=WhiteFluorescent, 0=CoolWhiteFluorescent, +1=DayWhiteFluorescent and
     2016            +3=DaylightFluorescent
     2017        },
     2018    },
     2019    0x40a => {
     2020        Name => 'WB_BluePresetsFluorescent',
     2021        Format => 'int16u[7]',
     2022        Notes => 'white balance blue presets for fluorescent -2 through +4',
     2023    },
     2024    0x418 => { Name => 'WB_RBPresetShade',                 Format => 'int16u[2]' },
     2025    0x424 => { Name => 'WB_RBPresetCustom',                Format => 'int16u[2]' },
     2026    0x49dc => {
     2027        Name => 'InternalSerialNumber',
     2028        Format => 'string[12]',
     2029    },
     2030);
     2031
     2032# tags in Konica Minolta MOV videos (ref PH)
     2033# (similar information in Kodak,Minolta,Nikon,Olympus,Pentax and Sanyo videos)
     2034%Image::ExifTool::Minolta::MOV1 = (
     2035    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     2036    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2037    FIRST_ENTRY => 0,
     2038    NOTES => q{
     2039        This information is found in MOV videos from some Konica Minolta models such
     2040        as the DiMage Z10 and X50.
     2041    },
     2042    0 => {
     2043        Name => 'Make',
     2044        Format => 'string[32]',
     2045    },
     2046    0x20 => {
     2047        Name => 'ModelType',
     2048        Format => 'string[8]',
     2049    },
     2050    # (01 00 at offset 0x28)
     2051    0x2e => {
     2052        Name => 'ExposureTime',
     2053        Format => 'int32u',
     2054        ValueConv => '$val ? 10 / $val : 0',
     2055        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     2056    },
     2057    0x32 => {
     2058        Name => 'FNumber',
     2059        Format => 'rational64u',
     2060        PrintConv => 'sprintf("%.1f",$val)',
     2061    },
     2062    0x3a => {
     2063        Name => 'ExposureCompensation',
     2064        Format => 'rational64s',
     2065        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     2066    },
     2067    # 0x4c => 'WhiteBalance', ?
     2068    0x50 => {
     2069        Name => 'FocalLength',
     2070        Format => 'rational64u',
     2071        PrintConv => 'sprintf("%.1f mm",$val)',
     2072    },
     2073);
     2074
     2075# tags in Minolta MOV videos (ref PH)
     2076# (similar information in Kodak,Minolta,Nikon,Olympus,Pentax and Sanyo videos)
     2077%Image::ExifTool::Minolta::MOV2 = (
     2078    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     2079    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2080    FIRST_ENTRY => 0,
     2081    NOTES => q{
     2082        This information is found in MOV videos from some Minolta models such as the
     2083        DiMAGE X and Xt.
     2084    },
     2085    0 => {
     2086        Name => 'Make',
     2087        Format => 'string[32]',
     2088    },
     2089    0x18 => {
     2090        Name => 'ModelType',
     2091        Format => 'string[8]',
     2092    },
     2093    # (01 00 at offset 0x20)
     2094    0x26 => {
     2095        Name => 'ExposureTime',
     2096        Format => 'int32u',
     2097        ValueConv => '$val ? 10 / $val : 0',
     2098        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     2099    },
     2100    0x2a => {
     2101        Name => 'FNumber',
     2102        Format => 'rational64u',
     2103        PrintConv => 'sprintf("%.1f",$val)',
     2104    },
     2105    0x32 => {
     2106        Name => 'ExposureCompensation',
     2107        Format => 'rational64s',
     2108        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     2109    },
     2110    # 0x44 => 'WhiteBalance', ?
     2111    0x48 => {
     2112        Name => 'FocalLength',
     2113        Format => 'rational64u',
     2114        PrintConv => 'sprintf("%.1f mm",$val)',
     2115    },
     2116);
     2117
     2118# more tags in Minolta MOV videos (ref PH)
     2119%Image::ExifTool::Minolta::MMA = (
     2120    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     2121    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2122    NOTES => q{
     2123        This information is found in MOV videos from Minolta models such as the
     2124        DiMAGE A2, S414 and 7Hi.
     2125    },
     2126    0 => {
     2127        Name => 'Make',
     2128        Format => 'string[20]',
     2129    },
     2130    20 => {
     2131        Name => 'SoftwareVersion',
     2132        Format => 'string[16]',
    13052133    },
    13062134);
     
    13742202=head1 AUTHOR
    13752203
    1376 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     2204Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    13772205
    13782206This library is free software; you can redistribute it and/or modify it
     
    13922220
    13932221Thanks to Jay Al-Saadi, Niels Kristian Bech Jensen, Shingo Noguchi, Pedro
    1394 Corte-Real and Jeffery Small for the information they provided.
     2222Corte-Real, Jeffery Small, Jens Duttke,  Thomas Kassner, Mladen Sever, Olaf
     2223Ulrich, Lukasz Stelmach and Igal Milchtaich for the information they
     2224provided, and for everyone who helped with the LensType list.
    13952225
    13962226=head1 SEE ALSO
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MinoltaRaw.pm

    r16842 r24107  
    88# References:   1) http://www.cybercom.net/~dcoffin/dcraw/
    99#               2) http://www.chauveau-central.net/mrw-format/
     10#               3) Igal Milchtaich private communication (A100)
    1011#------------------------------------------------------------------------------
    1112
     
    1516use vars qw($VERSION);
    1617use Image::ExifTool qw(:DataAccess :Utils);
    17 
    18 $VERSION = '1.02';
     18use Image::ExifTool::Minolta;
     19
     20$VERSION = '1.12';
     21
     22sub ProcessMRW($$;$);
     23sub WriteMRW($$;$);
    1924
    2025# Minolta MRW tags
    2126%Image::ExifTool::MinoltaRaw::Main = (
    2227    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     28    PROCESS_PROC => \&Image::ExifTool::MinoltaRaw::ProcessMRW,
     29    WRITE_PROC => \&Image::ExifTool::MinoltaRaw::WriteMRW,
    2330    NOTES => 'These tags are used in Minolta RAW format (MRW) images.',
    24     "\0TTW" => {
     31    "\0TTW" => { # TIFF Tags
    2532        Name => 'MinoltaTTW',
    2633        SubDirectory => {
     
    3138        },
    3239    },
    33     "\0PRD" => {
     40    "\0PRD" => { # Raw Picture Dimensions
    3441        Name => 'MinoltaPRD',
    3542        SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::PRD' },
    3643    },
    37     "\0WBG" => {
     44    "\0WBG" => { # White Balance Gains
    3845        Name => 'MinoltaWBG',
    3946        SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::WBG' },
    4047    },
    41     "\0RIF" => {
     48    "\0RIF" => { # Requested Image Format
    4249        Name => 'MinoltaRIF',
    4350        SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::RIF' },
    4451    },
     52    # "\0CSA" is padding
    4553);
    4654
     
    111119        Format => 'int8u[4]',
    112120    },
    113     4 => {
    114         Name => 'WBLevels',
    115         Format => 'int16u[4]',
    116     },
     121    4 => [
     122        {
     123            Condition => '$$self{Model} =~ /DiMAGE A200\b/',
     124            Name => 'WB_GBRGLevels',
     125            Format => 'int16u[4]',
     126            Notes => 'DiMAGE A200',
     127        },
     128        {
     129            Name => 'WB_RGGBLevels',
     130            Format => 'int16u[4]',
     131            Notes => 'other models',
     132        },
     133    ],
    117134);
    118135
     
    150167            4 => 'Sunset',
    151168            5 => 'Sports',
     169            # have seen these values in Sony ARW images: - PH
     170            # 7, 128, 129, 160
    152171        },
    153172    },
    154173    6 => {
    155174        Name => 'ISOSetting',
    156         ValueConv => '2 ** (($val-48)/8) * 100',
    157         ValueConvInv => '48 + 8*log($val/100)/log(2)',
    158         PrintConv => 'int($val + 0.5)',
    159         PrintConvInv => '$val',
    160     },
    161     7 => {
    162         Name => 'ColorMode',
    163         PrintHex => 1,
    164         PrintConv => {
    165             0 => 'Normal',
    166             1 => 'Black & White',
    167             2 => 'Vivid color',
    168             3 => 'Solarization',
    169             4 => 'Adobe RGB',
    170             13 => 'Natural sRGB',
    171             14 => 'Natural+ sRGB',
    172             0x84 => 'Adobe RGB', # what does the high bit mean?
    173         },
     175        RawConv => '$val == 255 ? undef : $val',
     176        PrintConv => { #3
     177            0 => 'Auto',
     178            48 => 100,
     179            56 => 200,
     180            64 => 400,
     181            72 => 800,
     182            80 => 1600,
     183            174 => '80 (Zone Matching Low)',
     184            184 => '200 (Zone Matching High)',
     185            OTHER => sub {
     186                my ($val, $inv) = @_;
     187                return int(2 ** (($val-48)/8) * 100 + 0.5) unless $inv;
     188                return 48 + 8*log($val/100)/log(2) if Image::ExifTool::IsFloat($val);
     189                return undef;
     190            },
     191        },
     192        #ValueConv => '2 ** (($val-48)/8) * 100',
     193        #ValueConvInv => '48 + 8*log($val/100)/log(2)',
     194        #PrintConv => 'int($val + 0.5)',
     195        #PrintConvInv => '$val',
     196    },
     197    7 => [
     198        {
     199            Name => 'ColorMode',
     200            Condition => '$$self{Make} !~ /^SONY/',
     201            Priority => 0,
     202            Writable => 'int32u',
     203            PrintConv => \%Image::ExifTool::Minolta::minoltaColorMode,
     204        },
     205        { #3
     206            Name => 'ColorMode',
     207            Condition => '$$self{Model} eq "DSLR-A100"',
     208            Writable => 'int32u',
     209            Notes => 'Sony A100',
     210            Priority => 0,
     211            PrintHex => 1,
     212            PrintConv => \%Image::ExifTool::Minolta::sonyColorMode,
     213        },
     214    ],
     215    # NOTE: some of these WB_RBLevels may apply to other models too...
     216    8  => { #3
     217        Name => 'WB_RBLevelsTungsten',
     218        Condition => '$$self{Model} eq "DSLR-A100"',
     219        Format => 'int16u[2]',
     220        Notes => 'these WB_RBLevels currently decoded only for the Sony A100',
     221    },
     222    12 => { #3
     223        Name => 'WB_RBLevelsDaylight',
     224        Condition => '$$self{Model} eq "DSLR-A100"',
     225        Format => 'int16u[2]',
     226    },
     227    16 => { #3
     228        Name => 'WB_RBLevelsCloudy',
     229        Condition => '$$self{Model} eq "DSLR-A100"',
     230        Format => 'int16u[2]',
     231    },
     232    20 => { #3
     233        Name => 'WB_RBLevelsCoolWhiteF',
     234        Condition => '$$self{Model} eq "DSLR-A100"',
     235        Format => 'int16u[2]',
     236    },
     237    24 => { #3
     238        Name => 'WB_RBLevelsFlash',
     239        Condition => '$$self{Model} eq "DSLR-A100"',
     240        Format => 'int16u[2]',
     241    },
     242    28 => { #3
     243        Name => 'WB_RBLevelsUnknown',
     244        Condition => '$$self{Model} eq "DSLR-A100"',
     245        Format => 'int16u[2]',
     246        Unknown => 1,
     247    },
     248    32 => { #3
     249        Name => 'WB_RBLevelsShade',
     250        Condition => '$$self{Model} eq "DSLR-A100"',
     251        Format => 'int16u[2]',
     252    },
     253    36 => { #3
     254        Name => 'WB_RBLevelsDaylightF',
     255        Condition => '$$self{Model} eq "DSLR-A100"',
     256        Format => 'int16u[2]',
     257    },
     258    40 => { #3
     259        Name => 'WB_RBLevelsDayWhiteF',
     260        Condition => '$$self{Model} eq "DSLR-A100"',
     261        Format => 'int16u[2]',
     262    },
     263    44 => { #3
     264        Name => 'WB_RBLevelsWhiteF',
     265        Condition => '$$self{Model} eq "DSLR-A100"',
     266        Format => 'int16u[2]',
    174267    },
    175268    56 => {
    176269        Name => 'ColorFilter',
     270        Condition => '$$self{Make} !~ /^SONY/',
    177271        Format => 'int8s',
     272        Notes => 'Minolta models',
    178273    },
    179274    57 => 'BWFilter',
    180275    58 => {
    181276        Name => 'ZoneMatching',
     277        Condition => '$$self{Make} !~ /^SONY/',
     278        Priority => 0,
     279        Notes => 'Minolta models',
    182280        PrintConv => {
    183281            0 => 'ISO Setting Used',
     
    192290    60 => {
    193291        Name => 'ColorTemperature',
     292        Condition => '$$self{Make} !~ /^SONY/',
     293        Notes => 'Minolta models',
    194294        ValueConv => '$val * 100',
    195295        ValueConvInv => '$val / 100',
     296    },
     297    74 => { #3
     298        Name => 'ZoneMatching',
     299        Condition => '$$self{Make} =~ /^SONY/',
     300        Priority => 0,
     301        Notes => 'Sony models',
     302        PrintConv => {
     303            0 => 'ISO Setting Used',
     304            1 => 'High Key',
     305            2 => 'Low Key',
     306        },
     307    },
     308    76 => { #3
     309        Name => 'ColorTemperature',
     310        Condition => '$$self{Make} =~ /^SONY/ and $$self{Model} eq "DSLR-A100"',
     311        Notes => 'A100',
     312        ValueConv => '$val * 100',
     313        ValueConvInv => '$val / 100',
     314        PrintConv => '$val ? $val : "Auto"',
     315        PrintConvInv => '$val=~/Auto/i ? 0 : $val',
     316    },
     317    77 => { #3
     318        Name => 'ColorFilter',
     319        Condition => '$$self{Make} =~ /^SONY/ and $$self{Model} eq "DSLR-A100"',
     320        Notes => 'A100',
     321    },
     322    78 => { #3
     323        Name => 'ColorTemperature',
     324        Condition => '$$self{Make} =~ /^SONY/ and $$self{Model} =~ /^DSLR-A(200|700)$/',
     325        Notes => 'A200 and A700',
     326        ValueConv => '$val * 100',
     327        ValueConvInv => '$val / 100',
     328        PrintConv => '$val ? $val : "Auto"',
     329        PrintConvInv => '$val=~/Auto/i ? 0 : $val',
     330    },
     331    79 => { #3
     332        Name => 'ColorFilter',
     333        Condition => '$$self{Make} =~ /^SONY/ and $$self{Model} =~ /^DSLR-A(200|700)$/',
     334        Notes => 'A200 and A700',
    196335    },
    197336);
     
    223362
    224363#------------------------------------------------------------------------------
     364# Write MRW directory (ie. in ARW images)
     365# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) optional tag table ref
     366# Returns: new MRW data or undef on error
     367sub WriteMRW($$;$)
     368{
     369    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     370    $exifTool or return 1;      # allow dummy access
     371    my $buff = '';
     372    $$dirInfo{OutFile} = \$buff;
     373    ProcessMRW($exifTool, $dirInfo, $tagTablePtr) > 0 or undef $buff;
     374    return $buff;
     375}
     376
     377#------------------------------------------------------------------------------
    225378# Read or write Minolta MRW file
    226 # Inputs: 0) ExifTool object reference, 1) dirInfo reference
     379# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) optional tag table ref
    227380# Returns: 1 on success, 0 if this wasn't a valid MRW file, or -1 on write error
    228 sub ProcessMRW($$)
     381# Notes: File pointer must be set to start of MRW in RAF upon entry
     382sub ProcessMRW($$;$)
    229383{
    230     my ($exifTool, $dirInfo) = @_;
     384    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    231385    my $raf = $$dirInfo{RAF};
    232386    my $outfile = $$dirInfo{OutFile};
     
    235389    my ($data, $err, $outBuff);
    236390
     391    if ($$dirInfo{DataPt}) {
     392        # make a RAF object for MRW information extracted from other file types
     393        $raf = new File::RandomAccess($$dirInfo{DataPt});
     394        # MRW information in DNG images may not start at beginning of data block
     395        $raf->Seek($$dirInfo{DirStart}, 0) if $$dirInfo{DirStart};
     396    }
    237397    $raf->Read($data,8) == 8 or return 0;
    238     $data =~ /^\0MRM/ or return 0;
    239     $exifTool->SetFileType() unless $exifTool->{VALUE}->{FileType};
    240     SetByteOrder('MM');
    241     my $tagTablePtr = GetTagTable('Image::ExifTool::MinoltaRaw::Main');
     398    # "\0MRM" for big-endian (MRW images), and
     399    # "\0MRI" for little-endian (MRWInfo in ARW images)
     400    $data =~ /^\0MR([MI])/ or return 0;
     401    my $hdr = "\0MR$1";
     402    SetByteOrder($1 . $1);
     403    $exifTool->SetFileType();
     404    $tagTablePtr = GetTagTable('Image::ExifTool::MinoltaRaw::Main');
    242405    if ($outfile) {
    243406        $exifTool->InitWriteDirs('TIFF'); # use same write dirs as TIFF
    244407        $outBuff = '';
    245408    }
    246     my $offset = Get32u(\$data, 4) + 8;
    247     my $pos = 8;
     409    my $pos = $raf->Tell();
     410    my $offset = Get32u(\$data, 4) + $pos;
    248411    my $rtnVal = 1;
    249412    $verbose and printf $out "  [MRW Data Offset: 0x%x]\n", $offset;
     
    258421            if ($verbose > 2) {
    259422                $raf->Read($data,$len) == $len and $raf->Seek($pos,0) or $err = 1, last;
    260                 my %parms = (Addr => $pos, Out => $out);
    261                 $parms{MaxLen} = 96 unless $verbose > 3;
    262                 Image::ExifTool::HexDump(\$data,undef,%parms);
     423                $exifTool->VerboseDump(\$data);
    263424            }
    264425        }
     
    267428            my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
    268429            my $buff;
     430            # save shift for values stored with wrong base offset
     431            $$exifTool{MRW_WrongBase} = -($raf->Tell());
    269432            $raf->Read($buff, $len) == $len or $err = 1, last;
    270433            my %subdirInfo = (
     
    307470    if ($outfile) {
    308471        # write the file header then the buffered meta information
    309         Write($outfile, "\0MRM", Set32u(length $outBuff), $outBuff) or $rtnVal = -1;
     472        Write($outfile, $hdr, Set32u(length $outBuff), $outBuff) or $rtnVal = -1;
    310473        # copy over image data
    311474        while ($raf->Read($outBuff, 65536)) {
    312475            Write($outfile, $outBuff) or $rtnVal = -1;
    313476        }
     477        # Sony IDC utility corrupts MRWInfo when writing ARW images,
     478        # so make this a minor error for these images
     479        $err and $exifTool->Error("MRW format error", $$exifTool{TIFF_TYPE} eq 'ARW');
     480    } else {
     481        $err and $exifTool->Warn("MRW format error");
    314482    }
    315     $err and $exifTool->Error("MRW format error");
    316483    return $rtnVal;
    317484}
     
    336503=head1 AUTHOR
    337504
    338 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     505Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    339506
    340507This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Nikon.pm

    r16842 r24107  
    88#               09/21/2004 - P. Harvey Changed tag 2 to ISOUsed & added PrintConv
    99#               12/01/2004 - P. Harvey Added default PRINT_CONV
    10 #               12/06/2004 - P. Harvey Added SceneMode
    1110#               01/01/2005 - P. Harvey Decode preview image and preview IFD
    1211#               03/35/2005 - T. Christiansen additions
    1312#               05/10/2005 - P. Harvey Decode encrypted lens data
     13#               [ongoing]  - P. Harvey Constantly decoding new information
    1414#
    1515# References:   1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
     
    2222#               8) Robert Rottmerhusen private communication
    2323#               9) http://members.aol.com/khancock/pilot/nbuddy/
    24 #              10) Werner Kober private communication (D2H, D2X, D100, D70, D200)
     24#              10) Werner Kober private communication (D2H, D2X, D100, D70, D200, D90)
    2525#              11) http://www.rottmerhusen.com/objektives/lensid/thirdparty.html
    2626#              12) http://libexif.sourceforge.net/internals/mnote-olympus-tag_8h-source.html
    2727#              13) Roger Larsson private communication (tests with D200)
    28 #              14) http://homepage3.nifty.com/kamisaka/makernote/makernote_nikon.htm
     28#              14) http://homepage3.nifty.com/kamisaka/makernote/makernote_nikon.htm (2007/09/15)
    2929#              15) http://tomtia.plala.jp/DigitalCamera/MakerNote/index.asp
    3030#              16) Jeffrey Friedl private communication (D200 with firmware update)
    3131#              17) http://www.wohlberg.net/public/software/photo/nstiffexif/
     32#                  and Brendt Wohlberg private communication
    3233#              18) Anonymous user private communication (D70, D200, D2x)
    33 #              19) Jens Duttke private communication
    34 #              20) Bruce Stevens private communication
    35 #              21) Vladimir Sauta private communication (D80)
     34#              19) Bruce Stevens private communication
     35#              20) Vladimir Sauta private communication (D80)
     36#              21) Gregor Dorlars private communication (D300)
     37#              22) Tanel Kuusk private communication
     38#              23) Alexandre Naaman private communication (D3)
     39#              24) Geert De Soete private communication
     40#              25) Niels Kristian private communication
     41#              26) Bozi (http://www.cpanforum.com/posts/8983)
     42#              27) Jens Kriese private communication
     43#              28) Warren Hatch private communication (D3v2.00 with SB-800 and SB-900)
     44#              29) Anonymous contribution 2011/05/25 (D700, D7000)
     45#              JD) Jens Duttke private communication
    3646#------------------------------------------------------------------------------
    3747
     
    4353use Image::ExifTool::Exif;
    4454
    45 $VERSION = '1.76';
     55$VERSION = '2.47';
     56
     57sub LensIDConv($$$);
     58sub ProcessNikonAVI($$$);
     59sub ProcessNikonMOV($$$);
     60sub FormatString($);
     61sub ProcessNikonCaptureEditVersions($$$);
    4662
    4763# nikon lens ID numbers (ref 8/11)
     
    5268        MaxApertureAtMinFocal, MaxApertureAtMaxFocal, MCUVersion and LensType, in
    5369        that order.  (source:
    54         L<http://www.rottmerhusen.com/objektives/lensid/thirdparty.html>)
    55     },
     70        L<http://www.rottmerhusen.com/objektives/lensid/thirdparty.html>.) Multiple
     71        lenses with the same LensID are differentiated by decimal values in the list
     72        below.  The user-defined "Lenses" list may be used to specify the lens for
     73        ExifTool to choose in these cases (see the
     74        L<sample config file|../config.html> for details).
     75    },
     76    OTHER => \&LensIDConv,
     77    # Note: Sync this list with Robert's Perl version at
     78    # http://www.rottmerhusen.com/objektives/lensid/files/exif/fmountlens.p.txt
    5679    # (hex digits must be uppercase in keys below)
    5780    '01 58 50 50 14 14 02 00' => 'AF Nikkor 50mm f/1.8',
    58     '01 00 00 00 00 00 02 00' => 'AF Teleconverter TC-16A 1.6x',
    59     '01 00 00 00 00 00 08 00' => 'AF Teleconverter TC-16A 1.6x',
    6081    '02 42 44 5C 2A 34 02 00' => 'AF Zoom-Nikkor 35-70mm f/3.3-4.5',
    6182    '02 42 44 5C 2A 34 08 00' => 'AF Zoom-Nikkor 35-70mm f/3.3-4.5',
     
    6889    '09 48 37 37 24 24 04 00' => 'AF Nikkor 24mm f/2.8',
    6990    '0A 48 8E 8E 24 24 03 00' => 'AF Nikkor 300mm f/2.8 IF-ED',
     91    '0A 48 8E 8E 24 24 05 00' => 'AF Nikkor 300mm f/2.8 IF-ED N',
    7092    '0B 48 7C 7C 24 24 05 00' => 'AF Nikkor 180mm f/2.8 IF-ED',
    7193    '0D 40 44 72 2C 34 07 00' => 'AF Zoom-Nikkor 35-135mm f/3.5-4.5',
     
    78100    '14 48 60 80 24 24 0B 00' => 'AF Zoom-Nikkor 80-200mm f/2.8 ED',
    79101    '15 4C 62 62 14 14 0C 00' => 'AF Nikkor 85mm f/1.8',
    80     '17 3C A0 A0 30 30 11 00' => 'Nikkor 500mm f/4 P',
     102    '17 3C A0 A0 30 30 0F 00' => 'Nikkor 500mm f/4 P ED IF',
     103    '17 3C A0 A0 30 30 11 00' => 'Nikkor 500mm f/4 P ED IF',
    81104    '18 40 44 72 2C 34 0E 00' => 'AF Zoom-Nikkor 35-135mm f/3.5-4.5 N',
    82105    '1A 54 44 44 18 18 11 00' => 'AF Nikkor 35mm f/2',
     
    86109    '1E 54 56 56 24 24 13 00' => 'AF Micro-Nikkor 60mm f/2.8',
    87110    '1F 54 6A 6A 24 24 14 00' => 'AF Micro-Nikkor 105mm f/2.8',
    88     '20 48 60 80 24 24 15 00' => 'AF Zoom-Nikkor ED 80-200mm f/2.8',
     111    '20 48 60 80 24 24 15 00' => 'AF Zoom-Nikkor 80-200mm f/2.8 ED',
    89112    '21 40 3C 5C 2C 34 16 00' => 'AF Zoom-Nikkor 28-70mm f/3.5-4.5',
    90113    '22 48 72 72 18 18 16 00' => 'AF DC-Nikkor 135mm f/2',
    91     '24 48 60 80 24 24 1A 02' => 'AF Zoom-Nikkor ED 80-200mm f/2.8D',
     114    '23 30 BE CA 3C 48 17 00' => 'Zoom-Nikkor 1200-1700mm f/5.6-8 P ED IF',
     115    '24 48 60 80 24 24 1A 02' => 'AF Zoom-Nikkor 80-200mm f/2.8D ED',
    92116    '25 48 44 5C 24 24 1B 02' => 'AF Zoom-Nikkor 35-70mm f/2.8D',
    93     '25 48 44 5C 24 24 52 02' => 'AF Zoom-Nikkor 35-70mm f/2.8D N',
    94     '27 48 8E 8E 24 24 F2 02' => 'AF-I Nikkor 300mm f/2.8D IF-ED',
     117    '25 48 44 5C 24 24 52 02' => 'AF Zoom-Nikkor 35-70mm f/2.8D',
     118    '26 40 3C 5C 2C 34 1C 02' => 'AF Zoom-Nikkor 28-70mm f/3.5-4.5D',
    95119    '27 48 8E 8E 24 24 1D 02' => 'AF-I Nikkor 300mm f/2.8D IF-ED',
     120    '27 48 8E 8E 24 24 F1 02' => 'AF-I Nikkor 300mm f/2.8D IF-ED + TC-14E',
     121    '27 48 8E 8E 24 24 E1 02' => 'AF-I Nikkor 300mm f/2.8D IF-ED + TC-17E',
     122    '27 48 8E 8E 24 24 F2 02' => 'AF-I Nikkor 300mm f/2.8D IF-ED + TC-20E',
    96123    '28 3C A6 A6 30 30 1D 02' => 'AF-I Nikkor 600mm f/4D IF-ED',
     124    '28 3C A6 A6 30 30 F1 02' => 'AF-I Nikkor 600mm f/4D IF-ED + TC-14E',
     125    '28 3C A6 A6 30 30 E1 02' => 'AF-I Nikkor 600mm f/4D IF-ED + TC-17E',
     126    '28 3C A6 A6 30 30 F2 02' => 'AF-I Nikkor 600mm f/4D IF-ED + TC-20E',
    97127    '2A 54 3C 3C 0C 0C 26 02' => 'AF Nikkor 28mm f/1.4D',
     128    '2B 3C 44 60 30 3C 1F 02' => 'AF Zoom-Nikkor 35-80mm f/4-5.6D',
    98129    '2C 48 6A 6A 18 18 27 02' => 'AF DC-Nikkor 105mm f/2D',
    99130    '2D 48 80 80 30 30 21 02' => 'AF Micro-Nikkor 200mm f/4D IF-ED',
     131    '2E 48 5C 82 30 3C 22 02' => 'AF Nikkor 70-210mm f/4-5.6D',
    100132    '2E 48 5C 82 30 3C 28 02' => 'AF Nikkor 70-210mm f/4-5.6D',
    101     '2F 48 30 44 24 24 29 02' => 'AF Zoom-Nikkor 20-35mm f/2.8(IF)',
     133    '2F 48 30 44 24 24 29 02.1' => 'AF Zoom-Nikkor 20-35mm f/2.8D IF',
     134    '30 48 98 98 24 24 24 02' => 'AF-I Nikkor 400mm f/2.8D IF-ED',
     135    '30 48 98 98 24 24 F1 02' => 'AF-I Nikkor 400mm f/2.8D IF-ED + TC-14E',
     136    '30 48 98 98 24 24 E1 02' => 'AF-I Nikkor 400mm f/2.8D IF-ED + TC-17E',
     137    '30 48 98 98 24 24 F2 02' => 'AF-I Nikkor 400mm f/2.8D IF-ED + TC-20E',
    102138    '31 54 56 56 24 24 25 02' => 'AF Micro-Nikkor 60mm f/2.8D',
    103     '32 54 6A 6A 24 24 35 02' => 'AF Micro-Nikkor 105mm f/2.8D',
     139    '32 54 6A 6A 24 24 35 02.1' => 'AF Micro-Nikkor 105mm f/2.8D',
    104140    '33 48 2D 2D 24 24 31 02' => 'AF Nikkor 18mm f/2.8D',
    105141    '34 48 29 29 24 24 32 02' => 'AF Fisheye Nikkor 16mm f/2.8D',
     142    '35 3C A0 A0 30 30 33 02' => 'AF-I Nikkor 500mm f/4D IF-ED',
     143    '35 3C A0 A0 30 30 F1 02' => 'AF-I Nikkor 500mm f/4D IF-ED + TC-14E',
     144    '35 3C A0 A0 30 30 E1 02' => 'AF-I Nikkor 500mm f/4D IF-ED + TC-17E',
     145    '35 3C A0 A0 30 30 F2 02' => 'AF-I Nikkor 500mm f/4D IF-ED + TC-20E',
    106146    '36 48 37 37 24 24 34 02' => 'AF Nikkor 24mm f/2.8D',
    107147    '37 48 30 30 24 24 36 02' => 'AF Nikkor 20mm f/2.8D',
    108148    '38 4C 62 62 14 14 37 02' => 'AF Nikkor 85mm f/1.8D',
     149    '3A 40 3C 5C 2C 34 39 02' => 'AF Zoom-Nikkor 28-70mm f/3.5-4.5D',
    109150    '3B 48 44 5C 24 24 3A 02' => 'AF Zoom-Nikkor 35-70mm f/2.8D N',
     151    '3C 48 60 80 24 24 3B 02' => 'AF Zoom-Nikkor 80-200mm f/2.8D ED', #25
    110152    '3D 3C 44 60 30 3C 3E 02' => 'AF Zoom-Nikkor 35-80mm f/4-5.6D',
    111153    '3E 48 3C 3C 24 24 3D 02' => 'AF Nikkor 28mm f/2.8D',
     154    '3F 40 44 6A 2C 34 45 02' => 'AF Zoom-Nikkor 35-105mm f/3.5-4.5D',
    112155    '41 48 7C 7C 24 24 43 02' => 'AF Nikkor 180mm f/2.8D IF-ED',
    113156    '42 54 44 44 18 18 44 02' => 'AF Nikkor 35mm f/2D',
    114157    '43 54 50 50 0C 0C 46 02' => 'AF Nikkor 50mm f/1.4D',
     158    '44 44 60 80 34 3C 47 02' => 'AF Zoom-Nikkor 80-200mm f/4.5-5.6D',
     159    '45 40 3C 60 2C 3C 48 02' => 'AF Zoom-Nikkor 28-80mm f/3.5-5.6D',
    115160    '46 3C 44 60 30 3C 49 02' => 'AF Zoom-Nikkor 35-80mm f/4-5.6D N',
    116161    '47 42 37 50 2A 34 4A 02' => 'AF Zoom-Nikkor 24-50mm f/3.3-4.5D',
    117162    '48 48 8E 8E 24 24 4B 02' => 'AF-S Nikkor 300mm f/2.8D IF-ED',
     163    '48 48 8E 8E 24 24 F1 02' => 'AF-S Nikkor 300mm f/2.8D IF-ED + TC-14E',
     164    '48 48 8E 8E 24 24 E1 02' => 'AF-S Nikkor 300mm f/2.8D IF-ED + TC-17E',
     165    '48 48 8E 8E 24 24 F2 02' => 'AF-S Nikkor 300mm f/2.8D IF-ED + TC-20E',
     166    '49 3C A6 A6 30 30 4C 02' => 'AF-S Nikkor 600mm f/4D IF-ED',
     167    '49 3C A6 A6 30 30 F1 02' => 'AF-S Nikkor 600mm f/4D IF-ED + TC-14E',
     168    '49 3C A6 A6 30 30 E1 02' => 'AF-S Nikkor 600mm f/4D IF-ED + TC-17E',
     169    '49 3C A6 A6 30 30 F2 02' => 'AF-S Nikkor 600mm f/4D IF-ED + TC-20E',
    118170    '4A 54 62 62 0C 0C 4D 02' => 'AF Nikkor 85mm f/1.4D IF',
     171    '4B 3C A0 A0 30 30 4E 02' => 'AF-S Nikkor 500mm f/4D IF-ED',
     172    '4B 3C A0 A0 30 30 F1 02' => 'AF-S Nikkor 500mm f/4D IF-ED + TC-14E',
     173    '4B 3C A0 A0 30 30 E1 02' => 'AF-S Nikkor 500mm f/4D IF-ED + TC-17E',
     174    '4B 3C A0 A0 30 30 F2 02' => 'AF-S Nikkor 500mm f/4D IF-ED + TC-20E',
    119175    '4C 40 37 6E 2C 3C 4F 02' => 'AF Zoom-Nikkor 24-120mm f/3.5-5.6D IF',
    120176    '4D 40 3C 80 2C 3C 62 02' => 'AF Zoom-Nikkor 28-200mm f/3.5-5.6D IF',
    121177    '4E 48 72 72 18 18 51 02' => 'AF DC-Nikkor 135mm f/2D',
    122178    '4F 40 37 5C 2C 3C 53 06' => 'IX-Nikkor 24-70mm f/3.5-5.6',
     179    '50 48 56 7C 30 3C 54 06' => 'IX-Nikkor 60-180mm f/4-5.6',
     180    '53 48 60 80 24 24 57 02' => 'AF Zoom-Nikkor 80-200mm f/2.8D ED',
    123181    '53 48 60 80 24 24 60 02' => 'AF Zoom-Nikkor 80-200mm f/2.8D ED',
    124182    '54 44 5C 7C 34 3C 58 02' => 'AF Zoom-Micro Nikkor 70-180mm f/4.5-5.6D ED',
    125183    '56 48 5C 8E 30 3C 5A 02' => 'AF Zoom-Nikkor 70-300mm f/4-5.6D ED',
    126184    '59 48 98 98 24 24 5D 02' => 'AF-S Nikkor 400mm f/2.8D IF-ED',
     185    '59 48 98 98 24 24 F1 02' => 'AF-S Nikkor 400mm f/2.8D IF-ED + TC-14E',
     186    '59 48 98 98 24 24 E1 02' => 'AF-S Nikkor 400mm f/2.8D IF-ED + TC-17E',
     187    '59 48 98 98 24 24 F2 02' => 'AF-S Nikkor 400mm f/2.8D IF-ED + TC-20E',
    127188    '5A 3C 3E 56 30 3C 5E 06' => 'IX-Nikkor 30-60mm f/4-5.6',
     189    '5B 44 56 7C 34 3C 5F 06' => 'IX-Nikkor 60-180mm f/4.5-5.6',
    128190    '5D 48 3C 5C 24 24 63 02' => 'AF-S Zoom-Nikkor 28-70mm f/2.8D IF-ED',
    129191    '5E 48 60 80 24 24 64 02' => 'AF-S Zoom-Nikkor 80-200mm f/2.8D IF-ED',
     
    142204    '6D 48 8E 8E 24 24 73 02' => 'AF-S Nikkor 300mm f/2.8D IF-ED II',
    143205    '6E 48 98 98 24 24 74 02' => 'AF-S Nikkor 400mm f/2.8D IF-ED II',
    144     '6F 3C A0 A0 30 30 75 02' => 'AF-S Nikkor 500mm f/4D IF-ED',
    145     '70 3C A6 A6 30 30 76 02' => 'AF-S Nikkor 600mm f/4D IF-ED',
     206    '6F 3C A0 A0 30 30 75 02' => 'AF-S Nikkor 500mm f/4D IF-ED II',
     207    '70 3C A6 A6 30 30 76 02' => 'AF-S Nikkor 600mm f/4D IF-ED II',
    146208    '72 48 4C 4C 24 24 77 00' => 'Nikkor 45mm f/2.8 P',
    147209    '74 40 37 62 2C 34 78 06' => 'AF-S Zoom-Nikkor 24-85mm f/3.5-4.5G IF-ED',
     
    151213    '78 40 37 6E 2C 3C 7C 0E' => 'AF-S VR Zoom-Nikkor 24-120mm f/3.5-5.6G IF-ED',
    152214    '79 40 3C 80 2C 3C 7F 06' => 'AF Zoom-Nikkor 28-200mm f/3.5-5.6G IF-ED',
    153     '7A 3C 1F 37 30 30 7E 06' => 'AF-S DX Zoom-Nikkor 12-24mm f/4G IF-ED',
     215    '7A 3C 1F 37 30 30 7E 06.1' => 'AF-S DX Zoom-Nikkor 12-24mm f/4G IF-ED',
    154216    '7B 48 80 98 30 30 80 0E' => 'AF-S VR Zoom-Nikkor 200-400mm f/4G IF-ED',
    155217    '7D 48 2B 53 24 24 82 06' => 'AF-S DX Zoom-Nikkor 17-55mm f/2.8G IF-ED',
     
    158220    '81 54 80 80 18 18 86 0E' => 'AF-S VR Nikkor 200mm f/2G IF-ED',
    159221    '82 48 8E 8E 24 24 87 0E' => 'AF-S VR Nikkor 300mm f/2.8G IF-ED',
     222    '83 00 B0 B0 5A 5A 88 04' => 'FSA-L2, EDG 65, 800mm F13 G',
    160223    '89 3C 53 80 30 3C 8B 06' => 'AF-S DX Zoom-Nikkor 55-200mm f/4-5.6G ED',
    161224    '8A 54 6A 6A 24 24 8C 0E' => 'AF-S VR Micro-Nikkor 105mm f/2.8G IF-ED', #10
    162     '8B 40 2D 80 2C 3C FD 0E' => 'AF-S DX VR Zoom-Nikkor 18-200mm f/3.5-5.6G IF-ED', #21
    163225    '8B 40 2D 80 2C 3C 8D 0E' => 'AF-S DX VR Zoom-Nikkor 18-200mm f/3.5-5.6G IF-ED',
     226    '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
    164227    '8C 40 2D 53 2C 3C 8E 06' => 'AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED',
    165228    '8D 44 5C 8E 34 3C 8F 0E' => 'AF-S VR Zoom-Nikkor 70-300mm f/4.5-5.6G IF-ED', #10
    166229    '8F 40 2D 72 2C 3C 91 06' => 'AF-S DX Zoom-Nikkor 18-135mm f/3.5-5.6G IF-ED',
    167230    '90 3B 53 80 30 3C 92 0E' => 'AF-S DX VR Zoom-Nikkor 55-200mm f/4-5.6G IF-ED',
    168     '93 48 37 5C 24 24 95 06' => 'AF-S Nikkor 24-70 f/2.8G ED',
     231    '92 48 24 37 24 24 94 06' => 'AF-S Zoom-Nikkor 14-24mm f/2.8G ED',
     232    '93 48 37 5C 24 24 95 06' => 'AF-S Zoom-Nikkor 24-70mm f/2.8G ED',
    169233    '94 40 2D 53 2C 3C 96 06' => 'AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED II', #10 (D40)
    170     '96 48 98 98 24 24 98 0E' => 'AF-S Nikkor 400mm f/2.8G ED VR',
    171     '98 3C A6 A6 30 30 9A 0E' => 'AF-S Nikkor 600mm f/4G ED VR',
    172 #
    173     '06 3F 68 68 2C 2C 06 00' => 'Cosina 100mm f/3.5 Macro',
    174 #
     234    '95 4C 37 37 2C 2C 97 02' => 'PC-E Nikkor 24mm f/3.5D ED',
     235    '95 00 37 37 2C 2C 97 06' => 'PC-E Nikkor 24mm f/3.5D ED', #JD
     236    '96 48 98 98 24 24 98 0E' => 'AF-S VR Nikkor 400mm f/2.8G ED',
     237    '97 3C A0 A0 30 30 99 0E' => 'AF-S VR Nikkor 500mm f/4G ED',
     238    '98 3C A6 A6 30 30 9A 0E' => 'AF-S VR Nikkor 600mm f/4G ED',
     239    '99 40 29 62 2C 3C 9B 0E' => 'AF-S DX VR Zoom-Nikkor 16-85mm f/3.5-5.6G ED',
     240    '9A 40 2D 53 2C 3C 9C 0E' => 'AF-S DX VR Zoom-Nikkor 18-55mm f/3.5-5.6G',
     241    '9B 54 4C 4C 24 24 9D 02' => 'PC-E Micro Nikkor 45mm f/2.8D ED',
     242    '9B 00 4C 4C 24 24 9D 06' => 'PC-E Micro Nikkor 45mm f/2.8D ED',
     243    '9C 54 56 56 24 24 9E 06' => 'AF-S Micro Nikkor 60mm f/2.8G ED',
     244    '9D 54 62 62 24 24 9F 02' => 'PC-E Micro Nikkor 85mm f/2.8D',
     245    '9D 00 62 62 24 24 9F 06' => 'PC-E Micro Nikkor 85mm f/2.8D',
     246    '9E 40 2D 6A 2C 3C A0 0E' => 'AF-S DX VR Zoom-Nikkor 18-105mm f/3.5-5.6G ED', #PH/10
     247    '9F 58 44 44 14 14 A1 06' => 'AF-S DX Nikkor 35mm f/1.8G', #27
     248    'A0 54 50 50 0C 0C A2 06' => 'AF-S Nikkor 50mm f/1.4G',
     249    'A1 40 18 37 2C 34 A3 06' => 'AF-S DX Nikkor 10-24mm f/3.5-4.5G ED',
     250    'A2 48 5C 80 24 24 A4 0E' => 'AF-S Nikkor 70-200mm f/2.8G ED VR II',
     251    'A3 3C 29 44 30 30 A5 0E' => 'AF-S Nikkor 16-35mm f/4G ED VR',
     252    'A4 54 37 37 0C 0C A6 06' => 'AF-S Nikkor 24mm f/1.4G ED',
     253    'A5 40 3C 8E 2C 3C A7 0E' => 'AF-S Nikkor 28-300mm f/3.5-5.6G ED VR',
     254    'A6 48 8E 8E 24 24 A8 0E' => 'AF-S VR Nikkor 300mm f/2.8G IF-ED II',
     255    'A7 4B 62 62 2C 2C A9 0E' => 'AF-S DX Micro Nikkor 85mm f/3.5G ED VR',
     256    'A9 54 80 80 18 18 AB 0E' => 'AF-S Nikkor 200mm f/2G ED VR II',
     257    'AA 3C 37 6E 30 30 AC 0E' => 'AF-S Nikkor 24-120mm f/4G ED VR',
     258    'AC 38 53 8E 34 3C AE 0E' => 'AF-S DX VR Nikkor 55-300mm 4.5-5.6G ED',
     259    'AE 54 62 62 0C 0C B0 06' => 'AF-S Nikkor 85mm f/1.4G',
     260    'AF 54 44 44 0C 0C B1 06' => 'AF-S Nikkor 35mm f/1.4G',
     261    'B0 4C 50 50 14 14 B2 06' => 'AF-S Nikkor 50mm f/1.8G',
     262    '01 00 00 00 00 00 02 00' => 'TC-16A',
     263    '01 00 00 00 00 00 08 00' => 'TC-16A',
     264    '00 00 00 00 00 00 F1 0C' => 'TC-14E [II] or Sigma APO Tele Converter 1.4x EX DG or Kenko Teleplus PRO 300 DG 1.4x',
     265    '00 00 00 00 00 00 F2 18' => 'TC-20E [II] or Sigma APO Tele Converter 2x EX DG or Kenko Teleplus PRO 300 DG 2.0x',
     266    '00 00 00 00 00 00 E1 12' => 'TC-17E II',
     267    'FE 47 00 00 24 24 4B 06' => 'Sigma 4.5mm F2.8 EX DC HSM Circular Fisheye', #JD
    175268    '26 48 11 11 30 30 1C 02' => 'Sigma 8mm F4 EX Circular Fisheye',
    176     '79 40 11 11 2C 2C 1C 06' => 'Sigma 8mm F3.5 EX', #19
     269    '79 40 11 11 2C 2C 1C 06' => 'Sigma 8mm F3.5 EX Circular Fisheye', #JD
     270    'DC 48 19 19 24 24 4B 06' => 'Sigma 10mm F2.8 EX DC HSM Fisheye',
     271    '02 3F 24 24 2C 2C 02 00' => 'Sigma 14mm F3.5',
     272    '48 48 24 24 24 24 4B 02' => 'Sigma 14mm F2.8 EX Aspherical HSM',
     273    '26 48 27 27 24 24 1C 02' => 'Sigma 15mm F2.8 EX Diagonal Fisheye',
     274    '26 58 31 31 14 14 1C 02' => 'Sigma 20mm F1.8 EX DG Aspherical RF',
     275    '26 58 37 37 14 14 1C 02' => 'Sigma 24mm F1.8 EX DG Aspherical Macro',
     276    'E1 58 37 37 14 14 1C 02' => 'Sigma 24mm F1.8 EX DG Aspherical Macro',
     277    '02 46 37 37 25 25 02 00' => 'Sigma 24mm F2.8 Super Wide II Macro',
     278    '26 58 3C 3C 14 14 1C 02' => 'Sigma 28mm F1.8 EX DG Aspherical Macro',
     279    '48 54 3E 3E 0C 0C 4B 06' => 'Sigma 30mm F1.4 EX DC HSM',
     280    'F8 54 3E 3E 0C 0C 4B 06' => 'Sigma 30mm F1.4 EX DC HSM', #JD
     281    'DE 54 50 50 0C 0C 4B 06' => 'Sigma 50mm F1.4 EX DG HSM',
     282    '32 54 50 50 24 24 35 02' => 'Sigma Macro 50mm F2.8 EX DG',
     283    '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
     284    '79 48 5C 5C 24 24 1C 06' => 'Sigma Macro 70mm F2.8 EX DG', #JD
     285    '9B 54 62 62 0C 0C 4B 06' => 'Sigma 85mm F1.4 EX DG HSM',
     286    '02 48 65 65 24 24 02 00' => 'Sigma 90mm F2.8 Macro',
     287    '32 54 6A 6A 24 24 35 02.2' => 'Sigma Macro 105mm F2.8 EX DG', #JD
     288    'E5 54 6A 6A 24 24 35 02' => 'Sigma Macro 105mm F2.8 EX DG',
     289    '48 48 76 76 24 24 4B 06' => 'Sigma 150mm F2.8 EX DG APO Macro HSM',
     290    'F5 48 76 76 24 24 4B 06' => 'Sigma 150mm F2.8 EX DG APO Macro HSM', #24
     291    '48 4C 7C 7C 2C 2C 4B 02' => 'Sigma 180mm F3.5 EX DG Macro',
     292    '48 4C 7D 7D 2C 2C 4B 02' => 'Sigma APO Macro 180mm F3.5 EX DG HSM',
     293    '48 54 8E 8E 24 24 4B 02' => 'Sigma APO 300mm F2.8 EX DG HSM',
     294    'FB 54 8E 8E 24 24 4B 02' => 'Sigma APO 300mm F2.8 EX DG HSM', #26
     295    '26 48 8E 8E 30 30 1C 02' => 'Sigma APO Tele Macro 300mm F4',
     296    '02 2F 98 98 3D 3D 02 00' => 'Sigma APO 400mm F5.6',
     297    '26 3C 98 98 3C 3C 1C 02' => 'Sigma APO Tele Macro 400mm F5.6',
     298    '02 37 A0 A0 34 34 02 00' => 'Sigma APO 500mm F4.5', #19
     299    '48 44 A0 A0 34 34 4B 02' => 'Sigma APO 500mm F4.5 EX HSM',
     300    'F1 44 A0 A0 34 34 4B 02' => 'Sigma APO 500mm F4.5 EX DG HSM',
     301    '02 34 A0 A0 44 44 02 00' => 'Sigma APO 500mm F7.2',
     302    '02 3C B0 B0 3C 3C 02 00' => 'Sigma APO 800mm F5.6',
     303    '48 3C B0 B0 3C 3C 4B 02' => 'Sigma APO 800mm F5.6 EX HSM',
     304    '9E 38 11 29 34 3C 4B 06' => 'Sigma 8-16mm F4.5-5.6 DC HSM',
     305    'A1 41 19 31 2C 2C 4B 06' => 'Sigma 10-20mm F3.5 EX DC HSM',
    177306    '48 3C 19 31 30 3C 4B 06' => 'Sigma 10-20mm F4-5.6 EX DC HSM',
    178     '48 38 1F 37 34 3C 4B 06' => 'Sigma 12-24mm F4.5-5.6 EX Aspherical DG HSM',
    179     '02 3F 24 24 2C 2C 02 00' => 'Sigma 14mm F3.5',
    180     '48 48 24 24 24 24 4B 02' => 'Sigma 14mm F2.8 EX ASPHERICAL HSM',
    181     '26 48 27 27 24 24 1C 02' => 'Sigma 15mm F2.8 EX Diagonal Fish-Eye',
    182     '26 40 27 3F 2C 34 1C 02' => 'Sigma 15-30mm F3.5-4.5 EX Aspherical DG DF',
     307    'F9 3C 19 31 30 3C 4B 06' => 'Sigma 10-20mm F4-5.6 EX DC HSM', #JD
     308    '48 38 1F 37 34 3C 4B 06' => 'Sigma 12-24mm F4.5-5.6 EX DG Aspherical HSM',
     309    'F0 38 1F 37 34 3C 4B 06' => 'Sigma 12-24mm F4.5-5.6 EX DG Aspherical HSM',
     310    '26 40 27 3F 2C 34 1C 02' => 'Sigma 15-30mm F3.5-4.5 EX DG Aspherical DF',
    183311    '48 48 2B 44 24 30 4B 06' => 'Sigma 17-35mm F2.8-4 EX DG  Aspherical HSM',
    184     '26 54 2B 44 24 30 1C 02' => 'Sigma 17-35mm F2.8-4 EX ASPHERICAL',
    185     '7F 48 2B 5C 24 34 1C 06' => 'Sigma 17-70mm F2.8-4.5 DC MACRO Asp. IF',
     312    '26 54 2B 44 24 30 1C 02' => 'Sigma 17-35mm F2.8-4 EX Aspherical',
     313    '7A 47 2B 5C 24 34 4B 06' => 'Sigma 17-70mm F2.8-4.5 DC Macro Asp. IF HSM',
     314    '7A 48 2B 5C 24 34 4B 06' => 'Sigma 17-70mm F2.8-4.5 DC Macro Asp. IF HSM',
     315    '7F 48 2B 5C 24 34 1C 06' => 'Sigma 17-70mm F2.8-4.5 DC Macro Asp. IF',
     316    '26 40 2D 44 2B 34 1C 02' => 'Sigma 18-35 F3.5-4.5 Aspherical',
    186317    '26 48 2D 50 24 24 1C 06' => 'Sigma 18-50mm F2.8 EX DC',
     318    '7F 48 2D 50 24 24 1C 06' => 'Sigma 18-50mm F2.8 EX DC Macro', #25
     319    '7A 48 2D 50 24 24 4B 06' => 'Sigma 18-50mm F2.8 EX DC Macro',
     320    'F6 48 2D 50 24 24 4B 06' => 'Sigma 18-50mm F2.8 EX DC Macro',
     321    'A4 47 2D 50 24 34 4B 0E' => 'Sigma 18-50mm F2.8-4.5 DC OS HSM',
    187322    '26 40 2D 50 2C 3C 1C 06' => 'Sigma 18-50mm F3.5-5.6 DC',
    188323    '7A 40 2D 50 2C 3C 4B 06' => 'Sigma 18-50mm F3.5-5.6 DC HSM',
    189324    '26 40 2D 70 2B 3C 1C 06' => 'Sigma 18-125mm F3.5-5.6 DC',
     325    'CD 3D 2D 70 2E 3C 4B 0E' => 'Sigma 18-125mm F3.8-5.6 DC OS HSM',
    190326    '26 40 2D 80 2C 40 1C 06' => 'Sigma 18-200mm F3.5-6.3 DC',
    191     '26 58 31 31 14 14 1C 02' => 'Sigma 20mm F1.8 EX Aspherical DG DF RF',
    192     '26 58 37 37 14 14 1C 02' => 'Sigma 24mm F1.8 EX Aspherical DG DF MACRO',
    193     '02 46 37 37 25 25 02 00' => 'Sigma 24mm F2.8 Macro',
     327    '7A 40 2D 80 2C 40 4B 0E' => 'Sigma 18-200mm F3.5-6.3 DC OS HSM',
     328    'ED 40 2D 80 2C 40 4B 0E' => 'Sigma 18-200mm F3.5-6.3 DC OS HSM', #JD
     329    'A5 40 2D 88 2C 40 4B 0E' => 'Sigma 18-250mm F3.5-6.3 DC OS HSM',
     330    '26 48 31 49 24 24 1C 02' => 'Sigma 20-40mm F2.8',
    194331    '26 48 37 56 24 24 1C 02' => 'Sigma 24-60mm F2.8 EX DG',
     332    'B6 48 37 56 24 24 1C 02' => 'Sigma 24-60mm F2.8 EX DG',
     333    'A6 48 37 5C 24 24 4B 06' => 'Sigma 24-70mm F2.8 IF EX DG HSM', #JD
    195334    '26 54 37 5C 24 24 1C 02' => 'Sigma 24-70mm F2.8 EX DG Macro',
    196335    '67 54 37 5C 24 24 1C 02' => 'Sigma 24-70mm F2.8 EX DG Macro',
    197     '26 40 37 5C 2C 3C 1C 02' => 'Sigma 24-70mm F3.5-5.6 ASPHERICAL HF',
     336    'E9 54 37 5C 24 24 1C 02' => 'Sigma 24-70mm F2.8 EX DG Macro',
     337    '26 40 37 5C 2C 3C 1C 02' => 'Sigma 24-70mm F3.5-5.6 Aspherical HF',
    198338    '26 54 37 73 24 34 1C 02' => 'Sigma 24-135mm F2.8-4.5',
    199     '26 58 3C 3C 14 14 1C 02' => 'Sigma 28mm F1.8 EX DG DF',
     339    '02 46 3C 5C 25 25 02 00' => 'Sigma 28-70mm F2.8',
     340    '26 54 3C 5C 24 24 1C 02' => 'Sigma 28-70mm F2.8 EX',
    200341    '26 48 3C 5C 24 24 1C 06' => 'Sigma 28-70mm F2.8 EX DG',
    201     '26 48 3C 5C 24 30 1C 02' => 'Sigma 28-70mm F2.8-4 HIGH SPEED ZOOM',
    202     '02 46 3C 5C 25 25 02 00' => 'Sigma 28-70mm F2.8',
     342    '26 48 3C 5C 24 30 1C 02' => 'Sigma 28-70mm F2.8-4 DG',
    203343    '02 3F 3C 5C 2D 35 02 00' => 'Sigma 28-70mm F3.5-4.5 UC',
    204344    '26 40 3C 60 2C 3C 1C 02' => 'Sigma 28-80mm F3.5-5.6 Mini Zoom Macro II Aspherical',
    205     '26 3E 3C 6A 2E 3C 1C 02' => 'Sigma 28-105mm F3.8-5.6 UC-III ASPHERICAL IF',
     345    '26 40 3C 65 2C 3C 1C 02' => 'Sigma 28-90mm F3.5-5.6 Macro',
     346    '26 48 3C 6A 24 30 1C 02' => 'Sigma 28-105mm F2.8-4 Aspherical',
     347    '26 3E 3C 6A 2E 3C 1C 02' => 'Sigma 28-105mm F3.8-5.6 UC-III Aspherical IF',
    206348    '26 40 3C 80 2C 3C 1C 02' => 'Sigma 28-200mm F3.5-5.6 Compact Aspherical Hyperzoom Macro',
    207349    '26 40 3C 80 2B 3C 1C 02' => 'Sigma 28-200mm F3.5-5.6 Compact Aspherical Hyperzoom Macro',
    208     '26 41 3C 8E 2C 40 1C 02' => 'Sigma 28-300mm F3.5-6.3 DG MACRO',
     350    '26 3D 3C 80 2F 3D 1C 02' => 'Sigma 28-300mm F3.8-5.6 Aspherical',
     351    '26 41 3C 8E 2C 40 1C 02' => 'Sigma 28-300mm F3.5-6.3 DG Macro',
     352    '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
    209353    '26 40 3C 8E 2C 40 1C 02' => 'Sigma 28-300mm F3.5-6.3 Macro',
    210     '48 54 3E 3E 0C 0C 4B 06' => 'Sigma 30mm F1.4 EX DC HSM',
     354    '02 3B 44 61 30 3D 02 00' => 'Sigma 35-80mm F4-5.6',
    211355    '02 40 44 73 2B 36 02 00' => 'Sigma 35-135mm F3.5-4.5 a',
    212     '32 54 50 50 24 24 35 02' => 'Sigma 50mm F2.8 EX DG Macro',
    213     '7A 47 50 76 24 24 4B 06' => 'Sigma APO 50-150mm F2.8 EX DC HSM',
     356    '7A 47 50 76 24 24 4B 06' => 'Sigma 50-150mm F2.8 EX APO DC HSM',
     357    'FD 47 50 76 24 24 4B 06' => 'Sigma 50-150mm F2.8 EX APO DC HSM II',
    214358    '48 3C 50 A0 30 40 4B 02' => 'Sigma 50-500mm F4-6.3 EX APO RF HSM',
     359    '9F 37 50 A0 34 40 4B 0E' => 'Sigma 50-500mm F4.5-6.3 DG OS HSM', #16
    215360    '26 3C 54 80 30 3C 1C 06' => 'Sigma 55-200mm F4-5.6 DC',
    216361    '7A 3B 53 80 30 3C 4B 06' => 'Sigma 55-200mm F4-5.6 DC HSM',
    217     '79 48 5C 5C 24 24 1C 06' => 'Sigma 70mm F2.8 EX DG Macro', #19
    218362    '48 54 5C 80 24 24 4B 02' => 'Sigma 70-200mm F2.8 EX APO IF HSM',
    219     '02 46 5C 82 25 25 02 00' => 'Sigma 70-210mm F2.8 APO', #19
     363    '7A 48 5C 80 24 24 4B 06' => 'Sigma 70-200mm F2.8 EX APO DG Macro HSM II',
     364    'EE 48 5C 80 24 24 4B 06' => 'Sigma 70-200mm F2.8 EX APO DG Macro HSM II', #JD
     365    '9C 48 5C 80 24 24 4B 0E' => 'Sigma 70-200mm F2.8 EX DG OS HSM', #Rolando Ruzic
     366    '02 46 5C 82 25 25 02 00' => 'Sigma 70-210mm F2.8 APO', #JD
    220367    '26 3C 5C 82 30 3C 1C 02' => 'Sigma 70-210mm F4-5.6 UC-II',
    221     '26 3C 5C 8E 30 3C 1C 02' => 'Sigma 70-300mm F4-5.6 DG MACRO',
     368    '26 3C 5C 8E 30 3C 1C 02' => 'Sigma 70-300mm F4-5.6 DG Macro',
    222369    '56 3C 5C 8E 30 3C 1C 02' => 'Sigma 70-300mm F4-5.6 APO Macro Super II',
     370    'E0 3C 5C 8E 30 3C 4B 06' => 'Sigma 70-300mm F4-5.6 APO DG Macro HSM', #22
     371    'A3 3C 5C 8E 30 3C 4B 0E' => 'Sigma 70-300mm F4-5.6 DG OS',
    223372    '02 37 5E 8E 35 3D 02 00' => 'Sigma 75-300mm F4.5-5.6 APO',
    224     '02 48 65 65 24 24 02 00' => 'Sigma 90mm F2.8 Macro',
    225     '77 44 61 98 34 3C 7B 0E' => 'Sigma 80-400mm f4.5-5.6 EX OS',
     373    '02 3A 5E 8E 32 3D 02 00' => 'Sigma 75-300mm F4.0-5.6',
     374    '77 44 61 98 34 3C 7B 0E' => 'Sigma 80-400mm F4.5-5.6 EX OS',
    226375    '48 48 68 8E 30 30 4B 02' => 'Sigma 100-300mm F4 EX IF HSM',
     376    'F3 48 68 8E 30 30 4B 02' => 'Sigma APO 100-300mm F4 EX IF HSM',
    227377    '48 54 6F 8E 24 24 4B 02' => 'Sigma APO 120-300mm F2.8 EX DG HSM',
     378    '7A 54 6E 8E 24 24 4B 02' => 'Sigma APO 120-300mm F2.8 EX DG HSM',
     379    '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
     380    'CF 38 6E 98 34 3C 4B 0E' => 'Sigma APO 120-400mm F4.5-5.6 DG OS HSM',
    228381    '26 44 73 98 34 3C 1C 02' => 'Sigma 135-400mm F4.5-5.6 APO Aspherical',
    229     '48 48 76 76 24 24 4B 06' => 'Sigma 150mm F2.8 EX DG APO Macro HSM',
    230     '48 4C 7C 7C 2C 2C 4B 02' => 'Sigma 180mm F3.5 EX DG Macro', #19
    231     '26 40 7B A0 34 40 1C 02' => 'Sigma APO 170-500mm F5-6.3 ASPHERICAL RF',
    232     '48 4C 7D 7D 2C 2C 4B 02' => 'Sigma APO MACRO 180mm F3.5 EX DG HSM',
    233     '48 54 8E 8E 24 24 4B 02' => 'Sigma APO 300mm F2.8 EX DG HSM',
    234     '26 48 8E 8E 30 30 1C 02' => 'Sigma APO TELE MACRO 300mm F4',
    235     '48 3C 8E B0 3C 3C 4B 02' => 'Sigma APO 300-800 F5.6 EX DG HSM',
    236     '02 2F 98 98 3D 3D 02 00' => 'Sigma 400mm F5.6 APO',
    237     '02 37 A0 A0 34 34 02 00' => 'Sigma APO 500mm F4.5', #20
     382    'CE 34 76 A0 38 40 4B 0E' => 'Sigma 150-500mm F5-6.3 DG OS APO HSM', #JD
     383    '26 40 7B A0 34 40 1C 02' => 'Sigma APO 170-500mm F5-6.3 Aspherical RF',
     384    'A7 49 80 A0 24 24 4B 06' => 'Sigma APO 200-500mm F2.8 EX DG',
     385    '48 3C 8E B0 3C 3C 4B 02' => 'Sigma APO 300-800mm F5.6 EX DG HSM',
    238386#
    239     '03 43 5C 81 35 35 02 00' => 'Soligor AF C/D ZOOM UMCS 70-210mm 1:4.5',
     387    '00 47 25 25 24 24 00 02' => 'Tamron SP AF 14mm f/2.8 Aspherical (IF) (69E)',
     388    'F4 54 56 56 18 18 84 06' => 'Tamron SP AF 60mm f/2.0 Di II Macro 1:1 (G005)', #24
     389    '1E 5D 64 64 20 20 13 00' => 'Tamron SP AF 90mm f/2.5 (52E)',
     390    '20 5A 64 64 20 20 14 00' => 'Tamron SP AF 90mm f/2.5 Macro (152E)',
     391    '22 53 64 64 24 24 E0 02' => 'Tamron SP AF 90mm f/2.8 Macro 1:1 (72E)',
     392    '32 53 64 64 24 24 35 02' => 'Tamron SP AF 90mm f/2.8 [Di] Macro 1:1 (172E/272E)',
     393    'F8 55 64 64 24 24 84 06' => 'Tamron SP AF 90mm f/2.8 Di Macro 1:1 (272NII)',
     394    'F8 54 64 64 24 24 DF 06' => 'Tamron SP AF 90mm f/2.8 Di Macro 1:1 (272NII)',
     395    '00 4C 7C 7C 2C 2C 00 02' => 'Tamron SP AF 180mm f/3.5 Di Model (B01)',
     396    '21 56 8E 8E 24 24 14 00' => 'Tamron SP AF 300mm f/2.8 LD-IF (60E)',
     397    '27 54 8E 8E 24 24 1D 02' => 'Tamron SP AF 300mm f/2.8 LD-IF (360E)',
     398    'F6 3F 18 37 2C 34 84 06' => 'Tamron SP AF 10-24mm f/3.5-4.5 Di II LD Aspherical (IF) (B001)',
     399    '00 36 1C 2D 34 3C 00 06' => 'Tamron SP AF 11-18mm f/4.5-5.6 Di II LD Aspherical (IF) (A13)',
     400    '07 46 2B 44 24 30 03 02' => 'Tamron SP AF 17-35mm f/2.8-4 Di LD Aspherical (IF) (A05)',
     401    '00 53 2B 50 24 24 00 06' => 'Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16)', #PH
     402    '00 54 2B 50 24 24 00 06' => 'Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16NII)',
     403    'F3 54 2B 50 24 24 84 0E' => 'Tamron SP AF 17-50mm f/2.8 XR Di II VC LD Aspherical (IF) (B005)',
     404    '00 3F 2D 80 2B 40 00 06' => 'Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) (A14)',
     405    '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)',
     406    '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
     407    '00 40 2D 88 2C 40 62 06' => 'Tamron AF 18-250mm f/3.5-6.3 Di II LD Aspherical (IF) Macro (A18)',
     408    '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
     409    '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)',
     410    '07 40 2F 44 2C 34 03 02' => 'Tamron AF 19-35mm f/3.5-4.5 (A10)',
     411    '07 40 30 45 2D 35 03 02' => 'Tamron AF 19-35mm f/3.5-4.5 (A10)',
     412    '00 49 30 48 22 2B 00 02' => 'Tamron SP AF 20-40mm f/2.7-3.5 (166D)',
     413    '0E 4A 31 48 23 2D 0E 02' => 'Tamron SP AF 20-40mm f/2.7-3.5 (166D)',
     414    '45 41 37 72 2C 3C 48 02' => 'Tamron SP AF 24-135mm f/3.5-5.6 AD Aspherical (IF) Macro (190D)',
     415    '33 54 3C 5E 24 24 62 02' => 'Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical (IF) Macro (A09)',
     416    'FA 54 3C 5E 24 24 84 06' => 'Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical (IF) Macro (A09NII)', #JD
     417    '10 3D 3C 60 2C 3C D2 02' => 'Tamron AF 28-80mm f/3.5-5.6 Aspherical (177D)',
     418    '45 3D 3C 60 2C 3C 48 02' => 'Tamron AF 28-80mm f/3.5-5.6 Aspherical (177D)',
     419    '00 48 3C 6A 24 24 00 02' => 'Tamron SP AF 28-105mm f/2.8 LD Aspherical IF (176D)',
     420    '0B 3E 3D 7F 2F 3D 0E 00' => 'Tamron AF 28-200mm f/3.8-5.6 (71D)',
     421    '0B 3E 3D 7F 2F 3D 0E 02' => 'Tamron AF 28-200mm f/3.8-5.6D (171D)',
     422    '12 3D 3C 80 2E 3C DF 02' => 'Tamron AF 28-200mm f/3.8-5.6 AF Aspherical LD (IF) (271D)',
     423    '4D 41 3C 8E 2B 40 62 02' => 'Tamron AF 28-300mm f/3.5-6.3 XR Di LD Aspherical (IF) (A061)',
     424    '4D 41 3C 8E 2C 40 62 02' => 'Tamron AF 28-300mm f/3.5-6.3 XR LD Aspherical (IF) (185D)',
     425    '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)',
     426    '00 47 53 80 30 3C 00 06' => 'Tamron AF 55-200mm f/4-5.6 Di II LD (A15)',
     427    'F7 53 5C 80 24 24 84 06' => 'Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)',
     428    'FE 53 5C 80 24 24 84 06' => 'Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)',
     429    '69 48 5C 8E 30 3C 6F 02' => 'Tamron AF 70-300mm f/4-5.6 LD Macro 1:2 (772D)',
     430    '69 47 5C 8E 30 3C 00 02' => 'Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2 (A17N)',
     431    '00 48 5C 8E 30 3C 00 06' => 'Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2 (A17)', #JD
     432    'F1 47 5C 8E 30 3C DF 0E' => 'Tamron SP 70-300mm f/4-5.6 Di VC USD (A005)',
     433    '20 3C 80 98 3D 3D 1E 02' => 'Tamron AF 200-400mm f/5.6 LD IF (75D)',
     434    '00 3E 80 A0 38 3F 00 02' => 'Tamron SP AF 200-500mm f/5-6.3 Di LD (IF) (A08)',
     435    '00 3F 80 A0 38 3F 00 02' => 'Tamron SP AF 200-500mm f/5-6.3 Di (A08)',
    240436#
    241     '00 40 18 2B 2C 34 00 06' => 'Tokina AT-X 107 DX Fish-Eye - AF 10-17mm F3.5-4.5',
    242     '00 3C 1F 37 30 30 00 06' => 'Tokina AT-X 124 AF PRO DX - AF 12-24mm F4',
    243     '00 48 29 50 24 24 00 06' => 'Tokina AT-X 165 PRO DX - AF 16-50mm F2.8',
    244     '00 40 2B 2B 2C 2C 00 02' => 'Tokina AT-X 17 AF PRO - AF 17mm F3.5',
    245     '25 48 3C 5C 24 24 1B 02' => 'Tokina AT-X 287 AF PRO SV 28-70mm F2.8',
    246     '00 48 3C 60 24 24 00 02' => 'Tokina AT-X 280 AF PRO 28-80mm F2.8 ASPHERICAL',
    247     '00 48 50 72 24 24 00 06' => 'Tokina AT-X 535 PRO DX - AF 50-135mm F2.8',
    248     '14 54 60 80 24 24 0B 00' => 'Tokina AT-X 828 AF 80-200mm F2.8',
    249     '24 44 60 98 34 3C 1A 02' => 'Tokina AT-X 840 AF II 80-400mm F4.5-5.6',
    250     '00 44 60 98 34 3C 00 02' => 'Tokina AT-X 840D 80-400mm F4.5-5.6', #PH
    251     '00 54 68 68 24 24 00 02' => 'Tokina AT-X M100 PRO D - 100mm F2.8',
    252     '14 48 68 8E 30 30 0B 00' => 'Tokina AT-X 340 AF II 100-300mm F4',
    253     '00 54 8E 8E 24 24 00 02' => 'Tokina AT-X 300 AF PRO 300mm F2.8',
     437    '00 40 2B 2B 2C 2C 00 02' => 'Tokina AT-X 17 AF PRO (AF 17mm f/3.5)',
     438    '00 47 44 44 24 24 00 06' => 'Tokina AT-X M35 PRO DX (AF 35mm f/2.8 Macro)',
     439    '00 54 68 68 24 24 00 02' => 'Tokina AT-X M100 PRO D (AF 100mm f/2.8 Macro)',
     440    '27 48 8E 8E 30 30 1D 02' => 'Tokina AT-X 304 AF (AF 300mm f/4.0)',
     441    '00 54 8E 8E 24 24 00 02' => 'Tokina AT-X 300 AF PRO (AF 300mm f/2.8)',
     442    '12 3B 98 98 3D 3D 09 00' => 'Tokina AT-X 400 AF SD (AF 400mm f/5.6)',
     443    '00 40 18 2B 2C 34 00 06' => 'Tokina AT-X 107 DX Fisheye (AF 10-17mm f/3.5-4.5)',
     444    '00 48 1C 29 24 24 00 06' => 'Tokina AT-X 116 PRO DX (AF 11-16mm f/2.8)',
     445    '00 3C 1F 37 30 30 00 06' => 'Tokina AT-X 124 AF PRO DX (AF 12-24mm f/4)',
     446    '7A 3C 1F 37 30 30 7E 06.2' => 'Tokina AT-X 124 AF PRO DX II (AF 12-24mm f/4)',
     447    '00 48 29 3C 24 24 00 06' => 'Tokina AT-X 16-28 AF PRO FX (AF 16-28mm f/2.8)',
     448    '00 48 29 50 24 24 00 06' => 'Tokina AT-X 165 PRO DX (AF 16-50mm f/2.8)',
     449    '00 40 2A 72 2C 3C 00 06' => 'Tokina AT-X 16.5-135 DX (AF 16.5-135mm F3.5-5.6)',
     450    '2F 40 30 44 2C 34 29 02.2' => 'Tokina AF 193 (AF 19-35mm f/3.5-4.5)',
     451    '2F 48 30 44 24 24 29 02.2' => 'Tokina AT-X 235 AF PRO (AF 20-35mm f/2.8)',
     452    '2F 40 30 44 2C 34 29 02.1' => 'Tokina AF 235 II (AF 20-35mm f/3.5-4.5)',
     453    '00 40 37 80 2C 3C 00 02' => 'Tokina AT-X 242 AF (AF 24-200mm f/3.5-5.6)',
     454    '25 48 3C 5C 24 24 1B 02.1' => 'Tokina AT-X 270 AF PRO II (AF 28-70mm f/2.6-2.8)',
     455    '25 48 3C 5C 24 24 1B 02.2' => 'Tokina AT-X 287 AF PRO SV (AF 28-70mm f/2.8)',
     456    '07 48 3C 5C 24 24 03 00' => 'Tokina AT-X 287 AF (AF 28-70mm f/2.8)',
     457    '07 47 3C 5C 25 35 03 00' => 'Tokina AF 287 SD (AF 28-70mm f/2.8-4.5)',
     458    '07 40 3C 5C 2C 35 03 00' => 'Tokina AF 270 II (AF 28-70mm f/3.5-4.5)',
     459    '00 48 3C 60 24 24 00 02' => 'Tokina AT-X 280 AF PRO (AF 28-80mm f/2.8)',
     460    '25 44 44 8E 34 42 1B 02' => 'Tokina AF 353 (AF 35-300mm f/4.5-6.7)',
     461    '00 48 50 72 24 24 00 06' => 'Tokina AT-X 535 PRO DX (AF 50-135mm f/2.8)',
     462    '12 44 5E 8E 34 3C 09 00' => 'Tokina AF 730 (AF 75-300mm F4.5-5.6)',
     463    '14 54 60 80 24 24 0B 00' => 'Tokina AT-X 828 AF (AF 80-200mm f/2.8)',
     464    '24 54 60 80 24 24 1A 02' => 'Tokina AT-X 828 AF PRO (AF 80-200mm f/2.8)',
     465    '24 44 60 98 34 3C 1A 02' => 'Tokina AT-X 840 AF-II (AF 80-400mm f/4.5-5.6)',
     466    '00 44 60 98 34 3C 00 02' => 'Tokina AT-X 840 D (AF 80-400mm f/4.5-5.6)',
     467    '14 48 68 8E 30 30 0B 00' => 'Tokina AT-X 340 AF (AF 100-300mm f/4)',
    254468#
    255     '00 36 1C 2D 34 3C 00 06' => 'Tamron SP AF11-18mm f/4.5-5.6 Di II LD Aspherical (IF)',
    256     '07 46 2B 44 24 30 03 02' => 'Tamron SP AF17-35mm f/2.8-4 Di LD Aspherical (IF)',
    257     '00 53 2B 50 24 24 00 06' => 'Tamron SP AF17-50mm f/2.8 (A16)', #PH
    258     '00 3F 2D 80 2B 40 00 06' => 'Tamron AF18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF)',
    259     '00 3F 2D 80 2C 40 00 06' => 'Tamron AF18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro',
    260     '07 40 2F 44 2C 34 03 02' => 'Tamron AF19-35mm f/3.5-4.5 N',
    261     '07 40 30 45 2D 35 03 02' => 'Tamron AF19-35mm f/3.5-4.5',
    262     '00 49 30 48 22 2B 00 02' => 'Tamron SP AF20-40mm f/2.7-3.5',
    263     '0E 4A 31 48 23 2D 0E 02' => 'Tamron SP AF20-40mm f/2.7-3.5',
    264     '45 41 37 72 2C 3C 48 02' => 'Tamron SP AF24-135mm f/3.5-5.6 AD Aspherical (IF) Macro',
    265     '33 54 3C 5E 24 24 62 02' => 'Tamron SP AF28-75mm f/2.8 XR Di LD Aspherical (IF) Macro',
    266     '10 3D 3C 60 2C 3C D2 02' => 'Tamron AF28-80mm f/3.5-5.6 Aspherical',
    267     '45 3D 3C 60 2C 3C 48 02' => 'Tamron AF28-80mm f/3.5-5.6 Aspherical',
    268     '00 48 3C 6A 24 24 00 02' => 'Tamron SP AF28-105mm f/2.8',
    269     '0B 3E 3D 7F 2F 3D 0E 02' => 'Tamron AF28-200mm f/3.8-5.6D',
    270     '0B 3E 3D 7F 2F 3D 0E 00' => 'Tamron AF28-200mm f/3.8-5.6',
    271     '4D 41 3C 8E 2B 40 62 02' => 'Tamron AF28-300mm f/3.5-6.3 XR Di LD Aspherical (IF)',
    272     '4D 41 3C 8E 2C 40 62 02' => 'Tamron AF28-300mm f/3.5-6.3D',
    273     '69 48 5C 8E 30 3C 6F 02' => 'Tamron AF70-300mm f/4-5.6 LD Macro 1:2',
    274     '32 53 64 64 24 24 35 02' => 'Tamron SP AF90mm f/2.8 Di 1:1 Macro',
    275     '00 4C 7C 7C 2C 2C 00 02' => 'Tamron SP AF180mm f/3.5 Di Model B01',
    276     '20 3C 80 98 3D 3D 1E 02' => 'Tamron AF200-400mm f/5.6 LD IF',
    277     '00 3E 80 A0 38 3F 00 02' => 'Tamron SP AF200-500mm f/5-6.3 Di LD (IF)',
    278     '00 3F 80 A0 38 3F 00 02' => 'Tamron SP AF200-500mm f/5-6.3 Di',
     469    '06 3F 68 68 2C 2C 06 00' => 'Cosina AF 100mm F3.5 Macro',
     470    '07 36 3D 5F 2C 3C 03 00' => 'Cosina AF Zoom 28-80mm F3.5-5.6 MC Macro',
     471    '07 46 3D 6A 25 2F 03 00' => 'Cosina AF Zoom 28-105mm F2.8-3.8 MC',
     472    '12 36 5C 81 35 3D 09 00' => 'Cosina AF Zoom 70-210mm F4.5-5.6 MC Macro',
     473    '12 39 5C 8E 34 3D 08 02' => 'Cosina AF Zoom 70-300mm F4.5-5.6 MC Macro',
     474    '12 3B 68 8D 3D 43 09 02' => 'Cosina AF Zoom 100-300mm F5.6-6.7 MC Macro',
     475#
     476    '00 40 31 31 2C 2C 00 00' => 'Voigtlander Color Skopar 20mm F3.5 SLII Aspherical',
     477    '00 54 48 48 18 18 00 00' => 'Voigtlander Ultron 40mm F2 SLII Aspherical',
     478    '00 54 55 55 0C 0C 00 00' => 'Voigtlander Nokton 58mm F1.4 SLII',
     479    '00 40 64 64 2C 2C 00 00' => 'Voigtlander APO-Lanthar 90mm F3.5 SLII Close Focus',
     480#
     481    '00 40 2D 2D 2C 2C 00 00' => 'Carl Zeiss Distagon T* 3,5/18 ZF.2',
     482    '00 48 32 32 24 24 00 00' => 'Carl Zeiss Distagon T* 2,8/21 ZF.2',
     483    '00 54 3C 3C 18 18 00 00' => 'Carl Zeiss Distagon T* 2/28 ZF.2',
     484    '00 54 44 44 18 18 00 00' => 'Carl Zeiss Distagon T* 2/35 ZF.2',
     485    '00 54 50 50 0C 0C 00 00' => 'Carl Zeiss Planar T* 1,4/50 ZF.2',
     486    '00 54 50 50 18 18 00 00' => 'Carl Zeiss Makro-Planar T* 2/50 ZF.2',
     487    '00 54 62 62 0C 0C 00 00' => 'Carl Zeiss Planar T* 1,4/85 ZF.2',
     488    '00 54 68 68 18 18 00 00' => 'Carl Zeiss Makro-Planar T* 2/100 ZF.2',
     489#
     490    '00 54 56 56 30 30 00 00' => 'Coastal Optical Systems 60mm 1:4 UV-VIS-IR Macro Apo',
     491#
     492    '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
     493    '4A 60 44 44 0C 0C 4D 02' => 'Samyang 35mm f/1.4 AS UMC',
     494    '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
     495#
     496    '02 40 44 5C 2C 34 02 00' => 'Exakta AF 35-70mm 1:3.5-4.5 MC',
     497#
     498    '07 3E 30 43 2D 35 03 00' => 'Soligor AF Zoom 19-35mm 1:3.5-4.5 MC',
     499    '03 43 5C 81 35 35 02 00' => 'Soligor AF C/D Zoom UMCS 70-210mm 1:4.5',
     500    '12 4A 5C 81 31 3D 09 00' => 'Soligor AF C/D Auto Zoom+Macro 70-210mm 1:4-5.6 UMCS',
    279501#
    280502    '00 00 00 00 00 00 00 01' => 'Manual Lens No CPU',
    281     '1E 5D 64 64 20 20 13 00' => 'Unknown 90mm f/2.5',
    282     '2F 40 30 44 2C 34 29 02' => 'Unknown 20-35mm f/3.5-4.5D',
    283     '12 3B 68 8D 3D 43 09 02' => 'Unknown 100-290mm f/5.6-6.7',
     503#
     504    '00 47 10 10 24 24 00 00' => 'Fisheye Nikkor 8mm f/2.8 AiS',
     505    '00 54 44 44 0C 0C 00 00' => 'Nikkor 35mm f/1.4 AiS',
     506    '00 48 50 50 18 18 00 00' => 'Nikkor H 50mm f/2',
     507    '00 58 64 64 20 20 00 00' => 'Soligor C/D Macro MC 90mm f/2.5',
     508    '00 48 68 68 24 24 00 00' => 'Series E 100mm f/2.8',
     509    '00 4C 6A 6A 20 20 00 00' => 'Nikkor 105mm f/2.5 AiS',
     510    '00 48 80 80 30 30 00 00' => 'Nikkor 200mm f/4 AiS',
     511);
     512
     513# flash firmware decoding (ref JD)
     514my %flashFirmware = (
     515    '0 0' => 'n/a',
     516    '1 1' => '1.01 (SB-800 or Metz 58 AF-1)',
     517    '1 3' => '1.03 (SB-800)',
     518    '2 1' => '2.01 (SB-800)',
     519    '2 4' => '2.04 (SB-600)',
     520    '2 5' => '2.05 (SB-600)',
     521    '3 1' => '3.01 (SU-800 Remote Commander)',
     522    '4 1' => '4.01 (SB-400)',
     523    '4 2' => '4.02 (SB-400)',
     524    '4 4' => '4.04 (SB-400)',
     525    '5 1' => '5.01 (SB-900)',
     526    '5 2' => '5.02 (SB-900)',
     527    OTHER => sub {
     528        my ($val, $inv) = @_;
     529        return sprintf('%d.%.2d (Unknown model)', split(' ', $val)) unless $inv;
     530        return "$1 $2" if $val =~ /(\d+)\.(\d+)/;
     531        return '0 0';
     532    },
     533);
     534
     535# flash Guide Number (GN) distance settings (ref 28)
     536my %flashGNDistance = (
     537    0 => 0,         19 => '2.8 m',
     538    1 => '0.1 m',   20 => '3.2 m',
     539    2 => '0.2 m',   21 => '3.6 m',
     540    3 => '0.3 m',   22 => '4.0 m',
     541    4 => '0.4 m',   23 => '4.5 m',
     542    5 => '0.5 m',   24 => '5.0 m',
     543    6 => '0.6 m',   25 => '5.6 m',
     544    7 => '0.7 m',   26 => '6.3 m',
     545    8 => '0.8 m',   27 => '7.1 m',
     546    9 => '0.9 m',   28 => '8.0 m',
     547    10 => '1.0 m',  29 => '9.0 m',
     548    11 => '1.1 m',  30 => '10.0 m',
     549    12 => '1.3 m',  31 => '11.0 m',
     550    13 => '1.4 m',  32 => '13.0 m',
     551    14 => '1.6 m',  33 => '14.0 m',
     552    15 => '1.8 m',  34 => '16.0 m',
     553    16 => '2.0 m',  35 => '18.0 m',
     554    17 => '2.2 m',  36 => '20.0 m',
     555    18 => '2.5 m',  255 => 'n/a',
     556);
     557
     558# flash control mode values (ref JD)
     559my %flashControlMode = (
     560    0x00 => 'Off',
     561    0x01 => 'iTTL-BL',
     562    0x02 => 'iTTL',
     563    0x03 => 'Auto Aperture',
     564    0x04 => 'Automatic', #28
     565    0x05 => 'GN (distance priority)', #28 (Guide Number, but called "GN" in manual)
     566    0x06 => 'Manual',
     567    0x07 => 'Repeating Flash',
     568);
     569
     570my %retouchValues = ( #PH
     571    0 => 'None',
     572    3 => 'B & W',
     573    4 => 'Sepia',
     574    5 => 'Trim',
     575    6 => 'Small Picture',
     576    7 => 'D-Lighting',
     577    8 => 'Red Eye',
     578    9 => 'Cyanotype',
     579    10 => 'Sky Light',
     580    11 => 'Warm Tone',
     581    12 => 'Color Custom',
     582    13 => 'Image Overlay',
     583    14 => 'Red Intensifier',
     584    15 => 'Green Intensifier',
     585    16 => 'Blue Intensifier',
     586    17 => 'Cross Screen',
     587    18 => 'Quick Retouch',
     588    19 => 'NEF Processing',
     589    23 => 'Distortion Control',
     590    25 => 'Fisheye',
     591    26 => 'Straighten',
     592    29 => 'Perspective Control',
     593    30 => 'Color Outline',
     594    31 => 'Soft Filter',
     595    33 => 'Miniature Effect',
     596);
     597
     598my %offOn = ( 0 => 'Off', 1 => 'On' );
     599
     600# common attributes for writable BinaryData directories
     601my %binaryDataAttrs = (
     602    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     603    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     604    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     605    WRITABLE => 1,
     606    FIRST_ENTRY => 0,
    284607);
    285608
     
    287610%Image::ExifTool::Nikon::Main = (
    288611    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikon,
    289     WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     612    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikon,
    290613    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
    291614    WRITABLE => 1,
    292615    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    293     PRINT_CONV => 'Image::ExifTool::Nikon::FormatString($val)',
     616    PRINT_CONV => \&FormatString,
    294617    0x0001 => { #2
    295618        # the format differs for different models.  for D70, this is a string '0210',
     
    312635        Priority => 0,  # the EXIF ISO is more reliable
    313636        Groups => { 2 => 'Image' },
     637        # D300 sets this to undef with 4 zero bytes when LO ISO is used - PH
     638        RawConv => '$val eq "\0\0\0\0" ? undef : $val',
    314639        # first number is 1 for "Hi ISO" modes (H0.3, H0.7 and H1.0 on D80) - PH
    315640        PrintConv => '$_=$val;s/^0 //;s/^1 (\d+)/Hi $1/;$_',
    316641        PrintConvInv => '$_=$val;/^\d+/ ? "0 $_" : (s/Hi ?//i ? "1 $_" : $_)',
    317642    },
     643    # Note: we attempt to fix the case of these string values (typically written in all caps)
    318644    0x0003 => { Name => 'ColorMode',    Writable => 'string' },
    319645    0x0004 => { Name => 'Quality',      Writable => 'string' },
     
    321647    0x0006 => { Name => 'Sharpness',    Writable => 'string' },
    322648    0x0007 => { Name => 'FocusMode',    Writable => 'string' },
     649    # FlashSetting (better named FlashSyncMode, ref 28) values:
     650    #   "Normal", "Slow", "Rear Slow", "RED-EYE", "RED-EYE SLOW"
    323651    0x0008 => { Name => 'FlashSetting', Writable => 'string' },
    324     # FlashType shows 'Built-in,TTL' when builtin flash fires,
    325     # and 'Optional,TTL' when external flash is used (ref 2)
    326     0x0009 => { #2
    327         Name => 'FlashType',
    328         Writable => 'string',
    329         Count => 13,
    330     },
    331     0x000b => { Name => 'WhiteBalanceFineTune', Writable => 'int16s' }, #2
    332     0x000c => {
    333         Name => 'ColorBalance1',
     652    # FlashType observed values:
     653    #   internal: "Built-in,TTL", "Built-in,RPT", "Comdr.", "NEW_TTL"
     654    #   external: "Optional,TTL", "Optional,RPT", "Optional,M", "Comdr."
     655    #   both:     "Built-in,TTL&Comdr."
     656    #   no flash: ""
     657    0x0009 => { Name => 'FlashType',    Writable => 'string' }, #2 (count varies by model - PH)
     658    # 0x000a - rational values: 5.6 to 9.283 - found in coolpix models - PH
     659    #          (not correlated with any LV or scale factor)
     660    0x000b => { #2
     661        Name => 'WhiteBalanceFineTune',
     662        Writable => 'int16s',
     663        Count => -1, # older models write 1 value, newer DSLR's write 2 - PH
     664    },
     665    0x000c => { # (D1X)
     666        Name => 'WB_RBLevels',
    334667        Writable => 'rational64u',
    335         Count => 4,
     668        Count => 4, # (not sure what the last 2 values are for)
    336669    },
    337670    0x000d => { #15
     
    344677            $a<-128 or $a>127 ? undef : pack("c4",$a,1,6,0);
    345678        },
    346         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    347         PrintConvInv => 'eval $val',
     679        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     680        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    348681    },
    349682    0x000e => {
     
    366699    },
    367700    0x0011 => {
    368         Name => 'NikonPreview',
    369         Groups => { 1 => 'NikonPreview', 2 => 'Image' },
     701        Name => 'PreviewIFD',
     702        Groups => { 1 => 'PreviewIFD', 2 => 'Image' },
    370703        Flags => 'SubIFD',
    371704        SubDirectory => {
    372             TagTable => 'Image::ExifTool::Nikon::PreviewImage',
     705            TagTable => 'Image::ExifTool::Nikon::PreviewIFD',
    373706            Start => '$val',
    374707        },
    375708    },
    376     0x0012 => { #2
     709    0x0012 => { #2 (camera setting: combination of command dial and menus - PH)
    377710        Name => 'FlashExposureComp',
    378711        Description => 'Flash Exposure Compensation',
    379712        Writable => 'undef',
    380713        Count => 4,
     714        Notes => 'may be set even if flash does not fire',
    381715        ValueConv => 'my ($a,$b,$c)=unpack("c3",$val); $c ? $a*($b/$c) : 0',
    382716        ValueConvInv => q{
     
    384718            $a<-128 or $a>127 ? undef : pack("c4",$a,1,6,0);
    385719        },
    386         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    387         PrintConvInv => 'eval $val',
     720        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     721        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    388722    },
    389723    # D70 - another ISO tag
     
    395729        PrintConvInv => '"0 $val"',
    396730    },
     731    0x0014 => [
     732        { #4
     733            Name => 'ColorBalanceA',
     734            Condition => '$format eq "undef" and $count == 2560',
     735            SubDirectory => {
     736                TagTable => 'Image::ExifTool::Nikon::ColorBalanceA',
     737                ByteOrder => 'BigEndian',
     738            },
     739        },
     740        { #PH
     741            Name => 'NRWData',
     742            Condition => '$$valPt =~ /^NRW/', # starts with "NRW 0100"
     743            Notes => 'large unknown block in NRW images, not copied to JPEG images',
     744            # 'Drop' because not found in JPEG images (too large for APP1 anyway)
     745            Flags => [ 'Unknown', 'Binary', 'Drop' ],
     746        },
     747    ],
    397748    # D70 Image boundary?? top x,y bot-right x,y
    398749    0x0016 => { #2
     
    400751        Writable => 'int16u',
    401752        Count => 4,
     753    },
     754    0x0017 => { #28
     755        Name => 'ExternalFlashExposureComp', #PH (setting from external flash unit)
     756        Writable => 'undef',
     757        Count => 4,
     758        ValueConv => 'my ($a,$b,$c)=unpack("c3",$val); $c ? $a*($b/$c) : 0',
     759        ValueConvInv => q{
     760            my $a = int($val*6 + ($val>0 ? 0.5 : -0.5));
     761            $a<-128 or $a>127 ? undef : pack("c4",$a,1,6,0);
     762        },
     763        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     764        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    402765    },
    403766    0x0018 => { #5
     
    416779        Name => 'ExposureBracketValue',
    417780        Writable => 'rational64s',
    418         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    419         PrintConvInv => 'eval $val',
     781        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     782        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    420783    },
    421784    0x001a => { #PH
     
    434797        }
    435798    },
     799    0x001c => { #28 (D3 "the application of CSb6 to the selected metering mode")
     800        Name => 'ExposureTuning',
     801        Writable => 'undef',
     802        Count => 3,
     803        ValueConv => 'my ($a,$b,$c)=unpack("c3",$val); $c ? $a*($b/$c) : 0',
     804        ValueConvInv => q{
     805            my $a = int($val*6 + ($val>0 ? 0.5 : -0.5));
     806            $a<-128 or $a>127 ? undef : pack("c3",$a,1,6);
     807        },
     808        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     809        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     810    },
    436811    0x001d => { #4
    437812        Name => 'SerialNumber',
    438         Writable => 0,
    439         Notes => 'Not writable because this value is used as a key to decrypt other information',
    440         RawConv => '$self->{NikonInfo}->{SerialNumber} = $val',
     813        Writable => 'string',
     814        Protected => 1,
     815        Notes => q{
     816            this value is used as a key to decrypt other information -- writing this tag
     817            causes the other information to be re-encrypted with the new key
     818        },
     819        PrintConv => undef, # disable default PRINT_CONV
    441820    },
    442821    0x001e => { #14
     
    448827        },
    449828    },
     829    0x001f => { #PH
     830        Name => 'VRInfo',
     831        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::VRInfo' },
     832    },
    450833    0x0020 => { #16
    451834        Name => 'ImageAuthentication',
    452835        Writable => 'int8u',
    453         PrintConv => { 0 => 'Off', 1 => 'On' },
     836        PrintConv => \%offOn,
     837    },
     838    0x0021 => { #PH
     839        Name => 'FaceDetect',
     840        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FaceDetect' },
     841    },
     842    0x0022 => { #21
     843        Name => 'ActiveD-Lighting',
     844        Writable => 'int16u',
     845        PrintConv => {
     846            0 => 'Off',
     847            1 => 'Low',
     848            3 => 'Normal',
     849            5 => 'High',
     850            7 => 'Extra High', #10
     851            0xffff => 'Auto', #10
     852        },
     853    },
     854    0x0023 => { #PH (D300, but also found in D3,D3S,D3X,D90,D300S,D700,D3000,D5000)
     855        Name => 'PictureControlData',
     856        Writable => 'undef',
     857        Permanent => 0,
     858        Binary => 1,
     859        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControl' },
     860    },
     861    0x0024 => { #JD
     862        Name => 'WorldTime',
     863        SubDirectory => {
     864            TagTable => 'Image::ExifTool::Nikon::WorldTime',
     865            # (CaptureNX does flip the byte order of this record)
     866        },
     867    },
     868    0x0025 => { #PH
     869        Name => 'ISOInfo',
     870        SubDirectory => {
     871            TagTable => 'Image::ExifTool::Nikon::ISOInfo',
     872            ByteOrder => 'BigEndian', #(NC)
     873        },
     874    },
     875    0x002a => { #23 (this tag added with D3 firmware 1.10 -- also written by Nikon utilities)
     876        Name => 'VignetteControl',
     877        Writable => 'int16u',
     878        PrintConv => {
     879            0 => 'Off',
     880            1 => 'Low',
     881            3 => 'Normal',
     882            5 => 'High',
     883        },
     884    },
     885    0x002b => { #PH
     886        Name => 'DistortInfo',
     887        SubDirectory => {
     888            TagTable => 'Image::ExifTool::Nikon::DistortInfo',
     889            ByteOrder => 'BigEndian', #(NC)
     890        },
     891    },
     892    0x002c => { #29 (D7000)
     893        Name => 'UnknownInfo',
     894        SubDirectory => {
     895            TagTable => 'Image::ExifTool::Nikon::UnknownInfo',
     896            ByteOrder => 'BigEndian', #(NC)
     897        },
     898    },
     899    0x0032 => { #PH
     900        Name => 'UnknownInfo2',
     901        SubDirectory => {
     902            TagTable => 'Image::ExifTool::Nikon::UnknownInfo2',
     903            ByteOrder => 'BigEndian', #(NC)
     904        },
    454905    },
    455906    0x0080 => { Name => 'ImageAdjustment',  Writable => 'string' },
     
    484935        Count => 4,
    485936        # short focal, long focal, aperture at short focal, aperture at long focal
    486         PrintConv => q{
    487             $val =~ tr/,/./;    # in case locale is whacky
    488             my ($a,$b,$c,$d) = split ' ', $val;
    489             ($a==$b ? $a : "$a-$b") . "mm f/" . ($c==$d ? $c : "$c-$d")
    490         },
    491         PrintConvInv => '$_=$val; tr/a-z\///d; s/(^|\s)([0-9.]+)(?=\s|$)/$1$2-$2/g; s/-/ /g; $_',
     937        PrintConv => \&Image::ExifTool::Exif::PrintLensInfo,
     938        PrintConvInv => \&Image::ExifTool::Exif::ConvertLensInfo,
    492939    },
    493940    0x0085 => {
     
    505952            0 => 'Did Not Fire',
    506953            1 => 'Fired, Manual', #14
     954            3 => 'Not Ready', #28
    507955            7 => 'Fired, External', #14
    508956            8 => 'Fired, Commander Mode',
     
    510958        },
    511959    },
    512     0x0088 => {
    513         Name => 'AFInfo',
    514         SubDirectory => {
    515             TagTable => 'Image::ExifTool::Nikon::AFInfo',
    516         },
    517     },
     960    0x0088 => [
     961        {
     962            Name => 'AFInfo',
     963            Condition => '$$self{Model} =~ /^NIKON D/i',
     964            SubDirectory => {
     965                TagTable => 'Image::ExifTool::Nikon::AFInfo',
     966                ByteOrder => 'BigEndian',
     967            },
     968        },
     969        {
     970            Name => 'AFInfo',
     971            SubDirectory => {
     972                TagTable => 'Image::ExifTool::Nikon::AFInfo',
     973                ByteOrder => 'LittleEndian',
     974            },
     975        },
     976    ],
    518977    0x0089 => { #5
    519978        Name => 'ShootingMode',
    520979        Writable => 'int16u',
     980        # the meaning of bit 5 seems to change:  For the D200 it indicates "Auto ISO" - PH
     981        Notes => 'for the D70, Bit 5 = Unused LE-NR Slowdown',
    521982        # credit to Tom Christiansen (ref 7) for figuring this out...
    522983        # The (new?) bit 5 seriously complicates our life here: after firmwareB's
     
    524985        # noise reduction feature, probably because even not using it, it still
    525986        # slows down your drive operation to 50% (1.5fps max not 3fps).  But no
    526         # longer does !$val alone indicate single-frame operation. - TC
     987        # longer does !$val alone indicate single-frame operation. - TC, D70
    527988        PrintConv => q[
    528989            $_ = '';
     
    537998                2 => 'PC Control',
    538999                4 => 'Exposure Bracketing',
    539                 5 => 'Unused LE-NR Slowdown',
     1000                5 => $$self{Model}=~/D70\b/ ? 'Unused LE-NR Slowdown' : 'Auto ISO',
    5401001                6 => 'White-Balance Bracketing',
    5411002                7 => 'IR Control',
     
    5431004        ],
    5441005    },
    545     0x008a => { #15
    546         Name => 'AutoBracketRelease',
    547         Writable => 'int16u',
    548         PrintConv => {
    549             0 => 'None',
    550             1 => 'Auto Release',
    551             2 => 'Manual Release',
    552         },
    553     },
     1006    # 0x008a - called "AutoBracketRelease" by ref 15 [but this seems wrong]
     1007    #   values: 0,255 (when writing NEF only), or 1,2 (when writing JPEG or JPEG+NEF)
     1008    #   --> makes odd, repeating pattern in sequential NEF images (ref 28)
    5541009    0x008b => { #8
    5551010        Name => 'LensFStops',
     
    5621017    },
    5631018    0x008c => {
    564         Name => 'NEFCurve1',
     1019        Name => 'ContrastCurve', #JD
    5651020        Writable => 0,
    5661021        Binary => 1,
     
    5751030    0x0090 => { Name => 'LightSource',      Writable => 'string' }, #2
    5761031    0x0091 => [ #18
     1032        { #PH
     1033            Condition => '$$valPt =~ /^0209/',
     1034            Name => 'ShotInfoD40',
     1035            SubDirectory => {
     1036                TagTable => 'Image::ExifTool::Nikon::ShotInfoD40',
     1037                DecryptStart => 4,
     1038                DecryptLen => 748,
     1039                ByteOrder => 'BigEndian',
     1040            },
     1041        },
     1042        {
     1043            Condition => '$$valPt =~ /^0208/',
     1044            Name => 'ShotInfoD80',
     1045            SubDirectory => {
     1046                TagTable => 'Image::ExifTool::Nikon::ShotInfoD80',
     1047                DecryptStart => 4,
     1048                DecryptLen => 764,
     1049                # (Capture NX can change the makernote byte order, but this stays big-endian)
     1050                ByteOrder => 'BigEndian',
     1051            },
     1052        },
     1053        { #PH (D90, firmware 1.00)
     1054            Condition => '$$valPt =~ /^0213/',
     1055            Name => 'ShotInfoD90',
     1056            SubDirectory => {
     1057                TagTable => 'Image::ExifTool::Nikon::ShotInfoD90',
     1058                DecryptStart => 4,
     1059                DecryptLen => 0x398,
     1060                ByteOrder => 'BigEndian',
     1061            },
     1062        },
     1063        { #PH (D3, firmware 0.37 and 1.00)
     1064            Condition => '$$valPt =~ /^0210/ and $count == 5399',
     1065            Name => 'ShotInfoD3a',
     1066            SubDirectory => {
     1067                TagTable => 'Image::ExifTool::Nikon::ShotInfoD3a',
     1068                DecryptStart => 4,
     1069                DecryptLen => 0x318,
     1070                ByteOrder => 'BigEndian',
     1071            },
     1072        },
     1073        { #PH (D3, firmware 1.10, 2.00 and 2.01 [count 5408], and 2.02 [count 5412])
     1074            Condition => '$$valPt =~ /^0210/ and ($count == 5408 or $count == 5412)',
     1075            Name => 'ShotInfoD3b',
     1076            SubDirectory => {
     1077                TagTable => 'Image::ExifTool::Nikon::ShotInfoD3b',
     1078                DecryptStart => 4,
     1079                DecryptLen => 0x321,
     1080                ByteOrder => 'BigEndian',
     1081            },
     1082        },
     1083        { #PH (D3X, firmware 1.00)
     1084            Condition => '$$valPt =~ /^0214/ and $count == 5409',
     1085            Name => 'ShotInfoD3X',
     1086            SubDirectory => {
     1087                TagTable => 'Image::ExifTool::Nikon::ShotInfoD3X',
     1088                DecryptStart => 4,
     1089                DecryptLen => 0x323,
     1090                ByteOrder => 'BigEndian',
     1091            },
     1092        },
     1093        { #PH (D3S, firmware 0.16 and 1.00)
     1094            Condition => '$$valPt =~ /^0218/ and ($count == 5356 or $count == 5388)',
     1095            Name => 'ShotInfoD3S',
     1096            SubDirectory => {
     1097                TagTable => 'Image::ExifTool::Nikon::ShotInfoD3S',
     1098                DecryptStart => 4,
     1099                DecryptLen => 0x2e6,
     1100                ByteOrder => 'BigEndian',
     1101            },
     1102        },
     1103        { #JD (D300, firmware 0.25 and 1.00)
     1104            # D3 and D300 use the same version number, but the length is different
     1105            Condition => '$$valPt =~ /^0210/ and $count == 5291',
     1106            Name => 'ShotInfoD300a',
     1107            SubDirectory => {
     1108                TagTable => 'Image::ExifTool::Nikon::ShotInfoD300a',
     1109                DecryptStart => 4,
     1110                DecryptLen => 813,
     1111                ByteOrder => 'BigEndian',
     1112            },
     1113        },
     1114        { #PH (D300, firmware version 1.10)
     1115            # yet again the same ShotInfoVersion for different data
     1116            Condition => '$$valPt =~ /^0210/ and $count == 5303',
     1117            Name => 'ShotInfoD300b',
     1118            SubDirectory => {
     1119                TagTable => 'Image::ExifTool::Nikon::ShotInfoD300b',
     1120                DecryptStart => 4,
     1121                DecryptLen => 825,
     1122                ByteOrder => 'BigEndian',
     1123            },
     1124        },
     1125        { #PH (D300S, firmware version 1.00)
     1126            # yet again the same ShotInfoVersion for different data
     1127            Condition => '$$valPt =~ /^0216/ and $count == 5311',
     1128            Name => 'ShotInfoD300S',
     1129            SubDirectory => {
     1130                TagTable => 'Image::ExifTool::Nikon::ShotInfoD300S',
     1131                DecryptStart => 4,
     1132                DecryptLen => 827,
     1133                ByteOrder => 'BigEndian',
     1134            },
     1135        },
     1136        { #29 (D700 firmware version 1.02f)
     1137            Condition => '$$valPt =~ /^0212/ and $count == 5312',
     1138            Name => 'ShotInfoD700',
     1139            SubDirectory => {
     1140                TagTable => 'Image::ExifTool::Nikon::ShotInfoD700',
     1141                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     1142                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     1143                DecryptStart => 4,
     1144                DecryptLen => 0x358,
     1145                ByteOrder => 'BigEndian',
     1146            },
     1147        },
     1148        { #PH
     1149            Condition => '$$valPt =~ /^0215/ and $count == 6745',
     1150            Name => 'ShotInfoD5000',
     1151            SubDirectory => {
     1152                TagTable => 'Image::ExifTool::Nikon::ShotInfoD5000',
     1153                DecryptStart => 4,
     1154                DecryptLen => 0x39a,
     1155                ByteOrder => 'BigEndian',
     1156            },
     1157        },
     1158        { #29 (D7000 firmware version 1.01b)
     1159            Condition => '$$valPt =~ /^0220/',
     1160            Name => 'ShotInfoD7000',
     1161            SubDirectory => {
     1162                TagTable => 'Image::ExifTool::Nikon::ShotInfoD7000',
     1163                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     1164                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     1165                DecryptStart => 4,
     1166                DecryptLen => 0x448,
     1167                ByteOrder => 'BigEndian',
     1168            },
     1169        },
    5771170        {
    5781171            Condition => '$$valPt =~ /^02/',
    579             Name => 'ShotInfo',
    580             Writable => 0, # can't yet write encrypted data
     1172            Name => 'ShotInfo02xx',
    5811173            SubDirectory => {
    5821174                TagTable => 'Image::ExifTool::Nikon::ShotInfo',
    5831175                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     1176                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
    5841177                DecryptStart => 4,
    585                 DecryptLen => 0x24e,
     1178                DecryptLen => 0x251,
     1179                ByteOrder => 'BigEndian',
    5861180            },
    5871181        },
    5881182        {
    589             Name => 'ShotInfo',
     1183            Name => 'ShotInfoUnknown',
    5901184            Writable => 0,
    591             Unknown => 1, # no tags known so don't process unless necessary
    5921185            SubDirectory => {
    5931186                TagTable => 'Image::ExifTool::Nikon::ShotInfo',
    594                 DirOffset => 4,
     1187                ByteOrder => 'BigEndian',
    5951188            },
    5961189        },
     
    6001193        Writable => 'int16s',
    6011194    },
    602 # this doesn't look right:
    603 #    0x0093 => { #15
    604 #        Name => 'SaturationAdjustment',
    605 #        Writable => 'int16s',
    606 #    },
     1195    # 0x0093 - ref 15 calls this Saturation, but this is wrong - PH
     1196    0x0093 => { #21
     1197        Name => 'NEFCompression',
     1198        Writable => 'int16u',
     1199        PrintConv => {
     1200            1 => 'Lossy (type 1)', # (older models)
     1201            2 => 'Uncompressed', #JD - D100 (even though TIFF compression is set!)
     1202            3 => 'Lossless',
     1203            4 => 'Lossy (type 2)',
     1204        },
     1205    },
    6071206    0x0094 => { Name => 'Saturation',       Writable => 'int16s' },
    6081207    0x0095 => { Name => 'NoiseReduction',   Writable => 'string' },
    6091208    0x0096 => {
    610         Name => 'NEFCurve2',
     1209        Name => 'LinearizationTable', # same table as DNG LinearizationTable (ref JD)
    6111210        Writable => 0,
    6121211        Binary => 1,
    6131212    },
    6141213    0x0097 => [ #4
     1214        # (NOTE: these are byte-swapped by NX when byte order changes)
    6151215        {
    6161216            Condition => '$$valPt =~ /^0100/', # (D100)
     
    6421242            Condition => '$$valPt =~ /^0205/', # (D50)
    6431243            Name => 'ColorBalance0205',
    644             Writable => 0, # can't yet write encrypted data
    6451244            SubDirectory => {
    6461245                TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
    6471246                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     1247                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
    6481248                DecryptStart => 4,
    6491249                DecryptLen => 22, # 284 bytes encrypted, but don't need to decrypt it all
     
    6521252        },
    6531253        {
    654             Condition => '$$valPt =~ /^02/', # (D2X=0204,D2Hs=0206,D200=0207,D40=0208)
     1254            Condition => '$$valPt =~ /^0209/', # (D3)
     1255            Name => 'ColorBalance0209',
     1256            SubDirectory => {
     1257                TagTable => 'Image::ExifTool::Nikon::ColorBalance4',
     1258                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     1259                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     1260                DecryptStart => 284,
     1261                DecryptLen => 18, # don't need to decrypt it all
     1262                DirOffset => 10,
     1263            },
     1264        },
     1265        {   # (D2X=0204,D2Hs=0206,D200=0207,D40=0208)
     1266            Condition => '$$valPt =~ /^02(\d{2})/ and $1 < 11',
    6551267            Name => 'ColorBalance02',
    656             Writable => 0, # can't yet write encrypted data
    6571268            SubDirectory => {
    6581269                TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
    6591270                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     1271                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
    6601272                DecryptStart => 284,
    6611273                DecryptLen => 14, # 324 bytes encrypted, but don't need to decrypt it all
     
    6631275            },
    6641276        },
    665         {
     1277        {   # (D90/D5000=0211,D300S=0212,D3000=0213,D3S=0214,D3100=0215,D7000/D5100=0216)
    6661278            Name => 'ColorBalanceUnknown',
    6671279            Writable => 0,
     
    6721284            Condition => '$$valPt =~ /^0100/', # D100, D1X - PH
    6731285            Name => 'LensData0100',
    674             SubDirectory => {
    675                 TagTable => 'Image::ExifTool::Nikon::LensData00',
    676             },
     1286            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::LensData00' },
    6771287        },
    6781288        { #8
    6791289            Condition => '$$valPt =~ /^0101/', # D70, D70s - PH
    6801290            Name => 'LensData0101',
    681             SubDirectory => {
    682                 TagTable => 'Image::ExifTool::Nikon::LensData01',
    683             },
     1291            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::LensData01' },
    6841292        },
    6851293        # note: this information is encrypted if the version is 02xx
     
    6901298            Condition => '$$valPt =~ /^020[1-3]/',
    6911299            Name => 'LensData0201',
    692             Writable => 0, # can't yet write encrypted data
    6931300            SubDirectory => {
    6941301                TagTable => 'Image::ExifTool::Nikon::LensData01',
    6951302                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     1303                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
    6961304                DecryptStart => 4,
    6971305            },
    6981306        },
     1307        { #PH
     1308            Condition => '$$valPt =~ /^0204/', # D90, D7000
     1309            Name => 'LensData0204',
     1310            SubDirectory => {
     1311                TagTable => 'Image::ExifTool::Nikon::LensData0204',
     1312                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     1313                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     1314                DecryptStart => 4,
     1315            },
     1316        },
    6991317        {
    7001318            Name => 'LensDataUnknown',
    701             Writable => 0,
     1319            SubDirectory => {
     1320                TagTable => 'Image::ExifTool::Nikon::LensDataUnknown',
     1321            },
    7021322        },
    7031323    ],
     
    7141334        PrintConvInv => '$val=~tr/a-zA-Z/ /;$val',
    7151335    },
    716     # 0x009c - observed values: "", "TWO-SHOT" - PH
     1336    0x009c => { #14
     1337        # L2/L3 has these modes (from owner's manual): - PH
     1338        # Portrait Assist: FACE-PRIORITY AF,PORTRAIT,PORTRAIT LEFT,PORTRAIT RIGHT,
     1339        #                  PORTRAIT CLOSE-UP,PORTRAIT COUPLE,PORTRAIT-FIGURE
     1340        # Landscape Assist:LANDSCAPE,SCENIC VIEW,ARCHITECTURE,GROUP RIGHT,GROUP LEFT
     1341        # Sports Assist:   SPORTS,SPORT SPECTATOR,SPORT COMPOSITE
     1342        Name => 'SceneAssist',
     1343        Writable => 'string',
     1344    },
     1345    0x009e => { #JD
     1346        Name => 'RetouchHistory',
     1347        Writable => 'int16u',
     1348        Count => 10,
     1349        # trim off extra "None" values
     1350        ValueConv => '$val=~s/( 0)+$//; $val',
     1351        ValueConvInv => 'my $n=($val=~/ \d+/g);$n < 9 ? $val . " 0" x (9-$n) : $val',
     1352        PrintConvColumns => 2,
     1353        PrintConv => [
     1354            \%retouchValues,
     1355            \%retouchValues,
     1356            \%retouchValues,
     1357            \%retouchValues,
     1358            \%retouchValues,
     1359            \%retouchValues,
     1360            \%retouchValues,
     1361            \%retouchValues,
     1362            \%retouchValues,
     1363            \%retouchValues,
     1364        ],
     1365    },
    7171366    0x00a0 => { Name => 'SerialNumber',     Writable => 'string' }, #2
    7181367    0x00a2 => { # size of compressed image data plus EOI segment (ref 10)
     
    7201369        Writable => 'int32u',
    7211370    },
     1371    # 0x00a3 - int8u: 0 (All DSLR's but D1,D1H,D1X,D100)
     1372    # 0x00a4 - version number found only in NEF images from DSLR models except the
     1373    # D1,D1X,D2H and D100.  Value is "0200" for all available samples except images
     1374    # edited by Nikon Capture Editor 4.3.1 W and 4.4.2 which have "0100" - PH
    7221375    0x00a5 => { #15
    7231376        Name => 'ImageCount',
     
    7311384    0x00a7 => { # Number of shots taken by camera so far (ref 2)
    7321385        Name => 'ShutterCount',
    733         Writable => 0,
    734         Notes => 'Not writable because this value is used as a key to decrypt other information',
    735         RawConv => '$self->{NikonInfo}->{ShutterCount} = $val',
    736     },
    737     0x00a9 => { #2
    738         Name => 'ImageOptimization',
    739         Writable => 'string',
    740         Count => 16,
    741     },
     1386        Writable => 'int32u',
     1387        Protected => 1,
     1388        Notes => q{
     1389            this value is used as a key to decrypt other information -- writing this tag
     1390            causes the other information to be re-encrypted with the new key
     1391        },
     1392    },
     1393    0x00a8 => [#JD
     1394        {
     1395            Name => 'FlashInfo0100',
     1396            Condition => '$$valPt =~ /^010[01]/',
     1397            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0100' },
     1398        },
     1399        {
     1400            Name => 'FlashInfo0102',
     1401            Condition => '$$valPt =~ /^0102/',
     1402            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0102' },
     1403        },
     1404        {
     1405            Name => 'FlashInfo0103',
     1406            Condition => '$$valPt =~ /^0103/',
     1407            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0103' },
     1408        },
     1409        { #29 (D7000, NC)
     1410            Name => 'FlashInfo0104',
     1411            Condition => '$$valPt =~ /^0104/',
     1412            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0103' },
     1413        },
     1414        {
     1415            Name => 'FlashInfoUnknown',
     1416            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfoUnknown' },
     1417        },
     1418    ],
     1419    0x00a9 => { Name => 'ImageOptimization',Writable => 'string' },#2
    7421420    0x00aa => { Name => 'Saturation',       Writable => 'string' }, #2
    743     0x00ab => { Name => 'VariProgram',      Writable => 'string' }, #2
     1421    0x00ab => { Name => 'VariProgram',      Writable => 'string' }, #2 (scene mode for DSLR's - PH)
    7441422    0x00ac => { Name => 'ImageStabilization',Writable=> 'string' }, #14
    7451423    0x00ad => { Name => 'AFResponse',       Writable => 'string' }, #14
     
    7471425        Name => 'MultiExposure',
    7481426        Condition => '$$valPt =~ /^0100/',
    749         SubDirectory => {
    750             TagTable => 'Image::ExifTool::Nikon::MultiExposure',
    751         },
    752     },
    753     0x00b1 => { #14/PH/19 (D80)
     1427        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::MultiExposure' },
     1428    },
     1429    0x00b1 => { #14/PH/JD (D80)
    7541430        Name => 'HighISONoiseReduction',
    7551431        Writable => 'int16u',
     
    7631439    },
    7641440    # 0x00b2 (string: 'Normal', 0xc3's, 0xff's or 0x20's)
     1441    0x00b3 => { #14
     1442        Name => 'ToningEffect',
     1443        Writable => 'string',
     1444    },
     1445    0x00b6 => { #PH
     1446        Name => 'PowerUpTime',
     1447        Groups => { 2 => 'Time' },
     1448        Shift => 'Time',
     1449        # not clear whether "powered up" means "turned on" or "power applied" - PH
     1450        Notes => 'date/time when camera was last powered up',
     1451        Writable => 'undef',
     1452        # must use RawConv so byte order is correct
     1453        RawConv => sub {
     1454            my $val = shift;
     1455            return $val if length $val < 7;
     1456            my $shrt = GetByteOrder() eq 'II' ? 'v' : 'n';
     1457            my @date = unpack("${shrt}C5", $val);
     1458            return sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', @date);
     1459        },
     1460        RawConvInv => sub {
     1461            my $val = shift;
     1462            my $shrt = GetByteOrder() eq 'II' ? 'v' : 'n';
     1463            my @date = ($val =~ /\d+/g);
     1464            return pack("${shrt}C6", @date, 0);
     1465        },
     1466        PrintConv => '$self->ConvertDateTime($val)',
     1467        PrintConvInv => '$self->InverseDateTime($val,0)',
     1468    },
     1469    0x00b7 => { #JD
     1470        Name => 'AFInfo2',
     1471        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::AFInfo2' },
     1472    },
     1473    0x00b8 => { #PH
     1474        Name => 'FileInfo',
     1475        SubDirectory => {
     1476            TagTable => 'Image::ExifTool::Nikon::FileInfo',
     1477            ByteOrder => 'BigEndian',
     1478        },
     1479    },
     1480    0x00b9 => { #28
     1481        Name => 'AFTune',
     1482        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::AFTune' },
     1483    },
     1484    # 0x00ba - custom curve data? (ref 28?) (only in NEF images)
     1485    0x00bd => { #PH (P6000)
     1486        Name => 'PictureControlData',
     1487        Writable => 'undef',
     1488        Permanent => 0,
     1489        Binary => 1,
     1490        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControl' },
     1491    },
    7651492    0x0e00 => {
    7661493        Name => 'PrintIM',
     
    7711498        },
    7721499    },
    773     # 0x0e01 I don't know what this is, but in D70 NEF files produced by Nikon
    774     # Capture, the data for this tag extends 4 bytes past the end of the maker notes.
    775     # Very odd.  I hope these 4 bytes aren't useful because they will get lost by any
    776     # utility that blindly copies the maker notes (not ExifTool) - PH
     1500    # 0x0e01 - In D70 NEF files produced by Nikon Capture, the data for this tag extends 4 bytes
     1501    # past the end of the maker notes.  Very odd.  I hope these 4 bytes aren't useful because
     1502    # they will get lost by any utility that blindly copies the maker notes (not ExifTool) - PH
    7771503    0x0e01 => {
    7781504        Name => 'NikonCaptureData',
     1505        Writable => 'undef',
     1506        Permanent => 0,
     1507        Drop => 1, # (may be too large for JPEG images)
     1508        Binary => 1,
     1509        Notes => q{
     1510            this data is dropped when copying Nikon MakerNotes since it may be too large
     1511            to fit in the EXIF segment of a JPEG image, but it may be copied as a block
     1512            into existing Nikon MakerNotes later if desired
     1513        },
    7791514        SubDirectory => {
     1515            DirName => 'NikonCapture',
    7801516            TagTable => 'Image::ExifTool::NikonCapture::Main',
    7811517        },
    7821518    },
     1519    # 0x0e05 written by Nikon Capture to NEF files, values of 1 and 2 - PH
    7831520    0x0e09 => { #12
    7841521        Name => 'NikonCaptureVersion',
    7851522        Writable => 'string',
     1523        PrintConv => undef,
    7861524    },
    7871525    # 0x0e0e is in D70 Nikon Capture files (not out-of-the-camera D70 files) - PH
     
    8031541        },
    8041542    },
    805     # 0x0e13 - some sort of edit history written by Nikon Capture
     1543    0x0e13 => [{ # PH/http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2737.0.html
     1544        Name => 'NikonCaptureEditVersions',
     1545        Condition => '$self->Options("ExtractEmbedded")',
     1546        Notes => q{
     1547            the ExtractEmbedded option may be used to decode settings from the stored
     1548            edit versions, otherwise this is extracted as a binary data block
     1549        },
     1550        Writable => 'undef',
     1551        Permanent => 0,
     1552        Drop => 1, # (may be too large for JPEG images)
     1553        SubDirectory => {
     1554            DirName => 'NikonCaptureEditVersions',
     1555            TagTable => 'Image::ExifTool::NikonCapture::Main',
     1556            ProcessProc => \&ProcessNikonCaptureEditVersions,
     1557            WriteProc => sub { return undef }, # (writing not yet supported)
     1558        },
     1559    },{
     1560        Name => 'NikonCaptureEditVersions',
     1561        Writable => 'undef',
     1562        Permanent => 0,
     1563        Binary => 1,
     1564        Drop => 1,
     1565    }],
     1566    0x0e1d => { #JD
     1567        Name => 'NikonICCProfile',
     1568        Binary => 1,
     1569        Protected => 1,
     1570        Writable => 'undef', # must be defined here so tag will be extracted if specified
     1571        WriteCheck => q{
     1572            require Image::ExifTool::ICC_Profile;
     1573            return Image::ExifTool::ICC_Profile::ValidateICC(\$val);
     1574        },
     1575        SubDirectory => {
     1576            DirName => 'NikonICCProfile',
     1577            TagTable => 'Image::ExifTool::ICC_Profile::Main',
     1578        },
     1579    },
     1580    0x0e1e => { #PH
     1581        Name => 'NikonCaptureOutput',
     1582        Writable => 'undef',
     1583        Permanent => 0,
     1584        Binary => 1,
     1585        SubDirectory => {
     1586            TagTable => 'Image::ExifTool::Nikon::CaptureOutput',
     1587            Validate => '$val =~ /^0100/',
     1588        },
     1589    },
     1590    0x0e22 => { #28
     1591        Name => 'NEFBitDepth',
     1592        Writable => 'int16u',
     1593        Count => 4,
     1594        Protected => 1,
     1595        PrintConv => {
     1596            '0 0 0 0' => 'n/a (JPEG)',
     1597            '8 8 8 0' => '8 x 3', # TIFF RGB
     1598            '12 0 0 0' => 12,
     1599            '14 0 0 0' => 14,
     1600        },
     1601    },
    8061602);
    8071603
     
    8131609    WRITABLE => 1,
    8141610    GROUPS => { 0 => 'MakerNotes', 1 => 'NikonScan', 2 => 'Image' },
     1611    VARS => { MINOR_ERRORS => 1 }, # this IFD is non-essential and often corrupted
    8151612    NOTES => 'This information is written by the Nikon Scan software.',
    8161613    0x02 => { Name => 'FilmType',    Writable => 'string', },
     
    8301627        PrintConvInv => '$val',
    8311628    },
     1629    0x60 => {
     1630        Name => 'ScanImageEnhancer',
     1631        Writable => 'int32u',
     1632        PrintConv => \%offOn,
     1633    },
    8321634    0x100 => { Name => 'DigitalICE', Writable => 'string' },
    8331635    0x110 => {
     
    8391641        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::GEM' },
    8401642    },
     1643    0x200 => { Name => 'DigitalDEEShadowAdj',   Writable => 'int32u' },
     1644    0x201 => { Name => 'DigitalDEEThreshold',   Writable => 'int32u' },
     1645    0x202 => { Name => 'DigitalDEEHighlightAdj',Writable => 'int32u' },
    8411646);
    8421647
    8431648# ref 17
    8441649%Image::ExifTool::Nikon::ROC = (
    845     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    846     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    847     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     1650    %binaryDataAttrs,
    8481651    FORMAT => 'int32u',
    849     WRITABLE => 1,
    850     FIRST_ENTRY => 0,
    8511652    GROUPS => { 0 => 'MakerNotes', 1 => 'NikonScan', 2 => 'Image' },
    8521653    0 => {
     
    8591660# ref 17
    8601661%Image::ExifTool::Nikon::GEM = (
    861     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    862     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    863     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     1662    %binaryDataAttrs,
    8641663    FORMAT => 'int32u',
    865     WRITABLE => 1,
    866     FIRST_ENTRY => 0,
    8671664    GROUPS => { 0 => 'MakerNotes', 1 => 'NikonScan', 2 => 'Image' },
    8681665    0 => {
     
    8731670);
    8741671
     1672# Vibration Reduction information - PH (D300)
     1673%Image::ExifTool::Nikon::VRInfo = (
     1674    %binaryDataAttrs,
     1675    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     1676    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
     1677    0 => {
     1678        Name => 'VRInfoVersion',
     1679        Format => 'undef[4]',
     1680        Writable => 0,
     1681    },
     1682    4 => {
     1683        Name => 'VibrationReduction',
     1684        PrintConv => {
     1685            1 => 'On',
     1686            2 => 'Off',
     1687        },
     1688    },
     1689    # 5 - values: 0, 1, 2
     1690    # 6 and 7 - values: 0
     1691);
     1692
     1693# Face detection information - PH (S8100)
     1694%Image::ExifTool::Nikon::FaceDetect = (
     1695    %binaryDataAttrs,
     1696    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     1697    FORMAT => 'int16u',
     1698    DATAMEMBER => [ 0x03 ],
     1699    0x01 => {
     1700        Name => 'FaceDetectFrameSize',
     1701        Format => 'int16u[2]',
     1702    },
     1703    0x03 => {
     1704        Name => 'FacesDetected',
     1705        DataMember => 'FacesDetected',
     1706        RawConv => '$$self{FacesDetected} = $val',
     1707    },
     1708    0x04 => {
     1709        Name => 'Face1Position',
     1710        Format => 'int16u[4]',
     1711        RawConv => '$$self{FacesDetected} < 1 ? undef : $val',
     1712        Notes => q{
     1713            top, left, width and height of face detect area in coordinates of
     1714            FaceDetectFrameSize
     1715        },
     1716    },
     1717    0x08 => {
     1718        Name => 'Face2Position',
     1719        Format => 'int16u[4]',
     1720        RawConv => '$$self{FacesDetected} < 2 ? undef : $val',
     1721    },
     1722    0x0c => {
     1723        Name => 'Face3Position',
     1724        Format => 'int16u[4]',
     1725        RawConv => '$$self{FacesDetected} < 3 ? undef : $val',
     1726    },
     1727    0x10 => {
     1728        Name => 'Face4Position',
     1729        Format => 'int16u[4]',
     1730        RawConv => '$$self{FacesDetected} < 4 ? undef : $val',
     1731    },
     1732    0x14 => {
     1733        Name => 'Face5Position',
     1734        Format => 'int16u[4]',
     1735        RawConv => '$$self{FacesDetected} < 5 ? undef : $val',
     1736    },
     1737    0x18 => {
     1738        Name => 'Face6Position',
     1739        Format => 'int16u[4]',
     1740        RawConv => '$$self{FacesDetected} < 6 ? undef : $val',
     1741    },
     1742    0x1c => {
     1743        Name => 'Face7Position',
     1744        Format => 'int16u[4]',
     1745        RawConv => '$$self{FacesDetected} < 7 ? undef : $val',
     1746    },
     1747    0x20 => {
     1748        Name => 'Face8Position',
     1749        Format => 'int16u[4]',
     1750        RawConv => '$$self{FacesDetected} < 8 ? undef : $val',
     1751    },
     1752    0x24 => {
     1753        Name => 'Face9Position',
     1754        Format => 'int16u[4]',
     1755        RawConv => '$$self{FacesDetected} < 9 ? undef : $val',
     1756    },
     1757    0x28 => {
     1758        Name => 'Face10Position',
     1759        Format => 'int16u[4]',
     1760        RawConv => '$$self{FacesDetected} < 10 ? undef : $val',
     1761    },
     1762    0x2c => {
     1763        Name => 'Face11Position',
     1764        Format => 'int16u[4]',
     1765        RawConv => '$$self{FacesDetected} < 11 ? undef : $val',
     1766    },
     1767    0x30 => {
     1768        Name => 'Face12Position',
     1769        Format => 'int16u[4]',
     1770        RawConv => '$$self{FacesDetected} < 12 ? undef : $val',
     1771    },
     1772);
     1773
     1774# Picture Control information - PH (D300,P6000)
     1775%Image::ExifTool::Nikon::PictureControl = (
     1776    %binaryDataAttrs,
     1777    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     1778    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
     1779    0 => {
     1780        Name => 'PictureControlVersion',
     1781        Format => 'undef[4]',
     1782        Writable => 0,
     1783    },
     1784    4 => {
     1785        Name => 'PictureControlName',
     1786        Format => 'string[20]',
     1787        # make lower case with a leading capital for each word
     1788        PrintConv => \&FormatString,
     1789        PrintConvInv => 'uc($val)',
     1790    },
     1791    24 => {
     1792        Name => 'PictureControlBase',
     1793        Format => 'string[20]',
     1794        PrintConv => \&FormatString,
     1795        PrintConvInv => 'uc($val)',
     1796    },
     1797    # beginning at byte 44, there is some interesting information.
     1798    # here are the observed bytes for each PictureControlMode:
     1799    #            44 45 46 47 48 49 50 51 52 53 54 55 56 57
     1800    # STANDARD   00 01 00 00 00 80 83 80 80 80 80 ff ff ff
     1801    # NEUTRAL    03 c2 00 00 00 ff 82 80 80 80 80 ff ff ff
     1802    # VIVID      00 c3 00 00 00 80 84 80 80 80 80 ff ff ff
     1803    # MONOCHROME 06 4d 00 01 02 ff 82 80 80 ff ff 80 80 ff
     1804    # Neutral2   03 c2 01 00 02 ff 80 7f 81 00 7f ff ff ff (custom)
     1805    # (note that up to 9 different custom picture controls can be stored)
     1806    #
     1807    48 => { #21
     1808        Name => 'PictureControlAdjust',
     1809        PrintConv => {
     1810            0 => 'Default Settings',
     1811            1 => 'Quick Adjust',
     1812            2 => 'Full Control',
     1813        },
     1814    },
     1815    49 => {
     1816        Name => 'PictureControlQuickAdjust',
     1817        # settings: -2 to +2 (n/a for Neutral and Monochrome modes)
     1818        DelValue => 0xff,
     1819        ValueConv => '$val - 0x80',
     1820        ValueConvInv => '$val + 0x80',
     1821        PrintConv => 'Image::ExifTool::Nikon::PrintPC($val)',
     1822        PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val)',
     1823    },
     1824    50 => {
     1825        Name => 'Sharpness',
     1826        # settings: 0 to 9, Auto
     1827        ValueConv => '$val - 0x80',
     1828        ValueConvInv => '$val + 0x80',
     1829        PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"No Sharpening","%d")',
     1830        PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val)',
     1831    },
     1832    51 => {
     1833        Name => 'Contrast',
     1834        # settings: -3 to +3, Auto
     1835        ValueConv => '$val - 0x80',
     1836        ValueConvInv => '$val + 0x80',
     1837        PrintConv => 'Image::ExifTool::Nikon::PrintPC($val)',
     1838        PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val)',
     1839    },
     1840    52 => {
     1841        Name => 'Brightness',
     1842        # settings: -1 to +1
     1843        ValueConv => '$val - 0x80',
     1844        ValueConvInv => '$val + 0x80',
     1845        PrintConv => 'Image::ExifTool::Nikon::PrintPC($val)',
     1846        PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val)',
     1847    },
     1848    53 => {
     1849        Name => 'Saturation',
     1850        # settings: -3 to +3, Auto (n/a for Monochrome mode)
     1851        DelValue => 0xff,
     1852        ValueConv => '$val - 0x80',
     1853        ValueConvInv => '$val + 0x80',
     1854        PrintConv => 'Image::ExifTool::Nikon::PrintPC($val)',
     1855        PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val)',
     1856    },
     1857    54 => {
     1858        Name => 'HueAdjustment',
     1859        # settings: -3 to +3 (n/a for Monochrome mode)
     1860        DelValue => 0xff,
     1861        ValueConv => '$val - 0x80',
     1862        ValueConvInv => '$val + 0x80',
     1863        PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None")',
     1864        PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val)',
     1865    },
     1866    55 => {
     1867        Name => 'FilterEffect',
     1868        # settings: Off,Yellow,Orange,Red,Green (n/a for color modes)
     1869        DelValue => 0xff,
     1870        PrintHex => 1,
     1871        PrintConv => {
     1872            0x80 => 'Off',
     1873            0x81 => 'Yellow',
     1874            0x82 => 'Orange',
     1875            0x83 => 'Red',
     1876            0x84 => 'Green',
     1877            0xff => 'n/a',
     1878        },
     1879    },
     1880    56 => {
     1881        Name => 'ToningEffect',
     1882        # settings: B&W,Sepia,Cyanotype,Red,Yellow,Green,Blue-Green,Blue,
     1883        #           Purple-Blue,Red-Purple (n/a for color modes)
     1884        DelValue => 0xff,
     1885        PrintHex => 1,
     1886        PrintConvColumns => 2,
     1887        PrintConv => {
     1888            0x80 => 'B&W',
     1889            0x81 => 'Sepia',
     1890            0x82 => 'Cyanotype',
     1891            0x83 => 'Red',
     1892            0x84 => 'Yellow',
     1893            0x85 => 'Green',
     1894            0x86 => 'Blue-green',
     1895            0x87 => 'Blue',
     1896            0x88 => 'Purple-blue',
     1897            0x89 => 'Red-purple',
     1898            0xff => 'n/a',
     1899        },
     1900    },
     1901    57 => { #21
     1902        Name => 'ToningSaturation',
     1903        # settings: B&W,Sepia,Cyanotype,Red,Yellow,Green,Blue-Green,Blue,
     1904        #           Purple-Blue,Red-Purple (n/a unless ToningEffect is used)
     1905        DelValue => 0xff,
     1906        ValueConv => '$val - 0x80',
     1907        ValueConvInv => '$val + 0x80',
     1908        PrintConv => '$val==0x7f ? "n/a" : $val',
     1909        PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val)',
     1910    },
     1911);
     1912
     1913# World Time information - JD (D300)
     1914%Image::ExifTool::Nikon::WorldTime = (
     1915    %binaryDataAttrs,
     1916    GROUPS => { 0 => 'MakerNotes', 2 => 'Time' },
     1917    0 => {
     1918        Name => 'Timezone',
     1919        Format => 'int16s',
     1920        PrintConv => q{
     1921            my $sign = $val < 0 ? '-' : '+';
     1922            my $h = int(abs($val) / 60);
     1923            sprintf("%s%.2d:%.2d", $sign, $h, abs($val)-60*$h);
     1924        },
     1925        PrintConvInv => q{
     1926            $val =~ /([-+]?)(\d+):(\d+)/ or return undef;
     1927            return $1 . ($2 * 60 + $3);
     1928        },
     1929    },
     1930    2 => {
     1931        Name => 'DaylightSavings',
     1932        PrintConv => { 0 => 'No', 1 => 'Yes' },
     1933    },
     1934    3 => {
     1935        Name => 'DateDisplayFormat',
     1936        PrintConv => {
     1937            0 => 'Y/M/D',
     1938            1 => 'M/D/Y',
     1939            2 => 'D/M/Y',
     1940        },
     1941    },
     1942);
     1943
     1944# ISO information - PH (D300)
     1945%Image::ExifTool::Nikon::ISOInfo = (
     1946    %binaryDataAttrs,
     1947    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     1948    0 => {
     1949        Name => 'ISO',
     1950        Notes => 'val = 100 * 2**(raw/12-5)',
     1951        Priority => 0, # because people like to see rounded-off values if they exist
     1952        ValueConv => '100*exp(($val/12-5)*log(2))',
     1953        ValueConvInv => '(log($val/100)/log(2)+5)*12',
     1954        PrintConv => 'int($val + 0.5)',
     1955        PrintConvInv => '$val',
     1956    },
     1957    # 1 - 0x01
     1958    # 2 - 0x0c (probably the ISO divisor above)
     1959    # 3 - 0x00
     1960    4 => {
     1961        Name => 'ISOExpansion',
     1962        Format => 'int16u',
     1963        PrintHex => 1,
     1964        PrintConvColumns => 2,
     1965        PrintConv => {
     1966            0x000 => 'Off',
     1967            0x101 => 'Hi 0.3',
     1968            0x102 => 'Hi 0.5',
     1969            0x103 => 'Hi 0.7',
     1970            0x104 => 'Hi 1.0',
     1971            0x105 => 'Hi 1.3', # (Hi 1.3-1.7 may be possible with future models)
     1972            0x106 => 'Hi 1.5',
     1973            0x107 => 'Hi 1.7',
     1974            0x108 => 'Hi 2.0', #(NC) - D3 should have this mode
     1975            0x201 => 'Lo 0.3',
     1976            0x202 => 'Lo 0.5',
     1977            0x203 => 'Lo 0.7',
     1978            0x204 => 'Lo 1.0',
     1979        },
     1980    },
     1981    # bytes 6-11 same as 0-4 in my samples (why is this duplicated?)
     1982    6 => {
     1983        Name => 'ISO2',
     1984        Notes => 'val = 100 * 2**(raw/12-5)',
     1985        ValueConv => '100*exp(($val/12-5)*log(2))',
     1986        ValueConvInv => '(log($val/100)/log(2)+5)*12',
     1987        PrintConv => 'int($val + 0.5)',
     1988        PrintConvInv => '$val',
     1989    },
     1990    # 7 - 0x01
     1991    # 8 - 0x0c (probably the ISO divisor above)
     1992    # 9 - 0x00
     1993    10 => {
     1994        Name => 'ISOExpansion2',
     1995        Format => 'int16u',
     1996        PrintHex => 1,
     1997        PrintConvColumns => 2,
     1998        PrintConv => {
     1999            0x000 => 'Off',
     2000            0x101 => 'Hi 0.3',
     2001            0x102 => 'Hi 0.5',
     2002            0x103 => 'Hi 0.7',
     2003            0x104 => 'Hi 1.0',
     2004            0x105 => 'Hi 1.3', # (Hi 1.3-1.7 may be possible with future models)
     2005            0x106 => 'Hi 1.5',
     2006            0x107 => 'Hi 1.7',
     2007            0x108 => 'Hi 2.0', #(NC) - D3 should have this mode
     2008            0x201 => 'Lo 0.3',
     2009            0x202 => 'Lo 0.5',
     2010            0x203 => 'Lo 0.7',
     2011            0x204 => 'Lo 1.0',
     2012        },
     2013    },
     2014    # bytes 12-13: 00 00
     2015);
     2016
     2017# distortion information - PH (D5000)
     2018%Image::ExifTool::Nikon::DistortInfo = (
     2019    %binaryDataAttrs,
     2020    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2021    0 => {
     2022        Name => 'DistortionVersion',
     2023        Format => 'undef[4]',
     2024        Writable => 0,
     2025        Unknown => 1,
     2026    },
     2027    4 => {
     2028        Name => 'AutoDistortionControl',
     2029        PrintConv => \%offOn,
     2030    },
     2031);
     2032
     2033# unknown information - PH (D7000)
     2034%Image::ExifTool::Nikon::UnknownInfo = (
     2035    %binaryDataAttrs,
     2036    FORMAT => 'int32u',
     2037    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2038    0 => {
     2039        Name => 'UnknownInfoVersion',
     2040        Condition => '$$valPt =~ /^\d{4}/',
     2041        Format => 'undef[4]',
     2042        Writable => 0,
     2043        Unknown => 1,
     2044    },
     2045);
     2046
     2047# more unknown information - PH (D7000)
     2048%Image::ExifTool::Nikon::UnknownInfo2 = (
     2049    %binaryDataAttrs,
     2050    FORMAT => 'int32u',
     2051    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2052    0 => {
     2053        Name => 'UnknownInfo2Version',
     2054        Condition => '$$valPt =~ /^\d{4}/',
     2055        Format => 'undef[4]',
     2056        Writable => 0,
     2057        Unknown => 1,
     2058    },
     2059);
     2060
    8752061# Nikon AF information (ref 13)
    8762062%Image::ExifTool::Nikon::AFInfo = (
    877     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    878     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    879     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    880     WRITABLE => 1,
    881     FIRST_ENTRY => 0,
     2063    %binaryDataAttrs,
    8822064    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    8832065    0 => {
     
    8862068            0 => 'Single Area',
    8872069            1 => 'Dynamic Area',
    888             2 => 'Dynamic Area, Closest Subject',
     2070            2 => 'Dynamic Area (closest subject)',
    8892071            3 => 'Group Dynamic',
    8902072            4 => 'Single Area (wide)',
     
    8952077        Name => 'AFPoint',
    8962078        Notes => 'in some focus modes this value is not meaningful',
     2079        PrintConvColumns => 2,
    8972080        PrintConv => {
    8982081            0 => 'Center',
    8992082            1 => 'Top',
    9002083            2 => 'Bottom',
    901             3 => 'Left',
    902             4 => 'Right',
     2084            3 => 'Mid-left',
     2085            4 => 'Mid-right',
    9032086            5 => 'Upper-left',
    9042087            6 => 'Upper-right',
     
    9122095        Name => 'AFPointsInFocus',
    9132096        Format => 'int16u',
     2097        PrintConvColumns => 2,
    9142098        PrintConv => {
     2099            0x7ff => 'All 11 Points',
    9152100            BITMASK => {
    9162101                0 => 'Center',
    9172102                1 => 'Top',
    9182103                2 => 'Bottom',
    919                 3 => 'Left',
    920                 4 => 'Right',
     2104                3 => 'Mid-left',
     2105                4 => 'Mid-right',
    9212106                5 => 'Upper-left',
    9222107                6 => 'Upper-right',
     
    9302115);
    9312116
     2117# Nikon AF information for D3 and D300 (ref JD)
     2118%Image::ExifTool::Nikon::AFInfo2 = (
     2119    %binaryDataAttrs,
     2120    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2121    DATAMEMBER => [ 4, 6 ],
     2122    NOTES => "These tags are written by Nikon DSLR's which have the live view feature.",
     2123    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
     2124    0 => {
     2125        Name => 'AFInfo2Version',
     2126        Format => 'undef[4]',
     2127        Writable => 0,
     2128    },
     2129    4 => { #PH
     2130        Name => 'ContrastDetectAF',
     2131        RawConv => '$$self{ContrastDetectAF} = $val',
     2132        PrintConv => \%offOn,
     2133    },
     2134    5 => [
     2135        {
     2136            Name => 'AFAreaMode',
     2137            Condition => 'not $$self{ContrastDetectAF}',
     2138            Notes => 'ContrastDetectAF Off',
     2139            PrintConv => {
     2140                0 => 'Single Area', # (called "Single Point" in manual - PH)
     2141                1 => 'Dynamic Area', #PH
     2142                2 => 'Dynamic Area (closest subject)', #PH
     2143                3 => 'Group Dynamic', #PH
     2144                4 => 'Dynamic Area (9 points)', #JD/28
     2145                5 => 'Dynamic Area (21 points)', #28
     2146                6 => 'Dynamic Area (51 points)', #28
     2147                7 => 'Dynamic Area (51 points, 3D-tracking)', #PH/28
     2148                8 => 'Auto-area',
     2149                9 => 'Dynamic Area (3D-tracking)', #PH (D5000 "3D-tracking (11 points)")
     2150                10 => 'Single Area (wide)', #PH
     2151                11 => 'Dynamic Area (wide)', #PH
     2152                12 => 'Dynamic Area (wide, 3D-tracking)', #PH
     2153            },
     2154        },
     2155        { #PH (D3/D90/D5000)
     2156            Name => 'AFAreaMode',
     2157            Notes => 'ContrastDetectAF On',
     2158            PrintConv => {
     2159                0 => 'Contrast-detect', # (D3)
     2160                1 => 'Contrast-detect (normal area)', # (D90/D5000)
     2161                # (D90 and D5000 give value of 2 when set to 'Face Priority' and
     2162                # 'Subject Tracking', but I didn't have a face to shoot at or a
     2163                #  moving subject to track so perhaps this value changes dynamically)
     2164                2 => 'Contrast-detect (wide area)', # (D90/D5000)
     2165                3 => 'Contrast-detect (face priority)', # (ViewNX)
     2166                4 => 'Contrast-detect (subject tracking)', # (ViewNX)
     2167            },
     2168        },
     2169    ],
     2170    6 => {
     2171        Name => 'PhaseDetectAF', #JD(AutoFocus), PH(PhaseDetectAF)
     2172        Notes => 'PrimaryAFPoint and AFPointsUsed below are only valid when this is On',
     2173        RawConv => '$$self{PhaseDetectAF} = $val',
     2174        PrintConv => {
     2175            0 => 'Off',
     2176            1 => 'On (51-point)', #PH
     2177            2 => 'On (11-point)', #PH
     2178            3 => 'On (39-point)', #29 (D7000)
     2179        },
     2180    },
     2181    7 => [
     2182        { #PH/JD
     2183            Name => 'PrimaryAFPoint',
     2184            Condition => '$$self{PhaseDetectAF} < 2',
     2185            Notes => 'models with 51-point AF: D3, D3S, D3X, D300, D300S and D700',
     2186            PrintConvColumns => 5,
     2187            PrintConv => {
     2188                0 => '(none)',      26 => 'C10',
     2189                1 => 'C6 (Center)', 27 => 'B10',
     2190                2 => 'B6',          28 => 'A9',
     2191                3 => 'A5',          29 => 'D10',
     2192                4 => 'D6',          30 => 'E9',
     2193                5 => 'E5',          31 => 'C11',
     2194                6 => 'C7',          32 => 'B11',
     2195                7 => 'B7',          33 => 'D11',
     2196                8 => 'A6',          34 => 'C4',
     2197                9 => 'D7',          35 => 'B4',
     2198                10 => 'E6',         36 => 'A3',
     2199                11 => 'C5',         37 => 'D4',
     2200                12 => 'B5',         38 => 'E3',
     2201                13 => 'A4',         39 => 'C3',
     2202                14 => 'D5',         40 => 'B3',
     2203                15 => 'E4',         41 => 'A2',
     2204                16 => 'C8',         42 => 'D3',
     2205                17 => 'B8',         43 => 'E2',
     2206                18 => 'A7',         44 => 'C2',
     2207                19 => 'D8',         45 => 'B2',
     2208                20 => 'E7',         46 => 'A1',
     2209                21 => 'C9',         47 => 'D2',
     2210                22 => 'B9',         48 => 'E1',
     2211                23 => 'A8',         49 => 'C1',
     2212                24 => 'D9',         50 => 'B1',
     2213                25 => 'E8',         51 => 'D1',
     2214            },
     2215        },
     2216        { #10
     2217            Name => 'PrimaryAFPoint',
     2218            Notes => 'models with 11-point AF: D90, D3000 and D5000',
     2219            Condition => '$$self{PhaseDetectAF} == 2',
     2220            PrintConvColumns => 2,
     2221            PrintConv => {
     2222                0 => '(none)',
     2223                1 => 'Center',
     2224                2 => 'Top',
     2225                3 => 'Bottom',
     2226                4 => 'Mid-left',
     2227                5 => 'Upper-left',
     2228                6 => 'Lower-left',
     2229                7 => 'Far Left',
     2230                8 => 'Mid-right',
     2231                9 => 'Upper-right',
     2232                10 => 'Lower-right',
     2233                11 => 'Far Right',
     2234            },
     2235        },
     2236        { #29
     2237            Name => 'PrimaryAFPoint',
     2238            Condition => '$$self{PhaseDetectAF} == 3',
     2239            Notes => 'models with 39-point AF: D7000 (not verified)',
     2240            PrintConvColumns => 5,
     2241            PrintConv => {
     2242                0 => '(none)',      22 => 'C10',
     2243                1 => 'C6 (Center)', 23 => 'B10',
     2244                2 => 'B6',          24 => 'D10',
     2245                3 => 'A2',          25 => 'C11',
     2246                4 => 'D6',          26 => 'B11',
     2247                5 => 'E2',          27 => 'D11',
     2248                6 => 'C7',          28 => 'C4',
     2249                7 => 'B7',          29 => 'B4',
     2250                8 => 'A3',          30 => 'D4',
     2251                9 => 'D7',          31 => 'C3',
     2252                10 => 'E3',         32 => 'B3',
     2253                11 => 'C5',         33 => 'D3',
     2254                12 => 'B5',         34 => 'C2',
     2255                13 => 'A1',         35 => 'B2',
     2256                14 => 'D5',         36 => 'D2',
     2257                15 => 'E1',         37 => 'C1',
     2258                16 => 'C8',         38 => 'B1',
     2259                17 => 'B8',         39 => 'D1',
     2260                18 => 'D8',
     2261                19 => 'C9',
     2262                20 => 'B9',
     2263                21 => 'D9',
     2264            },
     2265        },
     2266        {
     2267            Name => 'PrimaryAFPoint',
     2268            Notes => 'future models?...',
     2269            PrintConv => {
     2270                0 => '(none)',
     2271                1 => 'Center',
     2272            },
     2273        },
     2274    ],
     2275    8 => [
     2276        { #JD/PH
     2277            Name => 'AFPointsUsed',
     2278            Condition => '$$self{PhaseDetectAF} < 2',
     2279            Notes => q{
     2280                models with 51-point AF -- 5 rows: A1-9, B1-11, C1-11, D1-11, E1-9, center
     2281                point is C6
     2282            },
     2283            Format => 'undef[7]',
     2284            PrintConv => 'Image::ExifTool::Nikon::PrintAFPointsD3($val)',
     2285        },
     2286        { #10
     2287            Name => 'AFPointsUsed',
     2288            Condition => '$$self{PhaseDetectAF} == 2',
     2289            Notes => 'models with 11-point AF',
     2290            # read as int16u in little-endian byte order
     2291            Format => 'undef[2]',
     2292            ValueConv => 'unpack("v",$val)',
     2293            ValueConvInv => 'pack("v",$val)',
     2294            PrintConvColumns => 2,
     2295            PrintConv => {
     2296                0x7ff => 'All 11 Points',
     2297                BITMASK => {
     2298                    0 => 'Center',
     2299                    1 => 'Top',
     2300                    2 => 'Bottom',
     2301                    3 => 'Mid-left',
     2302                    4 => 'Upper-left',
     2303                    5 => 'Lower-left',
     2304                    6 => 'Far Left',
     2305                    7 => 'Mid-right',
     2306                    8 => 'Upper-right',
     2307                    9 => 'Lower-right',
     2308                    10 => 'Far Right',
     2309                },
     2310            },
     2311        },
     2312        { #29
     2313            Name => 'AFPointsUsed',
     2314            Condition => '$$self{PhaseDetectAF} == 3',
     2315            Notes => 'models with 39-point AF: D7000 (not decoded)',
     2316            Format => 'undef[7]',
     2317            PrintConv => '$_=unpack("H*",$val); "Unknown (".join(" ", /(..)/g).")"',
     2318        },
     2319        {
     2320            Name => 'AFPointsUsed',
     2321            Format => 'undef[7]',
     2322            PrintConv => '$_=unpack("H*",$val); "Unknown (".join(" ", /(..)/g).")"',
     2323        },
     2324    ],
     2325    0x10 => { #PH (D90 and D5000)
     2326        Name => 'AFImageWidth',
     2327        Format => 'int16u',
     2328        RawConv => '$val ? $val : undef',
     2329        Notes => 'this and the following tags are valid only for contrast-detect AF',
     2330    },
     2331    0x12 => { #PH
     2332        Name => 'AFImageHeight',
     2333        Format => 'int16u',
     2334        RawConv => '$val ? $val : undef',
     2335    },
     2336    0x14 => { #PH
     2337        Name => 'AFAreaXPosition',
     2338        Notes => 'center of AF area in AFImage coordinates',
     2339        Format => 'int16u',
     2340        RawConv => '$val ? $val : undef',
     2341    },
     2342    0x16 => { #PH
     2343        Name => 'AFAreaYPosition',
     2344        Format => 'int16u',
     2345        RawConv => '$val ? $val : undef',
     2346    },
     2347    # AFAreaWidth/Height for the D90 and D5000:
     2348    #   352x288 (AF normal area),
     2349    #   704x576 (AF face priority, wide area, subject tracking)
     2350    0x18 => { #PH
     2351        Name => 'AFAreaWidth',
     2352        Format => 'int16u',
     2353        Notes => 'size of AF area in AFImage coordinates',
     2354        RawConv => '$val ? $val : undef',
     2355    },
     2356    0x1a => { #PH
     2357        Name => 'AFAreaHeight',
     2358        Format => 'int16u',
     2359        RawConv => '$val ? $val : undef',
     2360    },
     2361    0x1c => { #PH
     2362        Name => 'ContrastDetectAFInFocus',
     2363        PrintConv => { 0 => 'No', 1 => 'Yes' },
     2364    },
     2365    # 0x1d - always zero (with or without live view)
     2366);
     2367
     2368# Nikon AF fine-tune information (ref 28)
     2369%Image::ExifTool::Nikon::AFTune = (
     2370    %binaryDataAttrs,
     2371    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2372    0 => {
     2373        Name => 'AFFineTune',
     2374        PrintConv => {
     2375            0 => 'Off',
     2376            # (don't know what the difference between 1 and 2 is)
     2377            1 => 'On (1)',
     2378            2 => 'On (2)',
     2379        },
     2380    },
     2381    1 => {
     2382        Name => 'AFFineTuneIndex',
     2383        Notes => 'index of saved lens',
     2384        PrintConv => '$val == 255 ? "n/a" : $val',
     2385        PrintConvInv => '$val eq "n/a" ? 255 : $val',
     2386    },
     2387    2 => {
     2388        Name => 'AFFineTuneAdj',
     2389        Priority => 0, # so other value takes priority if it exists
     2390        Notes => 'may only be valid for saved lenses',
     2391        Format => 'int8s',
     2392        PrintConv => '$val > 0 ? "+$val" : $val',
     2393        PrintConvInv => '$val',
     2394    },
     2395);
     2396
     2397# Nikon File information - D60, D3 and D300 (ref PH)
     2398%Image::ExifTool::Nikon::FileInfo = (
     2399    %binaryDataAttrs,
     2400    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     2401    0 => {
     2402        Name => 'FileInfoVersion',
     2403        Format => 'undef[4]',
     2404        Writable => 0,
     2405    },
     2406    6 => {
     2407        Name => 'DirectoryNumber',
     2408        Format => 'int16u',
     2409        PrintConv => 'sprintf("%.3d", $val)',
     2410        PrintConvInv => '$val',
     2411    },
     2412    8 => {
     2413        Name => 'FileNumber',
     2414        Format => 'int16u',
     2415        PrintConv => 'sprintf("%.4d", $val)',
     2416        PrintConvInv => '$val',
     2417    },
     2418);
     2419
    9322420# ref PH
    9332421%Image::ExifTool::Nikon::CaptureOffsets = (
     
    9392427);
    9402428
     2429# ref PH (Written by capture NX)
     2430%Image::ExifTool::Nikon::CaptureOutput = (
     2431    %binaryDataAttrs,
     2432    FORMAT => 'int32u',
     2433    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     2434    # 1 = 1
     2435    2 => 'OutputImageWidth',
     2436    3 => 'OutputImageHeight',
     2437    4 => 'OutputResolution',
     2438    # 5 = 1
     2439);
     2440
     2441# ref 4
     2442%Image::ExifTool::Nikon::ColorBalanceA = (
     2443    %binaryDataAttrs,
     2444    FORMAT => 'int16u',
     2445    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2446    624 => {
     2447        Name => 'RedBalance',
     2448        ValueConv => '$val / 256',
     2449        ValueConvInv => '$val * 256',
     2450        Protected => 1,
     2451    },
     2452    625 => {
     2453        Name => 'BlueBalance',
     2454        ValueConv => '$val / 256',
     2455        ValueConvInv => '$val * 256',
     2456        Protected => 1,
     2457    },
     2458);
     2459
    9412460# ref 4
    9422461%Image::ExifTool::Nikon::ColorBalance1 = (
    943     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    944     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    945     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    946     WRITABLE => 1,
     2462    %binaryDataAttrs,
    9472463    FORMAT => 'int16u',
    948     FIRST_ENTRY => 0,
    9492464    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    9502465    0 => {
     
    9572472# ref 4
    9582473%Image::ExifTool::Nikon::ColorBalance2 = (
    959     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    960     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    961     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    962     WRITABLE => 1,
     2474    %binaryDataAttrs,
    9632475    FORMAT => 'int16u',
    964     FIRST_ENTRY => 0,
    965     NOTES => q{
    966         This information is encrypted for most camera models, and if encrypted is
    967         not currently writable by exiftool.
    968     },
    9692476    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2477    NOTES => 'This information is encrypted for most camera models.',
    9702478    0 => {
    9712479        Name => 'WB_RGGBLevels',
     
    9772485# ref 4
    9782486%Image::ExifTool::Nikon::ColorBalance3 = (
    979     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    980     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    981     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    982     WRITABLE => 1,
     2487    %binaryDataAttrs,
    9832488    FORMAT => 'int16u',
    984     FIRST_ENTRY => 0,
    9852489    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    9862490    0 => {
    9872491        Name => 'WB_RGBGLevels',
     2492        Format => 'int16u[4]',
     2493        Protected => 1,
     2494    },
     2495);
     2496
     2497# ref 4
     2498%Image::ExifTool::Nikon::ColorBalance4 = (
     2499    %binaryDataAttrs,
     2500    FORMAT => 'int16u',
     2501    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2502    0 => {
     2503        Name => 'WB_GRBGLevels',
    9882504        Format => 'int16u[4]',
    9892505        Protected => 1,
     
    10062522);
    10072523
    1008 # these are standard EXIF tags, but they are duplicated here so we
    1009 # can change some names to extract the Nikon preview separately
    1010 %Image::ExifTool::Nikon::PreviewImage = (
     2524# these are standard EXIF tags, but they are duplicated here so we can
     2525# set the family 0 group to 'MakerNotes' and set the MINOR_ERRORS flag
     2526%Image::ExifTool::Nikon::PreviewIFD = (
    10112527    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
    10122528    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
    1013     GROUPS => { 0 => 'MakerNotes', 1 => 'NikonPreview', 2 => 'Image'},
     2529    GROUPS => { 0 => 'MakerNotes', 1 => 'PreviewIFD', 2 => 'Image'},
     2530    VARS => { MINOR_ERRORS => 1 }, # this IFD is non-essential and often corrupted
     2531    # (these tags are priority 0 by default because PreviewIFD is flagged in LOW_PRIORITY_DIR)
     2532    0xfe => { # (not used by Nikon, but SRW images also use this table)
     2533        Name => 'SubfileType',
     2534        DataMember => 'SubfileType',
     2535        RawConv => '$$self{SubfileType} = $val',
     2536        PrintConv => \%Image::ExifTool::Exif::subfileType,
     2537    },
    10142538    0x103 => {
    10152539        Name => 'Compression',
     2540        SeparateTable => 'EXIF Compression',
    10162541        PrintConv => \%Image::ExifTool::Exif::compression,
    1017         Priority => 0,
    1018     },
    1019     0x11a => {
    1020         Name => 'XResolution',
    1021         Priority => 0,
    1022     },
    1023     0x11b => {
    1024         Name => 'YResolution',
    1025         Priority => 0,
    1026     },
     2542    },
     2543    0x11a => 'XResolution',
     2544    0x11b => 'YResolution',
    10272545    0x128 => {
    10282546        Name => 'ResolutionUnit',
     
    10322550            3 => 'cm',
    10332551        },
    1034         Priority => 0,
    10352552    },
    10362553    0x201 => {
    10372554        Name => 'PreviewImageStart',
    10382555        Flags => [ 'IsOffset', 'Permanent' ],
    1039         OffsetPair => 0x202, # point to associated byte count
     2556        OffsetPair => 0x202,
    10402557        DataTag => 'PreviewImage',
    10412558        Writable => 'int32u',
    1042         WriteGroup => 'NikonPreview',
    10432559        Protected => 2,
    10442560    },
     
    10462562        Name => 'PreviewImageLength',
    10472563        Flags => 'Permanent' ,
    1048         OffsetPair => 0x201, # point to associated offset
     2564        OffsetPair => 0x201,
    10492565        DataTag => 'PreviewImage',
    10502566        Writable => 'int32u',
    1051         WriteGroup => 'NikonPreview',
    10522567        Protected => 2,
    10532568    },
     
    10582573            2 => 'Co-sited',
    10592574        },
    1060         Priority => 0,
    10612575    },
    10622576);
     
    10732587    ValueConv => '5 * 2**($val/24)',
    10742588    ValueConvInv => '$val>0 ? 24*log($val/5)/log(2) : 0',
    1075     PrintConv => 'sprintf("%.1fmm",$val)',
     2589    PrintConv => 'sprintf("%.1f mm",$val)',
    10762590    PrintConvInv => '$val=~s/\s*mm$//;$val',
    10772591);
     
    10792593# Version 100 Nikon lens data
    10802594%Image::ExifTool::Nikon::LensData00 = (
    1081     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1082     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1083     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    1084     WRITABLE => 1,
    1085     FIRST_ENTRY => 0,
     2595    %binaryDataAttrs,
    10862596    NOTES => 'This structure is used by the D100, and D1X with firmware version 1.1.',
    10872597    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2598    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
    10882599    0x00 => {
    10892600        Name => 'LensDataVersion',
    10902601        Format => 'undef[4]',
     2602        Writable => 0,
    10912603    },
    10922604    0x06 => { #8
     
    11222634# Nikon lens data (note: needs decrypting if LensDataVersion is 020x)
    11232635%Image::ExifTool::Nikon::LensData01 = (
    1124     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1125     FIRST_ENTRY => 0,
     2636    %binaryDataAttrs,
    11262637    NOTES => q{
    11272638        Nikon encrypts the LensData information below if LensDataVersion is 0201 or
    11282639        higher, but  the decryption algorithm is known so the information can be
    1129         extracted.  It isn't yet writable, however, because the encryption adds
    1130         complications which make writing more difficult.
     2640        extracted.
    11312641    },
    11322642    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2643    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
    11332644    0x00 => {
    11342645        Name => 'LensDataVersion',
    11352646        Format => 'string[4]',
     2647        Writable => 0,
    11362648    },
    11372649    0x04 => { #8
     
    11392651        ValueConv => '$val ? 2048 / $val : $val',
    11402652        ValueConvInv => '$val ? 2048 / $val : $val',
    1141         PrintConv => 'sprintf("%.1fmm",$val)',
    1142         PrintConvInv => '$val=~s/ ?mm$//; $val',
     2653        PrintConv => 'sprintf("%.1f mm",$val)',
     2654        PrintConvInv => '$val=~s/\s*mm$//; $val',
    11432655    },
    11442656    0x05 => { #8
     
    11472659    },
    11482660    0x08 => { #8
     2661        # this seems to be 2 values: the upper nibble gives the far focus
     2662        # range and the lower nibble gives the near focus range.  The values
     2663        # are in the range 1-N, where N is lens-dependent.  A value of 0 for
     2664        # the far focus range indicates infinity. (ref JD)
    11492665        Name => 'FocusPosition',
    11502666        PrintConv => 'sprintf("0x%02x", $val)',
     
    12012717);
    12022718
    1203 # information encrypted in some cameras - ref 18
    1204 %Image::ExifTool::Nikon::ShotInfo = (
     2719# Nikon lens data (note: needs decrypting)
     2720%Image::ExifTool::Nikon::LensData0204 = (
     2721    %binaryDataAttrs,
     2722    NOTES => q{
     2723        Nikon encrypts the LensData information below if LensDataVersion is 0201 or
     2724        higher, but  the decryption algorithm is known so the information can be
     2725        extracted.
     2726    },
     2727    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2728    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
     2729    0x00 => {
     2730        Name => 'LensDataVersion',
     2731        Format => 'string[4]',
     2732        Writable => 0,
     2733    },
     2734    0x04 => { #8
     2735        Name => 'ExitPupilPosition',
     2736        ValueConv => '$val ? 2048 / $val : $val',
     2737        ValueConvInv => '$val ? 2048 / $val : $val',
     2738        PrintConv => 'sprintf("%.1f mm",$val)',
     2739        PrintConvInv => '$val=~s/\s*mm$//; $val',
     2740    },
     2741    0x05 => { #8
     2742        Name => 'AFAperture',
     2743        %nikonApertureConversions,
     2744    },
     2745    0x08 => { #8
     2746        # this seems to be 2 values: the upper nibble gives the far focus
     2747        # range and the lower nibble gives the near focus range.  The values
     2748        # are in the range 1-N, where N is lens-dependent.  A value of 0 for
     2749        # the far focus range indicates infinity. (ref JD)
     2750        Name => 'FocusPosition',
     2751        PrintConv => 'sprintf("0x%02x", $val)',
     2752        PrintConvInv => '$val',
     2753    },
     2754    # --> extra byte at position 0x09 in this version of LensData (PH)
     2755    0x0a => { #8/9
     2756        # With older AF lenses this does not work... (ref 13)
     2757        # ie) AF Nikkor 50mm f/1.4 => 48 (0x30)
     2758        # AF Zoom-Nikkor 35-105mm f/3.5-4.5 => @35mm => 15 (0x0f), @105mm => 141 (0x8d)
     2759        Notes => 'this focus distance is approximate, and not very accurate for some lenses',
     2760        Name => 'FocusDistance',
     2761        ValueConv => '0.01 * 10**($val/40)', # in m
     2762        ValueConvInv => '$val>0 ? 40*log($val*100)/log(10) : 0',
     2763        PrintConv => '$val ? sprintf("%.2f m",$val) : "inf"',
     2764        PrintConvInv => '$val eq "inf" ? 0 : $val =~ s/\s*m$//, $val',
     2765    },
     2766    0x0b => { #8/9
     2767        Name => 'FocalLength',
     2768        Priority => 0,
     2769        %nikonFocalConversions,
     2770    },
     2771    0x0c => { #8
     2772        Name => 'LensIDNumber',
     2773        Notes => 'see LensID values below',
     2774    },
     2775    0x0d => { #8
     2776        Name => 'LensFStops',
     2777        ValueConv => '$val / 12',
     2778        ValueConvInv => '$val * 12',
     2779        PrintConv => 'sprintf("%.2f", $val)',
     2780        PrintConvInv => '$val',
     2781    },
     2782    0x0e => { #8/9
     2783        Name => 'MinFocalLength',
     2784        %nikonFocalConversions,
     2785    },
     2786    0x0f => { #8/9
     2787        Name => 'MaxFocalLength',
     2788        %nikonFocalConversions,
     2789    },
     2790    0x10 => { #8
     2791        Name => 'MaxApertureAtMinFocal',
     2792        %nikonApertureConversions,
     2793    },
     2794    0x11 => { #8
     2795        Name => 'MaxApertureAtMaxFocal',
     2796        %nikonApertureConversions,
     2797    },
     2798    0x12 => 'MCUVersion', #8
     2799    0x13 => { #8
     2800        Name => 'EffectiveMaxAperture',
     2801        %nikonApertureConversions,
     2802    },
     2803);
     2804
     2805# Unknown Nikon lens data (note: data may need decrypting after byte 4)
     2806%Image::ExifTool::Nikon::LensDataUnknown = (
    12052807    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    12062808    FIRST_ENTRY => 0,
     2809    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2810    0x00 => {
     2811        Name => 'LensDataVersion',
     2812        Format => 'string[4]',
     2813    },
     2814);
     2815
     2816# shot information (encrypted in some cameras) - ref 18
     2817%Image::ExifTool::Nikon::ShotInfo = (
     2818    %binaryDataAttrs,
    12072819    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    12082820    DATAMEMBER => [ 0 ],
    12092821    NOTES => q{
    12102822        This information is encrypted for ShotInfoVersion 02xx, and some tags are
    1211         only valid for specific versions.
     2823        only valid for specific models.
    12122824    },
    12132825    0x00 => {
    12142826        Name => 'ShotInfoVersion',
    1215         RawConv => '$$self{ShotInfoVersion} = $val',
    12162827        Format => 'string[4]',
     2828        Writable => 0,
     2829        RawConv => '$$self{ShotInfoVersion} = $val; $val =~ /^\d+$/ ? $val : undef',
     2830    },
     2831    0x04 => {
     2832        Name => 'FirmwareVersion',
     2833        Format => 'string[5]',
     2834        Writable => 0,
     2835        RawConv => '$val =~ /^\d\.\d+.$/ ? $val : undef',
     2836    },
     2837    0x10 => {
     2838        Name => 'DistortionControl',
     2839        Condition => '$$self{Model} =~ /P6000\b/',
     2840        Notes => 'P6000',
     2841        PrintConv => \%offOn,
    12172842    },
    12182843    0x66 => {
    12192844        Name => 'VR_0x66',
    1220         Condition => '$$self{ShotInfoVersion} =~ /^(0204)$/',
     2845        Condition => '$$self{ShotInfoVersion} eq "0204"',
    12212846        Format => 'int8u',
    12222847        Unknown => 1,
     
    12312856    0x6a => {
    12322857        Name => 'ShutterCount',
    1233         Condition => '$$self{ShotInfoVersion} =~ /^(0204)$/',
     2858        Condition => '$$self{ShotInfoVersion} eq "0204"',
    12342859        Format => 'int32u',
    12352860        Priority => 0,
     
    12382863    0x6e => {
    12392864        Name => 'DeletedImageCount',
    1240         Condition => '$$self{ShotInfoVersion} =~ /^(0204)$/',
     2865        Condition => '$$self{ShotInfoVersion} eq "0204"',
    12412866        Format => 'int32u',
    12422867        Priority => 0,
    12432868        Notes => 'D2X, D2Xs',
    12442869    },
    1245     0x75 => { #19
     2870    0x75 => { #JD
    12462871        Name => 'VibrationReduction',
    1247         Condition => '$$self{ShotInfoVersion} =~ /^(0207)$/',
     2872        Condition => '$$self{ShotInfoVersion} eq "0207"',
    12482873        Format => 'int8u',
    12492874        Notes => 'D200',
    12502875        PrintConv => {
    12512876            0 => 'Off',
    1252             1 => 'On (1)',
    1253             2 => 'On (2)',
     2877            # (not sure what the different values represent, but values
     2878            # of 1 and 2 have even been observed for non-VR lenses!)
     2879            1 => 'On (1)', #PH
     2880            2 => 'On (2)', #PH
     2881            3 => 'On (3)', #PH (rare -- only seen once)
    12542882        },
    12552883    },
    12562884    0x82 => { # educated guess, needs verification
    12572885        Name => 'VibrationReduction',
    1258         Condition => '$$self{ShotInfoVersion} =~ /^(0204)$/',
     2886        Condition => '$$self{ShotInfoVersion} eq "0204"',
    12592887        Format => 'int8u',
    12602888        Notes => 'D2X, D2Xs',
     
    12642892        },
    12652893    },
    1266     0x157 => { #19
     2894    0x157 => { #JD
    12672895        Name => 'ShutterCount',
    1268         Condition => '$$self{ShotInfoVersion} =~ /^(0205)$/',
     2896        Condition => '$$self{ShotInfoVersion} eq "0205"',
    12692897        Format => 'undef[2]',
    12702898        Priority => 0,
     
    12742902        ValueConvInv => 'pack("n",$val)',
    12752903    },
    1276     0x1ae => { #19
     2904    0x1ae => { #JD
    12772905        Name => 'VibrationReduction',
    1278         Condition => '$$self{ShotInfoVersion} =~ /^(0205)$/',
     2906        Condition => '$$self{ShotInfoVersion} eq "0205"',
    12792907        Format => 'int8u',
    12802908        Notes => 'D50',
     
    12862914        },
    12872915    },
    1288     0x24a => { #19
     2916    0x24d => { #PH
    12892917        Name => 'ShutterCount',
    1290         Condition => '$$self{ShotInfoVersion} =~ /^(0208)$/',
     2918        Condition => '$$self{ShotInfoVersion} eq "0211"',
     2919        Notes => 'D60',
    12912920        Format => 'int32u',
    12922921        Priority => 0,
    1293         Notes => 'D80',
    1294     },
    1295     0x24e => { #19
     2922    },
     2923    # note: DecryptLen currently set to 0x251
     2924);
     2925
     2926# shot information for D40 and D40X (encrypted) - ref PH
     2927%Image::ExifTool::Nikon::ShotInfoD40 = (
     2928    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     2929    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     2930    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     2931    VARS => { ID_LABEL => 'Index' },
     2932    IS_SUBDIR => [ 729 ],
     2933    WRITABLE => 1,
     2934    FIRST_ENTRY => 0,
     2935    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2936    NOTES => 'These tags are extracted from encrypted data in D40 and D40X images.',
     2937    0x00 => {
     2938        Name => 'ShotInfoVersion',
     2939        Format => 'string[4]',
     2940        Writable => 0,
     2941    },
     2942    582 => {
     2943        Name => 'ShutterCount',
     2944        Format => 'int32u',
     2945        Priority => 0,
     2946    },
     2947    586.1 => { #JD
    12962948        Name => 'VibrationReduction',
    1297         Condition => '$$self{ShotInfoVersion} =~ /^(0208)$/',
    1298         Notes => 'D80',
     2949        Mask => 0x08,
     2950        PrintConv => {
     2951            0x00 => 'Off',
     2952            0x08 => 'On',
     2953        },
     2954    },
     2955    729 => { #JD
     2956        Name => 'CustomSettingsD40',
     2957        Format => 'undef[12]',
     2958        SubDirectory => {
     2959            TagTable => 'Image::ExifTool::NikonCustom::SettingsD40',
     2960        },
     2961    },
     2962    # note: DecryptLen currently set to 748
     2963);
     2964
     2965# shot information for D80 (encrypted) - ref JD
     2966%Image::ExifTool::Nikon::ShotInfoD80 = (
     2967    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     2968    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     2969    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     2970    VARS => { ID_LABEL => 'Index' },
     2971    IS_SUBDIR => [ 748 ],
     2972    WRITABLE => 1,
     2973    FIRST_ENTRY => 0,
     2974    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2975    NOTES => 'These tags are extracted from encrypted data in D80 images.',
     2976    0x00 => {
     2977        Name => 'ShotInfoVersion',
     2978        Format => 'string[4]',
     2979        Writable => 0,
     2980    },
     2981    586 => {
     2982        Name => 'ShutterCount',
     2983        Format => 'int32u',
     2984        Priority => 0,
     2985    },
     2986    # split 590 into a few different tags
     2987    590.1 => {
     2988        Name => 'Rotation',
     2989        Mask => 0x07,
     2990        PrintConv => {
     2991            0x00 => 'Horizontal',
     2992            0x01 => 'Rotated 270 CW',
     2993            0x02 => 'Rotated 90 CW',
     2994            0x03 => 'Rotated 180',
     2995        },
     2996    },
     2997    590.2 => {
     2998        Name => 'VibrationReduction',
     2999        Mask => 0x18,
     3000        PrintConv => {
     3001            0x00 => 'Off',
     3002            0x18 => 'On',
     3003        },
     3004    },
     3005    590.3 => {
     3006        Name => 'FlashFired',
     3007        Mask => 0xe0,
     3008        PrintConv => { BITMASK => {
     3009            6 => 'Internal',
     3010            7 => 'External',
     3011        }},
     3012    },
     3013    708 => {
     3014        Name => 'NikonImageSize',
     3015        Mask => 0xf0,
     3016        PrintConv => {
     3017            0x00 => 'Large (10.0 M)',
     3018            0x10 => 'Medium (5.6 M)',
     3019            0x20 => 'Small (2.5 M)',
     3020        },
     3021    },
     3022    708.1 => {
     3023        Name => 'ImageQuality',
     3024        Mask => 0x0f,
     3025        PrintConv => {
     3026            0 => 'NEF (RAW)',
     3027            1 => 'JPEG Fine',
     3028            2 => 'JPEG Normal',
     3029            3 => 'JPEG Basic',
     3030            4 => 'NEF (RAW) + JPEG Fine',
     3031            5 => 'NEF (RAW) + JPEG Normal',
     3032            6 => 'NEF (RAW) + JPEG Basic',
     3033        },
     3034    },
     3035    748 => { #JD
     3036        Name => 'CustomSettingsD80',
     3037        Format => 'undef[17]',
     3038        SubDirectory => {
     3039            TagTable => 'Image::ExifTool::NikonCustom::SettingsD80',
     3040        },
     3041    },
     3042    # note: DecryptLen currently set to 764
     3043);
     3044
     3045# shot information for D90 (encrypted) - ref PH
     3046%Image::ExifTool::Nikon::ShotInfoD90 = (
     3047    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3048    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3049    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3050    VARS => { ID_LABEL => 'Index' },
     3051    IS_SUBDIR => [ 0x374 ],
     3052    WRITABLE => 1,
     3053    FIRST_ENTRY => 0,
     3054    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3055    NOTES => q{
     3056        These tags are extracted from encrypted data in images from the D90 with
     3057        firmware 1.00.
     3058    },
     3059    0x00 => {
     3060        Name => 'ShotInfoVersion',
     3061        Format => 'string[4]',
     3062        Writable => 0,
     3063    },
     3064    0x04 => {
     3065        Name => 'FirmwareVersion',
     3066        Format => 'string[5]',
     3067        Writable => 0,
     3068    },
     3069    0x2b5 => { #JD (same value found at offset 0x39, 0x2bf, 0x346)
     3070        Name => 'ISO2',
     3071        ValueConv => '100*exp(($val/12-5)*log(2))',
     3072        ValueConvInv => '(log($val/100)/log(2)+5)*12',
     3073        PrintConv => 'int($val + 0.5)',
     3074        PrintConvInv => '$val',
     3075    },
     3076    0x2d5 => {
     3077        Name => 'ShutterCount',
     3078        Format => 'int32u',
     3079        Priority => 0,
     3080    },
     3081    0x374 => {
     3082        Name => 'CustomSettingsD90',
     3083        Format => 'undef[36]',
     3084        SubDirectory => {
     3085            TagTable => 'Image::ExifTool::NikonCustom::SettingsD90',
     3086        },
     3087    },
     3088    # note: DecryptLen currently set to 0x398
     3089);
     3090
     3091# shot information for the D3 firmware 0.37 and 1.00 (encrypted) - ref PH
     3092%Image::ExifTool::Nikon::ShotInfoD3a = (
     3093    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3094    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3095    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3096    VARS => { ID_LABEL => 'Index' },
     3097    IS_SUBDIR => [ 0x301 ],
     3098    WRITABLE => 1,
     3099    FIRST_ENTRY => 0,
     3100    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3101    NOTES => q{
     3102        These tags are extracted from encrypted data in images from the D3 with
     3103        firmware 1.00 and earlier.
     3104    },
     3105    0x00 => {
     3106        Name => 'ShotInfoVersion',
     3107        Format => 'string[4]',
     3108        Writable => 0,
     3109    },
     3110    0x256 => { #JD (same value found at offset 0x26b)
     3111        Name => 'ISO2',
     3112        ValueConv => '100*exp(($val/12-5)*log(2))',
     3113        ValueConvInv => '(log($val/100)/log(2)+5)*12',
     3114        PrintConv => 'int($val + 0.5)',
     3115        PrintConvInv => '$val',
     3116    },
     3117    0x276 => { #JD
     3118        Name => 'ShutterCount',
     3119        Format => 'int32u',
     3120        Priority => 0,
     3121    },
     3122    723.1 => {
     3123        Name => 'NikonImageSize',
     3124        Mask => 0x18,
     3125        PrintConv => {
     3126            0x00 => 'Large',
     3127            0x08 => 'Medium',
     3128            0x10 => 'Small',
     3129        },
     3130    },
     3131    723.2 => {
     3132        Name => 'ImageQuality',
     3133        Mask => 0x07,
     3134        PrintConv => {
     3135            0 => 'NEF (RAW) + JPEG Fine',
     3136            1 => 'NEF (RAW) + JPEG Norm',
     3137            2 => 'NEF (RAW) + JPEG Basic',
     3138            3 => 'NEF (RAW)',
     3139            4 => 'TIF (RGB)',
     3140            5 => 'JPEG Fine',
     3141            6 => 'JPEG Normal',
     3142            7 => 'JPEG Basic',
     3143        },
     3144    },
     3145    0x301 => { #(NC)
     3146        Name => 'CustomSettingsD3',
     3147        Format => 'undef[24]',
     3148        SubDirectory => {
     3149            TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
     3150        },
     3151    },
     3152    # note: DecryptLen currently set to 0x318
     3153);
     3154
     3155# shot information for the D3 firmware 1.10, 2.00 and 2.01 (encrypted) - ref PH
     3156%Image::ExifTool::Nikon::ShotInfoD3b = (
     3157    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3158    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3159    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3160    VARS => { ID_LABEL => 'Index' },
     3161    IS_SUBDIR => [ 0x30a ],
     3162    WRITABLE => 1,
     3163    FIRST_ENTRY => 0,
     3164    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3165    DATAMEMBER => [ 4 ],
     3166    NOTES => q{
     3167        These tags are extracted from encrypted data in images from the D3 with
     3168        firmware 1.10, 2.00, 2.01 and 2.02.
     3169    },
     3170    0x00 => {
     3171        Name => 'ShotInfoVersion',
     3172        Format => 'string[4]',
     3173        Writable => 0,
     3174    },
     3175    0x04 => {
     3176        Name => 'FirmwareVersion',
     3177        Format => 'string[5]',
     3178        Writable => 0,
     3179        RawConv => '$$self{FirmwareVersion} = $val',
     3180    },
     3181    0x10 => { #28
     3182        Name => 'ImageArea',
     3183        PrintConv => {
     3184            0 => 'FX (36.0 x 23.9 mm)',
     3185            1 => 'DX (23.5 x 15.6 mm)',
     3186            2 => '5:4 (30.0 x 23.9 mm)',
     3187        },
     3188    },
     3189    0x25d => {
     3190        Name => 'ISO2',
     3191        ValueConv => '100*exp(($val/12-5)*log(2))',
     3192        ValueConvInv => '(log($val/100)/log(2)+5)*12',
     3193        PrintConv => 'int($val + 0.5)',
     3194        PrintConvInv => '$val',
     3195    },
     3196    0x27d => {
     3197        Name => 'ShutterCount',
     3198        Condition => '$$self{FirmwareVersion} =~ /^1.01/',
     3199        Notes => 'firmware 1.10',
     3200        Format => 'int32u',
     3201        Priority => 0,
     3202    },
     3203    0x27f => {
     3204        Name => 'ShutterCount',
     3205        Condition => '$$self{FirmwareVersion} =~ /^2.0[012]/',
     3206        Notes => 'firmware 2.00, 2.01 and 2.02',
     3207        Format => 'int32u',
     3208        Priority => 0,
     3209    },
     3210    732.1 => { #28
     3211        Name => 'NikonImageSize',
     3212        Mask => 0x18,
     3213        PrintConv => {
     3214            0x00 => 'Large',
     3215            0x08 => 'Medium',
     3216            0x10 => 'Small',
     3217        },
     3218    },
     3219    732.2 => { #28
     3220        Name => 'ImageQuality',
     3221        Mask => 0x07,
     3222        PrintConv => {
     3223            0 => 'NEF (RAW) + JPEG Fine',
     3224            1 => 'NEF (RAW) + JPEG Norm',
     3225            2 => 'NEF (RAW) + JPEG Basic',
     3226            3 => 'NEF (RAW)',
     3227            4 => 'TIF (RGB)',
     3228            5 => 'JPEG Fine',
     3229            6 => 'JPEG Normal',
     3230            7 => 'JPEG Basic',
     3231        },
     3232    },
     3233    0x28a => { #28
     3234        Name => 'PreFlashReturnStrength',
     3235        Notes => 'valid in TTL and TTL-BL flash control modes',
     3236        # this is used to set the flash power using this relationship
     3237        # for the SB-800 and SB-900:
     3238        # $val < 140 ? 2**(0.08372*$val-12.352) : $val
     3239    },
     3240    0x30a => { # tested with firmware 2.00
     3241        Name => 'CustomSettingsD3',
     3242        Format => 'undef[24]',
     3243        SubDirectory => {
     3244            TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
     3245        },
     3246    },
     3247    # note: DecryptLen currently set to 0x321
     3248);
     3249
     3250# shot information for the D3X firmware 1.00 (encrypted) - ref PH
     3251%Image::ExifTool::Nikon::ShotInfoD3X = (
     3252    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3253    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3254    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3255    VARS => { ID_LABEL => 'Index' },
     3256    IS_SUBDIR => [ 0x30b ],
     3257    WRITABLE => 1,
     3258    FIRST_ENTRY => 0,
     3259    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3260    NOTES => q{
     3261        These tags are extracted from encrypted data in images from the D3X with
     3262        firmware 1.00.
     3263    },
     3264    0x00 => {
     3265        Name => 'ShotInfoVersion',
     3266        Format => 'string[4]',
     3267        Writable => 0,
     3268    },
     3269    0x04 => {
     3270        Name => 'FirmwareVersion',
     3271        Format => 'string[5]',
     3272        Writable => 0,
     3273    },
     3274    0x25d => {
     3275        Name => 'ISO2',
     3276        ValueConv => '100*exp(($val/12-5)*log(2))',
     3277        ValueConvInv => '(log($val/100)/log(2)+5)*12',
     3278        PrintConv => 'int($val + 0.5)',
     3279        PrintConvInv => '$val',
     3280    },
     3281    0x280 => {
     3282        Name => 'ShutterCount',
     3283        Format => 'int32u',
     3284        Priority => 0,
     3285    },
     3286    0x30b => { #(NC)
     3287        Name => 'CustomSettingsD3X',
     3288        Format => 'undef[24]',
     3289        SubDirectory => {
     3290            TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
     3291        },
     3292    },
     3293    # note: DecryptLen currently set to 0x323
     3294);
     3295
     3296# shot information for the D3S firmware 0.16 and 1.00 (encrypted) - ref PH
     3297%Image::ExifTool::Nikon::ShotInfoD3S = (
     3298    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3299    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3300    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3301    VARS => { ID_LABEL => 'Index' },
     3302    IS_SUBDIR => [ 0x2ce ],
     3303    WRITABLE => 1,
     3304    FIRST_ENTRY => 0,
     3305    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3306    NOTES => q{
     3307        These tags are extracted from encrypted data in images from the D3S with
     3308        firmware 1.00 and earlier.
     3309    },
     3310    0x00 => {
     3311        Name => 'ShotInfoVersion',
     3312        Format => 'string[4]',
     3313        Writable => 0,
     3314    },
     3315    0x04 => {
     3316        Name => 'FirmwareVersion',
     3317        Format => 'string[5]',
     3318        Writable => 0,
     3319    },
     3320    0x10 => { #28
     3321        Name => 'ImageArea',
     3322        PrintConv => {
     3323            0 => 'FX (36x24)',
     3324            1 => 'DX (24x16)',
     3325            2 => '5:4 (30x24)',
     3326            3 => '1.2x (30x20)',
     3327        },
     3328    },
     3329    0x221 => {
     3330        Name => 'ISO2',
     3331        ValueConv => '100*exp(($val/12-5)*log(2))',
     3332        ValueConvInv => '(log($val/100)/log(2)+5)*12',
     3333        PrintConv => 'int($val + 0.5)',
     3334        PrintConvInv => '$val',
     3335    },
     3336    0x242 => {
     3337        Name => 'ShutterCount',
     3338        Format => 'int32u',
     3339        Priority => 0,
     3340    },
     3341    0x2ce => { #(NC)
     3342        Name => 'CustomSettingsD3S',
     3343        Format => 'undef[24]',
     3344        SubDirectory => {
     3345            TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
     3346        },
     3347    },
     3348    # note: DecryptLen currently set to 0x2e6
     3349);
     3350
     3351# shot information for the D300 firmware 1.00 (encrypted) - ref JD
     3352%Image::ExifTool::Nikon::ShotInfoD300a = (
     3353    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3354    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3355    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3356    VARS => { ID_LABEL => 'Index' },
     3357    IS_SUBDIR => [ 790 ],
     3358    WRITABLE => 1,
     3359    FIRST_ENTRY => 0,
     3360    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3361    NOTES => q{
     3362        These tags are extracted from encrypted data in images from the D300 with
     3363        firmware 1.00 and earlier.
     3364    },
     3365    0x00 => {
     3366        Name => 'ShotInfoVersion',
     3367        Format => 'string[4]',
     3368        Writable => 0,
     3369    },
     3370    604 => {
     3371        Name => 'ISO2',
     3372        ValueConv => '100*exp(($val/12-5)*log(2))',
     3373        ValueConvInv => '(log($val/100)/log(2)+5)*12',
     3374        PrintConv => 'int($val + 0.5)',
     3375        PrintConvInv => '$val',
     3376    },
     3377    633 => {
     3378        Name => 'ShutterCount',
     3379        Format => 'int32u',
     3380        Priority => 0,
     3381    },
     3382    721 => { #PH
     3383        Name => 'AFFineTuneAdj',
     3384        Format => 'int16u',
    12993385        PrintHex => 1,
     3386        PrintConvColumns => 3,
     3387        # thanks to Neil Nappe for the samples to decode this!...
     3388        # (have seen various unknown values here when flash is enabled, but
     3389        # these are yet to be decoded: 0x2e,0x619,0xd0d,0x103a,0x2029 - PH)
    13003390        PrintConv => {
    1301             0x00 => 'Off, Horizontal',
    1302             0x01 => 'Off, Rotated 270 CW',
    1303             0x02 => 'Off, Rotated 90 CW',
    1304             0x03 => 'Off, Rotated 180',
    1305             0x18 => 'On, Horizontal',
    1306             0x19 => 'On, Rotated 270 CW',
    1307             0x1a => 'On, Rotated 90 CW',
    1308             0x1b => 'On, Rotated 180',
    1309         },
    1310     },
    1311     # note: DecryptLen currently set to 0x24e
     3391            0x403e => '+20',
     3392            0x303e => '+19',
     3393            0x203e => '+18',
     3394            0x103e => '+17',
     3395            0x003e => '+16',
     3396            0xe03d => '+15',
     3397            0xc03d => '+14',
     3398            0xa03d => '+13',
     3399            0x803d => '+12',
     3400            0x603d => '+11',
     3401            0x403d => '+10',
     3402            0x203d => '+9',
     3403            0x003d => '+8',
     3404            0xc03c => '+7',
     3405            0x803c => '+6',
     3406            0x403c => '+5',
     3407            0x003c => '+4',
     3408            0x803b => '+3',
     3409            0x003b => '+2',
     3410            0x003a => '+1',
     3411            0x0000 => '0',
     3412            0x00c6 => '-1',
     3413            0x00c5 => '-2',
     3414            0x80c5 => '-3',
     3415            0x00c4 => '-4',
     3416            0x40c4 => '-5',
     3417            0x80c4 => '-6',
     3418            0xc0c4 => '-7',
     3419            0x00c3 => '-8',
     3420            0x20c3 => '-9',
     3421            0x40c3 => '-10',
     3422            0x60c3 => '-11',
     3423            0x80c3 => '-12',
     3424            0xa0c3 => '-13',
     3425            0xc0c3 => '-14',
     3426            0xe0c3 => '-15',
     3427            0x00c2 => '-16',
     3428            0x10c2 => '-17',
     3429            0x20c2 => '-18',
     3430            0x30c2 => '-19',
     3431            0x40c2 => '-20',
     3432        },
     3433    },
     3434    790 => {
     3435        Name => 'CustomSettingsD300',
     3436        Format => 'undef[24]',
     3437        SubDirectory => {
     3438            TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
     3439        },
     3440    },
     3441    # note: DecryptLen currently set to 813
     3442);
     3443
     3444# shot information for the D300 firmware 1.10 (encrypted) - ref PH
     3445%Image::ExifTool::Nikon::ShotInfoD300b = (
     3446    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3447    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3448    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3449    VARS => { ID_LABEL => 'Index' },
     3450    IS_SUBDIR => [ 802 ],
     3451    WRITABLE => 1,
     3452    FIRST_ENTRY => 0,
     3453    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3454    NOTES => q{
     3455        These tags are extracted from encrypted data in images from the D300 with
     3456        firmware 1.10.
     3457    },
     3458    0x00 => {
     3459        Name => 'ShotInfoVersion',
     3460        Format => 'string[4]',
     3461        Writable => 0,
     3462    },
     3463    0x04 => { #PH
     3464        Name => 'FirmwareVersion',
     3465        Format => 'string[5]',
     3466        Writable => 0,
     3467    },
     3468    613 => {
     3469        Name => 'ISO2',
     3470        ValueConv => '100*exp(($val/12-5)*log(2))',
     3471        ValueConvInv => '(log($val/100)/log(2)+5)*12',
     3472        PrintConv => 'int($val + 0.5)',
     3473        PrintConvInv => '$val',
     3474    },
     3475    644 => {
     3476        Name => 'ShutterCount',
     3477        Format => 'int32u',
     3478        Priority => 0,
     3479    },
     3480    732 => {
     3481        Name => 'AFFineTuneAdj',
     3482        Format => 'int16u',
     3483        PrintHex => 1,
     3484        PrintConvColumns => 3,
     3485        # thanks to Stuart Solomon for the samples to decode this!...
     3486        PrintConv => {
     3487            0x903e => '+20',
     3488            0x7c3e => '+19',
     3489            0x683e => '+18',
     3490            0x543e => '+17',
     3491            0x403e => '+16',
     3492            0x2c3e => '+15',
     3493            0x183e => '+14',
     3494            0x043e => '+13',
     3495            0xe03d => '+12',
     3496            0xb83d => '+11',
     3497            0x903d => '+10',
     3498            0x683d => '+9',
     3499            0x403d => '+8',
     3500            0x183d => '+7',
     3501            0xe03c => '+6',
     3502            0x903c => '+5',
     3503            0x403c => '+4',
     3504            0xe03b => '+3',
     3505            0x403b => '+2',
     3506            0x403a => '+1',
     3507            0x0000 => '0',
     3508            0x40c6 => '-1',
     3509            0x40c5 => '-2',
     3510            0xe0c5 => '-3',
     3511            0x40c4 => '-4',
     3512            0x90c4 => '-5',
     3513            0xe0c4 => '-6',
     3514            0x18c3 => '-7',
     3515            0x40c3 => '-8',
     3516            0x68c3 => '-9',
     3517            0x90c3 => '-10',
     3518            0xb8c3 => '-11',
     3519            0xe0c3 => '-12',
     3520            0x04c2 => '-13',
     3521            0x18c2 => '-14',
     3522            0x2cc2 => '-15',
     3523            0x40c2 => '-16',
     3524            0x54c2 => '-17',
     3525            0x68c2 => '-18',
     3526            0x7cc2 => '-19',
     3527            0x90c2 => '-20',
     3528        },
     3529    },
     3530    802 => {
     3531        Name => 'CustomSettingsD300',
     3532        Format => 'undef[24]',
     3533        SubDirectory => {
     3534            TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
     3535        },
     3536    },
     3537    # note: DecryptLen currently set to 825
     3538);
     3539
     3540# shot information for the D300S firmware 1.00 (encrypted) - ref PH
     3541%Image::ExifTool::Nikon::ShotInfoD300S = (
     3542    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3543    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3544    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3545    VARS => { ID_LABEL => 'Index' },
     3546    IS_SUBDIR => [ 804 ],
     3547    WRITABLE => 1,
     3548    FIRST_ENTRY => 0,
     3549    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3550    NOTES => q{
     3551        These tags are extracted from encrypted data in images from the D300S with
     3552        firmware 1.00.
     3553    },
     3554    0x00 => {
     3555        Name => 'ShotInfoVersion',
     3556        Format => 'string[4]',
     3557        Writable => 0,
     3558    },
     3559    0x04 => {
     3560        Name => 'FirmwareVersion',
     3561        Format => 'string[5]',
     3562        Writable => 0,
     3563    },
     3564    613 => {
     3565        Name => 'ISO2',
     3566        ValueConv => '100*exp(($val/12-5)*log(2))',
     3567        ValueConvInv => '(log($val/100)/log(2)+5)*12',
     3568        PrintConv => 'int($val + 0.5)',
     3569        PrintConvInv => '$val',
     3570    },
     3571    646 => {
     3572        Name => 'ShutterCount',
     3573        Format => 'int32u',
     3574        Priority => 0,
     3575    },
     3576    804 => { #(NC)
     3577        Name => 'CustomSettingsD300S',
     3578        Format => 'undef[24]',
     3579        SubDirectory => {
     3580            TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
     3581        },
     3582    },
     3583    # note: DecryptLen currently set to 827
     3584);
     3585
     3586# shot information for the D700 firmware 1.02f (encrypted) - ref 29
     3587%Image::ExifTool::Nikon::ShotInfoD700 = (
     3588    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3589    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3590    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3591    VARS => { ID_LABEL => 'Index' },
     3592    IS_SUBDIR => [ 804 ],
     3593    WRITABLE => 1,
     3594    FIRST_ENTRY => 0,
     3595    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3596    NOTES => q{
     3597        These tags are extracted from encrypted data in images from the D700 with
     3598        firmware 1.02f.
     3599    },
     3600    0x00 => {
     3601        Name => 'ShotInfoVersion',
     3602        Format => 'string[4]',
     3603        Writable => 0,
     3604    },
     3605    0x04 => {
     3606        Name => 'FirmwareVersion',
     3607        Format => 'string[5]',
     3608        Writable => 0,
     3609    },
     3610    613 => { # 0x265
     3611       Name => 'ISO2',
     3612       ValueConv => '100*exp(($val/12-5)*log(2))',
     3613       ValueConvInv => '(log($val/100)/log(2)+5)*12',
     3614       PrintConv => 'int($val + 0.5)',
     3615       PrintConvInv => '$val',
     3616    },
     3617    0x287 => {
     3618        Name => 'ShutterCount',
     3619        Format => 'int32u',
     3620        Priority => 0,
     3621    },
     3622    804 => { # 0x324 (NC)
     3623        Name => 'CustomSettingsD700',
     3624        Format => 'undef[48]',
     3625        SubDirectory => {
     3626            TagTable => 'Image::ExifTool::NikonCustom::SettingsD700',
     3627        },
     3628    },
     3629    # note: DecryptLen currently set to 852
     3630);
     3631
     3632# shot information for the D5000 firmware 1.00 (encrypted) - ref PH
     3633%Image::ExifTool::Nikon::ShotInfoD5000 = (
     3634    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3635    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3636    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3637    VARS => { ID_LABEL => 'Index' },
     3638    IS_SUBDIR => [ 0x378 ],
     3639    WRITABLE => 1,
     3640    FIRST_ENTRY => 0,
     3641    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3642    NOTES => q{
     3643        These tags are extracted from encrypted data in images from the D5000 with
     3644        firmware 1.00.
     3645    },
     3646    0x00 => {
     3647        Name => 'ShotInfoVersion',
     3648        Format => 'string[4]',
     3649        Writable => 0,
     3650    },
     3651    0x04 => {
     3652        Name => 'FirmwareVersion',
     3653        Format => 'string[5]',
     3654        Writable => 0,
     3655    },
     3656    0x2b5 => { # (also found at 0x2c0)
     3657        Name => 'ISO2',
     3658        ValueConv => '100*exp(($val/12-5)*log(2))',
     3659        ValueConvInv => '(log($val/100)/log(2)+5)*12',
     3660        PrintConv => 'int($val + 0.5)',
     3661        PrintConvInv => '$val',
     3662    },
     3663    0x2d6 => {
     3664        Name => 'ShutterCount',
     3665        Format => 'int32u',
     3666        Priority => 0,
     3667    },
     3668    0x378 => {
     3669        Name => 'CustomSettingsD5000',
     3670        Format => 'undef[34]',
     3671        SubDirectory => {
     3672            TagTable => 'Image::ExifTool::NikonCustom::SettingsD5000',
     3673        },
     3674    },
     3675    # note: DecryptLen currently set to 0x39a
     3676);
     3677
     3678# shot information for the D7000 firmware 1.01d (encrypted) - ref 29
     3679%Image::ExifTool::Nikon::ShotInfoD7000 = (
     3680    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3681    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
     3682    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3683    VARS => { ID_LABEL => 'Index' },
     3684    IS_SUBDIR => [ 1028 ],
     3685    WRITABLE => 1,
     3686    FIRST_ENTRY => 0,
     3687    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3688    NOTES => q{
     3689        These tags are extracted from encrypted data in images from the D7000 with
     3690        firmware 1.01b.
     3691    },
     3692    0x00 => {
     3693        Name => 'ShotInfoVersion',
     3694        Format => 'string[4]',
     3695        Writable => 0,
     3696    },
     3697    0x04 => {
     3698        Name => 'FirmwareVersion',
     3699        Format => 'string[5]',
     3700        Writable => 0,
     3701    },
     3702    #613 => {
     3703    #    Name => 'ISO2',
     3704    #    ValueConv => '100*exp(($val/12-5)*log(2))',
     3705    #    ValueConvInv => '(log($val/100)/log(2)+5)*12',
     3706    #    PrintConv => 'int($val + 0.5)',
     3707    #    PrintConvInv => '$val',
     3708    #},
     3709    0x320 => { # 800
     3710        Name => 'ShutterCount',
     3711        Format => 'int32u',
     3712        Priority => 0,
     3713    },
     3714    0x404 => { # 1028 (NC)
     3715        Name => 'CustomSettingsD7000',
     3716        Format => 'undef[48]',
     3717        SubDirectory => {
     3718            TagTable => 'Image::ExifTool::NikonCustom::SettingsD7000',
     3719        },
     3720    },
     3721);
     3722
     3723# Flash information (ref JD)
     3724%Image::ExifTool::Nikon::FlashInfo0100 = (
     3725    %binaryDataAttrs,
     3726    DATAMEMBER => [ 9.2, 15, 16 ],
     3727    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3728    NOTES => q{
     3729        These tags are used by the D2H, D2Hs, D2X, D2Xs, D50, D70, D70s, D80 and
     3730        D200.
     3731    },
     3732    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
     3733    0 => {
     3734        Name => 'FlashInfoVersion',
     3735        Format => 'string[4]',
     3736        Writable => 0,
     3737    },
     3738    4 => { #PH
     3739        Name => 'FlashSource',
     3740        PrintConv => {
     3741            0 => 'None',
     3742            1 => 'External',
     3743            2 => 'Internal',
     3744        },
     3745    },
     3746    # 5 - values: 46,48,50,54,78
     3747    6 => {
     3748        Format => 'int8u[2]',
     3749        Name => 'ExternalFlashFirmware',
     3750        SeparateTable => 'FlashFirmware',
     3751        PrintConv => \%flashFirmware,
     3752    },
     3753    8 => {
     3754        Name => 'ExternalFlashFlags',
     3755        PrintConv => { BITMASK => {
     3756            0 => 'Fired', #28
     3757            2 => 'Bounce Flash', #PH
     3758            4 => 'Wide Flash Adapter',
     3759            5 => 'Dome Diffuser', #28
     3760        }},
     3761    },
     3762    9.1 => {
     3763        Name => 'FlashCommanderMode',
     3764        Mask => 0x80,
     3765        PrintConv => {
     3766            0x00 => 'Off',
     3767            0x80 => 'On',
     3768        },
     3769    },
     3770    9.2 => {
     3771        Name => 'FlashControlMode',
     3772        Mask => 0x7f,
     3773        DataMember => 'FlashControlMode',
     3774        RawConv => '$$self{FlashControlMode} = $val',
     3775        PrintConv => \%flashControlMode,
     3776        SeparateTable => 'FlashControlMode',
     3777    },
     3778    10 => [
     3779        {
     3780            Name => 'FlashOutput',
     3781            Condition => '$$self{FlashControlMode} >= 0x06',
     3782            ValueConv => '2 ** (-$val/6)',
     3783            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
     3784            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
     3785            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
     3786        },
     3787        {
     3788            Name => 'FlashCompensation',
     3789            Format => 'int8s',
     3790            Priority => 0,
     3791            ValueConv => '-$val/6',
     3792            ValueConvInv => '-6 * $val',
     3793            PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     3794            PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     3795        },
     3796    ],
     3797    11 => {
     3798        Name => 'FlashFocalLength',
     3799        RawConv => '$val ? $val : undef',
     3800        PrintConv => '"$val mm"',
     3801        PrintConvInv => '$val=~/(\d+)/; $1 || 0',
     3802    },
     3803    12 => {
     3804        Name => 'RepeatingFlashRate',
     3805        RawConv => '$val ? $val : undef',
     3806        PrintConv => '"$val Hz"',
     3807        PrintConvInv => '$val=~/(\d+)/; $1 || 0',
     3808    },
     3809    13 => {
     3810        Name => 'RepeatingFlashCount',
     3811        RawConv => '$val ? $val : undef',
     3812    },
     3813    14 => { #PH
     3814        Name => 'FlashGNDistance',
     3815        SeparateTable => 1,
     3816        PrintConv => \%flashGNDistance,
     3817    },
     3818    15 => {
     3819        Name => 'FlashGroupAControlMode',
     3820        Mask => 0x0f,
     3821        DataMember => 'FlashGroupAControlMode',
     3822        RawConv => '$$self{FlashGroupAControlMode} = $val',
     3823        PrintConv => \%flashControlMode,
     3824        SeparateTable => 'FlashControlMode',
     3825    },
     3826    16 => {
     3827        Name => 'FlashGroupBControlMode',
     3828        Mask => 0x0f,
     3829        DataMember => 'FlashGroupBControlMode',
     3830        RawConv => '$$self{FlashGroupBControlMode} = $val',
     3831        PrintConv => \%flashControlMode,
     3832        SeparateTable => 'FlashControlMode',
     3833    },
     3834    17 => [
     3835        {
     3836            Name => 'FlashGroupAOutput',
     3837            Condition => '$$self{FlashGroupAControlMode} >= 0x06',
     3838            ValueConv => '2 ** (-$val/6)',
     3839            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
     3840            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
     3841            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
     3842        },
     3843        {
     3844            Name => 'FlashGroupACompensation',
     3845            Format => 'int8s',
     3846            ValueConv => '-$val/6',
     3847            ValueConvInv => '-6 * $val',
     3848            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
     3849            PrintConvInv => '$val',
     3850        },
     3851    ],
     3852    18 => [
     3853        {
     3854            Name => 'FlashGroupBOutput',
     3855            Condition => '$$self{FlashGroupBControlMode} >= 0x06',
     3856            ValueConv => '2 ** (-$val/6)',
     3857            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
     3858            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
     3859            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
     3860        },
     3861        {
     3862            Name => 'FlashGroupBCompensation',
     3863            Format => 'int8s',
     3864            ValueConv => '-$val/6',
     3865            ValueConvInv => '-6 * $val',
     3866            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
     3867            PrintConvInv => '$val',
     3868        },
     3869    ],
     3870);
     3871
     3872# Flash information for D40, D40x, D3 and D300 (ref JD)
     3873%Image::ExifTool::Nikon::FlashInfo0102 = (
     3874    %binaryDataAttrs,
     3875    DATAMEMBER => [ 9.2, 16.1, 17.1, 17.2 ],
     3876    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3877    NOTES => q{
     3878        These tags are used by the D3 (firmware 1.x), D40, D40X, D60 and D300
     3879        (firmware 1.00).
     3880    },
     3881    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
     3882    0 => {
     3883        Name => 'FlashInfoVersion',
     3884        Format => 'string[4]',
     3885        Writable => 0,
     3886    },
     3887    4 => { #PH
     3888        Name => 'FlashSource',
     3889        PrintConv => {
     3890            0 => 'None',
     3891            1 => 'External',
     3892            2 => 'Internal',
     3893        },
     3894    },
     3895    # 5 - values: 46,48,50,54,78
     3896    6 => {
     3897        Format => 'int8u[2]',
     3898        Name => 'ExternalFlashFirmware',
     3899        SeparateTable => 'FlashFirmware',
     3900        PrintConv => \%flashFirmware,
     3901    },
     3902    8 => {
     3903        Name => 'ExternalFlashFlags',
     3904        PrintConv => { BITMASK => {
     3905            0 => 'Fired', #28
     3906            2 => 'Bounce Flash', #PH
     3907            4 => 'Wide Flash Adapter',
     3908            5 => 'Dome Diffuser', #28
     3909        }},
     3910    },
     3911    9.1 => {
     3912        Name => 'FlashCommanderMode',
     3913        Mask => 0x80,
     3914        PrintConv => {
     3915            0x00 => 'Off',
     3916            0x80 => 'On',
     3917        },
     3918    },
     3919    9.2 => {
     3920        Name => 'FlashControlMode',
     3921        Mask => 0x7f,
     3922        DataMember => 'FlashControlMode',
     3923        RawConv => '$$self{FlashControlMode} = $val',
     3924        PrintConv => \%flashControlMode,
     3925        SeparateTable => 'FlashControlMode',
     3926    },
     3927    10 => [
     3928        {
     3929            Name => 'FlashOutput',
     3930            Condition => '$$self{FlashControlMode} >= 0x06',
     3931            ValueConv => '2 ** (-$val/6)',
     3932            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
     3933            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
     3934            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
     3935        },
     3936        {
     3937            Name => 'FlashCompensation',
     3938            # this is the compensation from the camera (0x0012) for "Built-in" FlashType, or
     3939            # the compensation from the external unit (0x0017) for "Optional" FlashType - PH
     3940            Format => 'int8s',
     3941            Priority => 0,
     3942            ValueConv => '-$val/6',
     3943            ValueConvInv => '-6 * $val',
     3944            PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     3945            PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     3946        },
     3947    ],
     3948    12 => {
     3949        Name => 'FlashFocalLength',
     3950        RawConv => '$val ? $val : undef',
     3951        PrintConv => '"$val mm"',
     3952        PrintConvInv => '$val=~/(\d+)/; $1 || 0',
     3953    },
     3954    13 => {
     3955        Name => 'RepeatingFlashRate',
     3956        RawConv => '$val ? $val : undef',
     3957        PrintConv => '"$val Hz"',
     3958        PrintConvInv => '$val=~/(\d+)/; $1 || 0',
     3959    },
     3960    14 => {
     3961        Name => 'RepeatingFlashCount',
     3962        RawConv => '$val ? $val : undef',
     3963    },
     3964    15 => { #PH
     3965        Name => 'FlashGNDistance',
     3966        SeparateTable => 1,
     3967        PrintConv => \%flashGNDistance,
     3968    },
     3969    16.1 => {
     3970        Name => 'FlashGroupAControlMode',
     3971        Mask => 0x0f,
     3972        Notes => 'note: group A tags may apply to the built-in flash settings for some models',
     3973        DataMember => 'FlashGroupAControlMode',
     3974        RawConv => '$$self{FlashGroupAControlMode} = $val',
     3975        PrintConv => \%flashControlMode,
     3976        SeparateTable => 'FlashControlMode',
     3977    },
     3978    17.1 => {
     3979        Name => 'FlashGroupBControlMode',
     3980        Mask => 0xf0,
     3981        Notes => 'note: group B tags may apply to group A settings for some models',
     3982        DataMember => 'FlashGroupBControlMode',
     3983        RawConv => '$$self{FlashGroupBControlMode} = $val',
     3984        ValueConv => '$val >> 4',
     3985        ValueConvInv => '$val << 4',
     3986        PrintConv => \%flashControlMode,
     3987        SeparateTable => 'FlashControlMode',
     3988    },
     3989    17.2 => { #PH
     3990        Name => 'FlashGroupCControlMode',
     3991        Mask => 0x0f,
     3992        Notes => 'note: group C tags may apply to group B settings for some models',
     3993        DataMember => 'FlashGroupCControlMode',
     3994        RawConv => '$$self{FlashGroupCControlMode} = $val',
     3995        PrintConv => \%flashControlMode,
     3996        SeparateTable => 'FlashControlMode',
     3997    },
     3998    18 => [
     3999        {
     4000            Name => 'FlashGroupAOutput',
     4001            Condition => '$$self{FlashGroupAControlMode} >= 0x06',
     4002            ValueConv => '2 ** (-$val/6)',
     4003            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
     4004            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
     4005            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
     4006        },
     4007        {
     4008            Name => 'FlashGroupACompensation',
     4009            Format => 'int8s',
     4010            ValueConv => '-$val/6',
     4011            ValueConvInv => '-6 * $val',
     4012            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
     4013            PrintConvInv => '$val',
     4014        },
     4015    ],
     4016    19 => [
     4017        {
     4018            Name => 'FlashGroupBOutput',
     4019            Condition => '$$self{FlashGroupBControlMode} >= 0x60',
     4020            ValueConv => '2 ** (-$val/6)',
     4021            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
     4022            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
     4023            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
     4024        },
     4025        {
     4026            Name => 'FlashGroupBCompensation',
     4027            Format => 'int8s',
     4028            ValueConv => '-$val/6',
     4029            ValueConvInv => '-6 * $val',
     4030            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
     4031            PrintConvInv => '$val',
     4032        },
     4033    ],
     4034    20 => [ #PH
     4035        {
     4036            Name => 'FlashGroupCOutput',
     4037            Condition => '$$self{FlashGroupCControlMode} >= 0x06',
     4038            ValueConv => '2 ** (-$val/6)',
     4039            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
     4040            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
     4041            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
     4042        },
     4043        {
     4044            Name => 'FlashGroupCCompensation',
     4045            Format => 'int8s',
     4046            ValueConv => '-$val/6',
     4047            ValueConvInv => '-6 * $val',
     4048            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
     4049            PrintConvInv => '$val',
     4050        },
     4051    ],
     4052);
     4053
     4054# Flash information for D90 and D700 (ref PH)
     4055%Image::ExifTool::Nikon::FlashInfo0103 = (
     4056    %binaryDataAttrs,
     4057    DATAMEMBER => [ 9.2, 17.1, 18.1, 18.2 ],
     4058    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4059    NOTES => q{
     4060        These tags are used by the D3 (firmware 2.x), D3X, D3S, D90, D300 (firmware
     4061        1.10), D300S, D700, D3000 and D5000.
     4062    },
     4063    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
     4064    0 => {
     4065        Name => 'FlashInfoVersion',
     4066        Format => 'string[4]',
     4067        Writable => 0,
     4068    },
     4069    4 => { #PH
     4070        Name => 'FlashSource',
     4071        PrintConv => {
     4072            0 => 'None',
     4073            1 => 'External',
     4074            2 => 'Internal',
     4075        },
     4076    },
     4077    # 5 - values: 46,48,50,54,78
     4078    6 => {
     4079        Format => 'int8u[2]',
     4080        Name => 'ExternalFlashFirmware',
     4081        SeparateTable => 'FlashFirmware',
     4082        PrintConv => \%flashFirmware,
     4083    },
     4084    8 => {
     4085        Name => 'ExternalFlashFlags',
     4086        PrintConv => { BITMASK => {
     4087            0 => 'Fired', #28
     4088            2 => 'Bounce Flash', #PH
     4089            4 => 'Wide Flash Adapter',
     4090            5 => 'Dome Diffuser', #28
     4091        }},
     4092    },
     4093    9.1 => {
     4094        Name => 'FlashCommanderMode',
     4095        Mask => 0x80,
     4096        PrintConv => {
     4097            0x00 => 'Off',
     4098            0x80 => 'On',
     4099        },
     4100    },
     4101    9.2 => {
     4102        Name => 'FlashControlMode',
     4103        Mask => 0x7f,
     4104        DataMember => 'FlashControlMode',
     4105        RawConv => '$$self{FlashControlMode} = $val',
     4106        PrintConv => \%flashControlMode,
     4107        SeparateTable => 'FlashControlMode',
     4108    },
     4109    10 => [
     4110        {
     4111            Name => 'FlashOutput',
     4112            Condition => '$$self{FlashControlMode} >= 0x06',
     4113            ValueConv => '2 ** (-$val/6)',
     4114            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
     4115            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
     4116            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
     4117        },
     4118        {
     4119            Name => 'FlashCompensation',
     4120            # this is the compensation from the camera (0x0012) for "Built-in" FlashType, or
     4121            # the compensation from the external unit (0x0017) for "Optional" FlashType - PH
     4122            Format => 'int8s',
     4123            Priority => 0,
     4124            ValueConv => '-$val/6',
     4125            ValueConvInv => '-6 * $val',
     4126            PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     4127            PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     4128        },
     4129    ],
     4130    12 => { #JD
     4131        Name => 'FlashFocalLength',
     4132        RawConv => '($val and $val != 255) ? $val : undef',
     4133        PrintConv => '"$val mm"',
     4134        PrintConvInv => '$val=~/(\d+)/; $1 || 0',
     4135    },
     4136    13 => { #JD
     4137        Name => 'RepeatingFlashRate',
     4138        RawConv => '($val and $val != 255) ? $val : undef',
     4139        PrintConv => '"$val Hz"',
     4140        PrintConvInv => '$val=~/(\d+)/; $1 || 0',
     4141    },
     4142    14 => { #JD
     4143        Name => 'RepeatingFlashCount',
     4144        RawConv => '($val and $val != 255) ? $val : undef',
     4145    },
     4146    15 => { #28
     4147        Name => 'FlashGNDistance',
     4148        SeparateTable => 1,
     4149        PrintConv => \%flashGNDistance,
     4150    },
     4151    16 => { #28
     4152        Name => 'FlashColorFilter',
     4153        PrintConv => {
     4154            0x00 => 'None',
     4155            1 => 'FL-GL1',
     4156            2 => 'FL-GL2',
     4157            9 => 'TN-A1',
     4158            10 => 'TN-A2',
     4159            65 => 'Red',
     4160            66 => 'Blue',
     4161            67 => 'Yellow',
     4162            68 => 'Amber',
     4163        },
     4164    },
     4165    17.1 => {
     4166        Name => 'FlashGroupAControlMode',
     4167        Mask => 0x0f,
     4168        Notes => 'note: group A tags may apply to the built-in flash settings for some models',
     4169        DataMember => 'FlashGroupAControlMode',
     4170        RawConv => '$$self{FlashGroupAControlMode} = $val',
     4171        PrintConv => \%flashControlMode,
     4172        SeparateTable => 'FlashControlMode',
     4173    },
     4174    18.1 => {
     4175        Name => 'FlashGroupBControlMode',
     4176        Mask => 0xf0,
     4177        Notes => 'note: group B tags may apply to group A settings for some models',
     4178        DataMember => 'FlashGroupBControlMode',
     4179        RawConv => '$$self{FlashGroupBControlMode} = $val',
     4180        ValueConv => '$val >> 4',
     4181        ValueConvInv => '$val << 4',
     4182        PrintConv => \%flashControlMode,
     4183        SeparateTable => 'FlashControlMode',
     4184    },
     4185    18.2 => { #PH
     4186        Name => 'FlashGroupCControlMode',
     4187        Mask => 0x0f,
     4188        Notes => 'note: group C tags may apply to group B settings for some models',
     4189        DataMember => 'FlashGroupCControlMode',
     4190        RawConv => '$$self{FlashGroupCControlMode} = $val',
     4191        PrintConv => \%flashControlMode,
     4192        SeparateTable => 'FlashControlMode',
     4193    },
     4194    19 => [
     4195        {
     4196            Name => 'FlashGroupAOutput',
     4197            Condition => '$$self{FlashGroupAControlMode} >= 0x06',
     4198            ValueConv => '2 ** (-$val/6)',
     4199            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
     4200            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
     4201            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
     4202        },
     4203        {
     4204            Name => 'FlashGroupACompensation',
     4205            Format => 'int8s',
     4206            ValueConv => '-$val/6',
     4207            ValueConvInv => '-6 * $val',
     4208            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
     4209            PrintConvInv => '$val',
     4210        },
     4211    ],
     4212    20 => [
     4213        {
     4214            Name => 'FlashGroupBOutput',
     4215            Condition => '$$self{FlashGroupBControlMode} >= 0x60',
     4216            ValueConv => '2 ** (-$val/6)',
     4217            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
     4218            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
     4219            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
     4220        },
     4221        {
     4222            Name => 'FlashGroupBCompensation',
     4223            Format => 'int8s',
     4224            ValueConv => '-$val/6',
     4225            ValueConvInv => '-6 * $val',
     4226            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
     4227            PrintConvInv => '$val',
     4228        },
     4229    ],
     4230    21 => [ #PH
     4231        {
     4232            Name => 'FlashGroupCOutput',
     4233            Condition => '$$self{FlashGroupCControlMode} >= 0x06',
     4234            ValueConv => '2 ** (-$val/6)',
     4235            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
     4236            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
     4237            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
     4238        },
     4239        {
     4240            Name => 'FlashGroupCCompensation',
     4241            Format => 'int8s',
     4242            ValueConv => '-$val/6',
     4243            ValueConvInv => '-6 * $val',
     4244            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
     4245            PrintConvInv => '$val',
     4246        },
     4247    ],
     4248);
     4249
     4250# Unknown Flash information
     4251%Image::ExifTool::Nikon::FlashInfoUnknown = (
     4252    %binaryDataAttrs,
     4253    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4254    0 => {
     4255        Name => 'FlashInfoVersion',
     4256        Format => 'string[4]',
     4257        Writable => 0,
     4258    },
    13124259);
    13134260
    13144261# Multi exposure / image overlay information (ref PH)
    13154262%Image::ExifTool::Nikon::MultiExposure = (
    1316     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1317     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1318     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    1319     WRITABLE => 1,
    1320     FIRST_ENTRY => 0,
     4263    %binaryDataAttrs,
    13214264    FORMAT => 'int32u',
    13224265    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4266    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
    13234267    0 => {
    13244268        Name => 'MultiExposureVersion',
    13254269        Format => 'string[4]',
     4270        Writable => 0,
    13264271    },
    13274272    1 => {
     
    13364281    3 => {
    13374282        Name => 'MultiExposureAutoGain',
    1338         PrintConv => { 0 => 'Off', 1 => 'On' },
     4283        PrintConv => \%offOn,
    13394284    },
    13404285);
    13414286
    13424287# tags in Nikon QuickTime videos (PH - observations with Coolpix S3)
    1343 # (note: very similar to information in Pentax videos)
     4288# (similar information in Kodak,Minolta,Nikon,Olympus,Pentax and Sanyo videos)
    13444289%Image::ExifTool::Nikon::MOV = (
    13454290    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    13464291    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4292    FIRST_ENTRY => 0,
    13474293    NOTES => q{
    1348         This information is found in Nikon QT video images, and is very similar to
    1349         information found in Pentax MOV videos.
     4294        This information is found in MOV and QT videos from some Nikon cameras.
    13504295    },
    13514296    0x00 => {
    13524297        Name => 'Make',
    1353         Format => 'string[5]',
    1354         PrintConv => 'ucfirst(lc($val))',
     4298        Format => 'string[24]',
    13554299    },
    13564300    0x18 => {
     
    13594303        Format => 'string[8]',
    13604304    },
     4305    # (01 00 at offset 0x20)
    13614306    0x26 => {
    13624307        Name => 'ExposureTime',
     
    13674312    0x2a => {
    13684313        Name => 'FNumber',
    1369         Format => 'int32u',
    1370         ValueConv => '$val * 0.1',
     4314        Format => 'rational64u',
    13714315        PrintConv => 'sprintf("%.1f",$val)',
    13724316    },
    13734317    0x32 => {
    13744318        Name => 'ExposureCompensation',
    1375         Format => 'int32s',
    1376         ValueConv => '$val * 0.1',
    1377         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     4319        Format => 'rational64s',
     4320        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
    13784321    },
    13794322    0x44 => {
     
    13914334    0x48 => {
    13924335        Name => 'FocalLength',
    1393         Writable => 'int32u',
    1394         ValueConv => '$val * 0.1',
    1395         PrintConv => 'sprintf("%.1fmm",$val)',
     4336        Format => 'rational64u',
     4337        PrintConv => 'sprintf("%.1f mm",$val)',
    13964338    },
    13974339    0xaf => {
     
    14024344        Name => 'ISO',
    14034345        Format => 'int16u',
    1404     },
    1405 );
    1406 
     4346        RawConv => '$val < 50 ? undef : $val', # (not valid for Coolpix L10)
     4347    },
     4348);
     4349
     4350# Nikon metadata in AVI videos (PH)
     4351%Image::ExifTool::Nikon::AVI = (
     4352    NOTES => 'Nikon-specific RIFF tags found in AVI videos.',
     4353    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
     4354    nctg => {
     4355        Name => 'NikonTags',
     4356        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::AVITags' },
     4357    },
     4358    ncth => {
     4359        Name => 'ThumbnailImage',
     4360        Binary => 1,
     4361    },
     4362    ncvr => {
     4363        Name => 'NikonVers',
     4364        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::AVIVers' },
     4365    },
     4366    ncvw => {
     4367        Name => 'PreviewImage',
     4368        RawConv => 'length($val) ? $val : undef',
     4369        Binary => 1,
     4370    },
     4371);
     4372
     4373# version information in AVI videos (PH)
     4374%Image::ExifTool::Nikon::AVIVers = (
     4375    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
     4376    PROCESS_PROC => \&ProcessNikonAVI,
     4377    FORMAT => 'string',
     4378    0x01 => 'MakerNoteType',
     4379    0x02 => {
     4380        Name => 'MakerNoteVersion',
     4381        Format => 'int8u',
     4382        ValueConv => 'my @a = reverse split " ", $val; join ".", @a;',
     4383    },
     4384);
     4385
     4386# tags in AVI videos (PH)
     4387%Image::ExifTool::Nikon::AVITags = (
     4388    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4389    PROCESS_PROC => \&ProcessNikonAVI,
     4390    FORMAT => 'string',
     4391    NOTES => q{
     4392        These tags and the AVIVer tags below are found in proprietary-format records
     4393        of Nikon AVI videos.
     4394    },
     4395    0x03 => 'Make',
     4396    0x04 => 'Model',
     4397    0x05 => {
     4398        Name => 'Software',
     4399        Format => 'undef',
     4400        ValueConv => '$val =~ tr/\0//d; $val',
     4401    },
     4402    0x06 => 'Equipment', # "NIKON DIGITAL CAMERA"
     4403    0x07 => { # (guess)
     4404        Name => 'Orientation',
     4405        Format => 'int16u',
     4406        Groups => { 2 => 'Image' },
     4407        PrintConv => \%Image::ExifTool::Exif::orientation,
     4408    },
     4409    0x08 => {
     4410        Name => 'ExposureTime',
     4411        Format => 'rational64u',
     4412        Groups => { 2 => 'Image' },
     4413        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     4414    },
     4415    0x09 => {
     4416        Name => 'FNumber',
     4417        Format => 'rational64u',
     4418        Groups => { 2 => 'Image' },
     4419        PrintConv => 'sprintf("%.1f",$val)',
     4420    },
     4421    0x0a => {
     4422        Name => 'ExposureCompensation',
     4423        Format => 'rational64s',
     4424        Groups => { 2 => 'Image' },
     4425        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     4426    },
     4427    0x0b => {
     4428        Name => 'MaxApertureValue',
     4429        Format => 'rational64u',
     4430        ValueConv => '2 ** ($val / 2)',
     4431        PrintConv => 'sprintf("%.1f",$val)',
     4432    },
     4433    0x0c => {
     4434        Name => 'MeteringMode', # (guess)
     4435        Format => 'int16u',
     4436        PrintConv => {
     4437            0 => 'Unknown',
     4438            1 => 'Average',
     4439            2 => 'Center-weighted average',
     4440            3 => 'Spot',
     4441            4 => 'Multi-spot',
     4442            5 => 'Multi-segment',
     4443            6 => 'Partial',
     4444            255 => 'Other',
     4445        },
     4446    },
     4447    0x0d => { # val: 0
     4448        Name => 'Nikon_AVITags_0x000d',
     4449        Format => 'int16u',
     4450        Flags => [ 'Hidden', 'Unknown' ],
     4451    },
     4452    0x0e => { # val: 0
     4453        Name => 'Nikon_AVITags_0x000e',
     4454        Format => 'int16u',
     4455        Flags => [ 'Hidden', 'Unknown' ],
     4456    },
     4457    0x0f => {
     4458        Name => 'FocalLength',
     4459        Format => 'rational64u',
     4460        PrintConv => 'sprintf("%.1f mm",$val)',
     4461    },
     4462    0x10 => {
     4463        Name => 'XResolution',
     4464        Format => 'rational64u',
     4465        Groups => { 2 => 'Image' },
     4466    },
     4467    0x11 => {
     4468        Name => 'YResolution',
     4469        Format => 'rational64u',
     4470        Groups => { 2 => 'Image' },
     4471    },
     4472    0x12 => {
     4473        Name => 'ResolutionUnit',
     4474        Format => 'int16u',
     4475        Groups => { 2 => 'Image' },
     4476        PrintConv => {
     4477            1 => 'None',
     4478            2 => 'inches',
     4479            3 => 'cm',
     4480        },
     4481    },
     4482    0x13 => {
     4483        Name => 'DateTimeOriginal', # (guess)
     4484        Description => 'Date/Time Original',
     4485        Groups => { 2 => 'Time' },
     4486        PrintConv => '$self->ConvertDateTime($val)',
     4487    },
     4488    0x14 => {
     4489        Name => 'CreateDate', # (guess)
     4490        Groups => { 2 => 'Time' },
     4491        PrintConv => '$self->ConvertDateTime($val)',
     4492    },
     4493    0x15 => {
     4494        Name => 'Nikon_AVITags_0x0015',
     4495        Format => 'int16u',
     4496        Flags => [ 'Hidden', 'Unknown' ],
     4497    },
     4498    0x16 => {
     4499        Name => 'Duration',
     4500        Format => 'rational64u',
     4501        PrintConv => '"$val s"',
     4502    },
     4503    0x17 => { # val: 1
     4504        Name => 'Nikon_AVITags_0x0017',
     4505        Format => 'int16u',
     4506        Flags => [ 'Hidden', 'Unknown' ],
     4507    },
     4508    0x18 => 'FocusMode',
     4509    0x19 => { # vals: -5, -2, 3, 5, 6, 8, 11, 12, 14, 20, 22
     4510        Name => 'Nikon_AVITags_0x0019',
     4511        Format => 'int32s',
     4512        Flags => [ 'Hidden', 'Unknown' ],
     4513    },
     4514    0x1b => { # vals: 1 (640x480), 1.25 (320x240)
     4515        Name => 'DigitalZoom',
     4516        Format => 'rational64u',
     4517    },
     4518    0x1c => { # (same as Nikon_0x000a)
     4519        Name => 'Nikon_AVITags_0x001c',
     4520        Format => 'rational64u',
     4521        Flags => [ 'Hidden', 'Unknown' ],
     4522    },
     4523    0x1d => 'ColorMode',
     4524    0x1e => { # string[8] - val: "AUTO"
     4525        Name => 'Sharpness', # (guess, could also be ISOSelection)
     4526    },
     4527    0x1f => { # string[16] - val: "AUTO"
     4528        Name => 'WhiteBalance', # (guess, could also be ImageAdjustment)
     4529    },
     4530    0x20 => { # string[4] - val: "OFF"
     4531        Name => 'NoiseReduction', # (guess)
     4532    },
     4533    0x801a => { # val: 0 (why is the 0x8000 bit set in the ID?)
     4534        Name => 'Nikon_AVITags_0x801a',
     4535        Format => 'int32s',
     4536        Flags => [ 'Hidden', 'Unknown' ],
     4537    }
     4538);
     4539
     4540# Nikon NCDT atoms (ref PH)
     4541%Image::ExifTool::Nikon::NCDT = (
     4542    GROUPS => { 0 => 'MakerNotes', 1 => 'Nikon', 2 => 'Video' },
     4543    NOTES => q{
     4544        Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some
     4545        Nikon cameras such as the Coolpix S8000.
     4546    },
     4547    NCHD => {
     4548        Name => 'MakerNoteVersion',
     4549        Format => 'undef',
     4550        ValueConv => q{
     4551            $val =~ s/\0$//;    # remove trailing null
     4552            $val =~ s/([\0-\x1f])/'.'.ord($1)/ge;
     4553            $val =~ s/\./ /; return $val;
     4554        },
     4555    },
     4556    NCTG => {
     4557        Name => 'NikonTags',
     4558        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::NCTG' },
     4559    },
     4560    NCTH => { Name => 'ThumbnailImage', Format => 'undef', Binary => 1 },
     4561    NCVW => { Name => 'PreviewImage',   Format => 'undef', Binary => 1 },
     4562    # NCDB - 0 bytes long, or 4 null bytes
     4563);
     4564
     4565# Nikon NCTG tags from MOV videos (ref PH)
     4566%Image::ExifTool::Nikon::NCTG = (
     4567    PROCESS_PROC => \&ProcessNikonMOV,
     4568    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4569    NOTES => q{
     4570        These tags are found in proprietary-format records of the NCTG atom in MOV
     4571        videos from some Nikon cameras.
     4572    },
     4573    0x01 => 'Make',
     4574    0x02 => 'Model',
     4575    0x03 => 'Software',
     4576    0x11 => {
     4577        Name => 'CreateDate', #(guess, but matches QuickTime CreateDate)
     4578        Groups => { 2 => 'Time' },
     4579        PrintConv => '$self->ConvertDateTime($val)',
     4580    },
     4581    0x12 => {
     4582        Name => 'DateTimeOriginal', #(guess, but time is 1 sec before tag 0x11)
     4583        Description => 'Date/Time Original',
     4584        Groups => { 2 => 'Time' },
     4585        PrintConv => '$self->ConvertDateTime($val)',
     4586    },
     4587    0x13 => {
     4588        Name => 'FrameCount',
     4589        # int32u[2]: "467 0", "1038 0", "1127 0"
     4590        ValueConv => '$val =~ s/ 0$//; $val', # (not sure what the extra "0" is for)
     4591    },
     4592    # 0x14 - int32u[2]: "0 0"
     4593    # 0x15 - int32u[2]: "0 0"
     4594    0x16 => {
     4595        Name => 'FrameRate',
     4596        Groups => { 2 => 'Video' },
     4597        PrintConv => 'int($val * 1000 + 0.5) / 1000',
     4598    },
     4599    # 0x21 - int16u: 1, 2
     4600    0x22 => {
     4601        Name => 'FrameWidth',
     4602        Groups => { 2 => 'Video' },
     4603    },
     4604    0x23 => {
     4605        Name => 'FrameHeight',
     4606        Groups => { 2 => 'Video' },
     4607    },
     4608    # 0x24 - int16u: 2
     4609    # 0x31 - int16u: 1, 2
     4610    0x32 => { #(guess)
     4611        Name => 'AudioChannels',
     4612        Groups => { 2 => 'Audio' },
     4613    },
     4614    0x33 => {
     4615        Name => 'AudioBitsPerSample',
     4616        Groups => { 2 => 'Audio' },
     4617    },
     4618    0x34 => {
     4619        Name => 'AudioSampleRate',
     4620        Groups => { 2 => 'Audio' },
     4621    },
     4622    0x2000001 => {
     4623        Name => 'MakerNoteVersion',
     4624        PrintConv => '$_=$val;s/^(\d{2})/$1\./;s/^0//;$_',
     4625    },
     4626    0x2000005 => 'WhiteBalance',
     4627    0x200000b => 'WhiteBalanceFineTune',
     4628    0x200001e => {
     4629        Name => 'ColorSpace',
     4630        PrintConv => {
     4631            1 => 'sRGB',
     4632            2 => 'Adobe RGB',
     4633        },
     4634    },
     4635    0x2000023 => {
     4636        Name => 'PictureControlData',
     4637        Binary => 1,
     4638        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControl' },
     4639    },
     4640    0x2000024 => {
     4641        Name => 'WorldTime',
     4642        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::WorldTime' },
     4643    },
     4644    0x2000032 => {
     4645        Name => 'UnknownInfo',
     4646        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::UnknownInfo' },
     4647    },
     4648    0x2000083 => {
     4649        Name => 'LensType',
     4650        # credit to Tom Christiansen (ref 7) for figuring this out...
     4651        PrintConv => q[$_ = $val ? Image::ExifTool::DecodeBits($val,
     4652            {
     4653                0 => 'MF',
     4654                1 => 'D',
     4655                2 => 'G',
     4656                3 => 'VR',
     4657            }) : 'AF';
     4658            # remove commas and change "D G" to just "G"
     4659            s/,//g; s/\bD G\b/G/; $_
     4660        ],
     4661    },
     4662    0x2000084 => {
     4663        Name => "Lens",
     4664        # short focal, long focal, aperture at short focal, aperture at long focal
     4665        PrintConv => \&Image::ExifTool::Exif::PrintLensInfo,
     4666    },
     4667);
    14074668
    14084669# Nikon composite tags
     
    14344695        PrintConv => \%nikonLensIDs,
    14354696    },
     4697    AutoFocus => {
     4698        Require => {
     4699            0 => 'Nikon:PhaseDetectAF',
     4700            1 => 'Nikon:ContrastDetectAF',
     4701        },
     4702        ValueConv => '($val[0] or $val[1]) ? 1 : 0',
     4703        PrintConv => \%offOn,
     4704    },
    14364705);
    14374706
     
    14394708Image::ExifTool::AddCompositeTags('Image::ExifTool::Nikon');
    14404709
     4710#------------------------------------------------------------------------------
     4711# Process Nikon AVI tags (D5000 videos)
     4712# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     4713# Returns: 1 on success
     4714sub ProcessNikonAVI($$$)
     4715{
     4716    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     4717    my $dataPt = $$dirInfo{DataPt};
     4718    my $pos = $$dirInfo{DirStart} || 0;
     4719    my $dirEnd = $pos + $$dirInfo{DirLen};
     4720    $exifTool->VerboseDir($dirInfo, undef, $$dirInfo{DirLen});
     4721    SetByteOrder('II');
     4722    while ($pos + 4 <= $dirEnd) {
     4723        my $tag = Get16u($dataPt, $pos);
     4724        my $size = Get16u($dataPt, $pos + 2);
     4725        $pos += 4;
     4726        last if $pos + $size > $dirEnd;
     4727        $exifTool->HandleTag($tagTablePtr, $tag, undef,
     4728            DataPt => $dataPt,
     4729            Start  => $pos,
     4730            Size   => $size,
     4731        );
     4732        $pos += $size;
     4733    }
     4734    return 1;
     4735}
     4736#------------------------------------------------------------------------------
     4737# Print D3/D300 AF points (similar to Canon::PrintAFPoints1D)
     4738# Inputs: 0) value to convert (undef[7])
     4739# Focus point pattern:
     4740#        A1  A2  A3  A4  A5  A6  A7  A8  A9
     4741#    B1  B2  B3  B4  B5  B6  B7  B8  B9  B10  B11
     4742#    C1  C2  C3  C4  C5  C6  C7  C8  C9  C10  C11
     4743#    D1  D2  D3  D4  D5  D6  D7  D8  D9  D10  D11
     4744#        E1  E2  E3  E4  E5  E6  E7  E8  E9
     4745sub PrintAFPointsD3($)
     4746{
     4747    my $val = shift;
     4748    return 'Unknown' unless length $val == 7;
     4749    # list of byte/bit positions for each focus point (upper/lower nibble)
     4750    my @focusPts = (
     4751             0x55,0x50,0x43,0x14,0x02,0x07,0x21,0x26,0x33,
     4752        0x61,0x54,0x47,0x42,0x13,0x01,0x06,0x20,0x25,0x32,0x37,
     4753        0x60,0x53,0x46,0x41,0x12,0x00,0x05,0x17,0x24,0x31,0x36,
     4754        0x62,0x56,0x51,0x44,0x15,0x03,0x10,0x22,0x27,0x34,0x40,
     4755             0x57,0x52,0x45,0x16,0x04,0x11,0x23,0x30,0x35
     4756    );
     4757    my ($focusPt, @points);
     4758    my @dat = unpack('C*', $val);
     4759    my @cols = (9,11,11,11,9);
     4760    my $cols = shift @cols;
     4761    my ($row, $col) = ('A', 1);
     4762    foreach $focusPt (@focusPts) {
     4763        push @points, $row . $col if $dat[$focusPt >> 4] & (0x01 << ($focusPt & 0x0f));
     4764        if (++$col > $cols) {
     4765            $cols = shift @cols;
     4766            $col = 1;
     4767            ++$row;
     4768        }
     4769    }
     4770    return '(none)' unless @points;
     4771    return join(',',@points);
     4772}
     4773
     4774#------------------------------------------------------------------------------
     4775# Print PictureControl value
     4776# Inputs: 0) value (with 0x80 subtracted),
     4777#         1) 'Normal' (0 value) string (default 'Normal')
     4778#         2) format string for numbers (default '%+d')
     4779# Returns: PrintConv value
     4780sub PrintPC($;$$)
     4781{
     4782    my ($val, $norm, $fmt) = @_;
     4783    return $norm || 'Normal' if $val == 0;
     4784    return 'n/a'             if $val == 0x7f;
     4785    return 'Auto'            if $val == -128;
     4786    # -127 = custom curve created in Camera Control Pro (show as "User" by D3) - ref 28
     4787    return 'User'            if $val == -127; #28
     4788    return sprintf($fmt || '%+d', $val);
     4789}
     4790
     4791#------------------------------------------------------------------------------
     4792# Inverse of PrintPC
     4793# Inputs: 0) PrintConv value (after subracting 0x80 from raw value)
     4794# Returns: unconverted value
     4795# Notes: raw values: 0=Auto, 1=User, 0xff=n/a, ... 0x7f=-1, 0x80=0, 0x81=1, ...
     4796sub PrintPCInv($)
     4797{
     4798    my $val = shift;
     4799    return $val if $val =~ /^[-+]?\d+$/;
     4800    return 0x7f if $val =~ /n\/a/i;
     4801    return -128 if $val =~ /auto/i;
     4802    return -127 if $val =~ /user/i; #28
     4803    return 0;
     4804}
     4805
     4806#------------------------------------------------------------------------------
     4807# Convert unknown LensID values
     4808# Inputs: 0) value, 1) flag for inverse conversion, 2) PrintConv hash ref
     4809sub LensIDConv($$$)
     4810{
     4811    my ($val, $inv, $conv) = @_;
     4812    return undef if $inv;
     4813    # multiple lenses with the same LensID are distinguished by decimal values
     4814    if ($$conv{"$val.1"}) {
     4815        my ($i, @vals, @user);
     4816        for ($i=1; ; ++$i) {
     4817            my $lens = $$conv{"$val.$i"} or last;
     4818            if ($Image::ExifTool::userLens{$lens}) {
     4819                push @user, $lens;
     4820            } else {
     4821                push @vals, $lens;
     4822            }
     4823        }
     4824        return join(' or ', @user) if @user;
     4825        return join(' or ', @vals);
     4826    }
     4827    my $regex = $val;
     4828    # Sigma has been changing the LensID on some new lenses
     4829    $regex =~ s/^\w+/../;
     4830    my @ids = sort grep /^$regex$/, keys %$conv;
     4831    return "Unknown ($val) $$conv{$ids[0]} ?" if @ids;
     4832    return undef;
     4833}
    14414834
    14424835#------------------------------------------------------------------------------
     
    14524845        $str = substr($str,0,55) . "[...]";
    14534846    } else {
    1454         $str =~ s/\s+$//;   # remove trailing white space and null terminator
    1455         # Don't change case of hyphenated strings (like AF-S) or non-words (no vowels)
    1456         unless ($str =~ /-/ or $str !~ /[AEIOUY]/) {
    1457             # change all letters but the first to lower case
    1458             $str =~ s/([A-Z]{1})([A-Z]+)/$1\L$2/g;
     4847        $str =~ s/\s+$//;   # remove trailing white space
     4848        # Don't change case of non-words (no vowels)
     4849        if ($str =~ /[AEIOUY]/) {
     4850            # change all letters but the first to lower case,
     4851            # but only in words containing a vowel
     4852            if ($str =~ s/\b([AEIOUY])([A-Z]+)/$1\L$2/g) {
     4853                $str =~ s/\bAf\b/AF/;   # patch for "AF"
     4854                # patch for a number of models that write improper string
     4855                # terminator for ImageStabilization (VR-OFF, VR-ON)
     4856                $str =~ s/  +.$//
     4857            }
     4858            if ($str =~ s/\b([A-Z])([A-Z]*[AEIOUY][A-Z]*)/$1\L$2/g) {
     4859                $str =~ s/\bRaw\b/RAW/; # patch for "RAW"
     4860            }
    14594861        }
    14604862    }
     
    15034905#         4) optional start offset (default 0)
    15044906#         5) optional number of bytes to decode (default to the end of the data)
    1505 # Returns: Decrypted data block
     4907# Returns: data block with specified data decrypted
    15064908sub Decrypt($$$;$$)
    15074909{
    15084910    my ($dataPt, $serial, $count, $start, $len) = @_;
     4911    my ($i, $dat);
     4912
    15094913    $start or $start = 0;
    1510     my $end = $len ? $start + $len : length($$dataPt);
    1511     my $i;
     4914    $len = length($$dataPt) - $start if not defined $len or $len > length($$dataPt) - $start;
     4915    return $$dataPt if $len <= 0;
    15124916    my $key = 0;
    15134917    for ($i=0; $i<4; ++$i) {
     
    15174921    my $cj = $xlat[1][$key];
    15184922    my $ck = 0x60;
    1519     my @data = unpack('C*',$$dataPt);
    1520     for ($i=$start; $i<$end; ++$i) {
     4923    my @data = unpack("x${start}C$len", $$dataPt);
     4924    foreach $dat (@data) {
    15214925        $cj = ($cj + $ci * $ck) & 0xff;
    15224926        $ck = ($ck + 1) & 0xff;
    1523         $data[$i] ^= $cj;
     4927        $dat ^= $cj;
    15244928    }
    1525     return pack('C*',@data);
     4929    my $end = $start + $len;
     4930    my $pre = $start ? substr($$dataPt, 0, $start) : '';
     4931    my $post = $end < length($$dataPt) ? substr($$dataPt, $end) : '';
     4932    return $pre . pack('C*',@data) . $post;
    15264933}
    15274934
    15284935#------------------------------------------------------------------------------
    1529 # process Nikon Encrypted data block
    1530 # Inputs: 0) ExifTool object reference, 1) reference to directory information
    1531 #         2) pointer to tag table
     4936# Get serial number for use as a decryption key
     4937# Inputs: 0) ExifTool object ref, 1) serial number string
     4938# Returns: serial key integer or undef if no serial number provided
     4939sub SerialKey($$)
     4940{
     4941    my ($exifTool, $serial) = @_;
     4942    # use serial number as key if integral
     4943    return $serial if not defined $serial or $serial =~ /^\d+$/;
     4944    return 0x22 if $$exifTool{Model} =~ /\bD50$/; # D50 (ref 8)
     4945    return 0x60; # D200 (ref 10), D40X (ref PH), etc
     4946}
     4947
     4948#------------------------------------------------------------------------------
     4949# Read Nikon NCTG tags in MOV videos
     4950# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
    15324951# Returns: 1 on success
     4952sub ProcessNikonMOV($$$)
     4953{
     4954    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     4955    my $dataPt = $$dirInfo{DataPt};
     4956    my $dataPos = $$dirInfo{DataPos};
     4957    my $pos = $$dirInfo{DirStart};
     4958    my $end = $pos + $$dirInfo{DirLen};
     4959    $exifTool->VerboseDir($$dirInfo{DirName}, 0, $$dirInfo{DirLen});
     4960    while ($pos + 8 < $end) {
     4961        my $tag = Get32u($dataPt, $pos);
     4962        my $fmt = Get16u($dataPt, $pos + 4); # (same format code as EXIF)
     4963        my $count = Get16u($dataPt, $pos + 6);
     4964        $pos += 8;
     4965        my $fmtStr = $Image::ExifTool::Exif::formatName[$fmt];
     4966        unless ($fmtStr) {
     4967            $exifTool->Warn(sprintf("Unknown format ($fmt) for $$dirInfo{DirName} tag 0x%x",$tag));
     4968            last;
     4969        }
     4970        my $size = $count * $Image::ExifTool::Exif::formatSize[$fmt];
     4971        if ($pos + $size > $end) {
     4972            $exifTool->Warn(sprintf("Truncated data for $$dirInfo{DirName} tag 0x%x",$tag));
     4973            last;
     4974        }
     4975        my $val = ReadValue($dataPt, $pos, $fmtStr, $count, $size);
     4976        $exifTool->HandleTag($tagTablePtr, $tag, $val,
     4977            DataPt  => $dataPt,
     4978            DataPos => $dataPos,
     4979            Format  => $fmtStr,
     4980            Start   => $pos,
     4981            Size    => $size,
     4982        );
     4983        $pos += $size;  # is this padded to an even offset????
     4984    }
     4985    return 1;
     4986}
     4987
     4988#------------------------------------------------------------------------------
     4989# Read/Write Nikon Encrypted data block
     4990# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     4991# Returns: 1 on success when reading, or new directory when writing (IsWriting set)
    15334992sub ProcessNikonEncrypted($$$)
    15344993{
    15354994    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    1536     # get the encrypted directory data
    1537     my $buff = substr(${$$dirInfo{DataPt}}, $$dirInfo{DirStart}, $$dirInfo{DirLen});
    1538     # save it until we have enough information to decrypt it later
    1539     push @{$exifTool->{NikonInfo}->{Encrypted}}, [ $tagTablePtr, $buff, $$dirInfo{TagInfo}];
    1540     if ($exifTool->Options('Verbose')) {
    1541         my $indent = substr($exifTool->{INDENT}, 0, -2);
    1542         $exifTool->VPrint(0, $indent, "[$dirInfo->{TagInfo}->{Name} directory to be decrypted later]\n");
     4995    $exifTool or return 1;    # allow dummy access
     4996    my $serial = $$exifTool{NikonSerialKey};
     4997    my $count = $$exifTool{NikonCountKey};
     4998    unless (defined $serial and defined $count) {
     4999        if (defined $serial or defined $count) {
     5000            my $missing = defined $serial ? 'ShutterCount' : 'SerialNumber';
     5001            $exifTool->Warn("Can't decrypt Nikon information (no $missing key)");
     5002        }
     5003        delete $$exifTool{NikonSerialKey};
     5004        delete $$exifTool{NikonCountKey};
     5005        return 0;
     5006    }
     5007    my $verbose = $$dirInfo{IsWriting} ? 0 : $exifTool->Options('Verbose');
     5008    my $tagInfo = $$dirInfo{TagInfo};
     5009    my $data = substr(${$$dirInfo{DataPt}}, $$dirInfo{DirStart}, $$dirInfo{DirLen});
     5010
     5011    my ($start, $len, $offset, $byteOrder, $recrypt, $newSerial, $newCount);
     5012
     5013    # must re-encrypt when writing if serial number or shutter count changes
     5014    if ($$dirInfo{IsWriting}) {
     5015        if ($$exifTool{NewNikonSerialKey}) {
     5016            $newSerial = $$exifTool{NewNikonSerialKey};
     5017            $recrypt = 1;
     5018        }
     5019        if ($$exifTool{NewNikonCountKey}) {
     5020            $newCount = $$exifTool{NewNikonCountKey};
     5021            $recrypt = 1;
     5022        }
     5023    }
     5024    if ($tagInfo and $$tagInfo{SubDirectory}) {
     5025        $start = $tagInfo->{SubDirectory}->{DecryptStart};
     5026        # may decrypt only part of the information to save time
     5027        if ($verbose < 3 and $exifTool->Options('Unknown') < 2 and not $recrypt) {
     5028            $len = $tagInfo->{SubDirectory}->{DecryptLen};
     5029        }
     5030        $offset = $tagInfo->{SubDirectory}->{DirOffset};
     5031        $byteOrder = $tagInfo->{SubDirectory}->{ByteOrder};
     5032    }
     5033    $start or $start = 0;
     5034    if (defined $offset) {
     5035        # offset, if specified, is releative to start of encrypted data
     5036        $offset += $start;
     5037    } else {
     5038        $offset = 0;
     5039    }
     5040    my $maxLen = length($data) - $start;
     5041    # decrypt all the data unless DecryptLen is given
     5042    $len = $maxLen unless $len and $len <= $maxLen;
     5043
     5044    $data = Decrypt(\$data, $serial, $count, $start, $len);
     5045
     5046    if ($verbose > 2) {
     5047        $exifTool->VerboseDir("Decrypted $$tagInfo{Name}");
     5048        $exifTool->VerboseDump(\$data,
     5049            Prefix  => $exifTool->{INDENT} . '  ',
     5050            DataPos => $$dirInfo{DirStart} + $$dirInfo{DataPos} + ($$dirInfo{Base} || 0),
     5051        );
     5052    }
     5053    # process the decrypted information
     5054    my %subdirInfo = (
     5055        DataPt   => \$data,
     5056        DirStart => $offset,
     5057        DirLen   => length($data) - $offset,
     5058        DirName  => $$dirInfo{DirName},
     5059        DataPos  => $$dirInfo{DataPos} + $$dirInfo{DirStart},
     5060        Base     => $$dirInfo{Base},
     5061    );
     5062    my $rtnVal;
     5063    my $oldOrder = GetByteOrder();
     5064    SetByteOrder($byteOrder) if $byteOrder;
     5065    if ($$dirInfo{IsWriting}) {
     5066        my $changed = $$exifTool{CHANGED};
     5067        $rtnVal = $exifTool->WriteBinaryData(\%subdirInfo, $tagTablePtr);
     5068        # must re-encrypt if serial number or shutter count changes
     5069        if ($recrypt) {
     5070            $serial = $newSerial if defined $newSerial;
     5071            $count = $newCount if defined $newCount;
     5072            ++$$exifTool{CHANGED};
     5073        }
     5074        if ($changed == $$exifTool{CHANGED}) {
     5075            undef $rtnVal;  # nothing changed so use original data
     5076        } else {
     5077            # add back any un-encrypted data at start
     5078            $rtnVal = substr($data, 0, $offset) . $rtnVal if $offset;
     5079            # re-encrypt data (symmetrical algorithm)
     5080            $rtnVal = Decrypt(\$rtnVal, $serial, $count, $start, $len);
     5081        }
     5082    } else {
     5083        $rtnVal = $exifTool->ProcessBinaryData(\%subdirInfo, $tagTablePtr);
     5084    }
     5085    SetByteOrder($oldOrder);
     5086    return $rtnVal;
     5087}
     5088
     5089#------------------------------------------------------------------------------
     5090# Pre-scan EXIF directory to extract specific tags
     5091# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) required tagID hash ref
     5092# Returns: 1 if directory was scanned successfully
     5093sub PrescanExif($$$)
     5094{
     5095    my ($exifTool, $dirInfo, $tagHash) = @_;
     5096    my $dataPt = $$dirInfo{DataPt};
     5097    my $dataPos = $$dirInfo{DataPos} || 0;
     5098    my $dataLen = $$dirInfo{DataLen};
     5099    my $dirStart = $$dirInfo{DirStart} || 0;
     5100    my $base = $$dirInfo{Base} || 0;
     5101    my $raf = $$dirInfo{RAF};
     5102    my ($index, $numEntries, $data, $buff);
     5103
     5104    # get number of entries in IFD
     5105    if ($dirStart >= 0 and $dirStart <= $dataLen-2) {
     5106        $numEntries = Get16u($dataPt, $dirStart);
     5107        # reset $numEntries to read from file if necessary
     5108        undef $numEntries if $dirStart + 2 + 12 * $numEntries > $dataLen;
     5109    }
     5110    # read IFD from file if necessary
     5111    unless ($numEntries) {
     5112        $raf or return 0;
     5113        $dataPos += $dirStart;  # read data from the start of the directory
     5114        $raf->Seek($dataPos + $base, 0) and $raf->Read($data, 2) == 2 or return 0;
     5115        $numEntries = Get16u(\$data, 0);
     5116        my $len = 12 * $numEntries;
     5117        $raf->Read($buff, $len) == $len or return 0;
     5118        $data .= $buff;
     5119        # update variables for the newly loaded IFD (already updated dataPos)
     5120        $dataPt = \$data;
     5121        $dataLen = length $data;
     5122        $dirStart = 0;
     5123    }
     5124    # loop through necessary IFD entries
     5125    my ($lastTag) = sort { $b <=> $a } keys %$tagHash; # (reverse sort)
     5126    for ($index=0; $index<$numEntries; ++$index) {
     5127        my $entry = $dirStart + 2 + 12 * $index;
     5128        my $tagID = Get16u($dataPt, $entry);
     5129        last if $tagID > $lastTag;  # (assuming tags are in order)
     5130        next unless exists $$tagHash{$tagID};   # only extract required tags
     5131        my $format = Get16u($dataPt, $entry+2);
     5132        next if $format < 1 or $format > 13;
     5133        my $count = Get32u($dataPt, $entry+4);
     5134        my $size = $count * $Image::ExifTool::Exif::formatSize[$format];
     5135        my $formatStr = $Image::ExifTool::Exif::formatName[$format];
     5136        my $valuePtr = $entry + 8;      # pointer to value within $$dataPt
     5137        if ($size > 4) {
     5138            next if $size > 0x1000000;  # set a reasonable limit on data size (16MB)
     5139            $valuePtr = Get32u($dataPt, $valuePtr);
     5140            # convert offset to pointer in $$dataPt
     5141            # (don't yet handle EntryBased or FixOffsets)
     5142            $valuePtr -= $dataPos;
     5143            if ($valuePtr < 0 or $valuePtr+$size > $dataLen) {
     5144                next unless $raf and $raf->Seek($base + $valuePtr + $dataPos,0) and
     5145                                     $raf->Read($buff,$size) == $size;
     5146                $$tagHash{$tagID} = ReadValue(\$buff,0,$formatStr,$count,$size);
     5147                next;
     5148            }
     5149        }
     5150        $$tagHash{$tagID} = ReadValue($dataPt,$valuePtr,$formatStr,$count,$size);
    15435151    }
    15445152    return 1;
     
    15465154
    15475155#------------------------------------------------------------------------------
     5156# Process Nikon Capture history data
     5157# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     5158# Returns: 1 on success
     5159sub ProcessNikonCaptureEditVersions($$$)
     5160{
     5161    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     5162    require Image::ExifTool::NikonCapture;
     5163    return Image::ExifTool::NikonCapture::ProcessNikonCaptureEditVersions($exifTool, $dirInfo, $tagTablePtr);
     5164}
     5165
     5166#------------------------------------------------------------------------------
    15485167# process Nikon Capture Offsets IFD (ref PH)
    1549 # Inputs: 0) ExifTool object reference, 1) reference to directory information
    1550 #         2) pointer to tag table
     5168# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
    15515169# Returns: 1 on success
    15525170# Notes: This isn't a normal IFD, but is close...
     
    15805198
    15815199#------------------------------------------------------------------------------
    1582 # Process Nikon Makernotes directory
    1583 # Inputs: 0) ExifTool object reference
    1584 #         1) Reference to directory information hash
    1585 #         2) Pointer to tag table for this directory
    1586 # Returns: 1 on success, otherwise returns 0 and sets a Warning
     5200# Read/write Nikon Makernotes directory
     5201# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     5202# Returns: 1 on success, otherwise returns 0 and sets a Warning when reading
     5203#          or new directory when writing (IsWriting set in dirInfo)
    15875204sub ProcessNikon($$$)
    15885205{
    15895206    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    1590     my $verbose = $exifTool->Options('Verbose');
    1591     my $nikonInfo = $exifTool->{NikonInfo} = { };
    1592     my @encrypted;  # list to save encrypted data
    1593     $$nikonInfo{Encrypted} = \@encrypted;
    1594     my $rtnVal = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
    1595     # process any encrypted information we found
    1596     my $encryptedDir;
    1597     if (@encrypted) {
    1598         my $serial = $exifTool->{NikonInfo}->{SerialNumber} || 0;
    1599         my $count = $exifTool->{NikonInfo}->{ShutterCount};
    1600         unless (defined $count) {
    1601             $exifTool->Warn("Can't decrypt Nikon information (no ShutterCount key)");
    1602             undef @encrypted;
    1603         }
    1604         foreach $encryptedDir (@encrypted) {
    1605             my ($subTablePtr, $data, $tagInfo) = @$encryptedDir;
    1606             my ($start, $len, $offset);
    1607             if ($tagInfo and $$tagInfo{SubDirectory}) {
    1608                 $start = $tagInfo->{SubDirectory}->{DecryptStart};
    1609                 # may decrypt only part of the information to save time
    1610                 if ($verbose < 3 and $exifTool->Options('Unknown') < 2) {
    1611                     $len = $tagInfo->{SubDirectory}->{DecryptLen};
    1612                 }
    1613                 $offset = $tagInfo->{SubDirectory}->{DirOffset};
    1614             }
    1615             $start or $start = 0;
    1616             if (defined $offset) {
    1617                 # offset, if specified, is releative to start of encrypted data
    1618                 $offset += $start;
    1619             } else {
    1620                 $offset = 0;
    1621             }
    1622             my $maxLen = length($data) - $start;
    1623             if ($len) {
    1624                 $len = $maxLen if $len > $maxLen;
    1625             } else {
    1626                 $len = $maxLen;
    1627             }
    1628             # use fixed serial numbers if no good serial number found
    1629             unless ($serial =~ /^\d+$/) {
    1630                 if ($exifTool->{CameraModel} =~ /\bD50$/) {
    1631                     $serial = 0x22; # D50 (ref 8)
    1632                 } else {
    1633                     $serial = 0x60; # D200 (ref 10), D40X (ref PH)
    1634                 }
    1635             }
    1636             $data = Decrypt(\$data, $serial, $count, $start, $len);
    1637             my %subdirInfo = (
    1638                 DataPt   => \$data,
    1639                 DirStart => $offset,
    1640                 DirLen   => length($data) - $offset,
    1641             );
    1642             if ($verbose > 2) {
    1643                 $exifTool->VerboseDir("Decrypted $$tagInfo{Name}");
    1644                 my %parms = (
    1645                     Prefix => $exifTool->{INDENT},
    1646                     Out => $exifTool->Options('TextOut'),
    1647                 );
    1648                 $parms{MaxLen} = 96 unless $verbose > 3;
    1649                 Image::ExifTool::HexDump(\$data, undef, %parms);
    1650             }
    1651             # process the decrypted information
    1652             $exifTool->ProcessBinaryData(\%subdirInfo, $subTablePtr);
    1653         }
     5207    $exifTool or return 1;    # allow dummy access
     5208
     5209    # pre-scan IFD to get SerialNumber (0x001d) and ShutterCount (0x00a7) for use in decryption
     5210    my %needTags = ( 0x001d => 0, 0x00a7 => undef );
     5211    PrescanExif($exifTool, $dirInfo, \%needTags);
     5212    $$exifTool{NikonSerialKey} = SerialKey($exifTool, $needTags{0x001d});
     5213    $$exifTool{NikonCountKey} = $needTags{0x00a7};
     5214
     5215    # process Nikon makernotes
     5216    my $rtnVal;
     5217    if ($$dirInfo{IsWriting}) {
     5218        # get new decryptino keys if they are being changed
     5219        my $serial = $exifTool->GetNewValues($Image::ExifTool::Nikon::Main{0x001d});
     5220        my $count = $exifTool->GetNewValues($Image::ExifTool::Nikon::Main{0x00a7});
     5221        $$exifTool{NewNikonSerialKey} = SerialKey($exifTool, $serial);
     5222        $$exifTool{NewNikonCountKey} = $count;
     5223        $rtnVal = Image::ExifTool::Exif::WriteExif($exifTool, $dirInfo, $tagTablePtr);
     5224        delete $$exifTool{NewNikonSerialKey};
     5225        delete $$exifTool{NewNikonCountKey};
     5226    } else {
     5227        $rtnVal = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
    16545228    }
    1655     delete $exifTool->{NikonInfo};
     5229    delete $$exifTool{NikonSerialKey};
     5230    delete $$exifTool{NikonCountKey};
    16565231    return $rtnVal;
    16575232}
     
    16765251=head1 AUTHOR
    16775252
    1678 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     5253Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    16795254
    16805255This library is free software; you can redistribute it and/or modify it
     
    17025277
    17035278Thanks to Joseph Heled, Thomas Walter, Brian Ristuccia, Danek Duvall, Tom
    1704 Christiansen, Robert Rottmerhusen, Werner Kober, Roger Larsson and Jens
    1705 Duttke for their help figuring out some Nikon tags, and Bruce Stevens for
    1706 his additions to the LensID list.
     5279Christiansen, Robert Rottmerhusen, Werner Kober, Roger Larsson, Jens Duttke,
     5280Gregor Dorlars, Neil Nappe, Alexandre Naaman, Brendt Wohlberg and Warren
     5281Hatch for their help figuring out some Nikon tags, and to everyone who
     5282helped contribute to the LensID list.
    17075283
    17085284=head1 SEE ALSO
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/NikonCapture.pm

    r16842 r24107  
    55#
    66# Revisions:    11/08/2005 - P. Harvey Created
     7#               10/10/2008 - P. Harvey Updated for Capture NX 2
     8#               16/04/2011 - P. Harvey Decode NikonCaptureEditVersions
    79#
    810# References:   1) http://www.cybercom.net/~dcoffin/dcraw/
     
    1618use Image::ExifTool::Exif;
    1719
    18 $VERSION = '1.02';
     20$VERSION = '1.07';
     21
     22sub ProcessNikonCapture($$$);
    1923
    2024# common print conversions
     
    4145        the maker notes of NEF images.
    4246    },
     47    # 0x007ddc9d contains contrast information
    4348    0x008ae85e => {
    4449        Name => 'LCHEditor',
     
    5055        Writable => 'int8u',
    5156        PrintConv => \%offOn,
     57    },
     58    0x116fea21 => {
     59        Name => 'HighlightData',
     60        SubDirectory => {
     61            TagTable => 'Image::ExifTool::NikonCapture::HighlightData',
     62        },
    5263    },
    5364    0x2175eb78 => {
     
    6677        },
    6778    },
     79    0x39c456ac => {
     80        Name => 'PictureCtrl',
     81        SubDirectory => {
     82            TagTable => 'Image::ExifTool::NikonCapture::PictureCtrl',
     83        },
     84    },
    6885    0x3cfc73c6 => {
    6986        Name => 'RedEyeData',
    7087        SubDirectory => {
    7188            TagTable => 'Image::ExifTool::NikonCapture::RedEyeData',
     89        },
     90    },
     91    0x3d136244 => {
     92        Name => 'EditVersionName',
     93        Writable => 'string', # (null terminated)
     94    },
     95    # 0x3e726567 added when I rotated by 90 degrees
     96    0x56a54260 => {
     97        Name => 'Exposure',
     98        SubDirectory => {
     99            TagTable => 'Image::ExifTool::NikonCapture::Exposure',
    72100        },
    73101    },
     
    126154        Writable => 'int16u',
    127155    },
     156    0x083a1a25 => {
     157        Name => 'HistogramXML',
     158        Writable => 'undef',
     159        Binary => 1,
     160        AdjustSize => 4,    # patch Nikon bug
     161    },
    128162    0x84589434 => {
    129163        Name => 'BrightnessData',
     
    150184        },
    151185    },
     186  # 0xa7264a72, 0x88f55e48 and 0x416391c6 all change from 0 to 1 when QuickFix is turned on
    152187    0xab5eca5e => {
    153188        Name => 'PhotoEffects',
     
    182217        PrintConv => \%offOn,
    183218    },
     219    0xe2173c47 => {
     220        Name => 'PictureControl',
     221        Writable => 'int8u',
     222        PrintConv => \%offOn,
     223    },
    184224    0xe37b4337 => {
    185225        Name => 'D-LightingHSData',
     
    193233            TagTable => 'Image::ExifTool::NikonCapture::UnsharpData',
    194234        },
     235    },
     236    0xe9651831 => {
     237        Name => 'PhotoEffectHistoryXML',
     238        Binary => 1,
     239        Writable => 'undef',
     240    },
     241    0xfe28a44f => {
     242        Name => 'AutoRedEye',
     243        Writable => 'int8u',
     244        PrintConv => \%offOn, # (have seen a value of 28 here for older software?)
    195245    },
    196246    0xfe443a45 => {
     
    249299    FIRST_ENTRY => 0,
    250300    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
    251     0 => 'D-LightingHSShadow',
    252     1 => 'D-LightingHSHighlight',
    253     2 => 'D-LightingHSColorBoost',
     301    0 => 'D-LightingHQShadow',
     302    1 => 'D-LightingHQHighlight',
     303    2 => 'D-LightingHQColorBoost',
    254304);
    255305
     
    299349            4 => 'Calculate Automatically'
    300350        },
     351    },
     352    0x14 => {
     353        Name => 'WBAdjLightingSubtype',
     354        # this varies for different lighting types
     355        # (ie. for Daylight, this is 0 => 'Direct', 1 => 'Shade', 2 => 'Cloudy')
    301356    },
    302357    0x15 => {
     
    315370        Format => 'int16u',
    316371    },
     372    0x25 => {
     373        Name => 'WBAdjTint',
     374        Format => 'int32s',
     375    },
    317376);
    318377
     
    376435    FIRST_ENTRY => 0,
    377436    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
    378     4 => {
     437    0x04 => {
    379438        Name => 'EdgeNoiseReduction',
    380439        PrintConv => \%offOn,
    381440    },
    382     5 => {
    383         Name => 'ColorMoireReduction',
     441    0x05 => {
     442        Name => 'ColorMoireReductionMode',
    384443        PrintConv => {
    385444            0 => 'Off',
     
    389448        },
    390449    },
    391     9 => {
     450    0x09 => {
    392451        Name => 'NoiseReductionIntensity',
    393452        Format => 'int32u',
    394453    },
    395     13 => {
     454    0x0d => {
    396455        Name => 'NoiseReductionSharpness',
    397456        Format => 'int32u',
    398457    },
    399     17 => {
     458    0x11 => {
    400459        Name => 'NoiseReductionMethod',
    401460        Format => 'int16u',
     
    405464        },
    406465    },
     466    0x15 => {
     467        Name => 'ColorMoireReduction',
     468        PrintConv => \%offOn,
     469    },
     470    0x17 => {
     471        Name => 'NoiseReduction',
     472        PrintConv => \%offOn,
     473    },
     474    0x18 => {
     475        Name => 'ColorNoiseReductionIntensity',
     476        Format => 'int32u',
     477    },
     478    0x1c => {
     479        Name => 'ColorNoiseReductionSharpness',
     480        Format => 'int32u',
     481    },
    407482);
    408483
     
    440515    },
    441516    0x8e => {
    442         Name => 'OutputWidthInches',
     517        Name => 'CropOutputWidthInches',
    443518        Format => 'double',
    444519    },
    445520    0x96 => {
    446         Name => 'OutputHeightInches',
     521        Name => 'CropOutputHeightInches',
    447522        Format => 'double',
    448523    },
    449524    0x9e => {
    450         Name => 'ScaledResolution',
     525        Name => 'CropScaledResolution',
    451526        Format => 'double',
    452527    },
    453528    0xae => {
    454         Name => 'SourceResolution',
     529        Name => 'CropSourceResolution',
    455530        Format => 'double',
    456531        ValueConv => '$val / 2',
     
    458533    },
    459534    0xb6 => {
    460         Name => 'OutputResolution',
     535        Name => 'CropOutputResolution',
    461536        Format => 'double',
    462537    },
     
    466541    },
    467542    0xc6 => {
    468         Name => 'OutputWidth',
     543        Name => 'CropOutputWidth',
    469544        Format => 'double',
    470545    },
    471546    0xce => {
    472         Name => 'OutputHeight',
     547        Name => 'CropOutputHeight',
    473548        Format => 'double',
    474549    },
    475550    0xd6 => {
    476         Name => 'OutputPixels',
    477         Format => 'double',
    478     },
     551        Name => 'CropOutputPixels',
     552        Format => 'double',
     553    },
     554);
     555
     556%Image::ExifTool::NikonCapture::PictureCtrl = (
     557    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     558    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     559    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     560    WRITABLE => 1,
     561    FORMAT => 'int8u',
     562    FIRST_ENTRY => 0,
     563    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     564    0x00 => {
     565        Name => 'PictureControlActive',
     566        PrintConv => \%offOn,
     567    },
     568    0x13 => {
     569        Name => 'PictureControlMode',
     570        Format => 'string[16]',
     571    },
     572    # 0x29 changes with Hue and Sharpening
     573    0x2a => {
     574        Name => 'QuickAdjust',
     575        ValueConv => '$val - 128',
     576        ValueConvInv => '$val + 128',
     577    },
     578    0x2b => {
     579        Name => 'SharpeningAdj',
     580        ValueConv => '$val ? $val - 128 : "Auto"',
     581        ValueConvInv => '$val=~/\d/ ? $val + 128 : 0',
     582    },
     583    0x2c => {
     584        Name => 'ContrastAdj',
     585        ValueConv => '$val ? $val - 128 : "Auto"',
     586        ValueConvInv => '$val=~/\d/ ? $val + 128 : 0',
     587    },
     588    0x2d => {
     589        Name => 'BrightnessAdj',
     590        ValueConv => '$val ? $val - 128 : "Auto"', # no "Auto" mode (yet) for this setting
     591        ValueConvInv => '$val=~/\d/ ? $val + 128 : 0',
     592    },
     593    0x2e => {
     594        Name => 'SaturationAdj',
     595        ValueConv => '$val ? $val - 128 : "Auto"',
     596        ValueConvInv => '$val=~/\d/ ? $val + 128 : 0',
     597    },
     598    0x2f => {
     599        Name => 'HueAdj',
     600        ValueConv => '$val - 128',
     601        ValueConvInv => '$val + 128',
     602    },
     603    # 0x37 changed from 0 to 2 when Picture Control is enabled (and no active DLighting)
    479604);
    480605
     
    495620        },
    496621    },
     622);
     623
     624%Image::ExifTool::NikonCapture::Exposure = (
     625    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     626    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     627    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     628    WRITABLE => 1,
     629    FORMAT => 'int8u',
     630    FIRST_ENTRY => 0,
     631    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     632    0x00 => {
     633        Name => 'ExposureAdj',
     634        Format => 'int16s',
     635        ValueConv => '$val / 100',
     636        ValueConvInv => '$val * 100',
     637    },
     638    0x12 => {
     639        Name => 'ExposureAdj2',
     640        Format => 'double',
     641        PrintConv => 'sprintf("%.4f", $val)',
     642        PrintConvInvn => '$val',
     643    },
     644    0x24 => {
     645        Name => 'ActiveD-Lighting',
     646        PrintConv => \%offOn,
     647    },
     648    0x25 => {
     649        Name => 'ActiveD-LightingMode',
     650        PrintConv => {
     651            0 => 'Unchanged',
     652            1 => 'Off',
     653            2 => 'Low',
     654            3 => 'Normal',
     655            4 => 'High',
     656            6 => 'Extra High',
     657        },
     658    },
     659);
     660
     661%Image::ExifTool::NikonCapture::HighlightData = (
     662    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     663    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     664    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     665    WRITABLE => 1,
     666    FORMAT => 'int8s',
     667    FIRST_ENTRY => 0,
     668    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     669    0 => 'ShadowProtection',
     670    1 => 'SaturationAdj',
     671    6 => 'HighlightProtection',
    497672);
    498673
     
    514689    my $dirStart = $$dirInfo{DirStart};
    515690    my $dirLen = $$dirInfo{DirLen};
    516     my $dirEnd = $dirStart + $dirLen;
    517691    if ($dirLen < 22) {
    518692        $exifTool->Warn('Short Nikon Capture Data',1);
     
    522696    SetByteOrder('II');
    523697    my $tagID = Get32u($dataPt, $dirStart);
     698    # sometimes size includes 18 header bytes, and other times it doesn't (ie. ViewNX 2.1.1)
    524699    my $size = Get32u($dataPt, $dirStart + 18);
    525     unless ($tagID == 0x7a86a940 and $size + 18 == $dirLen) {
     700    my $pad = $dirLen - $size - 18;
     701    unless ($tagID == 0x7a86a940 and ($pad >= 0 or $pad == -18)) {
    526702        $exifTool->Warn('Unrecognized Nikon Capture Data header');
    527703        return undef;
     704    }
     705    # determine if there is any data after this block
     706    if ($pad > 0) {
     707        $pad = substr($$dataPt, $dirStart + 18 + $size, $pad);
     708        $dirLen = $size + 18;
     709    } else {
     710        $pad = '';
    528711    }
    529712    my $outBuff = '';
    530713    my $pos;
    531714    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
     715    my $dirEnd = $dirStart + $dirLen;
    532716
    533717    # loop through all entries in the Nikon Capture data
     
    558742                my $format = $$tagInfo{Format} || $$tagInfo{Writable};
    559743                my $oldVal = ReadValue($dataPt,$pos+22,$format,1,$size);
    560                 my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
    561                 if (Image::ExifTool::IsOverwriting($newValueHash, $oldVal)) {
     744                my $nvHash = $exifTool->GetNewValueHash($tagInfo);
     745                if (Image::ExifTool::IsOverwriting($nvHash, $oldVal)) {
    562746                    my $val = $exifTool->GetNewValues($tagInfo);
    563747                    $newVal = WriteValue($val, $$tagInfo{Writable}) if defined $val;
     
    583767    }
    584768    unless ($pos == $dirEnd) {
    585         $exifTool->Warn('Nikon Capture Data improperly terminated',1);
    586         return undef;
     769        if ($pos == $dirEnd - 4) {
     770            # it seems that sometimes (NX2) the main block size is wrong by 4 bytes
     771            # (did they forget to include the size word?)
     772            $outBuff .= substr($$dataPt, $pos, 4);
     773        } else {
     774            $exifTool->Warn('Nikon Capture Data improperly terminated',1);
     775            return undef;
     776        }
    587777    }
    588778    # add the header and return the new directory
    589779    return substr($$dataPt, $dirStart, 18) .
    590780           Set32u(length($outBuff) + 4) .
    591            $outBuff;
     781           $outBuff . $pad;
    592782}
    593783
    594784#------------------------------------------------------------------------------
    595785# process Nikon Capture data (ref 1)
    596 # Inputs: 0) ExifTool object reference, 1) reference to directory information
    597 #         2) pointer to tag table
     786# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     787# Returns: 1 on success
     788sub ProcessNikonCaptureEditVersions($$$)
     789{
     790    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     791    my $dataPt = $$dirInfo{DataPt};
     792    my $dirStart = $$dirInfo{DirStart};
     793    my $dirLen = $$dirInfo{DirLen};
     794    my $dirEnd = $dirStart + $dirLen;
     795    my $verbose = $exifTool->Options('Verbose');
     796    SetByteOrder('II');
     797    return 0 unless $dirLen > 4;
     798    my $num = Get32u($dataPt, $dirStart);
     799    my $pos = $dirStart + 4;
     800    $verbose and $exifTool->VerboseDir('NikonCaptureEditVersions', $num);
     801    while ($num) {
     802        last if $pos + 4 > $dirEnd;
     803        my $len = Get32u($dataPt, $pos);
     804        last if $pos + $len + 4 > $dirEnd;
     805        my %dirInfo = (
     806            DirName  => 'NikonCapture',
     807            Parent   => 'NikonCaptureEditVersions',
     808            DataPt   => $dataPt,
     809            DirStart => $pos + 4,
     810            DirLen   => $len,
     811        );
     812        $$exifTool{DOC_NUM} = ++$$exifTool{DOC_COUNT};
     813        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
     814        --$num;
     815        $pos += $len + 4;
     816    }
     817    delete $$exifTool{DOC_NUM};
     818    return 1;
     819}
     820
     821#------------------------------------------------------------------------------
     822# process Nikon Capture data (ref 1)
     823# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
    598824# Returns: 1 on success
    599825sub ProcessNikonCapture($$$)
     
    624850            }
    625851            if ($format) {
    626                 $value = ReadValue($dataPt,$pos,$format,1,$size);
     852                my $count = 1;
     853                if ($format eq 'string' or $format eq 'undef') {
     854                    # patch Nikon bug in size of some values (HistogramXML)
     855                    $size += $$tagInfo{AdjustSize} if $tagInfo and $$tagInfo{AdjustSize};
     856                    $count = $size;
     857                }
     858                $value = ReadValue($dataPt,$pos,$format,$count,$size);
    627859            } elsif ($size == 1) {
    628860                $value = substr($$dataPt, $pos, $size);
     
    6418731;  # end
    642874
     875__END__
     876
    643877=head1 NAME
    644878
     
    656890=head1 AUTHOR
    657891
    658 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     892Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    659893
    660894This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Olympus.pm

    r16842 r24107  
    1919#              11) http://olypedia.de/Olympus_Makernotes
    2020#              12) Ioannis Panagiotopoulos private communication (E-510)
     21#              13) Chris Shaw private communication (E-3)
     22#              14) Viktor Lushnikov private communication (E-400)
     23#              15) Yrjo Rauste private communication (E-30)
     24#              16) Godfrey DiGiorgi private communcation (E-P1) + http://forums.dpreview.com/forums/read.asp?message=33187567
     25#              17) Martin Hibers private communication
     26#              18) Tomasz Kawecki private communication
    2127#------------------------------------------------------------------------------
    2228
     
    2834use Image::ExifTool::APP12;
    2935
    30 $VERSION = '1.40';
     36$VERSION = '1.79';
     37
     38sub PrintLensInfo($$$);
    3139
    3240my %offOn = ( 0 => 'Off', 1 => 'On' );
    3341
     42# lookup for Olympus LensType values
     43my %olympusLensTypes = (
     44    '0 0 0'  => 'None',
     45    # Olympus lenses
     46    '0 1 0'  => 'Olympus Zuiko Digital ED 50mm F2.0 Macro',
     47    '0 1 1'  => 'Olympus Zuiko Digital 40-150mm F3.5-4.5', #8
     48    '0 1 16' => 'Olympus M.Zuiko Digital ED 14-42mm F3.5-5.6', #PH (E-P1 pre-production)
     49    '0 2 0'  => 'Olympus Zuiko Digital ED 150mm F2.0',
     50    '0 2 16' => 'Olympus M.Zuiko Digital 17mm F2.8 Pancake', #PH (E-P1 pre-production)
     51    '0 3 0'  => 'Olympus Zuiko Digital ED 300mm F2.8',
     52    '0 3 16' => 'Olympus M.Zuiko Digital ED 14-150mm F4.0-5.6', #11
     53    '0 4 16' => 'Olympus M.Zuiko Digital ED 9-18mm F4.0-5.6', #11
     54    '0 5 0'  => 'Olympus Zuiko Digital 14-54mm F2.8-3.5',
     55    '0 5 1'  => 'Olympus Zuiko Digital Pro ED 90-250mm F2.8', #9
     56    '0 5 16' => 'Olympus M.Zuiko Digital ED 14-42mm F3.5-5.6', #11
     57    '0 6 0'  => 'Olympus Zuiko Digital ED 50-200mm F2.8-3.5',
     58    '0 6 1'  => 'Olympus Zuiko Digital ED 8mm F3.5 Fisheye', #9
     59    '0 7 0'  => 'Olympus Zuiko Digital 11-22mm F2.8-3.5',
     60    '0 7 1'  => 'Olympus Zuiko Digital 18-180mm F3.5-6.3', #6
     61    '0 8 1'  => 'Olympus Zuiko Digital 70-300mm F4.0-5.6', #7 (seen as release 1 - PH)
     62    '0 9 16' => 'Olympus M.Zuiko Digital 14-42mm F3.5-5.6 II', #PH (E-PL2)
     63    '0 21 0' => 'Olympus Zuiko Digital ED 7-14mm F4.0',
     64    '0 23 0' => 'Olympus Zuiko Digital Pro ED 35-100mm F2.0', #7
     65    '0 24 0' => 'Olympus Zuiko Digital 14-45mm F3.5-5.6',
     66    '0 32 0' => 'Olympus Zuiko Digital 35mm F3.5 Macro', #9
     67    '0 34 0' => 'Olympus Zuiko Digital 17.5-45mm F3.5-5.6', #9
     68    '0 35 0' => 'Olympus Zuiko Digital ED 14-42mm F3.5-5.6', #PH
     69    '0 36 0' => 'Olympus Zuiko Digital ED 40-150mm F4.0-5.6', #PH
     70    '0 48 0' => 'Olympus Zuiko Digital ED 50-200mm F2.8-3.5 SWD', #7
     71    '0 49 0' => 'Olympus Zuiko Digital ED 12-60mm F2.8-4.0 SWD', #7
     72    '0 50 0' => 'Olympus Zuiko Digital ED 14-35mm F2.0 SWD', #PH
     73    '0 51 0' => 'Olympus Zuiko Digital 25mm F2.8', #PH
     74    '0 52 0' => 'Olympus Zuiko Digital ED 9-18mm F4.0-5.6', #7
     75    '0 53 0' => 'Olympus Zuiko Digital 14-54mm F2.8-3.5 II', #PH
     76    # Sigma lenses
     77    '1 1 0'  => 'Sigma 18-50mm F3.5-5.6', #8
     78    '1 2 0'  => 'Sigma 55-200mm F4.0-5.6 DC',
     79    '1 3 0'  => 'Sigma 18-125mm F3.5-5.6 DC',
     80    '1 4 0'  => 'Sigma 18-125mm F3.5-5.6', #7
     81    '1 5 0'  => 'Sigma 30mm F1.4', #10
     82    '1 6 0'  => 'Sigma 50-500mm F4.0-6.3 EX DG APO HSM RF', #6
     83    '1 7 0'  => 'Sigma 105mm F2.8 DG', #PH
     84    '1 8 0'  => 'Sigma 150mm F2.8 DG HSM', #PH
     85    '1 16 0' => 'Sigma 24mm F1.8 EX DG Aspherical Macro', #PH
     86    '1 17 0' => 'Sigma 135-400mm F4.5-5.6 DG ASP APO RF', #11
     87    '1 18 0' => 'Sigma 300-800mm F5.6 EX DG APO', #11
     88    '1 20 0' => 'Sigma 50-500mm F4.0-6.3 EX DG APO HSM RF', #11
     89    '1 21 0' => 'Sigma 10-20mm F4.0-5.6 EX DC HSM', #11
     90    '1 22 0' => 'Sigma 70-200mm F2.8 EX DG Macro HSM II', #11
     91    '1 23 0' => 'Sigma 50mm F1.4 EX DG HSM', #11
     92    # Leica lenses (ref 11)
     93    '2 1 0'  => 'Leica D Vario Elmarit 14-50mm F2.8-3.5 Asph.',
     94    '2 1 16' => 'Lumix G Vario 14-45mm F3.5-5.6 Asph. Mega OIS', #16
     95    '2 2 0'  => 'Leica D Summilux 25mm F1.4 Asph.',
     96    '2 2 16' => 'Lumix G Vario 45-200mm F4-5.6 Mega OIS', #16
     97    '2 3 1'  => 'Leica D Vario Elmar 14-50mm F3.8-5.6 Asph.', #14 (L10 kit)
     98    '2 3 16' => 'Lumix G Vario HD 14-140mm F4-5.8 Asph. Mega OIS', #16
     99    '2 4 0'  => 'Leica D Vario Elmar 14-150mm F3.5-5.6', #13
     100    '2 4 16' => 'Lumix G Vario 7-14mm F4 Asph.', #PH (E-P1 pre-production)
     101    '2 5 16' => 'Lumix G 20mm F1.7 Asph.', #16
     102    '2 6 16' => 'Leica DG Macro-Elmarit 45mm F2.8', #PH
     103    '2 8 16' => 'Lumix G Fisheye 8mm F3.5', #PH
     104    '3 1 0'  => 'Leica D Vario Elmarit 14-50mm F2.8-3.5 Asph.',
     105    '3 2 0'  => 'Leica D Summilux 25mm F1.4 Asph.',
     106);
     107
     108# ArtFilter and MagicFilter values (ref PH)
     109my %filters = (
     110    '0'    => 'Off',
     111    '1' => 'Soft Focus',
     112    '2' => 'Pop Art',
     113    '3' => 'Pale & Light Color',
     114    '4' => 'Light Tone',
     115    '5' => 'Pin Hole',
     116    '6' => 'Grainy Film',
     117    '9' => 'Diorama',
     118    '10' => 'Cross Process',
     119    '12' => 'Fish Eye',
     120    '13' => 'Drawing',
     121    # Punk? Sparkle?
     122);
     123
     124# tag information for WAV "Index" tags
     125my %indexInfo = (
     126    Format => 'int32u',
     127    RawConv => '$val == 0xffffffff ? undef : $val',
     128    ValueConv => '$val / 1000',
     129    PrintConv => 'ConvertDuration($val)',
     130);
     131
     132# Olympus tags
    34133%Image::ExifTool::Olympus::Main = (
    35134    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     
    39138#
    40139# Tags 0x0000 through 0x0103 are the same as Konica/Minolta cameras (ref 3)
     140# (removed 0x0101-0x0103 because they weren't supported by my samples - PH)
    41141#
    42142    0x0000 => {
     
    87187        WriteCheck => '$self->CheckImage(\$val)',
    88188        Binary => 1,
    89     },
    90     0x0101 => {
    91         Name => 'ColorMode',
    92         Writable => 'int16u',
    93         PrintConv => {
    94             0 => 'Natural color',
    95             1 => 'Black&white',
    96             2 => 'Vivid color',
    97             3 => 'Solarization',
    98             4 => 'Adobe RGB',
    99         },
    100     },
    101     0x0102 => {
    102         Name => 'MinoltaQuality',
    103         Writable => 'int16u',
    104         PrintConv => {
    105             0 => 'Raw',
    106             1 => 'Superfine',
    107             2 => 'Fine',
    108             3 => 'Normal',
    109             4 => 'Economy',
    110             5 => 'Extra fine',
    111         },
    112     },
    113     # (0x0103 is the same as 0x0102 above)
    114     0x0103 => {
    115         Name => 'MinoltaQuality',
    116         Writable => 'int16u',
    117         PrintConv => {
    118             0 => 'Raw',
    119             1 => 'Superfine',
    120             2 => 'Fine',
    121             3 => 'Normal',
    122             4 => 'Economy',
    123             5 => 'Extra fine',
    124         },
    125189    },
    126190    0x0104 => { #11
     
    197261    0x0203 => { #6
    198262        Name => 'BWMode',
    199         Description => 'Black & White Mode',
     263        Description => 'Black And White Mode',
    200264        Writable => 'int16u',
    201265        PrintConv => \%offOn,
     
    285349            1 => 'Standard',
    286350            2 => 'Auto',
     351            3 => 'Intelligent Auto', #PH (guess, u7040)
    287352            4 => 'Portrait',
    288353            5 => 'Landscape+Portrait',
     
    293358            10 => 'Self Portrait',
    294359            11 => 'Indoor',
    295             12 => 'Beach&Snow',
     360            12 => 'Beach & Snow',
    296361            13 => 'Beach',
    297362            14 => 'Snow',
     
    309374            26 => 'Behind Glass',
    310375            27 => 'Auction',
    311             28 => 'Shoot&Select1',
    312             29 => 'Shoot&Select2',
     376            28 => 'Shoot & Select1',
     377            29 => 'Shoot & Select2',
    313378            30 => 'Underwater Wide2',
    314379            31 => 'Digital Image Stabilization',
    315380            32 => 'Face Portrait',
    316381            33 => 'Pet',
     382            34 => 'Smile Shot',
     383            101 => 'Magic Filter', #PH
    317384        },
    318385    },
     
    343410        Binary => 1,
    344411    },
     412    0x0f04 => {
     413        Name => 'ZoomedPreviewStart',
     414        # NOTE: this tag is not currently updated properly when the image is rewritten!
     415        OffsetPair => 0xf05,
     416        DataTag => 'ZoomedPreviewImage',
     417        Writable => 'int32u',
     418        Protected => 2,
     419    },
     420    0x0f05 => {
     421        Name => 'ZoomedPreviewLength',
     422        OffsetPair => 0xf04,
     423        DataTag => 'ZoomedPreviewImage',
     424        Writable => 'int32u',
     425        Protected => 2,
     426    },
     427    0x0f06 => {
     428        Name => 'ZoomedPreviewSize',
     429        Writable => 'int16u',
     430        Count => 2,
     431    },
    345432    0x1000 => { #6
    346433        Name => 'ShutterSpeedValue',
    347434        Writable => 'rational64s',
    348435        Priority => 0,
    349         ValueConv => 'abs($val)<100 ? 1/(2**$val) : 0',
     436        ValueConv => 'abs($val)<100 ? 2**(-$val) : 0',
    350437        ValueConvInv => '$val>0 ? -log($val)/log(2) : -100',
    351438        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    352         PrintConvInv => 'eval $val',
     439        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    353440    },
    354441    0x1001 => { #6
     
    397484        Writable => 'rational64s',
    398485    },
    399     0x1007 => { #6
     486    0x1007 => { #6 (E-10, E-20 and C2500L - numbers usually around 30-40)
    400487        Name => 'SensorTemperature',
    401488        Writable => 'int16s',
     
    631718    # 0x1032 HAFFINAL? #11
    632719    0x1033 => { #11
    633         Name => 'SceneDetectArea',
     720        Name => 'SceneDetectData',
    634721        Writable => 'int32u',
    635722        Count => 720,
     
    655742    },
    656743    0x1037 => { #6
     744        # (may contain data from multiple previews - PH, FE320)
    657745        Name => 'PreviewImageLength',
    658746        OffsetPair => 0x1036, # point to associated offset
     
    676764        Name => 'NoiseReduction',
    677765        Writable => 'int16u',
    678         PrintConv => {
    679             0 => 'Off',
    680             1 => 'On',
    681         },
     766        PrintConv => \%offOn,
    682767    },
    683768    0x103b => { #6
    684         Name => 'InfinityLensStep',
     769        Name => 'FocusStepInfinity',
    685770        Writable => 'int16u',
    686771    },
    687772    0x103c => { #6
    688         Name => 'NearLensStep',
     773        Name => 'FocusStepNear',
    689774        Writable => 'int16u',
    690775    },
     
    708793# (presumably the Olympus programmers forgot about the 2-byte entry count at the
    709794# start of the subdirectory).  This mess is straightened out and these subdirs
    710 # are written properly when ExifTool rewrites the file.  (This problem has been
    711 # fixed in the new-style MakerNoteOlympus2 maker notes since a standard SubIFD
    712 # offset value is used.) - PH
     795# are written properly when ExifTool rewrites the file.  Note that this problem
     796# has been fixed by Olympus in the new-style IFD maker notes since a standard
     797# SubIFD offset value is used.  As written by the camera, the old style
     798# directories have format 'undef' or 'string', and the new style has format
     799# 'ifd'.  However, some older versions of exiftool may have rewritten the new
     800# style as 'int32u', so handle both cases. - PH
    713801#
    714802    0x2010 => [ #PH
    715803        {
    716804            Name => 'Equipment',
    717             Condition => 'not $$self{OlympusType2}',
     805            Condition => '$format ne "ifd" and $format ne "int32u"',
     806            NestedHtmlDump => 2, # (so HtmlDump doesn't show these as double-referenced)
    718807            SubDirectory => {
    719808                TagTable => 'Image::ExifTool::Olympus::Equipment',
     
    722811        },
    723812        {
    724             Name => 'Equipment2',
     813            Name => 'EquipmentIFD',
    725814            Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
    726815            Flags => 'SubIFD',
     
    735824        {
    736825            Name => 'CameraSettings',
    737             Condition => 'not $$self{OlympusType2}',
     826            Condition => '$format ne "ifd" and $format ne "int32u"',
     827            NestedHtmlDump => 2,
    738828            SubDirectory => {
    739829                TagTable => 'Image::ExifTool::Olympus::CameraSettings',
     
    742832        },
    743833        {
    744             Name => 'CameraSettings2',
     834            Name => 'CameraSettingsIFD',
    745835            Groups => { 1 => 'MakerNotes' },
    746836            Flags => 'SubIFD',
     
    755845        {
    756846            Name => 'RawDevelopment',
    757             Condition => 'not $$self{OlympusType2}',
     847            Condition => '$format ne "ifd" and $format ne "int32u"',
     848            NestedHtmlDump => 2,
    758849            SubDirectory => {
    759850                TagTable => 'Image::ExifTool::Olympus::RawDevelopment',
     
    762853        },
    763854        {
    764             Name => 'RawDevelopment2',
     855            Name => 'RawDevelopmentIFD',
    765856            Groups => { 1 => 'MakerNotes' },
    766857            Flags => 'SubIFD',
     
    775866        {
    776867            Name => 'RawDev2',
    777             Condition => 'not $$self{OlympusType2}',
     868            Condition => '$format ne "ifd" and $format ne "int32u"',
     869            NestedHtmlDump => 2,
    778870            SubDirectory => {
    779871                TagTable => 'Image::ExifTool::Olympus::RawDevelopment2',
     
    782874        },
    783875        {
    784             Name => 'RawDev2_2',
     876            Name => 'RawDev2IFD',
    785877            Groups => { 1 => 'MakerNotes' },
    786878            Flags => 'SubIFD',
     
    795887        {
    796888            Name => 'ImageProcessing',
    797             Condition => 'not $$self{OlympusType2}',
     889            Condition => '$format ne "ifd" and $format ne "int32u"',
     890            NestedHtmlDump => 2,
    798891            SubDirectory => {
    799892                TagTable => 'Image::ExifTool::Olympus::ImageProcessing',
     
    802895        },
    803896        {
    804             Name => 'ImageProcessing2',
     897            Name => 'ImageProcessingIFD',
    805898            Groups => { 1 => 'MakerNotes' },
    806899            Flags => 'SubIFD',
     
    815908        {
    816909            Name => 'FocusInfo',
    817             Condition => 'not ($$self{OlympusType2} or $$self{OlympusCAMER})',
     910            Condition => '$format ne "ifd" and $format ne "int32u" and not $$self{OlympusCAMER}',
     911            NestedHtmlDump => 2,
    818912            SubDirectory => {
    819913                TagTable => 'Image::ExifTool::Olympus::FocusInfo',
     
    822916        },
    823917        {
    824             Name => 'FocusInfo2',
     918            Name => 'FocusInfoIFD',
    825919            Condition => 'not $$self{OlympusCAMER}',
    826920            Groups => { 1 => 'MakerNotes' },
     
    834928        {
    835929            # ASCII-based camera parameters if makernotes starts with "CAMER\0"
     930            # (or for Sony models starting with "SONY PI\0" or "PREMI\0")
    836931            Name => 'CameraParameters',
    837932            Writable => 'undef',
     
    839934        },
    840935    ],
    841     0x2100 => { #11
    842         Name => 'Olympus2100',
    843         SubDirectory => {
    844             TagTable => 'Image::ExifTool::Olympus::FETags',
    845             ByteOrder => 'Unknown',
    846         },
    847     },
    848     0x2200 => { #11
    849         Name => 'Olympus2200',
    850         SubDirectory => {
    851             TagTable => 'Image::ExifTool::Olympus::FETags',
    852             ByteOrder => 'Unknown',
    853         },
    854     },
    855     0x2300 => { #11
    856         Name => 'Olympus2300',
    857         SubDirectory => {
    858             TagTable => 'Image::ExifTool::Olympus::FETags',
    859             ByteOrder => 'Unknown',
    860         },
    861     },
    862     0x2400 => { #11
    863         Name => 'Olympus2400',
    864         SubDirectory => {
    865             TagTable => 'Image::ExifTool::Olympus::FETags',
    866             ByteOrder => 'Unknown',
    867         },
    868     },
    869     0x2500 => { #11
    870         Name => 'Olympus2500',
    871         SubDirectory => {
    872             TagTable => 'Image::ExifTool::Olympus::FETags',
    873             ByteOrder => 'Unknown',
    874         },
    875     },
    876     0x2600 => { #11
    877         Name => 'Olympus2600',
    878         SubDirectory => {
    879             TagTable => 'Image::ExifTool::Olympus::FETags',
    880             ByteOrder => 'Unknown',
    881         },
    882     },
    883     0x2700 => { #11
    884         Name => 'Olympus2700',
    885         SubDirectory => {
    886             TagTable => 'Image::ExifTool::Olympus::FETags',
    887             ByteOrder => 'Unknown',
    888         },
    889     },
    890     0x2800 => { #11
    891         Name => 'Olympus2800',
    892         SubDirectory => {
    893             TagTable => 'Image::ExifTool::Olympus::FETags',
    894             ByteOrder => 'Unknown',
    895         },
    896     },
    897     0x2900 => { #11
    898         Name => 'Olympus2900',
    899         SubDirectory => {
    900             TagTable => 'Image::ExifTool::Olympus::FETags',
    901             ByteOrder => 'Unknown',
    902         },
    903     },
     936    0x2100 => [
     937        { #11
     938            Name => 'Olympus2100',
     939            Condition => '$format ne "ifd" and $format ne "int32u"',
     940            NestedHtmlDump => 2,
     941            SubDirectory => {
     942                TagTable => 'Image::ExifTool::Olympus::FETags',
     943                ByteOrder => 'Unknown',
     944            },
     945        },
     946        { #PH
     947            Name => 'Olympus2100IFD',
     948            Groups => { 1 => 'MakerNotes' },
     949            Flags => 'SubIFD',
     950            FixFormat => 'ifd',
     951            SubDirectory => {
     952                TagTable => 'Image::ExifTool::Olympus::FETags',
     953                ByteOrder => 'Unknown',
     954                Start => '$val',
     955            },
     956        },
     957    ],
     958    0x2200 => [
     959        { #11
     960            Name => 'Olympus2200',
     961            Condition => '$format ne "ifd" and $format ne "int32u"',
     962            NestedHtmlDump => 2,
     963            SubDirectory => {
     964                TagTable => 'Image::ExifTool::Olympus::FETags',
     965                ByteOrder => 'Unknown',
     966            },
     967        },
     968        { #PH
     969            Name => 'Olympus2200IFD',
     970            Groups => { 1 => 'MakerNotes' },
     971            Flags => 'SubIFD',
     972            FixFormat => 'ifd',
     973            SubDirectory => {
     974                TagTable => 'Image::ExifTool::Olympus::FETags',
     975                ByteOrder => 'Unknown',
     976                Start => '$val',
     977            },
     978        },
     979    ],
     980    0x2300 => [
     981        { #11
     982            Name => 'Olympus2300',
     983            Condition => '$format ne "ifd" and $format ne "int32u"',
     984            NestedHtmlDump => 2,
     985            SubDirectory => {
     986                TagTable => 'Image::ExifTool::Olympus::FETags',
     987                ByteOrder => 'Unknown',
     988            },
     989        },
     990        { #PH
     991            Name => 'Olympus2300IFD',
     992            Groups => { 1 => 'MakerNotes' },
     993            Flags => 'SubIFD',
     994            FixFormat => 'ifd',
     995            SubDirectory => {
     996                TagTable => 'Image::ExifTool::Olympus::FETags',
     997                ByteOrder => 'Unknown',
     998                Start => '$val',
     999            },
     1000        },
     1001    ],
     1002    0x2400 => [
     1003        { #11
     1004            Name => 'Olympus2400',
     1005            Condition => '$format ne "ifd" and $format ne "int32u"',
     1006            NestedHtmlDump => 2,
     1007            SubDirectory => {
     1008                TagTable => 'Image::ExifTool::Olympus::FETags',
     1009                ByteOrder => 'Unknown',
     1010            },
     1011        },
     1012        { #PH
     1013            Name => 'Olympus2400IFD',
     1014            Groups => { 1 => 'MakerNotes' },
     1015            Flags => 'SubIFD',
     1016            FixFormat => 'ifd',
     1017            SubDirectory => {
     1018                TagTable => 'Image::ExifTool::Olympus::FETags',
     1019                ByteOrder => 'Unknown',
     1020                Start => '$val',
     1021            },
     1022        },
     1023    ],
     1024    0x2500 => [
     1025        { #11
     1026            Name => 'Olympus2500',
     1027            Condition => '$format ne "ifd" and $format ne "int32u"',
     1028            NestedHtmlDump => 2,
     1029            SubDirectory => {
     1030                TagTable => 'Image::ExifTool::Olympus::FETags',
     1031                ByteOrder => 'Unknown',
     1032            },
     1033        },
     1034        { #PH
     1035            Name => 'Olympus2500IFD',
     1036            Groups => { 1 => 'MakerNotes' },
     1037            Flags => 'SubIFD',
     1038            FixFormat => 'ifd',
     1039            SubDirectory => {
     1040                TagTable => 'Image::ExifTool::Olympus::FETags',
     1041                ByteOrder => 'Unknown',
     1042                Start => '$val',
     1043            },
     1044        },
     1045    ],
     1046    0x2600 => [
     1047        { #11
     1048            Name => 'Olympus2600',
     1049            Condition => '$format ne "ifd" and $format ne "int32u"',
     1050            NestedHtmlDump => 2,
     1051            SubDirectory => {
     1052                TagTable => 'Image::ExifTool::Olympus::FETags',
     1053                ByteOrder => 'Unknown',
     1054            },
     1055        },
     1056        { #PH
     1057            Name => 'Olympus2600IFD',
     1058            Groups => { 1 => 'MakerNotes' },
     1059            Flags => 'SubIFD',
     1060            FixFormat => 'ifd',
     1061            SubDirectory => {
     1062                TagTable => 'Image::ExifTool::Olympus::FETags',
     1063                ByteOrder => 'Unknown',
     1064                Start => '$val',
     1065            },
     1066        },
     1067    ],
     1068    0x2700 => [
     1069        { #11
     1070            Name => 'Olympus2700',
     1071            Condition => '$format ne "ifd" and $format ne "int32u"',
     1072            NestedHtmlDump => 2,
     1073            SubDirectory => {
     1074                TagTable => 'Image::ExifTool::Olympus::FETags',
     1075                ByteOrder => 'Unknown',
     1076            },
     1077        },
     1078        { #PH
     1079            Name => 'Olympus2700IFD',
     1080            Groups => { 1 => 'MakerNotes' },
     1081            Flags => 'SubIFD',
     1082            FixFormat => 'ifd',
     1083            SubDirectory => {
     1084                TagTable => 'Image::ExifTool::Olympus::FETags',
     1085                ByteOrder => 'Unknown',
     1086                Start => '$val',
     1087            },
     1088        },
     1089    ],
     1090    0x2800 => [
     1091        { #11
     1092            Name => 'Olympus2800',
     1093            Condition => '$format ne "ifd" and $format ne "int32u"',
     1094            NestedHtmlDump => 2,
     1095            SubDirectory => {
     1096                TagTable => 'Image::ExifTool::Olympus::FETags',
     1097                ByteOrder => 'Unknown',
     1098            },
     1099        },
     1100        { #PH
     1101            Name => 'Olympus2800IFD',
     1102            Groups => { 1 => 'MakerNotes' },
     1103            Flags => 'SubIFD',
     1104            FixFormat => 'ifd',
     1105            SubDirectory => {
     1106                TagTable => 'Image::ExifTool::Olympus::FETags',
     1107                ByteOrder => 'Unknown',
     1108                Start => '$val',
     1109            },
     1110        },
     1111    ],
     1112    0x2900 => [
     1113        { #11
     1114            Name => 'Olympus2900',
     1115            Condition => '$format ne "ifd" and $format ne "int32u"',
     1116            NestedHtmlDump => 2,
     1117            SubDirectory => {
     1118                TagTable => 'Image::ExifTool::Olympus::FETags',
     1119                ByteOrder => 'Unknown',
     1120            },
     1121        },
     1122        { #PH
     1123            Name => 'Olympus2900IFD',
     1124            Groups => { 1 => 'MakerNotes' },
     1125            Flags => 'SubIFD',
     1126            FixFormat => 'ifd',
     1127            SubDirectory => {
     1128                TagTable => 'Image::ExifTool::Olympus::FETags',
     1129                ByteOrder => 'Unknown',
     1130                Start => '$val',
     1131            },
     1132        },
     1133    ],
    9041134    0x3000 => [
    9051135        { #6
    9061136            Name => 'RawInfo',
    907             Condition => 'not $$self{OlympusType2}',
     1137            Condition => '$format ne "ifd" and $format ne "int32u"',
     1138            NestedHtmlDump => 2,
    9081139            SubDirectory => {
    9091140                TagTable => 'Image::ExifTool::Olympus::RawInfo',
     
    9121143        },
    9131144        { #PH
    914             Name => 'RawInfo2',
     1145            Name => 'RawInfoIFD',
    9151146            Groups => { 1 => 'MakerNotes' },
    9161147            Flags => 'SubIFD',
     
    9181149            SubDirectory => {
    9191150                TagTable => 'Image::ExifTool::Olympus::RawInfo',
     1151                Start => '$val',
     1152            },
     1153        },
     1154    ],
     1155    0x4000 => [ #PH
     1156        {
     1157            Name => 'MainInfo',
     1158            Condition => '$format ne "ifd" and $format ne "int32u"',
     1159            NestedHtmlDump => 2,
     1160            SubDirectory => {
     1161                TagTable => 'Image::ExifTool::Olympus::Main',
     1162                ByteOrder => 'Unknown',
     1163            },
     1164        },
     1165        {
     1166            Name => 'MainInfoIFD',
     1167            Groups => { 1 => 'MakerNotes' },
     1168            Flags => 'SubIFD',
     1169            FixFormat => 'ifd',
     1170            SubDirectory => {
     1171                TagTable => 'Image::ExifTool::Olympus::Main',
     1172                Start => '$val',
     1173            },
     1174        },
     1175    ],
     1176    0x5000 => [ #PH
     1177        {
     1178            Name => 'UnknownInfo',
     1179            Condition => '$format ne "ifd" and $format ne "int32u"',
     1180            NestedHtmlDump => 2,
     1181            SubDirectory => {
     1182                TagTable => 'Image::ExifTool::Olympus::UnknownInfo',
     1183                ByteOrder => 'Unknown',
     1184            },
     1185        },
     1186        {
     1187            Name => 'UnknownInfoIFD',
     1188            Groups => { 1 => 'MakerNotes' },
     1189            Flags => 'SubIFD',
     1190            FixFormat => 'ifd',
     1191            SubDirectory => {
     1192                TagTable => 'Image::ExifTool::Olympus::UnknownInfo',
    9201193                Start => '$val',
    9211194            },
     
    9511224        Name => 'EquipmentVersion',
    9521225        Writable => 'undef',
     1226        RawConv => '$val=~s/\0+$//; $val',  # (may be null terminated)
    9531227        Count => 4,
    9541228    },
     
    9871261        Writable => 'int8u',
    9881262        Count => 6,
    989         Notes => '6 numbers: 1. Make, 2. Unknown, 3. Model, 4. Release, 5-6. Unknown',
    990         PrintConv => 'Image::ExifTool::Olympus::PrintLensInfo($val,"Lens")',
     1263        Notes => q{
     1264            6 numbers: 0. Make, 1. Unknown, 2. Model, 3. Sub-model, 4-5. Unknown.  Only
     1265            the Make, Model and Sub-model are used to determine the lens model
     1266        },
     1267        SeparateTable => 'LensType',
     1268        # Have seen these values for the unknown numbers:
     1269        # 1: 0
     1270        # 4: 0, 2(Olympus lenses for which I have also seen 0 for this number)
     1271        # 5: 0, 16(new Lumix lenses)
     1272        ValueConv => 'my @a = split(" ",$val); "$a[0] $a[2] $a[3]"',
     1273        # set unknown values to zero when writing
     1274        ValueConvInv => 'my @a=split(" ",$val); "$a[0] 0 $a[1] $a[2] 0 0"',
     1275        PrintConv => \%olympusLensTypes,
    9911276    },
    9921277    # apparently the first 3 digits of the lens s/n give the type (ref 4):
     
    9971282    # 080 = EX-25
    9981283    # 101 = FL-50
     1284    # 272 = EC-20 #7
    9991285    0x202 => { #PH
    10001286        Name => 'LensSerialNumber',
     
    10041290        PrintConvInv => 'pack("A31",$val)', # pad with spaces to 31 chars
    10051291    },
     1292    0x203 => { #17
     1293        Name => 'LensModel',
     1294        Writable => 'string',
     1295    },
    10061296    0x204 => { #6
    10071297        Name => 'LensFirmwareVersion',
     
    10521342        Writable => 'int8u',
    10531343        Count => 6,
    1054         Notes => '6 numbers: 1. Make, 2. Unknown, 3. Model, 4. Release, 5-6. Unknown.',
    1055         PrintConv => 'Image::ExifTool::Olympus::PrintLensInfo($val,"Extender")',
     1344        Notes => q{
     1345            6 numbers: 0. Make, 1. Unknown, 2. Model, 3. Sub-model, 4-5. Unknown.  Only
     1346            the Make and Model are used to determine the extender model
     1347        },
     1348        ValueConv => 'my @a = split(" ",$val); "$a[0] $a[2]"',
     1349        ValueConvInv => 'my @a=split(" ",$val); "$a[0] 0 $a[1] 0 0 0"',
     1350        PrintConv => {
     1351            '0 0'   => 'None',
     1352            '0 4'   => 'Olympus Zuiko Digital EC-14 1.4x Teleconverter',
     1353            '0 8'   => 'Olympus EX-25 Extension Tube',
     1354            '0 16'  => 'Olympus Zuiko Digital EC-20 2.0x Teleconverter', #7
     1355        },
    10561356    },
    10571357    0x302 => { #4
     
    10841384        PrintConv => {
    10851385            0 => 'None',
    1086             1 => 'FL-20',
    1087             2 => 'FL-50',
     1386            1 => 'FL-20', # (or subtronic digital or Inon UW flash, ref 11)
     1387            2 => 'FL-50', # (or Metzblitz+SCA or Cullmann 34, ref 11)
    10881388            3 => 'RF-11',
    10891389            4 => 'TF-22',
    10901390            5 => 'FL-36',
     1391            6 => 'FL-50R', #11 (or Metz mecablitz digital)
     1392            7 => 'FL-36R', #11
     1393            # have seen value of 9 - PH
    10911394        },
    10921395    },
     
    11131416        Name => 'CameraSettingsVersion',
    11141417        Writable => 'undef',
     1418        RawConv => '$val=~s/\0+$//; $val',  # (may be null terminated)
    11151419        Count => 4,
    11161420    },
     
    11491453        Name => 'AELock',
    11501454        Writable => 'int16u',
    1151         PrintConv => {
    1152             0 => 'Off',
    1153             1 => 'On',
    1154         },
     1455        PrintConv => \%offOn,
    11551456    },
    11561457    0x202 => { #PH/4
     
    11581459        Writable => 'int16u',
    11591460        PrintConv => {
    1160             2 => 'Center Weighted',
     1461            2 => 'Center-weighted average',
    11611462            3 => 'Spot',
    11621463            5 => 'ESP',
     
    11661467        },
    11671468    },
     1469    0x203 => { #11 (some E-models only)
     1470        Name => 'ExposureShift',
     1471        Writable => 'rational64s',
     1472    },
    11681473    0x300 => { #6
    11691474        Name => 'MacroMode',
     
    11781483        Name => 'FocusMode',
    11791484        Writable => 'int16u',
    1180         PrintConv => {
     1485        Count => -1,
     1486        Notes => '1 or 2 values',
     1487        PrintConv => [{
    11811488            0 => 'Single AF',
    11821489            1 => 'Sequential shooting AF',
    11831490            2 => 'Continuous AF',
    11841491            3 => 'Multi AF',
     1492            5 => 'Face detect', #11
    11851493            10 => 'MF',
    1186         },
     1494        }, { BITMASK => { #11
     1495            0 => 'S-AF',
     1496            2 => 'C-AF',
     1497            4 => 'MF',
     1498            5 => 'Face detect',
     1499            6 => 'Imager AF',
     1500            8 => 'AF sensor',
     1501        }}],
    11871502    },
    11881503    0x302 => { #6
    11891504        Name => 'FocusProcess',
    11901505        Writable => 'int16u',
    1191         PrintConv => {
     1506        Count => -1,
     1507        Notes => '1 or 2 values',
     1508        PrintConv => [{
    11921509            0 => 'AF Not Used',
    11931510            1 => 'AF Used',
    1194         },
     1511        }],
     1512        # 2nd value written only by some models (u1050SW, u9000, uT6000, uT6010,
     1513        # uT8000, E-30, E-420, E-450, E-520, E-620, E-P1 and E-P2): - PH
     1514        # observed values when "AF Not Used": 0, 16
     1515        # observed values when "AF Used": 64, 96(face detect on), 256
    11951516    },
    11961517    0x303 => { #6
     
    12041525    0x304 => { #PH/4
    12051526        Name => 'AFAreas',
     1527        Notes => 'coordinates range from 0 to 255',
    12061528        Format => 'int32u',
    12071529        Count => 64,
    12081530        PrintConv => 'Image::ExifTool::Olympus::PrintAFAreas($val)',
     1531    },
     1532    0x0305 => { #PH
     1533        Name => 'AFPointSelected',
     1534        Notes => 'coordinates expressed as a percent',
     1535        Format => 'rational64s',
     1536        Count => 5,
     1537        ValueConv => '$val =~ s/\S* //; $val', # ignore first undefined value
     1538        ValueConvInv => '"undef $val"',
     1539        PrintConv => q{
     1540            return $val if $val =~ /undef/;
     1541            sprintf("(%d%%,%d%%) (%d%%,%d%%)", map {$_ * 100} split(" ",$val));
     1542        }
     1543    },
     1544    0x307 => { #15
     1545        Name => 'AFFineTuneAdj',
     1546        Format => 'int16s',
     1547        Count => 3, # not sure what the 3 values mean
    12091548    },
    12101549    0x400 => { #6
     
    12241563    },
    12251564    0x401 => { #6
    1226         Name => 'FlashExposureCompensation',
     1565        Name => 'FlashExposureComp',
    12271566        Writable => 'rational64s',
     1567    },
     1568    # 0x402 - FlashMode? bit0=TTL, bit2=SuperFP (ref 11)
     1569    0x403 => { #11
     1570        Name => 'FlashRemoteControl',
     1571        Writable => 'int16u',
     1572        PrintHex => 1,
     1573        PrintConv => {
     1574            0 => 'Off',
     1575            0x01 => 'Channel 1, Low',
     1576            0x02 => 'Channel 2, Low',
     1577            0x03 => 'Channel 3, Low',
     1578            0x04 => 'Channel 4, Low',
     1579            0x09 => 'Channel 1, Mid',
     1580            0x0a => 'Channel 2, Mid',
     1581            0x0b => 'Channel 3, Mid',
     1582            0x0c => 'Channel 4, Mid',
     1583            0x11 => 'Channel 1, High',
     1584            0x12 => 'Channel 2, High',
     1585            0x13 => 'Channel 3, High',
     1586            0x14 => 'Channel 4, High',
     1587        },
     1588    },
     1589    0x404 => { #11
     1590        Name => 'FlashControlMode',
     1591        Writable => 'int16u',
     1592        Count => 3,
     1593        PrintConv => [{
     1594            0 => 'Off',
     1595            3 => 'TTL',
     1596            4 => 'Auto',
     1597            5 => 'Manual',
     1598        }],
     1599    },
     1600    0x405 => { #11
     1601        Name => 'FlashIntensity',
     1602        Writable => 'rational64s',
     1603        Count => 3,
     1604        PrintConv => '$val eq "undef undef undef" ? "n/a" : $val',
     1605        PrintConvInv => '$val eq "n/a" ? "undef undef undef" : $val',
     1606    },
     1607    0x406 => { #11
     1608        Name => 'ManualFlashStrength',
     1609        Writable => 'rational64s',
     1610        Count => 3,
     1611        PrintConv => '$val eq "undef undef undef" ? "n/a" : $val',
     1612        PrintConvInv => '$val eq "n/a" ? "undef undef undef" : $val',
    12281613    },
    12291614    0x500 => { #6
     
    12671652        PrintConv => q{
    12681653            my ($a,$b,$c)=split ' ',$val;
    1269             if ($self->{CameraModel} =~ /^E-1\b/) {
     1654            if ($self->{Model} =~ /^E-1\b/) {
    12701655                $a-=$b; $c-=$b;
    12711656                return "CS$a (min CS0, max CS$c)";
     
    13221707            10 => 'Landscape',
    13231708            11 => 'Night Scene',
     1709            12 => 'Self Portrait', #11
    13241710            13 => 'Panorama', #6
     1711            14 => '2 in 1', #11
     1712            15 => 'Movie', #11
    13251713            16 => 'Landscape+Portrait', #6
    13261714            17 => 'Night+Portrait',
     1715            18 => 'Indoor', #11 (Party - PH)
    13271716            19 => 'Fireworks',
    13281717            20 => 'Sunset',
     1718            21 => 'Beauty Skin', #PH
    13291719            22 => 'Macro',
     1720            23 => 'Super Macro', #11
     1721            24 => 'Food', #11
    13301722            25 => 'Documents',
    13311723            26 => 'Museum',
    1332             28 => 'Beach&Snow',
     1724            27 => 'Shoot & Select', #11
     1725            28 => 'Beach & Snow',
     1726            29 => 'Self Protrait+Timer', #11
    13331727            30 => 'Candle',
     1728            31 => 'Available Light', #11
     1729            32 => 'Behind Glass', #11
     1730            33 => 'My Mode', #11
     1731            34 => 'Pet', #11
    13341732            35 => 'Underwater Wide1', #6
    13351733            36 => 'Underwater Macro', #6
     1734            37 => 'Shoot & Select1', #11
     1735            38 => 'Shoot & Select2', #11
    13361736            39 => 'High Key',
    13371737            40 => 'Digital Image Stabilization', #6
     1738            41 => 'Auction', #11
     1739            42 => 'Beach', #11
     1740            43 => 'Snow', #11
    13381741            44 => 'Underwater Wide2', #6
    13391742            45 => 'Low Key', #6
    13401743            46 => 'Children', #6
     1744            47 => 'Vivid', #11
    13411745            48 => 'Nature Macro', #6
     1746            49 => 'Underwater Snapshot', #11
     1747            50 => 'Shooting Guide', #11
     1748            51 => 'Face Portrait', #PH (NC)
     1749            52 => 'Smile Shot', #PH (NC)
     1750            53 => 'Quick Shutter', #PH (NC)
     1751            54 => 'Slow Shutter', #PH (NC)
     1752            55 => 'Bird Watching', #PH (NC)
     1753            56 => 'Multiple Exposure', #PH (NC)
     1754            57 => 'e-Portrait', #PH (NC)
     1755            58 => 'Beauty Fix', #PH (NC)
     1756            59 => 'Soft Background', #PH (NC)
    13421757        },
    13431758    },
     
    13461761        Writable => 'int16u',
    13471762        PrintConv => {
    1348             0 => 'Off',
    1349             1 => 'Noise Reduction',
    1350             2 => 'Noise Filter',
    1351             3 => 'Noise Reduction + Noise Filter',
    1352             4 => 'Noise Filter (ISO Boost)', #6
    1353             5 => 'Noise Reduction + Noise Filter (ISO Boost)', #6
     1763            BITMASK => {
     1764                0 => 'Noise Reduction',
     1765                1 => 'Noise Filter',
     1766                2 => 'Noise Filter (ISO Boost)',
     1767                3 => 'Auto', #11
     1768            },
    13541769        },
    13551770    },
     
    13711786        Name => 'Gradation',
    13721787        Writable => 'int16s',
    1373         Count => 3,
    1374         PrintConv => {
     1788        Notes => '3 or 4 values',
     1789        Count => -1,
     1790        Relist => [ [0..2], 3 ], # join values 0-2 for PrintConv
     1791        PrintConv => [{
    13751792           '-1 -1 1' => 'Low Key',
    13761793            '0 -1 1' => 'Normal',
    13771794            '1 -1 1' => 'High Key',
    1378         },
     1795        },{
     1796            0 => 'User-Selected',
     1797            1 => 'Auto-Override',
     1798        }],
    13791799    },
    13801800    0x520 => { #6
    13811801        Name => 'PictureMode',
    13821802        Writable => 'int16u',
    1383         PrintConv => {
     1803        Notes => '1 or 2 values',
     1804        Count => -1,
     1805        PrintConv => [{
    13841806            1 => 'Vivid',
    13851807            2 => 'Natural',
    13861808            3 => 'Muted',
     1809            4 => 'Portrait',
     1810            5 => 'i-Enhance', #11
    13871811            256 => 'Monotone',
    13881812            512 => 'Sepia',
    1389         },
     1813        }],
    13901814    },
    13911815    0x521 => { #6
     
    14531877           '1 -2 1' => 'High',
    14541878        },
     1879    },
     1880    0x529 => { #PH
     1881        Name => 'ArtFilter',
     1882        Writable => 'int16u',
     1883        Count => 4,
     1884        PrintConv => [ \%filters ],
     1885    },
     1886    0x52c => { #PH
     1887        Name => 'MagicFilter',
     1888        Writable => 'int16u',
     1889        Count => 4, # (2nd number is 0 or 1280, 3rd/4th are 0)
     1890        PrintConv => [ \%filters ],
    14551891    },
    14561892    0x600 => { #PH/4
     
    14901926            return 'Off' unless $a;
    14911927            my %a = (
    1492                 1 => 'Left to right',
    1493                 2 => 'Right to left',
    1494                 3 => 'Bottom to top',
    1495                 4 => 'Top to bottom',
     1928                1 => 'Left to Right',
     1929                2 => 'Right to Left',
     1930                3 => 'Bottom to Top',
     1931                4 => 'Top to Bottom',
    14961932            );
    14971933            return ($a{$a} || "Unknown ($a)") . ', Shot ' . $b;
     
    15061942            3 => 'SHQ',
    15071943            4 => 'RAW',
    1508         },
     1944            5 => 'SQ (5)', # (E-500)
     1945        },
     1946    },
     1947    0x604 => { #PH
     1948        Name => 'ImageStabilization',
     1949        Writable => 'int32u',
     1950        DataMember => 'ImageStabilization',
     1951        RawConv => '$$self{ImageStabilization} = $val',
     1952        PrintConv => {
     1953            0 => 'Off',
     1954            1 => 'On, Mode 1',
     1955            2 => 'On, Mode 2',
     1956            3 => 'On, Mode 3',
     1957        },
     1958    },
     1959    0x900 => { #11
     1960        Name => 'ManometerPressure',
     1961        Writable => 'int16u',
     1962        ValueConv => '$val / 10',
     1963        ValueConvInv => '$val * 10',
     1964        PrintConv => '"$val kPa"',
     1965        PrintConvInv => '$val=~s/ ?kPa//i; $val',
    15091966    },
    15101967    0x901 => { #PH (u770SW)
     
    15131970        Writable => 'int32s',
    15141971        Count => 2,
     1972        ValueConv => 'my @a=split(" ",$val); $_ /= 10 foreach @a; "@a"',
     1973        ValueConvInv => 'my @a=split(" ",$val); $_ *= 10 foreach @a; "@a"',
     1974        PrintConv => '$val=~s/(\S+) (\S+)/$1 m, $2 ft/; $val',
     1975        PrintConvInv => '$val=~s/ ?(m|ft)//gi; $val',
     1976    },
     1977    0x902 => { #11
     1978        Name => 'ExtendedWBDetect',
     1979        Writable => 'int16u',
     1980        PrintConv => \%offOn,
     1981    },
     1982    0x903 => { #11
     1983        Name => 'LevelGaugeRoll',
     1984        Writable => 'int16u',
     1985        PrintConv => \%offOn,
     1986    },
     1987    0x904 => { #11
     1988        Name => 'LevelGaugePitch',
     1989        Writable => 'int16u',
     1990        PrintConv => \%offOn,
    15151991    },
    15161992);
     
    15252001        Name => 'RawDevVersion',
    15262002        Writable => 'undef',
     2003        RawConv => '$val=~s/\0+$//; $val',  # (may be null terminated)
    15272004        Count => 4,
    15282005    },
     
    15892066                0 => 'Noise Reduction',
    15902067                1 => 'Noise Filter',
    1591                 2 => 'ISO Boost',
     2068                2 => 'Noise Filter (ISO Boost)',
    15922069            },
    15932070        },
     
    16092086            BITMASK => {
    16102087                0 => 'WB Color Temp',
    1611                 2 => 'WB Gray Point',
    1612                 3 => 'Saturation',
    1613                 4 => 'Contrast',
    1614                 5 => 'Sharpness',
    1615                 6 => 'Color Space',
    1616                 7 => 'High Function',
    1617                 8 => 'Noise Reduction',
     2088                1 => 'WB Gray Point',
     2089                2 => 'Saturation',
     2090                3 => 'Contrast',
     2091                4 => 'Sharpness',
     2092                5 => 'Color Space',
     2093                6 => 'High Function',
     2094                7 => 'Noise Reduction',
    16182095            },
    16192096        },
     
    16302107        Name => 'RawDevVersion',
    16312108        Writable => 'undef',
     2109        RawConv => '$val=~s/\0+$//; $val',  # (may be null terminated)
    16322110        Count => 4,
    16332111    },
     
    16922170                0 => 'Noise Reduction',
    16932171                1 => 'Noise Filter',
    1694                 2 => 'ISO Boost',
     2172                2 => 'Noise Filter (ISO Boost)',
    16952173            },
    16962174        },
     
    17562234        Writable => 'int16s',
    17572235        Count => 3,
     2236    },
     2237    0x113 => {
     2238        Name => 'RawDevSaturation3',
     2239        Writable => 'int16s',
     2240        Count => 3, #(NC)
     2241    },
     2242    0x119 => {
     2243        Name => 'RawDevAutoGradation',
     2244        Writable => 'int16u', #(NC)
     2245        PrintConv => \%offOn,
     2246    },
     2247    0x120 => {
     2248        Name => 'RawDevPMNoiseFilter',
     2249        Writable => 'int16u', #(NC)
    17582250    },
    17592251);
     
    17682260        Name => 'ImageProcessingVersion',
    17692261        Writable => 'undef',
     2262        RawConv => '$val=~s/\0+$//; $val',  # (may be null terminated)
    17702263        Count => 4,
    17712264    },
     
    17752268        Count => 2,
    17762269    },
     2270    0x102 => { #11
     2271        Name => 'WB_RBLevels3000K',
     2272        Writable => 'int16u',
     2273        Count => 2,
     2274    },
     2275    0x103 => { #11
     2276        Name => 'WB_RBLevels3300K',
     2277        Writable => 'int16u',
     2278        Count => 2,
     2279    },
     2280    0x104 => { #11
     2281        Name => 'WB_RBLevels3600K',
     2282        Writable => 'int16u',
     2283        Count => 2,
     2284    },
     2285    0x105 => { #11
     2286        Name => 'WB_RBLevels3900K',
     2287        Writable => 'int16u',
     2288        Count => 2,
     2289    },
     2290    0x106 => { #11
     2291        Name => 'WB_RBLevels4000K',
     2292        Writable => 'int16u',
     2293        Count => 2,
     2294    },
     2295    0x107 => { #11
     2296        Name => 'WB_RBLevels4300K',
     2297        Writable => 'int16u',
     2298        Count => 2,
     2299    },
     2300    0x108 => { #11
     2301        Name => 'WB_RBLevels4500K',
     2302        Writable => 'int16u',
     2303        Count => 2,
     2304    },
     2305    0x109 => { #11
     2306        Name => 'WB_RBLevels4800K',
     2307        Writable => 'int16u',
     2308        Count => 2,
     2309    },
     2310    0x10a => { #11
     2311        Name => 'WB_RBLevels5300K',
     2312        Writable => 'int16u',
     2313        Count => 2,
     2314    },
     2315    0x10b => { #11
     2316        Name => 'WB_RBLevels6000K',
     2317        Writable => 'int16u',
     2318        Count => 2,
     2319    },
     2320    0x10c => { #11
     2321        Name => 'WB_RBLevels6600K',
     2322        Writable => 'int16u',
     2323        Count => 2,
     2324    },
     2325    0x10d => { #11
     2326        Name => 'WB_RBLevels7500K',
     2327        Writable => 'int16u',
     2328        Count => 2,
     2329    },
     2330    0x10e => { #11
     2331        Name => 'WB_RBLevelsCWB1',
     2332        Writable => 'int16u',
     2333        Count => 2,
     2334    },
     2335    0x10f => { #11
     2336        Name => 'WB_RBLevelsCWB2',
     2337        Writable => 'int16u',
     2338        Count => 2,
     2339    },
     2340    0x110 => { #11
     2341        Name => 'WB_RBLevelsCWB3',
     2342        Writable => 'int16u',
     2343        Count => 2,
     2344    },
     2345    0x111 => { #11
     2346        Name => 'WB_RBLevelsCWB4',
     2347        Writable => 'int16u',
     2348        Count => 2,
     2349    },
     2350    0x113 => { #11
     2351        Name => 'WB_GLevel3000K',
     2352        Writable => 'int16u',
     2353    },
     2354    0x114 => { #11
     2355        Name => 'WB_GLevel3300K',
     2356        Writable => 'int16u',
     2357    },
     2358    0x115 => { #11
     2359        Name => 'WB_GLevel3600K',
     2360        Writable => 'int16u',
     2361    },
     2362    0x116 => { #11
     2363        Name => 'WB_GLevel3900K',
     2364        Writable => 'int16u',
     2365    },
     2366    0x117 => { #11
     2367        Name => 'WB_GLevel4000K',
     2368        Writable => 'int16u',
     2369    },
     2370    0x118 => { #11
     2371        Name => 'WB_GLevel4300K',
     2372        Writable => 'int16u',
     2373    },
     2374    0x119 => { #11
     2375        Name => 'WB_GLevel4500K',
     2376        Writable => 'int16u',
     2377    },
     2378    0x11a => { #11
     2379        Name => 'WB_GLevel4800K',
     2380        Writable => 'int16u',
     2381    },
     2382    0x11b => { #11
     2383        Name => 'WB_GLevel5300K',
     2384        Writable => 'int16u',
     2385    },
     2386    0x11c => { #11
     2387        Name => 'WB_GLevel6000K',
     2388        Writable => 'int16u',
     2389    },
     2390    0x11d => { #11
     2391        Name => 'WB_GLevel6600K',
     2392        Writable => 'int16u',
     2393    },
     2394    0x11e => { #11
     2395        Name => 'WB_GLevel7500K',
     2396        Writable => 'int16u',
     2397    },
     2398    0x11f => { #11
     2399        Name => 'WB_GLevel',
     2400        Writable => 'int16u',
     2401    },
    17772402    0x200 => { #6
    17782403        Name => 'ColorMatrix',
     
    17812406        Count => 9,
    17822407    },
    1783     0x300 => { #PH/4
    1784         Name => 'SmoothingParameter1',
    1785         Writable => 'int16u',
    1786     },
    1787     0x310 => { #PH/4
    1788         Name => 'SmoothingParameter2',
    1789         Writable => 'int16u',
    1790     },
    1791     0x600 => { #PH/4
    1792         Name => 'SmoothingThresholds',
     2408    # color matrices (ref 11):
     2409    # 0x0201-0x020d are sRGB color matrices
     2410    # 0x020e-0x021a are Adobe RGB color matrices
     2411    # 0x021b-0x0227 are ProPhoto RGB color matrices
     2412    # 0x0228 and 0x0229 are ColorMatrix for E-330
     2413    # 0x0250-0x0252 are sRGB color matrices
     2414    # 0x0253-0x0255 are Adobe RGB color matrices
     2415    # 0x0256-0x0258 are ProPhoto RGB color matrices
     2416    0x300 => { #11
     2417        Name => 'Enhancer',
     2418        Writable => 'int16u',
     2419    },
     2420    0x301 => { #11
     2421        Name => 'EnhancerValues',
     2422        Writable => 'int16u',
     2423        Count => 7,
     2424    },
     2425    0x310 => { #11
     2426        Name => 'CoringFilter',
     2427        Writable => 'int16u',
     2428    },
     2429    0x0311 => { #11
     2430        Name => 'CoringValues',
     2431        Writable => 'int16u',
     2432        Count => 7,
     2433    },
     2434    0x600 => { #11
     2435        Name => 'BlackLevel2',
    17932436        Writable => 'int16u',
    17942437        Count => 4,
    17952438    },
    1796     0x610 => { #PH/4
    1797         Name => 'SmoothingThreshold2',
     2439    0x610 => { #11
     2440        Name => 'GainBase',
    17982441        Writable => 'int16u',
    17992442    },
     
    18032446        Count => 2,
    18042447    },
    1805     0x614 => { #PH
    1806         Name => 'OlympusImageWidth2',
     2448    0x612 => { #11
     2449        Name => 'CropLeft',
     2450        Writable => 'int16u',
     2451        Count => 2,
     2452    },
     2453    0x613 => { #11
     2454        Name => 'CropTop',
     2455        Writable => 'int16u',
     2456        Count => 2,
     2457    },
     2458    0x614 => { #PH/11
     2459        Name => 'CropWidth',
    18072460        Writable => 'int32u',
    18082461    },
    1809     0x615 => { #PH
    1810         Name => 'OlympusImageHeight2',
     2462    0x615 => { #PH/11
     2463        Name => 'CropHeight',
    18112464        Writable => 'int32u',
    18122465    },
     2466    # 0x800 LensDistortionParams, float[9] (ref 11)
     2467    # 0x801 LensShadingParams, int16u[16] (ref 11)
    18132468    # 0x1010-0x1012 are the processing options used in camera or in
    18142469    # Olympus software, which 0x050a-0x050c are in-camera only (ref 6)
     
    18172472        Writable => 'int16u',
    18182473        PrintConv => {
    1819             0 => 'Off',
    1820             1 => 'Noise Filter',
    1821             2 => 'Noise Reduction',
    1822             3 => 'Noise Reduction + Noise Filter', #6
    1823             4 => 'Noise Filter (ISO Boost)', #6
    1824             5 => 'Noise Reduction + Noise Filter (ISO Boost)', #6
     2474            BITMASK => {
     2475                0 => 'Noise Reduction',
     2476                1 => 'Noise Filter',
     2477                2 => 'Noise Filter (ISO Boost)',
     2478            },
    18252479        },
    18262480    },
     
    18282482        Name => 'DistortionCorrection2',
    18292483        Writable => 'int16u',
    1830         PrintConv => {
    1831             0 => 'Off',
    1832             1 => 'On',
    1833         },
     2484        PrintConv => \%offOn,
    18342485    },
    18352486    0x1012 => { #PH/4
     
    18372488        Writable => 'int16u',
    18382489        PrintConv => \%offOn,
     2490    },
     2491    0x101c => { #11
     2492        Name => 'MultipleExposureMode',
     2493        Writable => 'int16u',
     2494        Count => 2,
     2495        PrintConv => [{
     2496            0 => 'Off',
     2497            2 => 'On (2 frames)',
     2498            3 => 'On (3 frames)',
     2499        }],
    18392500    },
    18402501    0x1103 => { #PH
     
    18442505        # 'Drop' because too large for APP1 in JPEG images
    18452506        Flags => [ 'Unknown', 'Binary', 'Drop' ],
     2507    },
     2508    0x1112 => { #11
     2509        Name => 'AspectRatio',
     2510        Writable => 'int8u',
     2511        Count => 2,
     2512        PrintConv => {
     2513            '1 1' => '4:3',
     2514            '2 2' => '3:2',
     2515            '3 3' => '16:9',
     2516            '4 4' => '6:6',
     2517            '5 5' => '5:4',
     2518            '6 6' => '7:6',
     2519            '7 7' => '6:5',
     2520            '8 8' => '7:5',
     2521            '9 9' => '3:4',
     2522        },
     2523    },
     2524    0x1113 => { #11
     2525        Name => 'AspectFrame',
     2526        Writable => 'int16u',
     2527        Count => 4,
     2528    },
     2529    0x1200 => { #11/PH
     2530        Name => 'FacesDetected',
     2531        Writable => 'int32u',
     2532        Count => -1,
     2533        Notes => '2 or 3 values',
     2534    },
     2535    0x1201 => { #11/PH
     2536        Name => 'FaceDetectArea',
     2537        Writable => 'int16s',
     2538        Count => -1, # (varies with model)
     2539        Binary => 1, # (too long)
     2540        Notes => q{
     2541            for models with 2 values in FacesDetected this gives X/Y coordinates in the
     2542            FaceDetectFrame for all 4 corners of the face rectangle.  For models with 3
     2543            values in FacesDetected this gives X/Y coordinates, size and rotation angle
     2544            of the face detect square
     2545        },
     2546    },
     2547    0x1202 => { #PH
     2548        Name => 'MaxFaces',
     2549        Writable => 'int32u',
     2550        Count => 3,
     2551    },
     2552    0x1203 => { #PH
     2553        Name => 'FaceDetectFrameSize',
     2554        Writable => 'int16u',
     2555        Count => 6,
     2556        Notes => 'width/height of the full face detect frame',
     2557    },
     2558    0x1207 => { #PH
     2559        Name => 'FaceDetectFrameCrop',
     2560        Writable => 'int16s',
     2561        Count => 12,
     2562        Notes => 'X/Y offset and width/height of the cropped face detect frame',
    18462563    },
    18472564);
     
    18562573        Name => 'FocusInfoVersion',
    18572574        Writable => 'undef',
     2575        RawConv => '$val=~s/\0+$//; $val',  # (may be null terminated)
    18582576        Count => 4,
    18592577    },
     
    18642582        Unknown => 1, #6
    18652583    },
     2584    0x210 => { #11
     2585        Name => 'SceneDetect',
     2586        Writable => 'int16u',
     2587    },
     2588    0x211 => { #11
     2589        Name => 'SceneArea',
     2590        Writable => 'int32u',
     2591        Count => 8,
     2592        Unknown => 1, # (numbers don't make much sense?)
     2593    },
     2594    0x212 => { #11
     2595        Name => 'SceneDetectData',
     2596        Writable => 'int32u',
     2597        Count => 720,
     2598        Binary => 1,
     2599        Unknown => 1, # (but what does it mean?)
     2600    },
    18662601    0x300 => { #6
    18672602        Name => 'ZoomStepCount',
     
    18702605    0x301 => { #11
    18712606        Name => 'FocusStepCount',
     2607        Writable => 'int16u',
     2608    },
     2609    0x303 => { #11
     2610        Name => 'FocusStepInfinity',
     2611        Writable => 'int16u',
     2612    },
     2613    0x304 => { #11
     2614        Name => 'FocusStepNear',
    18722615        Writable => 'int16u',
    18732616    },
     
    18932636        PrintConvInv => '$val eq "inf" ? 0 : $val=~s/\s*m$//, $val',
    18942637    },
    1895     0x308 => { #11
    1896         Name => 'AFPoint',
    1897         Writable => 'int16u',
    1898         PrintConv => {
    1899             0 => 'Left',
    1900             1 => 'Center (1)',
    1901             2 => 'Right',
    1902             3 => 'Center (3)',
    1903             255 => 'None',
    1904         },
    1905     },
     2638    0x308 => [ # NEED A BETTER WAY TO DETERMINE WHICH MODELS USE WHICH ENCODING!
     2639        {
     2640            Name => 'AFPoint',
     2641            Condition => '$$self{Model} =~ /E-(3|5|30)\b/',
     2642            Writable => 'int16u',
     2643            PrintHex => 1,
     2644            # decoded by ref 6
     2645            Notes => q{
     2646                for the E-3, E-5 and E-30 the value is separated into 2 parts: low 5 bits
     2647                give AF point, upper bits give AF target selection mode
     2648            },
     2649            ValueConv => '($val & 0x1f) . " " . ($val & 0xffe0)',
     2650            ValueConvInv => 'my @v=split(" ",$val); @v == 2 ? $v[0] + $v[1] : $val',
     2651            PrintConv => [
     2652                {
     2653                    0x00 => '(none)',
     2654                    0x01 => 'Top-left (horizontal)',
     2655                    0x02 => 'Top-center (horizontal)',
     2656                    0x03 => 'Top-right (horizontal)',
     2657                    0x04 => 'Left (horizontal)',
     2658                    0x05 => 'Mid-left (horizontal)',
     2659                    0x06 => 'Center (horizontal)',
     2660                    0x07 => 'Mid-right (horizontal)',
     2661                    0x08 => 'Right (horizontal)',
     2662                    0x09 => 'Bottom-left (horizontal)',
     2663                    0x0a => 'Bottom-center (horizontal)',
     2664                    0x0b => 'Bottom-right (horizontal)',
     2665                    0x0c => 'Top-left (vertical)',
     2666                    0x0d => 'Top-center (vertical)',
     2667                    0x0e => 'Top-right (vertical)',
     2668                    0x0f => 'Left (vertical)',
     2669                    0x10 => 'Mid-left (vertical)',
     2670                    0x11 => 'Center (vertical)',
     2671                    0x12 => 'Mid-right (vertical)',
     2672                    0x13 => 'Right (vertical)',
     2673                    0x14 => 'Bottom-left (vertical)',
     2674                    0x15 => 'Bottom-center (vertical)',
     2675                    0x16 => 'Bottom-right (vertical)',
     2676                },
     2677                {
     2678                    0x00 => 'Single Target',
     2679                    0x40 => 'All Target',
     2680                    0x80 => 'Dynamic Single Target',
     2681                }
     2682            ],
     2683        },{ #PH (models with 7-point AF)
     2684            Name => 'AFPoint',
     2685            Condition => '$$self{Model} =~ /E-(520|600|620)\b/',
     2686            Notes => 'models with 7-point AF',
     2687            Writable => 'int16u',
     2688            PrintHex => 1,
     2689            ValueConv => '($val & 0x1f) . " " . ($val & 0xffe0)',
     2690            ValueConvInv => 'my @v=split(" ",$val); @v == 2 ? $v[0] + $v[1] : $val',
     2691            PrintConv => [
     2692                {
     2693                    0x00 => '(none)',
     2694                    0x01 => 'Center',
     2695                    # need to fill this in...
     2696                },
     2697                {
     2698                    0x00 => 'Single Target',
     2699                    0x40 => 'All Target', # (guess)
     2700                },
     2701            ]
     2702        },{ #11
     2703            Name => 'AFPoint',
     2704            Writable => 'int16u',
     2705            Notes => 'other models',
     2706            RawConv => '($val or $$self{Model} ne "E-P1") ? $val : undef',
     2707            PrintConv => {
     2708                # (E-P1 always writes 0, maybe other models do too - PH)
     2709                0 => 'Left (or n/a)',
     2710                1 => 'Center (horizontal)', #6 (E-510)
     2711                2 => 'Right',
     2712                3 => 'Center (vertical)', #6 (E-510)
     2713                255 => 'None',
     2714            },
     2715        }
     2716    ],
    19062717    # 0x31a Continuous AF parameters?
     2718    # 0x328 Related to AF (maybe Imager AF data?) (ref PH, E-PL1):
     2719    #  - offset 0x2a (int8u)  ImagerAFMode?  0=Manual, 1=Auto
     2720    #  - offset 0x30 (int16u) AFAreaXPosition
     2721    #  - offset 0x32 (int16u) AFAreaWidth (202)
     2722    #  - offset 0x34 (int16u) AFAreaYPosition
     2723    #  - offset 0x36 (int16u) AFAreaHeight (50)
     2724    #  (AF area positions above give the top-left coordinates of the AF area in the
     2725    #   AF frame. Increasing Y is downwards, and the AF frame size is about 1280x256)
    19072726    # 0x1200-0x1209 Flash information:
    19082727    0x1201 => { #6
     
    19582777        Name => 'SensorTemperature',
    19592778        Writable => 'int16s',
     2779        Notes => q{
     2780            approximately Celsius for E-1, unknown calibration for E-3/410/420/510, and
     2781            always zero for E-300/330/400/500, divide by 10 for E-P1?
     2782        },
    19602783    },
    19612784    0x1600 => { # ref http://fourthirdsphoto.com/vbb/showpost.php?p=107607&postcount=15
    19622785        Name => 'ImageStabilization',
     2786        # (the other value is more reliable, so ignore this totally if the other exists)
     2787        Condition => 'not defined $$self{ImageStabilization}',
    19632788        Writable => 'undef',
    19642789        # if the first 4 bytes are non-zero, then bit 0x01 of byte 44
     
    19812806        Name => 'RawInfoVersion',
    19822807        Writable => 'undef',
     2808        RawConv => '$val=~s/\0+$//; $val',  # (may be null terminated)
    19832809        Count => 4,
    19842810    },
    19852811    0x100 => {
    19862812        Name => 'WB_RBLevelsUsed',
    1987         Writable => 'int16',
     2813        Writable => 'int16u',
    19882814        Count => 2,
    19892815    },
    19902816    0x110 => {
    19912817        Name => 'WB_RBLevelsAuto',
    1992         Writable => 'int16',
     2818        Writable => 'int16u',
    19932819        Count => 2,
    19942820    },
    19952821    0x120 => {
    19962822        Name => 'WB_RBLevelsShade',
    1997         Writable => 'int16',
     2823        Writable => 'int16u',
    19982824        Count => 2,
    19992825    },
    20002826    0x121 => {
    20012827        Name => 'WB_RBLevelsCloudy',
    2002         Writable => 'int16',
     2828        Writable => 'int16u',
    20032829        Count => 2,
    20042830    },
    20052831    0x122 => {
    20062832        Name => 'WB_RBLevelsFineWeather',
    2007         Writable => 'int16',
     2833        Writable => 'int16u',
    20082834        Count => 2,
    20092835    },
    20102836    0x123 => {
    20112837        Name => 'WB_RBLevelsTungsten',
    2012         Writable => 'int16',
     2838        Writable => 'int16u',
    20132839        Count => 2,
    20142840    },
    20152841    0x124 => {
    20162842        Name => 'WB_RBLevelsEveningSunlight',
    2017         Writable => 'int16',
     2843        Writable => 'int16u',
    20182844        Count => 2,
    20192845    },
    20202846    0x130 => {
    20212847        Name => 'WB_RBLevelsDaylightFluor',
    2022         Writable => 'int16',
     2848        Writable => 'int16u',
    20232849        Count => 2,
    20242850    },
    20252851    0x131 => {
    20262852        Name => 'WB_RBLevelsDayWhiteFluor',
    2027         Writable => 'int16',
     2853        Writable => 'int16u',
    20282854        Count => 2,
    20292855    },
    20302856    0x132 => {
    20312857        Name => 'WB_RBLevelsCoolWhiteFluor',
    2032         Writable => 'int16',
     2858        Writable => 'int16u',
    20332859        Count => 2,
    20342860    },
    20352861    0x133 => {
    20362862        Name => 'WB_RBLevelsWhiteFluorescent',
    2037         Writable => 'int16',
     2863        Writable => 'int16u',
    20382864        Count => 2,
    20392865    },
     
    20752901    },
    20762902    0x612 => { #11
    2077         Name => 'StartOffsetX',
     2903        Name => 'CropLeft',
    20782904        Writable => 'int16u',
    20792905    },
    20802906    0x613 => { #11
    2081         Name => 'StartOffsetY',
     2907        Name => 'CropTop',
    20822908        Writable => 'int16u',
    20832909    },
    20842910    0x614 => {
    2085         Name => 'FinalImageWidth',
     2911        Name => 'CropWidth',
    20862912        Writable => 'int32u',
    20872913    },
    20882914    0x615 => {
    2089         Name => 'FinalImageHeight',
     2915        Name => 'CropHeight',
    20902916        Writable => 'int32u',
    20912917    },
     
    20982924            17 => 'Cloudy',
    20992925            18 => 'Fine Weather',
    2100             20 => 'Tungsten (incandescent)',
     2926            20 => 'Tungsten (Incandescent)',
    21012927            22 => 'Evening Sunlight',
    2102             33 => 'Daylight Fluorescent (D 5700 - 7100K)',
    2103             34 => 'Day White Fluorescent (N 4600 - 5400K)',
    2104             35 => 'Cool White Fluorescent (W 3900 - 4500K)',
    2105             36 => 'White Fluorescent (WW 3200 - 3700K)',
     2928            33 => 'Daylight Fluorescent',
     2929            34 => 'Day White Fluorescent',
     2930            35 => 'Cool White Fluorescent',
     2931            36 => 'White Fluorescent',
    21062932            256 => 'One Touch White Balance',
    21072933            512 => 'Custom 1-4',
     
    21722998        Count => 3,
    21732999    },
     3000);
     3001
     3002# Olympus unknown information tags
     3003%Image::ExifTool::Olympus::UnknownInfo = (
     3004    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     3005    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     3006    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    21743007);
    21753008
     
    21893022);
    21903023
     3024# tags in Olympus QuickTime videos (ref PH)
     3025# (similar information in Kodak,Minolta,Nikon,Olympus,Pentax and Sanyo videos)
     3026%Image::ExifTool::Olympus::MOV1 = (
     3027    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     3028    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3029    FIRST_ENTRY => 0,
     3030    NOTES => q{
     3031        This information is found in MOV videos from Olympus models such as the
     3032        D540Z, D595Z, FE100, FE110, FE115, FE170 and FE200.
     3033    },
     3034    0x00 => {
     3035        Name => 'Make',
     3036        Format => 'string[24]',
     3037    },
     3038    0x18 => {
     3039        Name => 'Model',
     3040        Format => 'string[8]',
     3041    },
     3042    # (01 00 at offset 0x20)
     3043    0x26 => {
     3044        Name => 'ExposureUnknown',
     3045        Unknown => 1,
     3046        Format => 'int32u',
     3047        # this conversion doesn't work for all models (ie. gives "1/100000")
     3048        ValueConv => '$val ? 10 / $val : 0',
     3049        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     3050    },
     3051    0x2a => {
     3052        Name => 'FNumber',
     3053        Format => 'rational64u',
     3054        PrintConv => 'sprintf("%.1f",$val)',
     3055    },
     3056    0x32 => { #(NC)
     3057        Name => 'ExposureCompensation',
     3058        Format => 'rational64s',
     3059        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     3060    },
     3061  # 0x44 => WhiteBalance ?
     3062    0x48 => {
     3063        Name => 'FocalLength',
     3064        Format => 'rational64u',
     3065        PrintConv => 'sprintf("%.1f mm",$val)',
     3066    },
     3067  # 0xb1 => 'ISO', #(I don't think this works - PH)
     3068);
     3069
     3070# tags in Olympus QuickTime videos (ref PH)
     3071# (similar information in Kodak,Minolta,Nikon,Olympus,Pentax and Sanyo videos)
     3072%Image::ExifTool::Olympus::MOV2 = (
     3073    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     3074    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3075    FIRST_ENTRY => 0,
     3076    NOTES => q{
     3077        This information is found in MOV videos from Olympus models such as the
     3078        FE120, FE140 and FE190.
     3079    },
     3080    0x00 => {
     3081        Name => 'Make',
     3082        Format => 'string[24]',
     3083    },
     3084    0x18 => {
     3085        Name => 'Model',
     3086        Format => 'string[24]',
     3087    },
     3088    # (01 00 at offset 0x30)
     3089    0x36 => {
     3090        Name => 'ExposureTime',
     3091        Format => 'int32u',
     3092        ValueConv => '$val ? 10 / $val : 0',
     3093        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     3094    },
     3095    0x3a => {
     3096        Name => 'FNumber',
     3097        Format => 'rational64u',
     3098        PrintConv => 'sprintf("%.1f",$val)',
     3099    },
     3100    0x42 => { #(NC)
     3101        Name => 'ExposureCompensation',
     3102        Format => 'rational64s',
     3103        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     3104    },
     3105    0x58 => {
     3106        Name => 'FocalLength',
     3107        Format => 'rational64u',
     3108        PrintConv => 'sprintf("%.1f mm",$val)',
     3109    },
     3110    0xc1 => {
     3111        Name => 'ISO',
     3112        Format => 'int16u',
     3113    },
     3114);
     3115
     3116# tags in Olympus MP4 videos (ref PH)
     3117%Image::ExifTool::Olympus::MP4 = (
     3118    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     3119    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3120    FIRST_ENTRY => 0,
     3121    NOTES => q{
     3122        This information is found in MP4 videos from Olympus models such as the
     3123        u7040 and u9010.
     3124    },
     3125    0x00 => {
     3126        Name => 'Make',
     3127        Format => 'string[24]',
     3128    },
     3129    0x18 => {
     3130        Name => 'Model',
     3131        Format => 'string[24]',
     3132    },
     3133    0x28 => {
     3134        Name => 'FNumber',
     3135        Format => 'rational64u',
     3136        PrintConv => 'sprintf("%.1f",$val)',
     3137    },
     3138    0x30 => { #(NC)
     3139        Name => 'ExposureCompensation',
     3140        Format => 'rational64s',
     3141        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     3142    },
     3143    # NEED MORE SAMPLES TO DECODE THIS
     3144);
     3145
     3146# tags in Olympus AVI videos (ref PH)
     3147%Image::ExifTool::Olympus::AVI = (
     3148    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     3149    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3150    FIRST_ENTRY => 0,
     3151    NOTES => 'This information is found in Olympus AVI videos.',
     3152    0x12 => {
     3153        Name => 'Make',
     3154        Format => 'string[24]',
     3155    },
     3156    0x2c => {
     3157        Name => 'ModelType',
     3158        Format => 'string[24]',
     3159    },
     3160    0x5e => {
     3161        Name => 'FNumber',
     3162        Format => 'rational64u',
     3163        PrintConv => 'sprintf("%.1f",$val)',
     3164    },
     3165    0x83 => {
     3166        Name => 'DateTime1',
     3167        Format => 'string[24]',
     3168        Groups => { 2 => 'Time' },
     3169    },
     3170    0x9d => {
     3171        Name => 'DateTime2',
     3172        Format => 'string[24]',
     3173        Groups => { 2 => 'Time' },
     3174    },
     3175    0x12d => {
     3176        Name => 'ThumbnailLength',
     3177        Format => 'int32u',
     3178    },
     3179    0x131 => {
     3180        Name => 'ThumbnailImage',
     3181        Format => 'undef[$val{0x12d}]',
     3182        Notes => '160x120 JPEG thumbnail image',
     3183        RawConv => '$self->ValidateImage(\$val,$tag)',
     3184    },
     3185);
     3186
     3187# tags in WAV files from Olympus PCM linear recorders (ref 18)
     3188%Image::ExifTool::Olympus::WAV = (
     3189    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     3190    GROUPS => { 0 => 'MakerNotes', 2 => 'Audio' },
     3191    FIRST_ENTRY => 0,
     3192    NOTES => q{
     3193        This information is found in WAV files from Olympus PCM linear recorders
     3194        like the LS-5, LS-10, LS-11.
     3195    },
     3196    0x0c => {
     3197        Name => 'Model',
     3198        Format => 'string[16]',
     3199    },
     3200    0x1c => {
     3201        Name => 'FileNumber',
     3202        Format => 'int32u',
     3203        PrintConv => 'sprintf("%.4d", $val)',
     3204    },
     3205    0x26 => {
     3206        Name => 'DateTimeOriginal',
     3207        Description => 'Date/Time Original',
     3208        Groups => { 2 => 'Time' },
     3209        Format => 'undef[12]',
     3210        Notes => 'time at start of recording',
     3211        ValueConv => q{
     3212            return undef unless $val =~ /^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/;
     3213            my $y = $1 < 70 ? "20$1" : "19$1";
     3214            return "$y:$2:$3 $4:$5:$6";
     3215        },
     3216        PrintConv => '$self->ConvertDateTime($val)',
     3217    },
     3218    0x32 => {
     3219        Name => 'DateTimeEnd',
     3220        Groups => { 2 => 'Time' },
     3221        Format => 'undef[12]',
     3222        Notes => 'time at end of recording',
     3223        ValueConv => q{
     3224            return undef unless $val =~ /^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/;
     3225            my $y = $1 < 70 ? "20$1" : "19$1";
     3226            return "$y:$2:$3 $4:$5:$6";
     3227        },
     3228        PrintConv => '$self->ConvertDateTime($val)',
     3229    },
     3230    0x3e => {
     3231        Name => 'RecordingTime',
     3232        Format => 'undef[6]',
     3233        ValueConv => '$val =~ s/^(\d{2})(\d{2})/$1:$2:/; $val',
     3234    },
     3235    0x200 => {
     3236        Name => 'Duration',
     3237        Format => 'int32u',
     3238        ValueConv => '$val / 1000',
     3239        PrintConv => 'ConvertDuration($val)',
     3240    },
     3241    0x20a => { Name => 'Index01', %indexInfo },
     3242    0x214 => { Name => 'Index02', %indexInfo },
     3243    0x21e => { Name => 'Index03', %indexInfo },
     3244    0x228 => { Name => 'Index04', %indexInfo },
     3245    0x232 => { Name => 'Index05', %indexInfo },
     3246    0x23c => { Name => 'Index06', %indexInfo },
     3247    0x246 => { Name => 'Index07', %indexInfo },
     3248    0x250 => { Name => 'Index08', %indexInfo },
     3249    0x25a => { Name => 'Index09', %indexInfo },
     3250    0x264 => { Name => 'Index10', %indexInfo },
     3251    0x26e => { Name => 'Index11', %indexInfo },
     3252    0x278 => { Name => 'Index12', %indexInfo },
     3253    0x282 => { Name => 'Index13', %indexInfo },
     3254    0x28c => { Name => 'Index14', %indexInfo },
     3255    0x296 => { Name => 'Index15', %indexInfo },
     3256    0x2a0 => { Name => 'Index16', %indexInfo },
     3257);
     3258
    21913259# Olympus composite tags
    21923260%Image::ExifTool::Olympus::Composite = (
     
    22093277            2 => 'Removed',
    22103278        },
     3279    },
     3280    ZoomedPreviewImage => {
     3281        Require => {
     3282            0 => 'ZoomedPreviewStart',
     3283            1 => 'ZoomedPreviewLength',
     3284        },
     3285        RawConv => 'Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"ZoomedPreviewImage")',
    22113286    },
    22123287);
     
    22293304    my @info = split ' ', $extender;
    22303305    # validate that extender identifier is reasonable
    2231     return 0 unless @info >= 4 and $info[2];
     3306    return 0 unless @info >= 2 and $info[1];
    22323307    # if it's not an EC-14 (id 0 4) then assume it was really attached
    22333308    # (other extenders don't seem to affect the reported max aperture)
    2234     return 1 if "$info[0] $info[2]" ne "0 4";
     3309    return 1 if "$info[0] $info[1]" ne '0 4';
    22353310    # get the maximum aperture for this lens (in $1)
    22363311    $lensType =~ / F(\d+(.\d+)?)/ or return 1;
     
    22383313    # known max/max aperture of the lens, then the extender must be attached
    22393314    return ($maxAperture - $1 > 0.2) ? 1 : 2;
    2240 }
    2241 
    2242 #------------------------------------------------------------------------------
    2243 # Print lens information (ref 6)
    2244 # Inputs: 0) Lens info (string of integers: Make, Unknown, Model, Release, ...)
    2245 #         1) 'Lens' or 'Extender'
    2246 sub PrintLensInfo($$)
    2247 {
    2248     my ($val, $type) = @_;
    2249     my @info = split ' ', $val;
    2250     return "Unknown ($val)" unless @info >= 4;
    2251     return 'None' unless $info[2];
    2252     my %make = (
    2253         0 => 'Olympus',
    2254         1 => 'Sigma',
    2255         2 => 'Leica',
    2256         3 => 'Leica',
    2257     );
    2258     my %model = (
    2259         Lens => {
    2260             # Olympus lenses (key is "make model" with optional "release")
    2261             '0 1 0' => 'Zuiko Digital ED 50mm F2.0 Macro',
    2262             '0 1 1' => 'Zuiko Digital 40-150mm F3.5-4.5', #8
    2263             '0 2'   => 'Zuiko Digital ED 150mm F2.0',
    2264             '0 3'   => 'Zuiko Digital ED 300mm F2.8',
    2265             '0 5 0' => 'Zuiko Digital 14-54mm F2.8-3.5',
    2266             '0 5 1' => 'Zuiko Digital Pro ED 90-250mm F2.8', #9
    2267             '0 6 0' => 'Zuiko Digital ED 50-200mm F2.8-3.5',
    2268             '0 6 1' => 'Zuiko Digital ED 8mm F3.5 Fisheye', #9
    2269             '0 7 0' => 'Zuiko Digital 11-22mm F2.8-3.5',
    2270             '0 7 1' => 'Zuiko Digital 18-180mm F3.5-6.3', #6
    2271             '0 21'  => 'Zuiko Digital ED 7-14mm F4.0',
    2272             '0 23'  => 'Zuiko Digital Pro ED 35-100mm F2.0', #7
    2273             '0 24'  => 'Zuiko Digital 14-45mm F3.5-5.6',
    2274             '0 32'  => 'Zuiko Digital 35mm F3.5 Macro', #9
    2275             '0 34'  => 'Zuiko Digital 17.5-45mm F3.5-5.6', #9
    2276             '0 35'  => 'Zuiko Digital ED 14-42mm F3.5-5.6', #PH
    2277             '0 36'  => 'Zuiko Digital ED 40-150mm F4.0-5.6', #PH
    2278             # Sigma lenses
    2279             '1 1'   => '18-50mm F3.5-5.6', #8
    2280             '1 2'   => '55-200mm F4.0-5.6 DC',
    2281             '1 3'   => '18-125mm F3.5-5.6 DC',
    2282             '1 4'   => '18-125mm F3.5-5.6', #7
    2283             '1 5'   => '30mm F1.4', #10
    2284             '1 7'   => '105mm F2.8 DG', #PH
    2285             '1 8'   => '150mm F2.8 DG HSM', #PH
    2286             '1 17'  => '135-400mm F4.5-5.6 DG ASP APO RF', #11
    2287             '1 18'  => '300-800mm F5.6 EX DG APO', #11
    2288             # Leica lenses (ref 11)
    2289             '2 1'   => 'D Vario Elmarit 14-50mm, F2.8-3.5 Asph.',
    2290             '2 2'   => 'D Summilux 25mm, F1.4 Asph.',
    2291             '3 1'   => 'D Vario Elmarit 14-50mm, F2.8-3.5 Asph.',
    2292             '3 2'   => 'D Summilux 25mm, F1.4 Asph.',
    2293         },
    2294         Extender => {
    2295             # Olympus extenders
    2296             '0 4'   => 'Zuiko Digital EC-14 1.4x Teleconverter',
    2297             '0 8'   => 'EX-25 Extension Tube',
    2298         },
    2299     );
    2300     my %release = (
    2301         0 => '', # production
    2302         1 => ' (pre-release)',
    2303     );
    2304     my $make = $make{$info[0]} || "Unknown Make ($info[0])";
    2305     my $str = "$info[0] $info[2]";
    2306     my $rel = $release{$info[3]};
    2307     my $model = $model{$type}->{"$str $info[3]"};
    2308     if ($model) {
    2309         $rel = '';  # don't print release if it is used to differentiate models
    2310     } else {
    2311         $rel = " Unknown Release ($info[3])" unless defined $rel;
    2312         $model = $model{$type}->{$str} || "Unknown Model ($str)";
    2313     }
    2314     return "$make $model$rel";
    23153315}
    23163316
     
    23723372=head1 AUTHOR
    23733373
    2374 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     3374Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    23753375
    23763376This library is free software; you can redistribute it and/or modify it
     
    23943394
    23953395Thanks to Markku Hanninen, Remi Guyomarch, Frank Ledwon, Michael Meissner,
    2396 Mark Dapoz and Ioannis Panagiotopoulos for their help figuring out some
    2397 Olympus tags, and Lilo Huang for adding to the LensType list.
     3396Mark Dapoz, Ioannis Panagiotopoulos and Tomasz Kawecki for their help
     3397figuring out some Olympus tags, and Lilo Huang, Chris Shaw and Viktor
     3398Lushnikov for adding to the LensType list.
    23983399
    23993400=head1 SEE ALSO
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PDF.pm

    r16842 r24107  
    44# Description:  Read PDF meta information
    55#
    6 # Revisions:    07/11/05 - P. Harvey Created
    7 #               07/25/05 - P. Harvey Add support for encrypted documents
    8 #
    9 # References:   1) http://partners.adobe.com/public/developer/pdf/index_reference.html
    10 #               2) http://www.cr0.net:8040/code/crypto/rc4/
     6# Revisions:    07/11/2005 - P. Harvey Created
     7#               07/25/2005 - P. Harvey Add support for encrypted documents
     8#
     9# References:   1) http://www.adobe.com/devnet/pdf/pdf_reference.html
     10#               2) http://search.cpan.org/dist/Crypt-RC4/
     11#               3) http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf
     12#               4) http://www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/adobe_supplement_iso32000.pdf
     13#               5) http://tools.ietf.org/search/rfc3454
     14#               6) http://www.armware.dk/RFC/rfc/rfc4013.html
    1115#------------------------------------------------------------------------------
    1216
     
    1418
    1519use strict;
    16 use vars qw($VERSION);
     20use vars qw($VERSION $AUTOLOAD $lastFetched);
    1721use Image::ExifTool qw(:DataAccess :Utils);
    1822require Exporter;
    1923
    20 $VERSION = '1.10';
    21 
    22 sub LocateObject($$);
     24$VERSION = '1.29';
     25
    2326sub FetchObject($$$$);
    2427sub ExtractObject($$;$$);
    2528sub ReadToNested($;$);
    26 sub ProcessDict($$$$;$);
    27 
    28 my %warnedOnce;     # hash of warnings we issued
     29sub ProcessDict($$$$;$$);
     30sub ReadPDFValue($);
     31sub CheckPDF($$$);
     32
     33# $lastFetched - last fetched object reference (used for decryption)
     34#                (undefined if fetched object was already decrypted, ie. object from stream)
     35
     36my $cryptInfo;      # encryption object reference (plus additional information)
     37my $cryptString;    # flag that strings are encrypted
     38my $cryptStream;    # flag that streams are encrypted
     39my $lastOffset;     # last fetched object offset
    2940my %streamObjs;     # hash of stream objects
    3041my %fetched;        # dicts fetched in verbose mode (to avoid cyclical recursion)
    31 my $lastFetched;    # last fetched object reference (used for decryption)
    32 my $cryptInfo;      # encryption object reference (plus additional information)
     42my $pdfVer;         # version of PDF file being processed
    3343
    3444# tags in main PDF directories
    3545%Image::ExifTool::PDF::Main = (
     46    GROUPS => { 2 => 'Document' },
     47    VARS => { CAPTURE => ['Main','Prev'] },
    3648    Info => {
    37         SubDirectory => {
    38             TagTable => 'Image::ExifTool::PDF::Info',
    39         },
     49        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Info' },
    4050    },
    4151    Root => {
    42         SubDirectory => {
    43             TagTable => 'Image::ExifTool::PDF::Root',
    44         },
     52        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Root' },
     53    },
     54    Encrypt => {
     55        NoProcess => 1, # don't process normally (processed in advance)
     56        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Encrypt' },
     57    },
     58    _linearized => {
     59        Name => 'Linearized',
     60        Notes => 'flag set if document is linearized for fast web display; not a real Tag ID',
     61        PrintConv => { 'true' => 'Yes', 'false' => 'No' },
    4562    },
    4663);
     
    4865# tags in PDF Info directory
    4966%Image::ExifTool::PDF::Info = (
    50     GROUPS => { 2 => 'Image' },
     67    GROUPS => { 2 => 'Document' },
     68    VARS => { CAPTURE => ['Info'] },
    5169    EXTRACT_UNKNOWN => 1, # extract all unknown tags in this directory
     70    WRITE_PROC => \&Image::ExifTool::DummyWriteProc,
     71    CHECK_PROC => \&CheckPDF,
     72    WRITABLE => 'string',
    5273    NOTES => q{
    5374        As well as the tags listed below, the PDF specification allows for
    5475        user-defined tags to exist in the Info dictionary.  These tags, which should
    55         have corresponding XMP-pdfx entries in the PDF Metadata, are also extracted
    56         by ExifTool.
     76        have corresponding XMP-pdfx entries in the XMP of the PDF XML Metadata
     77        object, are also extracted by ExifTool.
     78
     79        B<Writable> specifies the value format, and may be C<string>, C<date>,
     80        C<integer>, C<real>, C<boolean> or C<name> for PDF tags.
    5781    },
    5882    Title       => { },
    5983    Author      => { Groups => { 2 => 'Author' } },
    6084    Subject     => { },
    61     Keywords    => { List => 1 },  # this is a list of tokens
     85    Keywords    => { List => 'string' },  # this is a string list
    6286    Creator     => { },
    6387    Producer    => { },
    6488    CreationDate => {
    6589        Name => 'CreateDate',
     90        Writable => 'date',
    6691        Groups => { 2 => 'Time' },
    67         ValueConv => 'Image::ExifTool::PDF::ConvertPDFDate($self, $val)',
     92        Shift => 'Time',
     93        PrintConv => '$self->ConvertDateTime($val)',
     94        PrintConvInv => '$self->InverseDateTime($val)',
    6895    },
    6996    ModDate => {
    7097        Name => 'ModifyDate',
     98        Writable => 'date',
    7199        Groups => { 2 => 'Time' },
    72         ValueConv => 'Image::ExifTool::PDF::ConvertPDFDate($self, $val)',
     100        Shift => 'Time',
     101        PrintConv => '$self->ConvertDateTime($val)',
     102        PrintConvInv => '$self->InverseDateTime($val)',
    73103    },
    74104    Trapped => {
     105        Protected => 1,
    75106        # remove leading '/' from '/True' or '/False'
    76107        ValueConv => '$val=~s{^/}{}; $val',
     108        ValueConvInv => '"/$val"',
     109    },
     110    'AAPL:Keywords' => { #PH
     111        Name => 'AppleKeywords',
     112        List => 'array', # this is an array of values
     113        Notes => q{
     114            keywords written by Apple utilities, although they seem to use PDF:Keywords
     115            when reading
     116        },
    77117    },
    78118);
     
    80120# tags in the PDF Root document catalog
    81121%Image::ExifTool::PDF::Root = (
     122    GROUPS => { 2 => 'Document' },
     123    # note: can't capture previous versions of Root since they are not parsed
     124    VARS => { CAPTURE => ['Root'] },
    82125    NOTES => 'This is the PDF document catalog.',
     126    MarkInfo => {
     127        SubDirectory => { TagTable => 'Image::ExifTool::PDF::MarkInfo' },
     128    },
    83129    Metadata => {
    84         SubDirectory => {
    85             TagTable => 'Image::ExifTool::PDF::Metadata',
     130        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Metadata' },
     131    },
     132    Pages => {
     133        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Pages' },
     134    },
     135    Perms => {
     136        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Perms' },
     137    },
     138    Lang       => 'Language',
     139    PageLayout => { },
     140    PageMode   => { },
     141    Version    => 'PDFVersion',
     142);
     143
     144# tags extracted from the PDF Encrypt dictionary
     145%Image::ExifTool::PDF::Encrypt = (
     146    GROUPS => { 2 => 'Document' },
     147    NOTES => 'Tags extracted from the document Encrypt dictionary.',
     148    Filter => {
     149        Name => 'Encryption',
     150        Notes => q{
     151            extracted value is actually a combination of the Filter, SubFilter, V, R and
     152            Length information from the Encrypt dictionary
    86153        },
    87154    },
    88     Pages => {
    89         SubDirectory => {
    90             TagTable => 'Image::ExifTool::PDF::Pages',
    91         },
     155    P => {
     156        Name => 'UserAccess',
     157        ValueConv => '$val & 0x0f3c',  # ignore reserved bits
     158        PrintConvColumns => 2,
     159        PrintConv => { BITMASK => {
     160            2 => 'Print',
     161            3 => 'Modify',
     162            4 => 'Copy',
     163            5 => 'Annotate',
     164            8 => 'Fill forms',
     165            9 => 'Extract',
     166            10 => 'Assemble',
     167            11 => 'Print high-res',
     168        }},
    92169    },
    93170);
     
    95172# tags in PDF Pages directory
    96173%Image::ExifTool::PDF::Pages = (
    97     GROUPS => { 2 => 'Image' },
     174    GROUPS => { 2 => 'Document' },
    98175    Count => 'PageCount',
    99176    Kids => {
    100         SubDirectory => {
    101             TagTable => 'Image::ExifTool::PDF::Kids',
    102         },
     177        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Kids' },
     178    },
     179);
     180
     181# tags in PDF Perms directory
     182%Image::ExifTool::PDF::Perms = (
     183    NOTES => 'Additional document permissions imposed by digital signatures.',
     184    DocMDP => {
     185        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Signature' },
     186    },
     187    FieldMDP => {
     188        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Signature' },
     189    },
     190    UR3 => {
     191        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Signature' },
    103192    },
    104193);
     
    107196%Image::ExifTool::PDF::Kids = (
    108197    Metadata => {
    109         SubDirectory => {
    110             TagTable => 'Image::ExifTool::PDF::Metadata',
    111         },
     198        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Metadata' },
    112199    },
    113200    PieceInfo => {
    114         SubDirectory => {
    115             TagTable => 'Image::ExifTool::PDF::PieceInfo',
    116         },
     201        SubDirectory => { TagTable => 'Image::ExifTool::PDF::PieceInfo' },
    117202    },
    118203    Resources => {
    119         SubDirectory => {
    120             TagTable => 'Image::ExifTool::PDF::Resources',
    121         },
     204        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Resources' },
    122205    },
    123206);
     
    126209%Image::ExifTool::PDF::Resources = (
    127210    ColorSpace => {
    128         SubDirectory => {
    129             TagTable => 'Image::ExifTool::PDF::ColorSpace',
    130         },
     211        SubDirectory => { TagTable => 'Image::ExifTool::PDF::ColorSpace' },
    131212    },
    132213);
     
    135216%Image::ExifTool::PDF::ColorSpace = (
    136217    DefaultRGB => {
    137         SubDirectory => {
    138             TagTable => 'Image::ExifTool::PDF::DefaultRGB',
    139         },
     218        SubDirectory => { TagTable => 'Image::ExifTool::PDF::DefaultRGB' },
    140219    },
    141220);
     
    144223%Image::ExifTool::PDF::DefaultRGB = (
    145224    ICCBased => {
    146         SubDirectory => {
    147             TagTable => 'Image::ExifTool::PDF::ICCBased',
    148         },
     225        SubDirectory => { TagTable => 'Image::ExifTool::PDF::ICCBased' },
    149226    },
    150227);
     
    152229# tags in PDF ICCBased directory
    153230%Image::ExifTool::PDF::ICCBased = (
    154     stream => {
    155         SubDirectory => {
    156             TagTable => 'Image::ExifTool::ICC_Profile::Main',
    157         },
     231    _stream => {
     232        SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' },
    158233    },
    159234);
     
    162237%Image::ExifTool::PDF::PieceInfo = (
    163238    AdobePhotoshop => {
    164         SubDirectory => {
    165             TagTable => 'Image::ExifTool::PDF::AdobePhotoshop',
     239        SubDirectory => { TagTable => 'Image::ExifTool::PDF::AdobePhotoshop' },
     240    },
     241    Illustrator => {
     242        # assume this is an illustrator file if it contains this directory
     243        # and doesn't have a ".PDF" extension
     244        Condition => q{
     245            $self->OverrideFileType("AI") unless $$self{FILE_EXT} and $$self{FILE_EXT} eq 'PDF';
     246            return 1;
    166247        },
     248        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Illustrator' },
    167249    },
    168250);
     
    171253%Image::ExifTool::PDF::AdobePhotoshop = (
    172254    Private => {
    173         SubDirectory => {
    174             TagTable => 'Image::ExifTool::PDF::Private',
    175         },
     255        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Private' },
     256    },
     257);
     258
     259# tags in PDF Illustrator directory
     260%Image::ExifTool::PDF::Illustrator = (
     261    Private => {
     262        SubDirectory => { TagTable => 'Image::ExifTool::PDF::AIPrivate' },
    176263    },
    177264);
     
    180267%Image::ExifTool::PDF::Private = (
    181268    ImageResources => {
    182         SubDirectory => {
    183             TagTable => 'Image::ExifTool::PDF::ImageResources',
     269        SubDirectory => { TagTable => 'Image::ExifTool::PDF::ImageResources' },
     270    },
     271);
     272
     273# tags in PDF AI Private directory
     274%Image::ExifTool::PDF::AIPrivate = (
     275    GROUPS => { 2 => 'Document' },
     276    EXTRACT_UNKNOWN => 0,   # extract known but numbered tags
     277    AIMetaData => {
     278        SubDirectory => { TagTable => 'Image::ExifTool::PDF::AIMetaData' },
     279    },
     280    AIPrivateData => {
     281        Notes => q{
     282            the ExtractEmbedded option enables information to be extracted from embedded
     283            PostScript documents in the AIPrivateData stream
    184284        },
     285        SubDirectory => { TagTable => 'Image::ExifTool::PostScript::Main' },
     286    },
     287    RoundTripVersion => { },
     288    ContainerVersion => { },
     289    CreatorVersion => { },
     290);
     291
     292# tags in PDF AIMetaData directory
     293%Image::ExifTool::PDF::AIMetaData = (
     294    _stream => {
     295        SubDirectory => { TagTable => 'Image::ExifTool::PostScript::Main' },
    185296    },
    186297);
     
    188299# tags in PDF ImageResources directory
    189300%Image::ExifTool::PDF::ImageResources = (
    190     stream => {
    191         SubDirectory => {
    192             TagTable => 'Image::ExifTool::Photoshop::Main',
    193         },
     301    _stream => {
     302        SubDirectory => { TagTable => 'Image::ExifTool::Photoshop::Main' },
     303    },
     304);
     305
     306# tags in PDF MarkInfo directory
     307%Image::ExifTool::PDF::MarkInfo = (
     308    GROUPS => { 2 => 'Document' },
     309    Marked => {
     310        Name => 'TaggedPDF',
     311        Notes => "not a Tagged PDF if this tag is missing",
     312        PrintConv => { 'true' => 'Yes', 'false' => 'No' },
    194313    },
    195314);
     
    197316# tags in PDF Metadata directory
    198317%Image::ExifTool::PDF::Metadata = (
    199     GROUPS => { 2 => 'Image' },
     318    GROUPS => { 2 => 'Document' },
    200319    XML_stream => { # this is the stream for a Subtype /XML dictionary (not a real tag)
    201320        Name => 'XMP',
    202         SubDirectory => {
    203             TagTable => 'Image::ExifTool::XMP::Main',
     321        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     322    },
     323);
     324
     325# tags in PDF signature directories (DocMDP, FieldMDP or UR3)
     326%Image::ExifTool::PDF::Signature = (
     327    GROUPS => { 2 => 'Document' },
     328    ContactInfo => 'SignerContactInfo',
     329    Location => 'SigningLocation',
     330    M => {
     331        Name => 'SigningDate',
     332        Format => 'date',
     333        Groups => { 2 => 'Time' },
     334        PrintConv => '$self->ConvertDateTime($val)',
     335    },
     336    Name     => 'SigningAuthority',
     337    Reason   => 'SigningReason',
     338    Reference => {
     339        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Reference' },
     340    },
     341    Prop_AuthTime => {
     342        Name => 'AuthenticationTime',
     343        PrintConv => 'ConvertTimeSpan($val) . " ago"',
     344    },
     345    Prop_AuthType => 'AuthenticationType',
     346);
     347
     348# tags in PDF Reference directory
     349%Image::ExifTool::PDF::Reference = (
     350    TransformParams => {
     351        SubDirectory => { TagTable => 'Image::ExifTool::PDF::TransformParams' },
     352    },
     353);
     354
     355# tags in PDF TransformParams directory
     356%Image::ExifTool::PDF::TransformParams = (
     357    GROUPS => { 2 => 'Document' },
     358    Annots => {
     359        Name => 'AnnotationUsageRights',
     360        Notes => 'UR3 signatures only',
     361        List => 1,
     362    },
     363    Document => {
     364        Name => 'DocumentUsageRights',
     365        Notes => 'UR3 signatures only',
     366        List => 1,
     367    },
     368    Form => {
     369        Name => 'FormUsageRights',
     370        Notes => 'UR3 signatures only',
     371        List => 1,
     372    },
     373    Signature => {
     374        Name => 'SignatureUsageRights',
     375        Notes => 'UR3 signatures only',
     376        List => 1,
     377    },
     378    EF => {
     379        Name => 'EmbeddedFileUsageRights',
     380        Notes => 'UR3 signatures only',
     381        List => 1,
     382    },
     383    Msg => {
     384        Name => 'UsageRightsMessage',
     385        Notes => 'UR3 signatures only',
     386    },
     387    P => {
     388        Name => 'ModificationPermissions',
     389        Notes => q{
     390            1-3 for DocMDP signatures, default 2; true/false for UR3 signatures, default
     391            false
    204392        },
     393        PrintConv => {
     394            1 => 'No changes permitted',
     395            2 => 'Fill forms, Create page templates, Sign',
     396            3 => 'Fill forms, Create page templates, Sign, Create/Delete/Edit annotations',
     397            'true' => 'Restrict al applications to reader permissions',
     398            'false' => 'Do not restrict applications to reader permissions',
     399        },
     400    },
     401    Action => {
     402        Name => 'FieldPermissions',
     403        Notes => 'FieldMDP signatures only',
     404        PrintConv => {
     405            'All' => 'Disallow changes to all form fields',
     406            'Include' => 'Disallow changes to specified form fields',
     407            'Exclude' => 'Allow changes to specified form fields',
     408        },
     409    },
     410    Fields => {
     411        Notes => 'FieldMDP signatures only',
     412        Name => 'FormFields',
     413        List => 1,
    205414    },
    206415);
     
    212421
    213422#------------------------------------------------------------------------------
    214 # Issue one warning of each type
    215 # Inputs: 0) ExifTool object reference, 1) warning
    216 sub WarnOnce($$)
     423# AutoLoad our writer routines when necessary
     424#
     425sub AUTOLOAD
    217426{
    218     my ($exifTool, $warn) = @_;
    219     unless ($warnedOnce{$warn}) {
    220         $warnedOnce{$warn} = 1;
    221         $exifTool->Warn($warn);
    222     }
     427    return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
    223428}
    224429
    225430#------------------------------------------------------------------------------
    226 # Set PDF format error warning
    227 # Inputs: 0) ExifTool object reference, 1) error string
    228 # Returns: 1
    229 sub PDFErr($$)
     431# Convert from PDF to EXIF-style date/time
     432# Inputs: 0) PDF date/time string (D:YYYYmmddHHMMSS+HH'MM')
     433# Returns: EXIF date string (YYYY:mm:dd HH:MM:SS+HH:MM)
     434sub ConvertPDFDate($)
    230435{
    231     my ($exifTool, $str) = @_;
    232     $exifTool->Warn("PDF format error ($str)");
    233     return 1;
    234 }
    235 
    236 #------------------------------------------------------------------------------
    237 # Convert from PDF to EXIF-style date/time
    238 # Inputs: 0) ExifTool object reference,
    239 #         1) PDF date/time string (D:yyyymmddhhmmss+hh'mm')
    240 # Returns: EXIF date string (yyyy:mm:dd hh:mm:ss+hh:mm)
    241 sub ConvertPDFDate($$)
    242 {
    243     my ($exifTool, $date) = @_;
     436    my $date = shift;
    244437    # remove optional 'D:' prefix
    245438    $date =~ s/^D://;
    246439    # fill in default values if necessary
    247     #              yyyymmddhhmmss
     440    #              YYYYmmddHHMMSS
    248441    my $default = '00000101000000';
    249442    if (length $date < length $default) {
     
    253446    $date = "$1:$2:$3 $4:$5:$6";
    254447    if ($7) {
    255         my @t = split /'/, $7;
    256         $date .= $t[0];
    257         $date .= ':' . ($t[1] || 0) if $t[0] ne 'Z';
    258     }
    259     return $exifTool->ConvertDateTime($date);
     448        my $tz = $7;
     449        if ($tz =~ /^\s*Z/i) {
     450            # ignore any "HH'mm'" after the Z (OS X 10.6 does this)
     451            $date .= 'Z';
     452        # tolerate some improper formatting in timezone specification
     453        } elsif ($tz =~ /^\s*([-+])\s*(\d+)[': ]+(\d*)/) {
     454            $date .= $1 . $2 . ':' . ($3 || '00');
     455        }
     456    }
     457    return $date;
    260458}
    261459
    262460#------------------------------------------------------------------------------
    263 # Locate an object in the XRref tables
    264 # Inputs: 0) XRef reference, 1) object reference string
    265 # Returns: offset to object in file, or undefined on error
    266 sub LocateObject($$)
     461# Locate any object in the XRef tables (including compressed objects)
     462# Inputs: 0) XRef reference, 1) object reference string (or free object number)
     463# Returns: offset to object in file or compressed object reference string,
     464#          0 if object is free, or undefined on error
     465sub LocateAnyObject($$)
    267466{
    268467    my ($xref, $ref) = @_;
    269468    return undef unless $xref;
    270     return $$xref{$ref} if $$xref{$ref};
     469    return $$xref{$ref} if exists $$xref{$ref};
    271470    # get the object number
    272471    return undef unless $ref =~ /^(\d+)/;
    273472    my $objNum = $1;
     473    # return 0 if the object number has been reused (old object is free)
     474    return 0 if defined $$xref{$objNum};
    274475#
    275476# scan our XRef stream dictionaries for this object
     
    283484        next if $objNum < $$index[0];
    284485        # scan the tables for the specified object
    285         my $size = $$dict{entry_size};
     486        my $size = $$dict{_entry_size};
    286487        my $num = scalar(@$index) / 2;
    287488        my $tot = 0;
     
    291492            my $count = $$index[$i*2+1];
    292493            # table is in ascending order, so quit if we have passed the object
    293             last if $objNum >= $start + $count;
    294             if ($objNum >= $start) {
     494            last if $objNum < $start;
     495            if ($objNum < $start + $count) {
    295496                my $offset = $size * ($objNum - $start + $tot);
    296                 last if $offset + $size > length $$dict{stream};
    297                 my @c = unpack("x$offset C$size", $$dict{stream});
     497                last if $offset + $size > length $$dict{_stream};
     498                my @c = unpack("x$offset C$size", $$dict{_stream});
    298499                # extract values from this table entry
    299500                # (can be 1, 2, 3, 4, etc.. bytes per value)
    300                 my (@t, $j, $k, $ref2);
     501                my (@t, $j, $k);
    301502                my $w = $$dict{W};
    302503                for ($j=0; $j<3; ++$j) {
    303504                    # use default value if W entry is 0 (as per spec)
    304                     $$w[$j] or $t[$j] = ($j ? 1 : 0), next;
     505                    # - 0th element defaults to 1, others default to 0
     506                    $$w[$j] or $t[$j] = ($j ? 0 : 1), next;
    305507                    $t[$j] = shift(@c);
    306508                    for ($k=1; $k < $$w[$j]; ++$k) {
     
    308510                    }
    309511                }
     512                # by default, use "o g R" as the xref key
     513                # (o = object number, g = generation number)
     514                my $ref2 = "$objNum $t[2] R";
    310515                if ($t[0] == 1) {
    311                     # normal object reference: use "o g R" as hash ref
    312                     # (o = object number, g = generation number)
    313                     $ref2 = "$objNum $t[2] R";
    314                     # xref is offset of object from start
     516                    # normal object reference:
     517                    # $t[1]=offset of object from start, $t[2]=generation number
    315518                    $$xref{$ref2} = $t[1];
    316519                } elsif ($t[0] == 2) {
    317520                    # compressed object reference:
     521                    # $t[1]=stream object number, $t[2]=index of object in stream
    318522                    $ref2 = "$objNum 0 R";
    319                     # xref is object index and stream object reference
    320523                    $$xref{$ref2} = "I$t[2] $t[1] 0 R";
     524                } elsif ($t[0] == 0) {
     525                    # free object:
     526                    # $t[1]=next free object in linked list, $t[2]=generation number
     527                    $$xref{$ref2} = 0;
    321528                } else {
    322                     last;
     529                    # treat as a null object
     530                    $$xref{$ref2} = undef;
    323531                }
     532                $$xref{$objNum} = $t[1];    # remember offsets by object number too
    324533                return $$xref{$ref} if $ref eq $ref2;
     534                return 0;   # object is free or was reused
    325535            }
    326536            $tot += $count;
     
    331541
    332542#------------------------------------------------------------------------------
     543# Locate a regular object in the XRef tables (does not include compressed objects)
     544# Inputs: 0) XRef reference, 1) object reference string (or free object number)
     545# Returns: offset to object in file, 0 if object is free,
     546#          or undef on error or if object was compressed
     547sub LocateObject($$)
     548{
     549    my ($xref, $ref) = @_;
     550    my $offset = LocateAnyObject($xref, $ref);
     551    return undef if $offset and $offset =~ /^I/;
     552    return $offset;
     553}
     554
     555#------------------------------------------------------------------------------
    333556# Fetch indirect object from file (from inside a stream if required)
    334 # Inputs: 0) ExifTool object reference, 1) object reference string, 2) xref lookup,
     557# Inputs: 0) ExifTool object reference, 1) object reference string,
     558#         2) xref lookup, 3) object name (for warning messages)
    335559# Returns: object data or undefined on error
     560# Notes: sets $lastFetched to the object reference, or undef if the object
     561#        was extracted from an encrypted stream
    336562sub FetchObject($$$$)
    337563{
    338564    my ($exifTool, $ref, $xref, $tag) = @_;
    339565    $lastFetched = $ref;    # save this for decoding if necessary
    340     my $offset = LocateObject($xref, $ref);
     566    my $offset = LocateAnyObject($xref, $ref);
     567    $lastOffset = $offset;
    341568    unless ($offset) {
    342         $exifTool->Warn("Bad $tag reference");
     569        $exifTool->Warn("Bad $tag reference") unless defined $offset;
    343570        return undef;
    344571    }
     
    348575        my ($objNum) = split ' ', $ref; # save original object number
    349576        $ref = $offset; # now a reference to the containing stream object
    350         my $obj = $streamObjs{$ref};
     577        $obj = $streamObjs{$ref};
    351578        unless ($obj) {
    352579            # don't try to load the same object stream twice
     
    359586            return undef unless $$obj{First} and $$obj{N};
    360587            return undef unless DecodeStream($exifTool, $obj);
    361             # add a special 'table' entry to this dictionary which contains
     588            # add a special '_table' entry to this dictionary which contains
    362589            # the list of object number/offset pairs from the stream header
    363590            my $num = $$obj{N} * 2;
    364             my @table = split ' ', $$obj{stream}, $num;
     591            my @table = split ' ', $$obj{_stream}, $num;
    365592            return undef unless @table == $num;
    366593            # remove everything before first object in stream
    367             $$obj{stream} = substr($$obj{stream}, $$obj{First});
    368             $table[$num-1] =~ s/^(\d+).*/$1/;  # trim excess from last number
    369             $$obj{table} = \@table;
     594            $$obj{_stream} = substr($$obj{_stream}, $$obj{First});
     595            $table[$num-1] =~ s/^(\d+).*/$1/s;  # trim excess from last number
     596            $$obj{_table} = \@table;
    370597            # save the object stream so we don't have to re-load it later
    371598            $streamObjs{$ref} = $obj;
     
    373600        # verify that we have the specified object
    374601        my $i = 2 * $index;
    375         my $table = $$obj{table};
     602        my $table = $$obj{_table};
    376603        unless ($index < $$obj{N} and $$table[$i] == $objNum) {
    377604            $exifTool->Warn("Bad index for stream object $tag");
     
    382609        #  the next offset to get the object length)
    383610        $offset = $$table[$i + 1];
    384         my $len = ($$table[$i + 3] || length($$obj{stream})) - $offset;
    385         $data = substr($$obj{stream}, $offset, $len);
     611        my $len = ($$table[$i + 3] || length($$obj{_stream})) - $offset;
     612        $data = substr($$obj{_stream}, $offset, $len);
     613        # avoid re-decrypting data in already decrypted streams
     614        undef $lastFetched if $cryptStream;
    386615        return ExtractObject($exifTool, \$data);
    387616    }
     
    396625    }
    397626    return ExtractObject($exifTool, \$data, $raf, $xref);
     627}
     628
     629#------------------------------------------------------------------------------
     630# Convert PDF value to something readable
     631# Inputs: 0) PDF object data
     632# Returns: converted object
     633sub ReadPDFValue($)
     634{
     635    my $str = shift;
     636    # decode all strings in an array
     637    if (ref $str eq 'ARRAY') {
     638        # create new list to not alter the original data when rewriting
     639        my ($val, @vals);
     640        foreach $val (@$str) {
     641            push @vals, ReadPDFValue($val);
     642        }
     643        return \@vals;
     644    }
     645    length $str or return $str;
     646    my $delim = substr($str, 0, 1);
     647    if ($delim eq '(') {    # literal string
     648        $str = $1 if $str =~ /.*?\((.*)\)/s;    # remove brackets
     649        # decode escape sequences in literal strings
     650        while ($str =~ /\\(.)/sg) {
     651            my $n = pos($str) - 2;
     652            my $c = $1;
     653            my $r;
     654            if ($c =~ /[0-7]/) {
     655                # get up to 2 more octal digits
     656                $c .= $1 if $str =~ /\G([0-7]{1,2})/g;
     657                # convert octal escape code
     658                $r = chr(oct($c) & 0xff);
     659            } elsif ($c eq "\x0d") {
     660                # the string is continued if the line ends with '\'
     661                # (also remove "\x0d\x0a")
     662                $c .= $1 if $str =~ /\G(\x0a)/g;
     663                $r = '';
     664            } elsif ($c eq "\x0a") {
     665                $r = '';
     666            } else {
     667                # convert escaped characters
     668                ($r = $c) =~ tr/nrtbf/\n\r\t\b\f/;
     669            }
     670            substr($str, $n, length($c)+1) = $r;
     671            # continue search after this character
     672            pos($str) = $n + length($r);
     673        }
     674        Crypt(\$str, $lastFetched) if $cryptString;
     675    } elsif ($delim eq '<') {   # hex string
     676        # decode hex data
     677        $str =~ tr/0-9A-Fa-f//dc;
     678        $str .= '0' if length($str) & 0x01; # (by the spec)
     679        $str = pack('H*', $str);
     680        Crypt(\$str, $lastFetched) if $cryptString;
     681    } elsif ($delim eq '/') {   # name
     682        $str = substr($str, 1);
     683        # convert escape codes (PDF 1.2 or later)
     684        $str =~ s/#([0-9a-f]{2})/chr(hex($1))/sgei if $pdfVer >= 1.2;
     685    }
     686    return $str;
    398687}
    399688
     
    408697#          d) string, name, integer, boolean, null --> scalar value
    409698# - updates $$dataPt on return to contain unused data
    410 # - creates two bogus entries ('stream' and 'tags') in dictionaries to represent
    411 #   the stream data and a list of the tags (not including 'stream' and 'tags')
     699# - creates two bogus entries ('_stream' and '_tags') in dictionaries to represent
     700#   the stream data and a list of the tags (not including '_stream' and '_tags')
    412701#   in their original order
    413702sub ExtractObject($$;$$)
     
    419708
    420709    for (;;) {
    421         if ($$dataPt =~ /^\s*(<{1,2}|\[|\()/) {
     710        if ($$dataPt =~ /^\s*(<{1,2}|\[|\()/s) {
    422711            $delim = $1;
     712            $$dataPt =~ s/^\s+//;   # remove leading white space
    423713            $objData = ReadToNested($dataPt, $raf);
    424714            return undef unless defined $objData;
    425715            last;
    426         } elsif ($$dataPt =~ s{^\s*(\S[^[(/<>\s]*)\s*}{}) {
     716        } elsif ($$dataPt =~ s{^\s*(\S[^[(/<>\s]*)\s*}{}s) {
    427717#
    428718# extract boolean, numerical, string, name, null object or indirect reference
     
    430720            $objData = $1;
    431721            # look for an indirect reference
    432             if ($objData =~ /^\d+$/ and $$dataPt =~ s/^(\d+)\s+R//) {
     722            if ($objData =~ /^\d+$/ and $$dataPt =~ s/^(\d+)\s+R//s) {
    433723                $objData .= "$1 R";
    434724                $objData = \$objData;   # return scalar reference
     
    440730    }
    441731#
    442 # extract literal string
    443 #
    444     if ($delim eq '(') {
    445         $objData = $1 if $objData =~ /.*?\((.*)\)/s;    # remove brackets
    446         # decode escape sequences in literal strings
    447         while ($objData =~ /\\(.)/sg) {
    448             my $n = pos($objData) - 2;
    449             my $c = $1;
    450             my $r;
    451             if ($c =~ /[0-7]/) {
    452                 # get up to 2 more octal digits
    453                 $c .= $1 if $objData =~ /\G([0-7]{1,2})/g;
    454                 # convert octal escape code
    455                 $r = chr(oct($c) & 0xff);
    456             } elsif ($c eq "\x0d") {
    457                 # the string is continued if the line ends with '\'
    458                 # (also remove "\x0d\x0a")
    459                 $c .= $1 if $objData =~ /\G(\x0a)/g;
    460                 $r = '';
    461             } elsif ($c eq "\x0a") {
    462                 # (also remove "\x0a\x0d")
    463                 $c .= $1 if $objData =~ /\G(\x0d)/g;
    464                 $r = '';
    465             } else {
    466                 # convert escaped characters
    467                 ($r = $c) =~ tr/nrtbf/\n\r\t\b\f/;
    468             }
    469             substr($objData, $n, length($c)+1) = $r;
    470             # contine search after this character
    471             pos($objData) = $n + length($r);
    472         }
    473         Decrypt(\$objData) if $cryptInfo;
    474         # convert from UTF-16 (big endian) to UTF-8 or Latin if necessary
    475         if ($objData =~ s/^\xfe\xff//) {
    476             $objData = $exifTool->Unicode2Charset($objData, 'MM');
    477         }
     732# return literal string or hex string without parsing
     733#
     734    if ($delim eq '(' or $delim eq '<') {
    478735        return $objData;
    479736#
    480 # extract hex string
    481 #
    482     } elsif ($delim eq '<') {
    483         # decode hex data
    484         $objData =~ tr/0-9A-Fa-f//dc;
    485         $objData .= '0' if length($objData) & 0x01; # (by the spec)
    486         $objData = pack('H*', $objData);
    487         Decrypt(\$objData) if $cryptInfo;
    488         return $objData;
    489 #
    490737# extract array
    491738#
    492739    } elsif ($delim eq '[') {
    493         $objData =~ /.*?\[(.*)\]/s or return;    # remove brackets
    494         my $data = $1;
     740        $objData =~ /.*?\[(.*)\]/s or return undef;
     741        my $data = $1;    # brackets removed
    495742        my @list;
    496743        for (;;) {
     
    536783        } elsif ($val =~ /^\d/) {
    537784            my $pos = pos($objData);
    538             if ($objData =~ /\G\s+(\d+)\s+R/g) {
     785            if ($objData =~ /\G\s+(\d+)\s+R/sg) {
    539786                $val = \ "$val $1 R";   # make a reference
    540787            } else {
     
    544791        if ($$dict{$tag}) {
    545792            # duplicate dictionary entries are not allowed
    546             $exifTool->Warn("Duplicate $tag entry in dictionary (ignored)");
     793            $exifTool->Warn('Duplicate $tag entry in dictionary (ignored)');
    547794        } else {
    548795            # save the entry
     
    552799    }
    553800    return undef unless @tags;
    554     $$dict{tags} = \@tags;
     801    $$dict{_tags} = \@tags;
    555802    return $dict unless $raf;   # direct objects can not have streams
    556803#
     
    563810        my $oldpos = $raf->Tell();
    564811        # get the location of the object specifying the length
     812        # (compressed objects are not allowed)
    565813        my $offset = LocateObject($xref, $length) or return $dict;
    566         $raf->Seek($offset, 0) or $exifTool->Warn("Bad Length offset"), return $dict;
     814        $offset or $exifTool->Warn('Bad Length object'), return $dict;
     815        $raf->Seek($offset, 0) or $exifTool->Warn('Bad Length offset'), return $dict;
    567816        # verify that we are reading the expected object
    568         $raf->ReadLine($data) or $exifTool->Warn("Error reading Length data"), return $dict;
     817        $raf->ReadLine($data) or $exifTool->Warn('Error reading Length data'), return $dict;
    569818        $length =~ s/R/obj/;
    570819        unless ($data =~ /^$length/) {
     
    572821            return $dict;
    573822        }
    574         $raf->ReadLine($data) or $exifTool->Warn("Error reading stream Length"), return $dict;
    575         $data =~ /(\d+)/ or $exifTool->Warn("Stream length not found"), return $dict;
     823        $raf->ReadLine($data) or $exifTool->Warn('Error reading stream Length'), return $dict;
     824        $data =~ /(\d+)/ or $exifTool->Warn('Stream length not found'), return $dict;
    576825        $length = $1;
    577826        $raf->Seek($oldpos, 0); # restore position to start of stream
     
    585834            $$dataPt .= $data if $raf->ReadLine($data);
    586835            # remove our stream header
    587             $$dataPt =~ s/^.*stream(\x0a|\x0d\x0a)//s;
     836            $$dataPt =~ s/^\s*stream(\x0a|\x0d\x0a)//s;
    588837            my $more = $length - length($$dataPt);
    589838            if ($more > 0) {
    590839                unless ($raf->Read($data, $more) == $more) {
    591                     $exifTool->Warn("Error reading stream data");
     840                    $exifTool->Warn('Error reading stream data');
    592841                    $$dataPt = '';
    593842                    return $dict;
    594843                }
    595                 $$dict{stream} = $$dataPt . $data;
     844                $$dict{_stream} = $$dataPt . $data;
    596845                $$dataPt = '';
    597846            } elsif ($more < 0) {
    598                 $$dict{stream} = substr($$dataPt, 0, $length);
     847                $$dict{_stream} = substr($$dataPt, 0, $length);
    599848                $$dataPt = substr($$dataPt, $length);
    600849            } else {
    601                 $$dict{stream} = $$dataPt;
     850                $$dict{_stream} = $$dataPt;
    602851                $$dataPt = '';
    603852            }
     
    616865# - updates data reference with trailing data
    617866# - unescapes characters in literal strings
     867my %closingDelim = (    # lookup for matching delimiter
     868    '(' => ')',
     869    '[' => ']',
     870    '<' => '>',
     871   '<<' => '>>',
     872);
    618873sub ReadToNested($;$)
    619874{
    620875    my ($dataPt, $raf) = @_;
    621     # matching closing delimiters
    622     my %closingDelim = (
    623         '<<' => '>>',
    624         '('  => ')',
    625         '['  => ']',
    626         '<'  => '>',
    627     );
    628876    my @delim = ('');   # closing delimiter list, most deeply nested first
    629877    pos($$dataPt) = 0;  # begin at start of data
     
    664912            pos($$dataPt) = pos($$dataPt) - 1;
    665913        }
    666         my $delim = shift @delim;   # remove from nesting list
     914        shift @delim;               # remove from nesting list
    667915        next if $delim[0];          # keep going if we have more nested delimiters
    668916        my $pos = pos($$dataPt);
     
    682930    my ($exifTool, $dict) = @_;
    683931
    684     return 0 unless $$dict{stream}; # no stream to decode
    685     # apply decryption first if required
    686     if ($cryptInfo and not $$dict{decrypted}) {
    687         $$dict{decrypted} = 1;
    688         if ($$cryptInfo{meta} or ($$dict{Type} and $$dict{Type} ne '/Metadata')) {
    689             Decrypt(\$$dict{stream});
    690         }
    691     }
    692     return 1 unless $$dict{Filter};
    693     if ($$dict{Filter} eq '/FlateDecode') {
    694         if (eval 'require Compress::Zlib') {
    695             my $inflate = Compress::Zlib::inflateInit();
    696             my ($buff, $stat);
    697             $inflate and ($buff, $stat) = $inflate->inflate($$dict{stream});
    698             if ($inflate and $stat == Compress::Zlib::Z_STREAM_END()) {
    699                 $$dict{stream} = $buff;
    700                 # move Filter to prevent double decoding
    701                 $$dict{oldFilter} = $$dict{Filter};
    702                 $$dict{Filter} = '';
     932    return 0 unless $$dict{_stream}; # no stream to decode
     933
     934    # get list of filters
     935    my (@filters, @decodeParms, $filter);
     936    if (ref $$dict{Filter} eq 'ARRAY') {
     937        @filters = @{$$dict{Filter}};
     938    } elsif (defined $$dict{Filter}) {
     939        @filters = ($$dict{Filter});
     940    }
     941    # apply decryption first if required (and if the default encryption
     942    # has not been overridden by a Crypt filter. Note: the Crypt filter
     943    # must be first in the Filter array: ref 3, page 38)
     944    unless (defined $$dict{_decrypted} or ($filters[0] and $filters[0] eq '/Crypt')) {
     945        CryptStream($dict, $lastFetched);
     946    }
     947    return 1 unless $$dict{Filter};         # Filter entry is mandatory
     948    return 0 if defined $$dict{_filtered};  # avoid double-filtering
     949    $$dict{_filtered} = 1;                  # set flag to prevent double-filtering
     950
     951    # get array of DecodeParms dictionaries
     952    if (ref $$dict{DecodeParms} eq 'ARRAY') {
     953        @decodeParms = @{$$dict{DecodeParms}};
     954    } else {
     955        @decodeParms = ($$dict{DecodeParms});
     956    }
     957    foreach $filter (@filters) {
     958        my $decodeParms = shift @decodeParms;
     959
     960        if ($filter eq '/FlateDecode') {
     961            if (eval 'require Compress::Zlib') {
     962                my $inflate = Compress::Zlib::inflateInit();
     963                my ($buff, $stat);
     964                $inflate and ($buff, $stat) = $inflate->inflate($$dict{_stream});
     965                if ($inflate and $stat == Compress::Zlib::Z_STREAM_END()) {
     966                    $$dict{_stream} = $buff;
     967                } else {
     968                    $exifTool->Warn('Error inflating stream');
     969                    return 0;
     970                }
    703971            } else {
    704                 $exifTool->Warn('Error inflating stream');
     972                $exifTool->WarnOnce('Install Compress::Zlib to process filtered streams');
    705973                return 0;
    706974            }
    707         } else {
    708             WarnOnce($exifTool,'Install Compress::Zlib to decode filtered streams');
     975            # apply anti-predictor if necessary
     976            next unless ref $decodeParms eq 'HASH';
     977            my $pre = $$decodeParms{Predictor};
     978            next unless $pre and $pre != 1;
     979            if ($pre != 12) {
     980                # currently only support 'up' prediction
     981                $exifTool->WarnOnce("FlateDecode Predictor $pre not currently supported");
     982                return 0;
     983            }
     984            my $cols = $$decodeParms{Columns};
     985            unless ($cols) {
     986                # currently only support 'up' prediction
     987                $exifTool->WarnOnce('No Columns for decoding stream');
     988                return 0;
     989            }
     990            my @bytes = unpack('C*', $$dict{_stream});
     991            my @pre = (0) x $cols;  # initialize predictor array
     992            my $buff = '';
     993            while (@bytes > $cols) {
     994                unless (($_ = shift @bytes) == 2) {
     995                    $exifTool->WarnOnce("Unsupported PNG filter $_"); # (yes, PNG)
     996                    return 0;
     997                }
     998                foreach (@pre) {
     999                    $_ = ($_ + shift(@bytes)) & 0xff;
     1000                }
     1001                $buff .= pack('C*', @pre);
     1002            }
     1003            $$dict{_stream} = $buff;
     1004
     1005        } elsif ($filter eq '/Crypt') {
     1006
     1007            # (we shouldn't have to check the _decrypted flag since we
     1008            #  already checked the _filtered flag, but what the heck...)
     1009            next if defined $$dict{_decrypted};
     1010            # assume Identity filter (the default) if DecodeParms are missing
     1011            next unless ref $decodeParms eq 'HASH';
     1012            my $name = $$decodeParms{Name};
     1013            next unless defined $name or $name eq 'Identity';
     1014            if ($name ne 'StdCF') {
     1015                $exifTool->WarnOnce("Unsupported Crypt Filter $name");
     1016                return 0;
     1017            }
     1018            unless ($cryptInfo) {
     1019                $exifTool->WarnOnce('Missing Encrypt StdCF entry');
     1020                return 0;
     1021            }
     1022            # decrypt the stream manually because we want to:
     1023            # 1) ignore $cryptStream (StmF) setting
     1024            # 2) ignore EncryptMetadata setting (I can't find mention of how to
     1025            #    reconcile this in the spec., but this would make sense)
     1026            # 3) avoid adding the crypt key extension (ref 3, page 58, Algorithm 1b)
     1027            # 4) set _decrypted flag so we will recrypt according to StmF when
     1028            #    writing (since we don't yet write Filter'd streams)
     1029            Crypt(\$$dict{_stream}, 'none');
     1030            $$dict{_decrypted} = ($cryptStream ? 1 : 0);
     1031
     1032        } elsif ($filter ne '/Identity') {
     1033
     1034            $exifTool->WarnOnce("Unsupported Filter $filter");
    7091035            return 0;
    7101036        }
    711 #
    712 # apply anti-predictor if necessary
    713 #
    714         return 1 unless $$dict{DecodeParms};
    715         my $pre = $dict->{DecodeParms}->{Predictor};
    716         return 1 unless $pre and $pre != 1;
    717         if ($pre != 12) {
    718             # currently only support 'up' prediction
    719             WarnOnce($exifTool,"FlateDecode Predictor $pre not currently supported");
    720             return 0;
    721         }
    722         my $cols = $dict->{DecodeParms}->{Columns};
    723         unless ($cols) {
    724             # currently only support 'up' prediction
    725             WarnOnce($exifTool,'No Columns for decoding stream');
    726             return 0;
    727         }
    728         my @bytes = unpack('C*', $$dict{stream});
    729         my @pre = (0) x $cols;  # initialize predictor array
    730         my $buff = '';
    731         while (@bytes > $cols) {
    732             unless (($_ = shift @bytes) == 2) {
    733                 WarnOnce($exifTool, "Unsupported PNG filter $_");
    734                 return 0;
    735             }
    736             foreach (@pre) {
    737                 $_ = ($_ + shift(@bytes)) & 0xff;
    738             }
    739             $buff .= pack('C*', @pre);
    740         }
    741         $$dict{stream} = $buff;
    742     } else {
    743         WarnOnce($exifTool, "Unsupported Filter $$dict{Filter}");
    744         return 0;
    7451037    }
    7461038    return 1;
     
    7951087# Inputs: 0) ExifTool object reference, 1) Encrypt dictionary reference,
    7961088#         2) ID from file trailer dictionary
    797 # Returns: error string or undef on success
     1089# Returns: error string or undef on success (and sets $cryptInfo)
    7981090sub DecryptInit($$$)
    7991091{
     1092    local $_;
    8001093    my ($exifTool, $encrypt, $id) = @_;
     1094
     1095    undef $cryptInfo;
    8011096    unless ($encrypt and ref $encrypt eq 'HASH') {
    8021097        return 'Error loading Encrypt object';
     
    8061101        return 'Encrypt dictionary has no Filter!';
    8071102    }
     1103    # extract some interesting tags
    8081104    my $ver = $$encrypt{V} || 0;
    8091105    my $rev = $$encrypt{R} || 0;
    810     $exifTool->FoundTag('Encryption', "$filt v$ver.$rev");
    811     unless ($$encrypt{Filter} eq '/Standard') {
    812         $$encrypt{Filter} =~ s/^\///;
    813         return "PDF '$$encrypt{Filter}' encryption not currently supported";
     1106    my $enc = "$filt V$ver";
     1107    $enc .= ".$rev" if $filt eq 'Standard';
     1108    $enc .= " ($1)" if $$encrypt{SubFilter} and $$encrypt{SubFilter} =~ /^\/(.*)/;
     1109    $enc .= ' (' . ($$encrypt{Length} || 40) . '-bit)' if $filt eq 'Standard';
     1110    my $tagTablePtr = GetTagTable('Image::ExifTool::PDF::Encrypt');
     1111    $exifTool->HandleTag($tagTablePtr, 'Filter', $enc);
     1112    if ($filt ne 'Standard') {
     1113        return "Encryption filter $filt not currently supported";
     1114    } elsif (not defined $$encrypt{R}) {
     1115        return 'Standard security handler missing revision';
    8141116    }
    8151117    unless ($$encrypt{O} and $$encrypt{P} and $$encrypt{U}) {
    8161118        return 'Incomplete Encrypt specification';
    8171119    }
    818     unless ($ver == 1 or $ver == 2) {
    819         return "Encryption algorithm $ver currently not supported";
     1120    $exifTool->HandleTag($tagTablePtr, 'P', $$encrypt{P});
     1121
     1122    my %parm;   # optional parameters extracted from Encrypt dictionary
     1123
     1124    if ($ver == 1 or $ver == 2) {
     1125        $cryptString = $cryptStream = 1;
     1126    } elsif ($ver == 4 or $ver == 5) {
     1127        # initialize our $cryptString and $cryptStream flags
     1128        foreach ('StrF', 'StmF') {
     1129            my $flagPt = $_ eq 'StrF' ? \$cryptString : \$cryptStream;
     1130            $$flagPt = $$encrypt{$_};
     1131            undef $$flagPt if $$flagPt and $$flagPt eq '/Identity';
     1132            return "Unsupported $_ encryption $$flagPt" if $$flagPt and $$flagPt ne '/StdCF';
     1133        }
     1134        if ($cryptString or $cryptStream) {
     1135            return 'Missing or invalid Encrypt StdCF entry' unless ref $$encrypt{CF} eq 'HASH' and
     1136                ref $$encrypt{CF}{StdCF} eq 'HASH' and $$encrypt{CF}{StdCF}{CFM};
     1137            my $cryptMeth = $$encrypt{CF}{StdCF}{CFM};
     1138            unless ($cryptMeth =~ /^\/(V2|AESV2|AESV3)$/) {
     1139                return "Unsupported encryption method $cryptMeth";
     1140            }
     1141            # set "_aesv2" or "_aesv3" flag in %$encrypt hash if AES encryption was used
     1142            $$encrypt{'_' . lc($1)} = 1 if $cryptMeth =~ /^\/(AESV2|AESV3)$/;
     1143        }
     1144        if ($ver == 5) {
     1145            # validate OE and UE entries
     1146            foreach ('OE', 'UE') {
     1147                return "Missing Encrypt $_ entry" unless $$encrypt{$_};
     1148                $parm{$_} = ReadPDFValue($$encrypt{$_});
     1149                return "Invalid Encrypt $_ entry" unless length $parm{$_} == 32;
     1150            }
     1151            require Image::ExifTool::AES;   # will need this later
     1152        }
     1153    } else {
     1154        return "Encryption version $ver not currently supported";
    8201155    }
    8211156    $id or return "Can't decrypt (no document ID)";
    822     unless (eval 'require Digest::MD5') {
    823         return 'Install Digest::MD5 to extract encrypted information';
    824     }
     1157
     1158    # make sure we have the necessary libraries available
     1159    if ($ver < 5) {
     1160        unless (eval 'require Digest::MD5') {
     1161            return "Install Digest::MD5 to process encrypted PDF";
     1162        }
     1163    } else {
     1164        unless (eval 'require Digest::SHA') {
     1165            return "Install Digest::SHA to process AES-256 encrypted PDF";
     1166        }
     1167    }
     1168
    8251169    # calculate file-level en/decryption key
    8261170    my $pad = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08".
    8271171              "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
    828     my $key = $pad . $$encrypt{O} . pack('V', $$encrypt{P}) . $id;
    829     my $rep = 1;
    830     $$encrypt{meta} = 1; # set flag that Metadata is encrypted
    831     if ($rev >= 3) {
    832         # in rev 4 (not yet supported), metadata streams may not be encrypted
    833         if ($$encrypt{EncryptMetadata} and $$encrypt{EncryptMetadata} =~ /false/i) {
    834             delete $$encrypt{meta};     # Meta data isn't encrypted after all
    835             $key .= "\xff\xff\xff\xff"; # must add this if metadata not encrypted
    836         }
    837         $rep += 50; # repeat MD5 50 more times if revision is 3 or greater
    838     }
    839     my ($len, $i);
    840     if ($ver == 1) {
    841         $len = 5;
    842     } else {
    843         $len = $$encrypt{Length} || 40;
    844         $len >= 40 or return 'Bad Encrypt Length';
    845         $len = int($len / 8);
    846     }
    847     for ($i=0; $i<$rep; ++$i) {
    848         $key = substr(Digest::MD5::md5($key), 0, $len);
    849     }
    850     # decrypt U to see if a user password is required
    851     my $dat;
    852     if ($rev >= 3) {
    853         $dat = Digest::MD5::md5($pad . $id);
    854         RC4Crypt(\$dat, $key);
    855         for ($i=1; $i<=19; ++$i) {
    856             my @key = unpack('C*', $key);
    857             foreach (@key) { $_ ^= $i; }
    858             RC4Crypt(\$dat, pack('C*', @key));
    859         }
    860         $dat .= substr($$encrypt{U}, 16);
    861     } else {
    862         $dat = $pad;
    863         RC4Crypt(\$dat, $key);
    864     }
    865     $dat eq $$encrypt{U} or return 'Document is password encrypted';
    866     $$encrypt{key} = $key;  # save the file-level encryption key
    867     $cryptInfo = $encrypt;  # save a reference to the Encrypt object
     1172    my $o = ReadPDFValue($$encrypt{O});
     1173    my $u = ReadPDFValue($$encrypt{U});
     1174
     1175    # set flag indicating whether metadata is encrypted
     1176    # (in version 4 and higher, metadata streams may not be encrypted)
     1177    if ($ver < 4 or not $$encrypt{EncryptMetadata} or $$encrypt{EncryptMetadata} !~ /false/i) {
     1178        $$encrypt{_meta} = 1;
     1179    }
     1180    # try no password first, then try provided password if available
     1181    my ($try, $key);
     1182    for ($try=0; ; ++$try) {
     1183        my $password;
     1184        if ($try == 0) {
     1185            $password = '';
     1186        } elsif ($try == 1) {
     1187            $password = $exifTool->Options('Password');
     1188            return 'Document is password protected (use Password option)' unless defined $password;
     1189            # make sure there is no UTF-8 flag on the password
     1190            if ($] >= 5.006 and (eval 'require Encode; Encode::is_utf8($password)' or $@)) {
     1191                # repack by hand if Encode isn't available
     1192                $password = $@ ? pack('C*',unpack('U0C*',$password)) : Encode::encode('utf8',$password);
     1193            }
     1194        } else {
     1195            return 'Incorrect password';
     1196        }
     1197        if ($ver < 5) {
     1198            if (length $password) {
     1199                # password must be encoding in PDFDocEncoding (ref iso32000)
     1200                $password = $exifTool->Encode($password, 'PDFDoc');
     1201                # truncate or pad the password to exactly 32 bytes
     1202                if (length($password) > 32) {
     1203                    $password = substr($password, 0, 32);
     1204                } elsif (length($password) < 32) {
     1205                    $password .= substr($pad, 0, 32-length($password));
     1206                }
     1207            } else {
     1208                $password = $pad;
     1209            }
     1210            $key = $password . $o . pack('V', $$encrypt{P}) . $id;
     1211            my $rep = 1;
     1212            if ($rev == 3 or $rev == 4) {
     1213                # must add this if metadata not encrypted
     1214                $key .= "\xff\xff\xff\xff" unless $$encrypt{_meta};
     1215                $rep += 50; # repeat MD5 50 more times if revision is 3 or greater
     1216            }
     1217            my ($len, $i, $dat);
     1218            if ($ver == 1) {
     1219                $len = 5;
     1220            } else {
     1221                $len = $$encrypt{Length} || 40;
     1222                $len >= 40 or return 'Bad Encrypt Length';
     1223                $len = int($len / 8);
     1224            }
     1225            for ($i=0; $i<$rep; ++$i) {
     1226                $key = substr(Digest::MD5::md5($key), 0, $len);
     1227            }
     1228            # decrypt U to see if a user password is required
     1229            if ($rev >= 3) {
     1230                $dat = Digest::MD5::md5($pad . $id);
     1231                RC4Crypt(\$dat, $key);
     1232                for ($i=1; $i<=19; ++$i) {
     1233                    my @key = unpack('C*', $key);
     1234                    foreach (@key) { $_ ^= $i; }
     1235                    RC4Crypt(\$dat, pack('C*', @key));
     1236                }
     1237                $dat .= substr($u, 16);
     1238            } else {
     1239                $dat = $pad;
     1240                RC4Crypt(\$dat, $key);
     1241            }
     1242            last if $dat eq $u; # all done if this was the correct key
     1243        } else {
     1244            return 'Invalid O or U Encrypt entries' if length($o) < 48 or length($u) < 48;
     1245            if (length $password) {
     1246                # Note: this should be good for passwords containing reasonable characters,
     1247                # but to be bullet-proof we need to apply the SASLprep (IETF RFC 4013) profile
     1248                # of stringprep (IETF RFC 3454) to the password before encoding in UTF-8
     1249                $password = $exifTool->Encode($password, 'UTF8');
     1250                $password = substr($password, 0, 127) if length($password) > 127;
     1251            }
     1252            # test for the owner password
     1253            my $sha = Digest::SHA::sha256($password, substr($o,32,8), substr($u,0,48));
     1254            if ($sha eq substr($o, 0, 32)) {
     1255                $key = Digest::SHA::sha256($password, substr($o,40,8), substr($u,0,48));
     1256                my $dat = ("\0" x 16) . $parm{OE};
     1257                # decrypt with no padding
     1258                my $err = Image::ExifTool::AES::Crypt(\$dat, $key, 0, 1);
     1259                return $err if $err;
     1260                $key = $dat;    # use this as the file decryption key
     1261                last;
     1262            }
     1263            # test for the user password
     1264            $sha = Digest::SHA::sha256($password, substr($u,32,8));
     1265            if ($sha eq substr($u, 0, 32)) {
     1266                $key = Digest::SHA::sha256($password, substr($u,40,8));
     1267                my $dat = ("\0" x 16) . $parm{UE};
     1268                my $err = Image::ExifTool::AES::Crypt(\$dat, $key, 0, 1);
     1269                return $err if $err;
     1270                $key = $dat;    # use this as the file decryption key
     1271                last;
     1272            }
     1273        }
     1274    }
     1275    $$encrypt{_key} = $key; # save the file-level encryption key
     1276    $cryptInfo = $encrypt;  # save reference to the file-level Encrypt object
    8681277    return undef;           # success!
    8691278}
    8701279
    8711280#------------------------------------------------------------------------------
    872 # Decrypt data
    873 # Inputs: 0) data reference
    874 sub Decrypt($)
     1281# Decrypt/Encrypt data
     1282# Inputs: 0) data ref
     1283#         1) PDF object reference to use as crypt key extension (may be 'none' to
     1284#            avoid extending the encryption key, as for streams with Crypt Filter)
     1285#         2) encrypt flag (false for decryption)
     1286sub Crypt($$;$)
    8751287{
    876     my $dataPt = shift;
    877     my $key = $$cryptInfo{key};
    878     my $len = length($key) + 5;
    879     return unless $lastFetched =~ /^(I\d+ )?(\d+) (\d+)/;
    880     $key .= substr(pack('V', $2), 0, 3) . substr(pack('V', $3), 0, 2);
    881     $len = 16 if $len > 16;
    882     $key = substr(Digest::MD5::md5($key), 0, $len);
    883     RC4Crypt($dataPt, $key);
     1288    return unless $cryptInfo;
     1289    my ($dataPt, $keyExt, $encrypt) = @_;
     1290    # do not decrypt if the key extension object is undefined
     1291    # (this doubles as a flag to disable decryption/encryption)
     1292    return unless defined $keyExt;
     1293    my $key = $$cryptInfo{_key};
     1294    # apply the necessary crypt key extension
     1295    unless ($$cryptInfo{_aesv3}) {
     1296        unless ($keyExt eq 'none') {
     1297            # extend crypt key using object and generation number
     1298            unless ($keyExt =~ /^(I\d+ )?(\d+) (\d+)/) {
     1299                $$cryptInfo{_error} = 'Invalid object reference for encryption';
     1300                return;
     1301            }
     1302            $key .= substr(pack('V', $2), 0, 3) . substr(pack('V', $3), 0, 2);
     1303        }
     1304        # add AES-128 salt if necessary (this little gem is conveniently
     1305        # omitted from the Adobe PDF 1.6 documentation, causing me to
     1306        # waste 12 hours trying to figure out why this wasn't working --
     1307        # it appears in ISO32000 though, so I should have been using that)
     1308        $key .= 'sAlT' if $$cryptInfo{_aesv2};
     1309        my $len = length($key);
     1310        $key = Digest::MD5::md5($key);              # get 16-byte MD5 digest
     1311        $key = substr($key, 0, $len) if $len < 16;  # trim if necessary
     1312    }
     1313    # perform the decryption/encryption
     1314    if ($$cryptInfo{_aesv2} or $$cryptInfo{_aesv3}) {
     1315        require Image::ExifTool::AES;
     1316        my $err = Image::ExifTool::AES::Crypt($dataPt, $key, $encrypt);
     1317        $err and $$cryptInfo{_error} = $err;
     1318    } else {
     1319        RC4Crypt($dataPt, $key);
     1320    }
     1321}
     1322
     1323#------------------------------------------------------------------------------
     1324# Decrypt/Encrypt stream data
     1325# Inputs: 0) dictionary ref, 1) PDF object reference to use as crypt key extension
     1326sub CryptStream($$)
     1327{
     1328    return unless $cryptStream;
     1329    my ($dict, $keyExt) = @_;
     1330    my $type = $$dict{Type} || '';
     1331    # XRef streams are not encrypted (ref 3, page 50),
     1332    # and Metadata may or may not be encrypted
     1333    if ($cryptInfo and $type ne '/XRef' and
     1334        ($$cryptInfo{_meta} or $type ne '/Metadata'))
     1335    {
     1336        Crypt(\$$dict{_stream}, $keyExt, $$dict{_decrypted});
     1337        # toggle _decrypted flag
     1338        $$dict{_decrypted} = ($$dict{_decrypted} ? undef : 1);
     1339    } else {
     1340        $$dict{_decrypted} = 0; # stream should never be encrypted
     1341    }
     1342}
     1343
     1344#------------------------------------------------------------------------------
     1345# Generate a new PDF tag (based on its ID) and add it to a tag table
     1346# Inputs: 0) tag table ref, 1) tag ID
     1347# Returns: tag info ref
     1348sub NewPDFTag($$)
     1349{
     1350    my ($tagTablePtr, $tag) = @_;
     1351    my $name = $tag;
     1352    # translate URL-like escape sequences
     1353    $name =~ s/#([0-9a-f]{2})/chr(hex($1))/ige;
     1354    $name =~ s/[^-\w]+/_/g;         # translate invalid characters to an underline
     1355    $name =~ s/(^|_)([a-z])/\U$2/g; # start words with upper case
     1356    my $tagInfo = { Name => $name };
     1357    Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
     1358    return $tagInfo;
    8841359}
    8851360
     
    8881363# Inputs: 0) ExifTool object reference, 1) tag table reference
    8891364#         2) dictionary reference, 3) cross-reference table reference,
    890 #         4) nesting depth
    891 sub ProcessDict($$$$;$)
     1365#         4) nesting depth, 5) dictionary capture type
     1366sub ProcessDict($$$$;$$)
    8921367{
    893     my ($exifTool, $tagTablePtr, $dict, $xref, $nesting) = @_;
     1368    my ($exifTool, $tagTablePtr, $dict, $xref, $nesting, $type) = @_;
    8941369    my $verbose = $exifTool->Options('Verbose');
    895     my @tags = @{$$dict{tags}};
     1370    my $unknown = $$tagTablePtr{EXTRACT_UNKNOWN};
     1371    my $embedded = (defined $unknown and not $unknown and $exifTool->Options('ExtractEmbedded'));
     1372    my @tags = @{$$dict{_tags}};
     1373    my ($next, %join);
    8961374    my $index = 0;
    897     my $next;
    8981375
    8991376    $nesting = ($nesting || 0) + 1;
    9001377    if ($nesting > 50) {
    901         WarnOnce($exifTool, 'Nesting too deep (directory ignored)');
     1378        $exifTool->WarnOnce('Nesting too deep (directory ignored)');
    9021379        return;
     1380    }
     1381    # save entire dictionary for rewriting if specified
     1382    if ($$exifTool{PDF_CAPTURE} and $$tagTablePtr{VARS} and
     1383        $tagTablePtr->{VARS}->{CAPTURE})
     1384    {
     1385        my $name;
     1386        foreach $name (@{$tagTablePtr->{VARS}->{CAPTURE}}) {
     1387            next if $exifTool->{PDF_CAPTURE}->{$name};
     1388            # make sure we load the right type if indicated
     1389            next if $type and $type ne $name;
     1390            $exifTool->{PDF_CAPTURE}->{$name} = $dict;
     1391            last;
     1392        }
    9031393    }
    9041394#
     
    9151405            last;
    9161406        }
     1407        my $val = $$dict{$tag};
    9171408        if ($$tagTablePtr{$tag}) {
    9181409            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
    919         }
    920         my $val = $$dict{$tag};
     1410            undef $tagInfo if $$tagInfo{NoProcess};
     1411        } elsif ($embedded and $tag =~ /^(.*?)(\d+)$/ and
     1412            $$tagTablePtr{$1} and ref $val eq 'SCALAR' and not $fetched{$$val})
     1413        {
     1414            my ($name, $num) = ($1, $2);
     1415            $join{$name} = [] unless $join{$name};
     1416            $fetched{$$val} = 1;
     1417            my $obj = FetchObject($exifTool, $$val, $xref, $tag);
     1418            next unless ref $obj eq 'HASH' and $$obj{_stream};
     1419            # save all the stream data to join later
     1420            $join{$name}->[$num] = $$obj{_stream};
     1421        }
    9211422        if ($verbose) {
    9221423            my ($val2, $extra);
     
    9321433                    $fetched{$$val} = 1;
    9331434                    $val = FetchObject($exifTool, $$val, $xref, $tag);
    934                     $val2 = '<err>' unless defined $val;
     1435                    unless (defined $val) {
     1436                        my $str;
     1437                        if (defined $lastOffset) {
     1438                            $val2 = '<free>';
     1439                            $str = 'Object was freed';
     1440                        } else {
     1441                            $val2 = '<err>';
     1442                            $str = 'Error reading object';
     1443                        }
     1444                        $exifTool->VPrint(0, "$$exifTool{INDENT}${str}:\n");
     1445                    }
    9351446                }
    9361447            } elsif (ref $val eq 'HASH') {
     
    9621473                    },
    9631474                };
    964             } elsif (ref $val eq 'ARRAY') {
    965                 my @list = @$val;
    966                 foreach (@list) {
    967                     $_ = "ref($$_)" if ref $_ eq 'SCALAR';
     1475            } else {
     1476                if (ref $val eq 'ARRAY') {
     1477                    my @list = @$val;
     1478                    foreach (@list) {
     1479                        $_ = "ref($$_)" if ref $_ eq 'SCALAR';
     1480                    }
     1481                    $val2 = '[' . join(',',@list) . ']';
    9681482                }
    969                 $val2 = '[' . join(',',@list) . ']';
     1483                # generate tag info if we will use it later
     1484                if (not $tagInfo and defined $val and $unknown) {
     1485                    $tagInfo = NewPDFTag($tagTablePtr, $tag);
     1486                }
    9701487            }
    9711488            $exifTool->VerboseInfo($tag, $tagInfo,
     
    9741491                Index => $index++,
    9751492            );
     1493            next unless defined $val;
    9761494        }
    9771495        unless ($tagInfo) {
    9781496            # add any tag found in Info directory to table
    979             next unless $$tagTablePtr{EXTRACT_UNKNOWN};
    980             $tagInfo = { Name => $tag };
    981             Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
     1497            next unless $unknown;
     1498            $tagInfo = NewPDFTag($tagTablePtr, $tag);
    9821499        }
    9831500        unless ($$tagInfo{SubDirectory}) {
     1501            # fetch object if necessary
     1502            # (OS X 10.6 writes indirect objects in the Info dictionary!)
     1503            if (ref $val eq 'SCALAR') {
     1504                my $prevFetched = $lastFetched;
     1505                # (note: fetching the same object multiple times is OK here)
     1506                $val = FetchObject($exifTool, $$val, $xref, $tag);
     1507                next unless defined $val;
     1508                $val = ReadPDFValue($val);
     1509                # set flag to re-encrypt if necessary if rewritten
     1510                $$dict{_needCrypt}{$tag} = ($lastFetched ? 0 : 1) if $cryptString;
     1511                $lastFetched = $prevFetched; # restore last fetched object reference
     1512            } else {
     1513                $val = ReadPDFValue($val);
     1514            }
     1515            my $format = $$tagInfo{Format} || $$tagInfo{Writable} || 'string';
     1516            $val = ConvertPDFDate($val) if $format eq 'date';
    9841517            # convert from UTF-16 (big endian) to UTF-8 or Latin if necessary
    9851518            # unless this is binary data (hex-encoded strings would not have been converted)
    986             if ($val =~ s/^\xfe\xff// and not $$tagInfo{Binary}) {
    987                 $val = $exifTool->Unicode2Charset($val, 'MM');
    988             }
    989             if ($$tagInfo{List}) {
    990                 # separate tokens in comma or whitespace delimited lists
    991                 my @values = ($val =~ /,/) ? split /,+\s*/, $val : split ' ', $val;
    992                 foreach $val (@values) {
     1519            if (ref $val) {
     1520                next if ref $val ne 'ARRAY';
     1521                my $v;
     1522                foreach $v (@$val) {
     1523                    $exifTool->FoundTag($tagInfo, $v);
     1524                }
     1525            } else {
     1526                if (not $$tagInfo{Binary} and $val =~ /[\x18-\x1f\x80-\xff]/) {
     1527                    # text string is already in Unicode if it starts with "\xfe\xff",
     1528                    # otherwise we must first convert from PDFDocEncoding
     1529                    $val = $exifTool->Decode($val, ($val=~s/^\xfe\xff// ? 'UCS2' : 'PDFDoc'), 'MM');
     1530                }
     1531                if ($$tagInfo{List}) {
     1532                    # separate tokens in comma or whitespace delimited lists
     1533                    my @values = ($val =~ /,/) ? split /,+\s*/, $val : split ' ', $val;
     1534                    foreach $val (@values) {
     1535                        $exifTool->FoundTag($tagInfo, $val);
     1536                    }
     1537                } else {
     1538                    # a simple tag value
    9931539                    $exifTool->FoundTag($tagInfo, $val);
    9941540                }
    995             } else {
    996                 # a tag value
    997                 $exifTool->FoundTag($tagInfo, $val);
    9981541            }
    9991542            next;
     
    10091552        for (;;) {
    10101553            my $subDict = shift @subDicts or last;
     1554            # save last fetched object in case we fetch another one here
     1555            my $prevFetched = $lastFetched;
    10111556            if (ref $subDict eq 'SCALAR') {
     1557                # only fetch once (other copies are obsolete)
     1558                next if $fetched{$$subDict};
    10121559                # load dictionary via an indirect reference
    10131560                $fetched{$$subDict} = 1;
    1014                 $subDict = FetchObject($exifTool, $$subDict, $xref, $tag);
    1015                 $subDict or $exifTool->Warn("Error reading $tag object"), next;
     1561                my $obj = FetchObject($exifTool, $$subDict, $xref, $tag);
     1562                unless (defined $obj) {
     1563                    unless (defined $lastOffset) {
     1564                        $exifTool->Warn("Error reading $tag object ($$subDict)");
     1565                    }
     1566                    next;
     1567                }
     1568                $subDict = $obj;
    10161569            }
    10171570            if (ref $subDict eq 'ARRAY') {
    10181571                # convert array of key/value pairs to a hash
    10191572                next if @$subDict < 2;
    1020                 my %hash = ( tags => [] );
     1573                my %hash = ( _tags => [] );
    10211574                while (@$subDict >= 2) {
    10221575                    my $key = shift @$subDict;
    10231576                    $key =~ s/^\///;
    1024                     push @{$hash{tags}}, $key;
     1577                    push @{$hash{_tags}}, $key;
    10251578                    $hash{$key} = shift @$subDict;
    10261579                }
     
    10291582                next unless ref $subDict eq 'HASH';
    10301583            }
     1584            # set flag to re-crypt all strings when rewriting if the dictionary
     1585            # came from an encrypted stream
     1586            $$subDict{_needCrypt}{'*'} = 1 unless $lastFetched;
    10311587            my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
    10321588            if (not $verbose) {
    1033                 ProcessDict($exifTool, $subTablePtr, $subDict, $xref, $nesting);
     1589                my $proc = $$subTablePtr{PROCESS_PROC} || \&ProcessDict;
     1590                &$proc($exifTool, $subTablePtr, $subDict, $xref, $nesting);
    10341591            } elsif ($next) {
    10351592                # handle 'Next' links at this level to avoid deep recursion
     
    10381595                $tagTablePtr = $subTablePtr;
    10391596                $dict = $subDict;
    1040                 @tags = @{$$subDict{tags}};
     1597                @tags = @{$$subDict{_tags}};
    10411598                $exifTool->VerboseDir($tag, scalar(@tags));
    10421599            } else {
     
    10451602                $exifTool->{INDENT} .= '| ';
    10461603                $exifTool->{DIR_NAME} = $tag;
    1047                 $exifTool->VerboseDir($tag, scalar(@{$$subDict{tags}}));
     1604                $exifTool->VerboseDir($tag, scalar(@{$$subDict{_tags}}));
    10481605                ProcessDict($exifTool, $subTablePtr, $subDict, $xref, $nesting);
    10491606                $exifTool->{INDENT} = $oldIndent;
    10501607                $exifTool->{DIR_NAME} = $oldDir;
    10511608            }
    1052         }
    1053     }
    1054 #
    1055 # extract information from stream object if it exists
    1056 #
    1057     return unless $$dict{stream};
    1058     my $tag = 'stream';
     1609            $lastFetched = $prevFetched;
     1610        }
     1611    }
     1612#
     1613# extract information from joined streams if necessary
     1614#
     1615
     1616    if (%join) {
     1617        my ($tag, $i);
     1618        foreach $tag (sort keys %join) {
     1619            my $list = $join{$tag};
     1620            last unless defined $$list[1] and $$list[1] =~ /^%.*?([\x0d\x0a]*)/;
     1621            my $buff = "%!PS-Adobe-3.0$1";  # add PS header with same line break
     1622            for ($i=1; defined $$list[$i]; ++$i) {
     1623                $buff .= $$list[$i];
     1624                undef $$list[$i];   # free memory
     1625            }
     1626            $exifTool->HandleTag($tagTablePtr, $tag, $buff);
     1627        }
     1628    }
     1629#
     1630# extract information from stream object if it exists (ie. Metadata stream)
     1631#
     1632    return unless $$dict{_stream};
     1633    my $tag = '_stream';
    10591634    # add Subtype (if it exists) to stream name and remove leading '/'
    1060     ($tag = "$$dict{Subtype}_$tag") =~ s/^\/// if $$dict{Subtype};
     1635    ($tag = $$dict{Subtype} . $tag) =~ s/^\/// if $$dict{Subtype};
    10611636    return unless $$tagTablePtr{$tag};
    10621637    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
     
    10651640    # extract information from stream
    10661641    my %dirInfo = (
    1067         DataPt => \$$dict{stream},
    1068         DataLen => length $$dict{stream},
     1642        DataPt   => \$$dict{_stream},
     1643        DataLen  => length $$dict{_stream},
    10691644        DirStart => 0,
    1070         DirLen => length $$dict{stream},
    1071         Parent => 'PDF',
     1645        DirLen   => length $$dict{_stream},
     1646        Parent   => 'PDF',
    10721647    );
    10731648    my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
     
    10861661    my $raf = $$dirInfo{RAF};
    10871662    my $verbose = $exifTool->Options('Verbose');
    1088     my ($data, $encrypt, $id);
     1663    my ($buff, $encrypt, $id);
    10891664#
    10901665# validate PDF file
    10911666#
    1092     $raf->Read($data, 4) == 4 or return 0;
    1093     $data eq '%PDF' or return 0;
     1667    # (linearization dictionary must be in the first 1024 bytes of the file)
     1668    $raf->Read($buff, 1024) >= 8 or return 0;
     1669    $buff =~ /^%PDF-(\d+\.\d+)/ or return 0;
     1670    $pdfVer = $1;
    10941671    $exifTool->SetFileType();   # set the FileType tag
    1095     my $tagTablePtr = GetTagTable('Image::ExifTool::PDF::Main');
     1672    $exifTool->Warn("May not be able to read a PDF version $pdfVer file") if $pdfVer >= 2.0;
     1673    # store PDFVersion tag
     1674    my $tagTablePtr = GetTagTable('Image::ExifTool::PDF::Root');
     1675    $exifTool->HandleTag($tagTablePtr, 'Version', $pdfVer);
     1676    $tagTablePtr = GetTagTable('Image::ExifTool::PDF::Main');
     1677#
     1678# check for a linearized PDF (only if reading)
     1679#
     1680    my $capture = $$exifTool{PDF_CAPTURE};
     1681    unless ($capture) {
     1682        my $lin = 'false';
     1683        if ($buff =~ /<</g) {
     1684            $buff = substr($buff, pos($buff) - 2);
     1685            my $dict = ExtractObject($exifTool, \$buff);
     1686            if (ref $dict eq 'HASH' and $$dict{Linearized} and $$dict{L}) {
     1687                if (not $$exifTool{VALUE}{FileSize}) {
     1688                    undef $lin; # can't determine if it is linearized
     1689                } elsif ($$dict{L} == $$exifTool{VALUE}{FileSize}) {
     1690                    $lin = 'true';
     1691                }
     1692            }
     1693        }
     1694        $exifTool->HandleTag($tagTablePtr, '_linearized', $lin) if $lin;
     1695    }
    10961696#
    10971697# read the xref tables referenced from startxref at the end of the file
     
    11031703    $len = 1024 if $len > 1024;
    11041704    $raf->Seek(-$len, 2) or return -2;
    1105     $raf->Read($data, $len) == $len or return -3;
    1106     $data =~ /.*startxref(\x0d\x0a|\x0a\x0a|\x0d|\x0a)(\d+)\1%%EOF/s or return -4;
    1107     $/ = $1;    # set input record separator
    1108     push @xrefOffsets, $2;
    1109     my (%xref, @mainDicts, %loaded);
     1705    $raf->Read($buff, $len) == $len or return -3;
     1706    # find the last xref table in the file (may be multiple %%EOF marks)
     1707    $buff =~ /.*startxref *(\x0d\x0a|\x0d|\x0a)\s*?(\d+)\s+%%EOF/s or return -4;
     1708    local $/ = $1;    # set input record separator
     1709    push @xrefOffsets, $2, 'Main';
     1710    my (%xref, @mainDicts, %loaded, $mainFree);
     1711    # initialize variables to capture when rewriting
     1712    if ($capture) {
     1713        $capture->{startxref} = $2;
     1714        $capture->{xref} = \%xref;
     1715        $capture->{newline} = $/;
     1716        $capture->{mainFree} = $mainFree = { };
     1717    }
    11101718    while (@xrefOffsets) {
    11111719        my $offset = shift @xrefOffsets;
     1720        my $type = shift @xrefOffsets;
    11121721        next if $loaded{$offset};   # avoid infinite recursion
    11131722        unless ($raf->Seek($offset, 0)) {
     
    11161725            next;
    11171726        }
    1118         unless ($raf->ReadLine($data)) {
     1727        # Note: care must be taken because ReadLine may read more than we want if
     1728        # the newline sequence for this table is different than the rest of the file
     1729        unless ($raf->ReadLine($buff)) {
    11191730            %loaded or return -6;
    11201731            $exifTool->Warn('Bad offset for secondary xref table');
     
    11221733        }
    11231734        my $loadXRefStream;
    1124         if ($data eq "xref$/") {
     1735        if ($buff =~ s/^xref\s+//s) {
    11251736            # load xref table
    11261737            for (;;) {
    1127                 $raf->ReadLine($data) or return -6;
    1128                 last if $data eq "trailer$/";
    1129                 my ($start, $num) = $data =~ /(\d+)\s+(\d+)/;
    1130                 $num or return -4;
     1738                # read another line if necessary (skipping blank lines)
     1739                $raf->ReadLine($buff) or return -6 until $buff =~ /\S/;
     1740                last if $buff =~ s/^\s*trailer\s+//s;
     1741                $buff =~ s/\s*(\d+)\s+(\d+)\s+//s or return -4;
     1742                my ($start, $num) = ($1, $2);
     1743                $raf->Seek(-length($buff), 1) or return -4;
    11311744                my $i;
    11321745                for ($i=0; $i<$num; ++$i) {
    1133                     $raf->Read($data, 20) == 20 or return -6;
    1134                     $data =~ /^(\d{10}) (\d{5}) (f|n)/ or return -4;
    1135                     next if $3 eq 'f';  # ignore free entries
    1136                     # save the object offset keyed by its reference
    1137                     my $ref = ($start + $i) . ' ' . int($2) . ' R';
    1138                     $xref{$ref} = int($1);
     1746                    $raf->Read($buff, 20) == 20 or return -6;
     1747                    $buff =~ /^\s*(\d{10}) (\d{5}) (f|n)/s or return -4;
     1748                    my $num = $start + $i;
     1749                    # save offset for newest copy of all objects
     1750                    # (or next object number for free objects)
     1751                    unless (defined $xref{$num}) {
     1752                        my ($offset, $gen) = (int($1), int($2));
     1753                        $xref{$num} = $offset;
     1754                        if ($3 eq 'f') {
     1755                            # save free objects in last xref table for rewriting
     1756                            $$mainFree{$num} =  [ $offset, $gen, 'f' ] if $mainFree;
     1757                            next;
     1758                        }
     1759                        # also save offset keyed by object reference string
     1760                        $xref{"$num $gen R"} = $offset;
     1761                    }
    11391762                }
    1140             }
    1141             %xref or return -4;
    1142             $data = '';
    1143         } elsif ($data =~ s/^(\d+)\s+(\d+)\s+obj//) {
     1763                # (I have a sample from Adobe which has an empty xref table)
     1764                # %xref or return -4; # xref table may not be empty
     1765                $buff = '';
     1766            }
     1767            undef $mainFree;    # only do this for the last xref table
     1768        } elsif ($buff =~ s/^(\d+)\s+(\d+)\s+obj//s) {
    11441769            # this is a PDF-1.5 cross-reference stream dictionary
    11451770            $loadXRefStream = 1;
     
    11491774            next;
    11501775        }
    1151         my $mainDict = ExtractObject($exifTool, \$data, $raf, \%xref);
    1152         unless ($mainDict) {
     1776        my $mainDict = ExtractObject($exifTool, \$buff, $raf, \%xref);
     1777        unless (ref $mainDict eq 'HASH') {
    11531778            %loaded or return -8;
    11541779            $exifTool->Warn('Error loading secondary dictionary');
     
    11571782        if ($loadXRefStream) {
    11581783            # decode and save our XRef stream from PDF-1.5 file
    1159             # (parse it later as required to avoid wasting time)
     1784            # (but parse it later as required to save time)
     1785            # Note: this technique can potentially result in an old object
     1786            # being used if the file was incrementally updated and an older
     1787            # object from an xref table was replaced by a newer object in an
     1788            # xref stream.  But doing so isn't a good idea (if allowed at all)
     1789            # because a PDF 1.4 consumer would also make this same mistake.
    11601790            if ($$mainDict{Type} eq '/XRef' and $$mainDict{W} and
    11611791                @{$$mainDict{W}} > 2 and $$mainDict{Size} and
     
    11641794                # create Index entry if it doesn't exist
    11651795                $$mainDict{Index} or $$mainDict{Index} = [ 0, $$mainDict{Size} ];
    1166                 # create 'entry_size' entry for internal use
     1796                # create '_entry_size' entry for internal use
    11671797                my $w = $$mainDict{W};
    11681798                my $size = 0;
    11691799                foreach (@$w) { $size += $_; }
    1170                 $$mainDict{entry_size} = $size;
     1800                $$mainDict{_entry_size} = $size;
    11711801                # save this stream dictionary to use later if required
    11721802                $xref{dicts} = [] unless $xref{dicts};
     
    11791809        $loaded{$offset} = 1;
    11801810        # load XRef stream in hybrid file if it exists
    1181         push @xrefOffsets, $$mainDict{XRefStm} if $$mainDict{XRefStm};
     1811        push @xrefOffsets, $$mainDict{XRefStm}, 'XRefStm' if $$mainDict{XRefStm};
    11821812        $encrypt = $$mainDict{Encrypt} if $$mainDict{Encrypt};
    11831813        if ($$mainDict{ID} and ref $$mainDict{ID} eq 'ARRAY') {
    1184             $id = $mainDict->{ID}->[0];
    1185         }
    1186         push @mainDicts, $mainDict;
     1814            $id = ReadPDFValue($mainDict->{ID}->[0]);
     1815        }
     1816        push @mainDicts, $mainDict, $type;
    11871817        # load previous xref table if it exists
    1188         push @xrefOffsets, $$mainDict{Prev} if $$mainDict{Prev};
     1818        push @xrefOffsets, $$mainDict{Prev}, 'Prev' if $$mainDict{Prev};
    11891819    }
    11901820#
     
    11971827        # generate Encryption tag information
    11981828        my $err = DecryptInit($exifTool, $encrypt, $id);
    1199         $err and $exifTool->Warn($err), return -1;
     1829        if ($err) {
     1830            $exifTool->Warn($err);
     1831            $$capture{Error} = $err if $capture;
     1832            return -1;
     1833        }
    12001834    }
    12011835#
    12021836# extract the information beginning with each of the main dictionaries
    12031837#
    1204     my $dict;
    1205     foreach $dict (@mainDicts) {
     1838    while (@mainDicts) {
     1839        my $dict = shift @mainDicts;
     1840        my $type = shift @mainDicts;
    12061841        if ($verbose) {
    1207             my $n = scalar(@{$$dict{tags}});
     1842            my $n = scalar(@{$$dict{_tags}});
    12081843            $exifTool->VPrint(0, "PDF dictionary with $n entries:\n");
    12091844        }
    1210         ProcessDict($exifTool, $tagTablePtr, $dict, \%xref);
     1845        ProcessDict($exifTool, $tagTablePtr, $dict, \%xref, 0, $type);
     1846    }
     1847    # handle any decryption errors
     1848    if ($encrypt) {
     1849        my $err = $$encrypt{_error};
     1850        if ($err) {
     1851            $exifTool->Warn($err);
     1852            $$capture{Error} = $err if $capture;
     1853            return -1;
     1854        }
    12111855    }
    12121856    return 1;
     
    12351879    my ($exifTool, $dirInfo) = @_;
    12361880
    1237     my $oldsep = $/;
     1881    undef $cryptInfo;   # (must not delete after returning so writer can use it)
     1882    undef $cryptStream;
     1883    undef $cryptString;
    12381884    my $result = ReadPDF($exifTool, $dirInfo);
    1239     $/ = $oldsep;   # restore input record separator in case it was changed
    12401885    if ($result < 0) {
    12411886        $exifTool->Warn($pdfWarning{$result}) if $pdfWarning{$result};
     
    12431888    }
    12441889    # clean up and return
    1245     undef %warnedOnce;
    12461890    undef %streamObjs;
    12471891    undef %fetched;
    1248     undef $cryptInfo;
    12491892    return $result;
    12501893}
     
    12671910This code reads meta information from PDF (Adobe Portable Document Format)
    12681911files.  It supports object streams introduced in PDF-1.5 but only with a
    1269 limited set of Filter and Predictor algorithms, and it decodes encrypted
    1270 information but only with a limited number of algorithms.
     1912limited set of Filter and Predictor algorithms, however all standard
     1913encryption methods through PDF-1.7 extension level 3 are supported,
     1914including AESV2 (AES-128) and AESV3 (AES-256).
    12711915
    12721916=head1 AUTHOR
    12731917
    1274 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1918Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    12751919
    12761920This library is free software; you can redistribute it and/or modify it
     
    12831927=item L<http://partners.adobe.com/public/developer/pdf/index_reference.html>
    12841928
    1285 =item L<http://www.cr0.net:8040/code/crypto/rc4/>
     1929=item L<Crypt::RC4|Crypt::RC4>
     1930
     1931=item L<http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf>
     1932
     1933=item L<http://www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/adobe_supplement_iso32000.pdf>
     1934
     1935=item L<http://tools.ietf.org/search/rfc3454>
     1936
     1937=item L<http://www.armware.dk/RFC/rfc/rfc4013.html>
    12861938
    12871939=back
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PICT.pm

    r16842 r24107  
    12371237=head1 AUTHOR
    12381238
    1239 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1239Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    12401240
    12411241This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PNG.pm

    r16842 r24107  
    1212#               3) http://www.libpng.org/pub/mng/
    1313#               4) http://www.libpng.org/pub/png/spec/register/
    14 #
    15 # Notes:        I haven't found a sample PNG image with a 'iTXt' chunk, so
    16 #               this part of the code is still untested.
    17 #
    18 #               Writing meta information in PNG images is a pain in the butt
     14#               5) ftp://ftp.simplesystems.org/pub/png/documents/pngext-1.4.0-pdg.html
     15#
     16# Notes:        Writing meta information in PNG images is a pain in the butt
    1917#               for a number of reasons:  One biggie is that you have to
    2018#               decompress then decode the ASCII/hex profile information before
     
    2927use Image::ExifTool qw(:DataAccess :Utils);
    3028
    31 $VERSION = '1.15';
     29$VERSION = '1.24';
    3230
    3331sub ProcessPNG_tEXt($$$);
     
    3836sub AddChunks($$);
    3937sub Add_iCCP($$);
     38sub GetLangInfo($$);
     39sub BuildTextChunk($$$$$);
    4040
    4141my $noCompressLib;
     
    4848);
    4949
     50# map for directories in PNG images
     51my %pngMap = (
     52    IFD1         => 'IFD0',
     53    EXIF         => 'IFD0', # to write EXIF as a block
     54    ExifIFD      => 'IFD0',
     55    GPS          => 'IFD0',
     56    SubIFD       => 'IFD0',
     57    GlobParamIFD => 'IFD0',
     58    PrintIM      => 'IFD0',
     59    InteropIFD   => 'ExifIFD',
     60    MakerNotes   => 'ExifIFD',
     61    IFD0         => 'PNG',
     62    XMP          => 'PNG',
     63    ICC_Profile  => 'PNG',
     64    Photoshop    => 'PNG',
     65    IPTC         => 'Photoshop',
     66    MakerNotes   => 'ExifIFD',
     67);
     68
    5069# color type of current image
    5170$Image::ExifTool::PNG::colorType = -1;
     
    5574    WRITE_PROC => \&Image::ExifTool::DummyWriteProc,
    5675    GROUPS => { 2 => 'Image' },
     76    PREFERRED => 1, # always add these tags when writing
     77    NOTES => q{
     78        Tags extracted from PNG images.  See
     79        L<http://www.libpng.org/pub/png/spec/1.2/> for the official PNG 1.2
     80        specification.
     81    },
    5782    bKGD => {
    5883        Name => 'BackgroundColor',
     
    6287        Name => 'PrimaryChromaticities',
    6388        SubDirectory => { TagTable => 'Image::ExifTool::PNG::PrimaryChromaticities' },
     89    },
     90    dSIG => {
     91        Name => 'DigitalSignature',
     92        Binary => 1,
    6493    },
    6594    fRAc => {
     
    130159        Name => 'SignificantBits',
    131160        ValueConv => 'join(" ",unpack("C*",$val))',
     161    },
     162    sCAL => { # png 1.4.0
     163        Name => 'SubjectScale',
     164        SubDirectory => { TagTable => 'Image::ExifTool::PNG::SubjectScale' },
    132165    },
    133166    sPLT => {
     
    145178            3 => 'Absolute Colorimetric',
    146179        },
     180    },
     181    sTER => { # png 1.4.0
     182        Name => 'StereoImage',
     183        SubDirectory => { TagTable => 'Image::ExifTool::PNG::StereoImage' },
    147184    },
    148185    tEXt => {
     
    162199        },
    163200        PrintConv => '$self->ConvertDateTime($val)',
    164         PrintConvInv => '$val',
     201        PrintConvInv => '$self->InverseDateTime($val)',
    165202    },
    166203    tRNS => {
     
    175212        Notes => 'obsolete location specified by older XMP draft',
    176213        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     214    },
     215    vpAg => { # private imagemagick chunk
     216        Name => 'VirtualPage',
     217        SubDirectory => { TagTable => 'Image::ExifTool::PNG::VirtualPage' },
    177218    },
    178219    zTXt => {
     
    256297);
    257298
     299# PNG sCAL chunk
     300%Image::ExifTool::PNG::SubjectScale = (
     301    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     302    GROUPS => { 2 => 'Image' },
     303    0 => {
     304        Name => 'SubjectUnits',
     305        PrintConv => { 1 => 'Meters', 2 => 'Radians' },
     306    },
     307    1 => {
     308        Name => 'SubjectPixelWidth',
     309        Format => 'var_string',
     310    },
     311    2 => {
     312        Name => 'SubjectPixelHeight',
     313        Format => 'var_string',
     314    },
     315);
     316
     317# PNG vpAg chunk
     318%Image::ExifTool::PNG::VirtualPage = (
     319    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     320    GROUPS => { 2 => 'Image' },
     321    FORMAT => 'int32u',
     322    0 => 'VirtualImageWidth',
     323    1 => 'VirtualImageHeight',
     324    2 => {
     325        Name => 'VirtualPageUnits',
     326        Format => 'int8u',
     327        # what is the conversion for this?
     328    },
     329);
     330
     331# PNG sTER chunk
     332%Image::ExifTool::PNG::StereoImage = (
     333    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     334    GROUPS => { 2 => 'Image' },
     335    0 => {
     336        Name => 'StereoMode',
     337        PrintConv => {
     338            0 => 'Cross-fuse Layout',
     339            1 => 'Diverging-fuse Layout',
     340        },
     341    },
     342);
     343
    258344my %unreg = ( Notes => 'unregistered' );
    259345
     
    266352    PREFERRED => 1, # always add these tags when writing
    267353    GROUPS => { 2 => 'Image' },
     354    LANG_INFO => \&GetLangInfo,
    268355    NOTES => q{
    269 The PNG TextualData format allows aribrary tag names to be used.  The tags
    270 listed below are the only ones that can be written (unless new user-defined
    271 tags are added via the configuration file), however ExifTool will extract
    272 any other TextualData tags that are found.
    273 
    274 The information for the TextualData tags may be stored as tEXt, zTXt or iTXt
    275 chunks in the PNG image.  ExifTool will read and edit tags in their original
    276 form, but tEXt chunks are written by default when creating new tags.
    277 Compressed zTXt chunks are written only if Compress::Zlib is available, and
    278 only for profile information or when the -z (Compress) option is specified.
    279 
    280 Some of the tags below are not registered as part of the PNG specification,
    281 but are included here because they are generated by other software such as
    282 ImageMagick.
     356        The PNG TextualData format allows arbitrary tag names to be used.  The tags
     357        listed below are the only ones that can be written (unless new user-defined
     358        tags are added via the configuration file), however ExifTool will extract
     359        any other TextualData tags that are found.
     360       
     361        These tags may be stored as tEXt, zTXt or iTXt chunks in the PNG image.  By
     362        default ExifTool writes new string-value tags as as uncompressed tEXt, or
     363        compressed zTXt if the Compress (-z) option is used and Compress::Zlib is
     364        available.  Alternate language tags and values containing special characters
     365        (unless the Latin character set is used) are written as iTXt, and compressed
     366        if the Compress option is used and Compress::Zlib is available.  Raw profile
     367        information is always created as compressed zTXt if Compress::Zlib is
     368        available, or tEXt otherwise.  Standard XMP is written as uncompressed iTXt.
     369
     370        Alternate languages are accessed by suffixing the tag name with a '-',
     371        followed by an RFC 3066 language code (ie. "PNG:Comment-fr", or
     372        "Title-en-US").  See L<http://www.ietf.org/rfc/rfc3066.txt> for the RFC 3066
     373        specification.
     374
     375        Some of the tags below are not registered as part of the PNG specification,
     376        but are included here because they are generated by other software such as
     377        ImageMagick.
    283378    },
    284379    Title       => { },
     
    306401    Make        => { %unreg, Groups => { 2 => 'Camera' } },
    307402    Model       => { %unreg, Groups => { 2 => 'Camera' } },
     403   'create-date'=> {
     404        Name => 'CreateDate',
     405        Groups => { 2 => 'Time' },
     406        Shift => 'Time',
     407        %unreg,
     408        ValueConv => 'require Image::ExifTool::XMP; Image::ExifTool::XMP::ConvertXMPDate($val)',
     409        ValueConvInv => 'require Image::ExifTool::XMP; Image::ExifTool::XMP::FormatXMPDate($val)',
     410        PrintConv => '$self->ConvertDateTime($val)',
     411        PrintConvInv => '$self->InverseDateTime($val,undef,1)',
     412    },
     413   'modify-date'=> {
     414        Name => 'ModDate', # (to distinguish from tIME chunk "ModifyDate")
     415        Groups => { 2 => 'Time' },
     416        Shift => 'Time',
     417        %unreg,
     418        ValueConv => 'require Image::ExifTool::XMP; Image::ExifTool::XMP::ConvertXMPDate($val)',
     419        ValueConvInv => 'require Image::ExifTool::XMP; Image::ExifTool::XMP::FormatXMPDate($val)',
     420        PrintConv => '$self->ConvertDateTime($val)',
     421        PrintConvInv => '$self->InverseDateTime($val,undef,1)',
     422    },
    308423    TimeStamp   => { %unreg, Groups => { 2 => 'Time' }, Shift => 'Time' },
    309424    URL         => { %unreg },
     
    311426        Name => 'XMP',
    312427        Notes => q{
    313             location according to the XMP specification -- this is where ExifTool will
    314             add a new XMP chunk if the image didn't already contain XMP
     428            unregistered, but this is the location according to the XMP specification,
     429            and is where ExifTool will add a new XMP chunk if the image didn't already
     430            contain XMP
    315431        },
    316432        SubDirectory => {
     
    323439            # (No condition because this is just for BuildTagLookup)
    324440            Name => 'APP1_Profile',
     441            %unreg,
    325442            SubDirectory => {
    326443                TagTable=>'Image::ExifTool::Exif::Main',
     
    338455   'Raw profile type exif' => {
    339456        Name => 'EXIF_Profile',
     457        %unreg,
    340458        SubDirectory => {
    341459            TagTable=>'Image::ExifTool::Exif::Main',
     
    345463   'Raw profile type icc' => {
    346464        Name => 'ICC_Profile',
     465        %unreg,
    347466        SubDirectory => {
    348467            TagTable => 'Image::ExifTool::ICC_Profile::Main',
     
    352471   'Raw profile type icm' => {
    353472        Name => 'ICC_Profile',
     473        %unreg,
    354474        SubDirectory => {
    355475            TagTable => 'Image::ExifTool::ICC_Profile::Main',
     
    359479   'Raw profile type iptc' => {
    360480        Name => 'IPTC_Profile',
     481        %unreg,
    361482        SubDirectory => {
    362483            TagTable => 'Image::ExifTool::Photoshop::Main',
     
    366487   'Raw profile type xmp' => {
    367488        Name => 'XMP_Profile',
     489        %unreg,
    368490        SubDirectory => {
    369491            TagTable => 'Image::ExifTool::XMP::Main',
     
    379501{
    380502    return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
     503}
     504
     505#------------------------------------------------------------------------------
     506# Get standard case for language code (this routine copied from XMP.pm)
     507# Inputs: 0) Language code
     508# Returns: Language code in standard case
     509sub StandardLangCase($)
     510{
     511    my $lang = shift;
     512    # make 2nd subtag uppercase only if it is 2 letters
     513    return lc($1) . uc($2) . lc($3) if $lang =~ /^([a-z]{2,3}|[xi])(-[a-z]{2})\b(.*)/i;
     514    return lc($lang);
     515}
     516
     517#------------------------------------------------------------------------------
     518# Get localized version of tagInfo hash
     519# Inputs: 0) tagInfo hash ref, 1) language code (ie. "x-default")
     520# Returns: new tagInfo hash ref, or undef if invalid
     521sub GetLangInfo($$)
     522{
     523    my ($tagInfo, $lang) = @_;
     524    $lang =~ tr/_/-/;   # RFC 3066 specifies '-' as a separator
     525    # no alternate languages for XMP or raw profile directories
     526    return undef if $$tagInfo{SubDirectory};
     527    # language code must normalized for use in tag ID
     528    return Image::ExifTool::GetLangInfo($tagInfo, StandardLangCase($lang));
    381529}
    382530
     
    386534#         2) Tag ID, 3) Tag value, 4) [optional] compressed data flag:
    387535#            0=not compressed, 1=unknown compression, 2-N=compression with type N-2
    388 #         5) optional output buffer reference
     536#         5) optional output buffer ref, 6) character encoding (tEXt/zTXt/iTXt only)
     537#         6) optional language code
    389538# Returns: 1 on success
    390 sub FoundPNG($$$$;$$)
     539sub FoundPNG($$$$;$$$$)
    391540{
    392     my ($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff) = @_;
     541    my ($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff, $enc, $lang) = @_;
     542    return 0 unless defined $val;
     543    my $verbose = $exifTool->Options('Verbose');
     544    my $id = $tag;  # generate tag ID which include language code
     545    if ($lang) {
     546        # case of language code must be normalized since they are case insensitive
     547        $lang = StandardLangCase($lang);
     548        $id .= '-' . $lang;
     549    }
     550    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $id) ||
     551                  # (some software forgets to capitalize first letter)
     552                  $exifTool->GetTagInfo($tagTablePtr, ucfirst($id));
     553    # create alternate language tag if necessary
     554    if (not $tagInfo and $lang) {
     555        $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag) ||
     556                   $exifTool->GetTagInfo($tagTablePtr, ucfirst($tag));
     557        $tagInfo = GetLangInfo($tagInfo, $lang) if $tagInfo;
     558    }
     559#
     560# uncompress data if necessary
     561#
    393562    my ($wasCompressed, $deflateErr);
    394     return 0 unless defined $val;
    395 #
    396 # First, uncompress data if requested
    397 #
    398     my $verbose = $exifTool->Options('Verbose');
    399     my $out = $exifTool->Options('TextOut');
    400     my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag) ||
    401                   # (some software forgets to capitalize first letter)
    402                   $exifTool->GetTagInfo($tagTablePtr, ucfirst($tag));
    403 
    404563    if ($compressed and $compressed > 1) {
    405564        if ($compressed == 2) { # Inflate/Deflate compression
     
    416575                }
    417576            } elsif (not $noCompressLib) {
    418                 $noCompressLib = 1;
    419                 my $verb = $outBuff ? 'write' : 'decode';
    420                 $deflateErr = "Install Compress::Zlib to $verb compressed information";
     577                $deflateErr = "Install Compress::Zlib to read compressed information";
    421578            } else {
    422579                $deflateErr = '';   # flag deflate error but no warning
     
    429586            $exifTool->VerboseDir("Unable to decompress $$tagInfo{Name}", 0, length($val));
    430587        }
    431         $exifTool->Warn($deflateErr) if $deflateErr and not $outBuff;
     588        # issue warning if relevant
     589        if ($deflateErr and (not $outBuff or
     590            ($tagInfo and $$tagInfo{SubDirectory} and $$exifTool{EDIT_DIRS}{$$tagInfo{Name}})))
     591        {
     592            $exifTool->Warn($deflateErr);
     593            $noCompressLib = 1 if $deflateErr =~ /^Install/;
     594        }
     595    }
     596    # translate character encoding if necessary (tEXt/zTXt/iTXt string values only)
     597    if ($enc and not $compressed and not ($tagInfo and $$tagInfo{SubDirectory})) {
     598        $val = $exifTool->Decode($val, $enc);
    432599    }
    433600#
     
    444611                    $wasCompressed and $name = "Decompressed $name";
    445612                    $exifTool->VerboseDir($name, 0, $len);
    446                     my %parms = ( Prefix => $exifTool->{INDENT}, Out => $out );
    447                     $parms{MaxLen} = 96 unless $verbose > 3;
    448                     Image::ExifTool::HexDump(\$val, undef, %parms);
     613                    $exifTool->VerboseDump(\$val);
    449614                }
    450615                # don't indent next directory (since it is really the same data)
     
    457622            return 1 if $outBuff and not $$subTable{WRITE_PROC};
    458623            my %subdirInfo = (
    459                 DataPt => \$val,
     624                DataPt   => \$val,
    460625                DirStart => 0,
    461                 DataLen => $len,
    462                 DirLen => $len,
    463                 DirName => $tagName,
    464                 TagInfo => $tagInfo,
     626                DataLen  => $len,
     627                DirLen   => $len,
     628                DirName  => $tagName,
     629                TagInfo  => $tagInfo,
    465630                ReadOnly => 1, # (only used by WriteXMP)
    466                 OutBuff => $outBuff,
     631                OutBuff  => $outBuff,
    467632            );
    468633            # no need to re-decompress if already done
     
    482647        if ($outBuff) {
    483648            my $writable = $tagInfo->{Writable};
     649            my $isOverwriting;
    484650            if ($writable or ($$tagTablePtr{WRITABLE} and
    485651                not defined $writable and not $$tagInfo{SubDirectory}))
    486652            {
    487653                # write new value for this tag if necessary
    488                 my ($isOverwriting, $newVal);
     654                my $newVal;
    489655                if ($exifTool->{DEL_GROUP}->{PNG}) {
    490656                    # remove this tag now, but keep in ADD_PNG list to add back later
     
    492658                } else {
    493659                    # remove this from the list of PNG tags to add
    494                     delete $exifTool->{ADD_PNG}->{$tag};
     660                    delete $exifTool->{ADD_PNG}->{$id};
    495661                    # (also handle case of tEXt tags written with lowercase first letter)
    496                     delete $exifTool->{ADD_PNG}->{ucfirst($tag)};
    497                     my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
    498                     $isOverwriting = Image::ExifTool::IsOverwriting($newValueHash);
     662                    delete $exifTool->{ADD_PNG}->{ucfirst($id)};
     663                    my $nvHash = $exifTool->GetNewValueHash($tagInfo);
     664                    $isOverwriting = Image::ExifTool::IsOverwriting($nvHash);
    499665                    if (defined $deflateErr) {
    500                         $newVal = Image::ExifTool::GetNewValues($newValueHash);
    501                         # can only write tag now if unconditionally deleting it
    502                         if ($isOverwriting > 0 and not defined $newVal) {
     666                        $newVal = Image::ExifTool::GetNewValues($nvHash);
     667                        # can only write tag now if always overwriting
     668                        if ($isOverwriting > 0) {
    503669                            $val = '<deflate error>';
    504                         } else {
    505                             $isOverwriting = 0; # can't rewrite this compressed text
     670                        } elsif ($isOverwriting) {
     671                            $isOverwriting = 0; # can't overwrite
    506672                            $exifTool->Warn($deflateErr) if $deflateErr;
    507673                        }
    508674                    } else {
    509675                        if ($isOverwriting < 0) {
    510                             $isOverwriting = Image::ExifTool::IsOverwriting($newValueHash, $val);
     676                            $isOverwriting = Image::ExifTool::IsOverwriting($nvHash, $val);
    511677                        }
    512678                        # (must get new value after IsOverwriting() in case it was shifted)
    513                         $newVal = Image::ExifTool::GetNewValues($newValueHash);
     679                        $newVal = Image::ExifTool::GetNewValues($nvHash);
    514680                    }
    515681                }
    516682                if ($isOverwriting) {
    517                     $$outBuff =  (defined $newVal) ? $newVal : '';
     683                    $$outBuff = (defined $newVal) ? $newVal : '';
    518684                    ++$exifTool->{CHANGED};
    519                     if ($verbose > 1) {
    520                         print $out "    - PNG:$tagName = '",$exifTool->Printable($val),"'\n";
    521                         print $out "    + PNG:$tagName = '",$exifTool->Printable($newVal),"'\n" if defined $newVal;
    522                     }
     685                    $exifTool->VerboseValue("- PNG:$tagName", $val);
     686                    $exifTool->VerboseValue("+ PNG:$tagName", $newVal) if defined $newVal;
    523687                }
    524688            }
    525             if ($$outBuff) {
    526                 if ($wasCompressed) {
     689            if (defined $$outBuff and length $$outBuff) {
     690                if ($enc) { # must be tEXt/zTXt/iTXt if $enc is set
     691                    $$outBuff = BuildTextChunk($exifTool, $tag, $tagInfo, $$outBuff, $lang);
     692                } elsif ($wasCompressed) {
    527693                    # re-compress the output data
    528694                    my $deflate;
     
    537703                    }
    538704                    $$outBuff or $exifTool->Warn("PNG:$tagName not written (compress error)");
    539                 } elsif ($exifTool->Options('Compress')) {
    540                     $exifTool->Warn("PNG:$tagName not compressed (uncompressed tag existed)", 1);
    541705                }
    542706            }
     
    548712        ($name = $tag) =~ s/\s+(.)/\u$1/g;   # remove white space from tag name
    549713        $tagInfo = { Name => $name };
     714        $$tagInfo{LangCode} = $lang if $lang;
    550715        # make unknown profiles binary data type
    551         $$tagInfo{ValueConv} = '\$val' if $tag =~ /^Raw profile type /;
     716        $$tagInfo{Binary} = 1 if $tag =~ /^Raw profile type /;
    552717        Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
    553718    }
     
    605770        if ($verbose > 2) {
    606771            $exifTool->VerboseDir("Decoded $tagName", 0, $len);
    607             my %parms = (
    608                 Prefix => $exifTool->{INDENT},
    609                 Out => $exifTool->Options('TextOut'),
    610             );
    611             $parms{MaxLen} = 96 unless $verbose > 3;
    612             Image::ExifTool::HexDump(\$buff, undef, %parms);
     772            $exifTool->VerboseDump(\$buff);
    613773        }
    614774        # don't indent next directory (since it is really the same data)
     
    647807        $dirInfo{DirStart} += $hdrLen;
    648808        $dirInfo{DirLen} -= $hdrLen;
    649         $processed = $exifTool->ProcessTIFF(\%dirInfo);
    650809        if ($outBuff) {
    651             if ($$outBuff) {
    652                 $$outBuff = $Image::ExifTool::exifAPP1hdr . $$outBuff if $$outBuff;
    653             } else {
    654                 $$outBuff = '' if $processed;
    655             }
     810            $$outBuff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr,
     811                                                  \&Image::ExifTool::WriteTIFF);
     812            $$outBuff = $Image::ExifTool::exifAPP1hdr . $$outBuff if $$outBuff;
    656813            delete $$addDirs{IFD0};
     814        } else {
     815            $processed = $exifTool->ProcessTIFF(\%dirInfo);
    657816        }
    658817    } elsif ($buff =~ /^$Image::ExifTool::xmpAPP1hdr/) {
     
    673832        # TIFF information (haven't seen this, but what the heck...)
    674833        return 1 if $outBuff and not $$editDirs{IFD0};
    675         $processed = $exifTool->ProcessTIFF(\%dirInfo);
    676834        if ($outBuff) {
    677             if ($$outBuff) {
    678                 $$outBuff = $Image::ExifTool::exifAPP1hdr . $$outBuff if $$outBuff;
    679             } else {
    680                 $$outBuff = '' if $processed;
    681             }
     835            $$outBuff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr,
     836                                                  \&Image::ExifTool::WriteTIFF);
     837            $$outBuff = $Image::ExifTool::exifAPP1hdr . $$outBuff if $$outBuff;
    682838            delete $$addDirs{IFD0};
     839        } else {
     840            $processed = $exifTool->ProcessTIFF(\%dirInfo);
    683841        }
    684842    } else {
     
    687845        $exifTool->Warn("Unknown raw profile '$profName'");
    688846    }
    689     if ($outBuff and $$outBuff) {
     847    if ($outBuff and defined $$outBuff and length $$outBuff) {
    690848        if ($exifTool->{CHANGED} != $oldChanged) {
    691849            my $hdr = sprintf("\n%s\n%8d\n", $profileType, length($$outBuff));
     
    703861# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table
    704862# Returns: 1 on success
     863# Notes: writes new chunk data to ${$$dirInfo{OutBuff}} if writing tag
    705864sub ProcessPNG_Compressed($$$)
    706865{
     
    712871    my $hdr = $tag . "\0" . substr($val, 0, 1);
    713872    $val = substr($val, 1); # remove compression method byte
     873    my $success;
     874    my $outBuff = $$dirInfo{OutBuff};
    714875    # use the PNG chunk tag instead of the embedded tag name for iCCP chunks
    715876    if ($$dirInfo{TagInfo} and $$dirInfo{TagInfo}->{Name} eq 'ICC_Profile') {
    716877        $tag = 'iCCP';
    717878        $tagTablePtr = \%Image::ExifTool::PNG::Main;
    718     }
    719     my $outBuff = $$dirInfo{OutBuff};
    720     my $rtnVal = FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff);
    721     # add header back onto this chunk if we are writing
    722     $$outBuff = $hdr . $$outBuff if $outBuff and $$outBuff;
    723     return $rtnVal;
     879        $success = FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff);
     880        $$outBuff = $hdr . $$outBuff if $outBuff and $$outBuff;
     881    } else {
     882        $success = FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff, 'Latin');
     883    }
     884    return $success;
    724885}
    725886
     
    728889# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table
    729890# Returns: 1 on success
     891# Notes: writes new chunk data to ${$$dirInfo{OutBuff}} if writing tag
    730892sub ProcessPNG_tEXt($$$)
    731893{
     
    733895    my ($tag, $val) = split /\0/, ${$$dirInfo{DataPt}}, 2;
    734896    my $outBuff = $$dirInfo{OutBuff};
    735     my $rtnVal = FoundPNG($exifTool, $tagTablePtr, $tag, $val, undef, $outBuff);
    736     # add header back onto this chunk if we are writing
    737     $$outBuff = $tag . "\0" . $$outBuff if $outBuff and $$outBuff;
    738     return $rtnVal;
     897    return FoundPNG($exifTool, $tagTablePtr, $tag, $val, undef, $outBuff, 'Latin');
    739898}
    740899
     
    743902# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table
    744903# Returns: 1 on success
     904# Notes: writes new chunk data to ${$$dirInfo{OutBuff}} if writing tag
    745905sub ProcessPNG_iTXt($$$)
    746906{
     
    753913    $compressed and $compressed = 2 + $meth;
    754914    my $outBuff = $$dirInfo{OutBuff};
    755     my $rtnVal = FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff);
    756     if ($outBuff and $$outBuff) {
    757         $$outBuff = $tag . "\0" . substr($dat, 0, 2) . "$lang\0$trans\0" . $$outBuff;
    758     }
    759     return $rtnVal;
     915    return FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff, 'UTF8', $lang);
    760916}
    761917
     
    777933    return 0 unless $raf->Read($sig,8) == 8 and $pngLookup{$sig};
    778934    if ($outfile) {
     935        delete $$exifTool{TextChunkType};
    779936        Write($outfile, $sig) or $err = 1 if $outfile;
    780937        # can only add tags in Main and TextualData tables
     
    782939            \%Image::ExifTool::PNG::Main,
    783940            \%Image::ExifTool::PNG::TextualData);
    784         # initialize with same directories as JPEG, but PNG tags take priority
    785         $exifTool->InitWriteDirs('JPEG','PNG');
     941        # initialize with same directories, with PNG tags taking priority
     942        $exifTool->InitWriteDirs(\%pngMap,'PNG');
    786943    }
    787944    my ($fileType, $hdrChunk, $endChunk) = @{$pngLookup{$sig}};
     
    8471004            if ($chunk eq $hdrChunk) {
    8481005                $foundHdr = 1;
     1006            } elsif ($hdrChunk eq 'IHDR' and $chunk eq 'CgBI') {
     1007                $exifTool->Warn('Non-standard PNG image (Apple iPhone format)');
    8491008            } else {
    8501009                $exifTool->Warn("$fileType image did not start with $hdrChunk");
     
    8621021            }
    8631022            print $out "$fileType $chunk ($len bytes):\n";
    864             if ($verbose > 2) {
    865                 my %dumpParms = ( Out => $out );
    866                 $dumpParms{MaxLen} = 96 if $verbose <= 4;
    867                 Image::ExifTool::HexDump(\$dbuf, undef, %dumpParms);
    868             }
     1023            $exifTool->VerboseDump(\$dbuf, Addr => $raf->Tell() - $len - 4) if $verbose > 2;
    8691024        }
    8701025        # only extract information from chunks in our tables
     
    8771032        }
    8781033        if ($outfile) {
    879             if ($theBuff) {
    880                 $hbuf = pack('Na4',length($theBuff), $chunk);
     1034            if (defined $theBuff) {
     1035                next unless length $theBuff; # empty if we deleted the information
     1036                # change chunk type if necessary
     1037                if ($$exifTool{TextChunkType}) {
     1038                    $chunk = $$exifTool{TextChunkType};
     1039                    delete $$exifTool{TextChunkType};
     1040                }
     1041                $hbuf = pack('Na4', length($theBuff), $chunk);
    8811042                $dbuf = $theBuff;
    8821043                my $crc = CalculateCRC(\$hbuf, undef, 4);
    8831044                $crc = CalculateCRC(\$dbuf, $crc);
    8841045                $cbuf = pack('N', $crc);
    885             } elsif (defined $theBuff) {
    886                 next;   # empty if we deleted the information
    8871046            }
    8881047            Write($outfile, $hbuf, $dbuf, $cbuf) or $err = 1;
     
    9131072=head1 AUTHOR
    9141073
    915 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1074Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    9161075
    9171076This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PPM.pm

    r16842 r24107  
    1717use Image::ExifTool qw(:DataAccess :Utils);
    1818
    19 $VERSION = '1.04';
     19$VERSION = '1.05';
    2020
    2121#------------------------------------------------------------------------------
     
    8585#
    8686    if ($outfile) {
    87         my $newValueHash;
    88         my $newComment = $exifTool->GetNewValues('Comment', \$newValueHash);
     87        my $nvHash;
     88        my $newComment = $exifTool->GetNewValues('Comment', \$nvHash);
    8989        my $oldComment = $info{Comment};
    90         if (Image::ExifTool::IsOverwriting($newValueHash, $oldComment)) {
     90        if (Image::ExifTool::IsOverwriting($nvHash, $oldComment)) {
    9191            ++$exifTool->{CHANGED};
    92             if ($verbose > 1) {
    93                 print $out "    - Comment = '$oldComment'\n" if defined $oldComment;
    94                 print $out "    + Comment = '$newComment'\n" if defined $newComment;
    95             }
     92            $exifTool->VerboseValue('- Comment', $oldComment) if defined $oldComment;
     93            $exifTool->VerboseValue('+ Comment', $newComment) if defined $newComment;
    9694        } else {
    9795            $newComment = $oldComment;  # use existing comment
     
    146144=head1 AUTHOR
    147145
    148 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     146Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    149147
    150148This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Panasonic.pm

    r16842 r24107  
    1010#               3) http://johnst.org/sw/exiftags/
    1111#               4) Tels (http://bloodgate.com/) private communication (tests with FZ5)
    12 #               5) CPAN forum post by 'hardloaf' (http://www.cpanforum.com/threads/2183)
    13 #               6) http://www.cybercom.net/~dcoffin/dcraw/
    14 #               7) http://homepage3.nifty.com/kamisaka/makernote/makernote_pana.htm
     12#               7) http://homepage3.nifty.com/kamisaka/makernote/makernote_pana.htm (2007/10/02)
    1513#               8) Marcel Coenen private communication (DMC-FZ50)
    1614#               9) http://forums.dpreview.com/forums/read.asp?forum=1033&message=22756430
    17 #              10) Jens Duttke private communication (TZ3,FZ30,FZ50)
     15#              10) http://bretteville.com/pdfs/M8Metadata_v2.pdf
     16#              11) http://www.digital-leica.com/lens_codes/index.html
     17#              12) Joerg - http://www.cpanforum.com/threads/11602 (LX3 firmware 2.0)
     18#              13) Michael Byczkowski private communication (Leica M9)
     19#              14) Carl Bretteville private communication (M9)
     20#              15) Zdenek Mihula private communication (TZ8)
     21#              JD) Jens Duttke private communication (TZ3,FZ30,FZ50)
    1822#------------------------------------------------------------------------------
    1923
     
    2226use strict;
    2327use vars qw($VERSION);
     28use Image::ExifTool qw(:DataAccess :Utils);
    2429use Image::ExifTool::Exif;
    2530
    26 $VERSION = '1.26';
     31$VERSION = '1.59';
    2732
    2833sub ProcessPanasonicType2($$$);
     34sub WhiteBalanceConv($;$$);
     35
     36# Leica lens types (ref 10)
     37my %leicaLensType = (
     38    OTHER => sub {
     39        my ($val, $inv, $conv) = @_;
     40        return undef if $inv or not $val =~ s/ .*//;
     41        return $$conv{$val};
     42    },
     43    Notes => q{
     44        Entries with 2 numbers give the lower 2 bits of the LensType value which are
     45        used to identify certain manually coded lenses on the M9, or the focal
     46        length of some multi-focal lenses.
     47    },
     48    # All M9 codes (two numbers: first the LensID then the lower 2 bits)
     49    # are ref PH with samples from ref 13.  From ref 10, the lower 2 bits of
     50    # the LensType value give the frame selector position for most lenses,
     51    # although for the 28-35-50mm (at least) it gives the focal length selection.
     52    # The M9 also gives the focal length selection but for other lenses the
     53    # lower 3 bits don't change with frame selector position except for the lens
     54    # shows as uncoded for certain lenses and some incorrect positions of the
     55    # frame selector.  The bits are zero for uncoded lenses when manually coding
     56    # from the menu on the M9. - PH
     57    '0 0' => 'Uncoded lens',
     58#
     59# NOTE: MUST ADD ENTRY TO %frameSelectorBits below when a new lens is added!!!!
     60#
     61                                            # model number(s):
     62    1 => 'Elmarit-M 21mm f/2.8',            # 11134
     63    3 => 'Elmarit-M 28mm f/2.8 (III)',      # 11804
     64    4 => 'Tele-Elmarit-M 90mm f/2.8 (II)',  # 11800
     65    5 => 'Summilux-M 50mm f/1.4 (II)',      # 11868/11856/11114
     66    6 => 'Summicron-M 35mm f/2 (IV)',       # 11310/11311
     67    '6 0' => 'Summilux-M 35mm f/1.4',       # 11869/11870/11860
     68    7 => 'Summicron-M 90mm f/2 (II)',       # 11136/11137
     69    9 => 'Elmarit-M 135mm f/2.8 (I/II)',    # 11829
     70    '9 0' => 'Apo-Telyt-M 135mm f/3.4',     # 11889
     71    16 => 'Tri-Elmar-M 16-18-21mm f/4 ASPH.',# 11626
     72    '16 1' => 'Tri-Elmar-M 16-18-21mm f/4 ASPH. (at 16mm)',
     73    '16 2' => 'Tri-Elmar-M 16-18-21mm f/4 ASPH. (at 18mm)',
     74    '16 3' => 'Tri-Elmar-M 16-18-21mm f/4 ASPH. (at 21mm)',
     75    23 => 'Summicron-M 50mm f/2 (III)',     # 11817, version (I) in camera menu
     76    24 => 'Elmarit-M 21mm f/2.8 ASPH.',     # 11135/11897
     77    25 => 'Elmarit-M 24mm f/2.8 ASPH.',     # 11878/11898
     78    26 => 'Summicron-M 28mm f/2 ASPH.',     # 11604
     79    27 => 'Elmarit-M 28mm f/2.8 (IV)',      # 11809
     80    28 => 'Elmarit-M 28mm f/2.8 ASPH.',     # 11606
     81    29 => 'Summilux-M 35mm f/1.4 ASPH.',    # 11874/11883
     82    '29 0' => 'Summilux-M 35mm f/1.4 ASPHERICAL', # 11873 (different from "ASPH." model!)
     83    30 => 'Summicron-M 35mm f/2 ASPH.',     # 11879/11882
     84    31 => 'Noctilux-M 50mm f/1',            # 11821/11822
     85    '31 0' => 'Noctilux-M 50mm f/1.2',      # 11820
     86    32 => 'Summilux-M 50mm f/1.4 ASPH.',    # 11891/11892
     87    33 => 'Summicron-M 50mm f/2 (IV, V)',   # 11819/11825/11826/11816, version (II,III) in camera menu
     88    34 => 'Elmar-M 50mm f/2.8',             # 11831/11823/11825
     89    35 => 'Summilux-M 75mm f/1.4',          # 11814/11815/11810
     90    36 => 'Apo-Summicron-M 75mm f/2 ASPH.', # 11637
     91    37 => 'Apo-Summicron-M 90mm f/2 ASPH.', # 11884/11885
     92    38 => 'Elmarit-M 90mm f/2.8',           # 11807/11808, version (II) in camera menu
     93    39 => 'Macro-Elmar-M 90mm f/4',         # 11633/11634
     94    '39 0' => 'Tele-Elmar-M 135mm f/4 (II)',# 11861
     95    40 => 'Macro-Adapter M',                # 14409
     96    42 => 'Tri-Elmar-M 28-35-50mm f/4 ASPH.',# 11625
     97    '42 1' => 'Tri-Elmar-M 28-35-50mm f/4 ASPH. (at 28mm)',
     98    '42 2' => 'Tri-Elmar-M 28-35-50mm f/4 ASPH. (at 35mm)',
     99    '42 3' => 'Tri-Elmar-M 28-35-50mm f/4 ASPH. (at 50mm)',
     100    43 => 'Summarit-M 35mm f/2.5',          # ? (ref PH)
     101    44 => 'Summarit-M 50mm f/2.5',          # ? (ref PH)
     102    45 => 'Summarit-M 75mm f/2.5',          # ? (ref PH)
     103    46 => 'Summarit-M 90mm f/2.5',          # ?
     104    47 => 'Summilux-M 21mm f/1.4 ASPH.',    # ? (ref 11)
     105    48 => 'Summilux-M 24mm f/1.4 ASPH.',    # ? (ref 11)
     106    49 => 'Noctilux-M 50mm f/0.95 ASPH.',   # ? (ref 11)
     107    50 => 'Elmar-M 24mm f/3.8 ASPH.',       # ? (ref 11)
     108    52 => 'Super-Elmar-M 18mm f/3.8 ASPH.', # ? (ref PH/11)
     109);
     110
     111# M9 frame selector bits for each lens
     112#  1 = towards lens    = 28/90mm or 21mm or Adapter (or Elmarit-M 135mm f/2.8)
     113#  2 = away from lens  = 24/35mm (or 35/135mm on the M9)
     114#  3 = middle position = 50/75mm or 18mm
     115my %frameSelectorBits = (
     116    1 => 1,
     117    3 => 1,
     118    4 => 1,
     119    5 => 3,
     120    6 => 2,
     121    7 => 1,
     122    9 => 1, # (because lens has special magnifier for the rangefinder)
     123    16 => 1, # or 2 or 3
     124    23 => 3,
     125    24 => 1,
     126    25 => 2,
     127    26 => 1,
     128    27 => 1,
     129    28 => 1,
     130    29 => 2,
     131    30 => 2,
     132    31 => 3,
     133    32 => 3,
     134    33 => 3,
     135    34 => 3,
     136    35 => 3,
     137    36 => 3,
     138    37 => 1,
     139    38 => 1,
     140    39 => 1,
     141    40 => 1,
     142    42 => 1, # or 2 or 3
     143    43 => 2, # (NC)
     144    44 => 3, # (NC)
     145    45 => 3,
     146    46 => 1, # (NC)
     147    47 => 1, # (NC)
     148    48 => 2, # (NC)
     149    49 => 3, # (NC)
     150    50 => 2, # (NC)
     151    52 => 3,
     152);
    29153
    30154# conversions for ShootingMode and SceneMode
     
    39163    8  => 'Shutter Priority',
    40164    9  => 'Macro',
     165    10 => 'Spot', #7
    41166    11 => 'Manual',
    42167    12 => 'Movie Preview', #PH (LZ6)
    43168    13 => 'Panning',
    44169    14 => 'Simple', #PH (LZ6)
     170    15 => 'Color Effects', #7
     171    16 => 'Self Portrait', #PH (TZ5)
     172    17 => 'Economy', #7
    45173    18 => 'Fireworks',
    46174    19 => 'Party',
     
    48176    21 => 'Night Scenery',
    49177    22 => 'Food', #7
    50     23 => 'Baby', #10
     178    23 => 'Baby', #JD
    51179    24 => 'Soft Skin', #PH (LZ6)
    52180    25 => 'Candlelight', #PH (LZ6)
    53181    26 => 'Starry Night', #PH (LZ6)
    54182    27 => 'High Sensitivity', #7 (LZ6)
     183    28 => 'Panorama Assist', #7
    55184    29 => 'Underwater', #7
    56185    30 => 'Beach', #PH (LZ6)
    57186    31 => 'Aerial Photo', #PH (LZ6)
    58187    32 => 'Sunset', #PH (LZ6)
    59     33 => 'Pet', #10
     188    33 => 'Pet', #JD
    60189    34 => 'Intelligent ISO', #PH (LZ6)
     190    35 => 'Clipboard', #7
     191    36 => 'High Speed Continuous Shooting', #7
     192    37 => 'Intelligent Auto', #7
     193    39 => 'Multi-aspect', #PH (TZ5)
     194    41 => 'Transform', #PH (FS7)
     195    42 => 'Flash Burst', #PH (FZ28)
     196    43 => 'Pin Hole', #PH (FZ28)
     197    44 => 'Film Grain', #PH (FZ28)
     198    45 => 'My Color', #PH (GF1)
     199    46 => 'Photo Frame', #PH (FS7)
     200    51 => 'HDR', #12
    61201);
    62202
     
    101241            2 => 'Daylight',
    102242            3 => 'Cloudy',
    103             4 => 'Halogen',
     243            4 => 'Incandescent', #PH
    104244            5 => 'Manual',
    105245            8 => 'Flash',
    106246            10 => 'Black & White', #3 (Leica)
    107247            11 => 'Manual', #PH (FZ8)
     248            12 => 'Shade', #PH (FS7)
    108249        },
    109250    },
     
    116257            4 => 'Auto, Focus button', #4
    117258            5 => 'Auto, Continuous', #4
    118         },
    119     },
    120     0x0f => {
    121         Name => 'AFMode',
    122         Writable => 'int8u',
    123         Count => 2,
    124         PrintConv => { #PH
    125             '0 1'   => 'Spot Mode On', # (maybe 9-area for some cameras?)
    126             '0 16'  => 'Spot Mode Off or 3-area (high speed)', # (FZ8 is 3-area)
    127             '1 0'   => 'Spot Focusing', # (FZ8)
    128             '1 1'   => '5-area', # (FZ8)
    129             '16'    => 'Normal?', # (only AFMode for DMC-LC20)
    130             '16 0'  => '1-area', # (FZ8)
    131             '16 16' => '1-area (high speed)', # (FZ8)
    132             '32 0'  => '3-area (auto)?', # (DMC-L1 guess)
    133             '32 1'  => '3-area (left)?', # (DMC-L1 guess)
    134             '32 2'  => '3-area (center)?', # (DMC-L1 guess)
    135             '32 3'  => '3-area (right)?', # (DMC-L1 guess)
    136         },
    137     },
     259            # have seens 6 for GF1 - PH
     260        },
     261    },
     262    0x0f => [
     263        {
     264            Name => 'AFAreaMode',
     265            Condition => '$$self{Model} =~ /DMC-FZ10\b/', #JD
     266            Writable => 'int8u',
     267            Count => 2,
     268            Notes => 'DMC-FZ10',
     269            PrintConv => {
     270                '0 1'   => 'Spot Mode On',
     271                '0 16'  => 'Spot Mode Off',
     272            },
     273        },{
     274            Name => 'AFAreaMode',
     275            Writable => 'int8u',
     276            Count => 2,
     277            Notes => 'other models',
     278            PrintConv => { #PH
     279                '0 1'   => '9-area', # (FS7)
     280                '0 16'  => '3-area (high speed)', # (FZ8)
     281                '1 0'   => 'Spot Focusing', # (FZ8)
     282                '1 1'   => '5-area', # (FZ8)
     283                '16'    => 'Normal?', # (only mode for DMC-LC20)
     284                '16 0'  => '1-area', # (FZ8)
     285                '16 16' => '1-area (high speed)', # (FZ8)
     286                '32 0'  => 'Auto or Face Detect', # (Face Detect for FS7, Auto is DMC-L1 guess)
     287                '32 1'  => '3-area (left)?', # (DMC-L1 guess)
     288                '32 2'  => '3-area (center)?', # (DMC-L1 guess)
     289                '32 3'  => '3-area (right)?', # (DMC-L1 guess)
     290                '64 0'  => 'Face Detect',
     291            },
     292        },
     293    ],
    138294    0x1a => {
    139295        Name => 'ImageStabilization',
     
    143299            3 => 'Off',
    144300            4 => 'On, Mode 2',
     301            # GF1 also has a mode 3
    145302        },
    146303    },
     
    152309            2 => 'Off',
    153310            0x101 => 'Tele-Macro', #7
     311            0x201 => 'Macro Zoom', #PH (FS7)
    154312        },
    155313    },
     
    157315        Name => 'ShootingMode',
    158316        Writable => 'int16u',
     317        PrintConvColumns => 2,
    159318        PrintConv => \%shootingMode,
    160319    },
     
    175334        Writable => 'int16s',
    176335        ValueConv => '$val / 3',
    177         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    178336        ValueConvInv => '$val * 3',
    179         PrintConvInv => 'eval $val',
     337        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     338        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    180339    },
    181340    0x24 => {
     
    214373            4 => 'Black & White',
    215374            5 => 'Sepia',
    216         },
    217     },
    218     0x29 => { #10
     375            6 => 'Happy', #PH (FX70) (yes, really. you wouldn't want sad colors now would you?)
     376        },
     377    },
     378    0x29 => { #JD
    219379        Name => 'TimeSincePowerOn',
    220380        Writable => 'int32u',
    221381        Notes => q{
    222             time in 1/100 sec from when the camera was powered on to when the image is
     382            time in 1/100 s from when the camera was powered on to when the image is
    223383            written to memory card
    224384        },
     
    255415        Name => 'BurstMode',
    256416        Writable => 'int16u',
     417        Notes => 'decoding may be different for some models',
    257418        PrintConv => {
    258419            0 => 'Off',
    259             1 => 'Low/High Quality',
     420            1 => 'On', #PH (TZ5) [was "Low/High Quality" from ref 4]
    260421            2 => 'Infinite',
     422            4 => 'Unlimited', #PH (TZ5)
    261423        },
    262424    },
     
    265427        Writable => 'int32u',
    266428    },
    267     0x2c => {
    268         Name => 'Contrast',
    269         Flags => 'PrintHex',
    270         Writable => 'int16u',
    271         PrintConv => {
    272             0 => 'Normal',
    273             1 => 'Low',
    274             2 => 'High',
    275             # 3 - observed with LZ6 in "Aerial Photo" mode - PH
    276             # 5 - observed with FX10 in "Underwater" mode - PH
    277             0x100 => 'Low',
    278             0x110 => 'Normal',
    279             0x120 => 'High',
    280         }
    281     },
     429    0x2c => [
     430        {
     431            Name => 'ContrastMode',
     432            Condition => '$$self{Model} !~ /^DMC-(FX10|G1|L1|L10|LC80|GF1|TZ10|ZS7)$/',
     433            Flags => 'PrintHex',
     434            Writable => 'int16u',
     435            Notes => q{
     436                this decoding seems to work for some models such as the LC1, LX2, FZ7, FZ8,
     437                FZ18 and FZ50, but may not be correct for other models such as the FX10, G1, L1,
     438                L10 and LC80
     439            },
     440            PrintConv => {
     441                0 => 'Normal',
     442                1 => 'Low',
     443                2 => 'High',
     444                # 3 - observed with LZ6 and TZ5 in Fireworks mode - PH
     445                # 5 - observed with FX01, FX40 and FP8 (EXIF contrast "Normal") - PH
     446                6 => 'Medium Low', #PH (FZ18)
     447                7 => 'Medium High', #PH (FZ18)
     448                # DMC-LC1 values:
     449                0x100 => 'Low',
     450                0x110 => 'Normal',
     451                0x120 => 'High',
     452            }
     453        },{
     454            Name => 'ContrastMode',
     455            Condition => '$$self{Model} eq "DMC-GF1"',
     456            Notes => 'these values are used by the GF1',
     457            Writable => 'int16u',
     458            PrintConv => {
     459                0 => '-2',
     460                1 => '-1',
     461                2 => 'Normal',
     462                3 => '+1',
     463                4 => '+2',
     464                # Note: Other Contrast tags will be "Normal" in any of these modes:
     465                7 => 'Nature (Color Film)',
     466                12 => 'Smooth (Color Film) or Pure (My Color)',
     467                17 => 'Dynamic (B&W Film)',
     468                22 => 'Smooth (B&W Film)',
     469                27 => 'Dynamic (Color Film)',
     470                32 => 'Vibrant (Color Film) or Expressive (My Color)',
     471                33 => 'Elegant (My Color)',
     472                37 => 'Nostalgic (Color Film)',
     473                41 => 'Dynamic Art (My Color)',
     474                42 => 'Retro (My Color)',
     475            },
     476        },{
     477            Name => 'ContrastMode',
     478            Condition => '$$self{Model} =~ /^DMC-(TZ10|ZS7)$/',
     479            Notes => 'these values are used by the TZ10 and ZS7',
     480            Writable => 'int16u',
     481            PrintConv => {
     482                0 => 'Normal',
     483                1 => '-2',
     484                2 => '+2',
     485                5 => '-1',
     486                6 => '+1',
     487            },
     488        },{
     489            Name => 'ContrastMode',
     490            Writable => 'int16u',
     491        },
     492    ],
    282493    0x2d => {
    283494        Name => 'NoiseReduction',
     
    285496        PrintConv => {
    286497            0 => 'Standard',
    287             1 => 'Low',
    288             2 => 'High',
     498            1 => 'Low (-1)',
     499            2 => 'High (+1)',
     500            3 => 'Lowest (-2)', #JD
     501            4 => 'Highest (+2)', #JD
    289502        },
    290503    },
     
    294507        PrintConv => {
    295508            1 => 'Off',
    296             2 => '10s',
    297             3 => '2s',
     509            2 => '10 s',
     510            3 => '2 s',
    298511        },
    299512    },
     
    304517        PrintConv => {
    305518            1 => 'Horizontal (normal)',
     519            3 => 'Rotate 180', #PH
    306520            6 => 'Rotate 90 CW', #PH (ref 7 gives 270 CW)
    307521            8 => 'Rotate 270 CW', #PH (ref 7 gives 90 CW)
    308522        },
    309523    },
    310     # 0x31 - values: 1-5 some sort of mode? (changes with FOC-L) (PH/10)
     524    0x31 => { #PH (FS7)
     525        Name => 'AFAssistLamp',
     526        Writable => 'int16u',
     527        PrintConv => {
     528            1 => 'Fired',
     529            2 => 'Enabled but Not Used',
     530            3 => 'Disabled but Required',
     531            4 => 'Disabled and Not Required',
     532            # have seen a value of 5 - PH
     533            # values possibly related to FOC-L? - JD
     534        },
     535    },
    311536    0x32 => { #7
    312537        Name => 'ColorMode',
     
    315540            0 => 'Normal',
    316541            1 => 'Natural',
    317             # 2 => observed in LZ6 for some shooting modes
    318         },
    319     },
    320     0x33 => { #10
     542            2 => 'Vivid',
     543            # have seen 3 for GF2 - PH
     544        },
     545    },
     546    0x33 => { #JD
    321547        Name => 'BabyAge',
    322548        Writable => 'string',
     
    330556        PrintConv => {
    331557            1 => 'Standard',
    332             2 => 'EX Optics',
     558            2 => 'Extended',
    333559        },
    334560    },
     
    349575        PrintConvInv => '$val =~ /(\d+)/ ? $1 : $val',
    350576    },
    351     # 0x37 - values: 0,1,2 (LZ6, 0 for movie preview) and 257 (FX10K)
    352     # 0x38 - values: 0,1,2 (LZ6, same as 0x37) and 1,2 (FX10K)
     577    # 0x37 - values: 0,1,2 (LZ6, 0 for movie preview); 257 (FX10K); 0,256 (TZ5, 0 for movie preview)
     578    # 0x38 - values: 0,1,2 (LZ6, same as 0x37); 1,2 (FX10K); 0,256 (TZ5, 0 for movie preview)
     579    0x39 => { #7 (L1/L10)
     580        Name => 'Contrast',
     581        Format => 'int16s',
     582        Writable => 'int16u',
     583        %Image::ExifTool::Exif::printParameter,
     584    },
    353585    0x3a => {
    354586        Name => 'WorldTimeLocation',
     
    359591        },
    360592    },
    361     # 0x3b - values: 1 (LZ6, FX10K)
     593    0x3b => { #PH (TZ5/FS7)
     594        # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
     595        Name => 'TextStamp',
     596        Writable => 'int16u',
     597        PrintConv => { 1 => 'Off', 2 => 'On' },
     598    },
    362599    0x3c => { #PH
    363         Name => 'ProgramISO',
    364         Writable => 'int16u',
    365         PrintConv => '$val == 65535 ? "n/a" : $val',
    366         PrintConvInv => '$val eq "n/a" ? 65535 : $val',
    367     },
    368     # 0x40 Chroma? (ref 7)
     600        Name => 'ProgramISO', # (maybe should rename this ISOSetting?)
     601        Writable => 'int16u',
     602        PrintConv => {
     603            OTHER => sub { return shift },
     604            65534 => 'Intelligent ISO', #PH (FS7)
     605            65535 => 'n/a',
     606        },
     607    },
     608    0x3d => { #PH
     609        Name => 'AdvancedSceneMode',
     610        Writable => 'int16u',
     611        # values for the FZ28 (SceneMode/AdvancedSceneMode, "*"=add mode name) - PH:
     612        # Portrait: 2/1=Normal*, 24/1=Soft Skin, 2/2=Outdoor*, 2/3=Indoor*, 2/4=Creative*
     613        # Scenery: 3/1=Normal*, 3/2=Nature, 3/3=Architecture, 3/4=Creative*
     614        # Sports: 4/1=Normal*, 4/2=Outdoor*, 4/3=Indoor*, 4/4=Creative*
     615        # Night Scenery: 5/1=Night Portrait, 21/1=*, 21/2=Illuminations, 21/4=Creative*
     616        # Macro (Close-up): 9/2=Flower, 22/1=Food, 9/3=Objects, 9/4=Creative*
     617        # - have seen value of 5 for TZ5 (Macro) and FS20 (Scenery and Intelligent Auto)
     618        #   --> I'm guessing this is "Auto" - PH
     619        # - values for HDR mode (ref 12): 1=Standard, 2=Art, 3=B&W
     620        PrintConv => {
     621            1 => 'Normal',
     622            2 => 'Outdoor/Illuminations/Flower/HDR Art',
     623            3 => 'Indoor/Architecture/Objects/HDR B&W',
     624            4 => 'Creative',
     625            5 => 'Auto',
     626            7 => 'Expressive', #(GF1)
     627            8 => 'Retro', #(GF1)
     628            9 => 'Pure', #(GF1)
     629            10 => 'Elegant', #(GF1)
     630            12 => 'Monochrome', #(GF1)
     631            13 => 'Dynamic Art', #(GF1)
     632            14 => 'Silhouette', #(GF1)
     633        },
     634    },
     635    0x3e => { #PH (TZ5/FS7)
     636        # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
     637        Name => 'TextStamp',
     638        Writable => 'int16u',
     639        PrintConv => { 1 => 'Off', 2 => 'On' },
     640    },
     641    0x3f => { #PH (TZ7)
     642        Name => 'FacesDetected',
     643        Writable => 'int16u',
     644    },
     645    0x40 => { #7 (L1/L10)
     646        Name => 'Saturation',
     647        Format => 'int16s',
     648        Writable => 'int16u',
     649        %Image::ExifTool::Exif::printParameter,
     650    },
     651    0x41 => { #7 (L1/L10)
     652        Name => 'Sharpness',
     653        Format => 'int16s',
     654        Writable => 'int16u',
     655        %Image::ExifTool::Exif::printParameter,
     656    },
    369657    0x42 => { #7 (DMC-L1)
    370658        Name => 'FilmMode',
    371659        Writable => 'int16u',
    372660        PrintConv => {
     661            0 => 'n/a', #PH (ie. FZ100 "Photo Frame" ShootingMode)
    373662            1 => 'Standard (color)',
    374663            2 => 'Dynamic (color)',
     
    380669            # 8 => 'My Film 1'? (from owner manual)
    381670            # 9 => 'My Film 2'?
    382         },
    383     },
    384     0x46 => { #PH/10
     671            10 => 'Nostalgic', # GH1
     672            11 => 'Vibrant', # GH1
     673            # 12 => 'Multi Film'? (in the GH1 specs)
     674        },
     675    },
     676    # 0x43 - int16u: 2,3
     677    # 0x44 - int16u: 0,2500
     678    # 0x45 - int16u: 0
     679    0x46 => { #PH/JD
    385680        Name => 'WBAdjustAB',
    386681        Format => 'int16s',
     
    388683        Notes => 'positive is a shift toward blue',
    389684    },
    390     0x47 => { #PH/10
     685    0x47 => { #PH/JD
    391686        Name => 'WBAdjustGM',
    392687        Format => 'int16s',
     
    394689        Notes => 'positive is a shift toward green',
    395690    },
     691    # 0x48 - int16u: 0
     692    # 0x49 - int16u: 2
     693    # 0x4a - int16u: 0
     694    0x4b => { #PH
     695        Name => 'PanasonicImageWidth',
     696        Writable => 'int32u',
     697    },
     698    0x4c => { #PH
     699        Name => 'PanasonicImageHeight',
     700        Writable => 'int32u',
     701    },
     702    0x4d => { #PH (FS7)
     703        Name => 'AFPointPosition',
     704        Writable => 'rational64u',
     705        Count => 2,
     706        Notes => 'X Y coordinates of primary AF area center, in the range 0.0 to 1.0',
     707        PrintConv => q{
     708            return 'none' if $val eq '16777216 16777216';
     709            my @a = split ' ', $val;
     710            sprintf("%.2g %.2g",@a);
     711        },
     712        PrintConvInv => '$val eq "none" ? "16777216 16777216" : $val',
     713    },
     714    0x4e => { #PH
     715        Name => 'FaceDetInfo',
     716        PrintConv => 'length $val',
     717        SubDirectory => {
     718            TagTable => 'Image::ExifTool::Panasonic::FaceDetInfo',
     719        },
     720    },
     721    # 0x4f,0x50 - int16u: 0
    396722    0x51 => {
    397723        Name => 'LensType',
     
    406732        Writable => 'string',
    407733    },
     734    # 0x54 - string[14]: "0000000"
     735    # 0x55 - int16u: 1
     736    # 0x57 - int16u: 0
     737    0x59 => { #PH (FS7)
     738        Name => 'Transform',
     739        Writable => 'undef',
     740        Notes => 'decoded as two 16-bit signed integers',
     741        Format => 'int16s',
     742        Count => 2,
     743        PrintConv => {
     744            '-3 2' => 'Slim High',
     745            '-1 1' => 'Slim Low',
     746            '0 0' => 'Off',
     747            '1 1' => 'Stretch Low',
     748            '3 2' => 'Stretch High',
     749        },
     750    },
     751    # 0x5a - int16u: 0,2
     752    # 0x5b - int16u: 0
     753    # 0x5c - int16u: 0,2
     754    0x5d => { #PH (GF1, FZ35)
     755        Name => 'IntelligentExposure',
     756        Notes => 'not valid for some models', # (doesn't change in ZS7 and GH1 images)
     757        Writable => 'int16u',
     758        PrintConv => {
     759            0 => 'Off',
     760            1 => 'Low',
     761            2 => 'Standard',
     762            3 => 'High',
     763        },
     764    },
     765    # 0x5e,0x5f,0x60 - undef[4]
     766    0x61 => { #PH
     767        Name => 'FaceRecInfo',
     768        SubDirectory => {
     769            TagTable => 'Image::ExifTool::Panasonic::FaceRecInfo',
     770        },
     771    },
     772    0x62 => { #PH (FS7)
     773        Name => 'FlashWarning',
     774        Writable => 'int16u',
     775        PrintConv => { 0 => 'No', 1 => 'Yes (flash required but disabled)' },
     776    },
     777    0x63 => { #PH
     778        # not sure exactly what this means, but in my samples this is
     779        # FacesRecognized bytes of 0x01, padded with 0x00 to a length of 4 - PH
     780        Name => 'RecognizedFaceFlags',
     781        Format => 'int8u',
     782        Count => 4,
     783        Writable => 'undef',
     784        Unknown => 1,
     785    },
     786    0x65 => { #15
     787        Name => 'Title',
     788        Format => 'string',
     789        Writable => 'undef', # (Count 64)
     790    },
     791    0x66 => { #15
     792        Name => 'BabyName',
     793        Notes => 'or pet name',
     794        Format => 'string',
     795        Writable => 'undef', # (Count 64)
     796    },
     797    0x67 => { #15
     798        Name => 'Location',
     799        Groups => { 2 => 'Location' },
     800        Format => 'string',
     801        Writable => 'undef', # (Count 64)
     802    },
     803    # 0x68 - int8u: 1
     804    0x69 => { #PH (ZS7)
     805        Name => 'Country', # (Country/Region)
     806        Groups => { 2 => 'Location' },
     807        Format => 'string',
     808        Writable => 'undef', # (Count 72)
     809    },
     810    # 0x6a - int8u: 1
     811    0x6b => { #PH (ZS7)
     812        Name => 'State', # (State/Province/Count -- what is Count?)
     813        Groups => { 2 => 'Location' },
     814        Format => 'string',
     815        Writable => 'undef', # (Count 72)
     816    },
     817    # 0x6c - int8u: 1
     818    0x6d => { #PH (ZS7)
     819        Name => 'City', # (City/Town)
     820        Groups => { 2 => 'Location' },
     821        Format => 'string',
     822        Writable => 'undef', # (Count 72)
     823    },
     824    # 0x6e - int8u: 1
     825    0x6f => { #PH (ZS7)
     826        Name => 'Landmark', # (Landmark)
     827        Groups => { 2 => 'Location' },
     828        Format => 'string',
     829        Writable => 'undef', # (Count 128)
     830    },
     831    0x70 => { #PH (ZS7)
     832        Name => 'IntelligentResolution',
     833        Writable => 'int8u',
     834        PrintConv => {
     835            0 => 'Off',
     836            # Note: I think these values make sense for the GH2, but meanings
     837            #       may be different for other models
     838            1 => 'Low',
     839            2 => 'Standard',
     840            3 => 'High',
     841            4 => 'Extended',
     842        },
     843    },
     844    # 0x71 - undef[128] (maybe text stamp text?)
     845    # 0x72,0x73,0x74,0x75,0x76,0x77,0x78: 0
     846    0x79 => { #PH (GH2)
     847        Name => 'IntelligentD-Range',
     848        Writable => 'int16u',
     849        PrintConv => {
     850            0 => 'Off',
     851            1 => 'Low',
     852            2 => 'Standard',
     853            3 => 'High',
     854        },
     855    },
     856    # 0x7a,0x7b: 0
    408857    0x0e00 => {
    409858        Name => 'PrintIM',
     
    418867        Format => 'undef',
    419868    },
    420     0x8001 => { #7/PH/10
     869    0x8001 => { #7/PH/JD
    421870        Name => 'SceneMode',
    422871        Writable => 'int16u',
     872        PrintConvColumns => 2,
    423873        PrintConv => {
    424874            0  => 'Off',
     
    426876        },
    427877    },
    428     # 0x8002 - values: 1,2 related to focus? (PH/10)
    429     # 0x8003 - values: 1,2 related to focus? (PH/10)
    430     0x8004 => { #PH/10
     878    # 0x8002 - values: 1,2 related to focus? (PH/JD)
     879    #          1 for HDR modes, 2 for Portrait (ref 12)
     880    # 0x8003 - values: 1,2 related to focus? (PH/JD)
     881    0x8004 => { #PH/JD
    431882        Name => 'WBRedLevel',
    432883        Writable => 'int16u',
    433884    },
    434     0x8005 => { #PH/10
     885    0x8005 => { #PH/JD
    435886        Name => 'WBGreenLevel',
    436887        Writable => 'int16u',
    437888    },
    438     0x8006 => { #PH/10
     889    0x8006 => { #PH/JD
    439890        Name => 'WBBlueLevel',
    440891        Writable => 'int16u',
    441892    },
    442     # 0x8007 - values: 1,2
     893    0x8007 => { #PH
     894        Name => 'FlashFired',
     895        Writable => 'int16u',
     896        PrintConv => { 1 => 'No', 2 => 'Yes' },
     897    },
     898    0x8008 => { #PH (TZ5/FS7)
     899        # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
     900        Name => 'TextStamp',
     901        Writable => 'int16u',
     902        PrintConv => { 1 => 'Off', 2 => 'On' },
     903    },
     904    0x8009 => { #PH (TZ5/FS7)
     905        # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
     906        Name => 'TextStamp',
     907        Writable => 'int16u',
     908        PrintConv => { 1 => 'Off', 2 => 'On' },
     909    },
    443910    0x8010 => { #PH
    444911        Name => 'BabyAge',
     
    448915        PrintConvInv => '$val =~ /^\d/ ? $val : "9999:99:99 00:00:00"',
    449916    },
     917    0x8012 => { #PH (FS7)
     918        Name => 'Transform',
     919        Writable => 'undef',
     920        Notes => 'decoded as two 16-bit signed integers',
     921        Format => 'int16s',
     922        Count => 2,
     923        PrintConv => {
     924            '-3 2' => 'Slim High',
     925            '-1 1' => 'Slim Low',
     926            '0 0' => 'Off',
     927            '1 1' => 'Stretch Low',
     928            '3 2' => 'Stretch High',
     929        },
     930    },
     931);
     932
     933# Leica type2 maker notes (ref 10)
     934%Image::ExifTool::Panasonic::Leica2 = (
     935    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     936    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     937    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     938    WRITABLE => 1,
     939    NOTES => 'These tags are used by the Leica M8.',
     940    0x300 => {
     941        Name => 'Quality',
     942        Writable => 'int16u',
     943        PrintConv => {
     944            1 => 'Fine',
     945            2 => 'Basic',
     946        },
     947    },
     948    0x302 => {
     949        Name => 'UserProfile',
     950        Writable => 'int32u',
     951        PrintConv => {
     952            1 => 'User Profile 1',
     953            2 => 'User Profile 2',
     954            3 => 'User Profile 3',
     955            4 => 'User Profile 0 (Dynamic)',
     956        },
     957    },
     958    0x303 => {
     959        Name => 'SerialNumber',
     960        Writable => 'int32u',
     961        PrintConv => 'sprintf("%.7d", $val)',
     962        PrintConvInv => '$val',
     963    },
     964    0x304 => {
     965        Name => 'WhiteBalance',
     966        Writable => 'int16u',
     967        Notes => 'values above 0x8000 are converted to Kelvin color temperatures',
     968        PrintConv => {
     969            0 => 'Auto or Manual',
     970            1 => 'Daylight',
     971            2 => 'Fluorescent',
     972            3 => 'Tungsten',
     973            4 => 'Flash',
     974            10 => 'Cloudy',
     975            11 => 'Shade',
     976            OTHER => \&WhiteBalanceConv,
     977        },
     978    },
     979    0x310 => {
     980        Name => 'LensInfo',
     981        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::LensInfo' },
     982    },
     983    0x311 => {
     984        Name => 'ExternalSensorBrightnessValue',
     985        Format => 'rational64s', # (incorrectly unsigned in JPEG images)
     986        Writable => 'rational64s',
     987        Notes => '"blue dot" measurement',
     988        PrintConv => 'sprintf("%.2f", $val)',
     989        PrintConvInv => '$val',
     990    },
     991    0x312 => {
     992        Name => 'MeasuredLV',
     993        Format => 'rational64s', # (incorrectly unsigned in JPEG images)
     994        Writable => 'rational64s',
     995        Notes => 'imaging sensor or TTL exposure meter measurement',
     996        PrintConv => 'sprintf("%.2f", $val)',
     997        PrintConvInv => '$val',
     998    },
     999    0x313 => {
     1000        Name => 'ApproximateFNumber',
     1001        Writable => 'rational64u',
     1002        PrintConv => 'sprintf("%.1f", $val)',
     1003        PrintConvInv => '$val',
     1004    },
     1005    0x320 => {
     1006        Name => 'CameraTemperature',
     1007        Writable => 'int32s',
     1008        PrintConv => '"$val C"',
     1009        PrintConvInv => '$val=~s/ ?C//; $val',
     1010    },
     1011    0x321 => { Name => 'ColorTemperature',  Writable => 'int32u' },
     1012    0x322 => { Name => 'WBRedLevel',        Writable => 'rational64u' },
     1013    0x323 => { Name => 'WBGreenLevel',      Writable => 'rational64u' },
     1014    0x324 => { Name => 'WBBlueLevel',       Writable => 'rational64u' },
     1015    0x325 => {
     1016        Name => 'UV-IRFilterCorrection',
     1017        Description => 'UV/IR Filter Correction',
     1018        Writable => 'int32u',
     1019        PrintConv => {
     1020            0 => 'Not Active',
     1021            1 => 'Active',
     1022        },
     1023    },
     1024    0x330 => { Name => 'CCDVersion',        Writable => 'int32u' },
     1025    0x331 => { Name => 'CCDBoardVersion',   Writable => 'int32u' },
     1026    0x332 => { Name => 'ControllerBoardVersion', Writable => 'int32u' },
     1027    0x333 => { Name => 'M16CVersion',       Writable => 'int32u' },
     1028    0x340 => { Name => 'ImageIDNumber',     Writable => 'int32u' },
     1029);
     1030
     1031# Leica type3 maker notes (ref PH)
     1032%Image::ExifTool::Panasonic::Leica3 = (
     1033    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     1034    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     1035    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     1036    WRITABLE => 1,
     1037    NOTES => 'These tags are used by the Leica R8 and R9 digital backs.',
     1038    0x0d => {
     1039        Name => 'WB_RGBLevels',
     1040        Writable => 'int16u',
     1041        Count => 3,
     1042    },
     1043);
     1044
     1045# Leica type4 maker notes (ref PH) (M9)
     1046%Image::ExifTool::Panasonic::Leica4 = (
     1047    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     1048    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     1049    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     1050    WRITABLE => 1,
     1051    NOTES => 'This information is written by the M9.',
     1052    0x3000 => {
     1053        Name => 'Subdir3000',
     1054        SubDirectory => {
     1055            TagTable => 'Image::ExifTool::Panasonic::Subdir',
     1056            ByteOrder => 'Unknown',
     1057        },
     1058    },
     1059    0x3100 => {
     1060        Name => 'Subdir3100',
     1061        SubDirectory => {
     1062            TagTable => 'Image::ExifTool::Panasonic::Subdir',
     1063            ByteOrder => 'Unknown',
     1064        },
     1065    },
     1066    0x3400 => {
     1067        Name => 'Subdir3400',
     1068        SubDirectory => {
     1069            TagTable => 'Image::ExifTool::Panasonic::Subdir',
     1070            ByteOrder => 'Unknown',
     1071        },
     1072    },
     1073    0x3900 => {
     1074        Name => 'Subdir3900',
     1075        SubDirectory => {
     1076            TagTable => 'Image::ExifTool::Panasonic::Subdir',
     1077            ByteOrder => 'Unknown',
     1078        },
     1079    },
     1080);
     1081
     1082# Leica M9 SubDirectory tags (ref PH)
     1083%Image::ExifTool::Panasonic::Subdir = (
     1084    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     1085    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     1086    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     1087    TAG_PREFIX => 'Leica_Subdir',
     1088    WRITABLE => 1,
     1089    # 0x3001 - normally 0 but value of 2 when manual coding is used
     1090    #          with a coded lens (but only tested with Elmar-M 50mm f/2.8) - PH
     1091    0x300a => {
     1092        Name => 'Contrast',
     1093        Writable => 'int32u',
     1094        PrintConv => {
     1095            0 => 'Low',
     1096            1 => 'Medium Low',
     1097            2 => 'Normal',
     1098            3 => 'Medium High',
     1099            4 => 'High',
     1100        },
     1101    },
     1102    0x300b => {
     1103        Name => 'Sharpening',
     1104        Writable => 'int32u',
     1105        PrintConv => {
     1106            0 => 'Off',
     1107            1 => 'Low',
     1108            2 => 'Normal',
     1109            3 => 'Medium High',
     1110            4 => 'High',
     1111        },
     1112    },
     1113    0x300d => {
     1114        Name => 'Saturation',
     1115        Writable => 'int32u',
     1116        PrintConv => {
     1117            0 => 'Low',
     1118            1 => 'Medium Low',
     1119            2 => 'Normal',
     1120            3 => 'Medium High',
     1121            4 => 'High',
     1122            5 => 'Black & White',
     1123            6 => 'Vintage B&W',
     1124        },
     1125    },
     1126    # 0x3032 - some sort of RGB coefficients? (zeros unless Kelvin WB, but same for all Color Temps)
     1127    0x3033 => {
     1128        Name => 'WhiteBalance',
     1129        Writable => 'int32u',
     1130        PrintConv => { #13
     1131            0 => 'Auto',
     1132            1 => 'Tungsten',
     1133            2 => 'Fluorescent',
     1134            3 => 'Daylight Fluorescent',
     1135            4 => 'Daylight',
     1136            5 => 'Flash',
     1137            6 => 'Cloudy',
     1138            7 => 'Shade',
     1139            8 => 'Manual',
     1140            9 => 'Kelvin',
     1141        },
     1142    },
     1143    0x3034 => {
     1144        Name => 'JPEGQuality',
     1145        Writable => 'int32u',
     1146        PrintConv => {
     1147            94 => 'Basic',
     1148            97 => 'Fine',
     1149        },
     1150    },
     1151    # 0x3035 (int32u): -1 unless Manual WB (2 in my Manual sample)
     1152    0x3036 => {
     1153        Name => 'WB_RGBLevels',
     1154        Writable => 'rational64u',
     1155        Count => 3,
     1156    },
     1157    0x3038 => {
     1158        Name => 'UserProfile', # (CameraProfile according to ref 14)
     1159        Writable => 'string',
     1160    },
     1161    0x303a => {
     1162        Name => 'JPEGSize',
     1163        Writable => 'int32u',
     1164        PrintConv => {
     1165            0 => '5216x3472',
     1166            1 => '3840x2592',
     1167            2 => '2592x1728',
     1168            3 => '1728x1152',
     1169            4 => '1280x864',
     1170        },
     1171    },
     1172    0x3103 => { #13 (valid for FW 1.116 and later)
     1173        Name => 'SerialNumber',
     1174        Writable => 'string',
     1175    },
     1176    # 0x3104 body-dependent string ("00012905000000") (not serial number)
     1177    # 0x3105 body-dependent string ("00012905000000")
     1178    # 0x3107 - body-dependent string ("4H205800116800") (not serial number)
     1179    0x3109 => {
     1180        Name => 'FirmwareVersion',
     1181        Writable => 'string',
     1182    },
     1183    0x312a => { #14 (NC)
     1184        Name => 'BaseISO',
     1185        Writable => 'int32u',
     1186    },
     1187    0x312b => {
     1188        Name => 'SensorWidth',
     1189        Writable => 'int32u',
     1190    },
     1191    0x312c => {
     1192        Name => 'SensorHeight',
     1193        Writable => 'int32u',
     1194    },
     1195    0x312d => { #14 (NC)
     1196        Name => 'SensorBitDepth',
     1197        Writable => 'int32u',
     1198    },
     1199    0x3402 => { #PH/13
     1200        Name => 'CameraTemperature',
     1201        Writable => 'int32s',
     1202        PrintConv => '"$val C"',
     1203        PrintConvInv => '$val=~s/ ?C//; $val',
     1204    },
     1205    0x3405 => {
     1206        Name => 'LensType',
     1207        Writable => 'int32u',
     1208        SeparateTable => 1,
     1209        ValueConv => '($val >> 2) . " " . ($val & 0x3)',
     1210        ValueConvInv => \&LensTypeConvInv,
     1211        PrintConv => \%leicaLensType,
     1212    },
     1213    0x3406 => { #PH/13
     1214        Name => 'ApproximateFNumber',
     1215        Writable => 'rational64u',
     1216        PrintConv => 'sprintf("%.1f", $val)',
     1217        PrintConvInv => '$val',
     1218    },
     1219    0x3407 => { #14
     1220        Name => 'MeasuredLV',
     1221        Writable => 'int32s',
     1222        Notes => 'imaging sensor or TTL exposure meter measurement',
     1223        ValueConv => '$val / 1e5', #PH (NC)
     1224        ValueConvInv => '$val * 1e5', #PH (NC)
     1225        PrintConv => 'sprintf("%.2f", $val)',
     1226        PrintConvInv => '$val',
     1227    },
     1228    0x3408 => { #14
     1229        Name => 'ExternalSensorBrightnessValue',
     1230        Writable => 'int32s',
     1231        Notes => '"blue dot" measurement',
     1232        ValueConv => '$val / 1e5', #PH (NC)
     1233        ValueConvInv => '$val * 1e5', #PH (NC)
     1234        PrintConv => 'sprintf("%.2f", $val)',
     1235        PrintConvInv => '$val',
     1236    },
     1237    0x3901 => {
     1238        Name => 'Data1',
     1239        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::Data1' },
     1240    },
     1241    0x3902 => {
     1242        Name => 'Data2',
     1243        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::Data2' },
     1244    },
     1245    # 0x3903 - larger binary data block
     1246);
     1247
     1248%Image::ExifTool::Panasonic::Data1 = (
     1249    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1250    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     1251    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     1252    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     1253    WRITABLE => 1,
     1254    TAG_PREFIX => 'Leica_Data1',
     1255    FIRST_ENTRY => 0,
     1256    0x0016 => {
     1257        Name => 'LensType',
     1258        Writable => 'int32u',
     1259        Priority => 0,
     1260        SeparateTable => 1,
     1261        ValueConv => '($val >> 2) . " " . ($val & 0x3)',
     1262        ValueConvInv => \&LensTypeConvInv,
     1263        PrintConv => \%leicaLensType,
     1264    },
     1265);
     1266
     1267%Image::ExifTool::Panasonic::Data2 = (
     1268    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1269    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     1270    TAG_PREFIX => 'Leica_Data2',
     1271    FIRST_ENTRY => 0,
     1272);
     1273
     1274# Leica type5 maker notes (ref PH) (X1)
     1275%Image::ExifTool::Panasonic::Leica5 = (
     1276    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     1277    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     1278    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     1279    WRITABLE => 1,
     1280    NOTES => 'This information is written by the X1.',
     1281    # 0x0406 - saturation or sharpness
     1282    0x0407 => { Name => 'OriginalFileName', Writable => 'string' },
     1283    0x0408 => { Name => 'OriginalDirectory',Writable => 'string' },
     1284    # 0x040b - related to white balance
     1285    0x040d => {
     1286        Name => 'ExposureMode',
     1287        Format => 'int8u',
     1288        Count => 4,
     1289        PrintConv => {
     1290            '0 0 0 0' => 'Program AE',
     1291            '1 0 0 0' => 'Aperture-priority AE',
     1292            '2 0 0 0' => 'Shutter speed priority AE', #(guess)
     1293            '3 0 0 0' => 'Manual',
     1294        },
     1295    },
     1296    # 0x0411 - saturation or sharpness
     1297    0x0412 => { Name => 'FilmMode',         Writable => 'string' },
     1298    0x0413 => { Name => 'WB_RGBLevels',     Writable => 'rational64u', Count => 3 },
     1299);
     1300
     1301# Leica type6 maker notes (ref PH) (S2)
     1302%Image::ExifTool::Panasonic::Leica6 = (
     1303    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     1304    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     1305    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     1306    NOTES => 'This information is written by the S2 (as a trailer in JPEG images).',
     1307    0x300 => {
     1308        Name => 'PreviewImage',
     1309        Writable => 'undef',
     1310        Notes => 'S2',
     1311        DataTag => 'PreviewImage',
     1312        RawConv => q{
     1313            return \$val if $val =~ /^Binary/;
     1314            return \$val if $val =~ /^\xff\xd8\xff/;
     1315            $$self{PreviewError} = 1 unless $val eq 'none';
     1316            return undef;
     1317        },
     1318        ValueConvInv => '$val || "none"',
     1319        WriteCheck => 'return $val=~/^(none|\xff\xd8\xff)/s ? undef : "Not a valid image"',
     1320        ChangeBase => '$dirStart + $dataPos - 8',
     1321    },
     1322    0x301 => {
     1323        Name => 'UnknownBlock',
     1324        Notes => 'unknown 320kB block, not copied to JPEG images',
     1325        Flags => [ 'Unknown', 'Binary', 'Drop' ],
     1326    },
     1327    # 0x302 - same value as 4 unknown bytes at the end of JPEG or after the DNG TIFF header
     1328    0x303 => {
     1329        Name => 'LensType',
     1330        Writable => 'string',
     1331    },
     1332    # 0x340 - same as 0x302
    4501333);
    4511334
     
    4701353);
    4711354
    472 # Tags found in Panasonic RAW images
    473 %Image::ExifTool::Panasonic::Raw = (
    474     GROUPS => { 0 => 'EXIF', 1 => 'IFD0', 2 => 'Image'},
    475     WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
    476     CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
    477     WRITE_GROUP => 'IFD0',   # default write group
    478     NOTES => 'These tags are found in IFD0 of Panasonic RAW images.',
    479     0x01 => {
    480         Name => 'PanasonicRawVersion',
    481         Writable => 'undef',
    482     },
    483     0x02 => 'SensorWidth', #5/PH
    484     0x03 => 'SensorHeight', #5/PH
    485     0x04 => 'SensorTopBorder', #10
    486     0x05 => 'SensorLeftBorder', #10
    487     0x06 => 'ImageHeight', #5/PH
    488     0x07 => 'ImageWidth', #5/PH
    489     0x11 => { #10
    490         Name => 'RedBalance',
    491         Writable => 'int16u',
    492         ValueConv => '$val / 256',
    493         ValueConvInv => 'int($val * 256 + 0.5)',
    494         Notes => 'found in Digilux 2 RAW images',
    495     },
    496     0x12 => { #10
    497         Name => 'BlueBalance',
    498         Writable => 'int16u',
    499         ValueConv => '$val / 256',
    500         ValueConvInv => 'int($val * 256 + 0.5)',
    501     },
    502     0x17 => { #5
    503         Name => 'ISO',
    504         Writable => 'int16u',
    505     },
    506     0x24 => { #6
    507         Name => 'WBRedLevel',
    508         Writable => 'int16u',
    509     },
    510     0x25 => { #6
    511         Name => 'WBGreenLevel',
    512         Writable => 'int16u',
    513     },
    514     0x26 => { #6
    515         Name => 'WBBlueLevel',
    516         Writable => 'int16u',
    517     },
    518     0x10f => {
    519         Name => 'Make',
    520         Groups => { 2 => 'Camera' },
    521         Writable => 'string',
    522         DataMember => 'CameraMake',
    523         # save this value as an ExifTool member variable
    524         RawConv => '$self->{CameraMake} = $val',
    525     },
    526     0x110 => {
    527         Name => 'Model',
    528         Description => 'Camera Model Name',
    529         Groups => { 2 => 'Camera' },
    530         Writable => 'string',
    531         DataMember => 'CameraModel',
    532         # save this value as an ExifTool member variable
    533         RawConv => '$self->{CameraModel} = $val',
    534     },
    535     0x111 => {
    536         Name => 'StripOffsets',
    537         Flags => 'IsOffset',
    538         OffsetPair => 0x117,  # point to associated byte counts
    539         ValueConv => 'length($val) > 32 ? \$val : $val',
    540     },
    541     0x112 => {
    542         Name => 'Orientation',
    543         Writable => 'int16u',
    544         PrintConv => \%Image::ExifTool::Exif::orientation,
    545         Priority => 0,  # so IFD1 doesn't take precedence
    546     },
    547     0x116 => {
    548         Name => 'RowsPerStrip',
    549         Priority => 0,
    550     },
    551     0x117 => {
    552         Name => 'StripByteCounts',
    553         OffsetPair => 0x111,   # point to associated offset
    554         ValueConv => 'length($val) > 32 ? \$val : $val',
    555     },
    556     0x8769 => {
    557         Name => 'ExifOffset',
    558         Groups => { 1 => 'ExifIFD' },
    559         Flags => 'SubIFD',
    560         SubDirectory => {
    561             TagTable => 'Image::ExifTool::Exif::Main',
    562             DirName => 'ExifIFD',
    563             Start => '$val',
    564         },
    565     },
    566     0x8825 => {
    567         Name => 'GPSInfo',
    568         Groups => { 1 => 'GPS' },
    569         Flags => 'SubIFD',
    570         SubDirectory => {
    571             DirName => 'GPS',
    572             TagTable => 'Image::ExifTool::GPS::Main',
    573             Start => '$val',
     1355# lens information (ref 10)
     1356%Image::ExifTool::Panasonic::LensInfo = (
     1357    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1358    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     1359    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     1360    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     1361    WRITABLE => 1,
     1362    FORMAT => 'int32u',
     1363    FIRST_ENTRY => 0,
     1364    0 => {
     1365        Name => 'LensType',
     1366        Mask => 0xfffffffc,
     1367        PrintHex => 0,
     1368        SeparateTable => 1,
     1369        ValueConv => '$val >> 2',
     1370        ValueConvInv => '$val << 2',
     1371        PrintConv => \%leicaLensType,
     1372    },
     1373    0.1 => { # lower 2 bits give frame selector position
     1374        Name => 'FrameSelector',
     1375        Mask => 0x03,
     1376        PrintConv => {
     1377            1 => '28/90mm frame lines engaged',
     1378            2 => '24/35mm frame lines engaged',
     1379            3 => '50/75mm frame lines engaged',
    5741380        },
    5751381    },
    5761382);
     1383
     1384# Face detection position information (ref PH)
     1385%Image::ExifTool::Panasonic::FaceDetInfo = (
     1386    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1387    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     1388    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     1389    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     1390    WRITABLE => 1,
     1391    FORMAT => 'int16u',
     1392    FIRST_ENTRY => 0,
     1393    DATAMEMBER => [ 0 ],
     1394    NOTES => 'Face detection position information.',
     1395    0 => {
     1396        Name => 'NumFacePositions',
     1397        Format => 'int16u',
     1398        DataMember => 'NumFacePositions',
     1399        RawConv => '$$self{NumFacePositions} = $val',
     1400        Notes => q{
     1401            number of detected face positions stored in this record.  May be less than
     1402            FacesDetected
     1403        },
     1404    },
     1405    1 => {
     1406        Name => 'Face1Position',
     1407        Format => 'int16u[4]',
     1408        RawConv => '$$self{NumFacePositions} < 1 ? undef : $val',
     1409        Notes => q{
     1410            4 numbers: X/Y coordinates of the face center and width/height of face.
     1411            Coordinates are relative to an image twice the size of the thumbnail, or 320
     1412            pixels wide
     1413        },
     1414    },
     1415    5 => {
     1416        Name => 'Face2Position',
     1417        Format => 'int16u[4]',
     1418        RawConv => '$$self{NumFacePositions} < 2 ? undef : $val',
     1419    },
     1420    9 => {
     1421        Name => 'Face3Position',
     1422        Format => 'int16u[4]',
     1423        RawConv => '$$self{NumFacePositions} < 3 ? undef : $val',
     1424    },
     1425    13 => {
     1426        Name => 'Face4Position',
     1427        Format => 'int16u[4]',
     1428        RawConv => '$$self{NumFacePositions} < 4 ? undef : $val',
     1429    },
     1430    17 => {
     1431        Name => 'Face5Position',
     1432        Format => 'int16u[4]',
     1433        RawConv => '$$self{NumFacePositions} < 5 ? undef : $val',
     1434    },
     1435);
     1436
     1437# Face recognition information from DMC-TZ7 (ref PH)
     1438%Image::ExifTool::Panasonic::FaceRecInfo = (
     1439    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1440    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     1441    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     1442    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     1443    WRITABLE => 1,
     1444    FIRST_ENTRY => 0,
     1445    DATAMEMBER => [ 0 ],
     1446    NOTES => q{
     1447        Tags written by cameras with facial recognition.  These cameras not only
     1448        detect faces in an image, but also recognize specific people based a
     1449        user-supplied set of known faces.
     1450    },
     1451    0 => {
     1452        Name => 'FacesRecognized',
     1453        Format => 'int16u',
     1454        DataMember => 'FacesRecognized',
     1455        RawConv => '$$self{FacesRecognized} = $val',
     1456    },
     1457    4 => {
     1458        Name => 'RecognizedFace1Name',
     1459        Format => 'string[20]',
     1460        RawConv => '$$self{FacesRecognized} < 1 ? undef : $val',
     1461    },
     1462    24 => {
     1463        Name => 'RecognizedFace1Position',
     1464        Format => 'int16u[4]',
     1465        RawConv => '$$self{FacesRecognized} < 1 ? undef : $val',
     1466        Notes => 'coordinates in same format as face detection tags above',
     1467    },
     1468    32 => {
     1469        Name => 'RecognizedFace1Age',
     1470        Format => 'string[20]',
     1471        RawConv => '$$self{FacesRecognized} < 1 ? undef : $val',
     1472    },
     1473    52 => {
     1474        Name => 'RecognizedFace2Name',
     1475        Format => 'string[20]',
     1476        RawConv => '$$self{FacesRecognized} < 2 ? undef : $val',
     1477    },
     1478    72 => {
     1479        Name => 'RecognizedFace2Position',
     1480        Format => 'int16u[4]',
     1481        RawConv => '$$self{FacesRecognized} < 2 ? undef : $val',
     1482    },
     1483    80 => {
     1484        Name => 'RecognizedFace2Age',
     1485        Format => 'string[20]',
     1486        RawConv => '$$self{FacesRecognized} < 2 ? undef : $val',
     1487    },
     1488    100 => {
     1489        Name => 'RecognizedFace3Name',
     1490        Format => 'string[20]',
     1491        RawConv => '$$self{FacesRecognized} < 3 ? undef : $val',
     1492    },
     1493    120 => {
     1494        Name => 'RecognizedFace3Position',
     1495        Format => 'int16u[4]',
     1496        RawConv => '$$self{FacesRecognized} < 3 ? undef : $val',
     1497    },
     1498    128 => {
     1499        Name => 'RecognizedFace3Age',
     1500        Format => 'string[20]',
     1501        RawConv => '$$self{FacesRecognized} < 3 ? undef : $val',
     1502    },
     1503);
     1504
     1505#------------------------------------------------------------------------------
     1506# Inverse conversion for Leica M9 lens codes
     1507# Inputs: 0) value
     1508# Returns: Converted value, or undef on error
     1509sub LensTypeConvInv($)
     1510{
     1511    my $val = shift;
     1512    if ($val =~ /^(\d+) (\d+)$/) {
     1513        return ($1 << 2) + ($2 & 0x03);
     1514    } elsif ($val =~ /^\d+$/) {
     1515        my $bits = $frameSelectorBits{$val};
     1516        return undef unless defined $bits;
     1517        return ($val << 2) | $bits;
     1518    } else {
     1519        return undef;
     1520    }
     1521}
     1522
     1523#------------------------------------------------------------------------------
     1524# Convert Leica Kelvin white balance
     1525# Inputs: 0) value, 1) flag to perform inverse conversion
     1526# Returns: Converted value, or undef on error
     1527sub WhiteBalanceConv($;$$)
     1528{
     1529    my ($val, $inv) = @_;
     1530    if ($inv) {
     1531        return $1 + 0x8000 if $val =~ /(\d+)/;
     1532    } else {
     1533        return ($val - 0x8000) . ' Kelvin' if $val > 0x8000;
     1534    }
     1535    return undef;
     1536}
     1537
     1538#------------------------------------------------------------------------------
     1539# Process MakerNote trailer written by Leica S2
     1540# Inputs: 0) ExifTool object ref, 1) new absolute position of Leica trailer when writing
     1541# Returns: On success: 1 when reading, directory data when writing; othewise undef
     1542# Notes:
     1543# - may be called twice for a file if the first call doesn't succeed
     1544# - must leave RAF position unchanged
     1545# - uses information from LeicaTrailer member:
     1546#      TagInfo = tag info ref for MakerNote SubDirectory
     1547#      Offset/Size = value offset/size from MakerNote IFD
     1548#      TrailStart/TrailLen = actual JPEG trailer position/size (2nd call only)
     1549# - deletes LeicaTrailer member and sets LeicaTrailerPos when successful
     1550sub ProcessLeicaTrailer($;$)
     1551{
     1552    my ($exifTool, $newPos) = @_;
     1553    my $trail = $$exifTool{LeicaTrailer};
     1554    my $raf = $$exifTool{RAF};
     1555    my $trailPos = $$trail{TrailPos};
     1556    my $pos = $trailPos || $$trail{Offset};
     1557    my $len = $$trail{TrailLen} || $$trail{Size};
     1558    my ($buff, $result, %tagPtr);
     1559
     1560    delete $$exifTool{LeicaTrailer} if $trailPos;   # done after this
     1561    unless ($len > 0) {
     1562        $exifTool->Warn('Missing Leica MakerNote trailer', 1) if $trailPos;
     1563        undef $$exifTool{LeicaTrailer};
     1564        return undef;
     1565    }
     1566    my $oldPos = $raf->Tell();
     1567    my $ok = ($raf->Seek($pos, 0) and $raf->Read($buff, $len) == $len);
     1568    $raf->Seek($oldPos, 0);
     1569    unless ($ok) {
     1570        $exifTool->Warn('Error reading Leica MakerNote trailer', 1) if $trailPos;
     1571        return undef;
     1572    }
     1573    # look for Leica MakerNote header (should be at start of
     1574    # trailer, but allow up to 256 bytes of garbage just in case)
     1575    if ($buff !~ /^(.{0,256})LEICA\0..../sg) {
     1576        my $what = $trailPos ? 'trailer' : 'offset';
     1577        $exifTool->Warn("Invalid Leica MakerNote $what", 1);
     1578        return undef;
     1579    }
     1580    my $junk = $1;
     1581    my $start = pos($buff) - 10;
     1582    if ($start and not $trailPos) {
     1583        $exifTool->Warn('Invalid Leica MakerNote offset', 1);
     1584        return undef;
     1585    }
     1586#
     1587# all checks passed -- go ahead and process the trailer now
     1588#
     1589    my $hdrLen = 8;
     1590    my $dirStart = $start + $hdrLen;
     1591    my $tagInfo = $$trail{TagInfo};
     1592    if ($$exifTool{HTML_DUMP}) {
     1593        my $name = $$tagInfo{Name};
     1594        $exifTool->HDump($pos+$start, $len-$start, "$name value", 'Leica MakerNote trailer', 4);
     1595        $exifTool->HDump($pos+$start, $hdrLen, "MakerNotes header", $name);
     1596    } elsif ($exifTool->Options('Verbose')) {
     1597        my $where = sprintf('at offset 0x%x', $pos);
     1598        $exifTool->VPrint(0, "Leica MakerNote trailer ($len bytes $where):\n");
     1599    }
     1600    # delete LeicaTrailer member so we don't try to process it again
     1601    delete $$exifTool{LeicaTrailer};
     1602    $$exifTool{LeicaTrailerPos} = $pos + $start;    # return actual start position of Leica trailer
     1603
     1604    my $oldOrder = GetByteOrder();
     1605    my $num = Get16u(\$buff, $dirStart);            # get entry count
     1606    ToggleByteOrder() if ($num>>8) > ($num&0xff);   # set byte order
     1607
     1608    # use specialized algorithm to automatically fix offsets
     1609    my $valStart = $dirStart + 2 + 12 * $num + 4;
     1610    my $fix = 0;
     1611    if ($valStart < $len) {
     1612        my $valBlock = Image::ExifTool::MakerNotes::GetValueBlocks(\$buff, $dirStart, \%tagPtr);
     1613        # find the minimum offset (excluding the PreviewImage tag 0x300)
     1614        my $minPtr;
     1615        foreach (keys %tagPtr) {
     1616            my $ptr = $tagPtr{$_};
     1617            next if $_ == 0x300 or not $ptr;
     1618            $minPtr = $ptr if not defined $minPtr or $minPtr > $ptr;
     1619        }
     1620        if ($minPtr) {
     1621            my $diff = $minPtr - ($valStart + $pos);
     1622            # scan value data for the first non-zero byte
     1623            pos($buff) = $valStart;
     1624            if ($buff =~ /[^\0]/g) {
     1625                my $n = pos($buff) - 1 - $valStart; # number of zero bytes
     1626                # S2 writes 282 bytes of zeros, exiftool writes none
     1627                my $expect = $n >= 282 ? 282 : 0;
     1628                my $fixBase = $exifTool->Options('FixBase');
     1629                if ($diff != $expect or defined $fixBase) {
     1630                    $fix = $expect - $diff;
     1631                    if (defined $fixBase) {
     1632                        $fix = $fixBase if $fixBase ne '';
     1633                        $exifTool->Warn("Adjusted MakerNotes base by $fix",1);
     1634                    } else {
     1635                        $exifTool->Warn("Possibly incorrect maker notes offsets (fixed by $fix)",1);
     1636                    }
     1637                }
     1638            }
     1639        }
     1640    }
     1641    # generate dirInfo for Leica MakerNote directory
     1642    my %dirInfo = (
     1643        Name       => $$tagInfo{Name},
     1644        Base       => $fix,
     1645        DataPt     => \$buff,
     1646        DataPos    => $pos - $fix,
     1647        DataLen    => $len,
     1648        DirStart   => $dirStart,
     1649        DirLen     => $len - $dirStart,
     1650        DirName    => 'MakerNotes',
     1651        Parent     => 'ExifIFD',
     1652        TagInfo    => $tagInfo,
     1653    );
     1654    my $tagTablePtr = GetTagTable($$tagInfo{SubDirectory}{TagTable});
     1655    if ($newPos) { # are we writing?
     1656        # set position of new MakerNote IFD (+ 8 for Leica MakerNote header)
     1657        $dirInfo{NewDataPos} = $newPos + $start + 8;
     1658        $result = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
     1659        # write preview image last if necessary and fix up the preview offsets
     1660        my $previewInfo = $$exifTool{PREVIEW_INFO};
     1661        delete $$exifTool{PREVIEW_INFO};
     1662        if ($result) {
     1663            if ($previewInfo) {
     1664                my $fixup = $previewInfo->{Fixup};
     1665                # set preview offset (relative to start of makernotes, + 8 for makernote header)
     1666                $fixup->SetMarkerPointers(\$result, 'PreviewImage', length($result) + 8);
     1667                $result .= $$previewInfo{Data};
     1668            }
     1669            return $junk . substr($buff, $start, $hdrLen) . $result;
     1670        }
     1671    } else {
     1672        # extract information
     1673        $result = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
     1674        # also extract as a block if necessary
     1675        if ($exifTool->Options('MakerNotes') or
     1676            $exifTool->{REQ_TAG_LOOKUP}{lc($$tagInfo{Name})})
     1677        {
     1678            # makernote header must be included in RebuildMakerNotes call
     1679            $dirInfo{DirStart} -= 8;
     1680            $dirInfo{DirLen} += 8;
     1681            $exifTool->{MAKER_NOTE_BYTE_ORDER} = GetByteOrder();
     1682            # rebuild maker notes (creates $exifTool->{MAKER_NOTE_FIXUP})
     1683            my $val = Image::ExifTool::Exif::RebuildMakerNotes($exifTool, $tagTablePtr, \%dirInfo);
     1684            unless (defined $val) {
     1685                $exifTool->Warn('Error rebuilding maker notes (may be corrupt)');
     1686                $val = $buff,
     1687            }
     1688            my $key = $exifTool->FoundTag($tagInfo, $val);
     1689            $exifTool->SetGroup($key, 'ExifIFD');
     1690        }
     1691    }
     1692    SetByteOrder($oldOrder);
     1693    return $result;
     1694}
    5771695
    57816961;  # end
     
    5951713=head1 AUTHOR
    5961714
    597 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1715Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    5981716
    5991717This library is free software; you can redistribute it and/or modify it
     
    6081726=item L<http://johnst.org/sw/exiftags/>
    6091727
    610 =item L<http://www.cybercom.net/~dcoffin/dcraw/>
    611 
    6121728=item L<http://homepage3.nifty.com/kamisaka/makernote/makernote_pana.htm>
    6131729
     1730=item L<http://bretteville.com/pdfs/M8Metadata_v2.pdf>
     1731
     1732=item L<http://www.digital-leica.com/lens_codes/index.html>
     1733
     1734=item (...plus lots of testing with store demos and my wife's DMC-FS7!)
     1735
    6141736=back
    6151737
     
    6171739
    6181740Thanks to Tels for the information he provided on decoding some tags, and to
    619 Marcel Coenen and Jens Duttke for their contributions.
     1741Marcel Coenen, Jens Duttke and Michael Byczkowski for their contributions.
    6201742
    6211743=head1 SEE ALSO
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Pentax.pm

    r16842 r24107  
    88#               02/16/2004 - W. Smith Updated (see ref 3)
    99#               11/10/2004 - P. Harvey Added support for Asahi cameras
    10 #               01/10/2005 - P. Harvey Added NikonLens with values from ref 4
     10#               01/10/2005 - P. Harvey Added LensType with values from ref 4
    1111#               03/30/2005 - P. Harvey Added new tags from ref 5
    1212#               10/04/2005 - P. Harvey Added MOV tags
     13#               10/22/2007 - P. Harvey Got my new K10D! (more new tags to decode)
     14#               11/03/2010 - P. Harvey Got my new K-5! (a gold mine of new tags to discover!)
    1315#
    1416# References:   1) Image::MakerNotes::Pentax
     
    2426#              11) http://forums.dpreview.com/forums/read.asp?forum=1036&message=17465929
    2527#              12) Derby Chang private communication
    26 #              13) http://homepage3.nifty.com/kamisaka/makernote/makernote_pentax.htm
     28#              13) http://homepage3.nifty.com/kamisaka/makernote/makernote_pentax.htm (2007/02/28)
    2729#              14) Ger Vermeulen private communication (Optio S6)
    2830#              15) Barney Garrett private communication (Samsung GX-1S)
     
    3032#              17) Cvetan Ivanov private communication (K100D)
    3133#              18) http://www.gvsoft.homedns.org/exif/makernote-pentax-type3.html
    32 #              19) Jens Duttke private communication
     34#              19) Dave Nicholson private communication (K10D)
     35#              20) Bogdan and yeryry (http://www.cpanforum.com/posts/8037)
     36#              21) Peter (*istD, http://www.cpanforum.com/posts/8078)
     37#              22) Bozi (K10D, http://www.cpanforum.com/posts/8480)
     38#              23) Akos Szalkai (https://rt.cpan.org/Ticket/Display.html?id=43743)
     39#              24) Albert Bogner private communication
     40#              25) Niels Kristian Bech Jensen private communication
     41#              JD) Jens Duttke private communication
    3342#
    3443# Notes:        See POD documentation at the bottom of this file
     
    4251use Image::ExifTool::HP;
    4352
    44 $VERSION = '1.61';
     53$VERSION = '2.30';
    4554
    4655sub CryptShutterCount($$);
     56sub PrintFilter($$$);
    4757
    4858# pentax lens type codes (ref 4)
    49 my %pentaxLensType = (
     59# The first number gives the lens series, and the 2nd gives the model number
     60# Series numbers: K=1; A=2; F=3; FAJ=4; DFA=4,7; FA=3,4,5,6; FA*=5,6;
     61#                 DA=3,4,7; DA*=7,8; FA645=11; DFA645=13
     62my %pentaxLensTypes = (
     63    Notes => q{
     64        The first number gives the series of the lens, and the second identifies the
     65        lens model.  Note that newer series numbers may not always be properly
     66        identified by cameras running older firmware versions.  Decimal values
     67        differentiate lenses which would otherwise have the same LensType, and are
     68        used by the Composite LensID tag when attempting to identify the specific
     69        lens model.
     70    },
    5071    '0 0' => 'M-42 or No Lens', #17
    51     '1 0' => 'K,M Lens',
     72    '1 0' => 'K or M Lens',
    5273    '2 0' => 'A Series Lens', #7 (from smc PENTAX-A 400mm F5.6)
    53     '3 0' => 'SIGMA',
     74    '3 0' => 'Sigma', # (includes 'Sigma 30mm F1.4 EX DC' - PH)
    5475    '3 17' => 'smc PENTAX-FA SOFT 85mm F2.8',
    5576    '3 18' => 'smc PENTAX-F 1.7X AF ADAPTER',
     
    5879    '3 21' => 'smc PENTAX-F 80-200mm F4.7-5.6',
    5980    '3 22' => 'smc PENTAX-F FISH-EYE 17-28mm F3.5-4.5',
    60     '3 23' => 'smc PENTAX-F 100-300mm F4.5-5.6',
     81    '3 23' => 'smc PENTAX-F 100-300mm F4.5-5.6 or Sigma Lens',
     82    '3 23.1' => 'Sigma AF 28-300mm F3.5-5.6 DL IF', #JD
     83    '3 23.2' => 'Sigma AF 28-300mm F3.5-6.3 DG IF Macro', #JD
    6184    '3 24' => 'smc PENTAX-F 35-135mm F3.5-4.5',
    62     '3 25' => 'smc PENTAX-F 35-105mm F4-5.6 or SIGMA or Tokina',
    63     # or '3 25' => SIGMA AF 28-300 F3.5-5.6 DL IF', #11
    64     # or '3 25' => 'Tokina 80-200mm F2.8 ATX-Pro', #12
    65     # or '3 25' => 'SIGMA 55-200mm F4-5.6 DC', #19
     85    '3 25' => 'smc PENTAX-F 35-105mm F4-5.6 or Sigma or Tokina Lens',
     86    '3 25.1' => 'Sigma AF 28-300mm F3.5-5.6 DL IF', #11
     87    '3 25.2' => 'Sigma 55-200mm F4-5.6 DC', #JD
     88    '3 25.3' => 'Sigma AF 28-300mm F3.5-5.6 DL IF', #JD
     89    '3 25.4' => 'Sigma AF 28-300mm F3.5-6.3 DG IF Macro', #JD
     90    '3 25.5' => 'Tokina 80-200mm F2.8 ATX-Pro', #12
    6691    '3 26' => 'smc PENTAX-F* 250-600mm F5.6 ED[IF]',
    67     '3 27' => 'smc PENTAX-F 28-80mm F3.5-4.5',
    68     '3 28' => 'smc PENTAX-F 35-70mm F3.5-4.5',
    69     # or '3 28' => 'Tokina 19-35mm F3.5-4.5 AF', #12
    70     '3 29' => 'PENTAX-F 28-80mm F3.5-4.5 or SIGMA AF 18-125mm F3.5-5.6 DC', #11 (sigma)
     92    '3 27' => 'smc PENTAX-F 28-80mm F3.5-4.5 or Tokina Lens',
     93    '3 27.1' => 'Tokina AT-X Pro AF 28-70mm F2.6-2.8', #JD
     94    '3 28' => 'smc PENTAX-F 35-70mm F3.5-4.5 or Tokina Lens',
     95    '3 28.1' => 'Tokina 19-35mm F3.5-4.5 AF', #12
     96    '3 29' => 'PENTAX-F 28-80mm F3.5-4.5 or Sigma or Tokina Lens',
     97    '3 29.1' => 'Sigma AF 18-125mm F3.5-5.6 DC', #11
     98    '3 29.2' => 'Tokina AT-X PRO 28-70mm F2.6-2.8', #22
    7199    '3 30' => 'PENTAX-F 70-200mm F4-5.6',
    72     '3 31' => 'smc PENTAX-F 70-210mm F4-5.6',
    73     # or '3 31' => 'Tokina AF 730 75-300mm F4.5-5.6',
     100    '3 31' => 'smc PENTAX-F 70-210mm F4-5.6 or Tokina or Takumar Lens',
     101    '3 31.1' => 'Tokina AF 730 75-300mm F4.5-5.6',
     102    '3 31.2' => 'Takumar-F 70-210mm F4-5.6', #JD
    74103    '3 32' => 'smc PENTAX-F 50mm F1.4',
    75104    '3 33' => 'smc PENTAX-F 50mm F1.7',
    76105    '3 34' => 'smc PENTAX-F 135mm F2.8 [IF]',
    77106    '3 35' => 'smc PENTAX-F 28mm F2.8',
    78     '3 36' => 'SIGMA 20mm F1.8 EX DG ASPHERICAL RF',
     107    '3 36' => 'Sigma 20mm F1.8 EX DG Aspherical RF',
    79108    '3 38' => 'smc PENTAX-F* 300mm F4.5 ED[IF]',
    80109    '3 39' => 'smc PENTAX-F* 600mm F4 ED[IF]',
    81     '3 40' => 'smc PENTAX-F MACRO 100mm F2.8',
    82     '3 41' => 'smc PENTAX-F MACRO 50mm F2.8 or Sigma 50mm F2,8 MACRO', #4,16
    83     #'3 44' => 'SIGMA 17-70mm F2.8-4.5 DC MACRO', (Bart Hickman)
    84     #'3 44' => 'SIGMA 18-50mm F3.5-5.6 DC, 12-24mm F4.5 EX DG or Tamron 35-90mm F4 AF', #4,12,12
    85     #'3 44' => 'SIGMA AF 10-20mm F4-5.6 EX DC', #19
    86     '3 44' => 'Tamron 35-90mm F4 AF or various SIGMA models', #4,12,Bart,19
    87     '3 46' => 'SIGMA APO 70-200mm F2.8 EX',
     110    '3 40' => 'smc PENTAX-F Macro 100mm F2.8',
     111    '3 41' => 'smc PENTAX-F Macro 50mm F2.8 or Sigma Lens', #4
     112    '3 41.1' => 'Sigma 50mm F2.8 Macro', #16
     113    '3 44' => 'Sigma or Tamron Lens (3 44)',
     114    '3 44.1' => 'Sigma AF 10-20mm F4-5.6 EX DC', #JD
     115    '3 44.2' => 'Sigma 12-24mm F4.5 EX DG', #12
     116    '3 44.3' => 'Sigma 17-70mm F2.8-4.5 DC Macro', #(Bart Hickman)
     117    '3 44.4' => 'Sigma 18-50mm F3.5-5.6 DC', #4
     118    '3 44.5' => 'Tamron 35-90mm F4 AF', #12
     119    '3 46' => 'Sigma Lens (3 46)',
     120    '3 46.1' => 'Sigma APO 70-200mm F2.8 EX',
     121    '3 46.2' => 'Sigma EX APO 100-300mm F4 IF', #JD
    88122    '3 50' => 'smc PENTAX-FA 28-70mm F4 AL',
    89     '3 51' => 'SIGMA 28mm F1.8 EX DG ASPHERICAL MACRO',
    90     '3 52' => 'smc PENTAX-FA 28-200mm F3.8-5.6 AL[IF]',
    91     # or '3 52' => 'Tamron AF LD 28-200mm F3.8-5.6 (IF) Aspherical (171D), #19
     123    '3 51' => 'Sigma 28mm F1.8 EX DG Aspherical Macro',
     124    '3 52' => 'smc PENTAX-FA 28-200mm F3.8-5.6 AL[IF] or Tamron Lens',
     125    '3 52.1' => 'Tamron AF LD 28-200mm F3.8-5.6 [IF] Aspherical (171D)', #JD
    92126    '3 53' => 'smc PENTAX-FA 28-80mm F3.5-5.6 AL',
    93127    '3 247' => 'smc PENTAX-DA FISH-EYE 10-17mm F3.5-4.5 ED[IF]',
     
    98132    '3 253' => 'smc PENTAX-DA 14mm F2.8 ED[IF]',
    99133    '3 254' => 'smc PENTAX-DA 16-45mm F4 ED AL',
    100     '3 255' => 'SIGMA',
    101     # '3 255' => 'SIGMA 18-200mm F3.5-6.3 DC', #8
    102     # '3 255' => 'SIGMA DL-II 35-80mm F4-5.6', #12
    103     # '3 255' => 'SIGMA DL Zoom 75-300mm F4-5.6', #12
    104     # '3 255' => 'SIGMA DF EX Aspherical 28-70mm F2.8', #12
    105     # '3 255' => 'SIGMA AF Tele 400mm F5.6 Multi-coated', #19
     134    '3 255' => 'Sigma Lens (3 255)',
     135    '3 255.1' => 'Sigma 18-200mm F3.5-6.3 DC', #8
     136    '3 255.2' => 'Sigma DL-II 35-80mm F4-5.6', #12
     137    '3 255.3' => 'Sigma DL Zoom 75-300mm F4-5.6', #12
     138    '3 255.4' => 'Sigma DF EX Aspherical 28-70mm F2.8', #12
     139    '3 255.5' => 'Sigma AF Tele 400mm F5.6 Multi-coated', #JD
     140    '3 255.6' => 'Sigma 24-60mm F2.8 EX DG', #PH
     141    '3 255.7' => 'Sigma 70-300mm F4-5.6 Macro', #JD
     142    '3 255.8' => 'Sigma 55-200mm F4-5.6 DC', #JD
     143    '3 255.9' => 'Sigma 18-50mm F2.8 EX DC', #JD
    106144    '4 1' => 'smc PENTAX-FA SOFT 28mm F2.8',
    107145    '4 2' => 'smc PENTAX-FA 80-320mm F4.5-5.6',
     
    110148    '4 12' => 'smc PENTAX-FA 50mm F1.4', #17
    111149    '4 15' => 'smc PENTAX-FA 28-105mm F4-5.6 [IF]',
    112     '4 16' => 'TAMRON AF 80-210mm F4-5.6 (178D)', #13
    113     '4 19' => 'TAMRON SP AF 90mm F2.8 (172E)',
     150    '4 16' => 'Tamron AF 80-210mm F4-5.6 (178D)', #13
     151    '4 19' => 'Tamron SP AF 90mm F2.8 (172E)',
    114152    '4 20' => 'smc PENTAX-FA 28-80mm F3.5-5.6',
    115     '4 22' => 'TOKINA 28-80mm F3.5-5.6', #13
     153    '4 21' => 'Cosina AF 100-300mm F5.6-6.7', #20
     154    '4 22' => 'Tokina 28-80mm F3.5-5.6', #13
    116155    '4 23' => 'smc PENTAX-FA 20-35mm F4 AL',
    117156    '4 24' => 'smc PENTAX-FA 77mm F1.8 Limited',
    118     '4 25' => 'TAMRON SP AF 14mm F2.8', #13
    119     '4 26' => 'smc PENTAX-FA MACRO 100mm F3.5',
    120     '4 27' => 'TAMRON AF28-300mm F/3.5-6.3 LD Aspherical[IF] MACRO (285D)',
     157    '4 25' => 'Tamron SP AF 14mm F2.8', #13
     158    '4 26' => 'smc PENTAX-FA Macro 100mm F3.5 or Cosina Lens',
     159    '4 26.1' => 'Cosina 100mm F3.5 Macro', #JD
     160    '4 27' => 'Tamron AF 28-300mm F3.5-6.3 LD Aspherical[IF] Macro (185D/285D)',
    121161    '4 28' => 'smc PENTAX-FA 35mm F2 AL',
    122     '4 29' => 'TAMRON AF 28-200mm F/3.8-5.6 LD Super II MACRO (371D)', #19
     162    '4 29' => 'Tamron AF 28-200mm F3.8-5.6 LD Super II Macro (371D)', #JD
    123163    '4 34' => 'smc PENTAX-FA 24-90mm F3.5-4.5 AL[IF]',
    124164    '4 35' => 'smc PENTAX-FA 100-300mm F4.7-5.8',
    125     '4 36' => 'TAMRON AF70-300mm F/4-5.6 LD MACRO', # both 572D and A17 (Di) - ref 19
    126     '4 37' => 'TAMRON SP AF 24-135mm F3.5-5.6 AD AL (190D)', #13
     165    '4 36' => 'Tamron AF70-300mm F4-5.6 LD Macro', # both 572D and A17 (Di) - ref JD
     166    '4 37' => 'Tamron SP AF 24-135mm F3.5-5.6 AD AL (190D)', #13
    127167    '4 38' => 'smc PENTAX-FA 28-105mm F3.2-4.5 AL[IF]',
    128     '4 39' => 'smc PENTAX-FA 31mm F1.8AL Limited',
    129     '4 41' => 'TAMRON AF 28-200mm Super Zoom F3.8-5.6 Aspherical XR [IF] MACRO (A03)',
     168    '4 39' => 'smc PENTAX-FA 31mm F1.8 AL Limited',
     169    '4 41' => 'Tamron AF 28-200mm Super Zoom F3.8-5.6 Aspherical XR [IF] Macro (A03)',
    130170    '4 43' => 'smc PENTAX-FA 28-90mm F3.5-5.6',
    131171    '4 44' => 'smc PENTAX-FA J 75-300mm F4.5-5.8 AL',
    132     '4 45' => 'TAMRON 28-300mm F3.5-6.3 Ultra zoom XR',
     172    '4 45' => 'Tamron Lens (4 45)',
     173    '4 45.1' => 'Tamron 28-300mm F3.5-6.3 Ultra zoom XR',
     174    '4 45.2' => 'Tamron AF 28-300mm F3.5-6.3 XR Di LD Aspherical [IF] Macro', #JD
    133175    '4 46' => 'smc PENTAX-FA J 28-80mm F3.5-5.6 AL',
    134176    '4 47' => 'smc PENTAX-FA J 18-35mm F4-5.6 AL',
    135     '4 49' => 'TAMRON SP AF 28-75mm F2.8 XR Di (A09)',
    136     '4 51' => 'smc PENTAX-D FA 50mm F2.8 MACRO',
    137     '4 52' => 'smc PENTAX-D FA 100mm F2.8 MACRO',
     177    '4 49' => 'Tamron SP AF 28-75mm F2.8 XR Di (A09)',
     178    '4 51' => 'smc PENTAX-D FA 50mm F2.8 Macro',
     179    '4 52' => 'smc PENTAX-D FA 100mm F2.8 Macro',
     180    '4 75' => 'Tamron SP AF 70-200mm F2.8 Di LD [IF] Macro (A001)', #JD
     181    '4 229' => 'smc PENTAX-DA 18-55mm F3.5-5.6 AL II', #JD
     182    '4 230' => 'Tamron SP AF 17-50mm F2.8 XR Di II', #20
     183    '4 231' => 'smc PENTAX-DA 18-250mm F3.5-6.3 ED AL [IF]', #21
     184    '4 237' => 'Samsung/Schneider D-XENOGON 10-17mm F3.5-4.5', #JD
     185    '4 239' => 'Samsung D-XENON 12-24mm F4 ED AL [IF]', #23
     186    '4 243' => 'smc PENTAX-DA 70mm F2.4 Limited', #JD
    138187    '4 244' => 'smc PENTAX-DA 21mm F3.2 AL Limited', #9
    139     '4 245' => 'Schneider D-XENON 50-200mm', #15
    140     '4 246' => 'Schneider D-XENON 18-55mm', #15
    141     '4 247' => 'smc PENTAX-DA 10-17mm F3.5-4.5 ED [IF] Fisheye zoom', #10
     188    '4 245' => 'Schneider D-XENON 50-200mm F4-5.6', #15
     189    '4 246' => 'Schneider D-XENON 18-55mm F3.5-5.6', #15
     190    '4 247' => 'smc PENTAX-DA FISH-EYE 10-17mm F3.5-4.5 ED[IF]', #10
    142191    '4 248' => 'smc PENTAX-DA 12-24mm F4 ED AL [IF]', #10
    143     '4 249' => 'TAMRON XR DiII 18-200mm F3.5-6.3 (A14)',
     192    '4 249' => 'Tamron XR DiII 18-200mm F3.5-6.3 (A14)',
    144193    '4 250' => 'smc PENTAX-DA 50-200mm F4-5.6 ED', #8
    145194    '4 251' => 'smc PENTAX-DA 40mm F2.8 Limited', #9
     
    154203    '5 6' => 'smc PENTAX-FA* 300mm F4.5 ED[IF]',
    155204    '5 7' => 'smc PENTAX-FA 135mm F2.8 [IF]',
    156     '5 8' => 'smc PENTAX-FA MACRO 50mm F2.8',
    157     '5 9' => 'smc PENTAX-FA MACRO 100mm F2.8',
     205    '5 8' => 'smc PENTAX-FA Macro 50mm F2.8',
     206    '5 9' => 'smc PENTAX-FA Macro 100mm F2.8',
    158207    '5 10' => 'smc PENTAX-FA* 85mm F1.4 [IF]',
    159208    '5 11' => 'smc PENTAX-FA* 200mm F2.8 ED[IF]',
     
    163212    '5 15' => 'smc PENTAX-FA 28-105mm F4-5.6',
    164213    '5 16' => 'smc PENTAX-FA 100-300mm F4.5-5.6',
    165     '6 1' => 'smc PENTAX-FA* 85mm F1.4[IF]',
     214    '5 98' => 'smc PENTAX-FA 100-300mm F4.5-5.6', #JD (pre-production? - PH)
     215    '6 1' => 'smc PENTAX-FA* 85mm F1.4 [IF]',
    166216    '6 2' => 'smc PENTAX-FA* 200mm F2.8 ED[IF]',
    167217    '6 3' => 'smc PENTAX-FA* 300mm F2.8 ED[IF]',
     
    174224    '6 10' => 'smc PENTAX-FA* 400mm F5.6 ED[IF]',
    175225    '6 13' => 'smc PENTAX-FA* 400mm F5.6 ED[IF]',
    176     '6 14' => 'smc PENTAX-FA* MACRO 200mm F4 ED[IF]',
     226    '6 14' => 'smc PENTAX-FA* Macro 200mm F4 ED[IF]',
    177227    '7 0' => 'smc PENTAX-DA 21mm F3.2 AL Limited', #13
    178     '7 238' => 'TAMRON AF 18-250mm F3.5-6.3 Di II LD Aspherical [IF] MACRO', #19
    179     '7 243' => 'smc PENTAX-DA 70mm F2.4 Limited', #PH (K10D)
     228    '7 58' => 'smc PENTAX-D FA Macro 100mm F2.8 WR', #PH - this bit of information cost me $600 ;)
     229    '7 75' => 'Tamron SP AF 70-200mm F2.8 Di LD [IF] Macro (A001)', #(Anton Bondar)
     230    '7 214' => 'smc PENTAX-DA 35mm F2.4 AL', #PH
     231    '7 216' => 'smc PENTAX-DA L 55-300mm F4-5.8 ED', #PH
     232    '7 217' => 'smc PENTAX-DA 50-200mm F4-5.6 ED WR', #JD
     233    '7 218' => 'smc PENTAX-DA 18-55mm F3.5-5.6 AL WR', #JD
     234    '7 220' => 'Tamron SP AF 10-24mm F3.5-4.5 Di II LD Aspherical [IF]', #24
     235    '7 221' => 'smc PENTAX-DA L 50-200mm F4-5.6 ED', #Ar't
     236    '7 222' => 'smc PENTAX-DA L 18-55mm F3.5-5.6', #PH (tag 0x003f -- was '7 229' in LensInfo of one test image)
     237    '7 223' => 'Samsung D-XENON 18-55mm F3.5-5.6 II', #PH
     238    '7 224' => 'smc PENTAX-DA 15mm F4 ED AL Limited', #JD
     239    '7 225' => 'Samsung D-XENON 18-250mm F3.5-6.3', #8/PH
     240    '7 226' => 'smc PENTAX-DA* 55mm F1.4 SDM (SDM unused)', #PH (NC)
     241    '7 227' => 'smc PENTAX DA* 60-250mm F4 [IF] SDM (SDM unused)', #PH (NC)
     242    '7 229' => 'smc PENTAX-DA 18-55mm F3.5-5.6 AL II', #JD
     243    '7 230' => 'Tamron AF 17-50mm F2.8 XR Di-II LD (Model A16)', #JD
     244    '7 231' => 'smc PENTAX-DA 18-250mm F3.5-6.3 ED AL [IF]', #JD
     245    '7 233' => 'smc PENTAX-DA 35mm F2.8 Macro Limited', #JD
     246    '7 234' => 'smc PENTAX-DA* 300mm F4 ED [IF] SDM (SDM unused)', #19 (NC)
     247    '7 235' => 'smc PENTAX-DA* 200mm F2.8 ED [IF] SDM (SDM unused)', #PH (NC)
     248    '7 236' => 'smc PENTAX-DA 55-300mm F4-5.8 ED', #JD
     249    '7 238' => 'Tamron AF 18-250mm F3.5-6.3 Di II LD Aspherical [IF] Macro', #JD
     250    '7 241' => 'smc PENTAX-DA* 50-135mm F2.8 ED [IF] SDM (SDM unused)', #PH
     251    '7 242' => 'smc PENTAX-DA* 16-50mm F2.8 ED AL [IF] SDM (SDM unused)', #19
     252    '7 243' => 'smc PENTAX-DA 70mm F2.4 Limited', #PH
    180253    '7 244' => 'smc PENTAX-DA 21mm F3.2 AL Limited', #16
    181     '8 241' => 'smc PENTAX-DA* 50-135mm F2.8 ED [IF] SDM', #19
    182     '8 242' => 'smc PENTAX-DA* 16-50mm F2.8 ED AL [IF] SDM', #19
     254    '8 14' => 'Sigma 17-70mm F2.8-4.0 DC Macro OS HSM', #(Hubert Meier)
     255    '8 18' => 'Sigma 8-16mm F4.5-5.6 DC HSM', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2998.0.html
     256    '8 215' => 'smc PENTAX-DA 18-135mm F3.5-5.6 ED AL [IF] DC WR', #PH
     257    '8 226' => 'smc PENTAX-DA* 55mm F1.4 SDM', #JD
     258    '8 227' => 'smc PENTAX DA* 60-250mm F4 [IF] SDM', #JD
     259    '8 232' => 'smc PENTAX-DA 17-70mm F4 AL [IF] SDM', #JD
     260    '8 234' => 'smc PENTAX-DA* 300mm F4 ED [IF] SDM', #19
     261    '8 235' => 'smc PENTAX-DA* 200mm F2.8 ED [IF] SDM', #JD
     262    '8 241' => 'smc PENTAX-DA* 50-135mm F2.8 ED [IF] SDM', #JD
     263    '8 242' => 'smc PENTAX-DA* 16-50mm F2.8 ED AL [IF] SDM', #JD
     264    '8 255' => 'Sigma Lens (8 255)',
     265    '8 255.1' => 'Sigma 70-200mm F2.8 EX DG Macro HSM II', #JD
     266    '8 255.2' => 'Sigma APO 150-500mm F5-6.3 DG OS HSM', #JD
     267    '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
     268    '11 4' => 'smc PENTAX-FA 645 45-85mm F4.5', #PH
     269    '11 8' => 'smc PENTAX-FA 645 80-160mm F4.5', #PH
     270    '11 11' => 'smc PENTAX-FA 645 35mm F3.5 AL [IF]', #PH
     271    '11 17' => 'smc PENTAX-FA 645 150-300mm F5.6 ED [IF]', #PH
     272    '13 18' => 'smc PENTAX-D FA 645 55mm F2.8 AL [IF] SDM AW', #PH
    183273);
    184274
    185 # Pentax model ID codes (PH)
     275# Pentax model ID codes - PH
    186276my %pentaxModelID = (
    187277    0x0000d => 'Optio 330/430',
     
    190280    0x12962 => 'Optio 450/550',
    191281    0x1296c => 'Optio S',
     282    0x12971 => 'Optio S V1.01',
    192283    0x12994 => '*ist D',
    193284    0x129b2 => 'Optio 33L',
     
    225316    0x12b9c => 'K100D',
    226317    0x12b9d => 'K110D',
    227     0x12ba2 => 'K100D Super', #19
     318    0x12ba2 => 'K100D Super', #JD
    228319    0x12bb0 => 'Optio T10/T20',
    229320    0x12be2 => 'Optio W10',
     
    238329    0x12c8c => 'Optio M30',
    239330    0x12c78 => 'Optio E30',
     331    0x12c7d => 'Optio E35',
    240332    0x12c82 => 'Optio T30',
     333    0x12c91 => 'Optio L30',
    241334    0x12c96 => 'Optio W30',
    242335    0x12ca0 => 'Optio A30',
    243336    0x12cb4 => 'Optio E40',
    244337    0x12cbe => 'Optio M40',
     338    0x12cc3 => 'Optio L40',
     339    0x12cc5 => 'Optio L36',
    245340    0x12cc8 => 'Optio Z10',
     341    0x12cd2 => 'K20D',
     342    0x12cd4 => 'Samsung GX20', #8
    246343    0x12cdc => 'Optio S10',
    247344    0x12ce6 => 'Optio A40',
    248345    0x12cf0 => 'Optio V10',
     346    0x12cfa => 'K200D',
     347    0x12d04 => 'Optio S12',
     348    0x12d0e => 'Optio E50',
     349    0x12d18 => 'Optio M50',
     350    0x12d22 => 'Optio L50',
     351    0x12d2c => 'Optio V20',
     352    0x12d40 => 'Optio W60',
     353    0x12d4a => 'Optio M60',
     354    0x12d68 => 'Optio E60/M90',
     355    0x12d72 => 'K2000',
     356    0x12d73 => 'K-m',
     357    0x12d86 => 'Optio P70',
     358    0x12d90 => 'Optio L70',
     359    0x12d9a => 'Optio E70',
     360    0x12dae => 'X70',
     361    0x12db8 => 'K-7',
     362    0x12dcc => 'Optio W80',
     363    0x12dea => 'Optio P80',
     364    0x12df4 => 'Optio WS80',
     365    0x12dfe => 'K-x',
     366    0x12e08 => '645D',
     367    0x12e12 => 'Optio E80',
     368    0x12e30 => 'Optio W90',
     369    0x12e3a => 'Optio I-10',
     370    0x12e44 => 'Optio H90',
     371    0x12e4e => 'Optio E90',
     372    0x12e58 => 'X90',
     373    0x12e6c => 'K-r',
     374    0x12e76 => 'K-5',
     375    0x12e8a => 'Optio RS1000 / RS1500',
     376    0x12e94 => 'Optio RZ10',
     377    0x12ebc => 'Optio WG-1 GPS',
    249378);
    250379
     
    322451    69 => 'Stockholm',
    323452    70 => 'Lisbon', #14
     453    71 => 'Copenhagen', #25
     454    72 => 'Warsaw',
     455    73 => 'Prague',
     456    74 => 'Budapest',
    324457);
    325458
     459# digital filter tag information (ref PH, K-5)
     460# (also see %filterSettings below for decoding of filter parameters)
     461my %digitalFilter = (
     462    Format => 'undef[17]',
     463    RawConv => '($val!~/^\\0/ or $$self{OPTIONS}{Unknown}) ? join(" ",unpack("Cc*",$val)) : undef',
     464    SeparateTable => 'DigitalFilter',
     465    ValueConvInv => q{
     466        return "\0" x 17 if $val eq "0";
     467        $val = pack("Cc*", $val=~/[-+]?\d+/g);
     468        length($val)==17 or warn("Expecting 17 values\n"), return undef;
     469        return $val;
     470    },
     471    PrintConv => {
     472        OTHER => \&PrintFilter, # this routine actually converts all values
     473        0 => 'Off',
     474        1 => 'Base Parameter Adjust',
     475        2 => 'Soft Focus',
     476        3 => 'High Contrast',
     477        4 => 'Color Filter',
     478        5 => 'Extract Color',
     479        6 => 'Monochrome',
     480        7 => 'Slim',
     481        9 => 'Fisheye',
     482        10 => 'Toy Camera',
     483        11 => 'Retro',
     484        12 => 'Pastel',
     485        13 => 'Water Color',
     486        14 => 'HDR',
     487        16 => 'Miniature',
     488        17 => 'Starburst',
     489        18 => 'Posterization',
     490        19 => 'Sketch Filter',
     491        254 => 'Custom Filter',
     492    },
     493);
     494
     495# digital filter setting names and conversions (ref PH, K-5)
     496# Note: names must be unique for writing
     497my %filterSettings = (
     498    1  => ['Brightness', '%+d'],    # BPA (-8-+8)
     499    2  => ['Saturation', '%+d'],    # BPA (-3-+3)
     500    3  => ['Hue', '%+d'],           # BPA (-3-+3)
     501    4  => ['Contrast', '%+d'],      # BPA (-3-+3)
     502    5  => ['Sharpness', '%+d'],     # BPA (-3-+3)
     503    6  => ['SoftFocus', '%d'],      # Soft Focus/Custom (1-3)
     504    7  => ['ShadowBlur',    { 0=>'Off',1=>'On' }], # Soft Focus
     505    8  => ['HighContrast', '%d'],   # High Contrast/Custom (1-5)
     506    9  => ['Color',         { 1=>'Red',2=>'Magenta',3=>'Blue',4=>'Cyan',5=>'Green',6=>'Yellow' }], # Color Filter
     507    10 => ['Density',       { 1=>'Light',2=>'Standard',3=>'Dark' }], # Color Filter
     508    11 => ['ExtractedColor',{ 0=>'Off',1=>'Red',2=>'Magenta',3=>'Blue',4=>'Cyan',5=>'Green',6=>'Yellow' }], # ExtractColor [x2]
     509    12 => ['ColorRange', '%+d'],    # ExtractColor [x2] (-2-+2)
     510    13 => ['FilterEffect',  { 0=>'Off',1=>'Red',2=>'Green',3=>'Blue',4=>'Infrared'}], # Monochrome
     511    14 => ['ToningBA', '%+d'],      # Monochrome (-3-+3)
     512    15 => ['InvertColor',   { 0=>'Off',1=>'On' }], # Custom
     513    16 => ['Slim', '%+d'],          # Slim (-8-+8)
     514    17 => ['EffectDensity', { 1=>'Sparse',2=>'Normal',3=>'Dense' }], # Starburst
     515    18 => ['Size',          { 1=>'Small',2=>'Medium',3=>'Large' }], # Starburst
     516    19 => ['Angle',         { 0=>'0deg',2=>'30deg',3=>'45deg',4=>'60deg'}], # Starburst (1 is unused)
     517    20 => ['Fisheye',       { 1=>'Weak',2=>'Medium',3=>'Strong' }], # Fisheye
     518    21 => ['DistortionType', '%d'], # Custom (1-3)
     519    22 => ['DistortionLevel',{0=>'Off',1=>'Weak',2=>'Medium',3=>'Strong' }], #Custom
     520    23 => ['ShadingType', '%d'],    # Custom (1-6)
     521    24 => ['ShadingLevel', '%+d'],  # Custom (-3-+3)
     522    25 => ['Shading', '%d'],        # Toy Camera (1-3)
     523    26 => ['Blur',  '%d'],          # Toy Camera (1-3)
     524    27 => ['ToneBreak',     { 0=>'Off',1=>'Red',2=>'Green',3=>'Blue',4=>'Yellow'}], # Toy Camera/Custom
     525    28 => ['Toning', '%+d'],        # Retro (-3-+3)
     526    29 => ['FrameComposite',{ 0=>'None',1=>'Thin',2=>'Medium',3=>'Thick' }], # Retro
     527    30 => ['PastelStrength',{ 1=>'Weak',2=>'Medium',3=>'Strong' }], # Pastel
     528    31 => ['Intensity', '%d'],      # Water Color (1-3)
     529    32 => ['Saturation2',   { 0=>'Off',1=>'Low',2=>'Medium',3=>'High' }], # Water Color
     530    33 => ['HDR',           { 1=>'Weak',2=>'Medium',3=>'Strong' }], # HDR
     531    35 => ['FocusPlane', '%+d'],    # Miniature (-3-+3)
     532    36 => ['FocusWidth',    { 1=>'Narrow',2=>'Middle',3=>'Wide' }], # Miniature
     533    37 => ['PlaneAngle',    { 0=>'Horizontal',1=>'Vertical',2=>'Positive slope',3=>'Negative slope' }], # Miniature
     534    38 => ['Blur2', '%d'],          # Miniature (1-3)
     535    39 => ['Shape',         { 1=>'Cross',2=>'Star',3=>'Snowflake',4=>'Heart',5=>'Note'}], # Starburst
     536    40 => ['Posterization', '%d'],  # Posterization (1-5)
     537    41 => ['Contrast2',     { 1=>'Low',2=>'Medium',3=>'High'}], # Sketch Filter
     538    42 => ['ScratchEffect', { 0=>'Off',1=>'On' }], # Sketch Filter
     539);
     540
     541# decoding for Pentax Firmware ID tags - PH
     542my %pentaxFirmwareID = (
     543    # the first 2 numbers are the firmware version, I'm not sure what the second 2 mean
     544    # Note: the byte order may be different for some models
     545    # which give, for example, version 0.01 instead of 1.00
     546    ValueConv => sub {
     547        my $val = shift;
     548        return $val unless length($val) == 4;
     549        # (value is encrypted by toggling all bits)
     550        my @a = map { $_ ^ 0xff } unpack("C*",$val);
     551        return sprintf('%d %.2d %.2d %.2d', @a);
     552    },
     553    ValueConvInv => sub {
     554        my $val = shift;
     555        my @a = $val=~/\b\d+\b/g;
     556        return $val unless @a == 4;
     557        @a = map { ($_ & 0xff) ^ 0xff } @a;
     558        return pack("C*", @a);
     559    },
     560    PrintConv => '$val=~tr/ /./; $val',
     561    PrintConvInv => '$val=~s/^(\d+)\.(\d+)\.(\d+)\.(\d+)/$1 $2 $3 $4/ ? $val : undef',
     562);
     563
     564# convert 16 or 77 metering segment values to approximate LV equivalent - PH
     565my %convertMeteringSegments = (
     566    PrintConv    => sub { join ' ', map(
     567        { $_==255 ? 'n/a' : $_==0 ? '0' : sprintf '%.1f', $_ / 8 - 6 } split(' ',$_[0])
     568    ) },
     569    PrintConvInv => sub { join ' ', map(
     570        { /^n/i ? 255 : $_==0 ? '0' : int(($_ + 6) * 8 + 0.5) }        split(' ',$_[0])
     571    ) },
     572);
     573
     574# lens code conversions
     575my %lensCode = (
     576    Unknown => 1,
     577    PrintConv => 'sprintf("0x%.2x", $val)',
     578    PrintConvInv => 'hex($val)',
     579);
     580
     581# common attributes for writable BinaryData directories
     582my %binaryDataAttrs = (
     583    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     584    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     585    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     586    WRITABLE => 1,
     587    FIRST_ENTRY => 0,
     588);
     589
     590# Pentax makernote tags
    326591%Image::ExifTool::Pentax::Main = (
    327592    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     
    376641        Name => 'Date',
    377642        Groups => { 2 => 'Time' },
     643        Notes => 'changing either Date or Time will affect ShutterCount decryption',
    378644        Writable => 'undef',
    379645        Count => 4,
     
    382648        RawConv => '$$self{PentaxDate} = $val', # save to decrypt ShutterCount
    383649        ValueConv => 'length($val)==4 ? sprintf("%.4d:%.2d:%.2d",unpack("nC2",$val)) : "Unknown ($val)"',
    384         ValueConvInv => 'my @v=split /:/, $val;pack("nC2",$v[0],$v[1],$v[2])',
     650        ValueConvInv => q{
     651            $val =~ s/(\d) .*/$1/;          # remove Time
     652            my @v = split /:/, $val;
     653            return pack("nC2",$v[0],$v[1],$v[2]);
     654        },
    385655    },
    386656    0x0007 => { #5
     
    393663        RawConv => '$$self{PentaxTime} = $val', # save to decrypt ShutterCount
    394664        ValueConv => 'length($val)>=3 ? sprintf("%.2d:%.2d:%.2d",unpack("C3",$val)) : "Unknown ($val)"',
    395         ValueConvInv => 'pack("C3",split(/:/,$val))',
     665        ValueConvInv => q{
     666            $val =~ s/^[0-9:]+ (\d)/$1/;    # remove Date
     667            return pack("C3",split(/:/,$val));
     668        },
    396669    },
    397670    0x0008 => { #2
    398671        Name => 'Quality',
    399672        Writable => 'int16u',
     673        PrintConvColumns => 2,
    400674        PrintConv => {
    401675            0 => 'Good',
     
    404678            3 => 'TIFF', #5
    405679            4 => 'RAW', #5
     680            5 => 'Premium', #PH (K20D)
    406681        },
    407682    },
     
    410685        Groups => { 2 => 'Image' },
    411686        Writable => 'int16u',
     687        PrintConvColumns => 2,
    412688        PrintConv => {
    413689            0 => '640x480',
     
    427703            25 => '2816x2212 or 2816x2112', #13 or #14
    428704            27 => '3648x2736', #PH (Optio A20)
     705            29 => '4000x3000', #PH (X70)
     706            30 => '4288x3216', #PH (Optio RS1000)
     707            129 => '1920x1080', #PH (Optio RZ10)
     708            257 => '3216x3216', #PH (Optio RZ10)
    429709            '0 0' => '2304x1728', #13
    430710            '4 0' => '1600x1200', #PH (Optio MX4)
     
    439719        },
    440720    },
    441     # 0x000a - (See note below)
    442721    0x000b => { #3
    443722        Name => 'PictureMode',
    444723        Writable => 'int16u',
    445         PrintConv => {
     724        Count => -1,
     725        Notes => q{
     726            1 or 2 values.  Decimal values differentiate Optio 555 modes which are
     727            different from other models
     728        },
     729        ValueConv => '($val < 4 and $$self{Model} =~ /Optio 555\b/) ? $val + 0.1 : $val',
     730        ValueConvInv => 'int $val',
     731        PrintConvColumns => 2,
     732        PrintConv => [{
    446733            0 => 'Program', #PH
     734            0.1 => 'Av', #PH (Optio 555)
     735            1 => 'Shutter Speed Priority', #JD
     736            1.1 => 'M', #PH (Optio 555)
    447737            2 => 'Program AE', #13
     738            2.1 => 'Tv', #PH (Optio 555)
    448739            3 => 'Manual', #13
     740            3.1 => 'USER', #PH (Optio 555)
    449741            5 => 'Portrait',
    450742            6 => 'Landscape',
    451743            8 => 'Sport', #PH
    452744            9 => 'Night Scene',
     745            # 10 "full mode"? #13
    453746            11 => 'Soft', #PH
    454747            12 => 'Surf & Snow',
    455             13 => 'Sunset or Candlelight', #14 (Candlelight)
     748            13 => 'Candlelight', #13
    456749            14 => 'Autumn',
    457750            15 => 'Macro',
     
    459752            18 => 'Text',
    460753            19 => 'Panorama', #PH
     754            20 => '3-D', #PH (Optio 555)
     755            21 => 'Black & White', #PH (Optio 555)
     756            22 => 'Sepia', #PH (Optio 555)
     757            23 => 'Red', #PH (Optio 555)
     758            24 => 'Pink', #PH (Optio 555)
     759            25 => 'Purple', #PH (Optio 555)
     760            26 => 'Blue', #PH (Optio 555)
     761            27 => 'Green', #PH (Optio 555)
     762            28 => 'Yellow', #PH (Optio 555)
    461763            30 => 'Self Portrait', #PH
    462764            31 => 'Illustrations', #13
    463765            33 => 'Digital Filter', #13
     766            35 => 'Night Scene Portrait', #25
    464767            37 => 'Museum', #PH
    465768            38 => 'Food', #PH
     769            39 => 'Underwater', #25
    466770            40 => 'Green Mode', #PH
    467771            49 => 'Light Pet', #PH
     
    473777            56 => 'Synchro Sound Record', #PH
    474778            58 => 'Frame Composite', #14
    475             '0 0' => 'Auto', #13
    476             '0 2' => 'Program AE', #13
    477             '5 2' => 'Portrait', #13
    478             '6 2' => 'Landscape', #13
    479             '9 1' => 'Night Scene', #13
    480             '13 1' => 'Candlelight', #13
    481             '15 1' => 'Macro', #13
    482             '255 0' => 'Digital Filter?', #13
    483         },
     779            59 => 'Report', #25
     780            60 => 'Kids', #13
     781            61 => 'Blur Reduction', #13
     782            65 => 'Half-length Portrait', #JD
     783            221 => 'P', #PH (Optio 555)
     784            255=> 'PICT', #PH (Optio 555)
     785        }],
    484786    },
    485787    0x000c => { #PH
    486788        Name => 'FlashMode',
    487789        Writable => 'int16u',
     790        Count => -1,
    488791        PrintHex => 1,
    489         ValueConv => '$val=~s/ .*//; $val', # ignore 2nd value
    490         PrintConv => {
     792        PrintConv => [{
    491793            0x000 => 'Auto, Did not fire',
    492             0x001 => 'Off',
     794            0x001 => 'Off, Did not fire',
     795            0x002 => 'On, Did not fire', #19
    493796            0x003 => 'Auto, Did not fire, Red-eye reduction',
     797            0x005 => 'On, Did not fire, Wireless (Master)', #19
    494798            0x100 => 'Auto, Fired',
    495             0x102 => 'On',
     799            0x102 => 'On, Fired',
    496800            0x103 => 'Auto, Fired, Red-eye reduction',
    497801            0x104 => 'On, Red-eye reduction',
    498             0x105 => 'On, Wireless',
     802            0x105 => 'On, Wireless (Master)', #19
     803            0x106 => 'On, Wireless (Control)', #19
    499804            0x108 => 'On, Soft',
    500805            0x109 => 'On, Slow-sync',
    501806            0x10a => 'On, Slow-sync, Red-eye reduction',
    502807            0x10b => 'On, Trailing-curtain Sync',
    503         },
     808        },{ #19 (AF-540FGZ flash)
     809            0x000 => 'n/a - Off-Auto-Aperture', #19
     810            0x03f => 'Internal',
     811            0x100 => 'External, Auto',
     812            0x23f => 'External, Flash Problem', #JD
     813            0x300 => 'External, Manual',
     814            0x304 => 'External, P-TTL Auto',
     815            0x305 => 'External, Contrast-control Sync', #JD
     816            0x306 => 'External, High-speed Sync',
     817            0x30c => 'External, Wireless',
     818            0x30d => 'External, Wireless, High-speed Sync',
     819        }],
    504820    },
    505821    0x000d => [ #2
    506822        {
    507             Condition => '$self->{CameraMake} =~ /^PENTAX/',
    508823            Name => 'FocusMode',
     824            Condition => '$self->{Make} =~ /^PENTAX/',
    509825            Notes => 'Pentax models',
    510826            Writable => 'int16u',
     827            PrintConvColumns => 2,
    511828            PrintConv => { #PH
    512829                0 => 'Normal',
     
    514831                2 => 'Infinity',
    515832                3 => 'Manual',
     833                4 => 'Super Macro', #JD
    516834                5 => 'Pan Focus',
    517835                16 => 'AF-S', #17
    518836                17 => 'AF-C', #17
     837                18 => 'AF-A', #PH (educated guess)
     838                32 => 'Contrast-detect', #PH (K-5)
     839                33 => 'Tracking Contrast-detect', #PH (K-5)
    519840            },
    520841        },
     
    534855        Name => 'AFPointSelected',
    535856        Writable => 'int16u',
    536         PrintConv => {
     857        PrintConvColumns => 2,
     858        PrintConv => {
     859            # 0 - Contrast-detect AF? - PH (K-5)
    537860            0xffff => 'Auto',
    538861            0xfffe => 'Fixed Center',
     862            0xfffd => 'Automatic Tracking AF', #JD
     863            0xfffc => 'Face Detect AF', #JD
    539864            1 => 'Upper-left',
    540865            2 => 'Top',
     
    579904        ValueConv => '$val * 1e-5',
    580905        ValueConvInv => '$val * 1e5',
    581         # value may be 0xffffffff in Bulb mode (ref 19)
     906        # value may be 0xffffffff in Bulb mode (ref JD)
    582907        PrintConv => '$val > 42949 ? "Unknown (Bulb)" : Image::ExifTool::Exif::PrintExposureTime($val)',
    583         PrintConvInv => '$val=~/(unknown|bulb)/i ? $val : eval $val',
     908        PrintConvInv => '$val=~/(unknown|bulb)/i ? $val : Image::ExifTool::Exif::ConvertFraction($val)',
    584909    },
    585910    0x0013 => { #PH
     
    596921        Name => 'ISO',
    597922        Writable => 'int16u',
    598         Priority => 0,
    599         PrintConv => {
    600             3 => 50, #(NC=Not Confirmed)
     923        Notes => 'may be different than EXIF:ISO, which can round to the nearest full stop',
     924        PrintConvColumns => 4,
     925        PrintConv => {
     926            # 1/3 EV step values
     927            3 => 50,
    601928            4 => 64,
    602             5 => 80, #(NC)
     929            5 => 80,
    603930            6 => 100,
    604931            7 => 125, #PH
    605932            8 => 160, #PH
    606933            9 => 200,
    607             10 => 250, #(NC)
     934            10 => 250,
    608935            11 => 320, #PH
    609936            12 => 400,
    610             13 => 500, #(NC)
    611             14 => 640, #(NC)
     937            13 => 500,
     938            14 => 640,
    612939            15 => 800,
    613             16 => 1000, #(NC)
    614             17 => 1250, #(NC)
     940            16 => 1000,
     941            17 => 1250,
    615942            18 => 1600, #PH
    616             21 => 3200, #(NC)
     943            19 => 2000, #PH
     944            20 => 2500, #PH
     945            21 => 3200, #PH
     946            22 => 4000,
     947            23 => 5000,
     948            24 => 6400, #PH
     949            25 => 8000, #PH
     950            26 => 10000, #PH
     951            27 => 12800, #PH
     952            28 => 16000, #PH
     953            29 => 20000, #PH
     954            30 => 25600, #PH
     955            31 => 32000, #PH
     956            32 => 40000, #PH
     957            33 => 51200, #PH
     958            # Optio 330/430 (oddball)
    617959            50 => 50, #PH
    618960            100 => 100, #PH
     
    622964            1600 => 1600, #PH
    623965            3200 => 3200, #PH
    624             # have seen 268 for ISO 1600 on K10D - PH
    625         },
    626     },
    627     # 0x0015 - Related to measured EV? ranges from -2 to 6 if interpreted as signed int (PH)
     966            # 1/2 EV step values
     967            258 => 50, #PH (NC)
     968            259 => 70, #PH (NC)
     969            260 => 100, #19
     970            261 => 140, #19
     971            262 => 200, #19
     972            263 => 280, #19
     973            264 => 400, #19
     974            265 => 560, #19
     975            266 => 800, #19
     976            267 => 1100, #19
     977            268 => 1600, #19
     978            269 => 2200, #PH
     979            270 => 3200, #PH
     980            271 => 4500, #PH
     981            272 => 6400, #PH
     982            273 => 9000, #PH
     983            274 => 12800, #PH
     984            275 => 18000, #PH
     985            276 => 25600, #PH
     986            277 => 36000, #PH
     987            278 => 51200, #PH
     988        },
     989    },
     990    0x0015 => { #PH
     991        Name => 'LightReading',
     992        Format => 'int16s', # (because I may have seen negative numbers)
     993        Writable => 'int16u',
     994        # ranges from 0-12 for my Optio WP - PH
     995        Notes => q{
     996            calibrated differently for different models.  For the Optio WP, add 6 to get
     997            approximate Light Value.  May not be valid for some models, ie. Optio S
     998        },
     999    },
    6281000    0x0016 => { #PH
    6291001        Name => 'ExposureCompensation',
     
    6311003        ValueConv => '($val - 50) / 10',
    6321004        ValueConvInv => 'int($val * 10 + 50.5)',
    633         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    634         PrintConvInv => 'eval $val',
     1005        PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
     1006        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    6351007    },
    6361008    0x0017 => { #3
     
    6381010        Writable => 'int16u',
    6391011        PrintConv => {
    640             0 => 'Multi Segment',
    641             1 => 'Center Weighted',
     1012            0 => 'Multi-segment',
     1013            1 => 'Center-weighted average',
    6421014            2 => 'Spot',
     1015            # have seen value of 16 for E70
    6431016        },
    6441017    },
     
    6481021        Count => -1,
    6491022        Notes => q{
    650             one or two numbers: exposure bracket step in EV, then extended bracket if
     1023            1 or 2 values: exposure bracket step in EV, then extended bracket if
    6511024            available.  Extended bracket values are printed as 'WB-BA', 'WB-GM',
    652             'Saturation', 'Sharpness' or 'Contrast' followed by '+1', '+2' or '+3' for
    653             step size
    654         },
    655         ValueConv => sub {
    656             my @v = split(' ', shift);
    657             if ($v[0] < 10) {
    658                 $v[0] /= 3;     # 1=.3ev, 2=.7, 3=1...
    659             } else {
    660                 $v[0] -= 9.5;   # 10=.5ev, 11=1.5...
    661             }
    662             return "@v";
    663         },
    664         ValueConvInv => sub {
    665             my @v = split(' ', shift);
    666             if (abs($v[0]-int($v[0])-.5) > 0.05) {
    667                 $v[0] = int($v[0] * 3 + 0.5);
    668             } else {
    669                 $v[0] = int($v[0] + 10);
    670             }
    671             return "@v";
    672         },
     1025            'Saturation', 'Sharpness', 'Contrast', 'Hue' or 'HighLowKey' followed by
     1026            '+1', '+2' or '+3' for step size
     1027        },
     1028        # 1=.3ev, 2=.7, 3=1.0, ... 10=.5ev, 11=1.5, ...
     1029        ValueConv => [ '$val<10 ? $val/3 : $val-9.5' ],
     1030        ValueConvInv => [ 'abs($val-int($val)-.5)>0.05 ? int($val*3+0.5) : int($val+10)' ],
    6731031        PrintConv => sub {
    6741032            my @v = split(' ', shift);
    6751033            $v[0] = sprintf('%.1f', $v[0]) if $v[0];
    6761034            if ($v[1]) {
    677                 my %s = (1=>'WB-BA',2=>'WB-GM',3=>'Saturation',4=>'Sharpness',5=>'Contrast');
     1035                my %s = (1=>'WB-BA',2=>'WB-GM',3=>'Saturation',4=>'Sharpness',
     1036                         5=>'Contrast',6=>'Hue',7=>'HighLowKey');
    6781037                my $t = $v[1] >> 8;
    6791038                $v[1] = sprintf('%s+%d', $s{$t} || "Unknown($t)", $v[1] & 0xff);
     
    6871046            $v[0] =~ s/ ?EV//i;
    6881047            if ($v[1]) {
    689                 my %s = ('WB-BA'=>1,'WB-GM'=>2,Saturation=>3,Sharpness=>4,Contrast=>5);
     1048                my %s = ('WB-BA'=>1,'WB-GM'=>2,'Saturation'=>3,'Sharpness'=>4,
     1049                         'Contrast'=>5,'Hue'=>6,'HighLowKey'=>7);
    6901050                if ($v[1] =~ /^No\b/i) {
    6911051                    $v[1] = 0;
     
    7041064        Name => 'WhiteBalance',
    7051065        Writable => 'int16u',
     1066        PrintConvColumns => 2,
    7061067        PrintConv => {
    7071068            0 => 'Auto',
     
    7111072            4 => 'Tungsten',
    7121073            5 => 'Manual',
    713             6 => 'DaylightFluorescent', #13
    714             7 => 'DaywhiteFluorescent', #13
    715             8 => 'WhiteFluorescent', #13
     1074            6 => 'Daylight Fluorescent', #13
     1075            7 => 'Day White Fluorescent', #13
     1076            8 => 'White Fluorescent', #13
    7161077            9 => 'Flash', #13
    7171078            10 => 'Cloudy', #13
    718             65534 => 'Unknown', #13
    719             65535 => 'User Selected', #13
     1079            15 => 'Color Temperature Enhancement', #PH
     1080            17 => 'Kelvin', #PH
     1081            0xfffe => 'Unknown', #13
     1082            0xffff => 'User-Selected', #13
    7201083        },
    7211084    },
     
    7281091            3 => 'Auto (Flash)',
    7291092            4 => 'Auto (Tungsten)',
    730             7 => 'Auto (DaywhiteFluorescent)', #17 (K100D guess)
    731             8 => 'Auto (WhiteFluorescent)', #17 (K100D guess)
     1093            6 => 'Auto (Daylight Fluorescent)', #19 (NC)
     1094            7 => 'Auto (Day White Fluorescent)', #17 (K100D guess)
     1095            8 => 'Auto (White Fluorescent)', #17 (K100D guess)
    7321096            10 => 'Auto (Cloudy)', #17 (K100D guess)
     1097            # 0xfffd observed in K100D (ref 17)
     1098            0xfffe => 'Unknown', #PH (you get this when shooting night sky shots)
    7331099            0xffff => 'User-Selected',
    734             0xfffe => 'Preset (Fireworks?)', #PH
    735             # 0xfffd observed in K100D (ref 17)
    7361100        },
    7371101    },
     
    7531117            # Optio 30, 33WR, 43WR, 450, 550, 555, 750Z, X
    7541118            Name => 'FocalLength',
    755             Condition => '$self->{CameraModel} =~ /^PENTAX Optio (30|33WR|43WR|450|550|555|750Z|X)\b/',
     1119            Condition => '$self->{Model} =~ /^PENTAX Optio (30|33WR|43WR|450|550|555|750Z|X)\b/',
    7561120            Writable => 'int32u',
    7571121            Priority => 0,
    7581122            ValueConv => '$val / 10',
    7591123            ValueConvInv => '$val * 10',
    760             PrintConv => 'sprintf("%.1fmm",$val)',
    761             PrintConvInv => '$val=~s/mm//;$val',
     1124            PrintConv => 'sprintf("%.1f mm",$val)',
     1125            PrintConvInv => '$val=~s/\s*mm//;$val',
    7621126        },
    7631127        {
     
    7711135            ValueConv => '$val / 100',
    7721136            ValueConvInv => '$val * 100',
    773             PrintConv => 'sprintf("%.1fmm",$val)',
    774             PrintConvInv => '$val=~s/mm//;$val',
     1137            PrintConv => 'sprintf("%.1f mm",$val)',
     1138            PrintConvInv => '$val=~s/\s*mm//;$val',
    7751139        },
    7761140    ],
     
    7841148        Name => 'Saturation',
    7851149        Writable => 'int16u',
    786         PrintConv => {
     1150        Count => -1,
     1151        Notes => '1 or 2 values',
     1152        PrintConvColumns => 2,
     1153        PrintConv => [{ # the *istD has pairs of values - PH
    7871154            0 => 'Low', #PH
    7881155            1 => 'Normal', #PH
     
    7921159            5 => 'Very Low', #(NC)
    7931160            6 => 'Very High', #(NC)
    794             # the *istD has pairs of values - PH
    795             '0 0' => 'Low',
    796             '1 0' => 'Normal',
    797             '2 0' => 'High',
    798         },
     1161            7 => '-4', #PH (K-5)
     1162            8 => '+4', #PH (NC)
     1163            65535 => 'None', #PH (Monochrome)
     1164        }],
    7991165    },
    8001166    0x0020 => {
    8011167        Name => 'Contrast',
    8021168        Writable => 'int16u',
    803         PrintConv => {
     1169        Count => -1,
     1170        Notes => '1 or 2 values',
     1171        PrintConvColumns => 2,
     1172        PrintConv => [{ # the *istD has pairs of values - PH
    8041173            0 => 'Low', #PH
    8051174            1 => 'Normal', #PH
     
    8081177            4 => 'Med High', #2
    8091178            5 => 'Very Low', #PH
    810             6 => 'Very High', #(NC)
    811             # the *istD has pairs of values - PH
    812             '0 0' => 'Low',
    813             '1 0' => 'Normal',
    814             '2 0' => 'High',
    815         },
     1179            6 => 'Very High', #PH (NC)
     1180            7 => '-4', #PH (NC)
     1181            8 => '+4', #PH (K-5)
     1182        }],
    8161183    },
    8171184    0x0021 => {
    8181185        Name => 'Sharpness',
    8191186        Writable => 'int16u',
    820         PrintConv => {
     1187        Count => -1,
     1188        Notes => '1 or 2 values',
     1189        PrintConvColumns => 2,
     1190        PrintConv => [{ # the *istD has pairs of values - PH
    8211191            0 => 'Soft', #PH
    8221192            1 => 'Normal', #PH
     
    8261196            5 => 'Very Soft', #(NC)
    8271197            6 => 'Very Hard', #(NC)
    828             # the *istD has pairs of values - PH
    829             '0 0' => 'Soft',
    830             '1 0' => 'Normal',
    831             '2 0' => 'Hard',
    832         },
     1198            7 => '-4', #PH (NC)
     1199            8 => '+4', #PH (NC)
     1200        }],
    8331201    },
    8341202    0x0022 => { #PH
     
    8671235        PrintConv => { 0 => 'No', 1 => 'Yes' },
    8681236    },
    869     # 0x0027 - could be a 5-byte string software version number for the Optio 550,
    870     #          but the offsets are wacky so it is hard to tell (PH)
     1237    0x0027 => { #PH
     1238        Name => 'DSPFirmwareVersion',
     1239        Writable => 'undef',
     1240        # - for K10D, this comes from 4 bytes at offset 0x1c in the firmware file
     1241        %pentaxFirmwareID,
     1242    },
     1243    0x0028 => { #PH
     1244        Name => 'CPUFirmwareVersion',
     1245        Writable => 'undef',
     1246        # - for K10D, this comes from 4 bytes at offset 0x83fbf8 in firmware file
     1247        %pentaxFirmwareID,
     1248    },
    8711249    0x0029 => { #5
    8721250        Name => 'FrameNumber',
     1251        # - one report that this has a value of 84 for the first image with a *istDS
     1252        # - another report that file number 4 has frameNumber 154 for *istD, and
     1253        #   that framenumber jumped at about 9700 to around 26000
     1254        # - with *istDS firmware 2.0, this tag was removed and ShutterCount was added
    8731255        Writable => 'int32u',
    8741256    },
    875     # 0x002b - definitely exposure related somehow (PH)
     1257    # 0x002b - definitely exposure related somehow - PH
     1258    0x002d => { #PH
     1259        Name => 'EffectiveLV',
     1260        Notes => 'camera-calculated light value, but includes exposure compensation',
     1261        Writable => 'int16u',
     1262        ValueConv => '$val/1024',
     1263        ValueConvInv => '$val * 1024',
     1264        PrintConv => 'sprintf("%.1f",$val)',
     1265        PrintConvInv => '$val',
     1266    },
    8761267    0x0032 => { #13
    877         Name => 'ImageProcessing',
     1268        Name => 'ImageEditing',
    8781269        Writable => 'undef',
    8791270        Format => 'int8u',
    8801271        Count => 4,
    8811272        PrintConv => {
    882             '0 0' => 'Unprocessed', #PH
    883             '0 0 0 0' => 'Unprocessed',
     1273            '0 0' => 'None', #PH
     1274            '0 0 0 0' => 'None',
    8841275            '0 0 0 4' => 'Digital Filter',
     1276            '1 0 0 0' => 'Resized', #PH (K-5)
    8851277            '2 0 0 0' => 'Cropped', #PH
    886             '4 0 0 0' => 'Color Filter',
     1278            # note: doesn't apply to digital filters applied when picture is taken
     1279            '4 0 0 0' => 'Digital Filter 4', #PH (K10D)
     1280            '6 0 0 0' => 'Digital Filter 6', #PH (K-5)
    8871281            '16 0 0 0' => 'Frame Synthesis?',
    8881282        },
    8891283    },
    890     # and "\0\0\0\x04" for Digital filter (ref 13)
    891     # and "\x04\0\0\0" for Color filter (ref 13) (PH - digital or color filter, K10D)
    892     0x0033 => { #PH (K110D/K100D)
     1284    0x0033 => { #PH (K110D/K100D/K-m)
    8931285        Name => 'PictureMode',
    8941286        Writable => 'int8u',
    8951287        Count => 3,
    896         PrintConv => {
    897             # Program dial modes
    898             '0 0 0'  => 'Program', # K110D
    899             '0 4 0'  => 'Standard', #13
    900             '0 5 0'  => 'Portrait', # K110D
    901             '0 6 0'  => 'Landscape', # K110D
    902             '0 7 0'  => 'Macro', # K110D
    903             '0 8 0'  => 'Sport', # K110D
    904             '0 9 0'  => 'Night Scene Portrait', # K110D
    905             '0 10 0' => 'No Flash', # K110D
    906             # SCN modes (menu-selected)
    907             '0 11 0' => 'Night Scene', # K100D
    908             '0 12 0' => 'Surf & Snow', # K100D
    909             '0 13 0' => 'Text', # K100D
    910             '0 14 0' => 'Sunset', # K100D
    911             '0 15 0' => 'Kids', # K100D
    912             '0 16 0' => 'Pet', # K100D
    913             '0 17 0' => 'Candlelight', # K100D
    914             '0 18 0' => 'Museum', # K100D
     1288        Relist => [ [0, 1], 2 ], # join values 0 and 1 for PrintConv
     1289        PrintConvColumns => 2,
     1290        PrintConv => [{
     1291            # Program dial modes (from K110D)
     1292            '0 0'  => 'Program',    # (also on K10D, custom settings: Program Line 1, e-dial in Program 3, 4 or 5)
     1293            '0 1'  => 'Hi-speed Program', #19 (K10D, custom settings: Program Line 2, e-dial in Program 3, 4 or 5)
     1294            '0 2'  => 'DOF Program', #19      (K10D, custom settings: Program Line 3, e-dial in Program 3, 4 or 5)
     1295            '0 3'  => 'MTF Program', #19      (K10D, custom settings: Program Line 4, e-dial in Program 3, 4 or 5)
     1296            '0 4'  => 'Standard', #13
     1297            '0 5'  => 'Portrait',
     1298            '0 6'  => 'Landscape',
     1299            '0 7'  => 'Macro',
     1300            '0 8'  => 'Sport',
     1301            '0 9'  => 'Night Scene Portrait',
     1302            '0 10' => 'No Flash',
     1303            # SCN modes (menu-selected) (from K100D)
     1304            '0 11' => 'Night Scene',
     1305            '0 12' => 'Surf & Snow',
     1306            '0 13' => 'Text',
     1307            '0 14' => 'Sunset',
     1308            '0 15' => 'Kids',
     1309            '0 16' => 'Pet',
     1310            '0 17' => 'Candlelight',
     1311            '0 18' => 'Museum',
     1312            '0 19' => 'Food', #(n/c)
     1313            '0 20' => 'Stage Lighting',
     1314            '0 21' => 'Night Snap',
    9151315            # AUTO PICT modes (auto-selected)
    916             '1 4 0'  => 'Auto PICT (Standard)', #13
    917             '1 5 0'  => 'Auto PICT (Portrait)', #7 (K100D)
    918             '1 6 0'  => 'Auto PICT (Landscape)', # K110D
    919             '1 7 0'  => 'Auto PICT (Macro)', #13
    920             '1 8 0'  => 'Auto PICT (Sport)', #13
    921             # Manual dial modes
    922             '2 0 0'  => 'Program AE', #13
    923             '3 0 0'  => 'Green Mode', #16
    924             '4 0 0'  => 'Shutter Speed Priority', # K110D
    925             '5 0 0'  => 'Aperture Priority', # K110D
    926             '8 0 0'  => 'Manual', # K110D
    927             '9 0 0'  => 'Bulb', # K110D
     1316            '1 4'  => 'Auto PICT (Standard)', #13
     1317            '1 5'  => 'Auto PICT (Portrait)', #7 (K100D)
     1318            '1 6'  => 'Auto PICT (Landscape)', # K110D
     1319            '1 7'  => 'Auto PICT (Macro)', #13
     1320            '1 8'  => 'Auto PICT (Sport)', #13
    9281321            # *istD modes (ref 7)
    929             '2 0 1'  => 'Program AE', # 'User Program AE' according to ref 16
    930             '2 1 1'  => 'Hi-speed Program',
    931             '2 2 1'  => 'DOF Program',
    932             '2 3 1'  => 'MTF Program',
    933             '3 0 1'  => 'Green Mode',
    934             '4 0 1'  => 'Shutter Speed Priority',
    935             '5 0 1'  => 'Aperture Priority',
    936             '6 0 1'  => 'Program Tv Shift',
    937             '7 0 1'  => 'Program Av Shift',
    938             '8 0 1'  => 'Manual',
    939             '9 0 1'  => 'Bulb',
    940             '10 0 1' => 'Aperture Priority (Off-Auto-Aperture)',
    941             '11 0 1' => 'Manual (Off-Auto-Aperture)',
    942             '12 0 1' => 'Bulb (Off-Auto-Aperture)',
    943             # K10D modes (ref 16)
    944             '13 0 0' => 'Shutter & Aperture Priority AE',
    945             '13 0 1' => 'Shutter & Aperture Priority AE (1)', #PH guess
    946             '15 0 0' => 'Sensitivity Priority AE',
    947             '15 0 1' => 'Sensitivity Priority AE (1)',
    948             '16 0 0' => 'Flash X-Sync Speed AE',
    949             '16 0 1' => 'Flash X-Sync Speed AE (1)', #PH guess
    950             # other modes
    951             '0 0 1'  => 'Program', #17 (K100D)
    952         },
     1322            '2 0'  => 'Program (HyP)', #13 (K-5 Normal program line - PH)
     1323            '2 1'  => 'Hi-speed Program (HyP)', #19 (K10D, custom settings: Program Line 2, e-dial in Program 1, 2)
     1324            '2 2'  => 'DOF Program (HyP)', #19      (K10D, custom settings: Program Line 3, e-dial in Program 1, 2)
     1325            '2 3'  => 'MTF Program (HyP)', #19      (K10D, custom settings: Program Line 4, e-dial in Program 1, 2)
     1326            '2 22' => 'Shallow DOF (HyP)', #PH (K-5)
     1327            '3 0'  => 'Green Mode', #16
     1328            '4 0'  => 'Shutter Speed Priority',
     1329            '5 0'  => 'Aperture Priority',
     1330            '6 0'  => 'Program Tv Shift',
     1331            '7 0'  => 'Program Av Shift', #19
     1332            '8 0'  => 'Manual',
     1333            '9 0'  => 'Bulb',
     1334            '10 0' => 'Aperture Priority, Off-Auto-Aperture',
     1335            '11 0' => 'Manual, Off-Auto-Aperture',
     1336            '12 0' => 'Bulb, Off-Auto-Aperture',
     1337            # extra K10D modes (ref 16)
     1338            '13 0' => 'Shutter & Aperture Priority AE',
     1339            '15 0' => 'Sensitivity Priority AE',
     1340            '16 0' => 'Flash X-Sync Speed AE',
     1341            '18 0' => 'Auto Program (Normal)', #PH (K-5)
     1342            '18 1' => 'Auto Program (Hi-speed)', #PH (NC)
     1343            '18 2' => 'Auto Program (DOF)', #PH (K-5)
     1344            '18 3' => 'Auto Program (MTF)', #PH (NC)
     1345            '18 22' => 'Auto Program (Shallow DOF)', #PH (NC)
     1346            '254 0' => 'Video', #PH (K-7,K-5)
     1347            '255 0' => 'Video (Auto Aperture)', #PH (K-5)
     1348            '255 4' => 'Video (4)', #PH (K-x)
     1349        },{
     1350            # EV step size (ref 19)
     1351            0 => '1/2 EV steps',
     1352            1 => '1/3 EV steps',
     1353        }],
    9531354    },
    9541355    0x0034 => { #7/PH
     
    9561357        Writable => 'int8u',
    9571358        Count => 4,
    958         PrintConv => {
    959             '0 0 0 0' => 'Single-frame',
    960             '1 0 0 0' => 'Continuous',
    961             '0 1 0 0' => 'Self-timer (12 sec)',
    962             '0 2 0 0' => 'Self-timer (2 sec)',
    963             '0 0 1 0' => 'Remote Control?', # needs validation
    964             '0 0 0 1' => 'Multiple Exposure',
    965         },
     1359        PrintConv => [{
     1360            0 => 'Single-frame',
     1361            1 => 'Continuous', # (K-5 Hi)
     1362            2 => 'Continuous (Lo)', #PH (K-5)
     1363            3 => 'Burst', #PH (K20D)
     1364            255 => 'Video', #PH (K-x)
     1365            # (K20D also has an Interval mode that needs decoding)
     1366        },{
     1367            0 => 'No Timer',
     1368            1 => 'Self-timer (12 s)',
     1369            2 => 'Self-timer (2 s)',
     1370            16 => 'Mirror Lock-up', # (K-5)
     1371            255 => 'n/a', #PH (K-x)
     1372        },{
     1373            0 => 'Shutter Button', # (also computer remote control - PH)
     1374            1 => 'Remote Control (3 s delay)', #19
     1375            2 => 'Remote Control', #19
     1376            4 => 'Remote Continuous Shooting', # (K-5)
     1377        },{
     1378            0x00 => 'Single Exposure',
     1379            0x01 => 'Multiple Exposure',
     1380            0x10 => 'HDR', #PH (645D)
     1381            0x20 => 'HDR Strong 1', #PH (NC) (K-5)
     1382            0x30 => 'HDR Strong 2', #PH (K-5)
     1383            0x40 => 'HDR Strong 3', #PH (K-5)
     1384            0xe0 => 'HDR Auto', #PH (K-5)
     1385            0xff => 'Video', #PH (K-x)
     1386        }],
     1387    },
     1388    0x0035 => { #PH
     1389        Name => 'SensorSize',
     1390        Format => 'int16u',
     1391        Count => 2,
     1392        Notes => 'includes masked pixels',
     1393        # values for various models (not sure why this is in 2um increments):
     1394        #  11894 7962 (K10D,K-m)   12012 7987 (*istDS,K100D,K110D)   12012 8019 (*istD),
     1395        #  12061 7988 (K-5)        12053 8005 (K-r,K-x)              14352 9535 (K20D,K-7)
     1396        #  22315 16711 (645)
     1397        ValueConv => 'my @a=split(" ",$val); $_/=500 foreach @a; join(" ",@a)',
     1398        ValueConvInv => 'my @a=split(" ",$val); $_*=500 foreach @a; join(" ",@a)',
     1399        PrintConv => 'sprintf("%.3f x %.3f mm", split(" ",$val))',
     1400        PrintConvInv => '$val=~s/\s*mm$//; $val=~s/\s*x\s*/ /; $val',
    9661401    },
    9671402    0x0037 => { #13
     
    9951430        Notes => '*istD only',
    9961431        ValueConv => '$val & 0x7ff', # ignore other bits for now
     1432        PrintConvColumns => 2,
    9971433        PrintConv => { BITMASK => {
    9981434            0 => 'Upper-left',
     
    10091445        } },
    10101446    },
    1011     # 0x003d = 8192 (PH, K10D)
     1447    # 0x003d - int16u: 8192 for most images, but occasionally 11571 for K100D/K110D,
     1448    #              and 8289 or 8456 for the K-x - PH
     1449    0x003e => { #PH
     1450        Name => 'PreviewImageBorders',
     1451        Writable => 'int8u',
     1452        Count => 4,
     1453        Notes => 'top, bottom, left, right',
     1454    },
    10121455    0x003f => { #PH
    10131456        Name => 'LensType',
     
    10151458        Count => 2,
    10161459        SeparateTable => 1,
    1017         ValueConv => '$val=~s/^(\d+ \d+) 0$/$1/; $val',
     1460        # the K-m adds two zeros to the LensType, some other models add only 1
     1461        ValueConv => '$val=~s/^(\d+ \d+)( 0){1,2}$/$1/; $val',
    10181462        ValueConvInv => '$val',
    1019         PrintConv => \%pentaxLensType,
    1020     },
    1021     # 0x0041 - increments for each cropped pic (PH)
    1022     #          (DigitalFilter according to ref 5)
     1463        PrintConv => \%pentaxLensTypes,
     1464    },
     1465    0x0040 => { #PH
     1466        Name => 'SensitivityAdjust',
     1467        Writable => 'int16u',
     1468        ValueConv => '($val - 50) / 10',
     1469        ValueConvInv => '$val * 10 + 50',
     1470        PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
     1471        PrintConvInv => '$val',
     1472    },
     1473    0x0041 => { #19
     1474        Name => 'ImageEditCount',
     1475        Writable => 'int16u',
     1476    },
    10231477    0x0047 => { #PH
    10241478        Name => 'CameraTemperature',
     
    10261480        PrintConv => '"$val C"',
    10271481        PrintConvInv => '$val=~s/ ?c$//i; $val',
     1482    },
     1483    0x0048 => { #19
     1484        Name => 'AELock',
     1485        Writable => 'int16u',
     1486        PrintConv => {
     1487            0 => 'Off',
     1488            1 => 'On',
     1489        },
    10281490    },
    10291491    0x0049 => { #13
     
    10381500        ValueConvInv => 'int($val * 256 + ($val > 0 ? 0.5 : -0.5))',
    10391501        PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
    1040         PrintConvInv => '$val',
     1502        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    10411503    },
    10421504    0x004f => { #PH
    1043         Name => 'ImageTone',
    1044         Writable => 'int16u',
     1505        Name => 'ImageTone', # (Called CustomImageMode in K20D manual)
     1506        Writable => 'int16u',
     1507        PrintConvColumns => 2,
    10451508        PrintConv => {
    10461509            0 => 'Natural',
    10471510            1 => 'Bright',
    1048         },
    1049     },
     1511            2 => 'Portrait', # (K20D/K200D)
     1512            3 => 'Landscape', # (K20D)
     1513            4 => 'Vibrant', # (K20D)
     1514            5 => 'Monochrome', # (K20D)
     1515            6 => 'Muted', # (645D)
     1516            7 => 'Reversal Film', # (645D)
     1517            8 => 'Bleach Bypass', # (K-5)
     1518        },
     1519    },
     1520    0x0050 => { #PH
     1521        Name => 'ColorTemperature',
     1522        Writable => 'int16u',
     1523        RawConv => '$val ? $val : undef',
     1524        ValueConv => '53190 - $val',
     1525        ValueConvInv => '53190 - $val',
     1526    },
     1527    # 0x0053-0x005a - not in JPEG images - PH
    10501528    0x005c => { #PH
    10511529        Name => 'ShakeReductionInfo',
    1052         Format => 'undef',
    1053         SubDirectory => {
    1054             TagTable => 'Image::ExifTool::Pentax::SRInfo',
    1055         },
    1056     },
    1057     0x005d => { #19/PH
    1058         # (used by all Pentax DSLR's except *istD and *istDS - PH)
    1059         # The lowest decrypted values observed are 246 for the first image from a
    1060         # brand new K10D, and 209 for one of the first 20 images from a new K10D,
    1061         # so either there are ~200 test images shot in the factory, or there is an
    1062         # offset of ~200 which is applied to this value before encryption
     1530        Format => 'undef', # (written as int8u) - do this just to save time converting the value
     1531        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::SRInfo' },
     1532    },
     1533    0x005d => { #JD/PH
     1534        # (used by all Pentax DSLR's except *istD and *istDS until firmware 2.0 - PH)
     1535        # Observed values for the first shot of a new K10D are:  81 [PH], 181 [19],
     1536        # 246 [7], and 209 [18 (one of the first 20 shots)], so there must be a number
     1537        # of test images shot in the factory. (But my new K-5 started at 1 - PH)
     1538        # This count includes shutter actuations even if they don't result in a
     1539        # recorded image (ie. manual white balance frame or digital preview), but
     1540        # does not include actuations due to Live View or video recording - PH
    10631541        Name => 'ShutterCount',
    10641542        Writable => 'undef',
    10651543        Count => 4,
    1066         Notes => 'raw value is a big-endian 4-byte integer, encrypted using Date and Time',
     1544        Notes => q{
     1545            Note: May be reset by servicing!  Also, does not include shutter actuations
     1546            for live view or video recording
     1547        },
     1548        # raw value is a big-endian 4-byte integer, encrypted using Date and Time
    10671549        RawConv => 'length($val) == 4 ? unpack("N",$val) : undef',
    10681550        RawConvInv => q{
     
    10731555        ValueConvInv => '$val',
    10741556    },
     1557    0x0060 => { #PH (K-5)
     1558        Name => 'FaceInfo',
     1559        Format => 'undef', # (written as int8u)
     1560        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::FaceInfo' },
     1561    },
     1562    # 0x0062 - int16u: 1 (K10D,K200D,K-m,K2000), 3 (K20D), 4 (K-7), 5 (K-x), 6 (645D), 7 (K-r), 8 (K-5)
     1563    0x0067 => { #PH (K-5)
     1564        Name => 'Hue',
     1565        Writable => 'int16u',
     1566        PrintConvColumns => 2,
     1567        PrintConv => {
     1568            0 => -2,
     1569            1 => 'Normal',
     1570            2 => 2,
     1571            3 => -1,
     1572            4 => 1,
     1573            5 => -3,
     1574            6 => 3,
     1575            7 => -4,
     1576            8 => 4,
     1577            65535 => 'None', # (Monochrome)
     1578        },
     1579    },
     1580    # 0x0067 - int16u: 1 [and 65535 in Monochrome] (K20D,K200D) - PH
     1581    0x0068 => { #PH
     1582        Name => 'AWBInfo',
     1583        Format => 'undef', # (written as int8u)
     1584        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::AWBInfo' },
     1585    },
     1586    0x0069 => { #PH (K20D; K-5 highlights only)
     1587        Name => 'DynamicRangeExpansion',
     1588        Writable => 'undef',
     1589        Format => 'int8u',
     1590        Count => 4,
     1591        PrintConv => {
     1592            '0 0 0 0' => 'Off',
     1593            '1 0 0 0' => 'On',
     1594        },
     1595    },
     1596    0x006b => { #PH (K-5)
     1597        Name => 'TimeInfo',
     1598        Format => 'undef', # (written as int8u)
     1599        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::TimeInfo' },
     1600    },
     1601    0x006c => { #PH (K-5)
     1602        Name => 'HighLowKeyAdj',
     1603        Description => 'High/Low Key Adj',
     1604        Writable => 'int16s',
     1605        Count => 2,
     1606        PrintConvColumns => 3,
     1607        PrintConv => {
     1608            '-4 0' => -4,
     1609            '-3 0' => -3,
     1610            '-2 0' => -2,
     1611            '-1 0' => -1,
     1612             '0 0' => 0,
     1613             '1 0' => 1,
     1614             '2 0' => 2,
     1615             '3 0' => 3,
     1616             '4 0' => 4,
     1617        },
     1618    },
     1619    0x006d => { #PH (K-5)
     1620        Name => 'ContrastHighlight',
     1621        Writable => 'int16s',
     1622        Count => 2,
     1623        PrintConvColumns => 3,
     1624        PrintConv => {
     1625            '-4 0' => -4,
     1626            '-3 0' => -3,
     1627            '-2 0' => -2,
     1628            '-1 0' => -1,
     1629             '0 0' => 0,
     1630             '1 0' => 1,
     1631             '2 0' => 2,
     1632             '3 0' => 3,
     1633             '4 0' => 4,
     1634        },
     1635    },
     1636    0x006e => { #PH (K-5)
     1637        Name => 'ContrastShadow',
     1638        Writable => 'int16s',
     1639        Count => 2,
     1640        PrintConvColumns => 3,
     1641        PrintConv => {
     1642            '-4 0' => -4,
     1643            '-3 0' => -3,
     1644            '-2 0' => -2,
     1645            '-1 0' => -1,
     1646             '0 0' => 0,
     1647             '1 0' => 1,
     1648             '2 0' => 2,
     1649             '3 0' => 3,
     1650             '4 0' => 4,
     1651        },
     1652    },
     1653    0x006f => { #PH (K-5)
     1654        Name => 'ContrastHighlightShadowAdj',
     1655        Description => 'Contrast Highlight/Shadow Adj',
     1656        Writable => 'int8u',
     1657        PrintConv => {
     1658            0 => 'Off',
     1659            1 => 'On',
     1660        },
     1661    },
     1662    0x0070 => { #PH (K-5)
     1663        Name => 'FineSharpness',
     1664        Writable => 'int8u',
     1665        Count => -1,    # 1 for K20/K200, 2 for K-5
     1666        PrintConv => [{
     1667            0 => 'Off',
     1668            1 => 'On',
     1669        },{
     1670            0 => 'Normal',
     1671            2 => 'Extra fine',
     1672        }],
     1673    },
     1674    0x0071 => { #PH (K20D,K-x)
     1675        Name => 'HighISONoiseReduction',
     1676        Format => 'int8u',
     1677        PrintConv => [{
     1678            0 => 'Off',
     1679            1 => 'Weakest',
     1680            2 => 'Weak', # (called "Low" by K-x)
     1681            3 => 'Strong', # (called "High" by K-x)
     1682            4 => 'Medium',
     1683            255 => 'Auto', # (K-5)
     1684        },{
     1685            0 => 'Inactive',
     1686            1 => 'Active',
     1687            2 => 'Active (Weak)', # (K-5)
     1688            3 => 'Active (Strong)', # (K-5)
     1689            4 => 'Active (Medium)', # (K-5)
     1690        },{ # Start ISO level for NR (K-x)
     1691            48 => 'ISO>400',
     1692            56 => 'ISO>800',
     1693            64 => 'ISO>1600',
     1694            72 => 'ISO>3200',
     1695        }],
     1696    },
     1697    0x0072 => { #JD (K20D)
     1698        Name => 'AFAdjustment',
     1699        Writable => 'int16s',
     1700    },
     1701    0x0073 => { #PH (K-5)
     1702        Name => 'MonochromeFilterEffect',
     1703        Writable => 'int16u',
     1704        PrintConvColumns => 2,
     1705        PrintConv => {
     1706            65535 => 'None',
     1707            1 => 'Green',
     1708            2 => 'Yellow',
     1709            3 => 'Orange',
     1710            4 => 'Red',
     1711            5 => 'Magenta',
     1712            6 => 'Blue',
     1713            7 => 'Cyan',
     1714            8 => 'Infrared',
     1715        },
     1716    },
     1717    0x0074 => { #PH (K-5)
     1718        Name => 'MonochromeToning',
     1719        Writable => 'int16u',
     1720        PrintConvColumns => 2,
     1721        PrintConv => {
     1722            65535 => 'None',
     1723            0 => -4,
     1724            1 => -3,
     1725            2 => -2,
     1726            3 => -1,
     1727            4 => 0,
     1728            5 => 1,
     1729            6 => 2,
     1730            7 => 3,
     1731            8 => 4,
     1732        },
     1733    },
     1734    0x0076 => { #PH (K-5)
     1735        Name => 'FaceDetect',
     1736        Writable => 'int8u',
     1737        Count => 2,
     1738        # the Optio S12 writes this but not the FacesDetected tag, so get FacesDetected from here
     1739        DataMember => 'FacesDetected',
     1740        RawConv => '$val =~ / (\d+)/ and $$self{FacesDetected} = $1; $val',
     1741        PrintConv => [
     1742            '$val ? "On ($val faces max)" : "Off"',
     1743            '"$val faces detected"',
     1744        ],
     1745        PrintConvInv => [
     1746            '$val =~ /(\d+)/ ? $1 : 0',
     1747            '$val =~ /(\d+)/ ? $1 : 0',
     1748        ],
     1749    },
     1750    0x0077 => { #PH (K-5)
     1751        # set by taking a picture with face detect AF,
     1752        # but it isn't reset until camera is turned off? - PH
     1753        Name => 'FaceDetectFrameSize',
     1754        Writable => 'int16u',
     1755        Count => 2,
     1756    },
     1757    # 0x0078 - int16u[2]: '0 0' (K-5,K-7,K-r,K-x)
     1758    0x0079 => { #PH
     1759        Name => 'ShadowCompensation',
     1760        Writable => 'int8u',
     1761        Count => -1,
     1762        PrintConvColumns => 2,
     1763        PrintConv => {
     1764            # (1 value for K-m/K2000, 2 for 645D)
     1765            0 => 'Off',
     1766            1 => 'On',
     1767            '0 0' => 'Off',
     1768            '1 1' => 'Weak',
     1769            '1 2' => 'Normal',
     1770            '1 3' => 'Strong',
     1771        },
     1772    },
     1773    0x007a => { #PH
     1774        Name => 'ISOAutoParameters',
     1775        Writable => 'int8u',
     1776        Count => 2,
     1777        PrintConv => {
     1778            '1 0' => 'Slow',
     1779            '2 0' => 'Standard',
     1780            '3 0' => 'Fast',
     1781        },
     1782    },
     1783    0x007b => { #PH (K-5)
     1784        Name => 'CrossProcess',
     1785        Writable => 'int8u',
     1786        PrintConvColumns => 2,
     1787        PrintConv => {
     1788            0 => 'Off',
     1789            1 => 'Random',
     1790            2 => 'Preset 1',
     1791            3 => 'Preset 2',
     1792            4 => 'Preset 3',
     1793            33 => 'Favorite 1',
     1794            34 => 'Favorite 2',
     1795            35 => 'Favorite 3',
     1796        },
     1797    },
     1798    0x007d => { #PH
     1799        Name => 'LensCorr',
     1800        Format => 'undef', # (written as int8u)
     1801        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensCorr' },
     1802    },
     1803    # 0x007e - int32u: 15859,15860,15864,15865,16315 (K-5 PEF/DNG only) - PH
     1804    0x007f => { #PH (K-5)
     1805        Name => 'BleachBypassToning',
     1806        Writable => 'int16u',
     1807        PrintConvColumns => 2,
     1808        PrintConv => {
     1809            65535 => 'Off',
     1810            1 => 'Green',
     1811            2 => 'Yellow',
     1812            3 => 'Orange',
     1813            4 => 'Red',
     1814            5 => 'Magenta',
     1815            6 => 'Purple',
     1816            7 => 'Blue',
     1817            8 => 'Cyan',
     1818        },
     1819    },
    10751820    0x0200 => { #5
    10761821        Name => 'BlackPoint',
     
    10791824    },
    10801825    0x0201 => { #5
     1826        # (this doesn't change for different fixed white balances in JPEG images: Daylight,
     1827        # Tungsten, Kelvin, etc -- always "8192 8192 8192 8192", but it varies for these in
     1828        # RAW images, all images in Auto, for different Manual WB settings, and for images
     1829        # taken via Pentax Remote Assistant) - PH
    10811830        Name => 'WhitePoint',
    10821831        Writable => 'int16u',
    10831832        Count => 4,
    10841833    },
    1085     # 0x0205 - Also stores PictureMode (PH)
     1834    # 0x0202: int16u[4]: all 0's in all my samples
     1835    0x0203 => { #JD (not really sure what these mean)
     1836        Name => 'ColorMatrixA',
     1837        Writable => 'int16s',
     1838        Count => 9,
     1839        ValueConv => 'join(" ",map({ $_/8192 } split(" ",$val)))',
     1840        ValueConvInv => 'join(" ",map({ int($_*8192 + ($_<0?-0.5:0.5)) } split(" ",$val)))',
     1841        PrintConv => 'join(" ",map({sprintf("%.5f",$_)} split(" ",$val)))',
     1842        PrintConvInv => '"$val"',
     1843    },
     1844    0x0204 => { #JD
     1845        Name => 'ColorMatrixB',
     1846        Writable => 'int16s',
     1847        Count => 9,
     1848        ValueConv => 'join(" ",map({ $_/8192 } split(" ",$val)))',
     1849        ValueConvInv => 'join(" ",map({ int($_*8192 + ($_<0?-0.5:0.5)) } split(" ",$val)))',
     1850        PrintConv => 'join(" ",map({sprintf("%.5f",$_)} split(" ",$val)))',
     1851        PrintConvInv => '"$val"',
     1852    },
     1853    0x0205 => { #19
     1854        Name => 'CameraSettings',
     1855        SubDirectory => {
     1856            TagTable => 'Image::ExifTool::Pentax::CameraSettings',
     1857            ByteOrder => 'BigEndian',
     1858        },
     1859    },
    10861860    0x0206 => { #PH
    10871861        Name => 'AEInfo',
    1088         SubDirectory => {
    1089             TagTable => 'Image::ExifTool::Pentax::AEInfo',
    1090         },
    1091     },
    1092     0x0207 => { #PH
    1093         Name => 'LensInfo',
    1094         SubDirectory => {
    1095             TagTable => 'Image::ExifTool::Pentax::LensInfo',
    1096         },
    1097     },
    1098     0x0208 => { #PH
    1099         Name => 'FlashInfo',
    1100         SubDirectory => {
    1101             TagTable => 'Image::ExifTool::Pentax::FlashInfo',
    1102         },
    1103     },
    1104     0x0209 => {
     1862        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::AEInfo' },
     1863    },
     1864    0x0207 => [ #PH
     1865        {
     1866            Name => 'LensInfo',
     1867            # the *ist series (and Samsung GX-1) always use the old format, and all
     1868            # other models but the K100D, K110D and K100D Super always use the newer
     1869            # format, and for the K110D/K110D we expect ff or 00 00 at byte 20 if
     1870            # it is the old format.)
     1871            Condition => q{
     1872                $$self{Model}=~/(\*ist|GX-1[LS])/ or
     1873               ($$self{Model}=~/(K100D|K110D)/ and $$valPt=~/^.{20}(\xff|\0\0)/s)
     1874            },
     1875            SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensInfo' },
     1876        },{
     1877            Name => 'LensInfo',
     1878            Condition => '$count < 90',
     1879            SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensInfo2' },
     1880        },{
     1881            Name => 'LensInfo',
     1882            Condition => '$count == 90',
     1883            SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensInfo3' },
     1884        },{
     1885            Name => 'LensInfo',
     1886            SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensInfo4' },
     1887        }
     1888    ],
     1889    0x0208 => [ #PH
     1890        {
     1891            Name => 'FlashInfo',
     1892            Condition => '$count == 27',
     1893            SubDirectory => { TagTable => 'Image::ExifTool::Pentax::FlashInfo' },
     1894        },
     1895        {
     1896            Name => 'FlashInfoUnknown',
     1897            SubDirectory => { TagTable => 'Image::ExifTool::Pentax::FlashInfoUnknown' },
     1898        },
     1899    ],
     1900    0x0209 => { #PH
    11051901        Name => 'AEMeteringSegments',
    11061902        Format => 'int8u',
    1107         Count => 16,
     1903        Count => -1,
    11081904        Notes => q{
    1109             measurements from each of the 16 AE metering segments, converted to LV
    1110         },
    1111         # metering segment locations (ref 19):
     1905            measurements from each of the 16 AE metering segments for models such as the
     1906            K10D, and 77 metering segments for models such as the K-5, converted to LV
     1907        },
     1908        %convertMeteringSegments,
     1909        #    16 metering segment             77 metering segment
     1910        #    locations (ref JD)              locations (ref PH, K-5)
    11121911        # +-------------------------+
    1113         # |           14            |
    1114         # |    +---+---+---+---+    |
    1115         # |    | 5 | 3/1\ 2| 4 |    |
    1116         # |  +-+-+-+-+ - +-+-+-+-+  |
    1117         # +--+ 9 | 7 ||0|| 6 | 8 +--+
    1118         # |  +-+-+-+-+ - +-+-+-+-+  |
    1119         # |    |13 |11\ /10|12 |    |
    1120         # |    +---+---+---+---+    |
    1121         # |           15            |
     1912        # |           14            | +----------------------------------+
     1913        # |    +---+---+---+---+    | |  0  1  2  3  4  5  6  7  8  9 10 |
     1914        # |    | 5 | 3/1\ 2| 4 |    | | 11 12 13 14 15 16 17 18 19 20 21 |
     1915        # |  +-+-+-+-+ - +-+-+-+-+  | | 22 23 24 25 26 27 28 29 30 31 32 |
     1916        # +--+ 9 | 7 ||0|| 6 | 8 +--+ | 33 34 35 36 37 38 39 40 41 42 43 |
     1917        # |  +-+-+-+-+ - +-+-+-+-+  | | 44 45 46 47 48 49 50 51 52 53 54 |
     1918        # |    |13 |11\ /10|12 |    | | 55 56 57 58 59 60 61 62 63 64 65 |
     1919        # |    +---+---+---+---+    | | 66 67 68 69 70 71 72 73 74 75 76 |
     1920        # |           15            | +----------------------------------+
    11221921        # +-------------------------+
    1123         # convert to approximate LV equivalent (PH):
    1124         ValueConv => q{
    1125             my @a;
    1126             foreach (split ' ', $val) { push @a, $_ / 8 - 6; }
    1127             return join(' ', @a);
    1128         },
    1129         ValueConvInv => q{
    1130             my @a;
    1131             foreach (split ' ', $val) { push @a, int(($_ + 6) * 8 + 0.5); }
    1132             return join(' ', @a);
    1133         },
    1134         PrintConv => q{
    1135             my @a;
    1136             foreach (split ' ', $val) { push @a, sprintf('%.1f', $_); }
    1137             return join(' ', @a);
    1138         },
    1139         PrintConvInv => '$val',
    1140     },
    1141     0x020a => {
    1142         Name => 'FlashADump',
    1143         Flags => ['Unknown','Binary'],
    1144     },
    1145     0x020b => {
    1146         Name => 'FlashBDump',
    1147         Flags => ['Unknown','Binary'],
     1922    },
     1923    0x020a => { #PH/JD/19
     1924        Name => 'FlashMeteringSegments',
     1925        Format => 'int8u',
     1926        Count => -1,
     1927        %convertMeteringSegments,
     1928    },
     1929    0x020b => { #PH/JD/19
     1930        Name => 'SlaveFlashMeteringSegments',
     1931        Format => 'int8u',
     1932        Count => -1,
     1933        Notes => 'used in wireless control mode',
     1934        %convertMeteringSegments,
    11481935    },
    11491936    0x020d => { #PH
     
    11891976    0x0215 => { #PH
    11901977        Name => 'CameraInfo',
    1191         SubDirectory => {
    1192             TagTable => 'Image::ExifTool::Pentax::CameraInfo',
    1193         },
     1978        Format => 'undef', # (written as int32u)
     1979        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::CameraInfo' },
    11941980    },
    11951981    0x0216 => { #PH
     
    11971983        SubDirectory => {
    11981984            TagTable => 'Image::ExifTool::Pentax::BatteryInfo',
    1199         },
    1200     },
    1201     0x021f => { #19
     1985            ByteOrder => 'BigEndian', # have seen makernotes changed to little-endian in DNG!
     1986        },
     1987    },
     1988    # 0x021a - undef[1068] (K-5)
     1989    0x021b => { #19
     1990        Name => 'SaturationInfo',
     1991        Flags => [ 'Unknown', 'Binary' ],
     1992        Writable => 0,
     1993        Notes => 'only in PEF and DNG images',
     1994        # K10D values with various Saturation settings (ref 19):
     1995        # Very Low: 000000022820f9a0fe4000802660f92002e0fee01e402c40f880fb40ffc02b20f52002e0fe401ee0
     1996        # Low:      000000022ae0f700fe20ff402840f88001e0fcc021602f60f560fb40fe602d20f48001c0fbc02280
     1997        # Med Low:  000000022dc0f420fe20fe002a20f7e000c0fa8024c032c0f220fb20fce02f60f3c000a0f9202640
     1998        # Normal:   000000023120f0e0fe00fc802c40f740ffa0f7e028803660ee80fb20fb4031c0f300ff60f6202a80
     1999        # Med High: 0000000234e0ed40fde0fae02ea0f680fe60f5002ca03a80ea80fb00f9603480f220fe00f2e02f20
     2000        # High:     0000000238c0e960fde0f9203140f5a0fce0f1e031403f00e600fb00f7803760f120fc60ef403460
     2001        # Very High:000000023d20e520fdc0f7203420f4c0fb60ee6036404400e120fae0f5403aa0f020fac0eb403a00
     2002    },
     2003    # 0x021c - undef[18] (K-5)
     2004    # 0x021d - undef[18] (K-5)
     2005    # 0x021e - undef[8] (K-5)
     2006    0x021f => { #JD
    12022007        Name => 'AFInfo',
    12032008        SubDirectory => {
     2009            # NOTE: Most of these subdirectories are 'undef' format, and as such the
     2010            # byte ordering is not changed when changed via the Pentax software (which
     2011            # will write a little-endian TIFF on an Intel system).  So we must define
     2012            # BigEndian byte ordering for any of these which contain multi-byte values. - PH
     2013            ByteOrder => 'BigEndian',
    12042014            TagTable => 'Image::ExifTool::Pentax::AFInfo',
    12052015        },
     2016    },
     2017    0x0220 => { #6
     2018        Name => 'HuffmanTable',
     2019        Flags => [ 'Unknown', 'Binary' ],
     2020        Writable => 0,
     2021        Notes => 'found in K10D, K20D and K2000D PEF images',
     2022    },
     2023    # 0x0221 - undef[138] (K-5)
     2024    0x0222 => { #PH
     2025        Name => 'ColorInfo',
     2026        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::ColorInfo' },
     2027    },
     2028    # 0x0223 - undef[198] (K-5 PEF/DNG only)
     2029    0x0224 => { #19
     2030        Name => 'EVStepInfo',
     2031        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::EVStepInfo' },
     2032    },
     2033    0x0226 => { #PH
     2034        Name => 'ShotInfo', # (may want to change this later when more is decoded)
     2035        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::ShotInfo' },
     2036    },
     2037    0x0227 => { #PH
     2038        Name => 'FacePos',
     2039        Condition => '$$self{FacesDetected}', # ignore if no faces to decode
     2040        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::FacePos' },
     2041    },
     2042    0x0228 => { #PH
     2043        Name => 'FaceSize',
     2044        Condition => '$$self{FacesDetected}', # ignore if no faces to decode
     2045        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::FaceSize' },
     2046    },
     2047    0x0229 => { #PH (verified) (K-m, K-x, K-7)
     2048        Name => 'SerialNumber',
     2049        Writable => 'string',
     2050        Notes => 'left blank by some cameras',
     2051    },
     2052    0x022a => { #PH (K-5)
     2053        Name => 'FilterInfo',
     2054        SubDirectory => {
     2055            TagTable => 'Image::ExifTool::Pentax::FilterInfo',
     2056            ByteOrder => 'BigEndian',
     2057        },
     2058    },
     2059    0x022b => { #PH (K-5)
     2060        Name => 'LevelInfo',
     2061        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LevelInfo' },
     2062    },
     2063    # 0x022c - undef[46] (K-5)
     2064    # 0x022d - undef[100] (K-5)
     2065    0x022e => { #PH (K-5 AVI videos)
     2066        Name => 'Artist',
     2067        Groups => { 2 => 'Author' },
     2068        Writable => 'string',
     2069    },
     2070    0x022f => { #PH (K-5 AVI videos)
     2071        Name => 'Copyright',
     2072        Groups => { 2 => 'Author' },
     2073        Writable => 'string',
     2074    },
     2075    0x0230 => { #PH (K-x AVI videos)
     2076        Name => 'FirmwareVersion',
     2077        Notes => 'only in AVI videos',
     2078        # this tag only exists in AVI videos, and for the K-x the value of
     2079        # this tag is "K-x Ver 1.00", which is the same as the EXIF Software
     2080        # tag.  I used a different tag name for this because Pentax uses the
     2081        # AVI Software tag for a different string, "PENTAX K-x".
     2082        Writable => 'string',
     2083    },
     2084    0x0231 => { #PH (K-5)
     2085        Name => 'ContrastDetectAFArea',
     2086        Writable => 'int16u',
     2087        Count => 4,
     2088        Notes => q{
     2089            AF area of the most recent contrast-detect focus operation. Coordinates
     2090            are left, top, width and height in a 720x480 frame, with Y downwards
     2091        },
     2092    },
     2093    0x0235 => { #PH (K-5)
     2094        Name => 'CrossProcessParams',
     2095        # (it would be interesting to know exactly what these mean)
     2096        Writable => 'undef',
     2097        Format => 'int8u',
     2098        Count => 10,
    12062099    },
    12072100    0x03fe => { #PH
     
    12102103        PrintConv => '\$val',
    12112104    },
     2105    0x03ff => [ #PH
     2106        {
     2107            Name => 'TempInfoK5',
     2108            Condition => '$$self{Model} =~ /K-5\b/',
     2109            SubDirectory => { TagTable => 'Image::ExifTool::Pentax::TempInfoK5' },
     2110        },{
     2111            Name => 'UnknownInfo',
     2112            SubDirectory => { TagTable => 'Image::ExifTool::Pentax::UnknownInfo' },
     2113        },
     2114    ],
    12122115    0x0402 => { #5
    12132116        Name => 'ToneCurve',
     
    12182121        PrintConv => '\$val',
    12192122    },
     2123    # 0x0404 - undef[2086] (K-5)
     2124    # 0x0405 - undef[24200] (K-5 PEF/DNG only)
     2125    # 0x0406 - undef[4116] (K-5)
    12202126    0x0e00 => {
    12212127        Name => 'PrintIM',
     
    12302136# shake reduction information (ref PH)
    12312137%Image::ExifTool::Pentax::SRInfo = (
    1232     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1233     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1234     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     2138    %binaryDataAttrs,
    12352139    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    1236     WRITABLE => 1,
    1237     FIRST_ENTRY => 0,
    12382140    NOTES => 'Shake reduction information.',
    12392141    0 => {
    12402142        Name => 'SRResult',
    1241         PrintConv => { #PH/19
     2143        PrintConv => { #PH/JD
    12422144            0 => 'Not stabilized',
    12432145            BITMASK => {
    12442146                0 => 'Stabilized',
     2147                # have seen 1 and 4 for 0.5 and 0.3 sec exposures with NR on and Bit 0 also set - ref 19
     2148                # have seen bits 1,2,3,4 in K-5 AVI videos - PH
    12452149                6 => 'Not ready',
    12462150            },
     
    12492153    1 => {
    12502154        Name => 'ShakeReduction',
    1251         PrintConv => { 0 => 'Off', 1 => 'On' },
     2155        PrintConv => {
     2156            0 => 'Off',
     2157            1 => 'On',
     2158            4 => 'Off (4)', # (K20D, K200D, K-7, K-5)
     2159            5 => 'On (5)', #(guess) (K20D)
     2160            # (got 5 for K-5 with HDR [auto-align off only], Composition Adjust, and movie with SR off!)
     2161            6 => 'On (Video)', # (K-7)
     2162            7 => 'On (7)', #(NC) (K20D, K200D, K-m, K-5)
     2163            15 => 'On (15)', # (K20D (with Tamron 10-20mm @ 10mm))
     2164        },
    12522165    },
    12532166    2 => {
    1254         Name => 'SR_SWSToSWRTime',
    1255         # SWS=photometering switch, SWR=shutter release switch
     2167        Name => 'SRHalfPressTime',
     2168        # (was SR_SWSToSWRTime: SWS=photometering switch, SWR=shutter release switch)
    12562169        # (from http://www.patentstorm.us/patents/6597867-description.html)
     2170        # (here, SR could more accurately mean Shutter Release, not Shake Reduction)
    12572171        Notes => q{
    12582172            time from when the shutter button was half pressed to when the shutter was
    1259             released
    1260         },
     2173            released, including time for focusing
     2174        },
     2175        # (constant of 60 determined from times: 2sec=127; 3sec=184,197; 4sec=244,249,243,246 - PH)
     2176        ValueConv => '$val / 60',
     2177        ValueConvInv => 'my $v=$val*60; $v < 255 ? int($v + 0.5) : 255',
     2178        PrintConv => 'sprintf("%.2f s",$val) . ($val > 254.5/60 ? " or longer" : "")',
     2179        PrintConvInv => '$val=~tr/0-9.//dc; $val',
     2180    },
     2181    3 => { #JD
     2182        Name => 'SRFocalLength',
     2183        ValueConv => '$val & 0x01 ? $val * 4 : $val / 2',
     2184        ValueConvInv => '$val <= 127 ? int($val) * 2 : int($val / 4) | 0x01',
     2185        PrintConv => '"$val mm"',
     2186        PrintConvInv => '$val=~s/\s*mm//;$val',
     2187    },
     2188);
     2189
     2190# face detection information (ref PH, K-5)
     2191%Image::ExifTool::Pentax::FaceInfo = (
     2192    %binaryDataAttrs,
     2193    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2194    DATAMEMBER => [ 0 ],
     2195    0 => {
     2196        Name => 'FacesDetected',
     2197        RawConv => '$$self{FacesDetected} = $val',
     2198    },
     2199    2 => {
     2200        Name => 'FacePosition',
     2201        Notes => q{
     2202            X/Y coordinates of the center of the main face in percent of frame size,
     2203            with positive Y downwards
     2204        },
     2205        Format => 'int8u[2]',
     2206    },
     2207);
     2208
     2209# automatic white balance settings (ref PH, K-5)
     2210%Image::ExifTool::Pentax::AWBInfo = (
     2211    %binaryDataAttrs,
     2212    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2213    # 0 - always 1?
     2214    # (data ends here for the K20D, K200D, K-x and K-7)
     2215    0 => {
     2216        Name => 'WhiteBalanceAutoAdjustment',
     2217        PrintConv => {
     2218            0 => 'Off',
     2219            1 => 'On',
     2220        },
     2221    },
     2222    1 => { # (exists only for K-5)
     2223        Name => 'TungstenAWB',
     2224        PrintConv => {
     2225            0 => 'Subtle Correction',
     2226            1 => 'Strong Correction',
     2227        },
     2228    },
     2229);
     2230
     2231# world time settings (ref PH, K-5)
     2232%Image::ExifTool::Pentax::TimeInfo = (
     2233    %binaryDataAttrs,
     2234    GROUPS => { 0 => 'MakerNotes', 2 => 'Time' },
     2235    0.1 => {
     2236        Name => 'WorldTimeLocation',
     2237        Mask => 0x01,
     2238        PrintConv => {
     2239            0x00 => 'Hometown',
     2240            0x01 => 'Destination',
     2241        },
     2242    },
     2243    0.2 => {
     2244        Name => 'HometownDST',
     2245        Mask => 0x02,
     2246        PrintConv => {
     2247            0x00 => 'No',
     2248            0x02 => 'Yes',
     2249        },
     2250    },
     2251    0.3 => {
     2252        Name => 'DestinationDST',
     2253        Mask => 0x04,
     2254        PrintConv => {
     2255            0x00 => 'No',
     2256            0x04 => 'Yes',
     2257        },
     2258    },
     2259    2 => {
     2260        Name => 'HometownCity',
     2261        SeparateTable => 'City',
     2262        PrintConv => \%pentaxCities,
     2263    },
     2264    3 => {
     2265        Name => 'DestinationCity',
     2266        SeparateTable => 'City',
     2267        PrintConv => \%pentaxCities,
     2268    },
     2269);
     2270
     2271# lens distortion correction (ref PH, K-5)
     2272%Image::ExifTool::Pentax::LensCorr = (
     2273    %binaryDataAttrs,
     2274    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     2275    0 => {
     2276        Name => 'DistortionCorrection',
     2277        PrintConv => { 0 => 'Off', 1 => 'On' },
     2278    },
     2279    1 => {
     2280        Name => 'ChromaticAberrationCorrection',
     2281        PrintConv => { 0 => 'Off', 1 => 'On' },
     2282    },
     2283);
     2284
     2285# camera settings (ref 19)
     2286%Image::ExifTool::Pentax::CameraSettings = (
     2287    %binaryDataAttrs,
     2288    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2289    PRIORITY => 0,
     2290    NOTES => 'Shot information written by Pentax DSLR cameras.',
     2291    0 => {
     2292        Name => 'PictureMode2',
     2293        PrintConv => {
     2294            0 => 'Scene Mode', #PH
     2295            1 => 'Auto PICT', #PH (NC)
     2296            2 => 'Program AE',
     2297            3 => 'Green Mode',
     2298            4 => 'Shutter Speed Priority',
     2299            5 => 'Aperture Priority',
     2300            6 => 'Program Tv Shift', #PH
     2301            7 => 'Program Av Shift',
     2302            8 => 'Manual', #PH
     2303            9 => 'Bulb', #PH
     2304            10 => 'Aperture Priority, Off-Auto-Aperture', #PH (NC)
     2305            11 => 'Manual, Off-Auto-Aperture', #PH
     2306            12 => 'Bulb, Off-Auto-Aperture', #PH (NC)
     2307            13 => 'Shutter & Aperture Priority AE',
     2308            15 => 'Sensitivity Priority AE',
     2309            16 => 'Flash X-Sync Speed AE', #PH
     2310        },
     2311    },
     2312    1.1 => {
     2313        Name => 'ProgramLine',
     2314        # only set to other than Normal when in Program AE mode
     2315        Mask => 0x03,
     2316        PrintConv => {
     2317            0 => 'Normal',
     2318            1 => 'Hi Speed',
     2319            2 => 'Depth',
     2320            3 => 'MTF',
     2321        },
     2322    },
     2323    1.2 => { # (K10D, K-5)
     2324        Name => 'EVSteps',
     2325        Mask => 0x20,
     2326        PrintConv => {
     2327            0x00 => '1/2 EV Steps',
     2328            0x20 => '1/3 EV Steps',
     2329        },
     2330    },
     2331    1.3 => { # (this bit is set for movies with the K-5 - PH)
     2332        Name => 'E-DialInProgram',
     2333        # always set even when not in Program AE mode
     2334        Mask => 0x40,
     2335        PrintConv => {
     2336            0x00 => 'Tv or Av',
     2337            0x40 => 'P Shift',
     2338        },
     2339    },
     2340    1.4 => { # (K10D, K-5)
     2341        Name => 'ApertureRingUse',
     2342        # always set even Aperture Ring is in A mode
     2343        Mask => 0x80,
     2344        PrintConv => {
     2345            0x00 => 'Prohibited',
     2346            0x80 => 'Permitted',
     2347        },
     2348    },
     2349    2 => {
     2350        Name => 'FlashOptions',
     2351        Notes => 'the camera flash options settings, set even if the flash is off',
     2352        Mask => 0xf0,
     2353        ValueConv => '$val>>4',
     2354        ValueConvInv => '$val<<4',
     2355        # Note: These tags correlate with the FlashMode and InternalFlashMode values,
     2356        # and match what is displayed by the Pentax software
     2357        PrintConv => {
     2358            0 => 'Normal', # (this value can occur in Green Mode) - ref 19
     2359            1 => 'Red-eye reduction', # (this value can occur in Green Mode) - ref 19
     2360            2 => 'Auto', # (this value can occur in other than Green Mode) - ref 19
     2361            3 => 'Auto, Red-eye reduction', #PH (this value can occur in other than Green Mode) - ref 19
     2362            5 => 'Wireless (Master)',
     2363            6 => 'Wireless (Control)',
     2364            8 => 'Slow-sync',
     2365            9 => 'Slow-sync, Red-eye reduction',
     2366            10 => 'Trailing-curtain Sync'
     2367        },
     2368    },
     2369    2.1 => {
     2370        Name => 'MeteringMode2',
     2371        Mask => 0x0f,
     2372        Notes => 'may not be valid for some models, ie. *ist D',
     2373        PrintConv => {
     2374            0 => 'Multi-segment',
     2375            BITMASK => {
     2376                0 => 'Center-weighted average',
     2377                1 => 'Spot',
     2378            },
     2379        },
     2380    },
     2381    3 => {
     2382        Name => 'AFPointMode',
     2383        Mask => 0xf0,
     2384        PrintConv => {
     2385            0x00 => 'Auto',
     2386            BITMASK => {
     2387                4 => 'Select',
     2388                5 => 'Fixed Center',
     2389                # have seen bit 6 set in pre-production images (firmware 0.20) - PH
     2390            },
     2391        },
     2392    },
     2393    3.1 => {
     2394        Name => 'FocusMode2',
     2395        Mask => 0x0f,
     2396        PrintConv => {
     2397            0 => 'Manual',
     2398            1 => 'AF-S',
     2399            2 => 'AF-C',
     2400            3 => 'AF-A', #PH
     2401        },
     2402    },
     2403    4 => {
     2404        Name => 'AFPointSelected2',
     2405        Format => 'int16u',
     2406        PrintConv => {
     2407            0 => 'Auto',
     2408            BITMASK => {
     2409                0 => 'Upper-left',
     2410                1 => 'Top',
     2411                2 => 'Upper-right',
     2412                3 => 'Left',
     2413                4 => 'Mid-left',
     2414                5 => 'Center',
     2415                6 => 'Mid-right',
     2416                7 => 'Right',
     2417                8 => 'Lower-left',
     2418                9 => 'Bottom',
     2419                10 => 'Lower-right',
     2420            },
     2421        },
     2422    },
     2423    6 => {
     2424        Name => 'ISOFloor', #PH
     2425        # manual ISO or minimum ISO in Auto ISO mode - PH
     2426        ValueConv => 'int(100*exp(Image::ExifTool::Pentax::PentaxEv($val-32)*log(2))+0.5)',
     2427        ValueConvInv => 'Image::ExifTool::Pentax::PentaxEvInv(log($val/100)/log(2))+32',
     2428    },
     2429    7 => {
     2430        Name => 'DriveMode2',
     2431        PrintConv => {
     2432            0 => 'Single-frame',
     2433            BITMASK => {
     2434                0 => 'Continuous', # (K-5 Hi)
     2435                1 => 'Continuous (Lo)', #PH (K-5)
     2436                2 => 'Self-timer (12 s)', #PH
     2437                3 => 'Self-timer (2 s)', #PH
     2438                4 => 'Remote Control (3 s delay)',
     2439                5 => 'Remote Control',
     2440                6 => 'Exposure Bracket', #PH/19
     2441                7 => 'Multiple Exposure',
     2442            },
     2443        },
     2444    },
     2445    8 => {
     2446        Name => 'ExposureBracketStepSize',
     2447        # This is set even when Exposure Bracket is Off (and the K10D
     2448        # displays Ò---Ó as the step size when you press the EB button) - DaveN
     2449        # because the last value is remembered and if you turn Exposure Bracket
     2450        # on the step size goes back to what it was before.
     2451        PrintConv => {
     2452            3 => '0.3',
     2453            4 => '0.5',
     2454            5 => '0.7',
     2455            8 => '1.0', #PH
     2456            11 => '1.3',
     2457            12 => '1.5',
     2458            13 => '1.7', #(NC)
     2459            16 => '2.0', #PH
     2460        },
     2461    },
     2462    9 => { #PH/19
     2463        Name => 'BracketShotNumber',
     2464        PrintHex => 1,
     2465        PrintConv => {
     2466            0 => 'n/a',
     2467            0x02 => '1 of 2', #PH (K-5)
     2468            0x12 => '2 of 2', #PH (K-5)
     2469            0x03 => '1 of 3',
     2470            0x13 => '2 of 3',
     2471            0x23 => '3 of 3',
     2472            0x05 => '1 of 5',
     2473            0x15 => '2 of 5',
     2474            0x25 => '3 of 5',
     2475            0x35 => '4 of 5',
     2476            0x45 => '5 of 5',
     2477        },
     2478    },
     2479    10 => {
     2480        Name => 'WhiteBalanceSet',
     2481        Mask => 0xf0,
     2482        # Not necessarily the white balance used; for example if the custom menu is set to
     2483        # "WB when using flash" -> "2 Flash", then this tag reports the camera setting while
     2484        # tag 0x0019 reports Flash if the Flash was used.
     2485        PrintConv => {
     2486            0 => 'Auto',
     2487            16 => 'Daylight',
     2488            32 => 'Shade',
     2489            48 => 'Cloudy',
     2490            64 => 'Daylight Fluorescent',
     2491            80 => 'Day White Fluorescent',
     2492            96 => 'White Fluorescent',
     2493            112 => 'Tungsten',
     2494            128 => 'Flash',
     2495            144 => 'Manual',
     2496            # The three Set Color Temperature settings refer to the 3 preset settings which
     2497            # can be saved in the menu (see page 123 of the K10D manual)
     2498            192 => 'Set Color Temperature 1',
     2499            208 => 'Set Color Temperature 2',
     2500            224 => 'Set Color Temperature 3',
     2501        },
     2502    },
     2503    10.1 => {
     2504        Name => 'MultipleExposureSet',
     2505        Mask => 0x0f,
     2506        PrintConv => {
     2507            0 => 'Off',
     2508            1 => 'On',
     2509        },
     2510    },
     2511    13 => {
     2512        Name => 'RawAndJpgRecording',
     2513        Condition => '$$self{Model} =~ /(K10D|GX10)\b/',
     2514        Notes => 'K10D only',
     2515        # this is actually a bit field: - PH
     2516        # bit 0=JPEG, bit 2=PEF, bit 3=DNG; high nibble: 0x00=best, 0x20=better, 0x40=good
     2517        PrintHex => 1,
     2518        PrintConv => {
     2519            0x01 => 'JPEG (Best)', #PH
     2520            0x04 => 'RAW (PEF, Best)',
     2521            0x05 => 'RAW+JPEG (PEF, Best)',
     2522            0x08 => 'RAW (DNG, Best)', #PH (NC)
     2523            0x09 => 'RAW+JPEG (DNG, Best)', #PH (NC)
     2524            0x21 => 'JPEG (Better)', #PH
     2525            0x24 => 'RAW (PEF, Better)',
     2526            0x25 => 'RAW+JPEG (PEF, Better)', #PH
     2527            0x28 => 'RAW (DNG, Better)', #PH
     2528            0x29 => 'RAW+JPEG (DNG, Better)', #PH (NC)
     2529            0x41 => 'JPEG (Good)',
     2530            0x44 => 'RAW (PEF, Good)', #PH (NC)
     2531            0x45 => 'RAW+JPEG (PEF, Good)', #PH (NC)
     2532            0x48 => 'RAW (DNG, Good)', #PH (NC)
     2533            0x49 => 'RAW+JPEG (DNG, Good)',
     2534            # have seen values of 0,2,34 for other models (not K10D) - PH
     2535        },
     2536    },
     2537    14.1 => { #PH
     2538        Name => 'JpgRecordedPixels',
     2539        Condition => '$$self{Model} =~ /(K10D|GX10)\b/',
     2540        Notes => 'K10D only',
     2541        Mask => 0x03,
     2542        PrintConv => {
     2543            0 => '10 MP',
     2544            1 => '6 MP',
     2545            2 => '2 MP',
     2546        },
     2547    },
     2548    14.2 => { #PH (K-5)
     2549        Name => 'LinkAEToAFPoint',
     2550        Condition => '$$self{Model} =~ /K-5\b/',
     2551        Notes => 'K-5 only',
     2552        Mask => 0x01,
     2553        PrintConv => {
     2554            0x00 => 'Off',
     2555            0x01 => 'On',
     2556        },
     2557    },
     2558    14.3 => { #PH (K-5)
     2559        Name => 'SensitivitySteps',
     2560        Condition => '$$self{Model} =~ /K-5\b/',
     2561        Notes => 'K-5 only',
     2562        Mask => 0x02,
     2563        PrintConv => {
     2564            0x00 => '1 EV Steps',
     2565            0x02 => 'As EV Steps',
     2566        },
     2567    },
     2568    14.4 => { #PH (K-5)
     2569        Name => 'ISOAuto',
     2570        Condition => '$$self{Model} =~ /K-5\b/',
     2571        Notes => 'K-5 only',
     2572        Mask => 0x04,
     2573        PrintConv => {
     2574            0x00 => 'Off',
     2575            0x04 => 'On',
     2576        },
     2577    },
     2578    # 14.5 Mask 0x80 - changes for K-5
     2579    16 => {
     2580        Name => 'FlashOptions2',
     2581        Condition => '$$self{Model} =~ /(K10D|GX10)\b/',
     2582        Notes => 'K10D only; set even if the flash is off',
     2583        Mask => 0xf0,
     2584        # Note: the Normal and Auto values (0x00 to 0x30) do not tags always
     2585        # correlate with the FlashMode, InternalFlashMode and FlashOptions values
     2586        # however, these values seem to better match the K10D's actual functionality
     2587        # (always Auto in Green mode always Normal otherwise if one of the other options
     2588        # isn't selected) - ref 19
     2589        # (these tags relate closely to InternalFlashMode values - PH)
     2590        PrintConv => {
     2591            0x00 => 'Normal', # (this value never occurs in Green Mode) - ref 19
     2592            0x10 => 'Red-eye reduction', # (this value never occurs in Green Mode) - ref 19
     2593            0x20 => 'Auto',  # (this value only occurs in Green Mode) - ref 19
     2594            0x30 => 'Auto, Red-eye reduction', # (this value only occurs in Green Mode) - ref 19
     2595            0x50 => 'Wireless (Master)',
     2596            0x60 => 'Wireless (Control)',
     2597            0x80 => 'Slow-sync',
     2598            0x90 => 'Slow-sync, Red-eye reduction',
     2599            0xa0 => 'Trailing-curtain Sync'
     2600        },
     2601    },
     2602    16.1 => {
     2603        Name => 'MeteringMode3',
     2604        Condition => '$$self{Model} =~ /(K10D|GX10)\b/',
     2605        Notes => 'K10D only',
     2606        Mask => 0x0f,
     2607        PrintConv => {
     2608            0 => 'Multi-segment',
     2609            BITMASK => {
     2610                0 => 'Center-weighted average',
     2611                1 => 'Spot',
     2612            },
     2613        },
     2614    },
     2615    # 16 Mask 0x0f - changes when changing EV steps? (K-5)
     2616    17.1 => {
     2617        Name => 'SRActive',
     2618        Condition => '$$self{Model} =~ /(K10D|GX10)\b/',
     2619        Notes => q{
     2620            K10D only; SR is active only when ShakeReduction is On, DriveMode is not
     2621            Remote or Self-timer, and Internal/ExternalFlashMode is not "On, Wireless"
     2622        },
     2623        Mask => 0x80,
     2624        PrintConv => {
     2625            0x00 => 'No',
     2626            0x80 => 'Yes',
     2627        },
     2628    },
     2629    17.2 => {
     2630        Name => 'Rotation',
     2631        Condition => '$$self{Model} =~ /(K10D|GX10)\b/',
     2632        Notes => 'K10D only',
     2633        Mask => 0x60,
     2634        PrintConv => {
     2635            0x00 => 'Horizontal (normal)',
     2636            0x20 => 'Rotate 180',
     2637            0x40 => 'Rotate 90 CW',
     2638            0x60 => 'Rotate 270 CW',
     2639        },
     2640    },
     2641    # Bit 0x08 is set on 3 of my 3000 shots to (All 3 were Shutter Priority
     2642    # but this may not mean anything with such a small sample) - ref 19
     2643    17.3 => {
     2644        Name => 'ISOSetting',
     2645        Condition => '$$self{Model} =~ /(K10D|GX10)\b/',
     2646        Notes => 'K10D only',
     2647        Mask => 0x04,
     2648        PrintConv => {
     2649            0x00 => 'Manual',
     2650            0x04 => 'Auto',
     2651        },
     2652    },
     2653    17.4 => {
     2654        Name => 'SensitivitySteps',
     2655        Condition => '$$self{Model} =~ /(K10D|GX10)\b/',
     2656        Notes => 'K10D only',
     2657        Mask => 0x02,
     2658        PrintConv => {
     2659            0x00 => '1 EV Steps',
     2660            0x02 => 'As EV Steps',
     2661        },
     2662    },
     2663    # 17 Mask 0x08 - changed when changing Auto ISO range (K-5)
     2664    18 => {
     2665        Name => 'TvExposureTimeSetting',
     2666        Condition => '$$self{Model} =~ /(K10D|GX10)\b/',
     2667        Notes => 'K10D only',
     2668        ValueConv => 'exp(-Image::ExifTool::Pentax::PentaxEv($val-68)*log(2))',
     2669        ValueConvInv => 'Image::ExifTool::Pentax::PentaxEvInv(-log($val)/log(2))+68',
     2670        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     2671        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     2672    },
     2673    19 => {
     2674        Name => 'AvApertureSetting',
     2675        Condition => '$$self{Model} =~ /(K10D|GX10)\b/',
     2676        Notes => 'K10D only',
     2677        ValueConv => 'exp(Image::ExifTool::Pentax::PentaxEv($val-68)*log(2)/2)',
     2678        ValueConvInv => 'Image::ExifTool::Pentax::PentaxEvInv(log($val)*2/log(2))+68',
     2679        PrintConv => 'sprintf("%.1f",$val)',
     2680        PrintConvInv => '$val',
     2681    },
     2682    20 => { #PH
     2683        Name => 'SvISOSetting',
     2684        Condition => '$$self{Model} =~ /(K10D|GX10)\b/',
     2685        Notes => 'K10D only',
     2686        # ISO setting for sensitivity-priority mode
     2687        # (conversion may not give actual displayed values:)
     2688        # 32 => 100, 35 => 125, 36 => 140, 37 => 160,
     2689        # 40 => 200, 43 => 250, 44 => 280, 45 => 320,
     2690        # 48 => 400, 51 => 500, 52 => 560, 53 => 640,
     2691        # 56 => 800, 59 => 1000,60 => 1100,61 => 1250, 64 => 1600
     2692        ValueConv => 'int(100*exp(Image::ExifTool::Pentax::PentaxEv($val-32)*log(2))+0.5)',
     2693        ValueConvInv => 'Image::ExifTool::Pentax::PentaxEvInv(log($val/100)/log(2))+32',
     2694    },
     2695    21 => { #PH
     2696        Name => 'BaseExposureCompensation',
     2697        Condition => '$$self{Model} =~ /(K10D|GX10)\b/',
     2698        Notes => 'K10D only; exposure compensation without auto bracketing',
     2699        ValueConv => 'Image::ExifTool::Pentax::PentaxEv(64-$val)',
     2700        ValueConvInv => '64-Image::ExifTool::Pentax::PentaxEvInv($val)',
     2701        PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
     2702        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    12612703    },
    12622704);
     
    12642706# auto-exposure information (ref PH)
    12652707%Image::ExifTool::Pentax::AEInfo = (
    1266     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1267     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1268     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     2708    %binaryDataAttrs,
    12692709    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    1270     WRITABLE => 1,
    1271     FIRST_ENTRY => 0,
     2710    DATAMEMBER => [ 8 ],
     2711    # instead of /8, should these be PentaxEV(), as in CameraSettings? - PH
    12722712    0 => {
    12732713        Name => 'AEExposureTime',
     
    12762716        ValueConvInv => '-log($val/24)*8/log(2)+32',
    12772717        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    1278         PrintConvInv => 'eval $val',
     2718        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    12792719    },
    12802720    1 => {
    12812721        Name => 'AEAperture',
    1282         Notes => 'val = (2**((raw-4)/16)) / 16',
    1283         # (same as val=2**((raw-68)/16), but 68 isn't a nice power of 2)
    1284         ValueConv => 'exp(($val-4)*log(2)/16)/16',
    1285         ValueConvInv => 'log($val*16)*16/log(2)+4',
     2722        Notes => 'val = 2**((raw-68)/16)',
     2723        ValueConv => 'exp(($val-68)*log(2)/16)',
     2724        ValueConvInv => 'log($val)*16/log(2)+68',
    12862725        PrintConv => 'sprintf("%.1f",$val)',
    12872726        PrintConvInv => '$val',
     
    13052744        Format => 'int8s',
    13062745        Notes => 'val = raw / 8',
    1307         ValueConv => '$val/8',
     2746        ValueConv => '$val / 8',
    13082747        ValueConvInv => '$val * 8',
    13092748    },
    13102749    5 => {
    1311         Name => 'AEFlashTv',
     2750        Name => 'AEMinExposureTime', #19
    13122751        Notes => 'val = 24 * 2**((32-raw)/8)',
    1313         ValueConv => '24*exp(-($val-32)*log(2)/8)', #19
     2752        ValueConv => '24*exp(-($val-32)*log(2)/8)', #JD
    13142753        ValueConvInv => '-log($val/24)*8/log(2)+32',
    13152754        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    1316         PrintConvInv => 'eval $val',
     2755        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    13172756    },
    13182757    6 => {
    13192758        Name => 'AEProgramMode',
    1320         PrintConv => {
    1321             0 => 'Manual/Program AE',
    1322             1 => 'Aperture Priority/Bulb',
    1323             2 => 'Shutter Speed Priority',
    1324             3 => 'Program',
     2759        PrintConvColumns => 2,
     2760        PrintConv => {
     2761            0 => 'M, P or TAv',
     2762            1 => 'Av, B or X',
     2763            2 => 'Tv',
     2764            3 => 'Sv or Green Mode',
     2765            8 => 'Hi-speed Program',
     2766            11 => 'Hi-speed Program (P-Shift)', #19
     2767            16 => 'DOF Program', #19
     2768            19 => 'DOF Program (P-Shift)', #19
     2769            24 => 'MTF Program', #19
     2770            27 => 'MTF Program (P-Shift)', #19
    13252771            35 => 'Standard',
    13262772            43 => 'Portrait',
     
    13382784            139 => 'Candlelight',
    13392785            147 => 'Museum',
     2786            184 => 'Shallow DOF Program', # (K-5)
    13402787        },
    13412788    },
    13422789    7 => {
    1343         Name => 'AEExtra',
     2790        Name => 'AEFlags',
    13442791        Unknown => 1,
     2792        Writable => 0,
     2793        PrintConv => { #19
     2794            # (seems to be the warnings displayed in the viewfinder for several bits)
     2795            BITMASK => {
     2796                # 0 - seen in extreme low light conditions (e.g. Lens Cap On)
     2797                # 1 - seen in 2 cases, Aperture Priority mode, Auto ISO at 100,
     2798                #     Shutter speed at 1/4000 and aperture opened wider causing under exposure
     2799                # 2 - only (but not always) set in Shutter Speed Priority (seems to be when over/under exposed).
     2800                #     In one case set when auto exposure compensation changed the Tv from 1/250 to 1/80.
     2801                #     In another case set when external flash was in SB mode so did not fire.
     2802                3 => 'AE lock',
     2803                4 => 'Flash recommended?', # not 100% sure of this one
     2804                # 5 - seen lots...
     2805                # 6 - seen lots...
     2806                7 => 'Aperture wide open', # mostly true...  (Set for all my lenses except for DA* 16-50mm)
     2807            },
     2808        },
     2809    },
     2810    8 => {
     2811        Name => 'AEUnknown',
     2812        Notes => 'indices after this are incremented by 1 for some models',
     2813        Format => 'var_int8u[$size > 20 ? 2 : 1]',
     2814        Writable => 0,
     2815        # (this tag can't be unknown because the Format must be evaluated
     2816        #  to shift the following offsets if necessary.  Instead, ignore
     2817        #  the return value unless Unknown > 1)
     2818        RawConv => '$$self{OPTIONS}{Unknown} > 1 ? $val : undef',
     2819    },
     2820    # Note: Offsets below shifted by 1 if record size is > 20 bytes
     2821    # (implemented by the var_int8u count above)
     2822    9 => { #19
     2823        Name => 'AEMaxAperture',
     2824        Notes => 'val = 2**((raw-68)/16)',
     2825        ValueConv => 'exp(($val-68)*log(2)/16)',
     2826        ValueConvInv => 'log($val)*16/log(2)+68',
     2827        PrintConv => 'sprintf("%.1f",$val)',
     2828        PrintConvInv => '$val',
     2829    },
     2830    10 => { #19
     2831        Name => 'AEMaxAperture2',
     2832        Notes => 'val = 2**((raw-68)/16)',
     2833        ValueConv => 'exp(($val-68)*log(2)/16)',
     2834        ValueConvInv => 'log($val)*16/log(2)+68',
     2835        PrintConv => 'sprintf("%.1f",$val)',
     2836        PrintConvInv => '$val',
     2837    },
     2838    11 => { #19
     2839        Name => 'AEMinAperture',
     2840        Notes => 'val = 2**((raw-68)/16)',
     2841        ValueConv => 'exp(($val-68)*log(2)/16)',
     2842        ValueConvInv => 'log($val)*16/log(2)+68',
     2843        PrintConv => 'sprintf("%.0f",$val)',
     2844        PrintConvInv => '$val',
     2845    },
     2846    12 => { #19
     2847        Name => 'AEMeteringMode',
     2848        PrintConv => {
     2849            0 => 'Multi-segment',
     2850            BITMASK => {
     2851                4 => 'Center-weighted average',
     2852                5 => 'Spot',
     2853            },
     2854        },
     2855    },
     2856    # 13 - related to program mode somehow - PH
     2857    14 => { #19
     2858        Name => 'FlashExposureCompSet',
     2859        Format => 'int8s',
     2860        Notes => q{
     2861            reports the camera setting, unlike tag 0x004d which reports 0 in Green mode
     2862            or if flash was on but did not fire.  Both this tag and 0x004d report the
     2863            setting even if the flash is off
     2864        },
     2865        ValueConv => 'Image::ExifTool::Pentax::PentaxEv($val)',
     2866        ValueConvInv => 'Image::ExifTool::Pentax::PentaxEvInv($val)',
     2867        PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
     2868        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    13452869    },
    13462870);
     
    13482872# lens information (ref PH)
    13492873%Image::ExifTool::Pentax::LensInfo = (
    1350     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1351     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1352     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     2874    %binaryDataAttrs,
    13532875    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    1354     WRITABLE => 1,
    1355     FIRST_ENTRY => 0,
    1356     # (must decode focus distance!)
     2876    IS_SUBDIR => [ 3 ],
     2877    NOTES => 'Pentax lens information structure for models such as the *istD.',
     2878    0 => {
     2879        Name => 'LensType',
     2880        Format => 'int8u[2]',
     2881        Priority => 0,
     2882        PrintConv => \%pentaxLensTypes,
     2883        SeparateTable => 1,
     2884    },
     2885    3 => {
     2886        Name => 'LensData',
     2887        Format => 'undef[17]',
     2888        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensData' },
     2889    },
     2890);
     2891
     2892# lens information for newer models (ref PH)
     2893%Image::ExifTool::Pentax::LensInfo2 = (
     2894    %binaryDataAttrs,
     2895    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2896    IS_SUBDIR => [ 4 ],
     2897    NOTES => 'Pentax lens information structure for models such as the K10D and K20D.',
    13572898    0 => {
    13582899        Name => 'LensType',
    13592900        Format => 'int8u[4]',
    13602901        Priority => 0,
    1361         Notes => q{
    1362             for most models the first 2 bytes are LensType, but for the K10D the
    1363             decoding is a bit different
    1364         },
    1365         # this is a bit funny and needs testing with more lenses on the K10D
    13662902        ValueConv => q{
    13672903            my @v = split(' ',$val);
    1368             if ($v[0] & 0xf0 or $$self{CameraModel} =~ /^PENTAX K10D\b/) {
    1369                 $v[0] &= 0x0f;
    1370                 $v[1] = GetByteOrder() eq 'MM' ? $v[2] * 256 + $v[3] : $v[3] * 256 + $v[2];
     2904            $v[0] &= 0x0f;
     2905            $v[1] = $v[2] * 256 + $v[3]; # (always high byte first)
     2906            return "$v[0] $v[1]";
     2907        },
     2908        PrintConv => \%pentaxLensTypes,
     2909        SeparateTable => 1,
     2910    },
     2911    4 => {
     2912        Name => 'LensData',
     2913        Format => 'undef[17]',
     2914        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensData' },
     2915    },
     2916);
     2917
     2918# lens information for 645D (ref PH)
     2919%Image::ExifTool::Pentax::LensInfo3 = (
     2920    %binaryDataAttrs,
     2921    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2922    IS_SUBDIR => [ 13 ],
     2923    NOTES => 'Pentax lens information structure for 645D.',
     2924    1 => {
     2925        Name => 'LensType',
     2926        Format => 'int8u[4]',
     2927        Priority => 0,
     2928        ValueConv => q{
     2929            my @v = split(' ',$val);
     2930            $v[0] &= 0x0f;
     2931            $v[1] = $v[2] * 256 + $v[3]; # (always high byte first)
     2932            return "$v[0] $v[1]";
     2933        },
     2934        PrintConv => \%pentaxLensTypes,
     2935        SeparateTable => 1,
     2936    },
     2937    13 => {
     2938        Name => 'LensData',
     2939        Format => 'undef[17]',
     2940        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensData' },
     2941    },
     2942);
     2943
     2944# lens information for K-5, K-r, etc (ref PH)
     2945%Image::ExifTool::Pentax::LensInfo4 = (
     2946    %binaryDataAttrs,
     2947    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2948    IS_SUBDIR => [ 12 ],
     2949    NOTES => 'Pentax lens information structure for models such as the K-5 and K-r.',
     2950    1 => {
     2951        Name => 'LensType',
     2952        Format => 'int8u[4]',
     2953        Priority => 0,
     2954        ValueConv => q{
     2955            my @v = split(' ',$val);
     2956            $v[0] &= 0x0f;
     2957            $v[1] = $v[2] * 256 + $v[3]; # (always high byte first)
     2958            return "$v[0] $v[1]";
     2959        },
     2960        PrintConv => \%pentaxLensTypes,
     2961        SeparateTable => 1,
     2962    },
     2963    12 => {
     2964        Name => 'LensData',
     2965        Format => 'undef[17]',
     2966        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensData' },
     2967    },
     2968);
     2969
     2970# lens data information, including lens codes (ref PH)
     2971%Image::ExifTool::Pentax::LensData = (
     2972    %binaryDataAttrs,
     2973    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     2974    NOTES => q{
     2975        Pentax lens data information.  Some of these tags require interesting binary
     2976        gymnastics to decode them into useful values.
     2977    },
     2978    # this byte comes from the lens electrical contacts
     2979    # (see http://kmp.bdimitrov.de/technology/K-mount/Ka.html)
     2980    0.1 => { #JD
     2981        Name => 'AutoAperture',
     2982        Mask => 0x01,
     2983        PrintConv => {
     2984            0 => 'On',
     2985            1 => 'Off',
     2986        },
     2987    },
     2988    0.2 => { #JD
     2989        Name => 'MinAperture',
     2990        Mask => 0x06,
     2991        PrintConv => {
     2992            0x00 => 22,
     2993            0x02 => 32,
     2994            0x04 => 45,
     2995            0x06 => 16,
     2996        },
     2997    },
     2998    0.3 => { #JD
     2999        Name => 'LensFStops',
     3000        Mask => 0x70,
     3001        ValueConv => '5 + (($val >> 4) ^ 0x07) / 2',
     3002        ValueConvInv => '((($val - 5) * 2) ^ 0x07) << 4',
     3003    },
     3004    # 1-16 look like Lens Codes LC0-LC15, ref patent 5617173 and 5999753 [+notes by PH]
     3005    1 => { # LC0 = lens kind + version data
     3006        Name => 'LensKind',
     3007        %lensCode,
     3008    },
     3009    2 => { # LC1 = lens data (changes with AF setting)
     3010        Name => 'LC1',
     3011        %lensCode,
     3012    },
     3013    3 => { # LC2 = distance data
     3014        Name => 'LC2',
     3015        %lensCode,
     3016        # FocusRange decoding needs more testing with various lenses - PH
     3017        TestName => 'FocusRange',
     3018        TestPrintConv => q{
     3019            my @v;
     3020            my $lsb = $val & 0x07;
     3021            my $msb = $val >> 3;
     3022            my $ls2 = $lsb ^ 0x07;
     3023            $ls2 ^= 0x01 if $ls2 & 0x02;
     3024            $ls2 ^= 0x03 if $ls2 & 0x04;
     3025            foreach ($ls2, $ls2+1) {
     3026                push(@v,'inf'), next if $_ > 7;
     3027                push @v, sprintf("%.2f m", 2 ** ($msb / 4) * 0.18 * ($_ + 4) / 16);
    13713028            }
    1372             return "$v[0] $v[1]";
    1373         },
    1374         PrintConv => \%pentaxLensType,
    1375         SeparateTable => 1,
    1376     },
    1377     4 => {
    1378         Condition => '$$self{CameraModel} !~ /K10D/',
    1379         Name => 'LensCodes',
    1380         Format => 'int8u[16]',
    1381         Notes => 'all models but the K10D',
    1382     },
    1383     5 => {
    1384         Condition => '$$self{CameraModel} =~ /K10D/',
    1385         Name => 'LensCodes',
    1386         Format => 'int8u[16]',
    1387         Notes => 'K10D only',
     3029            return join ' - ', @v;
     3030        },
     3031    },
     3032    4 => { # LC3 = K-value data (AF pulses to displace image by unit length)
     3033        Name => 'LC3',
     3034        %lensCode,
     3035    },
     3036    5 => { # LC4 = abberation correction, near distance data
     3037        Name => 'LC4',
     3038        %lensCode,
     3039    },
     3040    6 => { # LC5 = light color abberation correction data
     3041        Name => 'LC5',
     3042        %lensCode,
     3043    },
     3044    7 => { # LC6 = open abberation data
     3045        Name => 'LC6',
     3046        %lensCode,
     3047    },
     3048    8 => { # LC7 = AF minimum actuation condition
     3049        Name => 'LC7',
     3050        %lensCode,
     3051    },
     3052    9 => { # LC8 = focal length data
     3053        Name => 'FocalLength',
     3054        Priority => 0,
     3055        ValueConv => '10*($val>>2) * 4**(($val&0x03)-2)', #JD
     3056        ValueConvInv => q{
     3057            my $range = int(log($val/10)/(2*log(2)));
     3058            warn("Value out of range") and return undef if $range < 0 or $range > 3;
     3059            return $range + (int($val/(10*4**($range-2))+0.5) << 2);
     3060        },
     3061        PrintConv => 'sprintf("%.1f mm", $val)',
     3062        PrintConvInv => '$val=~s/\s*mm//; $val',
     3063    },
     3064    # the following aperture values change with focal length
     3065    10 => { # LC9 = nominal AVmin/AVmax data (open/closed aperture values)
     3066        Name => 'NominalMaxAperture',
     3067        Mask => 0xf0,
     3068        ValueConv => '2**(($val>>4)/4)', #JD
     3069        ValueConvInv => '4*log($val)/log(2) << 4',
     3070        PrintConv => 'sprintf("%.1f", $val)',
     3071        PrintConvInv => '$val',
     3072    },
     3073    10.1 => { # LC9 = nominal AVmin/AVmax data (open/closed aperture values)
     3074        Name => 'NominalMinAperture',
     3075        Mask => 0x0f,
     3076        ValueConv => '2**(($val+10)/4)', #JD
     3077        ValueConvInv => '4*log($val)/log(2) - 10',
     3078        PrintConv => 'sprintf("%.0f", $val)',
     3079        PrintConvInv => '$val',
     3080    },
     3081    11 => { # LC10 = mv'/nv' data (full-aperture metering error compensation/marginal lumination compensation)
     3082        Name => 'LC10',
     3083        %lensCode,
     3084    },
     3085    12 => { # LC11 = AVC 1/EXP data
     3086        Name => 'LC11',
     3087        %lensCode,
     3088    },
     3089    13 => { # LC12 = mv1 AVminsif data
     3090        Name => 'LC12',
     3091        %lensCode,
     3092    },
     3093    14.1 => { # LC13 = AVmin (open aperture value) [MaxAperture=(2**((AVmin-1)/32))]
     3094        Name => 'MaxAperture',
     3095        Notes => 'effective wide open aperture for current focal length',
     3096        Mask => 0x7f, # (not sure what the high bit indicates)
     3097        # (a value of 1 seems to indicate 'n/a')
     3098        RawConv => '$val > 1 ? $val : undef',
     3099        ValueConv => '2**(($val-1)/32)',
     3100        ValueConvInv => '32*log($val)/log(2) + 1',
     3101        PrintConv => 'sprintf("%.1f", $val)',
     3102        PrintConvInv => '$val',
     3103    },
     3104    15 => { # LC14 = UNT_12 UNT_6 data
     3105        Name => 'LC14',
     3106        %lensCode,
     3107    },
     3108    16 => { # LC15 = incorporated flash suited END data
     3109        Name => 'LC15',
     3110        %lensCode,
    13883111    },
    13893112);
     
    13913114# flash information (ref PH)
    13923115%Image::ExifTool::Pentax::FlashInfo = (
    1393     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1394     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1395     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3116    %binaryDataAttrs,
    13963117    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    1397     WRITABLE => 1,
    1398     FIRST_ENTRY => 0,
    1399     0 => 'FlashStatus',
     3118    NOTES => 'Flash information tags for the K10D, K20D and K200D.',
     3119    0 => {
     3120        Name => 'FlashStatus',
     3121        PrintHex => 1,
     3122        PrintConv => { #19
     3123            0x00 => 'Off',
     3124            0x01 => 'Off (1)', #PH (K-5)
     3125            0x02 => 'External, Did not fire', # 0010
     3126            0x06 => 'External, Fired',        # 0110
     3127            0x08 => 'Internal, Did not fire (0x08)',
     3128            0x09 => 'Internal, Did not fire', # 1001
     3129            0x0d => 'Internal, Fired',        # 1101
     3130        },
     3131    },
    14003132    1 => {
    1401         Name => 'FlashModeCode',
    1402         PrintConv => {
    1403             149 => 'On, Wireless', # K10D
    1404             192 => 'On', # K10D
    1405             193 => 'On, Red-eye reduction', # *istDS2, K10D
    1406             194 => 'Auto, Fired', # K100D, K110D
    1407             200 => 'On, Slow-sync', # K10D
    1408             201 => 'On, Slow-sync, Red-eye reduction', # K10D
    1409             202 => 'On, Trailing-curtain Sync', # K10D
    1410             240 => 'Off (240)', # *istD, *istDS, K100D, K10D
    1411             241 => 'Off (241)', # *istDL
    1412             242 => 'Off (242)', # *istDS, *istDL2, K100D, K110D
    1413             244 => 'Off (244)', # K100D, K110D (either "Auto, Did not fire" or "Off")
    1414         },
    1415     },
    1416     2 => 'ExternalFlashMode',
    1417     3 => 'InternalFlashMagni',
     3133        Name => 'InternalFlashMode',
     3134        PrintHex => 1,
     3135        PrintConv => {
     3136            0x00 => 'n/a - Off-Auto-Aperture', #19
     3137            0x86 => 'Fired, Wireless (Control)', #19
     3138            0x95 => 'Fired, Wireless (Master)', #19
     3139            0xc0 => 'Fired', # K10D
     3140            0xc1 => 'Fired, Red-eye reduction', # *istDS2, K10D
     3141            0xc2 => 'Fired, Auto', # K100D, K110D
     3142            0xc3 => 'Fired, Auto, Red-eye reduction', #PH
     3143            0xc6 => 'Fired, Wireless (Control), Fired normally not as control', #19 (Remote 3s)
     3144            0xc8 => 'Fired, Slow-sync', # K10D
     3145            0xc9 => 'Fired, Slow-sync, Red-eye reduction', # K10D
     3146            0xca => 'Fired, Trailing-curtain Sync', # K10D
     3147            0xf0 => 'Did not fire, Normal', #19
     3148            0xf1 => 'Did not fire, Red-eye reduction', #19
     3149            0xf2 => 'Did not fire, Auto', #19
     3150            0xf3 => 'Did not fire, Auto, Red-eye reduction', #19
     3151            0xf4 => 'Did not fire, (Unknown 0xf4)', #19
     3152            0xf5 => 'Did not fire, Wireless (Master)', #19
     3153            0xf6 => 'Did not fire, Wireless (Control)', #19
     3154            0xf8 => 'Did not fire, Slow-sync', #19
     3155            0xf9 => 'Did not fire, Slow-sync, Red-eye reduction', #19
     3156            0xfa => 'Did not fire, Trailing-curtain Sync', #19
     3157        },
     3158    },
     3159    2 => {
     3160        Name => 'ExternalFlashMode',
     3161        PrintHex => 1,
     3162        PrintConv => { #19
     3163            0x00 => 'n/a - Off-Auto-Aperture',
     3164            0x3f => 'Off',
     3165            0x40 => 'On, Auto',
     3166            0xbf => 'On, Flash Problem', #JD
     3167            0xc0 => 'On, Manual',
     3168            0xc4 => 'On, P-TTL Auto',
     3169            0xc5 => 'On, Contrast-control Sync', #JD
     3170            0xc6 => 'On, High-speed Sync',
     3171            0xcc => 'On, Wireless',
     3172            0xcd => 'On, Wireless, High-speed Sync',
     3173            0xf0 => 'Not Connected', #PH (K-5)
     3174        },
     3175    },
     3176    3 => {
     3177        Name => 'InternalFlashStrength',
     3178        Notes => 'saved from the most recent flash picture, on a scale of about 0 to 100',
     3179    },
    14183180    4 => 'TTL_DA_AUp',
    14193181    5 => 'TTL_DA_ADown',
    14203182    6 => 'TTL_DA_BUp',
    14213183    7 => 'TTL_DA_BDown',
    1422     # ? => 'ExternalFlashMagniA',
    1423     # ? => 'ExternalFlashMagniB',
     3184    24.1 => { #19/17
     3185        Name => 'ExternalFlashGuideNumber',
     3186        Mask => 0x1f,
     3187        Notes => 'val = 2**(raw/16 + 4), with a few exceptions',
     3188        ValueConv => q{
     3189            return 0 unless $val;
     3190            $val = -3 if $val == 29;  # -3 is stored as 0x1d
     3191            return 2**($val/16 + 4);
     3192        },
     3193        ValueConvInv => q{
     3194            return 0 unless $val;
     3195            my $raw = int((log($val)/log(2)-4)*16+0.5);
     3196            $raw = 29 if $raw < 0;   # guide number of 14 gives -3 which is stored as 0x1d
     3197            $raw = 31 if $raw > 31;  # maximum value is 0x1f
     3198            return $raw;
     3199        },
     3200        PrintConv => '$val ? int($val + 0.5) : "n/a"',
     3201        PrintConvInv => '$val=~/^n/ ? 0 : $val',
     3202        # observed values for various flash focal lengths/guide numbers:
     3203        #  AF-540FGZ (ref 19)  AF-360FGZ (ref 17)
     3204        #     6 => 20mm/21       29 => 20mm/14   (wide angle panel used)
     3205        #    16 => 24mm/32        6 => 24mm/21
     3206        #    18 => 28mm/35        7 => 28mm/22
     3207        #    21 => 35mm/39       10 => 35mm/25
     3208        #    24 => 50mm/45       14 => 50mm/30
     3209        #    26 => 70mm/50       17 => 70mm/33
     3210        #    28 => 85mm/54       19 => 85mm/36
     3211        # (I have also seen a value of 31 when both flashes are used together
     3212        # in a wired configuration, but I don't know exactly what this means - PH)
     3213    },
     3214    # 24 - have seen bit 0x80 set when 2 external wired flashes are used - PH
     3215    # 24 - have seen bit 0x40 set when wireless high speed sync is used - ref 19
     3216    25 => { #19
     3217        Name => 'ExternalFlashExposureComp',
     3218        PrintConv => {
     3219            0 => 'n/a', # Off or Auto Modes
     3220            144 => 'n/a (Manual Mode)', # Manual Flash Output
     3221            164 => '-3.0',
     3222            167 => '-2.5',
     3223            168 => '-2.0',
     3224            171 => '-1.5',
     3225            172 => '-1.0',
     3226            175 => '-0.5',
     3227            176 => '0.0',
     3228            179 => '0.5',
     3229            180 => '1.0',
     3230        },
     3231    },
     3232    26 => { #17
     3233        Name => 'ExternalFlashBounce',
     3234        Notes => 'saved from the most recent external flash picture', #19
     3235        PrintConv => {
     3236             0 => 'n/a',
     3237            16 => 'Direct',
     3238            48 => 'Bounce',
     3239        },
     3240    },
     3241    # ? => 'ExternalFlashAOutput',
     3242    # ? => 'ExternalFlashBOutput',
     3243);
     3244
     3245%Image::ExifTool::Pentax::FlashInfoUnknown = (
     3246    %binaryDataAttrs,
     3247    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3248    # 4 - changes with FEC for K-5 - PH
    14243249);
    14253250
    14263251# camera manufacture information (ref PH)
    14273252%Image::ExifTool::Pentax::CameraInfo = (
    1428     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1429     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1430     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3253    %binaryDataAttrs,
    14313254    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    1432     WRITABLE => 1,
    1433     FIRST_ENTRY => 0,
    14343255    FORMAT => 'int32u',
    14353256    0 => {
     
    14373258        Priority => 0, # (Optio SVi uses incorrect Optio SV ID here)
    14383259        SeparateTable => 1,
     3260        PrintHex => 1,
    14393261        PrintConv => \%pentaxModelID,
    14403262    },
    14413263    1 => {
    14423264        Name => 'ManufactureDate',
     3265        Groups => { 2 => 'Time' },
     3266        Notes => q{
     3267            this value, and the values of the tags below, may change if the camera is
     3268            serviced
     3269        },
    14433270        ValueConv => q{
    14443271            $val =~ /^(\d{4})(\d{2})(\d{2})$/ and return "$1:$2:$3";
     
    14503277    },
    14513278    2 => {
    1452         Name => 'ModelRevision',
     3279        #(see http://www.pentaxforums.com/forums/pentax-dslr-discussion/25711-k10d-update-model-revision-8-1-yes-no-8.html)
     3280        Name => 'ProductionCode', #(previously ModelRevision)
    14533281        Format => 'int32u[2]',
     3282        Note => 'values of 8.x indicate that the camera has been serviced',
    14543283        ValueConv => '$val=~tr/ /./; $val',
    14553284        ValueConvInv => '$val=~tr/./ /; $val',
     3285        PrintConv => '$val=~/^8\./ ? "$val (camera has been serviced)" : $val',
     3286        PrintConvInv => '$val=~s/\s+.*//s; $val',
    14563287    },
    14573288    4 => 'InternalSerialNumber',
     
    14603291# battery information (ref PH)
    14613292%Image::ExifTool::Pentax::BatteryInfo = (
    1462     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1463     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1464     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3293    %binaryDataAttrs,
    14653294    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    1466     WRITABLE => 1,
    1467     FIRST_ENTRY => 0,
    1468     0 => {
    1469         Name => 'BatteryType',
    1470         ValueConv => '$val & 0x7f',
    1471         ValueConvInv => '$val | 0x80',  # (not sure what this bit means)
    1472     },
    1473     1 => {
    1474         Name => 'BatteryBodyGripStates',
    1475         Notes => 'body and grip battery state',
    1476         ValueConv => '($val >> 4) . " " . ($val & 0x0f)',
    1477         ValueConvInv => 'my @a=split(" ",$val); ($a[0] << 4) + $a[1]',
    1478     },
     3295# size of data:
     3296# 4 (K-m,K2000=4xAA), 6 (*istD,K10D,K100D,K110D=2xCR-V3/4xAA),
     3297# 7 (K20D=D-LI50, K200D=4xAA), 8 (645D=D-LI90), 10 (K-r pre-production?),
     3298# 14 (K-7=D-LI90, K-r=D-LI109/4xAA, K-x=4xAA), 26 (K-5=D-LI90)
     3299# battery grips available for:
     3300# BG1 (*istD), BG2 (K10D/K20D), BG3 (K200D), BG4 (K-7,K-5)
     3301# no grip available: K-x
     3302    0.1 => { #19
     3303        Name => 'PowerSource',
     3304        Mask => 0x0f,
     3305        # have seen the upper bit set (value of 0x82) for the
     3306        # *istDS and K100D, but I'm not sure what this means - PH
     3307        # I've also seen: 0x42 (K2000), 0xf2 (K-7,K-r,K-5), 0x12,0x22 (K-x) - PH
     3308        PrintConv => {
     3309            2 => 'Body Battery',
     3310            3 => 'Grip Battery',
     3311            4 => 'External Power Supply', #PH
     3312        },
     3313    },
     3314    1.1 => [
     3315        {
     3316            Name => 'BodyBatteryState',
     3317            Condition => '$$self{Model} =~ /(\*ist|K100D|K200D|K10D|GX10|K20D|GX20)\b/',
     3318            Notes => '*istD, K100D, K200D, K10D and K20D',
     3319            Mask => 0xf0,
     3320            PrintConv => { #19
     3321                 0x10 => 'Empty or Missing',
     3322                 0x20 => 'Almost Empty',
     3323                 0x30 => 'Running Low',
     3324                 0x40 => 'Full',
     3325            },
     3326        },{
     3327            Name => 'BodyBatteryState',
     3328            Condition => '$$self{Model} =~ /(K-5|K-7|K-r|K-x|645D)\b/',
     3329            Notes => 'K-5, K-7, K-r, K-x and 645D',
     3330            Mask => 0xf0,
     3331            PrintConv => {
     3332                 0x10 => 'Empty or Missing',
     3333                 0x20 => 'Almost Empty',
     3334                 0x30 => 'Running Low',
     3335                 0x40 => 'Close to Full',
     3336                 0x50 => 'Full',
     3337            },
     3338        },{
     3339            Name => 'BodyBatteryState',
     3340            Notes => 'decoding unknown for other models',
     3341            Mask => 0xf0,
     3342            ValueConv => '$val >> 4',
     3343            ValueConvInv => '$val << 4',
     3344        },
     3345    ],
     3346    1.2 => [
     3347        {
     3348            Name => 'GripBatteryState',
     3349            Condition => '$$self{Model} =~ /(K10D|GX10|K20D|GX20)\b/',
     3350            Notes => 'K10D and K20D',
     3351            Mask => 0x0f,
     3352            PrintConv => { #19
     3353                 0x01 => 'Empty or Missing',
     3354                 0x02 => 'Almost Empty',
     3355                 0x03 => 'Running Low',
     3356                 0x04 => 'Full',
     3357            },
     3358        },{
     3359            Name => 'GripBatteryState',
     3360            Notes => 'decoding unknown for other models',
     3361            Unknown => 1, # (doesn't appear to be valid for the K-5)
     3362            Mask => 0x0f,
     3363        },
     3364    ],
    14793365    # internal and grip battery voltage Analogue to Digital measurements,
    14803366    # open circuit and under load
    1481     2 => 'BatteryADBodyNoLoad',
    1482     3 => 'BatteryADBodyLoad',
    1483     4 => 'BatteryADGripNoLoad',
    1484     5 => 'BatteryADGripLoad',
     3367    2 => [
     3368        {
     3369            Name => 'BodyBatteryADNoLoad',
     3370            Description => 'Body Battery A/D No Load',
     3371            Condition => '$$self{Model} =~ /(K10D|GX10|K20D|GX20)\b/',
     3372            Notes => 'roughly calibrated for K10D with a new Pentax battery',
     3373            # rough linear calibration drops quickly below 30% - PH
     3374            # DVM readings: 8.18V=186, 8.42-8.40V=192 (full), 6.86V=155 (empty)
     3375            PrintConv => 'sprintf("%d (%.1fV, %d%%)",$val,$val*8.18/186,($val-155)*100/35)',
     3376            PrintConvInv => '$val=~s/ .*//; $val',
     3377        },
     3378        {
     3379            Name => 'BodyBatteryADNoLoad',
     3380            Description => 'Body Battery A/D No Load',
     3381            Condition => '$$self{Model} =~ /(\*ist|K100D|K200D)\b/',
     3382        },
     3383        {
     3384            Name => 'BodyBatteryVoltage1', # (static?)
     3385            Condition => '$$self{Model} =~ /(K-5|K-7|K-r|K-x|645D)\b/',
     3386            Format => 'int16u',
     3387            ValueConv => '$val / 100',
     3388            ValueConvInv => '$val * 100',
     3389            PrintConv => 'sprintf("%.2f V", $val)',
     3390            PrintConvInv => '$val =~ s/\s*V$//',
     3391            # For my K-5:          Min (0%) Max (100%) Meas
     3392            # BodyBatteryVoltage1  6.24 V   7.75 V     7.66 V
     3393            # BodyBatteryVoltage2  5.98 V   7.43 V     7.34 V
     3394            # BodyBatteryVoltage3  6.41 V   7.93 V     7.84 V
     3395            # BodyBatteryVoltage4  6.10 V   7.55 V     7.45 V
     3396            # "Meas" open-circuit voltages with DVM: AB=0V, AC=+8.33V, BC=+8.22V
     3397            # (terminal "C" is closest to edge of battery)
     3398        },
     3399    ],
     3400    3 => [
     3401        {
     3402            Name => 'BodyBatteryADLoad',
     3403            Description => 'Body Battery A/D Load',
     3404            Condition => '$$self{Model} =~ /(K10D|GX10|K20D|GX20)\b/',
     3405            Notes => 'roughly calibrated for K10D with a new Pentax battery',
     3406            # [have seen 187] - PH
     3407            PrintConv => 'sprintf("%d (%.1fV, %d%%)",$val,$val*8.18/186,($val-152)*100/34)',
     3408            PrintConvInv => '$val=~s/ .*//; $val',
     3409        },
     3410        {
     3411            Name => 'BodyBatteryADLoad',
     3412            Description => 'Body Battery A/D Load',
     3413            Condition => '$$self{Model} =~ /(\*ist|K100D|K200D)\b/',
     3414        },
     3415    ],
     3416    4 => [
     3417        {
     3418            Name => 'GripBatteryADNoLoad',
     3419            Description => 'Grip Battery A/D No Load',
     3420            Condition => '$$self{Model} =~ /(\*ist|K10D|GX10|K20D|GX20)\b/',
     3421        },
     3422        {
     3423            Name => 'BodyBatteryVoltage2', # (less than BodyBatteryVoltage1 -- under load?)
     3424            Condition => '$$self{Model} =~ /(K-5|K-7|K-r|K-x|645D)\b/',
     3425            Format => 'int16u',
     3426            ValueConv => '$val / 100',
     3427            ValueConvInv => '$val * 100',
     3428            PrintConv => 'sprintf("%.2f V", $val)',
     3429            PrintConvInv => '$val =~ s/\s*V$//',
     3430        },
     3431    ],
     3432    5 => {
     3433        Name => 'GripBatteryADLoad',
     3434        Condition => '$$self{Model} =~ /(\*ist|K10D|GX10|K20D|GX20)\b/',
     3435        Description => 'Grip Battery A/D Load',
     3436    },
     3437    6 => {
     3438        Name => 'BodyBatteryVoltage3', # (greater than BodyBatteryVoltage1)
     3439        Condition => '$$self{Model} =~ /(K-5|K-r|645D)\b/',
     3440        Format => 'int16u',
     3441        Notes => 'K-5, K-r and 645D only',
     3442        ValueConv => '$val / 100',
     3443        ValueConvInv => '$val * 100',
     3444        PrintConv => 'sprintf("%.2f V", $val)',
     3445        PrintConvInv => '$val =~ s/\s*V$//',
     3446    },
     3447    8 => {
     3448        Name => 'BodyBatteryVoltage4', # (between BodyBatteryVoltage1 and BodyBatteryVoltage2)
     3449        Condition => '$$self{Model} =~ /(K-5|K-r)\b/',
     3450        Format => 'int16u',
     3451        Notes => 'K-5 and K-r only',
     3452        ValueConv => '$val / 100',
     3453        ValueConvInv => '$val * 100',
     3454        PrintConv => 'sprintf("%.2f V", $val)',
     3455        PrintConvInv => '$val =~ s/\s*V$//',
     3456    },
    14853457);
    14863458
    1487 # auto focus information (ref 19)
     3459# auto focus information
    14883460%Image::ExifTool::Pentax::AFInfo = (
    1489     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1490     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1491     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     3461    %binaryDataAttrs,
    14923462    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    1493     WRITABLE => 1,
    1494     FIRST_ENTRY => 0,
    1495     0x0b => {
     3463    # AF Info tag names in K10D debugging output - PH:
     3464    # SelectArea, InFocusArea, Predictor, Defocus, IntegTime2msStep,
     3465    # CalFlag, ContrastFlag, PrecalFlag, SelectSensor
     3466    0x00 => { #PH
     3467        Name => 'AFPointsUnknown1',
     3468        Unknown => 1,
     3469        Format => 'int16u',
     3470        ValueConv => '$self->Options("Unknown") ? $val : $val & 0x7ff',
     3471        ValueConvInv => '$val',
     3472        PrintConvColumns => 2,
     3473        PrintConv => {
     3474            0x07ff => 'All',
     3475            0x0777 => 'Central 9 points',
     3476            BITMASK => {
     3477                0 => 'Upper-left',
     3478                1 => 'Top',
     3479                2 => 'Upper-right',
     3480                3 => 'Left',
     3481                4 => 'Mid-left',
     3482                5 => 'Center',
     3483                6 => 'Mid-right',
     3484                7 => 'Right',
     3485                8 => 'Lower-left',
     3486                9 => 'Bottom',
     3487                10 => 'Lower-right',
     3488                # (bits 12-15 are flags of some sort)
     3489            },
     3490        },
     3491    },
     3492    0x02 => { #PH
     3493        Name => 'AFPointsUnknown2',
     3494        Unknown => 1,
     3495        Format => 'int16u',
     3496        ValueConv => '$self->Options("Unknown") ? $val : $val & 0x7ff',
     3497        ValueConvInv => '$val',
     3498        PrintConvColumns => 2,
     3499        PrintConv => {
     3500            0 => 'Auto',
     3501            BITMASK => {
     3502                0 => 'Upper-left',
     3503                1 => 'Top',
     3504                2 => 'Upper-right',
     3505                3 => 'Left',
     3506                4 => 'Mid-left',
     3507                5 => 'Center',
     3508                6 => 'Mid-right',
     3509                7 => 'Right',
     3510                8 => 'Lower-left',
     3511                9 => 'Bottom',
     3512                10 => 'Lower-right',
     3513                # (bits 12-15 are flags of some sort)
     3514                # bit 15 is set for center focus point only if it is vertical
     3515            },
     3516        },
     3517    },
     3518    0x04 => { #PH (educated guess - predicted amount to drive lens)
     3519        Name => 'AFPredictor',
     3520        Format => 'int16s',
     3521    },
     3522    0x06 => 'AFDefocus', #PH (educated guess - calculated distance from focused)
     3523    0x07 => { #PH
     3524        # effective exposure time for AF sensors in 2 ms increments
     3525        Name => 'AFIntegrationTime',
     3526        Notes => 'times less than 2 ms give a value of 0',
     3527        ValueConv => '$val * 2',
     3528        ValueConvInv => 'int($val / 2)', # (don't round up)
     3529        PrintConv => '"$val ms"',
     3530        PrintConvInv => '$val=~tr/0-9//dc; $val',
     3531    },
     3532    # 0x0a - values: 00,05,0d,15,86,8e,a6,ae
     3533    0x0b => { #JD
    14963534        Name => 'AFPointsInFocus',
    14973535        Notes => q{
     
    14993537            selected, in which case the selected AFPoint is the first reported
    15003538        },
     3539        PrintConvColumns => 2,
    15013540        PrintConv => {
    15023541            0 => 'None',
     
    15053544            3 => 'Lower-right, Bottom',
    15063545            4 => 'Mid-left, Center',
    1507             5 => 'Center (horizontal)', #PH (K10D)
     3546            5 => 'Center (horizontal)', #PH
    15083547            6 => 'Mid-right, Center',
    15093548            7 => 'Upper-left, Top',
     
    15193558            17 => 'Left',
    15203559            18 => 'Mid-left',
    1521             19 => 'Center (vertical)', #PH (K10D)
     3560            19 => 'Center (vertical)', #PH
    15223561            20 => 'Mid-right',
    15233562        },
     
    15253564);
    15263565
    1527 # tags in Pentax QuickTime videos (PH - tests with Optio WP)
    1528 # (note: very similar to information in Nikon videos)
    1529 %Image::ExifTool::Pentax::MOV = (
    1530     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     3566# color information - PH
     3567%Image::ExifTool::Pentax::ColorInfo = (
     3568    %binaryDataAttrs,
     3569    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     3570    FORMAT => 'int8s',
     3571    16 => {
     3572        Name => 'WBShiftAB',
     3573        Notes => 'positive is a shift toward blue',
     3574    },
     3575    17 => {
     3576        Name => 'WBShiftMG',
     3577        Notes => 'positive is a shift toward green',
     3578    },
     3579);
     3580
     3581# EV step size information - ref 19
     3582%Image::ExifTool::Pentax::EVStepInfo = (
     3583    %binaryDataAttrs,
    15313584    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    1532     NOTES => 'This information is found in Pentax MOV video images.',
    1533     0x00 => {
    1534         Name => 'Make',
    1535         Format => 'string[6]',
    1536         PrintConv => 'ucfirst(lc($val))',
    1537     },
    1538     0x26 => {
    1539         Name => 'ExposureTime',
    1540         Format => 'int32u',
    1541         ValueConv => '$val ? 10 / $val : 0',
    1542         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    1543     },
    1544     0x2a => {
    1545         Name => 'FNumber',
    1546         Format => 'int32u',
     3585    0 => {
     3586        Name => 'EVSteps',
     3587        PrintConv => {
     3588            0 => '1/2 EV Steps',
     3589            1 => '1/3 EV Steps',
     3590        },
     3591    },
     3592    1 => {
     3593        Name => 'SensitivitySteps',
     3594        PrintConv => {
     3595            0 => '1 EV Steps',
     3596            1 => 'As EV Steps',
     3597        },
     3598    },
     3599);
     3600
     3601# shot information? - ref PH (K-5)
     3602%Image::ExifTool::Pentax::ShotInfo = (
     3603    %binaryDataAttrs,
     3604    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     3605    # 0: 0xf2/0xf3 (HDR), 0xf0 (otherwise)
     3606    1 => { # (presumably this is from an orientation sensor)
     3607        Name => 'CameraOrientation',
     3608        Condition => '$$self{Model} =~ /K-[^m]/',
     3609        Notes => 'K-5, K-7, K-r and K-x',
     3610        PrintHex => 1,
     3611        PrintConv => {
     3612            0x10 => 'Horizontal (normal)',
     3613            0x20 => 'Rotate 180',
     3614            0x30 => 'Rotate 90 CW',
     3615            0x40 => 'Rotate 270 CW',
     3616            0x50 => 'Upwards', # (to the sky)
     3617            0x60 => 'Downwards', # (to the ground)
     3618        },
     3619    },
     3620    # 2: 0xd3 (live view), 0xdb (HDR), 0x7b (otherwise)
     3621    # 3: 0xff
     3622    # 4: 0x64, 0x6a, 0x6f, 0xa4, 0xaa, 0xab, 0xbf
     3623    # 5: 0xfe
     3624    # 6: 0x0e
     3625    # 7: 0x02 (live view), 0x06 (otherwise)
     3626    # 8-10: 0x00
     3627);
     3628
     3629# face detect positions - ref PH (Optio RZ10)
     3630%Image::ExifTool::Pentax::FacePos = (
     3631    %binaryDataAttrs,
     3632    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     3633    FORMAT => 'int16u',
     3634    0 => {
     3635        Name => 'Face1Position',
     3636        Format => 'int16u[2]',
     3637        RawConv => '$$self{FacesDetected} < 1 ? undef : $val',
     3638        Notes => 'X/Y coordinates of face center in full-sized image',
     3639    },
     3640    2 => {
     3641        Name => 'Face2Position',
     3642        Format => 'int16u[2]',
     3643        RawConv => '$$self{FacesDetected} < 2 ? undef : $val',
     3644    },
     3645    4 => {
     3646        Name => 'Face3Position',
     3647        Format => 'int16u[2]',
     3648        RawConv => '$$self{FacesDetected} < 3 ? undef : $val',
     3649    },
     3650    6 => {
     3651        Name => 'Face4Position',
     3652        Format => 'int16u[2]',
     3653        RawConv => '$$self{FacesDetected} < 4 ? undef : $val',
     3654    },
     3655    8 => {
     3656        Name => 'Face5Position',
     3657        Format => 'int16u[2]',
     3658        RawConv => '$$self{FacesDetected} < 5 ? undef : $val',
     3659    },
     3660    10 => {
     3661        Name => 'Face6Position',
     3662        Format => 'int16u[2]',
     3663        RawConv => '$$self{FacesDetected} < 6 ? undef : $val',
     3664    },
     3665    12 => {
     3666        Name => 'Face7Position',
     3667        Format => 'int16u[2]',
     3668        RawConv => '$$self{FacesDetected} < 7 ? undef : $val',
     3669    },
     3670    14 => {
     3671        Name => 'Face8Position',
     3672        Format => 'int16u[2]',
     3673        RawConv => '$$self{FacesDetected} < 8 ? undef : $val',
     3674    },
     3675    16 => {
     3676        Name => 'Face9Position',
     3677        Format => 'int16u[2]',
     3678        RawConv => '$$self{FacesDetected} < 9 ? undef : $val',
     3679    },
     3680    18 => {
     3681        Name => 'Face10Position',
     3682        Format => 'int16u[2]',
     3683        RawConv => '$$self{FacesDetected} < 10 ? undef : $val',
     3684    },
     3685    20 => {
     3686        Name => 'Face11Position',
     3687        Format => 'int16u[2]',
     3688        RawConv => '$$self{FacesDetected} < 11 ? undef : $val',
     3689    },
     3690    22 => {
     3691        Name => 'Face12Position',
     3692        Format => 'int16u[2]',
     3693        RawConv => '$$self{FacesDetected} < 12 ? undef : $val',
     3694    },
     3695    24 => {
     3696        Name => 'Face13Position',
     3697        Format => 'int16u[2]',
     3698        RawConv => '$$self{FacesDetected} < 13 ? undef : $val',
     3699    },
     3700    26 => {
     3701        Name => 'Face14Position',
     3702        Format => 'int16u[2]',
     3703        RawConv => '$$self{FacesDetected} < 14 ? undef : $val',
     3704    },
     3705    28 => {
     3706        Name => 'Face15Position',
     3707        Format => 'int16u[2]',
     3708        RawConv => '$$self{FacesDetected} < 15 ? undef : $val',
     3709    },
     3710    30 => {
     3711        Name => 'Face16Position',
     3712        Format => 'int16u[2]',
     3713        RawConv => '$$self{FacesDetected} < 16 ? undef : $val',
     3714    },
     3715    32 => {
     3716        Name => 'Face17Position',
     3717        Format => 'int16u[2]',
     3718        RawConv => '$$self{FacesDetected} < 17 ? undef : $val',
     3719    },
     3720    34 => {
     3721        Name => 'Face18Position',
     3722        Format => 'int16u[2]',
     3723        RawConv => '$$self{FacesDetected} < 18 ? undef : $val',
     3724    },
     3725    36 => {
     3726        Name => 'Face19Position',
     3727        Format => 'int16u[2]',
     3728        RawConv => '$$self{FacesDetected} < 19 ? undef : $val',
     3729    },
     3730    38 => {
     3731        Name => 'Face20Position',
     3732        Format => 'int16u[2]',
     3733        RawConv => '$$self{FacesDetected} < 20 ? undef : $val',
     3734    },
     3735    40 => {
     3736        Name => 'Face21Position',
     3737        Format => 'int16u[2]',
     3738        RawConv => '$$self{FacesDetected} < 21 ? undef : $val',
     3739    },
     3740    42 => {
     3741        Name => 'Face22Position',
     3742        Format => 'int16u[2]',
     3743        RawConv => '$$self{FacesDetected} < 22 ? undef : $val',
     3744    },
     3745    44 => {
     3746        Name => 'Face23Position',
     3747        Format => 'int16u[2]',
     3748        RawConv => '$$self{FacesDetected} < 23 ? undef : $val',
     3749    },
     3750    46 => {
     3751        Name => 'Face24Position',
     3752        Format => 'int16u[2]',
     3753        RawConv => '$$self{FacesDetected} < 24 ? undef : $val',
     3754    },
     3755    48 => {
     3756        Name => 'Face25Position',
     3757        Format => 'int16u[2]',
     3758        RawConv => '$$self{FacesDetected} < 25 ? undef : $val',
     3759    },
     3760    50 => {
     3761        Name => 'Face26Position',
     3762        Format => 'int16u[2]',
     3763        RawConv => '$$self{FacesDetected} < 26 ? undef : $val',
     3764    },
     3765    52 => {
     3766        Name => 'Face27Position',
     3767        Format => 'int16u[2]',
     3768        RawConv => '$$self{FacesDetected} < 27 ? undef : $val',
     3769    },
     3770    54 => {
     3771        Name => 'Face28Position',
     3772        Format => 'int16u[2]',
     3773        RawConv => '$$self{FacesDetected} < 28 ? undef : $val',
     3774    },
     3775    56 => {
     3776        Name => 'Face29Position',
     3777        Format => 'int16u[2]',
     3778        RawConv => '$$self{FacesDetected} < 29 ? undef : $val',
     3779    },
     3780    58 => {
     3781        Name => 'Face30Position',
     3782        Format => 'int16u[2]',
     3783        RawConv => '$$self{FacesDetected} < 30 ? undef : $val',
     3784    },
     3785    60 => {
     3786        Name => 'Face31Position',
     3787        Format => 'int16u[2]',
     3788        RawConv => '$$self{FacesDetected} < 31 ? undef : $val',
     3789    },
     3790    62 => {
     3791        Name => 'Face32Position',
     3792        Format => 'int16u[2]',
     3793        RawConv => '$$self{FacesDetected} < 32 ? undef : $val',
     3794    },
     3795);
     3796
     3797# face detect sizes - ref PH (Optio RZ10)
     3798%Image::ExifTool::Pentax::FaceSize = (
     3799    %binaryDataAttrs,
     3800    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     3801    FORMAT => 'int16u',
     3802    0 => {
     3803        Name => 'Face1Size',
     3804        Format => 'int16u[2]',
     3805        RawConv => '$$self{FacesDetected} < 1 ? undef : $val',
     3806    },
     3807    2 => {
     3808        Name => 'Face2Size',
     3809        Format => 'int16u[2]',
     3810        RawConv => '$$self{FacesDetected} < 2 ? undef : $val',
     3811    },
     3812    4 => {
     3813        Name => 'Face3Size',
     3814        Format => 'int16u[2]',
     3815        RawConv => '$$self{FacesDetected} < 3 ? undef : $val',
     3816    },
     3817    6 => {
     3818        Name => 'Face4Size',
     3819        Format => 'int16u[2]',
     3820        RawConv => '$$self{FacesDetected} < 4 ? undef : $val',
     3821    },
     3822    8 => {
     3823        Name => 'Face5Size',
     3824        Format => 'int16u[2]',
     3825        RawConv => '$$self{FacesDetected} < 5 ? undef : $val',
     3826    },
     3827    10 => {
     3828        Name => 'Face6Size',
     3829        Format => 'int16u[2]',
     3830        RawConv => '$$self{FacesDetected} < 6 ? undef : $val',
     3831    },
     3832    12 => {
     3833        Name => 'Face7Size',
     3834        Format => 'int16u[2]',
     3835        RawConv => '$$self{FacesDetected} < 7 ? undef : $val',
     3836    },
     3837    14 => {
     3838        Name => 'Face8Size',
     3839        Format => 'int16u[2]',
     3840        RawConv => '$$self{FacesDetected} < 8 ? undef : $val',
     3841    },
     3842    16 => {
     3843        Name => 'Face9Size',
     3844        Format => 'int16u[2]',
     3845        RawConv => '$$self{FacesDetected} < 9 ? undef : $val',
     3846    },
     3847    18 => {
     3848        Name => 'Face10Size',
     3849        Format => 'int16u[2]',
     3850        RawConv => '$$self{FacesDetected} < 10 ? undef : $val',
     3851    },
     3852    20 => {
     3853        Name => 'Face11Size',
     3854        Format => 'int16u[2]',
     3855        RawConv => '$$self{FacesDetected} < 11 ? undef : $val',
     3856    },
     3857    22 => {
     3858        Name => 'Face12Size',
     3859        Format => 'int16u[2]',
     3860        RawConv => '$$self{FacesDetected} < 12 ? undef : $val',
     3861    },
     3862    24 => {
     3863        Name => 'Face13Size',
     3864        Format => 'int16u[2]',
     3865        RawConv => '$$self{FacesDetected} < 13 ? undef : $val',
     3866    },
     3867    26 => {
     3868        Name => 'Face14Size',
     3869        Format => 'int16u[2]',
     3870        RawConv => '$$self{FacesDetected} < 14 ? undef : $val',
     3871    },
     3872    28 => {
     3873        Name => 'Face15Size',
     3874        Format => 'int16u[2]',
     3875        RawConv => '$$self{FacesDetected} < 15 ? undef : $val',
     3876    },
     3877    30 => {
     3878        Name => 'Face16Size',
     3879        Format => 'int16u[2]',
     3880        RawConv => '$$self{FacesDetected} < 16 ? undef : $val',
     3881    },
     3882    32 => {
     3883        Name => 'Face17Size',
     3884        Format => 'int16u[2]',
     3885        RawConv => '$$self{FacesDetected} < 17 ? undef : $val',
     3886    },
     3887    34 => {
     3888        Name => 'Face18Size',
     3889        Format => 'int16u[2]',
     3890        RawConv => '$$self{FacesDetected} < 18 ? undef : $val',
     3891    },
     3892    36 => {
     3893        Name => 'Face19Size',
     3894        Format => 'int16u[2]',
     3895        RawConv => '$$self{FacesDetected} < 19 ? undef : $val',
     3896    },
     3897    38 => {
     3898        Name => 'Face20Size',
     3899        Format => 'int16u[2]',
     3900        RawConv => '$$self{FacesDetected} < 20 ? undef : $val',
     3901    },
     3902    40 => {
     3903        Name => 'Face21Size',
     3904        Format => 'int16u[2]',
     3905        RawConv => '$$self{FacesDetected} < 21 ? undef : $val',
     3906    },
     3907    42 => {
     3908        Name => 'Face22Size',
     3909        Format => 'int16u[2]',
     3910        RawConv => '$$self{FacesDetected} < 22 ? undef : $val',
     3911    },
     3912    44 => {
     3913        Name => 'Face23Size',
     3914        Format => 'int16u[2]',
     3915        RawConv => '$$self{FacesDetected} < 23 ? undef : $val',
     3916    },
     3917    46 => {
     3918        Name => 'Face24Size',
     3919        Format => 'int16u[2]',
     3920        RawConv => '$$self{FacesDetected} < 24 ? undef : $val',
     3921    },
     3922    48 => {
     3923        Name => 'Face25Size',
     3924        Format => 'int16u[2]',
     3925        RawConv => '$$self{FacesDetected} < 25 ? undef : $val',
     3926    },
     3927    50 => {
     3928        Name => 'Face26Size',
     3929        Format => 'int16u[2]',
     3930        RawConv => '$$self{FacesDetected} < 26 ? undef : $val',
     3931    },
     3932    52 => {
     3933        Name => 'Face27Size',
     3934        Format => 'int16u[2]',
     3935        RawConv => '$$self{FacesDetected} < 27 ? undef : $val',
     3936    },
     3937    54 => {
     3938        Name => 'Face28Size',
     3939        Format => 'int16u[2]',
     3940        RawConv => '$$self{FacesDetected} < 28 ? undef : $val',
     3941    },
     3942    56 => {
     3943        Name => 'Face29Size',
     3944        Format => 'int16u[2]',
     3945        RawConv => '$$self{FacesDetected} < 29 ? undef : $val',
     3946    },
     3947    58 => {
     3948        Name => 'Face30Size',
     3949        Format => 'int16u[2]',
     3950        RawConv => '$$self{FacesDetected} < 30 ? undef : $val',
     3951    },
     3952    60 => {
     3953        Name => 'Face31Size',
     3954        Format => 'int16u[2]',
     3955        RawConv => '$$self{FacesDetected} < 31 ? undef : $val',
     3956    },
     3957    62 => {
     3958        Name => 'Face32Size',
     3959        Format => 'int16u[2]',
     3960        RawConv => '$$self{FacesDetected} < 32 ? undef : $val',
     3961    },
     3962);
     3963
     3964# digital filter information - ref PH (K-5)
     3965%Image::ExifTool::Pentax::FilterInfo = (
     3966    %binaryDataAttrs,
     3967    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     3968    FORMAT => 'int8u',
     3969    NOTES => q{
     3970        The parameters associated with each type of digital filter are unique, and
     3971        these settings are also extracted with the DigitalFilter tag.  Information
     3972        is not extracted for filters that are "Off" unless the Unknown option is
     3973        used.
     3974    },
     3975    0 => {
     3976        Name => 'SourceDirectoryIndex',
     3977        Format => 'int16u',
     3978    },
     3979    2 => {
     3980        Name => 'SourceFileIndex',
     3981        Format => 'int16u',
     3982    },
     3983    0x005 => { Name => 'DigitalFilter01', %digitalFilter },
     3984    0x016 => { Name => 'DigitalFilter02', %digitalFilter },
     3985    0x027 => { Name => 'DigitalFilter03', %digitalFilter },
     3986    0x038 => { Name => 'DigitalFilter04', %digitalFilter },
     3987    0x049 => { Name => 'DigitalFilter05', %digitalFilter },
     3988    0x05a => { Name => 'DigitalFilter06', %digitalFilter },
     3989    0x06b => { Name => 'DigitalFilter07', %digitalFilter },
     3990    0x07c => { Name => 'DigitalFilter08', %digitalFilter },
     3991    0x08d => { Name => 'DigitalFilter09', %digitalFilter },
     3992    0x09e => { Name => 'DigitalFilter10', %digitalFilter },
     3993    0x0af => { Name => 'DigitalFilter11', %digitalFilter },
     3994    0x0c0 => { Name => 'DigitalFilter12', %digitalFilter },
     3995    0x0d1 => { Name => 'DigitalFilter13', %digitalFilter },
     3996    0x0e2 => { Name => 'DigitalFilter14', %digitalFilter },
     3997    0x0f3 => { Name => 'DigitalFilter15', %digitalFilter },
     3998    0x104 => { Name => 'DigitalFilter16', %digitalFilter },
     3999    0x115 => { Name => 'DigitalFilter17', %digitalFilter },
     4000    0x126 => { Name => 'DigitalFilter18', %digitalFilter },
     4001    0x137 => { Name => 'DigitalFilter19', %digitalFilter },
     4002    0x148 => { Name => 'DigitalFilter20', %digitalFilter },
     4003);
     4004
     4005# electronic level information - ref PH (K-5)
     4006%Image::ExifTool::Pentax::LevelInfo = (
     4007    %binaryDataAttrs,
     4008    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4009    FORMAT => 'int8s',
     4010    NOTES => 'Tags decoded from the electronic level information.',
     4011    0 => {
     4012        Name => 'LevelOrientation',
     4013        Mask => 0x0f,
     4014        PrintHex => 0,
     4015        PrintConv => {
     4016            1 => 'Horizontal (normal)',
     4017            2 => 'Rotate 180',
     4018            3 => 'Rotate 90 CW',
     4019            4 => 'Rotate 270 CW',
     4020            9 => 'Horizontal; Off Level',
     4021            10 => 'Rotate 180; Off Level',
     4022            11 => 'Rotate 90 CW; Off Level',
     4023            12 => 'Rotate 270 CW; Off Level',
     4024            13 => 'Upwards',
     4025            14 => 'Downwards',
     4026        },
     4027    },
     4028    0.1 => {
     4029        Name => 'CompositionAdjust',
     4030        Mask => 0xf0,
     4031        PrintConv => {
     4032            0x00 => 'Off',
     4033            0x20 => 'Composition Adjust',
     4034            0xa0 => 'Composition Adjust + Horizon Correction',
     4035            0xc0 => 'Horizon Correction',
     4036        },
     4037    },
     4038    1 => {
     4039        Name => 'RollAngle',
     4040        Notes => 'degrees of clockwise camera rotation',
     4041        ValueConv => '-$val / 2',
     4042        ValueConvInv => '-$val * 2',
     4043    },
     4044    2 => {
     4045        Name => 'PitchAngle',
     4046        Notes => 'degrees of upward camera tilt',
     4047        ValueConv => '-$val / 2',
     4048        ValueConvInv => '-$val * 2',
     4049    },
     4050    # 3,4 - related somehow to horizon correction and composition adjust
     4051    # 5,6,7 - (the notes below refer to how the image moves in the LCD monitor)
     4052    5 => {
     4053        Name => 'CompositionAdjustX',
     4054        Notes => 'steps to the right, 1/16 mm per step',
     4055        ValueConv => '-$val',
     4056        ValueConvInv => '-$val',
     4057    },
     4058    6 => {
     4059        Name => 'CompositionAdjustY',
     4060        Notes => 'steps up, 1/16 mm per step',
     4061        ValueConv => '-$val',
     4062        ValueConvInv => '-$val',
     4063    },
     4064    7 => {
     4065        Name => 'CompositionAdjustRotation',
     4066        Notes => 'steps clockwise, 1/8 degree per step',
     4067        ValueConv => '-$val / 2',
     4068        ValueConvInv => '-$val * 2',
     4069    },
     4070);
     4071
     4072# temperature information for the K5 - PH
     4073%Image::ExifTool::Pentax::TempInfoK5 = (
     4074    %binaryDataAttrs,
     4075    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4076    NOTES => q{
     4077        A number of additional temperature readings are extracted from this 256-byte
     4078        binary-data block in images from the K-5.  It is not currently known where
     4079        the corresponding temperature sensors are located in the camera.
     4080    },
     4081    # (it would be nice to know where these temperature sensors are located,
     4082    #  but since according to the manual the Slow Shutter Speed NR Auto mode
     4083    #  is based on "internal temperature", my guess is that there must be
     4084    #  at least one on the sensor itself.  These temperatures seem to rise
     4085    #  more quickly than CameraTemperature when shooting video.)
     4086    0x0c => {
     4087        Name => 'CameraTemperature2',
     4088        Format => 'int16s',
    15474089        ValueConv => '$val / 10',
    1548         PrintConv => 'sprintf("%.1f",$val)',
    1549     },
    1550     0x32 => {
    1551         Name => 'ExposureCompensation',
    1552         Format => 'int32s',
     4090        ValueConvInv => '$val * 10',
     4091        PrintConv => 'sprintf("%.1f C", $val)',
     4092        PrintConvInv => '$val=~s/ ?c$//i; $val',
     4093    },
     4094    0x0e => {
     4095        Name => 'CameraTemperature3',
     4096        Format => 'int16s',
    15534097        ValueConv => '$val / 10',
    1554         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    1555     },
    1556     0x44 => {
    1557         Name => 'WhiteBalance',
    1558         Format => 'int16u',
    1559         PrintConv => {
    1560             0 => 'Auto',
    1561             1 => 'Daylight',
    1562             2 => 'Shade',
    1563             3 => 'Fluorescent', #2
    1564             4 => 'Tungsten',
    1565             5 => 'Manual',
    1566         },
    1567     },
    1568     0x48 => {
    1569         Name => 'FocalLength',
    1570         Writable => 'int32u',
    1571         ValueConv => '$val / 10',
    1572         PrintConv => 'sprintf("%.1fmm",$val)',
    1573     },
    1574     0xaf => {
    1575         Name => 'ISO',
    1576         Format => 'int16u',
    1577     },
     4098        ValueConvInv => '$val * 10',
     4099        PrintConv => 'sprintf("%.1f C", $val)',
     4100        PrintConvInv => '$val=~s/ ?c$//i; $val',
     4101    },
     4102    0x14 => {
     4103        Name => 'CameraTemperature4',
     4104        Format => 'int16s',
     4105        PrintConv => '"$val C"',
     4106        PrintConvInv => '$val=~s/ ?c$//i; $val',
     4107    },
     4108    0x16 => { # usually the same as CameraTemperature4, but not always
     4109        Name => 'CameraTemperature5',
     4110        Format => 'int16s',
     4111        PrintConv => '"$val C"',
     4112        PrintConvInv => '$val=~s/ ?c$//i; $val',
     4113    },
     4114);
     4115
     4116# currently unknown info
     4117%Image::ExifTool::Pentax::UnknownInfo = (
     4118    %binaryDataAttrs,
     4119    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4120    # K10D: first 8 bytes seem to be short integers which change with ISO (value
     4121    # is usually close to ISO/100) possibly smoothing or gain parameters? - PH
     4122    # byte 0-1 - Higher for high color temperatures (red boost or red noise suppression?)
     4123    # byte 6-7 - Higher for low color temperatures (blue boost or blue noise suppression?)
     4124    # also changing are bytes 10,11,14,15
    15784125);
    15794126
     
    17064253);
    17074254
    1708 # ASCII-based maker notes of Optio E20 - PH
     4255# ASCII-based maker notes of Optio E20 and E25 - PH
    17094256%Image::ExifTool::Pentax::Type4 = (
    17104257    PROCESS_PROC => \&Image::ExifTool::HP::ProcessHP,
     
    17124259    NOTES => q{
    17134260        The following few tags are extracted from the wealth of information
    1714         available in maker notes of the Optio E20.  These maker notes are stored as
    1715         ASCII text in a format very similar to some HP models.
     4261        available in maker notes of the Optio E20 and E25.  These maker notes are
     4262        stored as ASCII text in a format very similar to some HP models.
    17164263    },
    17174264   'F/W Version' => 'FirmwareVersion',
    17184265);
     4266
     4267# tags in Pentax QuickTime videos (PH - tests with Optio WP)
     4268# (similar information in Kodak,Minolta,Nikon,Olympus,Pentax and Sanyo videos)
     4269%Image::ExifTool::Pentax::MOV = (
     4270    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     4271    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4272    FIRST_ENTRY => 0,
     4273    NOTES => 'This information is found in Pentax MOV videos.',
     4274    0x00 => {
     4275        Name => 'Make',
     4276        Format => 'string[24]',
     4277    },
     4278    # (01 00 at offset 0x20)
     4279    0x26 => {
     4280        Name => 'ExposureTime',
     4281        Format => 'int32u',
     4282        ValueConv => '$val ? 10 / $val : 0',
     4283        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     4284    },
     4285    0x2a => {
     4286        Name => 'FNumber',
     4287        Format => 'rational64u',
     4288        PrintConv => 'sprintf("%.1f",$val)',
     4289    },
     4290    0x32 => {
     4291        Name => 'ExposureCompensation',
     4292        Format => 'rational64s',
     4293        PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
     4294    },
     4295    0x44 => {
     4296        Name => 'WhiteBalance',
     4297        Format => 'int16u',
     4298        PrintConv => {
     4299            0 => 'Auto',
     4300            1 => 'Daylight',
     4301            2 => 'Shade',
     4302            3 => 'Fluorescent', #2
     4303            4 => 'Tungsten',
     4304            5 => 'Manual',
     4305        },
     4306    },
     4307    0x48 => {
     4308        Name => 'FocalLength',
     4309        Format => 'rational64u',
     4310        PrintConv => 'sprintf("%.1f mm",$val)',
     4311    },
     4312    0xaf => {
     4313        Name => 'ISO',
     4314        Format => 'int16u',
     4315    },
     4316);
     4317
     4318# Pentax metadata in AVI videos (PH)
     4319%Image::ExifTool::Pentax::AVI = (
     4320    NOTES => 'Pentax-specific RIFF tags found in AVI videos.',
     4321    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
     4322    hymn => {
     4323        Name => 'MakerNotes',
     4324        SubDirectory => {
     4325            TagTable => 'Image::ExifTool::Pentax::Main',
     4326            Start => 10,
     4327            Base => '$start',
     4328            ByteOrder => 'BigEndian',
     4329        },
     4330    },
     4331);
     4332
     4333# Pentax metadata in AVI videos from the RS1000 (PH)
     4334%Image::ExifTool::Pentax::Junk = (
     4335    NOTES => 'Tags found in the JUNK chunk of AVI videos from the RS1000.',
     4336    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     4337    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     4338    0x0c => {
     4339        Name => 'Model',
     4340        Format => 'string[32]',
     4341    },
     4342);
     4343
     4344#------------------------------------------------------------------------------
     4345# Convert filter settings (ref PH, K-5)
     4346# Inputs: 0) value to convert, 1) flag for inverse conversion, 2) lookup table
     4347# Returns: converted value
     4348sub PrintFilter($$$)
     4349{
     4350    my ($val, $inv, $conv) = @_;
     4351    my (@vals, @cval, $t, $v);
     4352
     4353    if (not $inv) {
     4354        # forward conversion (reading):
     4355        @vals = split ' ',$val;
     4356        $t = shift @vals;
     4357        push @cval, $$conv{$t} || "Unknown ($t)";
     4358        while (@vals) {
     4359            $t = shift @vals;
     4360            $v = shift @vals;
     4361            next unless $t;
     4362            last unless defined $v;
     4363            my $c = $filterSettings{$t};
     4364            if ($c) {
     4365                my $c1 = $$c[1];
     4366                if (ref $c1) {
     4367                    $v = $$c1{$v} || "Unknown($v)";
     4368                } elsif ($v) {
     4369                    $v = sprintf $c1, $v;
     4370                }
     4371                push @cval, "$$c[0]=$v";
     4372            } else {
     4373                push @cval, "Unknown($t)=$v";
     4374            }
     4375        }
     4376        return @cval ? \@cval : undef;
     4377    } else {
     4378        # reverse conversion (writing):
     4379        @vals = split /,\s*/, $val;
     4380        # convert filter name
     4381        delete $$conv{OTHER}; # avoid recursion
     4382        $v = Image::ExifTool::ReverseLookup(shift(@vals), $conv);
     4383        $$conv{OTHER} = \&PrintFilter;
     4384        return undef unless defined $v;
     4385        push @cval, $v;
     4386        # generate a lookup table for the filter setting name
     4387        my %settingNames;
     4388        $settingNames{$_} = $filterSettings{$_}[0] foreach keys %filterSettings;
     4389        # convert filter settings
     4390        foreach $v (@vals) {
     4391            $v =~ /^(.*)=(.*)$/ or return undef;
     4392            ($t, $v) = ($1, $2);
     4393            # look up settings name
     4394            $t = Image::ExifTool::ReverseLookup($t, \%settingNames);
     4395            return undef unless defined $t;
     4396            if (ref $filterSettings{$t}[1]) {
     4397                # look up settings value
     4398                $v = Image::ExifTool::ReverseLookup($v, $filterSettings{$t}[1]);
     4399                return undef unless defined $v;
     4400            } else {
     4401                return undef unless Image::ExifTool::IsInt($v);
     4402            }
     4403            push @cval, $t, $v;
     4404        }
     4405        push @cval, (0) x (17 - @cval) if @cval < 17; # pad with zeros if necessary
     4406        return join(' ', @cval);
     4407    }
     4408}
     4409
     4410#------------------------------------------------------------------------------
     4411# Convert Pentax hex-based EV (modulo 8) to real number
     4412# Inputs: 0) value to convert
     4413# ie) 0x00 -> 0
     4414#     0x03 -> 0.33333
     4415#     0x04 -> 0.5
     4416#     0x05 -> 0.66666
     4417#     0x08 -> 1   ...  etc
     4418sub PentaxEv($)
     4419{
     4420    my $val = shift;
     4421    if ($val & 0x01) {
     4422        my $sign = $val < 0 ? -1 : 1;
     4423        my $frac = ($val * $sign) & 0x07;
     4424        if ($frac == 0x03) {
     4425            $val += $sign * ( 8 / 3 - $frac);
     4426        } elsif ($frac == 0x05) {
     4427            $val += $sign * (16 / 3 - $frac);
     4428        }
     4429    }
     4430    return $val / 8;
     4431}
     4432
     4433#------------------------------------------------------------------------------
     4434# Convert number to Pentax hex-based EV (modulo 8)
     4435# Inputs: 0) number
     4436# Returns: Pentax EV code
     4437sub PentaxEvInv($)
     4438{
     4439    my $num = shift;
     4440    my $val = $num * 8;
     4441    # extra fudging makes sure 0.3 and 0.33333 both round up to 3, etc
     4442    my $sign = $num < 0 ? -1 : 1;
     4443    my $inum = $num * $sign - int($num * $sign);
     4444    if ($inum > 0.29 and $inum < 0.4) {
     4445        $val += $sign / 3;
     4446    } elsif ($inum > 0.6 and $inum < .71) {
     4447        $val -= $sign / 3;
     4448    }
     4449    return int($val + 0.5 * $sign);
     4450}
    17194451
    17204452#------------------------------------------------------------------------------
     
    17554487
    17564488I couldn't find a good source for Pentax maker notes information, but I've
    1757 managed to discover a fair bit of information by analyzing sample pictures
    1758 from the Optio 330, Optio 550, Optio S, *istD, *istDs, and through tests
    1759 with my own Optio WP, and with help provided by other ExifTool users (see
    1760 L<ACKNOWLEDGEMENTS>).
     4489managed to discover a fair bit of information by analyzing sample images
     4490downloaded from the internet, and through tests with my own Optio WP,
     4491K10D, and K-5, and with help provided by other ExifTool users (see
     4492L</ACKNOWLEDGEMENTS>).
    17614493
    17624494The Pentax maker notes are stored in standard EXIF format, but the offsets
     
    17834515=item L<http://www.cybercom.net/~dcoffin/dcraw/>
    17844516
    1785 =item (...plus lots of testing with my Optio WP and K10D!)
     4517=item (...plus lots of testing with my Optio WP, K10D and K-5!)
    17864518
    17874519=back
     
    17894521=head1 ACKNOWLEDGEMENTS
    17904522
    1791 Thanks to Wayne Smith, John Francis, Douglas O'Brien Cvetan Ivanov and Jens
    1792 Duttke for help figuring out some Pentax tags, Denis Bourez, Kazumichi
    1793 Kawabata, David Buret, Barney Garrett and Axel Kellner for adding to the
    1794 LensType list, and Ger Vermeulen for contributing print conversion values
    1795 for some tags.
     4523Thanks to Wayne Smith, John Francis, Douglas O'Brien Cvetan Ivanov, Jens
     4524Duttke and Dave Nicholson for help figuring out some Pentax tags, Ger
     4525Vermeulen and Niels Kristian Bech Jensen for contributing print conversion
     4526values for some tags, and everyone who helped contribute to the LensType
     4527values.
    17964528
    17974529=head1 AUTHOR
    17984530
    1799 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     4531Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    18004532
    18014533This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PhotoMechanic.pm

    r16842 r24107  
    1616use Image::ExifTool::XMP;
    1717
    18 $VERSION = '1.00';
     18$VERSION = '1.02';
    1919
    2020sub ProcessPhotoMechanic($$);
     
    5050);
    5151
    52 # rawCrop coordinate conversions
     52# raw/preview crop coordinate conversions
    5353my %rawCropConv = (
    5454    ValueConv => '$val / 655.36',
     
    6565    WRITABLE => 1,
    6666    FORMAT => 'int32s',
    67     209 => {
    68         Name => 'RawCropLeft',
    69         %rawCropConv,
    70     },
    71     210 => {
    72         Name => 'RawCropTop',
    73         %rawCropConv,
    74     },
    75     211 => {
    76         Name => 'RawCropRight',
    77         %rawCropConv,
    78     },
    79     212 => {
    80         Name => 'RawCropBottom',
    81         %rawCropConv,
    82     },
     67    209 => { Name => 'RawCropLeft',   %rawCropConv },
     68    210 => { Name => 'RawCropTop',    %rawCropConv },
     69    211 => { Name => 'RawCropRight',  %rawCropConv },
     70    212 => { Name => 'RawCropBottom', %rawCropConv },
    8371    213 => 'ConstrainedCropWidth',
    8472    214 => 'ConstrainedCropHeight',
     
    10694    },
    10795    223 => 'Rating',
     96    236 => { Name => 'PreviewCropLeft',   %rawCropConv },
     97    237 => { Name => 'PreviewCropTop',    %rawCropConv },
     98    238 => { Name => 'PreviewCropRight',  %rawCropConv },
     99    239 => { Name => 'PreviewCropBottom', %rawCropConv },
    108100);
    109101
     
    122114    EditStatus  => { },
    123115    Prefs       => {
     116        Notes => 'format is "Tagged:0, ColorClass:1, Rating:2, FrameNum:3"',
    124117        PrintConv => q{
    125118            $val =~ s[\s*(\d+):\s*(\d+):\s*(\d+):\s*(\S*)]
     
    164157        last unless $footer =~ /cbipcbbl$/;
    165158        my $size = unpack('N', $footer);
    166    
     159
    167160        if ($size & 0x80000000 or not $raf->Seek(-$size-12, 1)) {
    168161            $exifTool->Warn('Bad PhotoMechanic trailer');
     
    178171        $$dirInfo{DataPos} = $raf->Tell() - $size;
    179172        $$dirInfo{DirLen} = $size + 12;
    180    
     173
    181174        my %dirInfo = (
    182175            DataPt => \$buff,
     
    238231=head1 AUTHOR
    239232
    240 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     233Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    241234
    242235This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Photoshop.pm

    r16842 r24107  
    44# Description:  Read/write Photoshop IRB meta information
    55#
    6 # Revisions:    02/06/04 - P. Harvey Created
    7 #               02/25/04 - P. Harvey Added hack for problem with old photoshops
    8 #               10/04/04 - P. Harvey Added a bunch of tags (ref Image::MetaData::JPEG)
    9 #                          but left most of them commented out until I have enough
    10 #                          information to write PrintConv routines for them to
    11 #                          display something useful
    12 #               07/08/05 - P. Harvey Added support for reading PSD files
    13 #               01/07/06 - P. Harvey Added PSD write support
    14 #               11/04/06 - P. Harvey Added handling of resource name
     6# Revisions:    02/06/2004 - P. Harvey Created
     7#               02/25/2004 - P. Harvey Added hack for problem with old photoshops
     8#               10/04/2004 - P. Harvey Added a bunch of tags (ref Image::MetaData::JPEG)
     9#                            but left most of them commented out until I have enough
     10#                            information to write PrintConv routines for them to
     11#                            display something useful
     12#               07/08/2005 - P. Harvey Added support for reading PSD files
     13#               01/07/2006 - P. Harvey Added PSD write support
     14#               11/04/2006 - P. Harvey Added handling of resource name
    1515#
    1616# References:   1) http://www.fine-view.com/jp/lab/doc/ps6ffspecsv2.pdf
     
    1818#               3) Matt Mueller private communication (tests with PS CS2)
    1919#               4) http://www.fileformat.info/format/psd/egff.htm
     20#               5) http://www.telegraphics.com.au/svn/psdparse/trunk/resources.c
     21#               6) http://libpsd.graphest.com/files/Photoshop%20File%20Formats.pdf
    2022#------------------------------------------------------------------------------
    2123
     
    2325
    2426use strict;
    25 use vars qw($VERSION $AUTOLOAD);
    26 use Image::ExifTool qw(:DataAccess);
    27 
    28 $VERSION = '1.32';
     27use vars qw($VERSION $AUTOLOAD $iptcDigestInfo);
     28use Image::ExifTool qw(:DataAccess :Utils);
     29
     30$VERSION = '1.41';
    2931
    3032sub ProcessPhotoshop($$$);
     
    5658    0x03e8 => { Unknown => 1, Name => 'Photoshop2Info' },
    5759    0x03e9 => { Unknown => 1, Name => 'MacintoshPrintInfo' },
    58     0x03ea => { Unknown => 1, Name => 'XMLData' }, #PH
     60    0x03ea => { Unknown => 1, Name => 'XMLData', Binary => 1 }, #PH
    5961    0x03eb => { Unknown => 1, Name => 'Photoshop2ColorTable' },
    6062    0x03ed => {
     
    6668    0x03ee => {
    6769        Name => 'AlphaChannelsNames',
    68         PrintConv => 'Image::ExifTool::Photoshop::ConvertPascalString($val)',
     70        ValueConv => 'Image::ExifTool::Photoshop::ConvertPascalString($self,$val)',
    6971    },
    7072    0x03ef => { Unknown => 1, Name => 'DisplayInfo' },
     
    107109        Name => 'PhotoshopBGRThumbnail',
    108110        Notes => 'this is a JPEG image, but in BGR format instead of RGB',
    109         ValueConv => 'my $img=substr($val,0x1c);$self->ValidateImage(\$img,$tag)',
     111        RawConv => 'my $img=substr($val,0x1c);$self->ValidateImage(\$img,$tag)',
    110112    },
    111113    0x040a => {
     
    127129    0x040c => {
    128130        Name => 'PhotoshopThumbnail',
    129         ValueConv => 'my $img=substr($val,0x1c);$self->ValidateImage(\$img,$tag)',
     131        RawConv => 'my $img=substr($val,0x1c);$self->ValidateImage(\$img,$tag)',
    130132    },
    131133    0x040d => {
     
    146148    0x0412 => { Unknown => 1, Name => 'EffectsVisible' },
    147149    0x0413 => { Unknown => 1, Name => 'SpotHalftone' },
    148     0x0414 => { Unknown => 1, Name => 'IDsBaseValue', Description => "ID's Base Value" },
     150    0x0414 => { Unknown => 1, Name => 'IDsBaseValue', Description => 'IDs Base Value' },
    149151    0x0415 => { Unknown => 1, Name => 'UnicodeAlphaNames' },
    150152    0x0416 => { Unknown => 1, Name => 'IndexedColourTableCount' },
     
    170172        },
    171173    },
     174    0x0423 => { Unknown => 1, Name => 'ExifInfo2', Binary => 1 }, #5
    172175    0x0424 => {
    173176        Name => 'XMP',
     
    176179        },
    177180    },
     181    0x0425 => {
     182        Name => 'IPTCDigest',
     183        Writable => 'string',
     184        Protected => 1,
     185        Notes => q{
     186            when writing, special values of "new" and "old" represent the digests of the
     187            IPTC from the edited and original files respectively, and are undefined if
     188            the IPTC does not exist in the respective file
     189        },
     190        # also note the 'new' feature requires that the IPTC comes before this tag is written
     191        ValueConv => 'unpack("H*", $val)',
     192        ValueConvInv => q{
     193            if (lc($val) eq 'new' or lc($val) eq 'old') {
     194                {
     195                    local $SIG{'__WARN__'} = sub { };
     196                    return lc($val) if eval 'require Digest::MD5';
     197                }
     198                warn "Digest::MD5 must be installed\n";
     199                return undef;
     200            }
     201            return pack('H*', $val) if $val =~ /^[0-9a-f]{32}$/i;
     202            warn "Value must be 'new', 'old' or 32 hexadecimal digits\n";
     203            return undef;
     204        }
     205    },
     206    0x0426 => { Unknown => 1, Name => 'PrintScale' }, #5
     207    0x0428 => { Unknown => 1, Name => 'PixelAspectRatio' }, #5
     208    0x0429 => { Unknown => 1, Name => 'LayerComps' }, #5
     209    0x042a => { Unknown => 1, Name => 'AlternateDuotoneColors' }, #5
     210    0x042b => { Unknown => 1, Name => 'AlternateSpotColors' }, #5
    178211    # 0x07d0-0x0bb6 Path information
    179     0x0bb7 => { Unknown => 1, Name => 'ClippingPathName' },
     212    0x0bb7 => {
     213        Name => 'ClippingPathName',
     214        # convert from a Pascal string (ignoring 6 bytes of unknown data after string)
     215        ValueConv => q{
     216            my $len = ord($val);
     217            $val = substr($val, 0, $len+1) if $len < length($val);
     218            return Image::ExifTool::Photoshop::ConvertPascalString($self,$val);
     219        },
     220    },
    180221    0x2710 => { Unknown => 1, Name => 'PrintFlagsInfo' },
    181222);
     
    267308    12 => {
    268309        Name => 'ColorMode',
     310        PrintConvColumns => 2,
    269311        PrintConv => {
    270312            0 => 'Bitmap',
     
    285327);
    286328
     329# define reference to IPTCDigest tagInfo hash for convenience
     330$iptcDigestInfo = $Image::ExifTool::Photoshop::Main{0x0425};
     331
     332
    287333#------------------------------------------------------------------------------
    288334# AutoLoad our writer routines when necessary
     
    297343# Inputs: 1) Pascal string data
    298344# Returns: Strings, concatenated with ', '
    299 sub ConvertPascalString($)
     345sub ConvertPascalString($$)
    300346{
    301     my $inStr = shift;
     347    my ($exifTool, $inStr) = @_;
    302348    my $outStr = '';
    303349    my $len = length($inStr);
     
    310356        $i += $n + 1;
    311357    }
    312     return $outStr;
     358    my $charset = $exifTool->Options('CharsetPhotoshop') || 'Latin';
     359    return $exifTool->Decode($outStr, $charset);
    313360}
    314361
     
    342389            $ttPtr = $tagTablePtr;
    343390        } elsif ($type =~ /^(PHUT|DCSR|AgHg)$/) {
    344             $ttPtr = Image::ExifTool::GetTagTable('Image::ExifTool::Photoshop::Unknown');
     391            $ttPtr = GetTagTable('Image::ExifTool::Photoshop::Unknown');
    345392        } else {
    346393            $type =~ s/([^\w])/sprintf("\\x%.2x",ord($1))/ge;
     
    406453
    407454    $raf->Read($data, 30) == 30 or return 0;
    408     $data =~ /^8BPS\0\x01/ or return 0;
     455    $data =~ /^8BPS\0([\x01\x02])/ or return 0;
    409456    SetByteOrder('MM');
    410     $exifTool->SetFileType();    # set the FileType tag
     457    $exifTool->SetFileType($1 eq "\x01" ? 'PSD' : 'PSB'); # set the FileType tag
    411458    my %dirInfo = (
    412459        DataPt => \$data,
    413460        DirStart => 0,
    414         DirName => 'PSD',
     461        DirName => 'Photoshop',
    415462    );
    416463    my $len = Get32u(\$data, 26);
     
    423470    } else {
    424471        # process the header
    425         $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::Photoshop::Header');
     472        $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Header');
    426473        $dirInfo{DirLen} = 30;
    427474        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
     
    431478    $len = Get32u(\$data, 0);
    432479    $raf->Read($data, $len) == $len or $err = 1;
    433     $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::Photoshop::Main');
     480    $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
    434481    $dirInfo{DirLen} = $len;
    435482    my $rtnVal = 1;
     
    520567=head1 AUTHOR
    521568
    522 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     569Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    523570
    524571This library is free software; you can redistribute it and/or modify it
     
    534581
    535582=item L<http://www.fileformat.info/format/psd/egff.htm>
     583
     584=item L<http://libpsd.graphest.com/files/Photoshop%20File%20Formats.pdf>
    536585
    537586=back
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PostScript.pm

    r16842 r24107  
    44# Description:  Read PostScript meta information
    55#
    6 # Revisions:    07/08/05 - P. Harvey Created
     6# Revisions:    07/08/2005 - P. Harvey Created
    77#
    88# References:   1) http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf
     
    1717use Image::ExifTool qw(:DataAccess :Utils);
    1818
    19 $VERSION = '1.19';
     19$VERSION = '1.33';
    2020
    2121sub WritePS($$);
    22 sub CheckPS($$$);
     22sub ProcessPS($$;$);
    2323
    2424# PostScript tag table
    2525%Image::ExifTool::PostScript::Main = (
     26    PROCESS_PROC => \&ProcessPS,
    2627    WRITE_PROC => \&WritePS,
    27     CHECK_PROC => \&CheckPS,
    2828    PREFERRED => 1, # always add these tags when writing
    2929    GROUPS => { 2 => 'Image' },
     
    3838        Groups => { 2 => 'Time' },
    3939        Writable => 'string',
     40        PrintConv => '$self->ConvertDateTime($val)',
    4041    },
    4142    Creator     => { Priority => 0, Writable => 'string' },
     
    4849        Groups => { 2 => 'Time' },
    4950        Writable => 'string',
     51        PrintConv => '$self->ConvertDateTime($val)',
    5052    },
    5153    Pages       => { Priority => 0 },
     
    8082        },
    8183    },
     84    BeginDocument => {
     85        Name => 'EmbeddedFile',
     86        SubDirectory => {
     87            TagTable => 'Image::ExifTool::PostScript::Main',
     88        },
     89        Notes => 'extracted with ExtractEmbedded option',
     90    },
     91    EmbeddedFileName => {
     92        Notes => q{
     93            not a real tag ID, but the file name from a BeginDocument statement.
     94            Extracted with document metadata when ExtractEmbedded option is used
     95        },
     96    },
    8297);
    8398
     
    89104    ImageWidth => {
    90105        Desire => {
    91             0 => 'PostScript:ImageData',
     106            0 => 'Main:PostScript:ImageData',
    92107            1 => 'PostScript:BoundingBox',
    93108        },
     
    96111    ImageHeight => {
    97112        Desire => {
    98             0 => 'PostScript:ImageData',
     113            0 => 'Main:PostScript:ImageData',
    99114            1 => 'PostScript:BoundingBox',
    100115        },
     
    112127{
    113128    return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
     129}
     130
     131#------------------------------------------------------------------------------
     132# Is this a PC system
     133# Returns: true for PC systems
     134my %isPC = (MSWin32 => 1, os2 => 1, dos => 1, NetWare => 1, symbian => 1, cygwin => 1);
     135sub IsPC()
     136{
     137    return $isPC{$^O};
    114138}
    115139
     
    137161    my ($exifTool, $str) = @_;
    138162    # set file type if not done already
    139     $exifTool->SetFileType('PS') unless $exifTool->GetValue('FileType');
     163    my $ext = $$exifTool{FILE_EXT};
     164    $exifTool->SetFileType(($ext and $ext eq 'AI') ? 'AI' : 'PS');
    140165    $exifTool->Warn("PostScript format error ($str)");
    141166    return 1;
     
    143168
    144169#------------------------------------------------------------------------------
    145 # set $/ according to the current file
     170# Return input record separator to use for the specified file
    146171# Inputs: 0) RAF reference
    147 # Returns: Original separator or undefined if on error
    148 sub SetInputRecordSeparator($)
     172# Returns: Input record separator or undef on error
     173sub GetInputRecordSeparator($)
    149174{
    150175    my $raf = shift;
    151     my $oldsep = $/;
    152176    my $pos = $raf->Tell(); # save current position
    153     my $data;
     177    my ($data, $sep);
    154178    $raf->Read($data,256) or return undef;
    155179    my ($a, $d) = (999,999);
     
    158182    my $diff = $a - $d;
    159183    if ($diff eq 1) {
    160         $/ = "\x0d\x0a";
     184        $sep = "\x0d\x0a";
    161185    } elsif ($diff eq -1) {
    162         $/ = "\x0a\x0d";
     186        $sep = "\x0a\x0d";
    163187    } elsif ($diff > 0) {
    164         $/ = "\x0d";
     188        $sep = "\x0d";
    165189    } elsif ($diff < 0) {
    166         $/ = "\x0a";
    167     } else {
    168         return undef;       # error
    169     }
     190        $sep = "\x0a";
     191    } # else error
    170192    $raf->Seek($pos, 0);    # restore original position
    171     return $oldsep;
     193    return $sep;
     194}
     195
     196#------------------------------------------------------------------------------
     197# Decode comment from PostScript file
     198# Inputs: 0) comment string, 1) RAF ref, 2) reference to lines array
     199#         3) optional data reference for extra lines read from file
     200# Returns: Decoded comment string (may be an array reference)
     201# - handles multi-line comments and escape sequences
     202sub DecodeComment($$$;$)
     203{
     204    my ($val, $raf, $lines, $dataPt) = @_;
     205    $val =~ s/\x0d*\x0a*$//;        # remove trailing CR, LF or CR/LF
     206    # check for continuation comments
     207    for (;;) {
     208        unless (@$lines) {
     209            my $buff;
     210            $raf->ReadLine($buff) or last;
     211            my $altnl = $/ eq "\x0d" ? "\x0a" : "\x0d";
     212            if ($buff =~ /$altnl/) {
     213                # split into separate lines
     214                @$lines = split /$altnl/, $buff, -1;
     215                # handle case of DOS newline data inside file using Unix newlines
     216                @$lines = ( $$lines[0] . $$lines[1] ) if @$lines == 2 and $$lines[1] eq $/;
     217            } else {
     218                push @$lines, $buff;
     219            }
     220        }
     221        last unless $$lines[0] =~ /^%%\+/;  # is the next line a continuation?
     222        $$dataPt .= $$lines[0] if $dataPt;  # add to data if necessary
     223        $$lines[0] =~ s/\x0d*\x0a*$//;      # remove trailing CR, LF or CR/LF
     224        $val .= substr(shift(@$lines), 3);  # add to value (without leading "%%+")
     225    }
     226    my @vals;
     227    # handle bracketed string values
     228    if ($val =~ s/^\((.*)\)$/$1/) { # remove brackets if necessary
     229        # split into an array of strings if necessary
     230        my $nesting = 1;
     231        while ($val =~ /(\(|\))/g) {
     232            my $bra = $1;
     233            my $pos = pos($val) - 2;
     234            my $backslashes = 0;
     235            while ($pos and substr($val, $pos, 1) eq '\\') {
     236                --$pos;
     237                ++$backslashes;
     238            }
     239            next if $backslashes & 0x01;    # escaped if odd number
     240            if ($bra eq '(') {
     241                ++$nesting;
     242            } else {
     243                --$nesting;
     244                unless ($nesting) {
     245                    push @vals, substr($val, 0, pos($val)-1);
     246                    $val = substr($val, pos($val));
     247                    ++$nesting if $val =~ s/\s*\(//;
     248                }
     249            }
     250        }
     251        push @vals, $val;
     252        foreach $val (@vals) {
     253            # decode escape sequences in bracketed strings
     254            # (similar to code in PDF.pm, but without line continuation)
     255            while ($val =~ /\\(.)/sg) {
     256                my $n = pos($val) - 2;
     257                my $c = $1;
     258                my $r;
     259                if ($c =~ /[0-7]/) {
     260                    # get up to 2 more octal digits
     261                    $c .= $1 if $val =~ /\G([0-7]{1,2})/g;
     262                    # convert octal escape code
     263                    $r = chr(oct($c) & 0xff);
     264                } else {
     265                    # convert escaped characters
     266                    ($r = $c) =~ tr/nrtbf/\n\r\t\b\f/;
     267                }
     268                substr($val, $n, length($c)+1) = $r;
     269                # continue search after this character
     270                pos($val) = $n + length($r);
     271            }
     272        }
     273        $val = @vals > 1 ? \@vals : $vals[0];
     274    }
     275    return $val;
     276}
     277
     278#------------------------------------------------------------------------------
     279# Unescape PostScript string
     280# Inputs: 0) string
     281# Returns: unescaped string
     282sub UnescapePostScript($)
     283{
     284    my $str = shift;
     285    # decode escape sequences in literal strings
     286    while ($str =~ /\\(.)/sg) {
     287        my $n = pos($str) - 2;
     288        my $c = $1;
     289        my $r;
     290        if ($c =~ /[0-7]/) {
     291            # get up to 2 more octal digits
     292            $c .= $1 if $str =~ /\G([0-7]{1,2})/g;
     293            # convert octal escape code
     294            $r = chr(oct($c) & 0xff);
     295        } elsif ($c eq "\x0d") {
     296            # the string is continued if the line ends with '\'
     297            # (also remove "\x0d\x0a")
     298            $c .= $1 if $str =~ /\G(\x0a)/g;
     299            $r = '';
     300        } elsif ($c eq "\x0a") {
     301            $r = '';
     302        } else {
     303            # convert escaped characters
     304            ($r = $c) =~ tr/nrtbf/\n\r\t\b\f/;
     305        }
     306        substr($str, $n, length($c)+1) = $r;
     307        # continue search after this character
     308        pos($str) = $n + length($r);
     309    }
     310    return $str;
    172311}
    173312
    174313#------------------------------------------------------------------------------
    175314# Extract information from EPS, PS or AI file
    176 # Inputs: 0) ExifTool object reference, 1) dirInfo reference
     315# Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) optional tag table ref
    177316# Returns: 1 if this was a valid PostScript file
    178 sub ProcessPS($$)
    179 {
    180     my ($exifTool, $dirInfo) = @_;
     317sub ProcessPS($$;$)
     318{
     319    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    181320    my $raf = $$dirInfo{RAF};
    182     my ($data, $dos);
     321    my $embedded = $exifTool->Options('ExtractEmbedded');
     322    my ($data, $dos, $endDoc, $fontTable, $comment);
     323
     324    # allow read from data
     325    $raf = new File::RandomAccess($$dirInfo{DataPt}) unless $raf;
    183326#
    184327# determine if this is a postscript file
     
    186329    $raf->Read($data, 4) == 4 or return 0;
    187330    # accept either ASCII or DOS binary postscript file format
    188     return 0 unless $data =~ /^(%!PS|%!Ad|\xc5\xd0\xd3\xc6)/;
     331    return 0 unless $data =~ /^(%!PS|%!Ad|%!Fo|\xc5\xd0\xd3\xc6)/;
    189332    if ($data =~ /^%!Ad/) {
    190333        # I've seen PS files start with "%!Adobe-PS"...
     
    200343            return PSErr($exifTool, 'invalid header');
    201344        }
     345    } else {
     346        # check for PostScript font file (PFA or PFB)
     347        my $d2;
     348        $data .= $d2 if $raf->Read($d2,12);
     349        if ($data =~ /^%!(PS-(AdobeFont-|Bitstream )|FontType1-)/) {
     350            $exifTool->SetFileType('PFA');  # PostScript ASCII font file
     351            $fontTable = GetTagTable('Image::ExifTool::Font::PSInfo');
     352            # PostScript font files may contain an unformatted comments which may
     353            # contain useful information, so accumulate these for the Comment tag
     354            $comment = 1;
     355        }
     356        $raf->Seek(-length($data), 1);
    202357    }
    203358#
    204359# set the newline type based on the first newline found in the file
    205360#
    206     my $oldsep = SetInputRecordSeparator($raf);
    207     $oldsep or return PSErr($exifTool, 'invalid PS data');
     361    local $/ = GetInputRecordSeparator($raf);
     362    $/ or return PSErr($exifTool, 'invalid PS data');
    208363
    209364    # set file type (PostScript or EPS)
    210     $raf->ReadLine($data) or return 0;
    211     $exifTool->SetFileType($data =~ /EPSF/ ? 'EPS' : 'PS');
     365    $raf->ReadLine($data) or $data = '';
     366    my $type;
     367    if ($data =~ /EPSF/) {
     368        $type = 'EPS';
     369    } else {
     370        # read next line to see if this is an Illustrator file
     371        my $line2;
     372        my $pos = $raf->Tell();
     373        if ($raf->ReadLine($line2) and $line2 =~ /^%%Creator: Adobe Illustrator/) {
     374            $type = 'AI';
     375        } else {
     376            $type = 'PS';
     377        }
     378        $raf->Seek($pos, 0);
     379    }
     380    $exifTool->SetFileType($type);
    212381#
    213382# extract TIFF information from DOS header
    214383#
    215     my $tagTablePtr = GetTagTable('Image::ExifTool::PostScript::Main');
     384    $tagTablePtr or $tagTablePtr = GetTagTable('Image::ExifTool::PostScript::Main');
    216385    if ($dos) {
    217386        my $base = Get32u(\$dos, 16);
     
    241410# parse the postscript
    242411#
    243     my ($buff, $mode, $endToken);
     412    my ($buff, $mode, $beginToken, $endToken, $docNum, $subDocNum, $changedNL);
    244413    my (@lines, $altnl);
    245414    if ($/ eq "\x0d") {
     
    256425            # check for alternate newlines as efficiently as possible
    257426            if ($data =~ /$altnl/) {
    258                 # split into separate lines
    259                 @lines = split /$altnl/, $data, -1;
    260                 $data = shift @lines;
    261                 if (@lines == 1 and $lines[0] eq $/) {
    262                     # handle case of DOS newline data inside file using Unix newlines
    263                     $data .= $lines[0];
    264                     undef @lines;
    265                 }
    266             }
    267         }
     427                if (length($data) > 500000 and IsPC()) {
     428                    # Windows can't split very long lines due to poor memory handling,
     429                    # so re-read the file with the other newline character instead
     430                    # (slower but uses less memory)
     431                    unless ($changedNL) {
     432                        $changedNL = 1;
     433                        my $t = $/;
     434                        $/ = $altnl;
     435                        $altnl = $t;
     436                        $raf->Seek(-length($data), 1);
     437                        next;
     438                    }
     439                } else {
     440                    # split into separate lines
     441                    @lines = split /$altnl/, $data, -1;
     442                    $data = shift @lines;
     443                    if (@lines == 1 and $lines[0] eq $/) {
     444                        # handle case of DOS newline data inside file using Unix newlines
     445                        $data .= $lines[0];
     446                        undef @lines;
     447                    }
     448                }
     449            }
     450        }
     451        undef $changedNL;
    268452        if ($mode) {
    269453            if (not $endToken) {
     
    274458                    $buff .= $data;
    275459                } elsif ($mode eq 'Document') {
    276                     # ignore embedded documents
     460                    # ignore embedded documents, but keep track of nesting level
     461                    $docNum .= '-1' if $data =~ /^$beginToken/;
    277462                } else {
    278463                    # data is ASCII-hex encoded
     
    281466                }
    282467                next;
    283             }
    284         } elsif ($data =~ /^(%{1,2})(Begin)(_xml_packet|Photoshop|ICCProfile|Binary)/i) {
     468            } elsif ($mode eq 'Document') {
     469                $docNum =~ s/-?\d+$//;  # decrement document nesting level
     470                # done with Document mode if we are back at the top level
     471                undef $mode unless $docNum;
     472                next;
     473            }
     474        } elsif ($endDoc and $data =~ /^$endDoc/i) {
     475            $docNum =~ s/-?(\d+)$//;        # decrement nesting level
     476            $subDocNum = $1;                # remember our last sub-document number
     477            $$exifTool{DOC_NUM} = $docNum;
     478            undef $endDoc unless $docNum;   # done with document if top level
     479            next;
     480        } elsif ($data =~ /^(%{1,2})(Begin)(_xml_packet|Photoshop|ICCProfile|Document|Binary)/i) {
    285481            # the beginning of a data block
    286482            my %modeLookup = (
    287483                _xml_packet => 'XMP',
     484                photoshop   => 'Photoshop',
    288485                iccprofile  => 'ICC_Profile',
    289                 photoshop   => 'Photoshop',
     486                document    => 'Document',
     487                binary      => undef, # (we will try to skip this)
    290488            );
    291             $mode = $modeLookup{lc($3)};
    292             unless ($mode or @lines) {
    293                 # skip binary data
    294                 $raf->Seek($1, 1) or last if $data =~ /^%{1,2}BeginBinary:\s*(\d+)/i;
     489            $mode = $modeLookup{lc $3};
     490            unless ($mode) {
     491                if (not @lines and $data =~ /^%{1,2}BeginBinary:\s*(\d+)/i) {
     492                    $raf->Seek($1, 1) or last;  # skip binary data
     493                }
    295494                next;
    296495            }
    297496            $buff = '';
     497            $beginToken = $1 . $2 . $3;
    298498            $endToken = $1 . ($2 eq 'begin' ? 'end' : 'End') . $3;
    299             next;
    300         } elsif ($data =~ /^(%{1,2})(Begin)(Document)/i) {
    301             $mode = 'Document';
     499            if ($mode eq 'Document') {
     500                # this is either the 1st sub-document or Nth document
     501                if ($docNum) {
     502                    # increase nesting level
     503                    $docNum .= '-' . (++$subDocNum);
     504                } else {
     505                    # this is the Nth document
     506                    $docNum = $$exifTool{DOC_COUNT} + 1;
     507                }
     508                $subDocNum = 0; # new level, so reset subDocNum
     509                next unless $embedded;  # skip over this document
     510                # set document number for family 4-7 group names
     511                $$exifTool{DOC_NUM} = $docNum;
     512                $$exifTool{LIST_TAGS} = { };  # don't build lists across different documents
     513                $exifTool->{PROCESSED} = { }; # re-initialize processed directory lookup too
     514                $endDoc = $endToken;          # parse to EndDocument token
     515                # reset mode to allow parsing into sub-directories
     516                undef $endToken;
     517                undef $mode;
     518                # save document name if available
     519                if ($data =~ /^$beginToken:\s+([^\n\r]+)/i) {
     520                    my $docName = $1;
     521                    # remove brackets if necessary
     522                    $docName = $1 if $docName =~ /^\((.*)\)$/;
     523                    $exifTool->HandleTag($tagTablePtr, 'EmbeddedFileName', $docName);
     524                }
     525            }
    302526            next;
    303527        } elsif ($data =~ /^<\?xpacket begin=.{7,13}W5M0MpCehiHzreSzNTczkc9d/) {
     
    312536            # only allow 'ImageData' to have single leading '%'
    313537            next unless $data =~ /^%%/ or $1 eq 'ImageData';
    314             # extract information from PostScript tags in comments
    315             $val =~ s/\x0d*\x0a*$//;        # remove trailing CR, LF or CR/LF
    316             if ($val =~ s/^\((.*)\)$/$1/) { # remove brackets if necessary
    317                 $val =~ s/\) \(/, /g;       # convert contained brackets too
    318             }
     538            # decode comment string (reading continuation lines if necessary)
     539            $val = DecodeComment($val, $raf, \@lines);
    319540            $exifTool->HandleTag($tagTablePtr, $tag, $val);
     541            next;
     542        } elsif ($embedded and $data =~ /^%AI12_CompressedData/) {
     543            # the rest of the file is compressed
     544            unless (eval 'require Compress::Zlib') {
     545                $exifTool->Warn('Install Compress::Zlib to extract compressed embedded data');
     546                last;
     547            }
     548            # seek back to find the start of the compressed data in the file
     549            my $tlen = length($data) + @lines;
     550            $tlen += length $_ foreach @lines;
     551            my $backTo = $raf->Tell() - $tlen - 64;
     552            $backTo = 0 if $backTo < 0;
     553            last unless $raf->Seek($backTo, 0) and $raf->Read($data, 2048);
     554            last unless $data =~ s/.*?%AI12_CompressedData//;
     555            my $inflate = Compress::Zlib::inflateInit();
     556            $inflate or $exifTool->Warn('Error initializing inflate'), last;
     557            # generate a PS-like file in memory from the compressed data
     558            my $verbose = $exifTool->Options('Verbose');
     559            if ($verbose > 1) {
     560                $exifTool->VerboseDir('AI12_CompressedData (first 4kB)');
     561                $exifTool->VerboseDump(\$data);
     562            }
     563            # remove header if it exists (Windows AI files only)
     564            $data =~ s/^.{0,256}EndData[\x0d\x0a]+//s;
     565            my $val;
     566            for (;;) {
     567                my ($v2, $stat) = $inflate->inflate($data);
     568                $stat == Compress::Zlib::Z_STREAM_END() and $val .= $v2, last;
     569                $stat != Compress::Zlib::Z_OK() and undef($val), last;
     570                if (defined $val) {
     571                    $val .= $v2;
     572                } elsif ($v2 =~ /^%!PS/) {
     573                    $val = $v2;
     574                } else {
     575                    # add postscript header (for file recognition) if it doesn't exist
     576                    $val = "%!PS-Adobe-3.0$/" . $v2;
     577                }
     578                $raf->Read($data, 65536) or last;
     579            }
     580            defined $val or $exifTool->Warn('Error inflating AI compressed data'), last;
     581            if ($verbose > 1) {
     582                $exifTool->VerboseDir('Uncompressed AI12 Data');
     583                $exifTool->VerboseDump(\$val);
     584            }
     585            # extract information from embedded images in the uncompressed data
     586            $val =  # add PS header in case it needs one
     587            ProcessPS($exifTool, { DataPt => \$val });
     588            last;
     589        } elsif ($fontTable) {
     590            if (defined $comment) {
     591                # extract initial comments from PostScript Font files
     592                if ($data =~ /^%\s+(.*?)[\x0d\x0a]/) {
     593                    $comment .= "\n" if $comment;
     594                    $comment .= $1;
     595                    next;
     596                } elsif ($data !~ /^%/) {
     597                    # stop extracting comments at the first non-comment line
     598                    $exifTool->FoundTag('Comment', $comment) if length $comment;
     599                    undef $comment;
     600                }
     601            }
     602            if ($data =~ m{^\s*/(\w+)\s*(.*)} and $$fontTable{$1}) {
     603                my ($tag, $val) = ($1, $2);
     604                if ($val =~ /^\((.*)\)/) {
     605                    $val = UnescapePostScript($1);
     606                } elsif ($val =~ m{/?(\S+)}) {
     607                    $val = $1;
     608                }
     609                $exifTool->HandleTag($fontTable, $tag, $val);
     610            } elsif ($data =~ /^currentdict end/) {
     611                # only extract tags from initial FontInfo dict
     612                undef $fontTable;
     613            }
    320614            next;
    321615        } else {
     
    323617        }
    324618        # extract information from buffered data
    325         if ($mode ne 'Document'){
    326             my %dirInfo = (
    327                 DataPt => \$buff,
    328                 DataLen => length $buff,
    329                 DirStart => 0,
    330                 DirLen => length $buff,
    331                 Parent => 'PostScript',
    332             );
    333             my $subTablePtr = GetTagTable("Image::ExifTool::${mode}::Main");
    334             unless ($exifTool->ProcessDirectory(\%dirInfo, $subTablePtr)) {
    335                 $exifTool->Warn("Error processing $mode information in PostScript file");
    336             }
    337             undef $buff;
    338         }
     619        my %dirInfo = (
     620            DataPt => \$buff,
     621            DataLen => length $buff,
     622            DirStart => 0,
     623            DirLen => length $buff,
     624            Parent => 'PostScript',
     625        );
     626        my $subTablePtr = GetTagTable("Image::ExifTool::${mode}::Main");
     627        unless ($exifTool->ProcessDirectory(\%dirInfo, $subTablePtr)) {
     628            $exifTool->Warn("Error processing $mode information in PostScript file");
     629        }
     630        undef $buff;
    339631        undef $mode;
    340632    }
    341     $/ = $oldsep;   # restore original separator
    342     $mode and $mode ne 'Document' and PSErr($exifTool, "unterminated $mode data");
     633    $mode = 'Document' if $endDoc and not $mode;
     634    $mode and PSErr($exifTool, "unterminated $mode data");
    343635    return 1;
    344636}
     
    371663(PostScript) and AI (Adobe Illustrator) files.
    372664
    373 =head1 NOTES
    374 
    375 Currently doesn't handle continued lines ("%+" syntax).
    376 
    377665=head1 AUTHOR
    378666
    379 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     667Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    380668
    381669This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PrintIM.pm

    r16842 r24107  
    1313use Image::ExifTool qw(:DataAccess);
    1414
    15 $VERSION = '1.03';
     15$VERSION = '1.06';
    1616
    1717sub ProcessPrintIM($$$);
    1818
    19 # PrintIM table (is this proprietary? I can't find any documentation on this)
     19# PrintIM table (proprietary specification by Epson)
    2020%Image::ExifTool::PrintIM::Main = (
    2121    PROCESS_PROC => \&ProcessPrintIM,
     
    2323    PRINT_CONV => 'sprintf("0x%.8x", $val)',
    2424    TAG_PREFIX => 'PrintIM',
     25    PrintIMVersion => { # values: 0100, 0250, 0260, 0300
     26        Description => 'PrintIM Version',
     27        PrintConv => undef,
     28    },
     29    # the following names are from http://www.kanzaki.com/ns/exif
     30    # but the decoding is unknown:
     31    # 9  => { Name => 'PIMContrast',     Unknown => 1 }, #1
     32    # 10 => { Name => 'PIMBrightness',   Unknown => 1 }, #1
     33    # 11 => { Name => 'PIMColorbalance', Unknown => 1 }, #1
     34    # 12 => { Name => 'PIMSaturation',   Unknown => 1 }, #1
     35    # 13 => { Name => 'PIMSharpness',    Unknown => 1 }, #1
    2536);
    2637
     
    2839#------------------------------------------------------------------------------
    2940# Process PrintIM IFD
    30 # Inputs: 0) ExifTool object reference, 1) reference to directory information
    31 #         2) pointer to tag table
     41# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
    3242# Returns: 1 on success
    3343sub ProcessPrintIM($$$)
     
    3949    my $verbose = $exifTool->Options('Verbose');
    4050
     51    unless ($size) {
     52        $exifTool->Warn('Empty PrintIM data', 1);
     53        return 0;
     54    }
    4155    unless ($size > 15) {
    4256        $exifTool->Warn('Bad PrintIM data');
    4357        return 0;
    4458    }
    45     my $header = substr($$dataPt, $offset, 7);
    46     unless ($header eq 'PrintIM') {
     59    unless (substr($$dataPt, $offset, 7) eq 'PrintIM') {
    4760        $exifTool->Warn('Invalid PrintIM header');
    4861        return 0;
     
    6073    }
    6174    $verbose and $exifTool->VerboseDir('PrintIM', $num);
     75    $exifTool->HandleTag($tagTablePtr, 'PrintIMVersion', substr($$dataPt, $offset + 8, 4),
     76        DataPt => $dataPt,
     77        Start  => $offset + 8,
     78        Size   => 4,
     79    );
    6280    my $n;
    6381    for ($n=0; $n<$num; ++$n) {
     
    6886            Index  => $n,
    6987            DataPt => $dataPt,
     88            Start  => $pos + 2,
    7089            Size   => 4,
    71             Start  => $pos + 2,
    7290        );
    7391    }
    7492    return 1;
    7593}
    76 
    7794
    7895
     
    96113=head1 AUTHOR
    97114
    98 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     115Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    99116
    100117This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/QuickTime.pm

    r16842 r24107  
    77#               12/19/2005 - P. Harvey Added MP4 support
    88#               09/22/2006 - P. Harvey Added M4A support
     9#               07/27/2010 - P. Harvey Updated to 2010-05-03 QuickTime spec
    910#
    10 # References:   1) http://developer.apple.com/documentation/QuickTime/
     11# References:   1) http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html
    1112#               2) http://search.cpan.org/dist/MP4-Info-1.04/
    1213#               3) http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt
    1314#               4) http://wiki.multimedia.cx/index.php?title=Apple_QuickTime
     15#               5) ISO 14496-12 (http://neuron2.net/library/avc/c041828_ISO_IEC_14496-12_2005(E).pdf)
     16#               6) ISO 14496-16 (http://www.iec-normen.de/previewpdf/info_isoiec14496-16%7Bed2.0%7Den.pdf)
     17#               7) http://atomicparsley.sourceforge.net/mpeg-4files.html
     18#               8) http://wiki.multimedia.cx/index.php?title=QuickTime_container
     19#               9) http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart3.pdf (Oct 2008)
     20#               10) http://code.google.com/p/mp4v2/wiki/iTunesMetadata
     21#               11) http://www.canieti.com.mx/assets/files/1011/IEC_100_1384_DC.pdf
     22#               12) QuickTime file format specification 2010-05-03
     23#               13) http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v10.pdf
     24#               14) http://standards.iso.org/ittf/PubliclyAvailableStandards/c051533_ISO_IEC_14496-12_2008.zip
    1425#------------------------------------------------------------------------------
    1526
     
    2132use Image::ExifTool::Exif;
    2233
    23 $VERSION = '1.12';
     34$VERSION = '1.48';
    2435
    2536sub FixWrongFormat($);
    2637sub ProcessMOV($$;$);
     38sub ProcessKeys($$$);
     39sub ProcessMetaData($$$);
     40sub ConvertISO6709($);
     41sub PrintGPSCoordinates($);
    2742
    2843# information for time/date-based tags (time zero is Jan 1, 1904)
    2944my %timeInfo = (
    30     Groups => { 2 => 'Time' },
    3145    # Note: This value will be in UTC if generated by a system that is aware of the time zone
    3246    ValueConv => 'ConvertUnixTime($val - ((66 * 365 + 17) * 24 * 3600))',
    3347    PrintConv => '$self->ConvertDateTime($val)',
     48    # (can't put Groups here because they aren't constant!)
    3449);
    3550# information for duration tags
    3651my %durationInfo = (
    37     ValueConv => '$self->{TimeScale} ? $val / $self->{TimeScale} : $val',
    38     PrintConv => '$self->{TimeScale} ? sprintf("%.2fs", $val) : $val',
     52    ValueConv => '$$self{TimeScale} ? $val / $$self{TimeScale} : $val',
     53    PrintConv => '$$self{TimeScale} ? ConvertDuration($val) : $val',
     54);
     55
     56# 4-character Vendor ID codes (ref PH)
     57my %vendorID = (
     58    appl => 'Apple',
     59    fe20 => 'Olympus (fe20)', # (FE200)
     60    FFMP => 'FFmpeg',
     61   'GIC '=> 'General Imaging Co.',
     62    kdak => 'Kodak',
     63    KMPI => 'Konica-Minolta',
     64    mino => 'Minolta',
     65    niko => 'Nikon',
     66    NIKO => 'Nikon',
     67    olym => 'Olympus',
     68    pana => 'Panasonic',
     69    pent => 'Pentax',
     70    pr01 => 'Olympus (pr01)', # (FE100,FE110,FE115)
     71    sany => 'Sanyo',
     72   'SMI '=> 'Sorenson Media Inc.',
     73    ZORA => 'Zoran Corporation',
     74);
     75
     76# QuickTime data atom encodings for string types (ref 12)
     77my %stringEncoding = (
     78    1 => 'UTF8',
     79    2 => 'UTF16',
     80    3 => 'ShiftJIS',
     81    4 => 'UTF8',
     82    5 => 'UTF16',
     83);
     84
     85# MIME types for all entries in the ftypLookup with file extensions
     86# (defaults to 'video/mp4' if not found in this lookup)
     87my %mimeLookup = (
     88   '3G2' => 'video/3gpp2',
     89   '3GP' => 'video/3gpp',
     90    DVB  => 'video/vnd.dvb.file',
     91    F4A  => 'audio/mp4',
     92    F4B  => 'audio/mp4',
     93    JP2  => 'image/jp2',
     94    JPM  => 'image/jpm',
     95    JPX  => 'image/jpx',
     96    M4A  => 'audio/mp4',
     97    M4B  => 'audio/mp4',
     98    M4P  => 'audio/mp4',
     99    M4V  => 'video/x-m4v',
     100    MOV  => 'video/quicktime',
     101    MQV  => 'video/quicktime',
     102);
     103
     104my %graphicsMode = (
     105    # (ref http://homepage.mac.com/vanhoek/MovieGuts%20docs/64.html)
     106    0x00 => 'srcCopy',
     107    0x01 => 'srcOr',
     108    0x02 => 'srcXor',
     109    0x03 => 'srcBic',
     110    0x04 => 'notSrcCopy',
     111    0x05 => 'notSrcOr',
     112    0x06 => 'notSrcXor',
     113    0x07 => 'notSrcBic',
     114    0x08 => 'patCopy',
     115    0x09 => 'patOr',
     116    0x0a => 'patXor',
     117    0x0b => 'patBic',
     118    0x0c => 'notPatCopy',
     119    0x0d => 'notPatOr',
     120    0x0e => 'notPatXor',
     121    0x0f => 'notPatBic',
     122    0x20 => 'blend',
     123    0x21 => 'addPin',
     124    0x22 => 'addOver',
     125    0x23 => 'subPin',
     126    0x24 => 'transparent',
     127    0x25 => 'addMax',
     128    0x26 => 'subOver',
     129    0x27 => 'addMin',
     130    0x31 => 'grayishTextOr',
     131    0x32 => 'hilite',
     132    0x40 => 'ditherCopy',
     133    # the following ref ISO/IEC 15444-3
     134    0x100 => 'Alpha',
     135    0x101 => 'White Alpha',
     136    0x102 => 'Pre-multiplied Black Alpha',
     137    0x110 => 'Component Alpha',
     138);
     139
     140# look up file type from ftyp atom type, with MIME type in comment if known
     141# (ref http://www.ftyps.com/)
     142my %ftypLookup = (
     143    '3g2a' => '3GPP2 Media (.3G2) compliant with 3GPP2 C.S0050-0 V1.0', # video/3gpp2
     144    '3g2b' => '3GPP2 Media (.3G2) compliant with 3GPP2 C.S0050-A V1.0.0', # video/3gpp2
     145    '3g2c' => '3GPP2 Media (.3G2) compliant with 3GPP2 C.S0050-B v1.0', # video/3gpp2
     146    '3ge6' => '3GPP (.3GP) Release 6 MBMS Extended Presentations', # video/3gpp
     147    '3ge7' => '3GPP (.3GP) Release 7 MBMS Extended Presentations', # video/3gpp
     148    '3gg6' => '3GPP Release 6 General Profile', # video/3gpp
     149    '3gp1' => '3GPP Media (.3GP) Release 1 (probably non-existent)', # video/3gpp
     150    '3gp2' => '3GPP Media (.3GP) Release 2 (probably non-existent)', # video/3gpp
     151    '3gp3' => '3GPP Media (.3GP) Release 3 (probably non-existent)', # video/3gpp
     152    '3gp4' => '3GPP Media (.3GP) Release 4', # video/3gpp
     153    '3gp5' => '3GPP Media (.3GP) Release 5', # video/3gpp
     154    '3gp6' => '3GPP Media (.3GP) Release 6 Basic Profile', # video/3gpp
     155    '3gp6' => '3GPP Media (.3GP) Release 6 Progressive Download', # video/3gpp
     156    '3gp6' => '3GPP Media (.3GP) Release 6 Streaming Servers', # video/3gpp
     157    '3gs7' => '3GPP Media (.3GP) Release 7 Streaming Servers', # video/3gpp
     158    'avc1' => 'MP4 Base w/ AVC ext [ISO 14496-12:2005]', # video/mp4
     159    'CAEP' => 'Canon Digital Camera',
     160    'caqv' => 'Casio Digital Camera',
     161    'CDes' => 'Convergent Design',
     162    'da0a' => 'DMB MAF w/ MPEG Layer II aud, MOT slides, DLS, JPG/PNG/MNG images',
     163    'da0b' => 'DMB MAF, extending DA0A, with 3GPP timed text, DID, TVA, REL, IPMP',
     164    'da1a' => 'DMB MAF audio with ER-BSAC audio, JPG/PNG/MNG images',
     165    'da1b' => 'DMB MAF, extending da1a, with 3GPP timed text, DID, TVA, REL, IPMP',
     166    'da2a' => 'DMB MAF aud w/ HE-AAC v2 aud, MOT slides, DLS, JPG/PNG/MNG images',
     167    'da2b' => 'DMB MAF, extending da2a, with 3GPP timed text, DID, TVA, REL, IPMP',
     168    'da3a' => 'DMB MAF aud with HE-AAC aud, JPG/PNG/MNG images',
     169    'da3b' => 'DMB MAF, extending da3a w/ BIFS, 3GPP timed text, DID, TVA, REL, IPMP',
     170    'dmb1' => 'DMB MAF supporting all the components defined in the specification',
     171    'dmpf' => 'Digital Media Project', # various
     172    'drc1' => 'Dirac (wavelet compression), encapsulated in ISO base media (MP4)',
     173    'dv1a' => 'DMB MAF vid w/ AVC vid, ER-BSAC aud, BIFS, JPG/PNG/MNG images, TS',
     174    'dv1b' => 'DMB MAF, extending dv1a, with 3GPP timed text, DID, TVA, REL, IPMP',
     175    'dv2a' => 'DMB MAF vid w/ AVC vid, HE-AAC v2 aud, BIFS, JPG/PNG/MNG images, TS',
     176    'dv2b' => 'DMB MAF, extending dv2a, with 3GPP timed text, DID, TVA, REL, IPMP',
     177    'dv3a' => 'DMB MAF vid w/ AVC vid, HE-AAC aud, BIFS, JPG/PNG/MNG images, TS',
     178    'dv3b' => 'DMB MAF, extending dv3a, with 3GPP timed text, DID, TVA, REL, IPMP',
     179    'dvr1' => 'DVB (.DVB) over RTP', # video/vnd.dvb.file
     180    'dvt1' => 'DVB (.DVB) over MPEG-2 Transport Stream', # video/vnd.dvb.file
     181    'F4A ' => 'Audio for Adobe Flash Player 9+ (.F4A)', # audio/mp4
     182    'F4B ' => 'Audio Book for Adobe Flash Player 9+ (.F4B)', # audio/mp4
     183    'F4P ' => 'Protected Video for Adobe Flash Player 9+ (.F4P)', # video/mp4
     184    'F4V ' => 'Video for Adobe Flash Player 9+ (.F4V)', # video/mp4
     185    'isc2' => 'ISMACryp 2.0 Encrypted File', # ?/enc-isoff-generic
     186    'iso2' => 'MP4 Base Media v2 [ISO 14496-12:2005]', # video/mp4
     187    'isom' => 'MP4  Base Media v1 [IS0 14496-12:2003]', # video/mp4
     188    'JP2 ' => 'JPEG 2000 Image (.JP2) [ISO 15444-1 ?]', # image/jp2
     189    'JP20' => 'Unknown, from GPAC samples (prob non-existent)',
     190    'jpm ' => 'JPEG 2000 Compound Image (.JPM) [ISO 15444-6]', # image/jpm
     191    'jpx ' => 'JPEG 2000 with extensions (.JPX) [ISO 15444-2]', # image/jpx
     192    'KDDI' => '3GPP2 EZmovie for KDDI 3G cellphones', # video/3gpp2
     193    'M4A ' => 'Apple iTunes AAC-LC (.M4A) Audio', # audio/x-m4a
     194    'M4B ' => 'Apple iTunes AAC-LC (.M4B) Audio Book', # audio/mp4
     195    'M4P ' => 'Apple iTunes AAC-LC (.M4P) AES Protected Audio', # audio/mp4
     196    'M4V ' => 'Apple iTunes Video (.M4V) Video', # video/x-m4v
     197    'M4VH' => 'Apple TV (.M4V)', # video/x-m4v
     198    'M4VP' => 'Apple iPhone (.M4V)', # video/x-m4v
     199    'mj2s' => 'Motion JPEG 2000 [ISO 15444-3] Simple Profile', # video/mj2
     200    'mjp2' => 'Motion JPEG 2000 [ISO 15444-3] General Profile', # video/mj2
     201    'mmp4' => 'MPEG-4/3GPP Mobile Profile (.MP4/3GP) (for NTT)', # video/mp4
     202    'mp21' => 'MPEG-21 [ISO/IEC 21000-9]', # various
     203    'mp41' => 'MP4 v1 [ISO 14496-1:ch13]', # video/mp4
     204    'mp42' => 'MP4 v2 [ISO 14496-14]', # video/mp4
     205    'mp71' => 'MP4 w/ MPEG-7 Metadata [per ISO 14496-12]', # various
     206    'MPPI' => 'Photo Player, MAF [ISO/IEC 23000-3]', # various
     207    'mqt ' => 'Sony / Mobile QuickTime (.MQV) US Patent 7,477,830 (Sony Corp)', # video/quicktime
     208    'MSNV' => 'MPEG-4 (.MP4) for SonyPSP', # audio/mp4
     209    'NDAS' => 'MP4 v2 [ISO 14496-14] Nero Digital AAC Audio', # audio/mp4
     210    'NDSC' => 'MPEG-4 (.MP4) Nero Cinema Profile', # video/mp4
     211    'NDSH' => 'MPEG-4 (.MP4) Nero HDTV Profile', # video/mp4
     212    'NDSM' => 'MPEG-4 (.MP4) Nero Mobile Profile', # video/mp4
     213    'NDSP' => 'MPEG-4 (.MP4) Nero Portable Profile', # video/mp4
     214    'NDSS' => 'MPEG-4 (.MP4) Nero Standard Profile', # video/mp4
     215    'NDXC' => 'H.264/MPEG-4 AVC (.MP4) Nero Cinema Profile', # video/mp4
     216    'NDXH' => 'H.264/MPEG-4 AVC (.MP4) Nero HDTV Profile', # video/mp4
     217    'NDXM' => 'H.264/MPEG-4 AVC (.MP4) Nero Mobile Profile', # video/mp4
     218    'NDXP' => 'H.264/MPEG-4 AVC (.MP4) Nero Portable Profile', # video/mp4
     219    'NDXS' => 'H.264/MPEG-4 AVC (.MP4) Nero Standard Profile', # video/mp4
     220    'odcf' => 'OMA DCF DRM Format 2.0 (OMA-TS-DRM-DCF-V2_0-20060303-A)', # various
     221    'opf2' => 'OMA PDCF DRM Format 2.1 (OMA-TS-DRM-DCF-V2_1-20070724-C)',
     222    'opx2' => 'OMA PDCF DRM + XBS extensions (OMA-TS-DRM_XBS-V1_0-20070529-C)',
     223    'pana' => 'Panasonic Digital Camera',
     224    'qt  ' => 'Apple QuickTime (.MOV/QT)', # video/quicktime
     225    'ROSS' => 'Ross Video',
     226    'sdv ' => 'SD Memory Card Video', # various?
     227    'ssc1' => 'Samsung stereoscopic, single stream',
     228    'ssc2' => 'Samsung stereoscopic, dual stream',
    39229);
    40230
    41231# QuickTime atoms
    42232%Image::ExifTool::QuickTime::Main = (
    43     PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
     233    PROCESS_PROC => \&ProcessMOV,
    44234    GROUPS => { 2 => 'Video' },
    45235    NOTES => q{
    46         These tags are used in QuickTime MOV and MP4 videos, and QTIF images.  Tags
    47         with a question mark after their name are not extracted unless the Unknown
    48         option is set.
     236        The QuickTime format is used for many different types of audio, video and
     237        image files.  Exiftool extracts meta information from the UserData atom
     238        (including some proprietary manufacturer-specific information), as well as
     239        extracting various audio, video and image parameters.  Tags with a question
     240        mark after their name are not extracted unless the Unknown option is set.
    49241    },
    50242    free => { Unknown => 1, Binary => 1 },
     
    52244    wide => { Unknown => 1, Binary => 1 },
    53245    ftyp => { #MP4
    54         Name => 'FrameType',
    55         Unknown => 1,
    56         Notes => 'MP4 only',
    57         Binary => 1,
     246        Name => 'FileType',
     247        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::FileType' },
    58248    },
    59249    pnot => {
     
    65255        Binary => 1,
    66256    },
     257    pict => { #8
     258        Name => 'PreviewPICT',
     259        Binary => 1,
     260    },
    67261    moov => {
    68262        Name => 'Movie',
    69263        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Movie' },
    70264    },
    71     mdat => { Unknown => 1, Binary => 1 },
     265    mdat => { Name => 'MovieData', Unknown => 1, Binary => 1 },
     266    'mdat-size' => {
     267        Name => 'MovieDataSize',
     268        Notes => q{
     269            not a real tag ID, this tag represents the size of the 'mdat' data in bytes
     270            and is used in the AvgBitrate calculation
     271        },
     272    },
     273    junk => { Unknown => 1, Binary => 1 }, #8
     274    uuid => [
     275        { #9 (MP4 files)
     276            Name => 'UUID-XMP',
     277            Condition => '$$valPt=~/^\xbe\x7a\xcf\xcb\x97\xa9\x42\xe8\x9c\x71\x99\x94\x91\xe3\xaf\xac/',
     278            SubDirectory => {
     279                TagTable => 'Image::ExifTool::XMP::Main',
     280                Start => 16,
     281            },
     282        },
     283        { #11 (MP4 files)
     284            Name => 'UUID-PROF',
     285            Condition => '$$valPt=~/^PROF!\xd2\x4f\xce\xbb\x88\x69\x5c\xfa\xc9\xc7\x40/',
     286            SubDirectory => {
     287                TagTable => 'Image::ExifTool::QuickTime::Profile',
     288                Start => 24, # uid(16) + version(1) + flags(3) + count(4)
     289            },
     290        },
     291        { #PH (Flip MP4 files)
     292            Name => 'UUID-Flip',
     293            Condition => '$$valPt=~/\x4a\xb0\x3b\x0f\x61\x8d\x40\x75\x82\xb2\xd9\xfa\xce\xd3\x5f\xf5/',
     294            SubDirectory => {
     295                TagTable => 'Image::ExifTool::QuickTime::Flip',
     296                Start => 16,
     297            },
     298        },
     299        # "\x98\x7f\xa3\xdf\x2a\x85\x43\xc0\x8f\x8f\xd9\x7c\x47\x1e\x8e\xea" - unknown data in Flip videos
     300        { #8
     301            Name => 'UUID-Unknown',
     302            Unknown => 1,
     303            Binary => 1,
     304        },
     305    ],
     306);
     307
     308# MPEG-4 'ftyp' atom
     309# (ref http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html)
     310%Image::ExifTool::QuickTime::FileType = (
     311    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     312    GROUPS => { 2 => 'Video' },
     313    FORMAT => 'int32u',
     314    0 => {
     315        Name => 'MajorBrand',
     316        Format => 'undef[4]',
     317        PrintConv => \%ftypLookup,
     318    },
     319    1 => {
     320        Name => 'MinorVersion',
     321        Format => 'undef[4]',
     322        ValueConv => 'sprintf("%x.%x.%x", unpack("nCC", $val))',
     323    },
     324    2 => {
     325        Name => 'CompatibleBrands',
     326        Format => 'undef[$size-8]',
     327        # ignore any entry with a null, and return others as a list
     328        ValueConv => 'my @a=($val=~/.{4}/sg); @a=grep(!/\0/,@a); \@a',
     329    },
    72330);
    73331
    74332# atoms used in QTIF files
    75333%Image::ExifTool::QuickTime::ImageFile = (
    76     PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
     334    PROCESS_PROC => \&ProcessMOV,
    77335    GROUPS => { 2 => 'Image' },
    78336    NOTES => 'Tags used in QTIF QuickTime Image Files.',
     
    95353    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    96354    GROUPS => { 2 => 'Image' },
    97     4 => { Name => 'CompressorID',  Format => 'string[4]' },
    98     20 => { Name => 'VendorID',     Format => 'string[4]' },
    99     28 => { Name => 'Quality',      Format => 'int32u' },
    100     32 => { Name => 'ImageWidth',   Format => 'int16u' },
    101     34 => { Name => 'ImageHeight',  Format => 'int16u' },
    102     36 => { Name => 'XResolution',  Format => 'int32u' },
    103     40 => { Name => 'YResolution',  Format => 'int32u' },
    104     48 => { Name => 'FrameCount',   Format => 'int16u' },
    105     50 => { Name => 'NameLength',   Format => 'int8u' },
    106     51 => { Name => 'Compressor',   Format => 'string[$val{46}]' },
    107     82 => { Name => 'BitDepth',     Format => 'int16u' },
     355    FORMAT => 'int16u',
     356    2 => {
     357        Name => 'CompressorID',
     358        Format => 'string[4]',
     359# not very useful since this isn't a complete list and name is given below
     360#        # ref http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html
     361#        PrintConv => {
     362#            cvid => 'Cinepak',
     363#            jpeg => 'JPEG',
     364#           'smc '=> 'Graphics',
     365#           'rle '=> 'Animation',
     366#            rpza => 'Apple Video',
     367#            kpcd => 'Kodak Photo CD',
     368#           'png '=> 'Portable Network Graphics',
     369#            mjpa => 'Motion-JPEG (format A)',
     370#            mjpb => 'Motion-JPEG (format B)',
     371#            SVQ1 => 'Sorenson video, version 1',
     372#            SVQ3 => 'Sorenson video, version 3',
     373#            mp4v => 'MPEG-4 video',
     374#           'dvc '=> 'NTSC DV-25 video',
     375#            dvcp => 'PAL DV-25 video',
     376#           'gif '=> 'Compuserve Graphics Interchange Format',
     377#            h263 => 'H.263 video',
     378#            tiff => 'Tagged Image File Format',
     379#           'raw '=> 'Uncompressed RGB',
     380#           '2vuY'=> "Uncompressed Y'CbCr, 3x8-bit 4:2:2 (2vuY)",
     381#           'yuv2'=> "Uncompressed Y'CbCr, 3x8-bit 4:2:2 (yuv2)",
     382#            v308 => "Uncompressed Y'CbCr, 8-bit 4:4:4",
     383#            v408 => "Uncompressed Y'CbCr, 8-bit 4:4:4:4",
     384#            v216 => "Uncompressed Y'CbCr, 10, 12, 14, or 16-bit 4:2:2",
     385#            v410 => "Uncompressed Y'CbCr, 10-bit 4:4:4",
     386#            v210 => "Uncompressed Y'CbCr, 10-bit 4:2:2",
     387#        },
     388    },
     389    10 => {
     390        Name => 'VendorID',
     391        Format => 'string[4]',
     392        RawConv => 'length $val ? $val : undef',
     393        PrintConv => \%vendorID,
     394        SeparateTable => 'VendorID',
     395    },
     396  # 14 - ("Quality" in QuickTime docs) ??
     397    16 => 'SourceImageWidth',
     398    17 => 'SourceImageHeight',
     399    18 => { Name => 'XResolution',  Format => 'fixed32u' },
     400    20 => { Name => 'YResolution',  Format => 'fixed32u' },
     401  # 24 => 'FrameCount', # always 1 (what good is this?)
     402    25 => {
     403        Name => 'CompressorName',
     404        Format => 'string[32]',
     405        # (sometimes this is a Pascal string, and sometimes it is a C string)
     406        RawConv => q{
     407            $val=substr($val,1,ord($1)) if $val=~/^([\0-\x1f])/ and ord($1)<length($val);
     408            length $val ? $val : undef;
     409        },
     410    },
     411    41 => 'BitDepth',
    108412);
    109413
     
    116420        Name => 'PreviewDate',
    117421        Format => 'int32u',
     422        Groups => { 2 => 'Time' },
    118423        %timeInfo,
    119424    },
     
    128433# movie atoms
    129434%Image::ExifTool::QuickTime::Movie = (
    130     PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
     435    PROCESS_PROC => \&ProcessMOV,
    131436    GROUPS => { 2 => 'Video' },
    132437    mvhd => {
    133438        Name => 'MovieHeader',
    134         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::MovieHdr' },
     439        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::MovieHeader' },
    135440    },
    136441    trak => {
     
    142447        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::UserData' },
    143448    },
     449    meta => { # 'meta' is found here in my EX-F1 MOV sample - PH
     450        Name => 'Meta',
     451        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Meta' },
     452    },
     453    iods => {
     454        Name => 'InitialObjectDescriptor',
     455        Flags => ['Binary','Unknown'],
     456    },
     457    uuid => [
     458        { #11 (MP4 files) (also found in QuickTime::Track)
     459            Name => 'UUID-USMT',
     460            Condition => '$$valPt=~/^USMT!\xd2\x4f\xce\xbb\x88\x69\x5c\xfa\xc9\xc7\x40/',
     461            SubDirectory => {
     462                TagTable => 'Image::ExifTool::QuickTime::UserMedia',
     463                Start => 16,
     464            },
     465        },
     466        {
     467            Name => 'UUID-Unknown',
     468            Unknown => 1,
     469            Binary => 1,
     470        },
     471    ],
     472    # prfl - Profile (ref 12)
     473    # clip - clipping --> contains crgn (clip region) (ref 12)
     474    # mvex - movie extends --> contains mehd (movie extends header), trex (track extends) (ref 14)
    144475);
    145476
    146477# movie header data block
    147 %Image::ExifTool::QuickTime::MovieHdr = (
     478%Image::ExifTool::QuickTime::MovieHeader = (
    148479    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    149480    GROUPS => { 2 => 'Video' },
    150481    FORMAT => 'int32u',
    151     0 => { Name => 'Version', Format => 'int8u' },
     482    0 => {
     483        Name => 'MovieHeaderVersion',
     484        Format => 'int8u',
     485        RawConv => '$$self{MovieHeaderVersion} = $val',
     486    },
    152487    1 => {
    153488        Name => 'CreateDate',
     489        Groups => { 2 => 'Time' },
    154490        %timeInfo,
     491        # this is int64u if MovieHeaderVersion == 1 (ref 13)
     492        Hook => '$$self{MovieHeaderVersion} and $format = "int64u", $varSize += 4',
    155493    },
    156494    2 => {
    157495        Name => 'ModifyDate',
     496        Groups => { 2 => 'Time' },
    158497        %timeInfo,
     498        # this is int64u if MovieHeaderVersion == 1 (ref 13)
     499        Hook => '$$self{MovieHeaderVersion} and $format = "int64u", $varSize += 4',
    159500    },
    160501    3 => {
    161502        Name => 'TimeScale',
    162         RawConv => '$self->{TimeScale} = $val',
    163     },
    164     4 => { Name => 'Duration', %durationInfo },
     503        RawConv => '$$self{TimeScale} = $val',
     504    },
     505    4 => {
     506        Name => 'Duration',
     507        %durationInfo,
     508        # this is int64u if MovieHeaderVersion == 1 (ref 13)
     509        Hook => '$$self{MovieHeaderVersion} and $format = "int64u", $varSize += 4',
     510    },
    165511    5 => {
    166512        Name => 'PreferredRate',
     
    172518        ValueConv => '$val / 256',
    173519        PrintConv => 'sprintf("%.2f%%", $val * 100)',
     520    },
     521    9 => {
     522        Name => 'MatrixStructure',
     523        Format => 'fixed32s[9]',
     524        # (the right column is fixed 2.30 instead of 16.16)
     525        ValueConv => q{
     526            my @a = split ' ',$val;
     527            $_ /= 0x4000 foreach @a[2,5,8];
     528            return "@a";
     529        },
    174530    },
    175531    18 => { Name => 'PreviewTime',      %durationInfo },
     
    184540# track atoms
    185541%Image::ExifTool::QuickTime::Track = (
    186     PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
     542    PROCESS_PROC => \&ProcessMOV,
    187543    GROUPS => { 2 => 'Video' },
    188544    tkhd => {
    189545        Name => 'TrackHeader',
    190         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TrackHdr' },
     546        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TrackHeader' },
    191547    },
    192548    udta => {
     
    198554        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Media' },
    199555    },
     556    meta => { #PH (MOV)
     557        Name => 'Meta',
     558        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Meta' },
     559    },
     560    tref => {
     561        Name => 'TrackRef',
     562        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TrackRef' },
     563    },
     564    uuid => [
     565        { #11 (MP4 files) (also found in QuickTime::Movie)
     566            Name => 'UUID-USMT',
     567            Condition => '$$valPt=~/^USMT!\xd2\x4f\xce\xbb\x88\x69\x5c\xfa\xc9\xc7\x40/',
     568            SubDirectory => {
     569                TagTable => 'Image::ExifTool::QuickTime::UserMedia',
     570                Start => 16,
     571            },
     572        },
     573        {
     574            Name => 'UUID-Unknown',
     575            Unknown => 1,
     576            Binary => 1,
     577        },
     578    ],
     579    # edts - edits --> contains elst (edit list)
     580    # tapt - TrackApertureModeDimensionsAID --> contains clef (TrackCleanApertureDimensionsAID),
     581    #        prof (TrackProductionApertureDimensionsAID), enof (TrackEncodedPixelsDimensionsAID)
     582    # clip - clipping --> contains crgn (clip region)
     583    # matt - track matt --> contains kmat (compressed matt)
     584    # load - track loading settings
     585    # imap - track input map --> contains '  in' --> contains '  ty', obid
     586    # prfl - Profile (ref 12)
    200587);
    201588
    202589# track header data block
    203 %Image::ExifTool::QuickTime::TrackHdr = (
     590%Image::ExifTool::QuickTime::TrackHeader = (
    204591    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    205592    GROUPS => { 1 => 'Track#', 2 => 'Video' },
    206593    FORMAT => 'int32u',
    207594    0 => {
    208         Name => 'TrackVersion',
     595        Name => 'TrackHeaderVersion',
    209596        Format => 'int8u',
    210597        Priority => 0,
     598        RawConv => '$$self{TrackHeaderVersion} = $val',
    211599    },
    212600    1 => {
    213601        Name => 'TrackCreateDate',
    214602        Priority => 0,
     603        Groups => { 2 => 'Time' },
    215604        %timeInfo,
     605        # this is int64u if TrackHeaderVersion == 1 (ref 13)
     606        Hook => '$$self{TrackHeaderVersion} and $format = "int64u", $varSize += 4',
    216607    },
    217608    2 => {
    218609        Name => 'TrackModifyDate',
    219610        Priority => 0,
     611        Groups => { 2 => 'Time' },
    220612        %timeInfo,
     613        # this is int64u if TrackHeaderVersion == 1 (ref 13)
     614        Hook => '$$self{TrackHeaderVersion} and $format = "int64u", $varSize += 4',
    221615    },
    222616    3 => {
     
    228622        Priority => 0,
    229623        %durationInfo,
     624        # this is int64u if TrackHeaderVersion == 1 (ref 13)
     625        Hook => '$$self{TrackHeaderVersion} and $format = "int64u", $varSize += 4',
    230626    },
    231627    8 => {
     
    241637        PrintConv => 'sprintf("%.2f%%", $val * 100)',
    242638    },
     639    10 => {
     640        Name => 'MatrixStructure',
     641        Format => 'fixed32s[9]',
     642        # (the right column is fixed 2.30 instead of 16.16)
     643        ValueConv => q{
     644            my @a = split ' ',$val;
     645            $_ /= 0x4000 foreach @a[2,5,8];
     646            return "@a";
     647        },
     648    },
    243649    19 => {
    244650        Name => 'ImageWidth',
     
    255661# user data atoms
    256662%Image::ExifTool::QuickTime::UserData = (
    257     PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
     663    PROCESS_PROC => \&ProcessMOV,
    258664    GROUPS => { 2 => 'Video' },
    259665    NOTES => q{
    260666        Tag ID's beginning with the copyright symbol (hex 0xa9) are multi-language
    261         text, but ExifTool only extracts the text from the first language in the
    262         record.  ExifTool will extract any multi-language user data tags found, even
    263         if they don't exist in this table.
    264     },
    265     "\xa9cpy" => 'Copyright',
    266     "\xa9day" => 'CreateDate',
    267     "\xa9dir" => 'Director',
     667        text.  Alternate language tags are accessed by adding a dash followed by the
     668        language/country code to the tag name.  ExifTool will extract any
     669        multi-language user data tags found, even if they don't exist in this table.
     670    },
     671    "\xa9cpy" => { Name => 'Copyright',  Groups => { 2 => 'Author' } },
     672    "\xa9day" => {
     673        Name => 'CreateDate',
     674        Groups => { 2 => 'Time' },
     675        # handle values in the form "2010-02-12T13:27:14-0800" (written by Apple iPhone)
     676        ValueConv => q{
     677            require Image::ExifTool::XMP;
     678            $val =  Image::ExifTool::XMP::ConvertXMPDate($val);
     679            $val =~ s/([-+]\d{2})(\d{2})$/$1:$2/; # add colon to timezone if necessary
     680            return $val;
     681        },
     682        PrintConv => '$self->ConvertDateTime($val)',
     683    },
     684    "\xa9ART" => 'Artist', #PH (iTunes 8.0.2)
     685    "\xa9alb" => 'Album', #PH (iTunes 8.0.2)
     686    "\xa9arg" => 'Arranger', #12
     687    "\xa9ark" => 'ArrangerKeywords', #12
     688    "\xa9cmt" => 'Comment', #PH (iTunes 8.0.2)
     689    "\xa9cok" => 'ComposerKeywords', #12
     690    "\xa9com" => 'Composer', #12
     691    "\xa9dir" => 'Director', #12
    268692    "\xa9ed1" => 'Edit1',
    269693    "\xa9ed2" => 'Edit2',
     
    276700    "\xa9ed9" => 'Edit9',
    277701    "\xa9fmt" => 'Format',
     702    "\xa9gen" => 'Genre', #PH (iTunes 8.0.2)
     703    "\xa9grp" => 'Grouping', #PH (NC)
    278704    "\xa9inf" => 'Information',
     705    "\xa9isr" => 'ISRCCode', #12
     706    "\xa9lab" => 'RecordLabelName', #12
     707    "\xa9lal" => 'RecordLabelURL', #12
     708    "\xa9lyr" => 'Lyrics', #PH (NC)
     709    "\xa9mak" => 'Make', #12
     710    "\xa9mal" => 'MakerURL', #12
     711    "\xa9mod" => 'Model', #PH
     712    "\xa9nam" => 'Title', #12
     713    "\xa9pdk" => 'ProducerKeywords', #12
     714    "\xa9phg" => 'RecordingCopyright', #12
    279715    "\xa9prd" => 'Producer',
    280716    "\xa9prf" => 'Performers',
     717    "\xa9prk" => 'PerformerKeywords', #12
     718    "\xa9prl" => 'PerformerURL',
     719    "\xa9dir" => 'Director', #12
    281720    "\xa9req" => 'Requirements',
    282     "\xa9src" => 'Source',
    283     "\xa9wrt" => 'Writer',
     721    "\xa9snk" => 'SubtitleKeywords', #12
     722    "\xa9snm" => 'Subtitle', #12
     723    "\xa9src" => 'SourceCredits', #12
     724    "\xa9swf" => 'SongWriter', #12
     725    "\xa9swk" => 'SongWriterKeywords', #12
     726    "\xa9swr" => 'SoftwareVersion', #12
     727    "\xa9too" => 'Encoder', #PH (NC)
     728    "\xa9trk" => 'Track', #PH (NC)
     729    "\xa9wrt" => 'Composer',
     730    "\xa9xyz" => { #PH (iPhone 3GS)
     731        Name => 'GPSCoordinates',
     732        Groups => { 2 => 'Location' },
     733        ValueConv => \&ConvertISO6709,
     734        PrintConv => \&PrintGPSCoordinates,
     735    },
    284736    name => 'Name',
    285737    WLOC => {
     
    307759        SubDirectory => {
    308760            TagTable => 'Image::ExifTool::QuickTime::Meta',
    309             HasVersion => 1, # must skip 4-byte version number header
     761            Start => 4, # must skip 4-byte version number header
     762        },
     763    },
     764    DcMD => {
     765        Name => 'DcMD',
     766        SubDirectory => {
     767            TagTable => 'Image::ExifTool::QuickTime::DcMD',
    310768        },
    311769    },
     
    314772        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Video' },
    315773    },
    316     # hnti => 'HintInfo',
    317     # hinf => 'HintTrackInfo',
    318     TAGS => [
     774   'hnti'=> {
     775        Name => 'HintInfo',
     776        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::HintInfo' },
     777    },
     778   'hinf' => {
     779        Name => 'HintTrackInfo',
     780        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::HintTrackInfo' },
     781    },
     782    TAGS => [ #PH
     783        # these tags were initially discovered in a Pentax movie,
     784        # but similar information is found in videos from other manufacturers
    319785        {
    320             # these tags were initially discovered in a Pentax movie, but
    321             # seem very similar to those used by Nikon
     786            Name => 'KodakTags',
     787            Condition => '$$valPt =~ /^EASTMAN KODAK COMPANY/',
     788            SubDirectory => {
     789                TagTable => 'Image::ExifTool::Kodak::MOV',
     790                ByteOrder => 'LittleEndian',
     791            },
     792        },
     793        {
     794            Name => 'KonicaMinoltaTags',
     795            Condition => '$$valPt =~ /^KONICA MINOLTA DIGITAL CAMERA/',
     796            SubDirectory => {
     797                TagTable => 'Image::ExifTool::Minolta::MOV1',
     798                ByteOrder => 'LittleEndian',
     799            },
     800        },
     801        {
     802            Name => 'MinoltaTags',
     803            Condition => '$$valPt =~ /^MINOLTA DIGITAL CAMERA/',
     804            SubDirectory => {
     805                TagTable => 'Image::ExifTool::Minolta::MOV2',
     806                ByteOrder => 'LittleEndian',
     807            },
     808        },
     809        {
     810            Name => 'NikonTags',
     811            Condition => '$$valPt =~ /^NIKON DIGITAL CAMERA\0/',
     812            SubDirectory => {
     813                TagTable => 'Image::ExifTool::Nikon::MOV',
     814                ByteOrder => 'LittleEndian',
     815            },
     816        },
     817        {
     818            Name => 'OlympusTags1',
     819            Condition => '$$valPt =~ /^OLYMPUS DIGITAL CAMERA\0.{9}\x01\0/s',
     820            SubDirectory => {
     821                TagTable => 'Image::ExifTool::Olympus::MOV1',
     822                ByteOrder => 'LittleEndian',
     823            },
     824        },
     825        {
     826            Name => 'OlympusTags2',
     827            Condition => '$$valPt =~ /^OLYMPUS DIGITAL CAMERA(?!\0.{21}\x0a\0{3})/s',
     828            SubDirectory => {
     829                TagTable => 'Image::ExifTool::Olympus::MOV2',
     830                ByteOrder => 'LittleEndian',
     831            },
     832        },
     833        {
     834            Name => 'OlympusTags3',
     835            Condition => '$$valPt =~ /^OLYMPUS DIGITAL CAMERA\0/',
     836            SubDirectory => {
     837                TagTable => 'Image::ExifTool::Olympus::MP4',
     838                ByteOrder => 'LittleEndian',
     839            },
     840        },
     841        {
    322842            Name => 'PentaxTags',
    323843            Condition => '$$valPt =~ /^PENTAX DIGITAL CAMERA\0/',
     
    328848        },
    329849        {
    330             Name => 'NikonTags',
    331             Condition => '$$valPt =~ /^NIKON DIGITAL CAMERA\0/',
     850            Name => 'SamsungTags',
     851            Condition => '$$valPt =~ /^SAMSUNG DIGITAL CAMERA\0/',
    332852            SubDirectory => {
    333                 TagTable => 'Image::ExifTool::Nikon::MOV',
     853                TagTable => 'Image::ExifTool::Samsung::MP4',
    334854                ByteOrder => 'LittleEndian',
    335855            },
     
    363883        },
    364884    ],
     885    NCDT => { #PH
     886        Name => 'NikonNCDT',
     887        SubDirectory => {
     888            TagTable => 'Image::ExifTool::Nikon::NCDT',
     889            ProcessProc => \&ProcessMOV,
     890        },
     891    },
     892    QVMI => { #PH
     893        Name => 'CasioQVMI',
     894        # Casio stores standard EXIF-format information in MOV videos (ie. EX-S880)
     895        SubDirectory => {
     896            TagTable => 'Image::ExifTool::Exif::Main',
     897            DirName => 'IFD0',
     898            Multi => 0, # (no NextIFD pointer)
     899            Start => 10,
     900            ByteOrder => 'BigEndian',
     901        },
     902    },
     903    MMA0 => { #PH (DiMage 7Hi)
     904        Name => 'MinoltaMMA0',
     905        SubDirectory => { TagTable => 'Image::ExifTool::Minolta::MMA' },
     906    },
     907    MMA1 => { #PH (Dimage A2)
     908        Name => 'MinoltaMMA1',
     909        SubDirectory => { TagTable => 'Image::ExifTool::Minolta::MMA' },
     910    },
     911    XMP_ => { #PH (Adobe CS3 Bridge)
     912        Name => 'XMP',
     913        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     914    },
     915    vndr => 'Vendor', #PH (Samsung PL70)
     916    SDLN => 'PlayMode', #PH (NC, Samsung ST80 "SEQ_PLAY")
     917    # Canon tags
     918    CNCV => 'CompressorVersion', #PH (5D Mark II)
     919    CNMN => 'Model', #PH (EOS 550D)
     920    CNFV => 'FirmwareVersion', #PH (EOS 550D)
     921    CNTH => { #PH (PowerShot S95)
     922        Name => 'CanonCNTH',
     923        SubDirectory => {
     924            TagTable => 'Image::ExifTool::Canon::CNTH',
     925            ProcessProc => \&ProcessMOV,
     926        },
     927    },
     928    # CNDB - 2112 bytes (550D)
     929    # CNDM - 4 bytes - 0xff,0xd8,0xff,0xd9 (S95)
     930    INFO => {
     931        Name => 'SamsungINFO',
     932        SubDirectory => { TagTable => 'Image::ExifTool::Samsung::INFO' },
     933    },
     934    FFMV => { #PH (FinePix HS20EXR)
     935        Name => 'FujiFilmFFMV',
     936        SubDirectory => { TagTable => 'Image::ExifTool::FujiFilm::FFMV' },
     937    },
     938    MVTG => { #PH (FinePix HS20EXR)
     939        Name => 'FujiFilmMVTG',
     940        SubDirectory => {
     941            TagTable => 'Image::ExifTool::Exif::Main',
     942            DirName => 'IFD0',
     943            Start => 16,
     944            Base => '$start',
     945            ByteOrder => 'LittleEndian',
     946        },
     947    },
     948);
     949
     950# User-specific media data atoms (ref 11)
     951%Image::ExifTool::QuickTime::UserMedia = (
     952    PROCESS_PROC => \&ProcessMOV,
     953    GROUPS => { 2 => 'Video' },
     954    MTDT => {
     955        Name => 'MetaData',
     956        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::MetaData' },
     957    },
     958);
     959
     960# User-specific media data atoms (ref 11)
     961%Image::ExifTool::QuickTime::MetaData = (
     962    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMetaData,
     963    GROUPS => { 2 => 'Video' },
     964    TAG_PREFIX => 'MetaData',
     965    0x01 => 'Title',
     966    0x03 => {
     967        Name => 'ProductionDate',
     968        Groups => { 2 => 'Time' },
     969        # translate from format "YYYY/mm/dd HH:MM:SS"
     970        ValueConv => '$val=~tr{/}{:}; $val',
     971        PrintConv => '$self->ConvertDateTime($val)',
     972    },
     973    0x04 => 'Software',
     974    0x05 => 'Product',
     975    0x0a => {
     976        Name => 'TrackProperty',
     977        RawConv => 'my @a=unpack("Nnn",$val); "@a"',
     978        PrintConv => [
     979            { 0 => 'No presentation', BITMASK => { 0 => 'Main track' } },
     980            { 0 => 'No attributes',   BITMASK => { 15 => 'Read only' } },
     981            '"Priority $val"',
     982        ],
     983    },
     984    0x0b => {
     985        Name => 'TimeZone',
     986        Groups => { 2 => 'Time' },
     987        RawConv => 'Get16s(\$val,0)',
     988        PrintConv => 'TimeZoneString($val)',
     989    },
     990    0x0c => {
     991        Name => 'ModifyDate',
     992        Groups => { 2 => 'Time' },
     993        # translate from format "YYYY/mm/dd HH:MM:SS"
     994        ValueConv => '$val=~tr{/}{:}; $val',
     995        PrintConv => '$self->ConvertDateTime($val)',
     996    },
     997);
     998
     999# Profile atoms (ref 11)
     1000%Image::ExifTool::QuickTime::Profile = (
     1001    PROCESS_PROC => \&ProcessMOV,
     1002    GROUPS => { 2 => 'Video' },
     1003    FPRF => {
     1004        Name => 'FileGlobalProfile',
     1005        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::FileProf' },
     1006    },
     1007    APRF => {
     1008        Name => 'AudioProfile',
     1009        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::AudioProf' },
     1010    },
     1011    VPRF => {
     1012        Name => 'VideoProfile',
     1013        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::VideoProf' },
     1014    },
     1015);
     1016
     1017# FPRF atom information (ref 11)
     1018%Image::ExifTool::QuickTime::FileProf = (
     1019    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1020    GROUPS => { 2 => 'Video' },
     1021    FORMAT => 'int32u',
     1022    0 => { Name => 'FileProfileVersion', Unknown => 1 }, # unknown = uninteresting
     1023    1 => {
     1024        Name => 'FileFunctionFlags',
     1025        PrintConv => { BITMASK => {
     1026            28 => 'Fragmented',
     1027            29 => 'Additional tracks',
     1028            30 => 'Edited', # (main AV track is edited)
     1029        }},
     1030    },
     1031    # 2 - reserved
     1032);
     1033
     1034# APRF atom information (ref 11)
     1035%Image::ExifTool::QuickTime::AudioProf = (
     1036    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1037    GROUPS => { 2 => 'Audio' },
     1038    FORMAT => 'int32u',
     1039    0 => { Name => 'AudioProfileVersion', Unknown => 1 },
     1040    1 => 'AudioTrackID',
     1041    2 => {
     1042        Name => 'AudioCodec',
     1043        Format => 'undef[4]',
     1044    },
     1045    3 => {
     1046        Name => 'AudioCodecInfo',
     1047        Unknown => 1,
     1048        PrintConv => 'sprintf("0x%.4x", $val)',
     1049    },
     1050    4 => {
     1051        Name => 'AudioAttributes',
     1052        PrintConv => { BITMASK => {
     1053            0 => 'Encrypted',
     1054            1 => 'Variable bitrate',
     1055            2 => 'Dual mono',
     1056        }},
     1057    },
     1058    5 => {
     1059        Name => 'AudioAvgBitrate',
     1060        ValueConv => '$val * 1000',
     1061        PrintConv => 'ConvertBitrate($val)',
     1062    },
     1063    6 => {
     1064        Name => 'AudioMaxBitrate',
     1065        ValueConv => '$val * 1000',
     1066        PrintConv => 'ConvertBitrate($val)',
     1067    },
     1068    7 => 'AudioSampleRate',
     1069    8 => 'AudioChannels',
     1070);
     1071
     1072# VPRF atom information (ref 11)
     1073%Image::ExifTool::QuickTime::VideoProf = (
     1074    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1075    GROUPS => { 2 => 'Video' },
     1076    FORMAT => 'int32u',
     1077    0 => { Name => 'VideoProfileVersion', Unknown => 1 },
     1078    1 => 'VideoTrackID',
     1079    2 => {
     1080        Name => 'VideoCodec',
     1081        Format => 'undef[4]',
     1082    },
     1083    3 => {
     1084        Name => 'VideoCodecInfo',
     1085        Unknown => 1,
     1086        PrintConv => 'sprintf("0x%.4x", $val)',
     1087    },
     1088    4 => {
     1089        Name => 'VideoAttributes',
     1090        PrintConv => { BITMASK => {
     1091            0 => 'Encrypted',
     1092            1 => 'Variable bitrate',
     1093            2 => 'Variable frame rate',
     1094            3 => 'Interlaced',
     1095        }},
     1096    },
     1097    5 => {
     1098        Name => 'VideoAvgBitrate',
     1099        ValueConv => '$val * 1000',
     1100        PrintConv => 'ConvertBitrate($val)',
     1101    },
     1102    6 => {
     1103        Name => 'VideoMaxBitrate',
     1104        ValueConv => '$val * 1000',
     1105        PrintConv => 'ConvertBitrate($val)',
     1106    },
     1107    7 => {
     1108        Name => 'VideoAvgFrameRate',
     1109        Format => 'fixed32u',
     1110        PrintConv => 'int($val * 1000 + 0.5) / 1000',
     1111    },
     1112    8 => {
     1113        Name => 'VideoMaxFrameRate',
     1114        Format => 'fixed32u',
     1115        PrintConv => 'int($val * 1000 + 0.5) / 1000',
     1116    },
     1117    9 => {
     1118        Name => 'VideoSize',
     1119        Format => 'int16u[2]',
     1120        PrintConv => '$val=~tr/ /x/; $val',
     1121    },
     1122    10 => {
     1123        Name => 'PixelAspectRatio',
     1124        Format => 'int16u[2]',
     1125        PrintConv => '$val=~tr/ /:/; $val',
     1126    },
    3651127);
    3661128
    3671129# meta atoms
    3681130%Image::ExifTool::QuickTime::Meta = (
    369     PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
     1131    PROCESS_PROC => \&ProcessMOV,
    3701132    GROUPS => { 2 => 'Video' },
    3711133    ilst => {
    372         Name => 'InfoList',
     1134        Name => 'ItemList',
    3731135        SubDirectory => {
    374             TagTable => 'Image::ExifTool::QuickTime::InfoList',
     1136            TagTable => 'Image::ExifTool::QuickTime::ItemList',
    3751137            HasData => 1, # process atoms as containers with 'data' elements
    3761138        },
    3771139    },
    378 );
    379 
    380 # info list atoms
     1140    # MP4 tags (ref 5)
     1141    hdlr => {
     1142        Name => 'Handler',
     1143        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Handler' },
     1144    },
     1145    dinf => {
     1146        Name => 'DataInformation',
     1147        Flags => ['Binary','Unknown'],
     1148    },
     1149    ipmc => {
     1150        Name => 'IPMPControl',
     1151        Flags => ['Binary','Unknown'],
     1152    },
     1153    iloc => {
     1154        Name => 'ItemLocation',
     1155        Flags => ['Binary','Unknown'],
     1156    },
     1157    ipro => {
     1158        Name => 'ItemProtection',
     1159        Flags => ['Binary','Unknown'],
     1160    },
     1161    iinf => {
     1162        Name => 'ItemInformation',
     1163        Flags => ['Binary','Unknown'],
     1164    },
     1165   'xml ' => {
     1166        Name => 'XML',
     1167        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     1168    },
     1169   'keys' => {
     1170        Name => 'Keys',
     1171        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Keys' },
     1172    },
     1173    bxml => {
     1174        Name => 'BinaryXML',
     1175        Flags => ['Binary','Unknown'],
     1176    },
     1177    pitm => {
     1178        Name => 'PrimaryItemReference',
     1179        Flags => ['Binary','Unknown'],
     1180    },
     1181    free => { #PH
     1182        Name => 'Free',
     1183        Flags => ['Binary','Unknown'],
     1184    },
     1185);
     1186
     1187# track reference atoms
     1188%Image::ExifTool::QuickTime::TrackRef = (
     1189    PROCESS_PROC => \&ProcessMOV,
     1190    GROUPS => { 2 => 'Video' },
     1191    chap => { Name => 'ChapterList', Format => 'int32u' },
     1192    # also: tmcd, sync, scpt, ssrc, iTunesInfo
     1193);
     1194
     1195# item list atoms
    3811196# -> these atoms are unique, and contain one or more 'data' atoms
    382 %Image::ExifTool::QuickTime::InfoList = (
    383     PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
     1197%Image::ExifTool::QuickTime::ItemList = (
     1198    PROCESS_PROC => \&ProcessMOV,
    3841199    GROUPS => { 2 => 'Audio' },
     1200    NOTES => q{
     1201        As well as these tags, the 'mdta' handler uses numerical tag ID's which are
     1202        added dynamically to this table after processing the Meta Keys information.
     1203    },
     1204    # in this table, binary 1 and 2-byte "data"-type tags are interpreted as
     1205    # int8u and int16u.  Multi-byte binary "data" tags are extracted as binary data
    3851206    "\xa9ART" => 'Artist',
    3861207    "\xa9alb" => 'Album',
    3871208    "\xa9cmt" => 'Comment',
    3881209    "\xa9com" => 'Composer',
    389     "\xa9day" => 'Year',
     1210    "\xa9day" => { Name => 'Year', Groups => { 2 => 'Time' } },
    3901211    "\xa9des" => 'Description', #4
     1212    "\xa9enc" => 'EncodedBy', #10
    3911213    "\xa9gen" => 'Genre',
    3921214    "\xa9grp" => 'Grouping',
    3931215    "\xa9lyr" => 'Lyrics',
    3941216    "\xa9nam" => 'Title',
     1217    # "\xa9st3" ? #10
    3951218    "\xa9too" => 'Encoder',
    3961219    "\xa9trk" => 'Track',
     
    4011224    },
    4021225    aART => 'AlbumArtist',
    403     apid => 'AppleStoreID',
    404     auth => 'Author',
    4051226    covr => 'CoverArt',
    406     cpil => {
     1227    cpil => { #10
    4071228        Name => 'Compilation',
    4081229        PrintConv => { 0 => 'No', 1 => 'Yes' },
    4091230    },
    410     cprt => 'Copyright',
    4111231    disk => {
    4121232        Name => 'DiskNumber',
    4131233        ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
    4141234    },
    415     dscp => 'Description',
    416     gnre => 'Genre',
    417     perf => 'Performer',
    418     pgap => {
     1235    pgap => { #10
    4191236        Name => 'PlayGap',
    4201237        PrintConv => {
     
    4231240        },
    4241241    },
    425     rtng => 'Rating', # int
    426     titl => 'Title',
    427     tmpo => 'BeatsPerMinute', # int
     1242    tmpo => {
     1243        Name => 'BeatsPerMinute',
     1244        Format => 'int16u', # marked as boolean but really int16u in my sample
     1245    },
    4281246    trkn => {
    4291247        Name => 'TrackNumber',
    4301248        ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
    4311249    },
    432 );
    433 
    434 # info list atoms
     1250#
     1251# Note: it is possible that the tags below are not being decoded properly
     1252# because I don't have samples to verify many of these - PH
     1253#
     1254    akID => { #10
     1255        Name => 'AppleStoreAccountType',
     1256        PrintConv => {
     1257            0 => 'iTunes',
     1258            1 => 'AOL',
     1259        },
     1260    },
     1261    albm => 'Album', #(ffmpeg source)
     1262    apID => 'AppleStoreAccount',
     1263    atID => { #10 (or TV series)
     1264        Name => 'AlbumTitleID',
     1265        Format => 'int32u',
     1266    },
     1267    auth => { Name => 'Author', Groups => { 2 => 'Author' } },
     1268    catg => 'Category', #7
     1269    cnID => { #10
     1270        Name => 'AppleStoreCatalogID',
     1271        Format => 'int32u',
     1272    },
     1273    cprt => { Name => 'Copyright', Groups => { 2 => 'Author' } },
     1274    dscp => 'Description',
     1275    desc => 'Description', #7
     1276    gnre => { #10
     1277        Name => 'Genre',
     1278        PrintConv => q{
     1279            return $val unless $val =~ /^\d+$/;
     1280            require Image::ExifTool::ID3;
     1281            Image::ExifTool::ID3::PrintGenre($val - 1); # note the "- 1"
     1282        },
     1283    },
     1284    egid => 'EpisodeGlobalUniqueID', #7
     1285    geID => { #10
     1286        Name => 'GenreID',
     1287        Format => 'int32u',
     1288        # 4005 = Kids
     1289        # 4010 = Teens
     1290    },
     1291    grup => 'Grouping', #10
     1292    hdvd => { #10
     1293        Name => 'HDVideo',
     1294        PrintConv => { 0 => 'No', 1 => 'Yes' },
     1295    },
     1296    keyw => 'Keyword', #7
     1297    ldes => 'LongDescription', #10
     1298    pcst => { #7
     1299        Name => 'Podcast',
     1300        PrintConv => { 0 => 'No', 1 => 'Yes' },
     1301    },
     1302    perf => 'Performer',
     1303    plID => { #10 (or TV season)
     1304        Name => 'PlayListID',
     1305        Format => 'int8u',  # actually int64u, but split it up
     1306    },
     1307    purd => 'PurchaseDate', #7
     1308    purl => 'PodcastURL', #7
     1309    rtng => { #10
     1310        Name => 'Rating',
     1311        PrintConv => {
     1312            0 => 'none',
     1313            2 => 'Clean',
     1314            4 => 'Explicit',
     1315        },
     1316    },
     1317    sfID => { #10
     1318        Name => 'AppleStoreCountry',
     1319        Format => 'int32u',
     1320        PrintConv => {
     1321            143460 => 'Australia',
     1322            143445 => 'Austria',
     1323            143446 => 'Belgium',
     1324            143455 => 'Canada',
     1325            143458 => 'Denmark',
     1326            143447 => 'Finland',
     1327            143442 => 'France',
     1328            143443 => 'Germany',
     1329            143448 => 'Greece',
     1330            143449 => 'Ireland',
     1331            143450 => 'Italy',
     1332            143462 => 'Japan',
     1333            143451 => 'Luxembourg',
     1334            143452 => 'Netherlands',
     1335            143461 => 'New Zealand',
     1336            143457 => 'Norway',
     1337            143453 => 'Portugal',
     1338            143454 => 'Spain',
     1339            143456 => 'Sweden',
     1340            143459 => 'Switzerland',
     1341            143444 => 'United Kingdom',
     1342            143441 => 'United States',
     1343        },
     1344    },
     1345    soaa => 'SortAlbumArtist', #10
     1346    soal => 'SortAlbum', #10
     1347    soar => 'SortArtist', #10
     1348    soco => 'SortComposer', #10
     1349    sonm => 'SortName', #10
     1350    sosn => 'SortShow', #10
     1351    stik => { #10
     1352        Name => 'MediaType',
     1353        PrintConv => { #(http://weblog.xanga.com/gryphondwb/615474010/iphone-ringtones---what-did-itunes-741-really-do.html)
     1354            0 => 'Movie',
     1355            1 => 'Normal (Music)',
     1356            2 => 'Audiobook',
     1357            5 => 'Whacked Bookmark',
     1358            6 => 'Music Video',
     1359            9 => 'Short Film',
     1360            10 => 'TV Show',
     1361            11 => 'Booklet',
     1362            14 => 'Ringtone',
     1363        },
     1364    },
     1365    titl => 'Title',
     1366    tven => 'TVEpisodeID', #7
     1367    tves => { #7/10
     1368        Name => 'TVEpisode',
     1369        Format => 'int32u',
     1370    },
     1371    tvnn => 'TVNetworkName', #7
     1372    tvsh => 'TVShow', #10
     1373    tvsn => { #7/10
     1374        Name => 'TVSeason',
     1375        Format => 'int32u',
     1376    },
     1377    yrrc => 'Year', #(ffmpeg source)
     1378);
     1379
     1380# item list keys (ref PH)
     1381%Image::ExifTool::QuickTime::Keys = (
     1382    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessKeys,
     1383    NOTES => q{
     1384        This directory contains a list of key names which are used to decode
     1385        ItemList tags written by the "mdta" handler.  The prefix of
     1386        "com.apple.quicktime." has been removed from all TagID's below.
     1387    },
     1388    version     => 'Version',
     1389    album       => 'Album',
     1390    artist      => { },
     1391    artwork     => { },
     1392    author      => { Name => 'Author',      Groups => { 2 => 'Author' } },
     1393    comment     => { },
     1394    copyright   => { Name => 'Copyright',   Groups => { 2 => 'Author' } },
     1395    creationdate=> {
     1396        Name => 'CreationDate',
     1397        Groups => { 2 => 'Time' },
     1398        ValueConv => q{
     1399            require Image::ExifTool::XMP;
     1400            $val =  Image::ExifTool::XMP::ConvertXMPDate($val,1);
     1401            $val =~ s/([-+]\d{2})(\d{2})$/$1:$2/; # add colon to timezone if necessary
     1402            return $val;
     1403        },
     1404        PrintConv => '$self->ConvertDateTime($val)',
     1405    },
     1406    description => { },
     1407    director    => { },
     1408    genre       => { },
     1409    information => { },
     1410    keywords    => { },
     1411    make        => { Name => 'Make',        Groups => { 2 => 'Camera' } },
     1412    model       => { Name => 'Model',       Groups => { 2 => 'Camera' } },
     1413    publisher   => { },
     1414    software    => { },
     1415    year        => { Groups => { 2 => 'Time' } },
     1416    'camera.identifier' => 'CameraIdentifier', # (iPhone 4)
     1417    'camera.framereadouttimeinmicroseconds' => { # (iPhone 4)
     1418        Name => 'FrameReadoutTime',
     1419        ValueConv => '$val * 1e-6',
     1420        PrintConv => '$val * 1e6 . " microseconds"',
     1421    },
     1422    'location.ISO6709' => {
     1423        Name => 'GPSCoordinates',
     1424        Groups => { 2 => 'Location' },
     1425        ValueConv => \&ConvertISO6709,
     1426        PrintConv => \&PrintGPSCoordinates,
     1427    },
     1428    'location.name' => { Name => 'LocationName', Groups => { 2 => 'Location' } },
     1429    'location.body' => { Name => 'LocationBody', Groups => { 2 => 'Location' } },
     1430    'location.note' => { Name => 'LocationNote', Groups => { 2 => 'Location' } },
     1431    'location.role' => {
     1432        Name => 'LocationRole',
     1433        Groups => { 2 => 'Location' },
     1434        PrintConv => {
     1435            0 => 'Shooting Location',
     1436            1 => 'Real Location',
     1437            2 => 'Fictional Location',
     1438        },
     1439    },
     1440    'location.date' => {
     1441        Name => 'LocationDate',
     1442        Groups => { 2 => 'Time' },
     1443        ValueConv => q{
     1444            require Image::ExifTool::XMP;
     1445            $val =  Image::ExifTool::XMP::ConvertXMPDate($val);
     1446            $val =~ s/([-+]\d{2})(\d{2})$/$1:$2/; # add colon to timezone if necessary
     1447            return $val;
     1448        },
     1449        PrintConv => '$self->ConvertDateTime($val)',
     1450    },
     1451    'direction.facing' => { Name => 'CameraDirection', Groups => { 2 => 'Location' } },
     1452    'direction.motion' => { Name => 'CameraMotion', Groups => { 2 => 'Location' } },
     1453    'location.body' => { Name => 'LocationBody', Groups => { 2 => 'Location' } },
     1454    'player.version'                => 'PlayerVersion',
     1455    'player.movie.visual.brightness'=> 'Brightness',
     1456    'player.movie.visual.color'     => 'Color',
     1457    'player.movie.visual.tint'      => 'Tint',
     1458    'player.movie.visual.contrast'  => 'Contrast',
     1459    'player.movie.audio.gain'       => 'AudioGain',
     1460    'player.movie.audio.treble'     => 'Trebel',
     1461    'player.movie.audio.bass'       => 'Bass',
     1462    'player.movie.audio.balance'    => 'Balance',
     1463    'player.movie.audio.pitchshift' => 'PitchShift',
     1464    'player.movie.audio.mute' => {
     1465        Name => 'Mute',
     1466        Format => 'int8u',
     1467        PrintConv => { 0 => 'Off', 1 => 'On' },
     1468    },
     1469);
     1470
     1471# iTunes info ('----') atoms
    4351472%Image::ExifTool::QuickTime::iTunesInfo = (
    436     PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
     1473    PROCESS_PROC => \&ProcessMOV,
    4371474    GROUPS => { 2 => 'Audio' },
     1475    # 'mean'/'name'/'data' atoms form a triplet, but unfortunately
     1476    # I can't find any source for decoding 'data'.
     1477    # 'mean' is normally 'com.apple.iTunes'
     1478    # 'name' values: 'tool', 'iTunNORM' (volume normalization),
     1479    #   'iTunSMPB', 'iTunes_CDDB_IDs', 'iTunes_CDDB_TrackNumber'
     1480    mean => {
     1481        Name => 'Mean',
     1482        Unknown => 1,
     1483    },
     1484    name => {
     1485        Name => 'Name',
     1486        Unknown => 1,
     1487    },
     1488    data => {
     1489        Name => 'Data',
     1490        Flags => ['Binary','Unknown'],
     1491    },
    4381492);
    4391493
     
    4611515);
    4621516
    463 # MP4 media
     1517# 'hnti' atoms
     1518%Image::ExifTool::QuickTime::HintInfo = (
     1519    PROCESS_PROC => \&ProcessMOV,
     1520    GROUPS => { 2 => 'Video' },
     1521    'rtp ' => {
     1522        Name => 'RealtimeStreamingProtocol',
     1523        PrintConv => '$val=~s/^sdp /(SDP) /; $val',
     1524    },
     1525    'sdp ' => 'StreamingDataProtocol',
     1526);
     1527
     1528# 'hinf' atoms
     1529%Image::ExifTool::QuickTime::HintTrackInfo = (
     1530    PROCESS_PROC => \&ProcessMOV,
     1531    GROUPS => { 2 => 'Video' },
     1532    trpY => { Name => 'TotalBytes', Format => 'int64u' }, #(documented)
     1533    trpy => { Name => 'TotalBytes', Format => 'int64u' }, #(observed)
     1534    totl => { Name => 'TotalBytes', Format => 'int32u' },
     1535    nump => { Name => 'NumPackets', Format => 'int64u' },
     1536    npck => { Name => 'NumPackets', Format => 'int32u' },
     1537    tpyl => { Name => 'TotalBytesNoRTPHeaders', Format => 'int64u' },
     1538    tpaY => { Name => 'TotalBytesNoRTPHeaders', Format => 'int32u' }, #(documented)
     1539    tpay => { Name => 'TotalBytesNoRTPHeaders', Format => 'int32u' }, #(observed)
     1540    maxr => {
     1541        Name => 'MaxDataRate',
     1542        Format => 'int32u',
     1543        Count => 2,
     1544        PrintConv => 'my @a=split(" ",$val);sprintf("%d bytes in %.3f s",$a[1],$a[0]/1000)',
     1545    },
     1546    dmed => { Name => 'MediaTrackBytes',    Format => 'int64u' },
     1547    dimm => { Name => 'ImmediateDataBytes', Format => 'int64u' },
     1548    drep => { Name => 'RepeatedDataBytes',  Format => 'int64u' },
     1549    tmin => {
     1550        Name => 'MinTransmissionTime',
     1551        Format => 'int32u',
     1552        PrintConv => 'sprintf("%.3f s",$val/1000)',
     1553    },
     1554    tmax => {
     1555        Name => 'MaxTransmissionTime',
     1556        Format => 'int32u',
     1557        PrintConv => 'sprintf("%.3f s",$val/1000)',
     1558    },
     1559    pmax => { Name => 'LargestPacketSize',  Format => 'int32u' },
     1560    dmax => {
     1561        Name => 'LargestPacketDuration',
     1562        Format => 'int32u',
     1563        PrintConv => 'sprintf("%.3f s",$val/1000)',
     1564    },
     1565    payt => {
     1566        Name => 'PayloadType',
     1567        ValueConv => 'unpack("N",$val) . " " . substr($val, 5)',
     1568        PrintConv => '$val=~s/ /, /;$val',
     1569    },
     1570);
     1571
     1572# Kodak DcMD atoms (ref PH)
     1573%Image::ExifTool::QuickTime::DcMD = (
     1574    PROCESS_PROC => \&ProcessMOV,
     1575    GROUPS => { 2 => 'Video' },
     1576    NOTES => 'Metadata directory found in MOV videos from some Kodak cameras.',
     1577    Cmbo => {
     1578        Name => 'CameraByteOrder',
     1579        PrintConv => {
     1580            II => 'Little-endian (Intel, II)',
     1581            MM => 'Big-endian (Motorola, MM)',
     1582        },
     1583    },
     1584    DcME => {
     1585        Name => 'DcME',
     1586        SubDirectory => {
     1587            TagTable => 'Image::ExifTool::QuickTime::DcME',
     1588        },
     1589    },
     1590);
     1591
     1592# Kodak DcME atoms (ref PH)
     1593%Image::ExifTool::QuickTime::DcME = (
     1594    PROCESS_PROC => \&ProcessMOV,
     1595    GROUPS => { 2 => 'Video' },
     1596    # Mtmd = binary data ("00 00 00 00 00 00 00 01" x 3)
     1597    # Keyw = keywords? (six bytes all zero)
     1598    # Rate = 2 bytes "00 00"
     1599);
     1600
     1601# MP4 media box (ref 5)
    4641602%Image::ExifTool::QuickTime::Media = (
    465     PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
     1603    PROCESS_PROC => \&ProcessMOV,
    4661604    GROUPS => { 2 => 'Video' },
    467     NOTES => 'MP4 only (most tags unknown because ISO charges for the specification).',
     1605    NOTES => 'MP4 media box.',
     1606    mdhd => {
     1607        Name => 'MediaHeader',
     1608        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::MediaHeader' },
     1609    },
     1610    hdlr => {
     1611        Name => 'Handler',
     1612        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Handler' },
     1613    },
    4681614    minf => {
    469         Name => 'Minf',
    470         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Minf' },
    471     },
    472 );
    473 
    474 %Image::ExifTool::QuickTime::Minf = (
    475     PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
     1615        Name => 'MediaInfo',
     1616        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::MediaInfo' },
     1617    },
     1618);
     1619
     1620# MP4 media header box (ref 5)
     1621%Image::ExifTool::QuickTime::MediaHeader = (
     1622    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    4761623    GROUPS => { 2 => 'Video' },
    477     NOTES => 'MP4 only (most tags unknown because ISO charges for the specification).',
     1624    FORMAT => 'int32u',
     1625    0 => {
     1626        Name => 'MediaHeaderVersion',
     1627        RawConv => '$$self{MediaHeaderVersion} = $val',
     1628    },
     1629    1 => {
     1630        Name => 'MediaCreateDate',
     1631        Groups => { 2 => 'Time' },
     1632        %timeInfo,
     1633        # this is int64u if MediaHeaderVersion == 1 (ref 5/13)
     1634        Hook => '$$self{MediaHeaderVersion} and $format = "int64u", $varSize += 4',
     1635    },
     1636    2 => {
     1637        Name => 'MediaModifyDate',
     1638        Groups => { 2 => 'Time' },
     1639        %timeInfo,
     1640        # this is int64u if MediaHeaderVersion == 1 (ref 5/13)
     1641        Hook => '$$self{MediaHeaderVersion} and $format = "int64u", $varSize += 4',
     1642    },
     1643    3 => {
     1644        Name => 'MediaTimeScale',
     1645        RawConv => '$$self{MediaTS} = $val',
     1646    },
     1647    4 => {
     1648        Name => 'MediaDuration',
     1649        RawConv => '$$self{MediaTS} ? $val / $$self{MediaTS} : $val',
     1650        PrintConv => '$$self{MediaTS} ? ConvertDuration($val) : $val',
     1651        # this is int64u if MediaHeaderVersion == 1 (ref 5/13)
     1652        Hook => '$$self{MediaHeaderVersion} and $format = "int64u", $varSize += 4',
     1653    },
     1654    5 => {
     1655        Name => 'MediaLanguageCode',
     1656        Format => 'int16u',
     1657        RawConv => '$val ? $val : undef',
     1658        # allow both Macintosh (for MOV files) and ISO (for MP4 files) language codes
     1659        ValueConv => '$val < 0x400 ? $val : pack "C*", map { (($val>>$_)&0x1f)+0x60 } 10, 5, 0',
     1660        PrintConv => q{
     1661            return $val unless $val =~ /^\d+$/;
     1662            require Image::ExifTool::Font;
     1663            return $Image::ExifTool::Font::ttLang{Macintosh}{$val} || "Unknown ($val)";
     1664        },
     1665    },
     1666);
     1667
     1668# MP4 media information box (ref 5)
     1669%Image::ExifTool::QuickTime::MediaInfo = (
     1670    PROCESS_PROC => \&ProcessMOV,
     1671    GROUPS => { 2 => 'Video' },
     1672    NOTES => 'MP4 media info box.',
     1673    vmhd => {
     1674        Name => 'VideoHeader',
     1675        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::VideoHeader' },
     1676    },
     1677    smhd => {
     1678        Name => 'AudioHeader',
     1679        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::AudioHeader' },
     1680    },
     1681    hmhd => {
     1682        Name => 'HintHeader',
     1683        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::HintHeader' },
     1684    },
     1685    nmhd => {
     1686        Name => 'NullMediaHeader',
     1687        Flags => ['Binary','Unknown'],
     1688    },
    4781689    dinf => {
    479         Name => 'Dinf',
    480         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Dinf' },
     1690        Name => 'DataInfo',
     1691        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::DataInfo' },
     1692    },
     1693    gmhd => {
     1694        Name => 'GenMediaHeader',
     1695        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::GenMediaHeader' },
     1696    },
     1697    hdlr => { #PH
     1698        Name => 'Handler',
     1699        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Handler' },
    4811700    },
    4821701    stbl => {
    483         Name => 'Stbl',
    484         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Stbl' },
    485     },
    486 );
    487 
    488 %Image::ExifTool::QuickTime::Stbl = (
    489     PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
     1702        Name => 'SampleTable',
     1703        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::SampleTable' },
     1704    },
     1705);
     1706
     1707# MP4 video media header (ref 5)
     1708%Image::ExifTool::QuickTime::VideoHeader = (
     1709    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    4901710    GROUPS => { 2 => 'Video' },
    491     NOTES => 'MP4 only (most tags unknown because ISO charges for the specification).',
    492 );
    493 
    494 %Image::ExifTool::QuickTime::Dinf = (
    495     PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
     1711    NOTES => 'MP4 video media header.',
     1712    FORMAT => 'int16u',
     1713    2 => {
     1714        Name => 'GraphicsMode',
     1715        PrintHex => 1,
     1716        SeparateTable => 'GraphicsMode',
     1717        PrintConv => \%graphicsMode,
     1718    },
     1719    3 => { Name => 'OpColor', Format => 'int16u[3]' },
     1720);
     1721
     1722# MP4 audio media header (ref 5)
     1723%Image::ExifTool::QuickTime::AudioHeader = (
     1724    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1725    GROUPS => { 2 => 'Audio' },
     1726    NOTES => 'MP4 audio media header.',
     1727    FORMAT => 'int16u',
     1728    2 => { Name => 'Balance', Format => 'fixed16s' },
     1729);
     1730
     1731# MP4 hint media header (ref 5)
     1732%Image::ExifTool::QuickTime::HintHeader = (
     1733    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1734    NOTES => 'MP4 hint media header.',
     1735    FORMAT => 'int16u',
     1736    2 => 'MaxPDUSize',
     1737    3 => 'AvgPDUSize',
     1738    4 => { Name => 'MaxBitrate', Format => 'int32u', PrintConv => 'ConvertBitrate($val)' },
     1739    6 => { Name => 'AvgBitrate', Format => 'int32u', PrintConv => 'ConvertBitrate($val)' },
     1740);
     1741
     1742# MP4 sample table box (ref 5)
     1743%Image::ExifTool::QuickTime::SampleTable = (
     1744    PROCESS_PROC => \&ProcessMOV,
    4961745    GROUPS => { 2 => 'Video' },
    497     NOTES => 'MP4 only (most tags unknown because ISO charges for the specification).',
    498 );
     1746    NOTES => 'MP4 sample table box.',
     1747    stsd => [
     1748        {
     1749            Name => 'AudioSampleDesc',
     1750            Condition => '$$self{HandlerType} and $$self{HandlerType} eq "soun"',
     1751            SubDirectory => {
     1752                TagTable => 'Image::ExifTool::QuickTime::AudioSampleDesc',
     1753                Start => 8, # skip version number and count
     1754            },
     1755        },{
     1756            Name => 'VideoSampleDesc',
     1757            Condition => '$$self{HandlerType} and $$self{HandlerType} eq "vide"',
     1758            SubDirectory => {
     1759                TagTable => 'Image::ExifTool::QuickTime::ImageDesc',
     1760                Start => 8, # skip version number and count
     1761            },
     1762        },{
     1763            Name => 'HintSampleDesc',
     1764            Condition => '$$self{HandlerType} and $$self{HandlerType} eq "hint"',
     1765            SubDirectory => {
     1766                TagTable => 'Image::ExifTool::QuickTime::HintSampleDesc',
     1767                Start => 8, # skip version number and count
     1768            },
     1769        },{
     1770            Name => 'OtherSampleDesc',
     1771            SubDirectory => {
     1772                TagTable => 'Image::ExifTool::QuickTime::OtherSampleDesc',
     1773                Start => 8, # skip version number and count
     1774            },
     1775        },
     1776        # (Note: "alis" HandlerType handled by the parent audio or video handler)
     1777    ],
     1778    stts => [ # decoding time-to-sample table
     1779        {
     1780            Name => 'VideoFrameRate',
     1781            Notes => 'average rate calculated from time-to-sample table for video media',
     1782            Condition => '$$self{HandlerType} and $$self{HandlerType} eq "vide"',
     1783            # (must be RawConv so appropriate MediaTS is used in calculation)
     1784            RawConv => 'Image::ExifTool::QuickTime::CalcSampleRate($self, \$val)',
     1785            PrintConv => 'int($val * 1000 + 0.5) / 1000',
     1786        },
     1787        {
     1788            Name => 'TimeToSampleTable',
     1789            Flags => ['Binary','Unknown'],
     1790        },
     1791    ],
     1792    ctts => {
     1793        Name => 'CompositionTimeToSample',
     1794        Flags => ['Binary','Unknown'],
     1795    },
     1796    stsc => {
     1797        Name => 'SampleToChunk',
     1798        Flags => ['Binary','Unknown'],
     1799    },
     1800    stsz => {
     1801        Name => 'SampleSizes',
     1802        Flags => ['Binary','Unknown'],
     1803    },
     1804    stz2 => {
     1805        Name => 'CompactSampleSizes',
     1806        Flags => ['Binary','Unknown'],
     1807    },
     1808    stco => {
     1809        Name => 'ChunkOffset',
     1810        Flags => ['Binary','Unknown'],
     1811    },
     1812    co64 => {
     1813        Name => 'ChunkOffset64',
     1814        Flags => ['Binary','Unknown'],
     1815    },
     1816    stss => {
     1817        Name => 'SyncSampleTable',
     1818        Flags => ['Binary','Unknown'],
     1819    },
     1820    stsh => {
     1821        Name => 'ShadowSyncSampleTable',
     1822        Flags => ['Binary','Unknown'],
     1823    },
     1824    padb => {
     1825        Name => 'SamplePaddingBits',
     1826        Flags => ['Binary','Unknown'],
     1827    },
     1828    stdp => {
     1829        Name => 'SampleDegradationPriority',
     1830        Flags => ['Binary','Unknown'],
     1831    },
     1832    sdtp => {
     1833        Name => 'IdependentAndDisposableSamples',
     1834        Flags => ['Binary','Unknown'],
     1835    },
     1836    sbgp => {
     1837        Name => 'SampleToGroup',
     1838        Flags => ['Binary','Unknown'],
     1839    },
     1840    sgpd => {
     1841        Name => 'SampleGroupDescription',
     1842        Flags => ['Binary','Unknown'],
     1843    },
     1844    subs => {
     1845        Name => 'Sub-sampleInformation',
     1846        Flags => ['Binary','Unknown'],
     1847    },
     1848    cslg => {
     1849        Name => 'CompositionToDecodeTimelineMapping',
     1850        Flags => ['Binary','Unknown'],
     1851    },
     1852);
     1853
     1854# MP4 audio sample description box (ref 5)
     1855%Image::ExifTool::QuickTime::AudioSampleDesc = (
     1856    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1857    GROUPS => { 2 => 'Audio' },
     1858    FORMAT => 'int16u',
     1859    NOTES => 'MP4 audio sample description.',
     1860    2  => {
     1861        Name => 'AudioFormat',
     1862        Format => 'undef[4]',
     1863        RawConv => q{
     1864            return undef unless $val =~ /^[\w ]{4}$/i;
     1865            # check for protected audio format
     1866            $self->OverrideFileType('M4P') if $val eq 'drms' and $$self{VALUE}{FileType} eq 'M4A';
     1867            return $val;
     1868        },
     1869    },
     1870    10 => { #PH
     1871        Name => 'AudioVendorID',
     1872        Format => 'undef[4]',
     1873        RawConv => '$val eq "\0\0\0\0" ? undef : $val',
     1874        PrintConv => \%vendorID,
     1875        SeparateTable => 'VendorID',
     1876    },
     1877    12 => 'AudioChannels',
     1878    13 => 'AudioBitsPerSample',
     1879    16 => { Name => 'AudioSampleRate', Format => 'fixed32u' },
     1880    28 => { #PH
     1881        Name => 'AudioFormat',
     1882        Format => 'undef[4]',
     1883        RawConv => '$val =~ /^[\w ]{4}$/i ? $val : undef',
     1884        Notes => 'in Casio MOV videos',
     1885    },
     1886);
     1887
     1888# MP4 hint sample description box (ref 5)
     1889%Image::ExifTool::QuickTime::HintSampleDesc = (
     1890    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1891    FORMAT => 'int16u',
     1892    NOTES => 'MP4 hint sample description.',
     1893    2 => { Name => 'HintFormat', Format => 'undef[4]' },
     1894);
     1895
     1896# MP4 generic sample description box
     1897%Image::ExifTool::QuickTime::OtherSampleDesc = (
     1898    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1899    FORMAT => 'int16u',
     1900    2 => { Name => 'OtherFormat', Format => 'undef[4]' },
     1901);
     1902
     1903# MP4 data information box (ref 5)
     1904%Image::ExifTool::QuickTime::DataInfo = (
     1905    PROCESS_PROC => \&ProcessMOV,
     1906    NOTES => 'MP4 data information box.',
     1907    dref => {
     1908        Name => 'DataRef',
     1909        SubDirectory => {
     1910            TagTable => 'Image::ExifTool::QuickTime::DataRef',
     1911            Start => 8,
     1912        },
     1913    },
     1914);
     1915
     1916# Generic media header
     1917%Image::ExifTool::QuickTime::GenMediaHeader = (
     1918    PROCESS_PROC => \&ProcessMOV,
     1919    gmin => {
     1920        Name => 'GenMediaInfo',
     1921        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::GenMediaInfo' },
     1922    },
     1923    text => {
     1924        Name => 'Text',
     1925        Flags => ['Binary','Unknown'],
     1926    },
     1927);
     1928
     1929# Generic media info (ref http://sourceforge.jp/cvs/view/ntvrec/ntvrec/libqtime/gmin.h?view=co)
     1930%Image::ExifTool::QuickTime::GenMediaInfo = (
     1931    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1932    GROUPS => { 2 => 'Video' },
     1933    0  => 'GenMediaVersion',
     1934    1  => { Name => 'GenFlags',   Format => 'int8u[3]' },
     1935    4  => { Name => 'GenGraphicsMode',
     1936        Format => 'int16u',
     1937        PrintHex => 1,
     1938        SeparateTable => 'GraphicsMode',
     1939        PrintConv => \%graphicsMode,
     1940    },
     1941    6  => { Name => 'GenOpColor', Format => 'int16u[3]' },
     1942    12 => { Name => 'GenBalance', Format => 'fixed16s' },
     1943);
     1944
     1945# MP4 data reference box (ref 5)
     1946%Image::ExifTool::QuickTime::DataRef = (
     1947    PROCESS_PROC => \&ProcessMOV,
     1948    NOTES => 'MP4 data reference box.',
     1949    'url ' => {
     1950        Name => 'URL',
     1951        RawConv => q{
     1952            # ignore if self-contained (flags bit 0 set)
     1953            return undef if unpack("N",$val) & 0x01;
     1954            $_ = substr($val,4); s/\0.*//s; $_;
     1955        },
     1956    },
     1957    'urn ' => {
     1958        Name => 'URN',
     1959        RawConv => q{
     1960            return undef if unpack("N",$val) & 0x01;
     1961            $_ = substr($val,4); s/\0.*//s; $_;
     1962        },
     1963    },
     1964);
     1965
     1966# MP4 handler box (ref 5)
     1967%Image::ExifTool::QuickTime::Handler = (
     1968    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1969    GROUPS => { 2 => 'Video' },
     1970    4 => { #PH
     1971        Name => 'HandlerClass',
     1972        Format => 'undef[4]',
     1973        RawConv => '$val eq "\0\0\0\0" ? undef : $val',
     1974        PrintConv => {
     1975            mhlr => 'Media Handler',
     1976            dhlr => 'Data Handler',
     1977        },
     1978    },
     1979    8 => {
     1980        Name => 'HandlerType',
     1981        Format => 'undef[4]',
     1982        RawConv => '$$self{HandlerType} = $val unless $val eq "alis"; $val',
     1983        PrintConv => {
     1984            alis => 'Alias Data', #PH
     1985            crsm => 'Clock Reference', #3
     1986            hint => 'Hint Track',
     1987            ipsm => 'IPMP', #3
     1988            m7sm => 'MPEG-7 Stream', #3
     1989            mdir => 'Metadata', #3
     1990            mdta => 'Metadata Tags', #PH
     1991            mjsm => 'MPEG-J', #3
     1992            ocsm => 'Object Content', #3
     1993            odsm => 'Object Descriptor', #3
     1994            sdsm => 'Scene Description', #3
     1995            soun => 'Audio Track',
     1996            text => 'Text', #PH (but what type? subtitle?)
     1997           'url '=> 'URL', #3
     1998            vide => 'Video Track',
     1999        },
     2000    },
     2001    12 => { #PH
     2002        Name => 'HandlerVendorID',
     2003        Format => 'undef[4]',
     2004        RawConv => '$val eq "\0\0\0\0" ? undef : $val',
     2005        PrintConv => \%vendorID,
     2006        SeparateTable => 'VendorID',
     2007    },
     2008    24 => {
     2009        Name => 'HandlerDescription',
     2010        Format => 'string',
     2011        # (sometimes this is a Pascal string, and sometimes it is a C string)
     2012        RawConv => q{
     2013            $val=substr($val,1,ord($1)) if $val=~/^([\0-\x1f])/ and ord($1)<length($val);
     2014            length $val ? $val : undef;
     2015        },
     2016    },
     2017);
     2018
     2019# Flip uuid data (ref PH)
     2020%Image::ExifTool::QuickTime::Flip = (
     2021    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     2022    FORMAT => 'int32u',
     2023    FIRST_ENTRY => 0,
     2024    NOTES => 'Found in MP4 files from Flip Video cameras.',
     2025    GROUPS => { 1 => 'MakerNotes', 2 => 'Image' },
     2026    1 => 'PreviewImageWidth',
     2027    2 => 'PreviewImageHeight',
     2028    13 => 'PreviewImageLength',
     2029    14 => { # (confirmed for FlipVideoMinoHD)
     2030        Name => 'SerialNumber',
     2031        Groups => { 2 => 'Camera' },
     2032        Format => 'string[16]',
     2033    },
     2034    28 => {
     2035        Name => 'PreviewImage',
     2036        Format => 'undef[$val{13}]',
     2037        RawConv => '$self->ValidateImage(\$val, $tag)',
     2038    },
     2039);
     2040
     2041# QuickTime composite tags
     2042%Image::ExifTool::QuickTime::Composite = (
     2043    GROUPS => { 2 => 'Video' },
     2044    Rotation => {
     2045        Require => {
     2046            0 => 'QuickTime:MatrixStructure',
     2047            1 => 'QuickTime:HandlerType',
     2048        },
     2049        ValueConv => 'Image::ExifTool::QuickTime::CalcRotation($self)',
     2050    },
     2051    AvgBitrate => {
     2052        Priority => 0,  # let QuickTime::AvgBitrate take priority
     2053        Require => {
     2054            0 => 'QuickTime::MovieDataSize',
     2055            1 => 'QuickTime::Duration',
     2056        },
     2057        RawConv => q{
     2058            return undef unless $val[1];
     2059            $val[1] /= $$self{TimeScale} if $$self{TimeScale};
     2060            return int($val[0] * 8 / $val[1] + 0.5);
     2061        },
     2062        PrintConv => 'ConvertBitrate($val)',
     2063    },
     2064    GPSLatitude => {
     2065        Require => 'QuickTime:GPSCoordinates',
     2066        Groups => { 2 => 'Location' },
     2067        ValueConv => 'my @c = split " ", $val; $c[0]',
     2068        PrintConv => q{
     2069            require Image::ExifTool::GPS;
     2070            Image::ExifTool::GPS::ToDMS($self, $val, 1, 'N');
     2071        },
     2072    },
     2073    GPSLongitude => {
     2074        Require => 'QuickTime:GPSCoordinates',
     2075        Groups => { 2 => 'Location' },
     2076        ValueConv => 'my @c = split " ", $val; $c[1]',
     2077        PrintConv => q{
     2078            require Image::ExifTool::GPS;
     2079            Image::ExifTool::GPS::ToDMS($self, $val, 1, 'E');
     2080        },
     2081    },
     2082    # split altitude into GPSAltitude/GPSAltitudeRef like EXIF and XMP
     2083    GPSAltitude => {
     2084        Require => 'QuickTime:GPSCoordinates',
     2085        Groups => { 2 => 'Location' },
     2086        Priority => 0, # (because it may not exist)
     2087        ValueConv => 'my @c = split " ", $val; defined $c[2] ? abs($c[2]) : undef',
     2088        PrintConv => '"$val m"',
     2089    },
     2090    GPSAltitudeRef  => {
     2091        Require => 'QuickTime:GPSCoordinates',
     2092        Groups => { 2 => 'Location' },
     2093        Priority => 0, # (because altitude information may not exist)
     2094        ValueConv => 'my @c = split " ", $val; defined $c[2] ? ($c[2] < 0 ? 1 : 0) : undef',
     2095        PrintConv => {
     2096            0 => 'Above Sea Level',
     2097            1 => 'Below Sea Level',
     2098        },
     2099    },
     2100);
     2101
     2102# add our composite tags
     2103Image::ExifTool::AddCompositeTags('Image::ExifTool::QuickTime');
     2104
     2105
     2106#------------------------------------------------------------------------------
     2107# Calculate rotation of video track
     2108# Inputs: 0) ExifTool object ref
     2109# Returns: rotation angle or undef
     2110sub CalcRotation($)
     2111{
     2112    my $exifTool = shift;
     2113    my $value = $$exifTool{VALUE};
     2114    my ($i, $track);
     2115    # get the video track family 1 group (ie. "Track1");
     2116    for ($i=0; ; ++$i) {
     2117        my $idx = $i ? " ($i)" : '';
     2118        my $tag = "HandlerType$idx";
     2119        last unless $$value{$tag};
     2120        next unless $$value{$tag} eq 'vide';
     2121        $track = $exifTool->GetGroup($tag, 1);
     2122        last;
     2123    }
     2124    return undef unless $track;
     2125    # get the video track matrix
     2126    for ($i=0; ; ++$i) {
     2127        my $idx = $i ? " ($i)" : '';
     2128        my $tag = "MatrixStructure$idx";
     2129        last unless $$value{$tag};
     2130        next unless $exifTool->GetGroup($tag, 1) eq $track;
     2131        my @a = split ' ', $$value{$tag};
     2132        return undef unless $a[0] or $a[1];
     2133        # calculate the rotation angle (assume uniform rotation)
     2134        my $angle = atan2($a[1], $a[0]) * 180 / 3.14159;
     2135        $angle += 360 if $angle < 0;
     2136        return int($angle * 1000 + 0.5) / 1000;
     2137    }
     2138    return undef;
     2139}
     2140
     2141#------------------------------------------------------------------------------
     2142# Determine the average sample rate from a time-to-sample table
     2143# Inputs: 0) ExifTool object ref, 1) time-to-sample table data ref
     2144# Returns: average sample rate (in Hz)
     2145sub CalcSampleRate($$)
     2146{
     2147    my ($exifTool, $valPt) = @_;
     2148    my @dat = unpack('N*', $$valPt);
     2149    my ($num, $dur) = (0, 0);
     2150    my $i;
     2151    for ($i=2; $i<@dat-1; $i+=2) {
     2152        $num += $dat[$i];               # total number of samples
     2153        $dur += $dat[$i] * $dat[$i+1];  # total sample duration
     2154    }
     2155    return undef unless $num and $dur and $$exifTool{MediaTS};
     2156    return $num * $$exifTool{MediaTS} / $dur;
     2157}
    4992158
    5002159#------------------------------------------------------------------------------
     
    5112170
    5122171#------------------------------------------------------------------------------
     2172# Convert ISO 6709 string to standard lag/lon format
     2173# Inputs: 0) ISO 6709 string (lat, lon, and optional alt)
     2174# Returns: position in decimal degress with altitude if available
     2175# Notes: Wikipedia indicates altitude may be in feet -- how is this specified?
     2176sub ConvertISO6709($)
     2177{
     2178    my $val = shift;
     2179    if ($val =~ /^([-+]\d{2}(?:\.\d*)?)([-+]\d{3}(?:\.\d*)?)([-+]\d+)?/) {
     2180        $val = ($1 + 0) . ' ' . ($2 + 0);
     2181        $val .= ' ' . ($3 + 0) if $3;
     2182    } elsif ($val =~ /^([-+])(\d{2})(\d{2}(?:\.\d*)?)([-+])(\d{3})(\d{2}(?:\.\d*)?)([-+]\d+)?/) {
     2183        my $lat = $2 + $3 / 60;
     2184        $lat = -$lat if $1 eq '-';
     2185        my $lon = $5 + $6 / 60;
     2186        $lon = -$lon if $4 eq '-';
     2187        $val = "$lat $lon";
     2188        $val .= ' ' . ($7 + 0) if $7;
     2189    } elsif ($val =~ /^([-+])(\d{2})(\d{2})(\d{2}(?:\.\d*)?)([-+])(\d{3})(\d{2})(\d{2}(?:\.\d*)?)([-+]\d+)?/) {
     2190        my $lat = $2 + $3 / 60 + $4 / 3600;
     2191        $lat = -$lat if $1 eq '-';
     2192        my $lon = $6 + $7 / 60 + $8 / 3600;
     2193        $lon = -$lon if $5 eq '-';
     2194        $val = "$lat $lon";
     2195        $val .= ' ' . ($9 + 0) if $9;
     2196    }
     2197    return $val;
     2198}
     2199
     2200#------------------------------------------------------------------------------
     2201# Format GPSCoordinates for printing
     2202# Inputs: 0) string with numerical lat, lon and optional alt, separated by spaces
     2203#         1) ExifTool object reference
     2204# Returns: PrintConv value
     2205sub PrintGPSCoordinates($)
     2206{
     2207    my ($val, $exifTool) = @_;
     2208    require Image::ExifTool::GPS;
     2209    my @v = split ' ', $val;
     2210    my $prt = Image::ExifTool::GPS::ToDMS($exifTool, $v[0], 1, "N") . ', ' .
     2211              Image::ExifTool::GPS::ToDMS($exifTool, $v[1], 1, "E");
     2212    if (defined $v[2]) {
     2213        $prt .= ', ' . ($v[2] < 0 ? -$v[2] . ' m Below' : $v[2] . ' m Above') . ' Sea Level';
     2214    }
     2215    return $prt;
     2216}
     2217
     2218#------------------------------------------------------------------------------
     2219# Unpack packed ISO 639/T language code
     2220# Inputs: 0) packed language code (or undef)
     2221# Returns: language code, or undef for default language, or 'err' for format error
     2222sub UnpackLang($)
     2223{
     2224    my $lang = shift;
     2225    if ($lang) {
     2226        # language code is packed in 5-bit characters
     2227        $lang = pack "C*", map { (($lang>>$_)&0x1f)+0x60 } 10, 5, 0;
     2228        # validate language code
     2229        if ($lang =~ /^[a-z]+$/) {
     2230            # treat 'eng' or 'und' as the default language
     2231            undef $lang if $lang eq 'und' or $lang eq 'eng';
     2232        } else {
     2233            $lang = 'err';  # invalid language code
     2234        }
     2235    }
     2236    return $lang;
     2237}
     2238
     2239#------------------------------------------------------------------------------
     2240# Process MPEG-4 MTDT atom (ref 11)
     2241# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     2242# Returns: 1 on success
     2243sub ProcessMetaData($$$)
     2244{
     2245    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     2246    my $dataPt = $$dirInfo{DataPt};
     2247    my $dirLen = length $$dataPt;
     2248    my $verbose = $exifTool->Options('Verbose');
     2249    return 0 unless $dirLen >= 2;
     2250    my $count = Get16u($dataPt, 0);
     2251    $verbose and $exifTool->VerboseDir('MetaData', $count);
     2252    my $i;
     2253    my $pos = 2;
     2254    for ($i=0; $i<$count; ++$i) {
     2255        last if $pos + 10 > $dirLen;
     2256        my $size = Get16u($dataPt, $pos);
     2257        last if $size < 10 or $size + $pos > $dirLen;
     2258        my $tag  = Get32u($dataPt, $pos + 2);
     2259        my $lang = Get16u($dataPt, $pos + 6);
     2260        my $enc  = Get16u($dataPt, $pos + 8);
     2261        my $val  = substr($$dataPt, $pos + 10, $size);
     2262        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
     2263        if ($tagInfo) {
     2264            # convert language code to ASCII (ignore read-only bit)
     2265            $lang = UnpackLang($lang);
     2266            # handle alternate languages
     2267            if ($lang) {
     2268                my $langInfo = Image::ExifTool::GetLangInfo($tagInfo, $lang);
     2269                $tagInfo = $langInfo if $langInfo;
     2270            }
     2271            $verbose and $exifTool->VerboseInfo($tag, $tagInfo,
     2272                Value  => $val,
     2273                DataPt => $dataPt,
     2274                Start  => $pos + 10,
     2275                Size   => $size - 10,
     2276            );
     2277            # convert from UTF-16 BE if necessary
     2278            $val = $exifTool->Decode($val, 'UCS2') if $enc == 1;
     2279            if ($enc == 0 and $$tagInfo{Unknown}) {
     2280                # binary data
     2281                $exifTool->FoundTag($tagInfo, \$val);
     2282            } else {
     2283                $exifTool->FoundTag($tagInfo, $val);
     2284            }
     2285        }
     2286        $pos += $size;
     2287    }
     2288    return 1;
     2289}
     2290
     2291#------------------------------------------------------------------------------
     2292# Process Meta keys and add tags to the ItemList table ('mdta' handler) (ref PH)
     2293# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     2294# Returns: 1 on success
     2295sub ProcessKeys($$$)
     2296{
     2297    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     2298    my $dataPt = $$dirInfo{DataPt};
     2299    my $dirLen = length $$dataPt;
     2300    my $out;
     2301    if ($exifTool->Options('Verbose')) {
     2302        $exifTool->VerboseDir('Keys');
     2303        $out = $exifTool->Options('TextOut');
     2304    }
     2305    my $pos = 8;
     2306    my $index = 1;
     2307    my $infoTable = GetTagTable('Image::ExifTool::QuickTime::ItemList');
     2308    my $userTable = GetTagTable('Image::ExifTool::QuickTime::UserData');
     2309    while ($pos < $dirLen - 4) {
     2310        my $len = unpack("x${pos}N", $$dataPt);
     2311        last if $len < 8 or $pos + $len > $dirLen;
     2312        delete $$tagTablePtr{$index};
     2313        my $ns  = substr($$dataPt, $pos + 4, 4);
     2314        my $tag = substr($$dataPt, $pos + 8, $len - 8);
     2315        $tag =~ s/\0.*//s; # truncate at null
     2316        if ($ns eq 'mdta') {
     2317            $tag =~ s/^com\.apple\.quicktime\.//;   # remove common apple quicktime domain
     2318        }
     2319        next unless $tag;
     2320        # (I have some samples where the tag is a reversed ItemList or UserData tag ID)
     2321        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
     2322        unless ($tagInfo) {
     2323            $tagInfo = $exifTool->GetTagInfo($infoTable, $tag);
     2324            unless ($tagInfo) {
     2325                $tagInfo = $exifTool->GetTagInfo($userTable, $tag);
     2326                if (not $tagInfo and $tag =~ /^\w{3}\xa9$/) {
     2327                    $tag = pack('N', unpack('V', $tag));
     2328                    $tagInfo = $exifTool->GetTagInfo($infoTable, $tag);
     2329                    $tagInfo or $tagInfo = $exifTool->GetTagInfo($userTable, $tag);
     2330                }
     2331            }
     2332        }
     2333        my $newInfo;
     2334        if ($tagInfo) {
     2335            $newInfo = {
     2336                Name      => $$tagInfo{Name},
     2337                Format    => $$tagInfo{Format},
     2338                ValueConv => $$tagInfo{ValueConv},
     2339                PrintConv => $$tagInfo{PrintConv},
     2340            };
     2341            my $groups = $$tagInfo{Groups};
     2342            $$newInfo{Groups} = { %$groups } if $groups;
     2343        } elsif ($tag =~ /^[-\w.]+$/) {
     2344            # create info for tags with reasonable id's
     2345            my $name = $tag;
     2346            $name =~ s/\.(.)/\U$1/g;
     2347            $newInfo = { Name => ucfirst($name) };
     2348        }
     2349        # substitute this tag in the ItemList table with the given index
     2350        delete $$infoTable{$index};
     2351        if ($newInfo) {
     2352            Image::ExifTool::AddTagToTable($infoTable, $index, $newInfo);
     2353            $out and printf $out "%sAdded ItemList Tag 0x%.4x = $tag\n", $exifTool->{INDENT}, $index;
     2354        }
     2355        $pos += $len;
     2356        ++$index;
     2357    }
     2358    return 1;
     2359}
     2360
     2361#------------------------------------------------------------------------------
    5132362# Process a QuickTime atom
    514 # Inputs: 0) ExifTool object reference, 1) directory information reference
    515 #         2) optional tag table reference
     2363# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) optional tag table ref
    5162364# Returns: 1 on success
    5172365sub ProcessMOV($$;$)
     
    5262374    # more convenient to package data as a RandomAccess file
    5272375    $raf or $raf = new File::RandomAccess($dataPt);
    528     # skip leading 4-byte version number if necessary
    529     ($raf->Read($buff,4) == 4 and $dataPos += 4) or return 0 if $$dirInfo{HasVersion};
     2376    # skip leading bytes if necessary
     2377    if ($$dirInfo{DirStart}) {
     2378        $raf->Seek($$dirInfo{DirStart}, 1) or return 0;
     2379        $dataPos += $$dirInfo{DirStart};
     2380    }
    5302381    # read size/tag name atom header
    5312382    $raf->Read($buff,8) == 8 or return 0;
     
    5392390        $$tagTablePtr{$tag} or return 0;
    5402391        if ($tag eq 'ftyp') {
    541             # read ahead 4 bytes to see if this is an M4A file
    542             my $ftyp = 'MP4';
     2392            # read ahead 4 bytes to see what type of file this is
     2393            my $fileType;
    5432394            if ($raf->Read($buff, 4) == 4) {
    5442395                $raf->Seek(-4, 1);
    545                 $ftyp = 'M4A' if $buff eq 'M4A ';
     2396                # see if we know the extension for this file type
     2397                $fileType = $1 if $ftypLookup{$buff} and $ftypLookup{$buff} =~ /\(\.(\w+)/;
    5462398            }
    547             $exifTool->SetFileType($ftyp);  # MP4 or M4A
     2399            $fileType or $fileType = 'MP4'; # default to MP4
     2400            $exifTool->SetFileType($fileType, $mimeLookup{$fileType} || 'video/mp4');
    5482401        } else {
    5492402            $exifTool->SetFileType();       # MOV
     
    5582411            $dataPos += 8;
    5592412            my ($hi, $lo) = unpack('NN', $buff);
     2413            $size = $lo;
    5602414            if ($hi or $lo > 0x7fffffff) {
    561                 $exifTool->Warn('End of processing at large atom');
    562                 last;
     2415                if ($hi > 0x7fffffff) {
     2416                    $exifTool->Warn('Invalid atom size');
     2417                    last;
     2418                } elsif (not $exifTool->Options('LargeFileSupport')) {
     2419                    $exifTool->Warn('End of processing at large atom (LargeFileSupport not enabled)');
     2420                    last;
     2421                }
    5632422            }
    564             $size = $lo;
     2423            $size = $hi * 4294967296 + $lo;
    5652424        }
    5662425        $size -= 8;
    5672426        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
     2427        # allow numerical tag ID's
     2428        unless ($tagInfo) {
     2429            my $num = unpack('N', $tag);
     2430            if ($$tagTablePtr{$num}) {
     2431                $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $num);
     2432                $tag = $num;
     2433            }
     2434        }
    5682435        # generate tagInfo if Unknown option set
    5692436        if (not defined $tagInfo and ($exifTool->{OPTIONS}->{Unknown} or
    570             $tag =~ /^\xa9/))
     2437            $verbose or $tag =~ /^\xa9/))
    5712438        {
    5722439            my $name = $tag;
    573             $name =~ s/([\x00-\x1f\x7f-\xff])/'x'.unpack('H*',$1)/eg;
     2440            my $n = ($name =~ s/([\x00-\x1f\x7f-\xff])/'x'.unpack('H*',$1)/eg);
     2441            # print in hex if tag is numerical
     2442            $name = sprintf('0x%.4x',unpack('N',$tag)) if $n > 2;
    5742443            if ($name =~ /^xa9(.*)/) {
    5752444                $tagInfo = {
     
    5872456            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
    5882457        }
     2458        # save required tag sizes
     2459        $exifTool->HandleTag($tagTablePtr, "$tag-size", $size) if $$tagTablePtr{"$tag-size"};
    5892460        # load values only if associated with a tag (or verbose) and < 16MB long
    5902461        if ((defined $tagInfo or $verbose) and $size < 0x1000000) {
     
    5962467            # use value to get tag info if necessary
    5972468            $tagInfo or $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag, \$val);
    598             my $hasData = ($$dirInfo{HasData} and $val =~ /^\0...data\0/s);
     2469            my $hasData = ($$dirInfo{HasData} and $val =~ /\0...data\0/s);
    5992470            if ($verbose and not $hasData) {
    6002471                $exifTool->VerboseInfo($tag, $tagInfo,
     
    6072478                my $subdir = $$tagInfo{SubDirectory};
    6082479                if ($subdir) {
     2480                    my $start = $$subdir{Start} || 0;
     2481                    my ($base, $dPos) = ($dataPos, 0);
     2482                    if ($$subdir{Base}) {
     2483                        $dPos -= eval $$subdir{Base};
     2484                        $base -= $dPos;
     2485                    }
    6092486                    my %dirInfo = (
    610                         DataPt => \$val,
    611                         DirStart => 0,
    612                         DirLen => $size,
    613                         DirName => $$tagInfo{Name},
    614                         HasData => $$subdir{HasData},
    615                         HasVersion => $$subdir{HasVersion},
     2487                        DataPt   => \$val,
     2488                        DataLen  => $size,
     2489                        DirStart => $start,
     2490                        DirLen   => $size - $start,
     2491                        DirName  => $$subdir{DirName} || $$tagInfo{Name},
     2492                        HasData  => $$subdir{HasData},
     2493                        Multi    => $$subdir{Multi},
     2494                        DataPos  => $dPos,
    6162495                        # Base needed for IsOffset tags in binary data
    617                         Base => $dataPos,
     2496                        Base     => $base,
    6182497                    );
    6192498                    if ($$subdir{ByteOrder} and $$subdir{ByteOrder} =~ /^Little/) {
    6202499                        SetByteOrder('II');
    6212500                    }
     2501                    my $oldGroup1 = $exifTool->{SET_GROUP1};
    6222502                    if ($$tagInfo{Name} eq 'Track') {
    6232503                        $track or $track = 0;
     
    6252505                    }
    6262506                    my $subTable = GetTagTable($$subdir{TagTable});
    627                     $exifTool->ProcessDirectory(\%dirInfo, $subTable);
    628                     delete $exifTool->{SET_GROUP1};
     2507                    my $proc = $$subdir{ProcessProc};
     2508                    $exifTool->ProcessDirectory(\%dirInfo, $subTable, $proc) if $size > $start;
     2509                    $exifTool->{SET_GROUP1} = $oldGroup1;
    6292510                    SetByteOrder('MM');
    6302511                } elsif ($hasData) {
    6312512                    # handle atoms containing 'data' tags
     2513                    # (currently ignore contained atoms: 'itif', 'name', etc.)
    6322514                    my $pos = 0;
    6332515                    for (;;) {
    6342516                        last if $pos + 16 > $size;
    635                         my ($len, $type, $flags) = unpack("x${pos}Na4N", $val);
     2517                        my ($len, $type, $flags, $ctry, $lang) = unpack("x${pos}Na4Nnn", $val);
    6362518                        last if $pos + $len > $size;
    6372519                        my $value;
     2520                        my $format = $$tagInfo{Format};
    6382521                        if ($type eq 'data' and $len >= 16) {
    6392522                            $pos += 16;
    6402523                            $len -= 16;
    6412524                            $value = substr($val, $pos, $len);
    642                             # format flags: 0x0=binary, 0x1=text, 0xd=image, 0x15=boolean
    643                             if ($flags == 0x0015) {
    644                                 $value = $len ? ReadValue(\$value, $len-1, 'int8u', 1, 1) : '';
    645                             } elsif ($flags != 0x01 and not $$tagInfo{ValueConv}) {
    646                                 # make binary data a scalar reference unless a ValueConv exists
    647                                 my $buf = $value;
    648                                 $value = \$buf;
     2525                            # format flags (ref 12):
     2526                            # 0x0=binary, 0x1=UTF-8, 0x2=UTF-16, 0x3=ShiftJIS,
     2527                            # 0x4=UTF-8  0x5=UTF-16, 0xd=JPEG, 0xe=PNG,
     2528                            # 0x15=signed int, 0x16=unsigned int, 0x17=float,
     2529                            # 0x18=double, 0x1b=BMP, 0x1c='meta' atom
     2530                            if ($stringEncoding{$flags}) {
     2531                                # handle all string formats
     2532                                $value = $exifTool->Decode($value, $stringEncoding{$flags});
     2533                            } else {
     2534                                if (not $format) {
     2535                                    if ($flags == 0x15 or $flags == 0x16) {
     2536                                        $format = { 1=>'int8', 2=>'int16', 4=>'int32' }->{$len};
     2537                                        $format .= $flags == 0x15 ? 's' : 'u' if $format;
     2538                                    } elsif ($flags == 0x17) {
     2539                                        $format = 'float';
     2540                                    } elsif ($flags == 0x18) {
     2541                                        $format = 'double';
     2542                                    } elsif ($flags == 0x00) {
     2543                                        # read 1 and 2-byte binary as integers
     2544                                        if ($len == 1) {
     2545                                            $format = 'int8u',
     2546                                        } elsif ($len == 2) {
     2547                                            $format = 'int16u',
     2548                                        }
     2549                                    }
     2550                                }
     2551                                if ($format) {
     2552                                    $value = ReadValue(\$value, 0, $format, $$tagInfo{Count}, $len);
     2553                                } elsif (not $$tagInfo{ValueConv}) {
     2554                                    # make binary data a scalar reference unless a ValueConv exists
     2555                                    my $buf = $value;
     2556                                    $value = \$buf;
     2557                                }
    6492558                            }
    6502559                        }
    651                         $exifTool->VerboseInfo($tag, $tagInfo,
    652                             Value => ref $value ? $$value : $value,
    653                             DataPt => \$val,
     2560                        my $langInfo;
     2561                        if ($ctry or $lang) {
     2562                            # ignore country ('ctry') and language lists ('lang') for now
     2563                            undef $ctry if $ctry and $ctry <= 255;
     2564                            undef $lang if $lang and $lang <= 255;
     2565                            $lang = UnpackLang($lang);
     2566                            # add country code if specified
     2567                            if ($ctry) {
     2568                                $ctry = unpack('a2',pack('n',$ctry)); # unpack as ISO 3166-1
     2569                                # treat 'ZZ' like a default country (see ref 12)
     2570                                undef $ctry if $ctry eq 'ZZ';
     2571                                if ($ctry and $ctry =~ /^[A-Z]{2}$/) {
     2572                                    $lang or $lang = 'und';
     2573                                    $lang .= "-$ctry";
     2574                                }
     2575                            }
     2576                            $langInfo = Image::ExifTool::GetLangInfo($tagInfo, $lang) if $lang;
     2577                        }
     2578                        $langInfo or $langInfo = $tagInfo;
     2579                        $exifTool->VerboseInfo($tag, $langInfo,
     2580                            Value   => ref $value ? $$value : $value,
     2581                            DataPt  => \$val,
    6542582                            DataPos => $dataPos,
    655                             Start => $pos,
    656                             Size => $len,
    657                             Extra => sprintf(", Type='$type', Flags=0x%x",$flags)
     2583                            Start   => $pos,
     2584                            Size    => $len,
     2585                            Format  => $format,
     2586                            Extra   => sprintf(", Type='$type', Flags=0x%x",$flags)
    6582587                        ) if $verbose;
    659                         $exifTool->FoundTag($tagInfo, $value) if defined $value;
     2588                        $exifTool->FoundTag($langInfo, $value) if defined $value;
     2589                        $pos += $len;
     2590                    }
     2591                } elsif ($tag =~ /^\xa9/) {
     2592                    # parse international text to extract all languages
     2593                    my $pos = 0;
     2594                    for (;;) {
     2595                        last if $pos + 4 > $size;
     2596                        my ($len, $lang) = unpack("x${pos}nn", $val);
     2597                        $pos += 4;
     2598                        # according to the QuickTime spec (ref 12), $len should include
     2599                        # 4 bytes for length and type words, but nobody (including
     2600                        # Apple, Pentax and Kodak) seems to add these in, so try
     2601                        # to allow for either
     2602                        if ($pos + $len > $size) {
     2603                            $len -= 4;
     2604                            last if $pos + $len > $size or $len < 0;
     2605                        }
     2606                        # ignore any empty entries (or null padding) after the first
     2607                        next if not $len and $pos;
     2608                        my $str = substr($val, $pos, $len);
     2609                        my $langInfo;
     2610                        if ($lang < 0x400) {
     2611                            # this is a Macintosh language code
     2612                            # a language code of 0 is Macintosh english, so treat as default
     2613                            if ($lang) {
     2614                                # use Font.pm to look up language string
     2615                                require Image::ExifTool::Font;
     2616                                $lang = $Image::ExifTool::Font::ttLang{Macintosh}{$lang};
     2617                            }
     2618                            # the spec says only "Macintosh text encoding", so
     2619                            # I can only assume that it is the most common one
     2620                            $str = $exifTool->Decode($str, 'MacRoman');
     2621                        } else {
     2622                            # convert language code to ASCII (ignore read-only bit)
     2623                            $lang = UnpackLang($lang);
     2624                            # may be either UTF-8 or UTF-16BE
     2625                            my $enc = $str=~s/^\xfe\xff// ? 'UTF16' : 'UTF8';
     2626                            $str = $exifTool->Decode($str, $enc);
     2627                        }
     2628                        $langInfo = Image::ExifTool::GetLangInfo($tagInfo, $lang) if $lang;
     2629                        $exifTool->FoundTag($langInfo || $tagInfo, $str);
    6602630                        $pos += $len;
    6612631                    }
    6622632                } else {
    663                     if ($tag =~ /^\xa9/) {
    664                         # parse international text to extract first string
    665                         my $len = unpack('n', $val);
    666                         # $len should include 4 bytes for length and type words,
    667                         # but Pentax forgets to add these in, so allow for this
    668                         $len += 4 if $len == $size - 4;
    669                         $val = substr($val, 4, $len - 4) if $len <= $size;
    670                     } elsif ($$tagInfo{Format}) {
     2633                    if ($$tagInfo{Format}) {
    6712634                        $val = ReadValue(\$val, 0, $$tagInfo{Format}, $$tagInfo{Count}, length($val));
    6722635                    }
     
    6902653sub ProcessQTIF($$)
    6912654{
     2655    my ($exifTool, $dirInfo) = @_;
    6922656    my $table = GetTagTable('Image::ExifTool::QuickTime::ImageFile');
    693     return ProcessMOV($_[0], $_[1], $table);
     2657    return ProcessMOV($exifTool, $dirInfo, $table);
    6942658}
    6952659
     
    7112675information from QuickTime and MP4 video, and M4A audio files.
    7122676
    713 =head1 BUGS
    714 
    715 The MP4 support is rather pathetic since the specification documentation is
    716 not freely available (yes, ISO sucks).
    717 
    7182677=head1 AUTHOR
    7192678
    720 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     2679Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    7212680
    7222681This library is free software; you can redistribute it and/or modify it
     
    7272686=over 4
    7282687
    729 =item L<http://developer.apple.com/documentation/QuickTime/>
     2688=item L<http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html>
     2689
     2690=item L<http://search.cpan.org/dist/MP4-Info-1.04/>
     2691
     2692=item L<http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt>
     2693
     2694=item L<http://wiki.multimedia.cx/index.php?title=Apple_QuickTime>
     2695
     2696=item L<http://atomicparsley.sourceforge.net/mpeg-4files.html>
     2697
     2698=item L<http://wiki.multimedia.cx/index.php?title=QuickTime_container>
     2699
     2700=item L<http://code.google.com/p/mp4v2/wiki/iTunesMetadata>
     2701
     2702=item L<http://www.canieti.com.mx/assets/files/1011/IEC_100_1384_DC.pdf>
     2703
     2704=item L<http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v10.pdf>
    7302705
    7312706=back
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/README

    r16842 r24107  
    44Description:  ExifTool support modules documentation
    55
    6 The ExifTool support modules are loaded by ExifTool to interpret various formats
    7 of meta information.
     6The ExifTool support modules are loaded by ExifTool to allow processing of
     7various meta information formats.
    88
    99The tables in these files are used as lookups based on the tag ID values.  The
     
    1111with EXIF tables, or the tag name if the ID is ASCII as with XMP tables).  In
    1212the case of a BinaryData table, the IDs are numerical and specify offsets into
    13 the binary data block.  The corresponding hash value provides information about
    14 the tag (explained later).
    15 
    16 Twenty-one special keys (PROCESS_PROC, WRITE_PROC, CHECK_PROC, GROUPS, FORMAT,
    17 FIRST_ENTRY, TAG_PREFIX, PRINT_CONV, DID_TAG_ID, WRITABLE, NOTES, IS_OFFSET,
    18 EXTRACT_UNKNOWN, NAMESPACE, PREFERRED, PARENT, PRIORITY, WRITE_GROUP, LANG_INFO,
    19 VARS and DATAMEMBER) are used to provide additional information about a table.
    20 The special keys have names that are all capitalized to avoid possible conflicts
    21 with tag keys.  Below is an explanation of the meaning of each special key:
     13the binary data block (floating point IDs allow multiple tags for the same
     14offset, with the integer part being used for the offset).  The corresponding
     15hash value provides information about the tag (explained later).
     16
     17Twenty-five special keys (TABLE_NAME, SHORT_NAME, PROCESS_PROC, WRITE_PROC,
     18CHECK_PROC, GROUPS, FORMAT, FIRST_ENTRY, TAG_PREFIX, PRINT_CONV, WRITABLE,
     19TABLE_DESC, NOTES, IS_OFFSET, IS_SUBDIR, EXTRACT_UNKNOWN, NAMESPACE, PREFERRED,
     20SRC_TABLE, PRIORITY, WRITE_GROUP, LANG_INFO, VARS, DATAMEMBER and SET_GROUP1)
     21are used to provide additional information about a table. The special keys have
     22names that are all capitalized to avoid possible conflicts with tag keys.  Below
     23is an explanation of the meaning of each special key:
     24
     25  TABLE_NAME : Name of this table (set by GetTagTable()).
     26
     27  SHORT_NAME : Table name with leading "Image::ExifTool::" removed.
    2228
    2329  PROCESS_PROC : Reference to a function used to process the directory for this
     
    5662  reference, 2) value reference, and returns undefined (and possibly modifies
    5763  the input value) if successful, or an error message if there was a format
    58   problem.
     64  problem.  May set ExifTool CHECK_WARN datamember for success with a warning.
    5965
    6066  GROUPS : A hash lookup for the default group names for all entries in this
     
    6470  FORMAT : Specifies the default tag Format and corresponding pointer increment
    6571  for entries in a BinaryData table, and defaults to 'int8u' if not specified.
    66   The possible values of FORMAT are:
     72  Format names starting with 'var_' cause subsequent tag ID's in BinaryData
     73  tables to be incremented according to the size of the data (not including the
     74  terminator).  The possible values of FORMAT are:
    6775
    6876    int8s       - Signed 8-bit integer                    (EXIF 'SBYTE')
     
    7078    int16s      - Signed 16-bit integer                   (EXIF 'SSHORT')
    7179    int16u      - Unsigned 16-bit integer                 (EXIF 'SHORT')
     80    int16uRev   - Unsigned 16-bit integer, reversed byte order
    7281    int32s      - Signed 32-bit integer                   (EXIF 'SLONG')
    7382    int32u      - Unsigned 32-bit integer                 (EXIF 'LONG')
     
    8695    extended    - 80-bit extended floating float
    8796    ifd         - Unsigned 32-bit integer sub-IFD pointer (EXIF 'IFD')
    88     ifd8        - Unsigned 64-bit integer sub-IFD pointer (BigTIFF 'IFD8')
     97    ifd64       - Unsigned 64-bit integer sub-IFD pointer (BigTIFF 'IFD8')
    8998    string      - Series of 8-bit ASCII characters        (EXIF 'ASCII')
     99    pstring     - Pascal string [BinaryData tables only]
    90100    undef       - Undefined-format binary data            (EXIF 'UNDEFINED')
    91101    binary      - Binary data
     102    var_string  - variable-length null-terminated ASCII string [BinaryData]
     103    var_ustring - variable-length null-terminated UCS-2 string [BinaryData]
     104    var_pstring - variable-length Pascal string                [BinaryData]
     105    var_pstr32  - variable-length Pascal string /w 32-bit len  [BinaryData]
     106    var_int16u  - variable-length undef data with int6u count  [BinaryData]
    92107
    93108  FIRST_ENTRY : Specifies the index for the first tag entry in a binary table.
     
    97112  TAG_PREFIX : Prefix for names of unknown tags.
    98113
    99   PRINT_CONV : Default print conversion tags where PrintConv isn't specified.
    100 
    101   DID_TAG_ID : Used by GetTagID() as a flag to indicate that TagID's have been
    102   defined for all tags in this table.  This may be set in the table definition
    103   to prevent GetTagID() from assigning TagID's.
     114  PRINT_CONV : Default print conversion for tags where PrintConv isn't
     115  specified.  PrintConv may be set to undef for individual tags to disable print
     116  conversion when PRINT_CONV is defined for a table.
    104117
    105118  WRITABLE : Indicates that all tags in this table are writable.  This is the
     
    107120  for SubDirectory tags which are not made Writable.
    108121
     122  TABLE_DESC : Short description for this table.  Plain text only.  Used only
     123  for XML tag database output.
     124
    109125  NOTES : Notes to introduce the table in the TagNames documentation.  Pod
    110126  formatting codes B<> and C<> may be used in this text.
    111127
    112   IS_OFFSET : Reference to list of TagID's representing offsets for binary
    113   data tables only.  Not used for EXIF tables.
     128  IS_OFFSET : Reference to list of sorted TagID's representing offsets for
     129  writable binary data tables only.  Not used for EXIF tables.
     130
     131  IS_SUBDIR : BinaryData tables only.  A reference to a list of sorted tag ID's
     132  representing subdirectories.  Required for writable subdirectories only.
    114133
    115134  EXTRACT_UNKNOWN : Used in PDF tables to specify a directory where all unknown
    116   tags should be extracted.
     135  tags should be extracted.  Set to 0 to extract only unknown numbered tags for
     136  which the unnumbered tag is known.
    117137
    118138  NAMESPACE : Namespace prefix for tags in the XMP table.  If this isn't a
     
    120140  this, the NAMESPACE value is a reference to either a list or a hash, where the
    121141  first element (or hash key) is the namespace prefix and and the second element
    122   (or hash value) is the URI.
     142  (or hash value) is the URI.  This is undef for XMP tables in which tags have
     143  variable namespaces, and in this case each tag must have a Namespace entry.
    123144
    124145  PREFERRED : Set to true if the tags in this table should always be added when
     
    128149  directories for tags which are already being creating in the preferred group.
    129150
    130   PARENT : Used internally to store the parent table name of a user-defined tag
    131   table so the appropriate module can be loaded as required.
     151  SRC_TABLE : Used internally to store the source table name of a user-defined
     152  tag table so the appropriate module can be loaded as required.
    132153
    133154  PRIORITY : Default Priority for all tags in this table.
     
    138159  language-specific tag information hash.  The routine takes two arguments: a
    139160  reference to the non-specific tagInfo hash, and the language code. Used only
    140   in tables which support tag name language extensions (ie. MIE and XMP).
     161  in tables with writable tags which support tag name language extensions (ie.
     162  MIE and XMP).
    141163
    142164  VARS : Hash used to store additional parameters.  Individual modules may use
     
    144166  have been defined, and may be used by any module:
    145167
    146     INDEX - Use "Index" instead of "Tag ID" for column heading in tag name docs.
    147 
    148     NO_ID - Avoid printing "Tag ID" column in tag name documentation.
    149 
    150   DATAMEMBER : BinaryData tables only.  A reference to a list of tag ID's which
    151   must be extracted as data members when writing.
     168    ID_LABEL      Label to use instead of "Tag ID" for column heading in tag
     169                  name documentation.  When this is set, numerical TagID's are
     170                  not converted to hexadecimal notation. Unless otherwise set,
     171                  an ID_LABEL of "Index" is assumed for tables which use
     172                  ProcessBinaryData.
     173
     174    NO_ID         Avoid printing "Tag ID" column in tag name documentation.
     175
     176    CAPTURE       Used by PDF module to name dictionaries to capture when
     177                  writing.
     178
     179    MINOR_ERRORS  [EXIF tables only] Flag to make errors in this IFD minor, or
     180                  to downgrade already minor errors to warnings while writing.
     181                  (Errors in MakerNote IFD's are already classified as minor.)
     182                  Note that for certain types errors, the response is to delete
     183                  the entire IFD from the image.
     184
     185    NUMBERS_LAST  Sort numerical tags after character tags in documentation.
     186
     187  DATAMEMBER : BinaryData tables only.  A reference to a list of sorted tag ID's
     188  which must be extracted as data members when writing.  Must also list "var_"
     189  format tags and tags with Hook so offsets are properly calculated if the table
     190  is writable.
     191
     192  SET_GROUP1 : [EXIF tables only] Flag to set group1 name to the directory name
     193  for all tags in the table.
    152194
    153195The remaining entries in a tag table are the tag IDs with their associated
     
    161203
    162204  Name          : The tag name.  Tag names need not be unique.  If they aren't
    163                   unique, duplicate tags overwrite values of previous tags
    164                   unless the Duplicates option is set or the new tag has lower
    165                   Priority.  With Duplicates set, to allow multiple tags with
    166                   the same name to exist in the tag information hash, the key of
    167                   the previous tag is changed to the form "TagName (N)", where N
    168                   starts at 1 and increments for subsequent duplicate tags.  A
    169                   tag name should start with an uppercase letter, and contain
    170                   only the charcters in the set [A-Za-z0-9_-].
     205                  unique, then duplicate tags will hide the values of previous
     206                  tags when extracting information unless the Duplicates option
     207                  is set or the new tag has lower Priority.  With Duplicates
     208                  set, to allow multiple tags with the same name to exist in the
     209                  tag information hash, the key of the previous tag is changed
     210                  to the form "TagName (N)", where N starts at 1 and increments
     211                  for subsequent duplicate tags.  A tag name should start with
     212                  an uppercase letter, and contain only the charcters in the set
     213                  [A-Za-z0-9_-].  If not given, the Name is taken from the tag
     214                  ID with the first character changed to upper case.
    171215
    172216  Description   : A more readable description of tag name.  If a tag doesn't
     
    181225                  or EXIF table, this gives the format that is used to convert
    182226                  the binary data, and is one of the FORMAT types specified
    183                   above. For BinaryData tables, the format may have a size in
    184                   trailing brackets which is a perl expression to be evaluated.
    185                   The expression may access any of the previous table entries
    186                   through a %val hash, or the data size via $size. For example,
     227                  above.  If not specified, the Format of an EXIF entry is taken
     228                  from the EXIF information, and the Format of a BinaryData
     229                  entry is taken from the FORMAT specified for the table (or
     230                  int8u if FORMAT is not specified).  Must be specified for
     231                  Writable tags where the value must be converted for a
     232                  Condition.  For BinaryData tables, the format may have a size
     233                  in trailing brackets which is a Perl expression to be
     234                  evaluated. The expression may access any of the previous table
     235                  entries through a %val hash (read-only tables), the data size
     236                  via $size, or the ExifTool object via $self. For example,
    187237                  'string[$val{3}]' defines a string with length given by the
    188                   table entry with tag index '3'. If not specified, the format
    189                   of an EXIF entry is taken from the EXIF information, and the
    190                   format of a BinaryData entry is taken from the FORMAT
    191                   specified for the table (or int8u if FORMAT is not specified).
     238                  table entry with tag index '3'.  An initial "var_" may be
     239                  added to the Format name of any BinaryData tag with a size in
     240                  brackets.  In this case, subsequent offsets are adjusted by
     241                  the total size minus the size of the base Format (ie.
     242                  "var_int16u[10]" causes subsequent offsets to be incremented
     243                  by sizeof(int16u) * 9).  Note that all "var_" Format tags must
     244                  have corresponding DATAMEMBER entries.
    192245
    193246  Count         : Used when writing EXIF information to specify the number
     
    199252                  count written to the file will be different.
    200253
     254  FixCount      : Flag set to determine correct count from offsets in IFD.  This
     255                  is necessary for some Kodak tags which write an incorrect
     256                  Count value.
     257
    201258  Flags         : Flags to specify characteristics for this tag.  May be a
    202259                  simple scalar flag name, a reference to a list of flag names,
     
    207264                  available flag names are:
    208265
    209                   'Avoid' - avoid creating this tag if possible.
     266                  'AutoSplit' - [List tags only] Similar to ListSplit option,
     267                  but applied automatically to individual tags.  Value specifies
     268                  pattern for split, or 1 for default pattern ',?\\s+'.
     269
     270                  'Avoid' - avoid creating this tag if possible.  This is only
     271                  effective if another tag exists with the same name.
    210272
    211273                  'Binary' - set to 1 for binary data.  This has the same effect
    212274                  as setting ValueConv to '\$val', but it it a bit cleaner and
    213275                  avoids dummy ValueConvInv entries for writable tags.  Has no
    214                   effect if ValueConv is defined for the tag.
     276                  effect if ValueConv is defined for the tag.  Some values may
     277                  be treated as binary data even if this flag is not set.
     278
     279                  'BlockExtract' - set for writable directories in EXIF
     280                  information which are extracted by default.  Otherwise
     281                  writable directories are only extracted as a block if
     282                  specified explicitly.
    215283
    216284                  'DataMember' - name of exiftool data member associated with
     
    218286                  writing information.  Necessary only if the value of the tag
    219287                  affects other written information.  Currently only used for
    220                   tags in EXIF tables.
     288                  tags in EXIF tables where it triggers the execution of the
     289                  RawConv to convert and stores the value as an ExifTool data
     290                  member when writing.
    221291
    222292                  'DataTag' - associated tag name containing data for offset or
     
    231301                  Casio PrintIM information).
    232302
     303                  'Flat' - [flattened XMP structure tags only] must be set for
     304                  all pre-defined flattened tags (including user-defined
     305                  flattened tags).  This flag is reset to 0 internally after all
     306                  associated flattened tags in the structure have been
     307                  generated.
     308
     309                  'Flattened' - [reserved] used internally to mark Struct tags
     310                  which have been processed to generate flattened equivalents.
     311
     312                  'GotGroups' - [reserved] flag used internally to indicate that
     313                  the Groups hash has been initialized for this tag.
     314
     315                  'Hidden' - set to hide tag from the TagName documentation.
     316                  Also suppresses verbose output of a BinaryData tag.
     317
    233318                  'IsOffset' - flag set if the tag represents an offset to some
    234319                  data, and causes value will be adjusted to an absolute file
    235320                  offset.  If set to 2, the offset base of the parent directory
    236321                  is used even if the base changes for the current directory
    237                   (only some maker notes are this messed up).
    238 
    239                   'List' - indicates that duplicate entries of this tag are
    240                   allowed, and will be accumulated in a list.  Note that for XMP
    241                   information, 3 different types of lists are supported and the
    242                   List value specifies the type: 'Bag', 'Seq' or 'Alt'.
     322                  (only some maker notes are this messed up).  Set to 3 if
     323                  absolute file offsets are used.  May be set to an expression
     324                  to be evaluated.  Expression may access $val and $exifTool,
     325                  and is evaluated only when reading.
     326
     327                  'List' - flag indicating that duplicate entries of this tag
     328                  are allowed, and will be accumulated in a list.  Note that for
     329                  XMP information, 3 different types of lists are supported and
     330                  the List value specifies the type: 'Bag', 'Seq' or 'Alt'.  As
     331                  well, a value of '1' is used internally in XMP to allow list
     332                  behaviour for a flattened tag which is itself not a list
     333                  element (ie. a member of list of structures).  Note that in
     334                  ExifTool an XMP lang-alt tag (Writable="lang-alt") is NOT a
     335                  List-type tag (unless it is a list of lang-alt lists, which is
     336                  uncommon).
    243337
    244338                  'MakerNotes' - set if this tag is maker note data.
    245339
     340                  'MakerPreview' - set in the PreviewImageStart tag information
     341                  if the preview must be stored inside the maker notes.
     342
     343                  'Mandatory' - set for mandatory tags.  Used only by TagInfoXML
     344                  and documentation purposes.  Mandatory tags may be added
     345                  automatically by ExifTool.
     346
     347                  'NestedHtmlDump' - flag set if value for this tag is also
     348                  dumped when processing the SubDirectory.  This flag is implied
     349                  if the MakerNotes flag is set.  Set to 2 if the dump should
     350                  only be underlined if nested inside other maker notes.
     351
    246352                  'NotIFD' - set for 'MakerNotes' tags only if the data is not
    247                   in standard EXIF IFD format.
    248                  
     353                  in standard EXIF IFD format.  (Note: All SubDirectory tags in
     354                  the MakerNotes table are 'MakerNotes' type by default.)
     355
    249356                  'OffsetPair' - set if the tag represents half of an offset/
    250357                  byte count pair.  Data for these tags must be handled
     
    252359
    253360                  'Permanent' - flag indicates that a tag is permanent, and
    254                   can't be added or deleted from the file.  By default, all
     361                  can't be added or deleted from the file, although a new value
     362                  may be written if the tag already exists.  By default, all
    255363                  MakerNotes tags are permanent unless otherwise specified.
    256364
    257365                  'PrintHex' - specifies that unknown PrintConv values should
    258                   be printed in hex (ie. 'Unknown (0x0)')
     366                  be printed in hex (ie. 'Unknown (0x01)').  Also causes
     367                  numerical tag values to be printed in hex in the HTML tag name
     368                  documentation.
     369
     370                  'PrintString' - flag set to force PrintConv values to be
     371                  printed as strings in the documentation.
    259372
    260373                  'Priority' - gives the priority of this tag while reading.  If
     
    265378                  special feature is that Priority 0 tags are automatically
    266379                  incremented to Priority 1 if they exist in the IFD of the full
    267                   resolution image (as determined by SubFileType).
     380                  resolution image (as determined by SubfileType).  If not
     381                  defined, the priority defaults to 1 for all tags except except
     382                  tags in IFD1 of JPEG images which default to priority 0.
    268383
    269384                  'Protected' - bit mask to protect tags from writing:
     
    273388                  directly by the user.
    274389
     390                  'PutFirst' - [EXIF only] flag to place this value before IFD0
     391                  when writing (ie. immediately after TIFF header).  Only used
     392                  for main IFD's (IFD0, IFD1, etc) and IFD's where SubIFD flag
     393                  is set to 2 (currently only ExifIFD).
     394
     395                  'Resource' - [XMP only] flag to write value as an rdf:resource
     396                  in an empty element instead of as a normal string.
     397
    275398                  'SeparateTable' - set to list PrintConv values in a separate
    276399                  table in the HTML documentation.  Value is 1 for a table name
    277400                  of 'Module TagName', or 'TAG' for 'Module TAG', or 'MODULE
    278                   TAG' to fully specify the table name.
     401                  TAG' to fully specify the table name.  The table may have a
     402                  'Notes' entry for a description of the table.
    279403
    280404                  'SetResourceName' - [Photoshop tags only] set to 1 to append
     
    285409                  provided.
    286410
     411                  'StructType' - [reserved] used internally by XMP writer for
     412                  flattened structure tags as a flag to indicate that one or
     413                  more enclosing structures has a TYPE field.
     414
     415                  'SubDoc' - [Composite tags only] set to cause this composite
     416                  tag to also be generated for each sub-document.  To achieve
     417                  this, 'Main:' and 'Doc#:' prefixes are added to all Require'd
     418                  and Desire'd tag names which don't already start with 'Main:'
     419                  or 'Doc#:', and the composite tag is built once for each of
     420                  the main document and all sub-documents.
     421
    287422                  'SubIFD' - used in writing to determine that the tag specifies
    288423                  an offset to a sub-IFD.  When this flag is set, the Group1
    289                   name gives the name of the IFD.
     424                  name gives the name of the IFD.  Must be set if and only if
     425                  the tag has a SubDirectory Start of '$val' (this is validated
     426                  by BuildTagLookup).  Set to 2 for standard EXIF SubIFD's where
     427                  the PutFirst flag is valid.
    290428
    291429                  'Unknown' - this is an unknown tag (only extracted when the
    292430                  Unknown option is set).
     431
     432                  'WrongBase' - ['IsOffset' tags only] An expression using $self
     433                  that is evaluated to generate a base shift for 'IsOffset' tags
     434                  which use a different base than the rest of the tags.
    293435
    294436  RawConv       : Used to convert the Raw value at extraction time (while the
     
    296438                  which are done later only if the value is requested).  May be
    297439                  a scalar expression using $val (the Raw tag value), $self (the
    298                   current ExifTool object) and $tag (the tag name), or a code
    299                   reference with $val and $self as arguments.  For Composite
    300                   tags, $val is a reference to a hash of component tag names,
     440                  current ExifTool object), $tag (the tag key) and $tagInfo
     441                  (reference to the tag information hash) or a code reference
     442                  with $val and $self as arguments.  For Composite tags, $val is
     443                  a reference to a hash of source ("derived from") tag names,
    301444                  and @val may be used to access the Raw values of these tags.
    302                   The returned value may be a scalar which is used as the new
    303                   Raw value, a scalar reference to a binary data value, a hash
    304                   reference for Composite tags, an ARRAY reference for a list of
    305                   values, or undefined to indicate that the tag should be
    306                   ignored.  Also, RawConv may generate Warning or Error tags,
    307                   while ValueConv and PrintConv may not. Note: RawConv should
    308                   only be used if necessary (in general, only if the tag may be
    309                   ignored).  It is preferable to use ValueConv instead of
    310                   RawConv because ValueConv is only executed if the tag value is
    311                   requested, while RawConv is executed for all extracted tags.
     445                  If RawConv is specified for a Composite tag, then ValueConv
     446                  and PrintConv evals will no longer have access to the source
     447                  @val and @prt values.  The returned value may be a scalar
     448                  which is used as the new Raw value, a scalar reference to a
     449                  binary data value, a hash reference for Composite tags, an
     450                  ARRAY reference for a list of values, or undefined to indicate
     451                  that the tag should be ignored.  Also, RawConv may generate
     452                  Warning or Error tags, while ValueConv and PrintConv may not.
     453                  Note: RawConv should only be used if necessary (in general,
     454                  only if the conversion may return undef to ignore the tag)
     455                  because ValueConv is more efficient since it is only executed
     456                  if the tag value is requested, while RawConv is executed for
     457                  all extracted tags.
    312458
    313459  ValueConv     : Used to convert the Raw value to a useable form. May be a hash
     
    319465                  list.  If a hash reference is used and the Raw value doesn't
    320466                  appear as one of the keys, then the converted value is set to
    321                   "Unknown (X)", where X is the Raw value (unless a special
    322                   'BITMASK' key exists, in which case the hash referenced by
    323                   'BITMASK' is used to decode individual value bits).  In an
     467                  "Unknown (X)", where X is the Raw value (unless either of the
     468                  special keys exist: 'BITMASK', a reference to a hash used to
     469                  decode individual value bits; or 'OTHER', a reference to a
     470                  subroutine used to convert unknown values.  The subroutine
     471                  takes 3 arguments: the value, a flag which is set for the
     472                  inverse conversion, and a reference to the PrintConv hash, and
     473                  returns the converted value or undef on error.  The lookup
     474                  hash may also contain a 'Notes' entry which is used for
     475                  documentation if the SeparateTable flag is set).  In an
    324476                  expression, $self is a reference to the current ExifTool
    325                   object, $val is the Raw value, and $tag is the tag name.  The
     477                  object, $val is the Raw value, and $tag is the tag key.  The
    326478                  subroutine takes 2 arguments: the Raw value and a reference to
    327479                  the current ExifTool object.  The expression or subroutine is
     
    333485                  to cyclical dependencies so they should be avoided). When
    334486                  evaluated, the expression or subroutine returns a scalar for
    335                   the converted value, or a scalar reference to a binary data
    336                   value (see the 'Binary' flag).  The return value should always
    337                   be defined -- use RawConv instead to return undef if it is
    338                   necessary to test the value for validity, otherwise an undef
    339                   tag may hide a previously defined value when the Duplicates
    340                   option is not enabled.  Composite tags which Require or Desire
    341                   other tags may access the ValueConv, PrintConv and Raw values
    342                   of these tags through the elements of the @val, @prt and @raw
    343                   lists respectively (only if there was no RawConv or returned a
    344                   hash reference).  For these tags, $val may be used in an
    345                   expression to represent $val[0], and the first argument passed
    346                   for a code reference is a reference to @val.  If ValueConv is
    347                   not specified, the Raw value is not converted.
     487                  the converted value, a SCALAR reference to a binary data value
     488                  (see the 'Binary' flag), or an ARRAY reference for a list of
     489                  values.  The return value should always be defined -- use
     490                  RawConv instead to return undef if it is necessary to test the
     491                  value for validity, otherwise an undef tag may hide a
     492                  previously defined value when the Duplicates option is not
     493                  enabled.  If this isn't possible (as with Composite tags where
     494                  the converted values of the source tags are needed), set the
     495                  Priority to 0 to avoid taking priority over a valid tag.
     496                  Composite tags which Require or Desire other tags may access
     497                  the ValueConv, PrintConv and Raw values of these tags through
     498                  the elements of the @val, @prt and @raw lists respectively
     499                  (only if there was no RawConv or it returned a hash
     500                  reference).  For these tags, $val may be used in an expression
     501                  to represent $val[0], and the first argument passed for a code
     502                  reference is a reference to @val. If ValueConv is not
     503                  specified, the Raw value is not converted.
    348504
    349505  PrintConv     : This entry is similar to ValueConv above, except that it is
     
    375531                  that DataMember tags may NOT be used in the inverse
    376532                  conversions because these conversions are done before the
    377                   input file is parsed. Instead, a Condition or RawConvInv must
    378                   be used.
     533                  input file is parsed.  Instead, a Condition or RawConvInv must
     534                  be used.  May return undef on conversion error and call warn()
     535                  to issue a warning.  If warn() is not called, a generic
     536                  warning is generated when undef is returned.  An empty warning
     537                  ("\n") may be issued to suppress warning messages when undef
     538                  is returned.  If a scalar, the expression may use the
     539                  variables $val, $self and $wantGroup.  If a code ref, the
     540                  routine is passed 2 arguments: $val and $self.  Note that this
     541                  conversion is not applied for deleted tags (ie. $val is
     542                  undef).
    379543
    380544  PrintConvInv  : The inverse of PrintConv.  Only necessary if for Writable tags
    381                   when PrintConv is specified (unless WriteAlso is used).
     545                  when PrintConv is specified (unless WriteAlso is used).  See
     546                  ValueConvInv above for more details.
     547
     548  PrintConvColumns : Number of columns for PrintConv lookup in HTML docs.
     549                  Default is 1 if not specified.
     550
     551  DelValue      : Raw value to be used when deleting a permanent tag.  (Note all
     552                  MakerNotes tags are permanent.)  If not specified, an attempt
     553                  is made to convert an empty string for the raw value.
     554
     555  Relist        : [Only if ValueConv or PrintConv is a list ref] Reference to a
     556                  list of original value indices used to reorganize values. Each
     557                  entry in the list may be a scalar index, or a reference to a
     558                  list of indices to join values.  (Currently values may be
     559                  joined, but the order of writable values must not be changed
     560                  until this ability is added to the writer.)
     561
     562  Mask          : [BinaryData tags only] Bitmask for this value.  (Multiple tags
     563                  may have the same index by using floating point indices.  An
     564                  unknown tag will only be generated for a certain TagID if
     565                  there is no integral TagID for that tag.)  When Mask is used,
     566                  PrintHex=1 is implied unless otherwise defined.
    382567
    383568  Condition     : If given, specifies scalar which is evaluated as a Perl
     
    386571                  first list entry with a true condition is taken.  If no
    387572                  condition exists, then a 'true' condition is assumed.  The
    388                   expression may use $self to access the ExifTool object, and
    389                   $oldVal to access the previous Raw value of the tag (if it
    390                   exists).  The first 48 bytes of the raw data value are
    391                   accessible through the reference $valPt for EXIF and Jpeg2000
    392                   tags only.  EXIF tags may also reference the format string and
    393                   value count through $format and $count.  Note that if the
    394                   value is writable and $valPt is used, the tag must have a
    395                   Format (unless 'undef' or 'string'), and a Count (unless 1 or
    396                   length of the 'undef' or 'string'), so the raw data may be
    397                   generated for evaluating the Condition.
     573                  expression may use $self to access the ExifTool object.  The
     574                  first 128 bytes of the raw data value are accessible through
     575                  the reference $valPt for EXIF, Jpeg2000 and BinaryData tags
     576                  only (note that for BinaryData tags, the raw data of $$valPt
     577                  is always 'undef' type, and may not be used when writing
     578                  except for SubDirectory tags).  EXIF tags may also reference
     579                  the format string and value count through $format and $count.
     580                  Note that if the value is writable and $valPt is used, the tag
     581                  must have a Format (unless 'undef' or 'string'), and a Count
     582                  (unless 1 or length of the 'undef' or 'string'), so the raw
     583                  data may be generated for evaluating the Condition.  When
     584                  writing, $valPt, $format and $count refer to the new value,
     585                  except for MakerNotes tags where $format and $count refer to
     586                  the old tag if it existed.
    398587
    399588  Require       : [Composite tags only] A hash reference specifying the tags
     
    436625                  information, this flag is only defined if the SubDirectory is
    437626                  writable as a block, or if the SubDirectory can not be edited
    438                   (in which case Writable is set to 0).
     627                  (in which case Writable is set to 0).  If non-zero, the
     628                  SubDirectory is also extracted as a block, so the Binary and
     629                  Protected flags should usually set as well.  There is
     630                  currently no way to specify a write format for a SubDirectory
     631                  that is not writable as a block (the default is 'int32u' for
     632                  IFD-type SubDirectories, and 'undef' for all others).
    439633
    440634  WriteAlso     : Used for writable tag to specify other tags to write when this
     
    442636                  are the names of the tags to write, and the values are
    443637                  evaluated to obtain the ValueConv values of each tag (or undef
    444                   to delete the tag).  In the eval, $val may be used as the Raw
    445                   value of the parent tag.  This will write Protected tags that
    446                   aren't directly writable (Protected bit 0x02 set).
     638                  to delete the tag).  In the eval, $val is the Raw value of the
     639                  parent tag (which may be undef if the tag is being deleted),
     640                  and the %opts hash may be accessed to modify SetNewValue
     641                  options for each tag.  By default, Type is set to "ValueConv"
     642                  and the Protected option has bit 0x02 set to allow writing of
     643                  Protected tags that aren't directly writable.  The AddValue
     644                  and DelValue options from the parent tag are also defined, but
     645                  no other options are set by default.  Previous new values of
     646                  WriteAlso tags have already been removed prior to the eval if
     647                  the Replace option was used for the parent tag.  If an empty
     648                  warning is issued ("\n"), the target tag is not written and no
     649                  error is reported.
    447650
    448651  WriteCheck    : If given, specifies a scalar which is evaluated as a Perl
     
    451654                  the value to be written, $self is the ExifTool object, and
    452655                  $tagInfo is the tag information hash reference.  It returns an
    453                   error string or undef if the value is good.
     656                  error string, or undef if the value is good.  If the error
     657                  string is empty, the tag is not written and no warnings are
     658                  issued, but WriteAlso is still evaluated if it exists.
     659
     660  DelCheck      : Similar to WriteCheck, but called when the tag is deleted. The
     661                  expression may access $self, $tagInfo and $wantGroup.  Returns
     662                  error string, or undef on success, and may set $val to
     663                  something other than undef.  May return empty string ('') to
     664                  suppress warning messages but not delete tag (ie. when
     665                  deleting only associated tags).
    454666
    455667  WriteCondition: [Writable EXIF tags only] Specifies a condition to be
    456668                  evaluated before the tag can be written to a specific file.
    457669                  The condition may use $self to reference the ExifTool object,
    458                   and returns true if it is OK for writing. Unlike WriteCheck
     670                  and returns true if it is OK for writing.  Unlike WriteCheck
    459671                  which is done only once when the new value is set, this
    460                   condition is evaluated before the information is written in
    461                   each file.
    462 
    463   WriteGroup    : [Required for writable EXIF tags] Specifies the IFD where the
    464                   information gets written by default.
     672                  condition is evaluated just before the tags of the specific
     673                  SubDirectory are written.
     674
     675  WriteGroup    : [Writable EXIF tags only] Specifies the IFD where the
     676                  information gets written by default.  Must be defined for
     677                  writable EXIF tags if WRITE_GROUP is not specified in table.
     678
     679  IsOverwriting : [Writable EXIF tags only] Specifies reference to subroutine
     680                  which determines if tag should be overwritten.  Arguments are:
     681                  0) ExifTool object ref, 1) new value hash ref, 2) old value,
     682                  3) new value reference.
     683
     684  AllowGroup    : [Writable tags only] Regular expression string (case
     685                  insensitive) to match group names which are allowed when
     686                  writing this tag.  Only needed if tag can be written to
     687                  groups other than the normal groups for this tag (very rare).
    465688
    466689  OffsetPair    : Used in EXIF table to specify the tagID for the corresponding
     
    470693                  associated with offset/length tags.
    471694
    472   Struct        : [XMP tags only] Used by XMP writer code to specify name of XMP
    473                   structure so the PropertyPath can be determined.
     695  FixFormat     : [Writable EXIF SubIFD SubDirectory's only] Used to specify a
     696                  format for writing an IFD pointer other than 'int32u'.
     697
     698  ChangeBase    : [EXIF tags in JPEG images only] Eval used to return new base
     699                  for the offset for this tag only.  Eval may use $dirStart and
     700                  $dataPos.  Note this is geared to the quirky Leica preview
     701                  image offset, and is only used if the preview is outside the
     702                  APP1 EXIF segment.
     703
     704  Struct        : [XMP tags only] Reference to structure hash for structured XMP
     705                  tags.  See "STRUCTURES" section below for more details.  (For
     706                  backward compatibility, this may be a name to an entry in
     707                  %Image::ExifTool::UserDefined::xmpStruct, but this use is
     708                  deprecated.)  Flattened tags are automatically generated for
     709                  each field in the structure.  Note that Struct tags can NOT
     710                  have ValueConv/PrintConv entries, because values that are HASH
     711                  references are are also used by Composite tags, which use the
     712                  the Conv entries to generate the composite value.
     713
     714  Namespace     : [XMP tags only] Gives standard XMP namespace prefix to use for
     715                  this tag.  If not defined, the tag table NAMESPACE is used.
    474716
    475717  Units         : [MIE tags only] Reference to a list of valid units strings.
    476718                  The default units are the first item in the list.
    477719
    478   TagID         : [reserved] This entry is used internally by GetTagID() to
    479                   cache tag ID numbers for speed.
     720  Hook          : [BinaryData tags only] Expression to be evaluated when
     721                  extracting tag to allow dynamic Format, etc for BinaryData
     722                  tags.  May access $self, and assign a new value to $format to
     723                  dynamically set the tag format, and/or increment $varSize to
     724                  add a byte offset to subsequent tags.
     725
     726  TagID         : [reserved] Used internally to save the table key for this tag.
     727                  Note: For XMP tables this corresponds to the XMP property
     728                  name, but the table key may have a full XMP namespace prefix
     729                  added.
     730
     731  NewTagID      : [reserved] Used internally to save new ID of tag in Composite
     732                  table if it is different that the original TagID (happens if
     733                  there was a conflict with an existing entry in the table)
     734
     735  Index         : [reserved] Used internally to save the index of tagInfo items
     736                  which are in a conditional list.
    480737
    481738  Table         : [reserved] Reference to parent tag table.
    482739
    483740  PropertyPath  : [reserved] Used internally by XMP writer to save property path
    484                   name.
     741                  name.  Also used in structure field information hashes, but
     742                  for these the full property path is not stored.
     743
     744  SrcTagInfo    : [reserved] Used internally by XMP module to store reference to
     745                  default language tagInfo hash for alternate-language tags.
     746
     747  RootTagInfo   : [reserved] Used internally to store a reference to the tag
     748                  information hash of the top-level structure for flattened
     749                  structure tags.
    485750
    486751  Module        : [reserved] Used internally to store module name for writable
     
    488753
    489754  LangCode      : [reserved] Used internally to indicate language code for
    490                   alternate language tags (MIE and XMP only)
     755                  alternate language tags (ie. 'fr').  Only used with formats
     756                  which support alternate languages (ie. XMP, MIE, etc).
    491757
    492758  SubDirectory {  If it exists, this specifies the start of a new subdirectory.
     
    514780                  same as the current directory, which is normally the case.
    515781                  May use $start to represent the subdirectory start location
    516                   relative to the current base.  If this is defined, the
    517                   automatic validation of base offsets is disabled for maker
    518                   notes directories.
    519 
    520      EntryBased : Flag indicating that the offsets are based on the indidual
     782                  relative to the current base, and $base for the value of the
     783                  current base.  If this is defined, the automatic validation of
     784                  base offsets is disabled for maker notes directories.  The
     785                  IFD is flagged as using relative offsets when writing if
     786                  '$start' is used in this expression.
     787
     788     EntryBased : Flag indicating that the offsets are based on the individual
    521789                  directory entry position, so offsets are incremented by 12
    522790                  times the corresponding entry index.
     
    526794                  tag value ($val) is used as-is.  If MaxSubdirs is specified,
    527795                  then one subdirectory is parsed for each value found up to the
    528                   maximum number specified.
     796                  maximum number specified.  Ignored when writing.
    529797
    530798     ByteOrder  : Specifies byte ordering if different than than the rest of the
     
    538806                  the expression: $val (value of the tag), $dirData (reference
    539807                  to directory data), $subdirStart (offset to subdirectory
    540                   start) and $size (size of subdirectory).
     808                  start) and $size (size of subdirectory).  Returns true if
     809                  subirectory is valid.
    541810
    542811     ProcessProc: If given, specifies processing procedure used to decode this
    543812                  subdirectory data.  This overrides the default procedure
    544813                  specified by PROCESS_PROC in the tag table.
     814
     815     WriteProc:  If given, specifies processing procedure used to write this
     816                  subdirectory data.  This overrides the default procedure
     817                  specified by WRITE_PROC in the tag table.
    545818
    546819     DirName    : Name of this subdirectory.  If not specified, the name is
     
    551824     FixBase    : Flag set if base offsets should be fixed.  Used to add a
    552825                  constant to maker notes offsets to fix damage done by some
    553                   image editing utilities. (maker notes only)
     826                  image editing utilities. (maker notes only)  Set to 2 for
     827                  unknown maker notes to be a bit more flexible in adjusting
     828                  the base offset.
     829
     830     AutoFix    : Flag set to patch GE makernote offset quirks and apply FixBase
     831                  without warnings when writing.
    554832
    555833     FixOffsets : Expression to evaluate for each value pointer to patch
     
    557835                  following variables: $valuePtr, $valEnd, $size, $tagID and
    558836                  $wFlag.  May return undef when writing to ignore the entry.
     837
     838     RelativeBase:[EXIF directories only] Flag to adjust all offsets relative
     839                  to the start of the IFD when writing.
     840
     841     Multi      : [EXIF directories only] Flag to allow multiple linked IFD's.
     842                  1 is assumed if DirName is IFD0 or SubIFD unless otherwise
     843                  defined.
     844
     845     Magic      : [TiffIFD directories only] Magic number used in TIFF-like
     846                  header.
    559847  }
    560848
     849STRUCTURES
     850
     851Structure hashes are very similar to tag tables in that their keys are structure
     852field ID's and their values are structure field information hashes.  The special
     853keys in structure hashes are:
     854
     855  NAMESPACE   : Same as in tag tables, but may be set to undef for a
     856                variable-namespace structure which holds any top-level tag. This
     857                is mandatory for built-in tags, but optional for user-defined
     858                tags (where it defaults to the NAMESPACE of the tag table).
     859
     860  STRUCT_NAME : Name of structure (used in warning messages).
     861
     862  TYPE        : rdf:type resource for structure.
     863
     864  NOTES       : Notes for documentation.
     865
     866  GROUPS      : Same as in tag table, but only the family 2 group name is used,
     867                as the default for the flattened tags.
     868
     869The contained structure field information hashes are similar to tag information
     870hashes, except that only the following elements are used:
     871
     872  Raw/Value/PrintConv (and their inverses), TagID (optional), Groups, List,
     873  Writable, Struct, Namespace, LangCode, PropertyPath.
     874
     875But note that for PropertyPath, only the element of the path corresponding to
     876the specific field is stored (including any necessary list properties).  The
     877full property path is obtained by walking the structure tree.
     878
     879Flattened tags corresponding to each field in a structure are automatically
     880generated (using an on-demand approach to avoid spending time generating them
     881unless necessary).  Pre-defined flattened tags are allowed, and are used when it
     882is necessary to change the Name or Description of a flattened tag.  The
     883flattened tag information hash entries are copied from the corresponding
     884structure field definitions, even for pre-defined flattened tags.  The exception
     885that the List tag is generated automatically unless explicity set to 0 in a
     886pre-defined flattened tag.
     887
    561888--------------------------------------------------------------------------------
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/RIFF.pm

    r16842 r24107  
    1515#               8) http://graphics.cs.uni-sb.de/NMM/dist-0.9.1/Docs/Doxygen/html/mmreg_8h-source.html
    1616#               9) http://developers.videolan.org/vlc/vlc/doc/doxygen/html/codecs_8h-source.html
     17#              10) http://wiki.multimedia.cx/index.php?title=TwoCC
     18#              11) Andreas Winter (SCLive) private communication
     19#              12) http://abcavi.kibi.ru/infotags.htm
     20#              13) http://tech.ebu.ch/docs/tech/tech3285.pdf
    1721#------------------------------------------------------------------------------
    1822
     
    2327use Image::ExifTool qw(:DataAccess :Utils);
    2428
    25 $VERSION = '1.10';
     29$VERSION = '1.28';
     30
     31sub ConvertTimecode($);
    2632
    2733# type of current stream
    2834$Image::ExifTool::RIFF::streamType = '';
    2935
    30 my %riffEncoding = ( #2
     36%Image::ExifTool::RIFF::audioEncoding = ( #2
     37    Notes => 'These "TwoCC" audio encoding codes are used in RIFF and ASF files.',
    3138    0x01 => 'Microsoft PCM',
    3239    0x02 => 'Microsoft ADPCM',
     
    3946    0x09 => 'DRM', #4
    4047    0x0a => 'WMA 9 Speech', #9
     48    0x0b => 'Microsoft Windows Media RT Voice', #10
    4149    0x10 => 'OKI-ADPCM',
    4250    0x11 => 'Intel IMA/DVI-ADPCM',
     
    4957    0x18 => 'Media Vision ADPCM', #6
    5058    0x19 => 'HP CU', #7
     59    0x1a => 'HP Dynamic Voice', #10
    5160    0x20 => 'Yamaha ADPCM', #6
    5261    0x21 => 'SONARC Speech Compression', #6
     
    7584    0x41 => 'Antex G.728 CELP',
    7685    0x42 => 'Microsoft MSG723', #7
     86    0x43 => 'IBM AVC ADPCM', #10
    7787    0x45 => 'ITU-T G.726', #9
    7888    0x50 => 'Microsoft MPEG',
     
    101111    0x78 => 'Voxware VR18', #7
    102112    0x79 => 'Voxware TQ40', #7
     113    0x7a => 'Voxware SC3', #10
     114    0x7b => 'Voxware SC3', #10
    103115    0x80 => 'Soundsoft', #6
    104116    0x81 => 'Voxware TQ60', #7
     
    110122    0x88 => 'Iterated Systems Audio', #7
    111123    0x89 => 'Onlive', #7
     124    0x8a => 'Multitude, Inc. FT SX20', #10
     125    0x8b => 'Infocom ITS A/S G.721 ADPCM', #10
     126    0x8c => 'Convedia G729', #10
     127    0x8d => 'Not specified congruency, Inc.', #10
    112128    0x91 => 'Siemens SBC24', #7
    113129    0x92 => 'Sonic Foundry Dolby AC3 APDIF', #7
     
    118134    0x99 => 'Studer Professional Audio Packed', #7
    119135    0xa0 => 'Malden PhonyTalk', #8
     136    0xa1 => 'Racal Recorder GSM', #10
     137    0xa2 => 'Racal Recorder G720.a', #10
     138    0xa3 => 'Racal G723.1', #10
     139    0xa4 => 'Racal Tetra ACELP', #10
     140    0xb0 => 'NEC AAC NEC Corporation', #10
     141    0xff => 'AAC', #10
    120142    0x100 => 'Rhetorex ADPCM', #6
    121143    0x101 => 'IBM u-Law', #3
     
    124146    0x111 => 'Vivo G.723', #7
    125147    0x112 => 'Vivo Siren', #7
     148    0x120 => 'Philips Speech Processing CELP', #10
     149    0x121 => 'Philips Speech Processing GRUNDIG', #10
    126150    0x123 => 'Digital G.723', #7
    127151    0x125 => 'Sanyo LD ADPCM', #8
     
    132156    0x134 => 'Sipro Lab G.729A', #8
    133157    0x135 => 'Sipro Lab Kelvin', #8
     158    0x136 => 'VoiceAge AMR', #10
    134159    0x140 => 'Dictaphone G.726 ADPCM', #8
    135160    0x150 => 'Qualcomm PureVoice', #8
     
    137162    0x155 => 'Ring Zero Systems TUBGSM', #8
    138163    0x160 => 'Microsoft Audio1', #8
     164    0x161 => 'Windows Media Audio V2 V7 V8 V9 / DivX audio (WMA) / Alex AC3 Audio', #10
     165    0x162 => 'Windows Media Audio Professional V9', #10
     166    0x163 => 'Windows Media Audio Lossless V9', #10
     167    0x164 => 'WMA Pro over S/PDIF', #10
     168    0x170 => 'UNISYS NAP ADPCM', #10
     169    0x171 => 'UNISYS NAP ULAW', #10
     170    0x172 => 'UNISYS NAP ALAW', #10
     171    0x173 => 'UNISYS NAP 16K', #10
     172    0x174 => 'MM SYCOM ACM SYC008 SyCom Technologies', #10
     173    0x175 => 'MM SYCOM ACM SYC701 G726L SyCom Technologies', #10
     174    0x176 => 'MM SYCOM ACM SYC701 CELP54 SyCom Technologies', #10
     175    0x177 => 'MM SYCOM ACM SYC701 CELP68 SyCom Technologies', #10
     176    0x178 => 'Knowledge Adventure ADPCM', #10
     177    0x180 => 'Fraunhofer IIS MPEG2AAC', #10
     178    0x190 => 'Digital Theater Systems DTS DS', #10
    139179    0x200 => 'Creative Labs ADPCM', #6
    140180    0x202 => 'Creative Labs FASTSPEECH8', #6
    141181    0x203 => 'Creative Labs FASTSPEECH10', #6
    142182    0x210 => 'UHER ADPCM', #8
     183    0x215 => 'Ulead DV ACM', #10
     184    0x216 => 'Ulead DV ACM', #10
    143185    0x220 => 'Quarterdeck Corp.', #6
    144186    0x230 => 'I-Link VC', #8
    145187    0x240 => 'Aureal Semiconductor Raw Sport', #8
     188    0x241 => 'ESST AC3', #10
    146189    0x250 => 'Interactive Products HSX', #8
    147190    0x251 => 'Interactive Products RPELP', #8
    148191    0x260 => 'Consistent CS2', #8
    149192    0x270 => 'Sony SCX', #8
     193    0x271 => 'Sony SCY', #10
     194    0x272 => 'Sony ATRAC3', #10
     195    0x273 => 'Sony SPC', #10
     196    0x280 => 'TELUM Telum Inc.', #10
     197    0x281 => 'TELUMIA Telum Inc.', #10
     198    0x285 => 'Norcom Voice Systems ADPCM', #10
    150199    0x300 => 'Fujitsu FM TOWNS SND', #6
     200    0x301 => 'Fujitsu (not specified)', #10
     201    0x302 => 'Fujitsu (not specified)', #10
     202    0x303 => 'Fujitsu (not specified)', #10
     203    0x304 => 'Fujitsu (not specified)', #10
     204    0x305 => 'Fujitsu (not specified)', #10
     205    0x306 => 'Fujitsu (not specified)', #10
     206    0x307 => 'Fujitsu (not specified)', #10
     207    0x308 => 'Fujitsu (not specified)', #10
     208    0x350 => 'Micronas Semiconductors, Inc. Development', #10
     209    0x351 => 'Micronas Semiconductors, Inc. CELP833', #10
    151210    0x400 => 'Brooktree Digital', #6
     211    0x401 => 'Intel Music Coder (IMC)', #10
     212    0x402 => 'Ligos Indeo Audio', #10
    152213    0x450 => 'QDesign Music', #8
     214    0x500 => 'On2 VP7 On2 Technologies', #10
     215    0x501 => 'On2 VP6 On2 Technologies', #10
    153216    0x680 => 'AT&T VME VMPCM', #7
    154217    0x681 => 'AT&T TCP', #8
     218    0x700 => 'YMPEG Alpha (dummy for MPEG-2 compressor)', #10
     219    0x8ae => 'ClearJump LiteWave (lossless)', #10
    155220    0x1000 => 'Olivetti GSM', #6
    156221    0x1001 => 'Olivetti ADPCM', #6
     
    159224    0x1004 => 'Olivetti OPR', #6
    160225    0x1100 => 'Lernout & Hauspie', #6
     226    0x1101 => 'Lernout & Hauspie CELP codec', #10
     227    0x1102 => 'Lernout & Hauspie SBC codec', #10
     228    0x1103 => 'Lernout & Hauspie SBC codec', #10
     229    0x1104 => 'Lernout & Hauspie SBC codec', #10
    161230    0x1400 => 'Norris Comm. Inc.', #6
    162231    0x1401 => 'ISIAudio', #7
    163232    0x1500 => 'AT&T Soundspace Music Compression', #7
     233    0x181c => 'VoxWare RT24 speech codec', #10
     234    0x181e => 'Lucent elemedia AX24000P Music codec', #10
     235    0x1971 => 'Sonic Foundry LOSSLESS', #10
     236    0x1979 => 'Innings Telecom Inc. ADPCM', #10
     237    0x1c07 => 'Lucent SX8300P speech codec', #10
     238    0x1c0c => 'Lucent SX5363S G.723 compliant codec', #10
     239    0x1f03 => 'CUseeMe DigiTalk (ex-Rocwell)', #10
     240    0x1fc4 => 'NCT Soft ALF2CD ACM', #10
    164241    0x2000 => 'FAST Multimedia DVM', #7
     242    0x2001 => 'Dolby DTS (Digital Theater System)', #10
     243    0x2002 => 'RealAudio 1 / 2 14.4', #10
     244    0x2003 => 'RealAudio 1 / 2 28.8', #10
     245    0x2004 => 'RealAudio G2 / 8 Cook (low bitrate)', #10
     246    0x2005 => 'RealAudio 3 / 4 / 5 Music (DNET)', #10
     247    0x2006 => 'RealAudio 10 AAC (RAAC)', #10
     248    0x2007 => 'RealAudio 10 AAC+ (RACP)', #10
     249    0x2500 => 'Reserved range to 0x2600 Microsoft', #10
     250    0x3313 => 'makeAVIS (ffvfw fake AVI sound from AviSynth scripts)', #10
     251    0x4143 => 'Divio MPEG-4 AAC audio', #10
     252    0x4201 => 'Nokia adaptive multirate', #10
     253    0x4243 => 'Divio G726 Divio, Inc.', #10
     254    0x434c => 'LEAD Speech', #10
     255    0x564c => 'LEAD Vorbis', #10
     256    0x5756 => 'WavPack Audio', #10
     257    0x674f => 'Ogg Vorbis (mode 1)', #10
     258    0x6750 => 'Ogg Vorbis (mode 2)', #10
     259    0x6751 => 'Ogg Vorbis (mode 3)', #10
     260    0x676f => 'Ogg Vorbis (mode 1+)', #10
     261    0x6770 => 'Ogg Vorbis (mode 2+)', #10
     262    0x6771 => 'Ogg Vorbis (mode 3+)', #10
     263    0x7000 => '3COM NBX 3Com Corporation', #10
     264    0x706d => 'FAAD AAC', #10
     265    0x7a21 => 'GSM-AMR (CBR, no SID)', #10
     266    0x7a22 => 'GSM-AMR (VBR, including SID)', #10
     267    0xa100 => 'Comverse Infosys Ltd. G723 1', #10
     268    0xa101 => 'Comverse Infosys Ltd. AVQSBC', #10
     269    0xa102 => 'Comverse Infosys Ltd. OLDSBC', #10
     270    0xa103 => 'Symbol Technologies G729A', #10
     271    0xa104 => 'VoiceAge AMR WB VoiceAge Corporation', #10
     272    0xa105 => 'Ingenient Technologies Inc. G726', #10
     273    0xa106 => 'ISO/MPEG-4 advanced audio Coding', #10
     274    0xa107 => 'Encore Software Ltd G726', #10
     275    0xa109 => 'Speex ACM Codec xiph.org', #10
     276    0xdfac => 'DebugMode SonicFoundry Vegas FrameServer ACM Codec', #10
     277    0xe708 => 'Unknown -', #10
     278    0xf1ac => 'Free Lossless Audio Codec FLAC', #10
    165279    0xfffe => 'Extensible', #7
    166280    0xffff => 'Development', #4
     
    171285    PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks,
    172286    NOTES => q{
    173         Windows WAV and AVI files are RIFF format files.  Meta information embedded
    174         in two types of RIFF C<LIST> chunks: C<INFO> and C<exif>.  As well, some
    175         information about the audio content is extracted from the C<fmt > chunk.
     287        The RIFF container format is used various types of fines including WAV, AVI
     288        and WEBP.  According to the EXIF specification, Meta information is embedded
     289        in two types of RIFF C<LIST> chunks: C<INFO> and C<exif>, and information
     290        about the audio content is stored in the C<fmt > chunk.  As well as this
     291        information, some video information and proprietary manufacturer-specific
     292        information is also extracted.
    176293    },
    177294   'fmt ' => {
     
    179296        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::AudioFormat' },
    180297    },
     298   'bext' => {
     299        Name => 'BroadcastExtension',
     300        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::BroadcastExt' },
     301    },
    181302    LIST_INFO => {
    182303        Name => 'Info',
     
    191312        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::Hdrl' },
    192313    },
     314    LIST_Tdat => { #PH (Adobe CS3 Bridge)
     315        Name => 'Tdat',
     316        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::Tdat' },
     317    },
     318    LIST_ncdt => { #PH (Nikon metadata)
     319        Name => 'NikonData',
     320        SubDirectory => {
     321            TagTable => 'Image::ExifTool::Nikon::AVI',
     322            # define ProcessProc here so we don't need to load RIFF.pm from Nikon.pm
     323            ProcessProc => \&Image::ExifTool::RIFF::ProcessChunks,
     324        },
     325    },
     326    LIST_hydt => { #PH (Pentax metadata)
     327        Name => 'PentaxData',
     328        SubDirectory => {
     329            TagTable => 'Image::ExifTool::Pentax::AVI',
     330            ProcessProc => \&Image::ExifTool::RIFF::ProcessChunks,
     331        },
     332    },
     333    JUNK => [
     334        {
     335            Name => 'OlympusJunk',
     336            Condition => '$$valPt =~ /^OLYMDigital Camera/',
     337            SubDirectory => { TagTable => 'Image::ExifTool::Olympus::AVI' },
     338        },
     339        {
     340            Name => 'CasioJunk',
     341            Condition => '$$valPt =~ /^QVMI/',
     342            # Casio stores standard EXIF-format information in AVI videos (EX-S600)
     343            SubDirectory => {
     344                TagTable => 'Image::ExifTool::Exif::Main',
     345                DirName => 'IFD0',
     346                Multi => 0, # (IFD1 is not written)
     347                Start => 10,
     348                ByteOrder => 'BigEndian',
     349            },
     350        },
     351        {
     352            Name => 'RicohJunk',
     353            # the Ricoh Caplio GX stores sub-chunks in here
     354            Condition => '$$valPt =~ /^ucmt/',
     355            SubDirectory => {
     356                TagTable => 'Image::ExifTool::Ricoh::AVI',
     357                ProcessProc => \&Image::ExifTool::RIFF::ProcessChunks,
     358            },
     359        },
     360        {
     361            Name => 'PentaxJunk', # (Optio RS1000)
     362            Condition => '$$valPt =~ /^IIII\x01\0/',
     363            SubDirectory => { TagTable => 'Image::ExifTool::Pentax::Junk' },
     364        },
     365        {
     366            Name => 'TextJunk',
     367            # try to interpret unknown junk as an ASCII string
     368            RawConv => '$val =~ /^([^\0-\x1f\x7f-\xff]+)\0*$/ ? $1 : undef',
     369        }
     370    ],
     371    _PMX => { #PH (Adobe CS3 Bridge)
     372        Name => 'XMP',
     373        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     374    },
     375    JUNQ => { #PH (Adobe CS3 Bridge)
     376        # old XMP is preserved when metadata is replaced in Bridge
     377        Name => 'OldXMP',
     378        Binary => 1,
     379    },
     380    olym => {
     381        Name => 'Olym',
     382        SubDirectory => { TagTable => 'Image::ExifTool::Olympus::WAV' },
     383    },
     384);
     385
     386# the maker notes used by some digital cameras
     387%Image::ExifTool::RIFF::Junk = (
     388    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     389    GROUPS => { 2 => 'Audio' },
    193390);
    194391
     
    201398        Name => 'Encoding',
    202399        PrintHex => 1,
    203         PrintConv => \%riffEncoding,
     400        PrintConv => \%Image::ExifTool::RIFF::audioEncoding,
     401        SeparateTable => 'AudioEncoding',
    204402    },
    205403    1 => 'NumChannels',
     
    217415);
    218416
     417# Broadcast Audio Extension 'bext' information (ref 13)
     418%Image::ExifTool::RIFF::BroadcastExt = (
     419    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     420    GROUPS => { 2 => 'Audio' },
     421    NOTES => q{
     422        Information found in the Broadcast Audio Extension chunk (see
     423        L<http://tech.ebu.ch/docs/tech/tech3285.pdf>).
     424    },
     425    0 => {
     426        Name => 'Description',
     427        Format => 'string[256]',
     428    },
     429    256 => {
     430        Name => 'Originator',
     431        Format => 'string[32]',
     432    },
     433    288 => {
     434        Name => 'OriginatorReference',
     435        Format => 'string[32]',
     436    },
     437    320 => {
     438        Name => 'DateTimeOriginal',
     439        Description => 'Date/Time Original',
     440        Groups => { 2 => 'Time' },
     441        Format => 'string[18]',
     442        ValueConv => '$_=$val; tr/-/:/; s/^(\d{4}:\d{2}:\d{2})/$1 /; $_',
     443        PrintConv => '$self->ConvertDateTime($val)',
     444    },
     445    338 => {
     446        Name => 'TimeReference',
     447        Notes => 'first sample count since midnight',
     448        Format => 'int32u[2]',
     449        ValueConv => 'my @v=split(" ",$val); $v[0] + $v[1] * 4294967296',
     450    },
     451    346 => {
     452        Name => 'BWFVersion',
     453        Format => 'int16u',
     454    },
     455    # 348 - int8u[64] - SMPTE 330M UMID (Unique Material Identifier)
     456    # 412 - int8u[190] - reserved
     457    602 => {
     458        Name => 'CodingHistory',
     459        Format => 'string[$size-602]',
     460    },
     461);
     462
    219463# Sub chunks of INFO LIST chunk
    220464%Image::ExifTool::RIFF::Info = (
    221465    PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks,
    222466    GROUPS => { 2 => 'Audio' },
     467    NOTES => q{
     468        RIFF INFO tags found in WAV audio and AVI video files.  Tags which are part
     469        of the EXIF 2.3 specification have an underlined Tag Name in the HTML
     470        version of this documentation.  Other tags are found in AVI files generated
     471        by some software.
     472    },
    223473    IARL => 'ArchivalLocation',
    224474    IART => { Name => 'Artist',    Groups => { 2 => 'Author' } },
     
    229479        Name => 'DateCreated',
    230480        Groups => { 2 => 'Time' },
    231         ValueConv => '$_=$val; s/-/:/g; s/\0.*//s; $_',
     481        ValueConv => '$_=$val; s/-/:/g; $_',
    232482    },
    233483    ICRP => 'Cropped',
     
    243493    IPRD => 'Product',
    244494    ISBJ => 'Subject',
    245     ISFT => 'Software',
     495    ISFT => {
     496        Name => 'Software',
     497        # remove trailing nulls/spaces and split at first null
     498        # (Casio writes "CASIO" in unicode after the first null)
     499        ValueConv => '$_=$val; s/(\s*\0)+$//; s/(\s*\0)/, /; s/\0+//g; $_',
     500    },
    246501    ISHP => 'Sharpness',
    247502    ISRC => 'Source',
    248503    ISRF => 'SourceForm',
    249504    ITCH => 'Technician',
     505#
     506# 3rd party tags
     507#
     508    # internet movie database (ref 12)
     509    ISGN => 'SecondaryGenre',
     510    IWRI => 'WrittenBy',
     511    IPRO => 'ProducedBy',
     512    ICNM => 'Cinematographer',
     513    IPDS => 'ProductionDesigner',
     514    IEDT => 'EditedBy',
     515    ICDS => 'CostumeDesigner',
     516    IMUS => 'MusicBy',
     517    ISTD => 'ProductionStudio',
     518    IDST => 'DistributedBy',
     519    ICNT => 'Country',
     520    ILNG => 'Language',
     521    IRTD => 'Rating',
     522    ISTR => 'Starring',
     523    # MovieID (ref12)
     524    TITL => 'Title',
     525    DIRC => 'Directory',
     526    YEAR => 'Year',
     527    GENR => 'Genre',
     528    COMM => 'Comments',
     529    LANG => 'Language',
     530    AGES => 'Rated',
     531    STAR => 'Starring',
     532    CODE => 'EncodedBy',
     533    PRT1 => 'Part',
     534    PRT2 => 'NumberOfParts',
     535    # Morgan Multimedia INFO tags (ref 12)
     536    IAS1 => 'FirstLanguage',
     537    IAS2 => 'SecondLanguage',
     538    IAS3 => 'ThirdLanguage',
     539    IAS4 => 'FourthLanguage',
     540    IAS5 => 'FifthLanguage',
     541    IAS6 => 'SixthLanguage',
     542    IAS7 => 'SeventhLanguage',
     543    IAS8 => 'EighthLanguage',
     544    IAS9 => 'NinthLanguage',
     545    ICAS => 'DefaultAudioStream',
     546    IBSU => 'BaseURL',
     547    ILGU => 'LogoURL',
     548    ILIU => 'LogoIconURL',
     549    IWMU => 'WatermarkURL',
     550    IMIU => 'MoreInfoURL',
     551    IMBI => 'MoreInfoBannerImage',
     552    IMBU => 'MoreInfoBannerURL',
     553    IMIT => 'MoreInfoText',
     554    # GSpot INFO tags (ref 12)
     555    IENC => 'EncodedBy',
     556    IRIP => 'RippedBy',
     557    # Sound Forge Pro tags
     558    DISP => 'SoundSchemeTitle',
     559    TLEN => { Name => 'Length', ValueConv => '$val/1000', PrintConv => '"$val s"' },
     560    TRCK => 'TrackNumber',
     561    TURL => 'URL',
     562    TVER => 'Version',
     563    LOCA => 'Location',
     564    TORG => 'Organization',
     565    # Sony Vegas AVI tags, also used by SCLive and Adobe Premier (ref 11)
     566    TAPE => {
     567        Name => 'TapeName',
     568        Groups => { 2 => 'Video' },
     569    },
     570    TCOD => {
     571        Name => 'StartTimecode',
     572        # this is the tape time code for the start of the video
     573        Groups => { 2 => 'Video' },
     574        ValueConv => '$val * 1e-7',
     575        PrintConv => \&ConvertTimecode,
     576    },
     577    TCDO => {
     578        Name => 'EndTimecode',
     579        Groups => { 2 => 'Video' },
     580        ValueConv => '$val * 1e-7',
     581        PrintConv => \&ConvertTimecode,
     582    },
     583    VMAJ => {
     584        Name => 'VegasVersionMajor',
     585        Groups => { 2 => 'Video' },
     586    },
     587    VMIN => {
     588        Name => 'VegasVersionMinor',
     589        Groups => { 2 => 'Video' },
     590    },
     591    CMNT => {
     592        Name => 'Comment',
     593        Groups => { 2 => 'Video' },
     594    },
     595    RATE => {
     596        Name => 'Rate', #? (video? units?)
     597        Groups => { 2 => 'Video' },
     598    },
     599    STAT => {
     600        Name => 'Statistics',
     601        Groups => { 2 => 'Video' },
     602        # ("7318 0 3.430307 1", "0 0 3500.000000 1", "7 0 3.433228 1")
     603        PrintConv => [
     604            '"$val frames captured"',
     605            '"$val dropped"',
     606            '"Data rate $val"',
     607            { 0 => 'Bad', 1 => 'OK' }, # capture OK?
     608        ],
     609    },
     610    DTIM => {
     611        Name => 'DateTimeOriginal',
     612        Description => 'Date/Time Original',
     613        Groups => { 2 => 'Time' },
     614        ValueConv => q{
     615            my @v = split ' ', $val;
     616            return undef unless @v == 2;
     617            # get time in seconds
     618            $val = 1e-7 * ($v[0] * 4294967296 + $v[1]);
     619            # shift from Jan 1, 1601 to Jan 1, 1970
     620            $val -= 134774 * 24 * 3600 if $val != 0;
     621            return Image::ExifTool::ConvertUnixTime($val);
     622        },
     623        PrintConv => '$self->ConvertDateTime($val)',
     624    },
    250625);
    251626
     
    254629    PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks,
    255630    GROUPS => { 2 => 'Audio' },
     631    NOTES => 'These tags are part of the EXIF 2.3 specification for WAV audio files.',
    256632    ever => 'ExifVersion',
    257633    erel => 'RelatedImageFile',
     
    281657        PrintConv => '$self->ConvertDateTime($val)',
    282658    },
    283     ISMP => 'TimeCode',
     659    ISMP => 'Timecode',
    284660    LIST_strl => {
    285661        Name => 'Stream',
    286662        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::Stream' },
    287663    },
     664    LIST_odml => {
     665        Name => 'OpenDML',
     666        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::OpenDML' },
     667    },
     668);
     669
     670# Sub chunks of Tdat LIST chunk (ref PH)
     671%Image::ExifTool::RIFF::Tdat = (
     672    PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks,
     673    GROUPS => { 2 => 'Video' },
     674    # (have seen tc_O, tc_A, rn_O and rn_A)
    288675);
    289676
     
    295682    0 => {
    296683        Name => 'FrameRate',
    297         ValueConv => '$val ? 1e6 / $val : undef',
     684        # (must use RawConv because raw value used in Composite tag)
     685        RawConv => '$val ? 1e6 / $val : undef',
    298686        PrintConv => 'int($val * 1000 + 0.5) / 1000',
    299687    },
     
    338726);
    339727
     728# Open DML tags (ref http://www.morgan-multimedia.com/download/odmlff2.pdf)
     729%Image::ExifTool::RIFF::OpenDML = (
     730    PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks,
     731    GROUPS => { 2 => 'Video' },
     732    dmlh => {
     733        Name => 'ExtendedAVIHeader',
     734        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::ExtAVIHdr' },
     735    },
     736);
     737
     738# Extended AVI Header tags (ref http://www.morgan-multimedia.com/download/odmlff2.pdf)
     739%Image::ExifTool::RIFF::ExtAVIHdr = (
     740    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     741    GROUPS => { 2 => 'Video' },
     742    FORMAT => 'int32u',
     743    0 => 'TotalFrameCount',
     744);
     745
    340746%Image::ExifTool::RIFF::StreamHeader = (
    341747    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     
    343749    FORMAT => 'int32u',
    344750    FIRST_ENTRY => 0,
     751    PRIORITY => 0,  # so we get values from the first stream
    345752    0 => {
    346753        Name => 'StreamType',
     
    354761        },
    355762    },
    356     1 => {
    357         Name => 'Codec',
    358         Format => 'string[4]',
    359     },
     763    1 => [
     764        {
     765            Name => 'AudioCodec',
     766            Condition => '$Image::ExifTool::RIFF::streamType eq "auds"',
     767            Format => 'string[4]',
     768        },
     769        {
     770            Name => 'VideoCodec',
     771            Condition => '$Image::ExifTool::RIFF::streamType eq "vids"',
     772            Format => 'string[4]',
     773        },
     774        {
     775            Name => 'Codec',
     776            Format => 'string[4]',
     777        },
     778    ],
    360779  # 2 => 'StreamFlags',
    361780  # 3 => 'StreamPriority',
    362781  # 3.5 => 'Language',
    363782  # 4 => 'InitialFrames',
    364   # 5 => 'Scale',
    365   # 6 => 'Rate',
     783    5 => [
     784        {
     785            Name => 'AudioSampleRate',
     786            Condition => '$Image::ExifTool::RIFF::streamType eq "auds"',
     787            Format => 'rational64u',
     788            ValueConv => '$val ? 1/$val : 0',
     789            PrintConv => 'int($val * 100 + 0.5) / 100',
     790        },
     791        {
     792            Name => 'VideoFrameRate',
     793            Condition => '$Image::ExifTool::RIFF::streamType eq "vids"',
     794            Format => 'rational64u',
     795            # (must use RawConv because raw value used in Composite tag)
     796            RawConv => '$val ? 1/$val : undef',
     797            PrintConv => 'int($val * 1000 + 0.5) / 1000',
     798        },
     799        {
     800            Name => 'StreamSampleRate',
     801            Format => 'rational64u',
     802            ValueConv => '$val ? 1/$val : 0',
     803            PrintConv => 'int($val * 1000 + 0.5) / 1000',
     804        },
     805    ],
    366806  # 7 => 'Start',
    367   # 8 => 'Length',
     807    8 => [
     808        {
     809            Name => 'AudioSampleCount',
     810            Condition => '$Image::ExifTool::RIFF::streamType eq "auds"',
     811        },
     812        {
     813            Name => 'VideoFrameCount',
     814            Condition => '$Image::ExifTool::RIFF::streamType eq "vids"',
     815        },
     816        {
     817            Name => 'StreamSampleCount',
     818        },
     819    ],
    368820  # 9 => 'SuggestedBufferSize',
    369     10 => 'Quality',
     821    10 => {
     822        Name => 'Quality',
     823        PrintConv => '$val eq 0xffffffff ? "Default" : $val',
     824    },
    370825    11 => {
    371826        Name => 'SampleSize',
     
    378833    PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessStreamData,
    379834    GROUPS => { 2 => 'Video' },
    380     NOTES => 'This chunk contains EXIF information in FujiFilm F30 AVI files.',
     835    NOTES => q{
     836        This chunk is used to store proprietary information in AVI videos from some
     837        cameras.  The first 4 characters of the data are used as the Tag ID below.
     838    },
    381839    AVIF => {
    382840        Name => 'AVIF',
     
    385843            DirName => 'IFD0',
    386844            Start => 8,
    387             ByteOrder => 'II',
    388         },
     845            ByteOrder => 'LittleEndian',
     846        },
     847    },
     848    CASI => { # (used by Casio GV-10)
     849        Name => 'CasioData',
     850        SubDirectory => { TagTable => 'Image::ExifTool::Casio::AVI' },
     851    },
     852    Zora => 'VendorName',   # (Samsung PL90 AVI files)
     853    unknown => {
     854        Name => 'UnknownData',
     855        # try to interpret unknown stream data as a string
     856        RawConv => '$_=$val; /^[^\0-\x1f\x7f-\xff]+$/ ? $_ : undef',
    389857    },
    390858);
     
    394862    Duration => {
    395863        Require => {
    396             0 => 'FrameRate',
    397             1 => 'FrameCount',
    398         },
    399         ValueConv => '$val[0] ? $val[1] / $val[0] : undef',
    400         PrintConv => 'sprintf("%.2fs",$val)',
     864            0 => 'RIFF:FrameRate',
     865            1 => 'RIFF:FrameCount',
     866        },
     867        Desire => {
     868            2 => 'VideoFrameRate',
     869            3 => 'VideoFrameCount',
     870        },
     871        # this is annoying.  Apparently (although I couldn't verify this), FrameCount
     872        # in the RIFF header includes multiple video tracks if they exist (ie. with the
     873        # FujiFilm REAL 3D AVI's), but the video stream information isn't reliable for
     874        # some cameras (ie. Olympus FE models), so use the video stream information
     875        # only if the RIFF header duration is 2 to 3 times longer
     876        RawConv => q {
     877            my ($dur1, $dur2);
     878            $dur1 = $val[1] / $val[0] if $val[0];
     879            return $dur1 unless $val[2] and $val[3];
     880            $dur2 = $val[3] / $val[2];
     881            my $rat = $dur1 / $dur2;
     882            return ($rat > 1.9 and $rat < 3.1) ? $dur2 : $dur1;
     883        },
     884        PrintConv => 'ConvertDuration($val)',
     885    },
     886    Duration2 => {
     887        Name => 'Duration',
     888        Require => {
     889            0 => 'RIFF:AvgBytesPerSec',
     890            1 => 'FileSize',
     891        },
     892        Desire => {
     893            # check FrameCount because this calculation only applies
     894            # to audio-only files (ie. WAV)
     895            2 => 'FrameCount',
     896            3 => 'VideoFrameCount',
     897        },
     898        RawConv => '($val[0] and not ($val[2] or $val[3])) ? $val[1] / $val[0] : undef',
     899        PrintConv => 'ConvertDuration($val)',
    401900    },
    402901);
     
    430929
    431930#------------------------------------------------------------------------------
     931# Print time
     932# Inputs: 0) time in seconds
     933# Returns: time string
     934sub ConvertTimecode($)
     935{
     936    my $val = shift;
     937    my $hr = int($val / 3600);
     938    $val -= $hr * 3600;
     939    my $min = int($val / 60);
     940    $val -= $min * 60;
     941    return sprintf("%d:%.2d:%05.2f", $hr, $min, $val);
     942}
     943
     944#------------------------------------------------------------------------------
    432945# Process stream data
    433946# Inputs: 0) ExifTool object ref, 1) dirInfo reference, 2) tag table ref
     
    445958    my $tag = substr($$dataPt, $start, 4);
    446959    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
     960    unless ($tagInfo) {
     961        $tagInfo = $exifTool->GetTagInfo($tagTablePtr, 'unknown');
     962        return 1 unless $tagInfo;
     963    }
    447964    my $subdir = $$tagInfo{SubDirectory};
    448     if ($subdir) {
     965    if ($$tagInfo{SubDirectory}) {
    449966        my $offset = $$subdir{Start} || 0;
    450967        my $baseShift = $$dirInfo{DataPos} + $$dirInfo{DirStart} + $offset;
     
    459976            Parent  => $$dirInfo{DirName},
    460977        );
     978        unless ($offset) {
     979            # allow processing of 2nd directory at the same address
     980            my $addr = $subdirInfo{DirStart} + $subdirInfo{DataPos} + $subdirInfo{Base};
     981            delete $exifTool->{PROCESSED}->{$addr}
     982        }
    461983        # (we could set FIRST_EXIF_POS to $subdirInfo{Base} here to make
    462984        #  htmlDump offsets relative to EXIF base if we wanted...)
    463985        my $subTable = GetTagTable($$subdir{TagTable});
    464986        $exifTool->ProcessDirectory(\%subdirInfo, $subTable);
     987    } else {
     988        $exifTool->HandleTag($tagTablePtr, $tag, undef,
     989            DataPt  => $dataPt,
     990            DataPos => $$dirInfo{DataPos},
     991            Start   => $start,
     992            Size    => $size,
     993            TagInfo => $tagInfo,
     994        );
    465995    }
    466996    return 1;
     
    4791009    my $size = $$dirInfo{DirLen};
    4801010    my $end = $start + $size;
     1011    my $base = $$dirInfo{Base};
    4811012
    4821013    if ($exifTool->Options('Verbose')) {
     
    4961027            $start += 4;
    4971028        }
    498         $exifTool->HandleTag($tagTablePtr, $tag, undef,
    499             DataPt => $dataPt,
    500             DataPos => $$dirInfo{DataPos},
    501             Start => $start,
    502             Size => $len,
     1029        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
     1030        my $baseShift = 0;
     1031        my $val;
     1032        if ($tagInfo) {
     1033            if ($$tagInfo{SubDirectory}) {
     1034                # adjust base if necessary (needed for Ricoh maker notes)
     1035                my $newBase = $tagInfo->{SubDirectory}{Base};
     1036                if (defined $newBase) {
     1037                    # different than your average Base eval...
     1038                    # here we use an absolute $start address
     1039                    $start += $base;
     1040                    #### eval Base ($start)
     1041                    $newBase = eval $newBase;
     1042                    $baseShift = $newBase - $base;
     1043                    $start -= $base;
     1044                }
     1045            } elsif (not $$tagInfo{Binary}) {
     1046                $val = substr($$dataPt, $start, $len);
     1047                $val =~ s/\0+$//;   # remove trailing nulls from strings
     1048            }
     1049        }
     1050        $exifTool->HandleTag($tagTablePtr, $tag, $val,
     1051            DataPt  => $dataPt,
     1052            DataPos => $$dirInfo{DataPos} - $baseShift,
     1053            Start   => $start,
     1054            Size    => $len,
     1055            Base    => $base + $baseShift,
    5031056        );
    5041057        ++$len if $len & 0x01;  # must account for padding if odd number of bytes
     
    5171070    my $raf = $$dirInfo{RAF};
    5181071    my ($buff, $err);
    519     my %types = ( 'WAVE' => 'WAV', 'AVI ' => 'AVI' );
     1072    my %types = ( 'WAVE' => 'WAV', 'AVI ' => 'AVI', 'WEBP' => 'WEBP' );
     1073    my $verbose = $exifTool->Options('Verbose');
    5201074
    5211075    # verify this is a valid RIFF file
    5221076    return 0 unless $raf->Read($buff, 12) == 12;
    5231077    return 0 unless $buff =~ /^RIFF....(.{4})/s;
    524     $exifTool->SetFileType($types{$1}); # set type to 'WAV', 'AVI' or 'RIFF'
     1078    $exifTool->SetFileType($types{$1}); # set type to 'WAV', 'AVI', 'WEBP' or 'RIFF'
    5251079    $Image::ExifTool::RIFF::streamType = '';    # initialize stream type
    5261080    SetByteOrder('II');
     
    5281082    my $pos = 12;
    5291083#
    530 # Read chunks in RIFF image until we get to the 'data' chunk
     1084# Read chunks in RIFF image
    5311085#
    5321086    for (;;) {
    533         $raf->Read($buff, 8) == 8 or $err=1, last;
     1087        my $num = $raf->Read($buff, 8);
     1088        if ($num < 8) {
     1089            $err = 1 if $num;
     1090            last;
     1091        }
    5341092        $pos += 8;
    5351093        my ($tag, $len) = unpack('a4V', $buff);
     
    5431101        $exifTool->VPrint(0, "RIFF '$tag' chunk ($len bytes of data):\n");
    5441102        # stop when we hit the audio data or AVI index or AVI movie data
    545         if ($tag eq 'data' or $tag eq 'idx1' or $tag eq 'LIST_movi') {
     1103        # --> no more because Adobe Bridge stores XMP after this!!
     1104        # (so now we only do this on the FastScan option)
     1105        if (($tag eq 'data' or $tag eq 'idx1' or $tag eq 'LIST_movi') and
     1106            $exifTool->Options('FastScan'))
     1107        {
    5461108            $exifTool->VPrint(0, "(end of parsing)\n");
    5471109            last;
    5481110        }
    549         my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
    5501111        # RIFF chunks are padded to an even number of bytes
    5511112        my $len2 = $len + ($len & 0x01);
    552         if ($tagInfo and $$tagInfo{SubDirectory}) {
     1113        if ($$tagTablePtr{$tag} or ($verbose and $tag !~ /^(data|idx1|LIST_movi)$/)) {
    5531114            $raf->Read($buff, $len2) == $len2 or $err=1, last;
    554             my %dirInfo = (
    555                 DataPt => \$buff,
    556                 DataPos => $pos,
    557                 DirStart => 0,
    558                 DirLen => $len,
     1115            $exifTool->HandleTag($tagTablePtr, $tag, $buff,
     1116                DataPt  => \$buff,
     1117                DataPos => 0,   # (relative to Base)
     1118                Start   => 0,
     1119                Size    => $len2,
     1120                Base    => $pos,
    5591121            );
    560             my $tagTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
    561             $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
    5621122        } else {
    5631123            $raf->Seek($len2, 1) or $err=1, last;
     
    5891149=head1 AUTHOR
    5901150
    591 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1151Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    5921152
    5931153This library is free software; you can redistribute it and/or modify it
     
    6081168=item L<http://msdn.microsoft.com/archive/en-us/directx9_c/directx/htm/avirifffilereference.asp>
    6091169
     1170=item L<http://wiki.multimedia.cx/index.php?title=TwoCC>
     1171
    6101172=back
    6111173
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Real.pm

    r16842 r24107  
    1717use Image::ExifTool::Canon;
    1818
    19 $VERSION = '1.01';
     19$VERSION = '1.04';
    2020
    2121sub ProcessRealMeta($$$);
     
    8989    GROUPS => { 1 => 'Real-PROP', 2 => 'Video' },
    9090    PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData,
     91    VARS => { ID_LABEL => 'Sequence' },
    9192    FORMAT => 'int32u',
    92     0  => 'MaxBitRate',
    93     1  => 'AvgBitRate',
     93    0  => { Name => 'MaxBitrate', PrintConv => 'ConvertBitrate($val)' },
     94    1  => { Name => 'AvgBitrate', PrintConv => 'ConvertBitrate($val)' },
    9495    2  => 'MaxPacketSize',
    9596    3  => 'AvgPacketSize',
    9697    4  => 'NumPackets',
    97     5 => { Name => 'Duration',      ValueConv => '$val / 1000' },
    98     6 => { Name => 'Preroll',       ValueConv => '$val / 1000' },
     98    5 => { Name => 'Duration',      ValueConv => '$val / 1000',  PrintConv => 'ConvertDuration($val)' },
     99    6 => { Name => 'Preroll',       ValueConv => '$val / 1000',  PrintConv => 'ConvertDuration($val)' },
    99100    7 => { Name => 'IndexOffset',   Unknown => 1 },
    100101    8 => { Name => 'DataOffset',    Unknown => 1 },
     
    115116    GROUPS => { 1 => 'Real-MDPR', 2 => 'Video' },
    116117    PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData,
     118    VARS => { ID_LABEL => 'Sequence' },
    117119    FORMAT => 'int32u',
    118120    PRIORITY => 0,  # first stream takes priority
    119121    0  => { Name => 'StreamNumber',  Format => 'int16u' },
    120     1  => { Name => 'StreamMaxBitRate' },
    121     2  => { Name => 'StreamAvgBitRate' },
     122    1  => { Name => 'StreamMaxBitrate', PrintConv => 'ConvertBitrate($val)' },
     123    2  => { Name => 'StreamAvgBitrate', PrintConv => 'ConvertBitrate($val)' },
    122124    3  => { Name => 'StreamMaxPacketSize' },
    123125    4  => { Name => 'StreamAvgPacketSize' },
    124126    5  => { Name => 'StreamStartTime' },
    125     6  => { Name => 'StreamPreroll',       ValueConv => '$val / 1000' },
    126     7  => { Name => 'StreamDuration',      FValueConv => '$val / 1000' },
     127    6  => { Name => 'StreamPreroll', ValueConv => '$val / 1000',  PrintConv => 'ConvertDuration($val)' },
     128    7  => { Name => 'StreamDuration',ValueConv => '$val / 1000',  PrintConv => 'ConvertDuration($val)' },
    127129    8  => { Name => 'StreamNameLen', Format => 'int8u', Unknown => 1 },
    128130    9  => { Name => 'StreamName',    Format => 'string[$val{8}]' },
     
    235237    GROUPS => { 1 => 'Real-CONT', 2 => 'Video' },
    236238    PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData,
     239    VARS => { ID_LABEL => 'Sequence' },
    237240    FORMAT => 'int16u',
    238241    0 => { Name => 'TitleLen',      Unknown => 1 },
     
    268271    GROUPS => { 1 => 'Real-RA3', 2 => 'Audio' },
    269272    PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData,
     273    VARS => { ID_LABEL => 'Sequence' },
    270274    FORMAT => 'int8u',
    271275    0  => { Name => 'Channels',       Format => 'int16u' },
     
    286290    GROUPS => { 1 => 'Real-RA4', 2 => 'Audio' },
    287291    PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData,
     292    VARS => { ID_LABEL => 'Sequence' },
    288293    FORMAT => 'int16u',
    289294    0  => { Name => 'FourCC1',        Format => 'undef[4]', Unknown => 1 },
     
    323328    GROUPS => { 1 => 'Real-RA5', 2 => 'Audio' },
    324329    PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData,
     330    VARS => { ID_LABEL => 'Sequence' },
    325331    FORMAT => 'int16u',
    326332    0  => { Name => 'FourCC1',        Format => 'undef[4]', Unknown => 1 },
     
    529535        $type = ($ext and $ext eq 'RPM') ? 'RPM' : 'RAM';
    530536        require Image::ExifTool::PostScript;
    531         my $oldSep = Image::ExifTool::PostScript::SetInputRecordSeparator($raf);
     537        local $/ = Image::ExifTool::PostScript::GetInputRecordSeparator($raf) || "\n";
    532538        $raf->Seek(0,0);
    533539        while ($raf->ReadLine($buff)) {
     
    545551            $exifTool->HandleTag($tagTablePtr, $tag, $buff);
    546552        }
    547         $/ = $oldSep if $oldSep;
    548553        return 1;
    549554    }
     
    646651    if (@mimeTypes == 1 and length $mimeTypes[0]) {
    647652        $exifTool->{VALUE}->{MIMEType} = $mimeTypes[0];
    648         $verbose and $exifTool->VPrint(0, "  MIMEType = $mimeTypes[0]\n");
     653        $exifTool->VPrint(0, "  MIMEType = $mimeTypes[0]\n");
    649654    }
    650655#
     
    708713=head1 AUTHOR
    709714
    710 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     715Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    711716
    712717This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Ricoh.pm

    r16842 r24107  
    1717use Image::ExifTool::Exif;
    1818
    19 $VERSION = '1.05';
     19$VERSION = '1.17';
    2020
    2121sub ProcessRicohText($$$);
    2222sub ProcessRicohRMETA($$$);
     23
     24# lens types for Ricoh GXR
     25my %ricohLensIDs = (
     26    Notes => q{
     27        Lens units available for the GXR, used by the Ricoh Composite LensID tag.  Note
     28        that unlike lenses for all other makes of cameras, the focal lengths in these
     29        model names have already been scaled to include the 35mm crop factor.
     30    },
     31    # (the exact lens model names used by Ricoh, except for a change in case)
     32    'RL1' => 'GR Lens A12 50mm F2.5 Macro',
     33    'RL2' => 'Ricoh Lens S10 24-70mm F2.5-4.4 VC',
     34    'RL3' => 'Ricoh Lens P10 28-300mm F3.5-5.6 VC',
     35    'RL5' => 'GR Lens A12 28mm F2.5',
     36);
    2337
    2438%Image::ExifTool::Ricoh::Main = (
     
    2741    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
    2842    WRITABLE => 1,
    29     NOTES => 'These tags are used by Ricoh Caplio camera models.',
    30     0x0001 => { Name => 'MakerNoteType',    Writable => 'string' },
    31     0x0002 => { Name => 'MakerNoteVersion', Writable => 'string' },
     43    0x0001 => { Name => 'MakerNoteType',   Writable => 'string' },
     44    0x0002 => { #PH
     45        Name => 'FirmwareVersion',
     46        Writable => 'string',
     47        # ie. "Rev0113" is firmware version 1.13
     48        PrintConv => '$val=~/^Rev(\d+)$/ ? sprintf("%.2f",$1/100) : $val',
     49        PrintConvInv => '$val=~/^(\d+)\.(\d+)$/ ? sprintf("Rev%.2d%.2d",$1,$2) : $val',
     50    },
     51    0x0005 => [ #PH
     52        {
     53            Condition => '$$valPt =~ /^[-\w ]+$/',
     54            Name => 'SerialNumber', # (verified for GXR)
     55            Writable => 'undef',
     56            Count => 16,
     57            Notes => q{
     58                the serial number stamped on the camera begins with 2 model-specific letters
     59                followed by the last 8 digits of this value.  For the GXR, this is the
     60                serial number of the lens unit
     61            },
     62            PrintConv => '$val=~s/^(.*)(.{8})$/($1)$2/; $val',
     63            PrintConvInv => '$val=~tr/()//d; $val',
     64        },{
     65            Name => 'InternalSerialNumber',
     66            Writable => 'undef',
     67            Count => 16,
     68            PrintConv => 'unpack("H*", $val)',
     69            PrintConvInv => 'pack("H*", $val)',
     70        },
     71    ],
    3272    0x0e00 => {
    3373        Name => 'PrintIM',
    3474        Writable => 0,
    3575        Description => 'Print Image Matching',
    36         SubDirectory => {
    37             TagTable => 'Image::ExifTool::PrintIM::Main',
    38         },
     76        SubDirectory => { TagTable => 'Image::ExifTool::PrintIM::Main' },
    3977    },
    4078    0x1001 => {
    4179        Name => 'ImageInfo',
    42         SubDirectory => {
    43             TagTable => 'Image::ExifTool::Ricoh::ImageInfo',
    44         },
     80        SubDirectory => { TagTable => 'Image::ExifTool::Ricoh::ImageInfo' },
    4581    },
    4682    0x1003 => {
     
    5692        {
    5793            Name => 'RicohSubdir',
    58             Condition => '$self->{CameraModel} !~ /^Caplio RR1\b/',
     94            Condition => '$self->{Model} !~ /^Caplio RR1\b/',
    5995            SubDirectory => {
    6096                Validate => '$val =~ /^\[Ricoh Camera Info\]/',
     
    119155        DataTag => 'PreviewImage',
    120156        Protected => 2,
     157        # prevent preview from being written to raw images
     158        RawConvInv => q{
     159            return $val if $$self{FILE_TYPE} eq "JPEG";
     160            warn "Can't write PreviewImage to $$self{TIFF_TYPE} file\n";
     161            return undef;
     162        },
    121163    },
    122164    30 => {
     
    126168        DataTag => 'PreviewImage',
    127169        Protected => 2,
     170        RawConvInv => q{
     171            return $val if $$self{FILE_TYPE} eq "JPEG";
     172            warn "\n"; # suppress warning (already issued for PreviewImageStart)
     173            return undef;
     174        },
    128175    },
    129176    32 => {
     
    155202            3 => 'Tungsten',
    156203            4 => 'Fluorescent',
    157             # 5 (One Pushes, flake setting?)
    158             # 7 (details setting?)
     204            5 => 'Manual', #PH (GXR)
     205            7 => 'Detail',
     206            9 => 'Multi-pattern Auto', #PH (GXR)
    159207        },
    160208    },
     
    169217            7 => 800,
    170218            8 => 1600,
     219            9 => 'Auto', #PH (? CX3)
    171220        },
    172221    },
     
    177226            1 => 'Normal',
    178227            2 => 'Low',
    179             3 => 'None (B&W)',
    180         },
    181     },
    182 );
    183 
     228            3 => 'B&W',
     229            6 => 'Toning Effect', #PH (GXR Sepia,Red,Green,Blue,Purple)
     230            9 => 'Vivid', #PH (GXR)
     231            10 => 'Natural', #PH (GXR)
     232        },
     233    },
     234);
     235
     236# Ricoh subdirectory tags (ref PH)
    184237# NOTE: this subdir is not currently writable because the offsets would require
    185238# special code to handle the funny start location and base offset
     
    188241    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
    189242    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
    190     0x0004 => { Name => 'RicohDateTime1', Groups => { 2 => 'Time' } }, #PH
    191     0x0005 => { Name => 'RicohDateTime2', Groups => { 2 => 'Time' } }, #PH
    192     # 0x000E ProductionNumber? (ref 2)
     243    # the significance of the following 2 dates is not known.  They are usually
     244    # within a month of each other, but I have seen differences of nearly a year.
     245    # Sometimes the first is more recent, and sometimes the second.
     246    0x0004 => { # (NC)
     247        Name => 'ManufactureDate1',
     248        Groups => { 2 => 'Time' },
     249        Writable => 'string',
     250        Count => 20,
     251    },
     252    0x0005 => { # (NC)
     253        Name => 'ManufactureDate2',
     254        Groups => { 2 => 'Time' },
     255        Writable => 'string',
     256        Count => 20,
     257    },
     258    # 0x000c - int32u[2] 1st number is a counter (file number? shutter count?) - PH
     259    # 0x0014 - int8u[338] - could contain some data related to face detection? - PH
     260    # 0x0015 - int8u[2]: related to noise reduction?
     261    0x001a => { #PH
     262        Name => 'FaceInfo',
     263        SubDirectory => { TagTable => 'Image::ExifTool::Ricoh::FaceInfo' },
     264    },
     265    0x0029 => {
     266        Name => 'FirmwareInfo',
     267        SubDirectory => { TagTable => 'Image::ExifTool::Ricoh::FirmwareInfo' },
     268    },
     269    0x002a => {
     270        Name => 'NoiseReduction',
     271        # this is the applied value if NR is set to "Auto"
     272        Writable => 'int32u',
     273        PrintConv => {
     274            0 => 'Off',
     275            1 => 'Weak',
     276            2 => 'Strong',
     277            3 => 'Max',
     278        },
     279    },
     280    0x002c => { # (GXR)
     281        Name => 'SerialInfo',
     282        SubDirectory => { TagTable => 'Image::ExifTool::Ricoh::SerialInfo' },
     283    }
     284    # 0x000E ProductionNumber? (ref 2) [no. zero for most models - PH]
     285);
     286
     287# face detection information (ref PH, CX4)
     288%Image::ExifTool::Ricoh::FaceInfo = (
     289    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     290    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     291    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     292    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     293    WRITABLE => 1,
     294    FIRST_ENTRY => 0,
     295    DATAMEMBER => [ 181 ],
     296    0xb5 => { # (should be int16u at 0xb4?)
     297        Name => 'FacesDetected',
     298        DataMember => 'FacesDetected',
     299        RawConv => '$$self{FacesDetected} = $val',
     300    },
     301    0xb6 => {
     302        Name => 'FaceDetectFrameSize',
     303        Format => 'int16u[2]',
     304    },
     305    0xbc => {
     306        Name => 'Face1Position',
     307        Condition => '$$self{FacesDetected} >= 1',
     308        Format => 'int16u[4]',
     309        Notes => q{
     310            left, top, width and height of detected face in coordinates of
     311            FaceDetectFrameSize with increasing Y downwards
     312        },
     313    },
     314    0xc8 => {
     315        Name => 'Face2Position',
     316        Condition => '$$self{FacesDetected} >= 2',
     317        Format => 'int16u[4]',
     318    },
     319    0xd4 => {
     320        Name => 'Face3Position',
     321        Condition => '$$self{FacesDetected} >= 3',
     322        Format => 'int16u[4]',
     323    },
     324    0xe0 => {
     325        Name => 'Face4Position',
     326        Condition => '$$self{FacesDetected} >= 4',
     327        Format => 'int16u[4]',
     328    },
     329    0xec => {
     330        Name => 'Face5Position',
     331        Condition => '$$self{FacesDetected} >= 5',
     332        Format => 'int16u[4]',
     333    },
     334    0xf8 => {
     335        Name => 'Face6Position',
     336        Condition => '$$self{FacesDetected} >= 6',
     337        Format => 'int16u[4]',
     338    },
     339    0x104 => {
     340        Name => 'Face7Position',
     341        Condition => '$$self{FacesDetected} >= 7',
     342        Format => 'int16u[4]',
     343    },
     344    0x110 => {
     345        Name => 'Face8Position',
     346        Condition => '$$self{FacesDetected} >= 8',
     347        Format => 'int16u[4]',
     348    },
     349);
     350
     351# firmware version information (ref PH)
     352%Image::ExifTool::Ricoh::FirmwareInfo = (
     353    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     354    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     355    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     356    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     357    WRITABLE => 1,
     358    0x00 => {
     359        Name => 'FirmwareRevision',
     360        Format => 'string[12]',
     361    },
     362    0x0c => {
     363        Name => 'FirmwareRevision2',
     364        Format => 'string[12]',
     365    },
     366);
     367
     368# serial/version number information written by GXR (ref PH)
     369%Image::ExifTool::Ricoh::SerialInfo = (
     370    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     371    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     372    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     373    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     374    WRITABLE => 1,
     375    NOTES => 'This information is found in images from the GXR.',
     376    0 => {
     377        Name => 'BodyFirmware', #(NC)
     378        Format => 'string[16]',
     379        # observed: "RS1 :V00560000" --> FirmwareVersion "Rev0056"
     380        #           "RS1 :V01020200" --> FirmwareVersion "Rev0102"
     381    },
     382    16 => {
     383        Name => 'BodySerialNumber',
     384        Format => 'string[16]',
     385        # observed: "SID:00100056" --> "WD00100056" on plate
     386    },
     387    32 => {
     388        Name => 'LensFirmware', #(NC)
     389        Format => 'string[16]',
     390        # observed: "RL1 :V00560000", "RL1 :V01020200" - A12 50mm F2.5 Macro
     391        #           "RL2 :V00560000", "RL2 :V01020300" - S10 24-70mm F2.5-4.4 VC
     392        # --> used in a Composite tag to determine LensType
     393    },
     394    48 => {
     395        Name => 'LensSerialNumber',
     396        Format => 'string[16]',
     397        # observed: (S10) "LID:00010024" --> "WF00010024" on plate
     398        #           (A12) "LID:00010054" --> "WE00010029" on plate??
     399    },
    193400);
    194401
     
    198405    PROCESS_PROC => \&ProcessRicohText,
    199406    NOTES => q{
    200         Ricoh RDC models such as the RDC-i700, RDC-5000, RDC-6000, RDC-7 and
    201         RDC-4300 use a text-based format for their maker notes instead of the IFD
    202         format used by the Caplio models.  Below is a list of known tags in this
    203         information.
    204     },
    205     Rev => 'Revision',
    206     Rv => 'Revision',
     407        Some Ricoh DC and RDC models use a text-based format for their maker notes
     408        instead of the IFD format used by the Caplio models.  Below is a list of known
     409        tags in this information.
     410    },
     411    Rev => {
     412        Name => 'FirmwareVersion',
     413        PrintConv => '$val=~/^\d+$/ ? sprintf("%.2f",$val/100) : $val',
     414        PrintConvInv => '$val=~/^(\d+)\.(\d+)$/ ? sprintf("%.2d%.2d",$1,$2) : $val',
     415    },
     416    Rv => {
     417        Name => 'FirmwareVersion',
     418        PrintConv => '$val=~/^\d+$/ ? sprintf("%.2f",$val/100) : $val',
     419        PrintConvInv => '$val=~/^(\d+)\.(\d+)$/ ? sprintf("%.2d%.2d",$1,$2) : $val',
     420    },
    207421    Rg => 'RedGain',
    208422    Gg => 'GreenGain',
     
    259473);
    260474
     475# information stored in Ricoh AVI images (ref PH)
     476%Image::ExifTool::Ricoh::AVI = (
     477    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
     478    ucmt => {
     479        Name => 'Comment',
     480        # Ricoh writes a "Unicode" header even when text is ASCII (spaces anyway)
     481        ValueConv => '$_=$val; s/^(Unicode\0|ASCII\0\0\0)//; tr/\0//d; s/\s+$//; $_',
     482    },
     483    mnrt => {
     484        Name => 'MakerNoteRicoh',
     485        SubDirectory => {
     486            TagTable => 'Image::ExifTool::Ricoh::Main',
     487            Start => '$valuePtr + 8',
     488            ByteOrder => 'BigEndian',
     489            Base => '8',
     490        },
     491    },
     492    rdc2 => {
     493        Name => 'RicohRDC2',
     494        Unknown => 1,
     495        ValueConv => 'unpack("H*",$val)',
     496        # have seen values like 0a000444 and 00000000 - PH
     497    },
     498    thum => {
     499        Name => 'ThumbnailImage',
     500        Binary => 1,
     501    },
     502);
     503
     504# Ricoh composite tags
     505%Image::ExifTool::Ricoh::Composite = (
     506    GROUPS => { 2 => 'Camera' },
     507    LensID => {
     508        SeparateTable => 'Ricoh LensID',
     509        Require => 'Ricoh:LensFirmware',
     510        RawConv => '$val[0] ? $val[0] : undef',
     511        ValueConv => '$val=~s/\s*:.*//; $val',
     512        PrintConv => \%ricohLensIDs,
     513    },
     514);
     515
     516# add our composite tags
     517Image::ExifTool::AddCompositeTags('Image::ExifTool::Ricoh');
     518
     519
    261520#------------------------------------------------------------------------------
    262521# Process Ricoh text-based maker notes
     
    281540        return 0;
    282541    }
    283     my $pos = 0;
    284542    while ($data =~ m/([A-Z][a-z]{1,2})([0-9A-F]+);/sg) {
    285543        my $tag = $1;
     
    419677=head1 AUTHOR
    420678
    421 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     679Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    422680
    423681This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sanyo.pm

    r16842 r24107  
    1515use Image::ExifTool::Exif;
    1616
    17 $VERSION = '1.10';
     17$VERSION = '1.14';
    1818
    1919my %offOn = (
     
    3636        Writable => 'undef',
    3737        WriteCheck => '$self->CheckImage(\$val)',
    38         ValueConv => '$self->ValidateImage(\$val,$tag)',
    39         ValueConvInv => '$val',
     38        RawConv => '$self->ValidateImage(\$val,$tag)',
    4039    },
    4140    0x0200 => {
     
    5756            0x0006 => 'Normal/Very High',
    5857            0x0007 => 'Normal/Super High',
     58            # have seen 0x11 with HD2000 in '8M-H JPEG' mode - PH
    5959            0x0100 => 'Fine/Very Low',
    6060            0x0101 => 'Fine/Low',
     
    122122        PrintConv => \%offOn,
    123123    },
     124    # 0x0215 - Flash?
    124125    0x0216 => {
    125126        Name => 'VoiceMemo',
     
    176177        },
    177178    },
    178     0x0223 => {
    179         Name => 'ManualFocusDistance',
    180         Writable => 'rational64u',
    181     },
     179    0x0223 => [
     180        {
     181            Name => 'ManualFocusDistance',
     182            Condition => '$format eq "rational64u"',
     183            Writable => 'rational64u',
     184        }, { #PH
     185            Name => 'FaceInfo',
     186            SubDirectory => { TagTable => 'Image::ExifTool::Sanyo::FaceInfo' },
     187        },
     188    ],
    182189    0x0224 => {
    183190        Name => 'SequenceShotInterval',
    184191        Writable => 'int16u',
    185192        PrintConv => {
    186             0 => '5 frames/sec',
    187             1 => '10 frames/sec',
    188             2 => '15 frames/sec',
    189             3 => '20 frames/sec',
     193            0 => '5 frames/s',
     194            1 => '10 frames/s',
     195            2 => '15 frames/s',
     196            3 => '20 frames/s',
    190197        },
    191198    },
     
    215222);
    216223
     224# face detection information (ref PH)
     225%Image::ExifTool::Sanyo::FaceInfo = (
     226    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     227    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     228    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     229    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     230    WRITABLE => 1,
     231    FORMAT => 'int32u',
     232    FIRST_ENTRY => 0,
     233    0 => 'FacesDetected',
     234    4 => {
     235        Name => 'FacePosition',
     236        Format => 'int32u[4]',
     237        Notes => q{
     238            left, top, right and bottom coordinates of detected face in an unrotated
     239            640-pixel-wide image, with increasing Y downwards
     240        },
     241    },
     242);
     243
    217244# tags in Sanyo MOV videos (PH - observations from an E6 sample)
    218 # (note: very similar to information in Nikon/Pentax videos)
     245# (similar information in Kodak,Minolta,Nikon,Olympus,Pentax and Sanyo videos)
    219246%Image::ExifTool::Sanyo::MOV = (
    220247    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    221248    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    222     NOTES => q{
    223         This information is found in Sanyo MOV video images, and is very similar to
    224         information found in Pentax MOV and Nikon QT videos.
    225     },
     249    NOTES => 'This information is found in Sanyo MOV videos.',
    226250    0x00 => {
    227251        Name => 'Make',
    228         Format => 'string[5]',
    229         PrintConv => 'ucfirst(lc($val))',
     252        Format => 'string[24]',
    230253    },
    231254    0x18 => {
     
    234257        Format => 'string[8]',
    235258    },
     259    # (01 00 at offset 0x20)
    236260    0x26 => {
    237261        Name => 'ExposureTime',
     
    243267        Name => 'FNumber',
    244268        Format => 'int32u',
    245         ValueConv => '$val * 0.1',
     269        ValueConv => '$val / 10',
    246270        PrintConv => 'sprintf("%.1f",$val)',
    247271    },
     
    249273        Name => 'ExposureCompensation',
    250274        Format => 'int32s',
    251         ValueConv => '$val * 0.1',
    252         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     275        ValueConv => '$val / 10',
     276        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
    253277    },
    254278    0x44 => {
     
    266290    0x48 => {
    267291        Name => 'FocalLength',
    268         Writable => 'int32u',
    269         ValueConv => '$val * 0.1',
    270         PrintConv => 'sprintf("%.1fmm",$val)',
     292        Format => 'int32u',
     293        ValueConv => '$val / 10',
     294        PrintConv => 'sprintf("%.1f mm",$val)',
    271295    },
    272296);
    273297
    274298# tags in Sanyo MP4 videos (PH - from C4, C5 and HD1A samples)
     299# --> very similar to Samsung MP4 information
    275300# (there is still a lot more information here that could be decoded!)
    276301%Image::ExifTool::Sanyo::MP4 = (
    277302    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    278303    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
    279     NOTES => 'This information is found in Sanyo MP4 video images.',
     304    NOTES => 'This information is found in Sanyo MP4 videos.',
    280305    0x00 => {
    281306        Name => 'Make',
     
    288313        Format => 'string[8]',
    289314    },
     315    # (01 00 at offset 0x28)
    290316    # (0x2e has values 0x31, 0x33 and 0x3c in my samples, but
    291317    # some of the shutter speeds should be around 1/500 or so)
    292318    0x32 => {
    293319        Name => 'FNumber',
    294         Format => 'int32u',
    295         ValueConv => '$val / 10',
     320        Format => 'rational64u',
    296321        PrintConv => 'sprintf("%.1f",$val)',
     322    },
     323    0x3a => { # (NC)
     324        Name => 'ExposureCompensation',
     325        Format => 'rational64s',
     326        PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
    297327    },
    298328    0x6a => {
     
    300330        Format => 'int32u',
    301331    },
    302 # (these tags are shifted by +1 byte for the C4 compared to the HD1A, so we can't use them)
    303 #     0xfe => {
    304 #         Name => 'ThumbnailLength',
    305 #         Format => 'int32u',
    306 #     },
    307 #     0x102 => {
    308 #         Name => 'ThumbnailOffset',
    309 #         IsOffset => 1,
    310 #         Format => 'int32u',
    311 #         RawConv => '$val + 0xf2',
    312 #     },
    313     # so instead, look for the JPEG header using brute force...
    314     0x800 => {
    315         Name => 'ThumbnailImage',
    316         Notes => 'position varies',
    317         Format => 'undef[$size - 0x800]',
    318         ValueConv => '$val=~s/.*(?=\xff\xd8\xff\xc4)//; $self->ValidateImage(\$val,$tag)',
     332    0xd1 => {
     333        Name => 'Software',
     334        Notes => 'these tags are shifted up by 1 byte for some models like the HD1A',
     335        Format => 'undef[32]',
     336        RawConv => q{
     337            $val =~ /^SANYO/ or return undef;
     338            $val =~ tr/\0//d;
     339            $$self{SanyoSledder0xd1} = 1;
     340            return $val;
     341        },
     342    },
     343    0xd2 => {
     344        Name => 'Software',
     345        Format => 'undef[32]',
     346        RawConv => q{
     347            $val =~ /^SANYO/ or return undef;
     348            $val =~ tr/\0//d;
     349            $$self{SanyoSledder0xd2} = 1;
     350            return $val;
     351        },
     352    },
     353    0xfd => {
     354        Name => 'ThumbnailLength',
     355        Condition => '$$self{SanyoSledder0xd1}',
     356        Format => 'int32u',
     357    },
     358    0xfe => {
     359        Name => 'ThumbnailLength',
     360        Condition => '$$self{SanyoSledder0xd2}',
     361        Format => 'int32u',
     362    },
     363    0x101 => {
     364        Name => 'ThumbnailOffset',
     365        Condition => '$$self{SanyoSledder0xd1}',
     366        IsOffset => 1,
     367        Format => 'int32u',
     368        RawConv => '$val + 0xf1',
     369    },
     370    0x102 => {
     371        Name => 'ThumbnailOffset',
     372        Condition => '$$self{SanyoSledder0xd2}',
     373        IsOffset => 1,
     374        Format => 'int32u',
     375        RawConv => '$val + 0xf2',
    319376    },
    320377);
     
    357414=head1 AUTHOR
    358415
    359 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     416Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    360417
    361418This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Shift.pl

    r16842 r24107  
    1515#------------------------------------------------------------------------------
    1616# apply shift to value in new value hash
    17 # Inputs: 0) shift type, 1) shift string, 2) value to shift, 3) new value hash ref
     17# Inputs: 0) shift type, 1) shift string, 2) raw date/time value, 3) new value hash ref
    1818# Returns: error string or undef on success and updates value in new value hash
    1919sub ApplyShift($$$;$)
    2020{
    21     my ($func, $shift, $val, $newValueHash) = @_;
     21    my ($func, $shift, $val, $nvHash) = @_;
    2222
    2323    # get shift direction from first character in shift string
     
    2525    my $pre = $1;
    2626    my $dir = ($pre eq '+') ? 1 : -1;
    27     my $tagInfo = $$newValueHash{TagInfo};
     27    my $tagInfo = $$nvHash{TagInfo};
    2828    my $tag = $$tagInfo{Name};
    29     my $self = $$newValueHash{Self};    # (used in eval)
     29    my $self = $$nvHash{Self};    # (used in eval)
    3030    my $shiftOffset;
    31     if ($$newValueHash{ShiftOffset}) {
    32         $shiftOffset = $$newValueHash{ShiftOffset};
     31    if ($$nvHash{ShiftOffset}) {
     32        $shiftOffset = $$nvHash{ShiftOffset};
    3333    } else {
    34         $shiftOffset = $$newValueHash{ShiftOffset} = { };
     34        $shiftOffset = $$nvHash{ShiftOffset} = { };
    3535    }
    3636
     
    6363    }
    6464    # update value in new value hash
    65     $newValueHash->{Value} = [ $val ];
     65    $nvHash->{Value} = [ $val ];
    6666    return undef;   # success
    6767}
     
    105105
    106106#------------------------------------------------------------------------------
    107 # split times into corresponding components: YYYY MM DD hh mm ss tzh tzm
     107# split times into corresponding components: YYYY mm dd HH MM SS tzh tzm
    108108# Inputs: 0) date/time or shift string 1) reference to list for returned components
    109109#         2) optional reference to list of time components (if shift string)
     
    152152            # this is a time (can't come after timezone)
    153153            (defined $v[3] or defined $v[6] or @vals > 3) and $err = 1, last;
    154             not $time and @vals != 3 and $err = 1, last;
     154            not $time and @vals != 3 and @vals != 2 and $err = 1, last;
    155155            $v[3] = shift(@vals);   # take hour first if only one specified
    156156            $v[4] = shift(@vals) || 0;
     
    175175#         2) shift direction, 3) reference to output list of shifted components
    176176#         4) number of decimal points in seconds
     177#         5) reference to return time difference due to rounding
    177178# Returns: error string or undef on success
    178 sub ShiftComponents($$$$$)
     179sub ShiftComponents($$$$$;$)
    179180{
    180     my ($time, $shift, $dir, $toTime, $dec) = @_;
     181    my ($time, $shift, $dir, $toTime, $dec, $rndPt) = @_;
    181182    # min/max for Y, M, D, h, m, s
    182183    my @min = (    0, 1, 1, 0, 0, 0);
     
    203204    if (defined $sec and $sec != int($sec)) {
    204205        my $mult = 10 ** $dec;
    205         $$toTime[5] = int($sec * $mult + 0.5 * ($sec <=> 0)) / $mult;
     206        my $rndSec = int($sec * $mult + 0.5 * ($sec <=> 0)) / $mult;
     207        $rndPt and $$rndPt = $sec - $rndSec;
     208        $$toTime[5] = $rndSec;
    206209    }
    207210#
     
    303306            $time[6] = $time[7] = 0 if $val =~ s/Z$/\+00:00/;
    304307        }
    305         my $err = ShiftComponents(\@time, \@shift, $dir, \@toTime, $dec);
     308        my $rndDiff;
     309        my $err = ShiftComponents(\@time, \@shift, $dir, \@toTime, $dec, \$rndDiff);
    306310        $err and return $err;
    307311#
     
    324328                    # handle fractional seconds separately
    325329                    $diff = $tm2[0] - int($tm2[0]) - ($tm1[0] - int($tm1[0]));
     330                    $diff += $rndDiff if defined $rndDiff;  # un-do rounding
    326331                    $tm1[0] = int($tm1[0]);
    327332                    $tm2[0] = int($tm2[0]);
     
    376381            $tm += $$shiftOffset{$mode};    # apply the shift
    377382            $tm < 0 and return 'Shift results in negative time';
    378             # strip off fractional seconds after rounding to desired precision
    379             # (only round if the result isn't integral)
     383            # save fractional seconds in shifted time
    380384            $frac = $tm - int($tm);
    381385            if ($frac) {
    382                 # round off to required number of decimal points
    383                 my $tmf = $tm + 0.5 * 10 ** (-$dec);
    384                 $tm = int($tmf);
    385                 $frac = $tm - $tmf;
     386                $tm = int($tm);
     387                # must account for any rounding that could occur
     388                $frac + 0.5 * 10 ** (-$dec) >= 1 and ++$tm, $frac = 0;
    386389            }
    387390            @tm = gmtime($tm);
     
    491494    '2:0'       - shift 2 hours (time, date/time), or 2 months (date)
    492495    '5:0:0'     - shift 5 hours (time, date/time), or 5 years (date)
    493     '0:0:1'     - shift 1 sec (time, date/time), or 1 day (date)
     496    '0:0:1'     - shift 1 s (time, date/time), or 1 day (date)
    494497
    495498If two arguments are given, the date shift is first, followed by the time
     
    561564philosophy).
    562565
     566=head1 BUGS
     567
     568This feature uses the standard time library functions, which typically are
     569limited to dates in the range 1970 to 2038.
     570
    563571=head1 AUTHOR
    564572
    565 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     573Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    566574
    567575This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Shortcuts.pm

    r16842 r24107  
    1616use vars qw($VERSION);
    1717
    18 $VERSION = '1.16';
     18$VERSION = '1.41';
    1919
    2020# this is a special table used to define command-line shortcuts
     
    5656        'ImageSize',
    5757        'Quality',
    58         'FlashOn',
     58        'Flash',
    5959        'FlashType',
    6060        'ConditionalFEC',
     
    6767        'Saturation',
    6868        'ColorTone',
    69         'FileSize',
    70         'FileNumber',
    71         'DriveMode',
    72         'OwnerName',
    73         'SerialNumber',
    74     ],
    75     # courtesy of Christian Koller
    76     Canon20D => [
    77         'FileName',
    78         'Model',
    79         'DateTimeOriginal',
    80         'ShootingMode',
    81         'ShutterSpeedValue', #changed for 20D
    82         'ApertureValue', #changed for 20D
    83         'MeteringMode',
    84         'ExposureCompensation',
    85         'ISO',
    86         'Lens',
    87         'FocalLength',
    88         #'ImageSize', #wrong in CR2
    89         'ExifImageWidth', #instead
    90         'ExifImageLength', #instead
    91         'Quality',
    92         'FlashOn',
    93         'FlashType',
    94         'ConditionalFEC',
    95         'RedEyeReduction',
    96         'ShutterCurtainHack',
    97         'WhiteBalance',
    98         'FocusMode',
    99         'Contrast',
    100         'Sharpness',
    101         'Saturation',
    102         'ColorTone',
    103         'ColorSpace', # new
    104         'LongExposureNoiseReduction', #new
     69        'ColorSpace',
     70        'LongExposureNoiseReduction',
    10571        'FileSize',
    10672        'FileNumber',
     
    147113        'MakerNoteCasio2',
    148114        'MakerNoteFujiFilm',
     115        'MakerNoteGE',
     116        'MakerNoteGE2',
    149117        'MakerNoteHP',
    150118        'MakerNoteHP2',
    151119        'MakerNoteHP4',
    152120        'MakerNoteHP6',
     121        'MakerNoteISL',
    153122        'MakerNoteJVC',
    154123        'MakerNoteJVCText',
     
    162131        'MakerNoteKodak6b',
    163132        'MakerNoteKodak7',
    164         'MakerNoteKodakIFD',
     133        'MakerNoteKodak8a',
     134        'MakerNoteKodak8b',
     135        'MakerNoteKodak9',
     136        'MakerNoteKodak10',
    165137        'MakerNoteKodakUnknown',
    166138        'MakerNoteKyocera',
     
    174146        'MakerNoteOlympus2',
    175147        'MakerNoteLeica',
     148        'MakerNoteLeica2',
     149        'MakerNoteLeica3',
     150        'MakerNoteLeica4',
     151        'MakerNoteLeica5',
     152        'MakerNoteLeica6',
    176153        'MakerNotePanasonic',
    177154        'MakerNotePanasonic2',
     
    180157        'MakerNotePentax3',
    181158        'MakerNotePentax4',
     159        'MakerNotePentax5',
     160        'MakerNotePhaseOne',
     161        'MakerNoteReconyx',
    182162        'MakerNoteRicoh',
    183163        'MakerNoteRicohText',
     164        'MakerNoteSamsung1a',
     165        'MakerNoteSamsung1b',
     166        'MakerNoteSamsung2',
    184167        'MakerNoteSanyo',
    185168        'MakerNoteSanyoC4',
     
    187170        'MakerNoteSigma',
    188171        'MakerNoteSony',
     172        'MakerNoteSony2',
     173        'MakerNoteSony3',
     174        'MakerNoteSony4',
     175        'MakerNoteSonyEricsson',
    189176        'MakerNoteSonySRF',
    190         'MakerNoteSonySR2',
     177        'MakerNoteUnknownText',
    191178        'MakerNoteUnknown',
    192179    ],
     180    # "unsafe" tags we normally don't copy in JPEG images, defined
     181    # as a shortcut to use when rebuilding JPEG EXIF from scratch
     182    Unsafe => [
     183        'IFD0:YCbCrPositioning',
     184        'IFD0:YCbCrCoefficients',
     185        'IFD0:TransferFunction',
     186        'ExifIFD:ComponentsConfiguration',
     187        'ExifIFD:CompressedBitsPerPixel',
     188        'InteropIFD:InteropIndex',
     189        'InteropIFD:InteropVersion',
     190        'InteropIFD:RelatedImageWidth',
     191        'InteropIFD:RelatedImageHeight',
     192    ],
     193    # common metadata tags found in IFD0 of TIFF images
     194    CommonIFD0 => [
     195        # standard EXIF
     196        'IFD0:ImageDescription',
     197        'IFD0:Make',
     198        'IFD0:Model',
     199        'IFD0:Software',
     200        'IFD0:ModifyDate',
     201        'IFD0:Artist',
     202        'IFD0:Copyright',
     203        # other TIFF tags
     204        'IFD0:Rating',
     205        'IFD0:RatingPercent',
     206        'IFD0:DNGLensInfo',
     207        'IFD0:PanasonicTitle',
     208        'IFD0:PanasonicTitle2',
     209        'IFD0:XPTitle',
     210        'IFD0:XPComment',
     211        'IFD0:XPAuthor',
     212        'IFD0:XPKeywords',
     213        'IFD0:XPSubject',
     214    ],
    193215);
    194216
     217#------------------------------------------------------------------------------
    195218# load user-defined shortcuts if available
    196 if (defined %Image::ExifTool::Shortcuts::UserDefined) {
     219# Inputs: reference to user-defined shortcut hash
     220sub LoadShortcuts($)
     221{
     222    my $shortcuts = shift;
    197223    my $shortcut;
    198     foreach $shortcut (keys %Image::ExifTool::Shortcuts::UserDefined) {
    199         my $val = $Image::ExifTool::Shortcuts::UserDefined{$shortcut};
     224    foreach $shortcut (keys %$shortcuts) {
     225        my $val = $$shortcuts{$shortcut};
    200226        # also allow simple aliases
    201227        $val = [ $val ] unless ref $val eq 'ARRAY';
     
    204230    }
    205231}
     232# (for backward compatibility, renamed in ExifTool 7.75)
     233if (%Image::ExifTool::Shortcuts::UserDefined) {
     234    LoadShortcuts(\%Image::ExifTool::Shortcuts::UserDefined);
     235}
     236if (%Image::ExifTool::UserDefined::Shortcuts) {
     237    LoadShortcuts(\%Image::ExifTool::UserDefined::Shortcuts);
     238}
    206239
    207240
     
    226259file in their home directory (or the directory specified by the
    227260EXIFTOOL_HOME environment variable).  The shortcuts are defined in a hash
    228 called %Image::ExifTool::Shortcuts::UserDefined.  The keys of the hash are
     261called %Image::ExifTool::UserDefined::Shortcuts.  The keys of the hash are
    229262the shortcut names, and the elements are either tag names or references to
    230263lists of tag names.
     
    232265An example shortcut definition in .ExifTool_config:
    233266
    234     %Image::ExifTool::Shortcuts::UserDefined = (
     267    %Image::ExifTool::UserDefined::Shortcuts = (
    235268        MyShortcut => ['createdate','exif:exposuretime','aperture'],
    236269        MyAlias => 'FocalLengthIn35mmFormat',
     
    243276=head1 AUTHOR
    244277
    245 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     278Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    246279
    247280This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sigma.pm

    r16842 r24107  
    66# Revisions:    04/06/2004 - P. Harvey Created
    77#               02/20/2007 - PH added SD14 tags
     8#               24/06/2010 - PH decode some SD15 tags
    89#
    910# Reference:    http://www.x3f.info/technotes/FileDocs/MakerNoteDoc.html
     
    1617use Image::ExifTool::Exif;
    1718
    18 $VERSION = '1.04';
     19$VERSION = '1.09';
    1920
    2021%Image::ExifTool::Sigma::Main = (
     
    4647        },
    4748    },
    48     0x000a => 'Lens',
     49    0x000a => 'LensFocalRange',
    4950    0x000b => 'ColorSpace',
     51    # SIGMA PhotoPro writes these tags as strings, but some cameras (at least) write them as rational
    5052    0x000c => [
    5153        {
    5254            Name => 'ExposureCompensation',
    53             Condition => '$$self{CameraModel} !~ /SD14$/',
     55            Condition => '$format eq "string"',
    5456            ValueConv => '$val =~ s/Expo:\s*//, $val',
    5557            ValueConvInv => 'IsFloat($val) ? sprintf("Expo:%+.1f",$val) : undef',
    5658        },
    5759        { #PH
    58             Name => 'UnknownCompensation',
     60            Name => 'ExposureAdjust',
    5961            Writable => 'rational64s',
    6062            Unknown => 1,
     
    6466        {
    6567            Name => 'Contrast',
    66             Condition => '$$self{CameraModel} !~ /SD14$/',
     68            Condition => '$format eq "string"',
    6769            ValueConv => '$val =~ s/Cont:\s*//, $val',
    6870            ValueConvInv => 'IsFloat($val) ? sprintf("Cont:%+.1f",$val) : undef',
     
    7678        {
    7779            Name => 'Shadow',
    78             Condition => '$$self{CameraModel} !~ /SD14$/',
     80            Condition => '$format eq "string"',
    7981            ValueConv => '$val =~ s/Shad:\s*//, $val',
    8082            ValueConvInv => 'IsFloat($val) ? sprintf("Shad:%+.1f",$val) : undef',
     
    8890        {
    8991            Name => 'Highlight',
    90             Condition => '$$self{CameraModel} !~ /SD14$/',
     92            Condition => '$format eq "string"',
    9193            ValueConv => '$val =~ s/High:\s*//, $val',
    9294            ValueConvInv => 'IsFloat($val) ? sprintf("High:%+.1f",$val) : undef',
     
    100102        {
    101103            Name => 'Saturation',
    102             Condition => '$$self{CameraModel} !~ /SD14$/',
     104            Condition => '$format eq "string"',
    103105            ValueConv => '$val =~ s/Satu:\s*//, $val',
    104106            ValueConvInv => 'IsFloat($val) ? sprintf("Satu:%+.1f",$val) : undef',
     
    112114        {
    113115            Name => 'Sharpness',
    114             Condition => '$$self{CameraModel} !~ /SD14$/',
     116            Condition => '$format eq "string"',
    115117            ValueConv => '$val =~ s/Shar:\s*//, $val',
    116118            ValueConvInv => 'IsFloat($val) ? sprintf("Shar:%+.1f",$val) : undef',
     
    124126        {
    125127            Name => 'X3FillLight',
    126             Condition => '$$self{CameraModel} !~ /SD14$/',
     128            Condition => '$format eq "string"',
    127129            ValueConv => '$val =~ s/Fill:\s*//, $val',
    128130            ValueConvInv => 'IsFloat($val) ? sprintf("Fill:%+.1f",$val) : undef',
     
    136138        {
    137139            Name => 'ColorAdjustment',
    138             Condition => '$$self{CameraModel} !~ /SD14$/',
     140            Condition => '$format eq "string"',
    139141            ValueConv => '$val =~ s/CC:\s*//, $val',
    140142            ValueConvInv => 'IsInt($val) ? "CC:$val" : undef',
     
    155157    0x0018 => 'Software',
    156158    0x0019 => 'AutoBracket',
    157     # 0x001a - int32u: 1884 to 2016
    158     # 0x001b - int32u: 20688 to 45335
    159     # 0x001c - int16u[2]: "640 480"
     159    0x001a => [ #PH
     160        {
     161            Name => 'PreviewImageStart',
     162            Condition => '$format eq "int32u"',
     163            IsOffset => 1,
     164            OffsetPair => 0x001b,
     165            DataTag => 'PreviewImage',
     166            Writable => 'int32u',
     167            Protected => 2,
     168        },{ # (written by Sigma Photo Pro)
     169            Name => 'ChrominanceNoiseReduction',
     170            ValueConv => '$val =~ s/Chro:\s*//, $val',
     171            ValueConvInv => 'IsFloat($val) ? sprintf("Chro:%+.1f",$val) : undef',
     172        },
     173    ],
     174    0x001b => [ #PH
     175        {
     176            Name => 'PreviewImageLength',
     177            Condition => '$format eq "int32u"',
     178            OffsetPair => 0x001a,
     179            DataTag => 'PreviewImage',
     180            Writable => 'int32u',
     181            Protected => 2,
     182        },{ # (written by Sigma Photo Pro)
     183            Name => 'LuminanceNoiseReduction',
     184            ValueConv => '$val =~ s/Luma:\s*//, $val',
     185            ValueConvInv => 'IsFloat($val) ? sprintf("Luma:%+.1f",$val) : undef',
     186        },
     187    ],
     188    0x001c => { #PH
     189        Name => 'PreviewImageSize',
     190        Writable => 'int16u',
     191        Count => 2,
     192    },
    160193    0x001d => { #PH
    161194        Name => 'MakerNoteVersion',
    162         Format => 'undef',
    163     },
    164     # 0x001e - int16u: 0
    165     # 0x001f - string: ""
     195        Writable => 'undef',
     196    },
     197    # 0x001e - int16u: 0, 4, 13 - flash mode?
     198    0x001f => { #PH (NC)
     199        Name => 'AFPoint',
     200        # values: "", "Center", "Center,Center", "Right,Right"
     201    },
    166202    # 0x0020-21 - string: " "
    167     0x0022 => { #PH
    168         Name => 'AdjustmentMode',
    169         Priority => 0,
    170         Unknown => 1,
    171     },
    172     # 0x0023 - string: 10, 131, 150, 152, 169
    173     # 0x0024-25 - string: ""
    174     # 0x0026-2e - int32u: 0
     203    0x0022 => { #PH (NC)
     204        Name => 'FileFormat',
     205        # values: "JPG", "JPG-S" or "X3F"
     206    },
     207    # 0x0023 - string: "", 10, 83, 131, 145, 150, 152, 169
     208    0x0024 => 'Calibration',
     209    # 0x0025 - string: "", "0.70", "0.90"
     210    # 0x0026-2b - int32u: 0
     211    0x002c => { #PH
     212        Name => 'ColorMode',
     213        Writable => 'int32u',
     214        PrintConv => {
     215            0 => 'n/a',
     216            1 => 'Sepia',
     217            2 => 'B&W',
     218            3 => 'Standard',
     219            4 => 'Vivid',
     220            5 => 'Neutral',
     221            6 => 'Portrait',
     222            7 => 'Landscape',
     223        },
     224    },
     225    # 0x002d - int32u: 0
     226    # 0x002e - rational64s: (the negative of FlashExposureComp, but why?)
    175227    # 0x002f - int32u: 0, 1
    176     0x0030 => 'LensApertureRange', #PH
     228    0x0030 => { #PH
     229        Name => 'LensApertureRange',
     230        Notes => 'changes with focal length. MaxAperture for some models',
     231    },
    177232    0x0031 => { #PH
    178233        Name => 'FNumber',
     
    185240        Writable => 'rational64u',
    186241        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    187         PrintConvInv => 'eval $val',
    188     },
    189     # 0x0033 - string: "3909" to "12337687"
    190     # 0x0034 - int32u: 0,1,2,3 or 4 (possibly AFPoint?)
     242        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     243    },
     244    0x0033 => { #PH
     245        Name => 'ExposureTime2',
     246        Writable => 'string',
     247        ValueConv => '$val * 1e-6',
     248        ValueConvInv => 'int($val * 1e6 + 0.5)',
     249        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     250        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     251    },
     252    0x0034 => { #PH
     253        Name => 'BurstShot',
     254        Writable => 'int32u',
     255    },
     256    # 0x0034 - int32u: 0,1,2,3 or 4
    191257    0x0035 => { #PH
    192258        Name => 'ExposureCompensation',
    193259        Writable => 'rational64s',
     260        # add a '+' sign to positive values
     261        PrintConv => '$val and $val =~ s/^(\d)/\+$1/; $val',
     262        PrintConvInv => '$val',
    194263    },
    195264    # 0x0036 - string: "                    "
    196     # 0x0037-39 - string: ""
    197     0x003a => { #PH (guess!)
     265    # 0x0037-38 - string: ""
     266    0x0039 => { #PH
     267        Name => 'SensorTemperature',
     268        # (string format)
     269        PrintConv => 'IsInt($val) ? "$val C" : $val',
     270        PrintConvInv => '$val=~s/ ?C$//; $val',
     271    },
     272    0x003a => { #PH
    198273        Name => 'FlashExposureComp',
    199274        Writable => 'rational64s',
     
    204279    },
    205280    0x003c => 'WhiteBalance', #PH
     281    0x003d => { #PH (new for SD15)
     282        Name => 'PictureMode',
     283        Notes => 'same as ColorMode, but "Standard" when ColorMode is Sepia or B&W',
     284    },
    206285);
    207286
     
    225304=head1 AUTHOR
    226305
    227 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     306Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    228307
    229308This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/SigmaRaw.pm

    r16842 r24107  
    44# Description:  Read Sigma/Foveon RAW (X3F) meta information
    55#
    6 # Revisions:    10/16/2005 - P. Harvey Created
     6# Revisions:    2005/10/16 - P. Harvey Created
     7#               2009/11/30 - P. Harvey Support X3F v2.3 written by Sigma DP2
    78#
    89# References:   1) http://www.x3f.info/technotes/FileDocs/X3F_Format.pdf
     
    1516use Image::ExifTool qw(:DataAccess :Utils);
    1617
    17 $VERSION = '1.03';
     18$VERSION = '1.14';
    1819
    1920sub ProcessX3FHeader($$$);
     
    2122sub ProcessX3FProperties($$$);
    2223
     24# sigma LensType lookup (ref PH)
     25my %sigmaLensTypes = (
     26    # 0 => 'Sigma 50mm F2.8 EX Macro', (0 used for other lenses too)
     27    # 8 - 18-125mm LENSARANGE@18mm=22-4
     28    16 => 'Sigma 18-50mm F3.5-5.6 DC',
     29    129 => 'Sigma 14mm F2.8 EX Aspherical',
     30    131 => 'Sigma 17-70mm F2.8-4.5 DC Macro',
     31    145 => 'Sigma Lens (145)',
     32    145.1 => 'Sigma 15-30mm F3.5-4.5 EX DG Aspherical',
     33    145.2 => 'Sigma 18-50mm F2.8 EX DG', #(NC)
     34    145.3 => 'Sigma 20-40mm F2.8 EX DG',
     35    165 => 'Sigma 70-200mm F2.8 EX', # ...but what specific model?:
     36    # 70-200mm F2.8 EX APO - Original version, minimum focus distance 1.8m (1999)
     37    # 70-200mm F2.8 EX DG - Adds 'digitally optimized' lens coatings to reduce flare (2005)
     38    # 70-200mm F2.8 EX DG Macro (HSM) - Minimum focus distance reduced to 1m (2006)
     39    # 70-200mm F2.8 EX DG Macro HSM II - Improved optical performance (2007)
     40    169 => 'Sigma 18-50mm F2.8 EX DC', #(NC)
     41    '100' => 'Sigma 24-70mm f/2.8 DG Macro', # (SD15)
     42    8900 => 'Sigma 70-300mm f/4-5.6 DG OS', # (SD15)
     43);
     44
    2345# main X3F sections (plus header stuff)
    2446%Image::ExifTool::SigmaRaw::Main = (
    2547    PROCESS_PROC => \&ProcessX3FDirectory,
    26     NOTES => 'These tags are used in Sigma and Foveon RAW (.X3F) images.',
     48    NOTES => q{
     49        These tags are used in Sigma and Foveon RAW (.X3F) images.  Metadata is also
     50        extracted from the JpgFromRaw image if it exists (all models but the SD9 and
     51        SD10).  Currently, metadata may only be written to the embedded JpgFromRaw.
     52    },
    2753    Header => {
    2854        SubDirectory => { TagTable => 'Image::ExifTool::SigmaRaw::Header' },
     
    3965        Binary => 1,
    4066    },
    41     IMA2 => {
    42         Name => 'PreviewImage',
    43         Binary => 1,
    44     },
     67    IMA2 => [
     68        {
     69            Name => 'PreviewImage',
     70            Condition => 'not $$self{IsJpgFromRaw}',
     71            Binary => 1,
     72        },
     73        {
     74            Name => 'JpgFromRaw',
     75            Binary => 1,
     76        },
     77    ]
    4578);
    4679
     
    5386        ValueConv => '($val >> 16) . "." . ($val & 0xffff)',
    5487    },
     88    2 => {
     89        Name => 'ImageUniqueID',
     90        # the serial number (with an extra leading "0") makes up
     91        # the first 8 digits of this UID,
     92        Format => 'undef[16]',
     93        ValueConv => 'unpack("H*", $val)',
     94    },
     95    6 => {
     96        Name => 'MarkBits',
     97        PrintConv => { BITMASK => { } },
     98    },
    5599    7 => 'ImageWidth',
    56100    8 => 'ImageHeight',
     
    60104        Format => 'string[32]',
    61105    },
     106    18 => { #PH (DP2, FileVersion 2.3)
     107        Name => 'SceneCaptureType',
     108        Format => 'string[32]',
     109    },
    62110);
    63111
     
    67115    NOTES => 'Extended header data found in version 2.1 and 2.2 files',
    68116    0 => 'Unused',
    69     1 => { Name => 'ExposureAdjust',PrintConv => 'sprintf("%.2f",$val)' },
    70     2 => { Name => 'Contrast',      PrintConv => 'sprintf("%.2f",$val)' },
    71     3 => { Name => 'Shadow',        PrintConv => 'sprintf("%.2f",$val)' },
    72     4 => { Name => 'Highlight',     PrintConv => 'sprintf("%.2f",$val)' },
    73     5 => { Name => 'Saturation',    PrintConv => 'sprintf("%.2f",$val)' },
    74     6 => { Name => 'Sharpness',     PrintConv => 'sprintf("%.2f",$val)' },
    75     7 => { Name => 'RedAdjust',     PrintConv => 'sprintf("%.2f",$val)' },
    76     8 => { Name => 'GreenAdjust',   PrintConv => 'sprintf("%.2f",$val)' },
    77     9 => { Name => 'BlueAdjust',    PrintConv => 'sprintf("%.2f",$val)' },
    78    10 => { Name => 'X3FillLight',   PrintConv => 'sprintf("%.2f",$val)' },
     117    1 => { Name => 'ExposureAdjust',PrintConv => 'sprintf("%.1f",$val)' },
     118    2 => { Name => 'Contrast',      PrintConv => 'sprintf("%.1f",$val)' },
     119    3 => { Name => 'Shadow',        PrintConv => 'sprintf("%.1f",$val)' },
     120    4 => { Name => 'Highlight',     PrintConv => 'sprintf("%.1f",$val)' },
     121    5 => { Name => 'Saturation',    PrintConv => 'sprintf("%.1f",$val)' },
     122    6 => { Name => 'Sharpness',     PrintConv => 'sprintf("%.1f",$val)' },
     123    7 => { Name => 'RedAdjust',     PrintConv => 'sprintf("%.1f",$val)' },
     124    8 => { Name => 'GreenAdjust',   PrintConv => 'sprintf("%.1f",$val)' },
     125    9 => { Name => 'BlueAdjust',    PrintConv => 'sprintf("%.1f",$val)' },
     126   10 => { Name => 'X3FillLight',   PrintConv => 'sprintf("%.1f",$val)' },
    79127);
    80128
     
    106154    CAMNAME     => 'CameraName',
    107155    CAMSERIAL   => 'SerialNumber',
     156    CM_DESC     => 'SceneCaptureType', #PH (DP2)
    108157    COLORSPACE  => 'ColorSpace', # observed: sRGB
    109158    DRIVE => {
     
    112161            SINGLE => 'Single Shot',
    113162            MULTI  => 'Multi Shot',
    114             '2S'   => '2-sec Timer',
    115             '10S'  => '10-sec Timer',
     163            '2S'   => '2 s Timer',
     164            '10S'  => '10 s Timer',
    116165            UP     => 'Mirror Up',
    117166            AB     => 'Auto Bracket',
     
    123172        Name => 'ExposureCompensation',
    124173        Groups => { 2 => 'Image' },
    125         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     174        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
    126175    },
    127176    EXPNET => {
    128177        Name => 'NetExposureCompensation',
    129178        Groups => { 2 => 'Image' },
    130         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     179        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
    131180    },
    132181    EXPTIME => {
     
    147196    FLENGTH => {
    148197        Name => 'FocalLength',
    149         PrintConv => 'sprintf("%.1fmm",$val)',
    150     },
    151     FLEQ35MM    => 'FocalLengthIn35mmFormat',
     198        PrintConv => 'sprintf("%.1f mm",$val)',
     199    },
     200    FLEQ35MM => {
     201        Name => 'FocalLengthIn35mmFormat',
     202        PrintConv => 'sprintf("%.1f mm",$val)',
     203    },
    152204    FOCUS => {
    153205        Name => 'Focus',
     
    159211    },
    160212    IMAGERBOARDID => 'ImagerBoardID',
    161     IMAGERTEMP  => 'SensorTemperature',
     213    IMAGERTEMP  => {
     214        Name => 'SensorTemperature',
     215        PrintConv => '"$val C"',
     216    },
     217    IMAGEBOARDID=> 'ImageBoardID', #PH (DP2)
    162218    ISO         => 'ISO',
    163219    LENSARANGE  => 'LensApertureRange',
    164220    LENSFRANGE  => 'LensFocalRange',
    165     LENSMODEL   => 'LensID',
     221    LENSMODEL   => {
     222        Name => 'LensType',
     223        Notes => q{
     224            decimal values differentiate lenses which would otherwise have the same
     225            LensType, and are used by the Composite LensID tag when attempting to
     226            identify the specific lens model
     227        },
     228        PrintConv => \%sigmaLensTypes,
     229    },
    166230    PMODE => {
    167231        Name => 'ExposureProgram',
     
    210274        last unless $$chars[$i];
    211275    }
    212     my $buff = pack('v*',@$chars[$pos..$i-1]);
    213     my $val = $exifTool->Unicode2Charset($buff, 'II');
    214     return $val;
     276    my $buff = pack('v*', @$chars[$pos..$i-1]);
     277    return $exifTool->Decode($buff, 'UCS2', 'II');
    215278}
    216279
     
    222285{
    223286    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     287    my $dataPt = $$dirInfo{DataPt};
     288    my $hdrLen = $$dirInfo{DirLen};
    224289    my $verbose = $exifTool->Options('Verbose');
    225290
     
    228293
    229294    # process extended data if available
    230     if ($$dirInfo{DirLen} >= 232) {
    231         $verbose and $exifTool->VerboseDir('X3F HeaderExt', 32);
     295    if (length $$dataPt >= 232) {
     296        if ($verbose) {
     297            $exifTool->VerboseDir('X3F HeaderExt', 32);
     298            Image::ExifTool::HexDump($dataPt, undef,
     299                MaxLen => $verbose > 3 ? 1024 : 96,
     300                Out    => $exifTool->Options('TextOut'),
     301                Prefix => $$exifTool{INDENT},
     302                Start  => $$dirInfo{DirLen},
     303            ) if $verbose > 2;
     304        }
    232305        $tagTablePtr = GetTagTable('Image::ExifTool::SigmaRaw::HeaderExt');
    233         my $dataPt = $$dirInfo{DataPt};
    234         my @vals = unpack('x72C32V32', $$dataPt);
     306        my @vals = unpack("x${hdrLen}C32V32", $$dataPt);
    235307        my $i;
    236308        my $unused = 0;
     
    250322            }
    251323            $exifTool->HandleTag($tagTablePtr, $vals[$i], $val,
    252                 Index => $i,
     324                Index  => $i,
    253325                DataPt => $dataPt,
    254                 Start => 104 + $i * 4,
    255                 Size => 4,
     326                Start  => $hdrLen + 32 + $i * 4,
     327                Size   => 4,
    256328            );
    257329        }
     
    305377            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
    306378        }
    307        
     379
    308380        $exifTool->HandleTag($tagTablePtr, $tag, $val,
    309381            Index => $index,
     
    314386    }
    315387    return 1;
     388}
     389
     390#------------------------------------------------------------------------------
     391# Write an X3F file
     392# Inputs: 0) ExifTool object reference, 1) DirInfo reference (DirStart = directory offset)
     393# Returns: error string, undef on success, or -1 on write error
     394# Notes: Writes metadata to embedded JpgFromRaw image
     395sub WriteX3F($$)
     396{
     397    my ($exifTool, $dirInfo) = @_;
     398    my $raf = $$dirInfo{RAF};
     399    my $outfile = $$dirInfo{OutFile};
     400    my ($outDir, $buff, $ver, $entries, $dir, $outPos, $index, $didContain);
     401
     402    $raf->Seek($$dirInfo{DirStart}, 0) or return 'Error seeking to directory start';
     403
     404    # read the X3F directory header (will be copied directly to output)
     405    $raf->Read($outDir, 12) == 12 or return 'Truncated X3F image';
     406    $outDir =~ /^SECd/ or return 'Bad section header';
     407    ($ver, $entries) = unpack('x4V2', $outDir);
     408
     409    # do sanity check on number of entries in directory
     410    return 'Invalid X3F directory count' unless $entries > 2 and $entries < 20;
     411    # read the directory entries
     412    unless ($raf->Read($dir, $entries * 12) == $entries * 12) {
     413        return 'Truncated X3F directory';
     414    }
     415    # do a quick scan to determine the offset of the first data subsection
     416    for ($index=0; $index<$entries; ++$index) {
     417        my $pos = $index * 12;
     418        my ($offset, $len, $tag) = unpack("x${pos}V2a4", $dir);
     419        # remember position of first data subsection
     420        $outPos = $offset if not defined $outPos or $outPos > $offset;
     421    }
     422    # copy the file header up to the start of the first data subsection
     423    unless ($raf->Seek(0,0) and $raf->Read($buff, $outPos) == $outPos) {
     424        return 'Error reading X3F header';
     425    }
     426    Write($outfile, $buff) or return -1;
     427
     428    # loop through directory, rewriting each section
     429    for ($index=0; $index<$entries; ++$index) {
     430
     431        my $pos = $index * 12;
     432        my ($offset, $len, $tag) = unpack("x${pos}V2a4", $dir);
     433        $raf->Seek($offset, 0) or return 'Bad data offset';
     434
     435        if ($tag eq 'IMA2' and $len > 28) {
     436            # check subsection header (28 bytes) to see if this is a JPEG preview image
     437            $raf->Read($buff, 28) == 28 or return 'Error reading PreviewImage header';
     438            Write($outfile, $buff) or return -1;
     439            $len -= 28;
     440
     441            # only rewrite full-sized JpgFromRaw (version 2.0, type 2, format 18)
     442            if ($buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/ and
     443                $$exifTool{ImageWidth} == unpack('x16V', $buff))
     444            {
     445                $raf->Read($buff, $len) == $len or return 'Error reading JpgFromRaw';
     446                # use same write directories as JPEG
     447                $exifTool->InitWriteDirs('JPEG');
     448                # rewrite the embedded JPEG in memory
     449                my $newData;
     450                my %jpegInfo = (
     451                    Parent  => 'X3F',
     452                    RAF     => new File::RandomAccess(\$buff),
     453                    OutFile => \$newData,
     454                );
     455                $$exifTool{FILE_TYPE} = 'JPEG';
     456                my $success = $exifTool->WriteJPEG(\%jpegInfo);
     457                $$exifTool{FILE_TYPE} = 'X3F';
     458                SetByteOrder('II');
     459                return 'Error writing X3F JpgFromRaw' unless $success and $newData;
     460                return -1 if $success < 0;
     461                # write new data if anything changed, otherwise copy old image
     462                my $outPt = $$exifTool{CHANGED} ? \$newData : \$buff;
     463                Write($outfile, $$outPt) or return -1;
     464                # set $len to the total subsection data length
     465                $len = length($$outPt) + 28;
     466                $didContain = 1;
     467            } else {
     468                # copy original image data
     469                Image::ExifTool::CopyBlock($raf, $outfile, $len) or return 'Corrupted X3F image';
     470                $len += 28;
     471            }
     472        } else {
     473            # copy data for this subsection
     474            Image::ExifTool::CopyBlock($raf, $outfile, $len) or return 'Corrupted X3F directory';
     475        }
     476        # add directory entry and update output file position
     477        $outDir .= pack('V2a4', $outPos, $len, $tag);
     478        $outPos += $len;
     479        # pad data to an even 4-byte boundary
     480        if ($len & 0x03) {
     481            my $pad = 4 - ($len & 0x03);
     482            Write($outfile, "\0" x $pad) or return -1;
     483            $outPos += $pad;
     484        }
     485    }
     486    # warn if we couldn't add metadata to this image (should only be SD9 or SD10)
     487    $didContain or $exifTool->Warn("Can't yet write SD9 or SD10 X3F images");
     488    # write out the directory and the directory pointer, and we are done
     489    Write($outfile, $outDir, pack('V', $outPos)) or return -1;
     490    return undef;
    316491}
    317492
     
    329504
    330505    # parse the X3F directory structure
    331     my ($buff, $ver, $entries, $index);
     506    my ($buff, $ver, $entries, $index, $dir);
    332507    $raf->Read($buff, 12) == 12 or return 'Truncated X3F image';
    333508    $buff =~ /^SECd/ or return 'Bad section header';
    334509    ($ver, $entries) = unpack('x4V2', $buff);
    335510    $verbose and $exifTool->VerboseDir('X3F Subsection', $entries);
    336     my $dir;
    337511    $raf->Read($dir, $entries * 12) == $entries * 12 or return 'Truncated X3F directory';
    338512    for ($index=0; $index<$entries; ++$index) {
     
    344518            if ($verbose > 2) {
    345519                $raf->Seek($offset, 0) or return 'Error seeking';
    346                 my $n = $verbose > 3 ? $len : 64;
    347                 $n = $len if $n > $len;
    348                 $raf->Read($buff, $n) == $n or return 'Truncated image';
    349                 Image::ExifTool::HexDump(\$buff, undef,
    350                     Prefix => $exifTool->{INDENT},
    351                     Out => $exifTool->Options('TextOut'),
    352                 );
     520                $raf->Read($buff, $len) == $len or return 'Truncated image';
     521                $exifTool->VerboseDump(\$buff);
    353522            }
    354523        }
     
    358527            # check image header to see if this is a JPEG preview image
    359528            $raf->Read($buff, 28) == 28 or return 'Error reading PreviewImage header';
    360             # igore all image data but JPEG compressed (type 18)
    361             next unless $buff =~ /^SECi.{4}\x02\0\0\0\x12/s;
     529            # ignore all image data but JPEG compressed (version 2.0, type 2, format 18)
     530            next unless $buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/;
     531            # check preview image size and extract full-sized preview as JpgFromRaw
     532            if ($$exifTool{ImageWidth} == unpack('x16V', $buff)) {
     533                $$exifTool{IsJpgFromRaw} = 1;
     534                $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
     535                delete $$exifTool{IsJpgFromRaw};
     536            }
     537            $offset += 28;
    362538            $len -= 28;
    363539        }
     
    369545            $exifTool->ProcessDirectory(\%dirInfo, $subTable);
    370546        } else {
     547            # extract metadata from JpgFromRaw
     548            if ($$tagInfo{Name} eq 'JpgFromRaw') {
     549                my %dirInfo = (
     550                    Parent => 'X3F',
     551                    RAF    => new File::RandomAccess(\$buff),
     552                );
     553                $$exifTool{BASE} += $offset;
     554                $exifTool->ProcessJPEG(\%dirInfo);
     555                $$exifTool{BASE} -= $offset;
     556                SetByteOrder('II');
     557            }
    371558            $exifTool->FoundTag($tagInfo, $buff);
    372559        }
     
    376563
    377564#------------------------------------------------------------------------------
    378 # Extract information from a Sigma raw (X3F) image
     565# Read/write information from a Sigma raw (X3F) image
    379566# Inputs: 0) ExifTool object reference, 1) DirInfo reference
    380 # Returns: 1 on success, 0 if this wasn't a valid X3F image
     567# Returns: 1 on success, 0 if this wasn't a valid X3F image, or -1 on write error
    381568sub ProcessX3F($$)
    382569{
    383570    my ($exifTool, $dirInfo) = @_;
     571    my $outfile = $$dirInfo{OutFile};
    384572    my $raf = $$dirInfo{RAF};
    385     my $buff;
     573    my $warn = $outfile ? \&Image::ExifTool::Error : \&Image::ExifTool::Warn;
     574    my ($buff, $err);
    386575
    387576    return 0 unless $raf->Read($buff, 40) == 40;
     
    395584    $ver = ($ver >> 16) . '.' . ($ver & 0xffff);
    396585    if ($ver >= 3) {
    397         $exifTool->Warn("Can't read version $ver X3F image");
     586        &$warn($exifTool, "Can't read version $ver X3F image");
    398587        return 1;
    399     }
    400     # read version 2.1/2.2 extended header
     588    } elsif ($ver > 2.3) {
     589        &$warn($exifTool, 'Untested X3F version. Please submit sample for testing', 1);
     590    }
     591    my $hdrLen = length $buff;
     592    # read version 2.1/2.2/2.3 extended header
    401593    if ($ver > 2) {
     594        $hdrLen += $ver > 2.2 ? 64 : 32;            # SceneCaptureType string added in 2.3
     595        my $more = $hdrLen - length($buff) + 160;   # (extended header is 160 bytes)
    402596        my $buf2;
    403         unless ($raf->Read($buf2, 192) == 192) {
    404             $exifTool->Warn('Error reading extended header');
     597        unless ($raf->Read($buf2, $more) == $more) {
     598            &$warn($exifTool, 'Error reading extended header');
    405599            return 1;
    406600        }
    407601        $buff .= $buf2;
    408602    }
     603    # extract ImageWidth for later
     604    $$exifTool{ImageWidth} = Get32u(\$buff, 28);
    409605    # process header information
    410606    my $tagTablePtr = GetTagTable('Image::ExifTool::SigmaRaw::Main');
    411     my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, 'Header');
    412     my $subdir = GetTagTable('Image::ExifTool::SigmaRaw::Header');
     607    unless ($outfile) {
     608        $exifTool->HandleTag($tagTablePtr, 'Header', $buff,
     609            DataPt => \$buff,
     610            Size   => $hdrLen,
     611        );
     612    }
     613    # read the directory pointer
     614    $raf->Seek(-4, 2) or &$warn($exifTool, 'Seek error'), return 1;
     615    unless ($raf->Read($buff, 4) == 4) {
     616        &$warn($exifTool, 'Error reading X3F dir pointer');
     617        return 1;
     618    }
     619    my $offset = unpack('V', $buff);
    413620    my %dirInfo = (
    414         DataPt => \$buff,
    415         DirStart => 0,
    416         DirLen => length($buff),
    417     );
    418     $exifTool->ProcessDirectory(\%dirInfo, $subdir);
    419     # read the directory pointer
    420     $raf->Seek(-4, 2);
    421     unless ($raf->Read($buff, 4) == 4) {
    422         $exifTool->Warn('Error reading X3F dir pointer');
    423         return 1;
    424     }
    425     my $offset = unpack('V', $buff);
    426     %dirInfo = (
    427621        RAF => $raf,
    428622        DirStart => $offset,
    429623    );
    430     # process the X3F subsections
    431     my $err = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
    432     $err and $exifTool->Warn($err);
     624    if ($outfile) {
     625        $dirInfo{OutFile} = $outfile;
     626        $err = WriteX3F($exifTool, \%dirInfo);
     627        return -1 if $err and $err eq '-1';
     628    } else {
     629        # process the X3F subsections
     630        $err = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
     631    }
     632    $err and &$warn($exifTool, $err);
    433633    return 1;
    434634}
     
    453653=head1 AUTHOR
    454654
    455 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     655Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    456656
    457657This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sony.pm

    r16842 r24107  
    77#
    88# References:   1) http://www.cybercom.net/~dcoffin/dcraw/
    9 #               2) http://homepage3.nifty.com/kamisaka/makernote/makernote_sony.htm
     9#               2) http://homepage3.nifty.com/kamisaka/makernote/makernote_sony.htm (2006/08/06)
    1010#               3) Thomas Bodenmann private communication
     11#               4) Philippe Devaux private communication (A700)
     12#               5) Marcus Holland-Moritz private communication (A700)
     13#               6) Andrey Tverdokhleb private communication
     14#               7) Rudiger Lange private communication (A700)
     15#               8) Igal Milchtaich private communication
     16#               9) Michael Reitinger private communication (DSC-TX7)
     17#               10) http://www.klingebiel.com/tempest/hd/pmp.html
     18#               11 Mike Battilana private communication
     19#               JD) Jens Duttke private communication
    1120#------------------------------------------------------------------------------
    1221
     
    1928use Image::ExifTool::Minolta;
    2029
    21 $VERSION = '1.10';
     30$VERSION = '1.50';
    2231
    2332sub ProcessSRF($$$);
    2433sub ProcessSR2($$$);
    25 
    26 my %sonyLensIDs;    # filled in based on Minolta LensID's
     34sub WriteSR2($$$);
     35
     36my %sonyLensTypes;  # filled in based on Minolta LensType's
     37
     38# ExposureProgram values (ref PH, mainly decoded from A200)
     39my %sonyExposureProgram = (
     40    0 => 'Auto', # (same as 'Program AE'?)
     41    1 => 'Manual',
     42    2 => 'Program AE',
     43    3 => 'Aperture-priority AE',
     44    4 => 'Shutter speed priority AE',
     45    8 => 'Program Shift A', #7
     46    9 => 'Program Shift S', #7
     47    19 => 'Night Portrait', # (A330)
     48    18 => 'Sunset', # (A330)
     49    17 => 'Sports', # (A330)
     50    21 => 'Macro', # (A330)
     51    20 => 'Landscape', # (A330)
     52    16 => 'Portrait', # (A330)
     53    35 => 'Auto No Flash', # (A330)
     54);
     55
     56my %binaryDataAttrs = (
     57    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     58    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     59    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     60    WRITABLE => 1,
     61    FIRST_ENTRY => 0,
     62);
    2763
    2864%Image::ExifTool::Sony::Main = (
     
    3066    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
    3167    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     68    0x0102 => { #5/JD
     69        Name => 'Quality',
     70        Writable => 'int32u',
     71        PrintConv => {
     72            0 => 'RAW',
     73            1 => 'Super Fine',
     74            2 => 'Fine',
     75            3 => 'Standard',
     76            4 => 'Economy',
     77            5 => 'Extra Fine',
     78            6 => 'RAW + JPEG',
     79            7 => 'Compressed RAW',
     80            8 => 'Compressed RAW + JPEG',
     81        },
     82    },
     83    0x0104 => { #5/JD
     84        Name => 'FlashExposureComp',
     85        Description => 'Flash Exposure Compensation',
     86        Writable => 'rational64s',
     87    },
     88    0x0105 => { #5/JD
     89        Name => 'Teleconverter',
     90        Writable => 'int32u',
     91        PrintHex => 1,
     92        PrintConv => {
     93            0 => 'None',
     94            72 => 'Minolta AF 2x APO (D)',
     95            80 => 'Minolta AF 2x APO II',
     96            136 => 'Minolta AF 1.4x APO (D)',
     97            144 => 'Minolta AF 1.4x APO II',
     98        },
     99    },
     100    0x0112 => { #JD
     101        Name => 'WhiteBalanceFineTune',
     102        Format => 'int32s',
     103        Writable => 'int32u',
     104    },
     105    0x0114 => [ #PH
     106        {
     107            Name => 'CameraSettings',
     108            Condition => '$$self{Model} =~ /DSLR-A(200|230|300|350|700|850|900)\b/',
     109            SubDirectory => {
     110                TagTable => 'Image::ExifTool::Sony::CameraSettings',
     111                ByteOrder => 'BigEndian',
     112            },
     113        },
     114        {
     115            Name => 'CameraSettings2',
     116            Condition => '$$self{Model} =~ /DSLR-A(330|380)\b/',
     117            SubDirectory => {
     118                TagTable => 'Image::ExifTool::Sony::CameraSettings2',
     119                ByteOrder => 'BigEndian',
     120            },
     121        },
     122        {
     123            Name => 'CameraSettingsUnknown',
     124            SubDirectory => {
     125                TagTable => 'Image::ExifTool::Sony::CameraSettingsUnknown',
     126                ByteOrder => 'BigEndian',
     127            },
     128        },
     129    ],
     130    0x0115 => { #JD
     131        Name => 'WhiteBalance',
     132        Writable => 'int32u',
     133        PrintHex => 1,
     134        PrintConv => {
     135            0x00 => 'Auto',
     136            0x01 => 'Color Temperature/Color Filter',
     137            0x10 => 'Daylight',
     138            0x20 => 'Cloudy',
     139            0x30 => 'Shade',
     140            0x40 => 'Tungsten',
     141            0x50 => 'Flash',
     142            0x60 => 'Fluorescent',
     143            0x70 => 'Custom',
     144        },
     145    },
    32146    0x0e00 => {
    33147        Name => 'PrintIM',
     
    37151        },
    38152    },
    39     # 0xb020 string with observed values "Standard", "None" and "Real"
     153    # the next 3 tags have a different meaning for some models (with format int32u)
     154    0x1000 => { #9 (F88, multi burst mode only)
     155        Name => 'MultiBurstMode',
     156        Condition => '$format eq "undef"',
     157        Notes => 'MultiBurst tags valid only for models with this feature, like the F88',
     158        Writable => 'undef',
     159        Format => 'int8u',
     160        PrintConv => { 0 => 'Off', 1 => 'On' },
     161    },
     162    0x1001 => { #9 (F88, multi burst mode only)
     163        Name => 'MultiBurstImageWidth',
     164        Condition => '$format eq "int16u"',
     165        Writable => 'int16u',
     166    },
     167    0x1002 => { #9 (F88, multi burst mode only)
     168        Name => 'MultiBurstImageHeight',
     169        Condition => '$format eq "int16u"',
     170        Writable => 'int16u',
     171    },
     172    0x1003 => { #9 (TX7, panorama mode only)
     173        Name => 'Panorama',
     174        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Panorama' },
     175    },
     176    0x2001 => { #PH (JPEG images from all DSLR's except the A100)
     177        Name => 'PreviewImage',
     178        Writable => 'undef',
     179        DataTag => 'PreviewImage',
     180        # Note: the preview data starts with a 32-byte proprietary Sony header
     181        WriteCheck => 'return $val=~/^(none|.{32}\xff\xd8\xff)/s ? undef : "Not a valid image"',
     182        RawConv => q{
     183            return \$val if $val =~ /^Binary/;
     184            $val = substr($val,0x20) if length($val) > 0x20;
     185            return \$val if $val =~ s/^.(\xd8\xff\xdb)/\xff$1/s;
     186            $$self{PreviewError} = 1 unless $val eq 'none';
     187            return undef;
     188        },
     189        # must construct 0x20-byte header which contains length, width and height
     190        ValueConvInv => q{
     191            return 'none' unless $val;
     192            my $e = new Image::ExifTool;
     193            my $info = $e->ImageInfo(\$val,'ImageWidth','ImageHeight');
     194            return undef unless $$info{ImageWidth} and $$info{ImageHeight};
     195            my $size = Set32u($$info{ImageWidth}) . Set32u($$info{ImageHeight});
     196            return Set32u(length $val) . $size . ("\0" x 8) . $size . ("\0" x 4) . $val;
     197        },
     198    },
     199    # 0x2002 - probably Sharpness (PH guess)
     200    0x2004 => { #PH (NEX-5)
     201        Name => 'Contrast',
     202        Writable => 'int32s',
     203        PrintConv => '$val > 0 ? "+$val" : $val',
     204        PrintConvInv => '$val',
     205    },
     206    0x2005 => { #PH (NEX-5)
     207        Name => 'Saturation',
     208        Writable => 'int32s',
     209        PrintConv => '$val > 0 ? "+$val" : $val',
     210        PrintConvInv => '$val',
     211    },
     212    0x2006 => { #PH
     213        Name => 'Sharpness',
     214        Writable => 'int32s',
     215        PrintConv => '$val > 0 ? "+$val" : $val',
     216        PrintConvInv => '$val',
     217    },
     218    0x2007 => { #PH
     219        Name => 'Brightness',
     220        Writable => 'int32s',
     221        PrintConv => '$val > 0 ? "+$val" : $val',
     222        PrintConvInv => '$val',
     223    },
     224    0x2008 => { #PH
     225        Name => 'LongExposureNoiseReduction',
     226        Writable => 'int32u',
     227        PrintHex => 1,
     228        PrintConv => {
     229            0 => 'Off',
     230            1 => 'On',
     231            0xffff0000 => 'Off 2',
     232            0xffff0001 => 'On 2',
     233            0xffffffff => 'n/a',
     234        },
     235    },
     236    0x2009 => { #PH
     237        Name => 'HighISONoiseReduction',
     238        Writable => 'int16u',
     239        PrintConv => {
     240            0 => 'Off',
     241            1 => 'Low',
     242            2 => 'Normal',
     243            3 => 'High',
     244            256 => 'Auto',
     245            65535 => 'n/a',
     246        },
     247    },
     248    0x200a => { #PH (A550)
     249        Name => 'HDR',
     250        Writable => 'int32u',
     251        PrintHex => 1,
     252        PrintConv => {
     253            0x0 => 'Off',
     254            0x10001 => 'Auto',
     255            0x10010 => '1.0 EV', # (NEX_5)
     256            0x10011 => '1.5 EV',
     257            0x10012 => '2.0 EV',
     258            0x10013 => '2.5 EV',
     259            0x10014 => '3.0 EV',
     260            0x10015 => '3.5 EV',
     261            0x10016 => '4.0 EV',
     262            0x10017 => '4.5 EV',
     263            0x10018 => '5.0 EV',
     264            0x10019 => '5.5 EV',
     265            0x1001a => '6.0 EV', # (SLT-A55V)
     266        },
     267    },
     268    0x200b => { #PH
     269        Name => 'MultiFrameNoiseReduction',
     270        Writable => 'int32u',
     271        PrintConv => {
     272            0 => 'Off',
     273            1 => 'On',
     274            255 => 'n/a',
     275        },
     276    },
     277    0x3000 => {
     278        Name => 'ShotInfo',
     279        SubDirectory => {
     280            TagTable => 'Image::ExifTool::Sony::ShotInfo',
     281        },
     282    },
     283    # 0x3000: data block that includes DateTimeOriginal string
     284    0xb000 => { #8
     285        Name => 'FileFormat',
     286        Writable => 'int8u',
     287        Count => 4,
     288        # dynamically set the file type to SR2 because we could have assumed ARW up till now
     289        RawConv => q{
     290            $self->OverrideFileType($$self{TIFF_TYPE} = 'SR2') if $val eq '1 0 0 0';
     291            return $val;
     292        },
     293        PrintConv => {
     294            '0 0 0 2' => 'JPEG',
     295            '1 0 0 0' => 'SR2',
     296            '2 0 0 0' => 'ARW 1.0',
     297            '3 0 0 0' => 'ARW 2.0',
     298            '3 1 0 0' => 'ARW 2.1',
     299            '3 2 0 0' => 'ARW 2.2', # (NEX-5)
     300            # what about cRAW images?
     301        },
     302    },
     303    0xb001 => { # ref http://forums.dpreview.com/forums/read.asp?forum=1037&message=33609644
     304        # (ARW and SR2 images only)
     305        Name => 'SonyModelID',
     306        Writable => 'int16u',
     307        PrintConvColumns => 2,
     308        PrintConv => {
     309            2 => 'DSC-R1',
     310            256 => 'DSLR-A100',
     311            257 => 'DSLR-A900',
     312            258 => 'DSLR-A700',
     313            259 => 'DSLR-A200',
     314            260 => 'DSLR-A350',
     315            261 => 'DSLR-A300',
     316            263 => 'DSLR-A380/A390', #PH (A390)
     317            264 => 'DSLR-A330',
     318            265 => 'DSLR-A230',
     319            266 => 'DSLR-A290', #PH
     320            269 => 'DSLR-A850',
     321            273 => 'DSLR-A550',
     322            274 => 'DSLR-A500', #PH
     323            275 => 'DSLR-A450', # (http://dev.exiv2.org/issues/show/0000611)
     324            278 => 'NEX-5', #PH
     325            279 => 'NEX-3', #PH
     326            280 => 'SLT-A33', #PH
     327            281 => 'SLT-A55V', #PH
     328            282 => 'DSLR-A560', #PH
     329            283 => 'DSLR-A580', # (http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2881.0.html)
     330        },
     331    },
     332    0xb020 => { #2
     333        Name => 'ColorReproduction',
     334        # observed values: None, Standard, Vivid, Real, AdobeRGB - PH
     335        Writable => 'string',
     336    },
    40337    0xb021 => { #2
    41338        Name => 'ColorTemperature',
     339        Writable => 'int32u',
    42340        PrintConv => '$val ? $val : "Auto"',
    43     },
    44     0xb023 => { #PH (A100)
     341        PrintConvInv => '$val=~/Auto/i ? 0 : $val',
     342    },
     343    0xb022 => { #7
     344        Name => 'ColorCompensationFilter',
     345        Format => 'int32s',
     346        Writable => 'int32u', # (written incorrectly as unsigned by Sony)
     347        Notes => 'negative is green, positive is magenta',
     348    },
     349    0xb023 => { #PH (A100) - (set by mode dial)
    45350        Name => 'SceneMode',
    46         PrintConv => {
    47             0 => 'Manual (P,A,S or M)',
    48             1 => 'Portrait',
    49             4 => 'Sunset',
    50             5 => 'Sports',
    51             6 => 'Landscape',
    52             8 => 'Macro',
    53             16 => 'Auto',
    54             17 => 'Night Portrait',
    55         },
     351        Writable => 'int32u',
     352        PrintConv => \%Image::ExifTool::Minolta::minoltaSceneMode,
    56353    },
    57354    0xb024 => { #PH (A100)
    58355        Name => 'ZoneMatching',
     356        Writable => 'int32u',
    59357        PrintConv => {
    60358            0 => 'ISO Setting Used',
     
    65363    0xb025 => { #PH (A100)
    66364        Name => 'DynamicRangeOptimizer',
     365        Writable => 'int32u',
    67366        PrintConv => {
    68367            0 => 'Off',
    69368            1 => 'Standard',
    70             2 => 'Advanced',
     369            2 => 'Advanced Auto',
     370            3 => 'Auto', # (A550)
     371            8 => 'Advanced Lv1', #JD
     372            9 => 'Advanced Lv2', #JD
     373            10 => 'Advanced Lv3', #JD
     374            11 => 'Advanced Lv4', #JD
     375            12 => 'Advanced Lv5', #JD
     376            16 => 'Lv1', # (NEX_5)
     377            17 => 'Lv2',
     378            18 => 'Lv3',
     379            19 => 'Lv4',
     380            20 => 'Lv5',
    71381        },
    72382    },
    73383    0xb026 => { #PH (A100)
    74384        Name => 'ImageStabilization',
     385        Writable => 'int32u',
    75386        PrintConv => { 0 => 'Off', 1 => 'On' },
    76387    },
    77388    0xb027 => { #2
    78         Name => 'LensID',
    79         PrintConv => \%sonyLensIDs,
     389        Name => 'LensType',
     390        Writable => 'int32u',
     391        SeparateTable => 1,
     392        PrintConv => \%sonyLensTypes,
    80393    },
    81394    0xb028 => { #2
    82395        # (used by the DSLR-A100)
    83396        Name => 'MinoltaMakerNote',
     397        # must check for zero since apparently a value of zero indicates the IFD doesn't exist
     398        # (dumb Sony -- they shouldn't write this tag if the IFD is missing!)
     399        Condition => '$$valPt ne "\0\0\0\0"',
    84400        Flags => 'SubIFD',
    85401        SubDirectory => {
     
    88404        },
    89405    },
    90     0xb029 => { #2
     406    0xb029 => { #2 (set by creative style menu)
    91407        Name => 'ColorMode',
    92408        Writable => 'int32u',
    93         PrintConv => {
    94             0 => 'Standard',
    95             1 => 'Vivid',
    96             2 => 'Portrait',
    97             3 => 'Landscape',
    98             4 => 'Sunset',
    99             5 => 'Night Scene',
    100             6 => 'B&W',
    101             7 => 'Adobe RGB',
    102         },
     409        PrintConv => \%Image::ExifTool::Minolta::sonyColorMode,
     410    },
     411    0xb02b => { #PH (A550 JPEG and A200, A230, A300, A350, A380, A700 and A900 ARW)
     412        Name => 'FullImageSize',
     413        Writable => 'int32u',
     414        Count => 2,
     415        # values stored height first, so swap to get "width height"
     416        ValueConv => 'join(" ", reverse split(" ", $val))',
     417        ValueConvInv => 'join(" ", reverse split(" ", $val))',
     418        PrintConv => '$val =~ tr/ /x/; $val',
     419        PrintConvInv => '$val =~ tr/x/ /; $val',
     420    },
     421    0xb02c => { #PH (A550 JPEG and A200, A230, A300, A350, A380, A700 and A900 ARW)
     422        Name => 'PreviewImageSize',
     423        Writable => 'int32u',
     424        Count => 2,
     425        ValueConv => 'join(" ", reverse split(" ", $val))',
     426        ValueConvInv => 'join(" ", reverse split(" ", $val))',
     427        PrintConv => '$val =~ tr/ /x/; $val',
     428        PrintConvInv => '$val =~ tr/x/ /; $val',
    103429    },
    104430    0xb040 => { #2
    105431        Name => 'Macro',
    106         PrintConv => { 0 => 'Off', 1 => 'On' },
     432        Writable => 'int16u',
     433        RawConv => '$val == 65535 ? undef : $val',
     434        PrintConv => {
     435            0 => 'Off',
     436            1 => 'On',
     437            2 => 'Close Focus', #9
     438            65535 => 'n/a', #PH (A100)
     439        },
    107440    },
    108441    0xb041 => { #2
    109442        Name => 'ExposureMode',
     443        Writable => 'int16u',
     444        RawConv => '$val == 65535 ? undef : $val',
    110445        PrintConv => {
    111446            0 => 'Auto',
     447            1 => 'Portrait', #PH (HX1)
     448            2 => 'Beach', #9
     449            4 => 'Snow', #9
    112450            5 => 'Landscape',
    113451            6 => 'Program',
    114452            7 => 'Aperture Priority',
    115453            8 => 'Shutter Priority',
    116             9 => 'Night Scene',
     454            9 => 'Night Scene / Twilight',#2/9
     455            10 => 'Hi-Speed Shutter', #9
     456            11 => 'Twilight Portrait', #9
     457            12 => 'Soft Snap', #9
     458            13 => 'Fireworks', #9
     459            14 => 'Smile Shutter', #9 (T200)
    117460            15 => 'Manual',
     461            18 => 'High Sensitivity', #9
     462            20 => 'Advanced Sports Shooting', #9
     463            29 => 'Underwater', #9
     464            33 => 'Gourmet', #9
     465            34 => 'Panorama', #PH (HX1)
     466            35 => 'Handheld Twilight', #PH (HX1/TX1)
     467            36 => 'Anti Motion Blur', #PH (TX1)
     468            37 => 'Pet', #9
     469            38 => 'Backlight Correction HDR', #9
     470            65535 => 'n/a', #PH (A100)
     471        },
     472    },
     473    0xb042 => { #9
     474        Name => 'FocusMode',
     475        Writable => 'int16u',
     476        RawConv => '$val == 65535 ? undef : $val',
     477        PrintConv => {
     478            1 => 'AF-S', # (called Single-AF by Sony)
     479            2 => 'AF-C', # (called Monitor-AF by Sony)
     480            4 => 'Permanent-AF', # (TX7)
     481            65535 => 'n/a', #PH (A100)
     482        },
     483    },
     484    0xb043 => { #9
     485        Name => 'AFMode',
     486        Writable => 'int16u',
     487        RawConv => '$val == 65535 ? undef : $val',
     488        PrintConv => {
     489            0 => 'Default', # (takes this value after camera reset, but can't be set back once changed)
     490            1 => 'Multi AF',
     491            2 => 'Center AF',
     492            3 => 'Spot AF',
     493            4 => 'Flexible Spot AF', # (T200)
     494            6 => 'Touch AF',
     495            14 => 'Manual Focus', # (T200)
     496            15 => 'Face Detected', # (not set when in face detect mode and no faces detected)
     497            65535 => 'n/a', #PH (A100)
     498        },
     499    },
     500    0xb044 => { #9
     501        Name => 'AFIlluminator',
     502        Writable => 'int16u',
     503        RawConv => '$val == 65535 ? undef : $val',
     504        PrintConv => {
     505            0 => 'Off',
     506            1 => 'Auto',
     507            65535 => 'n/a', #PH (A100)
    118508        },
    119509    },
    120510    0xb047 => { #2
    121511        Name => 'Quality',
     512        Writable => 'int16u',
     513        RawConv => '$val == 65535 ? undef : $val',
    122514        PrintConv => {
    123515            0 => 'Normal',
    124516            1 => 'Fine',
     517            65535 => 'n/a', #PH (A100)
     518        },
     519    },
     520    0xb048 => { #9
     521        Name => 'FlashLevel',
     522        Writable => 'int16s',
     523        RawConv => '$val == -1 ? undef : $val',
     524        PrintConv => {
     525            -32768 => 'Low',
     526            -1 => 'n/a', #PH (A100)
     527            0 => 'Normal',
     528            32767 => 'High',
     529        },
     530    },
     531    0xb049 => { #9
     532        Name => 'ReleaseMode',
     533        Writable => 'int16u',
     534        RawConv => '$val == 65535 ? undef : $val',
     535        PrintConv => {
     536            0 => 'Normal',
     537            2 => 'Burst',
     538            5 => 'Exposure Bracketing',
     539            6 => 'White Balance Bracketing', # (HX5)
     540            65535 => 'n/a', #PH (A100)
     541        },
     542    },
     543    0xb04a => { #9
     544        Name => 'SequenceNumber',
     545        Notes => 'shot number in continuous burst',
     546        Writable => 'int16u',
     547        RawConv => '$val == 65535 ? undef : $val',
     548        PrintConv => {
     549            0 => 'Single',
     550            65535 => 'n/a', #PH (A100)
     551            OTHER => sub { shift }, # pass all other numbers straight through
     552        },
     553    },
     554    0xb04b => { #2/PH
     555        Name => 'Anti-Blur',
     556        Writable => 'int16u',
     557        RawConv => '$val == 65535 ? undef : $val',
     558        PrintConv => {
     559            0 => 'Off',
     560            1 => 'On (Continuous)', #PH (NC)
     561            2 => 'On (Shooting)', #PH (NC)
     562            65535 => 'n/a',
    125563        },
    126564    },
    127565    0xb04e => { #2
    128566        Name => 'LongExposureNoiseReduction',
     567        Writable => 'int16u',
     568        RawConv => '$val == 65535 ? undef : $val',
     569        PrintConv => {
     570            0 => 'Off',
     571            1 => 'On',
     572            65535 => 'n/a', #PH (A100)
     573        },
     574    },
     575    0xb04f => { #PH (TX1)
     576        Name => 'DynamicRangeOptimizer',
     577        Writable => 'int16u',
     578        PrintConv => {
     579            0 => 'Off',
     580            1 => 'Standard',
     581            2 => 'Plus',
     582        },
     583    },
     584    0xb052 => { #PH (TX1)
     585        Name => 'IntelligentAuto',
     586        Writable => 'int16u',
     587        PrintConv => {
     588            0 => 'Off',
     589            1 => 'On',
     590            2 => 'Advanced', #9
     591        },
     592    },
     593    0xb054 => { #PH (TX1)
     594        Name => 'WhiteBalance',
     595        Writable => 'int16u',
     596        Priority => 0, # (until more values are filled in)
     597        PrintConv => {
     598            0 => 'Auto',
     599            4 => 'Manual',
     600            5 => 'Daylight',
     601            6 => 'Cloudy', #9
     602            7 => 'White Flourescent', #9      (Sony "Fluorescent 1 (White)")
     603            8 => 'Cool White Flourescent', #9 (Sony "Fluorescent 2 (Natural White)")
     604            9 => 'Day White Flourescent', #9  (Sony "Fluorescent 3 (Day White)")
     605            14 => 'Incandescent',
     606            15 => 'Flash', #9
     607            17 => 'Underwater 1 (Blue Water)', #9
     608            18 => 'Underwater 2 (Green Water)', #9
     609        },
     610    },
     611);
     612
     613# "SEMC MS" maker notes
     614%Image::ExifTool::Sony::Ericsson = (
     615    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     616    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     617    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     618    NOTES => 'Maker notes found in images from some Sony Ericsson phones.',
     619    0x2000 => {
     620        Name => 'MakerNoteVersion',
     621        Writable => 'undef',
     622        Count => 4,
     623    },
     624    0x201 => {
     625        Name => 'PreviewImageStart',
     626        IsOffset => 1,
     627        MakerPreview => 1, # force preview inside maker notes
     628        OffsetPair => 0x202,
     629        DataTag => 'PreviewImage',
     630        Writable => 'int32u',
     631        Protected => 2,
     632        Notes => 'a small 320x200 preview image',
     633    },
     634    0x202 => {
     635        Name => 'PreviewImageLength',
     636        OffsetPair => 0x201,
     637        DataTag => 'PreviewImage',
     638        Writable => 'int32u',
     639        Protected => 2,
     640    },
     641);
     642
     643# Camera settings (ref PH) (decoded mainly from A200)
     644%Image::ExifTool::Sony::CameraSettings = (
     645    %binaryDataAttrs,
     646    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     647    FORMAT => 'int16u',
     648    NOTES => q{
     649        Camera settings for the A200, A230, A300, A350, A700, A850 and A900.  Some
     650        tags are only valid for certain models.
     651    },
     652    0x04 => { #7 (A700, not valid for other models)
     653        Name => 'DriveMode',
     654        Condition => '$$self{Model} =~ /DSLR-A700\b/',
     655        Notes => 'A700 only',
     656        PrintConv => {
     657            1 => 'Single Frame',
     658            2 => 'Continuous High',
     659            4 => 'Self-timer 10 sec',
     660            5 => 'Self-timer 2 sec',
     661            7 => 'Continuous Bracketing',
     662            12 => 'Continuous Low',
     663            18 => 'White Balance Bracketing Low',
     664            19 => 'D-Range Optimizer Bracketing Low',
     665        },
     666    },
     667    0x06 => { #7 (A700, not valid for other models)
     668        Name => 'WhiteBalanceFineTune',
     669        Condition => '$$self{Model} =~ /DSLR-A700\b/',
     670        Format => 'int16s',
     671        Notes => 'A700 only',
     672    },
     673    0x10 => { #7 (A700, not confirmed for other models)
     674        Name => 'FocusMode',
     675        PrintConv => {
     676            0 => 'Manual',
     677            1 => 'AF-S',
     678            2 => 'AF-C',
     679            3 => 'AF-A',
     680        },
     681    },
     682    0x11 => { #JD (A700)
     683        Name => 'AFAreaMode',
     684        PrintConv => {
     685            0 => 'Wide',
     686            1 => 'Local',
     687            2 => 'Spot',
     688        },
     689    },
     690    0x12 => { #7 (A700, not confirmed for other models)
     691        Name => 'LocalAFAreaPoint',
     692        Format => 'int16u',
     693        Condition => '$$self{Model} !~ /DSLR-A230/',
     694        PrintConv => {
     695            1 => 'Center',
     696            2 => 'Top',
     697            3 => 'Top-Right',
     698            4 => 'Right',
     699            5 => 'Bottom-Right',
     700            6 => 'Bottom',
     701            7 => 'Bottom-Left',
     702            8 => 'Left',
     703            9 => 'Top-Left',
     704            10 => 'Far Right',
     705            11 => 'Far Left',
     706            # have seen value of 128 for A230, A330, A380 - PH
     707        },
     708    },
     709    0x15 => { #7
     710        Name => 'MeteringMode',
     711        Condition => '$$self{Model} !~ /DSLR-A230/',
     712        PrintConv => {
     713            1 => 'Multi-segment',
     714            2 => 'Center-weighted Average',
     715            4 => 'Spot',
     716        },
     717    },
     718    0x16 => {
     719        Name => 'ISOSetting',
     720        Condition => '$$self{Model} !~ /DSLR-A230/',
     721        # 0 indicates 'Auto' (I think)
     722        ValueConv => '$val ? exp(($val/8-6)*log(2))*100 : $val',
     723        ValueConvInv => '$val ? 8*(log($val/100)/log(2)+6) : $val',
     724        PrintConv => '$val ? sprintf("%.0f",$val) : "Auto"',
     725        PrintConvInv => '$val =~ /auto/i ? 0 : $val',
     726    },
     727    0x18 => { #7
     728        Name => 'DynamicRangeOptimizerMode',
     729        Condition => '$$self{Model} !~ /DSLR-A230/',
     730        PrintConv => {
     731            0 => 'Off',
     732            1 => 'Standard',
     733            2 => 'Advanced Auto',
     734            3 => 'Advanced Level',
     735            4097 => 'Auto', #PH (A550)
     736        },
     737    },
     738    0x19 => { #7
     739        Name => 'DynamicRangeOptimizerLevel',
     740        Condition => '$$self{Model} !~ /DSLR-A230/',
     741    },
     742    0x1a => { # style actually used (combination of mode dial + creative style menu)
     743        Name => 'CreativeStyle',
     744        Condition => '$$self{Model} !~ /DSLR-A230/',
     745        PrintConv => {
     746            1 => 'Standard',
     747            2 => 'Vivid',
     748            3 => 'Portrait',
     749            4 => 'Landscape',
     750            5 => 'Sunset',
     751            6 => 'Night View/Portrait',
     752            8 => 'B&W',
     753            9 => 'Adobe RGB', # A900
     754            11 => 'Neutral',
     755            12 => 'Clear', #7
     756            13 => 'Deep', #7
     757            14 => 'Light', #7
     758            15 => 'Autumn', #7
     759            16 => 'Sepia', #7
     760        },
     761    },
     762    0x1c => {
     763        Name => 'Sharpness',
     764        ValueConv => '$val - 10',
     765        ValueConvInv => '$val + 10',
     766        PrintConv => '$val > 0 ? "+$val" : $val',
     767        PrintConvInv => '$val',
     768    },
     769    0x1d => {
     770        Name => 'Contrast',
     771        ValueConv => '$val - 10',
     772        ValueConvInv => '$val + 10',
     773        PrintConv => '$val > 0 ? "+$val" : $val',
     774        PrintConvInv => '$val',
     775    },
     776    0x1e => {
     777        Name => 'Saturation',
     778        ValueConv => '$val - 10',
     779        ValueConvInv => '$val + 10',
     780        PrintConv => '$val > 0 ? "+$val" : $val',
     781        PrintConvInv => '$val',
     782    },
     783    0x1f => { #7
     784        Name => 'ZoneMatchingValue',
     785        Condition => '$$self{Model} !~ /DSLR-A230/',
     786        ValueConv => '$val - 10',
     787        ValueConvInv => '$val + 10',
     788        PrintConv => '$val > 0 ? "+$val" : $val',
     789        PrintConvInv => '$val',
     790    },
     791    0x22 => { #7
     792        Name => 'Brightness',
     793        Condition => '$$self{Model} !~ /DSLR-A230/',
     794        ValueConv => '$val - 10',
     795        ValueConvInv => '$val + 10',
     796        PrintConv => '$val > 0 ? "+$val" : $val',
     797        PrintConvInv => '$val',
     798    },
     799    0x23 => {
     800        Name => 'FlashMode',
     801        PrintConv => {
     802            0 => 'ADI',
     803            1 => 'TTL',
     804        },
     805    },
     806    0x28 => { #7
     807        Name => 'PrioritySetupShutterRelease',
     808        Condition => '$$self{Model} =~ /DSLR-A700\b/',
     809        Notes => 'A700 only',
     810        PrintConv => {
     811            0 => 'AF',
     812            1 => 'Release',
     813        },
     814    },
     815    0x29 => { #7
     816        Name => 'AFIlluminator',
     817        Condition => '$$self{Model} =~ /DSLR-A700\b/',
     818        Notes => 'A700 only',
     819        PrintConv => {
     820            0 => 'Auto',
     821            1 => 'Off',
     822        },
     823    },
     824    0x2a => { #7
     825        Name => 'AFWithShutter',
     826        Condition => '$$self{Model} =~ /DSLR-A700\b/',
     827        Notes => 'A700 only',
     828        PrintConv => { 0 => 'On', 1 => 'Off' },
     829    },
     830    0x2b => { #7
     831        Name => 'LongExposureNoiseReduction',
     832        Condition => '$$self{Model} =~ /DSLR-A700\b/',
     833        Notes => 'A700 only',
    129834        PrintConv => { 0 => 'Off', 1 => 'On' },
    130835    },
     836    0x2c => { #7
     837        Name => 'HighISONoiseReduction',
     838        Condition => '$$self{Model} =~ /DSLR-A700\b/',
     839        Notes => 'A700 only',
     840        0 => 'Normal',
     841        1 => 'Low',
     842        2 => 'High',
     843        3 => 'Off',
     844    },
     845    0x2d => { #7
     846        Name => 'ImageStyle',
     847        Condition => '$$self{Model} =~ /DSLR-A700\b/',
     848        Notes => 'A700 only',
     849        PrintConv => {
     850            1 => 'Standard',
     851            2 => 'Vivid',
     852            9 => 'Adobe RGB',
     853            11 => 'Neutral',
     854            129 => 'StyleBox1',
     855            130 => 'StyleBox2',
     856            131 => 'StyleBox3',
     857        },
     858    },
     859    # 0x2d - A900:1=?,4=?,129=std,130=vivid,131=neutral,132=portrait,133=landscape,134=b&w
     860    0x3c => {
     861        Name => 'ExposureProgram',
     862        Priority => 0,
     863        PrintConv => \%sonyExposureProgram,
     864    },
     865    0x3d => {
     866        Name => 'ImageStabilization',
     867        PrintConv => { 0 => 'Off', 1 => 'On' },
     868    },
     869    0x3f => { # (verified for A330/A380)
     870        Name => 'Rotation',
     871        PrintConv => {
     872            0 => 'Horizontal (normal)',
     873            1 => 'Rotate 90 CW', #(NC)
     874            2 => 'Rotate 270 CW',
     875        },
     876    },
     877    0x54 => {
     878        Name => 'SonyImageSize',
     879        PrintConv => {
     880            1 => 'Large',
     881            2 => 'Medium',
     882            3 => 'Small',
     883        },
     884    },
     885    0x55 => { #7
     886        Name => 'AspectRatio',
     887        PrintConv => {
     888            1 => '3:2',
     889            2 => '16:9',
     890        },
     891    },
     892    0x56 => { #PH/7
     893        Name => 'Quality',
     894        PrintConv => {
     895            0 => 'RAW',
     896            2 => 'CRAW',
     897            34 => 'RAW + JPEG',
     898            35 => 'CRAW + JPEG',
     899            16 => 'Extra Fine',
     900            32 => 'Fine',
     901            48 => 'Standard',
     902        },
     903    },
     904    0x58 => { #7
     905        Name => 'ExposureLevelIncrements',
     906        PrintConv => {
     907            33 => '1/3 EV',
     908            50 => '1/2 EV',
     909        },
     910    },           
    131911);
    132912
    133 # tag table for Sony RAW Format
     913# Camera settings (ref PH) (A330 and A380)
     914%Image::ExifTool::Sony::CameraSettings2 = (
     915    %binaryDataAttrs,
     916    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     917    FORMAT => 'int16u',
     918    NOTES => 'Camera settings for the A330 and A380.',
     919    0x10 => { #7 (A700, not confirmed for other models)
     920        Name => 'FocusMode',
     921        PrintConv => {
     922            0 => 'Manual',
     923            1 => 'AF-S',
     924            2 => 'AF-C',
     925            3 => 'AF-A',
     926        },
     927    },
     928    0x11 => { #JD (A700)
     929        Name => 'AFAreaMode',
     930        PrintConv => {
     931            0 => 'Wide',
     932            1 => 'Local',
     933            2 => 'Spot',
     934        },
     935    },
     936    0x12 => { #7 (A700, not confirmed for other models)
     937        Name => 'LocalAFAreaPoint',
     938        Format => 'int16u',
     939        PrintConv => {
     940            1 => 'Center',
     941            2 => 'Top',
     942            3 => 'Top-Right',
     943            4 => 'Right',
     944            5 => 'Bottom-Right',
     945            6 => 'Bottom',
     946            7 => 'Bottom-Left',
     947            8 => 'Left',
     948            9 => 'Top-Left',
     949            10 => 'Far Right',
     950            11 => 'Far Left',
     951            # see value of 128 for some models
     952        },
     953    },
     954    0x13 => {
     955        Name => 'MeteringMode',
     956        PrintConv => {
     957            1 => 'Multi-segment',
     958            2 => 'Center-weighted Average',
     959            4 => 'Spot',
     960        },
     961    },
     962    0x14 => { # A330/A380
     963        Name => 'ISOSetting',
     964        # 0 indicates 'Auto' (?)
     965        ValueConv => '$val ? exp(($val/8-6)*log(2))*100 : $val',
     966        ValueConvInv => '$val ? 8*(log($val/100)/log(2)+6) : $val',
     967        PrintConv => '$val ? sprintf("%.0f",$val) : "Auto"',
     968        PrintConvInv => '$val =~ /auto/i ? 0 : $val',
     969    },
     970    0x16 => {
     971        Name => 'DynamicRangeOptimizerMode',
     972        PrintConv => {
     973            0 => 'Off',
     974            1 => 'Standard',
     975            2 => 'Advanced Auto',
     976            3 => 'Advanced Level',
     977        },
     978    },
     979    0x17 => {
     980        Name => 'DynamicRangeOptimizerLevel',
     981    },
     982    0x18 => { # A380
     983        Name => 'CreativeStyle',
     984        PrintConv => {
     985            1 => 'Standard',
     986            2 => 'Vivid',
     987            3 => 'Portrait',
     988            4 => 'Landscape',
     989            5 => 'Sunset',
     990            6 => 'Night View/Portrait',
     991            8 => 'B&W',
     992            9 => 'Adobe RGB',
     993            11 => 'Neutral',
     994        },
     995    },
     996    0x19 => {
     997        Name => 'Sharpness',
     998        ValueConv => '$val - 10',
     999        ValueConvInv => '$val + 10',
     1000        PrintConv => '$val > 0 ? "+$val" : $val',
     1001        PrintConvInv => '$val',
     1002    },
     1003    0x1a => {
     1004        Name => 'Contrast',
     1005        ValueConv => '$val - 10',
     1006        ValueConvInv => '$val + 10',
     1007        PrintConv => '$val > 0 ? "+$val" : $val',
     1008        PrintConvInv => '$val',
     1009    },
     1010    0x1b => {
     1011        Name => 'Saturation',
     1012        ValueConv => '$val - 10',
     1013        ValueConvInv => '$val + 10',
     1014        PrintConv => '$val > 0 ? "+$val" : $val',
     1015        PrintConvInv => '$val',
     1016    },
     1017    0x23 => {
     1018        Name => 'FlashMode',
     1019        PrintConv => {
     1020            0 => 'ADI',
     1021            1 => 'TTL',
     1022        },
     1023    },
     1024    # 0x27 - also related to CreativeStyle:
     1025    #  A380:1=std,2=vivid,3=portrait,4=landscape,5=sunset,7=night view,8=b&w
     1026    0x3c => {
     1027        Name => 'ExposureProgram',
     1028        Priority => 0,
     1029        PrintConv => \%sonyExposureProgram,
     1030    },
     1031    0x3f => { # (verified for A330/A380)
     1032        Name => 'Rotation',
     1033        PrintConv => {
     1034            0 => 'Horizontal (normal)',
     1035            1 => 'Rotate 90 CW', #(NC)
     1036            2 => 'Rotate 270 CW',
     1037        },
     1038    },
     1039    0x54 => {
     1040        Name => 'SonyImageSize',
     1041        PrintConv => {
     1042            1 => 'Large',
     1043            2 => 'Medium',
     1044            3 => 'Small',
     1045        },
     1046    },
     1047    # 0x56 - something to do with JPEG quality?
     1048);
     1049
     1050# Camera settings for other models
     1051%Image::ExifTool::Sony::CameraSettingsUnknown = (
     1052    %binaryDataAttrs,
     1053    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     1054    FORMAT => 'int16u',
     1055);
     1056
     1057# shot information (ref PH)
     1058%Image::ExifTool::Sony::ShotInfo = (
     1059    %binaryDataAttrs,
     1060    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     1061    DATAMEMBER => [ 0x02, 0x30, 0x32 ],
     1062    IS_SUBDIR => [ 0x48, 0x5e ],
     1063    # 0x00 - byte order 'II'
     1064    0x02 => {
     1065        Name => 'FaceInfoOffset',
     1066        Format => 'int16u',
     1067        DataMember => 'FaceInfoOffset',
     1068        Writable => 0,
     1069        RawConv => '$$self{FaceInfoOffset} = $val',
     1070    },
     1071    0x06 => {
     1072        Name => 'SonyDateTime',
     1073        Format => 'string[20]',
     1074        Groups => { 2 => 'Time' },
     1075        Shift => 'Time',
     1076        PrintConv => '$self->ConvertDateTime($val)',
     1077        PrintConvInv => '$self->InverseDateTime($val,0)',
     1078    },
     1079    0x30 => { #Jeffrey Friedl
     1080        Name => 'FacesDetected',
     1081        DataMember => 'FacesDetected',
     1082        Format => 'int16u',
     1083        RawConv => '$$self{FacesDetected} = $val',
     1084    },
     1085    0x32 => {
     1086        Name => 'FaceInfoLength', # length of a single FaceInfo entry
     1087        DataMember => 'FaceInfoLength',
     1088        Format => 'int16u',
     1089        Writable => 0,
     1090        RawConv => '$$self{FaceInfoLength} = $val',
     1091    },
     1092    #0x34 => {
     1093    #    # values: 'DC5303320222000', 'DC6303320222000' or 'DC7303320222000'
     1094    #    Name => 'UnknownString',
     1095    #    Format => 'string[16]',
     1096    #    Unknown => 1,
     1097    #},
     1098    0x48 => { # (most models: DC5303320222000 and DC6303320222000)
     1099        Name => 'FaceInfo1',
     1100        Condition => q{
     1101            $$self{FacesDetected} and
     1102            $$self{FaceInfoOffset} == 0x48 and
     1103            $$self{FaceInfoLength} == 0x20
     1104        },
     1105        SubDirectory => { TagTable => 'Image::ExifTool::Sony::FaceInfo1' },
     1106    },
     1107    0x5e => { # (HX7V: DC7303320222000)
     1108        Name => 'FaceInfo2',
     1109        Condition => q{
     1110            $$self{FacesDetected} and
     1111            $$self{FaceInfoOffset} == 0x5e and
     1112            $$self{FaceInfoLength} == 0x25
     1113        },
     1114        SubDirectory => { TagTable => 'Image::ExifTool::Sony::FaceInfo2' },
     1115    },
     1116);
     1117
     1118%Image::ExifTool::Sony::FaceInfo1 = (
     1119    %binaryDataAttrs,
     1120    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     1121    0x00 => {
     1122        Name => 'Face1Position',
     1123        Format => 'int16u[4]',
     1124        RawConv => '$$self{FacesDetected} < 1 ? undef : $val',
     1125        Notes => q{
     1126            top, left, height and width of detected face.  Coordinates are relative to
     1127            the full-sized unrotated image, with increasing Y downwards
     1128        },
     1129    },
     1130    0x20 => {
     1131        Name => 'Face2Position',
     1132        Format => 'int16u[4]',
     1133        RawConv => '$$self{FacesDetected} < 2 ? undef : $val',
     1134    },
     1135    0x40 => {
     1136        Name => 'Face3Position',
     1137        Format => 'int16u[4]',
     1138        RawConv => '$$self{FacesDetected} < 3 ? undef : $val',
     1139    },
     1140    0x60 => {
     1141        Name => 'Face4Position',
     1142        Format => 'int16u[4]',
     1143        RawConv => '$$self{FacesDetected} < 4 ? undef : $val',
     1144    },
     1145    0x80 => {
     1146        Name => 'Face5Position',
     1147        Format => 'int16u[4]',
     1148        RawConv => '$$self{FacesDetected} < 5 ? undef : $val',
     1149    },
     1150    0xa0 => {
     1151        Name => 'Face6Position',
     1152        Format => 'int16u[4]',
     1153        RawConv => '$$self{FacesDetected} < 6 ? undef : $val',
     1154    },
     1155    0xc0 => {
     1156        Name => 'Face7Position',
     1157        Format => 'int16u[4]',
     1158        RawConv => '$$self{FacesDetected} < 7 ? undef : $val',
     1159    },
     1160    0xe0 => {
     1161        Name => 'Face8Position',
     1162        Format => 'int16u[4]',
     1163        RawConv => '$$self{FacesDetected} < 8 ? undef : $val',
     1164    },
     1165);
     1166
     1167%Image::ExifTool::Sony::FaceInfo2 = (
     1168    %binaryDataAttrs,
     1169    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     1170    0x00 => {
     1171        Name => 'Face1Position',
     1172        Format => 'int16u[4]',
     1173        RawConv => '$$self{FacesDetected} < 1 ? undef : $val',
     1174        Notes => q{
     1175            top, left, height and width of detected face.  Coordinates are relative to
     1176            the full-sized unrotated image, with increasing Y downwards
     1177        },
     1178    },
     1179    0x25 => {
     1180        Name => 'Face2Position',
     1181        Format => 'int16u[4]',
     1182        RawConv => '$$self{FacesDetected} < 2 ? undef : $val',
     1183    },
     1184    0x4a => {
     1185        Name => 'Face3Position',
     1186        Format => 'int16u[4]',
     1187        RawConv => '$$self{FacesDetected} < 3 ? undef : $val',
     1188    },
     1189    0x6f => {
     1190        Name => 'Face4Position',
     1191        Format => 'int16u[4]',
     1192        RawConv => '$$self{FacesDetected} < 4 ? undef : $val',
     1193    },
     1194    0x94 => {
     1195        Name => 'Face5Position',
     1196        Format => 'int16u[4]',
     1197        RawConv => '$$self{FacesDetected} < 5 ? undef : $val',
     1198    },
     1199    0xb9 => {
     1200        Name => 'Face6Position',
     1201        Format => 'int16u[4]',
     1202        RawConv => '$$self{FacesDetected} < 6 ? undef : $val',
     1203    },
     1204    0xde => {
     1205        Name => 'Face7Position',
     1206        Format => 'int16u[4]',
     1207        RawConv => '$$self{FacesDetected} < 7 ? undef : $val',
     1208    },
     1209    0x103 => {
     1210        Name => 'Face8Position',
     1211        Format => 'int16u[4]',
     1212        RawConv => '$$self{FacesDetected} < 8 ? undef : $val',
     1213    },
     1214);
     1215
     1216# panorama info for cameras such as the HX1, HX5, TX7 (ref 9/PH)
     1217%Image::ExifTool::Sony::Panorama = (
     1218    %binaryDataAttrs,
     1219    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     1220    FORMAT => 'int32u',
     1221    NOTES => q{
     1222        Tags found only in panorama images from Sony cameras such as the HX1, HX5
     1223        and TX7.  The width/height values of these tags are not affected by camera
     1224        rotation -- the width is always the longer dimension.
     1225    },
     1226    # 0: 257
     1227    1 => 'PanoramaFullWidth', # (including black/grey borders)
     1228    2 => 'PanoramaFullHeight',
     1229    3 => {
     1230        Name => 'PanoramaDirection',
     1231        PrintConv => {
     1232            0 => 'Right to Left',
     1233            1 => 'Left to Right',
     1234        },
     1235    },
     1236    # crop area to remove black/grey borders from full image
     1237    4 => 'PanoramaCropLeft',
     1238    5 => 'PanoramaCropTop', #PH guess (NC)
     1239    6 => 'PanoramaCropRight',
     1240    7 => 'PanoramaCropBottom',
     1241    # 8: 1728 (HX1), 1824 (HX5/TX7) (value8/value9 = 16/9)
     1242    8 => 'PanoramaFrameWidth', #PH guess (NC)
     1243    # 9: 972 (HX1), 1026 (HX5/TX7)
     1244    9 => 'PanoramaFrameHeight', #PH guess (NC)
     1245    # 10: 3200-3800 (HX1), 4000-4900 (HX5/TX7)
     1246    10 => 'PanoramaSourceWidth', #PH guess (NC)
     1247    # 11: 800-1800 (larger for taller panoramas)
     1248    11 => 'PanoramaSourceHeight', #PH guess (NC)
     1249    # 12-15: 0
     1250);
     1251
     1252# tag table for SRF0 IFD (ref 1)
    1341253%Image::ExifTool::Sony::SRF = (
    1351254    PROCESS_PROC => \&ProcessSRF,
    1361255    GROUPS => { 0 => 'MakerNotes', 1 => 'SRF#', 2 => 'Camera' },
    1371256    NOTES => q{
    138         The maker notes in SRF (Sony Raw Format) images contain 7 IFD's (with family
    139         1 group names SRF0 through SRF6).  SRF0 through SRF5 use these Sony tags,
    140         while SRF6 uses standard EXIF tags.  All information other than SRF0 is
    141         encrypted, but thanks to Dave Coffin the decryption algorithm is known.
    142     },
     1257        The maker notes in SRF (Sony Raw Format) images contain 7 IFD's with family
     1258        1 group names SRF0 through SRF6.  SRF0 and SRF1 use the tags in this table,
     1259        while SRF2 through SRF5 use the tags in the next table, and SRF6 uses
     1260        standard EXIF tags.  All information other than SRF0 is encrypted, but
     1261        thanks to Dave Coffin the decryption algorithm is known.  SRF images are
     1262        written by the Sony DSC-F828 and DSC-V3.
     1263    },
     1264    # tags 0-1 are used in SRF1
    1431265    0 => {
    144         Name => 'SRF2_Key',
     1266        Name => 'SRF2Key',
    1451267        Notes => 'key to decrypt maker notes from the start of SRF2',
    146         RawConv => '$self->{SRF2_Key} = $val',
     1268        RawConv => '$self->{SRF2Key} = $val',
    1471269    },
    1481270    1 => {
     
    1511273        RawConv => '$self->{SRFDataKey} = $val',
    1521274    },
     1275    # SRF0 contains a single unknown tag with TagID 0x0003
     1276);
     1277
     1278# tag table for Sony RAW Format (ref 1)
     1279%Image::ExifTool::Sony::SRF2 = (
     1280    PROCESS_PROC => \&ProcessSRF,
     1281    GROUPS => { 0 => 'MakerNotes', 1 => 'SRF#', 2 => 'Camera' },
     1282    NOTES => "These tags are found in the SRF2 through SRF5 IFD's.",
     1283    # the following tags are used in SRF2-5
     1284    2 => 'SRF6Offset', #PH
     1285    # SRFDataOffset references 2220 bytes of unknown data for the DSC-F828 - PH
     1286    3 => { Name => 'SRFDataOffset', Unknown => 1 }, #PH
     1287    4 => { Name => 'RawDataOffset' }, #PH
     1288    5 => { Name => 'RawDataLength' }, #PH
    1531289);
    1541290
     
    1561292%Image::ExifTool::Sony::SR2Private = (
    1571293    PROCESS_PROC => \&ProcessSR2,
     1294    WRITE_PROC => \&WriteSR2,
    1581295    GROUPS => { 0 => 'MakerNotes', 1 => 'SR2', 2 => 'Camera' },
    1591296    NOTES => q{
    1601297        The SR2 format uses the DNGPrivateData tag to reference a private IFD
    161         containing these tags.
     1298        containing these tags.  SR2 images are written by the Sony DSC-R1, but
     1299        this information is also written to ARW images by other models.
    1621300    },
    1631301    0x7200 => {
     
    1651303        # (adjusting offset messes up calculations for AdobeSR2 in DNG images)
    1661304        # Flags => 'IsOffset',
    167         OffsetPair => 0x7201,
    168         RawConv => '$self->{SR2SubIFDOffset} = $val',
     1305        # (can't set OffsetPair or else DataMember won't be set when writing)
     1306        # OffsetPair => 0x7201,
     1307        DataMember => 'SR2SubIFDOffset',
     1308        RawConv => '$$self{SR2SubIFDOffset} = $val',
    1691309    },
    1701310    0x7201 => {
    1711311        Name => 'SR2SubIFDLength',
    172         OffsetPair => 0x7200,
    173         RawConv => '$self->{SR2SubIFDLength} = $val',
     1312        # (can't set OffsetPair or else DataMember won't be set when writing)
     1313        # OffsetPair => 0x7200,
     1314        DataMember => 'SR2SubIFDLength',
     1315        RawConv => '$$self{SR2SubIFDLength} = $val',
    1741316    },
    1751317    0x7221 => {
     
    1771319        Format => 'int32u',
    1781320        Notes => 'key to decrypt SR2SubIFD',
    179         RawConv => '$self->{SR2SubIFDKey} = $val',
     1321        DataMember => 'SR2SubIFDKey',
     1322        RawConv => '$$self{SR2SubIFDKey} = $val',
     1323        PrintConv => 'sprintf("0x%.8x", $val)',
     1324    },
     1325    0x7240 => { #PH
     1326        Name => 'IDC_IFD',
     1327        Groups => { 1 => 'SonyIDC' },
     1328        Condition => '$$valPt !~ /^\0\0\0\0/',   # (just in case this could be zero)
     1329        Flags => 'SubIFD',
     1330        SubDirectory => {
     1331            DirName => 'SonyIDC',
     1332            TagTable => 'Image::ExifTool::SonyIDC::Main',
     1333            Start => '$val',
     1334        },
     1335    },
     1336    0x7241 => { #PH
     1337        Name => 'IDC2_IFD',
     1338        Groups => { 1 => 'SonyIDC' },
     1339        Condition => '$$valPt !~ /^\0\0\0\0/',   # may be zero if dir doesn't exist
     1340        Flags => 'SubIFD',
     1341        SubDirectory => {
     1342            DirName => 'SonyIDC2',
     1343            TagTable => 'Image::ExifTool::SonyIDC::Main',
     1344            Start => '$val',
     1345            Base => '$start',
     1346            MaxSubdirs => 20,   # (A900 has 10 null entries, but IDC writes only 1)
     1347            RelativeBase => 1,  # needed to write SubIFD with relative offsets
     1348        },
     1349    },
     1350    0x7250 => { #1
     1351        Name => 'MRWInfo',
     1352        Condition => '$$valPt !~ /^\0\0\0\0/',   # (just in case this could be zero)
     1353        SubDirectory => {
     1354            TagTable => 'Image::ExifTool::MinoltaRaw::Main',
     1355        },
    1801356    },
    1811357);
    1821358
    1831359%Image::ExifTool::Sony::SR2SubIFD = (
    184     GROUPS => { 0 => 'MakerNotes', 1 => 'SR2', 2 => 'Camera' },
     1360    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     1361    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     1362    GROUPS => { 0 => 'MakerNotes', 1 => 'SR2SubIFD', 2 => 'Camera' },
     1363    SET_GROUP1 => 1, # set group1 name to directory name for all tags in table
    1851364    NOTES => 'Tags in the encrypted SR2SubIFD',
    1861365    0x7303 => 'WB_GRBGLevels', #1
    1871366    0x74c0 => { #PH
    1881367        Name => 'SR2DataIFD',
     1368        Groups => { 1 => 'SR2DataIFD' }, # (needed to set SubIFD DirName)
    1891369        Flags => 'SubIFD',
    1901370        SubDirectory => {
    1911371            TagTable => 'Image::ExifTool::Sony::SR2DataIFD',
    1921372            Start => '$val',
    193             MaxSubdirs => 6,
    194         },
    195     },
     1373            MaxSubdirs => 20, # an A700 ARW has 14 of these! - PH
     1374        },
     1375    },
     1376    0x7313 => 'WB_RGGBLevels', #6
    1961377    0x74a0 => 'MaxApertureAtMaxFocal', #PH
    1971378    0x74a1 => 'MaxApertureAtMinFocal', #PH
     1379    0x7820 => 'WB_RGBLevelsDaylight', #6
     1380    0x7821 => 'WB_RGBLevelsCloudy', #6
     1381    0x7822 => 'WB_RGBLevelsTungsten', #6
     1382    0x7825 => 'WB_RGBLevelsShade', #6
     1383    0x7826 => 'WB_RGBLevelsFluorescent', #6
     1384    0x7828 => 'WB_RGBLevelsFlash', #6
    1981385);
    1991386
    2001387%Image::ExifTool::Sony::SR2DataIFD = (
    201     GROUPS => { 0 => 'MakerNotes', 1 => 'SR2', 2 => 'Camera' },
    202     0x7770 => 'ColorMode', #PH
     1388    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     1389    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     1390    GROUPS => { 0 => 'MakerNotes', 1 => 'SR2DataIFD', 2 => 'Camera' },
     1391    SET_GROUP1 => 1, # set group1 name to directory name for all tags in table
     1392    # 0x7313 => 'WB_RGGBLevels', (duplicated in all SR2DataIFD's)
     1393    0x7770 => { #PH
     1394        Name => 'ColorMode',
     1395        Priority => 0,
     1396    },
    2031397);
    2041398
    205 # fill in Sony LensID lookup based on Minolta values
     1399# tags found in DSC-F1 PMP header (ref 10)
     1400%Image::ExifTool::Sony::PMP = (
     1401    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1402    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     1403    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     1404    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     1405    FIRST_ENTRY => 0,
     1406    NOTES => q{
     1407        These tags are written in the proprietary-format header of PMP images from
     1408        the DSC-F1.
     1409    },
     1410    8 => { #PH
     1411        Name => 'JpgFromRawStart',
     1412        Format => 'int32u',
     1413        Notes => q{
     1414            OK, not really a RAW file, but this mechanism is used to allow extraction of
     1415            the JPEG image from a PMP file
     1416        },
     1417    },
     1418    12 => { Name => 'JpgFromRawLength',Format => 'int32u' },
     1419    22 => { Name => 'SonyImageWidth',  Format => 'int16u' },
     1420    24 => { Name => 'SonyImageHeight', Format => 'int16u' },
     1421    27 => {
     1422        Name => 'Orientation',
     1423        PrintConv => {
     1424            0 => 'Horizontal (normal)',
     1425            1 => 'Rotate 270 CW',#11
     1426            2 => 'Rotate 180',
     1427            3 => 'Rotate 90 CW',#11
     1428        },
     1429    },
     1430    29 => {
     1431        Name => 'ImageQuality',
     1432        PrintConv => {
     1433            8 => 'Snap Shot',
     1434            23 => 'Standard',
     1435            51 => 'Fine',
     1436        },
     1437    },
     1438    # 40 => ImageWidth again (int16u)
     1439    # 42 => ImageHeight again (int16u)
     1440    52 => { Name => 'Comment',         Format => 'string[19]' },
     1441    76 => {
     1442        Name => 'DateTimeOriginal',
     1443        Description => 'Date/Time Original',
     1444        Format => 'int8u[6]',
     1445        Groups => { 2 => 'Time' },
     1446        ValueConv => q{
     1447            my @a = split ' ', $val;
     1448            $a[0] += $a[0] < 70 ? 2000 : 1900;
     1449            sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', @a);
     1450        },
     1451        PrintConv => '$self->ConvertDateTime($val)',
     1452    },
     1453    84 => {
     1454        Name => 'ModifyDate',
     1455        Format => 'int8u[6]',
     1456        Groups => { 2 => 'Time' },
     1457        ValueConv => q{
     1458            my @a = split ' ', $val;
     1459            $a[0] += $a[0] < 70 ? 2000 : 1900;
     1460            sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', @a);
     1461        },
     1462        PrintConv => '$self->ConvertDateTime($val)',
     1463    },
     1464    102 => {
     1465        Name => 'ExposureTime',
     1466        Format => 'int16s',
     1467        RawConv => '$val <= 0 ? undef : $val',
     1468        ValueConv => '2 ** (-$val / 100)',
     1469        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     1470    },
     1471    106 => { # (NC -- not written by DSC-F1)
     1472        Name => 'FNumber',
     1473        Format => 'int16s',
     1474        RawConv => '$val <= 0 ? undef : $val',
     1475        ValueConv => '$val / 100', # (likely wrong)
     1476    },
     1477    108 => { # (NC -- not written by DSC-F1)
     1478        Name => 'ExposureCompensation',
     1479        Format => 'int16s',
     1480        RawConv => '($val == -1 or $val == -32768) ? undef : $val',
     1481        ValueConv => '$val / 100', # (probably wrong too)
     1482    },
     1483    112 => { # (NC -- not written by DSC-F1)
     1484        Name => 'FocalLength',
     1485        Format => 'int16s',
     1486        Groups => { 2 => 'Camera' },
     1487        RawConv => '$val <= 0 ? undef : $val',
     1488        ValueConv => '$val / 100',
     1489        PrintConv => 'sprintf("%.1f mm",$val)',
     1490    },
     1491    118 => {
     1492        Name => 'Flash',
     1493        Groups => { 2 => 'Camera' },
     1494        PrintConv => { 0 => 'No Flash', 1 => 'Fired' },
     1495    },
     1496);
     1497
     1498# fill in Sony LensType lookup based on Minolta values
    2061499{
     1500    my $minoltaTypes = \%Image::ExifTool::Minolta::minoltaLensTypes;
     1501    %sonyLensTypes = %$minoltaTypes;
     1502    my $notes = $$minoltaTypes{Notes};
     1503    delete $$minoltaTypes{Notes};
    2071504    my $id;
    208     foreach $id (keys %Image::ExifTool::Minolta::minoltaLensIDs) {
    209         # higher numbered lenses are missing last digit of ID
    210         my $sonyID = ($id < 10000) ? $id : int($id / 10);
    211         $sonyLensIDs{$sonyID} = $Image::ExifTool::Minolta::minoltaLensIDs{$id};
     1505    foreach $id (sort { $a <=> $b } keys %$minoltaTypes) {
     1506        # higher numbered lenses are missing last digit of ID for some Sony models
     1507        next if $id < 10000;
     1508        my $sid = int($id/10);
     1509        my $i;
     1510        my $lens = $$minoltaTypes{$id};
     1511        if ($sonyLensTypes{$sid}) {
     1512            # put lens name with "or" first in list
     1513            if ($lens =~ / or /) {
     1514                my $tmp = $sonyLensTypes{$sid};
     1515                $sonyLensTypes{$sid} = $lens;
     1516                $lens = $tmp;
     1517            }
     1518            for (;;) {
     1519                $i = ($i || 0) + 1;
     1520                $sid = int($id/10) . ".$i";
     1521                last unless $sonyLensTypes{$sid};
     1522            }
     1523        }
     1524        $sonyLensTypes{$sid} = $lens;
    2121525    }
     1526    $$minoltaTypes{Notes} = $sonyLensTypes{Notes} = $notes;
    2131527}
    2141528
    2151529#------------------------------------------------------------------------------
    216 # decrypt Sony data (ref 1)
     1530# Read Sony DSC-F1 PMP file
     1531# Inputs: 0) ExifTool object ref, 1) dirInfo ref
     1532# Returns: 1 on success when reading, 0 if this isn't a valid PMP file
     1533sub ProcessPMP($$)
     1534{
     1535    my ($exifTool, $dirInfo) = @_;
     1536    my $raf = $$dirInfo{RAF};
     1537    my $buff;
     1538    $raf->Read($buff, 128) == 128 or return 0;
     1539    # validate header length (124 bytes)
     1540    $buff =~ /^.{8}\0{3}\x7c.{112}\xff\xd8\xff\xdb$/s or return 0;
     1541    $exifTool->SetFileType();
     1542    SetByteOrder('MM');
     1543    $exifTool->FoundTag(Make => 'Sony');
     1544    $exifTool->FoundTag(Model => 'DSC-F1');
     1545    # extract information from 124-byte header
     1546    my $tagTablePtr = GetTagTable('Image::ExifTool::Sony::PMP');
     1547    my %dirInfo = ( DataPt => \$buff, DirName => 'PMP' );
     1548    $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
     1549    # process JPEG image
     1550    $raf->Seek(124, 0);
     1551    $$dirInfo{Base} = 124;
     1552    $exifTool->ProcessJPEG($dirInfo);
     1553    return 1;
     1554}
     1555
     1556#------------------------------------------------------------------------------
     1557# Decrypt Sony data (ref 1)
    2171558# Inputs: 0) data reference, 1) start offset, 2) data length, 3) decryption key
    2181559# Returns: nothing (original data buffer is updated with decrypted data)
     1560# Notes: data length should be a multiple of 4
    2191561sub Decrypt($$$$)
    2201562{
    2211563    my ($dataPt, $start, $len, $key) = @_;
    2221564    my ($i, $j, @pad);
    223     my $words = $len / 4;
     1565    my $words = int ($len / 4);
    2241566
    2251567    for ($i=0; $i<4; ++$i) {
     
    2411583
    2421584#------------------------------------------------------------------------------
     1585# Set the ARW file type and decide between SubIFD and A100DataOffset
     1586# Inputs: 0) ExifTool object ref, 1) reference to tag 0x14a raw data
     1587# Returns: true if tag 0x14a is a SubIFD, false otherwise
     1588sub SetARW($$)
     1589{
     1590    my ($exifTool, $valPt) = @_;
     1591
     1592    # assume ARW for now -- SR2's get identified when FileFormat is parsed
     1593    $exifTool->OverrideFileType($$exifTool{TIFF_TYPE} = 'ARW');
     1594
     1595    # this should always be a SubIFD for models other than the A100
     1596    return 1 unless $$exifTool{Model} eq 'DSLR-A100' and length $$valPt == 4;
     1597
     1598    # for the A100, IFD0 tag 0x14a is either a pointer to the raw data if this is
     1599    # an original image, or a SubIFD offset if the image was edited by Sony IDC,
     1600    # so assume it points to the raw data if it isn't a valid IFD (this assumption
     1601    # will be checked later when we try to parse the SR2Private directory)
     1602    my %subdir = (
     1603        DirStart => Get32u($valPt, 0),
     1604        Base     => 0,
     1605        RAF      => $$exifTool{RAF},
     1606        AllowOutOfOrderTags => 1, # doh!
     1607    );
     1608    return Image::ExifTool::Exif::ValidateIFD(\%subdir);
     1609}
     1610
     1611#------------------------------------------------------------------------------
     1612# Finish writing ARW image, patching necessary Sony quirks, etc
     1613# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) EXIF data ref, 3) image data reference
     1614# Returns: undef on success, error string otherwise
     1615# Notes: (it turns that all of this is for the A100 only)
     1616sub FinishARW($$$$)
     1617{
     1618    my ($exifTool, $dirInfo, $dataPt, $imageData) = @_;
     1619
     1620    # pre-scan IFD0 to get IFD entry offsets for each tag
     1621    my $dataLen = length $$dataPt;
     1622    return 'Truncated IFD0' if $dataLen < 2;
     1623    my $n = Get16u($dataPt, 0);
     1624    return 'Truncated IFD0' if $dataLen < 2 + 12 * $n;
     1625    my ($i, %entry, $dataBlock, $pad, $dataOffset);
     1626    for ($i=0; $i<$n; ++$i) {
     1627        my $entry = 2 + $i * 12;
     1628        $entry{Get16u($dataPt, $entry)} = $entry;
     1629    }
     1630    # fix up SR2Private offset and A100DataOffset (A100 only)
     1631    if ($entry{0xc634} and $$exifTool{MRWDirData}) {
     1632        return 'Unexpected MRW block' unless $$exifTool{Model} eq 'DSLR-A100';
     1633        return 'Missing A100DataOffset' unless $entry{0x14a} and $$exifTool{A100DataOffset};
     1634        # account for total length of image data
     1635        my $totalLen = 8 + $dataLen;
     1636        if (ref $imageData) {
     1637            foreach $dataBlock (@$imageData) {
     1638                my ($pos, $size, $pad) = @$dataBlock;
     1639                $totalLen += $size + $pad;
     1640            }
     1641        }
     1642        # align MRW block on an even 4-byte boundary
     1643        my $remain = $totalLen & 0x03;
     1644        $pad = 4 - $remain and $totalLen += $pad if $remain;
     1645        # set offset for the MRW directory data
     1646        Set32u($totalLen, $dataPt, $entry{0xc634} + 8);
     1647        # also pad MRWDirData data to an even 4 bytes (just to be safe)
     1648        $remain = length($$exifTool{MRWDirData}) & 0x03;
     1649        $$exifTool{MRWDirData} .= "\0" x (4 - $remain) if $remain;
     1650        $totalLen += length $$exifTool{MRWDirData};
     1651        # fix up A100DataOffset
     1652        $dataOffset = $$exifTool{A100DataOffset};
     1653        Set32u($totalLen, $dataPt, $entry{0x14a} + 8);
     1654    }
     1655    # patch double-referenced and incorrectly-sized A100 PreviewImage
     1656    if ($entry{0x201} and $$exifTool{A100PreviewStart} and
     1657        $entry{0x202} and $$exifTool{A100PreviewLength})
     1658    {
     1659        Set32u($$exifTool{A100PreviewStart}, $dataPt, $entry{0x201} + 8);
     1660        Set32u($$exifTool{A100PreviewLength}, $dataPt, $entry{0x202} + 8);
     1661    }
     1662    # write TIFF IFD structure
     1663    my $outfile = $$dirInfo{OutFile};
     1664    my $header = GetByteOrder() . Set16u(0x2a) . Set32u(8);
     1665    Write($outfile, $header, $$dataPt) or return 'Error writing';
     1666    # copy over image data
     1667    if (ref $imageData) {
     1668        $exifTool->CopyImageData($imageData, $outfile) or return 'Error copying image data';
     1669    }
     1670    # write MRW data if necessary
     1671    if ($$exifTool{MRWDirData}) {
     1672        Write($outfile, "\0" x $pad) if $pad;   # write padding if necessary
     1673        Write($outfile, $$exifTool{MRWDirData});
     1674        delete $$exifTool{MRWDirData};
     1675        # set TIFF_END to copy over the MRW image data
     1676        $$exifTool{TIFF_END} = $dataOffset if $dataOffset;
     1677    }
     1678    return undef;
     1679}
     1680
     1681#------------------------------------------------------------------------------
    2431682# Process SRF maker notes
    244 # Inputs: 0) ExifTool object reference, 1) reference to directory information
    245 #         2) pointer to tag table
     1683# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
    2461684# Returns: 1 on success
    2471685sub ProcessSRF($$$)
     
    2491687    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    2501688    my $dataPt = $$dirInfo{DataPt};
    251     my $dirLen = $$dirInfo{DirLen};
    2521689    my $start = $$dirInfo{DirStart};
    2531690    my $verbose = $exifTool->Options('Verbose');
     
    2561693    my ($ifd, $success);
    2571694    for ($ifd=0; ; ) {
     1695        # switch tag table for SRF2-5 and SRF6
     1696        if ($ifd == 2) {
     1697            $tagTablePtr = GetTagTable('Image::ExifTool::Sony::SRF2');
     1698        } elsif ($ifd == 6) {
     1699            # SRF6 uses standard EXIF tags
     1700            $tagTablePtr = GetTagTable('Image::ExifTool::Exif::Main');
     1701        }
    2581702        my $srf = $$dirInfo{DirName} = "SRF$ifd";
    259         my $srfTable = $tagTablePtr;
    260         # SRF6 uses standard EXIF tags
    261         $srfTable = GetTagTable('Image::ExifTool::Exif::Main') if $ifd == 6;
    2621703        $exifTool->{SET_GROUP1} = $srf;
    263         $success = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $srfTable);
     1704        $success = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
    2641705        delete $exifTool->{SET_GROUP1};
    2651706        last unless $success;
     
    2871728        } elsif ($ifd == 2) {
    2881729            # get the key to decrypt IFD2
    289             $key = $exifTool->{SRF2_Key};
     1730            $key = $exifTool->{SRF2Key};
    2901731            $len = length($$dataPt) - $nextIFD; # decrypt rest of maker notes
    2911732        } else {
     
    2971738        # display decrypted data in verbose mode
    2981739        $exifTool->VerboseDir("Decrypted SRF$ifd", 0, $nextIFD + $len);
    299         my %parms = (
     1740        $exifTool->VerboseDump($dataPt,
    3001741            Prefix => "$exifTool->{INDENT}  ",
    3011742            Start => $nextIFD,
    3021743            DataPos => $$dirInfo{DataPos},
    303             Out => $exifTool->Options('TextOut'),
    3041744        );
    305         $parms{MaxLen} = 96 unless $verbose > 3;
    306         Image::ExifTool::HexDump($dataPt, $len, %parms);
    3071745    }
    3081746}
    3091747
    3101748#------------------------------------------------------------------------------
    311 # Process SR2 data
    312 # Inputs: 0) ExifTool object reference, 1) reference to directory information
    313 #         2) pointer to tag table
    314 # Returns: 1 on success
     1749# Write SR2 data
     1750# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     1751# Returns: 1 on success when reading, or SR2 directory or undef when writing
     1752sub WriteSR2($$$)
     1753{
     1754    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     1755    $exifTool or return 1;      # allow dummy access
     1756    my $buff = '';
     1757    $$dirInfo{OutFile} = \$buff;
     1758    return ProcessSR2($exifTool, $dirInfo, $tagTablePtr);
     1759}
     1760
     1761#------------------------------------------------------------------------------
     1762# Read/Write SR2 IFD and its encrypted subdirectories
     1763# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     1764# Returns: 1 on success when reading, or SR2 directory or undef when writing
    3151765sub ProcessSR2($$$)
    3161766{
    3171767    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     1768    my $raf = $$dirInfo{RAF};
    3181769    my $dataPt = $$dirInfo{DataPt};
    3191770    my $dataPos = $$dirInfo{DataPos};
    3201771    my $dataLen = $$dirInfo{DataLen} || length $$dataPt;
    321     my $dirLen = $$dirInfo{DirLen};
     1772    my $base = $$dirInfo{Base} || 0;
     1773    my $outfile = $$dirInfo{OutFile};
     1774
     1775    # clear SR2 member variables to be safe
     1776    delete $$exifTool{SR2SubIFDOffset};
     1777    delete $$exifTool{SR2SubIFDLength};
     1778    delete $$exifTool{SR2SubIFDKey};
     1779
     1780    # make sure we have the first 4 bytes available to test directory type
     1781    my $buff;
     1782    if ($dataLen < 4 and $raf) {
     1783        my $pos = $dataPos + ($$dirInfo{DirStart}||0) + $base;
     1784        if ($raf->Seek($pos, 0) and $raf->Read($buff, 4) == 4) {
     1785            $dataPt = \$buff;
     1786            undef $$dirInfo{DataPt};    # must load data from file
     1787            $raf->Seek($pos, 0);
     1788        }
     1789    }
     1790    # this may either be a normal IFD, or a MRW data block
     1791    # (only original ARW images from the A100 use the MRW block)
     1792    my $dataOffset;
     1793    if ($dataPt and $$dataPt =~ /^\0MR[IM]/) {
     1794        my ($err, $srfPos, $srfLen, $dataOffset);
     1795        $dataOffset = $$exifTool{A100DataOffset};
     1796        if ($dataOffset) {
     1797            # save information about the RAW data trailer so it will be preserved
     1798            $$exifTool{KnownTrailer} = { Name => 'A100 RAW Data', Start => $dataOffset };
     1799        } else {
     1800            $err = 'A100DataOffset tag is missing from A100 ARW image';
     1801        }
     1802        $raf or $err = 'Unrecognized SR2 structure';
     1803        unless ($err) {
     1804            $srfPos = $raf->Tell();
     1805            $srfLen = $dataOffset - $srfPos;
     1806            unless ($srfLen > 0 and $raf->Read($buff, $srfLen) == $srfLen) {
     1807                $err = 'Error reading MRW directory';
     1808            }
     1809        }
     1810        if ($err) {
     1811            $outfile and $exifTool->Error($err), return undef;
     1812            $exifTool->Warn($err);
     1813            return 0;
     1814        }
     1815        my %dirInfo = ( DataPt => \$buff );
     1816        require Image::ExifTool::MinoltaRaw;
     1817        if ($outfile) {
     1818            # save MRW data to be written last
     1819            $$exifTool{MRWDirData} = Image::ExifTool::MinoltaRaw::WriteMRW($exifTool, \%dirInfo);
     1820            return $$exifTool{MRWDirData} ? "\0\0\0\0\0\0" : undef;
     1821        } else {
     1822            if (not $outfile and $$exifTool{HTML_DUMP}) {
     1823                $exifTool->HDump($srfPos, $srfLen, '[A100 SRF Data]');
     1824            }
     1825            return Image::ExifTool::MinoltaRaw::ProcessMRW($exifTool, \%dirInfo);
     1826        }
     1827    } elsif ($$exifTool{A100DataOffset}) {
     1828        my $err = 'Unexpected A100DataOffset tag';
     1829        $outfile and $exifTool->Error($err), return undef;
     1830        $exifTool->Warn($err);
     1831        return 0;
     1832    }
    3221833    my $verbose = $exifTool->Options('Verbose');
    323     my $result = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
    324     return $result unless $result;
    325     my $offset = $exifTool->{SR2SubIFDOffset};
     1834    my $result;
     1835    if ($outfile) {
     1836        $result = Image::ExifTool::Exif::WriteExif($exifTool, $dirInfo, $tagTablePtr);
     1837        return undef unless $result;
     1838        $$outfile .= $result;
     1839
     1840    } else {
     1841        $result = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
     1842    }
     1843    return $result unless $result and $$exifTool{SR2SubIFDOffset};
     1844    # only take first offset value if more than one!
     1845    my @offsets = split ' ', $exifTool->{SR2SubIFDOffset};
     1846    my $offset = shift @offsets;
    3261847    my $length = $exifTool->{SR2SubIFDLength};
    3271848    my $key = $exifTool->{SR2SubIFDKey};
    328     my $raf = $$dirInfo{RAF};
    329     my $base = $$dirInfo{Base} || 0;
     1849    my @subifdPos;
    3301850    if ($offset and $length and defined $key) {
    3311851        my $buff;
     
    3341854                $raf->Read($buff, $length) == $length) or
    3351855            # or read from data (when processing Adobe DNGPrivateData)
    336             ($offset - $dataPos >= 0 and $offset - $dataPos + $length < $dataLen and 
     1856            ($offset - $dataPos >= 0 and $offset - $dataPos + $length < $dataLen and
    3371857                ($buff = substr($$dataPt, $offset - $dataPos, $length))))
    3381858        {
    3391859            Decrypt(\$buff, 0, $length, $key);
    3401860            # display decrypted data in verbose mode
    341             if ($verbose > 2) {
     1861            if ($verbose > 2 and not $outfile) {
    3421862                $exifTool->VerboseDir("Decrypted SR2SubIFD", 0, $length);
    343                 my %parms = (
    344                     Out => $exifTool->{OPTIONS}->{TextOut},
    345                     Prefix => $exifTool->{INDENT},
    346                     Addr => $offset + $base,
     1863                $exifTool->VerboseDump(\$buff, Addr => $offset + $base);
     1864            }
     1865            my $num = '';
     1866            my $dPos = $offset;
     1867            for (;;) {
     1868                my %dirInfo = (
     1869                    Base => $base,
     1870                    DataPt => \$buff,
     1871                    DataLen => length $buff,
     1872                    DirStart => $offset - $dPos,
     1873                    DirName => "SR2SubIFD$num",
     1874                    DataPos => $dPos,
    3471875                );
    348                 $parms{MaxLen} = 96 unless $verbose > 3;
    349                 Image::ExifTool::HexDump(\$buff, $length, %parms);
     1876                my $subTable = GetTagTable('Image::ExifTool::Sony::SR2SubIFD');
     1877                if ($outfile) {
     1878                    my $fixup = new Image::ExifTool::Fixup;
     1879                    $dirInfo{Fixup} = $fixup;
     1880                    $result = $exifTool->WriteDirectory(\%dirInfo, $subTable);
     1881                    return undef unless $result;
     1882                    # save position of this SubIFD
     1883                    push @subifdPos, length($$outfile);
     1884                    # add this directory to the returned data
     1885                    $$fixup{Start} += length($$outfile);
     1886                    $$outfile .= $result;
     1887                    $dirInfo->{Fixup}->AddFixup($fixup);
     1888                } else {
     1889                    $result = $exifTool->ProcessDirectory(\%dirInfo, $subTable);
     1890                }
     1891                last unless @offsets;
     1892                $offset = shift @offsets;
     1893                $num = ($num || 1) + 1;
    3501894            }
    351             my %dirInfo = (
    352                 Base => $base,
    353                 DataPt => \$buff,
    354                 DataLen => length $buff,
    355                 DirStart => 0,
    356                 DirName => 'SR2SubIFD',
    357                 DataPos => $offset,
    358             );
    359             my $subTable = Image::ExifTool::GetTagTable('Image::ExifTool::Sony::SR2SubIFD');
    360             $result = $exifTool->ProcessDirectory(\%dirInfo, $subTable);
    3611895
    3621896        } else {
     
    3641898        }
    3651899    }
    366     delete $exifTool->{SR2SubIFDOffset};
    367     delete $exifTool->{SR2SubIFDLength};
    368     delete $exifTool->{SR2SubIFDKey};
    369     return $result;
     1900    if ($outfile and @subifdPos) {
     1901        # the SR2SubIFD must be padded to a multiple of 4 bytes for the encryption
     1902        my $sr2Len = length($$outfile) - $subifdPos[0];
     1903        if ($sr2Len & 0x03) {
     1904            my $pad = 4 - ($sr2Len & 0x03);
     1905            $sr2Len += $pad;
     1906            $$outfile .= ' ' x $pad;
     1907        }
     1908        # save the new SR2SubIFD Length and Key to be used later for encryption
     1909        $$exifTool{SR2SubIFDLength} = $sr2Len;
     1910        my $newKey = $$exifTool{VALUE}{SR2SubIFDKey};
     1911        $$exifTool{SR2SubIFDKey} = $newKey if defined $newKey;
     1912        # update SubIFD pointers manually and add to fixup, and set SR2SubIFDLength
     1913        my $n = Get16u($outfile, 0);
     1914        my ($i, %found);
     1915        for ($i=0; $i<$n; ++$i) {
     1916            my $entry = 2 + 12 * $i;
     1917            my $tagID = Get16u($outfile, $entry);
     1918            # only interested in SR2SubIFDOffset (0x7200) and SR2SubIFDLength (0x7201)
     1919            next unless $tagID == 0x7200 or $tagID == 0x7201;
     1920            $found{$tagID} = 1;
     1921            my $fmt = Get16u($outfile, $entry + 2);
     1922            if ($fmt != 0x04) { # must be int32u
     1923                $exifTool->Error("Unexpected format ($fmt) for SR2SubIFD tag");
     1924                return undef;
     1925            }
     1926            if ($tagID == 0x7201) { # SR2SubIFDLength
     1927                Set32u($sr2Len, $outfile, $entry + 8);
     1928                next;
     1929            }
     1930            my $tag = 'SR2SubIFDOffset';
     1931            my $valuePtr = @subifdPos < 2 ? $entry+8 : Get32u($outfile, $entry+8);
     1932            my $pos;
     1933            foreach $pos (@subifdPos) {
     1934                Set32u($pos, $outfile, $valuePtr);
     1935                $dirInfo->{Fixup}->AddFixup($valuePtr, $tag);
     1936                undef $tag;
     1937                $valuePtr += 4;
     1938            }
     1939        }
     1940        unless ($found{0x7200} and $found{0x7201}) {
     1941            $exifTool->Error('Missing SR2SubIFD tag');
     1942            return undef;
     1943        }
     1944    }
     1945    return $outfile ? $$outfile : $result;
    3701946}
    3711947
     
    3841960=head1 DESCRIPTION
    3851961
    386 This module contains definitions required by Image::ExifTool to
    387 interpret Sony maker notes EXIF meta information.
     1962This module contains definitions required by Image::ExifTool to interpret
     1963Sony maker notes EXIF meta information.
    3881964
    3891965=head1 NOTES
    3901966
    391 The Sony maker notes use the standard EXIF IFD structure, but unfortunately
    392 the entries are large blocks of binary data for which I can find no
    393 documentation.  You can use "exiftool -v3" to dump these blocks in hex.
     1967Also see Minolta.pm since Sony DSLR models use structures originating from
     1968Minolta.
    3941969
    3951970=head1 AUTHOR
    3961971
    397 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1972Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    3981973
    3991974This library is free software; you can redistribute it and/or modify it
     
    4081983=item L<http://homepage3.nifty.com/kamisaka/makernote/makernote_sony.htm>
    4091984
     1985=item L<http://www.klingebiel.com/tempest/hd/pmp.html>
     1986
    4101987=back
    4111988
    4121989=head1 ACKNOWLEDGEMENTS
    4131990
    414 Thanks to Thomas Bodenmann for providing information about the LensID's.
     1991Thanks to Thomas Bodenmann, Philippe Devaux, Jens Duttke, Marcus
     1992Holland-Moritz, Andrey Tverdokhleb, Rudiger Lange, Igal Milchtaich and
     1993Michael Reitinger for help decoding some tags.
    4151994
    4161995=head1 SEE ALSO
    4171996
    4181997L<Image::ExifTool::TagNames/Sony Tags>,
     1998L<Image::ExifTool::TagNames/Minolta Tags>,
    4191999L<Image::ExifTool(3pm)|Image::ExifTool>
    4202000
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/TagLookup.pm

    r23771 r24107  
    1717use Image::ExifTool qw(:Utils);
    1818
    19 $VERSION = '1.04';
     19$VERSION = '1.07';
    2020@ISA = qw(Exporter);
    2121@EXPORT_OK = qw(FindTagInfo TagExists);
     22
     23sub AddTags($$);
     24sub AddFields($$$$$$;$$);
    2225
    2326#
     
    3033my @tableList = (
    3134    'Image::ExifTool::APP12::Ducky',
    32     'Image::ExifTool::Canon::CameraInfo',
     35    'Image::ExifTool::Canon::AFMicroAdj',
     36    'Image::ExifTool::Canon::Ambience',
     37    'Image::ExifTool::Canon::AspectInfo',
     38    'Image::ExifTool::Canon::CameraInfo1000D',
     39    'Image::ExifTool::Canon::CameraInfo1D',
     40    'Image::ExifTool::Canon::CameraInfo1DmkII',
    3341    'Image::ExifTool::Canon::CameraInfo1DmkIII',
    34     'Image::ExifTool::Canon::CameraInfo2',
     42    'Image::ExifTool::Canon::CameraInfo1DmkIIN',
     43    'Image::ExifTool::Canon::CameraInfo1DmkIV',
     44    'Image::ExifTool::Canon::CameraInfo40D',
     45    'Image::ExifTool::Canon::CameraInfo450D',
     46    'Image::ExifTool::Canon::CameraInfo500D',
     47    'Image::ExifTool::Canon::CameraInfo50D',
     48    'Image::ExifTool::Canon::CameraInfo550D',
     49    'Image::ExifTool::Canon::CameraInfo5D',
     50    'Image::ExifTool::Canon::CameraInfo5DmkII',
     51    'Image::ExifTool::Canon::CameraInfo5DmkII_2',
     52    'Image::ExifTool::Canon::CameraInfo60D',
     53    'Image::ExifTool::Canon::CameraInfo7D',
     54    'Image::ExifTool::Canon::CameraInfo7D_2',
     55    'Image::ExifTool::Canon::CameraInfoPowerShot',
     56    'Image::ExifTool::Canon::CameraInfoPowerShot2',
     57    'Image::ExifTool::Canon::CameraInfoUnknown32',
    3558    'Image::ExifTool::Canon::CameraSettings',
    3659    'Image::ExifTool::Canon::ColorBalance',
    37     'Image::ExifTool::Canon::ColorBalance1',
    38     'Image::ExifTool::Canon::ColorBalance2',
    39     'Image::ExifTool::Canon::ColorBalance3',
     60    'Image::ExifTool::Canon::ColorCalib',
     61    'Image::ExifTool::Canon::ColorCoefs',
     62    'Image::ExifTool::Canon::ColorData1',
     63    'Image::ExifTool::Canon::ColorData2',
     64    'Image::ExifTool::Canon::ColorData3',
     65    'Image::ExifTool::Canon::ColorData4',
     66    'Image::ExifTool::Canon::ColorData5',
     67    'Image::ExifTool::Canon::ColorData6',
    4068    'Image::ExifTool::Canon::ColorInfo',
    41     'Image::ExifTool::Canon::ColorInfoD30',
     69    'Image::ExifTool::Canon::CropInfo',
    4270    'Image::ExifTool::Canon::FaceDetect1',
    4371    'Image::ExifTool::Canon::FaceDetect2',
     
    4573    'Image::ExifTool::Canon::Flags',
    4674    'Image::ExifTool::Canon::FocalLength',
     75    'Image::ExifTool::Canon::LensInfo',
     76    'Image::ExifTool::Canon::LightingOpt',
    4777    'Image::ExifTool::Canon::Main',
     78    'Image::ExifTool::Canon::MeasuredColor',
    4879    'Image::ExifTool::Canon::ModifiedInfo',
     80    'Image::ExifTool::Canon::MovieInfo',
    4981    'Image::ExifTool::Canon::MyColors',
     82    'Image::ExifTool::Canon::PSInfo',
     83    'Image::ExifTool::Canon::PSInfo2',
    5084    'Image::ExifTool::Canon::Panorama',
    5185    'Image::ExifTool::Canon::PreviewImageInfo',
    5286    'Image::ExifTool::Canon::Processing',
     87    'Image::ExifTool::Canon::SerialInfo',
    5388    'Image::ExifTool::Canon::ShotInfo',
     89    'Image::ExifTool::Canon::VignettingCorr',
     90    'Image::ExifTool::Canon::VignettingCorr2',
    5491    'Image::ExifTool::CanonCustom::Functions10D',
    5592    'Image::ExifTool::CanonCustom::Functions1D',
     
    71108    'Image::ExifTool::CanonRaw::RawJpgInfo',
    72109    'Image::ExifTool::CanonRaw::TimeStamp',
     110    'Image::ExifTool::CanonVRD::Main',
    73111    'Image::ExifTool::CanonVRD::Ver1',
    74112    'Image::ExifTool::CanonVRD::Ver2',
     113    'Image::ExifTool::Casio::FaceInfo1',
     114    'Image::ExifTool::Casio::FaceInfo2',
    75115    'Image::ExifTool::Casio::Main',
    76116    'Image::ExifTool::Casio::Type2',
     
    82122    'Image::ExifTool::FotoStation::SoftEdit',
    83123    'Image::ExifTool::FujiFilm::Main',
     124    'Image::ExifTool::GE::Main',
    84125    'Image::ExifTool::GPS::Main',
    85126    'Image::ExifTool::IPTC::ApplicationRecord',
     
    88129    'Image::ExifTool::JFIF::Main',
    89130    'Image::ExifTool::Kodak::CameraInfo',
     131    'Image::ExifTool::Kodak::IFD',
     132    'Image::ExifTool::Kodak::KDC_IFD',
    90133    'Image::ExifTool::Kodak::Main',
     134    'Image::ExifTool::Kodak::Meta',
    91135    'Image::ExifTool::Kodak::SubIFD0',
    92136    'Image::ExifTool::Kodak::SubIFD1',
     
    94138    'Image::ExifTool::Kodak::SubIFD3',
    95139    'Image::ExifTool::Kodak::SubIFD5',
     140    'Image::ExifTool::Kodak::Type10',
    96141    'Image::ExifTool::Kodak::Type2',
    97142    'Image::ExifTool::Kodak::Type3',
    98143    'Image::ExifTool::Kodak::Type4',
    99144    'Image::ExifTool::Kodak::Type7',
     145    'Image::ExifTool::Kodak::Type9',
    100146    'Image::ExifTool::MIE::Audio',
    101147    'Image::ExifTool::MIE::Camera',
     
    113159    'Image::ExifTool::MIE::UTM',
    114160    'Image::ExifTool::MIE::Video',
     161    'Image::ExifTool::Microsoft::MP',
     162    'Image::ExifTool::Microsoft::MP1',
     163    'Image::ExifTool::Microsoft::Stitch',
     164    'Image::ExifTool::Microsoft::XMP',
    115165    'Image::ExifTool::Minolta::CameraSettings',
    116166    'Image::ExifTool::Minolta::CameraSettings5D',
     
    118168    'Image::ExifTool::Minolta::CameraSettingsA100',
    119169    'Image::ExifTool::Minolta::Main',
     170    'Image::ExifTool::Minolta::WBInfoA100',
    120171    'Image::ExifTool::MinoltaRaw::PRD',
    121172    'Image::ExifTool::MinoltaRaw::RIF',
    122173    'Image::ExifTool::MinoltaRaw::WBG',
    123174    'Image::ExifTool::Nikon::AFInfo',
     175    'Image::ExifTool::Nikon::AFInfo2',
     176    'Image::ExifTool::Nikon::AFTune',
     177    'Image::ExifTool::Nikon::CaptureOutput',
    124178    'Image::ExifTool::Nikon::ColorBalance1',
    125179    'Image::ExifTool::Nikon::ColorBalance2',
    126180    'Image::ExifTool::Nikon::ColorBalance3',
     181    'Image::ExifTool::Nikon::ColorBalance4',
     182    'Image::ExifTool::Nikon::ColorBalanceA',
     183    'Image::ExifTool::Nikon::DistortInfo',
     184    'Image::ExifTool::Nikon::FaceDetect',
     185    'Image::ExifTool::Nikon::FileInfo',
     186    'Image::ExifTool::Nikon::FlashInfo0100',
     187    'Image::ExifTool::Nikon::FlashInfo0102',
     188    'Image::ExifTool::Nikon::FlashInfo0103',
    127189    'Image::ExifTool::Nikon::GEM',
     190    'Image::ExifTool::Nikon::ISOInfo',
    128191    'Image::ExifTool::Nikon::LensData00',
     192    'Image::ExifTool::Nikon::LensData01',
     193    'Image::ExifTool::Nikon::LensData0204',
    129194    'Image::ExifTool::Nikon::Main',
    130195    'Image::ExifTool::Nikon::MultiExposure',
    131     'Image::ExifTool::Nikon::PreviewImage',
     196    'Image::ExifTool::Nikon::PictureControl',
     197    'Image::ExifTool::Nikon::PreviewIFD',
    132198    'Image::ExifTool::Nikon::ROC',
    133199    'Image::ExifTool::Nikon::Scan',
     200    'Image::ExifTool::Nikon::ShotInfo',
     201    'Image::ExifTool::Nikon::ShotInfoD300S',
     202    'Image::ExifTool::Nikon::ShotInfoD300a',
     203    'Image::ExifTool::Nikon::ShotInfoD300b',
     204    'Image::ExifTool::Nikon::ShotInfoD3S',
     205    'Image::ExifTool::Nikon::ShotInfoD3X',
     206    'Image::ExifTool::Nikon::ShotInfoD3a',
     207    'Image::ExifTool::Nikon::ShotInfoD3b',
     208    'Image::ExifTool::Nikon::ShotInfoD40',
     209    'Image::ExifTool::Nikon::ShotInfoD5000',
     210    'Image::ExifTool::Nikon::ShotInfoD700',
     211    'Image::ExifTool::Nikon::ShotInfoD7000',
     212    'Image::ExifTool::Nikon::ShotInfoD80',
     213    'Image::ExifTool::Nikon::ShotInfoD90',
    134214    'Image::ExifTool::Nikon::Type2',
     215    'Image::ExifTool::Nikon::VRInfo',
     216    'Image::ExifTool::Nikon::WorldTime',
    135217    'Image::ExifTool::NikonCapture::Brightness',
    136218    'Image::ExifTool::NikonCapture::ColorBoost',
     
    138220    'Image::ExifTool::NikonCapture::DLightingHQ',
    139221    'Image::ExifTool::NikonCapture::DLightingHS',
     222    'Image::ExifTool::NikonCapture::Exposure',
     223    'Image::ExifTool::NikonCapture::HighlightData',
    140224    'Image::ExifTool::NikonCapture::Main',
    141225    'Image::ExifTool::NikonCapture::NoiseReduction',
    142226    'Image::ExifTool::NikonCapture::PhotoEffects',
     227    'Image::ExifTool::NikonCapture::PictureCtrl',
    143228    'Image::ExifTool::NikonCapture::RedEyeData',
    144229    'Image::ExifTool::NikonCapture::UnsharpData',
    145230    'Image::ExifTool::NikonCapture::WBAdjData',
     231    'Image::ExifTool::NikonCustom::SettingsD3',
     232    'Image::ExifTool::NikonCustom::SettingsD40',
     233    'Image::ExifTool::NikonCustom::SettingsD5000',
     234    'Image::ExifTool::NikonCustom::SettingsD700',
     235    'Image::ExifTool::NikonCustom::SettingsD7000',
     236    'Image::ExifTool::NikonCustom::SettingsD80',
     237    'Image::ExifTool::NikonCustom::SettingsD90',
    146238    'Image::ExifTool::Olympus::CameraSettings',
    147239    'Image::ExifTool::Olympus::Equipment',
     
    153245    'Image::ExifTool::Olympus::RawDevelopment2',
    154246    'Image::ExifTool::Olympus::RawInfo',
     247    'Image::ExifTool::PDF::Info',
    155248    'Image::ExifTool::PNG::Main',
    156249    'Image::ExifTool::PNG::TextualData',
     250    'Image::ExifTool::Panasonic::Data1',
     251    'Image::ExifTool::Panasonic::FaceDetInfo',
     252    'Image::ExifTool::Panasonic::FaceRecInfo',
     253    'Image::ExifTool::Panasonic::Leica2',
     254    'Image::ExifTool::Panasonic::Leica3',
     255    'Image::ExifTool::Panasonic::Leica5',
     256    'Image::ExifTool::Panasonic::Leica6',
     257    'Image::ExifTool::Panasonic::LensInfo',
    157258    'Image::ExifTool::Panasonic::Main',
    158     'Image::ExifTool::Panasonic::Raw',
     259    'Image::ExifTool::Panasonic::Subdir',
     260    'Image::ExifTool::PanasonicRaw::Main',
    159261    'Image::ExifTool::Pentax::AEInfo',
    160262    'Image::ExifTool::Pentax::AFInfo',
     263    'Image::ExifTool::Pentax::AWBInfo',
    161264    'Image::ExifTool::Pentax::BatteryInfo',
    162265    'Image::ExifTool::Pentax::CameraInfo',
     266    'Image::ExifTool::Pentax::CameraSettings',
     267    'Image::ExifTool::Pentax::ColorInfo',
     268    'Image::ExifTool::Pentax::EVStepInfo',
     269    'Image::ExifTool::Pentax::FaceInfo',
     270    'Image::ExifTool::Pentax::FacePos',
     271    'Image::ExifTool::Pentax::FaceSize',
     272    'Image::ExifTool::Pentax::FilterInfo',
    163273    'Image::ExifTool::Pentax::FlashInfo',
     274    'Image::ExifTool::Pentax::LensCorr',
     275    'Image::ExifTool::Pentax::LensData',
    164276    'Image::ExifTool::Pentax::LensInfo',
     277    'Image::ExifTool::Pentax::LensInfo2',
     278    'Image::ExifTool::Pentax::LensInfo3',
     279    'Image::ExifTool::Pentax::LensInfo4',
     280    'Image::ExifTool::Pentax::LevelInfo',
    165281    'Image::ExifTool::Pentax::Main',
    166282    'Image::ExifTool::Pentax::SRInfo',
     283    'Image::ExifTool::Pentax::ShotInfo',
     284    'Image::ExifTool::Pentax::TempInfoK5',
     285    'Image::ExifTool::Pentax::TimeInfo',
    167286    'Image::ExifTool::Pentax::Type2',
    168287    'Image::ExifTool::PhotoMechanic::SoftEdit',
     
    172291    'Image::ExifTool::Photoshop::Resolution',
    173292    'Image::ExifTool::PostScript::Main',
     293    'Image::ExifTool::Reconyx::Main',
     294    'Image::ExifTool::Ricoh::FaceInfo',
     295    'Image::ExifTool::Ricoh::FirmwareInfo',
    174296    'Image::ExifTool::Ricoh::ImageInfo',
    175297    'Image::ExifTool::Ricoh::Main',
     298    'Image::ExifTool::Ricoh::SerialInfo',
     299    'Image::ExifTool::Ricoh::Subdir',
     300    'Image::ExifTool::Samsung::Type1',
     301    'Image::ExifTool::Samsung::Type2',
     302    'Image::ExifTool::Sanyo::FaceInfo',
    176303    'Image::ExifTool::Sanyo::Main',
    177304    'Image::ExifTool::Sigma::Main',
     305    'Image::ExifTool::Sony::CameraSettings',
     306    'Image::ExifTool::Sony::CameraSettings2',
     307    'Image::ExifTool::Sony::Ericsson',
     308    'Image::ExifTool::Sony::FaceInfo1',
     309    'Image::ExifTool::Sony::FaceInfo2',
    178310    'Image::ExifTool::Sony::Main',
     311    'Image::ExifTool::Sony::Panorama',
     312    'Image::ExifTool::Sony::ShotInfo',
     313    'Image::ExifTool::SonyIDC::Main',
     314    'Image::ExifTool::XMP::Album',
    179315    'Image::ExifTool::XMP::DICOM',
    180316    'Image::ExifTool::XMP::Lightroom',
    181317    'Image::ExifTool::XMP::MediaPro',
    182     'Image::ExifTool::XMP::Microsoft',
     318    'Image::ExifTool::XMP::acdsee',
    183319    'Image::ExifTool::XMP::aux',
    184320    'Image::ExifTool::XMP::cc',
     321    'Image::ExifTool::XMP::cell',
    185322    'Image::ExifTool::XMP::crs',
    186323    'Image::ExifTool::XMP::dc',
    187324    'Image::ExifTool::XMP::dex',
     325    'Image::ExifTool::XMP::digiKam',
    188326    'Image::ExifTool::XMP::exif',
    189327    'Image::ExifTool::XMP::iptcCore',
     328    'Image::ExifTool::XMP::iptcExt',
     329    'Image::ExifTool::XMP::mwg_coll',
     330    'Image::ExifTool::XMP::mwg_kw',
     331    'Image::ExifTool::XMP::mwg_rs',
    190332    'Image::ExifTool::XMP::pdf',
    191333    'Image::ExifTool::XMP::photoshop',
     334    'Image::ExifTool::XMP::plus',
     335    'Image::ExifTool::XMP::prism',
     336    'Image::ExifTool::XMP::prl',
     337    'Image::ExifTool::XMP::pur',
     338    'Image::ExifTool::XMP::rdf',
     339    'Image::ExifTool::XMP::swf',
    192340    'Image::ExifTool::XMP::tiff',
     341    'Image::ExifTool::XMP::x',
    193342    'Image::ExifTool::XMP::xmp',
    194343    'Image::ExifTool::XMP::xmpBJ',
    195344    'Image::ExifTool::XMP::xmpDM',
    196345    'Image::ExifTool::XMP::xmpMM',
     346    'Image::ExifTool::XMP::xmpNote',
    197347    'Image::ExifTool::XMP::xmpPLUS',
    198348    'Image::ExifTool::XMP::xmpRights',
     
    202352# lookup for all writable tags
    203353my %tagLookup = (
    204     'abspeakaudiofilepath' => { 164 => 'absPeakAudioFilePath' },
    205     'accessorytype' => { 126 => 0x53 },
    206     'actionadvised' => { 54 => 0x2a },
    207     'activearea' => { 48 => 0xc68d },
    208     'addaspectratioinfo' => { 25 => 0x80e },
    209     'addoriginaldecisiondata' => { 25 => 0x80f, 26 => 0x11, 27 => 0x13, 30 => 0x14 },
    210     'address' => { 75 => 'Address' },
    211     'adjustmentmode' => { 146 => [0x15,0x22] },
    212     'advancedraw' => { 109 => 0x76a43203 },
    213     'advisory' => { 162 => 'Advisory' },
    214     'ae_iso' => { 128 => 0x2 },
    215     'aeaperture' => { 128 => 0x1 },
    216     'aebautocancel' => { 25 => 0x104 },
    217     'aebbracketvalue' => { 22 => 0x11 },
    218     'aebsequence' => { 23 => 0x9, 24 => 0x9, 25 => 0x105, 26 => 0x8, 27 => 0x9, 30 => 0x9, 31 => 0x7 },
    219     'aebshotcount' => { 25 => 0x106 },
    220     'aebxv' => { 128 => 0x4 },
    221     'aeexposuretime' => { 128 => 0x0 },
    222     'aeextra' => { 128 => 0x7 },
    223     'aeflashtv' => { 128 => 0x5 },
    224     'aelock' => { 115 => 0x201 },
    225     'aemeteringsegments' => { 134 => 0x209 },
    226     'aeprogrammode' => { 128 => 0x6 },
    227     'aesetting' => { 4 => 0x21 },
    228     'aexv' => { 128 => 0x3 },
    229     'afareamode' => { 92 => 0x0 },
    230     'afareas' => { 115 => 0x304 },
    231     'afassist' => { 23 => 0x5, 31 => 0x5 },
    232     'afassistbeam' => { 25 => 0x50e, 26 => 0x4, 27 => 0x5, 28 => 0x4, 29 => 0x4, 30 => 0x5 },
    233     'afduringliveview' => { 25 => 0x511 },
    234     'afexpansionwithselectedpoint' => { 25 => 0x508 },
    235     'afmicroadjustment' => { 25 => 0x507 },
    236     'afmode' => { 126 => 0xf, 146 => 0x5 },
    237     'afonaelockbuttonswitch' => { 25 => 0x702 },
    238     'afpoint' => { 4 => 0x13, 44 => 0x18, 92 => 0x1, 118 => 0x308 },
    239     'afpointactivationarea' => { 24 => 0x11, 30 => 0x11 },
    240     'afpointautoselection' => { 25 => 0x50b },
    241     'afpointbrightness' => { 25 => 0x50d },
    242     'afpointdisplayduringfocus' => { 25 => 0x50c },
    243     'afpointillumination' => { 24 => 0xa },
    244     'afpointregistration' => { 23 => 0x7 },
    245     'afpoints' => { 86 => 0x10 },
    246     'afpointselected' => { 134 => 0xe },
    247     'afpointselection' => { 24 => 0xb },
    248     'afpointselectionmethod' => { 25 => 0x50f, 26 => 0xc, 27 => 0xd, 30 => 0xd },
    249     'afpointsinfocus' => { 22 => 0xe, 92 => 0x2, 129 => 0xb, 134 => [0xf,0x3c] },
    250     'afpointsinfocus5d' => { 1 => 0x38 },
    251     'afpointspotmetering' => { 24 => 0xd },
    252     'afresponse' => { 98 => 0xad },
    253     'afresult' => { 120 => 0x1038 },
    254     'afsearch' => { 115 => 0x303 },
    255     'aiservoimagepriority' => { 25 => 0x503 },
    256     'aiservotrackingmethod' => { 25 => 0x504 },
    257     'aiservotrackingsensitivity' => { 24 => 0x14, 25 => 0x502 },
    258     'album' => { 164 => 'album' },
    259     'alreadyapplied' => { 154 => 'AlreadyApplied' },
    260     'alttapename' => { 164 => 'altTapeName' },
    261     'alttimecodetimeformat' => { 164 => 'altTimecodeTimeFormat' },
    262     'alttimecodetimevalue' => { 164 => 'altTimecodeTimeValue' },
    263     'antialiasstrength' => { 48 => 0xc632 },
    264     'aperturerange' => { 25 => 0x10d },
    265     'aperturevalue' => { 48 => 0x9202, 120 => 0x1002, 157 => 'ApertureValue' },
    266     'applicationrecordversion' => { 54 => 0x0 },
    267     'applyshootingmeteringmode' => { 25 => 0x10e },
    268     'armidentifier' => { 55 => 0x78 },
    269     'armversion' => { 55 => 0x7a },
    270     'artist' => { 48 => 0x13b, 125 => 'Artist', 161 => 'Artist', 164 => 'artist' },
    271     'asshoticcprofile' => { 48 => 0xc68f },
    272     'asshotpreprofilematrix' => { 48 => 0xc690 },
    273     'asshotwhitexy' => { 48 => 0xc629 },
    274     'assistbuttonfunction' => { 23 => 0xd },
    275     'audio' => { 126 => 0x20 },
    276     'audiochanneltype' => { 164 => 'audioChannelType' },
    277     'audiocompression' => { 69 => 'Compression' },
    278     'audiocompressor' => { 164 => 'audioCompressor' },
    279     'audioduration' => { 54 => 0x99 },
    280     'audiomoddate' => { 164 => 'audioModDate' },
    281     'audiooutcue' => { 54 => 0x9a },
    282     'audiosamplerate' => { 164 => 'audioSampleRate' },
    283     'audiosampletype' => { 164 => 'audioSampleType' },
    284     'audiosamplingrate' => { 54 => 0x97 },
    285     'audiosamplingresolution' => { 54 => 0x98 },
    286     'audiotype' => { 54 => 0x96 },
    287     'author' => { 71 => 'Author', 125 => 'Author', 142 => 'Author', 159 => 'Author' },
    288     'authorsposition' => { 160 => 'AuthorsPosition' },
    289     'autobracket' => { 146 => 0x19 },
    290     'autobracketing' => { 52 => 0x1100, 134 => 0x18 },
    291     'autobracketrelease' => { 98 => 0x8a },
    292     'autobrightness' => { 154 => 'AutoBrightness' },
    293     'autocontrast' => { 154 => 'AutoContrast' },
    294     'autoexposure' => { 154 => 'AutoExposure' },
    295     'autoexposurebracketing' => { 22 => 0x10 },
    296     'autofocus' => { 118 => 0x209 },
    297     'autoiso' => { 22 => 0x1, 45 => 0x3008 },
    298     'autorotate' => { 22 => 0x1b },
    299     'autoshadows' => { 154 => 'AutoShadows' },
    300     'auxiliarylens' => { 98 => 0x82 },
    301     'avsettingwithoutlens' => { 25 => 0x707 },
    302     'avvalue' => { 34 => 0x2 },
    303     'azimuth' => { 79 => 'Azimuth' },
    304     'babyage' => { 126 => [0x8010,0x33] },
    305     'baseiso' => { 22 => 0x2, 38 => 0x101c },
    306     'baselineexposure' => { 48 => 0xc62a },
    307     'baselinenoise' => { 48 => 0xc62b },
    308     'baselinesharpness' => { 48 => 0xc62c },
    309     'baseurl' => { 162 => 'BaseURL' },
    310     'batteryadbodyload' => { 130 => 0x3 },
    311     'batteryadbodynoload' => { 130 => 0x2 },
    312     'batteryadgripload' => { 130 => 0x5 },
    313     'batteryadgripnoload' => { 130 => 0x4 },
    314     'batterybodygripstates' => { 130 => 0x1 },
    315     'batterytype' => { 130 => 0x0 },
    316     'bayergreensplit' => { 48 => 0xc62d },
    317     'bayerpattern' => { 58 => 0xf902, 89 => 0x17 },
    318     'beatspliceparamsriseindecibel' => { 164 => 'beatSpliceParamsRiseInDecibel' },
    319     'beatspliceparamsriseintimeduration' => { 164 => 'beatSpliceParamsRiseInTimeDuration' },
    320     'beatspliceparamsusefilebeatsmarker' => { 164 => 'beatSpliceParamsUseFileBeatsMarker' },
    321     'bestqualityscale' => { 48 => 0xc65c },
    322     'bestshotmode' => { 45 => 0x3007 },
    323     'bitdepth' => { 76 => 'BitDepth', 89 => 0x11, 102 => 0x41 },
    324     'bitspercomponent' => { 56 => 0x87 },
    325     'bitspersample' => { 48 => 0x102, 161 => 'BitsPerSample' },
    326     'blacklevel' => { 120 => 0x1012 },
    327     'blacklevel2' => { 123 => 0x600 },
    328     'blackpoint' => { 134 => 0x200 },
    329     'bluebalance' => { 120 => 0x1018, 127 => 0x12, 134 => 0x1b },
    330     'bluecurvelimits' => { 42 => 0x1fe },
    331     'bluecurvepoints' => { 42 => 0x1d4 },
    332     'bluehue' => { 154 => 'BlueHue' },
    333     'bluesaturation' => { 154 => 'BlueSaturation' },
    334     'blurwarning' => { 52 => 0x1300 },
    335     'bodyfirmwareversion' => { 116 => 0x104, 117 => 0x100, 120 => 0x104 },
    336     'bracketmode' => { 13 => 0x3 },
    337     'bracketsequence' => { 45 => 0x301d },
    338     'bracketshotnumber' => { 13 => 0x5 },
    339     'bracketstep' => { 84 => 0xe },
    340     'bracketvalue' => { 13 => 0x4 },
    341     'brightness' => { 48 => 0xfe53, 70 => 'Brightness', 84 => 0x2c, 154 => 'Brightness' },
    342     'brightnessadj' => { 42 => 0x114, 104 => 0x0 },
    343     'brightnessvalue' => { 48 => 0x9203, 120 => 0x1003, 157 => 'BrightnessValue' },
    344     'bulbduration' => { 22 => 0x18 },
    345     'burstmode' => { 59 => 0xa, 126 => 0x2a },
    346     'burstmode2' => { 59 => 0x18 },
    347     'buttonfunctioncontroloff' => { 25 => 0x70a },
    348     'bwfilter' => { 84 => 0x2a, 90 => 0x39 },
    349     'bwmode' => { 120 => 0x203 },
    350     'by-line' => { 54 => 0x50 },
    351     'by-linetitle' => { 54 => 0x55 },
    352     'calibrationilluminant1' => { 48 => 0xc65a },
    353     'calibrationilluminant2' => { 48 => 0xc65b },
    354     'cameraid' => { 120 => 0x209, 145 => 0x209 },
    355     'cameraiso' => { 4 => 0x10 },
    356     'cameraparameters' => { 120 => 0x2050 },
    357     'cameraprofile' => { 154 => 'CameraProfile' },
    358     'cameraprofiledigest' => { 154 => 'CameraProfileDigest' },
    359     'cameraserialnumber' => { 48 => 0xc62f, 151 => 'CameraSerialNumber' },
    360     'camerasettingsversion' => { 115 => 0x0 },
    361     'cameratemperature' => { 134 => 0x47 },
    362     'cameratype' => { 22 => 0x1a, 120 => 0x207 },
    363     'cameratype2' => { 116 => 0x100 },
    364     'canonexposuremode' => { 4 => 0x14 },
    365     'canonfiledescription' => { 38 => 0x805 },
    366     'canonfilelength' => { 16 => 0xe },
    367     'canonfirmwareversion' => { 16 => 0x7, 38 => 0x80b },
    368     'canonflashinfo' => { 38 => 0x1028 },
    369     'canonflashmode' => { 4 => 0x4 },
    370     'canonimagesize' => { 4 => 0xa },
    371     'canonimagetype' => { 16 => 0x6, 38 => 0x815 },
    372     'canonmodelid' => { 16 => 0x10, 38 => 0x1834 },
    373     'canonvrd' => { 49 => 'CanonVRD' },
    374     'caption-abstract' => { 54 => 0x78 },
    375     'captionwriter' => { 160 => 'CaptionWriter' },
    376     'casioimagesize' => { 45 => 0x9 },
    377     'catalogsets' => { 150 => 'CatalogSets' },
    378     'category' => { 54 => 0xf, 160 => 'Category' },
    379     'ccdscanmode' => { 120 => 0x1039 },
    380     'ccdsensitivity' => { 103 => 0x6 },
    381     'celllength' => { 48 => 0x109 },
    382     'cellwidth' => { 48 => 0x108 },
    383     'certificate' => { 167 => 'Certificate' },
    384     'cfapattern' => { 48 => 0xa302 },
    385     'cfapatterncolumns' => { 157 => 'CFAPatternColumns' },
    386     'cfapatternrows' => { 157 => 'CFAPatternRows' },
    387     'cfapatternvalues' => { 157 => 'CFAPatternValues' },
    388     'channels' => { 69 => 'Channels' },
    389     'checkmark' => { 42 => 0x26a },
    390     'chromablurradius' => { 48 => 0xc631 },
    391     'chromaticaberrationb' => { 154 => 'ChromaticAberrationB' },
    392     'chromaticaberrationr' => { 154 => 'ChromaticAberrationR' },
    393     'chrominancenoisereduction' => { 43 => 0xbc },
    394     'chrominancenr_tiff_jpeg' => { 43 => 0xc0 },
    395     'city' => { 54 => 0x5a, 75 => 'City', 160 => 'City' },
    396     'clarity' => { 154 => 'Clarity' },
    397     'classifystate' => { 54 => 0xe1 },
    398     'cmcontrast' => { 123 => 0x2022 },
    399     'cmexposurecompensation' => { 123 => 0x2000 },
    400     'cmhue' => { 123 => 0x2021 },
    401     'cmsaturation' => { 123 => 0x2020 },
    402     'cmsharpness' => { 123 => 0x2023 },
    403     'cmwhitebalance' => { 123 => 0x2001 },
    404     'cmwhitebalancecomp' => { 123 => 0x2002 },
    405     'cmwhitebalancegraypoint' => { 123 => 0x2010 },
    406     'codec' => { 83 => 'Codec' },
    407     'codedcharacterset' => { 55 => 0x5a },
    408     'coloraberrationcontrol' => { 109 => 0xc89224b },
    409     'coloradjustment' => { 146 => 0x14 },
    410     'coloradjustmentmode' => { 145 => 0x210 },
    411     'colorantsa' => { 168 => 'ColorantsA' },
    412     'colorantsb' => { 168 => 'ColorantsB' },
    413     'colorantsblack' => { 168 => 'ColorantsBlack' },
    414     'colorantsblue' => { 168 => 'ColorantsBlue' },
    415     'colorantscyan' => { 168 => 'ColorantsCyan' },
    416     'colorantsgreen' => { 168 => 'ColorantsGreen' },
    417     'colorantsl' => { 168 => 'ColorantsL' },
    418     'colorantsmagenta' => { 168 => 'ColorantsMagenta' },
    419     'colorantsmode' => { 168 => 'ColorantsMode' },
    420     'colorantsred' => { 168 => 'ColorantsRed' },
    421     'colorantsswatchname' => { 168 => 'ColorantsSwatchName' },
    422     'colorantstype' => { 168 => 'ColorantsType' },
    423     'colorantsyellow' => { 168 => 'ColorantsYellow' },
    424     'colorbalance' => { 70 => 'ColorBalance' },
    425     'colorbalance1' => { 98 => 0xc },
    426     'colorbalanceadj' => { 109 => 0x76a43202 },
    427     'colorbalanceblue' => { 84 => 0x1e },
    428     'colorbalancegreen' => { 84 => 0x1d },
    429     'colorbalancered' => { 84 => 0x1c },
    430     'colorbooster' => { 109 => 0x5f0e7d23 },
    431     'colorboostlevel' => { 105 => 0x1 },
    432     'colorboosttype' => { 105 => 0x0 },
    433     'colorclass' => { 137 => 0xde },
    434     'colorcontrol' => { 120 => 0x102b },
    435     'coloreffect' => { 126 => 0x28 },
    436     'colorfilter' => { 44 => 0x17, 84 => 0x29, 90 => 0x38, 136 => 0x17 },
    437     'colorgain' => { 102 => 0x51 },
    438     'colorhue' => { 9 => 0x2, 98 => 0x8d },
    439     'colormatrix' => { 10 => 0xa, 119 => 0x200, 120 => 0x1011 },
    440     'colormatrix2' => { 123 => 0x200 },
    441     'colormatrixnumber' => { 120 => 0x1019 },
    442     'colormode' => { 45 => 0x3015, 52 => 0x1210, 59 => 0x66, 84 => 0x28, 87 => 0x16, 88 => 0x101, 90 => 0x7, 98 => 0x3, 103 => 0x4, 120 => 0x101, 126 => 0x32, 147 => 0xb029, 160 => 'ColorMode' },
    443     'colormoirereduction' => { 110 => 0x5 },
    444     'colornoisereduction' => { 154 => 'ColorNoiseReduction' },
    445     'colorplanes' => { 51 => 0x2 },
    446     'colorprofile' => { 84 => 0x33 },
    447     'colorrepresentation' => { 56 => 0x3c },
    448     'colorsequence' => { 56 => 0x41 },
    449     'colorspace' => { 9 => 0x3, 16 => 0xb4, 38 => 0x10b4, 48 => 0xa001, 76 => 'ColorSpace', 86 => 0x25, 98 => 0x1e, 115 => 0x507, 134 => 0x37, 146 => 0xb, 157 => 'ColorSpace' },
    450     'colortempasshot' => { 6 => 0x1d, 7 => 0x1c, 8 => 0x43 },
    451     'colortempauto' => { 6 => 0x22, 7 => 0x26, 8 => 0x48 },
    452     'colortempcloudy' => { 6 => 0x31, 7 => 0x35, 8 => 0x5c },
    453     'colortempcustom' => { 8 => 0x84 },
    454     'colortempcustom1' => { 6 => 0x45 },
    455     'colortempcustom2' => { 6 => 0x4a },
    456     'colortempdaylight' => { 6 => 0x27, 7 => 0x2b, 8 => 0x52 },
    457     'colortemperature' => { 10 => 0x9, 16 => 0xae, 21 => 0x9, 38 => 0x10ae, 52 => 0x1005, 70 => 'ColorTemperature', 85 => [0x6e,0x49], 86 => 0x3f, 87 => 0x5e, 88 => 0x10b, 90 => 0x3c },
    458     'colortemperaturebg' => { 120 => 0x1013 },
    459     'colortemperaturerg' => { 120 => 0x1014 },
    460     'colortempflash' => { 6 => 0x40, 7 => 0x49, 8 => 0x70 },
    461     'colortempfluorescent' => { 6 => 0x3b, 7 => 0x3f, 8 => 0x66 },
    462     'colortempkelvin' => { 7 => 0x44, 8 => 0x6b },
    463     'colortempmeasured' => { 8 => 0x4d },
    464     'colortemppc1' => { 7 => 0x94, 8 => 0x75 },
    465     'colortemppc2' => { 7 => 0x99, 8 => 0x7a },
    466     'colortemppc3' => { 7 => 0x9e, 8 => 0x7f },
    467     'colortempshade' => { 6 => 0x2c, 7 => 0x30, 8 => 0x57 },
    468     'colortemptungsten' => { 6 => 0x36, 7 => 0x3a, 8 => 0x61 },
    469     'colortempunknown' => { 7 => 0x21 },
    470     'colortempunknown10' => { 7 => 0x76 },
    471     'colortempunknown11' => { 7 => 0x7b },
    472     'colortempunknown12' => { 7 => 0x80 },
    473     'colortempunknown13' => { 7 => 0x85 },
    474     'colortempunknown14' => { 7 => 0x8a },
    475     'colortempunknown15' => { 7 => 0x8f },
    476     'colortempunknown16' => { 7 => 0xa3 },
    477     'colortempunknown2' => { 7 => 0x4e },
    478     'colortempunknown3' => { 7 => 0x53 },
    479     'colortempunknown4' => { 7 => 0x58 },
    480     'colortempunknown5' => { 7 => 0x5d },
    481     'colortempunknown6' => { 7 => 0x62 },
    482     'colortempunknown7' => { 7 => 0x67 },
    483     'colortempunknown8' => { 7 => 0x6c },
    484     'colortempunknown9' => { 7 => 0x71 },
    485     'colortone' => { 4 => 0x2a },
    486     'colortoneadj' => { 42 => 0x11e },
    487     'colortonefaithful' => { 1 => 0x107 },
    488     'colortonelandscape' => { 1 => 0x105 },
    489     'colortoneneutral' => { 1 => 0x106 },
    490     'colortoneportrait' => { 1 => 0x104 },
    491     'colortonestandard' => { 1 => 0x103 },
    492     'colortoneuserdef1' => { 1 => 0x109 },
    493     'colortoneuserdef2' => { 1 => 0x10a },
    494     'colortoneuserdef3' => { 1 => 0x10b },
    495     'comment' => { 0 => 0x2, 49 => 'Comment', 71 => 'Comment', 125 => 'Comment' },
    496     'componentsconfiguration' => { 48 => 0x9101, 76 => 'Components', 157 => 'ComponentsConfiguration' },
    497     'componentversion' => { 38 => 0x80c },
    498     'composer' => { 164 => 'composer' },
    499     'compressedbitsperpixel' => { 48 => 0x9102, 157 => 'CompressedBitsPerPixel' },
    500     'compressedimagesize' => { 88 => 0x40, 120 => 0x40 },
    501     'compression' => { 48 => 0x103, 161 => 'Compression' },
    502     'compressionfactor' => { 115 => 0x50d },
    503     'compressionratio' => { 76 => 'Compression', 120 => 0x1034 },
    504     'constrainedcropheight' => { 42 => 0x266, 137 => 0xd6 },
    505     'constrainedcropwidth' => { 42 => 0x262, 137 => 0xd5 },
    506     'contact' => { 54 => 0x76 },
    507     'contentlocationcode' => { 54 => 0x1a },
    508     'contentlocationname' => { 54 => 0x1b },
    509     'continuousdrive' => { 4 => 0x5 },
    510     'continuousshootingspeed' => { 25 => 0x610 },
    511     'continuousshotlimit' => { 25 => 0x611 },
    512     'contrast' => { 4 => 0xd, 44 => 0xc, 45 => [0x3012,0x20], 48 => [0xa408,0xfe54], 52 => 0x1004, 70 => 'Contrast', 84 => 0x20, 85 => 0x31, 86 => 0x27, 87 => 0x19, 90 => 0x2, 120 => 0x1029, 126 => 0x2c, 134 => 0x20, 136 => 0xc, 146 => 0xd, 154 => 'Contrast', 157 => 'Contrast' },
    513     'contrastadj' => { 42 => 0x115 },
    514     'contrastfaithful' => { 1 => 0xec },
    515     'contrastlandscape' => { 1 => 0xea },
    516     'contrastmonochrome' => { 1 => 0xed },
    517     'contrastneutral' => { 1 => 0xeb },
    518     'contrastportrait' => { 1 => 0xe9 },
    519     'contrastsetting' => { 115 => 0x505, 123 => 0x1012 },
    520     'contraststandard' => { 1 => 0xe8 },
    521     'contrastuserdef1' => { 1 => 0xee },
    522     'contrastuserdef2' => { 1 => 0xef },
    523     'contrastuserdef3' => { 1 => 0xf0 },
    524     'contributedmediaduration' => { 164 => 'contributedMediaDuration' },
    525     'contributedmediamanaged' => { 164 => 'contributedMediaManaged' },
    526     'contributedmediapath' => { 164 => 'contributedMediaPath' },
    527     'contributedmediastarttime' => { 164 => 'contributedMediaStartTime' },
    528     'contributedmediatrack' => { 164 => 'contributedMediaTrack' },
    529     'contributedmediawebstatement' => { 164 => 'contributedMediaWebStatement' },
    530     'contributor' => { 155 => 'contributor' },
    531     'contributors' => { 71 => 'Contributors' },
    532     'conversionlens' => { 126 => 0x35 },
    533     'converter' => { 48 => 0xfe4d, 103 => 0xb },
    534     'converttograyscale' => { 154 => 'ConvertToGrayscale' },
    535     'copyright' => { 0 => 0x3, 48 => 0x8298, 71 => 'Copyright', 125 => 'Copyright', 142 => 'Copyright', 161 => 'Copyright', 164 => 'copyright' },
    536     'copyrightflag' => { 140 => 0x40a },
    537     'copyrightnotice' => { 54 => 0x74 },
    538     'coringfilter' => { 120 => 0x102d, 123 => 0x310 },
    539     'coringvalues' => { 123 => 0x311 },
    540     'country' => { 75 => 'Country', 160 => 'Country' },
    541     'country-primarylocationcode' => { 54 => 0x64 },
    542     'country-primarylocationname' => { 54 => 0x65 },
    543     'countrycode' => { 138 => 'CountryCode', 158 => 'CountryCode' },
    544     'coverage' => { 155 => 'coverage' },
    545     'crc32' => { 156 => 'crc32' },
    546     'createdate' => { 48 => 0x9004, 71 => 'CreateDate', 142 => 'CreationDate', 162 => 'CreateDate' },
    547     'creationdate' => { 159 => 'CreationDate' },
    548     'creationtime' => { 125 => 'Creation Time' },
    549     'creator' => { 142 => 'Creator', 155 => 'creator', 159 => 'Creator' },
    550     'creatorcontactinfociadrcity' => { 158 => 'CreatorContactInfoCiAdrCity' },
    551     'creatorcontactinfociadrctry' => { 158 => 'CreatorContactInfoCiAdrCtry' },
    552     'creatorcontactinfociadrextadr' => { 158 => 'CreatorContactInfoCiAdrExtadr' },
    553     'creatorcontactinfociadrpcode' => { 158 => 'CreatorContactInfoCiAdrPcode' },
    554     'creatorcontactinfociadrregion' => { 158 => 'CreatorContactInfoCiAdrRegion' },
    555     'creatorcontactinfociemailwork' => { 158 => 'CreatorContactInfoCiEmailWork' },
    556     'creatorcontactinfocitelwork' => { 158 => 'CreatorContactInfoCiTelWork' },
    557     'creatorcontactinfociurlwork' => { 158 => 'CreatorContactInfoCiUrlWork' },
    558     'creatortool' => { 162 => 'CreatorTool' },
    559     'credit' => { 54 => 0x6e, 160 => 'Credit' },
    560     'creditlinereq' => { 166 => 'CreditLineReq' },
    561     'cropactive' => { 42 => 0x244 },
    562     'cropangle' => { 154 => 'CropAngle' },
    563     'cropaspectratio' => { 42 => 0x260 },
    564     'cropbottom' => { 51 => 0x9, 106 => 0x36, 137 => 0xdc, 154 => 'CropBottom' },
    565     'cropheight' => { 42 => 0x24c, 154 => 'CropHeight' },
    566     'crophispeed' => { 98 => 0x1b },
    567     'cropleft' => { 42 => 0x246, 51 => 0x6, 106 => 0x1e, 137 => 0xd9, 154 => 'CropLeft' },
    568     'cropoutputscale' => { 106 => 0xbe },
    569     'cropright' => { 51 => 0x8, 106 => 0x2e, 137 => 0xdb, 154 => 'CropRight' },
    570     'croprotation' => { 51 => 0xb },
    571     'croptop' => { 42 => 0x248, 51 => 0x7, 106 => 0x26, 137 => 0xda, 154 => 'CropTop' },
    572     'cropunits' => { 154 => 'CropUnits' },
    573     'cropwidth' => { 42 => 0x24a, 154 => 'CropWidth' },
    574     'currenticcprofile' => { 48 => 0xc691 },
    575     'currentpreprofilematrix' => { 48 => 0xc692 },
    576     'curves' => { 109 => 0x76a43201 },
    577     'customrendered' => { 48 => 0xa401, 157 => 'CustomRendered' },
    578     'customsaturation' => { 115 => 0x503 },
    579     'd-lightinghq' => { 109 => 0x2175eb78 },
    580     'd-lightinghqselected' => { 109 => 0x6a6e36b6 },
    581     'd-lightinghs' => { 109 => 0xce5554aa },
    582     'd-lightinghsadjustment' => { 108 => 0x0 },
    583     'd-lightinghscolorboost' => { 107 => 0x2, 108 => 0x1 },
    584     'd-lightinghshighlight' => { 107 => 0x1 },
    585     'd-lightinghsshadow' => { 107 => 0x0 },
    586     'datacompressionmethod' => { 56 => 0x6e },
    587     'dataimprint' => { 84 => 0x34 },
    588     'date' => { 134 => 0x6, 155 => 'date' },
    589     'dateacquired' => { 151 => 'DateAcquired' },
    590     'datecreated' => { 54 => 0x37, 160 => 'DateCreated' },
    591     'datesent' => { 55 => 0x46 },
    592     'datestampmode' => { 16 => 0x1c },
    593     'datetime' => { 161 => 'DateTime' },
    594     'datetimedigitized' => { 157 => 'DateTimeDigitized' },
    595     'datetimeoriginal' => { 41 => 0x0, 48 => 0x9003, 71 => 'OriginalDate', 157 => 'DateTimeOriginal' },
    596     'datetimestamp' => { 59 => 0x64 },
    597     'declination' => { 79 => 'Declination' },
    598     'decposition' => { 84 => 0x32 },
    599     'defaultcroporigin' => { 48 => 0xc61f },
    600     'defaultcropsize' => { 48 => 0xc620 },
    601     'defaultscale' => { 48 => 0xc61e },
    602     'defringe' => { 154 => 'Defringe' },
    603     'deletedimagecount' => { 98 => 0xa6 },
    604     'derivedfromdocumentid' => { 165 => 'DerivedFromDocumentID' },
    605     'derivedfrominstanceid' => { 165 => 'DerivedFromInstanceID' },
    606     'derivedfrommanager' => { 165 => 'DerivedFromManager' },
    607     'derivedfrommanagervariant' => { 165 => 'DerivedFromManagerVariant' },
    608     'derivedfrommanageto' => { 165 => 'DerivedFromManageTo' },
    609     'derivedfrommanageui' => { 165 => 'DerivedFromManageUI' },
    610     'derivedfromrenditionclass' => { 165 => 'DerivedFromRenditionClass' },
    611     'derivedfromrenditionparams' => { 165 => 'DerivedFromRenditionParams' },
    612     'derivedfromversionid' => { 165 => 'DerivedFromVersionID' },
    613     'description' => { 125 => 'Description', 155 => 'description' },
    614     'destination' => { 55 => 0x5 },
    615     'destinationcity' => { 134 => 0x24 },
    616     'destinationcitycode' => { 136 => 0x1001 },
    617     'destinationdst' => { 134 => 0x26 },
    618     'developmentdynamicrange' => { 52 => 0x1403 },
    619     'devicesettingdescriptioncolumns' => { 157 => 'DeviceSettingDescriptionColumns' },
    620     'devicesettingdescriptionrows' => { 157 => 'DeviceSettingDescriptionRows' },
    621     'devicesettingdescriptionsettings' => { 157 => 'DeviceSettingDescriptionSettings' },
    622     'dialdirectiontvav' => { 25 => 0x706 },
    623     'digitalcreationdate' => { 54 => 0x3e },
    624     'digitalcreationtime' => { 54 => 0x3f },
    625     'digitalgain' => { 21 => 0xb },
    626     'digitalgem' => { 96 => 0x0 },
    627     'digitalice' => { 102 => 0x100 },
    628     'digitalroc' => { 101 => 0x0 },
    629     'digitalzoom' => { 4 => 0xc, 44 => 0xa, 59 => 0x68, 70 => 'DigitalZoom', 84 => 0xc, 98 => 0x86, 103 => 0xa, 120 => 0x204, 134 => 0x1e, 136 => 0xa, 145 => 0x204 },
    630     'digitalzoomon' => { 145 => 0x21b },
    631     'digitalzoomratio' => { 48 => 0xa404, 157 => 'DigitalZoomRatio' },
    632     'directory' => { 49 => 'Directory' },
    633     'disclaimer' => { 125 => 'Disclaimer' },
    634     'displayaperture' => { 4 => 0x23 },
    635     'displayedunitsx' => { 141 => 0x2 },
    636     'displayedunitsy' => { 141 => 0x6 },
    637     'distance1' => { 59 => 0x28 },
    638     'distance2' => { 59 => 0x2c },
    639     'distance3' => { 59 => 0x30 },
    640     'distance4' => { 59 => 0x34 },
    641     'distortioncorrection' => { 115 => 0x50b },
    642     'distortioncorrection2' => { 119 => 0x1011 },
    643     'dngbackwardversion' => { 48 => 0xc613 },
    644     'dnglensinfo' => { 48 => 0xc630 },
    645     'dngversion' => { 48 => 0xc612 },
    646     'document' => { 125 => 'Document' },
    647     'documenthistory' => { 54 => 0xe7 },
    648     'documentid' => { 165 => 'DocumentID' },
    649     'documentname' => { 48 => 0x10d },
    650     'documentnotes' => { 54 => 0xe6 },
    651     'dotrange' => { 48 => 0x150 },
    652     'drivemode' => { 84 => 0x6, 87 => 0x1e, 115 => 0x600, 134 => 0x34, 146 => 0x3 },
    653     'duration' => { 69 => 'Duration', 83 => 'Duration', 164 => 'duration' },
    654     'dynamicrange' => { 52 => 0x1400 },
    655     'dynamicrangemax' => { 42 => 0x7c },
    656     'dynamicrangemin' => { 42 => 0x7a },
    657     'dynamicrangesetting' => { 52 => 0x1402 },
    658     'easymode' => { 4 => 0xb },
    659     'edgenoisereduction' => { 110 => 0x4 },
    660     'editorialupdate' => { 54 => 0x8 },
    661     'editstatus' => { 54 => 0x7, 138 => 'EditStatus' },
    662     'elevation' => { 79 => 'Elevation' },
    663     'email' => { 71 => 'EMail' },
    664     'engineer' => { 164 => 'engineer' },
    665     'enhancedarktones' => { 104 => 0x8 },
    666     'enhancement' => { 44 => 0x16, 45 => 0x3016 },
    667     'envelopenumber' => { 55 => 0x28 },
    668     'envelopepriority' => { 55 => 0x3c },
    669     'enveloperecordversion' => { 55 => 0x0 },
    670     'epsonimageheight' => { 120 => 0x20c },
    671     'epsonimagewidth' => { 120 => 0x20b },
    672     'epsonsoftware' => { 120 => 0x20d },
    673     'equipmentinstitution' => { 148 => 'EquipmentInstitution' },
    674     'equipmentmanufacturer' => { 148 => 'EquipmentManufacturer' },
    675     'equipmentversion' => { 116 => 0x0 },
    676     'ettlii' => { 25 => 0x304, 26 => 0xd, 27 => 0xe, 28 => 0x7, 29 => 0x7, 30 => 0xe },
    677     'event' => { 150 => 'Event' },
    678     'excursiontolerance' => { 56 => 0x82 },
    679     'exifbyteorder' => { 49 => 'ExifByteOrder' },
    680     'exifcamerainfo' => { 54 => 0xe8 },
    681     'exifimagelength' => { 48 => 0xa003, 157 => 'PixelYDimension' },
    682     'exifimagewidth' => { 48 => 0xa002, 157 => 'PixelXDimension' },
    683     'exifversion' => { 48 => 0x9000, 157 => 'ExifVersion' },
    684     'expirationdate' => { 54 => 0x25 },
    685     'expirationtime' => { 54 => 0x26 },
    686     'exposure' => { 48 => 0xfe51, 154 => 'Exposure' },
    687     'exposurebracketvalue' => { 98 => 0x19 },
    688     'exposurecompensation' => { 22 => 0x6, 34 => 0x0, 48 => 0x9204, 59 => 0x24, 70 => 'ExposureComp', 84 => 0xd, 85 => 0x53, 86 => 0x1e, 87 => 0x1, 120 => 0x1006, 134 => 0x16, 146 => [0xc,0x35], 157 => 'ExposureBiasValue' },
    689     'exposuredifference' => { 98 => 0xe },
    690     'exposureindex' => { 48 => 0xa215, 157 => 'ExposureIndex' },
    691     'exposurelevelincrements' => { 23 => 0x6, 24 => 0x6, 25 => 0x101, 26 => 0x5, 27 => 0x6, 28 => 0x5, 29 => 0x5, 30 => 0x6, 31 => 0x4 },
    692     'exposuremode' => { 48 => 0xa402, 70 => 'ExposureMode', 84 => 0x1, 85 => 0xa, 86 => 0x0, 87 => 0x0, 115 => 0x200, 146 => 0x8, 157 => 'ExposureMode' },
    693     'exposuremodeinmanual' => { 25 => 0x10b },
    694     'exposureprogram' => { 48 => 0x8822, 157 => 'ExposureProgram' },
    695     'exposuretime' => { 1 => 0x4, 2 => 0x4, 3 => 0x6, 22 => 0x16, 48 => 0x829a, 58 => 0xfd05, 59 => 0x20, 60 => 0xfa24, 62 => 0xf104, 66 => 0x38, 70 => 'ExposureTime', 84 => 0x9, 85 => 0x35, 86 => 0x48, 134 => 0x12, 146 => 0x32, 157 => 'ExposureTime' },
    696     'exposurewarning' => { 52 => 0x1302 },
    697     'extender' => { 116 => 0x301 },
    698     'extenderfirmwareversion' => { 116 => 0x304 },
    699     'extendermagnification' => { 72 => 'Magnification' },
    700     'extendermake' => { 72 => 'Make' },
    701     'extendermodel' => { 72 => 'Model', 116 => 0x303 },
    702     'extenderserialnumber' => { 72 => 'SerialNumber', 116 => 0x302 },
    703     'externalflash' => { 118 => 0x1201 },
    704     'externalflashae1' => { 120 => 0x101f },
    705     'externalflashae1_0' => { 120 => 0x101b },
    706     'externalflashae2' => { 120 => 0x1020 },
    707     'externalflashae2_0' => { 120 => 0x101c },
    708     'externalflashbounce' => { 118 => 0x1204, 120 => 0x1026 },
    709     'externalflashguidenumber' => { 118 => 0x1203 },
    710     'externalflashgvalue' => { 120 => 0x1025 },
    711     'externalflashmode' => { 120 => 0x1028, 132 => 0x2 },
    712     'externalflashzoom' => { 118 => 0x1205, 120 => 0x1027 },
    713     'face0position' => { 11 => 0x8 },
    714     'face1position' => { 11 => 0xa },
    715     'face2position' => { 11 => 0xc },
    716     'face3position' => { 11 => 0xe },
    717     'face4position' => { 11 => 0x10 },
    718     'face5position' => { 11 => 0x12 },
    719     'face6position' => { 11 => 0x14 },
    720     'face7position' => { 11 => 0x16 },
    721     'face8position' => { 11 => 0x18 },
    722     'facedetectframeheight' => { 11 => 0x4 },
    723     'facedetectframewidth' => { 11 => 0x3 },
    724     'facesdetected' => { 11 => 0x2, 12 => 0x2 },
    725     'ffid' => { 156 => 'ffid' },
    726     'fieldcount' => { 120 => 0x103f },
    727     'filedatarate' => { 164 => 'fileDataRate' },
    728     'fileformat' => { 36 => 0x0, 55 => 0x14 },
    729     'filemodifydate' => { 49 => 'FileModifyDate' },
    730     'filename' => { 49 => 'FileName' },
    731     'filenumber' => { 2 => 0x172, 13 => 0x1, 16 => 0x8, 38 => 0x1817 },
    732     'filenumbermemory' => { 84 => 0x1a },
    733     'filesource' => { 48 => 0xa300, 52 => 0x8000, 157 => 'FileSource' },
    734     'fileversion' => { 55 => 0x16 },
    735     'fillflashautoreduction' => { 23 => 0xe, 24 => 0xe, 31 => 0xa },
    736     'filllight' => { 154 => 'FillLight' },
    737     'fillorder' => { 48 => 0x10a },
    738     'filmmode' => { 52 => 0x1401, 126 => 0x42 },
    739     'filmtype' => { 102 => 0x2 },
    740     'filter' => { 45 => 0x3017 },
    741     'filtereffect' => { 13 => 0xe },
    742     'filtereffectmonochrome' => { 1 => 0xff },
    743     'finalimageheight' => { 123 => 0x615 },
    744     'finalimagewidth' => { 123 => 0x614 },
    745     'finderdisplayduringexposure' => { 24 => 0x1 },
    746     'firmware' => { 120 => 0x405, 146 => [0x17,0x3b], 152 => 'Firmware' },
    747     'firmwaredate' => { 45 => 0x2001 },
    748     'firmwareid' => { 89 => 0x0 },
    749     'firmwarerevision' => { 1 => 0xa4, 16 => 0x1e },
    750     'firmwareversion' => { 70 => 'FirmwareVersion', 126 => 0x2 },
    751     'fixtureidentifier' => { 54 => 0x16 },
    752     'flash' => { 48 => 0x9209, 85 => 0x1f, 86 => 0x15 },
    753     'flashactivity' => { 4 => 0x1c },
    754     'flashadump' => { 134 => 0x20a },
    755     'flashbdump' => { 134 => 0x20b },
    756     'flashbias' => { 126 => 0x24 },
    757     'flashbits' => { 4 => 0x1d },
    758     'flashchargelevel' => { 120 => 0x1010 },
    759     'flashcompensation' => { 152 => 'FlashCompensation' },
    760     'flashdevice' => { 120 => 0x1005 },
    761     'flashdistance' => { 45 => 0x2034 },
    762     'flashenergy' => { 48 => 0xa20b, 157 => 'FlashEnergy' },
    763     'flashexposurebracketvalue' => { 98 => 0x18 },
    764     'flashexposurecomp' => { 22 => 0xf, 73 => 'ExposureComp', 84 => 0x23, 88 => 0x104, 98 => 0x12, 120 => 0x1023, 134 => 0x4d, 146 => 0x3a },
    765     'flashexposurecompensation' => { 115 => 0x401 },
    766     'flashfired' => { 59 => 0x5d, 73 => 'Fired', 84 => 0x14, 157 => 'FlashFired' },
    767     'flashfiring' => { 25 => 0x306, 26 => 0x6, 27 => 0x7, 30 => 0x7 },
    768     'flashfirmwareversion' => { 116 => 0x1002 },
    769     'flashfunction' => { 157 => 'FlashFunction' },
    770     'flashguidenumber' => { 22 => 0xd, 35 => 0x0, 73 => 'GuideNumber' },
    771     'flashintensity' => { 44 => [0x19,0x5] },
    772     'flashmake' => { 73 => 'Make' },
    773     'flashmanufacturer' => { 151 => 'FlashManufacturer' },
    774     'flashmetering' => { 84 => 0x3f },
    775     'flashmode' => { 44 => 0x4, 59 => 0x5c, 73 => 'Mode', 84 => 0x2, 98 => 0x87, 115 => 0x400, 120 => 0x1004, 134 => 0xc, 136 => 0x4, 143 => 0x20, 145 => 0x225, 157 => 'FlashMode' },
    776     'flashmodecode' => { 132 => 0x1 },
    777     'flashmodel' => { 73 => 'Model', 116 => 0x1001, 151 => 'FlashModel' },
    778     'flashoutput' => { 22 => 0x21 },
    779     'flashpixversion' => { 48 => 0xa000, 157 => 'FlashpixVersion' },
    780     'flashredeyemode' => { 157 => 'FlashRedEyeMode' },
    781     'flashreturn' => { 157 => 'FlashReturn' },
    782     'flashserialnumber' => { 73 => 'SerialNumber', 116 => 0x1003 },
    783     'flashsetting' => { 98 => 0x8 },
    784     'flashstatus' => { 132 => 0x0 },
    785     'flashstrength' => { 52 => 0x1011 },
    786     'flashsyncspeedav' => { 23 => 0x3, 25 => 0x10f, 26 => 0x2, 27 => 0x3, 28 => 0x2, 29 => 0x2, 30 => 0x3, 31 => 0x6 },
    787     'flashthreshold' => { 35 => 0x1 },
    788     'flashtype' => { 73 => 'Type', 98 => 0x9, 116 => 0x1000 },
    789     'flickerreduce' => { 145 => 0x218 },
    790     'fliphorizontal' => { 109 => 0x76a43206 },
    791     'fnumber' => { 1 => 0x3, 2 => 0x3, 3 => 0x5, 22 => 0x15, 48 => 0x829d, 58 => 0xfd04, 59 => 0x1e, 60 => 0xfa23, 62 => 0xf103, 66 => 0x3c, 77 => 'FNumber', 84 => 0xa, 85 => 0x36, 86 => 0x47, 134 => 0x13, 146 => 0x31, 157 => 'FNumber' },
    792     'focallength' => { 1 => 0x9, 2 => 0x1d, 15 => 0x1, 45 => 0x1d, 48 => 0x920a, 77 => 'FocalLength', 84 => 0x12, 134 => 0x1d, 157 => 'FocalLength' },
    793     'focallengthin35mmformat' => { 48 => 0xa405, 157 => 'FocalLengthIn35mmFilm' },
    794     'focalplanediagonal' => { 116 => 0x103, 120 => 0x205 },
    795     'focalplaneresolutionunit' => { 48 => 0xa210, 157 => 'FocalPlaneResolutionUnit' },
    796     'focalplanexresolution' => { 48 => 0xa20e, 157 => 'FocalPlaneXResolution' },
    797     'focalplanexsize' => { 15 => 0x2 },
    798     'focalplaneyresolution' => { 48 => 0xa20f, 157 => 'FocalPlaneYResolution' },
    799     'focalplaneysize' => { 15 => 0x3 },
    800     'focaltype' => { 1 => 0x2d, 15 => 0x0 },
    801     'focalunits' => { 4 => 0x19 },
    802     'focus' => { 103 => 0x8 },
    803     'focusarea' => { 84 => 0x31 },
    804     'focuscontinuous' => { 4 => 0x20 },
    805     'focusdistance' => { 77 => 'FocusDistance', 84 => 0x13, 118 => 0x305 },
    806     'focusdistancelower' => { 22 => 0x14 },
    807     'focusdistanceupper' => { 22 => 0x13 },
    808     'focusinfoversion' => { 118 => 0x0 },
    809     'focusingscreen' => { 24 => 0x0, 25 => 0x80b, 30 => 0x0 },
    810     'focusmode' => { 4 => 0x7, 44 => 0x3, 45 => [0x3003,0xd], 52 => 0x1021, 59 => 0x38, 70 => 'FocusMode', 84 => 0x30, 86 => 0xe, 98 => 0x7, 115 => 0x301, 120 => 0x100b, 126 => 0x7, 134 => 0xd, 136 => 0x3 },
    811     'focuspixel' => { 52 => 0x1023 },
    812     'focusposition' => { 134 => 0x10 },
    813     'focusprocess' => { 115 => 0x302 },
    814     'focusrange' => { 4 => 0x12, 120 => 0x100a },
    815     'focussetting' => { 146 => 0x6 },
    816     'focusstepcount' => { 118 => 0x301, 120 => 0x100e },
    817     'focuswarning' => { 52 => 0x1301 },
    818     'foldername' => { 84 => 0x27 },
    819     'fontschildfontfiles' => { 168 => 'FontsChildFontFiles' },
    820     'fontscomposite' => { 168 => 'FontsComposite' },
    821     'fontsfontface' => { 168 => 'FontsFontFace' },
    822     'fontsfontfamily' => { 168 => 'FontsFontFamily' },
    823     'fontsfontfilename' => { 168 => 'FontsFontFileName' },
    824     'fontsfontname' => { 168 => 'FontsFontName' },
    825     'fontsfonttype' => { 168 => 'FontsFontType' },
    826     'fontsversionstring' => { 168 => 'FontsVersionString' },
    827     'for' => { 142 => 'For' },
    828     'format' => { 155 => 'format' },
    829     'framenum' => { 137 => 0xd7 },
    830     'framenumber' => { 52 => 0x8003, 134 => 0x29 },
    831     'freebytes' => { 38 => 0x1 },
    832     'freememorycardimages' => { 85 => [0x37,0x54], 86 => [0x2d,0x4a] },
    833     'fujiflashmode' => { 52 => 0x1010 },
    834     'fullsizeimage' => { 76 => 'data' },
    835     'fullsizeimagename' => { 76 => '1Name' },
    836     'fullsizeimagetype' => { 76 => '0Type' },
    837     'gaincontrol' => { 48 => 0xa407, 157 => 'GainControl' },
    838     'gamma' => { 48 => 0xa500 },
    839     'gammacompensatedvalue' => { 56 => 0x91 },
    840     'genre' => { 164 => 'genre' },
    841     'globalaltitude' => { 140 => 0x419 },
    842     'globalangle' => { 140 => 0x40d },
    843     'gpsaltitude' => { 53 => 0x6, 74 => 'Altitude', 157 => 'GPSAltitude' },
    844     'gpsaltituderef' => { 53 => 0x5, 157 => 'GPSAltitudeRef' },
    845     'gpsareainformation' => { 53 => 0x1c, 157 => 'GPSAreaInformation' },
    846     'gpsdatestamp' => { 53 => 0x1d },
    847     'gpsdatetime' => { 74 => 'DateTime' },
    848     'gpsdestbearing' => { 53 => 0x18, 74 => 'Bearing', 157 => 'GPSDestBearing' },
    849     'gpsdestbearingref' => { 53 => 0x17, 157 => 'GPSDestBearingRef' },
    850     'gpsdestdistance' => { 53 => 0x1a, 74 => 'Distance', 157 => 'GPSDestDistance' },
    851     'gpsdestdistanceref' => { 53 => 0x19, 157 => 'GPSDestDistanceRef' },
    852     'gpsdestlatitude' => { 53 => 0x14, 157 => 'GPSDestLatitude' },
    853     'gpsdestlatituderef' => { 53 => 0x13 },
    854     'gpsdestlongitude' => { 53 => 0x16, 157 => 'GPSDestLongitude' },
    855     'gpsdestlongituderef' => { 53 => 0x15 },
    856     'gpsdifferential' => { 53 => 0x1e, 74 => 'Differential', 157 => 'GPSDifferential' },
    857     'gpsdop' => { 53 => 0xb, 157 => 'GPSDOP' },
    858     'gpsimgdirection' => { 53 => 0x11, 157 => 'GPSImgDirection' },
    859     'gpsimgdirectionref' => { 53 => 0x10, 157 => 'GPSImgDirectionRef' },
    860     'gpslatitude' => { 53 => 0x2, 74 => 'Latitude', 157 => 'GPSLatitude' },
    861     'gpslatituderef' => { 53 => 0x1 },
    862     'gpslongitude' => { 53 => 0x4, 74 => 'Longitude', 157 => 'GPSLongitude' },
    863     'gpslongituderef' => { 53 => 0x3 },
    864     'gpsmapdatum' => { 53 => 0x12, 74 => 'Datum', 157 => 'GPSMapDatum' },
    865     'gpsmeasuremode' => { 53 => 0xa, 74 => 'MeasureMode', 157 => 'GPSMeasureMode' },
    866     'gpsprocessingmethod' => { 53 => 0x1b, 157 => 'GPSProcessingMethod' },
    867     'gpssatellites' => { 53 => 0x8, 74 => 'Satellites', 157 => 'GPSSatellites' },
    868     'gpsspeed' => { 53 => 0xd, 74 => 'Speed', 157 => 'GPSSpeed' },
    869     'gpsspeedref' => { 53 => 0xc, 157 => 'GPSSpeedRef' },
    870     'gpsstatus' => { 53 => 0x9, 157 => 'GPSStatus' },
    871     'gpstimestamp' => { 53 => 0x7, 157 => 'GPSTimeStamp' },
    872     'gpstrack' => { 53 => 0xf, 74 => 'Heading', 157 => 'GPSTrack' },
    873     'gpstrackref' => { 53 => 0xe, 157 => 'GPSTrackRef' },
    874     'gpsversionid' => { 53 => 0x0, 157 => 'GPSVersionID' },
    875     'gradation' => { 115 => 0x50f },
    876     'grayresponseunit' => { 48 => 0x122 },
    877     'greencurvelimits' => { 42 => 0x1c4 },
    878     'greencurvepoints' => { 42 => 0x19a },
    879     'greenhue' => { 154 => 'GreenHue' },
    880     'greensaturation' => { 154 => 'GreenSaturation' },
    881     'halftonehints' => { 48 => 0x141 },
    882     'hascrop' => { 154 => 'HasCrop' },
    883     'hassettings' => { 154 => 'HasSettings' },
    884     'headline' => { 54 => 0x69, 160 => 'Headline' },
    885     'hierarchicalsubject' => { 149 => 'hierarchicalSubject' },
    886     'highisonoisereduction' => { 25 => 0x202, 98 => 0xb1 },
    887     'highlight' => { 146 => 0xf },
    888     'highlightrecovery' => { 154 => 'HighlightRecovery' },
    889     'highlighttonepriority' => { 25 => 0x203 },
    890     'history' => { 160 => 'History' },
    891     'historyaction' => { 165 => 'HistoryAction' },
    892     'historyinstanceid' => { 165 => 'HistoryInstanceID' },
    893     'historyparameters' => { 165 => 'HistoryParameters' },
    894     'historysoftwareagent' => { 165 => 'HistorySoftwareAgent' },
    895     'historywhen' => { 165 => 'HistoryWhen' },
    896     'hometowncity' => { 45 => 0x3006, 134 => 0x23 },
    897     'hometowncitycode' => { 136 => 0x1000 },
    898     'hometowndst' => { 134 => 0x25 },
    899     'hostcomputer' => { 48 => 0x13c },
    900     'hue' => { 90 => 0x3b },
    901     'hueadjustment' => { 98 => 0x92 },
    902     'hueadjustmentaqua' => { 154 => 'HueAdjustmentAqua' },
    903     'hueadjustmentblue' => { 154 => 'HueAdjustmentBlue' },
    904     'hueadjustmentgreen' => { 154 => 'HueAdjustmentGreen' },
    905     'hueadjustmentmagenta' => { 154 => 'HueAdjustmentMagenta' },
    906     'hueadjustmentorange' => { 154 => 'HueAdjustmentOrange' },
    907     'hueadjustmentpurple' => { 154 => 'HueAdjustmentPurple' },
    908     'hueadjustmentred' => { 154 => 'HueAdjustmentRed' },
    909     'hueadjustmentyellow' => { 154 => 'HueAdjustmentYellow' },
    910     'huesetting' => { 123 => 0x1011 },
    911     'icc_profile' => { 49 => 'ICC_Profile' },
    912     'iccprofilename' => { 160 => 'ICCProfile' },
    913     'identifier' => { 155 => 'identifier', 162 => 'Identifier' },
    914     'imageadjustment' => { 98 => 0x80, 103 => 0x5 },
    915     'imageareaoffset' => { 134 => 0x38 },
    916     'imageauthentication' => { 98 => 0x20 },
    917     'imageboundary' => { 98 => 0x16 },
    918     'imagecount' => { 98 => 0xa5 },
    919     'imagedatasize' => { 98 => 0xa2 },
    920     'imagedescription' => { 48 => 0x10e, 161 => 'ImageDescription' },
    921     'imagedustoff' => { 109 => 0xfe443a45 },
    922     'imageheight' => { 48 => 0x101, 89 => 0xc, 161 => 'ImageLength' },
    923     'imagehistory' => { 48 => 0x9213 },
    924     'imagenumber' => { 1 => 0xd0, 48 => 0x9211, 70 => 'ImageNumber', 85 => 0xae, 86 => 0x5e, 152 => 'ImageNumber' },
    925     'imagenumber2' => { 86 => 0x62 },
    926     'imageoptimization' => { 98 => 0xa9 },
    927     'imageorientation' => { 54 => 0x83 },
    928     'imageprocessing' => { 98 => 0x1a, 134 => 0x32 },
    929     'imageprocessingversion' => { 119 => 0x0 },
    930     'imagequality' => { 70 => 'ImageQuality', 126 => 0x1 },
    931     'imagequality2' => { 115 => 0x603 },
    932     'imagesize' => { 76 => 'ImageSize' },
    933     'imagesourcedata' => { 48 => 0x935c },
    934     'imagestabilization' => { 4 => 0x22, 45 => 0x3020, 70 => 'ImageStabilization', 85 => 0xbd, 86 => 0x71, 87 => 0x87, 88 => [0x18,0x107,0x113], 98 => 0xac, 118 => 0x1600, 126 => 0x1a },
    935     'imagetone' => { 134 => 0x4f },
    936     'imagetype' => { 54 => 0x82 },
    937     'imageuniqueid' => { 48 => 0xa420, 157 => 'ImageUniqueID' },
    938     'imagewidth' => { 48 => 0x100, 89 => 0xe, 161 => 'ImageWidth' },
    939     'incrementaltemperature' => { 154 => 'IncrementalTemperature' },
    940     'incrementaltint' => { 154 => 'IncrementalTint' },
    941     'infinitylensstep' => { 120 => 0x103b },
    942     'infobuttonwhenshooting' => { 25 => 0x409 },
    943     'inkset' => { 48 => 0x14c },
    944     'instanceid' => { 165 => 'InstanceID' },
    945     'instructions' => { 160 => 'Instructions' },
    946     'instrument' => { 164 => 'instrument' },
    947     'intellectualgenre' => { 158 => 'IntellectualGenre' },
    948     'interchangecolorspace' => { 56 => 0x40 },
    949     'internalflash' => { 84 => 0x2b, 118 => 0x1208 },
    950     'internalflashae1' => { 120 => 0x1021 },
    951     'internalflashae1_0' => { 120 => 0x101d },
    952     'internalflashae2' => { 120 => 0x1022 },
    953     'internalflashae2_0' => { 120 => 0x101e },
    954     'internalflashmagni' => { 132 => 0x3 },
    955     'internalflashtable' => { 120 => 0x1024 },
    956     'internalserialnumber' => { 16 => 0x96, 52 => 0x10, 116 => 0x102, 126 => 0x25, 131 => 0x4 },
    957     'interopindex' => { 48 => 0x1 },
    958     'interopversion' => { 48 => 0x2 },
    959     'intervallength' => { 84 => 0x10 },
    960     'intervalmode' => { 84 => 0x26 },
    961     'intervalnumber' => { 84 => 0x11 },
    962     'introtime' => { 164 => 'introTime' },
    963     'iptc-naa' => { 48 => 0x83bb },
    964     'iptcbitspersample' => { 56 => 0x56 },
    965     'iptcimageheight' => { 56 => 0x1e },
    966     'iptcimagerotation' => { 56 => 0x66 },
    967     'iptcimagewidth' => { 56 => 0x14 },
    968     'iptcpicturenumber' => { 56 => 0xa },
    969     'iptcpixelheight' => { 56 => 0x32 },
    970     'iptcpixelwidth' => { 56 => 0x28 },
    971     'iso' => { 1 => 0x6, 2 => 0x6, 3 => 0x0, 44 => 0x14, 45 => [0x3014,0x14], 48 => 0x8827, 58 => 0xfd06, 59 => 0x60, 60 => [0xfa2e,0xfa46], 61 => [0x27,0x28], 62 => 0xf105, 66 => 0x4e, 70 => 'ISO', 84 => 0x8, 98 => 0x2, 127 => 0x17, 134 => 0x14, 136 => 0x14, 157 => 'ISOSpeedRatings' },
    972     'isoexpansion' => { 25 => 0x103, 26 => 0x7, 27 => 0x8, 30 => 0x8 },
    973     'isoselection' => { 98 => 0xf },
    974     'isosetting' => { 59 => 0x5e, 70 => 'ISOSetting', 84 => 0x24, 85 => 0x26, 86 => 0x1c, 90 => 0x6, 98 => 0x13, 143 => 0x27 },
    975     'isospeedexpansion' => { 24 => 0x3 },
    976     'isospeedincrements' => { 25 => 0x102 },
    977     'isospeedrange' => { 25 => 0x103 },
    978     'isovalue' => { 120 => 0x1001 },
    979     'jobid' => { 54 => 0xb8 },
    980     'jobrefid' => { 163 => 'JobRefId' },
    981     'jobrefname' => { 163 => 'JobRefName' },
    982     'jobrefurl' => { 163 => 'JobRefUrl' },
    983     'jpgfromraw' => { 38 => 0x2007, 46 => 'JpgFromRaw' },
    984     'jpgfromrawlength' => { 48 => [0x117,0x202] },
    985     'jpgfromrawstart' => { 48 => [0x111,0x201] },
    986     'key' => { 164 => 'key' },
    987     'keywords' => { 54 => 0x19, 71 => 'Keywords', 142 => 'Keywords', 159 => 'Keywords' },
    988     'kodakimageheight' => { 58 => 0xf908, 59 => 0xe, 60 => [0xfa1e,0xfa52], 65 => 0x70 },
    989     'kodakimagewidth' => { 58 => 0xf907, 59 => 0xc, 60 => [0xfa1d,0xfa51], 65 => 0x6c },
    990     'kodakinfotype' => { 58 => 0xfa00 },
    991     'kodakmaker' => { 65 => 0x8 },
    992     'kodakmodel' => { 59 => 0x0, 65 => 0x28 },
    993     'label' => { 125 => 'Label', 162 => 'Label' },
    994     'language' => { 155 => 'language' },
    995     'languageidentifier' => { 54 => 0x87 },
    996     'lastfilenumber' => { 84 => 0x1b },
    997     'lastkeywordiptc' => { 151 => 'LastKeywordIPTC' },
    998     'lastkeywordxmp' => { 151 => 'LastKeywordXMP' },
    999     'lasturl' => { 165 => 'LastURL' },
    1000     'lcddisplayatpoweron' => { 29 => 0xa },
    1001     'lcddisplayreturntoshoot' => { 30 => 0x12 },
    1002     'lcdilluminationduringbulb' => { 25 => 0x408 },
    1003     'lcdpanels' => { 24 => 0x8 },
    1004     'lcheditor' => { 109 => 0x8ae85e },
    1005     'legacyiptcdigest' => { 160 => 'LegacyIPTCDigest' },
    1006     'lens' => { 48 => 0xfdea, 98 => 0x84, 146 => 0xa, 152 => 'Lens' },
    1007     'lensafstopbutton' => { 23 => 0x11, 24 => 0x13, 25 => 0x506, 26 => 0x10, 27 => 0x12, 30 => 0x13, 31 => 0x9 },
    1008     'lensaperturerange' => { 146 => 0x30 },
    1009     'lenscodes' => { 133 => [0x4,0x5] },
    1010     'lensdataversion' => { 97 => 0x0 },
    1011     'lensdistortionparams' => { 120 => 0x206 },
    1012     'lensdrivenoaf' => { 25 => 0x505 },
    1013     'lensfirmwareversion' => { 116 => 0x204 },
    1014     'lensfstops' => { 97 => 0x7, 98 => 0x8b },
    1015     'lensid' => { 88 => 0x10c },
    1016     'lensidnumber' => { 97 => 0x6 },
    1017     'lensinfo' => { 152 => 'LensInfo' },
    1018     'lensmake' => { 77 => 'Make' },
    1019     'lensmanufacturer' => { 151 => 'LensManufacturer' },
    1020     'lensmodel' => { 77 => 'Model', 151 => 'LensModel' },
    1021     'lensproperties' => { 116 => 0x20b },
    1022     'lensserialnumber' => { 77 => 'SerialNumber', 116 => 0x202, 126 => 0x52 },
    1023     'lenstemperature' => { 120 => 0x1008 },
    1024     'lenstype' => { 1 => 0xd, 4 => 0x16, 16 => 0x95, 98 => 0x83, 116 => 0x201, 126 => 0x51, 133 => 0x0, 134 => 0x3f },
    1025     'license' => { 153 => 'license' },
    1026     'licensetype' => { 156 => 'licensetype' },
    1027     'lightcondition' => { 120 => 0x1009 },
    1028     'lightsource' => { 48 => 0x9208, 98 => 0x90, 123 => 0x1000, 157 => 'LightSource' },
    1029     'lightsourcespecial' => { 145 => 0x21d },
    1030     'lightvaluecenter' => { 120 => 0x103d },
    1031     'lightvalueperiphery' => { 120 => 0x103e },
    1032     'linearresponselimit' => { 48 => 0xc62e },
    1033     'liveviewexposuresimulation' => { 25 => 0x810 },
    1034     'localcaption' => { 54 => 0x79 },
    1035     'localizedcameramodel' => { 48 => 0xc615 },
    1036     'location' => { 150 => 'Location', 158 => 'Location' },
    1037     'lockmicrophonebutton' => { 25 => 0x709 },
    1038     'logcomment' => { 164 => 'logComment' },
    1039     'longexposurenoisereduction' => { 25 => 0x201, 26 => 0x1, 27 => 0x2, 28 => 0x1, 29 => 0x1, 30 => 0x2, 31 => 0x1 },
    1040     'longfocal' => { 1 => 0x13, 2 => 0x115, 4 => 0x17 },
    1041     'loop' => { 164 => 'loop' },
    1042     'luminanceadjustmentaqua' => { 154 => 'LuminanceAdjustmentAqua' },
    1043     'luminanceadjustmentblue' => { 154 => 'LuminanceAdjustmentBlue' },
    1044     'luminanceadjustmentgreen' => { 154 => 'LuminanceAdjustmentGreen' },
    1045     'luminanceadjustmentmagenta' => { 154 => 'LuminanceAdjustmentMagenta' },
    1046     'luminanceadjustmentorange' => { 154 => 'LuminanceAdjustmentOrange' },
    1047     'luminanceadjustmentpurple' => { 154 => 'LuminanceAdjustmentPurple' },
    1048     'luminanceadjustmentred' => { 154 => 'LuminanceAdjustmentRed' },
    1049     'luminanceadjustmentyellow' => { 154 => 'LuminanceAdjustmentYellow' },
    1050     'luminancenoisereduction' => { 43 => 0xbe },
    1051     'luminancesmoothing' => { 154 => 'LuminanceSmoothing' },
    1052     'macro' => { 52 => 0x1020, 120 => 0x202, 143 => 0x21, 145 => 0x202 },
    1053     'macromode' => { 4 => 0x1, 84 => 0xb, 115 => 0x300, 126 => 0x1c },
    1054     'magnifiedview' => { 27 => 0x11, 29 => 0x9 },
    1055     'make' => { 39 => 0x0, 48 => 0x10f, 70 => 'Make', 125 => 'Make', 127 => 0x10f, 161 => 'Make' },
    1056     'makernote' => { 157 => 'MakerNote' },
    1057     'makernotecanon' => { 47 => 'MakN', 48 => 0x927c },
    1058     'makernotecasio' => { 47 => 'MakN', 48 => 0x927c },
    1059     'makernotecasio2' => { 47 => 'MakN', 48 => 0x927c },
    1060     'makernotefujifilm' => { 47 => 'MakN', 48 => 0x927c },
    1061     'makernotehp' => { 47 => 'MakN', 48 => 0x927c },
    1062     'makernotehp2' => { 47 => 'MakN', 48 => 0x927c },
    1063     'makernotehp4' => { 47 => 'MakN', 48 => 0x927c },
    1064     'makernotehp6' => { 47 => 'MakN', 48 => 0x927c },
    1065     'makernotejvc' => { 47 => 'MakN', 48 => 0x927c },
    1066     'makernotejvctext' => { 47 => 'MakN', 48 => 0x927c },
    1067     'makernotekodak1a' => { 47 => 'MakN', 48 => 0x927c },
    1068     'makernotekodak1b' => { 47 => 'MakN', 48 => 0x927c },
    1069     'makernotekodak2' => { 47 => 'MakN', 48 => 0x927c },
    1070     'makernotekodak3' => { 47 => 'MakN', 48 => 0x927c },
    1071     'makernotekodak4' => { 47 => 'MakN', 48 => 0x927c },
    1072     'makernotekodak5' => { 47 => 'MakN', 48 => 0x927c },
    1073     'makernotekodak6a' => { 47 => 'MakN', 48 => 0x927c },
    1074     'makernotekodak6b' => { 47 => 'MakN', 48 => 0x927c },
    1075     'makernotekodak7' => { 47 => 'MakN', 48 => 0x927c },
    1076     'makernotekodakifd' => { 47 => 'MakN', 48 => 0x927c },
    1077     'makernotekodakunknown' => { 47 => 'MakN', 48 => 0x927c },
    1078     'makernotekyocera' => { 47 => 'MakN', 48 => 0x927c },
    1079     'makernoteleica' => { 47 => 'MakN', 48 => 0x927c },
    1080     'makernoteminolta' => { 47 => 'MakN', 48 => 0x927c },
    1081     'makernoteminolta2' => { 47 => 'MakN', 48 => 0x927c },
    1082     'makernoteminolta3' => { 47 => 'MakN', 48 => 0x927c },
    1083     'makernotenikon' => { 47 => 'MakN', 48 => 0x927c },
    1084     'makernotenikon2' => { 47 => 'MakN', 48 => 0x927c },
    1085     'makernotenikon3' => { 47 => 'MakN', 48 => 0x927c },
    1086     'makernoteoffset' => { 145 => 0xff },
    1087     'makernoteolympus' => { 47 => 'MakN', 48 => 0x927c },
    1088     'makernoteolympus2' => { 47 => 'MakN', 48 => 0x927c },
    1089     'makernotepanasonic' => { 47 => 'MakN', 48 => 0x927c },
    1090     'makernotepanasonic2' => { 47 => 'MakN', 48 => 0x927c },
    1091     'makernotepentax' => { 47 => 'MakN', 48 => 0x927c },
    1092     'makernotepentax2' => { 47 => 'MakN', 48 => 0x927c },
    1093     'makernotepentax3' => { 47 => 'MakN', 48 => 0x927c },
    1094     'makernotepentax4' => { 47 => 'MakN', 48 => 0x927c },
    1095     'makernotericoh' => { 47 => 'MakN', 48 => 0x927c },
    1096     'makernotericohtext' => { 47 => 'MakN', 48 => 0x927c },
    1097     'makernotesafety' => { 48 => 0xc635 },
    1098     'makernotesanyo' => { 47 => 'MakN', 48 => 0x927c },
    1099     'makernotesanyoc4' => { 47 => 'MakN', 48 => 0x927c },
    1100     'makernotesanyopatch' => { 47 => 'MakN', 48 => 0x927c },
    1101     'makernotesigma' => { 47 => 'MakN', 48 => 0x927c },
    1102     'makernotesony' => { 47 => 'MakN', 48 => 0x927c },
    1103     'makernotesonysr2' => { 47 => 'MakN', 48 => 0x927c },
    1104     'makernotesonysrf' => { 47 => 'MakN', 48 => 0x927c },
    1105     'makernotetype' => { 144 => 0x1 },
    1106     'makernoteunknown' => { 47 => 'MakN', 48 => 0x927c },
    1107     'makernoteversion' => { 88 => 0x0, 98 => 0x1, 120 => 0x0, 126 => 0x8000, 144 => 0x2, 146 => 0x1d },
    1108     'managedfromdocumentid' => { 165 => 'ManagedFromDocumentID' },
    1109     'managedfrominstanceid' => { 165 => 'ManagedFromInstanceID' },
    1110     'managedfrommanager' => { 165 => 'ManagedFromManager' },
    1111     'managedfrommanagervariant' => { 165 => 'ManagedFromManagerVariant' },
    1112     'managedfrommanageto' => { 165 => 'ManagedFromManageTo' },
    1113     'managedfrommanageui' => { 165 => 'ManagedFromManageUI' },
    1114     'managedfromrenditionclass' => { 165 => 'ManagedFromRenditionClass' },
    1115     'managedfromrenditionparams' => { 165 => 'ManagedFromRenditionParams' },
    1116     'managedfromversionid' => { 165 => 'ManagedFromVersionID' },
    1117     'manager' => { 165 => 'Manager' },
    1118     'managervariant' => { 165 => 'ManagerVariant' },
    1119     'manageto' => { 165 => 'ManageTo' },
    1120     'manageui' => { 165 => 'ManageUI' },
    1121     'manometerreading' => { 115 => 0x901 },
    1122     'manualflash' => { 118 => 0x1209 },
    1123     'manualflashoutput' => { 4 => 0x29 },
    1124     'manualfocusdistance' => { 98 => 0x85, 120 => 0x100c, 145 => 0x223 },
    1125     'manualtv' => { 24 => 0x5, 25 => 0x705 },
    1126     'manufacturedate' => { 131 => 0x1 },
    1127     'marked' => { 167 => 'Marked' },
    1128     'markerscomment' => { 164 => 'markersComment' },
    1129     'markersduration' => { 164 => 'markersDuration' },
    1130     'markerslocation' => { 164 => 'markersLocation' },
    1131     'markersname' => { 164 => 'markersName' },
    1132     'markersstarttime' => { 164 => 'markersStartTime' },
    1133     'markerstarget' => { 164 => 'markersTarget' },
    1134     'markerstype' => { 164 => 'markersType' },
    1135     'maskedareas' => { 48 => 0xc68e },
    1136     'masterdocumentid' => { 54 => 0xb9 },
    1137     'mastergain' => { 102 => 0x50 },
    1138     'maxaperture' => { 4 => 0x1a, 62 => 0x6103, 77 => 'MaxAperture', 84 => 0x17 },
    1139     'maxapertureatcurrentfocal' => { 116 => 0x20a },
    1140     'maxapertureatmaxfocal' => { 52 => 0x1407, 77 => 'MaxApertureAtMaxFocal', 97 => 0xb, 116 => 0x206 },
    1141     'maxapertureatminfocal' => { 52 => 0x1406, 97 => 0xa, 116 => 0x205 },
    1142     'maxaperturevalue' => { 48 => 0x9205, 157 => 'MaxApertureValue' },
    1143     'maxfocallength' => { 52 => 0x1405, 77 => 'MaxFocalLength', 97 => 0x9, 116 => 0x208 },
    1144     'maximumdensityrange' => { 56 => 0x8c },
    1145     'maxpagesizeh' => { 168 => 'MaxPageSizeH' },
    1146     'maxpagesizeunit' => { 168 => 'MaxPageSizeUnit' },
    1147     'maxpagesizew' => { 168 => 'MaxPageSizeW' },
    1148     'maxsamplevalue' => { 48 => 0x119 },
    1149     'mcuversion' => { 97 => 0xc },
    1150     'md5digest' => { 78 => 'zmd5' },
    1151     'measuredev' => { 22 => 0x3, 38 => 0x1814, 70 => 'MeasuredEV' },
    1152     'menubuttondisplayposition' => { 23 => 0xb, 26 => 0xa, 27 => 0xb, 30 => 0xb },
    1153     'menubuttonreturn' => { 31 => 0xb },
    1154     'metadatadate' => { 162 => 'MetadataDate' },
    1155     'metadatamoddate' => { 164 => 'metadataModDate' },
    1156     'meteringmode' => { 4 => 0x11, 48 => 0x9207, 59 => 0x1c, 84 => 0x7, 85 => 0x25, 115 => 0x202, 134 => 0x17, 146 => 0x9, 157 => 'MeteringMode' },
    1157     'mieversion' => { 78 => '0Vers' },
    1158     'minaperture' => { 4 => 0x1b, 77 => 'MinAperture' },
    1159     'minfocallength' => { 52 => 0x1404, 77 => 'MinFocalLength', 97 => 0x8, 116 => 0x207 },
    1160     'minoltadate' => { 84 => 0x15 },
    1161     'minoltaimagesize' => { 84 => 0x4, 85 => 0xc, 86 => 0x2, 88 => 0x103 },
    1162     'minoltamodelid' => { 84 => 0x25 },
    1163     'minoltaquality' => { 84 => 0x5, 85 => 0xd, 86 => 0x3, 88 => [0x102,0x103], 120 => [0x102,0x103] },
    1164     'minoltatime' => { 84 => 0x16 },
    1165     'minsamplevalue' => { 48 => 0x118 },
    1166     'mirrorlockup' => { 23 => 0xc, 24 => 0xc, 25 => 0x60f, 26 => 0xb, 27 => 0xc, 28 => 0x6, 29 => 0x6, 30 => 0xc, 31 => 0x3 },
    1167     'moddate' => { 159 => 'ModDate' },
    1168     'model' => { 39 => 0x6, 48 => 0x110, 70 => 'Model', 125 => 'Model', 127 => 0x110, 161 => 'Model' },
    1169     'modelrevision' => { 131 => 0x2 },
    1170     'modifiedcolortemp' => { 17 => 0x9 },
    1171     'modifieddigitalgain' => { 17 => 0xb },
    1172     'modifiedparamflag' => { 14 => 0x1 },
    1173     'modifiedpicturestyle' => { 17 => 0xa },
    1174     'modifiedsaturation' => { 115 => 0x504 },
    1175     'modifiedsensorbluelevel' => { 17 => 0x5 },
    1176     'modifiedsensorredlevel' => { 17 => 0x4 },
    1177     'modifiedsharpness' => { 17 => 0x2 },
    1178     'modifiedsharpnessfreq' => { 17 => 0x3 },
    1179     'modifiedtonecurve' => { 17 => 0x1 },
    1180     'modifiedwhitebalance' => { 17 => 0x8 },
    1181     'modifiedwhitebalanceblue' => { 17 => 0x7 },
    1182     'modifiedwhitebalancered' => { 17 => 0x6 },
    1183     'modifydate' => { 48 => 0x132, 71 => 'ModifyDate', 124 => 'tIME', 142 => 'ModDate', 162 => 'ModifyDate' },
    1184     'moirefilter' => { 48 => 0xfe58 },
    1185     'monochromecontrast' => { 43 => 0x78 },
    1186     'monochromefiltereffect' => { 43 => 0x74 },
    1187     'monochromelinear' => { 43 => 0x7a },
    1188     'monochromesharpness' => { 43 => 0x7c },
    1189     'monochrometoningeffect' => { 43 => 0x76 },
    1190     'monthdaycreated' => { 59 => 0x12, 66 => 0xe },
    1191     'multiexposureautogain' => { 99 => 0x3 },
    1192     'multiexposuremode' => { 99 => 0x1 },
    1193     'multiexposureshots' => { 99 => 0x2 },
    1194     'multiexposureversion' => { 99 => 0x0 },
    1195     'multisample' => { 102 => 0x40 },
    1196     'mycolormode' => { 18 => 0x2 },
    1197     'nativedigest' => { 157 => 'NativeDigest', 161 => 'NativeDigest' },
    1198     'ndfilter' => { 22 => 0x1c },
    1199     'nearlensstep' => { 120 => 0x103c },
    1200     'newsphotoversion' => { 56 => 0x0 },
    1201     'nickname' => { 162 => 'Nickname' },
    1202     'nikoncaptureversion' => { 98 => 0xe09 },
    1203     'noisefilter' => { 115 => 0x527 },
    1204     'noisereduction' => { 13 => 0x8, 85 => 0xb0, 86 => 0x60, 87 => 0x3f, 98 => 0x95, 109 => 0x753dcbc0, 115 => 0x50a, 120 => 0x103a, 126 => 0x2d, 134 => 0x49 },
    1205     'noisereduction2' => { 119 => 0x1010 },
    1206     'noisereductionintensity' => { 110 => 0x9 },
    1207     'noisereductionmethod' => { 110 => 0x11 },
    1208     'noisereductionsharpness' => { 110 => 0xd },
    1209     'npages' => { 168 => 'NPages' },
    1210     'nullrecord' => { 38 => 0x0 },
    1211     'numberofbeats' => { 164 => 'numberOfBeats' },
    1212     'numindexentries' => { 56 => 0x54 },
    1213     'objectattributereference' => { 54 => 0x4 },
    1214     'objectcycle' => { 54 => 0x4b },
    1215     'objectdistance' => { 44 => 0x6, 45 => 0x2022 },
    1216     'objectname' => { 54 => 0x5 },
    1217     'objectpreviewdata' => { 54 => 0xca },
    1218     'objectpreviewfileformat' => { 54 => 0xc8 },
    1219     'objectpreviewfileversion' => { 54 => 0xc9 },
    1220     'objecttypereference' => { 54 => 0x3 },
    1221     'oecfcolumns' => { 157 => 'OECFColumns' },
    1222     'oecfnames' => { 157 => 'OECFNames' },
    1223     'oecfrows' => { 157 => 'OECFRows' },
    1224     'oecfvalues' => { 157 => 'OECFValues' },
    1225     'offsetschema' => { 48 => 0xea1d },
    1226     'oldsubfiletype' => { 48 => 0xff },
    1227     'olympusimageheight' => { 120 => 0x102f },
    1228     'olympusimageheight2' => { 119 => 0x615 },
    1229     'olympusimagewidth' => { 120 => 0x102e },
    1230     'olympusimagewidth2' => { 119 => 0x614 },
    1231     'onetouchwb' => { 120 => 0x302 },
    1232     'opticalzoom' => { 60 => 0xfa3d, 62 => [0x6006,0xf006], 63 => 0x1000, 64 => 0xf, 66 => 0x1e, 77 => 'OpticalZoom' },
    1233     'opticalzoomcode' => { 22 => 0xa },
    1234     'opticalzoommode' => { 126 => 0x34 },
    1235     'opticalzoomon' => { 145 => 0x219 },
    1236     'ordernumber' => { 52 => 0x8002 },
    1237     'orientation' => { 48 => 0x112, 127 => 0x112, 161 => 'Orientation' },
    1238     'originaldecisiondata' => { 16 => 0x83 },
    1239     'originalfilename' => { 38 => 0x816, 67 => 0x20 },
    1240     'originalimageheight' => { 51 => 0x1 },
    1241     'originalimagewidth' => { 51 => 0x0 },
    1242     'originalrawfiledata' => { 48 => 0xc68c },
    1243     'originalrawfilename' => { 48 => 0xc68b },
    1244     'originaltransmissionreference' => { 54 => 0x67 },
    1245     'originatingprogram' => { 54 => 0x41 },
    1246     'os' => { 156 => 'os' },
    1247     'outcue' => { 164 => 'outCue' },
    1248     'outputheight' => { 106 => 0xce },
    1249     'outputheightinches' => { 106 => 0x96 },
    1250     'outputpixels' => { 106 => 0xd6 },
    1251     'outputresolution' => { 106 => 0xb6 },
    1252     'outputwidth' => { 106 => 0xc6 },
    1253     'outputwidthinches' => { 106 => 0x8e },
    1254     'owner' => { 167 => 'Owner' },
    1255     'ownerid' => { 54 => 0xbc },
    1256     'ownername' => { 16 => 0x9, 38 => 0x810, 48 => 0xfde8, 70 => 'OwnerName', 152 => 'OwnerName' },
    1257     'pagename' => { 48 => 0x11d },
    1258     'pagenumber' => { 48 => 0x129 },
    1259     'panasonicexifversion' => { 126 => 0x26 },
    1260     'panasonicrawversion' => { 127 => 0x1 },
    1261     'panoramadirection' => { 19 => 0x5 },
    1262     'panoramaframe' => { 19 => 0x2 },
    1263     'panoramamode' => { 59 => 0x3c, 115 => 0x601 },
    1264     'parametricdarks' => { 154 => 'ParametricDarks' },
    1265     'parametrichighlights' => { 154 => 'ParametricHighlights' },
    1266     'parametrichighlightsplit' => { 154 => 'ParametricHighlightSplit' },
    1267     'parametriclights' => { 154 => 'ParametricLights' },
    1268     'parametricmidtonesplit' => { 154 => 'ParametricMidtoneSplit' },
    1269     'parametricshadows' => { 154 => 'ParametricShadows' },
    1270     'parametricshadowsplit' => { 154 => 'ParametricShadowSplit' },
    1271     'patientid' => { 148 => 'PatientID' },
    1272     'patientsbirthdate' => { 148 => 'PatientDOB' },
    1273     'patientsname' => { 148 => 'PatientName' },
    1274     'patientssex' => { 148 => 'PatientSex' },
    1275     'pdfversion' => { 159 => 'PDFVersion' },
    1276     'pentaximagesize' => { 134 => 0x9 },
    1277     'pentaxmodelid' => { 131 => 0x0, 134 => 0x5 },
    1278     'pentaxmodeltype' => { 134 => 0x1 },
    1279     'pentaxversion' => { 134 => 0x0 },
    1280     'people' => { 150 => 'People' },
    1281     'pf0customfuncregistration' => { 33 => 0x1 },
    1282     'pf10retainprogramshift' => { 33 => 0xb },
    1283     'pf13drivepriority' => { 33 => 0xe },
    1284     'pf14disablefocussearch' => { 33 => 0xf },
    1285     'pf15disableafassistbeam' => { 33 => 0x10 },
    1286     'pf16autofocuspointshoot' => { 33 => 0x11 },
    1287     'pf17disableafpointsel' => { 33 => 0x12 },
    1288     'pf18enableautoafpointsel' => { 33 => 0x13 },
    1289     'pf19continuousshootspeed' => { 33 => 0x14 },
    1290     'pf19shootingspeedhigh' => { 32 => 0xa },
    1291     'pf19shootingspeedlow' => { 32 => 0x9 },
    1292     'pf1disableshootingmodes' => { 33 => 0x2 },
    1293     'pf1value' => { 32 => 0x1 },
    1294     'pf20limitcontinousshots' => { 33 => 0x15 },
    1295     'pf20maxcontinousshots' => { 32 => 0xb },
    1296     'pf21enablequietoperation' => { 33 => 0x16 },
    1297     'pf23felocktime' => { 32 => 0xd },
    1298     'pf23postreleasetime' => { 32 => 0xe },
    1299     'pf23settimerlengths' => { 33 => 0x18 },
    1300     'pf23shutterbuttontime' => { 32 => 0xc },
    1301     'pf24lightlcdduringbulb' => { 33 => 0x19 },
    1302     'pf25aemode' => { 32 => 0xf },
    1303     'pf25afmode' => { 32 => 0x12 },
    1304     'pf25afpointsel' => { 32 => 0x13 },
    1305     'pf25colormatrix' => { 32 => 0x17 },
    1306     'pf25defaultclearsettings' => { 33 => 0x1a },
    1307     'pf25drivemode' => { 32 => 0x11 },
    1308     'pf25imagesize' => { 32 => 0x14 },
    1309     'pf25meteringmode' => { 32 => 0x10 },
    1310     'pf25parameters' => { 32 => 0x16 },
    1311     'pf25wbmode' => { 32 => 0x15 },
    1312     'pf26shortenreleaselag' => { 33 => 0x1b },
    1313     'pf27reversedialrotation' => { 33 => 0x1c },
    1314     'pf27value' => { 32 => 0x18 },
    1315     'pf28noquickdialexpcomp' => { 33 => 0x1d },
    1316     'pf29quickdialswitchoff' => { 33 => 0x1e },
    1317     'pf2disablemeteringmodes' => { 33 => 0x3 },
    1318     'pf2value' => { 32 => 0x2 },
    1319     'pf30enlargementmode' => { 33 => 0x1f },
    1320     'pf31originaldecisiondata' => { 33 => 0x20 },
    1321     'pf3manualexposuremetering' => { 33 => 0x4 },
    1322     'pf3value' => { 32 => 0x3 },
    1323     'pf4exposuretimelimits' => { 33 => 0x5 },
    1324     'pf4exposuretimemax' => { 32 => 0x5 },
    1325     'pf4exposuretimemin' => { 32 => 0x4 },
    1326     'pf5aperturelimits' => { 33 => 0x6 },
    1327     'pf5aperturemax' => { 32 => 0x7 },
    1328     'pf5aperturemin' => { 32 => 0x6 },
    1329     'pf6presetshootingmodes' => { 33 => 0x7 },
    1330     'pf7bracketcontinuousshoot' => { 33 => 0x8 },
    1331     'pf8bracketshots' => { 32 => 0x8 },
    1332     'pf8setbracketshots' => { 33 => 0x9 },
    1333     'pf9changebracketsequence' => { 33 => 0xa },
    1334     'phonenumber' => { 71 => 'Phone' },
    1335     'photoeffect' => { 4 => 0x28 },
    1336     'photoeffects' => { 109 => 0xab5eca5e },
    1337     'photoeffectsblue' => { 111 => 0x8 },
    1338     'photoeffectsgreen' => { 111 => 0x6 },
    1339     'photoeffectsred' => { 111 => 0x4 },
    1340     'photoeffectstype' => { 111 => 0x0 },
    1341     'photometricinterpretation' => { 48 => 0x106, 161 => 'PhotometricInterpretation' },
    1342     'photoshopquality' => { 139 => 0x0 },
    1343     'pictinfo' => { 145 => 0x208 },
    1344     'picturemode' => { 52 => 0x1031, 115 => 0x520, 134 => [0xb,0x33] },
    1345     'picturemodebwfilter' => { 115 => 0x525 },
    1346     'picturemodecontrast' => { 115 => 0x523 },
    1347     'picturemodehue' => { 115 => 0x522 },
    1348     'picturemodesaturation' => { 115 => 0x521 },
    1349     'picturemodesharpness' => { 115 => 0x524 },
    1350     'picturemodetone' => { 115 => 0x526 },
    1351     'picturestyle' => { 1 => 0x6c, 2 => 0x86, 21 => 0xa, 43 => 0x4 },
    1352     'planarconfiguration' => { 48 => 0x11c, 161 => 'PlanarConfiguration' },
    1353     'platenames' => { 168 => 'PlateNames' },
    1354     'pngwarning' => { 125 => 'Warning' },
    1355     'postalcode' => { 75 => 'PostalCode' },
    1356     'precaptureframes' => { 120 => 0x300 },
    1357     'predictor' => { 48 => 0x13d },
    1358     'prefs' => { 54 => 0xdd, 138 => 'Prefs' },
    1359     'preservedfilename' => { 165 => 'PreservedFileName' },
    1360     'previewfocalplanexresolution' => { 20 => 0x6 },
    1361     'previewfocalplaneyresolution' => { 20 => 0x8 },
    1362     'previewheight' => { 60 => 0xfa58 },
    1363     'previewimage' => { 45 => 0x2000, 46 => 'PreviewImage', 47 => 'MakN', 48 => 0x927c, 50 => 0x4, 80 => 'data', 88 => 0x81, 120 => 0x280 },
    1364     'previewimageheight' => { 20 => 0x4 },
    1365     'previewimagelength' => { 20 => 0x2, 45 => 0x3, 48 => [0x117,0x202], 88 => 0x89, 100 => 0x202, 115 => 0x102, 120 => 0x1037, 134 => 0x3, 143 => 0x1e },
    1366     'previewimagename' => { 80 => '1Name' },
    1367     'previewimagesize' => { 45 => 0x2, 80 => 'ImageSize', 134 => 0x2 },
    1368     'previewimagestart' => { 20 => 0x5, 45 => 0x4, 48 => [0x111,0x201], 88 => 0x88, 100 => 0x201, 115 => 0x101, 120 => 0x1036, 134 => 0x4, 143 => 0x1c },
    1369     'previewimagetype' => { 80 => '0Type' },
    1370     'previewimagevalid' => { 115 => 0x100, 120 => 0x1035 },
    1371     'previewimagewidth' => { 20 => 0x3 },
    1372     'previewquality' => { 20 => 0x1 },
    1373     'previewwidth' => { 60 => 0xfa57 },
    1374     'primarychromaticities' => { 48 => 0x13f, 161 => 'PrimaryChromaticities' },
    1375     'printim' => { 48 => 0xc4a5 },
    1376     'privatertkinfo' => { 149 => 'privateRTKInfo' },
    1377     'processingsoftware' => { 48 => 0xb },
    1378     'producer' => { 159 => 'Producer' },
    1379     'productid' => { 55 => 0x32 },
    1380     'programiso' => { 126 => 0x3c },
    1381     'programmode' => { 90 => 0x5 },
    1382     'programshift' => { 98 => 0xd },
    1383     'programversion' => { 54 => 0x46 },
    1384     'projectrefpath' => { 164 => 'projectRefPath' },
    1385     'projectreftype' => { 164 => 'projectRefType' },
    1386     'province-state' => { 54 => 0x5f },
    1387     'publisher' => { 155 => 'publisher' },
    1388     'pulldown' => { 164 => 'pullDown' },
    1389     'quality' => { 0 => 0x1, 4 => 0x3, 44 => 0x2, 45 => 0x3002, 52 => 0x1000, 59 => 0x9, 98 => 0x4, 103 => 0x3, 120 => 0x201, 134 => 0x8, 136 => 0x2, 146 => 0x16 },
    1390     'qualitymode' => { 45 => 0x8 },
    1391     'quantizationmethod' => { 56 => 0x78 },
    1392     'quickcontroldialinmeter' => { 25 => 0x703 },
    1393     'quickshot' => { 145 => 0x213 },
    1394     'rasterizedcaption' => { 54 => 0x7d },
    1395     'rating' => { 48 => 0x4746, 137 => 0xdf, 156 => 'rating', 162 => 'Rating' },
    1396     'ratingpercent' => { 48 => 0x4749, 151 => 'Rating' },
    1397     'rawandjpgrecording' => { 23 => 0x8 },
    1398     'rawbrightnessadj' => { 42 => 0x38 },
    1399     'rawcoloradj' => { 42 => 0x2e },
    1400     'rawcolortoneadj' => { 43 => 0x1a },
    1401     'rawcontrastadj' => { 43 => 0x1e },
    1402     'rawcropbottom' => { 137 => 0xd4 },
    1403     'rawcropleft' => { 137 => 0xd1 },
    1404     'rawcropright' => { 137 => 0xd3 },
    1405     'rawcroptop' => { 137 => 0xd2 },
    1406     'rawcustomsaturation' => { 42 => 0x30 },
    1407     'rawcustomtone' => { 42 => 0x34 },
    1408     'rawdatauniqueid' => { 48 => 0xc65d },
    1409     'rawdepth' => { 89 => 0x10 },
    1410     'rawdevcolorspace' => { 121 => 0x108, 122 => 0x109 },
    1411     'rawdevcontrastvalue' => { 121 => 0x106, 122 => 0x105 },
    1412     'rawdeveditstatus' => { 121 => 0x10b },
    1413     'rawdevengine' => { 121 => 0x109, 122 => 0x10b },
    1414     'rawdevexposurebiasvalue' => { 121 => 0x100, 122 => 0x100 },
    1415     'rawdevgradation' => { 122 => 0x112 },
    1416     'rawdevgraypoint' => { 121 => 0x103, 122 => 0x104 },
    1417     'rawdevmemorycoloremphasis' => { 121 => 0x105, 122 => 0x108 },
    1418     'rawdevnoisereduction' => { 121 => 0x10a, 122 => 0x10a },
    1419     'rawdevpicturemode' => { 122 => 0x10c },
    1420     'rawdevpm_bwfilter' => { 122 => 0x110 },
    1421     'rawdevpmcontrast' => { 122 => 0x10e },
    1422     'rawdevpmpicturetone' => { 122 => 0x111 },
    1423     'rawdevpmsaturation' => { 122 => 0x10d },
    1424     'rawdevpmsharpness' => { 122 => 0x10f },
    1425     'rawdevsaturationemphasis' => { 121 => 0x104, 122 => 0x107 },
    1426     'rawdevsettings' => { 121 => 0x10c },
    1427     'rawdevsharpnessvalue' => { 121 => 0x107, 122 => 0x106 },
    1428     'rawdevversion' => { 121 => 0x0, 122 => 0x0 },
    1429     'rawdevwbfineadjustment' => { 121 => 0x102, 122 => 0x103 },
    1430     'rawdevwhitebalance' => { 122 => 0x101 },
    1431     'rawdevwhitebalancevalue' => { 121 => 0x101, 122 => 0x102 },
    1432     'rawfile' => { 48 => 0xfe4c },
    1433     'rawfilename' => { 154 => 'RawFileName' },
    1434     'rawhighlightpoint' => { 43 => 0x24 },
    1435     'rawimagecenter' => { 98 => 0x99 },
    1436     'rawimagesize' => { 134 => 0x39 },
    1437     'rawinfoversion' => { 123 => 0x0 },
    1438     'rawjpgheight' => { 40 => 0x4 },
    1439     'rawjpgquality' => { 13 => 0x6, 40 => 0x1 },
    1440     'rawjpgsize' => { 13 => 0x7, 40 => 0x2 },
    1441     'rawjpgwidth' => { 40 => 0x3 },
    1442     'rawlinear' => { 43 => 0x20 },
    1443     'rawsaturationadj' => { 43 => 0x1c },
    1444     'rawshadowpoint' => { 43 => 0x26 },
    1445     'rawsharpnessadj' => { 43 => 0x22 },
    1446     'recordid' => { 38 => 0x1804 },
    1447     'recordingmode' => { 44 => 0x1, 136 => 0x1 },
    1448     'recordmode' => { 4 => 0x9, 45 => 0x3000 },
    1449     'recordshutterrelease' => { 145 => 0x217 },
    1450     'redbalance' => { 120 => 0x1017, 127 => 0x11, 134 => 0x1c },
    1451     'redcurvelimits' => { 42 => 0x18a },
    1452     'redcurvepoints' => { 42 => 0x160 },
    1453     'redeyecorrection' => { 112 => 0x0 },
    1454     'redhue' => { 154 => 'RedHue' },
    1455     'redsaturation' => { 154 => 'RedSaturation' },
    1456     'referenceblackwhite' => { 48 => 0x214, 161 => 'ReferenceBlackWhite' },
    1457     'referencedate' => { 54 => 0x2f },
    1458     'referencenumber' => { 54 => 0x32 },
    1459     'references' => { 71 => 'References' },
    1460     'referenceservice' => { 54 => 0x2d },
    1461     'relatedaudiofile' => { 69 => 'data' },
    1462     'relatedaudiofilename' => { 69 => '1Name' },
    1463     'relatedaudiofiletype' => { 69 => '0Type' },
    1464     'relatedimagefileformat' => { 48 => 0x1000 },
    1465     'relatedimagelength' => { 48 => 0x1002 },
    1466     'relatedimagewidth' => { 48 => 0x1001 },
    1467     'relatedsoundfile' => { 48 => 0xa004, 157 => 'RelatedSoundFile' },
    1468     'relatedvideofile' => { 83 => 'data' },
    1469     'relatedvideofilename' => { 83 => '1Name' },
    1470     'relatedvideofiletype' => { 83 => '0Type' },
    1471     'relation' => { 155 => 'relation' },
    1472     'relativepeakaudiofilepath' => { 164 => 'relativePeakAudioFilePath' },
    1473     'relativetimestamp' => { 164 => 'relativeTimestamp' },
    1474     'releasedate' => { 54 => 0x1e, 164 => 'releaseDate' },
    1475     'releasesetting' => { 38 => 0x1016 },
    1476     'releasetime' => { 54 => 0x23 },
    1477     'renditionclass' => { 165 => 'RenditionClass' },
    1478     'renditionofdocumentid' => { 165 => 'RenditionOfDocumentID' },
    1479     'renditionofinstanceid' => { 165 => 'RenditionOfInstanceID' },
    1480     'renditionofmanager' => { 165 => 'RenditionOfManager' },
    1481     'renditionofmanagervariant' => { 165 => 'RenditionOfManagerVariant' },
    1482     'renditionofmanageto' => { 165 => 'RenditionOfManageTo' },
    1483     'renditionofmanageui' => { 165 => 'RenditionOfManageUI' },
    1484     'renditionofrenditionclass' => { 165 => 'RenditionOfRenditionClass' },
    1485     'renditionofrenditionparams' => { 165 => 'RenditionOfRenditionParams' },
    1486     'renditionofversionid' => { 165 => 'RenditionOfVersionID' },
    1487     'renditionparams' => { 165 => 'RenditionParams' },
    1488     'resampleparamsquality' => { 164 => 'resampleParamsQuality' },
    1489     'resaved' => { 145 => 0x21e },
    1490     'resolution' => { 76 => 'Resolution' },
    1491     'resolutionmode' => { 146 => 0x4 },
    1492     'resolutionunit' => { 48 => 0x128, 57 => 0x2, 161 => 'ResolutionUnit' },
    1493     'reuseallowed' => { 166 => 'ReuseAllowed' },
    1494     'revision' => { 156 => 'revision' },
    1495     'rgbcurvelimits' => { 42 => 0x238 },
    1496     'rgbcurvepoints' => { 42 => 0x20e },
    1497     'ricohdate' => { 143 => 0x6 },
    1498     'ricohimageheight' => { 143 => 0x2 },
    1499     'ricohimagewidth' => { 143 => 0x0 },
    1500     'rightascension' => { 79 => 'RightAscension' },
    1501     'rights' => { 155 => 'rights' },
    1502     'romoperationmode' => { 38 => 0x80d },
    1503     'rotation' => { 3 => 0x17, 37 => 0x3, 42 => 0x26e, 51 => 0x4, 79 => 'Rotation', 85 => 0x50, 86 => 0x46, 87 => 0x5a, 109 => 0x76a43207, 126 => 0x30, 137 => 0xd8 },
    1504     'routing' => { 142 => 'Routing' },
    1505     'rowsperstrip' => { 48 => 0x116 },
    1506     'safetyshift' => { 25 => 0x108 },
    1507     'safetyshiftinavortv' => { 23 => 0x10, 24 => 0x10, 26 => 0xf, 27 => 0x10, 30 => 0x10 },
    1508     'samplebits' => { 69 => 'SampleBits' },
    1509     'samplerate' => { 69 => 'SampleRate' },
    1510     'samplesperpixel' => { 48 => 0x115, 161 => 'SamplesPerPixel' },
    1511     'samplestructure' => { 56 => 0x5a },
    1512     'sanyoquality' => { 145 => 0x201 },
    1513     'sanyothumbnail' => { 145 => 0x100 },
    1514     'saturation' => { 4 => 0xe, 9 => 0x1, 44 => 0xd, 45 => [0x3013,0x1f], 48 => [0xa409,0xfe55], 52 => 0x1003, 70 => 'Saturation', 84 => 0x1f, 85 => 0x32, 86 => 0x28, 87 => 0x1a, 90 => 0x1, 98 => [0x94,0xaa], 134 => 0x1f, 136 => 0xd, 143 => 0x28, 146 => 0x10, 154 => 'Saturation', 157 => 'Saturation' },
    1515     'saturationadj' => { 42 => 0x116 },
    1516     'saturationadjustmentaqua' => { 154 => 'SaturationAdjustmentAqua' },
    1517     'saturationadjustmentblue' => { 154 => 'SaturationAdjustmentBlue' },
    1518     'saturationadjustmentgreen' => { 154 => 'SaturationAdjustmentGreen' },
    1519     'saturationadjustmentmagenta' => { 154 => 'SaturationAdjustmentMagenta' },
    1520     'saturationadjustmentorange' => { 154 => 'SaturationAdjustmentOrange' },
    1521     'saturationadjustmentpurple' => { 154 => 'SaturationAdjustmentPurple' },
    1522     'saturationadjustmentred' => { 154 => 'SaturationAdjustmentRed' },
    1523     'saturationadjustmentyellow' => { 154 => 'SaturationAdjustmentYellow' },
    1524     'saturationfaithful' => { 1 => 0xfe },
    1525     'saturationlandscape' => { 1 => 0xfc },
    1526     'saturationneutral' => { 1 => 0xfd },
    1527     'saturationportrait' => { 1 => 0xfb },
    1528     'saturationsetting' => { 123 => 0x1010 },
    1529     'saturationstandard' => { 1 => 0xfa },
    1530     'saturationuserdef1' => { 1 => 0x100 },
    1531     'saturationuserdef2' => { 1 => 0x101 },
    1532     'saturationuserdef3' => { 1 => 0x102 },
    1533     'saveid' => { 165 => 'SaveID' },
    1534     'scaledresolution' => { 106 => 0x9e },
    1535     'scaletype' => { 164 => 'scaleType' },
    1536     'scanningdirection' => { 56 => 0x64 },
    1537     'scene' => { 158 => 'Scene', 164 => 'scene' },
    1538     'scenearea' => { 120 => 0x1031 },
    1539     'scenecapturetype' => { 48 => 0xa406, 157 => 'SceneCaptureType' },
    1540     'scenedetect' => { 120 => 0x1030 },
    1541     'scenedetectarea' => { 120 => 0x1033 },
    1542     'scenemode' => { 60 => 0xfa02, 88 => 0x100, 98 => 0x8f, 115 => 0x509, 120 => 0x403, 126 => 0x8001 },
    1543     'scenemodeused' => { 62 => [0x6002,0xf002] },
    1544     'sceneselect' => { 145 => 0x21f },
    1545     'scenetype' => { 48 => 0xa301, 157 => 'SceneType' },
    1546     'securityclassification' => { 48 => 0x9212 },
    1547     'selectableafpoint' => { 25 => 0x509 },
    1548     'self-timer' => { 4 => 0x2 },
    1549     'self-timer2' => { 22 => 0x1d },
    1550     'selftimer' => { 45 => 0x3001, 126 => 0x2e, 145 => 0x214 },
    1551     'selftimermode' => { 48 => 0x882b },
    1552     'selftimertime' => { 38 => 0x1806 },
    1553     'seminfo' => { 48 => 0x8546 },
    1554     'sensingmethod' => { 48 => 0xa217, 157 => 'SensingMethod' },
    1555     'sensorbluelevel' => { 21 => 0x5 },
    1556     'sensorcleaning' => { 31 => 0xd },
    1557     'sensorfullheight' => { 58 => 0xf904 },
    1558     'sensorfullwidth' => { 58 => 0xf903 },
    1559     'sensorheight' => { 58 => 0xf901, 60 => 0xfa21, 89 => 0x8 },
    1560     'sensorpixelsize' => { 98 => 0x9a },
    1561     'sensorredlevel' => { 21 => 0x4 },
    1562     'sensorsize' => { 70 => 'SensorSize' },
    1563     'sensortemperature' => { 118 => 0x1500, 120 => 0x1007 },
    1564     'sensorwidth' => { 58 => 0xf900, 60 => 0xfa20, 89 => 0xa },
    1565     'sequencenumber' => { 22 => 0x9, 45 => 0x301c, 52 => 0x1101, 59 => 0x1d, 126 => 0x2b },
    1566     'sequenceshotinterval' => { 145 => 0x224 },
    1567     'sequentialshot' => { 145 => 0x20e },
    1568     'serialnumber' => { 16 => 0xc, 38 => 0x180b, 48 => 0xfde9, 58 => 0xfa04, 60 => 0xfa19, 68 => 0x0, 70 => 'SerialNumber', 98 => 0xa0, 116 => 0x101, 120 => [0x404,0x101a], 146 => 0x2, 152 => 'SerialNumber' },
    1569     'serialnumberformat' => { 16 => 0x15, 38 => 0x183b },
    1570     'seriesdatetime' => { 148 => 'SeriesDateTime' },
    1571     'seriesdescription' => { 148 => 'SeriesDescription' },
    1572     'seriesmodality' => { 148 => 'SeriesModality' },
    1573     'seriesnumber' => { 148 => 'SeriesNumber' },
    1574     'serviceidentifier' => { 55 => 0x1e },
    1575     'setbuttoncrosskeysfunc' => { 28 => 0x0, 29 => 0x0 },
    1576     'setbuttonfunction' => { 23 => 0x1, 31 => 0xc },
    1577     'setbuttonwhenshooting' => { 25 => 0x704 },
    1578     'setfunctionwhenshooting' => { 26 => 0x0, 27 => 0x1, 30 => 0x1 },
    1579     'shadingcompensation' => { 115 => 0x50c },
    1580     'shadingcompensation2' => { 119 => 0x1012 },
    1581     'shadow' => { 146 => 0xe },
    1582     'shadows' => { 48 => 0xfe52, 154 => 'Shadows' },
    1583     'shadowscale' => { 48 => 0xc633 },
    1584     'shadowtint' => { 154 => 'ShadowTint' },
    1585     'shakereduction' => { 135 => 0x1 },
    1586     'sharpendetail' => { 154 => 'SharpenDetail' },
    1587     'sharpenedgemasking' => { 154 => 'SharpenEdgeMasking' },
    1588     'sharpenradius' => { 154 => 'SharpenRadius' },
    1589     'sharpness' => { 4 => 0xf, 21 => 0x2, 44 => 0xb, 45 => [0x3011,0x21], 48 => [0xa40a,0xfe56], 52 => 0x1001, 59 => 0x6b, 66 => 0x37, 70 => 'Sharpness', 84 => 0x21, 85 => 0x30, 86 => 0x26, 87 => 0x18, 90 => 0x3, 98 => 0x6, 120 => 0x100f, 134 => 0x21, 136 => 0xb, 143 => 0x22, 144 => 0x1003, 146 => 0x11, 154 => 'Sharpness', 157 => 'Sharpness' },
    1590     'sharpnessfactor' => { 120 => 0x102a },
    1591     'sharpnessfaithful' => { 1 => 0xf5 },
    1592     'sharpnessfrequency' => { 21 => 0x3 },
    1593     'sharpnesslandscape' => { 1 => 0xf3 },
    1594     'sharpnessmonochrome' => { 1 => 0xf6 },
    1595     'sharpnessneutral' => { 1 => 0xf4 },
    1596     'sharpnessportrait' => { 1 => 0xf2 },
    1597     'sharpnesssetting' => { 115 => 0x506, 123 => 0x1013 },
    1598     'sharpnessstandard' => { 1 => 0xf1 },
    1599     'sharpnessuserdef1' => { 1 => 0xf7 },
    1600     'sharpnessuserdef2' => { 1 => 0xf8 },
    1601     'sharpnessuserdef3' => { 1 => 0xf9 },
    1602     'shootingmode' => { 70 => 'ShootingMode', 98 => 0x89, 126 => 0x1f },
    1603     'shortdescription' => { 156 => 'shortdescription' },
    1604     'shortdocumentid' => { 54 => 0xba },
    1605     'shortfocal' => { 1 => 0x11, 2 => 0x113, 4 => 0x18 },
    1606     'shortownername' => { 1 => 0xac },
    1607     'shortreleasetimelag' => { 25 => 0x80d },
    1608     'shotdate' => { 164 => 'shotDate' },
    1609     'shotlocation' => { 164 => 'shotLocation' },
    1610     'shotname' => { 164 => 'shotName' },
    1611     'shutter-aelock' => { 23 => 0x4, 26 => 0x3, 27 => 0x4, 28 => 0x3, 29 => 0x3, 30 => 0x4, 31 => 0x2 },
    1612     'shutteraelbutton' => { 24 => 0x4 },
    1613     'shutterbuttonafonbutton' => { 25 => 0x701 },
    1614     'shuttercount' => { 2 => 0x176, 13 => 0x1, 134 => 0x5d },
    1615     'shuttercurtainsync' => { 23 => 0xf, 24 => 0xf, 25 => 0x305, 26 => 0xe, 27 => 0xf, 28 => 0x8, 29 => 0x8, 30 => 0xf, 31 => 0x8 },
    1616     'shuttermode' => { 59 => 0x1b },
    1617     'shutterreleasemethod' => { 38 => 0x1010 },
    1618     'shutterreleasenocfcard' => { 23 => 0x2, 24 => 0x2, 31 => 0xf },
    1619     'shutterreleasetiming' => { 38 => 0x1011 },
    1620     'shutterspeedrange' => { 25 => 0x10c },
    1621     'shutterspeedvalue' => { 48 => 0x9201, 120 => 0x1000, 157 => 'ShutterSpeedValue' },
    1622     'sidecarforextension' => { 160 => 'SidecarForExtension' },
    1623     'similarityindex' => { 54 => 0xe4 },
    1624     'slowshutter' => { 22 => 0x8 },
    1625     'slowsync' => { 52 => 0x1030 },
    1626     'smoothingparameter1' => { 119 => 0x300 },
    1627     'smoothingparameter2' => { 119 => 0x310 },
    1628     'smoothingthreshold2' => { 119 => 0x610 },
    1629     'smoothingthresholds' => { 119 => 0x600 },
    1630     'smoothness' => { 48 => 0xfe57 },
    1631     'software' => { 48 => 0x131, 71 => 'Software', 125 => 'Software', 146 => 0x18, 161 => 'Software' },
    1632     'softwareversion' => { 145 => 0x207 },
    1633     'source' => { 54 => 0x73, 125 => 'Source', 155 => 'source', 156 => 'source', 160 => 'Source' },
    1634     'sourceresolution' => { 106 => 0xae },
    1635     'spatialfrequencyresponsecolumns' => { 157 => 'SpatialFrequencyResponseColumns' },
    1636     'spatialfrequencyresponsenames' => { 157 => 'SpatialFrequencyResponseNames' },
    1637     'spatialfrequencyresponserows' => { 157 => 'SpatialFrequencyResponseRows' },
    1638     'spatialfrequencyresponsevalues' => { 157 => 'SpatialFrequencyResponseValues' },
    1639     'speakerplacement' => { 164 => 'speakerPlacement' },
    1640     'specialinstructions' => { 54 => 0x28 },
    1641     'specialmode' => { 120 => 0x200, 145 => 0x200 },
    1642     'spectralsensitivity' => { 48 => 0x8824, 157 => 'SpectralSensitivity' },
    1643     'splittoningbalance' => { 154 => 'SplitToningBalance' },
    1644     'splittoninghighlighthue' => { 154 => 'SplitToningHighlightHue' },
    1645     'splittoninghighlightsaturation' => { 154 => 'SplitToningHighlightSaturation' },
    1646     'splittoningshadowhue' => { 154 => 'SplitToningShadowHue' },
    1647     'splittoningshadowsaturation' => { 154 => 'SplitToningShadowSaturation' },
    1648     'spotfocuspointx' => { 84 => 0x2d },
    1649     'spotfocuspointy' => { 84 => 0x2e },
    1650     'spotmeterlinktoafpoint' => { 25 => 0x107 },
    1651     'sr_swstoswrtime' => { 135 => 0x2 },
    1652     'srresult' => { 135 => 0x0 },
    1653     'startoffsetx' => { 123 => 0x612 },
    1654     'startoffsety' => { 123 => 0x613 },
    1655     'starttimecodetimeformat' => { 164 => 'startTimecodeTimeFormat' },
    1656     'starttimecodetimevalue' => { 164 => 'startTimecodeTimeValue' },
    1657     'state' => { 75 => 'State', 160 => 'State' },
    1658     'status' => { 150 => 'Status' },
    1659     'storagemethod' => { 89 => 0x12 },
    1660     'straightenangle' => { 109 => 0x2fc08431 },
    1661     'stretchmode' => { 164 => 'stretchMode' },
    1662     'studydatetime' => { 148 => 'StudyDateTime' },
    1663     'studydescription' => { 148 => 'StudyDescription' },
    1664     'studyid' => { 148 => 'StudyID' },
    1665     'studyphysician' => { 148 => 'StudyPhysician' },
    1666     'sub-location' => { 54 => 0x5c },
    1667     'subfiledata' => { 78 => 'data' },
    1668     'subfiledirectory' => { 78 => '1Directory' },
    1669     'subfilemimetype' => { 78 => '2MIME' },
    1670     'subfilename' => { 78 => '1Name' },
    1671     'subfileresource' => { 78 => 'rsrc' },
    1672     'subfiletype' => { 48 => 0xfe, 78 => '0Type' },
    1673     'subject' => { 142 => 'Subject', 155 => 'subject', 159 => 'Subject' },
    1674     'subjectarea' => { 157 => 'SubjectArea' },
    1675     'subjectcode' => { 158 => 'SubjectCode' },
    1676     'subjectdistance' => { 48 => 0x9206, 59 => 0x3e, 157 => 'SubjectDistance' },
    1677     'subjectdistancerange' => { 48 => 0xa40c, 157 => 'SubjectDistanceRange' },
    1678     'subjectlocation' => { 48 => [0x9214,0xa214], 157 => 'SubjectLocation' },
    1679     'subjectprogram' => { 84 => 0x22 },
    1680     'subjectreference' => { 54 => 0xc },
    1681     'subsectime' => { 48 => 0x9290 },
    1682     'subsectimedigitized' => { 48 => 0x9292 },
    1683     'subsectimeoriginal' => { 48 => 0x9291 },
    1684     'superimposeddisplay' => { 23 => 0xa, 25 => 0x510, 26 => 0x9, 27 => 0xa, 30 => 0xa, 31 => 0xe },
    1685     'supplementalcategories' => { 54 => 0x14, 160 => 'SupplementalCategories' },
    1686     'supplementaltype' => { 56 => 0x37 },
    1687     'switchtoregisteredafpoint' => { 24 => 0x12, 25 => 0x50a },
    1688     'tagged' => { 137 => 0xdd },
    1689     'tapename' => { 164 => 'tapeName' },
    1690     'targetaperture' => { 22 => 0x4 },
    1691     'targetcompressionratio' => { 36 => 0x1 },
    1692     'targetdistancesetting' => { 38 => 0x1807 },
    1693     'targetexposuretime' => { 22 => 0x5 },
    1694     'targetimagetype' => { 38 => 0x100a },
    1695     'temperature' => { 154 => 'Temperature' },
    1696     'tempo' => { 164 => 'tempo' },
    1697     'thresholding' => { 48 => 0x107 },
    1698     'thumbnailfilename' => { 38 => 0x817 },
    1699     'thumbnailheight' => { 60 => 0xfa55 },
    1700     'thumbnailimage' => { 38 => 0x2008, 46 => 'ThumbnailImage', 50 => 0x3, 81 => 'data', 120 => 0x100 },
    1701     'thumbnailimagename' => { 81 => '1Name' },
    1702     'thumbnailimagesize' => { 81 => 'ImageSize' },
    1703     'thumbnailimagetype' => { 81 => '0Type' },
    1704     'thumbnaillength' => { 48 => 0x202 },
    1705     'thumbnailoffset' => { 48 => 0x201 },
    1706     'thumbnailsformat' => { 162 => 'ThumbnailsFormat' },
    1707     'thumbnailsheight' => { 162 => 'ThumbnailsHeight' },
    1708     'thumbnailsimage' => { 162 => 'ThumbnailsImage' },
    1709     'thumbnailswidth' => { 162 => 'ThumbnailsWidth' },
    1710     'thumbnailwidth' => { 60 => 0xfa54 },
    1711     'tilelength' => { 48 => 0x143 },
    1712     'tilewidth' => { 48 => 0x142 },
    1713     'time' => { 134 => 0x7 },
    1714     'timecreated' => { 54 => 0x3c, 59 => 0x14, 66 => 0x10, 138 => 'TimeCreated' },
    1715     'timerlength' => { 25 => 0x80c },
    1716     'timescaleparamsframeoverlappingpercentage' => { 164 => 'timeScaleParamsFrameOverlappingPercentage' },
    1717     'timescaleparamsframesize' => { 164 => 'timeScaleParamsFrameSize' },
    1718     'timescaleparamsquality' => { 164 => 'timeScaleParamsQuality' },
    1719     'timesent' => { 55 => 0x50 },
    1720     'timesignature' => { 164 => 'timeSignature' },
    1721     'timesincepoweron' => { 126 => 0x29 },
    1722     'timestamp' => { 1 => 0x11c, 2 => 0x45e, 125 => 'TimeStamp' },
    1723     'timezonecode' => { 41 => 0x1 },
    1724     'timezoneinfo' => { 41 => 0x2 },
    1725     'timezoneoffset' => { 48 => 0x882a },
    1726     'tint' => { 154 => 'Tint' },
    1727     'title' => { 71 => 'Title', 125 => 'Title', 142 => 'Title', 155 => 'title', 159 => 'Title' },
    1728     'tonecomp' => { 98 => 0x81 },
    1729     'tonecurve' => { 21 => 0x1, 134 => 0x402, 154 => 'ToneCurve' },
    1730     'tonecurveactive' => { 42 => 0x110 },
    1731     'tonecurvename' => { 154 => 'ToneCurveName' },
    1732     'tonecurveproperty' => { 42 => 0x3c },
    1733     'tonecurves' => { 134 => 0x403 },
    1734     'toningeffect' => { 13 => 0xf },
    1735     'toningeffectmonochrome' => { 1 => 0x108 },
    1736     'totalzoom' => { 59 => 0x62 },
    1737     'tracknumber' => { 164 => 'trackNumber' },
    1738     'trailersignature' => { 78 => 'zmie' },
    1739     'transferfunction' => { 161 => 'TransferFunction' },
    1740     'transmissionreference' => { 160 => 'TransmissionReference' },
    1741     'travelday' => { 126 => 0x36 },
    1742     'ttl_da_adown' => { 132 => 0x5 },
    1743     'ttl_da_aup' => { 132 => 0x4 },
    1744     'ttl_da_bdown' => { 132 => 0x7 },
    1745     'ttl_da_bup' => { 132 => 0x6 },
    1746     'tvvalue' => { 34 => 0x1 },
    1747     'type' => { 155 => 'type' },
    1748     'uniquecameramodel' => { 48 => 0xc614 },
    1749     'uniquedocumentid' => { 54 => 0xbb },
    1750     'uniqueobjectname' => { 55 => 0x64 },
    1751     'unknownblock' => { 119 => 0x1103 },
    1752     'unknowncompensation' => { 146 => 0xc },
    1753     'unsharp1color' => { 113 => 0x13 },
    1754     'unsharp1halowidth' => { 113 => 0x19 },
    1755     'unsharp1intensity' => { 113 => 0x17 },
    1756     'unsharp1threshold' => { 113 => 0x1b },
    1757     'unsharp2color' => { 113 => 0x2e },
    1758     'unsharp2halowidth' => { 113 => 0x34 },
    1759     'unsharp2intensity' => { 113 => 0x32 },
    1760     'unsharp2threshold' => { 113 => 0x36 },
    1761     'unsharp3color' => { 113 => 0x49 },
    1762     'unsharp3halowidth' => { 113 => 0x4f },
    1763     'unsharp3intensity' => { 113 => 0x4d },
    1764     'unsharp3threshold' => { 113 => 0x51 },
    1765     'unsharp4color' => { 113 => 0x64 },
    1766     'unsharp4halowidth' => { 113 => 0x6a },
    1767     'unsharp4intensity' => { 113 => 0x68 },
    1768     'unsharp4threshold' => { 113 => 0x6c },
    1769     'unsharpcount' => { 113 => 0x0 },
    1770     'unsharpmask' => { 109 => 0x76a43200 },
    1771     'urgency' => { 54 => 0xa, 160 => 'Urgency' },
    1772     'url' => { 71 => 'URL', 125 => 'URL', 140 => 0x40b },
    1773     'usablemeteringmodes' => { 25 => 0x10a },
    1774     'usableshootingmodes' => { 25 => 0x109 },
    1775     'usageterms' => { 167 => 'UsageTerms' },
    1776     'usercomment' => { 38 => 0x805, 48 => 0x9286, 157 => 'UserComment' },
    1777     'userdef1picturestyle' => { 1 => 0x10c },
    1778     'userdef2picturestyle' => { 1 => 0x10e },
    1779     'userdef3picturestyle' => { 1 => 0x110 },
    1780     'userfields' => { 150 => 'UserFields' },
    1781     'usmlenselectronicmf' => { 24 => 0x7, 25 => 0x501 },
    1782     'utmeasting' => { 82 => 'Easting' },
    1783     'utmmapdatum' => { 82 => 'Datum' },
    1784     'utmnorthing' => { 82 => 'Northing' },
    1785     'utmzone' => { 82 => 'Zone' },
    1786     'validbits' => { 119 => 0x611, 120 => 0x102c },
    1787     'validpixeldepth' => { 123 => 0x611 },
    1788     'variousmodes' => { 59 => 0x26 },
    1789     'variousmodes2' => { 59 => 0x3a },
    1790     'variprogram' => { 98 => 0xab },
    1791     'version' => { 52 => 0x0, 142 => 'Version', 154 => 'Version' },
    1792     'versionid' => { 165 => 'VersionID' },
    1793     'versionscomments' => { 165 => 'VersionsComments' },
    1794     'versionseventaction' => { 165 => 'VersionsEventAction' },
    1795     'versionseventinstanceid' => { 165 => 'VersionsEventInstanceID' },
    1796     'versionseventparameters' => { 165 => 'VersionsEventParameters' },
    1797     'versionseventsoftwareagent' => { 165 => 'VersionsEventSoftwareAgent' },
    1798     'versionseventwhen' => { 165 => 'VersionsEventWhen' },
    1799     'versionsmodifier' => { 165 => 'VersionsModifier' },
    1800     'versionsmodifydate' => { 165 => 'VersionsModifyDate' },
    1801     'versionsversion' => { 165 => 'VersionsVersion' },
    1802     'vibrance' => { 154 => 'Vibrance' },
    1803     'videoalphamode' => { 164 => 'videoAlphaMode' },
    1804     'videoalphapremultiplecolora' => { 164 => 'videoAlphaPremultipleColorA' },
    1805     'videoalphapremultiplecolorb' => { 164 => 'videoAlphaPremultipleColorB' },
    1806     'videoalphapremultiplecolorblack' => { 164 => 'videoAlphaPremultipleColorBlack' },
    1807     'videoalphapremultiplecolorblue' => { 164 => 'videoAlphaPremultipleColorBlue' },
    1808     'videoalphapremultiplecolorcyan' => { 164 => 'videoAlphaPremultipleColorCyan' },
    1809     'videoalphapremultiplecolorgreen' => { 164 => 'videoAlphaPremultipleColorGreen' },
    1810     'videoalphapremultiplecolorl' => { 164 => 'videoAlphaPremultipleColorL' },
    1811     'videoalphapremultiplecolormagenta' => { 164 => 'videoAlphaPremultipleColorMagenta' },
    1812     'videoalphapremultiplecolormode' => { 164 => 'videoAlphaPremultipleColorMode' },
    1813     'videoalphapremultiplecolorred' => { 164 => 'videoAlphaPremultipleColorRed' },
    1814     'videoalphapremultiplecolorswatchname' => { 164 => 'videoAlphaPremultipleColorSwatchName' },
    1815     'videoalphapremultiplecolortype' => { 164 => 'videoAlphaPremultipleColorType' },
    1816     'videoalphapremultiplecoloryellow' => { 164 => 'videoAlphaPremultipleColorYellow' },
    1817     'videoalphaunityistransparent' => { 164 => 'videoAlphaUnityIsTransparent' },
    1818     'videocolorspace' => { 164 => 'videoColorSpace' },
    1819     'videocompressor' => { 164 => 'videoCompressor' },
    1820     'videofieldorder' => { 164 => 'videoFieldOrder' },
    1821     'videoframerate' => { 164 => 'videoFrameRate' },
    1822     'videoframesizeh' => { 164 => 'videoFrameSizeH' },
    1823     'videoframesizeunit' => { 164 => 'videoFrameSizeUnit' },
    1824     'videoframesizew' => { 164 => 'videoFrameSizeW' },
    1825     'videomoddate' => { 164 => 'videoModDate' },
    1826     'videopixelaspectratio' => { 164 => 'videoPixelAspectRatio' },
    1827     'videopixeldepth' => { 164 => 'videoPixelDepth' },
    1828     'viewinfoduringexposure' => { 25 => 0x407 },
    1829     'vignetteamount' => { 154 => 'VignetteAmount' },
    1830     'vignettecontrol' => { 109 => 0x76a43205 },
    1831     'vignettecontrolintensity' => { 109 => 0xac6bd5c0 },
    1832     'vignettemidpoint' => { 154 => 'VignetteMidpoint' },
    1833     'voicememo' => { 145 => 0x216 },
    1834     'vrdoffset' => { 16 => 0xd0 },
    1835     'wb_rbgglevels' => { 93 => 0x0 },
    1836     'wb_rblevels' => { 119 => 0x100 },
    1837     'wb_rblevelsauto' => { 123 => 0x110 },
    1838     'wb_rblevelscloudy' => { 123 => 0x121 },
    1839     'wb_rblevelscoolwhitefluor' => { 123 => 0x132 },
    1840     'wb_rblevelsdaylightfluor' => { 123 => 0x130 },
    1841     'wb_rblevelsdaywhitefluor' => { 123 => 0x131 },
    1842     'wb_rblevelseveningsunlight' => { 123 => 0x124 },
    1843     'wb_rblevelsfineweather' => { 123 => 0x122 },
    1844     'wb_rblevelsshade' => { 123 => 0x120 },
    1845     'wb_rblevelstungsten' => { 123 => 0x123 },
    1846     'wb_rblevelsused' => { 123 => 0x100 },
    1847     'wb_rblevelswhitefluorescent' => { 123 => 0x133 },
    1848     'wb_rgbglevels' => { 95 => 0x0 },
    1849     'wb_rggblevels' => { 94 => 0x0 },
    1850     'wb_rggblevelsasshot' => { 6 => 0x19, 7 => 0x18, 8 => 0x3f },
    1851     'wb_rggblevelsauto' => { 5 => 0x0, 6 => 0x1e, 7 => 0x22, 8 => 0x44 },
    1852     'wb_rggblevelscloudy' => { 5 => 0xc, 6 => 0x2d, 7 => 0x31, 8 => 0x58, 134 => 0x20f },
    1853     'wb_rggblevelscustom' => { 5 => 0x1c, 8 => 0x80 },
    1854     'wb_rggblevelscustom1' => { 6 => 0x41 },
    1855     'wb_rggblevelscustom2' => { 6 => 0x46 },
    1856     'wb_rggblevelsdaylight' => { 5 => 0x4, 6 => 0x23, 7 => 0x27, 8 => 0x4e, 134 => 0x20d },
    1857     'wb_rggblevelsflash' => { 5 => 0x18, 6 => 0x3c, 7 => 0x45, 8 => 0x6c, 134 => 0x214 },
    1858     'wb_rggblevelsfluorescent' => { 5 => 0x14, 6 => 0x37, 7 => 0x3b, 8 => 0x62 },
    1859     'wb_rggblevelsfluorescentd' => { 134 => 0x211 },
    1860     'wb_rggblevelsfluorescentn' => { 134 => 0x212 },
    1861     'wb_rggblevelsfluorescentw' => { 134 => 0x213 },
    1862     'wb_rggblevelskelvin' => { 5 => 0x20, 7 => 0x40, 8 => 0x67 },
    1863     'wb_rggblevelsmeasured' => { 8 => 0x49 },
    1864     'wb_rggblevelspc1' => { 7 => 0x90, 8 => 0x71 },
    1865     'wb_rggblevelspc2' => { 7 => 0x95, 8 => 0x76 },
    1866     'wb_rggblevelspc3' => { 7 => 0x9a, 8 => 0x7b },
    1867     'wb_rggblevelsshade' => { 5 => 0x8, 6 => 0x28, 7 => 0x2c, 8 => 0x53, 134 => 0x20e },
    1868     'wb_rggblevelstungsten' => { 5 => 0x10, 6 => 0x32, 7 => 0x36, 8 => 0x5d, 134 => 0x210 },
    1869     'wb_rggblevelsunknown' => { 7 => 0x1d },
    1870     'wb_rggblevelsunknown10' => { 7 => 0x72 },
    1871     'wb_rggblevelsunknown11' => { 7 => 0x77 },
    1872     'wb_rggblevelsunknown12' => { 7 => 0x7c },
    1873     'wb_rggblevelsunknown13' => { 7 => 0x81 },
    1874     'wb_rggblevelsunknown14' => { 7 => 0x86 },
    1875     'wb_rggblevelsunknown15' => { 7 => 0x8b },
    1876     'wb_rggblevelsunknown16' => { 7 => 0x9f },
    1877     'wb_rggblevelsunknown2' => { 7 => 0x4a },
    1878     'wb_rggblevelsunknown3' => { 7 => 0x4f },
    1879     'wb_rggblevelsunknown4' => { 7 => 0x54 },
    1880     'wb_rggblevelsunknown5' => { 7 => 0x59 },
    1881     'wb_rggblevelsunknown6' => { 7 => 0x5e },
    1882     'wb_rggblevelsunknown7' => { 7 => 0x63 },
    1883     'wb_rggblevelsunknown8' => { 7 => 0x68 },
    1884     'wb_rggblevelsunknown9' => { 7 => 0x6d },
    1885     'wbadjbluebalance' => { 114 => 0x8 },
    1886     'wbadjcolortemp' => { 42 => 0x1a },
    1887     'wbadjlighting' => { 114 => 0x15 },
    1888     'wbadjmode' => { 114 => 0x10 },
    1889     'wbadjredbalance' => { 114 => 0x0 },
    1890     'wbadjrgblevels' => { 42 => 0x8 },
    1891     'wbadjtemperature' => { 114 => 0x18 },
    1892     'wbadjustab' => { 126 => 0x46 },
    1893     'wbadjustgm' => { 126 => 0x47 },
    1894     'wbbluelevel' => { 126 => 0x8006, 127 => 0x26 },
    1895     'wbbracketmode' => { 13 => 0x9 },
    1896     'wbbracketvalueab' => { 13 => 0xc },
    1897     'wbbracketvaluegm' => { 13 => 0xd },
    1898     'wbfinetuneactive' => { 42 => 0x24 },
    1899     'wbfinetunesaturation' => { 42 => 0x28 },
    1900     'wbfinetunetone' => { 42 => 0x2c },
    1901     'wbgreenlevel' => { 126 => 0x8005, 127 => 0x25 },
    1902     'wblevels' => { 91 => 0x4 },
    1903     'wbmediaimagesizesetting' => { 25 => 0x708 },
    1904     'wbmode' => { 90 => 0x4, 120 => 0x1015 },
    1905     'wbredlevel' => { 126 => 0x8004, 127 => 0x24 },
    1906     'wbscale' => { 91 => 0x0 },
    1907     'wbshiftab' => { 21 => 0xc },
    1908     'wbshiftgm' => { 21 => 0xd },
    1909     'webstatement' => { 167 => 'WebStatement' },
    1910     'whitebalance' => { 21 => 0x8, 22 => 0x7, 44 => 0x7, 45 => [0x19,0x2012], 48 => [0xa403,0xfe4e], 52 => 0x1002, 59 => 0x40, 84 => 0x3, 85 => 0xe, 86 => 0x4, 87 => 0xb, 98 => 0x5, 103 => 0x7, 126 => 0x3, 134 => 0x19, 136 => 0x7, 143 => 0x26, 146 => [0x3c,0x7], 154 => 'WhiteBalance', 157 => 'WhiteBalance' },
    1911     'whitebalance2' => { 115 => 0x500 },
    1912     'whitebalanceadj' => { 42 => 0x18, 109 => 0x76a43204 },
    1913     'whitebalancebias' => { 45 => 0x2011, 120 => 0x304, 126 => 0x23 },
    1914     'whitebalanceblue' => { 21 => 0x7 },
    1915     'whitebalancebracket' => { 115 => 0x502, 120 => 0x303 },
    1916     'whitebalancecomp' => { 123 => 0x1001 },
    1917     'whitebalancefinetune' => { 98 => 0xb },
    1918     'whitebalancemode' => { 134 => 0x1a },
    1919     'whitebalancered' => { 21 => 0x6 },
    1920     'whitebalancetemperature' => { 115 => 0x501 },
    1921     'whiteboard' => { 120 => 0x301 },
    1922     'whitepoint' => { 48 => 0x13e, 134 => 0x201, 161 => 'WhitePoint' },
    1923     'widefocuszone' => { 84 => 0x2f },
    1924     'widerange' => { 145 => 0x20f },
    1925     'workcolorspace' => { 42 => 0x270 },
    1926     'worldtimelocation' => { 126 => 0x3a, 134 => 0x22 },
    1927     'writer-editor' => { 54 => 0x7a },
    1928     'x3filllight' => { 146 => 0x12 },
    1929     'xmp' => { 49 => 'XMP' },
    1930     'xpauthor' => { 48 => 0x9c9d },
    1931     'xpcomment' => { 48 => 0x9c9c },
    1932     'xpkeywords' => { 48 => 0x9c9e },
    1933     'xposition' => { 48 => 0x11e },
    1934     'xpsubject' => { 48 => 0x9c9f },
    1935     'xptitle' => { 48 => 0x9c9b },
    1936     'xresolution' => { 48 => 0x11a, 57 => 0x3, 141 => 0x0, 161 => 'XResolution' },
    1937     'xyresolution' => { 51 => 0x3 },
    1938     'ycbcrcoefficients' => { 48 => 0x211, 161 => 'YCbCrCoefficients' },
    1939     'ycbcrpositioning' => { 48 => 0x213, 161 => 'YCbCrPositioning' },
    1940     'ycbcrsubsampling' => { 48 => 0x212, 161 => 'YCbCrSubSampling' },
    1941     'yearcreated' => { 59 => 0x10, 66 => 0xc },
    1942     'yposition' => { 48 => 0x11f },
    1943     'yresolution' => { 48 => 0x11b, 57 => 0x5, 141 => 0x4, 161 => 'YResolution' },
    1944     'zonematching' => { 88 => 0x10a, 90 => 0x3a },
    1945     'zonematchingon' => { 86 => 0x75 },
    1946     'zoomsourcewidth' => { 4 => 0x24 },
    1947     'zoomstepcount' => { 118 => 0x300, 120 => 0x100d },
    1948     'zoomtargetwidth' => { 4 => 0x25 },
     354    'aberrationcorrectiondistance' => { 78 => 0x69 },
     355    'about' => { 304 => 'about' },
     356    'abspeakaudiofilepath' => { 310 => 'absPeakAudioFilePath' },
     357    'accessorytype' => { 224 => 0x53 },
     358    'actionadvised' => { 92 => 0x2a },
     359    'activearea' => { 85 => 0xc68d },
     360    'actived-lighting' => { 160 => 0x22, 188 => 0x24 },
     361    'actived-lightingmode' => { 188 => 0x25 },
     362    'addaspectratioinfo' => { 59 => 0x80e },
     363    'additionalmodelinformation' => { 294 => 'AddlModelInfo' },
     364    'addoriginaldecisiondata' => { 59 => 0x80f, 60 => 0x11, 61 => 0x13, 64 => 0x14 },
     365    'address' => { 118 => 'Address' },
     366    'adjustmentmode' => { 270 => 0x15 },
     367    'adultcontentwarning' => { 300 => 'AdultContentWarning', 303 => 'adultContentWarning' },
     368    'advancedraw' => { 190 => 0x76a43203 },
     369    'advancedscenemode' => { 224 => 0x3d },
     370    'advisory' => { 308 => 'Advisory' },
     371    'ae_iso' => { 227 => 0x2 },
     372    'aeaperture' => { 227 => 0x1 },
     373    'aebautocancel' => { 59 => 0x104 },
     374    'aebbracketvalue' => { 54 => 0x11 },
     375    'aebsequence' => { 59 => 0x105 },
     376    'aebsequenceautocancel' => { 57 => 0x9, 58 => 0x9, 60 => 0x8, 61 => 0x9, 64 => 0x9, 65 => 0x7 },
     377    'aebshotcount' => { 59 => 0x106 },
     378    'aebxv' => { 227 => 0x4 },
     379    'aeexposuretime' => { 227 => 0x0 },
     380    'aelbutton' => { 134 => 0x45 },
     381    'aelexposureindicator' => { 134 => 0x51 },
     382    'aelock' => { 134 => 0x5b, 198 => '4.2', 202 => '4.2', 204 => 0x201, 247 => 0x48 },
     383    'aelockbutton' => { 197 => '16.1', 198 => '4.1', 199 => '15.1', 200 => '30.1', 201 => '16.1', 202 => '4.1', 203 => '17.1' },
     384    'aelockbuttonplusdials' => { 197 => '16.2', 200 => '32.1' },
     385    'aelockformb-d80' => { 203 => '3.1' },
     386    'aemaxaperture' => { 227 => 0x9 },
     387    'aemaxaperture2' => { 227 => 0xa },
     388    'aemeteringmode' => { 227 => 0xc },
     389    'aemeteringsegments' => { 247 => 0x209 },
     390    'aemicroadjustment' => { 59 => 0x111 },
     391    'aeminaperture' => { 227 => 0xb },
     392    'aeminexposuretime' => { 227 => 0x5 },
     393    'aeprogrammode' => { 227 => 0x6 },
     394    'aesetting' => { 24 => 0x21 },
     395    'aexv' => { 227 => 0x3 },
     396    'af-cpriorityselection' => { 197 => '1.1', 200 => '1.1', 201 => '0.1' },
     397    'af-onformb-d10' => { 197 => '3.3', 200 => '3.2' },
     398    'af-onformb-d11' => { 201 => '2.2' },
     399    'af-spriorityselection' => { 197 => '1.2', 200 => '1.2', 201 => '0.2' },
     400    'afactivation' => { 197 => '2.1', 200 => '2.1' },
     401    'afadjustment' => { 247 => 0x72 },
     402    'afandmeteringbuttons' => { 59 => 0x701 },
     403    'afaperture' => { 158 => 0x5, 159 => 0x5 },
     404    'afareaheight' => { 141 => 0x1a },
     405    'afareaillumination' => { 134 => 0x4b, 202 => '15.3' },
     406    'afareamode' => { 134 => 0xe, 140 => 0x0, 141 => 0x5, 224 => 0xf, 271 => 0x11, 272 => 0x11 },
     407    'afareamodesetting' => { 198 => '11.1', 199 => '0.1', 202 => '16.1', 203 => '2.1' },
     408    'afareas' => { 204 => 0x304 },
     409    'afareawidth' => { 141 => 0x18 },
     410    'afareaxposition' => { 141 => 0x14 },
     411    'afareayposition' => { 141 => 0x16 },
     412    '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' },
     413    'afassistbeam' => { 59 => 0x50e, 60 => 0x4, 61 => 0x5, 62 => 0x4, 63 => 0x4, 64 => 0x5 },
     414    'afassistlamp' => { 224 => 0x31 },
     415    'afdefocus' => { 228 => 0x6 },
     416    'afduringliveview' => { 59 => 0x511 },
     417    'affinetune' => { 142 => 0x0 },
     418    'affinetuneadj' => { 142 => 0x2, 168 => 0x2d1, 169 => 0x2dc, 204 => 0x307 },
     419    'affinetuneindex' => { 142 => 0x1 },
     420    'afilluminator' => { 271 => 0x29, 276 => 0xb044 },
     421    'afimageheight' => { 141 => 0x12 },
     422    'afimagewidth' => { 141 => 0x10 },
     423    'afintegrationtime' => { 228 => 0x7 },
     424    'afmicroadjactive' => { 1 => 0x1 },
     425    'afmicroadjustment' => { 59 => 0x507 },
     426    'afmicroadjvalue' => { 1 => 0x2 },
     427    'afmode' => { 82 => 0x3009, 270 => 0x5, 276 => 0xb043 },
     428    'afonaelockbuttonswitch' => { 59 => 0x702 },
     429    'afonbutton' => { 197 => '3.1' },
     430    'afpoint' => { 24 => 0x13, 81 => 0x18, 140 => 0x1, 207 => 0x308, 270 => 0x1f },
     431    'afpointactivationarea' => { 58 => 0x11, 64 => 0x11 },
     432    'afpointareaexpansion' => { 59 => 0x508 },
     433    'afpointautoselection' => { 59 => 0x50b },
     434    'afpointbrightness' => { 59 => 0x50d, 197 => '2.4' },
     435    'afpointdisplayduringfocus' => { 59 => 0x50c },
     436    'afpointillumination' => { 58 => 0xa, 197 => '2.3', 200 => '2.3', 201 => '1.3', 203 => '2.4' },
     437    'afpointmode' => { 232 => 0x3 },
     438    'afpointposition' => { 82 => 0x2021, 224 => 0x4d },
     439    'afpointregistration' => { 57 => 0x7 },
     440    'afpoints' => { 133 => 0x10 },
     441    'afpointselected' => { 204 => 0x305, 247 => 0xe },
     442    'afpointselected2' => { 232 => 0x4 },
     443    'afpointselection' => { 58 => 0xb, 197 => '1.3', 200 => '1.3' },
     444    'afpointselectionmethod' => { 59 => 0x50f, 60 => 0xc, 61 => 0xd, 64 => 0xd },
     445    'afpointsinfocus' => { 54 => 0xe, 140 => 0x2, 228 => 0xb, 247 => [0xf,0x3c] },
     446    'afpointsinfocus5d' => { 15 => 0x38 },
     447    'afpointspotmetering' => { 58 => 0xd },
     448    'afpointsunknown1' => { 228 => 0x0 },
     449    'afpointsunknown2' => { 228 => 0x2 },
     450    'afpointsused' => { 141 => 0x8 },
     451    'afpredictor' => { 228 => 0x4 },
     452    'afresponse' => { 160 => 0xad },
     453    'afresult' => { 209 => 0x1038 },
     454    'afsearch' => { 204 => 0x303 },
     455    'afwithshutter' => { 271 => 0x2a },
     456    'aggregationtype' => { 301 => 'aggregationType' },
     457    'agreement' => { 303 => 'agreement' },
     458    'aiservocontinuousshooting' => { 58 => 0x15 },
     459    'aiservoimagepriority' => { 59 => 0x503 },
     460    'aiservotrackingmethod' => { 59 => 0x504 },
     461    'aiservotrackingsensitivity' => { 58 => 0x14, 59 => 0x502 },
     462    'album' => { 310 => 'album' },
     463    'alreadyapplied' => { 288 => 'AlreadyApplied' },
     464    'alternatetitle' => { 301 => 'alternateTitle' },
     465    'alttapename' => { 310 => 'altTapeName' },
     466    'alttimecode' => { 310 => 'altTimecode' },
     467    'alttimecodetimeformat' => { 310 => [\'altTimecode','altTimecodeTimeFormat'] },
     468    'alttimecodetimevalue' => { 310 => [\'altTimecode','altTimecodeTimeValue'] },
     469    'alttimecodevalue' => { 310 => [\'altTimecode','altTimecodeValue'] },
     470    'ambienceselection' => { 2 => 0x1 },
     471    'ambienttemperature' => { 259 => 0x14 },
     472    'ambienttemperaturefahrenheit' => { 259 => 0x13 },
     473    'analogbalance' => { 85 => 0xc627 },
     474    'angleadj' => { 78 => 0x8b },
     475    'anti-blur' => { 276 => 0xb04b },
     476    'antialiasstrength' => { 85 => 0xc632 },
     477    'aperturerange' => { 59 => 0x10d },
     478    'apertureringuse' => { 232 => '1.4' },
     479    'aperturevalue' => { 68 => 0x2, 85 => 0x9202, 209 => 0x1002, 292 => 'ApertureValue' },
     480    'applekeywords' => { 213 => 'AAPL:Keywords' },
     481    'applicationnotes' => { 85 => 0x2bc, 226 => 0x2bc },
     482    'applicationrecordversion' => { 92 => 0x0 },
     483    'applyshootingmeteringmode' => { 59 => 0x10e },
     484    'approximatefnumber' => { 219 => 0x313, 225 => 0x3406 },
     485    'approximatefocusdistance' => { 285 => 'ApproximateFocusDistance' },
     486    'armidentifier' => { 93 => 0x78 },
     487    'armversion' => { 93 => 0x7a },
     488    'artfilter' => { 204 => 0x529 },
     489    'artist' => { 85 => 0x13b, 215 => 'Artist', 247 => 0x22e, 306 => 'Artist', 310 => 'artist' },
     490    'artworkcopyrightnotice' => { 294 => [\'ArtworkOrObject','ArtworkOrObjectAOCopyrightNotice'] },
     491    'artworkcreator' => { 294 => [\'ArtworkOrObject','ArtworkOrObjectAOCreator'] },
     492    'artworkdatecreated' => { 294 => [\'ArtworkOrObject','ArtworkOrObjectAODateCreated'] },
     493    'artworkorobject' => { 294 => 'ArtworkOrObject' },
     494    'artworksource' => { 294 => [\'ArtworkOrObject','ArtworkOrObjectAOSource'] },
     495    'artworksourceinventoryno' => { 294 => [\'ArtworkOrObject','ArtworkOrObjectAOSourceInvNo'] },
     496    'artworktitle' => { 294 => [\'ArtworkOrObject','ArtworkOrObjectAOTitle'] },
     497    'aspectframe' => { 208 => 0x1113 },
     498    'aspectratio' => { 3 => 0x0, 208 => 0x1112, 271 => 0x55 },
     499    'asshoticcprofile' => { 85 => 0xc68f },
     500    'asshotneutral' => { 85 => 0xc628 },
     501    'asshotpreprofilematrix' => { 85 => 0xc690 },
     502    'asshotprofilename' => { 85 => 0xc6f6 },
     503    'asshotwhitexy' => { 85 => 0xc629 },
     504    'assignbktbutton' => { 197 => '4.2' },
     505    'assignfuncbutton' => { 59 => 0x70b },
     506    'assistbuttonfunction' => { 57 => 0xd },
     507    'attributionname' => { 286 => 'attributionName' },
     508    'attributionurl' => { 286 => 'attributionURL' },
     509    'audio' => { 224 => 0x20 },
     510    'audiobitrate' => { 46 => 0x6c },
     511    'audiochannels' => { 46 => 0x70 },
     512    'audiochanneltype' => { 310 => 'audioChannelType' },
     513    'audiocompression' => { 112 => 'Compression' },
     514    'audiocompressor' => { 310 => 'audioCompressor' },
     515    'audioduration' => { 92 => 0x99 },
     516    'audiomoddate' => { 310 => 'audioModDate' },
     517    'audiooutcue' => { 92 => 0x9a },
     518    'audiosamplerate' => { 46 => 0x6e, 310 => 'audioSampleRate' },
     519    'audiosampletype' => { 310 => 'audioSampleType' },
     520    'audiosamplingrate' => { 92 => 0x97 },
     521    'audiosamplingresolution' => { 92 => 0x98 },
     522    'audiotype' => { 92 => 0x96 },
     523    'author' => { 114 => 'Author', 213 => 'Author', 215 => 'Author', 258 => 'Author', 284 => 'author', 298 => 'Author' },
     524    'authorsposition' => { 299 => 'AuthorsPosition' },
     525    'autoaperture' => { 241 => '0.1' },
     526    'autobracket' => { 270 => 0x19 },
     527    'autobracketing' => { 89 => 0x1100, 247 => 0x18 },
     528    'autobracketmodem' => { 197 => '21.2', 200 => '26.2' },
     529    'autobracketorder' => { 134 => 0x43, 197 => '21.3', 200 => '26.3', 201 => '12.2', 202 => '2.2', 203 => '13.2' },
     530    'autobracketset' => { 197 => '21.1', 199 => '11.1', 200 => '26.1', 201 => '12.1', 202 => '2.1', 203 => '13.1' },
     531    'autobrightness' => { 288 => 'AutoBrightness' },
     532    'autocontrast' => { 288 => 'AutoContrast' },
     533    'autodistortioncontrol' => { 149 => 0x4 },
     534    'autodynamicrange' => { 89 => 0x140b },
     535    'autoexposure' => { 288 => 'AutoExposure' },
     536    'autoexposurebracketing' => { 54 => 0x10 },
     537    'autofocus' => { 207 => 0x209 },
     538    'autofp' => { 202 => '7.3', 203 => '31.4' },
     539    'autoiso' => { 54 => 0x1, 82 => 0x3008, 198 => '1.1', 202 => '1.1' },
     540    'autoisomax' => { 198 => '1.2', 202 => '1.2' },
     541    'autoisominshutterspeed' => { 198 => '1.3', 202 => '1.3' },
     542    'autolightingoptimizer' => { 12 => 0xbe, 13 => 0xbf, 16 => 0xbf, 42 => 0x2, 59 => 0x204, 78 => 0x6f },
     543    'autolightingoptimizeron' => { 78 => 0x6e },
     544    'autoredeye' => { 190 => 0xfe28a44f },
     545    'autorotate' => { 54 => 0x1b },
     546    'autoshadows' => { 288 => 'AutoShadows' },
     547    'auxiliarylens' => { 160 => 0x82 },
     548    'avaperturesetting' => { 232 => 0x13 },
     549    'avsettingwithoutlens' => { 59 => 0x707 },
     550    'azimuth' => { 122 => 'Azimuth' },
     551    'babyage' => { 224 => [0x8010,0x33] },
     552    'babyname' => { 224 => 0x66 },
     553    'backgroundalpha' => { 305 => 'bgalpha' },
     554    'baseexposurecompensation' => { 232 => 0x15 },
     555    'baseiso' => { 54 => 0x2, 72 => 0x101c, 225 => 0x312a },
     556    'baselineexposure' => { 85 => 0xc62a },
     557    'baselinenoise' => { 85 => 0xc62b },
     558    'baselinesharpness' => { 85 => 0xc62c },
     559    'baseurl' => { 308 => 'BaseURL' },
     560    'batterylevel' => { 134 => 0x60 },
     561    'batteryorder' => { 197 => '12.5', 200 => '13.2', 201 => '2.1' },
     562    'batteryvoltage' => { 259 => 0x2a },
     563    'bayergreensplit' => { 85 => 0xc62d },
     564    'bayerpattern' => { 96 => 0xf902, 137 => 0x17 },
     565    'beatspliceparams' => { 310 => 'beatSpliceParams' },
     566    'beatspliceparamsriseindecibel' => { 310 => [\'beatSpliceParams','beatSpliceParamsRiseInDecibel'] },
     567    'beatspliceparamsriseintimeduration' => { 310 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDuration'] },
     568    'beatspliceparamsriseintimedurationscale' => { 310 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDurationScale'] },
     569    'beatspliceparamsriseintimedurationvalue' => { 310 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDurationValue'] },
     570    'beatspliceparamsusefilebeatsmarker' => { 310 => [\'beatSpliceParams','beatSpliceParamsUseFileBeatsMarker'] },
     571    'beep' => { 197 => '13.1', 198 => '0.1', 199 => '2.1', 200 => '10.1', 202 => '0.1', 203 => '4.1' },
     572    'beeppitch' => { 201 => '3.1' },
     573    'beepvolume' => { 201 => '4.5' },
     574    'bestqualityscale' => { 85 => 0xc65c },
     575    'bestshotmode' => { 82 => 0x3007 },
     576    'bitdepth' => { 119 => 'BitDepth', 137 => 0x11, 165 => 0x41 },
     577    'bitspercomponent' => { 94 => 0x87 },
     578    'bitspersample' => { 85 => 0x102, 306 => 'BitsPerSample' },
     579    'blacklevel' => { 85 => 0xc61a, 209 => 0x1012 },
     580    'blacklevel2' => { 208 => 0x600, 212 => 0x600 },
     581    'blacklevelrepeatdim' => { 85 => 0xc619 },
     582    'blackpoint' => { 247 => 0x200 },
     583    'bleachbypasstoning' => { 247 => 0x7f },
     584    'bluebalance' => { 148 => 0x271, 209 => 0x1018, 226 => 0x12, 247 => 0x1b },
     585    'bluecurvelimits' => { 77 => 0x1fe },
     586    'bluecurvepoints' => { 77 => 0x1d4 },
     587    'bluehue' => { 288 => 'BlueHue' },
     588    'bluesaturation' => { 288 => 'BlueSaturation' },
     589    'blurwarning' => { 89 => 0x1300 },
     590    'bodybatteryadload' => { 230 => 0x3 },
     591    'bodybatteryadnoload' => { 230 => 0x2 },
     592    'bodybatterystate' => { 230 => '1.1' },
     593    'bodybatteryvoltage1' => { 230 => 0x2 },
     594    'bodybatteryvoltage2' => { 230 => 0x4 },
     595    'bodybatteryvoltage3' => { 230 => 0x6 },
     596    'bodybatteryvoltage4' => { 230 => 0x8 },
     597    'bodyfirmware' => { 264 => 0x0 },
     598    'bodyfirmwareversion' => { 205 => 0x104, 206 => 0x100, 209 => 0x104 },
     599    'bodyserialnumber' => { 264 => 0x10 },
     600    'bracketmode' => { 38 => 0x3 },
     601    'bracketsequence' => { 82 => 0x301d },
     602    'bracketshotnumber' => { 38 => 0x5, 232 => 0x9 },
     603    'bracketstep' => { 131 => 0xe },
     604    'bracketvalue' => { 38 => 0x4 },
     605    'brightness' => { 85 => 0xfe53, 113 => 'Brightness', 131 => 0x2c, 162 => 0x34, 259 => 0x25, 271 => 0x22, 276 => 0x2007, 288 => 'Brightness' },
     606    'brightnessadj' => { 77 => 0x114, 183 => 0x0, 193 => 0x2d, 279 => 0x8018 },
     607    'brightnessvalue' => { 85 => 0x9203, 209 => 0x1003, 292 => 'BrightnessValue' },
     608    'bulbduration' => { 54 => 0x18 },
     609    'burstmode' => { 99 => 0xa, 224 => 0x2a },
     610    'burstmode2' => { 99 => 0x18 },
     611    'burstshot' => { 270 => 0x34 },
     612    'buttonfunctioncontroloff' => { 59 => 0x70a },
     613    'bwfilter' => { 131 => 0x2a, 138 => 0x39 },
     614    'bwmode' => { 209 => 0x203 },
     615    'by-line' => { 92 => 0x50 },
     616    'by-linetitle' => { 92 => 0x55 },
     617    'bytecount' => { 301 => 'byteCount' },
     618    'calibration' => { 270 => 0x24 },
     619    'calibrationilluminant1' => { 85 => 0xc65a },
     620    'calibrationilluminant2' => { 85 => 0xc65b },
     621    'cameraangle' => { 310 => 'cameraAngle' },
     622    'cameracalibration1' => { 85 => 0xc623 },
     623    'cameracalibration2' => { 85 => 0xc624 },
     624    'cameracalibrationsig' => { 85 => 0xc6f3 },
     625    'cameracolorcalibration01' => { 26 => 0x0, 32 => 0xba },
     626    'cameracolorcalibration02' => { 26 => 0x4, 32 => 0xbf },
     627    'cameracolorcalibration03' => { 26 => 0x8, 32 => 0xc4 },
     628    'cameracolorcalibration04' => { 26 => 0xc, 32 => 0xc9 },
     629    'cameracolorcalibration05' => { 26 => 0x10, 32 => 0xce },
     630    'cameracolorcalibration06' => { 26 => 0x14, 32 => 0xd3 },
     631    'cameracolorcalibration07' => { 26 => 0x18, 32 => 0xd8 },
     632    'cameracolorcalibration08' => { 26 => 0x1c, 32 => 0xdd },
     633    'cameracolorcalibration09' => { 26 => 0x20, 32 => 0xe2 },
     634    'cameracolorcalibration10' => { 26 => 0x24, 32 => 0xe7 },
     635    'cameracolorcalibration11' => { 26 => 0x28, 32 => 0xec },
     636    'cameracolorcalibration12' => { 26 => 0x2c, 32 => 0xf1 },
     637    'cameracolorcalibration13' => { 26 => 0x30, 32 => 0xf6 },
     638    'cameracolorcalibration14' => { 26 => 0x34, 32 => 0xfb },
     639    'cameracolorcalibration15' => { 26 => 0x38, 32 => 0x100 },
     640    'cameraid' => { 209 => 0x209, 269 => 0x209 },
     641    'cameraiso' => { 24 => 0x10 },
     642    'cameralabel' => { 310 => 'cameraLabel' },
     643    'cameramodel' => { 310 => 'cameraModel' },
     644    'cameramove' => { 310 => 'cameraMove' },
     645    '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 },
     646    'cameraowner' => { 100 => 0xc353 },
     647    'cameraparameters' => { 209 => 0x2050 },
     648    'cameraprofile' => { 288 => 'CameraProfile' },
     649    'cameraprofiledigest' => { 288 => 'CameraProfileDigest' },
     650    'cameraserialnumber' => { 85 => 0xc62f, 130 => 'CameraSerialNumber' },
     651    'camerasettingsversion' => { 204 => 0x0 },
     652    '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 },
     653    'cameratemperature2' => { 250 => 0xc },
     654    'cameratemperature3' => { 250 => 0xe },
     655    'cameratemperature4' => { 250 => 0x14 },
     656    'cameratemperature5' => { 250 => 0x16 },
     657    'cameratype' => { 54 => 0x1a, 209 => 0x207 },
     658    'cameratype2' => { 205 => 0x100 },
     659    'canonexposuremode' => { 24 => 0x14 },
     660    'canonfiledescription' => { 72 => 0x805 },
     661    'canonfilelength' => { 43 => 0xe },
     662    'canonfirmwareversion' => { 43 => 0x7, 72 => 0x80b },
     663    'canonflashinfo' => { 72 => 0x1028 },
     664    'canonflashmode' => { 24 => 0x4 },
     665    'canonimagesize' => { 6 => 0x39, 24 => 0xa },
     666    'canonimagetype' => { 43 => 0x6, 72 => 0x815 },
     667    'canonmodelid' => { 43 => 0x10, 72 => 0x1834 },
     668    'canonvrd' => { 86 => 'CanonVRD' },
     669    'caption' => { 284 => 'caption' },
     670    'caption-abstract' => { 92 => 0x78 },
     671    'captionsauthornames' => { 291 => 'CaptionsAuthorNames' },
     672    'captionsdatetimestamps' => { 291 => 'CaptionsDateTimeStamps' },
     673    'captionwriter' => { 299 => 'CaptionWriter' },
     674    'captureframerate' => { 82 => 0x4001 },
     675    'cardshutterlock' => { 134 => 0x49 },
     676    'casioimagesize' => { 82 => 0x9 },
     677    'catalogsets' => { 92 => 0xff, 283 => 'CatalogSets' },
     678    'categories' => { 43 => 0x23, 284 => 'categories' },
     679    'category' => { 92 => 0xf, 299 => 'Category' },
     680    'ccdboardversion' => { 219 => 0x331 },
     681    'ccdscanmode' => { 209 => 0x1039 },
     682    'ccdsensitivity' => { 180 => 0x6 },
     683    'ccdversion' => { 219 => 0x330 },
     684    'cellglobalid' => { 287 => 'cgi' },
     685    'celllength' => { 85 => 0x109 },
     686    'cellr' => { 287 => 'r' },
     687    'celltowerid' => { 287 => 'cellid' },
     688    'cellwidth' => { 85 => 0x108 },
     689    'centerafarea' => { 202 => '15.1' },
     690    'centerfocuspoint' => { 203 => '2.2' },
     691    'centerweightedareasize' => { 197 => '7.1', 200 => '5.1', 201 => '7.1', 202 => '6.3', 203 => '8.1' },
     692    'certificate' => { 314 => 'Certificate' },
     693    'cfapattern' => { 85 => 0xa302, 292 => 'CFAPattern' },
     694    'cfapatterncolumns' => { 292 => [\'CFAPattern','CFAPatternColumns'] },
     695    'cfapatternrows' => { 292 => [\'CFAPattern','CFAPatternRows'] },
     696    'cfapatternvalues' => { 292 => [\'CFAPattern','CFAPatternValues'] },
     697    'channel' => { 301 => 'channel' },
     698    'channels' => { 112 => 'Channels' },
     699    'checkmark' => { 77 => 0x26a },
     700    'checkmark2' => { 78 => 0x8e },
     701    'childfontfiles' => { 315 => [\'Fonts','FontsChildFontFiles'] },
     702    'chmodeshootingspeed' => { 197 => '10.3' },
     703    'chromablurradius' => { 85 => 0xc631 },
     704    'chromaticaberration' => { 78 => 0x66 },
     705    'chromaticaberrationb' => { 288 => 'ChromaticAberrationB' },
     706    'chromaticaberrationblue' => { 78 => 0x6b },
     707    'chromaticaberrationcorrection' => { 240 => 0x1 },
     708    'chromaticaberrationon' => { 78 => 0x62 },
     709    'chromaticaberrationr' => { 288 => 'ChromaticAberrationR' },
     710    'chromaticaberrationred' => { 78 => 0x6a },
     711    'chrominancenoisereduction' => { 78 => 0x5e, 270 => 0x1a },
     712    'chrominancenr_tiff_jpeg' => { 78 => 0x60 },
     713    'city' => { 92 => 0x5a, 118 => 'City', 224 => 0x6d, 299 => 'City' },
     714    'clarity' => { 288 => 'Clarity' },
     715    'classifystate' => { 92 => 0xe1 },
     716    'client' => { 310 => 'client' },
     717    'clmodeshootingspeed' => { 197 => '10.2', 200 => '11.2', 201 => '10.2', 203 => '11.1' },
     718    'cmcontrast' => { 212 => 0x2022 },
     719    'cmexposurecompensation' => { 212 => 0x2000 },
     720    'cmhue' => { 212 => 0x2021 },
     721    'cmsaturation' => { 212 => 0x2020 },
     722    'cmsharpness' => { 212 => 0x2023 },
     723    'cmwhitebalance' => { 212 => 0x2001 },
     724    'cmwhitebalancecomp' => { 212 => 0x2002 },
     725    'cmwhitebalancegraypoint' => { 212 => 0x2010 },
     726    'codec' => { 126 => 'Codec' },
     727    'codedcharacterset' => { 93 => 0x5a },
     728    'collectionname' => { 295 => [\'Collections','CollectionsCollectionName'] },
     729    'collections' => { 295 => 'Collections' },
     730    'collectionuri' => { 295 => [\'Collections','CollectionsCollectionURI'] },
     731    'coloraberrationcontrol' => { 190 => 0xc89224b },
     732    'coloradjustment' => { 270 => 0x14 },
     733    'coloradjustmentmode' => { 269 => 0x210 },
     734    'coloranta' => { 315 => [\'Colorants','ColorantsA'] },
     735    'colorantb' => { 315 => [\'Colorants','ColorantsB'] },
     736    'colorantblack' => { 315 => [\'Colorants','ColorantsBlack'] },
     737    'colorantblue' => { 315 => [\'Colorants','ColorantsBlue'] },
     738    'colorantcyan' => { 315 => [\'Colorants','ColorantsCyan'] },
     739    'colorantgreen' => { 315 => [\'Colorants','ColorantsGreen'] },
     740    'colorantl' => { 315 => [\'Colorants','ColorantsL'] },
     741    'colorantmagenta' => { 315 => [\'Colorants','ColorantsMagenta'] },
     742    'colorantmode' => { 315 => [\'Colorants','ColorantsMode'] },
     743    'colorantred' => { 315 => [\'Colorants','ColorantsRed'] },
     744    'colorants' => { 315 => 'Colorants' },
     745    'colorantswatchname' => { 315 => [\'Colorants','ColorantsSwatchName'] },
     746    'coloranttype' => { 315 => [\'Colorants','ColorantsType'] },
     747    'colorantyellow' => { 315 => [\'Colorants','ColorantsYellow'] },
     748    'colorbalance' => { 113 => 'ColorBalance' },
     749    'colorbalanceadj' => { 190 => 0x76a43202 },
     750    'colorbalanceblue' => { 131 => 0x1e },
     751    'colorbalancegreen' => { 131 => 0x1d },
     752    'colorbalancered' => { 131 => 0x1c },
     753    'colorblur' => { 78 => 0x65 },
     754    'colorbooster' => { 190 => 0x5f0e7d23 },
     755    'colorboostlevel' => { 184 => 0x1 },
     756    'colorboosttype' => { 184 => 0x0 },
     757    'colorclass' => { 253 => 0xde },
     758    'colorcompensationfilter' => { 134 => [0x3a,0x5f], 135 => 0x111, 276 => 0xb022 },
     759    'colorcontrol' => { 209 => 0x102b },
     760    'colorcorrection' => { 279 => 0x8015 },
     761    'colordataversion' => { 30 => 0x0, 31 => 0x0, 33 => 0x0 },
     762    'coloreffect' => { 224 => 0x28 },
     763    'colorfilter' => { 81 => 0x17, 82 => 0x3017, 131 => 0x29, 138 => [0x38,0x4d,0x4f], 252 => 0x17 },
     764    'colorgain' => { 165 => 0x51 },
     765    'colorhue' => { 160 => 0x8d },
     766    'colorimetricreference' => { 85 => 0xc6bf },
     767    'colormatrix' => { 208 => 0x200, 209 => 0x1011, 267 => 0xa030 },
     768    'colormatrix1' => { 85 => 0xc621 },
     769    'colormatrix2' => { 85 => 0xc622, 212 => 0x200 },
     770    'colormatrixa' => { 247 => 0x203 },
     771    'colormatrixadobergb' => { 267 => 0xa032 },
     772    'colormatrixb' => { 247 => 0x204 },
     773    'colormatrixnumber' => { 209 => 0x1019 },
     774    'colormatrixsrgb' => { 267 => 0xa031 },
     775    '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' },
     776    'colormoirereduction' => { 191 => 0x15 },
     777    'colormoirereductionmode' => { 191 => 0x5 },
     778    'colornoisereduction' => { 279 => 0x8029, 288 => 'ColorNoiseReduction' },
     779    'colornoisereductiondetail' => { 288 => 'ColorNoiseReductionDetail' },
     780    'colornoisereductionintensity' => { 191 => 0x18 },
     781    'colornoisereductionsharpness' => { 191 => 0x1c },
     782    'colorplanes' => { 88 => 0x2 },
     783    'colorprofile' => { 131 => 0x33 },
     784    'colorrepresentation' => { 94 => 0x3c },
     785    'colorreproduction' => { 276 => 0xb020 },
     786    'colorsequence' => { 94 => 0x41 },
     787    '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' },
     788    'colortempasshot' => { 27 => 0x4, 28 => 0x1d, 29 => 0x26, 30 => 0x43, 33 => 0x43 },
     789    'colortempauto' => { 27 => 0x9, 28 => 0x22, 29 => 0x1c, 30 => 0x48, 33 => 0x48 },
     790    'colortempcloudy' => { 27 => 0x22, 28 => 0x31, 29 => 0x35, 30 => 0x5c, 33 => 0x75 },
     791    'colortempcustom' => { 30 => 0x84 },
     792    'colortempcustom1' => { 28 => 0x45 },
     793    'colortempcustom2' => { 28 => 0x4a },
     794    'colortempdaylight' => { 27 => 0x18, 28 => 0x27, 29 => 0x2b, 30 => 0x52, 33 => 0x6b },
     795    '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' },
     796    'colortemperatureadj' => { 279 => 0x8013 },
     797    'colortemperaturebg' => { 209 => 0x1013 },
     798    'colortemperaturerg' => { 209 => 0x1014 },
     799    'colortemperaturesetting' => { 134 => 0x25 },
     800    'colortempflash' => { 27 => 0x36, 28 => 0x40, 29 => 0x49, 30 => 0x70, 33 => 0x89 },
     801    'colortempflashdata' => { 30 => 0x24a },
     802    'colortempfluorescent' => { 27 => 0x2c, 28 => 0x3b, 29 => 0x3f, 30 => 0x66, 33 => 0x7f },
     803    'colortempkelvin' => { 27 => 0x31, 29 => 0x44, 30 => 0x6b, 33 => 0x84 },
     804    'colortempmeasured' => { 27 => 0xe, 30 => 0x4d, 33 => 0x4d },
     805    'colortemppc1' => { 29 => 0x94, 30 => 0x75 },
     806    'colortemppc2' => { 29 => 0x99, 30 => 0x7a },
     807    'colortemppc3' => { 29 => 0x9e, 30 => 0x7f },
     808    'colortempshade' => { 27 => 0x1d, 28 => 0x2c, 29 => 0x30, 30 => 0x57, 33 => 0x70 },
     809    'colortemptungsten' => { 27 => 0x27, 28 => 0x36, 29 => 0x3a, 30 => 0x61, 33 => 0x7a },
     810    'colortempunknown' => { 27 => 0x13, 29 => 0x21, 33 => 0x52 },
     811    'colortempunknown10' => { 27 => 0x63, 29 => 0x76, 33 => 0xa2 },
     812    'colortempunknown11' => { 27 => 0x68, 29 => 0x7b, 33 => 0xa7 },
     813    'colortempunknown12' => { 27 => 0x6d, 29 => 0x80, 33 => 0xac },
     814    'colortempunknown13' => { 27 => 0x72, 29 => 0x85, 33 => 0xb1 },
     815    'colortempunknown14' => { 29 => 0x8a, 33 => 0xb6 },
     816    'colortempunknown15' => { 29 => 0x8f, 33 => 0xbb },
     817    'colortempunknown16' => { 29 => 0xa3 },
     818    'colortempunknown2' => { 27 => 0x3b, 29 => 0x4e, 33 => 0x57 },
     819    'colortempunknown3' => { 27 => 0x40, 29 => 0x53, 33 => 0x5c },
     820    'colortempunknown4' => { 27 => 0x45, 29 => 0x58, 33 => 0x61 },
     821    'colortempunknown5' => { 27 => 0x4a, 29 => 0x5d, 33 => 0x66 },
     822    'colortempunknown6' => { 27 => 0x4f, 29 => 0x62, 33 => 0x8e },
     823    'colortempunknown7' => { 27 => 0x54, 29 => 0x67, 33 => 0x93 },
     824    'colortempunknown8' => { 27 => 0x59, 29 => 0x6c, 33 => 0x98 },
     825    'colortempunknown9' => { 27 => 0x5e, 29 => 0x71, 33 => 0x9d },
     826    'colortone' => { 6 => 0x6f, 8 => 0x77, 24 => 0x2a, 34 => 0x2 },
     827    'colortoneadj' => { 77 => 0x11e },
     828    'colortonefaithful' => { 15 => 0x107, 48 => 0x6c, 49 => 0x6c },
     829    'colortonelandscape' => { 15 => 0x105, 48 => 0x3c, 49 => 0x3c },
     830    'colortonemonochrome' => { 48 => 0x84, 49 => 0x84 },
     831    'colortoneneutral' => { 15 => 0x106, 48 => 0x54, 49 => 0x54 },
     832    'colortoneportrait' => { 15 => 0x104, 48 => 0x24, 49 => 0x24 },
     833    'colortonestandard' => { 15 => 0x103, 48 => 0xc, 49 => 0xc },
     834    'colortoneunknown' => { 49 => 0x9c },
     835    'colortoneuserdef1' => { 15 => 0x109, 48 => 0x9c, 49 => 0xb4 },
     836    'colortoneuserdef2' => { 15 => 0x10a, 48 => 0xb4, 49 => 0xcc },
     837    'colortoneuserdef3' => { 15 => 0x10b, 48 => 0xcc, 49 => 0xe4 },
     838    'commanddials' => { 202 => '5.1' },
     839    'commanddialsaperturesetting' => { 197 => '17.3', 200 => '33.3', 201 => '17.3' },
     840    'commanddialschangemainsub' => { 197 => '17.2', 200 => '33.2', 201 => '17.2' },
     841    'commanddialsmenuandplayback' => { 197 => '17.4', 200 => '33.4', 201 => '17.4' },
     842    'commanddialsreverserotation' => { 197 => '17.1', 199 => '16.2', 200 => '33.1', 201 => '17.1', 203 => '18.1' },
     843    'commanderchannel' => { 202 => '10.2' },
     844    'commandergroupa_ttl-aacomp' => { 202 => '13.1' },
     845    'commandergroupa_ttlcomp' => { 203 => '32.1' },
     846    'commandergroupamanualoutput' => { 202 => '13.2' },
     847    'commandergroupamode' => { 202 => '11.2' },
     848    'commandergroupb_ttl-aacomp' => { 202 => '14.1' },
     849    'commandergroupb_ttlcomp' => { 203 => '33.1' },
     850    'commandergroupbmanualoutput' => { 202 => '14.2' },
     851    'commandergroupbmode' => { 202 => '11.3' },
     852    'commanderinternalflash' => { 202 => '11.1' },
     853    'commanderinternalmanualoutput' => { 202 => '12.2' },
     854    'commanderinternalttlchannel' => { 200 => '18.2' },
     855    'commanderinternalttlcomp' => { 202 => '12.1', 203 => '31.2' },
     856    'commanderinternalttlcompbuiltin' => { 200 => '20.1', 201 => '26.1' },
     857    'commanderinternalttlcompgroupa' => { 200 => '21.1', 201 => '27.1' },
     858    'commanderinternalttlcompgroupb' => { 200 => '22.1', 201 => '28.1' },
     859    'comment' => { 0 => 0x2, 86 => 'Comment', 114 => 'Comment', 215 => 'Comment' },
     860    'complianceprofile' => { 301 => 'complianceProfile' },
     861    'componentsconfiguration' => { 85 => 0x9101, 119 => 'Components', 292 => 'ComponentsConfiguration' },
     862    'componentversion' => { 72 => 0x80c },
     863    'composer' => { 310 => 'composer' },
     864    'compositionadjust' => { 246 => '0.1' },
     865    'compositionadjustrotation' => { 246 => 0x7 },
     866    'compositionadjustx' => { 246 => 0x5 },
     867    'compositionadjusty' => { 246 => 0x6 },
     868    'compressedbitsperpixel' => { 85 => 0x9102, 292 => 'CompressedBitsPerPixel' },
     869    'compressedimagesize' => { 135 => 0x40, 209 => 0x40 },
     870    'compression' => { 85 => 0x103, 306 => 'Compression' },
     871    'compressionfactor' => { 204 => 0x50d },
     872    'compressionratio' => { 119 => 'Compression', 209 => 0x1034 },
     873    'constrainedcropheight' => { 77 => 0x266, 253 => 0xd6 },
     874    'constrainedcropwidth' => { 77 => 0x262, 253 => 0xd5 },
     875    'contact' => { 92 => 0x76 },
     876    'contentlocationcode' => { 92 => 0x1a },
     877    'contentlocationname' => { 92 => 0x1b },
     878    'continuousbracketing' => { 134 => 0x20 },
     879    'continuousdrive' => { 24 => 0x5 },
     880    'continuousshootingspeed' => { 59 => 0x610 },
     881    'continuousshotlimit' => { 59 => 0x611 },
     882    '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' },
     883    'contrastadj' => { 77 => 0x115, 193 => 0x2c, 279 => 0x8017 },
     884    'contrastdetectaf' => { 141 => 0x4 },
     885    'contrastdetectafarea' => { 247 => 0x231 },
     886    'contrastdetectafinfocus' => { 141 => 0x1c },
     887    'contrastfaithful' => { 15 => 0xec, 48 => 0x60, 49 => 0x60 },
     888    'contrasthighlight' => { 247 => 0x6d },
     889    'contrasthighlightshadowadj' => { 247 => 0x6f },
     890    'contrastlandscape' => { 15 => 0xea, 48 => 0x30, 49 => 0x30 },
     891    'contrastmode' => { 224 => 0x2c },
     892    'contrastmonochrome' => { 15 => 0xed, 48 => 0x78, 49 => 0x78 },
     893    'contrastneutral' => { 15 => 0xeb, 48 => 0x48, 49 => 0x48 },
     894    'contrastportrait' => { 15 => 0xe9, 48 => 0x18, 49 => 0x18 },
     895    'contrastsetting' => { 204 => 0x505, 212 => 0x1012 },
     896    'contrastshadow' => { 247 => 0x6e },
     897    'contraststandard' => { 15 => 0xe8, 48 => 0x0, 49 => 0x0 },
     898    'contrastunknown' => { 49 => 0x90 },
     899    'contrastuserdef1' => { 15 => 0xee, 48 => 0x90, 49 => 0xa8 },
     900    'contrastuserdef2' => { 15 => 0xef, 48 => 0xa8, 49 => 0xc0 },
     901    'contrastuserdef3' => { 15 => 0xf0, 48 => 0xc0, 49 => 0xd8 },
     902    'contributedmedia' => { 310 => 'contributedMedia' },
     903    'contributedmediaduration' => { 310 => [\'contributedMedia','contributedMediaDuration'] },
     904    'contributedmediadurationscale' => { 310 => [\'contributedMedia','contributedMediaDurationScale'] },
     905    'contributedmediadurationvalue' => { 310 => [\'contributedMedia','contributedMediaDurationValue'] },
     906    'contributedmediamanaged' => { 310 => [\'contributedMedia','contributedMediaManaged'] },
     907    'contributedmediapath' => { 310 => [\'contributedMedia','contributedMediaPath'] },
     908    'contributedmediastarttime' => { 310 => [\'contributedMedia','contributedMediaStartTime'] },
     909    'contributedmediastarttimescale' => { 310 => [\'contributedMedia','contributedMediaStartTimeScale'] },
     910    'contributedmediastarttimevalue' => { 310 => [\'contributedMedia','contributedMediaStartTimeValue'] },
     911    'contributedmediatrack' => { 310 => [\'contributedMedia','contributedMediaTrack'] },
     912    'contributedmediawebstatement' => { 310 => [\'contributedMedia','contributedMediaWebStatement'] },
     913    'contributor' => { 289 => 'contributor' },
     914    'contributors' => { 114 => 'Contributors' },
     915    'controldialset' => { 134 => 0x46 },
     916    'controlledvocabularyterm' => { 294 => 'CVterm' },
     917    'controllerboardversion' => { 219 => 0x332 },
     918    'controlmode' => { 54 => 0x12 },
     919    'conversionlens' => { 224 => 0x35 },
     920    'converter' => { 85 => 0xfe4d, 180 => 0xb, 288 => 'Converter' },
     921    'converttograyscale' => { 288 => 'ConvertToGrayscale' },
     922    'copyright' => { 0 => 0x3, 85 => 0x8298, 114 => 'Copyright', 215 => 'Copyright', 247 => 0x22f, 258 => 'Copyright', 298 => 'Copyright', 301 => 'copyright', 303 => 'copyright', 306 => 'Copyright', 310 => 'copyright' },
     923    'copyrightflag' => { 256 => 0x40a },
     924    'copyrightnotice' => { 92 => 0x74 },
     925    'copyrightowner' => { 300 => 'CopyrightOwner' },
     926    'copyrightownerid' => { 300 => [\'CopyrightOwner','CopyrightOwnerCopyrightOwnerID'] },
     927    'copyrightownerimageid' => { 300 => 'CopyrightOwnerImageID' },
     928    'copyrightownername' => { 300 => [\'CopyrightOwner','CopyrightOwnerCopyrightOwnerName'] },
     929    'copyrightregistrationnumber' => { 300 => 'CopyrightRegistrationNumber' },
     930    'copyrightstatus' => { 300 => 'CopyrightStatus' },
     931    'coringfilter' => { 208 => 0x310, 209 => 0x102d, 212 => 0x310 },
     932    'coringvalues' => { 208 => 0x311, 212 => 0x311 },
     933    'corporateentity' => { 301 => 'corporateEntity' },
     934    'country' => { 118 => 'Country', 224 => 0x69, 299 => 'Country' },
     935    'country-primarylocationcode' => { 92 => 0x64 },
     936    'country-primarylocationname' => { 92 => 0x65 },
     937    'countrycode' => { 254 => 'CountryCode', 293 => 'CountryCode' },
     938    'coverage' => { 289 => 'coverage' },
     939    'coverdate' => { 301 => 'coverDate' },
     940    'coverdisplaydate' => { 301 => 'coverDisplayDate' },
     941    'cpufirmwareversion' => { 247 => 0x28 },
     942    'crc32' => { 290 => 'crc32' },
     943    'createdate' => { 85 => 0x9004, 114 => 'CreateDate', 213 => 'CreationDate', 215 => 'create-date', 258 => 'CreationDate', 308 => 'CreateDate' },
     944    'creationdate' => { 298 => 'CreationDate', 301 => 'creationDate' },
     945    'creationtime' => { 215 => 'Creation Time' },
     946    'creativestyle' => { 271 => 0x1a, 272 => 0x18 },
     947    'creativestylewaschanged' => { 279 => 0x8001 },
     948    'creator' => { 213 => 'Creator', 258 => 'Creator', 289 => 'creator', 298 => 'Creator' },
     949    'creatoraddress' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiAdrExtadr'] },
     950    'creatorcity' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiAdrCity'] },
     951    'creatorcontactinfo' => { 293 => 'CreatorContactInfo' },
     952    'creatorcountry' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiAdrCtry'] },
     953    'creatorpostalcode' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiAdrPcode'] },
     954    'creatorregion' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiAdrRegion'] },
     955    'creatortool' => { 308 => 'CreatorTool' },
     956    'creatorworkemail' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiEmailWork'] },
     957    'creatorworktelephone' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiTelWork'] },
     958    'creatorworkurl' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiUrlWork'] },
     959    'credit' => { 92 => 0x6e, 299 => 'Credit' },
     960    'creditline' => { 303 => 'creditLine' },
     961    'creditlinereq' => { 313 => 'CreditLineReq' },
     962    'creditlinerequired' => { 300 => 'CreditLineRequired' },
     963    'cropactive' => { 77 => 0x244 },
     964    'cropangle' => { 288 => 'CropAngle' },
     965    'cropaspectratio' => { 77 => 0x260 },
     966    'cropbottom' => { 88 => 0x9, 185 => 0x36, 253 => 0xdc, 288 => 'CropBottom' },
     967    'cropbottommargin' => { 35 => 0x3 },
     968    'cropconstraintowarp' => { 288 => 'CropConstrainToWarp' },
     969    'cropheight' => { 77 => 0x24c, 208 => 0x615, 212 => 0x615, 288 => 'CropHeight' },
     970    'crophispeed' => { 160 => 0x1b },
     971    'cropleft' => { 77 => 0x246, 88 => 0x6, 185 => 0x1e, 208 => 0x612, 212 => 0x612, 253 => 0xd9, 288 => 'CropLeft' },
     972    'cropleftmargin' => { 35 => 0x0 },
     973    'cropoutputheight' => { 185 => 0xce },
     974    'cropoutputheightinches' => { 185 => 0x96 },
     975    'cropoutputpixels' => { 185 => 0xd6 },
     976    'cropoutputresolution' => { 185 => 0xb6 },
     977    'cropoutputscale' => { 185 => 0xbe },
     978    'cropoutputwidth' => { 185 => 0xc6 },
     979    'cropoutputwidthinches' => { 185 => 0x8e },
     980    'croppedimageheight' => { 3 => 0x2 },
     981    'croppedimagewidth' => { 3 => 0x1 },
     982    'cropright' => { 88 => 0x8, 185 => 0x2e, 253 => 0xdb, 288 => 'CropRight' },
     983    'croprightmargin' => { 35 => 0x1 },
     984    'croprotation' => { 88 => 0xb },
     985    'cropscaledresolution' => { 185 => 0x9e },
     986    'cropsourceresolution' => { 185 => 0xae },
     987    'croptop' => { 77 => 0x248, 88 => 0x7, 185 => 0x26, 208 => 0x613, 212 => 0x613, 253 => 0xda, 288 => 'CropTop' },
     988    'croptopmargin' => { 35 => 0x2 },
     989    'cropunit' => { 288 => 'CropUnit' },
     990    'cropunits' => { 288 => 'CropUnits' },
     991    'cropwidth' => { 77 => 0x24a, 208 => 0x614, 212 => 0x614, 288 => 'CropWidth' },
     992    'crossprocess' => { 247 => 0x7b },
     993    'crossprocessparams' => { 247 => 0x235 },
     994    'currenticcprofile' => { 85 => 0xc691 },
     995    'currentpreprofilematrix' => { 85 => 0xc692 },
     996    'currentversion' => { 279 => 0xd000 },
     997    'curves' => { 190 => 0x76a43201 },
     998    'custom1' => { 300 => 'Custom1' },
     999    'custom10' => { 300 => 'Custom10' },
     1000    'custom2' => { 300 => 'Custom2' },
     1001    'custom3' => { 300 => 'Custom3' },
     1002    'custom4' => { 300 => 'Custom4' },
     1003    'custom5' => { 300 => 'Custom5' },
     1004    'custom6' => { 300 => 'Custom6' },
     1005    'custom7' => { 300 => 'Custom7' },
     1006    'custom8' => { 300 => 'Custom8' },
     1007    'custom9' => { 300 => 'Custom9' },
     1008    'customcontrast' => { 78 => 0x4e },
     1009    'customcontrols' => { 59 => 0x70c },
     1010    'customlinear' => { 78 => 0x4f },
     1011    'customoutputhighlightpoint' => { 78 => 0x53 },
     1012    'customoutputshadowpoint' => { 78 => 0x54 },
     1013    'custompicturestylefilename' => { 43 => 0x4010 },
     1014    'customrawhighlight' => { 78 => 0x7c },
     1015    'customrawhighlightpoint' => { 78 => 0x51 },
     1016    'customrawshadow' => { 78 => 0x85 },
     1017    'customrawshadowpoint' => { 78 => 0x52 },
     1018    'customrendered' => { 85 => 0xa401, 292 => 'CustomRendered' },
     1019    'customsaturation' => { 204 => 0x503 },
     1020    'customsettingsalldefault' => { 197 => '0.2', 200 => '0.2' },
     1021    'customsettingsbank' => { 197 => '0.1', 200 => '0.1' },
     1022    'customsharpness' => { 78 => 0x50 },
     1023    'customwbbluelevel' => { 134 => 0x36 },
     1024    'customwberror' => { 134 => 0x37 },
     1025    'customwbgreenlevel' => { 134 => 0x35 },
     1026    'customwbredlevel' => { 134 => 0x34 },
     1027    'customwbsetting' => { 134 => 0x26 },
     1028    'd-lightinghq' => { 190 => 0x2175eb78 },
     1029    'd-lightinghqcolorboost' => { 186 => 0x2 },
     1030    'd-lightinghqhighlight' => { 186 => 0x1 },
     1031    'd-lightinghqselected' => { 190 => 0x6a6e36b6 },
     1032    'd-lightinghqshadow' => { 186 => 0x0 },
     1033    'd-lightinghs' => { 190 => 0xce5554aa },
     1034    'd-lightinghsadjustment' => { 187 => 0x0 },
     1035    'd-lightinghscolorboost' => { 187 => 0x1 },
     1036    'd-rangeoptimizerhighlight' => { 279 => 0x8024 },
     1037    'd-rangeoptimizermode' => { 279 => 0x8022 },
     1038    'd-rangeoptimizershadow' => { 279 => 0x802d },
     1039    'd-rangeoptimizervalue' => { 279 => 0x8023 },
     1040    'datacompressionmethod' => { 94 => 0x6e },
     1041    'dataimprint' => { 131 => 0x34 },
     1042    'date' => { 247 => 0x6, 289 => 'date' },
     1043    'dateacquired' => { 130 => 'DateAcquired' },
     1044    'datecreated' => { 92 => 0x37, 299 => 'DateCreated' },
     1045    'datedisplayformat' => { 182 => 0x3 },
     1046    'dateimprint' => { 199 => '4.2' },
     1047    'daterecieved' => { 301 => 'dateRecieved' },
     1048    'datesent' => { 93 => 0x46 },
     1049    'datestampmode' => { 43 => 0x1c },
     1050    'datetime' => { 284 => 'datetime', 306 => 'DateTime' },
     1051    'datetimedigitized' => { 292 => 'DateTimeDigitized' },
     1052    'datetimeoriginal' => { 75 => 0x0, 85 => 0x9003, 111 => 0x14, 114 => 'OriginalDate', 259 => 0xb, 292 => 'DateTimeOriginal' },
     1053    'datetimestamp' => { 99 => 0x64 },
     1054    'daylightsavings' => { 182 => 0x2 },
     1055    'declination' => { 122 => 'Declination' },
     1056    'decposition' => { 131 => 0x32 },
     1057    'defaultcroporigin' => { 85 => 0xc61f },
     1058    'defaultcropsize' => { 85 => 0xc620 },
     1059    'defaultscale' => { 85 => 0xc61e },
     1060    'defringe' => { 288 => 'Defringe' },
     1061    'deletedimagecount' => { 160 => 0xa6, 166 => 0x6e },
     1062    'derivedfrom' => { 311 => 'DerivedFrom' },
     1063    'derivedfromalternatepaths' => { 311 => [\'DerivedFrom','DerivedFromAlternatePaths'] },
     1064    'derivedfromdocumentid' => { 311 => [\'DerivedFrom','DerivedFromDocumentID'] },
     1065    'derivedfromfilepath' => { 311 => [\'DerivedFrom','DerivedFromFilePath'] },
     1066    'derivedfromfrompart' => { 311 => [\'DerivedFrom','DerivedFromFromPart'] },
     1067    'derivedfrominstanceid' => { 311 => [\'DerivedFrom','DerivedFromInstanceID'] },
     1068    'derivedfromlastmodifydate' => { 311 => [\'DerivedFrom','DerivedFromLastModifyDate'] },
     1069    'derivedfrommanager' => { 311 => [\'DerivedFrom','DerivedFromManager'] },
     1070    'derivedfrommanagervariant' => { 311 => [\'DerivedFrom','DerivedFromManagerVariant'] },
     1071    'derivedfrommanageto' => { 311 => [\'DerivedFrom','DerivedFromManageTo'] },
     1072    'derivedfrommanageui' => { 311 => [\'DerivedFrom','DerivedFromManageUI'] },
     1073    'derivedfrommaskmarkers' => { 311 => [\'DerivedFrom','DerivedFromMaskMarkers'] },
     1074    'derivedfromoriginaldocumentid' => { 311 => [\'DerivedFrom','DerivedFromOriginalDocumentID'] },
     1075    'derivedfrompartmapping' => { 311 => [\'DerivedFrom','DerivedFromPartMapping'] },
     1076    'derivedfromrenditionclass' => { 311 => [\'DerivedFrom','DerivedFromRenditionClass'] },
     1077    'derivedfromrenditionparams' => { 311 => [\'DerivedFrom','DerivedFromRenditionParams'] },
     1078    'derivedfromtopart' => { 311 => [\'DerivedFrom','DerivedFromToPart'] },
     1079    'derivedfromversionid' => { 311 => [\'DerivedFrom','DerivedFromVersionID'] },
     1080    'description' => { 215 => 'Description', 289 => 'description' },
     1081    'destination' => { 93 => 0x5 },
     1082    'destinationcity' => { 247 => 0x24, 251 => 0x3 },
     1083    'destinationcitycode' => { 252 => 0x1001 },
     1084    'destinationdst' => { 247 => 0x26, 251 => '0.3' },
     1085    'developmentdynamicrange' => { 89 => 0x1403 },
     1086    'devicesettingdescription' => { 292 => 'DeviceSettingDescription' },
     1087    'devicesettingdescriptioncolumns' => { 292 => [\'DeviceSettingDescription','DeviceSettingDescriptionColumns'] },
     1088    'devicesettingdescriptionrows' => { 292 => [\'DeviceSettingDescription','DeviceSettingDescriptionRows'] },
     1089    'devicesettingdescriptionsettings' => { 292 => [\'DeviceSettingDescription','DeviceSettingDescriptionSettings'] },
     1090    'dialdirectiontvav' => { 59 => 0x706 },
     1091    'digitalcreationdate' => { 92 => 0x3e },
     1092    'digitalcreationtime' => { 92 => 0x3f },
     1093    'digitaldeehighlightadj' => { 165 => 0x202 },
     1094    'digitaldeeshadowadj' => { 165 => 0x200 },
     1095    'digitaldeethreshold' => { 165 => 0x201 },
     1096    'digitalfilter01' => { 238 => 0x5 },
     1097    'digitalfilter02' => { 238 => 0x16 },
     1098    'digitalfilter03' => { 238 => 0x27 },
     1099    'digitalfilter04' => { 238 => 0x38 },
     1100    'digitalfilter05' => { 238 => 0x49 },
     1101    'digitalfilter06' => { 238 => 0x5a },
     1102    'digitalfilter07' => { 238 => 0x6b },
     1103    'digitalfilter08' => { 238 => 0x7c },
     1104    'digitalfilter09' => { 238 => 0x8d },
     1105    'digitalfilter10' => { 238 => 0x9e },
     1106    'digitalfilter11' => { 238 => 0xaf },
     1107    'digitalfilter12' => { 238 => 0xc0 },
     1108    'digitalfilter13' => { 238 => 0xd1 },
     1109    'digitalfilter14' => { 238 => 0xe2 },
     1110    'digitalfilter15' => { 238 => 0xf3 },
     1111    'digitalfilter16' => { 238 => 0x104 },
     1112    'digitalfilter17' => { 238 => 0x115 },
     1113    'digitalfilter18' => { 238 => 0x126 },
     1114    'digitalfilter19' => { 238 => 0x137 },
     1115    'digitalfilter20' => { 238 => 0x148 },
     1116    'digitalgain' => { 52 => 0xb },
     1117    'digitalgem' => { 155 => 0x0 },
     1118    'digitalice' => { 165 => 0x100 },
     1119    'digitalimageguid' => { 294 => 'DigImageGUID' },
     1120    'digitalroc' => { 164 => 0x0 },
     1121    'digitalsourcefiletype' => { 294 => 'DigitalSourcefileType' },
     1122    'digitalsourcetype' => { 294 => 'DigitalSourceType' },
     1123    'digitalzoom' => { 24 => 0xc, 81 => 0xa, 99 => 0x68, 113 => 'DigitalZoom', 131 => 0xc, 160 => 0x86, 180 => 0xa, 209 => 0x204, 247 => 0x1e, 252 => 0xa, 269 => 0x204 },
     1124    'digitalzoomon' => { 269 => 0x21b },
     1125    'digitalzoomratio' => { 85 => 0xa404, 292 => 'DigitalZoomRatio' },
     1126    'director' => { 310 => 'director' },
     1127    'directorphotography' => { 310 => 'directorPhotography' },
     1128    'directory' => { 86 => 'Directory' },
     1129    '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 },
     1130    'directorynumber' => { 151 => 0x6 },
     1131    'disclaimer' => { 215 => 'Disclaimer' },
     1132    'displayallafpoints' => { 59 => 0x514 },
     1133    'displayaperture' => { 24 => 0x23 },
     1134    'displayedunitsx' => { 257 => 0x2 },
     1135    'displayedunitsy' => { 257 => 0x6 },
     1136    'distance1' => { 99 => 0x28 },
     1137    'distance2' => { 99 => 0x2c },
     1138    'distance3' => { 99 => 0x30 },
     1139    'distance4' => { 99 => 0x34 },
     1140    'distortioncontrol' => { 166 => 0x10 },
     1141    'distortioncorrection' => { 78 => 0x67, 204 => 0x50b, 240 => 0x0 },
     1142    'distortioncorrection2' => { 208 => 0x1011 },
     1143    'distortioncorrectionon' => { 78 => 0x63 },
     1144    'distributor' => { 301 => 'distributor' },
     1145    'dmcomment' => { 310 => 'comment' },
     1146    'dngbackwardversion' => { 85 => 0xc613 },
     1147    'dnglensinfo' => { 85 => 0xc630 },
     1148    'dngversion' => { 85 => 0xc612 },
     1149    'document' => { 215 => 'Document' },
     1150    'documentancestorid' => { 299 => [\'DocumentAncestors','DocumentAncestorsAncestorID'] },
     1151    'documentancestors' => { 299 => 'DocumentAncestors' },
     1152    'documenthistory' => { 92 => 0xe7 },
     1153    'documentid' => { 311 => 'DocumentID' },
     1154    'documentname' => { 85 => 0x10d },
     1155    'documentnotes' => { 92 => 0xe6 },
     1156    'doi' => { 301 => 'doi' },
     1157    'dotrange' => { 85 => 0x150 },
     1158    'drivemode' => { 82 => 0x3103, 131 => 0x6, 134 => 0x1e, 204 => 0x600, 247 => 0x34, 270 => 0x3, 271 => 0x4 },
     1159    'drivemode2' => { 134 => 0xa, 232 => 0x7 },
     1160    'dspfirmwareversion' => { 247 => 0x27 },
     1161    'duration' => { 46 => 0x6a, 112 => 'Duration', 126 => 'Duration', 310 => 'duration' },
     1162    'durationscale' => { 310 => [\'duration','durationScale'] },
     1163    'durationvalue' => { 310 => [\'duration','durationValue'] },
     1164    'dustremovaldata' => { 43 => 0x97 },
     1165    'dynamicafarea' => { 197 => '1.4', 200 => '1.4' },
     1166    'dynamicrange' => { 89 => 0x1400 },
     1167    'dynamicrangeexpansion' => { 247 => 0x69 },
     1168    'dynamicrangemax' => { 77 => 0x7c },
     1169    'dynamicrangemin' => { 77 => 0x7a },
     1170    'dynamicrangeoptimizer' => { 134 => 0x15, 276 => [0xb025,0xb04f] },
     1171    'dynamicrangeoptimizerlevel' => { 271 => 0x19, 272 => 0x17 },
     1172    'dynamicrangeoptimizermode' => { 271 => 0x18, 272 => 0x16 },
     1173    'dynamicrangeoptimizersetting' => { 134 => 0x27 },
     1174    'dynamicrangesetting' => { 89 => 0x1402 },
     1175    'e-dialinprogram' => { 232 => '1.3' },
     1176    'easyexposurecomp' => { 203 => '6.1' },
     1177    'easyexposurecompensation' => { 197 => '6.4', 200 => '4.4', 201 => '5.2' },
     1178    'easymode' => { 24 => 0xb },
     1179    'edgenoisereduction' => { 191 => 0x4, 279 => 0x8028 },
     1180    'edition' => { 301 => 'edition' },
     1181    'editorialupdate' => { 92 => 0x8 },
     1182    'editstatus' => { 92 => 0x7, 254 => 'EditStatus' },
     1183    'editversionname' => { 190 => 0x3d136244 },
     1184    'effectivelv' => { 247 => 0x2d },
     1185    'effectivemaxaperture' => { 158 => 0x12, 159 => 0x13 },
     1186    'eissn' => { 301 => 'eIssn' },
     1187    'elevation' => { 122 => 'Elevation' },
     1188    'email' => { 114 => 'EMail' },
     1189    'embargodate' => { 301 => 'embargoDate', 303 => 'embargoDate' },
     1190    'encryptionkey' => { 267 => 0xa020 },
     1191    'endingpage' => { 301 => 'endingPage' },
     1192    'enduser' => { 300 => 'EndUser' },
     1193    'enduserid' => { 300 => [\'EndUser','EndUserEndUserID'] },
     1194    'endusername' => { 300 => [\'EndUser','EndUserEndUserName'] },
     1195    'engineer' => { 310 => 'engineer' },
     1196    'enhancedarktones' => { 183 => 0x8 },
     1197    'enhancement' => { 81 => 0x16, 82 => 0x3016 },
     1198    'enhancer' => { 208 => 0x300 },
     1199    'enhancervalues' => { 208 => 0x301 },
     1200    'envelopenumber' => { 93 => 0x28 },
     1201    'envelopepriority' => { 93 => 0x3c },
     1202    'enveloperecordversion' => { 93 => 0x0 },
     1203    'epsonimageheight' => { 209 => 0x20c },
     1204    'epsonimagewidth' => { 209 => 0x20b },
     1205    'epsonsoftware' => { 209 => 0x20d },
     1206    'equipmentinstitution' => { 281 => 'EquipmentInstitution' },
     1207    'equipmentmanufacturer' => { 281 => 'EquipmentManufacturer' },
     1208    'equipmentversion' => { 205 => 0x0 },
     1209    'ettlii' => { 59 => 0x304, 60 => 0xd, 61 => 0xe, 62 => 0x7, 63 => 0x7, 64 => 0xe },
     1210    'event' => { 283 => 'Event', 294 => 'Event', 301 => 'event' },
     1211    'eventnumber' => { 259 => 0x9 },
     1212    'evsteps' => { 232 => '1.2', 234 => 0x0 },
     1213    'evstepsize' => { 199 => '5.1', 202 => '0.7' },
     1214    'exclusivityenddate' => { 303 => 'exclusivityEndDate' },
     1215    'excursiontolerance' => { 94 => 0x82 },
     1216    'exif' => { 86 => 'EXIF' },
     1217    'exifbyteorder' => { 86 => 'ExifByteOrder' },
     1218    'exifcamerainfo' => { 92 => 0xe8 },
     1219    'exifimageheight' => { 85 => 0xa003, 292 => 'PixelYDimension' },
     1220    'exifimagewidth' => { 85 => 0xa002, 292 => 'PixelXDimension' },
     1221    'exifunicodebyteorder' => { 86 => 'ExifUnicodeByteOrder' },
     1222    'exifversion' => { 85 => 0x9000, 292 => 'ExifVersion' },
     1223    'exitpupilposition' => { 158 => 0x4, 159 => 0x4 },
     1224    'expirationdate' => { 92 => 0x25, 301 => 'expirationDate', 303 => 'expirationDate' },
     1225    'expirationtime' => { 92 => 0x26 },
     1226    'exposure' => { 85 => 0xfe51, 288 => 'Exposure' },
     1227    'exposureadj' => { 188 => 0x0 },
     1228    'exposureadj2' => { 188 => 0x12 },
     1229    'exposureadjust' => { 270 => 0xc },
     1230    'exposurebracketingindicatorlast' => { 134 => 0x52 },
     1231    'exposurebracketstepsize' => { 232 => 0x8 },
     1232    'exposurebracketvalue' => { 160 => 0x19 },
     1233    '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' },
     1234    'exposurecompensationmode' => { 134 => 0x47 },
     1235    'exposurecompensationsetting' => { 134 => 0x1 },
     1236    'exposurecompstepsize' => { 197 => '6.3', 200 => '4.3' },
     1237    'exposurecontrolstep' => { 201 => '6.1' },
     1238    'exposurecontrolstepsize' => { 197 => '6.2', 200 => '4.2', 203 => '7.1' },
     1239    'exposuredelaymode' => { 197 => '10.1', 199 => '9.1', 200 => '10.4', 201 => '10.1', 202 => '6.4', 203 => '11.2' },
     1240    'exposuredifference' => { 160 => 0xe },
     1241    'exposureindex' => { 85 => 0xa215, 292 => 'ExposureIndex' },
     1242    'exposureindicator' => { 134 => 0x50 },
     1243    'exposurelevelincrements' => { 57 => 0x6, 58 => 0x6, 59 => 0x101, 60 => 0x5, 61 => 0x6, 62 => 0x5, 63 => 0x5, 64 => 0x6, 65 => 0x4, 271 => 0x58 },
     1244    'exposuremode' => { 85 => 0xa402, 113 => 'ExposureMode', 131 => 0x1, 132 => 0xa, 133 => 0x0, 134 => 0x0, 204 => 0x200, 221 => 0x40d, 270 => 0x8, 276 => 0xb041, 292 => 'ExposureMode' },
     1245    'exposuremodeinmanual' => { 59 => 0x10b },
     1246    'exposureprogram' => { 85 => 0x8822, 271 => 0x3c, 272 => 0x3c, 292 => 'ExposureProgram' },
     1247    'exposureshift' => { 204 => 0x203 },
     1248    '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' },
     1249    'exposuretime2' => { 270 => 0x33 },
     1250    'exposuretuning' => { 160 => 0x1c },
     1251    'exposurevalue' => { 97 => 0x3 },
     1252    'exposurewarning' => { 89 => 0x1302 },
     1253    'exrauto' => { 89 => 0x1033 },
     1254    'exrmode' => { 89 => 0x1034 },
     1255    'extendedwbdetect' => { 204 => 0x902 },
     1256    'extender' => { 205 => 0x301 },
     1257    'extenderfirmwareversion' => { 205 => 0x304 },
     1258    'extendermagnification' => { 115 => 'Magnification' },
     1259    'extendermake' => { 115 => 'Make' },
     1260    'extendermodel' => { 115 => 'Model', 205 => 0x303 },
     1261    'extenderserialnumber' => { 115 => 'SerialNumber', 205 => 0x302 },
     1262    'externalflash' => { 207 => 0x1201 },
     1263    'externalflashae1' => { 209 => 0x101f },
     1264    'externalflashae1_0' => { 209 => 0x101b },
     1265    'externalflashae2' => { 209 => 0x1020 },
     1266    'externalflashae2_0' => { 209 => 0x101c },
     1267    'externalflashbounce' => { 207 => 0x1204, 209 => 0x1026, 239 => 0x1a },
     1268    'externalflashexposurecomp' => { 160 => 0x17, 239 => 0x19 },
     1269    'externalflashfirmware' => { 152 => 0x6, 153 => 0x6, 154 => 0x6 },
     1270    'externalflashflags' => { 152 => 0x8, 153 => 0x8, 154 => 0x8 },
     1271    'externalflashguidenumber' => { 207 => 0x1203, 239 => '24.1' },
     1272    'externalflashgvalue' => { 209 => 0x1025 },
     1273    'externalflashmode' => { 209 => 0x1028, 239 => 0x2 },
     1274    'externalflashzoom' => { 207 => 0x1205, 209 => 0x1027 },
     1275    'externalsensorbrightnessvalue' => { 219 => 0x311, 225 => 0x3408 },
     1276    'eyestartaf' => { 134 => 0x40 },
     1277    'face10position' => { 79 => 0x3f4, 80 => 0x1ec, 150 => 0x28, 236 => 0x12 },
     1278    'face10size' => { 237 => 0x12 },
     1279    'face11position' => { 150 => 0x2c, 236 => 0x14 },
     1280    'face11size' => { 237 => 0x14 },
     1281    'face12position' => { 150 => 0x30, 236 => 0x16 },
     1282    'face12size' => { 237 => 0x16 },
     1283    'face13position' => { 236 => 0x18 },
     1284    'face13size' => { 237 => 0x18 },
     1285    'face14position' => { 236 => 0x1a },
     1286    'face14size' => { 237 => 0x1a },
     1287    'face15position' => { 236 => 0x1c },
     1288    'face15size' => { 237 => 0x1c },
     1289    'face16position' => { 236 => 0x1e },
     1290    'face16size' => { 237 => 0x1e },
     1291    'face17position' => { 236 => 0x20 },
     1292    'face17size' => { 237 => 0x20 },
     1293    'face18position' => { 236 => 0x22 },
     1294    'face18size' => { 237 => 0x22 },
     1295    'face19position' => { 236 => 0x24 },
     1296    'face19size' => { 237 => 0x24 },
     1297    'face1position' => { 36 => 0x8, 79 => 0xd, 80 => 0x18, 150 => 0x4, 217 => 0x1, 236 => 0x0, 260 => 0xbc, 274 => 0x0, 275 => 0x0 },
     1298    'face1size' => { 237 => 0x0 },
     1299    'face20position' => { 236 => 0x26 },
     1300    'face20size' => { 237 => 0x26 },
     1301    'face21position' => { 236 => 0x28 },
     1302    'face21size' => { 237 => 0x28 },
     1303    'face22position' => { 236 => 0x2a },
     1304    'face22size' => { 237 => 0x2a },
     1305    'face23position' => { 236 => 0x2c },
     1306    'face23size' => { 237 => 0x2c },
     1307    'face24position' => { 236 => 0x2e },
     1308    'face24size' => { 237 => 0x2e },
     1309    'face25position' => { 236 => 0x30 },
     1310    'face25size' => { 237 => 0x30 },
     1311    'face26position' => { 236 => 0x32 },
     1312    'face26size' => { 237 => 0x32 },
     1313    'face27position' => { 236 => 0x34 },
     1314    'face27size' => { 237 => 0x34 },
     1315    'face28position' => { 236 => 0x36 },
     1316    'face28size' => { 237 => 0x36 },
     1317    'face29position' => { 236 => 0x38 },
     1318    'face29size' => { 237 => 0x38 },
     1319    'face2position' => { 36 => 0xa, 79 => 0x7c, 80 => 0x4c, 150 => 0x8, 217 => 0x5, 236 => 0x2, 260 => 0xc8, 274 => 0x20, 275 => 0x25 },
     1320    'face2size' => { 237 => 0x2 },
     1321    'face30position' => { 236 => 0x3a },
     1322    'face30size' => { 237 => 0x3a },
     1323    'face31position' => { 236 => 0x3c },
     1324    'face31size' => { 237 => 0x3c },
     1325    'face32position' => { 236 => 0x3e },
     1326    'face32size' => { 237 => 0x3e },
     1327    'face3position' => { 36 => 0xc, 79 => 0xeb, 80 => 0x80, 150 => 0xc, 217 => 0x9, 236 => 0x4, 260 => 0xd4, 274 => 0x40, 275 => 0x4a },
     1328    'face3size' => { 237 => 0x4 },
     1329    'face4position' => { 36 => 0xe, 79 => 0x15a, 80 => 0xb4, 150 => 0x10, 217 => 0xd, 236 => 0x6, 260 => 0xe0, 274 => 0x60, 275 => 0x6f },
     1330    'face4size' => { 237 => 0x6 },
     1331    'face5position' => { 36 => 0x10, 79 => 0x1c9, 80 => 0xe8, 150 => 0x14, 217 => 0x11, 236 => 0x8, 260 => 0xec, 274 => 0x80, 275 => 0x94 },
     1332    'face5size' => { 237 => 0x8 },
     1333    'face6position' => { 36 => 0x12, 79 => 0x238, 80 => 0x11c, 150 => 0x18, 236 => 0xa, 260 => 0xf8, 274 => 0xa0, 275 => 0xb9 },
     1334    'face6size' => { 237 => 0xa },
     1335    'face7position' => { 36 => 0x14, 79 => 0x2a7, 80 => 0x150, 150 => 0x1c, 236 => 0xc, 260 => 0x104, 274 => 0xc0, 275 => 0xde },
     1336    'face7size' => { 237 => 0xc },
     1337    'face8position' => { 36 => 0x16, 79 => 0x316, 80 => 0x184, 150 => 0x20, 236 => 0xe, 260 => 0x110, 274 => 0xe0, 275 => 0x103 },
     1338    'face8size' => { 237 => 0xe },
     1339    'face9position' => { 36 => 0x18, 79 => 0x385, 80 => 0x1b8, 150 => 0x24, 236 => 0x10 },
     1340    'face9size' => { 237 => 0x10 },
     1341    'facedetect' => { 247 => 0x76 },
     1342    'facedetectarea' => { 208 => 0x1201 },
     1343    'facedetectframecrop' => { 208 => 0x1207 },
     1344    'facedetectframesize' => { 36 => 0x3, 79 => 0x1, 80 => 0x4, 150 => 0x1, 208 => 0x1203, 247 => 0x77, 260 => 0xb6 },
     1345    'faceinfounknown' => { 82 => 0x2089 },
     1346    'faceorientation' => { 80 => 0x8 },
     1347    'faceposition' => { 235 => 0x2, 268 => 0x4 },
     1348    'facepositions' => { 89 => 0x4103 },
     1349    '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 },
     1350    'facesrecognized' => { 218 => 0x0 },
     1351    'facewidth' => { 37 => 0x1 },
     1352    'faithfuloutputhighlightpoint' => { 78 => 0x38 },
     1353    'faithfuloutputshadowpoint' => { 78 => 0x39 },
     1354    'faithfulrawcolortone' => { 78 => 0x31 },
     1355    'faithfulrawcontrast' => { 78 => 0x33 },
     1356    'faithfulrawhighlight' => { 78 => 0x79 },
     1357    'faithfulrawhighlightpoint' => { 78 => 0x36 },
     1358    'faithfulrawlinear' => { 78 => 0x34 },
     1359    'faithfulrawsaturation' => { 78 => 0x32 },
     1360    'faithfulrawshadow' => { 78 => 0x82 },
     1361    'faithfulrawshadowpoint' => { 78 => 0x37 },
     1362    'faithfulrawsharpness' => { 78 => 0x35 },
     1363    'femicroadjustment' => { 59 => 0x110 },
     1364    'ffid' => { 290 => 'ffid' },
     1365    'fieldcount' => { 209 => 0x103f },
     1366    'filedatarate' => { 310 => 'fileDataRate' },
     1367    'fileformat' => { 70 => 0x0, 93 => 0x14, 270 => 0x22, 276 => 0xb000 },
     1368    '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 },
     1369    'filemodifydate' => { 86 => 'FileModifyDate' },
     1370    'filename' => { 86 => 'FileName' },
     1371    'filenameasdelivered' => { 300 => 'FileNameAsDelivered' },
     1372    'filenumber' => { 38 => 0x1, 43 => 0x8, 72 => 0x1817, 83 => 'FileNumber', 151 => 0x8 },
     1373    'filenumbermemory' => { 131 => 0x1a },
     1374    'filenumbersequence' => { 197 => '12.2', 199 => '3.1', 200 => '11.1', 201 => '4.3', 203 => '5.2' },
     1375    'filesource' => { 85 => 0xa300, 89 => 0x8000, 292 => 'FileSource' },
     1376    'fileversion' => { 93 => 0x16 },
     1377    'fillflashautoreduction' => { 57 => 0xe, 58 => 0xe, 65 => 0xa },
     1378    'filllight' => { 288 => 'FillLight' },
     1379    'fillorder' => { 85 => 0x10a },
     1380    'filmmode' => { 89 => 0x1401, 221 => 0x412, 224 => 0x42 },
     1381    'filmtype' => { 165 => 0x2 },
     1382    'filtereffect' => { 38 => 0xe, 162 => 0x37 },
     1383    'filtereffectfaithful' => { 48 => 0x70, 49 => 0x70 },
     1384    'filtereffectlandscape' => { 48 => 0x40, 49 => 0x40 },
     1385    'filtereffectmonochrome' => { 15 => 0xff, 48 => 0x88, 49 => 0x88 },
     1386    'filtereffectneutral' => { 48 => 0x58, 49 => 0x58 },
     1387    'filtereffectportrait' => { 48 => 0x28, 49 => 0x28 },
     1388    'filtereffectstandard' => { 48 => 0x10, 49 => 0x10 },
     1389    'filtereffectunknown' => { 49 => 0xa0 },
     1390    'filtereffectuserdef1' => { 48 => 0xa0, 49 => 0xb8 },
     1391    'filtereffectuserdef2' => { 48 => 0xb8, 49 => 0xd0 },
     1392    'filtereffectuserdef3' => { 48 => 0xd0, 49 => 0xe8 },
     1393    'finderdisplayduringexposure' => { 58 => 0x1 },
     1394    'finesharpness' => { 247 => 0x70 },
     1395    'finetuneoptcenterweighted' => { 197 => '7.2', 203 => '9.1' },
     1396    'finetuneoptmatrixmetering' => { 197 => '8.1', 200 => '6.1', 203 => '8.2' },
     1397    'finetuneoptspotmetering' => { 197 => '8.2', 200 => '6.2', 203 => '9.2' },
     1398    'firmware' => { 209 => 0x405, 270 => [0x17,0x3b], 285 => 'Firmware' },
     1399    'firmwaredate' => { 81 => 0x15, 82 => 0x2001, 259 => 0x4 },
     1400    'firmwareid' => { 137 => 0x0 },
     1401    'firmwarename' => { 267 => 0xa001 },
     1402    'firmwarerevision' => { 15 => 0xa4, 43 => 0x1e, 261 => 0x0 },
     1403    'firmwarerevision2' => { 261 => 0xc },
     1404    'firmwareversion' => { 4 => 0x10b, 7 => 0x136, 10 => 0xff, 11 => 0x107, 97 => 0xce5, 111 => 0x57, 113 => 'FirmwareVersion', 224 => 0x2, 225 => 0x3109, 247 => 0x230, 263 => 0x2 },
     1405    'firstpublicationdate' => { 300 => 'FirstPublicationDate' },
     1406    'fixtureidentifier' => { 92 => 0x16 },
     1407    'flash' => { 85 => 0x9209, 132 => 0x1f, 133 => 0x15, 292 => 'Flash' },
     1408    'flashactivity' => { 24 => 0x1c },
     1409    'flashbatterylevel' => { 30 => 0x249 },
     1410    'flashbias' => { 224 => 0x24 },
     1411    'flashbits' => { 24 => 0x1d },
     1412    'flashchargelevel' => { 209 => 0x1010 },
     1413    'flashcolorfilter' => { 154 => 0x10 },
     1414    'flashcommandermode' => { 152 => '9.1', 153 => '9.1', 154 => '9.1' },
     1415    'flashcompensation' => { 152 => 0xa, 153 => 0xa, 154 => 0xa, 285 => 'FlashCompensation' },
     1416    'flashcontrolbuilt-in' => { 200 => '16.1', 201 => '23.1' },
     1417    'flashcontrolmode' => { 152 => '9.2', 153 => '9.2', 154 => '9.2', 204 => 0x404 },
     1418    'flashdefault' => { 134 => 0x42 },
     1419    'flashdevice' => { 209 => 0x1005 },
     1420    'flashdistance' => { 82 => 0x2034 },
     1421    'flashenergy' => { 85 => 0xa20b, 292 => 'FlashEnergy' },
     1422    'flashexposurebracketvalue' => { 160 => 0x18 },
     1423    'flashexposurecomp' => { 54 => 0xf, 89 => 0x1011, 116 => 'ExposureComp', 131 => 0x23, 135 => 0x104, 160 => 0x12, 204 => 0x401, 209 => 0x1023, 247 => 0x4d, 270 => 0x3a, 276 => 0x104 },
     1424    'flashexposurecompset' => { 227 => 0xe },
     1425    'flashexposurecompsetting' => { 134 => 0x10 },
     1426    'flashexposureindicator' => { 134 => 0x54 },
     1427    'flashexposureindicatorlast' => { 134 => 0x56 },
     1428    'flashexposureindicatornext' => { 134 => 0x55 },
     1429    'flashexposurelock' => { 38 => 0x19 },
     1430    'flashfired' => { 99 => 0x5d, 116 => 'Fired', 131 => 0x14, 178 => '590.3', 224 => 0x8007, 292 => [\'Flash','FlashFired'] },
     1431    'flashfiring' => { 59 => 0x306, 60 => 0x6, 61 => 0x7, 64 => 0x7 },
     1432    'flashfirmwareversion' => { 205 => 0x1002 },
     1433    'flashfocallength' => { 152 => 0xb, 153 => 0xc, 154 => 0xc },
     1434    'flashfunction' => { 292 => [\'Flash','FlashFunction'] },
     1435    'flashgndistance' => { 152 => 0xe, 153 => 0xf, 154 => 0xf },
     1436    'flashgroupacompensation' => { 152 => 0x11, 153 => 0x12, 154 => 0x13 },
     1437    'flashgroupacontrolmode' => { 152 => 0xf, 153 => '16.1', 154 => '17.1' },
     1438    'flashgroupaoutput' => { 152 => 0x11, 153 => 0x12, 154 => 0x13 },
     1439    'flashgroupbcompensation' => { 152 => 0x12, 153 => 0x13, 154 => 0x14 },
     1440    'flashgroupbcontrolmode' => { 152 => 0x10, 153 => '17.1', 154 => '18.1' },
     1441    'flashgroupboutput' => { 152 => 0x12, 153 => 0x13, 154 => 0x14 },
     1442    'flashgroupccompensation' => { 153 => 0x14, 154 => 0x15 },
     1443    'flashgroupccontrolmode' => { 153 => '17.2', 154 => '18.2' },
     1444    'flashgroupcoutput' => { 153 => 0x14, 154 => 0x15 },
     1445    'flashguidenumber' => { 54 => 0xd, 69 => 0x0, 116 => 'GuideNumber' },
     1446    'flashintensity' => { 81 => [0x19,0x5], 204 => 0x405 },
     1447    'flashlevel' => { 198 => 0x9, 276 => 0xb048 },
     1448    'flashmake' => { 116 => 'Make' },
     1449    'flashmanufacturer' => { 130 => 'FlashManufacturer' },
     1450    'flashmetering' => { 131 => 0x3f, 134 => 0x1c },
     1451    'flashmeteringmode' => { 4 => 0x15, 9 => 0x15, 10 => 0x15, 11 => 0x15, 12 => 0x15, 13 => 0x15, 14 => 0x15, 16 => 0x15, 19 => 0x15 },
     1452    'flashmeteringsegments' => { 247 => 0x20a },
     1453    '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'] },
     1454    'flashmodel' => { 116 => 'Model', 130 => 'FlashModel', 205 => 0x1001 },
     1455    'flashoptions' => { 232 => 0x2 },
     1456    'flashoptions2' => { 232 => 0x10 },
     1457    'flashoutput' => { 30 => 0x248, 54 => 0x21, 152 => 0xa, 153 => 0xa, 154 => 0xa },
     1458    'flashpixversion' => { 85 => 0xa000, 292 => 'FlashpixVersion' },
     1459    'flashredeyemode' => { 292 => [\'Flash','FlashRedEyeMode'] },
     1460    'flashremotecontrol' => { 204 => 0x403 },
     1461    'flashreturn' => { 292 => [\'Flash','FlashReturn'] },
     1462    'flashserialnumber' => { 116 => 'SerialNumber', 205 => 0x1003 },
     1463    'flashsetting' => { 160 => 0x8 },
     1464    'flashshutterspeed' => { 197 => '20.2', 200 => '15.2', 201 => '22.2', 202 => '7.2', 203 => '23.1' },
     1465    'flashsource' => { 152 => 0x4, 153 => 0x4, 154 => 0x4 },
     1466    'flashstatus' => { 239 => 0x0 },
     1467    'flashsyncspeed' => { 197 => '20.1', 200 => '15.1', 201 => '22.1' },
     1468    'flashsyncspeedav' => { 57 => 0x3, 59 => 0x10f, 60 => 0x2, 61 => 0x3, 62 => 0x2, 63 => 0x2, 64 => 0x3, 65 => 0x6 },
     1469    'flashthreshold' => { 69 => 0x1 },
     1470    'flashtype' => { 116 => 'Type', 134 => 0x59, 160 => 0x9, 205 => 0x1000 },
     1471    'flashwarning' => { 201 => '30.1', 202 => '7.1', 203 => '31.1', 224 => 0x62 },
     1472    'flickerreduce' => { 269 => 0x218 },
     1473    'fliphorizontal' => { 190 => 0x76a43206 },
     1474    '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' },
     1475    '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' },
     1476    'focallengthin35mmformat' => { 85 => 0xa405, 267 => 0xa01a, 292 => 'FocalLengthIn35mmFilm' },
     1477    'focalplanediagonal' => { 205 => 0x103, 209 => 0x205 },
     1478    'focalplaneresolutionunit' => { 85 => 0xa210, 292 => 'FocalPlaneResolutionUnit' },
     1479    'focalplanexresolution' => { 85 => 0xa20e, 292 => 'FocalPlaneXResolution' },
     1480    'focalplanexsize' => { 40 => 0x2 },
     1481    'focalplanexunknown' => { 40 => 0x2 },
     1482    'focalplaneyresolution' => { 85 => 0xa20f, 292 => 'FocalPlaneYResolution' },
     1483    'focalplaneysize' => { 40 => 0x3 },
     1484    'focalplaneyunknown' => { 40 => 0x3 },
     1485    'focaltype' => { 6 => 0x2d, 40 => 0x0 },
     1486    'focalunits' => { 24 => 0x19 },
     1487    'focus' => { 180 => 0x8 },
     1488    'focusarea' => { 131 => 0x31 },
     1489    'focusareaselection' => { 202 => '15.2' },
     1490    'focuscontinuous' => { 24 => 0x20 },
     1491    'focusdisplayaiservoandmf' => { 59 => 0x515 },
     1492    'focusdistance' => { 120 => 'FocusDistance', 131 => 0x13, 158 => 0x9, 159 => 0xa, 207 => 0x305 },
     1493    '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 },
     1494    '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 },
     1495    'focusholdbutton' => { 134 => 0x44 },
     1496    'focusinfoversion' => { 207 => 0x0 },
     1497    'focusingscreen' => { 58 => 0x0, 59 => 0x80b, 64 => 0x0 },
     1498    '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 },
     1499    'focusmode2' => { 232 => '3.1' },
     1500    'focusmodesetting' => { 198 => '10.1' },
     1501    'focusmodeswitch' => { 134 => 0x58 },
     1502    'focuspixel' => { 89 => 0x1023 },
     1503    'focuspointwrap' => { 197 => '2.2', 200 => '2.2', 201 => '1.2', 203 => '2.5' },
     1504    'focusposition' => { 158 => 0x8, 159 => 0x8, 247 => 0x10 },
     1505    'focusprocess' => { 204 => 0x302 },
     1506    'focusrange' => { 24 => 0x12, 209 => 0x100a },
     1507    'focussetting' => { 270 => 0x6 },
     1508    'focusstepcount' => { 207 => 0x301, 209 => 0x100e },
     1509    'focusstepinfinity' => { 207 => 0x303, 209 => 0x103b },
     1510    'focusstepnear' => { 207 => 0x304, 209 => 0x103c },
     1511    'focustrackinglockon' => { 197 => ['1.5','4.1'], 200 => '3.1', 201 => '0.4' },
     1512    'focuswarning' => { 89 => 0x1301 },
     1513    'foldername' => { 131 => 0x27 },
     1514    'fontcomposite' => { 315 => [\'Fonts','FontsComposite'] },
     1515    'fontface' => { 315 => [\'Fonts','FontsFontFace'] },
     1516    'fontfamily' => { 315 => [\'Fonts','FontsFontFamily'] },
     1517    'fontfilename' => { 315 => [\'Fonts','FontsFontFileName'] },
     1518    'fontname' => { 315 => [\'Fonts','FontsFontName'] },
     1519    'fonts' => { 315 => 'Fonts' },
     1520    'fonttype' => { 315 => [\'Fonts','FontsFontType'] },
     1521    'fontversion' => { 315 => [\'Fonts','FontsVersionString'] },
     1522    'for' => { 258 => 'For' },
     1523    'format' => { 289 => 'format' },
     1524    'forwardlock' => { 305 => 'forwardlock' },
     1525    'forwardmatrix1' => { 85 => 0xc714 },
     1526    'forwardmatrix2' => { 85 => 0xc715 },
     1527    'framecount' => { 46 => [0x2,0x4] },
     1528    'framenum' => { 253 => 0xd7 },
     1529    'framenumber' => { 89 => 0x8003, 247 => 0x29 },
     1530    'framerate' => { 46 => [0x1,0x6] },
     1531    'frameselector' => { 223 => '0.1' },
     1532    'freebytes' => { 72 => 0x1 },
     1533    'freememorycardimages' => { 132 => [0x37,0x54], 133 => [0x2d,0x4a], 134 => 0x32 },
     1534    'fujiflashmode' => { 89 => 0x1010 },
     1535    'fullimagesize' => { 276 => 0xb02b },
     1536    'fullsizeimage' => { 119 => 'data' },
     1537    'fullsizeimagename' => { 119 => '1Name' },
     1538    'fullsizeimagetype' => { 119 => '0Type' },
     1539    'funcbutton' => { 197 => ['14.1','15.1'], 200 => '28.1', 201 => '13.1', 203 => '14.1' },
     1540    'funcbuttonplusdials' => { 197 => ['14.2','15.2'], 200 => '31.1' },
     1541    'functionbutton' => { 202 => '5.2' },
     1542    'gainbase' => { 208 => 0x610 },
     1543    'gaincontrol' => { 85 => 0xa407, 292 => 'GainControl' },
     1544    'gamma' => { 85 => 0xa500 },
     1545    'gammacompensatedvalue' => { 94 => 0x91 },
     1546    'geimagesize' => { 89 => 0x1304 },
     1547    'gemake' => { 90 => 0x300 },
     1548    'gemodel' => { 90 => 0x207 },
     1549    'genre' => { 301 => 'genre', 310 => 'genre' },
     1550    'geography' => { 302 => 'geography' },
     1551    'geosync' => { 86 => 'Geosync' },
     1552    'geotag' => { 86 => 'Geotag' },
     1553    'geotime' => { 86 => 'Geotime' },
     1554    'globalaltitude' => { 256 => 0x419 },
     1555    'globalangle' => { 256 => 0x40d },
     1556    'good' => { 310 => 'good' },
     1557    'gpsaltitude' => { 91 => 0x6, 117 => 'Altitude', 292 => 'GPSAltitude' },
     1558    'gpsaltituderef' => { 91 => 0x5, 292 => 'GPSAltitudeRef' },
     1559    'gpsareainformation' => { 91 => 0x1c, 292 => 'GPSAreaInformation' },
     1560    'gpsdatestamp' => { 91 => 0x1d },
     1561    'gpsdatetime' => { 117 => 'DateTime', 292 => 'GPSTimeStamp' },
     1562    'gpsdestbearing' => { 91 => 0x18, 117 => 'Bearing', 292 => 'GPSDestBearing' },
     1563    'gpsdestbearingref' => { 91 => 0x17, 292 => 'GPSDestBearingRef' },
     1564    'gpsdestdistance' => { 91 => 0x1a, 117 => 'Distance', 292 => 'GPSDestDistance' },
     1565    'gpsdestdistanceref' => { 91 => 0x19, 292 => 'GPSDestDistanceRef' },
     1566    'gpsdestlatitude' => { 91 => 0x14, 292 => 'GPSDestLatitude' },
     1567    'gpsdestlatituderef' => { 91 => 0x13 },
     1568    'gpsdestlongitude' => { 91 => 0x16, 292 => 'GPSDestLongitude' },
     1569    'gpsdestlongituderef' => { 91 => 0x15 },
     1570    'gpsdifferential' => { 91 => 0x1e, 117 => 'Differential', 292 => 'GPSDifferential' },
     1571    'gpsdop' => { 91 => 0xb, 292 => 'GPSDOP' },
     1572    'gpshpositioningerror' => { 91 => 0x1f },
     1573    'gpsimgdirection' => { 91 => 0x11, 292 => 'GPSImgDirection' },
     1574    'gpsimgdirectionref' => { 91 => 0x10, 292 => 'GPSImgDirectionRef' },
     1575    'gpslatitude' => { 91 => 0x2, 117 => 'Latitude', 292 => 'GPSLatitude' },
     1576    'gpslatituderef' => { 91 => 0x1 },
     1577    'gpslongitude' => { 91 => 0x4, 117 => 'Longitude', 292 => 'GPSLongitude' },
     1578    'gpslongituderef' => { 91 => 0x3 },
     1579    'gpsmapdatum' => { 91 => 0x12, 117 => 'Datum', 292 => 'GPSMapDatum' },
     1580    'gpsmeasuremode' => { 91 => 0xa, 117 => 'MeasureMode', 292 => 'GPSMeasureMode' },
     1581    'gpsprocessingmethod' => { 91 => 0x1b, 292 => 'GPSProcessingMethod' },
     1582    'gpssatellites' => { 91 => 0x8, 117 => 'Satellites', 292 => 'GPSSatellites' },
     1583    'gpsspeed' => { 91 => 0xd, 117 => 'Speed', 292 => 'GPSSpeed' },
     1584    'gpsspeedref' => { 91 => 0xc, 292 => 'GPSSpeedRef' },
     1585    'gpsstatus' => { 91 => 0x9, 292 => 'GPSStatus' },
     1586    'gpstimestamp' => { 91 => 0x7 },
     1587    'gpstrack' => { 91 => 0xf, 117 => 'Heading', 292 => 'GPSTrack' },
     1588    'gpstrackref' => { 91 => 0xe, 292 => 'GPSTrackRef' },
     1589    'gpsversionid' => { 91 => 0x0, 292 => 'GPSVersionID' },
     1590    'gradation' => { 204 => 0x50f },
     1591    'gradientbasedcorractive' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionActive'] },
     1592    'gradientbasedcorramount' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionAmount'] },
     1593    'gradientbasedcorrbrightness' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalBrightness'] },
     1594    'gradientbasedcorrclarity' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalClarity'] },
     1595    'gradientbasedcorrcontrast' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalContrast'] },
     1596    'gradientbasedcorrections' => { 288 => 'GradientBasedCorrections' },
     1597    'gradientbasedcorrexposure' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalExposure'] },
     1598    'gradientbasedcorrhue' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalToningHue'] },
     1599    'gradientbasedcorrmaskcenterweight' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksCenterWeight'] },
     1600    'gradientbasedcorrmaskdabs' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksDabs'] },
     1601    'gradientbasedcorrmaskflow' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFlow'] },
     1602    'gradientbasedcorrmaskfullx' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullX'] },
     1603    'gradientbasedcorrmaskfully' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullY'] },
     1604    'gradientbasedcorrmaskradius' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRadius'] },
     1605    'gradientbasedcorrmasks' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasks'] },
     1606    'gradientbasedcorrmaskvalue' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksMaskValue'] },
     1607    'gradientbasedcorrmaskwhat' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksWhat'] },
     1608    'gradientbasedcorrmaskzerox' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroX'] },
     1609    'gradientbasedcorrmaskzeroy' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroY'] },
     1610    'gradientbasedcorrsaturation' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSaturation','GradientBasedCorrectionsLocalToningSaturation'] },
     1611    'gradientbasedcorrsharpness' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSharpness'] },
     1612    'gradientbasedcorrwhat' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsWhat'] },
     1613    'grainamount' => { 288 => 'GrainAmount' },
     1614    'grainfrequency' => { 288 => 'GrainFrequency' },
     1615    'grainsize' => { 288 => 'GrainSize' },
     1616    'graymixeraqua' => { 288 => 'GrayMixerAqua' },
     1617    'graymixerblue' => { 288 => 'GrayMixerBlue' },
     1618    'graymixergreen' => { 288 => 'GrayMixerGreen' },
     1619    'graymixermagenta' => { 288 => 'GrayMixerMagenta' },
     1620    'graymixerorange' => { 288 => 'GrayMixerOrange' },
     1621    'graymixerpurple' => { 288 => 'GrayMixerPurple' },
     1622    'graymixerred' => { 288 => 'GrayMixerRed' },
     1623    'graymixeryellow' => { 288 => 'GrayMixerYellow' },
     1624    'graypoint' => { 279 => 0x8021 },
     1625    'grayresponseunit' => { 85 => 0x122 },
     1626    'greencurvelimits' => { 77 => 0x1c4 },
     1627    'greencurvepoints' => { 77 => 0x19a },
     1628    'greenhue' => { 288 => 'GreenHue' },
     1629    'greensaturation' => { 288 => 'GreenSaturation' },
     1630    'griddisplay' => { 197 => '13.3', 199 => '2.2', 200 => '10.5', 201 => '3.4', 202 => '6.1', 203 => '4.2' },
     1631    'gripbatteryadload' => { 230 => 0x5 },
     1632    'gripbatteryadnoload' => { 230 => 0x4 },
     1633    'gripbatterystate' => { 230 => '1.2' },
     1634    'halftonehints' => { 85 => 0x141 },
     1635    'hasalternative' => { 301 => 'hasAlternative' },
     1636    'hascorrection' => { 301 => 'hasCorrection' },
     1637    'hascrop' => { 288 => 'HasCrop' },
     1638    'hasextendedxmp' => { 312 => 'HasExtendedXMP' },
     1639    'haspreviousversion' => { 301 => 'hasPreviousVersion' },
     1640    'hassettings' => { 288 => 'HasSettings' },
     1641    'hastranslation' => { 301 => 'hasTranslation' },
     1642    'hdr' => { 276 => 0x200a },
     1643    'headline' => { 92 => 0x69, 299 => 'Headline' },
     1644    'hierarchicalkeywords' => { 296 => [\'Keywords','KeywordsHierarchy'] },
     1645    'hierarchicalkeywords1' => { 296 => [\'Keywords','KeywordsHierarchyKeyword'] },
     1646    'hierarchicalkeywords1applied' => { 296 => [\'Keywords','KeywordsHierarchyApplied'] },
     1647    'hierarchicalkeywords1children' => { 296 => [\'Keywords','KeywordsHierarchyChildren'] },
     1648    'hierarchicalkeywords2' => { 296 => [\'Keywords','KeywordsHierarchyChildrenKeyword'] },
     1649    'hierarchicalkeywords2applied' => { 296 => [\'Keywords','KeywordsHierarchyChildrenApplied'] },
     1650    'hierarchicalkeywords2children' => { 296 => [\'Keywords','KeywordsHierarchyChildrenChildren'] },
     1651    'hierarchicalkeywords3' => { 296 => [\'Keywords','KeywordsHierarchyChildrenChildrenKeyword'] },
     1652    'hierarchicalkeywords3applied' => { 296 => [\'Keywords','KeywordsHierarchyChildrenChildrenApplied'] },
     1653    'hierarchicalkeywords3children' => { 296 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildren'] },
     1654    'hierarchicalkeywords4' => { 296 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenKeyword'] },
     1655    'hierarchicalkeywords4applied' => { 296 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenApplied'] },
     1656    'hierarchicalsubject' => { 282 => 'hierarchicalSubject' },
     1657    'highisonoisereduction' => { 12 => 0xbc, 13 => 0xbd, 16 => 0xbd, 20 => 0xa5, 59 => 0x202, 89 => 0x100e, 160 => 0xb1, 247 => 0x71, 271 => 0x2c, 276 => 0x2009 },
     1658    'highlight' => { 270 => 0xf },
     1659    'highlightcolordistortreduct' => { 279 => 0x8026 },
     1660    'highlightprotection' => { 189 => 0x6 },
     1661    'highlightrecovery' => { 288 => 'HighlightRecovery' },
     1662    'highlighttonepriority' => { 9 => 0x7, 12 => 0x7, 13 => 0x7, 14 => 0x7, 16 => 0x7, 19 => 0x7, 59 => 0x203 },
     1663    'highlowkeyadj' => { 247 => 0x6c },
     1664    'highspeedsync' => { 134 => 0x5 },
     1665    'histogramxml' => { 190 => 0x83a1a25 },
     1666    'history' => { 299 => 'History', 311 => 'History' },
     1667    'historyaction' => { 311 => [\'History','HistoryAction'] },
     1668    'historychanged' => { 311 => [\'History','HistoryChanged'] },
     1669    'historyinstanceid' => { 311 => [\'History','HistoryInstanceID'] },
     1670    'historyparameters' => { 311 => [\'History','HistoryParameters'] },
     1671    'historysoftwareagent' => { 311 => [\'History','HistorySoftwareAgent'] },
     1672    'historywhen' => { 311 => [\'History','HistoryWhen'] },
     1673    'hometowncity' => { 82 => 0x3006, 247 => 0x23, 251 => 0x2 },
     1674    'hometowncitycode' => { 252 => 0x1000 },
     1675    'hometowndst' => { 247 => 0x25, 251 => '0.2' },
     1676    'hostcomputer' => { 85 => 0x13c },
     1677    'hue' => { 138 => 0x3b, 247 => 0x67 },
     1678    'hueadj' => { 193 => 0x2f, 279 => 0x8019 },
     1679    'hueadjustment' => { 132 => 0x4a, 133 => 0x40, 160 => 0x92, 162 => 0x36 },
     1680    'hueadjustmentaqua' => { 288 => 'HueAdjustmentAqua' },
     1681    'hueadjustmentblue' => { 288 => 'HueAdjustmentBlue' },
     1682    'hueadjustmentgreen' => { 288 => 'HueAdjustmentGreen' },
     1683    'hueadjustmentmagenta' => { 288 => 'HueAdjustmentMagenta' },
     1684    'hueadjustmentorange' => { 288 => 'HueAdjustmentOrange' },
     1685    'hueadjustmentpurple' => { 288 => 'HueAdjustmentPurple' },
     1686    'hueadjustmentred' => { 288 => 'HueAdjustmentRed' },
     1687    'hueadjustmentyellow' => { 288 => 'HueAdjustmentYellow' },
     1688    'huesetting' => { 212 => 0x1011 },
     1689    'icc_profile' => { 86 => 'ICC_Profile' },
     1690    'iccprofilename' => { 299 => 'ICCProfile' },
     1691    'idccreativestyle' => { 279 => 0x8000 },
     1692    'idcpreviewlength' => { 279 => 0x202 },
     1693    'idcpreviewstart' => { 279 => 0x201 },
     1694    'identifier' => { 289 => 'identifier', 308 => 'Identifier' },
     1695    'illumination' => { 202 => '0.5' },
     1696    'imageadjustment' => { 160 => 0x80, 180 => 0x5 },
     1697    'imagealterationconstraints' => { 300 => 'ImageAlterationConstraints' },
     1698    'imagearea' => { 170 => 0x10, 173 => 0x10 },
     1699    'imageareaoffset' => { 247 => 0x38 },
     1700    'imageauthentication' => { 160 => 0x20 },
     1701    'imageboundary' => { 160 => 0x16 },
     1702    'imagecount' => { 160 => 0xa5 },
     1703    'imagecreator' => { 300 => 'ImageCreator' },
     1704    'imagecreatorid' => { 300 => [\'ImageCreator','ImageCreatorImageCreatorID'] },
     1705    'imagecreatorimageid' => { 300 => 'ImageCreatorImageID' },
     1706    'imagecreatorname' => { 300 => [\'ImageCreator','ImageCreatorImageCreatorName'] },
     1707    'imagedatasize' => { 160 => 0xa2 },
     1708    'imagedescription' => { 85 => 0x10e, 306 => 'ImageDescription' },
     1709    'imageduplicationconstraints' => { 300 => 'ImageDuplicationConstraints' },
     1710    'imagedustoff' => { 190 => 0xfe443a45 },
     1711    'imageeditcount' => { 247 => 0x41 },
     1712    'imageediting' => { 247 => 0x32 },
     1713    'imagefileconstraints' => { 300 => 'ImageFileConstraints' },
     1714    'imagefileformatasdelivered' => { 300 => 'ImageFileFormatAsDelivered' },
     1715    'imagefilesizeasdelivered' => { 300 => 'ImageFileSizeAsDelivered' },
     1716    'imageheight' => { 85 => 0x101, 137 => 0xc, 306 => 'ImageLength' },
     1717    'imagehistory' => { 85 => 0x9213 },
     1718    'imageidnumber' => { 219 => 0x340 },
     1719    'imagenumber' => { 15 => 0xd0, 85 => 0x9211, 113 => 'ImageNumber', 132 => 0xae, 133 => 0x5e, 285 => 'ImageNumber' },
     1720    'imagenumber2' => { 133 => 0x62 },
     1721    'imageoptimization' => { 160 => 0xa9 },
     1722    'imageorientation' => { 92 => 0x83 },
     1723    'imageprocessing' => { 160 => 0x1a },
     1724    'imageprocessingversion' => { 208 => 0x0 },
     1725    'imagequality' => { 113 => 'ImageQuality', 172 => '723.2', 173 => '732.2', 178 => '708.1', 224 => 0x1 },
     1726    'imagequality2' => { 204 => 0x603 },
     1727    'imagereview' => { 198 => '0.4', 202 => '0.4' },
     1728    'imagereviewtime' => { 198 => '2.1', 199 => '19.1', 200 => '9.2', 201 => '20.1', 203 => '21.2' },
     1729    'imagesize' => { 119 => 'ImageSize' },
     1730    'imagesizerestriction' => { 303 => 'imageSizeRestriction' },
     1731    'imagesourcedata' => { 85 => 0x935c },
     1732    '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 },
     1733    'imagestyle' => { 271 => 0x2d },
     1734    'imagesupplier' => { 300 => 'ImageSupplier' },
     1735    'imagesupplierid' => { 300 => [\'ImageSupplier','ImageSupplierImageSupplierID'] },
     1736    'imagesupplierimageid' => { 300 => 'ImageSupplierImageID' },
     1737    'imagesuppliername' => { 300 => [\'ImageSupplier','ImageSupplierImageSupplierName'] },
     1738    'imagetone' => { 247 => 0x4f },
     1739    'imagetype' => { 92 => 0x82, 300 => 'ImageType' },
     1740    'imageuniqueid' => { 43 => 0x28, 85 => 0xa420, 292 => 'ImageUniqueID' },
     1741    'imagewidth' => { 85 => 0x100, 137 => 0xe, 306 => 'ImageWidth' },
     1742    'incrementaltemperature' => { 288 => 'IncrementalTemperature' },
     1743    'incrementaltint' => { 288 => 'IncrementalTint' },
     1744    'industry' => { 301 => 'industry', 302 => 'industry' },
     1745    'infobuttonwhenshooting' => { 59 => 0x409 },
     1746    'infraredilluminator' => { 259 => 0x28 },
     1747    'ingredients' => { 311 => 'Ingredients' },
     1748    'ingredientsalternatepaths' => { 311 => [\'Ingredients','IngredientsAlternatePaths'] },
     1749    'ingredientsdocumentid' => { 311 => [\'Ingredients','IngredientsDocumentID'] },
     1750    'ingredientsfilepath' => { 311 => [\'Ingredients','IngredientsFilePath'] },
     1751    'ingredientsfrompart' => { 311 => [\'Ingredients','IngredientsFromPart'] },
     1752    'ingredientsinstanceid' => { 311 => [\'Ingredients','IngredientsInstanceID'] },
     1753    'ingredientslastmodifydate' => { 311 => [\'Ingredients','IngredientsLastModifyDate'] },
     1754    'ingredientsmanager' => { 311 => [\'Ingredients','IngredientsManager'] },
     1755    'ingredientsmanagervariant' => { 311 => [\'Ingredients','IngredientsManagerVariant'] },
     1756    'ingredientsmanageto' => { 311 => [\'Ingredients','IngredientsManageTo'] },
     1757    'ingredientsmanageui' => { 311 => [\'Ingredients','IngredientsManageUI'] },
     1758    'ingredientsmaskmarkers' => { 311 => [\'Ingredients','IngredientsMaskMarkers'] },
     1759    'ingredientsoriginaldocumentid' => { 311 => [\'Ingredients','IngredientsOriginalDocumentID'] },
     1760    'ingredientspartmapping' => { 311 => [\'Ingredients','IngredientsPartMapping'] },
     1761    'ingredientsrenditionclass' => { 311 => [\'Ingredients','IngredientsRenditionClass'] },
     1762    'ingredientsrenditionparams' => { 311 => [\'Ingredients','IngredientsRenditionParams'] },
     1763    'ingredientstopart' => { 311 => [\'Ingredients','IngredientsToPart'] },
     1764    'ingredientsversionid' => { 311 => [\'Ingredients','IngredientsVersionID'] },
     1765    'initialzoomliveview' => { 197 => '4.4' },
     1766    'initialzoomsetting' => { 197 => '9.3', 200 => '27.3' },
     1767    'inkset' => { 85 => 0x14c },
     1768    'instanceid' => { 311 => 'InstanceID' },
     1769    'instantplaybacksetup' => { 134 => 0x3e },
     1770    'instantplaybacktime' => { 134 => 0x3d },
     1771    'instructions' => { 299 => 'Instructions' },
     1772    'instrument' => { 310 => 'instrument' },
     1773    'intellectualgenre' => { 293 => 'IntellectualGenre' },
     1774    'intelligentauto' => { 276 => 0xb052 },
     1775    'intelligentd-range' => { 224 => 0x79 },
     1776    'intelligentexposure' => { 224 => 0x5d },
     1777    'intelligentresolution' => { 224 => 0x70 },
     1778    'interchangecolorspace' => { 94 => 0x40 },
     1779    'internalflash' => { 131 => 0x2b, 197 => '23.1', 198 => '8.1', 199 => '22.1', 202 => '8.1', 203 => '24.1', 207 => 0x1208 },
     1780    'internalflashae1' => { 209 => 0x1021 },
     1781    'internalflashae1_0' => { 209 => 0x101d },
     1782    'internalflashae2' => { 209 => 0x1022 },
     1783    'internalflashae2_0' => { 209 => 0x101e },
     1784    'internalflashmode' => { 239 => 0x1 },
     1785    'internalflashstrength' => { 239 => 0x3 },
     1786    'internalflashtable' => { 209 => 0x1024 },
     1787    'internalserialnumber' => { 43 => 0x96, 53 => 0x9, 89 => 0x10, 136 => 0x49dc, 205 => 0x102, 224 => 0x25, 231 => 0x4, 263 => 0x5 },
     1788    'interopindex' => { 85 => 0x1 },
     1789    'interopversion' => { 85 => 0x2 },
     1790    'intervallength' => { 131 => 0x10 },
     1791    'intervalmode' => { 131 => 0x26 },
     1792    'intervalnumber' => { 131 => 0x11 },
     1793    'introtime' => { 310 => 'introTime' },
     1794    'introtimescale' => { 310 => [\'introTime','introTimeScale'] },
     1795    'introtimevalue' => { 310 => [\'introTime','introTimeValue'] },
     1796    'iptc-naa' => { 85 => 0x83bb, 226 => 0x83bb },
     1797    'iptcbitspersample' => { 94 => 0x56 },
     1798    'iptcdigest' => { 256 => 0x425 },
     1799    'iptcimageheight' => { 94 => 0x1e },
     1800    'iptcimagerotation' => { 94 => 0x66 },
     1801    'iptcimagewidth' => { 94 => 0x14 },
     1802    'iptclastedited' => { 294 => 'IptcLastEdited' },
     1803    'iptcpicturenumber' => { 94 => 0xa },
     1804    'iptcpixelheight' => { 94 => 0x32 },
     1805    'iptcpixelwidth' => { 94 => 0x28 },
     1806    'isbn' => { 301 => 'isbn' },
     1807    'iscorrectionof' => { 301 => 'isCorrectionOf' },
     1808    'iscustompicturestyle' => { 78 => 0x3 },
     1809    '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' },
     1810    'iso2' => { 156 => 0x6, 167 => 0x265, 168 => 0x25c, 169 => 0x265, 170 => 0x221, 171 => 0x25d, 172 => 0x256, 173 => 0x25d, 175 => 0x2b5, 176 => 0x265, 179 => 0x2b5 },
     1811    'isoauto' => { 232 => '14.4' },
     1812    'isoautoparameters' => { 247 => 0x7a },
     1813    'isodisplay' => { 199 => '2.3', 201 => '3.3', 203 => '4.3' },
     1814    'isoexpansion' => { 59 => 0x103, 60 => 0x7, 61 => 0x8, 64 => 0x8, 156 => 0x4 },
     1815    'isoexpansion2' => { 156 => 0xa },
     1816    'isofloor' => { 232 => 0x6 },
     1817    'isoselection' => { 160 => 0xf },
     1818    'isosensitivitystep' => { 201 => '6.2' },
     1819    '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 },
     1820    'isospeed' => { 85 => 0x8833 },
     1821    'isospeedexpansion' => { 58 => 0x3 },
     1822    'isospeedincrements' => { 59 => 0x102 },
     1823    'isospeedlatitudeyyy' => { 85 => 0x8834 },
     1824    'isospeedlatitudezzz' => { 85 => 0x8835 },
     1825    'isospeedrange' => { 59 => 0x103 },
     1826    'isostepsize' => { 197 => '6.1', 200 => '4.1' },
     1827    'isovalue' => { 209 => 0x1001 },
     1828    'issn' => { 301 => 'issn' },
     1829    'issueidentifier' => { 301 => 'issueIdentifier' },
     1830    'issuename' => { 301 => 'issueName' },
     1831    'istranslationof' => { 301 => 'isTranslationOf' },
     1832    'jobid' => { 92 => 0xb8 },
     1833    'jobref' => { 309 => 'JobRef' },
     1834    'jobrefid' => { 309 => [\'JobRef','JobRefId'] },
     1835    'jobrefname' => { 309 => [\'JobRef','JobRefName'] },
     1836    'jobrefurl' => { 309 => [\'JobRef','JobRefUrl'] },
     1837    'jpegquality' => { 6 => 0x66, 225 => 0x3034 },
     1838    'jpegsize' => { 225 => 0x303a },
     1839    'jpgfromraw' => { 72 => 0x2007, 83 => 'JpgFromRaw', 226 => 0x2e },
     1840    'jpgfromrawlength' => { 85 => [0x117,0x202] },
     1841    'jpgfromrawstart' => { 85 => [0x111,0x201] },
     1842    'jpgrecordedpixels' => { 232 => '14.1' },
     1843    'key' => { 310 => 'key' },
     1844    'keyword' => { 301 => 'keyword' },
     1845    'keywordinfo' => { 296 => 'Keywords' },
     1846    'keywords' => { 92 => 0x19, 114 => 'Keywords', 213 => 'Keywords', 258 => 'Keywords', 284 => 'keywords', 298 => 'Keywords' },
     1847    'killdate' => { 301 => 'killDate' },
     1848    'kodakimageheight' => { 96 => 0xf908, 99 => 0xe, 101 => [0xfa1e,0xfa52], 107 => 0x70 },
     1849    'kodakimagewidth' => { 96 => 0xf907, 99 => 0xc, 101 => [0xfa1d,0xfa51], 107 => 0x6c },
     1850    'kodakinfotype' => { 96 => 0xfa00 },
     1851    'kodakmaker' => { 107 => 0x8 },
     1852    'kodakmodel' => { 99 => 0x0, 107 => 0x28 },
     1853    'label' => { 215 => 'Label', 308 => 'Label' },
     1854    'landmark' => { 224 => 0x6f },
     1855    'landscapeoutputhighlightpoint' => { 78 => 0x26 },
     1856    'landscapeoutputshadowpoint' => { 78 => 0x27 },
     1857    'landscaperawcolortone' => { 78 => 0x1f },
     1858    'landscaperawcontrast' => { 78 => 0x21 },
     1859    'landscaperawhighlight' => { 78 => 0x77 },
     1860    'landscaperawhighlightpoint' => { 78 => 0x24 },
     1861    'landscaperawlinear' => { 78 => 0x22 },
     1862    'landscaperawsaturation' => { 78 => 0x20 },
     1863    'landscaperawshadow' => { 78 => 0x80 },
     1864    'landscaperawshadowpoint' => { 78 => 0x25 },
     1865    'landscaperawsharpness' => { 78 => 0x23 },
     1866    'language' => { 289 => 'language' },
     1867    'languageidentifier' => { 92 => 0x87 },
     1868    'lastfilenumber' => { 131 => 0x1b },
     1869    'lastkeywordiptc' => { 130 => 'LastKeywordIPTC' },
     1870    'lastkeywordxmp' => { 130 => 'LastKeywordXMP' },
     1871    'lasturl' => { 311 => 'LastURL' },
     1872    'lc1' => { 241 => 0x2 },
     1873    'lc10' => { 241 => 0xb },
     1874    'lc11' => { 241 => 0xc },
     1875    'lc12' => { 241 => 0xd },
     1876    'lc14' => { 241 => 0xf },
     1877    'lc15' => { 241 => 0x10 },
     1878    'lc2' => { 241 => 0x3 },
     1879    'lc3' => { 241 => 0x4 },
     1880    'lc4' => { 241 => 0x5 },
     1881    'lc5' => { 241 => 0x6 },
     1882    'lc6' => { 241 => 0x7 },
     1883    'lc7' => { 241 => 0x8 },
     1884    'lcddisplayatpoweron' => { 59 => 0x811, 63 => 0xa },
     1885    'lcddisplayreturntoshoot' => { 64 => 0x12 },
     1886    'lcdillumination' => { 197 => '17.5', 200 => '10.3', 201 => '4.2', 203 => '5.4' },
     1887    'lcdilluminationduringbulb' => { 59 => 0x408 },
     1888    'lcdpanels' => { 58 => 0x8 },
     1889    'lcheditor' => { 190 => 0x8ae85e },
     1890    'legacyiptcdigest' => { 299 => 'LegacyIPTCDigest' },
     1891    'lens' => { 85 => 0xfdea, 160 => 0x84, 285 => 'Lens' },
     1892    'lensafstopbutton' => { 57 => 0x11, 58 => 0x13, 59 => 0x506, 60 => 0x10, 61 => 0x12, 64 => 0x13, 65 => 0x9 },
     1893    'lensaperturerange' => { 270 => 0x30 },
     1894    'lensdistortionparams' => { 209 => 0x206 },
     1895    'lensdrivenoaf' => { 59 => 0x505 },
     1896    'lensfirmware' => { 264 => 0x20, 267 => 0xa004 },
     1897    'lensfirmwareversion' => { 205 => 0x204 },
     1898    'lensfocalrange' => { 270 => 0xa },
     1899    'lensfstops' => { 157 => 0x7, 158 => 0xc, 159 => 0xd, 160 => 0x8b, 241 => '0.3' },
     1900    'lensid' => { 285 => 'LensID' },
     1901    'lensidnumber' => { 157 => 0x6, 158 => 0xb, 159 => 0xc },
     1902    'lensinfo' => { 85 => 0xa432, 285 => 'LensInfo' },
     1903    'lenskind' => { 241 => 0x1 },
     1904    'lensmake' => { 85 => 0xa433, 120 => 'Make' },
     1905    'lensmanualdistortionamount' => { 288 => 'LensManualDistortionAmount' },
     1906    'lensmanufacturer' => { 130 => 'LensManufacturer' },
     1907    'lensmodel' => { 4 => 0x937, 10 => 0x92b, 11 => 0x933, 43 => 0x95, 85 => 0xa434, 120 => 'Model', 130 => 'LensModel', 205 => 0x203 },
     1908    'lensprofilechromaticaberrationscale' => { 288 => 'LensProfileChromaticAberrationScale' },
     1909    'lensprofiledigest' => { 288 => 'LensProfileDigest' },
     1910    'lensprofiledistortionscale' => { 288 => 'LensProfileDistortionScale' },
     1911    'lensprofileenable' => { 288 => 'LensProfileEnable' },
     1912    'lensprofilefilename' => { 288 => 'LensProfileFilename' },
     1913    'lensprofilename' => { 288 => 'LensProfileName' },
     1914    'lensprofilesetup' => { 288 => 'LensProfileSetup' },
     1915    'lensprofilevignettingscale' => { 288 => 'LensProfileVignettingScale' },
     1916    'lensproperties' => { 205 => 0x20b },
     1917    'lensserialnumber' => { 41 => 0x0, 85 => 0xa435, 120 => 'SerialNumber', 205 => 0x202, 224 => 0x52, 264 => 0x30 },
     1918    'lensshutterlock' => { 134 => 0x4a },
     1919    'lenstemperature' => { 209 => 0x1008 },
     1920    '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 },
     1921    'levelgaugepitch' => { 204 => 0x904 },
     1922    'levelgaugeroll' => { 204 => 0x903 },
     1923    'levelorientation' => { 246 => 0x0 },
     1924    'license' => { 286 => 'license' },
     1925    'licensee' => { 300 => 'Licensee' },
     1926    'licenseeid' => { 300 => [\'Licensee','LicenseeLicenseeID'] },
     1927    'licenseeimageid' => { 300 => 'LicenseeImageID' },
     1928    'licenseeimagenotes' => { 300 => 'LicenseeImageNotes' },
     1929    'licenseename' => { 300 => [\'Licensee','LicenseeLicenseeName'] },
     1930    'licenseenddate' => { 300 => 'LicenseEndDate' },
     1931    'licenseeprojectreference' => { 300 => 'LicenseeProjectReference' },
     1932    'licenseetransactionid' => { 300 => 'LicenseeTransactionID' },
     1933    'licenseid' => { 300 => 'LicenseID' },
     1934    'licensestartdate' => { 300 => 'LicenseStartDate' },
     1935    'licensetransactiondate' => { 300 => 'LicenseTransactionDate' },
     1936    'licensetype' => { 290 => 'licensetype' },
     1937    'licensor' => { 300 => 'Licensor' },
     1938    'licensorcity' => { 300 => [\'Licensor','LicensorLicensorCity'] },
     1939    'licensorcountry' => { 300 => [\'Licensor','LicensorLicensorCountry'] },
     1940    'licensoremail' => { 300 => [\'Licensor','LicensorLicensorEmail'] },
     1941    'licensorextendedaddress' => { 300 => [\'Licensor','LicensorLicensorExtendedAddress'] },
     1942    'licensorid' => { 300 => [\'Licensor','LicensorLicensorID'] },
     1943    'licensorimageid' => { 300 => 'LicensorImageID' },
     1944    'licensorname' => { 300 => [\'Licensor','LicensorLicensorName'] },
     1945    'licensornotes' => { 300 => 'LicensorNotes' },
     1946    'licensorpostalcode' => { 300 => [\'Licensor','LicensorLicensorPostalCode'] },
     1947    'licensorregion' => { 300 => [\'Licensor','LicensorLicensorRegion'] },
     1948    'licensorstreetaddress' => { 300 => [\'Licensor','LicensorLicensorStreetAddress'] },
     1949    'licensortelephone1' => { 300 => [\'Licensor','LicensorLicensorTelephone1'] },
     1950    'licensortelephone2' => { 300 => [\'Licensor','LicensorLicensorTelephone2'] },
     1951    'licensortelephonetype1' => { 300 => [\'Licensor','LicensorLicensorTelephoneType1'] },
     1952    'licensortelephonetype2' => { 300 => [\'Licensor','LicensorLicensorTelephoneType2'] },
     1953    'licensortransactionid' => { 300 => 'LicensorTransactionID' },
     1954    'licensorurl' => { 300 => [\'Licensor','LicensorLicensorURL'] },
     1955    'lightcondition' => { 209 => 0x1009 },
     1956    'lightingmode' => { 82 => 0x302a },
     1957    'lightreading' => { 247 => 0x15 },
     1958    'lightsource' => { 85 => 0x9208, 160 => 0x90, 212 => 0x1000, 292 => 'LightSource' },
     1959    'lightsourcespecial' => { 269 => 0x21d },
     1960    'lightswitch' => { 203 => '0.1' },
     1961    'lightvaluecenter' => { 209 => 0x103d },
     1962    'lightvalueperiphery' => { 209 => 0x103e },
     1963    'linearresponselimit' => { 85 => 0xc62e },
     1964    'linkaetoafpoint' => { 232 => '14.2' },
     1965    'liveviewaf' => { 199 => '32.1', 203 => '34.1' },
     1966    'liveviewafareamode' => { 201 => '34.1' },
     1967    'liveviewafmode' => { 201 => '34.2' },
     1968    'liveviewexposuresimulation' => { 59 => 0x810 },
     1969    'liveviewmonitorofftime' => { 201 => '20.2' },
     1970    'liveviewshooting' => { 38 => 0x13 },
     1971    'localafareapoint' => { 134 => 0xd, 271 => 0x12, 272 => 0x12 },
     1972    'localcaption' => { 92 => 0x79 },
     1973    'localizedcameramodel' => { 85 => 0xc615 },
     1974    'locallocationname' => { 267 => 0x30 },
     1975    'location' => { 224 => 0x67, 283 => 'Location', 293 => 'Location', 301 => 'location' },
     1976    'locationareacode' => { 287 => 'lac' },
     1977    'locationcreated' => { 294 => 'LocationCreated' },
     1978    'locationcreatedcity' => { 294 => [\'LocationCreated','LocationCreatedCity'] },
     1979    'locationcreatedcountrycode' => { 294 => [\'LocationCreated','LocationCreatedCountryCode'] },
     1980    'locationcreatedcountryname' => { 294 => [\'LocationCreated','LocationCreatedCountryName'] },
     1981    'locationcreatedprovincestate' => { 294 => [\'LocationCreated','LocationCreatedProvinceState'] },
     1982    'locationcreatedsublocation' => { 294 => [\'LocationCreated','LocationCreatedSublocation'] },
     1983    'locationcreatedworldregion' => { 294 => [\'LocationCreated','LocationCreatedWorldRegion'] },
     1984    'locationname' => { 267 => 0x31 },
     1985    'locationshown' => { 294 => 'LocationShown' },
     1986    'locationshowncity' => { 294 => [\'LocationShown','LocationShownCity'] },
     1987    'locationshowncountrycode' => { 294 => [\'LocationShown','LocationShownCountryCode'] },
     1988    'locationshowncountryname' => { 294 => [\'LocationShown','LocationShownCountryName'] },
     1989    'locationshownprovincestate' => { 294 => [\'LocationShown','LocationShownProvinceState'] },
     1990    'locationshownsublocation' => { 294 => [\'LocationShown','LocationShownSublocation'] },
     1991    'locationshownworldregion' => { 294 => [\'LocationShown','LocationShownWorldRegion'] },
     1992    'lockmicrophonebutton' => { 59 => 0x709 },
     1993    'logcomment' => { 310 => 'logComment' },
     1994    'longexposurenoisereduction' => { 59 => 0x201, 60 => 0x1, 61 => 0x2, 62 => 0x1, 63 => 0x1, 64 => 0x2, 65 => 0x1, 271 => 0x2b, 276 => [0xb04e,0x2008] },
     1995    'longexposurenoisereduction2' => { 38 => 0x8 },
     1996    '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 },
     1997    'loop' => { 310 => 'loop' },
     1998    'luminanceadjustmentaqua' => { 288 => 'LuminanceAdjustmentAqua' },
     1999    'luminanceadjustmentblue' => { 288 => 'LuminanceAdjustmentBlue' },
     2000    'luminanceadjustmentgreen' => { 288 => 'LuminanceAdjustmentGreen' },
     2001    'luminanceadjustmentmagenta' => { 288 => 'LuminanceAdjustmentMagenta' },
     2002    'luminanceadjustmentorange' => { 288 => 'LuminanceAdjustmentOrange' },
     2003    'luminanceadjustmentpurple' => { 288 => 'LuminanceAdjustmentPurple' },
     2004    'luminanceadjustmentred' => { 288 => 'LuminanceAdjustmentRed' },
     2005    'luminanceadjustmentyellow' => { 288 => 'LuminanceAdjustmentYellow' },
     2006    'luminancecurvelimits' => { 77 => 0x150 },
     2007    'luminancecurvepoints' => { 77 => 0x126 },
     2008    'luminancenoisereduction' => { 78 => 0x5f, 270 => 0x1b },
     2009    'luminancenoisereductioncontrast' => { 288 => 'LuminanceNoiseReductionContrast' },
     2010    'luminancenoisereductiondetail' => { 288 => 'LuminanceNoiseReductionDetail' },
     2011    'luminancenr_tiff_jpeg' => { 78 => 0x6d },
     2012    'luminancesmoothing' => { 288 => 'LuminanceSmoothing' },
     2013    'm16cversion' => { 219 => 0x333 },
     2014    'macro' => { 89 => 0x1020, 90 => 0x202, 209 => 0x202, 262 => 0x21, 269 => 0x202, 276 => 0xb040 },
     2015    'macromagnification' => { 4 => 0x1b, 7 => 0x1b, 10 => 0x1b, 11 => 0x1b, 15 => 0x1b, 16 => 0x1b, 38 => 0x10 },
     2016    'macromode' => { 24 => 0x1, 131 => 0xb, 204 => 0x300, 224 => 0x1c },
     2017    'magicfilter' => { 204 => 0x52c },
     2018    'magnifiedview' => { 61 => 0x11, 63 => 0x9 },
     2019    'maindialexposurecomp' => { 202 => '0.6' },
     2020    'make' => { 73 => 0x0, 85 => 0x10f, 113 => 'Make', 215 => 'Make', 226 => 0x10f, 306 => 'Make' },
     2021    'makernote' => { 292 => 'MakerNote' },
     2022    'makernotecanon' => { 84 => 'MakN', 85 => 0x927c },
     2023    'makernotecasio' => { 84 => 'MakN', 85 => 0x927c },
     2024    'makernotecasio2' => { 84 => 'MakN', 85 => 0x927c },
     2025    'makernotefujifilm' => { 84 => 'MakN', 85 => 0x927c },
     2026    'makernotege' => { 84 => 'MakN', 85 => 0x927c },
     2027    'makernotege2' => { 84 => 'MakN', 85 => 0x927c },
     2028    'makernotehp' => { 84 => 'MakN', 85 => 0x927c },
     2029    'makernotehp2' => { 84 => 'MakN', 85 => 0x927c },
     2030    'makernotehp4' => { 84 => 'MakN', 85 => 0x927c },
     2031    'makernotehp6' => { 84 => 'MakN', 85 => 0x927c },
     2032    'makernoteisl' => { 84 => 'MakN', 85 => 0x927c },
     2033    'makernotejvc' => { 84 => 'MakN', 85 => 0x927c },
     2034    'makernotejvctext' => { 84 => 'MakN', 85 => 0x927c },
     2035    'makernotekodak10' => { 84 => 'MakN', 85 => 0x927c },
     2036    'makernotekodak1a' => { 84 => 'MakN', 85 => 0x927c },
     2037    'makernotekodak1b' => { 84 => 'MakN', 85 => 0x927c },
     2038    'makernotekodak2' => { 84 => 'MakN', 85 => 0x927c },
     2039    'makernotekodak3' => { 84 => 'MakN', 85 => 0x927c },
     2040    'makernotekodak4' => { 84 => 'MakN', 85 => 0x927c },
     2041    'makernotekodak5' => { 84 => 'MakN', 85 => 0x927c },
     2042    'makernotekodak6a' => { 84 => 'MakN', 85 => 0x927c },
     2043    'makernotekodak6b' => { 84 => 'MakN', 85 => 0x927c },
     2044    'makernotekodak7' => { 84 => 'MakN', 85 => 0x927c },
     2045    'makernotekodak8a' => { 84 => 'MakN', 85 => 0x927c },
     2046    'makernotekodak8b' => { 84 => 'MakN', 85 => 0x927c },
     2047    'makernotekodak9' => { 84 => 'MakN', 85 => 0x927c },
     2048    'makernotekodakunknown' => { 84 => 'MakN', 85 => 0x927c },
     2049    'makernotekyocera' => { 84 => 'MakN', 85 => 0x927c },
     2050    'makernoteleica' => { 84 => 'MakN', 85 => 0x927c },
     2051    'makernoteleica2' => { 84 => 'MakN', 85 => 0x927c },
     2052    'makernoteleica3' => { 84 => 'MakN', 85 => 0x927c },
     2053    'makernoteleica4' => { 84 => 'MakN', 85 => 0x927c },
     2054    'makernoteleica5' => { 84 => 'MakN', 85 => 0x927c },
     2055    'makernoteleica6' => { 84 => 'MakN', 85 => 0x927c },
     2056    'makernoteminolta' => { 84 => 'MakN', 85 => 0x927c },
     2057    'makernoteminolta2' => { 84 => 'MakN', 85 => 0x927c },
     2058    'makernoteminolta3' => { 84 => 'MakN', 85 => 0x927c },
     2059    'makernotenikon' => { 84 => 'MakN', 85 => 0x927c },
     2060    'makernotenikon2' => { 84 => 'MakN', 85 => 0x927c },
     2061    'makernotenikon3' => { 84 => 'MakN', 85 => 0x927c },
     2062    'makernoteoffset' => { 269 => 0xff },
     2063    'makernoteolympus' => { 84 => 'MakN', 85 => 0x927c },
     2064    'makernoteolympus2' => { 84 => 'MakN', 85 => 0x927c },
     2065    'makernotepanasonic' => { 84 => 'MakN', 85 => 0x927c },
     2066    'makernotepanasonic2' => { 84 => 'MakN', 85 => 0x927c },
     2067    'makernotepentax' => { 84 => 'MakN', 85 => 0x927c },
     2068    'makernotepentax2' => { 84 => 'MakN', 85 => 0x927c },
     2069    'makernotepentax3' => { 84 => 'MakN', 85 => 0x927c },
     2070    'makernotepentax4' => { 84 => 'MakN', 85 => 0x927c },
     2071    'makernotepentax5' => { 84 => 'MakN', 85 => 0x927c },
     2072    'makernotephaseone' => { 84 => 'MakN', 85 => 0x927c },
     2073    'makernotereconyx' => { 84 => 'MakN', 85 => 0x927c },
     2074    'makernotericoh' => { 84 => 'MakN', 85 => 0x927c },
     2075    'makernotericohtext' => { 84 => 'MakN', 85 => 0x927c },
     2076    'makernotesafety' => { 85 => 0xc635 },
     2077    'makernotesamsung1a' => { 84 => 'MakN', 85 => 0x927c },
     2078    'makernotesamsung1b' => { 84 => 'MakN', 85 => 0x927c },
     2079    'makernotesamsung2' => { 84 => 'MakN', 85 => 0x927c },
     2080    'makernotesanyo' => { 84 => 'MakN', 85 => 0x927c },
     2081    'makernotesanyoc4' => { 84 => 'MakN', 85 => 0x927c },
     2082    'makernotesanyopatch' => { 84 => 'MakN', 85 => 0x927c },
     2083    'makernotesigma' => { 84 => 'MakN', 85 => 0x927c },
     2084    'makernotesony' => { 84 => 'MakN', 85 => 0x927c },
     2085    'makernotesony2' => { 84 => 'MakN', 85 => 0x927c },
     2086    'makernotesony3' => { 84 => 'MakN', 85 => 0x927c },
     2087    'makernotesony4' => { 84 => 'MakN', 85 => 0x927c },
     2088    'makernotesonyericsson' => { 84 => 'MakN', 85 => 0x927c },
     2089    'makernotesonysrf' => { 84 => 'MakN', 85 => 0x927c },
     2090    'makernotetype' => { 263 => 0x1 },
     2091    'makernoteunknown' => { 84 => 'MakN', 85 => 0x927c },
     2092    'makernoteunknowntext' => { 84 => 'MakN', 85 => 0x927c },
     2093    'makernoteversion' => { 135 => 0x0, 160 => 0x1, 209 => 0x0, 224 => 0x8000, 266 => 0x0, 267 => 0x1, 270 => 0x1d, 273 => 0x2000 },
     2094    'managedfrom' => { 311 => 'ManagedFrom' },
     2095    'managedfromalternatepaths' => { 311 => [\'ManagedFrom','ManagedFromAlternatePaths'] },
     2096    'managedfromdocumentid' => { 311 => [\'ManagedFrom','ManagedFromDocumentID'] },
     2097    'managedfromfilepath' => { 311 => [\'ManagedFrom','ManagedFromFilePath'] },
     2098    'managedfromfrompart' => { 311 => [\'ManagedFrom','ManagedFromFromPart'] },
     2099    'managedfrominstanceid' => { 311 => [\'ManagedFrom','ManagedFromInstanceID'] },
     2100    'managedfromlastmodifydate' => { 311 => [\'ManagedFrom','ManagedFromLastModifyDate'] },
     2101    'managedfrommanager' => { 311 => [\'ManagedFrom','ManagedFromManager'] },
     2102    'managedfrommanagervariant' => { 311 => [\'ManagedFrom','ManagedFromManagerVariant'] },
     2103    'managedfrommanageto' => { 311 => [\'ManagedFrom','ManagedFromManageTo'] },
     2104    'managedfrommanageui' => { 311 => [\'ManagedFrom','ManagedFromManageUI'] },
     2105    'managedfrommaskmarkers' => { 311 => [\'ManagedFrom','ManagedFromMaskMarkers'] },
     2106    'managedfromoriginaldocumentid' => { 311 => [\'ManagedFrom','ManagedFromOriginalDocumentID'] },
     2107    'managedfrompartmapping' => { 311 => [\'ManagedFrom','ManagedFromPartMapping'] },
     2108    'managedfromrenditionclass' => { 311 => [\'ManagedFrom','ManagedFromRenditionClass'] },
     2109    'managedfromrenditionparams' => { 311 => [\'ManagedFrom','ManagedFromRenditionParams'] },
     2110    'managedfromtopart' => { 311 => [\'ManagedFrom','ManagedFromToPart'] },
     2111    'managedfromversionid' => { 311 => [\'ManagedFrom','ManagedFromVersionID'] },
     2112    'manager' => { 311 => 'Manager' },
     2113    'managervariant' => { 311 => 'ManagerVariant' },
     2114    'manageto' => { 311 => 'ManageTo' },
     2115    'manageui' => { 311 => 'ManageUI' },
     2116    'manifest' => { 311 => 'Manifest' },
     2117    'manifestlinkform' => { 311 => [\'Manifest','ManifestLinkForm'] },
     2118    'manifestplacedresolutionunit' => { 311 => [\'Manifest','ManifestPlacedResolutionUnit'] },
     2119    'manifestplacedxresolution' => { 311 => [\'Manifest','ManifestPlacedXResolution'] },
     2120    'manifestplacedyresolution' => { 311 => [\'Manifest','ManifestPlacedYResolution'] },
     2121    'manifestreference' => { 311 => [\'Manifest','ManifestReference'] },
     2122    'manifestreferencealternatepaths' => { 311 => [\'Manifest','ManifestReferenceAlternatePaths'] },
     2123    'manifestreferencedocumentid' => { 311 => [\'Manifest','ManifestReferenceDocumentID'] },
     2124    'manifestreferencefilepath' => { 311 => [\'Manifest','ManifestReferenceFilePath'] },
     2125    'manifestreferencefrompart' => { 311 => [\'Manifest','ManifestReferenceFromPart'] },
     2126    'manifestreferenceinstanceid' => { 311 => [\'Manifest','ManifestReferenceInstanceID'] },
     2127    'manifestreferencelastmodifydate' => { 311 => [\'Manifest','ManifestReferenceLastModifyDate'] },
     2128    'manifestreferencemanager' => { 311 => [\'Manifest','ManifestReferenceManager'] },
     2129    'manifestreferencemanagervariant' => { 311 => [\'Manifest','ManifestReferenceManagerVariant'] },
     2130    'manifestreferencemanageto' => { 311 => [\'Manifest','ManifestReferenceManageTo'] },
     2131    'manifestreferencemanageui' => { 311 => [\'Manifest','ManifestReferenceManageUI'] },
     2132    'manifestreferencemaskmarkers' => { 311 => [\'Manifest','ManifestReferenceMaskMarkers'] },
     2133    'manifestreferenceoriginaldocumentid' => { 311 => [\'Manifest','ManifestReferenceOriginalDocumentID'] },
     2134    'manifestreferencepartmapping' => { 311 => [\'Manifest','ManifestReferencePartMapping'] },
     2135    'manifestreferencerenditionclass' => { 311 => [\'Manifest','ManifestReferenceRenditionClass'] },
     2136    'manifestreferencerenditionparams' => { 311 => [\'Manifest','ManifestReferenceRenditionParams'] },
     2137    'manifestreferencetopart' => { 311 => [\'Manifest','ManifestReferenceToPart'] },
     2138    'manifestreferenceversionid' => { 311 => [\'Manifest','ManifestReferenceVersionID'] },
     2139    'manometerpressure' => { 204 => 0x900 },
     2140    'manometerreading' => { 204 => 0x901 },
     2141    'manualafpointselectpattern' => { 59 => 0x513 },
     2142    'manualexposuretime' => { 134 => 0x6 },
     2143    'manualflash' => { 207 => 0x1209 },
     2144    'manualflashoutput' => { 24 => 0x29, 198 => '8.2', 199 => '22.2', 200 => '16.2', 201 => '23.2', 202 => '8.2', 203 => '24.2' },
     2145    'manualflashstrength' => { 204 => 0x406 },
     2146    'manualfnumber' => { 134 => 0x7 },
     2147    'manualfocusdistance' => { 160 => 0x85, 209 => 0x100c, 269 => 0x223 },
     2148    'manualtv' => { 58 => 0x5, 59 => 0x705 },
     2149    'manufacturedate' => { 231 => 0x1 },
     2150    'manufacturedate1' => { 265 => 0x4 },
     2151    'manufacturedate2' => { 265 => 0x5 },
     2152    'marked' => { 298 => 'Marked', 314 => 'Marked' },
     2153    'markers' => { 310 => 'markers' },
     2154    'markerscomment' => { 310 => [\'markers','markersComment'] },
     2155    'markerscuepointparams' => { 310 => [\'markers','markersCuePointParams'] },
     2156    'markerscuepointparamskey' => { 310 => [\'markers','markersCuePointParamsKey'] },
     2157    'markerscuepointparamsvalue' => { 310 => [\'markers','markersCuePointParamsValue'] },
     2158    'markerscuepointtype' => { 310 => [\'markers','markersCuePointType'] },
     2159    'markersduration' => { 310 => [\'markers','markersDuration'] },
     2160    'markerslocation' => { 310 => [\'markers','markersLocation'] },
     2161    'markersname' => { 310 => [\'markers','markersName'] },
     2162    'markersprobability' => { 310 => [\'markers','markersProbability'] },
     2163    'markersspeaker' => { 310 => [\'markers','markersSpeaker'] },
     2164    'markersstarttime' => { 310 => [\'markers','markersStartTime'] },
     2165    'markerstarget' => { 310 => [\'markers','markersTarget'] },
     2166    'markerstype' => { 310 => [\'markers','markersType'] },
     2167    'maskedareas' => { 85 => 0xc68e },
     2168    'masterdocumentid' => { 92 => 0xb9 },
     2169    'mastergain' => { 165 => 0x50 },
     2170    'maxaperture' => { 24 => 0x1a, 103 => 0x6103, 120 => 'MaxAperture', 131 => 0x17, 241 => '14.1' },
     2171    'maxapertureatcurrentfocal' => { 205 => 0x20a },
     2172    'maxapertureatmaxfocal' => { 89 => 0x1407, 120 => 'MaxApertureAtMaxFocal', 157 => 0xb, 158 => 0x10, 159 => 0x11, 205 => 0x206 },
     2173    'maxapertureatminfocal' => { 89 => 0x1406, 157 => 0xa, 158 => 0xf, 159 => 0x10, 205 => 0x205 },
     2174    'maxaperturevalue' => { 85 => 0x9205, 292 => 'MaxApertureValue' },
     2175    'maxavailheight' => { 294 => 'MaxAvailHeight' },
     2176    'maxavailwidth' => { 294 => 'MaxAvailWidth' },
     2177    'maxcontinuousrelease' => { 197 => 0xb, 200 => 0xc, 201 => 0xb },
     2178    'maxfaces' => { 208 => 0x1202 },
     2179    'maxfocallength' => { 89 => 0x1405, 120 => 'MaxFocalLength', 157 => 0x9, 158 => 0xe, 159 => 0xf, 205 => 0x208 },
     2180    'maximumdensityrange' => { 94 => 0x8c },
     2181    'maxpagesize' => { 315 => 'MaxPageSize' },
     2182    'maxpagesizeh' => { 315 => [\'MaxPageSize','MaxPageSizeH'] },
     2183    'maxpagesizeunit' => { 315 => [\'MaxPageSize','MaxPageSizeUnit'] },
     2184    'maxpagesizew' => { 315 => [\'MaxPageSize','MaxPageSizeW'] },
     2185    'maxsamplevalue' => { 85 => 0x119 },
     2186    'maxstorage' => { 305 => 'maxstorage' },
     2187    'mb-d10batteries' => { 197 => '12.6' },
     2188    'mb-d10batterytype' => { 200 => '13.3' },
     2189    'mb-d11batterytype' => { 201 => '2.3' },
     2190    'mb-d80batteries' => { 202 => '6.5' },
     2191    'mb-d80batterytype' => { 203 => '3.2' },
     2192    'mcuversion' => { 157 => 0xc, 158 => 0x11, 159 => 0x12 },
     2193    'md5digest' => { 121 => 'zmd5' },
     2194    'measuredev' => { 19 => 0x9, 54 => 0x3, 72 => 0x1814, 113 => 'MeasuredEV' },
     2195    'measuredev2' => { 9 => 0x8, 19 => 0x8, 54 => 0x17 },
     2196    'measuredev3' => { 9 => 0x9 },
     2197    'measuredlv' => { 219 => 0x312, 225 => 0x3407 },
     2198    'measuredrggb' => { 44 => 0x1 },
     2199    'measuredrggbdata' => { 30 => 0x287 },
     2200    'mediaconstraints' => { 300 => 'MediaConstraints' },
     2201    'mediasummarycode' => { 300 => 'MediaSummaryCode' },
     2202    'menubuttondisplayposition' => { 57 => 0xb, 60 => 0xa, 61 => 0xb, 64 => 0xb },
     2203    'menubuttonreturn' => { 65 => 0xb },
     2204    'menumonitorofftime' => { 200 => '8.2', 201 => '21.1', 203 => '22.1' },
     2205    'metadatadate' => { 308 => 'MetadataDate' },
     2206    'metadatamoddate' => { 310 => 'metadataModDate' },
     2207    'metering' => { 198 => '6.1' },
     2208    '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' },
     2209    'meteringmode2' => { 232 => '2.1' },
     2210    'meteringmode3' => { 232 => '16.1' },
     2211    'meteringoffscaleindicator' => { 134 => 0x53 },
     2212    'meteringtime' => { 197 => '22.2', 198 => '3.2', 199 => '17.1', 200 => '7.3', 201 => '18.1', 202 => '3.2', 203 => '19.1' },
     2213    'mieversion' => { 121 => '0Vers' },
     2214    'minaperture' => { 24 => 0x1b, 120 => 'MinAperture', 241 => '0.2' },
     2215    'minfocallength' => { 89 => 0x1404, 120 => 'MinFocalLength', 157 => 0x8, 158 => 0xd, 159 => 0xe, 205 => 0x207 },
     2216    'minoltadate' => { 131 => 0x15 },
     2217    'minoltaimagesize' => { 131 => 0x4, 132 => 0xc, 133 => 0x2, 135 => 0x103 },
     2218    'minoltamodelid' => { 131 => 0x25 },
     2219    'minoltaquality' => { 131 => 0x5, 132 => 0xd, 133 => 0x3, 135 => [0x102,0x103] },
     2220    'minoltatime' => { 131 => 0x16 },
     2221    'minormodelagedisclosure' => { 300 => 'MinorModelAgeDisclosure' },
     2222    'minsamplevalue' => { 85 => 0x118 },
     2223    'mirrorlockup' => { 57 => 0xc, 58 => 0xc, 59 => 0x60f, 60 => 0xb, 61 => 0xc, 62 => 0x6, 63 => 0x6, 64 => 0xc, 65 => 0x3 },
     2224    'mobilecountrycode' => { 287 => 'mcc' },
     2225    'mobilenetworkcode' => { 287 => 'mnc' },
     2226    'moddate' => { 215 => 'modify-date', 298 => 'ModDate' },
     2227    'model' => { 73 => 0x6, 85 => 0x110, 113 => 'Model', 215 => 'Model', 226 => 0x110, 306 => 'Model' },
     2228    'modelage' => { 294 => 'ModelAge' },
     2229    'modelingflash' => { 197 => '21.4', 200 => '26.4', 201 => '30.2', 202 => '7.4', 203 => '31.3' },
     2230    'modelreleaseid' => { 300 => 'ModelReleaseID' },
     2231    'modelreleasestatus' => { 300 => 'ModelReleaseStatus' },
     2232    'modificationdate' => { 301 => 'modificationDate' },
     2233    'modifiedcolortemp' => { 45 => 0x9 },
     2234    'modifieddigitalgain' => { 45 => 0xb },
     2235    'modifiedparamflag' => { 39 => 0x1 },
     2236    'modifiedpicturestyle' => { 45 => 0xa },
     2237    'modifiedsaturation' => { 204 => 0x504 },
     2238    'modifiedsensorbluelevel' => { 45 => 0x5 },
     2239    'modifiedsensorredlevel' => { 45 => 0x4 },
     2240    'modifiedsharpness' => { 45 => 0x2 },
     2241    'modifiedsharpnessfreq' => { 45 => 0x3 },
     2242    'modifiedtonecurve' => { 45 => 0x1 },
     2243    'modifiedwhitebalance' => { 45 => 0x8 },
     2244    'modifiedwhitebalanceblue' => { 45 => 0x7 },
     2245    'modifiedwhitebalancered' => { 45 => 0x6 },
     2246    'modifydate' => { 85 => 0x132, 114 => 'ModifyDate', 213 => 'ModDate', 214 => 'tIME', 258 => 'ModDate', 308 => 'ModifyDate' },
     2247    'moirefilter' => { 85 => 0xfe58, 288 => 'MoireFilter' },
     2248    'monitordisplayoff' => { 134 => 0x4c },
     2249    'monitorofftime' => { 197 => '18.2', 198 => '3.1', 202 => '3.1' },
     2250    'monochromecontrast' => { 78 => 0x3c },
     2251    'monochromefiltereffect' => { 78 => 0x3a, 247 => 0x73 },
     2252    'monochromelinear' => { 78 => 0x3d },
     2253    'monochromeoutputhighlightpoint' => { 78 => 0x41 },
     2254    'monochromeoutputshadowpoint' => { 78 => 0x42 },
     2255    'monochromerawhighlight' => { 78 => 0x7a },
     2256    'monochromerawhighlightpoint' => { 78 => 0x3f },
     2257    'monochromerawshadow' => { 78 => 0x83 },
     2258    'monochromerawshadowpoint' => { 78 => 0x40 },
     2259    'monochromesharpness' => { 78 => 0x3e },
     2260    'monochrometoning' => { 247 => 0x74 },
     2261    'monochrometoningeffect' => { 78 => 0x3b },
     2262    'monthdaycreated' => { 99 => 0x12, 108 => 0xe },
     2263    'moonphase' => { 259 => 0x12 },
     2264    'morepermissions' => { 286 => 'morePermissions' },
     2265    'motionsensitivity' => { 259 => 0x29 },
     2266    'multiburstimageheight' => { 276 => 0x1002 },
     2267    'multiburstimagewidth' => { 276 => 0x1001 },
     2268    'multiburstmode' => { 276 => 0x1000 },
     2269    'multicontrollerwhilemetering' => { 59 => 0x517 },
     2270    'multiexposureautogain' => { 161 => 0x3 },
     2271    'multiexposuremode' => { 161 => 0x1 },
     2272    'multiexposureshots' => { 161 => 0x2 },
     2273    'multiframenoisereduction' => { 276 => 0x200b },
     2274    'multipleexposuremode' => { 208 => 0x101c },
     2275    'multipleexposureset' => { 232 => '10.1' },
     2276    'multisample' => { 165 => 0x40 },
     2277    'multiselector' => { 197 => '9.4', 200 => '27.4' },
     2278    'multiselectorliveview' => { 197 => '4.3' },
     2279    'multiselectorplaybackmode' => { 197 => ['13.5','9.2'], 200 => '27.2' },
     2280    'multiselectorshootmode' => { 197 => '9.1', 200 => '27.1' },
     2281    'mycolormode' => { 47 => 0x2 },
     2282    'nativedigest' => { 292 => 'NativeDigest', 306 => 'NativeDigest' },
     2283    'ncdfileinfo' => { 97 => 0x414 },
     2284    'ndfilter' => { 54 => 0x1c },
     2285    'nefbitdepth' => { 160 => 0xe22 },
     2286    'nefcompression' => { 160 => 0x93 },
     2287    'neutraloutputhighlightpoint' => { 78 => 0x2f },
     2288    'neutraloutputshadowpoint' => { 78 => 0x30 },
     2289    'neutralrawcolortone' => { 78 => 0x28 },
     2290    'neutralrawcontrast' => { 78 => 0x2a },
     2291    'neutralrawhighlight' => { 78 => 0x78 },
     2292    'neutralrawhighlightpoint' => { 78 => 0x2d },
     2293    'neutralrawlinear' => { 78 => 0x2b },
     2294    'neutralrawsaturation' => { 78 => 0x29 },
     2295    'neutralrawshadow' => { 78 => 0x81 },
     2296    'neutralrawshadowpoint' => { 78 => 0x2e },
     2297    'neutralrawsharpness' => { 78 => 0x2c },
     2298    'newsphotoversion' => { 94 => 0x0 },
     2299    'nickname' => { 308 => 'Nickname' },
     2300    'nikoncapturedata' => { 160 => 0xe01 },
     2301    'nikoncaptureeditversions' => { 160 => 0xe13 },
     2302    'nikoncaptureoutput' => { 160 => 0xe1e },
     2303    'nikoncaptureversion' => { 160 => 0xe09 },
     2304    'nikoniccprofile' => { 160 => 0xe1d },
     2305    'nikonimagesize' => { 172 => '723.1', 173 => '732.1', 178 => 0x2c4 },
     2306    'noisefilter' => { 204 => 0x527 },
     2307    '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 },
     2308    'noisereduction2' => { 208 => 0x1010 },
     2309    'noisereductionapplied' => { 85 => 0xc6f7 },
     2310    'noisereductionintensity' => { 191 => 0x9 },
     2311    'noisereductionmethod' => { 191 => 0x11 },
     2312    'noisereductionmode' => { 279 => 0x801e },
     2313    'noisereductionsharpness' => { 191 => 0xd },
     2314    'noisereductionvalue' => { 279 => 0x8027 },
     2315    'nomemorycard' => { 197 => '22.1', 198 => '0.3', 199 => '2.4', 200 => '33.7', 201 => '3.2', 202 => '0.3', 203 => '4.5' },
     2316    'nominalmaxaperture' => { 241 => 0xa },
     2317    'nominalminaperture' => { 241 => '10.1' },
     2318    'notes' => { 280 => 'Notes', 284 => 'notes' },
     2319    'npages' => { 315 => 'NPages' },
     2320    'nrwdata' => { 160 => 0x14 },
     2321    'nullrecord' => { 72 => 0x0 },
     2322    'number' => { 301 => 'number' },
     2323    'numberofbeats' => { 310 => 'numberOfBeats' },
     2324    'numberoffocuspoints' => { 201 => '0.3' },
     2325    'numfacepositions' => { 217 => 0x0 },
     2326    'numindexentries' => { 94 => 0x54 },
     2327    'object' => { 301 => 'object' },
     2328    'objectattributereference' => { 92 => 0x4 },
     2329    'objectcycle' => { 92 => 0x4b },
     2330    'objectdistance' => { 81 => 0x6, 82 => 0x2022 },
     2331    'objectname' => { 92 => 0x5 },
     2332    'objectpreviewdata' => { 92 => 0xca },
     2333    'objectpreviewfileformat' => { 92 => 0xc8 },
     2334    'objectpreviewfileversion' => { 92 => 0xc9 },
     2335    'objecttypereference' => { 92 => 0x3 },
     2336    'oecfcolumns' => { 292 => [\'OECF','OECFColumns'] },
     2337    'oecfnames' => { 292 => [\'OECF','OECFNames'] },
     2338    'oecfrows' => { 292 => [\'OECF','OECFRows'] },
     2339    'oecfvalues' => { 292 => [\'OECF','OECFValues'] },
     2340    'offsetschema' => { 85 => 0xea1d },
     2341    'okbutton' => { 201 => '15.1', 203 => '16.1' },
     2342    'oldsubfiletype' => { 85 => 0xff },
     2343    'olympusimageheight' => { 209 => 0x102f },
     2344    'olympusimagewidth' => { 209 => 0x102e },
     2345    'onetouchwb' => { 209 => 0x302 },
     2346    'opticalzoom' => { 101 => 0xfa3d, 103 => [0x6006,0xf006], 104 => 0x1000, 105 => 0xf, 108 => 0x1e, 120 => 'OpticalZoom' },
     2347    'opticalzoomcode' => { 54 => 0xa },
     2348    'opticalzoommode' => { 224 => 0x34 },
     2349    'opticalzoomon' => { 269 => 0x219 },
     2350    'optionenddate' => { 303 => 'optionEndDate' },
     2351    'opto-electricconvfactor' => { 292 => 'OECF' },
     2352    'ordernumber' => { 89 => 0x8002 },
     2353    'organisationinimagecode' => { 294 => 'OrganisationInImageCode' },
     2354    'organisationinimagename' => { 294 => 'OrganisationInImageName' },
     2355    'organization' => { 301 => 'organization' },
     2356    'orientation' => { 85 => 0x112, 226 => 0x112, 306 => 'Orientation' },
     2357    'orientationlinkedafpoint' => { 59 => 0x516 },
     2358    'originaldecisiondata' => { 83 => 'OriginalDecisionData' },
     2359    'originaldecisiondataoffset' => { 43 => 0x83 },
     2360    'originaldirectory' => { 221 => 0x408 },
     2361    'originaldocumentid' => { 311 => 'OriginalDocumentID' },
     2362    'originalfilename' => { 72 => 0x816, 97 => 0x3e9, 109 => 0x20, 221 => 0x407 },
     2363    'originalimageheight' => { 55 => 0xc, 88 => 0x1 },
     2364    'originalimagewidth' => { 55 => 0xb, 88 => 0x0 },
     2365    'originalrawfiledata' => { 85 => 0xc68c },
     2366    'originalrawfiledigest' => { 85 => 0xc71d },
     2367    'originalrawfilename' => { 85 => 0xc68b },
     2368    'originaltransmissionreference' => { 92 => 0x67 },
     2369    'originatingprogram' => { 92 => 0x41 },
     2370    'originplatform' => { 301 => 'originPlatform' },
     2371    'os' => { 290 => 'os' },
     2372    'otherconditions' => { 300 => 'OtherConditions' },
     2373    'otherconstraints' => { 300 => 'OtherConstraints' },
     2374    'otherimageinfo' => { 300 => 'OtherImageInfo' },
     2375    'otherlicensedocuments' => { 300 => 'OtherLicenseDocuments' },
     2376    'otherlicenseinfo' => { 300 => 'OtherLicenseInfo' },
     2377    'otherlicenserequirements' => { 300 => 'OtherLicenseRequirements' },
     2378    'outcue' => { 310 => 'outCue' },
     2379    'outcuescale' => { 310 => [\'outCue','outCueScale'] },
     2380    'outcuevalue' => { 310 => [\'outCue','outCueValue'] },
     2381    'outputimageheight' => { 143 => 0x3 },
     2382    'outputimagewidth' => { 143 => 0x2 },
     2383    'outputresolution' => { 143 => 0x4 },
     2384    'owner' => { 314 => 'Owner' },
     2385    'ownerid' => { 92 => 0xbc },
     2386    'ownername' => { 11 => 0x10f, 43 => 0x9, 72 => 0x810, 85 => [0xa430,0xfde8], 113 => 'OwnerName', 285 => 'OwnerName' },
     2387    'padding' => { 85 => 0xea1c },
     2388    'pageimage' => { 308 => [\'PageInfo','PageInfoImage'] },
     2389    'pageimageformat' => { 308 => [\'PageInfo','PageInfoFormat'] },
     2390    'pageimageheight' => { 308 => [\'PageInfo','PageInfoHeight'] },
     2391    'pageimagepagenumber' => { 308 => [\'PageInfo','PageInfoPageNumber'] },
     2392    'pageimagewidth' => { 308 => [\'PageInfo','PageInfoWidth'] },
     2393    'pageinfo' => { 308 => 'PageInfo' },
     2394    'pagename' => { 85 => 0x11d },
     2395    'pagenumber' => { 85 => 0x129 },
     2396    'pagerange' => { 301 => 'pageRange' },
     2397    'paintbasedcorrectionmasks' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasks'] },
     2398    'paintbasedcorrections' => { 288 => 'PaintBasedCorrections' },
     2399    'paintcorrectionactive' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionActive'] },
     2400    'paintcorrectionamount' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionAmount'] },
     2401    'paintcorrectionbrightness' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalBrightness'] },
     2402    'paintcorrectionclarity' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalClarity'] },
     2403    'paintcorrectioncontrast' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalContrast'] },
     2404    'paintcorrectionexposure' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalExposure'] },
     2405    'paintcorrectionhue' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalToningHue'] },
     2406    'paintcorrectionmaskcenterweight' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksCenterWeight'] },
     2407    'paintcorrectionmaskdabs' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksDabs'] },
     2408    'paintcorrectionmaskflow' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFlow'] },
     2409    'paintcorrectionmaskfullx' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullX'] },
     2410    'paintcorrectionmaskfully' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullY'] },
     2411    'paintcorrectionmaskradius' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRadius'] },
     2412    'paintcorrectionmaskvalue' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksMaskValue'] },
     2413    'paintcorrectionmaskwhat' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksWhat'] },
     2414    'paintcorrectionmaskzerox' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroX'] },
     2415    'paintcorrectionmaskzeroy' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroY'] },
     2416    'paintcorrectionsaturation' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSaturation','PaintBasedCorrectionsLocalToningSaturation'] },
     2417    'paintcorrectionsharpness' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSharpness'] },
     2418    'paintcorrectionwhat' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsWhat'] },
     2419    'panasonicexifversion' => { 224 => 0x26 },
     2420    'panasonicimageheight' => { 224 => 0x4c },
     2421    'panasonicimagewidth' => { 224 => 0x4b },
     2422    'panasonicrawversion' => { 226 => 0x1 },
     2423    'panasonictitle' => { 85 => 0xc6d2 },
     2424    'panasonictitle2' => { 85 => 0xc6d3 },
     2425    'panoramacropbottom' => { 277 => 0x7 },
     2426    'panoramacropleft' => { 277 => 0x4 },
     2427    'panoramacropright' => { 277 => 0x6 },
     2428    'panoramacroptop' => { 277 => 0x5 },
     2429    'panoramadirection' => { 50 => 0x5, 277 => 0x3 },
     2430    'panoramaframeheight' => { 277 => 0x9 },
     2431    'panoramaframenumber' => { 50 => 0x2 },
     2432    'panoramaframewidth' => { 277 => 0x8 },
     2433    'panoramafullheight' => { 277 => 0x2 },
     2434    'panoramafullwidth' => { 277 => 0x1 },
     2435    'panoramamode' => { 99 => 0x3c, 204 => 0x601 },
     2436    'panoramasourceheight' => { 277 => 0xb },
     2437    'panoramasourcewidth' => { 277 => 0xa },
     2438    'panoramicstitchcameramotion' => { 128 => 'PanoramicStitchCameraMotion', 129 => 0x1 },
     2439    'panoramicstitchmaptype' => { 128 => 'PanoramicStitchMapType', 129 => 0x2 },
     2440    'panoramicstitchphi0' => { 128 => 'PanoramicStitchPhi0', 129 => 0x5 },
     2441    'panoramicstitchphi1' => { 128 => 'PanoramicStitchPhi1', 129 => 0x6 },
     2442    'panoramicstitchtheta0' => { 128 => 'PanoramicStitchTheta0', 129 => 0x3 },
     2443    'panoramicstitchtheta1' => { 128 => 'PanoramicStitchTheta1', 129 => 0x4 },
     2444    'panoramicstitchversion' => { 129 => 0x0 },
     2445    'pantry' => { 311 => 'Pantry' },
     2446    'parallax' => { 89 => 0xb211 },
     2447    'parametricdarks' => { 288 => 'ParametricDarks' },
     2448    'parametrichighlights' => { 288 => 'ParametricHighlights' },
     2449    'parametrichighlightsplit' => { 288 => 'ParametricHighlightSplit' },
     2450    'parametriclights' => { 288 => 'ParametricLights' },
     2451    'parametricmidtonesplit' => { 288 => 'ParametricMidtoneSplit' },
     2452    'parametricshadows' => { 288 => 'ParametricShadows' },
     2453    'parametricshadowsplit' => { 288 => 'ParametricShadowSplit' },
     2454    'patientbirthdate' => { 281 => 'PatientDOB' },
     2455    'patientid' => { 281 => 'PatientID' },
     2456    'patientname' => { 281 => 'PatientName' },
     2457    'patientsex' => { 281 => 'PatientSex' },
     2458    'pdfversion' => { 298 => 'PDFVersion' },
     2459    'pentaximagesize' => { 247 => 0x9 },
     2460    'pentaxmodelid' => { 231 => 0x0, 247 => 0x5 },
     2461    'pentaxmodeltype' => { 247 => 0x1 },
     2462    'pentaxversion' => { 247 => 0x0 },
     2463    'people' => { 283 => 'People' },
     2464    'peripheralillumcentralradius' => { 279 => 0x8030 },
     2465    'peripheralillumcentralvalue' => { 279 => 0x8031 },
     2466    'peripheralillumination' => { 78 => 0x68 },
     2467    'peripheralilluminationon' => { 78 => 0x64 },
     2468    'peripheralillumperiphvalue' => { 279 => 0x8032 },
     2469    'peripherallighting' => { 55 => 0x2 },
     2470    'peripherallightingsetting' => { 56 => 0x5 },
     2471    'peripherallightingvalue' => { 55 => 0x6 },
     2472    'permissions' => { 303 => 'permissions' },
     2473    'person' => { 301 => 'person' },
     2474    'personinimage' => { 294 => 'PersonInImage' },
     2475    'perspectivehorizontal' => { 288 => 'PerspectiveHorizontal' },
     2476    'perspectiverotate' => { 288 => 'PerspectiveRotate' },
     2477    'perspectivescale' => { 288 => 'PerspectiveScale' },
     2478    'perspectivevertical' => { 288 => 'PerspectiveVertical' },
     2479    'pf0customfuncregistration' => { 67 => 0x1 },
     2480    'pf10retainprogramshift' => { 67 => 0xb },
     2481    'pf13drivepriority' => { 67 => 0xe },
     2482    'pf14disablefocussearch' => { 67 => 0xf },
     2483    'pf15disableafassistbeam' => { 67 => 0x10 },
     2484    'pf16autofocuspointshoot' => { 67 => 0x11 },
     2485    'pf17disableafpointsel' => { 67 => 0x12 },
     2486    'pf18enableautoafpointsel' => { 67 => 0x13 },
     2487    'pf19continuousshootspeed' => { 67 => 0x14 },
     2488    'pf19shootingspeedhigh' => { 66 => 0xa },
     2489    'pf19shootingspeedlow' => { 66 => 0x9 },
     2490    'pf1disableshootingmodes' => { 67 => 0x2 },
     2491    'pf1value' => { 66 => 0x1 },
     2492    'pf20limitcontinousshots' => { 67 => 0x15 },
     2493    'pf20maxcontinousshots' => { 66 => 0xb },
     2494    'pf21enablequietoperation' => { 67 => 0x16 },
     2495    'pf23felocktime' => { 66 => 0xd },
     2496    'pf23postreleasetime' => { 66 => 0xe },
     2497    'pf23settimerlengths' => { 67 => 0x18 },
     2498    'pf23shutterbuttontime' => { 66 => 0xc },
     2499    'pf24lightlcdduringbulb' => { 67 => 0x19 },
     2500    'pf25aemode' => { 66 => 0xf },
     2501    'pf25afmode' => { 66 => 0x12 },
     2502    'pf25afpointsel' => { 66 => 0x13 },
     2503    'pf25colormatrix' => { 66 => 0x17 },
     2504    'pf25defaultclearsettings' => { 67 => 0x1a },
     2505    'pf25drivemode' => { 66 => 0x11 },
     2506    'pf25imagesize' => { 66 => 0x14 },
     2507    'pf25meteringmode' => { 66 => 0x10 },
     2508    'pf25parameters' => { 66 => 0x16 },
     2509    'pf25wbmode' => { 66 => 0x15 },
     2510    'pf26shortenreleaselag' => { 67 => 0x1b },
     2511    'pf27reversedialrotation' => { 67 => 0x1c },
     2512    'pf27value' => { 66 => 0x18 },
     2513    'pf28noquickdialexpcomp' => { 67 => 0x1d },
     2514    'pf29quickdialswitchoff' => { 67 => 0x1e },
     2515    'pf2disablemeteringmodes' => { 67 => 0x3 },
     2516    'pf2value' => { 66 => 0x2 },
     2517    'pf30enlargementmode' => { 67 => 0x1f },
     2518    'pf31originaldecisiondata' => { 67 => 0x20 },
     2519    'pf3manualexposuremetering' => { 67 => 0x4 },
     2520    'pf3value' => { 66 => 0x3 },
     2521    'pf4exposuretimelimits' => { 67 => 0x5 },
     2522    'pf4exposuretimemax' => { 66 => 0x5 },
     2523    'pf4exposuretimemin' => { 66 => 0x4 },
     2524    'pf5aperturelimits' => { 67 => 0x6 },
     2525    'pf5aperturemax' => { 66 => 0x7 },
     2526    'pf5aperturemin' => { 66 => 0x6 },
     2527    'pf6presetshootingmodes' => { 67 => 0x7 },
     2528    'pf7bracketcontinuousshoot' => { 67 => 0x8 },
     2529    'pf8bracketshots' => { 66 => 0x8 },
     2530    'pf8setbracketshots' => { 67 => 0x9 },
     2531    'pf9changebracketsequence' => { 67 => 0xa },
     2532    'phasedetectaf' => { 141 => 0x6 },
     2533    'phonenumber' => { 114 => 'Phone' },
     2534    'photoeffect' => { 24 => 0x28 },
     2535    'photoeffecthistoryxml' => { 190 => 0xe9651831 },
     2536    'photoeffects' => { 190 => 0xab5eca5e },
     2537    'photoeffectsblue' => { 192 => 0x8 },
     2538    'photoeffectsgreen' => { 192 => 0x6 },
     2539    'photoeffectsred' => { 192 => 0x4 },
     2540    'photoeffectstype' => { 192 => 0x0 },
     2541    'photoinfoplayback' => { 197 => '17.6', 200 => '33.6' },
     2542    'photometricinterpretation' => { 85 => 0x106, 306 => 'PhotometricInterpretation' },
     2543    'photoshopquality' => { 255 => 0x0 },
     2544    'pictinfo' => { 269 => 0x208 },
     2545    'picturecontrol' => { 190 => 0xe2173c47 },
     2546    'picturecontrolactive' => { 193 => 0x0 },
     2547    'picturecontroladjust' => { 162 => 0x30 },
     2548    'picturecontrolbase' => { 162 => 0x18 },
     2549    'picturecontroldata' => { 160 => [0xbd,0x23] },
     2550    'picturecontrolmode' => { 193 => 0x13 },
     2551    'picturecontrolname' => { 162 => 0x4 },
     2552    'picturecontrolquickadjust' => { 162 => 0x31 },
     2553    'picturefinish' => { 132 => 0x71 },
     2554    'picturemode' => { 89 => 0x1031, 204 => 0x520, 247 => [0xb,0x33], 270 => 0x3d },
     2555    'picturemode2' => { 232 => 0x0 },
     2556    'picturemodebwfilter' => { 204 => 0x525 },
     2557    'picturemodecontrast' => { 204 => 0x523 },
     2558    'picturemodehue' => { 204 => 0x522 },
     2559    'picturemodesaturation' => { 204 => 0x521 },
     2560    'picturemodesharpness' => { 204 => 0x524 },
     2561    'picturemodetone' => { 204 => 0x526 },
     2562    'picturestyle' => { 5 => [0x4b,0x51], 6 => 0x6c, 7 => 0x86, 8 => 0x73, 12 => 0xab, 13 => 0xa7, 14 => 0xb0, 15 => 0x6c, 16 => 0xa7, 52 => 0xa, 78 => 0x2 },
     2563    'picturewizard' => { 267 => 0x21 },
     2564    'pitchangle' => { 246 => 0x2 },
     2565    'planarconfiguration' => { 85 => 0x11c, 306 => 'PlanarConfiguration' },
     2566    'platenames' => { 315 => 'PlateNames' },
     2567    'playbackmenustime' => { 199 => '20.1' },
     2568    'playbackmonitorofftime' => { 200 => '8.1', 201 => '35.1', 203 => '21.1' },
     2569    'playdisplay' => { 134 => 0x4e },
     2570    'plusversion' => { 300 => 'Version' },
     2571    'pngwarning' => { 215 => 'Warning' },
     2572    'portraitoutputhighlightpoint' => { 78 => 0x1d },
     2573    'portraitoutputshadowpoint' => { 78 => 0x1e },
     2574    'portraitrawcolortone' => { 78 => 0x16 },
     2575    'portraitrawcontrast' => { 78 => 0x18 },
     2576    'portraitrawhighlight' => { 78 => 0x76 },
     2577    'portraitrawhighlightpoint' => { 78 => 0x1b },
     2578    'portraitrawlinear' => { 78 => 0x19 },
     2579    'portraitrawsaturation' => { 78 => 0x17 },
     2580    'portraitrawshadow' => { 78 => 0x7f },
     2581    'portraitrawshadowpoint' => { 78 => 0x1c },
     2582    'portraitrawsharpness' => { 78 => 0x1a },
     2583    'portraitrefiner' => { 82 => 0x302b },
     2584    'postalcode' => { 118 => 'PostalCode' },
     2585    'postcropvignetteamount' => { 288 => 'PostCropVignetteAmount' },
     2586    'postcropvignettefeather' => { 288 => 'PostCropVignetteFeather' },
     2587    'postcropvignettemidpoint' => { 288 => 'PostCropVignetteMidpoint' },
     2588    'postcropvignetteroundness' => { 288 => 'PostCropVignetteRoundness' },
     2589    'postcropvignettestyle' => { 288 => 'PostCropVignetteStyle' },
     2590    'powersource' => { 230 => '0.1' },
     2591    'poweruptime' => { 160 => 0xb6 },
     2592    'precaptureframes' => { 209 => 0x300 },
     2593    'predictor' => { 85 => 0x13d },
     2594    'preflashreturnstrength' => { 173 => 0x28a },
     2595    'prefs' => { 92 => 0xdd, 254 => 'Prefs' },
     2596    'preservedfilename' => { 311 => 'PreservedFileName' },
     2597    'presetwhitebalance' => { 134 => 0x24, 279 => 0x8002 },
     2598    'presetwhitebalanceadj' => { 279 => 0x8014 },
     2599    'previewapplicationname' => { 85 => 0xc716 },
     2600    'previewapplicationversion' => { 85 => 0xc717 },
     2601    'previewbutton' => { 197 => ['14.1','15.1'], 200 => '29.1', 201 => '14.1' },
     2602    'previewbuttonplusdials' => { 197 => ['14.2','15.2'], 200 => '31.2' },
     2603    'previewcolorspace' => { 85 => 0xc71a },
     2604    'previewcropbottom' => { 253 => 0xef },
     2605    'previewcropleft' => { 253 => 0xec },
     2606    'previewcropright' => { 253 => 0xee },
     2607    'previewcroptop' => { 253 => 0xed },
     2608    'previewdatetime' => { 85 => 0xc71b },
     2609    'previewheight' => { 101 => 0xfa58 },
     2610    'previewimage' => { 82 => 0x2000, 83 => 'PreviewImage', 86 => 'PreviewImage', 87 => 0x4, 123 => 'data', 135 => 0x81, 209 => 0x280, 222 => 0x300, 276 => 0x2001 },
     2611    'previewimageborders' => { 247 => 0x3e },
     2612    'previewimageheight' => { 51 => 0x4 },
     2613    '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 },
     2614    'previewimagename' => { 123 => '1Name' },
     2615    'previewimagesize' => { 82 => 0x2, 106 => 0x2, 123 => 'ImageSize', 247 => 0x2, 270 => 0x1c, 276 => 0xb02c },
     2616    '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 },
     2617    'previewimagetype' => { 123 => '0Type' },
     2618    'previewimagevalid' => { 204 => 0x100, 209 => 0x1035 },
     2619    'previewimagewidth' => { 51 => 0x3 },
     2620    'previewquality' => { 51 => 0x1 },
     2621    'previewsettingsdigest' => { 85 => 0xc719 },
     2622    'previewsettingsname' => { 85 => 0xc718 },
     2623    'previewwidth' => { 101 => 0xfa57 },
     2624    'primaryafpoint' => { 141 => 0x7 },
     2625    'primarychromaticities' => { 85 => 0x13f, 306 => 'PrimaryChromaticities' },
     2626    'printim' => { 85 => 0xc4a5 },
     2627    'prioritysetupshutterrelease' => { 134 => 0x1d, 271 => 0x28 },
     2628    'privatertkinfo' => { 282 => 'privateRTKInfo' },
     2629    'processingsoftware' => { 85 => 0xb },
     2630    'processversion' => { 288 => 'ProcessVersion' },
     2631    'producer' => { 213 => 'Producer', 298 => 'Producer' },
     2632    'productid' => { 93 => 0x32 },
     2633    'productioncode' => { 231 => 0x2 },
     2634    'productorserviceconstraints' => { 300 => 'ProductOrServiceConstraints' },
     2635    'profilecalibrationsig' => { 85 => 0xc6f4 },
     2636    'profilecopyright' => { 85 => 0xc6fe },
     2637    'profileembedpolicy' => { 85 => 0xc6fd },
     2638    'profilehuesatmapdata1' => { 85 => 0xc6fa },
     2639    'profilehuesatmapdata2' => { 85 => 0xc6fb },
     2640    'profilehuesatmapdims' => { 85 => 0xc6f9 },
     2641    'profilelooktabledata' => { 85 => 0xc726 },
     2642    'profilelooktabledims' => { 85 => 0xc725 },
     2643    'profilename' => { 85 => 0xc6f8 },
     2644    'profiletonecurve' => { 85 => 0xc6fc },
     2645    'programiso' => { 224 => 0x3c },
     2646    'programline' => { 232 => '1.1' },
     2647    'programmode' => { 138 => 0x5 },
     2648    'programshift' => { 160 => 0xd },
     2649    'programversion' => { 92 => 0x46 },
     2650    'projectname' => { 310 => 'projectName' },
     2651    'projectref' => { 310 => 'projectRef' },
     2652    'projectrefpath' => { 310 => [\'projectRef','projectRefPath'] },
     2653    'projectreftype' => { 310 => [\'projectRef','projectRefType'] },
     2654    'propertyreleaseid' => { 300 => 'PropertyReleaseID' },
     2655    'propertyreleasestatus' => { 300 => 'PropertyReleaseStatus' },
     2656    'province-state' => { 92 => 0x5f },
     2657    'publicationdate' => { 301 => 'publicationDate' },
     2658    'publicationname' => { 301 => 'publicationName' },
     2659    'publisher' => { 289 => 'publisher' },
     2660    'pulldown' => { 310 => 'pullDown' },
     2661    '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] },
     2662    'qualitymode' => { 82 => 0x8 },
     2663    'quantizationmethod' => { 94 => 0x78 },
     2664    'quickadjust' => { 193 => 0x2a },
     2665    'quickcontroldialinmeter' => { 59 => 0x703 },
     2666    'quickshot' => { 269 => 0x213 },
     2667    'rangefinder' => { 199 => '4.1' },
     2668    'rasterizedcaption' => { 92 => 0x7d },
     2669    'rating' => { 85 => 0x4746, 253 => 0xdf, 284 => 'rating', 290 => 'rating', 308 => 'Rating' },
     2670    'ratingpercent' => { 85 => 0x4749, 130 => 'Rating' },
     2671    'rawandjpgrecording' => { 57 => 0x8, 135 => 0x109, 232 => 0xd },
     2672    'rawbrightnessadj' => { 77 => 0x38 },
     2673    'rawcoloradj' => { 77 => 0x2e },
     2674    'rawcropbottom' => { 253 => 0xd4 },
     2675    'rawcropleft' => { 253 => 0xd1 },
     2676    'rawcropright' => { 253 => 0xd3 },
     2677    'rawcroptop' => { 253 => 0xd2 },
     2678    'rawcustomsaturation' => { 77 => 0x30 },
     2679    'rawcustomtone' => { 77 => 0x34 },
     2680    'rawdatauniqueid' => { 85 => 0xc65d },
     2681    'rawdepth' => { 137 => 0x10 },
     2682    'rawdevautogradation' => { 211 => 0x119 },
     2683    'rawdevcolorspace' => { 210 => 0x108, 211 => 0x109 },
     2684    'rawdevcontrastvalue' => { 210 => 0x106, 211 => 0x105 },
     2685    'rawdeveditstatus' => { 210 => 0x10b },
     2686    'rawdevengine' => { 210 => 0x109, 211 => 0x10b },
     2687    'rawdevexposurebiasvalue' => { 210 => 0x100, 211 => 0x100 },
     2688    'rawdevgradation' => { 211 => 0x112 },
     2689    'rawdevgraypoint' => { 210 => 0x103, 211 => 0x104 },
     2690    'rawdevmemorycoloremphasis' => { 210 => 0x105, 211 => 0x108 },
     2691    'rawdevnoisereduction' => { 210 => 0x10a, 211 => 0x10a },
     2692    'rawdevpicturemode' => { 211 => 0x10c },
     2693    'rawdevpm_bwfilter' => { 211 => 0x110 },
     2694    'rawdevpmcontrast' => { 211 => 0x10e },
     2695    'rawdevpmnoisefilter' => { 211 => 0x120 },
     2696    'rawdevpmpicturetone' => { 211 => 0x111 },
     2697    'rawdevpmsaturation' => { 211 => 0x10d },
     2698    'rawdevpmsharpness' => { 211 => 0x10f },
     2699    'rawdevsaturation3' => { 211 => 0x113 },
     2700    'rawdevsaturationemphasis' => { 210 => 0x104, 211 => 0x107 },
     2701    'rawdevsettings' => { 210 => 0x10c },
     2702    'rawdevsharpnessvalue' => { 210 => 0x107, 211 => 0x106 },
     2703    'rawdevversion' => { 210 => 0x0, 211 => 0x0 },
     2704    'rawdevwbfineadjustment' => { 210 => 0x102, 211 => 0x103 },
     2705    'rawdevwhitebalance' => { 211 => 0x101 },
     2706    'rawdevwhitebalancevalue' => { 210 => 0x101, 211 => 0x102 },
     2707    'rawfile' => { 85 => 0xfe4c },
     2708    'rawfilename' => { 288 => 'RawFileName' },
     2709    'rawimagecenter' => { 160 => 0x99 },
     2710    'rawimagedigest' => { 85 => 0xc71c },
     2711    'rawimagesize' => { 247 => 0x39 },
     2712    'rawinfoversion' => { 212 => 0x0 },
     2713    'rawjpgheight' => { 74 => 0x4 },
     2714    'rawjpgquality' => { 38 => 0x6, 74 => 0x1 },
     2715    'rawjpgsize' => { 38 => 0x7, 74 => 0x2 },
     2716    'rawjpgwidth' => { 74 => 0x3 },
     2717    'rawmeasuredrggb' => { 29 => 0x26a, 31 => 0x280, 33 => 0x194 },
     2718    'reardisplay' => { 197 => '12.3' },
     2719    'recognizedface1age' => { 218 => 0x20 },
     2720    'recognizedface1name' => { 218 => 0x4 },
     2721    'recognizedface1position' => { 218 => 0x18 },
     2722    'recognizedface2age' => { 218 => 0x50 },
     2723    'recognizedface2name' => { 218 => 0x34 },
     2724    'recognizedface2position' => { 218 => 0x48 },
     2725    'recognizedface3age' => { 218 => 0x80 },
     2726    'recognizedface3name' => { 218 => 0x64 },
     2727    'recognizedface3position' => { 218 => 0x78 },
     2728    'recognizedfaceflags' => { 224 => 0x63 },
     2729    'recommendedexposureindex' => { 85 => 0x8832 },
     2730    'recorddisplay' => { 134 => 0x4d },
     2731    'recordid' => { 72 => 0x1804 },
     2732    'recordingmode' => { 81 => 0x1, 252 => 0x1 },
     2733    'recordmode' => { 24 => 0x9, 82 => 0x3000 },
     2734    'recordshutterrelease' => { 269 => 0x217 },
     2735    'redbalance' => { 148 => 0x270, 209 => 0x1017, 226 => 0x11, 247 => 0x1c },
     2736    'redcurvelimits' => { 77 => 0x18a },
     2737    'redcurvepoints' => { 77 => 0x160 },
     2738    'redeyecorrection' => { 194 => 0x0 },
     2739    'redeyeinfo' => { 288 => 'RedEyeInfo' },
     2740    'redeyereduction' => { 134 => 0x41 },
     2741    'redhue' => { 288 => 'RedHue' },
     2742    'redsaturation' => { 288 => 'RedSaturation' },
     2743    'reductionmatrix1' => { 85 => 0xc625 },
     2744    'reductionmatrix2' => { 85 => 0xc626 },
     2745    'referenceblackwhite' => { 85 => 0x214, 306 => 'ReferenceBlackWhite' },
     2746    'referencedate' => { 92 => 0x2f },
     2747    'referencenumber' => { 92 => 0x32 },
     2748    'references' => { 114 => 'References' },
     2749    'referenceservice' => { 92 => 0x2d },
     2750    'regionappliedtodimensions' => { 297 => [\'Regions','RegionsAppliedToDimensions'] },
     2751    'regionappliedtodimensionsh' => { 297 => [\'Regions','RegionsAppliedToDimensionsH'] },
     2752    'regionappliedtodimensionsunit' => { 297 => [\'Regions','RegionsAppliedToDimensionsUnit'] },
     2753    'regionappliedtodimensionsw' => { 297 => [\'Regions','RegionsAppliedToDimensionsW'] },
     2754    'regionarea' => { 297 => [\'Regions','RegionsRegionListArea'] },
     2755    'regionaread' => { 297 => [\'Regions','RegionsRegionListAreaD'] },
     2756    'regionareah' => { 297 => [\'Regions','RegionsRegionListAreaH'] },
     2757    'regionareaunit' => { 297 => [\'Regions','RegionsRegionListAreaUnit'] },
     2758    'regionareaw' => { 297 => [\'Regions','RegionsRegionListAreaW'] },
     2759    'regionareax' => { 297 => [\'Regions','RegionsRegionListAreaX'] },
     2760    'regionareay' => { 297 => [\'Regions','RegionsRegionListAreaY'] },
     2761    'regionbarcodevalue' => { 297 => [\'Regions','RegionsRegionListBarCodeValue'] },
     2762    'regionconstraints' => { 300 => 'RegionConstraints' },
     2763    'regiondescription' => { 297 => [\'Regions','RegionsRegionListDescription'] },
     2764    'regionextensions' => { 297 => [\'Regions','RegionsRegionListExtensions'] },
     2765    'regionfocususage' => { 297 => [\'Regions','RegionsRegionListFocusUsage'] },
     2766    'regioninfo' => { 297 => 'Regions' },
     2767    'regioninfomp' => { 127 => 'RegionInfo' },
     2768    'regioninfompregions' => { 127 => [\'RegionInfo','RegionInfoRegions'] },
     2769    'regionlist' => { 297 => [\'Regions','RegionsRegionList'] },
     2770    'regionname' => { 297 => [\'Regions','RegionsRegionListName'] },
     2771    'regionpersondisplayname' => { 127 => [\'RegionInfo','RegionInfoRegionsPersonDisplayName'] },
     2772    'regionrectangle' => { 127 => [\'RegionInfo','RegionInfoRegionsRectangle'] },
     2773    'regionseealso' => { 297 => [\'Regions','RegionsRegionListSeeAlso'] },
     2774    'regiontype' => { 297 => [\'Regions','RegionsRegionListType'] },
     2775    'registryid' => { 294 => 'RegistryId' },
     2776    'registryitemid' => { 294 => [\'RegistryId','RegistryIdRegItemId'] },
     2777    'registryorganisationid' => { 294 => [\'RegistryId','RegistryIdRegOrgId'] },
     2778    'relatedaudiofile' => { 112 => 'data' },
     2779    'relatedaudiofilename' => { 112 => '1Name' },
     2780    'relatedaudiofiletype' => { 112 => '0Type' },
     2781    'relatedimagefileformat' => { 85 => 0x1000 },
     2782    'relatedimageheight' => { 85 => 0x1002 },
     2783    'relatedimagewidth' => { 85 => 0x1001 },
     2784    'relatedsoundfile' => { 85 => 0xa004, 292 => 'RelatedSoundFile' },
     2785    'relatedvideofile' => { 126 => 'data' },
     2786    'relatedvideofilename' => { 126 => '1Name' },
     2787    'relatedvideofiletype' => { 126 => '0Type' },
     2788    'relation' => { 289 => 'relation' },
     2789    'relativepeakaudiofilepath' => { 310 => 'relativePeakAudioFilePath' },
     2790    'relativetimestamp' => { 310 => 'relativeTimestamp' },
     2791    'relativetimestampscale' => { 310 => [\'relativeTimestamp','relativeTimestampScale'] },
     2792    'relativetimestampvalue' => { 310 => [\'relativeTimestamp','relativeTimestampValue'] },
     2793    'releasebuttontousedial' => { 197 => '17.8', 200 => '33.8', 201 => '17.6' },
     2794    'releasedate' => { 92 => 0x1e, 310 => 'releaseDate' },
     2795    'releasemode' => { 82 => 0x3001, 276 => 0xb049 },
     2796    'releasesetting' => { 72 => 0x1016 },
     2797    'releasetime' => { 92 => 0x23 },
     2798    'remoteonduration' => { 198 => '3.4', 199 => '17.2', 201 => '18.2', 202 => '4.3', 203 => '19.2' },
     2799    'renditionclass' => { 311 => 'RenditionClass' },
     2800    'renditionof' => { 311 => 'RenditionOf' },
     2801    'renditionofalternatepaths' => { 311 => [\'RenditionOf','RenditionOfAlternatePaths'] },
     2802    'renditionofdocumentid' => { 311 => [\'RenditionOf','RenditionOfDocumentID'] },
     2803    'renditionoffilepath' => { 311 => [\'RenditionOf','RenditionOfFilePath'] },
     2804    'renditionoffrompart' => { 311 => [\'RenditionOf','RenditionOfFromPart'] },
     2805    'renditionofinstanceid' => { 311 => [\'RenditionOf','RenditionOfInstanceID'] },
     2806    'renditionoflastmodifydate' => { 311 => [\'RenditionOf','RenditionOfLastModifyDate'] },
     2807    'renditionofmanager' => { 311 => [\'RenditionOf','RenditionOfManager'] },
     2808    'renditionofmanagervariant' => { 311 => [\'RenditionOf','RenditionOfManagerVariant'] },
     2809    'renditionofmanageto' => { 311 => [\'RenditionOf','RenditionOfManageTo'] },
     2810    'renditionofmanageui' => { 311 => [\'RenditionOf','RenditionOfManageUI'] },
     2811    'renditionofmaskmarkers' => { 311 => [\'RenditionOf','RenditionOfMaskMarkers'] },
     2812    'renditionoforiginaldocumentid' => { 311 => [\'RenditionOf','RenditionOfOriginalDocumentID'] },
     2813    'renditionofpartmapping' => { 311 => [\'RenditionOf','RenditionOfPartMapping'] },
     2814    'renditionofrenditionclass' => { 311 => [\'RenditionOf','RenditionOfRenditionClass'] },
     2815    'renditionofrenditionparams' => { 311 => [\'RenditionOf','RenditionOfRenditionParams'] },
     2816    'renditionoftopart' => { 311 => [\'RenditionOf','RenditionOfToPart'] },
     2817    'renditionofversionid' => { 311 => [\'RenditionOf','RenditionOfVersionID'] },
     2818    'renditionparams' => { 311 => 'RenditionParams' },
     2819    'repeatingflashcount' => { 152 => 0xd, 153 => 0xe, 154 => 0xe, 200 => '17.2', 201 => '24.2', 202 => '9.2', 203 => '25.2' },
     2820    'repeatingflashoutput' => { 200 => '17.1', 201 => '24.1', 202 => '9.1', 203 => '25.1' },
     2821    'repeatingflashrate' => { 152 => 0xc, 153 => 0xd, 154 => 0xd, 200 => '18.1', 201 => '25.1', 202 => '10.1', 203 => '26.1' },
     2822    'resampleparams' => { 310 => 'resampleParams' },
     2823    'resampleparamsquality' => { 310 => [\'resampleParams','resampleParamsQuality'] },
     2824    'resaved' => { 269 => 0x21e },
     2825    'resolution' => { 119 => 'Resolution' },
     2826    'resolutionmode' => { 270 => 0x4 },
     2827    'resolutionunit' => { 85 => 0x128, 95 => 0x2, 306 => 'ResolutionUnit' },
     2828    'restrictions' => { 303 => 'restrictions' },
     2829    'retouchhistory' => { 160 => 0x9e },
     2830    'retouchinfo' => { 288 => 'RetouchInfo' },
     2831    'reuse' => { 300 => 'Reuse' },
     2832    'reuseallowed' => { 313 => 'ReuseAllowed' },
     2833    'reuseprohibited' => { 303 => 'reuseProhibited' },
     2834    'reverseindicators' => { 197 => '12.1', 199 => '4.3', 200 => '33.5', 201 => '5.1', 203 => '6.2' },
     2835    'revision' => { 290 => 'revision' },
     2836    'rgbcurvelimits' => { 77 => 0x238 },
     2837    'rgbcurvepoints' => { 77 => 0x20e },
     2838    'ricohdate' => { 262 => 0x6 },
     2839    'ricohimageheight' => { 262 => 0x2 },
     2840    'ricohimagewidth' => { 262 => 0x0 },
     2841    'rightascension' => { 122 => 'RightAscension' },
     2842    'rights' => { 289 => 'rights' },
     2843    'rightsagent' => { 301 => 'rightsAgent', 303 => 'rightsAgent' },
     2844    'rightsowner' => { 303 => 'rightsOwner' },
     2845    'rollangle' => { 246 => 0x1 },
     2846    'romoperationmode' => { 72 => 0x80d },
     2847    '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 },
     2848    'routing' => { 258 => 'Routing' },
     2849    'rowsperstrip' => { 85 => 0x116 },
     2850    'rpp' => { 284 => 'rpp' },
     2851    'safetyshift' => { 59 => 0x108 },
     2852    'safetyshiftinavortv' => { 57 => 0x10, 58 => 0x10, 60 => 0xf, 61 => 0x10, 64 => 0x10 },
     2853    'samplebits' => { 112 => 'SampleBits' },
     2854    'samplerate' => { 112 => 'SampleRate' },
     2855    'samplesperpixel' => { 85 => 0x115, 306 => 'SamplesPerPixel' },
     2856    'samplestructure' => { 94 => 0x5a },
     2857    'sanyoquality' => { 269 => 0x201 },
     2858    'sanyothumbnail' => { 269 => 0x100 },
     2859    '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' },
     2860    'saturationadj' => { 77 => 0x116, 189 => 0x1, 193 => 0x2e, 279 => 0x8016 },
     2861    'saturationadjustmentaqua' => { 288 => 'SaturationAdjustmentAqua' },
     2862    'saturationadjustmentblue' => { 288 => 'SaturationAdjustmentBlue' },
     2863    'saturationadjustmentgreen' => { 288 => 'SaturationAdjustmentGreen' },
     2864    'saturationadjustmentmagenta' => { 288 => 'SaturationAdjustmentMagenta' },
     2865    'saturationadjustmentorange' => { 288 => 'SaturationAdjustmentOrange' },
     2866    'saturationadjustmentpurple' => { 288 => 'SaturationAdjustmentPurple' },
     2867    'saturationadjustmentred' => { 288 => 'SaturationAdjustmentRed' },
     2868    'saturationadjustmentyellow' => { 288 => 'SaturationAdjustmentYellow' },
     2869    'saturationfaithful' => { 15 => 0xfe, 48 => 0x68, 49 => 0x68 },
     2870    'saturationlandscape' => { 15 => 0xfc, 48 => 0x38, 49 => 0x38 },
     2871    'saturationmonochrome' => { 48 => 0x80, 49 => 0x80 },
     2872    'saturationneutral' => { 15 => 0xfd, 48 => 0x50, 49 => 0x50 },
     2873    'saturationportrait' => { 15 => 0xfb, 48 => 0x20, 49 => 0x20 },
     2874    'saturationsetting' => { 212 => 0x1010 },
     2875    'saturationstandard' => { 15 => 0xfa, 48 => 0x8, 49 => 0x8 },
     2876    'saturationunknown' => { 49 => 0x98 },
     2877    'saturationuserdef1' => { 15 => 0x100, 48 => 0x98, 49 => 0xb0 },
     2878    'saturationuserdef2' => { 15 => 0x101, 48 => 0xb0, 49 => 0xc8 },
     2879    'saturationuserdef3' => { 15 => 0x102, 48 => 0xc8, 49 => 0xe0 },
     2880    'saveid' => { 311 => 'SaveID' },
     2881    'scaletype' => { 310 => 'scaleType' },
     2882    'scanimageenhancer' => { 165 => 0x60 },
     2883    'scanningdirection' => { 94 => 0x64 },
     2884    'scene' => { 293 => 'Scene', 310 => 'scene' },
     2885    'scenearea' => { 207 => 0x211, 209 => 0x1031 },
     2886    'sceneassist' => { 160 => 0x9c },
     2887    'scenecapturetype' => { 85 => 0xa406, 292 => 'SceneCaptureType' },
     2888    'scenedetect' => { 207 => 0x210, 209 => 0x1030 },
     2889    'scenedetectdata' => { 207 => 0x212, 209 => 0x1033 },
     2890    'scenemode' => { 101 => 0xfa02, 135 => 0x100, 160 => 0x8f, 204 => 0x509, 209 => 0x403, 224 => 0x8001, 276 => 0xb023 },
     2891    'scenemodeused' => { 103 => [0x6002,0xf002] },
     2892    'sceneselect' => { 269 => 0x21f },
     2893    'scenetype' => { 85 => 0xa301, 292 => 'SceneType' },
     2894    'screentips' => { 197 => '12.7', 200 => '13.1', 201 => '4.4', 203 => '5.1' },
     2895    'section' => { 301 => 'section' },
     2896    'securityclassification' => { 85 => 0x9212 },
     2897    'selectableafpoint' => { 59 => 0x509 },
     2898    'selectafareaselectmode' => { 59 => 0x512 },
     2899    'selftimer' => { 24 => 0x2, 224 => 0x2e, 269 => 0x214 },
     2900    'selftimer2' => { 54 => 0x1d },
     2901    'selftimerinterval' => { 201 => '19.2' },
     2902    'selftimermode' => { 85 => 0x882b },
     2903    'selftimershotcount' => { 199 => '18.2', 201 => '19.3', 203 => '20.2' },
     2904    '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' },
     2905    'seminfo' => { 85 => 0x8546 },
     2906    'sensingmethod' => { 85 => 0xa217, 292 => 'SensingMethod' },
     2907    'sensitivityadjust' => { 247 => 0x40 },
     2908    'sensitivitysteps' => { 232 => ['14.3','17.4'], 234 => 0x1 },
     2909    'sensitivitytype' => { 85 => 0x8830 },
     2910    'sensorareas' => { 267 => 0xa010 },
     2911    'sensorbitdepth' => { 225 => 0x312d },
     2912    'sensorbluelevel' => { 52 => 0x5 },
     2913    'sensorcleaning' => { 65 => 0xd },
     2914    'sensorfullheight' => { 96 => 0xf904 },
     2915    'sensorfullwidth' => { 96 => 0xf903 },
     2916    'sensorheight' => { 96 => 0xf901, 101 => 0xfa21, 137 => 0x8, 225 => 0x312c },
     2917    'sensorpixelsize' => { 160 => 0x9a },
     2918    'sensorredlevel' => { 52 => 0x4 },
     2919    'sensorsize' => { 113 => 'SensorSize', 247 => 0x35 },
     2920    'sensortemperature' => { 207 => 0x1500, 209 => 0x1007, 270 => 0x39 },
     2921    'sensorwidth' => { 96 => 0xf900, 101 => 0xfa20, 137 => 0xa, 225 => 0x312b },
     2922    'sequence' => { 259 => 0x7 },
     2923    'sequencenumber' => { 54 => 0x9, 82 => 0x301c, 89 => 0x1101, 99 => 0x1d, 224 => 0x2b, 276 => 0xb04a },
     2924    'sequenceshotinterval' => { 269 => 0x224 },
     2925    'sequentialshot' => { 269 => 0x20e },
     2926    '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' },
     2927    'serialnumberformat' => { 43 => 0x15, 72 => 0x183b },
     2928    'seriesdatetime' => { 281 => 'SeriesDateTime' },
     2929    'seriesdescription' => { 281 => 'SeriesDescription' },
     2930    'seriesmodality' => { 281 => 'SeriesModality' },
     2931    'seriesnumber' => { 281 => 'SeriesNumber' },
     2932    'serviceidentifier' => { 93 => 0x1e },
     2933    'setbuttoncrosskeysfunc' => { 62 => 0x0, 63 => 0x0 },
     2934    'setbuttonwhenshooting' => { 57 => 0x1, 59 => 0x704, 65 => 0xc },
     2935    'setfunctionwhenshooting' => { 60 => 0x0, 61 => 0x1, 64 => 0x1 },
     2936    'shadingcompensation' => { 204 => 0x50c },
     2937    'shadingcompensation2' => { 208 => 0x1012 },
     2938    'shadow' => { 270 => 0xe },
     2939    'shadowcompensation' => { 247 => 0x79 },
     2940    'shadowprotection' => { 189 => 0x0 },
     2941    'shadows' => { 85 => 0xfe52, 288 => 'Shadows' },
     2942    'shadowscale' => { 85 => 0xc633 },
     2943    'shadowtint' => { 288 => 'ShadowTint' },
     2944    'shakereduction' => { 248 => 0x1 },
     2945    'sharpendetail' => { 288 => 'SharpenDetail' },
     2946    'sharpenedgemasking' => { 288 => 'SharpenEdgeMasking' },
     2947    'sharpening' => { 225 => 0x300b },
     2948    'sharpeningadj' => { 193 => 0x2b },
     2949    'sharpenradius' => { 288 => 'SharpenRadius' },
     2950    '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' },
     2951    'sharpnessadj' => { 77 => 0x25a, 279 => 0x801a },
     2952    'sharpnessfactor' => { 209 => 0x102a },
     2953    'sharpnessfaithful' => { 15 => 0xf5, 48 => 0x64, 49 => 0x64 },
     2954    'sharpnessfrequency' => { 5 => [0x41,0x47], 52 => 0x3 },
     2955    'sharpnesslandscape' => { 15 => 0xf3, 48 => 0x34, 49 => 0x34 },
     2956    'sharpnessmonochrome' => { 15 => 0xf6, 48 => 0x7c, 49 => 0x7c },
     2957    'sharpnessneutral' => { 15 => 0xf4, 48 => 0x4c, 49 => 0x4c },
     2958    'sharpnessovershoot' => { 279 => 0x801b },
     2959    'sharpnessportrait' => { 15 => 0xf2, 48 => 0x1c, 49 => 0x1c },
     2960    'sharpnesssetting' => { 204 => 0x506, 212 => 0x1013 },
     2961    'sharpnessstandard' => { 15 => 0xf1, 48 => 0x4, 49 => 0x4 },
     2962    'sharpnessthreshold' => { 279 => 0x801d },
     2963    'sharpnessundershoot' => { 279 => 0x801c },
     2964    'sharpnessunknown' => { 49 => 0x94 },
     2965    'sharpnessuserdef1' => { 15 => 0xf7, 48 => 0x94, 49 => 0xac },
     2966    'sharpnessuserdef2' => { 15 => 0xf8, 48 => 0xac, 49 => 0xc4 },
     2967    'sharpnessuserdef3' => { 15 => 0xf9, 48 => 0xc4, 49 => 0xdc },
     2968    'shootinginfodisplay' => { 197 => '13.2', 200 => '10.2', 201 => '4.1', 203 => '5.3' },
     2969    'shootinginfomonitorofftime' => { 200 => '9.1', 201 => '21.2', 203 => '22.2' },
     2970    'shootingmode' => { 113 => 'ShootingMode', 160 => 0x89, 224 => 0x1f },
     2971    'shootingmodesetting' => { 198 => '5.1' },
     2972    'shortdescription' => { 290 => 'shortdescription' },
     2973    'shortdocumentid' => { 92 => 0xba },
     2974    '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 },
     2975    'shortownername' => { 15 => 0xac },
     2976    'shortreleasetimelag' => { 59 => 0x80d },
     2977    'shotdate' => { 310 => 'shotDate' },
     2978    'shotday' => { 310 => 'shotDay' },
     2979    'shotlocation' => { 310 => 'shotLocation' },
     2980    'shotname' => { 310 => 'shotName' },
     2981    'shotnumber' => { 310 => 'shotNumber' },
     2982    'shotsize' => { 310 => 'shotSize' },
     2983    'shutter-aelock' => { 57 => 0x4, 59 => 0x701, 60 => 0x3, 61 => 0x4, 62 => 0x3, 63 => 0x3, 64 => 0x4, 65 => 0x2 },
     2984    'shutteraelbutton' => { 58 => 0x4 },
     2985    'shutterbuttonafonbutton' => { 59 => 0x701 },
     2986    '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 },
     2987    'shuttercurtainsync' => { 57 => 0xf, 58 => 0xf, 59 => 0x305, 60 => 0xe, 61 => 0xf, 62 => 0x8, 63 => 0x8, 64 => 0xf, 65 => 0x8 },
     2988    'shuttermode' => { 99 => 0x1b },
     2989    'shutterreleasebuttonae-l' => { 197 => '17.7', 199 => '16.1', 200 => '7.1', 201 => '17.5', 203 => '18.2' },
     2990    'shutterreleasemethod' => { 72 => 0x1010 },
     2991    'shutterreleasenocfcard' => { 57 => 0x2, 58 => 0x2, 65 => 0xf },
     2992    'shutterreleasetiming' => { 72 => 0x1011 },
     2993    'shutterspeedrange' => { 59 => 0x10c },
     2994    'shutterspeedvalue' => { 68 => 0x1, 85 => 0x9201, 209 => 0x1000, 292 => 'ShutterSpeedValue' },
     2995    'sidecarforextension' => { 299 => 'SidecarForExtension' },
     2996    'similarityindex' => { 92 => 0xe4 },
     2997    'singleframebracketing' => { 134 => 0x21 },
     2998    'slaveflashmeteringsegments' => { 247 => 0x20b },
     2999    'slowshutter' => { 54 => 0x8 },
     3000    'slowsync' => { 89 => 0x1030 },
     3001    'smartrange' => { 267 => 0xa012 },
     3002    'smoothness' => { 85 => 0xfe57, 288 => 'Smoothness' },
     3003    'software' => { 85 => 0x131, 114 => 'Software', 215 => 'Software', 270 => 0x18, 306 => 'Software' },
     3004    'softwareversion' => { 269 => 0x207 },
     3005    'sonydatetime' => { 278 => 0x6 },
     3006    'sonyimagesize' => { 134 => 0x3b, 271 => 0x54, 272 => 0x54 },
     3007    'sonymodelid' => { 276 => 0xb001 },
     3008    'sonyquality' => { 134 => 0x3c },
     3009    'source' => { 92 => 0x73, 215 => 'Source', 289 => 'source', 290 => 'source', 299 => 'Source' },
     3010    'sourcedirectoryindex' => { 238 => 0x0 },
     3011    'sourcefileindex' => { 238 => 0x2 },
     3012    'spatialfrequencyresponse' => { 292 => 'SpatialFrequencyResponse' },
     3013    'spatialfrequencyresponsecolumns' => { 292 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseColumns'] },
     3014    'spatialfrequencyresponsenames' => { 292 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseNames'] },
     3015    'spatialfrequencyresponserows' => { 292 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseRows'] },
     3016    'spatialfrequencyresponsevalues' => { 292 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseValues'] },
     3017    'speakerplacement' => { 310 => 'speakerPlacement' },
     3018    'specialeffectlevel' => { 82 => 0x3030 },
     3019    'specialeffectmode' => { 82 => 0x2076 },
     3020    'specialeffectsetting' => { 82 => 0x3031 },
     3021    'specialinstructions' => { 92 => 0x28 },
     3022    'specialmode' => { 209 => 0x200, 269 => 0x200 },
     3023    'spectralsensitivity' => { 85 => 0x8824, 292 => 'SpectralSensitivity' },
     3024    'splittoningbalance' => { 288 => 'SplitToningBalance' },
     3025    'splittoninghighlighthue' => { 288 => 'SplitToningHighlightHue' },
     3026    'splittoninghighlightsaturation' => { 288 => 'SplitToningHighlightSaturation' },
     3027    'splittoningshadowhue' => { 288 => 'SplitToningShadowHue' },
     3028    'splittoningshadowsaturation' => { 288 => 'SplitToningShadowSaturation' },
     3029    'spotfocuspointx' => { 131 => 0x2d },
     3030    'spotfocuspointy' => { 131 => 0x2e },
     3031    'spotmeteringmode' => { 24 => 0x27 },
     3032    'spotmeterlinktoafpoint' => { 59 => 0x107 },
     3033    'sractive' => { 232 => '17.1' },
     3034    'srawquality' => { 24 => 0x2e },
     3035    'srfocallength' => { 248 => 0x3 },
     3036    'srhalfpresstime' => { 248 => 0x2 },
     3037    'srresult' => { 248 => 0x0 },
     3038    'standardoutputhighlightpoint' => { 78 => 0x14 },
     3039    'standardoutputsensitivity' => { 85 => 0x8831 },
     3040    'standardoutputshadowpoint' => { 78 => 0x15 },
     3041    'standardrawcolortone' => { 78 => 0xd },
     3042    'standardrawcontrast' => { 78 => 0xf },
     3043    'standardrawhighlight' => { 78 => 0x75 },
     3044    'standardrawhighlightpoint' => { 78 => 0x12 },
     3045    'standardrawlinear' => { 78 => 0x10 },
     3046    'standardrawsaturation' => { 78 => 0xe },
     3047    'standardrawshadow' => { 78 => 0x7e },
     3048    'standardrawshadowpoint' => { 78 => 0x13 },
     3049    'standardrawsharpness' => { 78 => 0x11 },
     3050    'startingpage' => { 301 => 'startingPage' },
     3051    'startmovieshooting' => { 59 => 0x70d },
     3052    'starttimecode' => { 310 => 'startTimecode' },
     3053    'starttimecodetimeformat' => { 310 => [\'startTimecode','startTimecodeTimeFormat'] },
     3054    'starttimecodetimevalue' => { 310 => [\'startTimecode','startTimecodeTimeValue'] },
     3055    'starttimecodevalue' => { 310 => [\'startTimecode','startTimecodeValue'] },
     3056    'state' => { 118 => 'State', 224 => 0x6b, 299 => 'State' },
     3057    'status' => { 283 => 'Status' },
     3058    'storagemethod' => { 137 => 0x12 },
     3059    'straightenangle' => { 190 => 0x2fc08431 },
     3060    'stretchmode' => { 310 => 'stretchMode' },
     3061    'studydatetime' => { 281 => 'StudyDateTime' },
     3062    'studydescription' => { 281 => 'StudyDescription' },
     3063    'studyid' => { 281 => 'StudyID' },
     3064    'studyphysician' => { 281 => 'StudyPhysician' },
     3065    'sub-location' => { 92 => 0x5c },
     3066    'subfiledata' => { 121 => 'data' },
     3067    'subfiledirectory' => { 121 => '1Directory' },
     3068    'subfilemimetype' => { 121 => '2MIME' },
     3069    'subfilename' => { 121 => '1Name' },
     3070    'subfileresource' => { 121 => 'rsrc' },
     3071    'subfiletype' => { 85 => 0xfe, 121 => '0Type' },
     3072    'subject' => { 213 => 'Subject', 258 => 'Subject', 289 => 'subject', 298 => 'Subject' },
     3073    'subjectarea' => { 85 => 0x9214, 292 => 'SubjectArea' },
     3074    'subjectcode' => { 293 => 'SubjectCode' },
     3075    'subjectdistance' => { 85 => 0x9206, 99 => 0x3e, 292 => 'SubjectDistance' },
     3076    'subjectdistancerange' => { 85 => 0xa40c, 292 => 'SubjectDistanceRange' },
     3077    'subjectlocation' => { 85 => 0xa214, 292 => 'SubjectLocation' },
     3078    'subjectprogram' => { 131 => 0x22 },
     3079    'subjectreference' => { 92 => 0xc },
     3080    'subsectime' => { 85 => 0x9290 },
     3081    'subsectimedigitized' => { 85 => 0x9292 },
     3082    'subsectimeoriginal' => { 85 => 0x9291 },
     3083    'subsection1' => { 301 => 'subsection1' },
     3084    'subsection2' => { 301 => 'subsection2' },
     3085    'subsection3' => { 301 => 'subsection3' },
     3086    'subsection4' => { 301 => 'subsection4' },
     3087    'superimposeddisplay' => { 57 => 0xa, 59 => 0x510, 60 => 0x9, 61 => 0xa, 64 => 0xa, 65 => 0xe },
     3088    'supermacro' => { 43 => 0x1a },
     3089    'supplementalcategories' => { 92 => 0x14, 299 => 'SupplementalCategories' },
     3090    'supplementaltype' => { 94 => 0x37 },
     3091    'svisosetting' => { 232 => 0x14 },
     3092    'switchtoregisteredafpoint' => { 58 => 0x12, 59 => 0x50a },
     3093    'tagged' => { 253 => 0xdd, 284 => 'tagged' },
     3094    'tagslist' => { 291 => 'TagsList' },
     3095    'takenumber' => { 310 => 'takeNumber' },
     3096    'tapename' => { 310 => 'tapeName' },
     3097    'targetaperture' => { 54 => 0x4 },
     3098    'targetcompressionratio' => { 70 => 0x1 },
     3099    'targetdistancesetting' => { 72 => 0x1807 },
     3100    'targetexposuretime' => { 54 => 0x5 },
     3101    'targetimagetype' => { 72 => 0x100a },
     3102    'teaser' => { 301 => 'teaser' },
     3103    'teleconverter' => { 135 => 0x105, 276 => 0x105 },
     3104    'tempo' => { 310 => 'tempo' },
     3105    'termsandconditionstext' => { 300 => 'TermsAndConditionsText' },
     3106    'termsandconditionsurl' => { 300 => 'TermsAndConditionsURL' },
     3107    'textlayername' => { 299 => [\'TextLayers','TextLayersLayerName'] },
     3108    'textlayers' => { 299 => 'TextLayers' },
     3109    'textlayertext' => { 299 => [\'TextLayers','TextLayersLayerText'] },
     3110    'textstamp' => { 224 => [0x8008,0x8009,0x3b,0x3e] },
     3111    'thresholding' => { 85 => 0x107 },
     3112    'thumbnailfilename' => { 72 => 0x817 },
     3113    'thumbnailformat' => { 308 => [\'Thumbnails','ThumbnailsFormat'] },
     3114    'thumbnailheight' => { 101 => 0xfa55, 308 => [\'Thumbnails','ThumbnailsHeight'] },
     3115    'thumbnailimage' => { 72 => 0x2008, 83 => 'ThumbnailImage', 87 => 0x3, 124 => 'data', 209 => 0x100, 308 => [\'Thumbnails','ThumbnailsImage'] },
     3116    'thumbnailimagename' => { 124 => '1Name' },
     3117    'thumbnailimagesize' => { 124 => 'ImageSize' },
     3118    'thumbnailimagetype' => { 124 => '0Type' },
     3119    'thumbnailimagevalidarea' => { 43 => 0x13 },
     3120    'thumbnaillength' => { 85 => 0x202 },
     3121    'thumbnailoffset' => { 85 => 0x201 },
     3122    'thumbnails' => { 308 => 'Thumbnails' },
     3123    'thumbnailwidth' => { 101 => 0xfa54, 308 => [\'Thumbnails','ThumbnailsWidth'] },
     3124    'ticker' => { 301 => 'ticker' },
     3125    'tilelength' => { 85 => 0x143 },
     3126    'tilewidth' => { 85 => 0x142 },
     3127    'time' => { 97 => 0x401, 247 => 0x7 },
     3128    'timecreated' => { 92 => 0x3c, 99 => 0x14, 108 => 0x10, 254 => 'TimeCreated' },
     3129    'timeperiod' => { 301 => 'timePeriod' },
     3130    'timerfunctionbutton' => { 198 => '5.2', 199 => '12.1' },
     3131    'timerlength' => { 59 => 0x80c },
     3132    'timescaleparams' => { 310 => 'timeScaleParams' },
     3133    'timescaleparamsframeoverlappingpercentage' => { 310 => [\'timeScaleParams','timeScaleParamsFrameOverlappingPercentage'] },
     3134    'timescaleparamsframesize' => { 310 => [\'timeScaleParams','timeScaleParamsFrameSize'] },
     3135    'timescaleparamsquality' => { 310 => [\'timeScaleParams','timeScaleParamsQuality'] },
     3136    'timesent' => { 93 => 0x50 },
     3137    'timesignature' => { 310 => 'timeSignature' },
     3138    'timesincepoweron' => { 224 => 0x29 },
     3139    'timestamp' => { 7 => 0x45e, 15 => 0x11c, 215 => 'TimeStamp' },
     3140    'timestamp1' => { 7 => 0x45a },
     3141    'timezone' => { 182 => 0x0 },
     3142    'timezonecode' => { 75 => 0x1 },
     3143    'timezoneinfo' => { 75 => 0x2 },
     3144    'timezoneoffset' => { 85 => 0x882a },
     3145    'tint' => { 288 => 'Tint' },
     3146    'title' => { 114 => 'Title', 213 => 'Title', 215 => 'Title', 224 => 0x65, 258 => 'Title', 289 => 'title', 298 => 'Title' },
     3147    'tonecomp' => { 160 => 0x81 },
     3148    'tonecurve' => { 52 => 0x1, 247 => 0x402, 288 => 'ToneCurve' },
     3149    'tonecurve1' => { 267 => 0xa040 },
     3150    'tonecurve2' => { 267 => 0xa041 },
     3151    'tonecurve3' => { 267 => 0xa042 },
     3152    'tonecurve4' => { 267 => 0xa043 },
     3153    'tonecurveactive' => { 77 => 0x110 },
     3154    'tonecurvebluex' => { 279 => 0x9003 },
     3155    'tonecurvebluey' => { 279 => 0x9007 },
     3156    'tonecurvebrightnessx' => { 279 => 0x9000 },
     3157    'tonecurvebrightnessy' => { 279 => 0x9004 },
     3158    'tonecurvefilename' => { 97 => 0x1391 },
     3159    'tonecurvegreenx' => { 279 => 0x9002 },
     3160    'tonecurvegreeny' => { 279 => 0x9006 },
     3161    'tonecurveinterpolation' => { 77 => 0x159 },
     3162    'tonecurvemode' => { 77 => 0x113 },
     3163    'tonecurvename' => { 288 => 'ToneCurveName' },
     3164    'tonecurveproperty' => { 77 => 0x3c },
     3165    'tonecurveredx' => { 279 => 0x9001 },
     3166    'tonecurveredy' => { 279 => 0x9005 },
     3167    'tonecurves' => { 247 => 0x403 },
     3168    'toningeffect' => { 38 => 0xf, 160 => 0xb3, 162 => 0x38 },
     3169    'toningeffectfaithful' => { 48 => 0x74, 49 => 0x74 },
     3170    'toningeffectlandscape' => { 48 => 0x44, 49 => 0x44 },
     3171    'toningeffectmonochrome' => { 15 => 0x108, 48 => 0x8c, 49 => 0x8c },
     3172    'toningeffectneutral' => { 48 => 0x5c, 49 => 0x5c },
     3173    'toningeffectportrait' => { 48 => 0x2c, 49 => 0x2c },
     3174    'toningeffectstandard' => { 48 => 0x14, 49 => 0x14 },
     3175    'toningeffectunknown' => { 49 => 0xa4 },
     3176    'toningeffectuserdef1' => { 48 => 0xa4, 49 => 0xbc },
     3177    'toningeffectuserdef2' => { 48 => 0xbc, 49 => 0xd4 },
     3178    'toningeffectuserdef3' => { 48 => 0xd4, 49 => 0xec },
     3179    'toningsaturation' => { 162 => 0x39 },
     3180    'totalzoom' => { 99 => 0x62 },
     3181    'tracknumber' => { 310 => 'trackNumber' },
     3182    'tracks' => { 310 => 'Tracks' },
     3183    'tracksframerate' => { 310 => [\'Tracks','TracksFrameRate'] },
     3184    'tracksmarkers' => { 310 => [\'Tracks','TracksMarkers'] },
     3185    'tracksmarkerscomment' => { 310 => [\'Tracks','TracksMarkersComment'] },
     3186    'tracksmarkerscuepointparams' => { 310 => [\'Tracks','TracksMarkersCuePointParams'] },
     3187    'tracksmarkerscuepointparamskey' => { 310 => [\'Tracks','TracksMarkersCuePointParamsKey'] },
     3188    'tracksmarkerscuepointparamsvalue' => { 310 => [\'Tracks','TracksMarkersCuePointParamsValue'] },
     3189    'tracksmarkerscuepointtype' => { 310 => [\'Tracks','TracksMarkersCuePointType'] },
     3190    'tracksmarkersduration' => { 310 => [\'Tracks','TracksMarkersDuration'] },
     3191    'tracksmarkerslocation' => { 310 => [\'Tracks','TracksMarkersLocation'] },
     3192    'tracksmarkersname' => { 310 => [\'Tracks','TracksMarkersName'] },
     3193    'tracksmarkersprobability' => { 310 => [\'Tracks','TracksMarkersProbability'] },
     3194    'tracksmarkersspeaker' => { 310 => [\'Tracks','TracksMarkersSpeaker'] },
     3195    'tracksmarkersstarttime' => { 310 => [\'Tracks','TracksMarkersStartTime'] },
     3196    'tracksmarkerstarget' => { 310 => [\'Tracks','TracksMarkersTarget'] },
     3197    'tracksmarkerstype' => { 310 => [\'Tracks','TracksMarkersType'] },
     3198    'trackstrackname' => { 310 => [\'Tracks','TracksTrackName'] },
     3199    'trackstracktype' => { 310 => [\'Tracks','TracksTrackType'] },
     3200    'trailersignature' => { 121 => 'zmie' },
     3201    'transferfunction' => { 85 => 0x12d, 306 => 'TransferFunction' },
     3202    'transform' => { 224 => [0x8012,0x59] },
     3203    'transmissionreference' => { 299 => 'TransmissionReference' },
     3204    'trapped' => { 213 => 'Trapped', 298 => 'Trapped' },
     3205    'travelday' => { 224 => 0x36 },
     3206    'triggermode' => { 259 => 0x6 },
     3207    'ttl_da_adown' => { 239 => 0x5 },
     3208    'ttl_da_aup' => { 239 => 0x4 },
     3209    'ttl_da_bdown' => { 239 => 0x7 },
     3210    'ttl_da_bup' => { 239 => 0x6 },
     3211    'tungstenawb' => { 229 => 0x1 },
     3212    'tvexposuretimesetting' => { 232 => 0x12 },
     3213    'type' => { 289 => 'type', 305 => 'type' },
     3214    'uniquecameramodel' => { 85 => 0xc614 },
     3215    'uniquedocumentid' => { 92 => 0xbb },
     3216    'uniqueobjectname' => { 93 => 0x64 },
     3217    'unknownblock' => { 208 => 0x1103 },
     3218    'unknowncontrast' => { 78 => 0x45 },
     3219    'unknownev' => { 97 => 0x1 },
     3220    'unknownlinear' => { 78 => 0x46 },
     3221    'unknownmode' => { 82 => 0x301b },
     3222    'unknownnumber' => { 72 => 0x180b },
     3223    'unknownoutputhighlightpoint' => { 78 => 0x4a },
     3224    'unknownoutputshadowpoint' => { 78 => 0x4b },
     3225    'unknownrawhighlight' => { 78 => 0x7b },
     3226    'unknownrawhighlightpoint' => { 78 => 0x48 },
     3227    'unknownrawshadow' => { 78 => 0x84 },
     3228    'unknownrawshadowpoint' => { 78 => 0x49 },
     3229    'unknownsharpness' => { 78 => 0x47 },
     3230    'unsharp1color' => { 195 => 0x13 },
     3231    'unsharp1halowidth' => { 195 => 0x19 },
     3232    'unsharp1intensity' => { 195 => 0x17 },
     3233    'unsharp1threshold' => { 195 => 0x1b },
     3234    'unsharp2color' => { 195 => 0x2e },
     3235    'unsharp2halowidth' => { 195 => 0x34 },
     3236    'unsharp2intensity' => { 195 => 0x32 },
     3237    'unsharp2threshold' => { 195 => 0x36 },
     3238    'unsharp3color' => { 195 => 0x49 },
     3239    'unsharp3halowidth' => { 195 => 0x4f },
     3240    'unsharp3intensity' => { 195 => 0x4d },
     3241    'unsharp3threshold' => { 195 => 0x51 },
     3242    'unsharp4color' => { 195 => 0x64 },
     3243    'unsharp4halowidth' => { 195 => 0x6a },
     3244    'unsharp4intensity' => { 195 => 0x68 },
     3245    'unsharp4threshold' => { 195 => 0x6c },
     3246    'unsharpcount' => { 195 => 0x0 },
     3247    'unsharpmask' => { 78 => 0x90, 190 => 0x76a43200 },
     3248    'unsharpmaskfineness' => { 78 => 0x94 },
     3249    'unsharpmaskstrength' => { 78 => 0x92 },
     3250    'unsharpmaskthreshold' => { 78 => 0x96 },
     3251    'urgency' => { 92 => 0xa, 299 => 'Urgency' },
     3252    'url' => { 114 => 'URL', 215 => 'URL', 256 => 0x40b, 301 => 'url' },
     3253    'usablemeteringmodes' => { 59 => 0x10a },
     3254    'usableshootingmodes' => { 59 => 0x109 },
     3255    'usage' => { 302 => 'usage' },
     3256    'usagefee' => { 303 => 'usageFee' },
     3257    'usageterms' => { 314 => 'UsageTerms' },
     3258    'usercomment' => { 72 => 0x805, 85 => 0x9286, 292 => 'UserComment' },
     3259    'userdef1picturestyle' => { 15 => 0x10c, 48 => 0xd8, 49 => 0xf0 },
     3260    'userdef2picturestyle' => { 15 => 0x10e, 48 => 0xda, 49 => 0xf2 },
     3261    'userdef3picturestyle' => { 15 => 0x110, 48 => 0xdc, 49 => 0xf4 },
     3262    'userfields' => { 283 => 'UserFields' },
     3263    'userlabel' => { 259 => 0x2b },
     3264    'userprofile' => { 219 => 0x302, 225 => 0x3038 },
     3265    'usmlenselectronicmf' => { 58 => 0x7, 59 => 0x501 },
     3266    'utmeasting' => { 125 => 'Easting' },
     3267    'utmmapdatum' => { 125 => 'Datum' },
     3268    'utmnorthing' => { 125 => 'Northing' },
     3269    'utmzone' => { 125 => 'Zone' },
     3270    'uv-irfiltercorrection' => { 219 => 0x325 },
     3271    'validbits' => { 208 => 0x611, 209 => 0x102c },
     3272    'validpixeldepth' => { 212 => 0x611 },
     3273    'variousmodes' => { 99 => 0x26 },
     3274    'variousmodes2' => { 99 => 0x3a },
     3275    'variprogram' => { 160 => 0xab },
     3276    'version' => { 89 => 0x0, 258 => 'Version', 288 => 'Version' },
     3277    'versioncreatedate' => { 279 => 0xd100 },
     3278    'versionid' => { 311 => 'VersionID' },
     3279    'versionidentifier' => { 301 => 'versionIdentifier' },
     3280    'versionmodifydate' => { 279 => 0xd101 },
     3281    'versions' => { 311 => 'Versions' },
     3282    'versionscomments' => { 311 => [\'Versions','VersionsComments'] },
     3283    'versionsevent' => { 311 => [\'Versions','VersionsEvent'] },
     3284    'versionseventaction' => { 311 => [\'Versions','VersionsEventAction'] },
     3285    'versionseventchanged' => { 311 => [\'Versions','VersionsEventChanged'] },
     3286    'versionseventinstanceid' => { 311 => [\'Versions','VersionsEventInstanceID'] },
     3287    'versionseventparameters' => { 311 => [\'Versions','VersionsEventParameters'] },
     3288    'versionseventsoftwareagent' => { 311 => [\'Versions','VersionsEventSoftwareAgent'] },
     3289    'versionseventwhen' => { 311 => [\'Versions','VersionsEventWhen'] },
     3290    'versionsmodifier' => { 311 => [\'Versions','VersionsModifier'] },
     3291    'versionsmodifydate' => { 311 => [\'Versions','VersionsModifyDate'] },
     3292    'versionsversion' => { 311 => [\'Versions','VersionsVersion'] },
     3293    'verticalafonbutton' => { 197 => '3.2' },
     3294    'vfdisplayillumination' => { 59 => 0x510 },
     3295    'vibrance' => { 288 => 'Vibrance' },
     3296    'vibrationreduction' => { 166 => [0x75,0x82,0x1ae], 174 => '586.1', 178 => '590.2', 181 => 0x4 },
     3297    'videoalphamode' => { 310 => 'videoAlphaMode' },
     3298    'videoalphapremultiplecolor' => { 310 => 'videoAlphaPremultipleColor' },
     3299    'videoalphapremultiplecolora' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorA'] },
     3300    'videoalphapremultiplecolorb' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorB'] },
     3301    'videoalphapremultiplecolorblack' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorBlack'] },
     3302    'videoalphapremultiplecolorblue' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorBlue'] },
     3303    'videoalphapremultiplecolorcyan' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorCyan'] },
     3304    'videoalphapremultiplecolorgreen' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorGreen'] },
     3305    'videoalphapremultiplecolorl' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorL'] },
     3306    'videoalphapremultiplecolormagenta' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorMagenta'] },
     3307    'videoalphapremultiplecolormode' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorMode'] },
     3308    'videoalphapremultiplecolorred' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorRed'] },
     3309    'videoalphapremultiplecolorswatchname' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorSwatchName'] },
     3310    'videoalphapremultiplecolortype' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorType'] },
     3311    'videoalphapremultiplecoloryellow' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorYellow'] },
     3312    'videoalphaunityistransparent' => { 310 => 'videoAlphaUnityIsTransparent' },
     3313    'videocodec' => { 46 => 0x74 },
     3314    'videocolorspace' => { 310 => 'videoColorSpace' },
     3315    'videocompressor' => { 310 => 'videoCompressor' },
     3316    'videofieldorder' => { 310 => 'videoFieldOrder' },
     3317    'videoframerate' => { 310 => 'videoFrameRate' },
     3318    'videoframesize' => { 310 => 'videoFrameSize' },
     3319    'videoframesizeh' => { 310 => [\'videoFrameSize','videoFrameSizeH'] },
     3320    'videoframesizeunit' => { 310 => [\'videoFrameSize','videoFrameSizeUnit'] },
     3321    'videoframesizew' => { 310 => [\'videoFrameSize','videoFrameSizeW'] },
     3322    'videomoddate' => { 310 => 'videoModDate' },
     3323    'videopixelaspectratio' => { 310 => 'videoPixelAspectRatio' },
     3324    'videopixeldepth' => { 310 => 'videoPixelDepth' },
     3325    'videoquality' => { 82 => 0x4003 },
     3326    'viewfinderdisplay' => { 197 => '12.4' },
     3327    'viewfinderwarning' => { 197 => '13.4', 201 => '3.5', 202 => '6.2', 203 => '4.4' },
     3328    'viewinfoduringexposure' => { 59 => 0x407 },
     3329    'vignetteamount' => { 288 => 'VignetteAmount' },
     3330    'vignettecontrol' => { 160 => 0x2a, 190 => 0x76a43205 },
     3331    'vignettecontrolintensity' => { 190 => 0xac6bd5c0 },
     3332    'vignettemidpoint' => { 288 => 'VignetteMidpoint' },
     3333    'voicememo' => { 269 => 0x216 },
     3334    'volume' => { 301 => 'volume' },
     3335    'vr_0x66' => { 166 => 0x66 },
     3336    'vrdoffset' => { 43 => 0xd0 },
     3337    'wb_bluepresetsfluorescent' => { 136 => 0x40a },
     3338    'wb_gbrglevels' => { 136 => 0xae, 139 => 0x4 },
     3339    'wb_glevel' => { 208 => 0x11f },
     3340    'wb_glevel3000k' => { 208 => 0x113 },
     3341    'wb_glevel3300k' => { 208 => 0x114 },
     3342    'wb_glevel3600k' => { 208 => 0x115 },
     3343    'wb_glevel3900k' => { 208 => 0x116 },
     3344    'wb_glevel4000k' => { 208 => 0x117 },
     3345    'wb_glevel4300k' => { 208 => 0x118 },
     3346    'wb_glevel4500k' => { 208 => 0x119 },
     3347    'wb_glevel4800k' => { 208 => 0x11a },
     3348    'wb_glevel5300k' => { 208 => 0x11b },
     3349    'wb_glevel6000k' => { 208 => 0x11c },
     3350    'wb_glevel6600k' => { 208 => 0x11d },
     3351    'wb_glevel7500k' => { 208 => 0x11e },
     3352    'wb_grbglevels' => { 147 => 0x0 },
     3353    'wb_rbgglevels' => { 144 => 0x0 },
     3354    'wb_rblevels' => { 160 => 0xc, 208 => 0x100 },
     3355    'wb_rblevels3000k' => { 208 => 0x102 },
     3356    'wb_rblevels3300k' => { 208 => 0x103 },
     3357    'wb_rblevels3600k' => { 208 => 0x104 },
     3358    'wb_rblevels3900k' => { 208 => 0x105 },
     3359    'wb_rblevels4000k' => { 208 => 0x106 },
     3360    'wb_rblevels4300k' => { 208 => 0x107 },
     3361    'wb_rblevels4500k' => { 208 => 0x108 },
     3362    'wb_rblevels4800k' => { 208 => 0x109 },
     3363    'wb_rblevels5300k' => { 208 => 0x10a },
     3364    'wb_rblevels6000k' => { 208 => 0x10b },
     3365    'wb_rblevels6600k' => { 208 => 0x10c },
     3366    'wb_rblevels7500k' => { 208 => 0x10d },
     3367    'wb_rblevelsauto' => { 212 => 0x110 },
     3368    'wb_rblevelscloudy' => { 138 => 0x10, 212 => 0x121 },
     3369    'wb_rblevelscoolwhitef' => { 138 => 0x14 },
     3370    'wb_rblevelscoolwhitefluor' => { 212 => 0x132 },
     3371    'wb_rblevelscwb1' => { 208 => 0x10e },
     3372    'wb_rblevelscwb2' => { 208 => 0x10f },
     3373    'wb_rblevelscwb3' => { 208 => 0x110 },
     3374    'wb_rblevelscwb4' => { 208 => 0x111 },
     3375    'wb_rblevelsdaylight' => { 138 => 0xc },
     3376    'wb_rblevelsdaylightf' => { 138 => 0x24 },
     3377    'wb_rblevelsdaylightfluor' => { 212 => 0x130 },
     3378    'wb_rblevelsdaywhitef' => { 138 => 0x28 },
     3379    'wb_rblevelsdaywhitefluor' => { 212 => 0x131 },
     3380    'wb_rblevelseveningsunlight' => { 212 => 0x124 },
     3381    'wb_rblevelsfineweather' => { 212 => 0x122 },
     3382    'wb_rblevelsflash' => { 138 => 0x18 },
     3383    'wb_rblevelsshade' => { 138 => 0x20, 212 => 0x120 },
     3384    'wb_rblevelstungsten' => { 138 => 0x8, 212 => 0x123 },
     3385    'wb_rblevelsunknown' => { 138 => 0x1c },
     3386    'wb_rblevelsused' => { 212 => 0x100 },
     3387    'wb_rblevelswhitef' => { 138 => 0x2c },
     3388    'wb_rblevelswhitefluorescent' => { 212 => 0x133 },
     3389    'wb_rbpresetcloudy' => { 136 => 0x3f0 },
     3390    'wb_rbpresetcoolwhitef' => { 136 => 0x308 },
     3391    'wb_rbpresetcustom' => { 136 => 0x424 },
     3392    'wb_rbpresetdaylight' => { 136 => 0x3ec },
     3393    'wb_rbpresetflash' => { 136 => [0x3f4,0x304] },
     3394    'wb_rbpresetshade' => { 136 => 0x418 },
     3395    'wb_rbpresettungsten' => { 136 => 0x3e8 },
     3396    'wb_redpresetsfluorescent' => { 136 => 0x3fc },
     3397    'wb_rgbglevels' => { 146 => 0x0 },
     3398    'wb_rgblevels' => { 136 => 0x96, 220 => 0xd, 221 => 0x413, 225 => 0x3036 },
     3399    'wb_rggblevels' => { 139 => 0x4, 145 => 0x0 },
     3400    'wb_rggblevelsasshot' => { 27 => 0x0, 28 => 0x19, 29 => 0x22, 30 => 0x3f, 33 => 0x3f },
     3401    'wb_rggblevelsauto' => { 25 => 0x0, 27 => 0x5, 28 => 0x1e, 29 => 0x18, 30 => 0x44, 33 => 0x44, 267 => 0xa022 },
     3402    'wb_rggblevelsblack' => { 267 => 0xa028 },
     3403    'wb_rggblevelscloudy' => { 25 => 0xc, 27 => 0x1e, 28 => 0x2d, 29 => 0x31, 30 => 0x58, 33 => 0x71, 247 => 0x20f },
     3404    'wb_rggblevelscustom' => { 25 => 0x1c, 30 => 0x80 },
     3405    'wb_rggblevelscustom1' => { 28 => 0x41 },
     3406    'wb_rggblevelscustom2' => { 28 => 0x46 },
     3407    'wb_rggblevelsdaylight' => { 25 => 0x4, 27 => 0x14, 28 => 0x23, 29 => 0x27, 30 => 0x4e, 33 => 0x67, 247 => 0x20d },
     3408    'wb_rggblevelsflash' => { 25 => 0x18, 27 => 0x32, 28 => 0x3c, 29 => 0x45, 30 => 0x6c, 33 => 0x85, 247 => 0x214 },
     3409    'wb_rggblevelsfluorescent' => { 25 => 0x14, 27 => 0x28, 28 => 0x37, 29 => 0x3b, 30 => 0x62, 33 => 0x7b },
     3410    'wb_rggblevelsfluorescentd' => { 247 => 0x211 },
     3411    'wb_rggblevelsfluorescentn' => { 247 => 0x212 },
     3412    'wb_rggblevelsfluorescentw' => { 247 => 0x213 },
     3413    'wb_rggblevelsilluminator1' => { 267 => 0xa023 },
     3414    'wb_rggblevelsilluminator2' => { 267 => 0xa024 },
     3415    'wb_rggblevelskelvin' => { 25 => 0x20, 27 => 0x2d, 29 => 0x40, 30 => 0x67, 33 => 0x80 },
     3416    'wb_rggblevelsmeasured' => { 27 => 0xa, 30 => 0x49, 33 => 0x49 },
     3417    'wb_rggblevelspc1' => { 29 => 0x90, 30 => 0x71 },
     3418    'wb_rggblevelspc2' => { 29 => 0x95, 30 => 0x76 },
     3419    'wb_rggblevelspc3' => { 29 => 0x9a, 30 => 0x7b },
     3420    'wb_rggblevelsshade' => { 25 => 0x8, 27 => 0x19, 28 => 0x28, 29 => 0x2c, 30 => 0x53, 33 => 0x6c, 247 => 0x20e },
     3421    'wb_rggblevelstungsten' => { 25 => 0x10, 27 => 0x23, 28 => 0x32, 29 => 0x36, 30 => 0x5d, 33 => 0x76, 247 => 0x210 },
     3422    'wb_rggblevelsuncorrected' => { 267 => 0xa021 },
     3423    'wb_rggblevelsunknown' => { 27 => 0xf, 29 => 0x1d, 33 => 0x4e },
     3424    'wb_rggblevelsunknown10' => { 27 => 0x5f, 29 => 0x72, 33 => 0x9e },
     3425    'wb_rggblevelsunknown11' => { 27 => 0x64, 29 => 0x77, 33 => 0xa3 },
     3426    'wb_rggblevelsunknown12' => { 27 => 0x69, 29 => 0x7c, 33 => 0xa8 },
     3427    'wb_rggblevelsunknown13' => { 27 => 0x6e, 29 => 0x81, 33 => 0xad },
     3428    'wb_rggblevelsunknown14' => { 29 => 0x86, 33 => 0xb2 },
     3429    'wb_rggblevelsunknown15' => { 29 => 0x8b, 33 => 0xb7 },
     3430    'wb_rggblevelsunknown16' => { 29 => 0x9f },
     3431    'wb_rggblevelsunknown2' => { 27 => 0x37, 29 => 0x4a, 33 => 0x53 },
     3432    'wb_rggblevelsunknown3' => { 27 => 0x3c, 29 => 0x4f, 33 => 0x58 },
     3433    'wb_rggblevelsunknown4' => { 27 => 0x41, 29 => 0x54, 33 => 0x5d },
     3434    'wb_rggblevelsunknown5' => { 27 => 0x46, 29 => 0x59, 33 => 0x62 },
     3435    'wb_rggblevelsunknown6' => { 27 => 0x4b, 29 => 0x5e, 33 => 0x8a },
     3436    'wb_rggblevelsunknown7' => { 27 => 0x50, 29 => 0x63, 33 => 0x8f },
     3437    'wb_rggblevelsunknown8' => { 27 => 0x55, 29 => 0x68, 33 => 0x94 },
     3438    'wb_rggblevelsunknown9' => { 27 => 0x5a, 29 => 0x6d, 33 => 0x99 },
     3439    'wbadjbluebalance' => { 196 => 0x8 },
     3440    'wbadjcolortemp' => { 77 => 0x1a },
     3441    'wbadjlighting' => { 196 => 0x15 },
     3442    'wbadjlightingsubtype' => { 196 => 0x14 },
     3443    'wbadjmode' => { 196 => 0x10 },
     3444    'wbadjredbalance' => { 196 => 0x0 },
     3445    'wbadjrgblevels' => { 77 => 0x8 },
     3446    'wbadjtemperature' => { 196 => 0x18 },
     3447    'wbadjtint' => { 196 => 0x25 },
     3448    'wbadjustab' => { 224 => 0x46 },
     3449    'wbadjustgm' => { 224 => 0x47 },
     3450    'wbbluelevel' => { 219 => 0x324, 224 => 0x8006, 226 => 0x26 },
     3451    'wbbracketmode' => { 38 => 0x9 },
     3452    'wbbracketvalueab' => { 38 => 0xc },
     3453    'wbbracketvaluegm' => { 38 => 0xd },
     3454    'wbfinetuneactive' => { 77 => 0x24 },
     3455    'wbfinetunesaturation' => { 77 => 0x28 },
     3456    'wbfinetunetone' => { 77 => 0x2c },
     3457    'wbgreenlevel' => { 219 => 0x323, 224 => 0x8005, 226 => 0x25 },
     3458    'wbmediaimagesizesetting' => { 59 => 0x708 },
     3459    'wbmode' => { 138 => 0x4, 209 => 0x1015 },
     3460    'wbredlevel' => { 219 => 0x322, 224 => 0x8004, 226 => 0x24 },
     3461    'wbscale' => { 139 => 0x0 },
     3462    'wbshiftab' => { 52 => 0xc, 233 => 0x10 },
     3463    'wbshiftgm' => { 52 => 0xd },
     3464    'wbshiftmg' => { 233 => 0x11 },
     3465    'webstatement' => { 314 => 'WebStatement' },
     3466    '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' },
     3467    'whitebalance2' => { 204 => 0x500 },
     3468    'whitebalanceadj' => { 77 => 0x18, 190 => 0x76a43204 },
     3469    'whitebalanceautoadjustment' => { 229 => 0x0 },
     3470    'whitebalancebias' => { 82 => 0x2011, 209 => 0x304, 224 => 0x23 },
     3471    'whitebalanceblue' => { 52 => 0x7 },
     3472    'whitebalancebracket' => { 204 => 0x502, 209 => 0x303 },
     3473    'whitebalancebracketing' => { 134 => 0x22 },
     3474    'whitebalancecomp' => { 212 => 0x1001 },
     3475    'whitebalancefinetune' => { 89 => 0x100a, 134 => 0x38, 135 => 0x112, 160 => 0xb, 271 => 0x6, 276 => 0x112 },
     3476    'whitebalancemode' => { 247 => 0x1a },
     3477    'whitebalancered' => { 52 => 0x6 },
     3478    'whitebalanceset' => { 232 => 0xa },
     3479    'whitebalancesetting' => { 134 => 0x23 },
     3480    'whitebalancetemperature' => { 204 => 0x501 },
     3481    'whiteboard' => { 209 => 0x301 },
     3482    'whitelevel' => { 85 => 0xc61d },
     3483    'whitepoint' => { 85 => 0x13e, 247 => 0x201, 306 => 'WhitePoint' },
     3484    'widefocuszone' => { 131 => 0x2f },
     3485    'widerange' => { 269 => 0x20f },
     3486    'wordcount' => { 301 => 'wordCount' },
     3487    'workcolorspace' => { 77 => 0x270 },
     3488    'worldtimelocation' => { 224 => 0x3a, 247 => 0x22, 251 => '0.1' },
     3489    'writer-editor' => { 92 => 0x7a },
     3490    'x3filllight' => { 270 => 0x12 },
     3491    'xmp' => { 76 => 0xffff00f6, 86 => 'XMP' },
     3492    'xmptoolkit' => { 307 => 'xmptk' },
     3493    'xpauthor' => { 85 => 0x9c9d },
     3494    'xpcomment' => { 85 => 0x9c9c },
     3495    'xpkeywords' => { 85 => 0x9c9e },
     3496    'xposition' => { 85 => 0x11e },
     3497    'xpsubject' => { 85 => 0x9c9f },
     3498    'xptitle' => { 85 => 0x9c9b },
     3499    'xresolution' => { 85 => 0x11a, 95 => 0x3, 257 => 0x0, 306 => 'XResolution' },
     3500    'xyresolution' => { 88 => 0x3 },
     3501    'ycbcrcoefficients' => { 85 => 0x211, 306 => 'YCbCrCoefficients' },
     3502    'ycbcrpositioning' => { 85 => 0x213, 306 => 'YCbCrPositioning' },
     3503    'ycbcrsubsampling' => { 85 => 0x212, 306 => 'YCbCrSubSampling' },
     3504    'yearcreated' => { 99 => 0x10, 108 => 0xc },
     3505    'yposition' => { 85 => 0x11f },
     3506    'yresolution' => { 85 => 0x11b, 95 => 0x5, 257 => 0x4, 306 => 'YResolution' },
     3507    'zonematching' => { 135 => 0x10a, 138 => [0x3a,0x4a], 276 => 0xb024 },
     3508    'zonematchingmode' => { 134 => 0x14 },
     3509    'zonematchingon' => { 133 => 0x75 },
     3510    'zonematchingvalue' => { 271 => 0x1f },
     3511    'zoomedpreviewlength' => { 209 => 0xf05 },
     3512    'zoomedpreviewsize' => { 209 => 0xf06 },
     3513    'zoomedpreviewstart' => { 209 => 0xf04 },
     3514    'zoomsourcewidth' => { 24 => 0x24 },
     3515    'zoomstepcount' => { 207 => 0x300, 209 => 0x100d },
     3516    'zoomtargetwidth' => { 24 => 0x25 },
    19493517);
    19503518
    19513519# lookup for non-writable tags to check if the name exists
    19523520my %tagExists = (
     3521    '_ac3' => 1,
     3522    '_h264' => 1,
     3523    '_stream' => 1,
     3524    'a100dataoffset' => 1,
    19533525    'abstract' => 1,
     3526    'accessdate' => 1,
     3527    'acdsee' => 1,
     3528    'actualcompensation' => 1,
    19543529    'adobe' => 1,
    19553530    'adobe_cm' => 1,
    19563531    'adobecmtype' => 1,
    19573532    'adobecrw' => 1,
     3533    'adobekoda' => 1,
     3534    'adobeleaf' => 1,
    19583535    'adobemrw' => 1,
     3536    'adobepano' => 1,
    19593537    'adobephotoshop' => 1,
    19603538    'adoberaf' => 1,
     
    19623540    'advancedcontentencryption' => 1,
    19633541    'advancedmutualexcl' => 1,
     3542    'adventrevision' => 1,
     3543    'adventscale' => 1,
     3544    'aeflags' => 1,
    19643545    'aeinfo' => 1,
    1965     'afaperture' => 1,
     3546    'aeunknown' => 1,
    19663547    'afarea' => 1,
    1967     'afareaheight' => 1,
    19683548    'afareaheights' => 1,
    1969     'afareawidth' => 1,
    19703549    'afareawidths' => 1,
    19713550    'afareaxpositions' => 1,
     
    19733552    'afcp' => 1,
    19743553    'afcp_iptc' => 1,
    1975     'afimageheight' => 1,
    1976     'afimagewidth' => 1,
    19773554    'afinfo' => 1,
     3555    'afinfo2' => 1,
     3556    'afinfo2version' => 1,
    19783557    'afinfocus' => 1,
    19793558    'afinfosize' => 1,
     3559    'afm' => 1,
     3560    'afmicroadj' => 1,
    19803561    'afpointsinfocus1d' => 1,
    19813562    'afpointsselected' => 1,
     3563    'aftune' => 1,
     3564    'aimetadata' => 1,
     3565    'aiprivatedata' => 1,
     3566    'album2' => 1,
    19823567    'albumartist' => 1,
    19833568    'albumcoverurl' => 1,
     
    19853570    'albumsortorder' => 1,
    19863571    'albumtitle' => 1,
     3572    'albumtitleid' => 1,
    19873573    'aliaslayermetadata' => 1,
    19883574    'alphabitdepth' => 1,
     
    19963582    'alphaoffset' => 1,
    19973583    'alphasample' => 1,
    1998     'analogbalance' => 1,
     3584    'alternateduotonecolors' => 1,
     3585    'alternatespotcolors' => 1,
     3586    'ambienceinfo' => 1,
     3587    'animationextension' => 1,
     3588    'animationiterations' => 1,
    19993589    'annotation' => 1,
    20003590    'annotations' => 1,
     3591    'annotationusagerights' => 1,
     3592    'anta' => 1,
    20013593    'aperture' => 1,
    20023594    'aperturedisplayed' => 1,
     3595    'aperturesetting' => 1,
    20033596    'apeversion' => 1,
    20043597    'app14flags0' => 1,
    20053598    'app14flags1' => 1,
    20063599    'app1_profile' => 1,
    2007     'applestoreid' => 1,
    2008     'applicationnotes' => 1,
     3600    'applestoreaccount' => 1,
     3601    'applestoreaccounttype' => 1,
     3602    'applestorecatalogid' => 1,
     3603    'applestorecountry' => 1,
     3604    'application' => 1,
     3605    'applicationdata' => 1,
     3606    'applicationmissingmsg' => 1,
     3607    'applicationversion' => 1,
    20093608    'appversion' => 1,
    20103609    'archivallocation' => 1,
     3610    'archivedfilename' => 1,
     3611    'arranger' => 1,
     3612    'arrangerkeywords' => 1,
     3613    'artist2' => 1,
    20113614    'artistlen' => 1,
    20123615    'artisturl' => 1,
     3616    'artwork' => 1,
     3617    'ascender' => 1,
     3618    'ascent' => 1,
    20133619    'asfleakybucketpairs' => 1,
    20143620    'asfpacketcount' => 1,
    20153621    'asfsecurityobjectssize' => 1,
    2016     'aspectratio' => 1,
     3622    'aspectinfo' => 1,
     3623    'aspectratiotype' => 1,
    20173624    'aspectratiox' => 1,
    20183625    'aspectratioy' => 1,
    2019     'asshotneutral' => 1,
    20203626    'association' => 1,
     3627    'assumeddisplaysize' => 1,
     3628    'assumeddistanceview' => 1,
    20213629    'atob0' => 1,
    20223630    'atob1' => 1,
    20233631    'atob2' => 1,
     3632    'attachedfile' => 1,
     3633    'attachedfiledata' => 1,
     3634    'attachedfiledescription' => 1,
     3635    'attachedfilemimetype' => 1,
     3636    'attachedfilename' => 1,
     3637    'attachedfilereferral' => 1,
     3638    'attachedfileuid' => 1,
     3639    'attachments' => 1,
    20243640    'audiences' => 1,
    2025     'audiobitrate' => 1,
     3641    'audioattributes' => 1,
     3642    'audioavgbitrate' => 1,
     3643    'audiobitspersample' => 1,
    20263644    'audiobytes' => 1,
    2027     'audiochannels' => 1,
     3645    'audiocodec' => 1,
    20283646    'audiocodecdescription' => 1,
    20293647    'audiocodecid' => 1,
     3648    'audiocodecinfo' => 1,
    20303649    'audiocodecname' => 1,
    20313650    'audiodelay' => 1,
     
    20353654    'audioformat' => 1,
    20363655    'audioframesize' => 1,
     3656    'audiogain' => 1,
     3657    'audioheader' => 1,
    20373658    'audioinfo' => 1,
    20383659    'audiolayer' => 1,
     3660    'audiomaxbitrate' => 1,
    20393661    'audiomode' => 1,
    2040     'audiosamplebits' => 1,
     3662    'audioprofile' => 1,
     3663    'audioprofileversion' => 1,
     3664    'audiosamplecount' => 1,
     3665    'audiosampledesc' => 1,
    20413666    'audiosamplesize' => 1,
    20423667    'audiosize' => 1,
    20433668    'audiosourceurl' => 1,
    20443669    'audiostream' => 1,
     3670    'audiostreamtype' => 1,
     3671    'audiotrackid' => 1,
     3672    'audiovendorid' => 1,
     3673    'authenticationtime' => 1,
     3674    'authenticationtype' => 1,
    20453675    'authorlen' => 1,
    20463676    'authorship' => 1,
     
    20513681    'avgbytespersec' => 1,
    20523682    'avgpacketsize' => 1,
     3683    'avgpdusize' => 1,
     3684    'avgwidth' => 1,
     3685    'avi1' => 1,
    20533686    'avif' => 1,
    20543687    'aviheader' => 1,
     3688    'awbinfo' => 1,
     3689    'axisdistancex' => 1,
     3690    'axisdistancey' => 1,
     3691    'axisdistancez' => 1,
    20553692    'background' => 1,
    20563693    'backgroundcolor' => 1,
     
    20613698    'backlight' => 1,
    20623699    'backserial' => 1,
     3700    'backuptime' => 1,
    20633701    'badfaxlines' => 1,
     3702    'balance' => 1,
    20643703    'band' => 1,
    20653704    'bandwidthsharing' => 1,
     
    20683707    'bannerimagetype' => 1,
    20693708    'bannerimageurl' => 1,
     3709    'baselinelength' => 1,
     3710    'baseviewpointnum' => 1,
    20703711    'basisobject' => 1,
     3712    'bass' => 1,
    20713713    'batteryinfo' => 1,
    2072     'batterylevel' => 1,
    20733714    'beatsperminute' => 1,
    20743715    'binaryfilter' => 1,
     3716    'binaryxml' => 1,
    20753717    'bitrate' => 1,
    20763718    'bitratemutualexclusion' => 1,
    20773719    'bitsperextendedrunlength' => 1,
     3720    'bitsperpixel' => 1,
    20783721    'bitsperrunlength' => 1,
    20793722    'blackleveldeltah' => 1,
    20803723    'blackleveldeltav' => 1,
    2081     'blacklevelrepeatdim' => 1,
     3724    'blackmaskbottomborder' => 1,
     3725    'blackmaskleftborder' => 1,
     3726    'blackmaskrightborder' => 1,
     3727    'blackmasktopborder' => 1,
     3728    'block' => 1,
     3729    'blockaddid' => 1,
     3730    'blockadditional' => 1,
     3731    'blockadditionalid' => 1,
     3732    'blockadditions' => 1,
     3733    'blockduration' => 1,
     3734    'blockgroup' => 1,
    20823735    'blocklocation' => 1,
     3736    'blockmore' => 1,
    20833737    'blocksize' => 1,
    20843738    'blocksizemax' => 1,
    20853739    'blocksizemin' => 1,
     3740    'blockspercolumn' => 1,
    20863741    'blocksperframe' => 1,
     3742    'blocksperrow' => 1,
     3743    'blockvirtual' => 1,
    20873744    'blueadjust' => 1,
    20883745    'bluegain' => 1,
     
    20933750    'bluex' => 1,
    20943751    'bluey' => 1,
     3752    'booktitle' => 1,
    20953753    'bordercolor' => 1,
    20963754    'borderid' => 1,
     
    21043762    'boundingbox' => 1,
    21053763    'bracketshot' => 1,
     3764    'breakchar' => 1,
    21063765    'brightnessdata' => 1,
    21073766    'broadcast' => 1,
     3767    'broadcastextension' => 1,
    21083768    'btoa0' => 1,
    21093769    'btoa1' => 1,
    21103770    'btoa2' => 1,
     3771    'btod0' => 1,
     3772    'btod1' => 1,
     3773    'btod2' => 1,
     3774    'btod3' => 1,
    21113775    'bufferaverage' => 1,
    2112     'burstshot' => 1,
     3776    'builddate' => 1,
     3777    'buildversion' => 1,
    21133778    'bw_halftoninginfo' => 1,
    21143779    'bw_transferfunc' => 1,
     3780    'bwfversion' => 1,
     3781    'bytelength' => 1,
    21153782    'bytes' => 1,
    21163783    'bytesperminute' => 1,
     
    21203787    'calibrationdatetime' => 1,
    21213788    'camera' => 1,
     3789    'camera1' => 1,
     3790    'camera2' => 1,
     3791    'cameraarrangementinterval' => 1,
    21223792    'camerabacktype' => 1,
    2123     'cameracalibration1' => 1,
    2124     'cameracalibration2' => 1,
     3793    'camerabody' => 1,
     3794    'camerabyteorder' => 1,
    21253795    'cameradatetime' => 1,
     3796    'cameradirection' => 1,
     3797    'cameraidentifier' => 1,
    21263798    'camerainfo' => 1,
     3799    'camerainfo5dmkii_2a' => 1,
     3800    'camerainfo5dmkii_2b' => 1,
     3801    'camerainfo7d_2a' => 1,
     3802    'camerainfo7d_2b' => 1,
     3803    'cameramotion' => 1,
    21273804    'cameraname' => 1,
    21283805    'cameraobjbacktype' => 1,
     
    21313808    'cameraobjtype' => 1,
    21323809    'cameraobjversion' => 1,
    2133     'cameraowner' => 1,
    21343810    'cameraprofileversion' => 1,
    21353811    'camerasettings' => 1,
    21363812    'camerasettings2' => 1,
     3813    'camerasettingsa100' => 1,
     3814    'camerasettingsifd' => 1,
     3815    'camerasettingsunknown' => 1,
    21373816    'camerasetup' => 1,
    21383817    'cameraspecification' => 1,
     
    21443823    'canonafinfo' => 1,
    21453824    'canonafinfo2' => 1,
    2146     'canoncamerainfo' => 1,
     3825    'canoncamerainfo1000d' => 1,
     3826    'canoncamerainfo1d' => 1,
     3827    'canoncamerainfo1dmkii' => 1,
    21473828    'canoncamerainfo1dmkiii' => 1,
    2148     'canoncamerainfo2' => 1,
     3829    'canoncamerainfo1dmkiin' => 1,
     3830    'canoncamerainfo1dmkiv' => 1,
     3831    'canoncamerainfo40d' => 1,
     3832    'canoncamerainfo450d' => 1,
     3833    'canoncamerainfo500d' => 1,
     3834    'canoncamerainfo50d' => 1,
     3835    'canoncamerainfo550d' => 1,
     3836    'canoncamerainfo5d' => 1,
     3837    'canoncamerainfo5dmkii' => 1,
     3838    'canoncamerainfo60d' => 1,
     3839    'canoncamerainfo7d' => 1,
     3840    'canoncamerainfopowershot' => 1,
     3841    'canoncamerainfopowershot2' => 1,
     3842    'canoncamerainfounknown' => 1,
    21493843    'canoncamerainfounknown16' => 1,
    21503844    'canoncamerainfounknown32' => 1,
    2151     'canoncamerainfounknown8' => 1,
    21523845    'canoncamerasettings' => 1,
     3846    'canoncnth' => 1,
    21533847    'canoncolorinfo1' => 1,
    21543848    'canoncolorinfo2' => 1,
     
    21613855    'canonrawmakemodel' => 1,
    21623856    'canonshotinfo' => 1,
     3857    'canseekontime' => 1,
    21633858    'canseektoend' => 1,
     3859    'capheight' => 1,
    21643860    'captiontext' => 1,
    21653861    'captprofbacktype' => 1,
     
    21823878    'captureyresolutionunit' => 1,
    21833879    'casio' => 1,
     3880    'casiodata' => 1,
     3881    'casiojunk' => 1,
     3882    'casioquality' => 1,
     3883    'casioqvmi' => 1,
    21843884    'cc' => 1,
    21853885    'ccdrect' => 1,
    21863886    'ccdvalidrect' => 1,
    21873887    'ccdvideorect' => 1,
     3888    'cell' => 1,
    21883889    'centerdarkrect' => 1,
    21893890    'cfalayout' => 1,
     
    21923893    'cfarepeatpatterndim' => 1,
    21933894    'channelmode' => 1,
    2194     'charcount' => 1,
     3895    'channelpositions' => 1,
     3896    'chapter' => 1,
     3897    'chapteratom' => 1,
     3898    'chaptercountry' => 1,
     3899    'chapterdisplay' => 1,
     3900    'chapterflagenabled' => 1,
     3901    'chapterflaghidden' => 1,
     3902    'chapterlanguage' => 1,
     3903    'chapterlist' => 1,
     3904    'chapterphysicalequivalent' => 1,
     3905    'chapterprocess' => 1,
     3906    'chapterprocesscodecid' => 1,
     3907    'chapterprocesscommand' => 1,
     3908    'chapterprocessdata' => 1,
     3909    'chapterprocessprivate' => 1,
     3910    'chapterprocesstime' => 1,
     3911    'chapters' => 1,
     3912    'chaptersegmenteditionuid' => 1,
     3913    'chaptersegmentuid' => 1,
     3914    'chapterstring' => 1,
     3915    'chaptertimeend' => 1,
     3916    'chaptertimestart' => 1,
     3917    'chaptertrack' => 1,
     3918    'chaptertracknumber' => 1,
     3919    'chaptertranslate' => 1,
     3920    'chaptertranslatecodec' => 1,
     3921    'chaptertranslateeditionuid' => 1,
     3922    'chaptertranslateid' => 1,
     3923    'chapteruid' => 1,
     3924    'characters' => 1,
     3925    'characterset' => 1,
     3926    'characterswithspaces' => 1,
    21953927    'charcountwithspaces' => 1,
    2196     'charset' => 1,
    21973928    'chartarget' => 1,
     3929    'checkedby' => 1,
    21983930    'chromaticadaptation' => 1,
    21993931    'chromaticity' => 1,
     
    22043936    'chromaticitychannels' => 1,
    22053937    'chromaticitycolorant' => 1,
     3938    'chunkoffset' => 1,
     3939    'chunkoffset64' => 1,
    22063940    'ciff' => 1,
     3941    'cinematographer' => 1,
     3942    'cip3datafile' => 1,
     3943    'cip3sheet' => 1,
     3944    'cip3side' => 1,
    22073945    'circleofconfusion' => 1,
    22083946    'class' => 1,
     
    22173955    'cloneobject' => 1,
    22183956    'clonetype' => 1,
     3957    'cluster' => 1,
     3958    'clusterduration' => 1,
    22193959    'cmmflags' => 1,
     3960    'cmykequivalent' => 1,
     3961    'codecdecodeall' => 1,
     3962    'codecdownloadurl' => 1,
    22203963    'codecflavorid' => 1,
     3964    'codecid' => 1,
     3965    'codecinfourl' => 1,
    22213966    'codeclist' => 1,
     3967    'codecname' => 1,
     3968    'codecprivate' => 1,
     3969    'codecsettings' => 1,
     3970    'codecstate' => 1,
    22223971    'codedframesize' => 1,
    22233972    'codepage' => 1,
     3973    'codesize' => 1,
    22243974    'codestreamheader' => 1,
    22253975    'codestreamregistration' => 1,
     3976    'codinghistory' => 1,
    22263977    'codingmethods' => 1,
     3978    'color' => 1,
    22273979    'colorant1coordinates' => 1,
    22283980    'colorant1name' => 1,
     
    22343986    'colorantorder' => 1,
    22353987    'coloranttable' => 1,
     3988    'coloranttableout' => 1,
    22363989    'coloraverages' => 1,
    22373990    'colorbalance0100' => 1,
     
    22403993    'colorbalance02' => 1,
    22413994    'colorbalance0205' => 1,
    2242     'colorbalance2' => 1,
    2243     'colorbalance3' => 1,
     3995    'colorbalance0209' => 1,
     3996    'colorbalancea' => 1,
    22443997    'colorbalanceunknown' => 1,
    22453998    'colorbitdepth' => 1,
    22463999    'colorboostdata' => 1,
    22474000    'colorbw' => 1,
     4001    'colorcalib' => 1,
    22484002    'colorcalibrationmatrix' => 1,
    22494003    'colorcasts' => 1,
    22504004    'colorcharacterization' => 1,
     4005    'colorcoefs' => 1,
    22514006    'colorcomponents' => 1,
     4007    'colordata1' => 1,
     4008    'colordata2' => 1,
     4009    'colordata3' => 1,
     4010    'colordata4' => 1,
     4011    'colordata5' => 1,
     4012    'colordata6' => 1,
     4013    'colordataunknown' => 1,
    22524014    'colorgroup' => 1,
    22534015    'colorhalftoninginfo' => 1,
     4016    'colorimetricintentimagestate' => 1,
     4017    'colorimetry' => 1,
    22544018    'colorinfo' => 1,
    2255     'colorinfod30' => 1,
    22564019    'colormap' => 1,
    2257     'colormatrix1' => 1,
    22584020    'colorobjbacktype' => 1,
    22594021    'colorobjname' => 1,
     
    22614023    'colorobjversion' => 1,
    22624024    'colorpalette' => 1,
     4025    'colorresolutiondepth' => 1,
    22634026    'colorresponseunit' => 1,
    22644027    'colors' => 1,
     
    22724035    'colortwistmatrix' => 1,
    22734036    'colortype' => 1,
     4037    'commandlinearguments' => 1,
    22744038    'commentlen' => 1,
    22754039    'comments' => 1,
     
    22784042    'commissioned' => 1,
    22794043    'common' => 1,
     4044    'commonnetworkrellink' => 1,
     4045    'commonpathsuffix' => 1,
     4046    'compactsamplesizes' => 1,
    22804047    'company' => 1,
     4048    'companyname' => 1,
    22814049    'compatibility' => 1,
     4050    'compatiblebrands' => 1,
     4051    'compatiblefontname' => 1,
    22824052    'compilation' => 1,
    22834053    'compobj' => 1,
     
    22874057    'componentdefinition' => 1,
    22884058    'componentmapping' => 1,
     4059    'composerkeywords' => 1,
    22894060    'compositinglayerheader' => 1,
    22904061    'composition' => 1,
    22914062    'compositionmode' => 1,
    22924063    'compositionoptions' => 1,
     4064    'compositiontimetosample' => 1,
     4065    'compositiontodecodetimelinemapping' => 1,
    22934066    'compressed' => 1,
     4067    'compressedannotation' => 1,
     4068    'compresseddatalength' => 1,
     4069    'compresseddataoffset' => 1,
     4070    'compressedsize' => 1,
    22944071    'compressedtext' => 1,
    22954072    'compressionlevel' => 1,
    22964073    'compressiontype' => 1,
    2297     'compressor' => 1,
    22984074    'compressorid' => 1,
     4075    'compressorname' => 1,
     4076    'compressorversion' => 1,
    22994077    'concreteflag' => 1,
    23004078    'condition' => 1,
     
    23044082    'connectionspaceilluminant' => 1,
    23054083    'consecutivebadfaxlines' => 1,
     4084    'consoledata' => 1,
     4085    'consolefedata' => 1,
    23064086    'cont' => 1,
    23074087    'containerformat' => 1,
     4088    'containerversion' => 1,
    23084089    'contake' => 1,
    23094090    'contentbranding' => 1,
     4091    'contentcompression' => 1,
     4092    'contentcompressionalgorithm' => 1,
     4093    'contentcompressionsettings' => 1,
    23104094    'contentdescription' => 1,
    23114095    'contentdescriptionnotes' => 1,
    23124096    'contentdisposition' => 1,
    23134097    'contentdistributor' => 1,
     4098    'contentencoding' => 1,
     4099    'contentencodingorder' => 1,
     4100    'contentencodings' => 1,
     4101    'contentencodingscope' => 1,
     4102    'contentencodingtype' => 1,
    23144103    'contentencryption' => 1,
     4104    'contentencryptionalgorithm' => 1,
     4105    'contentencryptionkeyid' => 1,
    23154106    'contentgroupdescription' => 1,
    23164107    'contentlanguage' => 1,
    23174108    'contentrating' => 1,
     4109    'contents' => 1,
    23184110    'contentscripttype' => 1,
     4111    'contentsignature' => 1,
     4112    'contentsignaturealgorithm' => 1,
     4113    'contentsignaturehashalgorithm' => 1,
     4114    'contentsignaturekeyid' => 1,
    23194115    'contentstyletype' => 1,
    23204116    'contenttype' => 1,
    23214117    'contiguouscodestream' => 1,
    23224118    'contrastadjustment' => 1,
     4119    'contrastcurve' => 1,
     4120    'convergenceangle' => 1,
     4121    'convergencebaseimage' => 1,
     4122    'convergencedistance' => 1,
    23234123    'copyrightlen' => 1,
    23244124    'copyrighturl' => 1,
     4125    'costumedesigner' => 1,
    23254126    'coverart' => 1,
    23264127    'coverartmimetype' => 1,
     4128    'cpuarchitecture' => 1,
     4129    'cpubyteorder' => 1,
     4130    'cpucount' => 1,
     4131    'cpusubtype' => 1,
     4132    'cputype' => 1,
    23274133    'cpuversions' => 1,
     4134    'crc-32' => 1,
     4135    'crcdevelparams' => 1,
    23284136    'crdinfo' => 1,
     4137    'createdby' => 1,
    23294138    'creatingapplication' => 1,
    23304139    'creatingtransform' => 1,
    23314140    'creationpathvector' => 1,
     4141    'creatorappid' => 1,
     4142    'creatorapplication' => 1,
     4143    'creatorappversion' => 1,
     4144    'creatorinfo' => 1,
     4145    'creatorversion' => 1,
    23324146    'cropdata' => 1,
     4147    'cropinfo' => 1,
    23334148    'cropped' => 1,
     4149    'cropx' => 1,
     4150    'cropxcommonoffset' => 1,
     4151    'cropxoffset' => 1,
     4152    'cropxoffset2' => 1,
     4153    'cropxsize' => 1,
     4154    'cropxviewpointnumber' => 1,
     4155    'cropxviewpointnumber2' => 1,
     4156    'cropy' => 1,
     4157    'cropycommonoffset' => 1,
     4158    'cropyoffset' => 1,
     4159    'cropyoffset2' => 1,
     4160    'cropysize' => 1,
     4161    'cropyviewpointnumber' => 1,
     4162    'cropyviewpointnumber2' => 1,
    23344163    'cross-reference' => 1,
     4164    'crossref' => 1,
    23354165    'crs' => 1,
     4166    'crwparam' => 1,
     4167    'cueblocknumber' => 1,
     4168    'cueclusterposition' => 1,
     4169    'cuecodecstate' => 1,
    23364170    'cuepoint' => 1,
     4171    'cuerefcluster' => 1,
     4172    'cuerefcodecstate' => 1,
     4173    'cuereference' => 1,
     4174    'cuerefnumber' => 1,
     4175    'cuereftime' => 1,
     4176    'cues' => 1,
     4177    'cuetime' => 1,
     4178    'cuetrack' => 1,
     4179    'cuetrackpositions' => 1,
    23374180    'currentbitrate' => 1,
     4181    'currentiptcdigest' => 1,
    23384182    'currenttime' => 1,
    23394183    'currentuser' => 1,
     4184    'cursorsize' => 1,
    23404185    'customfunctions10d' => 1,
    23414186    'customfunctions1d' => 1,
     
    23494194    'customfunctionsd60' => 1,
    23504195    'customfunctionsunknown' => 1,
     4196    'custompicturestyledata' => 1,
     4197    'customsettingsd3' => 1,
     4198    'customsettingsd300' => 1,
     4199    'customsettingsd300s' => 1,
     4200    'customsettingsd3s' => 1,
     4201    'customsettingsd3x' => 1,
     4202    'customsettingsd40' => 1,
     4203    'customsettingsd5000' => 1,
     4204    'customsettingsd700' => 1,
     4205    'customsettingsd7000' => 1,
     4206    'customsettingsd80' => 1,
     4207    'customsettingsd90' => 1,
    23514208    'd-lightinghqdata' => 1,
    23524209    'd-lightinghsdata' => 1,
    23534210    'darkcorrectiontype' => 1,
     4211    'darwindata' => 1,
    23544212    'data' => 1,
     4213    'data1' => 1,
     4214    'data2' => 1,
    23554215    'datacreatedate' => 1,
    23564216    'datadump' => 1,
    23574217    'datadump2' => 1,
     4218    'datainfo' => 1,
     4219    'datainformation' => 1,
    23584220    'datakey' => 1,
    23594221    'datalen' => 1,
     4222    'datalength' => 1,
     4223    'datalocation' => 1,
    23604224    'datamodifydate' => 1,
    23614225    'dataobject' => 1,
     
    23664230    'dataoffsets' => 1,
    23674231    'datapackets' => 1,
     4232    'dataref' => 1,
    23684233    'datareference' => 1,
    23694234    'datasize' => 1,
    23704235    'datatype' => 1,
     4236    'datecompleted' => 1,
     4237    'datetime1' => 1,
     4238    'datetime2' => 1,
    23714239    'datetimecreated' => 1,
     4240    'datetimeend' => 1,
    23724241    'dc' => 1,
     4242    'dcmd' => 1,
     4243    'dcme' => 1,
    23734244    'dctencodeversion' => 1,
    23744245    'dealeridnumber' => 1,
     
    23774248    'decode' => 1,
    23784249    'decodertable' => 1,
     4250    'decodertablenumber' => 1,
     4251    'defaultaudiostream' => 1,
     4252    'defaultchar' => 1,
    23794253    'defaultdisplayheight' => 1,
    23804254    'defaultdisplaywidth' => 1,
     4255    'defaultduration' => 1,
    23814256    'defaultimagecolor' => 1,
    23824257    'defaultrgb' => 1,
    23834258    'defaultstyle' => 1,
    23844259    'defineobject' => 1,
     4260    'definequantizationtable' => 1,
    23854261    'delay' => 1,
    23864262    'deltapngheader' => 1,
    23874263    'deltatype' => 1,
    23884264    'deltaxy' => 1,
     4265    'department' => 1,
     4266    'dependentimage1entrynumber' => 1,
     4267    'dependentimage2entrynumber' => 1,
    23894268    'depth' => 1,
     4269    'descender' => 1,
     4270    'designer' => 1,
     4271    'designerurl' => 1,
    23904272    'desiredreproductions' => 1,
    23914273    'destinationid' => 1,
     
    23954277    'devicemodel' => 1,
    23964278    'devicemodeldesc' => 1,
    2397     'devicesettingdescription' => 1,
     4279    'devicename' => 1,
    23984280    'devicesettings' => 1,
    23994281    'dex' => 1,
    24004282    'dicom' => 1,
    24014283    'dictionary' => 1,
     4284    'digikam' => 1,
     4285    'digitalcreationdatetime' => 1,
    24024286    'digitaleffectsname' => 1,
    24034287    'digitaleffectstype' => 1,
     
    24064290    'digitalsignature' => 1,
    24074291    'dimensions' => 1,
    2408     'dinf' => 1,
    2409     'director' => 1,
    24104292    'discardobjects' => 1,
    24114293    'disknumber' => 1,
     4294    'displayheight' => 1,
    24124295    'displayinfo' => 1,
    24134296    'displayresolution' => 1,
    24144297    'displaysize' => 1,
     4298    'displayunit' => 1,
    24154299    'displayunits' => 1,
     4300    'displaywidth' => 1,
    24164301    'displayxresolution' => 1,
    24174302    'displayxresolutionunit' => 1,
     
    24194304    'displayyresolutionunit' => 1,
    24204305    'dispose' => 1,
     4306    'disposition' => 1,
     4307    'distortinfo' => 1,
     4308    'distortionversion' => 1,
     4309    'distributedby' => 1,
    24214310    'distribution' => 1,
     4311    'division' => 1,
     4312    'djvuversion' => 1,
    24224313    'dngadobedata' => 1,
    2423     'dngpentaxdata' => 1,
    24244314    'dngprivatedata' => 1,
    24254315    'docclass' => 1,
     4316    'docmdp' => 1,
    24264317    'docrights' => 1,
     4318    'docsecurity' => 1,
    24274319    'doctype' => 1,
     4320    'doctypereadversion' => 1,
     4321    'doctypeversion' => 1,
    24284322    'documentinfo' => 1,
     4323    'documentnumber' => 1,
     4324    'documentusagerights' => 1,
    24294325    'dof' => 1,
    24304326    'donotshow' => 1,
    24314327    'dotsperinch' => 1,
     4328    'driveserialnumber' => 1,
     4329    'drivetype' => 1,
    24324330    'drm' => 1,
    24334331    'drm_contentid' => 1,
     
    24494347    'dropbykeyword' => 1,
    24504348    'dropchunks' => 1,
     4349    'dtob0' => 1,
     4350    'dtob1' => 1,
     4351    'dtob2' => 1,
     4352    'dtob3' => 1,
    24514353    'ducky' => 1,
    24524354    'duotonehalftoninginfo' => 1,
    24534355    'duotoneimageinfo' => 1,
    24544356    'duotonetransferfuncs' => 1,
    2455     'dustremovaldata' => 1,
    24564357    'dvdid' => 1,
    2457     'dynamicrangeoptimizer' => 1,
     4358    'ebmlheader' => 1,
     4359    'ebmlmaxidlength' => 1,
     4360    'ebmlmaxsizelength' => 1,
     4361    'ebmlreadversion' => 1,
     4362    'ebmlversion' => 1,
    24584363    'edit1' => 1,
    24594364    'edit2' => 1,
     
    24654370    'edit8' => 1,
    24664371    'edit9' => 1,
     4372    'editdata' => 1,
     4373    'editedby' => 1,
     4374    'editionentry' => 1,
     4375    'editionflagdefault' => 1,
     4376    'editionflaghidden' => 1,
     4377    'editionflagordered' => 1,
     4378    'editionuid' => 1,
     4379    'editor' => 1,
    24674380    'edittagarray' => 1,
     4381    'effect' => 1,
    24684382    'effectivebw' => 1,
    2469     'effectivemaxaperture' => 1,
    24704383    'effectsvisible' => 1,
     4384    'eighthlanguage' => 1,
     4385    'embeddedfile' => 1,
     4386    'embeddedfilename' => 1,
     4387    'embeddedfileusagerights' => 1,
    24714388    'emphasis' => 1,
    24724389    'encodedby' => 1,
     
    24774394    'encoding' => 1,
    24784395    'encodingprocess' => 1,
     4396    'encodingscheme' => 1,
    24794397    'encodingsettings' => 1,
    24804398    'encodingtime' => 1,
     4399    'encrypt' => 1,
     4400    'encryptedblock' => 1,
    24814401    'encryption' => 1,
    24824402    'endpoints' => 1,
     4403    'endtime' => 1,
     4404    'endtimecode' => 1,
     4405    'entrypoint' => 1,
     4406    'envvardata' => 1,
     4407    'episodeglobaluniqueid' => 1,
    24834408    'eppim' => 1,
     4409    'eprint' => 1,
    24844410    'epsoptions' => 1,
    24854411    'equipment' => 1,
    2486     'equipment2' => 1,
     4412    'equipmentifd' => 1,
    24874413    'error' => 1,
    24884414    'errorcorrection' => 1,
    24894415    'errorcorrectiontype' => 1,
     4416    'escchar' => 1,
    24904417    'evalstate' => 1,
    24914418    'events' => 1,
    2492     'exif' => 1,
     4419    'evstepinfo' => 1,
    24934420    'exif_profile' => 1,
     4421    'exifdata' => 1,
    24944422    'exifinfo' => 1,
     4423    'exifinfo2' => 1,
    24954424    'exifinformation' => 1,
    24964425    'exifoffset' => 1,
    24974426    'exiftoolversion' => 1,
    2498     'exitpupilposition' => 1,
     4427    'expandfilm' => 1,
     4428    'expandfilterlens' => 1,
     4429    'expandflashlamp' => 1,
     4430    'expandlens' => 1,
     4431    'expandscanner' => 1,
     4432    'expandsoftware' => 1,
    24994433    'expires' => 1,
    25004434    'exportimage' => 1,
    2501     'exposureadjust' => 1,
     4435    'exposurebias' => 1,
    25024436    'exposureinfo' => 1,
     4437    'exposureunknown' => 1,
    25034438    'extcache' => 1,
     4439    'extendedaviheader' => 1,
    25044440    'extendedcontentdescr' => 1,
    25054441    'extendedcontentencryption' => 1,
     4442    'extendedinfo' => 1,
    25064443    'extendedstreamprops' => 1,
     4444    'extendedxmp' => 1,
    25074445    'extenderstatus' => 1,
    25084446    'extensionclassid' => 1,
     
    25134451    'extensionpersistence' => 1,
    25144452    'extensions' => 1,
     4453    'externalleading' => 1,
     4454    'extraflags' => 1,
    25154455    'extrasamples' => 1,
     4456    'face1birthday' => 1,
     4457    'face1category' => 1,
     4458    'face1name' => 1,
     4459    'face2birthday' => 1,
     4460    'face2category' => 1,
     4461    'face2name' => 1,
     4462    'face3birthday' => 1,
     4463    'face3category' => 1,
     4464    'face3name' => 1,
     4465    'face4birthday' => 1,
     4466    'face4category' => 1,
     4467    'face4name' => 1,
     4468    'face5birthday' => 1,
     4469    'face5category' => 1,
     4470    'face5name' => 1,
     4471    'face6birthday' => 1,
     4472    'face6category' => 1,
     4473    'face6name' => 1,
     4474    'face7birthday' => 1,
     4475    'face7category' => 1,
     4476    'face7name' => 1,
     4477    'face8birthday' => 1,
     4478    'face8category' => 1,
     4479    'face8name' => 1,
    25164480    'facedetect1' => 1,
    25174481    'facedetect2' => 1,
     4482    'facedetinfo' => 1,
     4483    'faceinfo' => 1,
     4484    'faceinfo1' => 1,
     4485    'faceinfo2' => 1,
     4486    'faceinfolength' => 1,
     4487    'faceinfooffset' => 1,
     4488    'facepos' => 1,
     4489    'facerecinfo' => 1,
     4490    'facesize' => 1,
    25184491    'fastseek' => 1,
    25194492    'faxprofile' => 1,
     
    25214494    'faxrecvtime' => 1,
    25224495    'faxsubaddress' => 1,
     4496    'fieldmdp' => 1,
     4497    'fieldpermissions' => 1,
     4498    'fifthlanguage' => 1,
     4499    'fileattributes' => 1,
     4500    'filedescription' => 1,
     4501    'fileflags' => 1,
     4502    'fileflagsmask' => 1,
     4503    'filefunctionflags' => 1,
     4504    'fileglobalprofile' => 1,
    25234505    'fileid' => 1,
     4506    'fileinfo' => 1,
    25244507    'fileinfolen' => 1,
    25254508    'fileinfolen2' => 1,
    25264509    'fileinfoproperties' => 1,
    25274510    'fileinfoversion' => 1,
     4511    'filelength' => 1,
     4512    'fileos' => 1,
    25284513    'fileowner' => 1,
     4514    'filepermissions' => 1,
     4515    'fileprofileversion' => 1,
    25294516    'fileproperties' => 1,
    2530     'filerul' => 1,
    25314517    'files' => 1,
    25324518    'filesize' => 1,
    25334519    'filesizebytes' => 1,
     4520    'filesubtype' => 1,
    25344521    'filetype' => 1,
     4522    'fileurl' => 1,
     4523    'fileversionnumber' => 1,
     4524    'fillattributes' => 1,
    25354525    'fillmethod' => 1,
    25364526    'filmbrand' => 1,
     
    25414531    'filmrollnumber' => 1,
    25424532    'filmsize' => 1,
     4533    'filter' => 1,
     4534    'filterinfo' => 1,
    25434535    'filtering' => 1,
    25444536    'finalframeblocks' => 1,
     4537    'firmwareinfo' => 1,
     4538    'firstchar' => 1,
     4539    'firstlanguage' => 1,
    25454540    'firstobject' => 1,
    25464541    'firstobjectid' => 1,
     
    25484543    'flashexpcomp' => 1,
    25494544    'flashinfo' => 1,
    2550     'flashon' => 1,
     4545    'flashinfo0100' => 1,
     4546    'flashinfo0102' => 1,
     4547    'flashinfo0103' => 1,
     4548    'flashinfo0104' => 1,
     4549    'flashinfounknown' => 1,
     4550    'flashinfoversion' => 1,
    25514551    'flashpixstreamfieldoffset' => 1,
    25524552    'flashpixstreampathname' => 1,
    25534553    'flashpower' => 1,
     4554    'flashsyncmode' => 1,
    25544555    'flashttlmode' => 1,
    25554556    'flashversion' => 1,
     4557    'flavor' => 1,
    25564558    'focallength35efl' => 1,
     4559    'focalplanecolorimetryestimates' => 1,
     4560    'focalrange' => 1,
    25574561    'focusinfo' => 1,
    2558     'focusinfo2' => 1,
     4562    'focusinfoifd' => 1,
    25594563    'focuspos' => 1,
     4564    'font' => 1,
     4565    'fontsize' => 1,
     4566    'fontsubfamily' => 1,
     4567    'fontsubfamilyid' => 1,
     4568    'fontweight' => 1,
     4569    'footerposition' => 1,
    25604570    'footnotes' => 1,
     4571    'form' => 1,
    25614572    'formatter' => 1,
    25624573    'formatversion' => 1,
    25634574    'formatversiontime' => 1,
     4575    'formfields' => 1,
     4576    'formusagerights' => 1,
     4577    'forwardto' => 1,
    25644578    'fotostation' => 1,
    25654579    'fourcc1' => 1,
     
    25684582    'fourcc3' => 1,
    25694583    'fourcc3len' => 1,
     4584    'fourthlanguage' => 1,
     4585    'fov' => 1,
    25704586    'fpxr' => 1,
    25714587    'fractalparameters' => 1,
     
    25734589    'fragmenttable' => 1,
    25744590    'frame' => 1,
    2575     'framecount' => 1,
     4591    'frameheight' => 1,
     4592    'frameinfo' => 1,
    25764593    'framepriority' => 1,
    2577     'framerate' => 1,
     4594    'framereadouttime' => 1,
    25784595    'framesize' => 1,
    25794596    'framesizemax' => 1,
    25804597    'framesizemin' => 1,
    2581     'frametype' => 1,
     4598    'framewidth' => 1,
    25824599    'free' => 1,
    25834600    'freebytecounts' => 1,
    25844601    'freeoffsets' => 1,
     4602    'fstype' => 1,
    25854603    'fujifilm' => 1,
     4604    'fujifilmffmv' => 1,
     4605    'fujifilmmvtg' => 1,
    25864606    'fujilayout' => 1,
     4607    'fullname' => 1,
     4608    'fullscreen' => 1,
    25874609    'gain' => 1,
    25884610    'gamut' => 1,
     
    25914613    'gdalnodata' => 1,
    25924614    'geminfo' => 1,
     4615    'genbalance' => 1,
    25934616    'generator' => 1,
     4617    'genflags' => 1,
     4618    'gengraphicsmode' => 1,
     4619    'genmediaheader' => 1,
     4620    'genmediainfo' => 1,
     4621    'genmediaversion' => 1,
     4622    'genopcolor' => 1,
    25944623    'genr' => 1,
    25954624    'genreid' => 1,
     
    26164645    'gifgraphiccontrolextension' => 1,
    26174646    'gifplaintextextension' => 1,
     4647    'gifversion' => 1,
    26184648    'globalinfo' => 1,
    26194649    'globalparametersifd' => 1,
     
    26214651    'googlebot' => 1,
    26224652    'gps' => 1,
     4653    'gpscoordinates' => 1,
    26234654    'gpsinfo' => 1,
    26244655    'gpsposition' => 1,
     4656    'grainybwfilter' => 1,
    26254657    'graphicconverter' => 1,
     4658    'graphicsmode' => 1,
    26264659    'graphicstechnologystandardoutput' => 1,
    26274660    'grayresponsecurve' => 1,
     
    26364669    'greeny' => 1,
    26374670    'gridguidesinfo' => 1,
     4671    'group' => 1,
    26384672    'groupcaption' => 1,
    26394673    'grouping' => 1,
     
    26424676    'gtmodeltype' => 1,
    26434677    'gtrastertype' => 1,
     4678    'handler' => 1,
     4679    'handlerclass' => 1,
     4680    'handlerdescription' => 1,
     4681    'handlertype' => 1,
     4682    'handlervendorid' => 1,
    26444683    'hasarbitrarydatastream' => 1,
    26454684    'hasattachedimages' => 1,
    26464685    'hasaudio' => 1,
     4686    'hascolormap' => 1,
    26474687    'hascuepoints' => 1,
    26484688    'hasfiletransferstream' => 1,
     
    26554695    'hcusage' => 1,
    26564696    'hdrl' => 1,
     4697    'hdvideo' => 1,
    26574698    'header' => 1,
    26584699    'headerext' => 1,
     
    26624703    'heightresolution' => 1,
    26634704    'hiddenslides' => 1,
     4705    'highlightdata' => 1,
    26644706    'highlightendpoints' => 1,
     4707    'hintformat' => 1,
     4708    'hintheader' => 1,
     4709    'hintinfo' => 1,
     4710    'hintsampledesc' => 1,
     4711    'hinttrackinfo' => 1,
     4712    'historybuffersize' => 1,
     4713    'hotkey' => 1,
     4714    'howpublished' => 1,
     4715    'hp_tdhd' => 1,
    26654716    'http-equiv' => 1,
     4717    'httphostheader' => 1,
     4718    'huffmantable' => 1,
    26664719    'hyperfocaldistance' => 1,
    26674720    'hyperlinkbase' => 1,
     
    26704723    'icc_untagged' => 1,
    26714724    'iccbased' => 1,
     4725    'iconenvdata' => 1,
     4726    'iconfilename' => 1,
     4727    'iconindex' => 1,
    26724728    'id' => 1,
    26734729    'id3' => 1,
     4730    'id3size' => 1,
    26744731    'id3v1' => 1,
     4732    'id3v1_enh' => 1,
    26754733    'id3v2_2' => 1,
    26764734    'id3v2_3' => 1,
    26774735    'id3v2_4' => 1,
     4736    'idc2_ifd' => 1,
     4737    'idc_ifd' => 1,
     4738    'idcpreviewimage' => 1,
    26784739    'identification' => 1,
     4740    'idependentanddisposablesamples' => 1,
    26794741    'idsbasevalue' => 1,
    26804742    'ifd0_offset' => 1,
     4743    'ihl_exif' => 1,
     4744    'ihldata' => 1,
     4745    'illustrator' => 1,
    26814746    'image' => 1,
     4747    'imagearrangement' => 1,
     4748    'imageboardid' => 1,
    26824749    'imagebounds' => 1,
    26834750    'imagebytecount' => 1,
     4751    'imageclass' => 1,
     4752    'imagecolor' => 1,
    26844753    'imagecolorindicator' => 1,
    26854754    'imagecolorvalue' => 1,
     
    26964765    'imageoffset' => 1,
    26974766    'imageprintstatus' => 1,
    2698     'imageprocessing2' => 1,
     4767    'imageprocessingifd' => 1,
    26994768    'imageprofile' => 1,
    27004769    'imageprops' => 1,
    27014770    'imagerboardid' => 1,
     4771    'imageresolution' => 1,
    27024772    'imageresources' => 1,
    27034773    'imagerotated' => 1,
     4774    'imagerotation' => 1,
    27044775    'imagerotationstatus' => 1,
    27054776    'imagesourceek' => 1,
    27064777    'imagestatus' => 1,
    27074778    'imagetoolbar' => 1,
     4779    'imageuidlist' => 1,
     4780    'imageversion' => 1,
    27084781    'imgprofbacktype' => 1,
    27094782    'imgprofname' => 1,
    27104783    'imgproftype' => 1,
    27114784    'imgprofversion' => 1,
     4785    'immediatedatabytes' => 1,
     4786    'includedfileid' => 1,
    27124787    'index' => 1,
     4788    'index01' => 1,
     4789    'index02' => 1,
     4790    'index03' => 1,
     4791    'index04' => 1,
     4792    'index05' => 1,
     4793    'index06' => 1,
     4794    'index07' => 1,
     4795    'index08' => 1,
     4796    'index09' => 1,
     4797    'index10' => 1,
     4798    'index11' => 1,
     4799    'index12' => 1,
     4800    'index13' => 1,
     4801    'index14' => 1,
     4802    'index15' => 1,
     4803    'index16' => 1,
    27134804    'indexable' => 1,
    27144805    'indexed' => 1,
     
    27174808    'indexparameters' => 1,
    27184809    'info' => 1,
    2719     'infolist' => 1,
    27204810    'information' => 1,
     4811    'ingrreserved' => 1,
     4812    'initialdisplayeffect' => 1,
     4813    'initializeddatasize' => 1,
    27214814    'initialkey' => 1,
     4815    'initialobjectdescriptor' => 1,
    27224816    'inknames' => 1,
    27234817    'inputdataobjectlist' => 1,
    27244818    'inputprofile' => 1,
     4819    'insertmode' => 1,
     4820    'institution' => 1,
    27254821    'instructionset' => 1,
    27264822    'integrationtime' => 1,
     
    27324828    'intergraphpacketdata' => 1,
    27334829    'interlace' => 1,
     4830    'interleavedfield' => 1,
     4831    'internalidnumber' => 1,
     4832    'internalleading' => 1,
     4833    'internalname' => 1,
     4834    'internalversionnumber' => 1,
    27344835    'internationaltext' => 1,
    27354836    'internetradiostationname' => 1,
     
    27394840    'interpretedby' => 1,
    27404841    'involvedpeople' => 1,
     4842    'ipmpcontrol' => 1,
    27414843    'iptc' => 1,
    27424844    'iptc_profile' => 1,
     
    27454847    'iptcdata' => 1,
    27464848    'iptcenvelope' => 1,
     4849    'iptcext' => 1,
     4850    'iptcfotostation' => 1,
    27474851    'iptcnewsphoto' => 1,
    27484852    'iptcobjectdata' => 1,
     
    27514855    'is_protected' => 1,
    27524856    'is_trusted' => 1,
    2753     'isospeed' => 1,
     4857    'isbasefont' => 1,
     4858    'isfixedpitch' => 1,
     4859    'isfixedv' => 1,
     4860    'isoinfo' => 1,
    27544861    'isrc' => 1,
     4862    'isrccode' => 1,
    27554863    'isrcnumber' => 1,
    27564864    'isvbr' => 1,
    27574865    'it8header' => 1,
     4866    'italic' => 1,
     4867    'italicangle' => 1,
     4868    'itch' => 1,
     4869    'item' => 1,
     4870    'item0032' => 1,
     4871    'itemid' => 1,
     4872    'iteminformation' => 1,
     4873    'itemlist' => 1,
     4874    'itemlocation' => 1,
     4875    'itemprotection' => 1,
    27584876    'iterationcount' => 1,
    27594877    'iterationendaction' => 1,
     
    27664884    'jfxx' => 1,
    27674885    'jngheader' => 1,
     4886    'journal' => 1,
    27684887    'jp2header' => 1,
    27694888    'jp2signature' => 1,
     
    27714890    'jpegactables' => 1,
    27724891    'jpegdctables' => 1,
     4892    'jpegdigest' => 1,
     4893    'jpegexifdata' => 1,
    27734894    'jpeglosslesspredictors' => 1,
    27744895    'jpegpointtransforms' => 1,
    27754896    'jpegproc' => 1,
     4897    'jpegprocess' => 1,
    27764898    'jpegqtables' => 1,
    27774899    'jpegrestartinterval' => 1,
    27784900    'jpegtables' => 1,
    27794901    'jumptoxpep' => 1,
     4902    'junk' => 1,
    27804903    'kbytesize' => 1,
     4904    'kdc_ifd' => 1,
    27814905    'keyframepositions' => 1,
    27824906    'keyframestimes' => 1,
     4907    'keys' => 1,
    27834908    'kids' => 1,
     4909    'knownfolderdata' => 1,
    27844910    'kodak' => 1,
    27854911    'kodakbordersifd' => 1,
    27864912    'kodakeffectsifd' => 1,
     4913    'kodakifd' => 1,
     4914    'kodaktags' => 1,
    27874915    'konicaminolta' => 1,
     4916    'konicaminoltatags' => 1,
     4917    'lacenumber' => 1,
     4918    'lamebitrate' => 1,
     4919    'lameheader' => 1,
     4920    'lamelowpassfilter' => 1,
     4921    'lamemethod' => 1,
     4922    'lamequality' => 1,
     4923    'lamestereomode' => 1,
     4924    'lamevbrquality' => 1,
     4925    'languagecode' => 1,
    27884926    'languagelist' => 1,
     4927    'largestpacketduration' => 1,
     4928    'largestpacketsize' => 1,
     4929    'lastauthor' => 1,
     4930    'lastchar' => 1,
    27894931    'lastkeyframetime' => 1,
     4932    'lastmodifiedby' => 1,
    27904933    'lastmodifier' => 1,
    27914934    'lastobject' => 1,
    27924935    'lastobjectid' => 1,
    27934936    'lastprinted' => 1,
    2794     'lastsavedby' => 1,
    27954937    'lasttimestamp' => 1,
     4938    'layercomps' => 1,
    27964939    'layersgroupinfo' => 1,
    27974940    'layerstateinfo' => 1,
     
    28064949    'leftdarkrect' => 1,
    28074950    'leftmag' => 1,
     4951    'legalcopyright' => 1,
     4952    'legaltrademarks' => 1,
    28084953    'length' => 1,
    28094954    'lens35efl' => 1,
     4955    'lenscorr' => 1,
     4956    'lensdata' => 1,
    28104957    'lensdata0100' => 1,
    28114958    'lensdata0101' => 1,
    28124959    'lensdata0201' => 1,
     4960    'lensdata0204' => 1,
    28134961    'lensdataunknown' => 1,
    2814     'lensfocalrange' => 1,
     4962    'lensdataversion' => 1,
    28154963    'lensshading' => 1,
    28164964    'lensspec' => 1,
     4965    'levelinfo' => 1,
     4966    'libraryid' => 1,
     4967    'licenseinfourl' => 1,
     4968    'lightingopt' => 1,
    28174969    'lightness' => 1,
    28184970    'lights' => 1,
    28194971    'lightvalue' => 1,
    28204972    'linearizationtable' => 1,
     4973    'linearized' => 1,
    28214974    'lines' => 1,
     4975    'linkerversion' => 1,
     4976    'linkinfo' => 1,
    28224977    'linksuptodate' => 1,
    28234978    'lit' => 1,
     4979    'localbasepath' => 1,
    28244980    'localdeltatype' => 1,
    28254981    'localeindicator' => 1,
     4982    'locationbody' => 1,
     4983    'locationdate' => 1,
     4984    'locationnote' => 1,
     4985    'locationrole' => 1,
    28264986    'lockedpropertylist' => 1,
    28274987    'locks' => 1,
     4988    'logoiconurl' => 1,
     4989    'logourl' => 1,
     4990    'longdescription' => 1,
    28284991    'lookheadbacktype' => 1,
    28294992    'lookheader' => 1,
     
    28354998    'lotus' => 1,
    28364999    'lr' => 1,
     5000    'lslv' => 1,
    28375001    'luminance' => 1,
    28385002    'luminanceconsts' => 1,
     
    28405004    'lyrics' => 1,
    28415005    'lyrics_synchronised' => 1,
     5006    'machineid' => 1,
     5007    'machinetype' => 1,
    28425008    'macintoshprintinfo' => 1,
    28435009    'magnification' => 1,
    28445010    'magnifyobject' => 1,
     5011    'mailstop' => 1,
     5012    'maininfo' => 1,
     5013    'maininfoifd' => 1,
     5014    'majorbrand' => 1,
    28455015    'makeandmodel' => 1,
     5016    'makemodel' => 1,
    28465017    'makernotes' => 1,
     5018    'makerurl' => 1,
    28475019    'mandatorybackground' => 1,
     5020    'manufacturecode' => 1,
     5021    'manufactureindex' => 1,
     5022    'manufacturer' => 1,
     5023    'manufacturername' => 1,
     5024    'mappingscheme' => 1,
     5025    'markbits' => 1,
    28485026    'marker' => 1,
    28495027    'markerid' => 1,
     5028    'markinfo' => 1,
     5029    'matrixstructure' => 1,
    28505030    'mattcolor' => 1,
    28515031    'matte' => 1,
    28525032    'matteing' => 1,
     5033    'matter' => 1,
    28535034    'maxband' => 1,
    28545035    'maxbitrate' => 1,
     5036    'maxblockadditionid' => 1,
     5037    'maxcache' => 1,
    28555038    'maxdatarate' => 1,
    28565039    'maximumbitrate' => 1,
     
    28625045    'maxpacketsize' => 1,
    28635046    'maxpagenormal' => 1,
     5047    'maxpdusize' => 1,
    28645048    'maxsubfilesize' => 1,
     5049    'maxtransmissiontime' => 1,
    28655050    'maxval' => 1,
     5051    'maxwidth' => 1,
    28665052    'mcdi' => 1,
    2867     'mdat' => 1,
    28685053    'mdcolortable' => 1,
    28695054    'mdfiletag' => 1,
    28705055    'mdfileunits' => 1,
    28715056    'mdlabname' => 1,
     5057    'mdpm' => 1,
    28725058    'mdpr' => 1,
    28735059    'mdprepdate' => 1,
     
    28755061    'mdsampleinfo' => 1,
    28765062    'mdscalepixel' => 1,
     5063    'mean' => 1,
     5064    'measuredcolor' => 1,
    28775065    'measuredinfo' => 1,
    28785066    'measurement' => 1,
     
    28865074    'mediaclassprimaryid' => 1,
    28875075    'mediaclasssecondaryid' => 1,
     5076    'mediacolor' => 1,
     5077    'mediacreatedate' => 1,
    28885078    'mediacredits' => 1,
    28895079    'mediadata' => 1,
     5080    'mediaduration' => 1,
     5081    'mediaheader' => 1,
     5082    'mediaheaderversion' => 1,
    28905083    'mediaindex' => 1,
     5084    'mediainfo' => 1,
    28915085    'mediaisdelay' => 1,
    28925086    'mediaisfinale' => 1,
     
    28985092    'mediaissubtitled' => 1,
    28995093    'mediaistape' => 1,
     5094    'medialanguagecode' => 1,
     5095    'mediamodifydate' => 1,
    29005096    'medianetworkaffiliation' => 1,
    29015097    'mediaoriginalbroadcastdatetime' => 1,
     
    29045100    'mediastationcallsign' => 1,
    29055101    'mediastationname' => 1,
     5102    'mediatimescale' => 1,
     5103    'mediatrackbytes' => 1,
     5104    'mediatype' => 1,
     5105    'mediaweight' => 1,
    29065106    'mediawhitepoint' => 1,
    29075107    'medium' => 1,
     5108    'message' => 1,
    29085109    'meta' => 1,
    29095110    'metadata' => 1,
    29105111    'metadatacreator' => 1,
     5112    'metadataid' => 1,
    29115113    'metadatalibrary' => 1,
    29125114    'metadatanumber' => 1,
     5115    'metermode' => 1,
    29135116    'microsoft' => 1,
    29145117    'mie' => 1,
    29155118    'mimetype' => 1,
    2916     'minf' => 1,
     5119    'mincache' => 1,
     5120    'miniaturefilter' => 1,
     5121    'miniaturefilterorientation' => 1,
     5122    'miniaturefilterposition' => 1,
    29175123    'minimumbitrate' => 1,
    29185124    'minoltacamerasettings' => 1,
     
    29205126    'minoltacamerasettings5d' => 1,
    29215127    'minoltacamerasettings7d' => 1,
    2922     'minoltacamerasettingsa100' => 1,
    29235128    'minoltacamerasettingsold' => 1,
    29245129    'minoltamakernote' => 1,
     5130    'minoltamma0' => 1,
     5131    'minoltamma1' => 1,
    29255132    'minoltaprd' => 1,
    29265133    'minoltarif' => 1,
     5134    'minoltatags' => 1,
    29275135    'minoltattw' => 1,
    29285136    'minoltawbg' => 1,
     5137    'minorversion' => 1,
    29295138    'minpacketsize' => 1,
     5139    'mintransmissiontime' => 1,
    29305140    'mmclips' => 1,
    29315141    'mngheader' => 1,
     
    29355145    'modeltiepoint' => 1,
    29365146    'modeltransform' => 1,
     5147    'modeltype' => 1,
    29375148    'modenumber' => 1,
     5149    'modificationpermissions' => 1,
    29385150    'modifiedby' => 1,
    29395151    'modifiedinfo' => 1,
    29405152    'montage' => 1,
     5153    'month' => 1,
    29415154    'mood' => 1,
     5155    'moreinfobannerimage' => 1,
     5156    'moreinfobannerurl' => 1,
     5157    'moreinfotext' => 1,
     5158    'moreinfourl' => 1,
    29425159    'mosaicpattern' => 1,
    29435160    'moveobjects' => 1,
    29445161    'movie' => 1,
     5162    'moviedata' => 1,
     5163    'moviedatasize' => 1,
    29455164    'movieheader' => 1,
     5165    'movieheaderversion' => 1,
     5166    'movieinfo' => 1,
     5167    'moviestreamname' => 1,
     5168    'mp' => 1,
     5169    'mp1' => 1,
    29465170    'mpeg7binary' => 1,
    29475171    'mpegaudioversion' => 1,
     5172    'mpf' => 1,
     5173    'mpfversion' => 1,
     5174    'mpimage' => 1,
     5175    'mpimageflags' => 1,
     5176    'mpimageformat' => 1,
     5177    'mpimagelength' => 1,
     5178    'mpimagelist' => 1,
     5179    'mpimagestart' => 1,
     5180    'mpimagetype' => 1,
     5181    'mpindividualnum' => 1,
     5182    'mrwinfo' => 1,
     5183    'msdocumenttext' => 1,
     5184    'msdocumenttextposition' => 1,
     5185    'mspropertysetstorage' => 1,
    29485186    'msstereo' => 1,
    29495187    'multiexposure' => 1,
     5188    'multiexposureversion' => 1,
    29505189    'multimediatype' => 1,
     5190    'multiprofiles' => 1,
    29515191    'multiquality' => 1,
     5192    'musicby' => 1,
    29525193    'musiccdidentifier' => 1,
    29535194    'musiciancredits' => 1,
     5195    'mute' => 1,
     5196    'muxingapp' => 1,
     5197    'mwg-coll' => 1,
     5198    'mwg-kw' => 1,
     5199    'mwg-rs' => 1,
     5200    'mxfversion' => 1,
    29545201    'mycolors' => 1,
    29555202    'name' => 1,
    29565203    'namedcolor' => 1,
    29575204    'namedcolor2' => 1,
    2958     'namelength' => 1,
     5205    'nametableversion' => 1,
    29595206    'narrator' => 1,
    29605207    'nativedisplayinfo' => 1,
     
    29635210    'nativeyresolution' => 1,
    29645211    'ncc' => 1,
    2965     'nefcurve1' => 1,
    2966     'nefcurve2' => 1,
    29675212    'nestlevel' => 1,
    29685213    'netexposurecompensation' => 1,
     5214    'netname' => 1,
     5215    'netprovidertype' => 1,
    29695216    'neutals' => 1,
    29705217    'neutobjbacktype' => 1,
     
    29755222    'newbitdepth' => 1,
    29765223    'newcolortype' => 1,
     5224    'nextfilename' => 1,
    29775225    'nexttrackid' => 1,
     5226    'nextuid' => 1,
    29785227    'nikon' => 1,
    2979     'nikoncapturedata' => 1,
    29805228    'nikoncaptureoffsets' => 1,
    2981     'nikonpreview' => 1,
     5229    'nikondata' => 1,
     5230    'nikonncdt' => 1,
    29825231    'nikonscanifd' => 1,
    29835232    'nikontags' => 1,
     5233    'nikonvers' => 1,
     5234    'ninthlanguage' => 1,
     5235    'nitf' => 1,
     5236    'nitfversion' => 1,
    29845237    'noise' => 1,
     5238    'noiseprofile' => 1,
    29855239    'noisereductiondata' => 1,
    29865240    'nominalbitrate' => 1,
     
    29895243    'nominalplaytime' => 1,
    29905244    'nomssmarttags' => 1,
    2991     'notes' => 1,
     5245    'note' => 1,
     5246    'notice' => 1,
     5247    'now' => 1,
    29925248    'npts' => 1,
    29935249    'nsc_address' => 1,
     
    29965252    'nsc_name' => 1,
    29975253    'nsc_phone' => 1,
     5254    'nullmediaheader' => 1,
    29985255    'numafpoints' => 1,
    29995256    'numberlist' => 1,
    30005257    'numberofcomponents' => 1,
    30015258    'numberofframes' => 1,
     5259    'numberofimages' => 1,
    30025260    'numberofinks' => 1,
     5261    'numberofparts' => 1,
    30035262    'numberofplanes' => 1,
    30045263    'numberofresolutions' => 1,
    30055264    'numchannels' => 1,
    30065265    'numcolors' => 1,
     5266    'numfonts' => 1,
     5267    'numhistorybuffers' => 1,
    30075268    'numimportantcolors' => 1,
    30085269    'numpackets' => 1,
     
    30115272    'numsampleframes' => 1,
    30125273    'numstreams' => 1,
     5274    'objectfiletype' => 1,
    30135275    'objectid' => 1,
    30145276    'objectsizeannounced' => 1,
     
    30175279    'obsoletephotoshoptag2' => 1,
    30185280    'obsoletephotoshoptag3' => 1,
     5281    'ocad' => 1,
     5282    'ocadrevision' => 1,
    30195283    'oceapplicationselector' => 1,
    30205284    'oceidnumber' => 1,
    30215285    'oceimagelogic' => 1,
    30225286    'ocescanjobdesc' => 1,
     5287    'office' => 1,
    30235288    'offsetorigin' => 1,
    30245289    'offsetxy' => 1,
     5290    'oldxmp' => 1,
     5291    'olym' => 1,
    30255292    'olympus' => 1,
    30265293    'olympus2100' => 1,
     5294    'olympus2100ifd' => 1,
    30275295    'olympus2200' => 1,
     5296    'olympus2200ifd' => 1,
    30285297    'olympus2300' => 1,
     5298    'olympus2300ifd' => 1,
    30295299    'olympus2400' => 1,
     5300    'olympus2400ifd' => 1,
    30305301    'olympus2500' => 1,
     5302    'olympus2500ifd' => 1,
    30315303    'olympus2600' => 1,
     5304    'olympus2600ifd' => 1,
    30325305    'olympus2700' => 1,
     5306    'olympus2700ifd' => 1,
    30335307    'olympus2800' => 1,
     5308    'olympus2800ifd' => 1,
    30345309    'olympus2900' => 1,
     5310    'olympus2900ifd' => 1,
     5311    'olympusjunk' => 1,
     5312    'olympustags1' => 1,
     5313    'olympustags2' => 1,
     5314    'olympustags3' => 1,
    30355315    'opacity' => 1,
     5316    'opcodelist1' => 1,
     5317    'opcodelist2' => 1,
     5318    'opcodelist3' => 1,
     5319    'opcolor' => 1,
     5320    'opendml' => 1,
     5321    'openwithapplication' => 1,
     5322    'operatingsystem' => 1,
    30365323    'operation' => 1,
    30375324    'operationclassid' => 1,
     
    30405327    'opiproxy' => 1,
    30415328    'optimalbitrate' => 1,
    3042     'opto-electricconvfactor' => 1,
    30435329    'orderingrestrictions' => 1,
    3044     'organization' => 1,
    30455330    'originalalbum' => 1,
    30465331    'originalalbumtitle' => 1,
    30475332    'originalartist' => 1,
    30485333    'originaldocumentsize' => 1,
     5334    'originalfilesize' => 1,
     5335    'originalfiletype' => 1,
    30495336    'originalimagebroker' => 1,
    30505337    'originallyricist' => 1,
     
    30625349    'originalthmimage' => 1,
    30635350    'originalthmresource' => 1,
     5351    'originator' => 1,
     5352    'originatorreference' => 1,
     5353    'osversion' => 1,
    30645354    'othercodecdescription' => 1,
    30655355    'othercodecname' => 1,
     5356    'otherformat' => 1,
    30665357    'otherimage' => 1,
    30675358    'otherimagelength' => 1,
    30685359    'otherimagestart' => 1,
     5360    'otherinfo' => 1,
     5361    'othersampledesc' => 1,
     5362    'outputaudiosamplerate' => 1,
    30695363    'outputdataobjectlist' => 1,
    30705364    'outputprofile' => 1,
    30715365    'outputresponse' => 1,
    30725366    'packets' => 1,
    3073     'padding' => 1,
     5367    'packingmethod' => 1,
    30745368    'page' => 1,
    30755369    'pagecount' => 1,
     
    30775371    'pageexit' => 1,
    30785372    'pagefront' => 1,
     5373    'pagelayout' => 1,
     5374    'pagemode' => 1,
    30795375    'pagenormal' => 1,
    30805376    'pages' => 1,
     
    30835379    'palettehistogram' => 1,
    30845380    'panasonic' => 1,
     5381    'panorama' => 1,
     5382    'panorientation' => 1,
     5383    'panoverlaph' => 1,
     5384    'panoverlapv' => 1,
    30855385    'paragraphs' => 1,
    30865386    'parameter' => 1,
     5387    'parasites' => 1,
    30875388    'parentalrating' => 1,
    30885389    'parentalratingreason' => 1,
     5390    'part' => 1,
    30895391    'partialpalette' => 1,
    30905392    'partofset' => 1,
     
    30925394    'pasteimage' => 1,
    30935395    'patternangle' => 1,
     5396    'payloadtype' => 1,
    30945397    'paymenturl' => 1,
    30955398    'pcscitation' => 1,
    30965399    'pdahistogram' => 1,
    30975400    'pdf' => 1,
     5401    'pdfx' => 1,
    30985402    'peakbitrate' => 1,
    30995403    'peakvalue' => 1,
     5404    'pefversion' => 1,
    31005405    'pentax' => 1,
     5406    'pentaxdata' => 1,
     5407    'pentaxjunk' => 1,
    31015408    'pentaxtags' => 1,
     5409    'perceptualrenderingintentgamut' => 1,
    31025410    'performer' => 1,
     5411    'performerkeywords' => 1,
    31035412    'performers' => 1,
    31045413    'performersortorder' => 1,
     5414    'performerurl' => 1,
    31055415    'period' => 1,
     5416    'perms' => 1,
    31065417    'perpicturenotes' => 1,
    31075418    'personalfunctions' => 1,
    31085419    'personalfunctionvalues' => 1,
     5420    'petype' => 1,
     5421    'pfmheader' => 1,
     5422    'pfmversion' => 1,
     5423    'pgfversion' => 1,
    31095424    'photoeffectsdata' => 1,
    31105425    'photomech' => 1,
     
    31165431    'photoshopdata' => 1,
    31175432    'photoshopformat' => 1,
     5433    'photoshopinfo' => 1,
    31185434    'photoshopsettings' => 1,
    31195435    'photoshopthumbnail' => 1,
     
    31245440    'picslabel' => 1,
    31255441    'picture' => 1,
     5442    'picturebitsperpixel' => 1,
     5443    'picturecontrolversion' => 1,
     5444    'picturectrl' => 1,
     5445    'picturedescription' => 1,
     5446    'pictureformat' => 1,
     5447    'pictureheight' => 1,
     5448    'pictureindexedcolors' => 1,
    31265449    'pictureinfo' => 1,
     5450    'picturelength' => 1,
     5451    'picturemimetype' => 1,
     5452    'picturestyleinfo' => 1,
     5453    'picturestyleinfo2' => 1,
     5454    'picturetype' => 1,
     5455    'picturewidth' => 1,
    31275456    'pieceinfo' => 1,
     5457    'pitchandfamily' => 1,
     5458    'pitchshift' => 1,
    31285459    'pixelaspectratio' => 1,
    31295460    'pixelcalibration' => 1,
     
    31315462    'pixelintensityrange' => 1,
    31325463    'pixellive' => 1,
     5464    'pixelmagicjbigoptions' => 1,
    31335465    'pixelscale' => 1,
    31345466    'pixelspermeterx' => 1,
     
    31375469    'pixelsperunity' => 1,
    31385470    'pixelunits' => 1,
     5471    'pixheight' => 1,
     5472    'pixwidth' => 1,
    31395473    'places' => 1,
    31405474    'planes' => 1,
     
    31425476    'playcounter' => 1,
    31435477    'playduration' => 1,
     5478    'playerversion' => 1,
    31445479    'playgap' => 1,
    31455480    'playlistdelay' => 1,
     5481    'playlistid' => 1,
     5482    'playmode' => 1,
    31465483    'playselection' => 1,
     5484    'plus' => 1,
     5485    'podcast' => 1,
     5486    'podcasturl' => 1,
     5487    'pointsize' => 1,
     5488    'popupfillattributes' => 1,
     5489    'popupflash' => 1,
     5490    'position' => 1,
    31475491    'postertime' => 1,
    31485492    'postscript2crd0' => 1,
     
    31505494    'postscript2crd2' => 1,
    31515495    'postscript2csa' => 1,
     5496    'postscriptfontname' => 1,
    31525497    'pragma' => 1,
     5498    'preferredfamily' => 1,
    31535499    'preferredrate' => 1,
     5500    'preferredsubfamily' => 1,
    31545501    'preferredvolume' => 1,
    31555502    'preroll' => 1,
     5503    'presentationformat' => 1,
    31565504    'presentationtarget' => 1,
     5505    'prevfilename' => 1,
    31575506    'preview' => 1,
    31585507    'preview0' => 1,
     
    31625511    'previewatomtype' => 1,
    31635512    'previewdate' => 1,
    3164     'previewdescription' => 1,
    31655513    'previewduration' => 1,
     5514    'previewifd' => 1,
    31665515    'previewifd_offset' => 1,
    31675516    'previewimagedata' => 1,
    31685517    'previewimageinfo' => 1,
    31695518    'previewinfo' => 1,
    3170     'previewmimetype' => 1,
    31715519    'previewpict' => 1,
     5520    'previewpng' => 1,
    31725521    'previewtime' => 1,
    3173     'previewtype' => 1,
    31745522    'previewversion' => 1,
    3175     'primaryafpoint' => 1,
     5523    'prevsize' => 1,
     5524    'prevuid' => 1,
     5525    'primaryitemreference' => 1,
    31765526    'primaryplatform' => 1,
    31775527    'printflags' => 1,
    31785528    'printflagsinfo' => 1,
     5529    'printimversion' => 1,
    31795530    'printquality' => 1,
     5531    'printscale' => 1,
    31805532    'printtovideo' => 1,
    31815533    'priority' => 1,
     5534    'prism' => 1,
    31825535    'private' => 1,
    3183     'proccessinginfo' => 1,
     5536    'privatebuild' => 1,
     5537    'prl' => 1,
     5538    'processing' => 1,
     5539    'processinginfo' => 1,
    31845540    'prod' => 1,
    31855541    'prodnotes' => 1,
     5542    'producedby' => 1,
    31865543    'produceddate' => 1,
    31875544    'producednotice' => 1,
     5545    'producerkeywords' => 1,
    31885546    'product' => 1,
     5547    'productiondate' => 1,
     5548    'productiondesigner' => 1,
     5549    'productionstudio' => 1,
     5550    'productname' => 1,
     5551    'productversion' => 1,
     5552    'productversionnumber' => 1,
    31895553    'profile' => 1,
    31905554    'profileclass' => 1,
    31915555    'profilecmmtype' => 1,
    31925556    'profileconnectionspace' => 1,
    3193     'profilecopyright' => 1,
    31945557    'profilecreator' => 1,
    31955558    'profiledatetime' => 1,
     
    31995562    'profileheader' => 1,
    32005563    'profileid' => 1,
     5564    'profileifd' => 1,
    32015565    'profilesequencedesc' => 1,
     5566    'profilesequenceidentifier' => 1,
    32025567    'profiletype' => 1,
    32035568    'profileversion' => 1,
     
    32105575    'projcenternorthing' => 1,
    32115576    'projcoordtrans' => 1,
     5577    'project' => 1,
    32125578    'projectedcstype' => 1,
    32135579    'projection' => 1,
     5580    'projects' => 1,
    32145581    'projfalseeasting' => 1,
    32155582    'projfalsenorthing' => 1,
     
    32345601    'propertysetidcodes' => 1,
    32355602    'propertysetpathname' => 1,
     5603    'propertystoredata' => 1,
    32365604    'propertyvectorelements' => 1,
    32375605    'protect' => 1,
     
    32425610    'providerstyle' => 1,
    32435611    'ps2crdvmsize' => 1,
    3244     'ps2renteringintent' => 1,
     5612    'ps2renderingintent' => 1,
     5613    'psfontinfo' => 1,
    32455614    'pstringcaption' => 1,
    32465615    'publisherurl' => 1,
     5616    'pur' => 1,
     5617    'purchasedate' => 1,
     5618    'purpose' => 1,
     5619    'pyramidlevels' => 1,
     5620    'quickedit' => 1,
    32475621    'quickmaskinfo' => 1,
     5622    'qvci' => 1,
    32485623    'ra3' => 1,
    32495624    'ra4' => 1,
     
    32515626    'radiostationname' => 1,
    32525627    'radiostationowner' => 1,
     5628    'rafversion' => 1,
    32535629    'rasterpadding' => 1,
     5630    'rate' => 1,
     5631    'rated' => 1,
     5632    'rawcodecversion' => 1,
    32545633    'rawdata' => 1,
     5634    'rawdatalength' => 1,
     5635    'rawdataoffset' => 1,
    32555636    'rawdatarotation' => 1,
    32565637    'rawdev2' => 1,
    3257     'rawdev2_2' => 1,
     5638    'rawdev2ifd' => 1,
    32585639    'rawdevelopment' => 1,
    3259     'rawdevelopment2' => 1,
     5640    'rawdevelopmentifd' => 1,
    32605641    'rawimagefullsize' => 1,
    32615642    'rawimagemode' => 1,
     5643    'rawimagesegmentation' => 1,
    32625644    'rawinfo' => 1,
    3263     'rawinfo2' => 1,
     5645    'rawinfoifd' => 1,
    32645646    'rawjpginfo' => 1,
     5647    'rawzorcreatorversion' => 1,
     5648    'rawzorrequiredversion' => 1,
     5649    'rdf' => 1,
    32655650    'readerrequirements' => 1,
     5651    'realtimestreamingprotocol' => 1,
     5652    'receivedfrom' => 1,
    32665653    'recengineer' => 1,
     5654    'recinfo' => 1,
    32675655    'reclocation' => 1,
    32685656    'reconstructiontype' => 1,
     5657    'recordedby' => 1,
     5658    'recordeddate' => 1,
     5659    'recordingcopyright' => 1,
    32695660    'recordingdates' => 1,
    32705661    'recordingtime' => 1,
     5662    'recordlabelname' => 1,
     5663    'recordlabelurl' => 1,
    32715664    'rect' => 1,
    32725665    'rectangleofinterest' => 1,
    32735666    'redadjust' => 1,
    32745667    'redeyedata' => 1,
    3275     'redeyereduction' => 1,
    32765668    'redgain' => 1,
    32775669    'redmatrixcolumn' => 1,
     
    32795671    'redsample' => 1,
    32805672    'redtrc' => 1,
    3281     'reductionmatrix1' => 1,
    3282     'reductionmatrix2' => 1,
    32835673    'redx' => 1,
    32845674    'redy' => 1,
     5675    'reference' => 1,
     5676    'referenceblock' => 1,
     5677    'referencepriority' => 1,
     5678    'referencevirtual' => 1,
     5679    'reflectionhardcopyorigcolorimetry' => 1,
     5680    'reflectionprintoutputcolorimetry' => 1,
    32855681    'refresh' => 1,
    32865682    'relatedimagefile' => 1,
     5683    'relativepath' => 1,
     5684    'removehistoryduplicates' => 1,
    32875685    'renderingintent' => 1,
     5686    'repeateddatabytes' => 1,
    32885687    'replaygainalbumgain' => 1,
    32895688    'replaygainalbumpeak' => 1,
     
    32915690    'replaygaintrackpeak' => 1,
    32925691    'replyto' => 1,
     5692    'representativedisparityfar' => 1,
     5693    'representativedisparitynear' => 1,
     5694    'representativeimage' => 1,
    32935695    'requirements' => 1,
    32945696    'reserved1' => 1,
    32955697    'resolutioninfo' => 1,
     5698    'resourceforksize' => 1,
    32965699    'resources' => 1,
    32975700    'resourcesneeded' => 1,
     
    33035706    'rgb_profile' => 1,
    33045707    'ricoh' => 1,
    3305     'ricohdatetime1' => 1,
    3306     'ricohdatetime2' => 1,
     5708    'ricohjunk' => 1,
     5709    'ricohrdc2' => 1,
    33075710    'ricohrr1subdir' => 1,
    33085711    'ricohsubdir' => 1,
    33095712    'rightdarkrect' => 1,
    33105713    'rightmag' => 1,
     5714    'rippedby' => 1,
    33115715    'rjmd' => 1,
    33125716    'rmeta' => 1,
     
    33175721    'root' => 1,
    33185722    'rotationangle' => 1,
     5723    'roundtripversion' => 1,
     5724    'rowinterleavefactor' => 1,
     5725    'runwindow' => 1,
     5726    'sampledegradationpriority' => 1,
    33195727    'sampleformat' => 1,
     5728    'samplegroupdescription' => 1,
     5729    'samplepaddingbits' => 1,
    33205730    'samplerate2' => 1,
    33215731    'samplesize' => 1,
     5732    'samplesizes' => 1,
     5733    'sampletable' => 1,
     5734    'sampletext' => 1,
     5735    'sampletochunk' => 1,
     5736    'sampletogroup' => 1,
     5737    'samsunginfo' => 1,
     5738    'samsungtags' => 1,
    33225739    'sanyomov' => 1,
    33235740    'sanyomp4' => 1,
     5741    'saturationinfo' => 1,
     5742    'saturationrenderingintentgamut' => 1,
    33245743    'saveobjbacktype' => 1,
    33255744    'saveobjects' => 1,
     
    33325751    'sbainputimagebitdepth' => 1,
    33335752    'sbainputimagecolorspace' => 1,
     5753    'scalado' => 1,
    33345754    'scale' => 1,
    33355755    'scalecrop' => 1,
    33365756    'scalefactor35efl' => 1,
     5757    'scalingfactor' => 1,
    33375758    'scandate' => 1,
    33385759    'scannermake' => 1,
     
    33435764    'scansoftware' => 1,
    33445765    'scansoftwarerevisiondate' => 1,
     5766    'sceneappearanceestimates' => 1,
     5767    'scenecolorimetryestimates' => 1,
     5768    'school' => 1,
     5769    'screenbuffersize' => 1,
     5770    'screendescriptor' => 1,
    33455771    'screening' => 1,
    33465772    'screeningdesc' => 1,
    33475773    'screennail' => 1,
    33485774    'scriptcommand' => 1,
     5775    'secondarygenre' => 1,
     5776    'secondlanguage' => 1,
    33495777    'security' => 1,
     5778    'seek' => 1,
    33505779    'seekable' => 1,
     5780    'seekhead' => 1,
     5781    'seekid' => 1,
    33515782    'seekpoint' => 1,
     5783    'seekposition' => 1,
     5784    'segmentfamily' => 1,
     5785    'segmentfilename' => 1,
     5786    'segmentheader' => 1,
     5787    'segmentuid' => 1,
    33525788    'selection' => 1,
    33535789    'selectionduration' => 1,
     
    33605796    'sensorbottomborder' => 1,
    33615797    'sensorid' => 1,
     5798    'sensorimageheight' => 1,
     5799    'sensorimagewidth' => 1,
    33625800    'sensorinfo' => 1,
    33635801    'sensorleftborder' => 1,
    33645802    'sensorrightborder' => 1,
    33655803    'sensortopborder' => 1,
     5804    'serialinfo' => 1,
     5805    'series' => 1,
    33665806    'serviceorganizationname' => 1,
    33675807    'setcookie' => 1,
    33685808    'setinfo' => 1,
    33695809    'setsubtitle' => 1,
     5810    'seventhlanguage' => 1,
    33705811    'shadowendpoints' => 1,
     5812    'shadowsyncsampletable' => 1,
    33715813    'shakereductioninfo' => 1,
     5814    'shareddata' => 1,
    33725815    'shareddoc' => 1,
    33735816    'shareduserrating' => 1,
     
    33815824    'sharpobjtype' => 1,
    33825825    'sharpobjversion' => 1,
     5826    'shimdata' => 1,
     5827    'shootingcount' => 1,
    33835828    'shootingrecord' => 1,
    33845829    'shootobjbacktype' => 1,
     
    33885833    'shootsetup' => 1,
    33895834    'shotinfo' => 1,
     5835    'shotinfo02xx' => 1,
     5836    'shotinfod300a' => 1,
     5837    'shotinfod300b' => 1,
     5838    'shotinfod300s' => 1,
     5839    'shotinfod3a' => 1,
     5840    'shotinfod3b' => 1,
     5841    'shotinfod3s' => 1,
     5842    'shotinfod3x' => 1,
     5843    'shotinfod40' => 1,
     5844    'shotinfod5000' => 1,
     5845    'shotinfod700' => 1,
     5846    'shotinfod7000' => 1,
     5847    'shotinfod80' => 1,
     5848    'shotinfod90' => 1,
     5849    'shotinfounknown' => 1,
    33905850    'shotinfoversion' => 1,
    33915851    'showmode' => 1,
    33925852    'showobjects' => 1,
     5853    'shutter' => 1,
    33935854    'shuttercurtainhack' => 1,
    33945855    'shutterspeed' => 1,
     
    33995860    'signature' => 1,
    34005861    'signature_name' => 1,
     5862    'signaturealgo' => 1,
     5863    'signatureelementlist' => 1,
     5864    'signatureelements' => 1,
     5865    'signaturehash' => 1,
     5866    'signaturepublickey' => 1,
     5867    'signatureslot' => 1,
     5868    'signatureusagerights' => 1,
     5869    'signedelement' => 1,
     5870    'signercontactinfo' => 1,
    34015871    'significantbits' => 1,
     5872    'signingauthority' => 1,
     5873    'signingdate' => 1,
     5874    'signinglocation' => 1,
     5875    'signingreason' => 1,
    34025876    'signtype' => 1,
     5877    'silenttracknumber' => 1,
     5878    'silenttracks' => 1,
     5879    'simpleblock' => 1,
    34035880    'simpleindex' => 1,
     5881    'simpletag' => 1,
    34045882    'simplicityprofile' => 1,
    34055883    'singlequality' => 1,
     
    34075885    'siteenter' => 1,
    34085886    'siteexit' => 1,
     5887    'sixthlanguage' => 1,
    34095888    'size' => 1,
    34105889    'sizemode' => 1,
     
    34185897    'snapshotname' => 1,
    34195898    'softedit' => 1,
     5899    'softfocusfilter' => 1,
    34205900    'softwarerelease' => 1,
     5901    'songwriter' => 1,
     5902    'songwriterkeywords' => 1,
    34215903    'sony' => 1,
     5904    'sonyimageheight' => 1,
     5905    'sonyimagewidth' => 1,
     5906    'sortalbum' => 1,
     5907    'sortalbumartist' => 1,
     5908    'sortartist' => 1,
     5909    'sortcomposer' => 1,
     5910    'sortname' => 1,
     5911    'sortshow' => 1,
     5912    'soundschemetitle' => 1,
     5913    'sourcecredits' => 1,
     5914    'sourcedata' => 1,
    34225915    'sourcedate' => 1,
    34235916    'sourceedition' => 1,
     
    34265919    'sourceimagedirectory' => 1,
    34275920    'sourceimagefilename' => 1,
     5921    'sourceimageheight' => 1,
    34285922    'sourceimagevolumename' => 1,
     5923    'sourceimagewidth' => 1,
    34295924    'sourcepublisher' => 1,
    34305925    'sourcerights' => 1,
    34315926    'sourcetitle' => 1,
    34325927    'sourceurl' => 1,
    3433     'spatialfrequencyresponse' => 1,
    34345928    'spatialorientation' => 1,
     5929    'spatialresolution' => 1,
     5930    'specialbuild' => 1,
    34355931    'specialeffectsopticalfilter' => 1,
     5932    'specialfolderdata' => 1,
     5933    'speed' => 1,
    34365934    'spiff' => 1,
    34375935    'spiffversion' => 1,
     
    34425940    'sr2subifdlength' => 1,
    34435941    'sr2subifdoffset' => 1,
    3444     'srf2_key' => 1,
     5942    'srf2key' => 1,
     5943    'srf6offset' => 1,
     5944    'srfdataoffset' => 1,
    34455945    'srgbrendering' => 1,
    34465946    'stamptoolcount' => 1,
     5947    'starring' => 1,
    34475948    'startofframe' => 1,
    3448     'stbl' => 1,
     5949    'starttime' => 1,
     5950    'statistics' => 1,
    34495951    'stdautoactive' => 1,
    34505952    'stdbasename' => 1,
     
    34595961    'stdsharpenoutput' => 1,
    34605962    'stereo' => 1,
     5963    'stereo3dmode' => 1,
     5964    'stereoimage' => 1,
     5965    'stereomode' => 1,
     5966    'stim' => 1,
     5967    'stimversion' => 1,
     5968    'stitchinfo' => 1,
    34615969    'stonits' => 1,
    34625970    'storage-streampathname' => 1,
     
    34645972    'streamavgbitrate' => 1,
    34655973    'streamavgpacketsize' => 1,
     5974    'streambitdepth' => 1,
    34665975    'streambitrateprops' => 1,
     5976    'streamcolor' => 1,
    34675977    'streamcount' => 1,
    34685978    'streamdata' => 1,
     
    34705980    'streamheader' => 1,
    34715981    'streaminfo' => 1,
     5982    'streamingdataprotocol' => 1,
    34725983    'streammaxbitrate' => 1,
    34735984    'streammaxpacketsize' => 1,
     
    34805991    'streamprioritization' => 1,
    34815992    'streamproperties' => 1,
     5993    'streamsamplecount' => 1,
     5994    'streamsamplerate' => 1,
    34825995    'streamstarttime' => 1,
    34835996    'streamtype' => 1,
    34845997    'streamtypeinfo' => 1,
    34855998    'stridable' => 1,
     5999    'strikeout' => 1,
    34866000    'stripbytecounts' => 1,
    34876001    'stripoffsets' => 1,
     
    34896003    'strobe' => 1,
    34906004    'strobetime' => 1,
     6005    'sub-sampleinformation' => 1,
     6006    'subdir3000' => 1,
     6007    'subdir3100' => 1,
     6008    'subdir3400' => 1,
     6009    'subdir3900' => 1,
    34916010    'subfile' => 1,
    34926011    'subifd' => 1,
     
    34946013    'subifd1' => 1,
    34956014    'subifd2' => 1,
     6015    'subifd255' => 1,
    34966016    'subifd3' => 1,
    34976017    'subifd4' => 1,
    34986018    'subifd5' => 1,
     6019    'subifd6' => 1,
    34996020    'subifd_offset' => 1,
    35006021    'subimagecolor' => 1,
     
    35086029    'subimagetilewidth' => 1,
    35096030    'subimagewidth' => 1,
     6031    'subjectpixelheight' => 1,
     6032    'subjectpixelwidth' => 1,
     6033    'subjectscale' => 1,
     6034    'subjectunits' => 1,
    35106035    'subpacketh' => 1,
    35116036    'subpacketsize' => 1,
    35126037    'subscriptioncontentid' => 1,
     6038    'subseccreatedate' => 1,
    35136039    'subsecdatetimeoriginal' => 1,
     6040    'subsecmodifydate' => 1,
     6041    'subsystem' => 1,
     6042    'subsystemversion' => 1,
     6043    'subtileblocksize' => 1,
    35146044    'subtitle' => 1,
    35156045    'subtitledescription' => 1,
     6046    'subtitlekeywords' => 1,
    35166047    'suggestedpalette' => 1,
    35176048    'summaryinfo' => 1,
     6049    'surroundmode' => 1,
     6050    'svgversion' => 1,
     6051    'swf' => 1,
     6052    'synchronizedlyrictext' => 1,
     6053    'syncsampletable' => 1,
    35186054    't4options' => 1,
    35196055    't6options' => 1,
     6056    't82options' => 1,
     6057    't88options' => 1,
     6058    'tag' => 1,
     6059    'tagattachmentuid' => 1,
     6060    'tagbinary' => 1,
     6061    'tagchapteruid' => 1,
     6062    'tagdefault' => 1,
     6063    'tageditionuid' => 1,
     6064    'taggedpdf' => 1,
    35206065    'taggingtime' => 1,
     6066    'taglanguage' => 1,
     6067    'tagname' => 1,
     6068    'tags' => 1,
     6069    'tagstring' => 1,
     6070    'tagtrackuid' => 1,
    35216071    'targetaudiences' => 1,
    35226072    'targetdeltatype' => 1,
     6073    'targetfiledosname' => 1,
     6074    'targetfilesize' => 1,
    35236075    'targetprinter' => 1,
     6076    'targets' => 1,
     6077    'targettype' => 1,
     6078    'targettypevalue' => 1,
    35246079    'targetxy' => 1,
     6080    'tdat' => 1,
     6081    'tdhd' => 1,
    35256082    'technician' => 1,
    35266083    'technology' => 1,
     6084    'telephonenumber' => 1,
     6085    'temperature' => 1,
     6086    'tempinfok5' => 1,
    35276087    'template' => 1,
    35286088    'terminationaction' => 1,
     
    35326092    'text' => 1,
    35336093    'textinfo' => 1,
     6094    'textjunk' => 1,
    35346095    'textualdata' => 1,
     6096    'textualinfo' => 1,
    35356097    'things' => 1,
     6098    'thirdlanguage' => 1,
    35366099    'thumbnail' => 1,
    35376100    'thumbnailclip' => 1,
     
    35396102    'tiff' => 1,
    35406103    'tiff-epstandardid' => 1,
     6104    'tiff_fxextensions' => 1,
    35416105    'tiffpreview' => 1,
    35426106    'tilebytecounts' => 1,
     
    35466110    'timecodeindex' => 1,
    35476111    'timecodeindexparms' => 1,
     6112    'timecodescale' => 1,
     6113    'timeinfo' => 1,
    35486114    'timeoffset' => 1,
     6115    'timereference' => 1,
    35496116    'timescale' => 1,
     6117    'timeslice' => 1,
     6118    'timetosampletable' => 1,
     6119    'title2' => 1,
    35506120    'titlelen' => 1,
    35516121    'titleofparts' => 1,
     6122    'titlesofparts' => 1,
    35526123    'titlesortorder' => 1,
    35536124    'tocitems' => 1,
     
    35646135    'toolversion' => 1,
    35656136    'topmag' => 1,
     6137    'totalbitrate' => 1,
     6138    'totalbytes' => 1,
     6139    'totalbytesnortpheaders' => 1,
     6140    'totaldatarate' => 1,
     6141    'totalduration' => 1,
    35666142    'totaledittime' => 1,
     6143    'totalframecount' => 1,
    35676144    'totalframes' => 1,
    35686145    'totalsamples' => 1,
     6146    'toycamerafilter' => 1,
    35696147    'track' => 1,
     6148    'trackattachmentuid' => 1,
    35706149    'trackcategory' => 1,
    35716150    'trackcomments' => 1,
    35726151    'trackcreatedate' => 1,
     6152    'trackdefault' => 1,
    35736153    'trackduration' => 1,
     6154    'trackentry' => 1,
     6155    'trackerdata' => 1,
     6156    'trackforced' => 1,
    35746157    'trackheader' => 1,
     6158    'trackheaderversion' => 1,
    35756159    'trackid' => 1,
     6160    'tracklacing' => 1,
     6161    'tracklanguage' => 1,
    35766162    'tracklayer' => 1,
    35776163    'tracklyrics' => 1,
    35786164    'trackmodifydate' => 1,
    3579     'trackversion' => 1,
     6165    'trackname' => 1,
     6166    'trackoffset' => 1,
     6167    'trackoverlay' => 1,
     6168    'trackproperty' => 1,
     6169    'trackref' => 1,
     6170    'tracktimecodescale' => 1,
     6171    'tracktranslate' => 1,
     6172    'tracktranslatecodec' => 1,
     6173    'tracktranslateeditionuid' => 1,
     6174    'tracktranslatetrackid' => 1,
     6175    'tracktype' => 1,
     6176    'trackuid' => 1,
     6177    'trackused' => 1,
    35806178    'trackvolume' => 1,
     6179    'trademark' => 1,
    35816180    'transferrange' => 1,
    3582     'transfomation' => 1,
    3583     'transform' => 1,
     6181    'transformation' => 1,
    35846182    'transformcreatedate' => 1,
    35856183    'transformedimagetitle' => 1,
    35866184    'transformmodifydate' => 1,
    35876185    'transformnodeid' => 1,
     6186    'transformparams' => 1,
    35886187    'transformtitle' => 1,
    35896188    'transparency' => 1,
    35906189    'transparencyindicator' => 1,
    35916190    'transparentindex' => 1,
    3592     'trapped' => 1,
     6191    'trapindicator' => 1,
     6192    'trebel' => 1,
     6193    'tvepisode' => 1,
     6194    'tvepisodeid' => 1,
     6195    'tvnetworkname' => 1,
     6196    'tvseason' => 1,
     6197    'tvshow' => 1,
    35936198    'typeoforiginal' => 1,
     6199    'typist' => 1,
    35946200    'ucrbg' => 1,
     6201    'uic1tag' => 1,
     6202    'uic2tag' => 1,
     6203    'uic3tag' => 1,
     6204    'uic4tag' => 1,
    35956205    'uncompressed' => 1,
     6206    'uncompressedsize' => 1,
     6207    'underline' => 1,
     6208    'underlineposition' => 1,
     6209    'underlinethickness' => 1,
    35966210    'unicodealphanames' => 1,
     6211    'uninitializeddatasize' => 1,
    35976212    'uniquefileidentifier' => 1,
    35986213    'units' => 1,
    35996214    'unknown' => 1,
    3600     'unknownblock1' => 1,
    3601     'unknownblock2' => 1,
     6215    'unknownd30' => 1,
     6216    'unknowndata' => 1,
     6217    'unknowninfo' => 1,
     6218    'unknowninfo2' => 1,
     6219    'unknowninfo2version' => 1,
     6220    'unknowninfoifd' => 1,
     6221    'unknowninfoversion' => 1,
    36026222    'unknowntags' => 1,
    36036223    'unsharpdata' => 1,
    36046224    'unused' => 1,
     6225    'ur3' => 1,
    36056226    'url_list' => 1,
     6227    'urn' => 1,
     6228    'usagerightsmessage' => 1,
    36066229    'usedextensionnumbers' => 1,
     6230    'useraccess' => 1,
    36076231    'useradjsba_rgbshifts' => 1,
    36086232    'userdata' => 1,
     
    36136237    'userweburl' => 1,
    36146238    'usingtransforms' => 1,
     6239    'usptomiscellaneous' => 1,
     6240    'usptooriginalcontenttype' => 1,
    36156241    'utm' => 1,
    36166242    'uuid-exif' => 1,
     6243    'uuid-flip' => 1,
    36176244    'uuid-geojp2' => 1,
    36186245    'uuid-iptc' => 1,
     6246    'uuid-prof' => 1,
    36196247    'uuid-unknown' => 1,
     6248    'uuid-usmt' => 1,
    36206249    'uuid-xmp' => 1,
    36216250    'uuidinfo' => 1,
     
    36236252    'validafpoints' => 1,
    36246253    'vary' => 1,
     6254    'vbrbytes' => 1,
     6255    'vbrframes' => 1,
    36256256    'vbrpeak' => 1,
     6257    'vbrscale' => 1,
     6258    'vegasversionmajor' => 1,
     6259    'vegasversionminor' => 1,
    36266260    'vendor' => 1,
    36276261    'vendorid' => 1,
     6262    'vendorname' => 1,
     6263    'vendorurl' => 1,
    36286264    'version2' => 1,
    36296265    'versionbf' => 1,
     6266    'versionifd' => 1,
    36306267    'versioninfo' => 1,
    36316268    'versionyear' => 1,
     
    36336270    'verticalcstype' => 1,
    36346271    'verticaldatum' => 1,
     6272    'verticaldivergence' => 1,
    36356273    'verticalunits' => 1,
    3636     'vibrationreduction' => 1,
    36376274    'video' => 1,
     6275    'videoattributes' => 1,
     6276    'videoavgbitrate' => 1,
     6277    'videoavgframerate' => 1,
    36386278    'videobitrate' => 1,
    36396279    'videocardgamma' => 1,
     
    36416281    'videocodecdescription' => 1,
    36426282    'videocodecid' => 1,
     6283    'videocodecinfo' => 1,
    36436284    'videocodecname' => 1,
    36446285    'videoencoding' => 1,
    36456286    'videoformat' => 1,
     6287    'videoframecount' => 1,
     6288    'videoheader' => 1,
    36466289    'videoheight' => 1,
     6290    'videomaxbitrate' => 1,
     6291    'videomaxframerate' => 1,
    36476292    'videomode' => 1,
    3648     'videoquality' => 1,
     6293    'videoprofile' => 1,
     6294    'videoprofileversion' => 1,
     6295    'videosampledesc' => 1,
     6296    'videoscantype' => 1,
    36496297    'videosize' => 1,
     6298    'videostreamtype' => 1,
     6299    'videotrackid' => 1,
    36506300    'videowidth' => 1,
    36516301    'viewable' => 1,
     
    36556305    'viewingconditions' => 1,
    36566306    'viewingcondsurround' => 1,
     6307    'viewtype' => 1,
     6308    'vignettingcorr' => 1,
     6309    'vignettingcorr2' => 1,
     6310    'virtualimageheight' => 1,
     6311    'virtualimagewidth' => 1,
     6312    'virtualpage' => 1,
     6313    'virtualpageunits' => 1,
    36576314    'visibleoutputs' => 1,
     6315    'vistaidlistdata' => 1,
     6316    'void' => 1,
     6317    'volumeid' => 1,
     6318    'volumelabel' => 1,
    36586319    'vorbiscomment' => 1,
    36596320    'vorbisversion' => 1,
    3660     'vr_0x66' => 1,
    36616321    'vrd1' => 1,
    36626322    'vrd2' => 1,
    36636323    'vrdstamptool' => 1,
    36646324    'vrdversion' => 1,
     6325    'vrinfo' => 1,
     6326    'vrinfoversion' => 1,
    36656327    'vw96' => 1,
    36666328    'wangannotation' => 1,
     6329    'wangtag1' => 1,
     6330    'wangtag3' => 1,
     6331    'wangtag4' => 1,
    36676332    'warning' => 1,
    36686333    'watermark' => 1,
    36696334    'watermarktype' => 1,
    3670     'wb_grbglevels' => 1,
     6335    'watermarkurl' => 1,
    36716336    'wb_grgblevels' => 1,
     6337    'wb_rgbcoeffs0' => 1,
     6338    'wb_rgbcoeffs1' => 1,
     6339    'wb_rgbcoeffs2' => 1,
     6340    'wb_rgbcoeffs3' => 1,
     6341    'wb_rgblevelsauto' => 1,
     6342    'wb_rgblevelscloudy' => 1,
     6343    'wb_rgblevelsdaylight' => 1,
     6344    'wb_rgblevelsflash' => 1,
     6345    'wb_rgblevelsfluorescent' => 1,
     6346    'wb_rgblevelsshade' => 1,
     6347    'wb_rgblevelstungsten' => 1,
     6348    'wb_rgbmul0' => 1,
     6349    'wb_rgbmul1' => 1,
     6350    'wb_rgbmul2' => 1,
     6351    'wb_rgbmul3' => 1,
    36726352    'wbadjdata' => 1,
     6353    'wbinfoa100' => 1,
    36736354    'wcsprofiles' => 1,
     6355    'weight' => 1,
    36746356    'whitebalancematching' => 1,
    36756357    'whitebalancetable' => 1,
    3676     'whitelevel' => 1,
    36776358    'whitepointx' => 1,
    36786359    'whitepointy' => 1,
     6360    'whitesample' => 1,
     6361    'whitesamplebits' => 1,
     6362    'whitesampleheight' => 1,
     6363    'whitesampleleftborder' => 1,
     6364    'whitesampletopborder' => 1,
     6365    'whitesamplewidth' => 1,
    36796366    'wide' => 1,
     6367    'widthbytes' => 1,
    36806368    'widthresolution' => 1,
    36816369    'windowlocation' => 1,
     6370    'windoworigin' => 1,
     6371    'windoworiginauto' => 1,
     6372    'windowsize' => 1,
    36826373    'windowtarget' => 1,
    36836374    'wmadrcaveragereference' => 1,
     
    36886379    'wmcollectionid' => 1,
    36896380    'wmcontentid' => 1,
    3690     'wordcount' => 1,
     6381    'words' => 1,
    36916382    'workflowurl' => 1,
     6383    'workingdirectory' => 1,
    36926384    'workingpath' => 1,
     6385    'worldtime' => 1,
    36936386    'writer' => 1,
     6387    'writingapp' => 1,
     6388    'writtenby' => 1,
     6389    'wwsfamilyname' => 1,
     6390    'wwssubfamilyname' => 1,
     6391    'x' => 1,
     6392    'xcfversion' => 1,
    36946393    'xclippathunits' => 1,
     6394    'xheight' => 1,
    36956395    'xmag' => 1,
    36966396    'xmethod' => 1,
     
    37006400    'xmpbj' => 1,
    37016401    'xmpdm' => 1,
     6402    'xmpextension' => 1,
    37026403    'xmpmm' => 1,
     6404    'xmpnote' => 1,
    37036405    'xmpplus' => 1,
    37046406    'xmprights' => 1,
    37056407    'xmptpg' => 1,
     6408    'xp_dip_xml' => 1,
    37066409    'xylocation' => 1,
    37076410    'xyoffsetinfo' => 1,
     6411    'yawangle' => 1,
    37086412    'yclippathunits' => 1,
    37096413    'year' => 1,
     
    37126416    'ymethod' => 1,
    37136417    'ytarget' => 1,
     6418    'zipbitflag' => 1,
     6419    'zipcompressedsize' => 1,
     6420    'zipcompression' => 1,
     6421    'zipcrc' => 1,
     6422    'zipfilename' => 1,
     6423    'zipmodifydate' => 1,
     6424    'ziprequiredversion' => 1,
     6425    'zipuncompressedsize' => 1,
    37146426    'zoom' => 1,
     6427    'zoomedpreviewimage' => 1,
    37156428    'zoompos' => 1,
    37166429);
     
    37186431# module names for writable Composite tags
    37196432my %compositeModules = (
     6433    'filenumber' => 'Image::ExifTool::Canon',
    37206434    'jpgfromraw' => 'Image::ExifTool::Exif',
     6435    'originaldecisiondata' => 'Image::ExifTool::Canon',
    37216436    'previewimage' => 'Image::ExifTool::Exif',
    37226437    'thumbnailimage' => 'Image::ExifTool::Exif',
     
    37256440#++++ End automatically generated code ++++
    37266441
     6442my %specialStruct = (
     6443    NAMESPACE   => 1,
     6444    STRUCT_NAME => 1,
     6445    TYPE        => 1,
     6446    NOTES       => 1,
     6447);
     6448
    37276449# insert any user-defined tags into our tag lookup
    37286450if (%Image::ExifTool::UserDefined) {
    3729     my ($table, %tableNum, $tagID);
    3730     my $tnum = 0; # make hash lookup to get table numbers
    3731     foreach $table (@tableList) {
    3732         $tableNum{$table} = $tnum++;
    3733     }
    37346451    my @userTables = sort keys %Image::ExifTool::UserDefined;
    37356452    while (@userTables) {
    37366453        my $table = shift @userTables;
    3737         $tnum = $tableNum{$table};
    3738         unless ($tnum) {
     6454        AddTags($Image::ExifTool::UserDefined{$table}, $table);
     6455    }
     6456}
     6457
     6458# insert any other queued tags from plug-in modules
     6459if (@Image::ExifTool::pluginTags) {
     6460    my $args;
     6461    foreach $args (@Image::ExifTool::pluginTags) {
     6462        AddTags($$args[0], $$args[1]);
     6463    }
     6464    undef @Image::ExifTool::pluginTags;
     6465}
     6466
     6467
     6468#------------------------------------------------------------------------------
     6469# Add tag names corresponding to flattened XMP tags for all structure fields
     6470# Inputs: 0) tag table ref for flattened tags, 1) tagID, 2) lowercase tag name,
     6471#         3) tag ID list ref, 4) reference to list of lowercase tag names
     6472#         5) table number in lookup, 6) tagInfo hash for parent structure
     6473#         7) tag ID of top-level stucture
     6474# Notes: Used only for user-defined structures
     6475sub AddFields($$$$$$;$$)
     6476{
     6477    my ($tagTablePtr, $tagID, $lcTag, $tagIDs, $lcTags, $tnum, $tagInfo, $baseID) = @_;
     6478    unless ($tagInfo) {
     6479        $tagInfo = $$tagTablePtr{$tagID};
     6480        $baseID = $tagID;
     6481    }
     6482    my $strTable = $$tagInfo{Struct};
     6483    unless (ref $strTable) {
     6484        my $strName = $strTable;
     6485        $strTable = $Image::ExifTool::UserDefined::xmpStruct{$strTable};
     6486        $strTable or warn("No definition for structure '$strName'\n"), return;
     6487        $$strTable{STRUCT_NAME} or $$strTable{STRUCT_NAME} = $strName;
     6488        $$tagInfo{Struct} = $strTable;  # replace name with hash ref
     6489        delete $$tagInfo{SubDirectory}; # deprecated use of SubDirectory in Struct tags
     6490    }
     6491    # inherit NAMESPACE from parent table if it doesn't exist
     6492    $$strTable{NAMESPACE} = $$tagTablePtr{NAMESPACE} unless exists $$strTable{NAMESPACE};
     6493    my $field;
     6494    foreach $field (keys %$strTable) {
     6495        next if $specialStruct{$field};
     6496        my $id = $tagID . ucfirst($field);
     6497        # use name of existing flattened tag if already defined
     6498        my $lc = $$tagTablePtr{$id} ? lc $$tagTablePtr{$id}{Name} : $lcTag . lc($field);
     6499        my $copyID = $baseID;
     6500        push @$tagIDs, \$copyID, $id;
     6501        push @$lcTags, $lc, $lc;
     6502        my $fieldInfo = $$strTable{$field};
     6503        next unless ref $fieldInfo eq 'HASH' and $$fieldInfo{Struct};
     6504        # recursively add flattened tags for all sub-fields
     6505        AddFields($tagTablePtr, $id, $lc, $tagIDs, $lcTags, $tnum, $fieldInfo, $baseID);
     6506    }
     6507}
     6508
     6509#------------------------------------------------------------------------------
     6510# Add tags to the lookup (for user-defined tags, etc)
     6511# Inputs: 0) tag table ref, 1) table name
     6512my %tableNumHash;
     6513sub AddTags($$)
     6514{
     6515    my ($tagTablePtr, $table) = @_;
     6516
     6517    # generate lookup for table numbers if not done already
     6518    unless (%tableNumHash) {
     6519        my $tnum = 0;
     6520        my $tbl;
     6521        foreach $tbl (@tableList) {
     6522            $tableNumHash{$tbl} = $tnum++;
     6523        }
     6524    }
     6525    my (@moreTables, %moreTableRefs);
     6526    for (;;) {
     6527        my $tnum = $tableNumHash{$table};
     6528        unless (defined $tnum) {
     6529            # add new table to list
    37396530            $tnum = scalar @tableList;
    37406531            push @tableList, $table;
    37416532        }
    3742         my $userTable = $Image::ExifTool::UserDefined{$table};
    3743         foreach $tagID (Image::ExifTool::TagTableKeys($userTable)) {
    3744             my $newInfo = $$userTable{$tagID};
     6533        my $tagID;
     6534        foreach $tagID (Image::ExifTool::TagTableKeys($tagTablePtr)) {
     6535            my $newInfo = $$tagTablePtr{$tagID};
    37456536            if (ref $newInfo eq 'HASH') {
    37466537                $$newInfo{Name} or $$newInfo{Name} = ucfirst($tagID);
     6538                # use new ID of tag in Composite table in case it changed
     6539                $tagID = $$newInfo{NewTagID} if defined $$newInfo{NewTagID};
    37476540            } else {
    3748                 $newInfo = $$userTable{$tagID} = { Name => $newInfo };
     6541                $newInfo = $$tagTablePtr{$tagID} = { Name => $newInfo };
    37496542            }
    3750             my $lcTag = lc($$newInfo{Name});
    3751             # add to lookup even though we don't know it is writable
     6543            my $lcTag = lc $$newInfo{Name};
     6544            my (@lcTags, @tagIDs, $existed, $isFlat);
     6545            # if this is a structure, add all flattened tag names to lookup
     6546            if ($$newInfo{Struct}) {
     6547                AddFields($tagTablePtr, $tagID, $lcTag, \@tagIDs, \@lcTags, $tnum);
     6548            }
     6549            # add tags to lookup even though we don't know if they are writable
    37526550            # (to save speed by not having to load the module)
    3753             my $lookup = $tagLookup{$lcTag};
    3754             $lookup or $lookup = $tagLookup{$lcTag} = { };
    3755             if ($$lookup{$tnum}) {
    3756                 my $le = $$lookup{$tnum};
    3757                 my @ids = (ref $le eq 'ARRAY') ? @{$le} : ( $le );
    3758                 # only add new tag ID if it didn't already exist
    3759                 next if grep /^$tagID$/, @ids;
    3760                 push @ids, $tagID;
    3761                 $$lookup{$tnum} = \@ids;
    3762             } else {
    3763                 $$lookup{$tnum} = $tagID;
     6551Tags:       for (;;) {
     6552                my $lookup = $tagLookup{$lcTag};
     6553                $lookup or $lookup = $tagLookup{$lcTag} = { };
     6554                if ($$lookup{$tnum}) {
     6555                    my $le = $$lookup{$tnum};
     6556                    my $ids = (ref $le eq 'ARRAY') ? $le : [ $le ];
     6557                    if (ref $tagID) {
     6558                        # a reference points to the tag ID of the base structure for
     6559                        # a flattened tag.  There must be only one of these,
     6560                        # and it must come first.
     6561                        unshift @$ids, $tagID unless ref $$ids[0];
     6562                    # only add new tag ID if it didn't already exist
     6563                    } elsif (grep /^$tagID$/, @$ids) {
     6564                        $existed = 1 unless $isFlat;
     6565                    } else {
     6566                        push @$ids, $tagID;
     6567                    }
     6568                    # only update lookup if there is now more than one entry
     6569                    $$lookup{$tnum} = $ids if @$ids > 1;
     6570                } else {
     6571                    $$lookup{$tnum} = $tagID;
     6572                }
     6573                last unless @tagIDs;
     6574                for (;;) {
     6575                    $tagID = shift @tagIDs;
     6576                    $lcTag = shift @lcTags;
     6577                    last unless $$tagTablePtr{$tagID}; # don't waste time if it exists
     6578                    last Tags unless @tagIDs;
     6579                }
     6580                $isFlat = 1;
    37646581            }
    3765             # add any new subdirectory tables
    3766             next unless $$newInfo{SubDirectory};
    3767             my $subTable = $newInfo->{SubDirectory}->{TagTable};
    3768             next unless $subTable and not defined $tableNum{$subTable};
    3769             next if $Image::ExifTool::UserDefined{$subTable};
     6582            # add any new subdirectory tables (unless done already)
     6583            next if $existed or not $$newInfo{SubDirectory};
     6584            my $subTable = $$newInfo{SubDirectory}{TagTable};
     6585            next unless $subTable and not defined $tableNumHash{$subTable};
     6586            next if $moreTableRefs{$subTable};
    37706587            no strict 'refs';
    37716588            next unless %$subTable;
    3772             $Image::ExifTool::UserDefined{$subTable} = \%$subTable;
    3773             push @userTables, $subTable;
    3774             # save parent table name so we can load it when necessary
    3775             $$subTable{PARENT} = $table;
     6589            # save new table to process after this one
     6590            push @moreTables, $subTable;
     6591            $moreTableRefs{$subTable} = \%$subTable;
     6592            # save source table name so we can load it when necessary
     6593            $$subTable{SRC_TABLE} = $table;
    37766594        }
     6595        $table = shift @moreTables or last;
     6596        $tagTablePtr = $moreTableRefs{$table};
    37776597    }
    37786598}
     
    38046624        foreach $tableNum (keys %$lookup) {
    38056625            my $table = GetTagTable($tableList[$tableNum]);
    3806             my $tagID = $$lookup{$tableNum};
    3807             my @tagIDs;
    3808             if (ref $tagID eq 'ARRAY') {
    3809                 @tagIDs = @$tagID;
     6626            my $le = $$lookup{$tableNum};
     6627            my ($tagID, $tagIDs);
     6628            if (ref $le eq 'ARRAY') {
     6629                $tagIDs = $le;
     6630                # if first entry is a reference, it indicates that this is a
     6631                # flattened tag and refers to the tag ID of the containing top-level
     6632                # structure, so now is the time to generate the flattened tags
     6633                if (ref $$tagIDs[0]) {
     6634                    # (remove from the lookup since we only need to do this once)
     6635                    my $rootIDPtr = shift @$tagIDs;
     6636                    require Image::ExifTool::XMP;
     6637                    Image::ExifTool::XMP::AddFlattenedTags($table, $$rootIDPtr);
     6638                }
    38106639            } else {
    3811                 push @tagIDs, $tagID;
     6640                $tagIDs = [ $le ];
    38126641            }
    3813             foreach $tagID (@tagIDs) {
     6642            foreach $tagID (@$tagIDs) {
    38146643                my @infoList = GetTagInfoList($table,$tagID);
    38156644                unless (@infoList) {
     
    38626691=head1 AUTHOR
    38636692
    3864 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     6693Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    38656694
    38666695This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/TagNames.pod

    r16842 r24107  
    77
    88This document contains a complete list of ExifTool tag names, organized into
    9 tables based on information type.  Tag names are used to indicate the
    10 specific meta information that is extracted or written in an image.
     9tables based on information type.  Tag names are used to reference specific
     10meta information extracted from or written to a file.
    1111
    1212=head1 TAG TABLES
     
    2424tag ID.  In these cases, the actual name used depends on the context in
    2525which the information is found.  Case is not significant for tag names.  A
    26 question mark after a tag name indicates that the information is either not
    27 understood, not verified, or not very useful -- these tags are not extracted
    28 by ExifTool unless the Unknown (-u) option is enabled.  Be aware that some
    29 tag names are different than the descriptions printed out by default when
    30 extracting information with exiftool.  To see the tag names instead of the
    31 descriptions, use C<exiftool -s>.
     26question mark (C<?>) after a tag name indicates that the information is
     27either not understood, not verified, or not very useful -- these tags are
     28not extracted by ExifTool unless the Unknown (-u) option is enabled.  Be
     29aware that some tag names are different than the descriptions printed out by
     30default when extracting information with exiftool.  To see the tag names
     31instead of the descriptions, use C<exiftool -s>.
    3232
    3333The B<Writable> column indicates whether the tag is writable by ExifTool.
     
    4040(including a null terminator which is added if required).
    4141
    42 An asterisk (C<*>) after an entry in the B<Writable> column indicates a
    43 "protected" tag which is not writable directly, but is set via a Composite
    44 tag.  A tilde (C<~>) indicates a tag this is only writable when print
    45 conversion is disabled (by setting PrintConv to 0, or using the -n option).
    46 A slash (C</>) indicates an "avoided" tag that is not created unless the
    47 group is specified (due to name conflicts with other tags).  An exclamation
    48 point (C<!>) indicates a tag that is considered unsafe to write under normal
    49 circumstances.  These "unsafe" tags are not set when calling
    50 SetNewValuesFromFile() or when using the exiftool -TagsFromFile option
    51 unless specified explicitly, and care should be taken when editing them
    52 manually since they may affect the way an image is rendered.  A plus sign
    53 (C<+>) indicates a "list" tag which supports multiple instances.
    54 
    55 The HTML version of these tables also list possible B<Values> for
    56 discrete-valued tags, as well as B<Notes> for some tags.
     42A plus sign (C<+>) after an entry in the B<Writable> column indicates a
     43"list" tag which supports multiple values and allows individual values to be
     44added and deleted.  A slash (C</>) indicates an "avoided" tag that is not
     45created when writing if another same-named tag may be created instead.  To
     46write these tags, the group should be specified.  A tilde (C<~>) indicates a
     47tag this is writable only when the print conversion is disabled (by setting
     48PrintConv to 0, using the -n option, or suffixing the tag name with a C<#>
     49character).  An exclamation point (C<!>) indicates a tag that is considered
     50unsafe to write under normal circumstances.  These "unsafe" tags are not set
     51when calling SetNewValuesFromFile() or copied with the exiftool
     52-tagsFromFile option unless specified explicitly, and care should be taken
     53when editing them manually since they may affect the way an image is
     54rendered.  An asterisk (C<*>) indicates a "protected" tag which is not
     55writable directly, but is written automatically by ExifTool (often when a
     56corresponding Composite or Extra tag is written).  A colon (C<:>) indicates
     57a mandatory tag which may be added automatically when writing.
     58
     59The HTML version of these tables also lists possible B<Values> for
     60discrete-valued tags, as well as B<Notes> for some tags.  The B<Values> are
     61listed as the computer-readable and human-readable values on the left and
     62right hand side of an equals sign (C<=>) respectively.  The human-readable
     63values are used by default when reading and writing, but the
     64computer-readable values may be accessed by disabling the value conversion
     65with the -n option on the command line, by setting the ValueConv option to 0
     66in the API, or or on a per-tag basis by appending a number symbol (C<#>) to
     67the tag name.
    5768
    5869B<Note>: If you are familiar with common meta-information tag names, you may
     
    7283               JFXX                             JFIF Extension
    7384               CIFF                             CanonRaw
     85               AVI1                             JPEG AVI1
     86               Ocad                             JPEG Ocad
    7487  'APP1'       EXIF                             EXIF
     88               ExtendedXMP                      XMP
    7589               XMP                              XMP
     90               QVCI                             Casio QVCI
    7691  'APP2'       ICC_Profile                      ICC_Profile
    7792               FPXR                             FlashPix
     93               MPF                              MPF
     94               PreviewImage                     N
    7895  'APP3'       Meta                             Kodak Meta
     96               Stim                             Stim
     97               PreviewImage                     N
     98  'APP4'       Scalado                          JPEG Scalado
     99               FPXR                             FlashPix
     100               PreviewImage                     N
    79101  'APP5'       RMETA                            Ricoh RMETA
    80102  'APP6'       EPPIM                            JPEG EPPIM
     103               NITF                             JPEG NITF
     104               HP_TDHD                          HP TDHD
    81105  'APP8'       SPIFF                            JPEG SPIFF
    82106  'APP10'      Comment                          N
     
    88112  'APP15'      GraphicConverter                 JPEG GraphConv
    89113  'COM'        Comment                          Y
     114  'DQT'        DefineQuantizationTable          N
    90115  'SOF'        StartOfFrame                     JPEG SOF
    91116  'Trailer'    AFCP                             AFCP
     
    96121               PreviewImage                     Y
    97122
     123=head3 JPEG AVI1 Tags
     124
     125This information may be found in APP0 of JPEG image data from AVI videos.
     126
     127   Index   Tag Name                             Writable
     128   -----   --------                             --------
     129      0    InterleavedField                     N
     130
     131=head3 JPEG Ocad Tags
     132
     133Tags extracted from the JPEG APP0 "Ocad" segment (found in Photobucket
     134images).
     135
     136  Tag ID   Tag Name                             Writable
     137  ------   --------                             --------
     138  'Rev'    OcadRevision                         N
     139
     140=head3 JPEG Scalado Tags
     141
     142Tags extracted from the JPEG APP4 "SCALADO" segment (presumably written by
     143Scalado mobile software, L<http://www.scalado.com/>).
     144
     145  Tag ID   Tag Name                             Writable
     146  ------   --------                             --------
     147  'HGHT'   PreviewImageHeight                   N
     148  'QUAL'   PreviewQuality                       N
     149  'SPMO'   DataLength                           N
     150  'WDTH'   PreviewImageWidth                    N
     151
    98152=head3 JPEG EPPIM Tags
    99153
     
    105159  0xc4a5   PrintIM                              PrintIM
    106160
     161=head3 JPEG NITF Tags
     162
     163Information in APP6 used by the National Imagery Transmission Format.  See
     164L<http://www.gwg.nga.mil/ntb/baseline/docs/n010697/bwcguide25aug98.pdf> for
     165the official specification.
     166
     167   Index   Tag Name                             Writable
     168   -----   --------                             --------
     169      0    NITFVersion                          N
     170      2    ImageFormat                          N
     171      3    BlocksPerRow                         N
     172      5    BlocksPerColumn                      N
     173      7    ImageColor                           N
     174      8    BitDepth                             N
     175      9    ImageClass                           N
     176     10    JPEGProcess                          N
     177     11    Quality                              N
     178     12    StreamColor                          N
     179     13    StreamBitDepth                       N
     180     14    Flags                                N
     181
    107182=head3 JPEG SPIFF Tags
    108183
    109184This information is found in APP8 of SPIFF-style JPEG images (the "official"
    110185yet rarely used JPEG file format standard: Still Picture Interchange File
    111 Format).
     186Format).  See L<http://www.jpeg.org/public/spiff.pdf> for the official
     187specification.
    112188
    113189   Index   Tag Name                             Writable
     
    171247EXIF stands for "Exchangeable Image File Format".  This type of information
    172248is formatted according to the TIFF specification, and may be found in JPG,
    173 TIFF, PNG, MIFF and WDP images, as well as many TIFF-based RAW images.
     249TIFF, PNG, PGF, MIFF, HDP, PSP and XCF images, as well as many TIFF-based
     250RAW images, and even some AVI and MOV videos.
    174251
    175252The EXIF meta information is organized into different Image File Directories
     
    178255B<Group> listed below is used unless another group is specified.
    179256
    180 Also listed in the table below are TIFF, DNG, WDP and other tags which are
    181 not part of the EXIF specification, but may co-exist with EXIF tags in some
    182 images.
     257The table below lists all EXIF tags.  Also listed are TIFF, DNG, HDP and
     258other tags which are not part of the EXIF specification, but may co-exist
     259with EXIF tags in some images.  Tags which are part of the EXIF 2.3
     260specification have an underlined B<Tag Name> in the HTML version of this
     261documentation.  See
     262L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-008-2010_E.pdf> for the
     263official EXIF 2.3 specification.
    183264
    184265  Tag ID   Tag Name                  Group      Writable
    185266  ------   --------                  -----      --------
    186267  0x0001   InteropIndex              InteropIFD string!
    187   0x0002   InteropVersion            InteropIFD undef!
     268  0x0002   InteropVersion            InteropIFD undef!:
    188269  0x000b   ProcessingSoftware        IFD0       string
    189270  0x00fe   SubfileType               IFD0       int32u!
     
    192273  0x0101   ImageHeight               IFD0       int32u!
    193274  0x0102   BitsPerSample             IFD0       int16u[n]!
    194   0x0103   Compression               IFD0       int16u!
     275  0x0103   Compression               IFD0       int16u!:
    195276  0x0106   PhotometricInterpretation IFD0       int16u!
    196277  0x0107   Thresholding              IFD0       int16u!
     
    215296  0x0118   MinSampleValue            IFD0       int16u
    216297  0x0119   MaxSampleValue            IFD0       int16u
    217   0x011a   XResolution               IFD0       rational64u
    218   0x011b   YResolution               IFD0       rational64u
     298  0x011a   XResolution               IFD0       rational64u:
     299  0x011b   YResolution               IFD0       rational64u:
    219300  0x011c   PlanarConfiguration       IFD0       int16u!
    220301  0x011d   PageName                  IFD0       string
     
    227308  0x0124   T4Options                 -          N
    228309  0x0125   T6Options                 -          N
    229   0x0128   ResolutionUnit            IFD0       int16u
     310  0x0128   ResolutionUnit            IFD0       int16u:
    230311  0x0129   PageNumber                IFD0       int16u[2]
    231312  0x012c   ColorResponseUnit         -          N
    232   0x012d   TransferFunction          -          N
     313  0x012d   TransferFunction          IFD0       int16u[768]!
    233314  0x0131   Software                  IFD0       string
    234315  0x0132   ModifyDate                IFD0       string
     
    248329  0x0148   ConsecutiveBadFaxLines    -          N
    249330  0x014a   SubIFD                    -          EXIF
     331           A100DataOffset            -          N
    250332  0x014c   InkSet                    IFD0       int16u
    251333  0x014d   InkNames                  -          N
     
    272354  0x01b1   Decode                    -          N
    273355  0x01b2   DefaultImageColor         -          N
     356  0x01b3   T82Options                -          N
     357  0x01b5   JPEGTables                -          N
    274358  0x0200   JPEGProc                  -          N
    275359  0x0201   ThumbnailOffset           IFD1       int32u*
     360           ThumbnailOffset           IFD0       int32u*
     361           ThumbnailOffset           SubIFD     int32u*
    276362           PreviewImageStart         MakerNotes int32u*
     363           PreviewImageStart         IFD0       int32u*
    277364           JpgFromRawStart           SubIFD     int32u*
    278365           JpgFromRawStart           IFD2       int32u*
    279366           OtherImageStart           -          N
    280367  0x0202   ThumbnailLength           IFD1       int32u*
     368           ThumbnailLength           IFD0       int32u*
     369           ThumbnailLength           SubIFD     int32u*
    281370           PreviewImageLength        MakerNotes int32u*
     371           PreviewImageLength        IFD0       int32u*
    282372           JpgFromRawLength          SubIFD     int32u*
    283373           JpgFromRawLength          IFD2       int32u*
     
    291381  0x0211   YCbCrCoefficients         IFD0       rational64u[3]!
    292382  0x0212   YCbCrSubSampling          IFD0       int16u[2]!
    293   0x0213   YCbCrPositioning          IFD0       int16u!
     383  0x0213   YCbCrPositioning          IFD0       int16u!:
    294384  0x0214   ReferenceBlackWhite       IFD0       rational64u[6]
    295385  0x022f   StripRowCounts            -          N
    296   0x02bc   ApplicationNotes          -          XMP
     386  0x02bc   ApplicationNotes          ExifIFD    XMP
     387  0x03e7   USPTOMiscellaneous        -          N
    297388  0x1000   RelatedImageFileFormat    InteropIFD string!
    298389  0x1001   RelatedImageWidth         InteropIFD int16u!
    299   0x1002   RelatedImageLength        InteropIFD int16u!
     390  0x1002   RelatedImageHeight        InteropIFD int16u!
    300391  0x4746   Rating                    IFD0       int16u/
     392  0x4747   XP_DIP_XML                -          N
     393  0x4748   StitchInfo                -          Microsoft Stitch
    301394  0x4749   RatingPercent             IFD0       int16u/
    302395  0x800d   ImageID                   -          N
     396  0x80a3   WangTag1                  -          N
    303397  0x80a4   WangAnnotation            -          N
     398  0x80a5   WangTag3                  -          N
     399  0x80a6   WangTag4                  -          N
    304400  0x80e3   Matteing                  -          N
    305401  0x80e4   DataType                  -          N
     
    310406  0x828e   CFAPattern2               -          N
    311407  0x828f   BatteryLevel              -          N
     408  0x8290   KodakIFD                  -          Kodak IFD
    312409  0x8298   Copyright                 IFD0       string
    313410  0x829a   ExposureTime              ExifIFD    rational64u
     
    322419  0x82ac   MDFileUnits               -          N
    323420  0x830e   PixelScale                -          N
     421  0x8335   AdventScale               -          N
     422  0x8336   AdventRevision            -          N
     423  0x835c   UIC1Tag                   -          N
     424  0x835d   UIC2Tag                   -          N
     425  0x835e   UIC3Tag                   -          N
     426  0x835f   UIC4Tag                   -          N
    324427  0x83bb   IPTC-NAA                  IFD0       IPTC
    325428  0x847e   IntergraphPacketData      -          N
    326429  0x847f   IntergraphFlagRegisters   -          N
    327430  0x8480   IntergraphMatrix          -          N
     431  0x8481   INGRReserved              -          N
    328432  0x8482   ModelTiePoint             -          N
    329433  0x84e0   Site                      -          N
     
    342446  0x84ed   ColorCharacterization     -          N
    343447  0x84ee   HCUsage                   -          N
     448  0x84ef   TrapIndicator             -          N
     449  0x84f0   CMYKEquivalent            -          N
    344450  0x8546   SEMInfo                   IFD0       string
    345451  0x8568   AFCP_IPTC                 -          IPTC
     452  0x85b8   PixelMagicJBIGOptions     -          N
    346453  0x85d8   ModelTransform            -          N
     454  0x8602   WB_GRGBLevels             -          N
    347455  0x8606   LeafData                  -          Leaf
    348456  0x8649   PhotoshopSettings         -          Photoshop
    349457  0x8769   ExifOffset                -          EXIF
    350458  0x8773   ICC_Profile               -          ICC_Profile
     459  0x877f   TIFF_FXExtensions         -          N
     460  0x8780   MultiProfiles             -          N
     461  0x8781   SharedData                -          N
     462  0x8782   T88Options                -          N
    351463  0x87ac   ImageLayer                -          N
    352464  0x87af   GeoTiffDirectory          -          N
     
    356468  0x8824   SpectralSensitivity       ExifIFD    string
    357469  0x8825   GPSInfo                   -          GPS
    358   0x8827   ISO                       ExifIFD    int16u
     470  0x8827   ISO                       ExifIFD    int16u[n]
    359471  0x8828   Opto-ElectricConvFactor   -          N
    360472  0x8829   Interlace                 -          N
    361473  0x882a   TimeZoneOffset            ExifIFD    int16s[n]
    362474  0x882b   SelfTimerMode             ExifIFD    int16u
     475  0x8830   SensitivityType           ExifIFD    int16u
     476  0x8831   StandardOutputSensitivity ExifIFD    int32u
     477  0x8832   RecommendedExposureIndex  ExifIFD    int32u
     478  0x8833   ISOSpeed                  ExifIFD    int32u
     479  0x8834   ISOSpeedLatitudeyyy       ExifIFD    int32u
     480  0x8835   ISOSpeedLatitudezzz       ExifIFD    int32u
    363481  0x885c   FaxRecvParams             -          N
    364482  0x885d   FaxSubAddress             -          N
    365483  0x885e   FaxRecvTime               -          N
    366484  0x888a   LeafSubIFD                -          Leaf SubIFD
    367   0x9000   ExifVersion               ExifIFD    undef
     485  0x9000   ExifVersion               ExifIFD    undef:
    368486  0x9003   DateTimeOriginal          ExifIFD    string
    369487  0x9004   CreateDate                ExifIFD    string
    370   0x9101   ComponentsConfiguration   ExifIFD    undef
    371   0x9102   CompressedBitsPerPixel    ExifIFD    rational64u
     488  0x9101   ComponentsConfiguration   ExifIFD    undef[4]!:
     489  0x9102   CompressedBitsPerPixel    ExifIFD    rational64u!
    372490  0x9201   ShutterSpeedValue         ExifIFD    rational64s
    373491  0x9202   ApertureValue             ExifIFD    rational64u
     
    389507  0x9212   SecurityClassification    ExifIFD    string
    390508  0x9213   ImageHistory              ExifIFD    string
    391   0x9214   SubjectLocation           ExifIFD    int16u[4]
     509  0x9214   SubjectArea               ExifIFD    int16u[n]
    392510  0x9215   ExposureIndex             -          N
    393511  0x9216   TIFF-EPStandardID         -          N
    394512  0x9217   SensingMethod             -          N
     513  0x923a   CIP3DataFile              -          N
     514  0x923b   CIP3Sheet                 -          N
     515  0x923c   CIP3Side                  -          N
    395516  0x923f   StoNits                   -          N
    396517  0x927c   MakerNoteCanon            ExifIFD    Canon
     
    398519           MakerNoteCasio2           ExifIFD    Casio Type2
    399520           MakerNoteFujiFilm         ExifIFD    FujiFilm
     521           MakerNoteGE               ExifIFD    GE
     522           MakerNoteGE2              ExifIFD    FujiFilm
    400523           MakerNoteHP               ExifIFD    HP
    401524           MakerNoteHP2              ExifIFD    HP Type2
    402525           MakerNoteHP4              ExifIFD    HP Type4
    403526           MakerNoteHP6              ExifIFD    HP Type6
     527           MakerNoteISL              ExifIFD    Unknown
    404528           MakerNoteJVC              ExifIFD    JVC
    405529           MakerNoteJVCText          ExifIFD    JVC Text
     
    413537           MakerNoteKodak6b          ExifIFD    Kodak Type6
    414538           MakerNoteKodak7           ExifIFD    Kodak Type7
    415            MakerNoteKodakIFD         ExifIFD    Kodak IFD
     539           MakerNoteKodak8a          ExifIFD    Kodak Type8
     540           MakerNoteKodak8b          ExifIFD    Kodak Type8
     541           MakerNoteKodak9           ExifIFD    Kodak Type9
     542           MakerNoteKodak10          ExifIFD    Kodak Type10
    416543           MakerNoteKodakUnknown     ExifIFD    Kodak Unknown
    417544           MakerNoteKyocera          ExifIFD    Unknown
     
    425552           MakerNoteOlympus2         ExifIFD    Olympus
    426553           MakerNoteLeica            ExifIFD    Panasonic
     554           MakerNoteLeica2           ExifIFD    Panasonic Leica2
     555           MakerNoteLeica3           ExifIFD    Panasonic Leica3
     556           MakerNoteLeica4           ExifIFD    Panasonic Leica4
     557           MakerNoteLeica5           ExifIFD    Panasonic Leica5
     558           MakerNoteLeica6           ExifIFD    Panasonic Leica6
    427559           MakerNotePanasonic        ExifIFD    Panasonic
    428560           MakerNotePanasonic2       ExifIFD    Panasonic Type2
     
    431563           MakerNotePentax3          ExifIFD    Casio Type2
    432564           MakerNotePentax4          ExifIFD    Pentax Type4
     565           MakerNotePentax5          ExifIFD    Pentax
     566           MakerNotePhaseOne         ExifIFD    undef
     567           MakerNoteReconyx          ExifIFD    Reconyx
    433568           MakerNoteRicoh            ExifIFD    Ricoh
    434569           MakerNoteRicohText        ExifIFD    Ricoh Text
    435            PreviewImage              ExifIFD    undef
     570           MakerNoteSamsung1a        ExifIFD    undef
     571           MakerNoteSamsung1b        ExifIFD    Samsung Type1
     572           MakerNoteSamsung2         ExifIFD    Samsung Type2
    436573           MakerNoteSanyo            ExifIFD    Sanyo
    437574           MakerNoteSanyoC4          ExifIFD    Sanyo
     
    439576           MakerNoteSigma            ExifIFD    Sigma
    440577           MakerNoteSony             ExifIFD    Sony
     578           MakerNoteSony2            ExifIFD    Olympus
     579           MakerNoteSony3            ExifIFD    Olympus
     580           MakerNoteSony4            ExifIFD    Sony
     581           MakerNoteSonyEricsson     ExifIFD    Sony Ericsson
    441582           MakerNoteSonySRF          ExifIFD    Sony SRF
    442            MakerNoteSonySR2          ExifIFD    Sony
     583           MakerNoteUnknownText      ExifIFD    undef
    443584           MakerNoteUnknown          ExifIFD    Unknown
    444585  0x9286   UserComment               ExifIFD    undef
     
    446587  0x9291   SubSecTimeOriginal        ExifIFD    string
    447588  0x9292   SubSecTimeDigitized       ExifIFD    string
    448   0x935c   ImageSourceData           IFD0       undef
     589  0x932f   MSDocumentText            -          N
     590  0x9330   MSPropertySetStorage      -          N
     591  0x9331   MSDocumentTextPosition    -          N
     592  0x935c   ImageSourceData           IFD0       undef!
    449593  0x9c9b   XPTitle                   IFD0       int8u
    450594  0x9c9c   XPComment                 IFD0       int8u
     
    452596  0x9c9e   XPKeywords                IFD0       int8u
    453597  0x9c9f   XPSubject                 IFD0       int8u
    454   0xa000   FlashpixVersion           ExifIFD    undef
    455   0xa001   ColorSpace                ExifIFD    int16u
    456   0xa002   ExifImageWidth            ExifIFD    int16u
    457   0xa003   ExifImageLength           ExifIFD    int16u
     598  0xa000   FlashpixVersion           ExifIFD    undef:
     599  0xa001   ColorSpace                ExifIFD    int16u:
     600  0xa002   ExifImageWidth            ExifIFD    int16u:
     601  0xa003   ExifImageHeight           ExifIFD    int16u:
    458602  0xa004   RelatedSoundFile          ExifIFD    string
    459603  0xa005   InteropOffset             -          EXIF
     
    487631  0xa40c   SubjectDistanceRange      ExifIFD    int16u
    488632  0xa420   ImageUniqueID             ExifIFD    string
     633  0xa430   OwnerName                 ExifIFD    string
     634  0xa431   SerialNumber              ExifIFD    string
     635  0xa432   LensInfo                  ExifIFD    rational64u[4]
     636  0xa433   LensMake                  ExifIFD    string
     637  0xa434   LensModel                 ExifIFD    string
     638  0xa435   LensSerialNumber          ExifIFD    string
    489639  0xa480   GDALMetadata              -          N
    490640  0xa481   GDALNoData                -          N
    491641  0xa500   Gamma                     ExifIFD    rational64u
     642  0xafc0   ExpandSoftware            -          N
     643  0xafc1   ExpandLens                -          N
     644  0xafc2   ExpandFilm                -          N
     645  0xafc3   ExpandFilterLens          -          N
     646  0xafc4   ExpandScanner             -          N
     647  0xafc5   ExpandFlashLamp           -          N
    492648  0xbc01   PixelFormat               -          N
    493   0xbc02   Transfomation             -          N
     649  0xbc02   Transformation            -          N
    494650  0xbc03   Uncompressed              -          N
    495651  0xbc04   ImageType                 -          N
     
    510666  0xc44f   Annotations               -          N
    511667  0xc4a5   PrintIM                   IFD0       PrintIM
    512   0xc612   DNGVersion                IFD0       int8u[4]
    513   0xc613   DNGBackwardVersion        IFD0       int8u[4]
     668  0xc580   USPTOOriginalContentType  -          N
     669  0xc612   DNGVersion                IFD0       int8u[4]!
     670  0xc613   DNGBackwardVersion        IFD0       int8u[4]!
    514671  0xc614   UniqueCameraModel         IFD0       string
    515672  0xc615   LocalizedCameraModel      IFD0       string
     
    517674  0xc617   CFALayout                 -          N
    518675  0xc618   LinearizationTable        -          N
    519   0xc619   BlackLevelRepeatDim       -          N
    520   0xc61a   BlackLevel                -          N
     676  0xc619   BlackLevelRepeatDim       SubIFD     int16u[2]!
     677  0xc61a   BlackLevel                SubIFD     rational64u[n]!
    521678  0xc61b   BlackLevelDeltaH          -          N
    522679  0xc61c   BlackLevelDeltaV          -          N
    523   0xc61d   WhiteLevel                -          N
    524   0xc61e   DefaultScale              SubIFD     rational64u[2]
    525   0xc61f   DefaultCropOrigin         SubIFD     int32u[2]
    526   0xc620   DefaultCropSize           SubIFD     int32u[2]
    527   0xc621   ColorMatrix1              -          N
    528   0xc622   ColorMatrix2              -          N
    529   0xc623   CameraCalibration1        -          N
    530   0xc624   CameraCalibration2        -          N
    531   0xc625   ReductionMatrix1          -          N
    532   0xc626   ReductionMatrix2          -          N
    533   0xc627   AnalogBalance             -          N
    534   0xc628   AsShotNeutral             -          N
    535   0xc629   AsShotWhiteXY             IFD0       rational64u[2]
    536   0xc62a   BaselineExposure          IFD0       rational64s
    537   0xc62b   BaselineNoise             IFD0       rational64u
    538   0xc62c   BaselineSharpness         IFD0       rational64u
    539   0xc62d   BayerGreenSplit           SubIFD     int32u
    540   0xc62e   LinearResponseLimit       IFD0       rational64u
     680  0xc61d   WhiteLevel                SubIFD     int32u[n]!
     681  0xc61e   DefaultScale              SubIFD     rational64u[2]!
     682  0xc61f   DefaultCropOrigin         SubIFD     int32u[2]!
     683  0xc620   DefaultCropSize           SubIFD     int32u[2]!
     684  0xc621   ColorMatrix1              IFD0       rational64s[n]!
     685  0xc622   ColorMatrix2              IFD0       rational64s[n]!
     686  0xc623   CameraCalibration1        IFD0       rational64s[n]!
     687  0xc624   CameraCalibration2        IFD0       rational64s[n]!
     688  0xc625   ReductionMatrix1          IFD0       rational64s[n]!
     689  0xc626   ReductionMatrix2          IFD0       rational64s[n]!
     690  0xc627   AnalogBalance             IFD0       rational64u[n]!
     691  0xc628   AsShotNeutral             IFD0       rational64u[n]!
     692  0xc629   AsShotWhiteXY             IFD0       rational64u[2]!
     693  0xc62a   BaselineExposure          IFD0       rational64s!
     694  0xc62b   BaselineNoise             IFD0       rational64u!
     695  0xc62c   BaselineSharpness         IFD0       rational64u!
     696  0xc62d   BayerGreenSplit           SubIFD     int32u!
     697  0xc62e   LinearResponseLimit       IFD0       rational64u!
    541698  0xc62f   CameraSerialNumber        IFD0       string
    542699  0xc630   DNGLensInfo               IFD0       rational64u[4]
    543   0xc631   ChromaBlurRadius          SubIFD     rational64u
    544   0xc632   AntiAliasStrength         SubIFD     rational64u
    545   0xc633   ShadowScale               IFD0       rational64u
     700  0xc631   ChromaBlurRadius          SubIFD     rational64u!
     701  0xc632   AntiAliasStrength         SubIFD     rational64u!
     702  0xc633   ShadowScale               IFD0       rational64u!
    546703  0xc634   SR2Private                -          Sony SR2Private
    547704           DNGAdobeData              -          DNG AdobeData
    548            DNGPentaxData             -          Pentax
     705           MakerNotePentax           -          Pentax
    549706           DNGPrivateData            -          N
    550707  0xc635   MakerNoteSafety           IFD0       int16u
    551   0xc65a   CalibrationIlluminant1    IFD0       int16u
    552   0xc65b   CalibrationIlluminant2    IFD0       int16u
    553   0xc65c   BestQualityScale          SubIFD     rational64u
    554   0xc65d   RawDataUniqueID           IFD0       int8u[16]
     708  0xc640   RawImageSegmentation      -          N
     709  0xc65a   CalibrationIlluminant1    IFD0       int16u!
     710  0xc65b   CalibrationIlluminant2    IFD0       int16u!
     711  0xc65c   BestQualityScale          SubIFD     rational64u!
     712  0xc65d   RawDataUniqueID           IFD0       int8u[16]!
    555713  0xc660   AliasLayerMetadata        -          N
    556   0xc68b   OriginalRawFileName       IFD0       string
     714  0xc68b   OriginalRawFileName       IFD0       string!
    557715  0xc68c   OriginalRawFileData       IFD0       DNG OriginalRaw
    558   0xc68d   ActiveArea                SubIFD     int32u[4]
    559   0xc68e   MaskedAreas               SubIFD     int32u[4]
     716  0xc68d   ActiveArea                SubIFD     int32u[4]!
     717  0xc68e   MaskedAreas               SubIFD     int32u[4]!
    560718  0xc68f   AsShotICCProfile          IFD0       ICC_Profile
    561719  0xc690   AsShotPreProfileMatrix    IFD0       rational64s[n]!
    562720  0xc691   CurrentICCProfile         IFD0       ICC_Profile
    563721  0xc692   CurrentPreProfileMatrix   IFD0       rational64s[n]!
     722  0xc6bf   ColorimetricReference     IFD0       int16u!
     723  0xc6d2   PanasonicTitle            IFD0       undef
     724  0xc6d3   PanasonicTitle2           IFD0       undef
     725  0xc6f3   CameraCalibrationSig      IFD0       string!
     726  0xc6f4   ProfileCalibrationSig     IFD0       string!
     727  0xc6f5   ProfileIFD                -          EXIF
     728  0xc6f6   AsShotProfileName         IFD0       string!
     729  0xc6f7   NoiseReductionApplied     SubIFD     rational64u!
     730  0xc6f8   ProfileName               IFD0       string!
     731  0xc6f9   ProfileHueSatMapDims      IFD0       int32u[3]!
     732  0xc6fa   ProfileHueSatMapData1     IFD0       float[n]!
     733  0xc6fb   ProfileHueSatMapData2     IFD0       float[n]!
     734  0xc6fc   ProfileToneCurve          IFD0       float[n]!
     735  0xc6fd   ProfileEmbedPolicy        IFD0       int32u!
     736  0xc6fe   ProfileCopyright          IFD0       string!
     737  0xc714   ForwardMatrix1            IFD0       rational64s[n]!
     738  0xc715   ForwardMatrix2            IFD0       rational64s[n]!
     739  0xc716   PreviewApplicationName    IFD0       string!
     740  0xc717   PreviewApplicationVersion IFD0       string!
     741  0xc718   PreviewSettingsName       IFD0       string!
     742  0xc719   PreviewSettingsDigest     IFD0       int8u!
     743  0xc71a   PreviewColorSpace         IFD0       int32u!
     744  0xc71b   PreviewDateTime           IFD0       string!
     745  0xc71c   RawImageDigest            IFD0       int8u!
     746  0xc71d   OriginalRawFileDigest     IFD0       int8u!
     747  0xc71e   SubTileBlockSize          -          N
     748  0xc71f   RowInterleaveFactor       -          N
     749  0xc725   ProfileLookTableDims      IFD0       int32u[3]!
     750  0xc726   ProfileLookTableData      IFD0       float[n]!
     751  0xc740   OpcodeList1               -          N
     752  0xc741   OpcodeList2               -          N
     753  0xc74e   OpcodeList3               -          N
     754  0xc761   NoiseProfile              -          N
     755  0xea1c   Padding                   ExifIFD    undef
    564756  0xea1d   OffsetSchema              ExifIFD    int32s
    565757  0xfde8   OwnerName                 ExifIFD    string/
    566758  0xfde9   SerialNumber              ExifIFD    string/
    567759  0xfdea   Lens                      ExifIFD    string/
     760  0xfe00   KDC_IFD                   -          Kodak KDC_IFD
    568761  0xfe4c   RawFile                   ExifIFD    string/
    569762  0xfe4d   Converter                 ExifIFD    string/
     
    580773=head2 IPTC Tags
    581774
    582 IPTC stands for "International Press Telecommunications Council".  This is
    583 an older meta information format that is slowly being phased out in favor of
    584 XMP.  IPTC information may be embedded in JPG, TIFF, PNG, MIFF, PS, PDF, PSD
    585 and DNG images.
    586 
    587 The IPTC specification dictates a length for ASCII (C<string> or C<digits>)
    588 values.  These lengths are given in square brackets after the B<Writable>
    589 format name.  For tags where a range of lengths is allowed, the minimum and
    590 maximum lengths are separated by a comma within the brackets.  IPTC strings
    591 are not null terminated.
     775The tags listed below are part of the International Press Telecommunications
     776Council (IPTC) and the Newspaper Association of America (NAA) Information
     777Interchange Model (IIM).  This is an older meta information format, slowly
     778being phased out in favor of XMP.  (In fact, the newer IPTCCore
     779specification actually uses XMP format!)  IPTC information may be embedded
     780in JPG, TIFF, PNG, MIFF, PS, PDF, PSD, XCF and DNG images.
    592781
    593782IPTC information is separated into different records, each of which has its
    594 own set of tags.
     783own set of tags.  See
     784L<http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf> for the
     785official specification.
     786
     787This specification dictates a length for ASCII (C<string> or C<digits>) and
     788binary (C<undef>) values.  These lengths are given in square brackets after
     789the B<Writable> format name.  For tags where a range of lengths is allowed,
     790the minimum and maximum lengths are separated by a comma within the
     791brackets.  IPTC strings are not null terminated.  When writing, ExifTool
     792issues a minor warning and truncates the value if it is longer than allowed
     793by the IPTC specification. Minor errors may be ignored with the
     794IgnoreMinorErrors (-m) option, allowing longer values to be written, but
     795beware that values like this may cause problems for some other IPTC readers.
     796
     797Separate IPTC date and time tags may be written with a combined date/time
     798value and ExifTool automagically takes the appropriate part of the date/time
     799string depending on whether a date or time tag is being written.  This is
     800very useful when copying date/time values to IPTC from other metadata
     801formats.
     802
     803IPTC time values include a timezone offset.  If written with a value which
     804doesn't include a timezone then the current local timezone offset is used
     805(unless written with a combined date/time, in which case the local timezone
     806offset at the specified date/time is used, which may be different due to
     807changes in daylight savings time).
    595808
    596809  Record   Tag Name                             Writable
     
    602815      8    IPTCObjectData                       IPTC ObjectData
    603816      9    IPTCPostObjectData                   IPTC PostObjectData
     817    240    IPTCFotoStation                      IPTC FotoStation
    604818
    605819=head3 IPTC EnvelopeRecord Tags
     
    607821  Tag ID   Tag Name                             Writable
    608822  ------   --------                             --------
    609       0    EnvelopeRecordVersion                int16u
     823      0    EnvelopeRecordVersion                int16u:
    610824      5    Destination                          string[0,1024]+
    611825     20    FileFormat                           int16u
     
    617831     70    DateSent                             digits[8]
    618832     80    TimeSent                             string[11]
    619      90    CodedCharacterSet                    string[0,32]
     833     90    CodedCharacterSet                    string[0,32]!
    620834    100    UniqueObjectName                     string[14,80]
    621835    120    ARMIdentifier                        int16u
     
    626840  Tag ID   Tag Name                             Writable
    627841  ------   --------                             --------
    628       0    ApplicationRecordVersion             int16u
     842      0    ApplicationRecordVersion             int16u:
    629843      3    ObjectTypeReference                  string[3,67]
    630844      4    ObjectAttributeReference             string[4,68]+
     
    672886    121    LocalCaption                         string[0,256]
    673887    122    Writer-Editor                        string[0,32]+
    674     125    RasterizedCaption                    string[7360]
     888    125    RasterizedCaption                    undef[7360]
    675889    130    ImageType                            string[2]
    676890    131    ImageOrientation                     string[1]
     
    688902    200    ObjectPreviewFileFormat              int16u
    689903    201    ObjectPreviewFileVersion             int16u
    690     202    ObjectPreviewData                    string[0,256000]
     904    202    ObjectPreviewData                    undef[0,256000]
    691905    221    Prefs                                string[0,64]
    692906    225    ClassifyState                        string[0,64]
     
    695909    231    DocumentHistory                      string[0,256]
    696910    232    ExifCameraInfo                       string[0,4096]
     911    255    CatalogSets                          string[0,256]+
    697912
    698913=head3 IPTC NewsPhoto Tags
     
    700915  Tag ID   Tag Name                             Writable
    701916  ------   --------                             --------
    702       0    NewsPhotoVersion                     int16u
     917      0    NewsPhotoVersion                     int16u:
    703918     10    IPTCPictureNumber                    string[16]
    704919     20    IPTCImageWidth                       int16u
     
    748963     10    ConfirmedObjectSize                  N
    749964
     965=head3 IPTC FotoStation Tags
     966
     967  Tag ID   Tag Name                             Writable
     968  ------   --------                             --------
     969  [no tags known]
     970
    750971=head2 XMP Tags
    751972
    752973XMP stands for "Extensible Metadata Platform", an XML/RDF-based metadata
    753974format which is being pushed by Adobe.  Information in this format can be
    754 embedded in many different image file types including JPG, JP2, TIFF, PNG,
    755 MIFF, PS, PDF, PSD and DNG, as well as audio file formats supporting ID3v2
    756 information.
     975embedded in many different image file types including JPG, JP2, TIFF, GIF,
     976EPS, PDF, PSD, IND, PNG, DJVU, SVG, PGF, MIFF, XCF, CRW, DNG and a variety
     977of proprietary TIFF-based RAW images, as well as MOV, AVI, ASF, WMV, FLV,
     978SWF and MP4 videos, and WMA and audio formats supporting ID3v2 information.
    757979
    758980The XMP B<Tag ID>'s aren't listed because in most cases they are identical
    759 to the B<Tag Name>.
     981to the B<Tag Name> (aside from differences in case).  Tags with different
     982ID's are mentioned in the B<Notes> column of the HTML version of this
     983document.
    760984
    761985All XMP information is stored as character strings.  The B<Writable> column
    762 specifies the information format:  C<integer> is a string of digits
    763 (possibly beginning with a '+' or '-'), C<real> is a floating point number,
    764 C<rational> is two C<integer> strings separated by a '/' character, C<date>
    765 is a date/time string in the format "YYYY:MM:DD HH:MM:SS[+/-HH:MM]",
    766 C<boolean> is either "True" or "False", and C<lang-alt> is a list of string
    767 alternatives in different languages.
     986specifies the information format:  C<string> is an unformatted string,
     987C<integer> is a string of digits (possibly beginning with a '+' or '-'),
     988C<real> is a floating point number, C<rational> is entered as a floating
     989point number but stored as two C<integer> strings separated by a '/'
     990character, C<date> is a date/time string entered in the format "YYYY:mm:dd
     991HH:MM:SS[.ss][+/-HH:MM]", C<boolean> is either "True" or "False",
     992C<lang-alt> indicates that the tag supports alternate languages (see below),
     993and C<struct> is an XMP structure.  When reading, structures are extracted
     994only if the Struct (-struct) option is used.  Otherwise the corresponding
     995"flattened" tags, indicated by an underline (C<_>) after the B<Writable>
     996type, are extracted.  When copying information, the Struct option is in
     997effect by default.  When writing, the Struct option has no effect, and both
     998structured and flattened tags may be written.  See
     999L<http://owl.phy.queensu.ca/~phil/exiftool/struct.html> for more details.
    7681000
    7691001Individual languages for C<lang-alt> tags are accessed by suffixing the tag
    7701002name with a '-', followed by an RFC 3066 language code (ie. "XMP:Title-fr",
    771 or "Rights-en-US").  A C<lang-alt> tag with no language code accesses the
    772 "x-default" language, but causes other languages to be deleted when writing.
    773 The "x-default" language code may be specified when writing a new value to
    774 write only the default language, but note that all languages are still
    775 deleted if "x-default" tag is deleted.  When reading, "x-default" is not
    776 specified.
     1003or "Rights-en-US").  (See L<http://www.ietf.org/rfc/rfc3066.txt> for the RFC
     10043066 specification.)  A C<lang-alt> tag with no language code accesses the
     1005"x-default" language, but causes other languages for this tag to be deleted
     1006when writing.  The "x-default" language code may be specified when writing
     1007to preserve other existing languages (ie. "XMP-dc:Description-x-default").
     1008When reading, "x-default" is not specified.
    7771009
    7781010The XMP tags are organized according to schema B<Namespace> in the following
     
    7821014more than one namespace, less common namespaces are avoided when writing.
    7831015However, any namespace may be written by specifying a family 1 group name
    784 for the tag, ie) XMP-exif:Contrast or XMP-crs:Contrast.
     1016for the tag, ie) XMP-exif:Contrast or XMP-crs:Contrast.  When deciding on
     1017which tags to add to an image, using standard schemas such as
     1018L<dc|/XMP dc Tags>, L<xmp|/XMP xmp Tags> or L<iptc|/XMP iptcCore Tags> is
     1019recommended if possible.
     1020
     1021For structures, the heading of the first column is B<Field Name>.  Field
     1022names are very similar to tag names, except they are used to identify fields
     1023inside structures instead of stand-alone tags.  See
     1024L<http://owl.phy.queensu.ca/~phil/exiftool/struct.html#Fields> for more
     1025details.
    7851026
    7861027ExifTool will extract XMP information even if it is not listed in these
    7871028tables.  For example, the C<pdfx> namespace doesn't have a predefined set of
    7881029tag names because it is used to store application-defined PDF information,
    789 but this information is extracted by ExifTool anyway.
     1030but this information is extracted by ExifTool.
     1031
     1032See L<http://www.adobe.com/devnet/xmp/> for the official XMP specification.
    7901033
    7911034  Namespace                                     Writable
    7921035  ---------                                     --------
     1036  acdsee                                        XMP acdsee
     1037  album                                         XMP Album
    7931038  aux                                           XMP aux
    7941039  cc                                            XMP cc
     1040  cell                                          XMP cell
    7951041  crs                                           XMP crs
    7961042  dc                                            XMP dc
    7971043  dex                                           XMP dex
    7981044  DICOM                                         XMP DICOM
     1045  digiKam                                       XMP digiKam
    7991046  exif                                          XMP exif
    8001047  iptcCore                                      XMP iptcCore
     1048  iptcExt                                       XMP iptcExt
    8011049  lr                                            XMP Lightroom
    8021050  mediapro                                      XMP MediaPro
    803   microsoft                                     XMP Microsoft
     1051  microsoft                                     Microsoft XMP
     1052  MP                                            Microsoft MP
     1053  MP1                                           Microsoft MP1
     1054  mwg-coll                                      XMP mwg_coll
     1055  mwg-kw                                        XMP mwg_kw
     1056  mwg-rs                                        XMP mwg_rs
    8041057  pdf                                           XMP pdf
     1058  pdfx                                          XMP pdfx
    8051059  photomech                                     PhotoMechanic XMP
    8061060  photoshop                                     XMP photoshop
    8071061  PixelLive                                     XMP PixelLive
     1062  plus                                          XMP plus
     1063  prism                                         XMP prism
     1064  prl                                           XMP prl
     1065  pur                                           XMP pur
     1066  rdf                                           XMP rdf
     1067  swf                                           XMP swf
    8081068  tiff                                          XMP tiff
     1069  x                                             XMP x
    8091070  xmp                                           XMP xmp
    8101071  xmpBJ                                         XMP xmpBJ
    8111072  xmpDM                                         XMP xmpDM
    8121073  xmpMM                                         XMP xmpMM
     1074  xmpNote                                       XMP xmpNote
    8131075  xmpPLUS                                       XMP xmpPLUS
    8141076  xmpRights                                     XMP xmpRights
    8151077  xmpTPg                                        XMP xmpTPg
    8161078
    817 =head3 XMP aux Tags
    818 
    819 Photoshop Auxiliary schema tags.
     1079=head3 XMP acdsee Tags
     1080
     1081ACD Systems ACDSee schema tags.
     1082
     1083(A note to software developers: Re-inventing your own private tags instead
     1084of using the equivalent tags in standard XMP schemas defeats one of the most
     1085valuable features of metadata: interoperability.  Your applications mumble
     1086to themselves instead of speaking out for the rest of the world to hear.)
    8201087
    8211088  Tag Name                                      Writable
    8221089  --------                                      --------
     1090  Author                                        string/
     1091  Caption                                       string/
     1092  Categories                                    string/
     1093  Datetime                                      date/
     1094  Keywords                                      string/+
     1095  Notes                                         string/
     1096  Rating                                        real/
     1097  RPP                                           lang-alt
     1098  Tagged                                        boolean/
     1099
     1100=head3 XMP Album Tags
     1101
     1102Adobe Album schema tags.
     1103
     1104  Tag Name                                      Writable
     1105  --------                                      --------
     1106  Notes                                         string
     1107
     1108=head3 XMP aux Tags
     1109
     1110Photoshop Auxiliary schema tags.
     1111
     1112  Tag Name                                      Writable
     1113  --------                                      --------
     1114  ApproximateFocusDistance                      rational
    8231115  Firmware                                      string
    8241116  FlashCompensation                             rational
    8251117  ImageNumber                                   string
    8261118  Lens                                          string
     1119  LensID                                        string
    8271120  LensInfo                                      string
    8281121  OwnerName                                     string
     
    8311124=head3 XMP cc Tags
    8321125
    833 Creative Commons schema tags.
     1126Creative Commons schema tags.  (see
     1127L<http://creativecommons.org/technology/xmp>)
    8341128
    8351129  Tag Name                                      Writable
    8361130  --------                                      --------
     1131  AttributionName                               string
     1132  AttributionURL                                string
    8371133  License                                       string
     1134  MorePermissions                               string
     1135
     1136=head3 XMP cell Tags
     1137
     1138Location tags written by some Sony Ericsson phones.
     1139
     1140  Tag Name                                      Writable
     1141  --------                                      --------
     1142  CellTowerID                                   string
     1143  CellGlobalID                                  string
     1144  LocationAreaCode                              string
     1145  MobileCountryCode                             string
     1146  MobileNetworkCode                             string
     1147  CellR                                         string
    8381148
    8391149=head3 XMP crs Tags
     
    8571167  Clarity                                       integer
    8581168  ColorNoiseReduction                           integer
     1169  ColorNoiseReductionDetail                     integer
    8591170  Contrast                                      integer/
     1171  Converter                                     string
    8601172  ConvertToGrayscale                            boolean
    8611173  CropAngle                                     real
    8621174  CropBottom                                    real
     1175  CropConstrainToWarp                           integer
    8631176  CropHeight                                    real
    8641177  CropLeft                                      real
    8651178  CropRight                                     real
    8661179  CropTop                                       real
     1180  CropUnit                                      integer
    8671181  CropUnits                                     integer
    8681182  CropWidth                                     real
     
    8701184  Exposure                                      real
    8711185  FillLight                                     integer
     1186  GradientBasedCorrections                      Correction Struct+
     1187  GradientBasedCorrActive                       boolean_
     1188  GradientBasedCorrAmount                       real_
     1189  GradientBasedCorrMasks                        CorrectionMask Struct_+
     1190  GradientBasedCorrMaskCenterWeight             real_
     1191  GradientBasedCorrMaskDabs                     string_
     1192  GradientBasedCorrMaskFlow                     real_
     1193  GradientBasedCorrMaskFullX                    real_
     1194  GradientBasedCorrMaskFullY                    real_
     1195  GradientBasedCorrMaskValue                    real_
     1196  GradientBasedCorrMaskRadius                   real_
     1197  GradientBasedCorrMaskWhat                     string_
     1198  GradientBasedCorrMaskZeroX                    real_
     1199  GradientBasedCorrMaskZeroY                    real_
     1200  GradientBasedCorrBrightness                   real_
     1201  GradientBasedCorrClarity                      real_
     1202  GradientBasedCorrContrast                     real_
     1203  GradientBasedCorrExposure                     real_
     1204  GradientBasedCorrSaturation                   real_
     1205  GradientBasedCorrSharpness                    real_
     1206  GradientBasedCorrHue                          real_
     1207  GradientBasedCorrSaturation                   real_
     1208  GradientBasedCorrWhat                         string_
     1209  GrainAmount                                   integer
     1210  GrainFrequency                                integer
     1211  GrainSize                                     integer
     1212  GrayMixerAqua                                 integer
     1213  GrayMixerBlue                                 integer
     1214  GrayMixerGreen                                integer
     1215  GrayMixerMagenta                              integer
     1216  GrayMixerOrange                               integer
     1217  GrayMixerPurple                               integer
     1218  GrayMixerRed                                  integer
     1219  GrayMixerYellow                               integer
    8721220  GreenHue                                      integer
    8731221  GreenSaturation                               integer
     
    8851233  IncrementalTemperature                        integer
    8861234  IncrementalTint                               integer
     1235  LensManualDistortionAmount                    integer
     1236  LensProfileChromaticAberrationScale           integer
     1237  LensProfileDigest                             string
     1238  LensProfileDistortionScale                    integer
     1239  LensProfileEnable                             integer
     1240  LensProfileFilename                           string
     1241  LensProfileName                               string
     1242  LensProfileSetup                              string
     1243  LensProfileVignettingScale                    integer
    8871244  LuminanceAdjustmentAqua                       integer
    8881245  LuminanceAdjustmentBlue                       integer
     
    8931250  LuminanceAdjustmentRed                        integer
    8941251  LuminanceAdjustmentYellow                     integer
     1252  LuminanceNoiseReductionContrast               integer
     1253  LuminanceNoiseReductionDetail                 integer
    8951254  LuminanceSmoothing                            integer
     1255  MoireFilter                                   string
     1256  PaintBasedCorrections                         Correction Struct+
     1257  PaintCorrectionActive                         boolean_
     1258  PaintCorrectionAmount                         real_
     1259  PaintBasedCorrectionMasks                     CorrectionMask Struct_+
     1260  PaintCorrectionMaskCenterWeight               real_
     1261  PaintCorrectionMaskDabs                       string_
     1262  PaintCorrectionMaskFlow                       real_
     1263  PaintCorrectionMaskFullX                      real_
     1264  PaintCorrectionMaskFullY                      real_
     1265  PaintCorrectionMaskValue                      real_
     1266  PaintCorrectionMaskRadius                     real_
     1267  PaintCorrectionMaskWhat                       string_
     1268  PaintCorrectionMaskZeroX                      real_
     1269  PaintCorrectionMaskZeroY                      real_
     1270  PaintCorrectionBrightness                     real_
     1271  PaintCorrectionClarity                        real_
     1272  PaintCorrectionContrast                       real_
     1273  PaintCorrectionExposure                       real_
     1274  PaintCorrectionSaturation                     real_
     1275  PaintCorrectionSharpness                      real_
     1276  PaintCorrectionHue                            real_
     1277  PaintCorrectionSaturation                     real_
     1278  PaintCorrectionWhat                           string_
    8961279  ParametricDarks                               integer
    8971280  ParametricHighlights                          integer
     
    9011284  ParametricShadows                             integer
    9021285  ParametricShadowSplit                         integer
     1286  PerspectiveHorizontal                         integer
     1287  PerspectiveRotate                             real
     1288  PerspectiveScale                              integer
     1289  PerspectiveVertical                           integer
     1290  PostCropVignetteAmount                        integer
     1291  PostCropVignetteFeather                       integer
     1292  PostCropVignetteMidpoint                      integer
     1293  PostCropVignetteRoundness                     integer
     1294  PostCropVignetteStyle                         integer
     1295  ProcessVersion                                string
    9031296  RawFileName                                   string
     1297  RedEyeInfo                                    string+
    9041298  RedHue                                        integer
    9051299  RedSaturation                                 integer
     1300  RetouchInfo                                   string+
    9061301  Saturation                                    integer/
    9071302  SaturationAdjustmentAqua                      integer
     
    9191314  SharpenRadius                                 real
    9201315  Sharpness                                     integer/
     1316  Smoothness                                    integer
    9211317  SplitToningBalance                            integer
    9221318  SplitToningHighlightHue                       integer
     
    9241320  SplitToningShadowHue                          integer
    9251321  SplitToningShadowSaturation                   integer
    926   Temperature                                   integer
     1322  ColorTemperature                              integer/
    9271323  Tint                                          integer
    9281324  ToneCurve                                     string+
     
    9331329  VignetteMidpoint                              integer
    9341330  WhiteBalance                                  string/
     1331
     1332=head3 XMP Correction Struct
     1333
     1334  Field Name                                    Writable
     1335  ----------                                    --------
     1336  CorrectionActive                              boolean
     1337  CorrectionAmount                              real
     1338  CorrectionMasks                               CorrectionMask Struct+
     1339  LocalBrightness                               real
     1340  LocalClarity                                  real
     1341  LocalContrast                                 real
     1342  LocalExposure                                 real
     1343  LocalSaturation                               real
     1344  LocalSharpness                                real
     1345  LocalToningHue                                real
     1346  LocalToningSaturation                         real
     1347  What                                          string
     1348
     1349=head3 XMP CorrectionMask Struct
     1350
     1351  Field Name                                    Writable
     1352  ----------                                    --------
     1353  CenterWeight                                  real
     1354  Dabs                                          string+
     1355  Flow                                          real
     1356  FullX                                         real
     1357  FullY                                         real
     1358  MaskValue                                     real
     1359  Radius                                        real
     1360  What                                          string
     1361  ZeroX                                         real
     1362  ZeroY                                         real
    9351363
    9361364=head3 XMP dc Tags
     
    9511379  Relation                                      string+
    9521380  Rights                                        lang-alt
    953   Source                                        string
     1381  Source                                        string/
    9541382  Subject                                       string+
    9551383  Title                                         lang-alt
     
    9601388Description Explorer schema tags.  These tags are not very common.  The
    9611389Source and Rating tags are avoided when writing due to name conflicts with
    962 other XMP tags.
     1390other XMP tags.  (see L<http://www.optimasc.com/products/fileid/>)
    9631391
    9641392  Tag Name                                      Writable
     
    9811409  EquipmentInstitution                          string
    9821410  EquipmentManufacturer                         string
    983   PatientsBirthDate                             date
     1411  PatientBirthDate                              date
    9841412  PatientID                                     string
    985   PatientsName                                  string
    986   PatientsSex                                   string
     1413  PatientName                                   string
     1414  PatientSex                                    string
    9871415  SeriesDateTime                                date
    9881416  SeriesDescription                             string
     
    9941422  StudyPhysician                                string
    9951423
     1424=head3 XMP digiKam Tags
     1425
     1426DigiKam schema tags.
     1427
     1428  Tag Name                                      Writable
     1429  --------                                      --------
     1430  CaptionsAuthorNames                           lang-alt
     1431  CaptionsDateTimeStamps                        lang-alt
     1432  TagsList                                      string+
     1433
    9961434=head3 XMP exif Tags
    9971435
     
    10021440  ApertureValue                                 rational
    10031441  BrightnessValue                               rational
    1004   CFAPatternColumns                             integer
    1005   CFAPatternRows                                integer
    1006   CFAPatternValues                              integer+
     1442  CFAPattern                                    CFAPattern Struct
     1443  CFAPatternColumns                             integer_
     1444  CFAPatternRows                                integer_
     1445  CFAPatternValues                              integer_+
    10071446  ColorSpace                                    integer
    10081447  ComponentsConfiguration                       integer+
     
    10121451  DateTimeDigitized                             date
    10131452  DateTimeOriginal                              date
    1014   DeviceSettingDescriptionColumns               integer
    1015   DeviceSettingDescriptionRows                  integer
    1016   DeviceSettingDescriptionSettings              string+
     1453  DeviceSettingDescription                      DeviceSettings Struct
     1454  DeviceSettingDescriptionColumns               integer_
     1455  DeviceSettingDescriptionRows                  integer_
     1456  DeviceSettingDescriptionSettings              string_+
    10171457  DigitalZoomRatio                              rational
    10181458  ExifVersion                                   string
     
    10231463  ExposureTime                                  rational
    10241464  FileSource                                    integer
     1465  Flash                                         Flash Struct
    10251466  FlashEnergy                                   rational
    1026   FlashFired                                    boolean
    1027   FlashFunction                                 boolean
    1028   FlashMode                                     integer
     1467  FlashFired                                    boolean_
     1468  FlashFunction                                 boolean_
     1469  FlashMode                                     integer_
    10291470  FlashpixVersion                               string
    1030   FlashRedEyeMode                               boolean
    1031   FlashReturn                                   integer
     1471  FlashRedEyeMode                               boolean_
     1472  FlashReturn                                   integer_
    10321473  FNumber                                       rational
    10331474  FocalLength                                   rational
     
    10591500  GPSSpeedRef                                   string
    10601501  GPSStatus                                     string
    1061   GPSTimeStamp                                  date
     1502  GPSDateTime                                   date
    10621503  GPSTrack                                      rational
    10631504  GPSTrackRef                                   string
     
    10701511  MeteringMode                                  integer
    10711512  NativeDigest                                  string
    1072   OECFColumns                                   integer
    1073   OECFNames                                     string+
    1074   OECFRows                                      integer
    1075   OECFValues                                    rational+
     1513  Opto-ElectricConvFactor                       OECF Struct
     1514  OECFColumns                                   integer_
     1515  OECFNames                                     string_+
     1516  OECFRows                                      integer_
     1517  OECFValues                                    rational_+
    10761518  ExifImageWidth                                integer
    1077   ExifImageLength                               integer
     1519  ExifImageHeight                               integer
    10781520  RelatedSoundFile                              string
    10791521  Saturation                                    integer
     
    10831525  Sharpness                                     integer
    10841526  ShutterSpeedValue                             rational
    1085   SpatialFrequencyResponseColumns               integer
    1086   SpatialFrequencyResponseNames                 string+
    1087   SpatialFrequencyResponseRows                  integer
    1088   SpatialFrequencyResponseValues                rational+
     1527  SpatialFrequencyResponse                      OECF Struct
     1528  SpatialFrequencyResponseColumns               integer_
     1529  SpatialFrequencyResponseNames                 string_+
     1530  SpatialFrequencyResponseRows                  integer_
     1531  SpatialFrequencyResponseValues                rational_+
    10891532  SpectralSensitivity                           string
    10901533  SubjectArea                                   integer+
     
    10951538  WhiteBalance                                  integer
    10961539
     1540=head3 XMP CFAPattern Struct
     1541
     1542  Field Name                                    Writable
     1543  ----------                                    --------
     1544  Columns                                       integer
     1545  Rows                                          integer
     1546  Values                                        integer+
     1547
     1548=head3 XMP DeviceSettings Struct
     1549
     1550  Field Name                                    Writable
     1551  ----------                                    --------
     1552  Columns                                       integer
     1553  Rows                                          integer
     1554  Settings                                      string+
     1555
     1556=head3 XMP Flash Struct
     1557
     1558  Field Name                                    Writable
     1559  ----------                                    --------
     1560  Fired                                         boolean
     1561  Function                                      boolean
     1562  Mode                                          integer
     1563  RedEyeMode                                    boolean
     1564  Return                                        integer
     1565
     1566=head3 XMP OECF Struct
     1567
     1568  Field Name                                    Writable
     1569  ----------                                    --------
     1570  Columns                                       integer
     1571  Names                                         string+
     1572  Rows                                          integer
     1573  Values                                        rational+
     1574
    10971575=head3 XMP iptcCore Tags
    10981576
    1099 IPTC Core schema tags.  The actual IPTC Core namespace schema prefix is
     1577IPTC Core schema tags.  The actual IPTC Core namespace prefix is
    11001578"Iptc4xmpCore", which is the prefix recorded in the file, but ExifTool
    1101 shortens this for the "XMP-iptcCore" family 1 group name.
     1579shortens this for the "XMP-iptcCore" family 1 group name. (see
     1580L<http://www.iptc.org/IPTC4XMP/>)
    11021581
    11031582  Tag Name                                      Writable
    11041583  --------                                      --------
    11051584  CountryCode                                   string
    1106   CreatorContactInfoCiAdrCity                   string
    1107   CreatorContactInfoCiAdrCtry                   string
    1108   CreatorContactInfoCiAdrExtadr                 string
    1109   CreatorContactInfoCiAdrPcode                  string
    1110   CreatorContactInfoCiAdrRegion                 string
    1111   CreatorContactInfoCiEmailWork                 string
    1112   CreatorContactInfoCiTelWork                   string
    1113   CreatorContactInfoCiUrlWork                   string
     1585  CreatorContactInfo                            ContactInfo Struct
     1586  CreatorCity                                   string_
     1587  CreatorCountry                                string_
     1588  CreatorAddress                                string_
     1589  CreatorPostalCode                             string_
     1590  CreatorRegion                                 string_
     1591  CreatorWorkEmail                              string_
     1592  CreatorWorkTelephone                          string_
     1593  CreatorWorkURL                                string_
    11141594  IntellectualGenre                             string
    11151595  Location                                      string
     
    11171597  SubjectCode                                   string+
    11181598
     1599=head3 XMP ContactInfo Struct
     1600
     1601  Field Name                                    Writable
     1602  ----------                                    --------
     1603  CiAdrCity                                     string
     1604  CiAdrCtry                                     string
     1605  CiAdrExtadr                                   string
     1606  CiAdrPcode                                    string
     1607  CiAdrRegion                                   string
     1608  CiEmailWork                                   string
     1609  CiTelWork                                     string
     1610  CiUrlWork                                     string
     1611
     1612=head3 XMP iptcExt Tags
     1613
     1614IPTC Extension schema tags.  The actual namespace prefix is "Iptc4xmpExt",
     1615but ExifTool shortens this for the "XMP-iptcExt" family 1 group name.
     1616(see L<http://www.iptc.org/IPTC4XMP/>)
     1617
     1618  Tag Name                                      Writable
     1619  --------                                      --------
     1620  AdditionalModelInformation                    string
     1621  ArtworkOrObject                               ArtworkOrObjectDetails Struct+
     1622  ArtworkCopyrightNotice                        string_+
     1623  ArtworkCreator                                string_+
     1624  ArtworkDateCreated                            date_+
     1625  ArtworkSource                                 string_+
     1626  ArtworkSourceInventoryNo                      string_+
     1627  ArtworkTitle                                  lang-alt_+
     1628  ControlledVocabularyTerm                      string+
     1629  DigitalImageGUID                              string
     1630  DigitalSourceFileType                         string
     1631  DigitalSourceType                             string
     1632  Event                                         lang-alt
     1633  IptcLastEdited                                date
     1634  LocationCreated                               LocationDetails Struct+
     1635  LocationCreatedCity                           string_+
     1636  LocationCreatedCountryCode                    string_+
     1637  LocationCreatedCountryName                    string_+
     1638  LocationCreatedProvinceState                  string_+
     1639  LocationCreatedSublocation                    string_+
     1640  LocationCreatedWorldRegion                    string_+
     1641  LocationShown                                 LocationDetails Struct+
     1642  LocationShownCity                             string_+
     1643  LocationShownCountryCode                      string_+
     1644  LocationShownCountryName                      string_+
     1645  LocationShownProvinceState                    string_+
     1646  LocationShownSublocation                      string_+
     1647  LocationShownWorldRegion                      string_+
     1648  MaxAvailHeight                                integer
     1649  MaxAvailWidth                                 integer
     1650  ModelAge                                      integer+
     1651  OrganisationInImageCode                       string+
     1652  OrganisationInImageName                       string+
     1653  PersonInImage                                 string+
     1654  RegistryId                                    RegistryEntryDetails Struct+
     1655  RegistryItemID                                string_+
     1656  RegistryOrganisationID                        string_+
     1657
     1658=head3 XMP ArtworkOrObjectDetails Struct
     1659
     1660  Field Name                                    Writable
     1661  ----------                                    --------
     1662  AOCopyrightNotice                             string
     1663  AOCreator                                     string+
     1664  AODateCreated                                 date
     1665  AOSource                                      string
     1666  AOSourceInvNo                                 string
     1667  AOTitle                                       lang-alt
     1668
     1669=head3 XMP LocationDetails Struct
     1670
     1671  Field Name                                    Writable
     1672  ----------                                    --------
     1673  City                                          string
     1674  CountryCode                                   string
     1675  CountryName                                   string
     1676  ProvinceState                                 string
     1677  Sublocation                                   string
     1678  WorldRegion                                   string
     1679
     1680=head3 XMP RegistryEntryDetails Struct
     1681
     1682  Field Name                                    Writable
     1683  ----------                                    --------
     1684  RegItemId                                     string
     1685  RegOrgId                                      string
     1686
    11191687=head3 XMP Lightroom Tags
    11201688
     
    11281696=head3 XMP MediaPro Tags
    11291697
    1130 IView MediaPro schema tags.
     1698iView MediaPro schema tags.
    11311699
    11321700  Tag Name                                      Writable
     
    11391707  UserFields                                    string+
    11401708
    1141 =head3 XMP Microsoft Tags
    1142 
    1143 Microsoft Photo schema tags.  This is likely not a complete list, but
    1144 represents tags which have been observed in sample images.  The actual
    1145 namespace prefix is "MicrosoftPhoto", but ExifTool shortens this to
    1146 "XMP-microsoft" in the family 1 group name.
     1709=head3 XMP mwg_coll Tags
     1710
     1711Collections metadata defined by the MWG 2.0 specification.  See
     1712L<http://www.metadataworkinggroup.org/> for the official specification.
    11471713
    11481714  Tag Name                                      Writable
    11491715  --------                                      --------
    1150   CameraSerialNumber                            string
    1151   DateAcquired                                  date
    1152   FlashManufacturer                             string
    1153   FlashModel                                    string
    1154   LastKeywordIPTC                               string+
    1155   LastKeywordXMP                                string+
    1156   LensManufacturer                              string
    1157   LensModel                                     string
    1158   RatingPercent                                 string
     1716  Collections                                   CollectionInfo Struct+
     1717  CollectionName                                string_+
     1718  CollectionURI                                 string_+
     1719
     1720=head3 XMP CollectionInfo Struct
     1721
     1722  Field Name                                    Writable
     1723  ----------                                    --------
     1724  CollectionName                                string
     1725  CollectionURI                                 string
     1726
     1727=head3 XMP mwg_kw Tags
     1728
     1729Hierarchical keywords metadata defined by the MWG 2.0 specification.
     1730ExifTool unrolls keyword structures to an arbitrary depth of 4 to allow
     1731individual levels to be accessed with different tag names, and to avoid
     1732infinite recursion.  See L<http://www.metadataworkinggroup.org/> for the
     1733official specification.
     1734
     1735  Tag Name                                      Writable
     1736  --------                                      --------
     1737  KeywordInfo                                   KeywordInfo Struct
     1738  HierarchicalKeywords                          KeywordStruct1 Struct_+
     1739  HierarchicalKeywords1Applied                  boolean_+
     1740  HierarchicalKeywords1Children                 KeywordStruct2 Struct_+
     1741  HierarchicalKeywords2Applied                  boolean_+
     1742  HierarchicalKeywords2Children                 KeywordStruct3 Struct_+
     1743  HierarchicalKeywords3Applied                  boolean_+
     1744  HierarchicalKeywords3Children                 KeywordStruct4 Struct_+
     1745  HierarchicalKeywords4Applied                  boolean_+
     1746  HierarchicalKeywords4                         string_+
     1747  HierarchicalKeywords3                         string_+
     1748  HierarchicalKeywords2                         string_+
     1749  HierarchicalKeywords1                         string_+
     1750
     1751=head3 XMP KeywordInfo Struct
     1752
     1753  Field Name                                    Writable
     1754  ----------                                    --------
     1755  Hierarchy                                     KeywordStruct1 Struct+
     1756
     1757=head3 XMP KeywordStruct1 Struct
     1758
     1759  Field Name                                    Writable
     1760  ----------                                    --------
     1761  Applied                                       boolean
     1762  Children                                      KeywordStruct2 Struct+
     1763  Keyword                                       string
     1764
     1765=head3 XMP KeywordStruct2 Struct
     1766
     1767  Field Name                                    Writable
     1768  ----------                                    --------
     1769  Applied                                       boolean
     1770  Children                                      KeywordStruct3 Struct+
     1771  Keyword                                       string
     1772
     1773=head3 XMP KeywordStruct3 Struct
     1774
     1775  Field Name                                    Writable
     1776  ----------                                    --------
     1777  Applied                                       boolean
     1778  Children                                      KeywordStruct4 Struct+
     1779  Keyword                                       string
     1780
     1781=head3 XMP KeywordStruct4 Struct
     1782
     1783  Field Name                                    Writable
     1784  ----------                                    --------
     1785  Applied                                       boolean
     1786  Keyword                                       string
     1787
     1788=head3 XMP mwg_rs Tags
     1789
     1790Image region metadata defined by the MWG 2.0 specification.  See
     1791L<http://www.metadataworkinggroup.org/> for the official specification.
     1792
     1793  Tag Name                                      Writable
     1794  --------                                      --------
     1795  RegionInfo                                    RegionInfo Struct
     1796  RegionAppliedToDimensions                     Dimensions Struct_
     1797  RegionAppliedToDimensionsH                    real_
     1798  RegionAppliedToDimensionsUnit                 string_
     1799  RegionAppliedToDimensionsW                    real_
     1800  RegionList                                    RegionStruct Struct_+
     1801  RegionArea                                    Area Struct_+
     1802  RegionAreaD                                   real_+
     1803  RegionAreaH                                   real_+
     1804  RegionAreaUnit                                string_+
     1805  RegionAreaW                                   real_+
     1806  RegionAreaX                                   real_+
     1807  RegionAreaY                                   real_+
     1808  RegionBarCodeValue                            string_+
     1809  RegionDescription                             string_+
     1810  RegionExtensions                              Extensions Struct_+
     1811  RegionFocusUsage                              string_+
     1812  RegionName                                    string_+
     1813  RegionSeeAlso                                 string_+
     1814  RegionType                                    string_+
     1815
     1816=head3 XMP RegionInfo Struct
     1817
     1818  Field Name                                    Writable
     1819  ----------                                    --------
     1820  AppliedToDimensions                           Dimensions Struct
     1821  RegionList                                    RegionStruct Struct+
     1822
     1823=head3 XMP Dimensions Struct
     1824
     1825  Field Name                                    Writable
     1826  ----------                                    --------
     1827  H                                             real
     1828  Unit                                          string
     1829  W                                             real
     1830
     1831=head3 XMP RegionStruct Struct
     1832
     1833  Field Name                                    Writable
     1834  ----------                                    --------
     1835  Area                                          Area Struct
     1836  BarCodeValue                                  string
     1837  Description                                   string
     1838  Extensions                                    Extensions Struct
     1839  FocusUsage                                    string
     1840  Name                                          string
     1841  Type                                          string
     1842  SeeAlso                                       string
     1843
     1844=head3 XMP Area Struct
     1845
     1846  Field Name                                    Writable
     1847  ----------                                    --------
     1848  D                                             real
     1849  H                                             real
     1850  Unit                                          string
     1851  W                                             real
     1852  X                                             real
     1853  Y                                             real
     1854
     1855=head3 XMP Extensions Struct
     1856
     1857This structure may contain any top-level XMP tags, but none have been
     1858pre-defined in ExifTool.  Without pre-defined flattened tag names,
     1859RegionExtensions may be written only as a structure (ie.
     1860C<{xmp-dc:creator=me,rating=5}>).  Fields for this structure are identified
     1861using the standard ExifTool tag name (with optional leading group name,
     1862and/or trailing language code, and/or trailing C<#> symbol to disable print
     1863conversion).
     1864
     1865  Field Name                                    Writable
     1866  ----------                                    --------
     1867  [no tags known]
    11591868
    11601869=head3 XMP pdf Tags
    11611870
    11621871Adobe PDF schema tags.  The official XMP specification defines only
    1163 Keywords, PDFVersion and Producer.  The other tags are included because they
    1164 have been observed in PDF files, but Creator, Subject and Title are avoided
    1165 when writing due to name conflicts with XMP-dc tags.
     1872Keywords, PDFVersion, Producer and Trapped.  The other tags are included
     1873because they have been observed in PDF files, but some are avoided when
     1874writing due to name conflicts with other XMP namespaces.
    11661875
    11671876  Tag Name                                      Writable
    11681877  --------                                      --------
    11691878  Author                                        string
     1879  Copyright                                     string/
    11701880  CreationDate                                  date
    11711881  Creator                                       string/
    11721882  Keywords                                      string
     1883  Marked                                        boolean/
    11731884  ModDate                                       date
    11741885  PDFVersion                                    string
     
    11761887  Subject                                       string/
    11771888  Title                                         string/
     1889  Trapped                                       string
     1890
     1891=head3 XMP pdfx Tags
     1892
     1893PDF extension tags.  This namespace is used to store application-defined PDF
     1894information, so there are no pre-defined tags.  User-defined tags must be
     1895created to enable writing of XMP-pdfx information.
     1896
     1897  Tag Name                                      Writable
     1898  --------                                      --------
     1899  [no tags known]
    11781900
    11791901=head3 XMP photoshop Tags
     
    11871909  Category                                      string
    11881910  City                                          string
    1189   ColorMode                                     string
     1911  ColorMode                                     integer
    11901912  Country                                       string
    11911913  Credit                                        string
    11921914  DateCreated                                   date
     1915  DocumentAncestors                             Ancestor Struct+
     1916  DocumentAncestorID                            string_+
    11931917  Headline                                      string
    11941918  History                                       string
     
    11971921  LegacyIPTCDigest                              string
    11981922  SidecarForExtension                           string
    1199   Source                                        string/
     1923  Source                                        string
    12001924  State                                         string
    12011925  SupplementalCategories                        string+
     1926  TextLayers                                    Layer Struct+
     1927  TextLayerName                                 string_+
     1928  TextLayerText                                 string_+
    12021929  TransmissionReference                         string
    12031930  Urgency                                       integer
     1931
     1932=head3 XMP Ancestor Struct
     1933
     1934  Field Name                                    Writable
     1935  ----------                                    --------
     1936  AncestorID                                    string
     1937
     1938=head3 XMP Layer Struct
     1939
     1940  Field Name                                    Writable
     1941  ----------                                    --------
     1942  LayerName                                     string
     1943  LayerText                                     string
    12041944
    12051945=head3 XMP PixelLive Tags
     
    12171957  Genre                                         N
    12181958  Title                                         N
     1959
     1960=head3 XMP plus Tags
     1961
     1962PLUS License Data Format 1.2.0 schema tags.  Note that all
     1963controlled-vocabulary tags in this table (ie. tags with a fixed set of
     1964values) have raw values which begin with "http://ns.useplus.org/ldf/vocab/",
     1965but to reduce clutter this prefix has been removed from the values shown
     1966below.  (see L<http://ns.useplus.org/>)
     1967
     1968  Tag Name                                      Writable
     1969  --------                                      --------
     1970  AdultContentWarning                           string
     1971  CopyrightOwner                                CopyrightOwner Struct+
     1972  CopyrightOwnerID                              string_+
     1973  CopyrightOwnerName                            string_+
     1974  CopyrightOwnerImageID                         string
     1975  CopyrightRegistrationNumber                   string
     1976  CopyrightStatus                               string
     1977  CreditLineRequired                            string
     1978  Custom1                                       lang-alt+
     1979  Custom10                                      lang-alt+
     1980  Custom2                                       lang-alt+
     1981  Custom3                                       lang-alt+
     1982  Custom4                                       lang-alt+
     1983  Custom5                                       lang-alt+
     1984  Custom6                                       lang-alt+
     1985  Custom7                                       lang-alt+
     1986  Custom8                                       lang-alt+
     1987  Custom9                                       lang-alt+
     1988  EndUser                                       EndUser Struct+
     1989  EndUserID                                     string_+
     1990  EndUserName                                   string_+
     1991  FileNameAsDelivered                           string
     1992  FirstPublicationDate                          date
     1993  ImageAlterationConstraints                    string+
     1994  ImageCreator                                  ImageCreator Struct+
     1995  ImageCreatorID                                string_+
     1996  ImageCreatorName                              string_+
     1997  ImageCreatorImageID                           string
     1998  ImageDuplicationConstraints                   string
     1999  ImageFileConstraints                          string+
     2000  ImageFileFormatAsDelivered                    string
     2001  ImageFileSizeAsDelivered                      string
     2002  ImageSupplier                                 ImageSupplier Struct+
     2003  ImageSupplierImageID                          string
     2004  ImageSupplierID                               string_+
     2005  ImageSupplierName                             string_+
     2006  ImageType                                     string
     2007  Licensee                                      Licensee Struct+
     2008  LicenseeImageID                               string
     2009  LicenseeImageNotes                            lang-alt
     2010  LicenseeID                                    string_+
     2011  LicenseeName                                  string_+
     2012  LicenseEndDate                                date
     2013  LicenseeProjectReference                      string+
     2014  LicenseeTransactionID                         string+
     2015  LicenseID                                     string
     2016  LicenseStartDate                              date
     2017  LicenseTransactionDate                        date
     2018  Licensor                                      Licensor Struct+
     2019  LicensorImageID                               string
     2020  LicensorCity                                  string_+
     2021  LicensorCountry                               string_+
     2022  LicensorEmail                                 string_+
     2023  LicensorExtendedAddress                       string_+
     2024  LicensorID                                    string_+
     2025  LicensorName                                  string_+
     2026  LicensorPostalCode                            string_+
     2027  LicensorRegion                                string_+
     2028  LicensorStreetAddress                         string_+
     2029  LicensorTelephone1                            string_+
     2030  LicensorTelephone2                            string_+
     2031  LicensorTelephoneType1                        string_+
     2032  LicensorTelephoneType2                        string_+
     2033  LicensorURL                                   string_+
     2034  LicensorNotes                                 lang-alt
     2035  LicensorTransactionID                         string+
     2036  MediaConstraints                              lang-alt
     2037  MediaSummaryCode                              string
     2038  MinorModelAgeDisclosure                       string
     2039  ModelReleaseID                                string+
     2040  ModelReleaseStatus                            string
     2041  OtherConditions                               lang-alt
     2042  OtherConstraints                              lang-alt
     2043  OtherImageInfo                                lang-alt
     2044  OtherLicenseDocuments                         string+
     2045  OtherLicenseInfo                              lang-alt
     2046  OtherLicenseRequirements                      lang-alt
     2047  ProductOrServiceConstraints                   lang-alt
     2048  PropertyReleaseID                             string+
     2049  PropertyReleaseStatus                         string
     2050  RegionConstraints                             lang-alt
     2051  Reuse                                         string
     2052  TermsAndConditionsText                        lang-alt
     2053  TermsAndConditionsURL                         string
     2054  PLUSVersion                                   string
     2055
     2056=head3 XMP CopyrightOwner Struct
     2057
     2058  Field Name                                    Writable
     2059  ----------                                    --------
     2060  CopyrightOwnerID                              string
     2061  CopyrightOwnerName                            string
     2062
     2063=head3 XMP EndUser Struct
     2064
     2065  Field Name                                    Writable
     2066  ----------                                    --------
     2067  EndUserID                                     string
     2068  EndUserName                                   string
     2069
     2070=head3 XMP ImageCreator Struct
     2071
     2072  Field Name                                    Writable
     2073  ----------                                    --------
     2074  ImageCreatorID                                string
     2075  ImageCreatorName                              string
     2076
     2077=head3 XMP ImageSupplier Struct
     2078
     2079  Field Name                                    Writable
     2080  ----------                                    --------
     2081  ImageSupplierID                               string
     2082  ImageSupplierName                             string
     2083
     2084=head3 XMP Licensee Struct
     2085
     2086  Field Name                                    Writable
     2087  ----------                                    --------
     2088  LicenseeID                                    string
     2089  LicenseeName                                  string
     2090
     2091=head3 XMP Licensor Struct
     2092
     2093  Field Name                                    Writable
     2094  ----------                                    --------
     2095  LicensorCity                                  string
     2096  LicensorCountry                               string
     2097  LicensorEmail                                 string
     2098  LicensorExtendedAddress                       string
     2099  LicensorID                                    string
     2100  LicensorName                                  string
     2101  LicensorPostalCode                            string
     2102  LicensorRegion                                string
     2103  LicensorStreetAddress                         string
     2104  LicensorTelephone1                            string
     2105  LicensorTelephone2                            string
     2106  LicensorTelephoneType1                        string
     2107  LicensorTelephoneType2                        string
     2108  LicensorURL                                   string
     2109
     2110=head3 XMP prism Tags
     2111
     2112Publishing Requirements for Industry Standard Metadata 2.1 schema tags. (see
     2113L<http://www.prismstandard.org/>)
     2114
     2115  Tag Name                                      Writable
     2116  --------                                      --------
     2117  AggregationType                               string/+
     2118  AlternateTitle                                string/+
     2119  ByteCount                                     integer/
     2120  Channel                                       string/+
     2121  ComplianceProfile                             string/
     2122  Copyright                                     string/
     2123  CorporateEntity                               string/+
     2124  CoverDate                                     date/
     2125  CoverDisplayDate                              string/
     2126  CreationDate                                  date/
     2127  DateRecieved                                  date/
     2128  Distributor                                   string/
     2129  DOI                                           string/
     2130  Edition                                       string/
     2131  EIssn                                         string/
     2132  EmbargoDate                                   date/+
     2133  EndingPage                                    string/
     2134  Event                                         string/+
     2135  ExpirationDate                                date/+
     2136  Genre                                         string/+
     2137  HasAlternative                                string/+
     2138  HasCorrection                                 string/
     2139  HasPreviousVersion                            string/
     2140  HasTranslation                                string/+
     2141  Industry                                      string/+
     2142  ISBN                                          string/
     2143  IsCorrectionOf                                string/+
     2144  ISSN                                          string/
     2145  IssueIdentifier                               string/
     2146  IssueName                                     string/
     2147  IsTranslationOf                               string/
     2148  Keyword                                       string/+
     2149  KillDate                                      date/
     2150  Location                                      string/+
     2151  ModificationDate                              date/
     2152  Number                                        string/
     2153  Object                                        string/+
     2154  Organization                                  string/+
     2155  OriginPlatform                                string/+
     2156  PageRange                                     string/+
     2157  Person                                        string/
     2158  PublicationDate                               date/+
     2159  PublicationName                               string/
     2160  RightsAgent                                   string/
     2161  Section                                       string/
     2162  StartingPage                                  string/
     2163  Subsection1                                   string/
     2164  Subsection2                                   string/
     2165  Subsection3                                   string/
     2166  Subsection4                                   string/
     2167  Teaser                                        string/+
     2168  Ticker                                        string/+
     2169  TimePeriod                                    string/
     2170  URL                                           string/+
     2171  VersionIdentifier                             string/
     2172  Volume                                        string/
     2173  WordCount                                     integer/
     2174
     2175=head3 XMP prl Tags
     2176
     2177PRISM Rights Language 2.1 schema tags.  (see
     2178L<http://www.prismstandard.org/>)
     2179
     2180  Tag Name                                      Writable
     2181  --------                                      --------
     2182  Geography                                     string/+
     2183  Industry                                      string/+
     2184  Usage                                         string/+
     2185
     2186=head3 XMP pur Tags
     2187
     2188Prism Usage Rights 2.1 schema tags.  (see L<http://www.prismstandard.org/>)
     2189
     2190  Tag Name                                      Writable
     2191  --------                                      --------
     2192  AdultContentWarning                           string/+
     2193  Agreement                                     string/+
     2194  Copyright                                     lang-alt/
     2195  CreditLine                                    string/+
     2196  EmbargoDate                                   date/+
     2197  ExclusivityEndDate                            date/+
     2198  ExpirationDate                                date/+
     2199  ImageSizeRestriction                          string/
     2200  OptionEndDate                                 date/+
     2201  Permissions                                   string/+
     2202  Restrictions                                  string/+
     2203  ReuseProhibited                               boolean/
     2204  RightsAgent                                   string/
     2205  RightsOwner                                   string/
     2206  UsageFee                                      string/+
     2207
     2208=head3 XMP rdf Tags
     2209
     2210Most RDF attributes are handled internally, but the "about" attribute is
     2211treated specially to allow it to be set to a specific value if required.
     2212
     2213  Tag Name                                      Writable
     2214  --------                                      --------
     2215  About                                         string!
     2216
     2217=head3 XMP swf Tags
     2218
     2219Adobe SWF schema tags.
     2220
     2221  Tag Name                                      Writable
     2222  --------                                      --------
     2223  BackgroundAlpha                               integer
     2224  ForwardLock                                   boolean
     2225  MaxStorage                                    integer
     2226  Type                                          string/
    12192227
    12202228=head3 XMP tiff Tags
     
    12512259  YResolution                                   rational
    12522260
     2261=head3 XMP x Tags
     2262
     2263The "x" namespace is used for the "xmpmeta" wrapper, and may contain an
     2264"xmptk" attribute that is extracted as the XMPToolkit tag.  When writing,
     2265the XMPToolkit tag is automatically generated by ExifTool unless
     2266specifically set to another value.
     2267
     2268  Tag Name                                      Writable
     2269  --------                                      --------
     2270  XMPToolkit                                    string!
     2271
    12532272=head3 XMP xmp Tags
    12542273
     
    12682287  ModifyDate                                    date
    12692288  Nickname                                      string
    1270   Rating                                        integer
    1271   ThumbnailsFormat                              string+
    1272   ThumbnailsHeight                              string+
    1273   ThumbnailsImage                               N+
    1274   ThumbnailsWidth                               string+
     2289  PageInfo                                      PageInfo Struct+
     2290  PageImageFormat                               string_+
     2291  PageImageHeight                               integer_+
     2292  PageImage                                     string_+
     2293  PageImagePageNumber                           integer_+
     2294  PageImageWidth                                integer_+
     2295  Rating                                        real
     2296  Thumbnails                                    Thumbnail Struct+
     2297  ThumbnailFormat                               string_+
     2298  ThumbnailHeight                               integer_+
     2299  ThumbnailImage                                string/_+
     2300  ThumbnailWidth                                integer_+
     2301
     2302=head3 XMP PageInfo Struct
     2303
     2304  Field Name                                    Writable
     2305  ----------                                    --------
     2306  PageNumber                                    integer
     2307  Format                                        string
     2308  Height                                        integer
     2309  Image                                         string
     2310  Width                                         integer
     2311
     2312=head3 XMP Thumbnail Struct
     2313
     2314  Field Name                                    Writable
     2315  ----------                                    --------
     2316  Format                                        string
     2317  Height                                        integer
     2318  Image                                         string
     2319  Width                                         integer
    12752320
    12762321=head3 XMP xmpBJ Tags
     
    12802325  Tag Name                                      Writable
    12812326  --------                                      --------
    1282   JobRefId                                      string+
    1283   JobRefName                                    string+
    1284   JobRefUrl                                     string+
     2327  JobRef                                        JobRef Struct+
     2328  JobRefId                                      string_+
     2329  JobRefName                                    string_+
     2330  JobRefUrl                                     string_+
     2331
     2332=head3 XMP JobRef Struct
     2333
     2334  Field Name                                    Writable
     2335  ----------                                    --------
     2336  Id                                            string
     2337  Name                                          string
     2338  Url                                           string
    12852339
    12862340=head3 XMP xmpDM Tags
     
    12932347  Album                                         string
    12942348  AltTapeName                                   string
    1295   AltTimecodeTimeFormat                         string
    1296   AltTimecodeTimeValue                          string
     2349  AltTimecode                                   Timecode Struct
     2350  AltTimecodeTimeFormat                         string_
     2351  AltTimecodeTimeValue                          string_
     2352  AltTimecodeValue                              integer_
    12972353  Artist                                        string/
    12982354  AudioChannelType                              string
     
    13012357  AudioSampleRate                               integer
    13022358  AudioSampleType                               string
    1303   BeatSpliceParamsRiseInDecibel                 real
    1304   BeatSpliceParamsRiseInTimeDuration            string
    1305   BeatSpliceParamsUseFileBeatsMarker            boolean
     2359  BeatSpliceParams                              BeatSpliceStretch Struct
     2360  BeatSpliceParamsRiseInDecibel                 real_
     2361  BeatSpliceParamsRiseInTimeDuration            Time Struct_
     2362  BeatSpliceParamsRiseInTimeDurationScale       rational_
     2363  BeatSpliceParamsRiseInTimeDurationValue       integer_
     2364  BeatSpliceParamsUseFileBeatsMarker            boolean_
     2365  CameraAngle                                   string
     2366  CameraLabel                                   string
     2367  CameraModel                                   string
     2368  CameraMove                                    string
     2369  Client                                        string
     2370  DMComment                                     string
    13062371  Composer                                      string
    1307   ContributedMediaDuration                      string+
    1308   ContributedMediaManaged                       boolean+
    1309   ContributedMediaPath                          string+
    1310   ContributedMediaStartTime                     string+
    1311   ContributedMediaTrack                         string+
    1312   ContributedMediaWebStatement                  string+
     2372  ContributedMedia                              Media Struct+
     2373  ContributedMediaDuration                      Time Struct_+
     2374  ContributedMediaDurationScale                 rational_+
     2375  ContributedMediaDurationValue                 integer_+
     2376  ContributedMediaManaged                       boolean_+
     2377  ContributedMediaPath                          string_+
     2378  ContributedMediaStartTime                     Time Struct_+
     2379  ContributedMediaStartTimeScale                rational_+
     2380  ContributedMediaStartTimeValue                integer_+
     2381  ContributedMediaTrack                         string_+
     2382  ContributedMediaWebStatement                  string_+
    13132383  Copyright                                     string/
    1314   Duration                                      string
     2384  Director                                      string
     2385  DirectorPhotography                           string
     2386  Duration                                      Time Struct
     2387  DurationScale                                 rational_
     2388  DurationValue                                 integer_
    13152389  Engineer                                      string
    13162390  FileDataRate                                  rational
    13172391  Genre                                         string
     2392  Good                                          boolean
    13182393  Instrument                                    string
    1319   IntroTime                                     string
     2394  IntroTime                                     Time Struct
     2395  IntroTimeScale                                rational_
     2396  IntroTimeValue                                integer_
    13202397  Key                                           string
    13212398  LogComment                                    string
    13222399  Loop                                          boolean
    1323   MarkersComment                                string+
    1324   MarkersDuration                               string+
    1325   MarkersLocation                               string+
    1326   MarkersName                                   string+
    1327   MarkersStartTime                              string+
    1328   MarkersTarget                                 string+
    1329   MarkersType                                   string+
     2400  Markers                                       Marker Struct+
     2401  MarkersComment                                string_+
     2402  MarkersCuePointParams                         CuePointParam Struct_+
     2403  MarkersCuePointParamsKey                      string_+
     2404  MarkersCuePointParamsValue                    string_+
     2405  MarkersCuePointType                           string_+
     2406  MarkersDuration                               string_+
     2407  MarkersLocation                               string_+
     2408  MarkersName                                   string_+
     2409  MarkersProbability                            real_+
     2410  MarkersSpeaker                                string_+
     2411  MarkersStartTime                              string_+
     2412  MarkersTarget                                 string_+
     2413  MarkersType                                   string_+
    13302414  MetadataModDate                               date
    13312415  NumberOfBeats                                 real
    1332   OutCue                                        string
    1333   ProjectRefPath                                string
    1334   ProjectRefType                                string
     2416  OutCue                                        Time Struct
     2417  OutCueScale                                   rational_
     2418  OutCueValue                                   integer_
     2419  ProjectName                                   string
     2420  ProjectRef                                    ProjectLink Struct
     2421  ProjectRefPath                                string_
     2422  ProjectRefType                                string_
    13352423  PullDown                                      string
    13362424  RelativePeakAudioFilePath                     string
    1337   RelativeTimestamp                             string
     2425  RelativeTimestamp                             Time Struct
     2426  RelativeTimestampScale                        rational_
     2427  RelativeTimestampValue                        integer_
    13382428  ReleaseDate                                   date
    1339   ResampleParamsQuality                         string
     2429  ResampleParams                                ResampleStretch Struct
     2430  ResampleParamsQuality                         string_
    13402431  ScaleType                                     string
    13412432  Scene                                         string/
    13422433  ShotDate                                      date
     2434  ShotDay                                       string
    13432435  ShotLocation                                  string
    13442436  ShotName                                      string
     2437  ShotNumber                                    string
     2438  ShotSize                                      string
    13452439  SpeakerPlacement                              string
    1346   StartTimecodeTimeFormat                       string
    1347   StartTimecodeTimeValue                        string
     2440  StartTimecode                                 Timecode Struct
     2441  StartTimecodeTimeFormat                       string_
     2442  StartTimecodeTimeValue                        string_
     2443  StartTimecodeValue                            integer_
    13482444  StretchMode                                   string
     2445  TakeNumber                                    integer
    13492446  TapeName                                      string
    13502447  Tempo                                         real
    1351   TimeScaleParamsFrameOverlappingPercentage     real
    1352   TimeScaleParamsFrameSize                      real
    1353   TimeScaleParamsQuality                        string
     2448  TimeScaleParams                               TimeScaleStretch Struct
     2449  TimeScaleParamsFrameOverlappingPercentage     real_
     2450  TimeScaleParamsFrameSize                      real_
     2451  TimeScaleParamsQuality                        string_
    13542452  TimeSignature                                 string
    13552453  TrackNumber                                   integer
     2454  Tracks                                        Track Struct+
     2455  TracksFrameRate                               string_+
     2456  TracksMarkers                                 Marker Struct_+
     2457  TracksMarkersComment                          string_+
     2458  TracksMarkersCuePointParams                   CuePointParam Struct_+
     2459  TracksMarkersCuePointParamsKey                string_+
     2460  TracksMarkersCuePointParamsValue              string_+
     2461  TracksMarkersCuePointType                     string_+
     2462  TracksMarkersDuration                         string_+
     2463  TracksMarkersLocation                         string_+
     2464  TracksMarkersName                             string_+
     2465  TracksMarkersProbability                      real_+
     2466  TracksMarkersSpeaker                          string_+
     2467  TracksMarkersStartTime                        string_+
     2468  TracksMarkersTarget                           string_+
     2469  TracksMarkersType                             string_+
     2470  TracksTrackName                               string_+
     2471  TracksTrackType                               string_+
    13562472  VideoAlphaMode                                string
    1357   VideoAlphaPremultipleColorA                   integer
    1358   VideoAlphaPremultipleColorB                   integer
    1359   VideoAlphaPremultipleColorBlack               real
    1360   VideoAlphaPremultipleColorBlue                integer
    1361   VideoAlphaPremultipleColorCyan                real
    1362   VideoAlphaPremultipleColorGreen               integer
    1363   VideoAlphaPremultipleColorL                   real
    1364   VideoAlphaPremultipleColorMagenta             real
    1365   VideoAlphaPremultipleColorMode                string
    1366   VideoAlphaPremultipleColorRed                 integer
    1367   VideoAlphaPremultipleColorSwatchName          string
    1368   VideoAlphaPremultipleColorType                string
    1369   VideoAlphaPremultipleColorYellow              real
     2473  VideoAlphaPremultipleColor                    Colorant Struct
     2474  VideoAlphaPremultipleColorA                   integer_
     2475  VideoAlphaPremultipleColorB                   integer_
     2476  VideoAlphaPremultipleColorBlack               real_
     2477  VideoAlphaPremultipleColorBlue                integer_
     2478  VideoAlphaPremultipleColorCyan                real_
     2479  VideoAlphaPremultipleColorGreen               integer_
     2480  VideoAlphaPremultipleColorL                   real_
     2481  VideoAlphaPremultipleColorMagenta             real_
     2482  VideoAlphaPremultipleColorMode                string_
     2483  VideoAlphaPremultipleColorRed                 integer_
     2484  VideoAlphaPremultipleColorSwatchName          string_
     2485  VideoAlphaPremultipleColorType                string_
     2486  VideoAlphaPremultipleColorYellow              real_
    13702487  VideoAlphaUnityIsTransparent                  boolean
    13712488  VideoColorSpace                               string
     
    13732490  VideoFieldOrder                               string
    13742491  VideoFrameRate                                string
    1375   VideoFrameSizeH                               real
    1376   VideoFrameSizeUnit                            string
    1377   VideoFrameSizeW                               real
     2492  VideoFrameSize                                Dimensions Struct
     2493  VideoFrameSizeH                               real_
     2494  VideoFrameSizeUnit                            string_
     2495  VideoFrameSizeW                               real_
    13782496  VideoModDate                                  date
    13792497  VideoPixelAspectRatio                         rational
    13802498  VideoPixelDepth                               string
    13812499
     2500=head3 XMP Timecode Struct
     2501
     2502  Field Name                                    Writable
     2503  ----------                                    --------
     2504  TimeFormat                                    string
     2505  TimeValue                                     string
     2506  Value                                         integer
     2507
     2508=head3 XMP BeatSpliceStretch Struct
     2509
     2510  Field Name                                    Writable
     2511  ----------                                    --------
     2512  RiseInDecibel                                 real
     2513  RiseInTimeDuration                            Time Struct
     2514  UseFileBeatsMarker                            boolean
     2515
     2516=head3 XMP Time Struct
     2517
     2518  Field Name                                    Writable
     2519  ----------                                    --------
     2520  Scale                                         rational
     2521  Value                                         integer
     2522
     2523=head3 XMP Media Struct
     2524
     2525  Field Name                                    Writable
     2526  ----------                                    --------
     2527  Duration                                      Time Struct
     2528  Managed                                       boolean
     2529  Path                                          string
     2530  StartTime                                     Time Struct
     2531  Track                                         string
     2532  WebStatement                                  string
     2533
     2534=head3 XMP Marker Struct
     2535
     2536  Field Name                                    Writable
     2537  ----------                                    --------
     2538  Comment                                       string
     2539  CuePointParams                                CuePointParam Struct+
     2540  CuePointType                                  string
     2541  Duration                                      string
     2542  Location                                      string
     2543  Name                                          string
     2544  Probability                                   real
     2545  Speaker                                       string
     2546  StartTime                                     string
     2547  Target                                        string
     2548  Type                                          string
     2549
     2550=head3 XMP CuePointParam Struct
     2551
     2552  Field Name                                    Writable
     2553  ----------                                    --------
     2554  Key                                           string
     2555  Value                                         string
     2556
     2557=head3 XMP ProjectLink Struct
     2558
     2559  Field Name                                    Writable
     2560  ----------                                    --------
     2561  Path                                          string
     2562  Type                                          string
     2563
     2564=head3 XMP ResampleStretch Struct
     2565
     2566  Field Name                                    Writable
     2567  ----------                                    --------
     2568  Quality                                       string
     2569
     2570=head3 XMP TimeScaleStretch Struct
     2571
     2572  Field Name                                    Writable
     2573  ----------                                    --------
     2574  FrameOverlappingPercentage                    real
     2575  FrameSize                                     real
     2576  Quality                                       string
     2577
     2578=head3 XMP Track Struct
     2579
     2580  Field Name                                    Writable
     2581  ----------                                    --------
     2582  FrameRate                                     string
     2583  Markers                                       Marker Struct+
     2584  TrackName                                     string
     2585  TrackType                                     string
     2586
     2587=head3 XMP Colorant Struct
     2588
     2589  Field Name                                    Writable
     2590  ----------                                    --------
     2591  A                                             integer
     2592  B                                             integer
     2593  L                                             real
     2594  Black                                         real
     2595  Blue                                          integer
     2596  Cyan                                          real
     2597  Green                                         integer
     2598  Magenta                                       real
     2599  Mode                                          string
     2600  Red                                           integer
     2601  SwatchName                                    string
     2602  Type                                          string
     2603  Yellow                                        real
     2604
    13822605=head3 XMP xmpMM Tags
    13832606
     
    13862609  Tag Name                                      Writable
    13872610  --------                                      --------
    1388   DerivedFromDocumentID                         string
    1389   DerivedFromInstanceID                         string
    1390   DerivedFromManager                            string
    1391   DerivedFromManagerVariant                     string
    1392   DerivedFromManageTo                           string
    1393   DerivedFromManageUI                           string
    1394   DerivedFromRenditionClass                     string
    1395   DerivedFromRenditionParams                    string
    1396   DerivedFromVersionID                          string
     2611  DerivedFrom                                   ResourceRef Struct
     2612  DerivedFromAlternatePaths                     string_+
     2613  DerivedFromDocumentID                         string_
     2614  DerivedFromFilePath                           string_
     2615  DerivedFromFromPart                           string_
     2616  DerivedFromInstanceID                         string_
     2617  DerivedFromLastModifyDate                     date_
     2618  DerivedFromManager                            string_
     2619  DerivedFromManagerVariant                     string_
     2620  DerivedFromManageTo                           string_
     2621  DerivedFromManageUI                           string_
     2622  DerivedFromMaskMarkers                        string_
     2623  DerivedFromOriginalDocumentID                 string_
     2624  DerivedFromPartMapping                        string_
     2625  DerivedFromRenditionClass                     string_
     2626  DerivedFromRenditionParams                    string_
     2627  DerivedFromToPart                             string_
     2628  DerivedFromVersionID                          string_
    13972629  DocumentID                                    string
    1398   HistoryAction                                 string+
    1399   HistoryInstanceID                             string+
    1400   HistoryParameters                             string+
    1401   HistorySoftwareAgent                          string+
    1402   HistoryWhen                                   date+
     2630  History                                       ResourceEvent Struct+
     2631  HistoryAction                                 string_+
     2632  HistoryChanged                                string_+
     2633  HistoryInstanceID                             string_+
     2634  HistoryParameters                             string_+
     2635  HistorySoftwareAgent                          string_+
     2636  HistoryWhen                                   date_+
     2637  Ingredients                                   ResourceRef Struct+
     2638  IngredientsAlternatePaths                     string_+
     2639  IngredientsDocumentID                         string_+
     2640  IngredientsFilePath                           string_+
     2641  IngredientsFromPart                           string_+
     2642  IngredientsInstanceID                         string_+
     2643  IngredientsLastModifyDate                     date_+
     2644  IngredientsManager                            string_+
     2645  IngredientsManagerVariant                     string_+
     2646  IngredientsManageTo                           string_+
     2647  IngredientsManageUI                           string_+
     2648  IngredientsMaskMarkers                        string_+
     2649  IngredientsOriginalDocumentID                 string_+
     2650  IngredientsPartMapping                        string_+
     2651  IngredientsRenditionClass                     string_+
     2652  IngredientsRenditionParams                    string_+
     2653  IngredientsToPart                             string_+
     2654  IngredientsVersionID                          string_+
    14032655  InstanceID                                    string
    14042656  LastURL                                       string
    1405   ManagedFromDocumentID                         string
    1406   ManagedFromInstanceID                         string
    1407   ManagedFromManager                            string
    1408   ManagedFromManagerVariant                     string
    1409   ManagedFromManageTo                           string
    1410   ManagedFromManageUI                           string
    1411   ManagedFromRenditionClass                     string
    1412   ManagedFromRenditionParams                    string
    1413   ManagedFromVersionID                          string
     2657  ManagedFrom                                   ResourceRef Struct
     2658  ManagedFromAlternatePaths                     string_+
     2659  ManagedFromDocumentID                         string_
     2660  ManagedFromFilePath                           string_
     2661  ManagedFromFromPart                           string_
     2662  ManagedFromInstanceID                         string_
     2663  ManagedFromLastModifyDate                     date_
     2664  ManagedFromManager                            string_
     2665  ManagedFromManagerVariant                     string_
     2666  ManagedFromManageTo                           string_
     2667  ManagedFromManageUI                           string_
     2668  ManagedFromMaskMarkers                        string_
     2669  ManagedFromOriginalDocumentID                 string_
     2670  ManagedFromPartMapping                        string_
     2671  ManagedFromRenditionClass                     string_
     2672  ManagedFromRenditionParams                    string_
     2673  ManagedFromToPart                             string_
     2674  ManagedFromVersionID                          string_
    14142675  Manager                                       string
    14152676  ManagerVariant                                string
    14162677  ManageTo                                      string
    14172678  ManageUI                                      string
     2679  Manifest                                      ManifestItem Struct+
     2680  ManifestLinkForm                              string_+
     2681  ManifestPlacedResolutionUnit                  string_+
     2682  ManifestPlacedXResolution                     real_+
     2683  ManifestPlacedYResolution                     real_+
     2684  ManifestReference                             ResourceRef Struct_+
     2685  ManifestReferenceAlternatePaths               string_+
     2686  ManifestReferenceDocumentID                   string_+
     2687  ManifestReferenceFilePath                     string_+
     2688  ManifestReferenceFromPart                     string_+
     2689  ManifestReferenceInstanceID                   string_+
     2690  ManifestReferenceLastModifyDate               date_+
     2691  ManifestReferenceManager                      string_+
     2692  ManifestReferenceManagerVariant               string_+
     2693  ManifestReferenceManageTo                     string_+
     2694  ManifestReferenceManageUI                     string_+
     2695  ManifestReferenceMaskMarkers                  string_+
     2696  ManifestReferenceOriginalDocumentID           string_+
     2697  ManifestReferencePartMapping                  string_+
     2698  ManifestReferenceRenditionClass               string_+
     2699  ManifestReferenceRenditionParams              string_+
     2700  ManifestReferenceToPart                       string_+
     2701  ManifestReferenceVersionID                    string_+
     2702  OriginalDocumentID                            string
     2703  Pantry                                        PantryItem Struct+
    14182704  PreservedFileName                             string
    14192705  RenditionClass                                string
    1420   RenditionOfDocumentID                         string
    1421   RenditionOfInstanceID                         string
    1422   RenditionOfManager                            string
    1423   RenditionOfManagerVariant                     string
    1424   RenditionOfManageTo                           string
    1425   RenditionOfManageUI                           string
    1426   RenditionOfRenditionClass                     string
    1427   RenditionOfRenditionParams                    string
    1428   RenditionOfVersionID                          string
     2706  RenditionOf                                   ResourceRef Struct
     2707  RenditionOfAlternatePaths                     string_+
     2708  RenditionOfDocumentID                         string_
     2709  RenditionOfFilePath                           string_
     2710  RenditionOfFromPart                           string_
     2711  RenditionOfInstanceID                         string_
     2712  RenditionOfLastModifyDate                     date_
     2713  RenditionOfManager                            string_
     2714  RenditionOfManagerVariant                     string_
     2715  RenditionOfManageTo                           string_
     2716  RenditionOfManageUI                           string_
     2717  RenditionOfMaskMarkers                        string_
     2718  RenditionOfOriginalDocumentID                 string_
     2719  RenditionOfPartMapping                        string_
     2720  RenditionOfRenditionClass                     string_
     2721  RenditionOfRenditionParams                    string_
     2722  RenditionOfToPart                             string_
     2723  RenditionOfVersionID                          string_
    14292724  RenditionParams                               string
    14302725  SaveID                                        integer
    14312726  VersionID                                     string
    1432   VersionsComments                              string+
    1433   VersionsEventAction                           string+
    1434   VersionsEventInstanceID                       string+
    1435   VersionsEventParameters                       string+
    1436   VersionsEventSoftwareAgent                    string+
    1437   VersionsEventWhen                             date+
    1438   VersionsModifier                              string+
    1439   VersionsModifyDate                            date+
    1440   VersionsVersion                               string+
     2727  Versions                                      Version Struct+
     2728  VersionsComments                              string_+
     2729  VersionsEvent                                 ResourceEvent Struct_+
     2730  VersionsEventAction                           string_+
     2731  VersionsEventChanged                          string_+
     2732  VersionsEventInstanceID                       string_+
     2733  VersionsEventParameters                       string_+
     2734  VersionsEventSoftwareAgent                    string_+
     2735  VersionsEventWhen                             date_+
     2736  VersionsModifier                              string_+
     2737  VersionsModifyDate                            date_+
     2738  VersionsVersion                               string_+
     2739
     2740=head3 XMP ResourceRef Struct
     2741
     2742  Field Name                                    Writable
     2743  ----------                                    --------
     2744  AlternatePaths                                string+
     2745  DocumentID                                    string
     2746  FilePath                                      string
     2747  FromPart                                      string
     2748  InstanceID                                    string
     2749  LastModifyDate                                date
     2750  ManageTo                                      string
     2751  ManageUI                                      string
     2752  Manager                                       string
     2753  ManagerVariant                                string
     2754  MaskMarkers                                   string
     2755  OriginalDocumentID                            string
     2756  PartMapping                                   string
     2757  RenditionClass                                string
     2758  RenditionParams                               string
     2759  ToPart                                        string
     2760  VersionID                                     string
     2761
     2762=head3 XMP ResourceEvent Struct
     2763
     2764  Field Name                                    Writable
     2765  ----------                                    --------
     2766  Action                                        string
     2767  Changed                                       string
     2768  InstanceID                                    string
     2769  Parameters                                    string
     2770  SoftwareAgent                                 string
     2771  When                                          date
     2772
     2773=head3 XMP ManifestItem Struct
     2774
     2775  Field Name                                    Writable
     2776  ----------                                    --------
     2777  LinkForm                                      string
     2778  PlacedResolutionUnit                          string
     2779  PlacedXResolution                             real
     2780  PlacedYResolution                             real
     2781  Reference                                     ResourceRef Struct
     2782
     2783=head3 XMP PantryItem Struct
     2784
     2785This structure must have an InstanceID field, but may also contain any other
     2786XMP properties.
     2787
     2788  Field Name                                    Writable
     2789  ----------                                    --------
     2790  InstanceID                                    string
     2791
     2792=head3 XMP Version Struct
     2793
     2794  Field Name                                    Writable
     2795  ----------                                    --------
     2796  Comments                                      string
     2797  Event                                         ResourceEvent Struct
     2798  Modifier                                      string
     2799  ModifyDate                                    date
     2800  Version                                       string
     2801
     2802=head3 XMP xmpNote Tags
     2803
     2804XMP Note schema tags.
     2805
     2806  Tag Name                                      Writable
     2807  --------                                      --------
     2808  HasExtendedXMP                                boolean*
    14412809
    14422810=head3 XMP xmpPLUS Tags
     
    14672835  Tag Name                                      Writable
    14682836  --------                                      --------
    1469   ColorantsA                                    integer+
    1470   ColorantsB                                    integer+
    1471   ColorantsBlack                                real+
    1472   ColorantsBlue                                 integer+
    1473   ColorantsCyan                                 real+
    1474   ColorantsGreen                                integer+
    1475   ColorantsL                                    real+
    1476   ColorantsMagenta                              real+
    1477   ColorantsMode                                 string+
    1478   ColorantsRed                                  integer+
    1479   ColorantsSwatchName                           string+
    1480   ColorantsType                                 string+
    1481   ColorantsYellow                               real+
    1482   FontsChildFontFiles                           string+
    1483   FontsComposite                                boolean+
    1484   FontsFontFace                                 string+
    1485   FontsFontFamily                               string+
    1486   FontsFontFileName                             string+
    1487   FontsFontName                                 string+
    1488   FontsFontType                                 string+
    1489   FontsVersionString                            string+
    1490   MaxPageSizeH                                  real
    1491   MaxPageSizeUnit                               string
    1492   MaxPageSizeW                                  real
     2837  Colorants                                     Colorant Struct+
     2838  ColorantA                                     integer_+
     2839  ColorantB                                     integer_+
     2840  ColorantBlack                                 real_+
     2841  ColorantBlue                                  integer_+
     2842  ColorantCyan                                  real_+
     2843  ColorantGreen                                 integer_+
     2844  ColorantL                                     real_+
     2845  ColorantMagenta                               real_+
     2846  ColorantMode                                  string_+
     2847  ColorantRed                                   integer_+
     2848  ColorantSwatchName                            string_+
     2849  ColorantType                                  string_+
     2850  ColorantYellow                                real_+
     2851  Fonts                                         Font Struct+
     2852  ChildFontFiles                                string_+
     2853  FontComposite                                 boolean_+
     2854  FontFace                                      string_+
     2855  FontFamily                                    string_+
     2856  FontFileName                                  string_+
     2857  FontName                                      string_+
     2858  FontType                                      string_+
     2859  FontVersion                                   string_+
     2860  MaxPageSize                                   Dimensions Struct
     2861  MaxPageSizeH                                  real_
     2862  MaxPageSizeUnit                               string_
     2863  MaxPageSizeW                                  real_
    14932864  NPages                                        integer
    14942865  PlateNames                                    string+
     2866
     2867=head3 XMP Font Struct
     2868
     2869  Field Name                                    Writable
     2870  ----------                                    --------
     2871  ChildFontFiles                                string+
     2872  Composite                                     boolean
     2873  FontFace                                      string
     2874  FontFamily                                    string
     2875  FontFileName                                  string
     2876  FontName                                      string
     2877  FontType                                      string
     2878  VersionString                                 string
     2879
     2880=head3 XMP SVG Tags
     2881
     2882SVG (Scalable Vector Graphics) image tags.  By default, only the top-level
     2883SVG and Metadata tags are extracted from these images, but all graphics tags
     2884may be extracted by setting the Unknown option to 2 (-U on the command
     2885line).  The SVG tags are not part of XMP as such, but are included with the
     2886XMP module for convenience.  (see L<http://www.w3.org/TR/SVG11/>)
     2887
     2888  Tag ID               Tag Name                 Writable
     2889  ------               --------                 --------
     2890  'height'             ImageHeight              N
     2891  'id'                 ID                       N
     2892  'metadataId'         MetadataID               N
     2893  'version'            SVGVersion               N
     2894  'width'              ImageWidth               N
    14952895
    14962896=head2 GPS Tags
     
    15092909automatically by ExifTool.  Remember that the descriptive values are used
    15102910when writing (ie. 'Above Sea Level', not '0') unless the print conversion is
    1511 disabled (with '-n' on the command line, or the PrintConv option in the
    1512 API).
     2911disabled (with '-n' on the command line or the PrintConv option in the API,
     2912or by suffixing the tag name with a C<#> character).
    15132913
    15142914When adding GPS information to an image, it is important to set all of the
     
    15192919  Tag ID   Tag Name                             Writable
    15202920  ------   --------                             --------
    1521   0x0000   GPSVersionID                         int8u[4]
     2921  0x0000   GPSVersionID                         int8u[4]:
    15222922  0x0001   GPSLatitudeRef                       string[2]
    15232923  0x0002   GPSLatitude                          rational64u[3]
     
    15502950  0x001d   GPSDateStamp                         string[11]
    15512951  0x001e   GPSDifferential                      int16u
     2952  0x001f   GPSHPositioningError                 rational64u
    15522953
    15532954=head2 GeoTiff Tags
     2955
     2956ExifTool extracts the following tags from GeoTIFF images.  See
     2957L<http://www.remotesensing.org/geotiff/spec/geotiffhome.html> for the
     2958complete GeoTIFF specification.
    15542959
    15552960  Tag ID   Tag Name                             Writable
     
    16063011
    16073012ICC profile information is used in many different file types including JPEG,
    1608 TIFF, PDF, PostScript, Photoshop, PNG, MIFF, PICT, QuickTime and some RAW
    1609 formats.  While the tags listed below are not individually writable, the
     3013TIFF, PDF, PostScript, Photoshop, PNG, MIFF, PICT, QuickTime, XCF and some
     3014RAW formats.  While the tags listed below are not individually writable, the
    16103015entire profile itself can be accessed via the extra 'ICC_Profile' tag, but
    1611 this tag is neither extracted nor written unless specified explicitly.
     3016this tag is neither extracted nor written unless specified explicitly.  See
     3017L<http://www.color.org/icc_specs2.xalter> for the official ICC
     3018specification.
    16123019
    16133020  Tag ID   Tag Name                             Writable
     
    16193026  'B2A1'   BToA1                                N
    16203027  'B2A2'   BToA2                                N
     3028  'B2D0'   BToD0                                N
     3029  'B2D1'   BToD1                                N
     3030  'B2D2'   BToD2                                N
     3031  'B2D3'   BToD3                                N
     3032  'D2B0'   DToB0                                N
     3033  'D2B1'   DToB1                                N
     3034  'D2B2'   DToB2                                N
     3035  'D2B3'   DToB3                                N
    16213036  'Header' ProfileHeader                        ICC_Profile Header
    16223037  'MS00'   WCSProfiles                          N
     
    16283043  'chad'   ChromaticAdaptation                  N
    16293044  'chrm'   Chromaticity                         ICC_Profile Chromaticity
     3045  'ciis'   ColorimetricIntentImageState         N
     3046  'clot'   ColorantTableOut                     N
    16303047  'clro'   ColorantOrder                        N
    16313048  'clrt'   ColorantTable                        ICC_Profile ColorantTable
     
    16373054  'dmnd'   DeviceMfgDesc                        N
    16383055  'dscm'   ProfileDescriptionML                 N
     3056  'fpce'   FocalPlaneColorimetryEstimates       N
    16393057  'gTRC'   GreenTRC                             N
    16403058  'gXYZ'   GreenMatrixColumn                    N
     
    16433061  'lumi'   Luminance                            N
    16443062  'meas'   Measurement                          ICC_Profile Measurement
     3063  'meta'   Metadata                             ICC_Profile Metadata
    16453064  'mmod'   MakeAndModel                         N
    16463065  'ncl2'   NamedColor2                          N
     
    16503069  'pre1'   Preview1                             N
    16513070  'pre2'   Preview2                             N
    1652   'ps2i'   PS2RenteringIntent                   N
     3071  'ps2i'   PS2RenderingIntent                   N
    16533072  'ps2s'   PostScript2CSA                       N
    16543073  'psd0'   PostScript2CRD0                      N
     
    16563075  'psd2'   PostScript2CRD2                      N
    16573076  'pseq'   ProfileSequenceDesc                  N
     3077  'psid'   ProfileSequenceIdentifier            N
    16583078  'psvm'   PS2CRDVMSize                         N
    16593079  'rTRC'   RedTRC                               N
    16603080  'rXYZ'   RedMatrixColumn                      N
    16613081  'resp'   OutputResponse                       N
     3082  'rhoc'   ReflectionHardcopyOrigColorimetry    N
     3083  'rig0'   PerceptualRenderingIntentGamut       N
     3084  'rig2'   SaturationRenderingIntentGamut       N
     3085  'rpoc'   ReflectionPrintOutputColorimetry     N
     3086  'sape'   SceneAppearanceEstimates             N
     3087  'scoe'   SceneColorimetryEstimates            N
    16623088  'scrd'   ScreeningDesc                        N
    16633089  'scrn'   Screening                            N
     
    17233149     32    MeasurementIlluminant                N
    17243150
     3151=head3 ICC_Profile Metadata Tags
     3152
     3153Only these few tags have been pre-defined, but ExifTool will extract any
     3154Metadata tags that exist.
     3155
     3156  Tag Name                                      Writable
     3157  --------                                      --------
     3158  ManufacturerName                              N
     3159  MediaColor                                    N
     3160  MediaWeight                                   N
     3161
    17253162=head3 ICC_Profile ViewingConditions Tags
    17263163
     
    17363173been decoded.  Use the Unknown (-u) option to extract PrintIM information.
    17373174
    1738   Tag ID   Tag Name                             Writable
    1739   ------   --------                             --------
    1740   [no tags known]
     3175  Tag ID               Tag Name                 Writable
     3176  ------               --------                 --------
     3177  'PrintIMVersion'     PrintIMVersion           N
    17413178
    17423179=head2 Photoshop Tags
    17433180
    1744 Photoshop tags are found in PSD files, as well as inside embedded Photoshop
    1745 information in many other file types (JPEG, TIFF, PDF, PNG to name a few).
     3181Photoshop tags are found in PSD and PSB files, as well as inside embedded
     3182Photoshop information in many other file types (JPEG, TIFF, PDF, PNG to name
     3183a few).
    17463184
    17473185Many Photoshop tags are marked as Unknown (indicated by a question mark
    17483186after the tag name) because the information they provide is not very useful
    1749 under normal circumstances (and because Adobe denied my application for
     3187under normal circumstances I<[and because Adobe denied my application for
    17503188their file format documentation -- apparently open source software is too
    1751 big a concept for them).  These unknown tags are not extracted unless the
     3189big a concept for them]>.  These unknown tags are not extracted unless the
    17523190Unknown (-u) option is used.
    17533191
     
    18083246  0x0421   VersionInfo?                         N
    18093247  0x0422   EXIFInfo                             EXIF
     3248  0x0423   ExifInfo2?                           N
    18103249  0x0424   XMP                                  XMP
    1811   0x0bb7   ClippingPathName?                    N
     3250  0x0425   IPTCDigest                           string!
     3251  0x0426   PrintScale?                          N
     3252  0x0428   PixelAspectRatio?                    N
     3253  0x0429   LayerComps?                          N
     3254  0x042a   AlternateDuotoneColors?              N
     3255  0x042b   AlternateSpotColors?                 N
     3256  0x0bb7   ClippingPathName                     N
    18123257  0x2710   PrintFlagsInfo?                      N
    18133258
     
    18543299  0x0008   FileNumber                           int32u
    18553300  0x0009   OwnerName                            string
    1856   0x000a   ColorInfoD30                         Canon ColorInfoD30
     3301  0x000a   UnknownD30                           Canon UnknownD30
    18573302  0x000c   SerialNumber                         int32u
    1858   0x000d   CanonCameraInfo                      Canon CameraInfo
     3303  0x000d   CanonCameraInfo1D                    Canon CameraInfo1D
     3304           CanonCameraInfo1DmkII                Canon CameraInfo1DmkII
     3305           CanonCameraInfo1DmkIIN               Canon CameraInfo1DmkIIN
    18593306           CanonCameraInfo1DmkIII               Canon CameraInfo1DmkIII
    1860            CanonCameraInfo2                     Canon CameraInfo2
     3307           CanonCameraInfo1DmkIV                Canon CameraInfo1DmkIV
     3308           CanonCameraInfo5D                    Canon CameraInfo5D
     3309           CanonCameraInfo5DmkII                Canon CameraInfo5DmkII
     3310           CanonCameraInfo7D                    Canon CameraInfo7D
     3311           CanonCameraInfo40D                   Canon CameraInfo40D
     3312           CanonCameraInfo50D                   Canon CameraInfo50D
     3313           CanonCameraInfo60D                   Canon CameraInfo60D
     3314           CanonCameraInfo450D                  Canon CameraInfo450D
     3315           CanonCameraInfo500D                  Canon CameraInfo500D
     3316           CanonCameraInfo550D                  Canon CameraInfo550D
     3317           CanonCameraInfo1000D                 Canon CameraInfo1000D
     3318           CanonCameraInfoPowerShot             Canon CameraInfoPowerShot
     3319           CanonCameraInfoPowerShot2            Canon CameraInfoPowerShot2
    18613320           CanonCameraInfoUnknown32             Canon CameraInfoUnknown32
    18623321           CanonCameraInfoUnknown16             Canon CameraInfoUnknown16
    1863            CanonCameraInfoUnknown8              Canon CameraInfoUnknown8
     3322           CanonCameraInfoUnknown               Canon CameraInfoUnknown
    18643323  0x000e   CanonFileLength                      int32u
    18653324  0x000f   CustomFunctions1D                    CanonCustom Functions1D
     
    18743333           CustomFunctionsUnknown               CanonCustom FuncsUnknown
    18753334  0x0010   CanonModelID                         int32u
     3335  0x0011   MovieInfo                            Canon MovieInfo
    18763336  0x0012   CanonAFInfo                          Canon AFInfo
     3337  0x0013   ThumbnailImageValidArea              int16u[4]
    18773338  0x0015   SerialNumberFormat                   int32u
     3339  0x001a   SuperMacro                           int16u
    18783340  0x001c   DateStampMode                        int16u
    18793341  0x001d   MyColors                             Canon MyColors
    18803342  0x001e   FirmwareRevision                     int32u
     3343  0x0023   Categories                           int32u[2]
    18813344  0x0024   FaceDetect1                          Canon FaceDetect1
    18823345  0x0025   FaceDetect2                          Canon FaceDetect2
    18833346  0x0026   CanonAFInfo2                         Canon AFInfo2
    1884   0x0083   OriginalDecisionData                 int32u
     3347  0x0028   ImageUniqueID                        int8u
     3348  0x0081   RawDataOffset                        N
     3349  0x0083   OriginalDecisionDataOffset           int32u*
    18853350  0x0090   CustomFunctions1D                    CanonCustom Functions1D
    18863351  0x0091   PersonalFunctions                    CanonCustom PersonalFuncs
     
    18883353  0x0093   CanonFileInfo                        Canon FileInfo
    18893354  0x0094   AFPointsInFocus1D                    N
    1890   0x0095   LensType                             string
    1891   0x0096   InternalSerialNumber                 string
    1892   0x0097   DustRemovalData                      N
     3355  0x0095   LensModel                            string
     3356  0x0096   SerialInfo                           Canon SerialInfo
     3357           InternalSerialNumber                 string
     3358  0x0097   DustRemovalData                      undef!
     3359  0x0098   CropInfo                             Canon CropInfo
    18933360  0x0099   CustomFunctions2                     CanonCustom Functions2
    1894   0x00a0   ProccessingInfo                      Canon Processing
     3361  0x009a   AspectInfo                           Canon AspectInfo
     3362  0x00a0   ProcessingInfo                       Canon Processing
    18953363  0x00a1   ToneCurveTable                       N
    18963364  0x00a2   SharpnessTable                       N
     
    18983366  0x00a4   WhiteBalanceTable                    N
    18993367  0x00a9   ColorBalance                         Canon ColorBalance
     3368  0x00aa   MeasuredColor                        Canon MeasuredColor
    19003369  0x00ae   ColorTemperature                     int16u
    19013370  0x00b0   CanonFlags                           Canon Flags
     
    19073376  0x00d0   VRDOffset                            int32u*
    19083377  0x00e0   SensorInfo                           Canon SensorInfo
    1909   0x4001   ColorBalance1                        Canon ColorBalance1
    1910            ColorBalance2                        Canon ColorBalance2
    1911            ColorBalance3                        Canon ColorBalance3
    1912            ColorBalanceUnknown                  N
    1913   0x4002   UnknownBlock1?                       N
     3378  0x4001   ColorData1                           Canon ColorData1
     3379           ColorData2                           Canon ColorData2
     3380           ColorData3                           Canon ColorData3
     3381           ColorData4                           Canon ColorData4
     3382           ColorData5                           Canon ColorData5
     3383           ColorData6                           Canon ColorData6
     3384           ColorDataUnknown                     Canon ColorDataUnknown
     3385  0x4002   CRWParam?                            N
    19143386  0x4003   ColorInfo                            Canon ColorInfo
    1915   0x4005   UnknownBlock2?                       N
     3387  0x4005   Flavor?                              N
    19163388  0x4008   BlackLevel?                          N
     3389  0x4010   CustomPictureStyleFileName           string
     3390  0x4013   AFMicroAdj                           Canon AFMicroAdj
     3391  0x4015   VignettingCorr                       Canon VignettingCorr
     3392  0x4016   VignettingCorr2                      Canon VignettingCorr2
     3393  0x4018   LightingOpt                          Canon LightingOpt
     3394  0x4019   LensInfo                             Canon LensInfo
     3395  0x4020   AmbienceInfo                         Canon Ambience
     3396  0x4024   FilterInfo                           Canon FilterInfo
    19173397
    19183398=head3 Canon CameraSettings Tags
     
    19213401   -----   --------                             --------
    19223402      1    MacroMode                            int16s
    1923       2    Self-timer                           int16s
     3403      2    SelfTimer                            int16s
    19243404      3    Quality                              int16s
    19253405      4    CanonFlashMode                       int16s
     
    19523432     36    ZoomSourceWidth                      int16s
    19533433     37    ZoomTargetWidth                      int16s
     3434     39    SpotMeteringMode                     int16s
    19543435     40    PhotoEffect                          int16s
    19553436     41    ManualFlashOutput                    int16s
    19563437     42    ColorTone                            int16s
     3438     46    SRAWQuality                          int16s
    19573439
    19583440=head3 Canon FocalLength Tags
     
    19633445      1    FocalLength                          int16u
    19643446      2    FocalPlaneXSize                      int16u
     3447           FocalPlaneXUnknown?                  int16u
    19653448      3    FocalPlaneYSize                      int16u
     3449           FocalPlaneYUnknown?                  int16u
    19663450
    19673451=head3 Canon ShotInfo Tags
     
    19793463      9    SequenceNumber                       int16s
    19803464     10    OpticalZoomCode                      int16s
     3465     12    CameraTemperature                    int16s
    19813466     13    FlashGuideNumber                     int16s
    19823467     14    AFPointsInFocus                      int16s
     
    19843469     16    AutoExposureBracketing               int16s
    19853470     17    AEBBracketValue                      int16s
    1986      19    FocusDistanceUpper                   int16s
    1987      20    FocusDistanceLower                   int16s
     3471     18    ControlMode                          int16s
     3472     19    FocusDistanceUpper                   int16u
     3473     20    FocusDistanceLower                   int16u
    19883474     21    FNumber                              int16s
    19893475     22    ExposureTime                         int16s
     3476     23    MeasuredEV2                          int16s
    19903477     24    BulbDuration                         int16s
    19913478     26    CameraType                           int16s
    19923479     27    AutoRotate                           int16s
    19933480     28    NDFilter                             int16s
    1994      29    Self-timer2                          int16s
     3481     29    SelfTimer2                           int16s
    19953482     33    FlashOutput                          int16s
    19963483
     
    19993486   Index   Tag Name                             Writable
    20003487   -----   --------                             --------
    2001       2    PanoramaFrame                        int16s
     3488      2    PanoramaFrameNumber                  int16s
    20023489      5    PanoramaDirection                    int16s
    20033490
    2004 =head3 Canon ColorInfoD30 Tags
    2005 
    2006    Index   Tag Name                             Writable
    2007    -----   --------                             --------
    2008       9    ColorTemperature                     int16s
    2009      10    ColorMatrix                          int16s
    2010 
    2011 =head3 Canon CameraInfo Tags
     3491=head3 Canon UnknownD30 Tags
     3492
     3493   Index   Tag Name                             Writable
     3494   -----   --------                             --------
     3495  [no tags known]
     3496
     3497=head3 Canon CameraInfo1D Tags
    20123498
    20133499Information in the "CameraInfo" records is tricky to decode because the
    20143500encodings are very different than in other Canon records (even sometimes
    20153501switching endianness between values within a single camera), plus there is
    2016 considerable variation in format from model to model. The table below is
    2017 common to the 1D, 1DS, 1DmkII, 1DSmkII and 5D, but individual tags may not
    2018 be valid for all these models.
     3502considerable variation in format from model to model. The first table below
     3503lists CameraInfo tags for the 1D and 1DS.
     3504
     3505   Index   Tag Name                             Writable
     3506   -----   --------                             --------
     3507      4    ExposureTime                         int8u
     3508     10    FocalLength                          int16u
     3509     13    LensType                             int16uRev
     3510     14    ShortFocal                           int16u
     3511     16    LongFocal                            int16u
     3512     65    SharpnessFrequency                   int8u
     3513     66    Sharpness                            int8s
     3514     68    WhiteBalance                         int8u
     3515     71    SharpnessFrequency                   int8u
     3516     72    ColorTemperature                     int16u
     3517           Sharpness                            int8s
     3518     74    WhiteBalance                         int8u
     3519     75    PictureStyle                         int8u
     3520     78    ColorTemperature                     int16u
     3521     81    PictureStyle                         int8u
     3522
     3523=head3 Canon CameraInfo1DmkII Tags
     3524
     3525CameraInfo tags for the 1DmkII and 1DSmkII.
     3526
     3527   Index   Tag Name                             Writable
     3528   -----   --------                             --------
     3529      4    ExposureTime                         int8u
     3530      9    FocalLength                          int16uRev
     3531     12    LensType                             int16uRev
     3532     17    ShortFocal                           int16uRev
     3533     19    LongFocal                            int16uRev
     3534     45    FocalType                            int8u
     3535     54    WhiteBalance                         int8u
     3536     55    ColorTemperature                     int16uRev
     3537     57    CanonImageSize                       int16u
     3538    102    JPEGQuality                          int8u
     3539    108    PictureStyle                         int8u
     3540    110    Saturation                           int8s
     3541    111    ColorTone                            int8s
     3542    114    Sharpness                            int8s
     3543    115    Contrast                             int8s
     3544    117    ISO                                  string[5]
     3545
     3546=head3 Canon CameraInfo1DmkIIN Tags
     3547
     3548CameraInfo tags for the 1DmkIIN.
     3549
     3550   Index   Tag Name                             Writable
     3551   -----   --------                             --------
     3552      4    ExposureTime                         int8u
     3553      9    FocalLength                          int16uRev
     3554     12    LensType                             int16uRev
     3555     17    ShortFocal                           int16uRev
     3556     19    LongFocal                            int16uRev
     3557     54    WhiteBalance                         int8u
     3558     55    ColorTemperature                     int16uRev
     3559    115    PictureStyle                         int8u
     3560    116    Sharpness                            int8s
     3561    117    Contrast                             int8s
     3562    118    Saturation                           int8s
     3563    119    ColorTone                            int8s
     3564    121    ISO                                  string[5]
     3565
     3566=head3 Canon CameraInfo1DmkIII Tags
     3567
     3568CameraInfo tags for the 1DmkIII and 1DSmkIII.
    20193569
    20203570   Index   Tag Name                             Writable
     
    20233573      4    ExposureTime                         int8u
    20243574      6    ISO                                  int8u
    2025       9    FocalLength                          int16u
    2026      13    LensType                             int8u
    2027      17    ShortFocal                           int16u
    2028      19    LongFocal                            int16u
    2029      45    FocalType                            int8u
    2030      56    AFPointsInFocus5D                    undef[2]
    2031     108    PictureStyle                         int16u
     3575     24    CameraTemperature                    int8u
     3576     27    MacroMagnification                   int8u
     3577     29    FocalLength                          int16uRev
     3578     48    CameraOrientation                    int8u
     3579     67    FocusDistanceUpper                   int16uRev
     3580     69    FocusDistanceLower                   int16uRev
     3581     94    WhiteBalance                         int16u
     3582     98    ColorTemperature                     int16u
     3583    134    PictureStyle                         int8u
     3584    273    LensType                             int16uRev
     3585    275    ShortFocal                           int16uRev
     3586    277    LongFocal                            int16uRev
     3587    310    FirmwareVersion                      string[6]
     3588    370    FileIndex                            int32u
     3589    374    ShutterCount                         int32u
     3590    382    DirectoryIndex                       int32u
     3591    682    PictureStyleInfo                     Canon PSInfo
     3592   1114    TimeStamp1                           int32u
     3593   1118    TimeStamp                            int32u
     3594
     3595=head3 Canon PSInfo Tags
     3596
     3597Custom picture style information for various models.
     3598
     3599   Index   Tag Name                             Writable
     3600   -----   --------                             --------
     3601      0    ContrastStandard                     int32s
     3602      4    SharpnessStandard                    int32s
     3603      8    SaturationStandard                   int32s
     3604     12    ColorToneStandard                    int32s
     3605     16    FilterEffectStandard?                int32s
     3606     20    ToningEffectStandard?                int32s
     3607     24    ContrastPortrait                     int32s
     3608     28    SharpnessPortrait                    int32s
     3609     32    SaturationPortrait                   int32s
     3610     36    ColorTonePortrait                    int32s
     3611     40    FilterEffectPortrait?                int32s
     3612     44    ToningEffectPortrait?                int32s
     3613     48    ContrastLandscape                    int32s
     3614     52    SharpnessLandscape                   int32s
     3615     56    SaturationLandscape                  int32s
     3616     60    ColorToneLandscape                   int32s
     3617     64    FilterEffectLandscape?               int32s
     3618     68    ToningEffectLandscape?               int32s
     3619     72    ContrastNeutral                      int32s
     3620     76    SharpnessNeutral                     int32s
     3621     80    SaturationNeutral                    int32s
     3622     84    ColorToneNeutral                     int32s
     3623     88    FilterEffectNeutral?                 int32s
     3624     92    ToningEffectNeutral?                 int32s
     3625     96    ContrastFaithful                     int32s
     3626    100    SharpnessFaithful                    int32s
     3627    104    SaturationFaithful                   int32s
     3628    108    ColorToneFaithful                    int32s
     3629    112    FilterEffectFaithful?                int32s
     3630    116    ToningEffectFaithful?                int32s
     3631    120    ContrastMonochrome                   int32s
     3632    124    SharpnessMonochrome                  int32s
     3633    128    SaturationMonochrome?                int32s
     3634    132    ColorToneMonochrome?                 int32s
     3635    136    FilterEffectMonochrome               int32s
     3636    140    ToningEffectMonochrome               int32s
     3637    144    ContrastUserDef1                     int32s
     3638    148    SharpnessUserDef1                    int32s
     3639    152    SaturationUserDef1                   int32s
     3640    156    ColorToneUserDef1                    int32s
     3641    160    FilterEffectUserDef1                 int32s
     3642    164    ToningEffectUserDef1                 int32s
     3643    168    ContrastUserDef2                     int32s
     3644    172    SharpnessUserDef2                    int32s
     3645    176    SaturationUserDef2                   int32s
     3646    180    ColorToneUserDef2                    int32s
     3647    184    FilterEffectUserDef2                 int32s
     3648    188    ToningEffectUserDef2                 int32s
     3649    192    ContrastUserDef3                     int32s
     3650    196    SharpnessUserDef3                    int32s
     3651    200    SaturationUserDef3                   int32s
     3652    204    ColorToneUserDef3                    int32s
     3653    208    FilterEffectUserDef3                 int32s
     3654    212    ToningEffectUserDef3                 int32s
     3655    216    UserDef1PictureStyle                 int16u
     3656    218    UserDef2PictureStyle                 int16u
     3657    220    UserDef3PictureStyle                 int16u
     3658
     3659=head3 Canon CameraInfo1DmkIV Tags
     3660
     3661CameraInfo tags for the 1DmkIV.
     3662
     3663   Index   Tag Name                             Writable
     3664   -----   --------                             --------
     3665      3    FNumber                              int8u
     3666      4    ExposureTime                         int8u
     3667      6    ISO                                  int8u
     3668      7    HighlightTonePriority                int8u
     3669      8    MeasuredEV2                          int8u
     3670      9    MeasuredEV3                          int8u
     3671     21    FlashMeteringMode                    int8u
     3672     25    CameraTemperature                    int8u
     3673     30    FocalLength                          int16uRev
     3674     53    CameraOrientation                    int8u
     3675     84    FocusDistanceUpper                   int16uRev
     3676     86    FocusDistanceLower                   int16uRev
     3677    119    WhiteBalance                         int16u
     3678    120    WhiteBalance                         int16u
     3679    123    ColorTemperature                     int16u
     3680    124    ColorTemperature                     int16u
     3681    334    LensType                             int16uRev
     3682    335    LensType                             int16uRev
     3683    336    ShortFocal                           int16uRev
     3684    337    ShortFocal                           int16uRev
     3685    338    LongFocal                            int16uRev
     3686    339    LongFocal                            int16uRev
     3687    488    FirmwareVersion                      N
     3688    493    FirmwareVersion                      N
     3689    551    FileIndex                            int32u
     3690    556    FileIndex                            int32u
     3691    563    DirectoryIndex                       int32u
     3692    568    DirectoryIndex                       int32u
     3693    867    PictureStyleInfo                     Canon PSInfo
     3694    872    PictureStyleInfo                     Canon PSInfo
     3695
     3696=head3 Canon CameraInfo5D Tags
     3697
     3698CameraInfo tags for the EOS 5D.
     3699
     3700   Index   Tag Name                             Writable
     3701   -----   --------                             --------
     3702      3    FNumber                              int8u
     3703      4    ExposureTime                         int8u
     3704      6    ISO                                  int8u
     3705     12    LensType                             int16uRev
     3706     23    CameraTemperature                    int8u
     3707     27    MacroMagnification                   int8s
     3708     39    CameraOrientation                    int8s
     3709     40    FocalLength                          int16uRev
     3710     56    AFPointsInFocus5D                    int16uRev
     3711     84    WhiteBalance                         int16u
     3712     88    ColorTemperature                     int16u
     3713    108    PictureStyle                         int8u
     3714    147    ShortFocal                           int16uRev
     3715    149    LongFocal                            int16uRev
     3716    151    LensType                             int16uRev
    20323717    164    FirmwareRevision                     string[8]
    20333718    172    ShortOwnerName                       string[16]
     
    20743759    284    TimeStamp                            int32u
    20753760
    2076 =head3 Canon CameraInfo1DmkIII Tags
    2077 
    2078 CameraInfo tags valid for the EOS 1D Mark III.
     3761=head3 Canon CameraInfo5DmkII Tags
     3762
     3763CameraInfo tags for the EOS 5D Mark II.
    20793764
    20803765   Index   Tag Name                             Writable
     
    20833768      4    ExposureTime                         int8u
    20843769      6    ISO                                  int8u
    2085      29    FocalLength                          int16u
    2086     134    PictureStyle                         int8u
    2087     275    ShortFocal                           int16u
    2088     277    LongFocal                            int16u
    2089     370    FileNumber                           int32u
    2090     374    ShutterCount                         int32u
    2091    1118    TimeStamp                            int32u
    2092 
    2093 =head3 Canon CameraInfo2 Tags
    2094 
    2095 These tags used by a number of newer PowerShot models.
     3770      7    HighlightTonePriority                int8u
     3771     21    FlashMeteringMode                    int8u
     3772     25    CameraTemperature                    int8u
     3773     27    MacroMagnification                   int8u
     3774     30    FocalLength                          int16uRev
     3775     49    CameraOrientation                    int8u
     3776     80    FocusDistanceUpper                   int16uRev
     3777     82    FocusDistanceLower                   int16uRev
     3778    111    WhiteBalance                         int16u
     3779    115    ColorTemperature                     int16u
     3780    167    PictureStyle                         int8u
     3781    189    HighISONoiseReduction                int8u
     3782    191    AutoLightingOptimizer                int8u
     3783    230    LensType                             int16uRev
     3784    232    ShortFocal                           int16uRev
     3785    234    LongFocal                            int16uRev
     3786    346    CameraInfo5DmkII_2a                  Canon CameraInfo5DmkII_2
     3787    382    CameraInfo5DmkII_2b                  Canon CameraInfo5DmkII_2
     3788
     3789=head3 Canon CameraInfo5DmkII_2 Tags
     3790
     3791More CameraInfo tags for the EOS 5D Mark II.
     3792
     3793   Index   Tag Name                             Writable
     3794   -----   --------                             --------
     3795      0    FirmwareVersion                      N
     3796     61    FileIndex                            int32u
     3797     73    DirectoryIndex                       int32u
     3798    377    PictureStyleInfo                     Canon PSInfo
     3799
     3800=head3 Canon CameraInfo7D Tags
     3801
     3802CameraInfo tags for the EOS 7D.
     3803
     3804   Index   Tag Name                             Writable
     3805   -----   --------                             --------
     3806      3    FNumber                              int8u
     3807      4    ExposureTime                         int8u
     3808      6    ISO                                  int8u
     3809      7    HighlightTonePriority                int8u
     3810      8    MeasuredEV2                          int8u
     3811      9    MeasuredEV                           int8u
     3812     21    FlashMeteringMode                    int8u
     3813     25    CameraTemperature                    int8u
     3814     30    FocalLength                          int16uRev
     3815     32    CameraInfo7D_2a                      Canon CameraInfo7D_2
     3816     36    CameraInfo7D_2b                      Canon CameraInfo7D_2
     3817
     3818=head3 Canon CameraInfo7D_2 Tags
     3819
     3820More CameraInfo tags for the EOS 7D.
     3821
     3822   Index   Tag Name                             Writable
     3823   -----   --------                             --------
     3824     17    CameraOrientation                    int8u
     3825     48    FocusDistanceUpper                   int16uRev
     3826     50    FocusDistanceLower                   int16uRev
     3827     83    WhiteBalance                         int16u
     3828     87    ColorTemperature                     int16u
     3829    165    HighISONoiseReduction                int8u
     3830    238    LensType                             int16uRev
     3831    240    ShortFocal                           int16uRev
     3832    242    LongFocal                            int16uRev
     3833    392    FirmwareVersion                      N
     3834    455    FileIndex                            int32u
     3835    467    DirectoryIndex                       int32u
     3836    771    PictureStyleInfo                     Canon PSInfo
     3837
     3838=head3 Canon CameraInfo40D Tags
     3839
     3840CameraInfo tags for the EOS 40D.
     3841
     3842   Index   Tag Name                             Writable
     3843   -----   --------                             --------
     3844      3    FNumber                              int8u
     3845      4    ExposureTime                         int8u
     3846      6    ISO                                  int8u
     3847     21    FlashMeteringMode                    int8u
     3848     24    CameraTemperature                    int8u
     3849     27    MacroMagnification                   int8u
     3850     29    FocalLength                          int16uRev
     3851     48    CameraOrientation                    int8u
     3852     67    FocusDistanceUpper                   int16uRev
     3853     69    FocusDistanceLower                   int16uRev
     3854    111    WhiteBalance                         int16u
     3855    115    ColorTemperature                     int16u
     3856    214    LensType                             int16uRev
     3857    216    ShortFocal                           int16uRev
     3858    218    LongFocal                            int16uRev
     3859    255    FirmwareVersion                      string[6]
     3860    307    FileIndex                            int32u
     3861    319    DirectoryIndex                       int32u
     3862    603    PictureStyleInfo                     Canon PSInfo
     3863   2347    LensModel                            string[64]
     3864
     3865=head3 Canon CameraInfo50D Tags
     3866
     3867CameraInfo tags for the EOS 50D.
     3868
     3869   Index   Tag Name                             Writable
     3870   -----   --------                             --------
     3871      3    FNumber                              int8u
     3872      4    ExposureTime                         int8u
     3873      6    ISO                                  int8u
     3874      7    HighlightTonePriority                int8u
     3875     21    FlashMeteringMode                    int8u
     3876     25    CameraTemperature                    int8u
     3877     30    FocalLength                          int16uRev
     3878     49    CameraOrientation                    int8u
     3879     80    FocusDistanceUpper                   int16uRev
     3880     82    FocusDistanceLower                   int16uRev
     3881    111    WhiteBalance                         int16u
     3882    115    ColorTemperature                     int16u
     3883    167    PictureStyle                         int8u
     3884    189    HighISONoiseReduction                int8u
     3885    191    AutoLightingOptimizer                int8u
     3886    234    LensType                             int16uRev
     3887    236    ShortFocal                           int16uRev
     3888    238    LongFocal                            int16uRev
     3889    346    FirmwareVersion                      N
     3890    350    FirmwareVersion                      N
     3891    407    FileIndex                            int32u
     3892    411    FileIndex                            int32u
     3893    419    DirectoryIndex                       int32u
     3894    423    DirectoryIndex                       int32u
     3895    723    PictureStyleInfo                     Canon PSInfo
     3896    727    PictureStyleInfo                     Canon PSInfo
     3897
     3898=head3 Canon CameraInfo60D Tags
     3899
     3900CameraInfo tags for the EOS 60D.
     3901
     3902   Index   Tag Name                             Writable
     3903   -----   --------                             --------
     3904      3    FNumber                              int8u
     3905      4    ExposureTime                         int8u
     3906      6    ISO                                  int8u
     3907     25    CameraTemperature                    int8u
     3908     30    FocalLength                          int16uRev
     3909     54    CameraOrientation                    int8u
     3910     85    FocusDistanceUpper                   int16uRev
     3911     87    FocusDistanceLower                   int16uRev
     3912    125    ColorTemperature                     int16u
     3913    232    LensType                             int16uRev
     3914    234    ShortFocal                           int16uRev
     3915    236    LongFocal                            int16uRev
     3916    409    FirmwareVersion                      N
     3917    473    FileIndex                            int32u
     3918    485    DirectoryIndex                       int32u
     3919    801    PictureStyleInfo2                    Canon PSInfo2
     3920
     3921=head3 Canon PSInfo2 Tags
     3922
     3923Custom picture style information for the EOS 60D.
     3924
     3925   Index   Tag Name                             Writable
     3926   -----   --------                             --------
     3927      0    ContrastStandard                     int32s
     3928      4    SharpnessStandard                    int32s
     3929      8    SaturationStandard                   int32s
     3930     12    ColorToneStandard                    int32s
     3931     16    FilterEffectStandard?                int32s
     3932     20    ToningEffectStandard?                int32s
     3933     24    ContrastPortrait                     int32s
     3934     28    SharpnessPortrait                    int32s
     3935     32    SaturationPortrait                   int32s
     3936     36    ColorTonePortrait                    int32s
     3937     40    FilterEffectPortrait?                int32s
     3938     44    ToningEffectPortrait?                int32s
     3939     48    ContrastLandscape                    int32s
     3940     52    SharpnessLandscape                   int32s
     3941     56    SaturationLandscape                  int32s
     3942     60    ColorToneLandscape                   int32s
     3943     64    FilterEffectLandscape?               int32s
     3944     68    ToningEffectLandscape?               int32s
     3945     72    ContrastNeutral                      int32s
     3946     76    SharpnessNeutral                     int32s
     3947     80    SaturationNeutral                    int32s
     3948     84    ColorToneNeutral                     int32s
     3949     88    FilterEffectNeutral?                 int32s
     3950     92    ToningEffectNeutral?                 int32s
     3951     96    ContrastFaithful                     int32s
     3952    100    SharpnessFaithful                    int32s
     3953    104    SaturationFaithful                   int32s
     3954    108    ColorToneFaithful                    int32s
     3955    112    FilterEffectFaithful?                int32s
     3956    116    ToningEffectFaithful?                int32s
     3957    120    ContrastMonochrome                   int32s
     3958    124    SharpnessMonochrome                  int32s
     3959    128    SaturationMonochrome?                int32s
     3960    132    ColorToneMonochrome?                 int32s
     3961    136    FilterEffectMonochrome               int32s
     3962    140    ToningEffectMonochrome               int32s
     3963    144    ContrastUnknown?                     int32s
     3964    148    SharpnessUnknown?                    int32s
     3965    152    SaturationUnknown?                   int32s
     3966    156    ColorToneUnknown?                    int32s
     3967    160    FilterEffectUnknown?                 int32s
     3968    164    ToningEffectUnknown?                 int32s
     3969    168    ContrastUserDef1                     int32s
     3970    172    SharpnessUserDef1                    int32s
     3971    176    SaturationUserDef1                   int32s
     3972    180    ColorToneUserDef1                    int32s
     3973    184    FilterEffectUserDef1                 int32s
     3974    188    ToningEffectUserDef1                 int32s
     3975    192    ContrastUserDef2                     int32s
     3976    196    SharpnessUserDef2                    int32s
     3977    200    SaturationUserDef2                   int32s
     3978    204    ColorToneUserDef2                    int32s
     3979    208    FilterEffectUserDef2                 int32s
     3980    212    ToningEffectUserDef2                 int32s
     3981    216    ContrastUserDef3                     int32s
     3982    220    SharpnessUserDef3                    int32s
     3983    224    SaturationUserDef3                   int32s
     3984    228    ColorToneUserDef3                    int32s
     3985    232    FilterEffectUserDef3                 int32s
     3986    236    ToningEffectUserDef3                 int32s
     3987    240    UserDef1PictureStyle                 int16u
     3988    242    UserDef2PictureStyle                 int16u
     3989    244    UserDef3PictureStyle                 int16u
     3990
     3991=head3 Canon CameraInfo450D Tags
     3992
     3993CameraInfo tags for the EOS 450D.
     3994
     3995   Index   Tag Name                             Writable
     3996   -----   --------                             --------
     3997      3    FNumber                              int8u
     3998      4    ExposureTime                         int8u
     3999      6    ISO                                  int8u
     4000     21    FlashMeteringMode                    int8u
     4001     24    CameraTemperature                    int8u
     4002     27    MacroMagnification                   int8u
     4003     29    FocalLength                          int16uRev
     4004     48    CameraOrientation                    int8u
     4005     67    FocusDistanceUpper                   int16uRev
     4006     69    FocusDistanceLower                   int16uRev
     4007    111    WhiteBalance                         int16u
     4008    115    ColorTemperature                     int16u
     4009    222    LensType                             int16uRev
     4010    263    FirmwareVersion                      string[6]
     4011    271    OwnerName                            string[32]
     4012    307    DirectoryIndex                       int32u
     4013    319    FileIndex                            int32u
     4014    611    PictureStyleInfo                     Canon PSInfo
     4015   2355    LensModel                            string[64]
     4016
     4017=head3 Canon CameraInfo500D Tags
     4018
     4019CameraInfo tags for the EOS 500D.
     4020
     4021   Index   Tag Name                             Writable
     4022   -----   --------                             --------
     4023      3    FNumber                              int8u
     4024      4    ExposureTime                         int8u
     4025      6    ISO                                  int8u
     4026      7    HighlightTonePriority                int8u
     4027     21    FlashMeteringMode                    int8u
     4028     25    CameraTemperature                    int8u
     4029     30    FocalLength                          int16uRev
     4030     49    CameraOrientation                    int8u
     4031     80    FocusDistanceUpper                   int16uRev
     4032     82    FocusDistanceLower                   int16uRev
     4033    115    WhiteBalance                         int16u
     4034    119    ColorTemperature                     int16u
     4035    171    PictureStyle                         int8u
     4036    188    HighISONoiseReduction                int8u
     4037    190    AutoLightingOptimizer                int8u
     4038    246    LensType                             int16uRev
     4039    248    ShortFocal                           int16uRev
     4040    250    LongFocal                            int16uRev
     4041    400    FirmwareVersion                      N
     4042    467    FileIndex                            int32u
     4043    479    DirectoryIndex                       int32u
     4044    779    PictureStyleInfo                     Canon PSInfo
     4045
     4046=head3 Canon CameraInfo550D Tags
     4047
     4048CameraInfo tags for the EOS 550D.
     4049
     4050   Index   Tag Name                             Writable
     4051   -----   --------                             --------
     4052      3    FNumber                              int8u
     4053      4    ExposureTime                         int8u
     4054      6    ISO                                  int8u
     4055      7    HighlightTonePriority                int8u
     4056     21    FlashMeteringMode                    int8u
     4057     25    CameraTemperature                    int8u
     4058     30    FocalLength                          int16uRev
     4059     53    CameraOrientation                    int8u
     4060     84    FocusDistanceUpper                   int16uRev
     4061     86    FocusDistanceLower                   int16uRev
     4062    120    WhiteBalance                         int16u
     4063    124    ColorTemperature                     int16u
     4064    176    PictureStyle                         int8u
     4065    255    LensType                             int16uRev
     4066    257    ShortFocal                           int16uRev
     4067    259    LongFocal                            int16uRev
     4068    420    FirmwareVersion                      N
     4069    484    FileIndex                            int32u
     4070    496    DirectoryIndex                       int32u
     4071    796    PictureStyleInfo                     Canon PSInfo
     4072
     4073=head3 Canon CameraInfo1000D Tags
     4074
     4075CameraInfo tags for the EOS 1000D.
     4076
     4077   Index   Tag Name                             Writable
     4078   -----   --------                             --------
     4079      3    FNumber                              int8u
     4080      4    ExposureTime                         int8u
     4081      6    ISO                                  int8u
     4082     21    FlashMeteringMode                    int8u
     4083     24    CameraTemperature                    int8u
     4084     27    MacroMagnification                   int8u
     4085     29    FocalLength                          int16uRev
     4086     48    CameraOrientation                    int8u
     4087     67    FocusDistanceUpper                   int16uRev
     4088     69    FocusDistanceLower                   int16uRev
     4089    111    WhiteBalance                         int16u
     4090    115    ColorTemperature                     int16u
     4091    226    LensType                             int16uRev
     4092    267    FirmwareVersion                      string[6]
     4093    311    DirectoryIndex                       int32u
     4094    323    FileIndex                            int32u
     4095    615    PictureStyleInfo                     Canon PSInfo
     4096   2359    LensModel                            string[64]
     4097
     4098=head3 Canon CameraInfoPowerShot Tags
     4099
     4100CameraInfo tags for PowerShot models such as the A450, A460, A550, A560,
     4101A570, A630, A640, A650, A710, A720, G7, G9, S5, SD40, SD750, SD800, SD850,
     4102SD870, SD900, SD950, SD1000, SX100 and TX1.
    20964103
    20974104   Index   Tag Name                             Writable
     
    21014108      6    ExposureTime                         int32s
    21024109     23    Rotation                             int32s
     4110    135    CameraTemperature                    int32s
     4111    145    CameraTemperature                    int32s
     4112
     4113=head3 Canon CameraInfoPowerShot2 Tags
     4114
     4115CameraInfo tags for PowerShot models such as the A470, A480, A490, A495,
     4116A580, A590, A1000, A1100, A2000, A2100, A3000, A3100, D10, E1, G10, G11,
     4117S90, S95, SD770, SD780, SD790, SD880, SD890, SD940, SD960, SD970, SD980,
     4118SD990, SD1100, SD1200, SD1300, SD1400, SD3500, SD4000, SD4500, SX1, SX10,
     4119SX20, SX110, SX120, SX130, SX200 and SX210.
     4120
     4121   Index   Tag Name                             Writable
     4122   -----   --------                             --------
     4123      1    ISO                                  int32s
     4124      6    FNumber                              int32s
     4125      7    ExposureTime                         int32s
     4126     24    Rotation                             int32s
     4127    153    CameraTemperature                    int32s
     4128    159    CameraTemperature                    int32s
     4129    164    CameraTemperature                    int32s
     4130    168    CameraTemperature                    int32s
     4131    261    CameraTemperature                    int32s
    21034132
    21044133=head3 Canon CameraInfoUnknown32 Tags
     
    21084137   Index   Tag Name                             Writable
    21094138   -----   --------                             --------
     4139     71    CameraTemperature                    int32s
     4140     83    CameraTemperature                    int32s
     4141     91    CameraTemperature                    int32s
     4142     92    CameraTemperature                    int32s
     4143    100    CameraTemperature                    int32s
     4144    466    CameraTemperature                    int32s
     4145    503    CameraTemperature                    int32s
     4146    506    CameraTemperature                    int32s
     4147
     4148=head3 Canon CameraInfoUnknown16 Tags
     4149
     4150   Index   Tag Name                             Writable
     4151   -----   --------                             --------
    21104152  [no tags known]
    21114153
    2112 =head3 Canon CameraInfoUnknown16 Tags
     4154=head3 Canon CameraInfoUnknown Tags
    21134155
    21144156   Index   Tag Name                             Writable
     
    21164158  [no tags known]
    21174159
    2118 =head3 Canon CameraInfoUnknown8 Tags
    2119 
    2120    Index   Tag Name                             Writable
    2121    -----   --------                             --------
    2122   [no tags known]
     4160=head3 Canon MovieInfo Tags
     4161
     4162Tags written by some Canon cameras when recording video.
     4163
     4164   Index   Tag Name                             Writable
     4165   -----   --------                             --------
     4166      1    FrameRate                            int16u
     4167      2    FrameCount                           int16u
     4168      4    FrameCount                           int32u
     4169      6    FrameRate                            rational32u
     4170    106    Duration                             int32u
     4171    108    AudioBitrate                         int32u
     4172    110    AudioSampleRate                      int32u
     4173    112    AudioChannels                        int32u
     4174    116    VideoCodec                           undef[4]
    21234175
    21244176=head3 Canon AFInfo Tags
     
    21604212   -----   --------                             --------
    21614213      2    FacesDetected                        int16u
    2162       3    FaceDetectFrameWidth                 int16u
    2163       4    FaceDetectFrameHeight                int16u
    2164       8    Face0Position                        int16s[2]
    2165      10    Face1Position                        int16s[2]
    2166      12    Face2Position                        int16s[2]
    2167      14    Face3Position                        int16s[2]
    2168      16    Face4Position                        int16s[2]
    2169      18    Face5Position                        int16s[2]
    2170      20    Face6Position                        int16s[2]
    2171      22    Face7Position                        int16s[2]
    2172      24    Face8Position                        int16s[2]
     4214      3    FaceDetectFrameSize                  int16u[2]
     4215      8    Face1Position                        int16s[2]
     4216     10    Face2Position                        int16s[2]
     4217     12    Face3Position                        int16s[2]
     4218     14    Face4Position                        int16s[2]
     4219     16    Face5Position                        int16s[2]
     4220     18    Face6Position                        int16s[2]
     4221     20    Face7Position                        int16s[2]
     4222     22    Face8Position                        int16s[2]
     4223     24    Face9Position                        int16s[2]
    21734224
    21744225=head3 Canon FaceDetect2 Tags
     
    21764227   Index   Tag Name                             Writable
    21774228   -----   --------                             --------
     4229      1    FaceWidth                            int8u
    21784230      2    FacesDetected                        int8u
    21794231
     
    21874239  -------- --------                             --------
    21884240      0    AFInfoSize?                          N
    2189       1    AFMode                               N
     4241      1    AFAreaMode                           N
    21904242      2    NumAFPoints                          N
    21914243      3    ValidAFPoints                        N
    21924244      4    CanonImageWidth                      N
    2193       5    CanonImageWidth                      N
     4245      5    CanonImageHeight                     N
    21944246      6    AFImageWidth                         N
    21954247      7    AFImageHeight                        N
     
    22144266      6    RawJpgQuality                        int16s
    22154267      7    RawJpgSize                           int16s
    2216       8    NoiseReduction                       int16s
     4268      8    LongExposureNoiseReduction2          int16s
    22174269      9    WBBracketMode                        int16s
    22184270     12    WBBracketValueAB                     int16s
     
    22204272     14    FilterEffect                         int16s
    22214273     15    ToningEffect                         int16s
     4274     16    MacroMagnification                   int16s
     4275     19    LiveViewShooting                     int16s
     4276     25    FlashExposureLock                    int16s
     4277
     4278=head3 Canon SerialInfo Tags
     4279
     4280   Index   Tag Name                             Writable
     4281   -----   --------                             --------
     4282      9    InternalSerialNumber                 string
     4283
     4284=head3 Canon CropInfo Tags
     4285
     4286   Index   Tag Name                             Writable
     4287   -----   --------                             --------
     4288      0    CropLeftMargin                       int16u
     4289      1    CropRightMargin                      int16u
     4290      2    CropTopMargin                        int16u
     4291      3    CropBottomMargin                     int16u
     4292
     4293=head3 Canon AspectInfo Tags
     4294
     4295   Index   Tag Name                             Writable
     4296   -----   --------                             --------
     4297      0    AspectRatio                          int32u
     4298      1    CroppedImageWidth                    int32u
     4299      2    CroppedImageHeight                   int32u
    22224300
    22234301=head3 Canon Processing Tags
     
    22414319=head3 Canon ColorBalance Tags
    22424320
    2243 This table is used by the 10D and 300D.
    2244 
    2245    Index   Tag Name                             Writable
    2246    -----   --------                             --------
    2247       0    WB_RGGBLevelsAuto                    int16u[4]
    2248       4    WB_RGGBLevelsDaylight                int16u[4]
    2249       8    WB_RGGBLevelsShade                   int16u[4]
    2250      12    WB_RGGBLevelsCloudy                  int16u[4]
    2251      16    WB_RGGBLevelsTungsten                int16u[4]
    2252      20    WB_RGGBLevelsFluorescent             int16u[4]
    2253      24    WB_RGGBLevelsFlash                   int16u[4]
    2254      28    WB_RGGBLevelsCustom                  int16u[4]
    2255      32    WB_RGGBLevelsKelvin                  int16u[4]
     4321These tags are used by the 10D and 300D.
     4322
     4323   Index   Tag Name                             Writable
     4324   -----   --------                             --------
     4325      0    WB_RGGBLevelsAuto                    int16s[4]
     4326      4    WB_RGGBLevelsDaylight                int16s[4]
     4327      8    WB_RGGBLevelsShade                   int16s[4]
     4328     12    WB_RGGBLevelsCloudy                  int16s[4]
     4329     16    WB_RGGBLevelsTungsten                int16s[4]
     4330     20    WB_RGGBLevelsFluorescent             int16s[4]
     4331     24    WB_RGGBLevelsFlash                   int16s[4]
     4332     28    WB_RGGBLevelsCustom                  int16s[4]
     4333     32    WB_RGGBLevelsKelvin                  int16s[4]
     4334
     4335=head3 Canon MeasuredColor Tags
     4336
     4337   Index   Tag Name                             Writable
     4338   -----   --------                             --------
     4339      1    MeasuredRGGB                         int16u[4]
    22564340
    22574341=head3 Canon Flags Tags
     
    22864370      4    PreviewImageHeight                   int32u
    22874371      5    PreviewImageStart                    int32u*
    2288       6    PreviewFocalPlaneXResolution         rational64s
    2289       8    PreviewFocalPlaneYResolution         rational64s
    22904372
    22914373=head3 Canon SensorInfo Tags
     
    22994381      7    SensorRightBorder                    N
    23004382      8    SensorBottomBorder                   N
    2301 
    2302 =head3 Canon ColorBalance1 Tags
    2303 
    2304 This table is used by the 20D and 350D.
    2305 
    2306    Index   Tag Name                             Writable
    2307    -----   --------                             --------
    2308      25    WB_RGGBLevelsAsShot                  int16u[4]
    2309      29    ColorTempAsShot                      int16u
    2310      30    WB_RGGBLevelsAuto                    int16u[4]
    2311      34    ColorTempAuto                        int16u
    2312      35    WB_RGGBLevelsDaylight                int16u[4]
    2313      39    ColorTempDaylight                    int16u
    2314      40    WB_RGGBLevelsShade                   int16u[4]
    2315      44    ColorTempShade                       int16u
    2316      45    WB_RGGBLevelsCloudy                  int16u[4]
    2317      49    ColorTempCloudy                      int16u
    2318      50    WB_RGGBLevelsTungsten                int16u[4]
    2319      54    ColorTempTungsten                    int16u
    2320      55    WB_RGGBLevelsFluorescent             int16u[4]
    2321      59    ColorTempFluorescent                 int16u
    2322      60    WB_RGGBLevelsFlash                   int16u[4]
    2323      64    ColorTempFlash                       int16u
    2324      65    WB_RGGBLevelsCustom1                 int16u[4]
    2325      69    ColorTempCustom1                     int16u
    2326      70    WB_RGGBLevelsCustom2                 int16u[4]
    2327      74    ColorTempCustom2                     int16u
    2328 
    2329 =head3 Canon ColorBalance2 Tags
    2330 
    2331 This table is used by the 1DmkII and 1DSmkII.
    2332 
    2333    Index   Tag Name                             Writable
    2334    -----   --------                             --------
    2335      24    WB_RGGBLevelsAsShot                  int16u[4]
    2336      28    ColorTempAsShot                      int16u
    2337      29    WB_RGGBLevelsUnknown?                int16u[4]
    2338      33    ColorTempUnknown?                    int16u
    2339      34    WB_RGGBLevelsAuto                    int16u[4]
    2340      38    ColorTempAuto                        int16u
    2341      39    WB_RGGBLevelsDaylight                int16u[4]
    2342      43    ColorTempDaylight                    int16u
    2343      44    WB_RGGBLevelsShade                   int16u[4]
    2344      48    ColorTempShade                       int16u
    2345      49    WB_RGGBLevelsCloudy                  int16u[4]
    2346      53    ColorTempCloudy                      int16u
    2347      54    WB_RGGBLevelsTungsten                int16u[4]
    2348      58    ColorTempTungsten                    int16u
    2349      59    WB_RGGBLevelsFluorescent             int16u[4]
    2350      63    ColorTempFluorescent                 int16u
    2351      64    WB_RGGBLevelsKelvin                  int16u[4]
    2352      68    ColorTempKelvin                      int16u
    2353      69    WB_RGGBLevelsFlash                   int16u[4]
    2354      73    ColorTempFlash                       int16u
    2355      74    WB_RGGBLevelsUnknown2?               int16u[4]
    2356      78    ColorTempUnknown2?                   int16u
    2357      79    WB_RGGBLevelsUnknown3?               int16u[4]
    2358      83    ColorTempUnknown3?                   int16u
    2359      84    WB_RGGBLevelsUnknown4?               int16u[4]
    2360      88    ColorTempUnknown4?                   int16u
    2361      89    WB_RGGBLevelsUnknown5?               int16u[4]
    2362      93    ColorTempUnknown5?                   int16u
    2363      94    WB_RGGBLevelsUnknown6?               int16u[4]
    2364      98    ColorTempUnknown6?                   int16u
    2365      99    WB_RGGBLevelsUnknown7?               int16u[4]
    2366     103    ColorTempUnknown7?                   int16u
    2367     104    WB_RGGBLevelsUnknown8?               int16u[4]
    2368     108    ColorTempUnknown8?                   int16u
    2369     109    WB_RGGBLevelsUnknown9?               int16u[4]
    2370     113    ColorTempUnknown9?                   int16u
    2371     114    WB_RGGBLevelsUnknown10?              int16u[4]
    2372     118    ColorTempUnknown10?                  int16u
    2373     119    WB_RGGBLevelsUnknown11?              int16u[4]
    2374     123    ColorTempUnknown11?                  int16u
    2375     124    WB_RGGBLevelsUnknown12?              int16u[4]
    2376     128    ColorTempUnknown12?                  int16u
    2377     129    WB_RGGBLevelsUnknown13?              int16u[4]
    2378     133    ColorTempUnknown13?                  int16u
    2379     134    WB_RGGBLevelsUnknown14?              int16u[4]
    2380     138    ColorTempUnknown14?                  int16u
    2381     139    WB_RGGBLevelsUnknown15?              int16u[4]
    2382     143    ColorTempUnknown15?                  int16u
    2383     144    WB_RGGBLevelsPC1                     int16u[4]
    2384     148    ColorTempPC1                         int16u
    2385     149    WB_RGGBLevelsPC2                     int16u[4]
    2386     153    ColorTempPC2                         int16u
    2387     154    WB_RGGBLevelsPC3                     int16u[4]
    2388     158    ColorTempPC3                         int16u
    2389     159    WB_RGGBLevelsUnknown16?              int16u[4]
    2390     163    ColorTempUnknown16?                  int16u
    2391 
    2392 =head3 Canon ColorBalance3 Tags
    2393 
    2394 This table is used by the 1DmkIIN, 5D, 30D and 400D.
    2395 
    2396    Index   Tag Name                             Writable
    2397    -----   --------                             --------
    2398      63    WB_RGGBLevelsAsShot                  int16u[4]
    2399      67    ColorTempAsShot                      int16u
    2400      68    WB_RGGBLevelsAuto                    int16u[4]
    2401      72    ColorTempAuto                        int16u
    2402      73    WB_RGGBLevelsMeasured                int16u[4]
    2403      77    ColorTempMeasured                    int16u
    2404      78    WB_RGGBLevelsDaylight                int16u[4]
    2405      82    ColorTempDaylight                    int16u
    2406      83    WB_RGGBLevelsShade                   int16u[4]
    2407      87    ColorTempShade                       int16u
    2408      88    WB_RGGBLevelsCloudy                  int16u[4]
    2409      92    ColorTempCloudy                      int16u
    2410      93    WB_RGGBLevelsTungsten                int16u[4]
    2411      97    ColorTempTungsten                    int16u
    2412      98    WB_RGGBLevelsFluorescent             int16u[4]
    2413     102    ColorTempFluorescent                 int16u
    2414     103    WB_RGGBLevelsKelvin                  int16u[4]
    2415     107    ColorTempKelvin                      int16u
    2416     108    WB_RGGBLevelsFlash                   int16u[4]
    2417     112    ColorTempFlash                       int16u
    2418     113    WB_RGGBLevelsPC1                     int16u[4]
    2419     117    ColorTempPC1                         int16u
    2420     118    WB_RGGBLevelsPC2                     int16u[4]
    2421     122    ColorTempPC2                         int16u
    2422     123    WB_RGGBLevelsPC3                     int16u[4]
    2423     127    ColorTempPC3                         int16u
    2424     128    WB_RGGBLevelsCustom                  int16u[4]
    2425     132    ColorTempCustom                      int16u
     4383      9    BlackMaskLeftBorder                  N
     4384     10    BlackMaskTopBorder                   N
     4385     11    BlackMaskRightBorder                 N
     4386     12    BlackMaskBottomBorder                N
     4387
     4388=head3 Canon ColorData1 Tags
     4389
     4390These tags are used by the 20D and 350D.
     4391
     4392   Index   Tag Name                             Writable
     4393   -----   --------                             --------
     4394     25    WB_RGGBLevelsAsShot                  int16s[4]
     4395     29    ColorTempAsShot                      int16s
     4396     30    WB_RGGBLevelsAuto                    int16s[4]
     4397     34    ColorTempAuto                        int16s
     4398     35    WB_RGGBLevelsDaylight                int16s[4]
     4399     39    ColorTempDaylight                    int16s
     4400     40    WB_RGGBLevelsShade                   int16s[4]
     4401     44    ColorTempShade                       int16s
     4402     45    WB_RGGBLevelsCloudy                  int16s[4]
     4403     49    ColorTempCloudy                      int16s
     4404     50    WB_RGGBLevelsTungsten                int16s[4]
     4405     54    ColorTempTungsten                    int16s
     4406     55    WB_RGGBLevelsFluorescent             int16s[4]
     4407     59    ColorTempFluorescent                 int16s
     4408     60    WB_RGGBLevelsFlash                   int16s[4]
     4409     64    ColorTempFlash                       int16s
     4410     65    WB_RGGBLevelsCustom1                 int16s[4]
     4411     69    ColorTempCustom1                     int16s
     4412     70    WB_RGGBLevelsCustom2                 int16s[4]
     4413     74    ColorTempCustom2                     int16s
     4414     75    ColorCalib?                          Canon ColorCalib
     4415
     4416=head3 Canon ColorCalib Tags
     4417
     4418Camera color calibration data.  For the 20D, 350D, 1DmkII and 1DSmkII the
     4419order of the cooefficients is A, B, C, Temperature, but for newer models it
     4420is B, C, A, Temperature.  These tags are extracted only when the Unknown
     4421option is used.
     4422
     4423   Index   Tag Name                             Writable
     4424   -----   --------                             --------
     4425      0    CameraColorCalibration01?            int16s[4]
     4426      4    CameraColorCalibration02?            int16s[4]
     4427      8    CameraColorCalibration03?            int16s[4]
     4428     12    CameraColorCalibration04?            int16s[4]
     4429     16    CameraColorCalibration05?            int16s[4]
     4430     20    CameraColorCalibration06?            int16s[4]
     4431     24    CameraColorCalibration07?            int16s[4]
     4432     28    CameraColorCalibration08?            int16s[4]
     4433     32    CameraColorCalibration09?            int16s[4]
     4434     36    CameraColorCalibration10?            int16s[4]
     4435     40    CameraColorCalibration11?            int16s[4]
     4436     44    CameraColorCalibration12?            int16s[4]
     4437     48    CameraColorCalibration13?            int16s[4]
     4438     52    CameraColorCalibration14?            int16s[4]
     4439     56    CameraColorCalibration15?            int16s[4]
     4440
     4441=head3 Canon ColorData2 Tags
     4442
     4443These tags are used by the 1DmkII and 1DSmkII.
     4444
     4445   Index   Tag Name                             Writable
     4446   -----   --------                             --------
     4447     24    WB_RGGBLevelsAuto                    int16s[4]
     4448     28    ColorTempAuto                        int16s
     4449     29    WB_RGGBLevelsUnknown?                int16s[4]
     4450     33    ColorTempUnknown?                    int16s
     4451     34    WB_RGGBLevelsAsShot                  int16s[4]
     4452     38    ColorTempAsShot                      int16s
     4453     39    WB_RGGBLevelsDaylight                int16s[4]
     4454     43    ColorTempDaylight                    int16s
     4455     44    WB_RGGBLevelsShade                   int16s[4]
     4456     48    ColorTempShade                       int16s
     4457     49    WB_RGGBLevelsCloudy                  int16s[4]
     4458     53    ColorTempCloudy                      int16s
     4459     54    WB_RGGBLevelsTungsten                int16s[4]
     4460     58    ColorTempTungsten                    int16s
     4461     59    WB_RGGBLevelsFluorescent             int16s[4]
     4462     63    ColorTempFluorescent                 int16s
     4463     64    WB_RGGBLevelsKelvin                  int16s[4]
     4464     68    ColorTempKelvin                      int16s
     4465     69    WB_RGGBLevelsFlash                   int16s[4]
     4466     73    ColorTempFlash                       int16s
     4467     74    WB_RGGBLevelsUnknown2?               int16s[4]
     4468     78    ColorTempUnknown2?                   int16s
     4469     79    WB_RGGBLevelsUnknown3?               int16s[4]
     4470     83    ColorTempUnknown3?                   int16s
     4471     84    WB_RGGBLevelsUnknown4?               int16s[4]
     4472     88    ColorTempUnknown4?                   int16s
     4473     89    WB_RGGBLevelsUnknown5?               int16s[4]
     4474     93    ColorTempUnknown5?                   int16s
     4475     94    WB_RGGBLevelsUnknown6?               int16s[4]
     4476     98    ColorTempUnknown6?                   int16s
     4477     99    WB_RGGBLevelsUnknown7?               int16s[4]
     4478    103    ColorTempUnknown7?                   int16s
     4479    104    WB_RGGBLevelsUnknown8?               int16s[4]
     4480    108    ColorTempUnknown8?                   int16s
     4481    109    WB_RGGBLevelsUnknown9?               int16s[4]
     4482    113    ColorTempUnknown9?                   int16s
     4483    114    WB_RGGBLevelsUnknown10?              int16s[4]
     4484    118    ColorTempUnknown10?                  int16s
     4485    119    WB_RGGBLevelsUnknown11?              int16s[4]
     4486    123    ColorTempUnknown11?                  int16s
     4487    124    WB_RGGBLevelsUnknown12?              int16s[4]
     4488    128    ColorTempUnknown12?                  int16s
     4489    129    WB_RGGBLevelsUnknown13?              int16s[4]
     4490    133    ColorTempUnknown13?                  int16s
     4491    134    WB_RGGBLevelsUnknown14?              int16s[4]
     4492    138    ColorTempUnknown14?                  int16s
     4493    139    WB_RGGBLevelsUnknown15?              int16s[4]
     4494    143    ColorTempUnknown15?                  int16s
     4495    144    WB_RGGBLevelsPC1                     int16s[4]
     4496    148    ColorTempPC1                         int16s
     4497    149    WB_RGGBLevelsPC2                     int16s[4]
     4498    153    ColorTempPC2                         int16s
     4499    154    WB_RGGBLevelsPC3                     int16s[4]
     4500    158    ColorTempPC3                         int16s
     4501    159    WB_RGGBLevelsUnknown16?              int16s[4]
     4502    163    ColorTempUnknown16?                  int16s
     4503    164    ColorCalib?                          Canon ColorCalib
     4504    618    RawMeasuredRGGB                      int32u[4]
     4505
     4506=head3 Canon ColorData3 Tags
     4507
     4508These tags are used by the 1DmkIIN, 5D, 30D and 400D.
     4509
     4510   Index   Tag Name                             Writable
     4511   -----   --------                             --------
     4512      0    ColorDataVersion                     int16s
     4513     63    WB_RGGBLevelsAsShot                  int16s[4]
     4514     67    ColorTempAsShot                      int16s
     4515     68    WB_RGGBLevelsAuto                    int16s[4]
     4516     72    ColorTempAuto                        int16s
     4517     73    WB_RGGBLevelsMeasured                int16s[4]
     4518     77    ColorTempMeasured                    int16s
     4519     78    WB_RGGBLevelsDaylight                int16s[4]
     4520     82    ColorTempDaylight                    int16s
     4521     83    WB_RGGBLevelsShade                   int16s[4]
     4522     87    ColorTempShade                       int16s
     4523     88    WB_RGGBLevelsCloudy                  int16s[4]
     4524     92    ColorTempCloudy                      int16s
     4525     93    WB_RGGBLevelsTungsten                int16s[4]
     4526     97    ColorTempTungsten                    int16s
     4527     98    WB_RGGBLevelsFluorescent             int16s[4]
     4528    102    ColorTempFluorescent                 int16s
     4529    103    WB_RGGBLevelsKelvin                  int16s[4]
     4530    107    ColorTempKelvin                      int16s
     4531    108    WB_RGGBLevelsFlash                   int16s[4]
     4532    112    ColorTempFlash                       int16s
     4533    113    WB_RGGBLevelsPC1                     int16s[4]
     4534    117    ColorTempPC1                         int16s
     4535    118    WB_RGGBLevelsPC2                     int16s[4]
     4536    122    ColorTempPC2                         int16s
     4537    123    WB_RGGBLevelsPC3                     int16s[4]
     4538    127    ColorTempPC3                         int16s
     4539    128    WB_RGGBLevelsCustom                  int16s[4]
     4540    132    ColorTempCustom                      int16s
     4541    133    ColorCalib?                          Canon ColorCalib
     4542    584    FlashOutput                          int16s
     4543    585    FlashBatteryLevel                    int16s
     4544    586    ColorTempFlashData                   int16s
     4545    647    MeasuredRGGBData                     int32u[4]
     4546
     4547=head3 Canon ColorData4 Tags
     4548
     4549These tags are used by the 1DmkIII, 1DSmkIII, 1DmkIV, 5DmkII, 7D, 40D, 50D,
     4550450D, 500D, 550D, 1000D and 1100D.
     4551
     4552   Index   Tag Name                             Writable
     4553   -----   --------                             --------
     4554      0    ColorDataVersion                     int16s
     4555     63    ColorCoefs                           Canon ColorCoefs
     4556    168    ColorCalib?                          Canon ColorCalib
     4557    640    RawMeasuredRGGB                      int32u[4]
     4558
     4559=head3 Canon ColorCoefs Tags
     4560
     4561   Index   Tag Name                             Writable
     4562   -----   --------                             --------
     4563      0    WB_RGGBLevelsAsShot                  int16s[4]
     4564      4    ColorTempAsShot                      int16s
     4565      5    WB_RGGBLevelsAuto                    int16s[4]
     4566      9    ColorTempAuto                        int16s
     4567     10    WB_RGGBLevelsMeasured                int16s[4]
     4568     14    ColorTempMeasured                    int16s
     4569     15    WB_RGGBLevelsUnknown?                int16s[4]
     4570     19    ColorTempUnknown?                    int16s
     4571     20    WB_RGGBLevelsDaylight                int16s[4]
     4572     24    ColorTempDaylight                    int16s
     4573     25    WB_RGGBLevelsShade                   int16s[4]
     4574     29    ColorTempShade                       int16s
     4575     30    WB_RGGBLevelsCloudy                  int16s[4]
     4576     34    ColorTempCloudy                      int16s
     4577     35    WB_RGGBLevelsTungsten                int16s[4]
     4578     39    ColorTempTungsten                    int16s
     4579     40    WB_RGGBLevelsFluorescent             int16s[4]
     4580     44    ColorTempFluorescent                 int16s
     4581     45    WB_RGGBLevelsKelvin                  int16s[4]
     4582     49    ColorTempKelvin                      int16s
     4583     50    WB_RGGBLevelsFlash                   int16s[4]
     4584     54    ColorTempFlash                       int16s
     4585     55    WB_RGGBLevelsUnknown2?               int16s[4]
     4586     59    ColorTempUnknown2?                   int16s
     4587     60    WB_RGGBLevelsUnknown3?               int16s[4]
     4588     64    ColorTempUnknown3?                   int16s
     4589     65    WB_RGGBLevelsUnknown4?               int16s[4]
     4590     69    ColorTempUnknown4?                   int16s
     4591     70    WB_RGGBLevelsUnknown5?               int16s[4]
     4592     74    ColorTempUnknown5?                   int16s
     4593     75    WB_RGGBLevelsUnknown6?               int16s[4]
     4594     79    ColorTempUnknown6?                   int16s
     4595     80    WB_RGGBLevelsUnknown7?               int16s[4]
     4596     84    ColorTempUnknown7?                   int16s
     4597     85    WB_RGGBLevelsUnknown8?               int16s[4]
     4598     89    ColorTempUnknown8?                   int16s
     4599     90    WB_RGGBLevelsUnknown9?               int16s[4]
     4600     94    ColorTempUnknown9?                   int16s
     4601     95    WB_RGGBLevelsUnknown10?              int16s[4]
     4602     99    ColorTempUnknown10?                  int16s
     4603    100    WB_RGGBLevelsUnknown11?              int16s[4]
     4604    104    ColorTempUnknown11?                  int16s
     4605    105    WB_RGGBLevelsUnknown12?              int16s[4]
     4606    109    ColorTempUnknown12?                  int16s
     4607    110    WB_RGGBLevelsUnknown13?              int16s[4]
     4608    114    ColorTempUnknown13?                  int16s
     4609
     4610=head3 Canon ColorData5 Tags
     4611
     4612These tags are used by the PowerShot G10.
     4613
     4614   Index   Tag Name                             Writable
     4615   -----   --------                             --------
     4616     71    ColorCoefs                           Canon ColorCoefs
     4617    186    CameraColorCalibration01?            int16s[5]
     4618    191    CameraColorCalibration02?            int16s[5]
     4619    196    CameraColorCalibration03?            int16s[5]
     4620    201    CameraColorCalibration04?            int16s[5]
     4621    206    CameraColorCalibration05?            int16s[5]
     4622    211    CameraColorCalibration06?            int16s[5]
     4623    216    CameraColorCalibration07?            int16s[5]
     4624    221    CameraColorCalibration08?            int16s[5]
     4625    226    CameraColorCalibration09?            int16s[5]
     4626    231    CameraColorCalibration10?            int16s[5]
     4627    236    CameraColorCalibration11?            int16s[5]
     4628    241    CameraColorCalibration12?            int16s[5]
     4629    246    CameraColorCalibration13?            int16s[5]
     4630    251    CameraColorCalibration14?            int16s[5]
     4631    256    CameraColorCalibration15?            int16s[5]
     4632
     4633=head3 Canon ColorData6 Tags
     4634
     4635These tags are used by the EOS 600D.
     4636
     4637   Index   Tag Name                             Writable
     4638   -----   --------                             --------
     4639      0    ColorDataVersion                     int16s
     4640     63    WB_RGGBLevelsAsShot                  int16s[4]
     4641     67    ColorTempAsShot                      int16s
     4642     68    WB_RGGBLevelsAuto                    int16s[4]
     4643     72    ColorTempAuto                        int16s
     4644     73    WB_RGGBLevelsMeasured                int16s[4]
     4645     77    ColorTempMeasured                    int16s
     4646     78    WB_RGGBLevelsUnknown?                int16s[4]
     4647     82    ColorTempUnknown?                    int16s
     4648     83    WB_RGGBLevelsUnknown2?               int16s[4]
     4649     87    ColorTempUnknown2?                   int16s
     4650     88    WB_RGGBLevelsUnknown3?               int16s[4]
     4651     92    ColorTempUnknown3?                   int16s
     4652     93    WB_RGGBLevelsUnknown4?               int16s[4]
     4653     97    ColorTempUnknown4?                   int16s
     4654     98    WB_RGGBLevelsUnknown5?               int16s[4]
     4655    102    ColorTempUnknown5?                   int16s
     4656    103    WB_RGGBLevelsDaylight                int16s[4]
     4657    107    ColorTempDaylight                    int16s
     4658    108    WB_RGGBLevelsShade                   int16s[4]
     4659    112    ColorTempShade                       int16s
     4660    113    WB_RGGBLevelsCloudy                  int16s[4]
     4661    117    ColorTempCloudy                      int16s
     4662    118    WB_RGGBLevelsTungsten                int16s[4]
     4663    122    ColorTempTungsten                    int16s
     4664    123    WB_RGGBLevelsFluorescent             int16s[4]
     4665    127    ColorTempFluorescent                 int16s
     4666    128    WB_RGGBLevelsKelvin                  int16s[4]
     4667    132    ColorTempKelvin                      int16s
     4668    133    WB_RGGBLevelsFlash                   int16s[4]
     4669    137    ColorTempFlash                       int16s
     4670    138    WB_RGGBLevelsUnknown6?               int16s[4]
     4671    142    ColorTempUnknown6?                   int16s
     4672    143    WB_RGGBLevelsUnknown7?               int16s[4]
     4673    147    ColorTempUnknown7?                   int16s
     4674    148    WB_RGGBLevelsUnknown8?               int16s[4]
     4675    152    ColorTempUnknown8?                   int16s
     4676    153    WB_RGGBLevelsUnknown9?               int16s[4]
     4677    157    ColorTempUnknown9?                   int16s
     4678    158    WB_RGGBLevelsUnknown10?              int16s[4]
     4679    162    ColorTempUnknown10?                  int16s
     4680    163    WB_RGGBLevelsUnknown11?              int16s[4]
     4681    167    ColorTempUnknown11?                  int16s
     4682    168    WB_RGGBLevelsUnknown12?              int16s[4]
     4683    172    ColorTempUnknown12?                  int16s
     4684    173    WB_RGGBLevelsUnknown13?              int16s[4]
     4685    177    ColorTempUnknown13?                  int16s
     4686    178    WB_RGGBLevelsUnknown14?              int16s[4]
     4687    182    ColorTempUnknown14?                  int16s
     4688    183    WB_RGGBLevelsUnknown15?              int16s[4]
     4689    187    ColorTempUnknown15?                  int16s
     4690    188    ColorCalib?                          Canon ColorCalib
     4691    404    RawMeasuredRGGB                      int32u[4]
     4692
     4693=head3 Canon ColorDataUnknown Tags
     4694
     4695   Index   Tag Name                             Writable
     4696   -----   --------                             --------
     4697  [no tags known]
    24264698
    24274699=head3 Canon ColorInfo Tags
     
    24304702   -----   --------                             --------
    24314703      1    Saturation                           int16s
    2432       2    ColorHue                             int16s
     4704      2    ColorTone                            int16s
    24334705      3    ColorSpace                           int16s
     4706
     4707=head3 Canon AFMicroAdj Tags
     4708
     4709   Index   Tag Name                             Writable
     4710   -----   --------                             --------
     4711      1    AFMicroAdjActive                     int32s
     4712      2    AFMicroAdjValue                      rational64s
     4713
     4714=head3 Canon VignettingCorr Tags
     4715
     4716This information is found in images from the 1DmkIV, 5DmkII, 7D, 50D, 500D
     4717and 550D.
     4718
     4719   Index   Tag Name                             Writable
     4720   -----   --------                             --------
     4721      2    PeripheralLighting                   int16s
     4722      6    PeripheralLightingValue              int16s
     4723     11    OriginalImageWidth                   int16s
     4724     12    OriginalImageHeight                  int16s
     4725
     4726=head3 Canon VignettingCorr2 Tags
     4727
     4728   Index   Tag Name                             Writable
     4729   -----   --------                             --------
     4730      5    PeripheralLightingSetting            int32s
     4731
     4732=head3 Canon LightingOpt Tags
     4733
     4734This information is new in images from the EOS 7D.
     4735
     4736   Index   Tag Name                             Writable
     4737   -----   --------                             --------
     4738      2    AutoLightingOptimizer                int32s
     4739
     4740=head3 Canon LensInfo Tags
     4741
     4742   Index   Tag Name                             Writable
     4743   -----   --------                             --------
     4744      0    LensSerialNumber                     undef[5]
     4745
     4746=head3 Canon Ambience Tags
     4747
     4748   Index   Tag Name                             Writable
     4749   -----   --------                             --------
     4750      1    AmbienceSelection                    int32s
     4751
     4752=head3 Canon FilterInfo Tags
     4753
     4754Information about creative filter settings.
     4755
     4756  Tag ID   Tag Name                             Writable
     4757  ------   --------                             --------
     4758  0x0101   GrainyBWFilter                       N
     4759  0x0201   SoftFocusFilter                      N
     4760  0x0301   ToyCameraFilter                      N
     4761  0x0401   MiniatureFilter                      N
     4762  0x0402   MiniatureFilterOrientation           N
     4763  0x0403   MiniatureFilterPosition              N
     4764
     4765=head3 Canon CNTH Tags
     4766
     4767Canon-specific QuickTime tags found in the CNTH atom of MOV videos from some
     4768cameras such as the PowerShot S95.
     4769
     4770  Tag ID   Tag Name                             Writable
     4771  ------   --------                             --------
     4772  'CNDA'   ThumbnailImage                       N
    24344773
    24354774=head2 CanonCustom Tags
     
    24514790      7    USMLensElectronicMF                  int8u
    24524791      8    LCDPanels                            int8u
    2453       9    AEBSequence                          int8u
     4792      9    AEBSequenceAutoCancel                int8u
    24544793     10    AFPointIllumination                  int8u
    24554794     11    AFPointSelection                     int8u
     
    24634802     19    LensAFStopButton                     int8u
    24644803     20    AIServoTrackingSensitivity           int8u
     4804     21    AIServoContinuousShooting            int8u
    24654805
    24664806=head3 CanonCustom Functions5D Tags
     
    24774817      7    FlashFiring                          int8u
    24784818      8    ISOExpansion                         int8u
    2479       9    AEBSequence                          int8u
     4819      9    AEBSequenceAutoCancel                int8u
    24804820     10    SuperimposedDisplay                  int8u
    24814821     11    MenuButtonDisplayPosition            int8u
     
    24944834  Tag ID   Tag Name                             Writable
    24954835  ------   --------                             --------
    2496       1    SetButtonFunction                    int8u
     4836      1    SetButtonWhenShooting                int8u
    24974837      2    ShutterReleaseNoCFCard               int8u
    24984838      3    FlashSyncSpeedAv                     int8u
     
    25024842      7    AFPointRegistration                  int8u
    25034843      8    RawAndJpgRecording                   int8u
    2504       9    AEBSequence                          int8u
     4844      9    AEBSequenceAutoCancel                int8u
    25054845     10    SuperimposedDisplay                  int8u
    25064846     11    MenuButtonDisplayPosition            int8u
     
    25244864      6    FlashFiring                          int8u
    25254865      7    ISOExpansion                         int8u
    2526       8    AEBSequence                          int8u
     4866      8    AEBSequenceAutoCancel                int8u
    25274867      9    SuperimposedDisplay                  int8u
    25284868     10    MenuButtonDisplayPosition            int8u
     
    25474887      7    FlashFiring                          int8u
    25484888      8    ISOExpansion                         int8u
    2549       9    AEBSequence                          int8u
     4889      9    AEBSequenceAutoCancel                int8u
    25504890     10    SuperimposedDisplay                  int8u
    25514891     11    MenuButtonDisplayPosition            int8u
     
    25914931=head3 CanonCustom FunctionsD30 Tags
    25924932
    2593 Custom functions for the EOS-D30 and D60.
     4933Custom functions for the EOS D30 and D60.
    25944934
    25954935  Tag ID   Tag Name                             Writable
     
    26014941      5    AFAssist                             int8u
    26024942      6    FlashSyncSpeedAv                     int8u
    2603       7    AEBSequence                          int8u
     4943      7    AEBSequenceAutoCancel                int8u
    26044944      8    ShutterCurtainSync                   int8u
    26054945      9    LensAFStopButton                     int8u
    26064946     10    FillFlashAutoReduction               int8u
    26074947     11    MenuButtonReturn                     int8u
    2608      12    SetButtonFunction                    int8u
     4948     12    SetButtonWhenShooting                int8u
    26094949     13    SensorCleaning                       int8u
    26104950     14    SuperimposedDisplay                  int8u
     
    26855025
    26865026Beginning with the EOS 1D Mark III, Canon finally created a set of custom
    2687 function tags which are consistent across models.  The EOS 1D Mark III has
    2688 57 custom function tags divided into four main groups: 1. Exposure
    2689 (0x0101-0x010f), 2. Image (0x0201-0x0203), Flash Exposure (0x0304-0x0306)
    2690 and Display (0x0407-0x0409), 3. Auto Focus (0x0501-0x050e) and Drive
    2691 (0x060f-0x0611), and 4. Operation (0x0701-0x070a) and Others
     5027function tags which are (reasonably) consistent across models.  The EOS 1D
     5028Mark III has 57 custom function tags divided into four main groups: 1.
     5029Exposure (0x0101-0x010f), 2. Image (0x0201-0x0203), Flash Exposure
     5030(0x0304-0x0306) and Display (0x0407-0x0409), 3. Auto Focus (0x0501-0x050e)
     5031and Drive (0x060f-0x0611), and 4. Operation (0x0701-0x070a) and Others
    26925032(0x080b-0x0810).  The table below lists tags used by the EOS 1D Mark III, as
    2693 well as newer values and tags used by the EOS 40D.  It is expected that
    2694 future models will re-use some of these tags (possibly with minor value
    2695 changes), as well as defining additional new tags of their own.
     5033well as newer tags and values added by later models.
    26965034
    26975035  Tag ID   Tag Name                             Writable
     
    26995037  0x0101   ExposureLevelIncrements              int32s
    27005038  0x0102   ISOSpeedIncrements                   int32s
    2701   0x0103   ISOExpansion                         int32s
    2702            ISOSpeedRange                        int32s[3]
     5039  0x0103   ISOSpeedRange                        int32s[3]
     5040           ISOExpansion                         int32s
    27035041  0x0104   AEBAutoCancel                        int32s
    27045042  0x0105   AEBSequence                          int32s
    2705   0x0106   AEBShotCount                         int32s
     5043  0x0106   AEBShotCount                         int32s[n]
    27065044  0x0107   SpotMeterLinkToAFPoint               int32s
    27075045  0x0108   SafetyShift                          int32s
     
    27135051  0x010e   ApplyShootingMeteringMode            int32s[8]
    27145052  0x010f   FlashSyncSpeedAv                     int32s
     5053  0x0110   FEMicroadjustment                    int32s[3]
     5054  0x0111   AEMicroadjustment                    int32s[3]
    27155055  0x0201   LongExposureNoiseReduction           int32s
    27165056  0x0202   HighISONoiseReduction                int32s
    27175057  0x0203   HighlightTonePriority                int32s
     5058  0x0204   AutoLightingOptimizer                int32s
    27185059  0x0304   ETTLII                               int32s
    27195060  0x0305   ShutterCurtainSync                   int32s
     
    27295070  0x0506   LensAFStopButton                     int32s
    27305071  0x0507   AFMicroadjustment                    int32s[5]
    2731   0x0508   AFExpansionWithSelectedPoint         int32s
     5072  0x0508   AFPointAreaExpansion                 int32s
    27325073  0x0509   SelectableAFPoint                    int32s
    27335074  0x050a   SwitchToRegisteredAFPoint            int32s
     
    27375078  0x050e   AFAssistBeam                         int32s
    27385079  0x050f   AFPointSelectionMethod               int32s
    2739   0x0510   SuperimposedDisplay                  int32s
     5080  0x0510   VFDisplayIllumination                int32s
     5081           SuperimposedDisplay                  int32s
    27405082  0x0511   AFDuringLiveView                     int32s
     5083  0x0512   SelectAFAreaSelectMode               int32s
     5084  0x0513   ManualAFPointSelectPattern           int32s
     5085  0x0514   DisplayAllAFPoints                   int32s
     5086  0x0515   FocusDisplayAIServoAndMF             int32s
     5087  0x0516   OrientationLinkedAFPoint             int32s
     5088  0x0517   MultiControllerWhileMetering         int32s
    27415089  0x060f   MirrorLockup                         int32s
    27425090  0x0610   ContinuousShootingSpeed              int32s[3]
    27435091  0x0611   ContinuousShotLimit                  int32s[2]
    2744   0x0701   ShutterButtonAFOnButton              int32s
     5092  0x0701   Shutter-AELock                       int32s
     5093           AFAndMeteringButtons                 int32s
     5094           ShutterButtonAFOnButton              int32s
    27455095  0x0702   AFOnAELockButtonSwitch               int32s
    27465096  0x0703   QuickControlDialInMeter              int32s
     
    27525102  0x0709   LockMicrophoneButton                 int32s
    27535103  0x070a   ButtonFunctionControlOff             int32s
     5104  0x070b   AssignFuncButton                     int32s
     5105  0x070c   CustomControls                       int32s
     5106  0x070d   StartMovieShooting                   int32s
    27545107  0x080b   FocusingScreen                       int32s
    27555108  0x080c   TimerLength                          int32s[4]
     
    27585111  0x080f   AddOriginalDecisionData              int32s
    27595112  0x0810   LiveViewExposureSimulation           int32s
     5113  0x0811   LCDDisplayAtPowerOn                  int32s
     5114
     5115=head2 CanonVRD Tags
     5116
     5117Canon Digital Photo Professional writes VRD (Recipe Data) information as a
     5118trailer record to JPEG, TIFF, CRW and CR2 images, or as a stand-alone VRD
     5119file.  The tags listed below represent information found in this record.
     5120The complete VRD data record may be accessed as a block using the Extra
     5121'CanonVRD' tag, but this tag is not extracted or copied unless specified
     5122explicitly.
     5123
     5124  Tag ID       Tag Name                         Writable
     5125  ------       --------                         --------
     5126  0xffff00f4   EditData                         CanonVRD Edit
     5127  0xffff00f5   IHLData                          CanonVRD IHL
     5128  0xffff00f6   XMP                              XMP
     5129
     5130=head3 CanonVRD Edit Tags
     5131
     5132Canon VRD edit information.
     5133
     5134   Index   Tag Name                             Writable
     5135   -----   --------                             --------
     5136      0    VRD1                                 CanonVRD Ver1
     5137      1    VRDStampTool                         CanonVRD StampTool
     5138      2    VRD2                                 CanonVRD Ver2
     5139
     5140=head3 CanonVRD Ver1 Tags
     5141
     5142   Index   Tag Name                             Writable
     5143   -----   --------                             --------
     5144      2    VRDVersion                           N
     5145      8    WBAdjRGBLevels                       int16u[3]
     5146     24    WhiteBalanceAdj                      int16u
     5147     26    WBAdjColorTemp                       int16u
     5148     36    WBFineTuneActive                     int16u
     5149     40    WBFineTuneSaturation                 int16u
     5150     44    WBFineTuneTone                       int16u
     5151     46    RawColorAdj                          int16u
     5152     48    RawCustomSaturation                  int32s
     5153     52    RawCustomTone                        int32s
     5154     56    RawBrightnessAdj                     int32s
     5155     60    ToneCurveProperty                    int16u
     5156    122    DynamicRangeMin                      int16u
     5157    124    DynamicRangeMax                      int16u
     5158    272    ToneCurveActive                      int16u
     5159    275    ToneCurveMode                        int8u
     5160    276    BrightnessAdj                        int8s
     5161    277    ContrastAdj                          int8s
     5162    278    SaturationAdj                        int16s
     5163    286    ColorToneAdj                         int32s
     5164    294    LuminanceCurvePoints                 int16u[21]
     5165    336    LuminanceCurveLimits                 int16u[4]
     5166    345    ToneCurveInterpolation               int8u
     5167    352    RedCurvePoints                       int16u[21]
     5168    394    RedCurveLimits                       int16u[4]
     5169    410    GreenCurvePoints                     int16u[21]
     5170    452    GreenCurveLimits                     int16u[4]
     5171    468    BlueCurvePoints                      int16u[21]
     5172    510    BlueCurveLimits                      int16u[4]
     5173    526    RGBCurvePoints                       int16u[21]
     5174    568    RGBCurveLimits                       int16u[4]
     5175    580    CropActive                           int16u
     5176    582    CropLeft                             int16u
     5177    584    CropTop                              int16u
     5178    586    CropWidth                            int16u
     5179    588    CropHeight                           int16u
     5180    602    SharpnessAdj                         int16u
     5181    608    CropAspectRatio                      int16u
     5182    610    ConstrainedCropWidth                 float
     5183    614    ConstrainedCropHeight                float
     5184    618    CheckMark                            int16u
     5185    622    Rotation                             int16u
     5186    624    WorkColorSpace                       int16u
     5187
     5188=head3 CanonVRD StampTool Tags
     5189
     5190   Index   Tag Name                             Writable
     5191   -----   --------                             --------
     5192      0    StampToolCount                       N
     5193
     5194=head3 CanonVRD Ver2 Tags
     5195
     5196Tags added in DPP version 2.0 and later.
     5197
     5198   Index   Tag Name                             Writable
     5199   -----   --------                             --------
     5200      2    PictureStyle                         int16s
     5201      3    IsCustomPictureStyle                 int16s
     5202     13    StandardRawColorTone                 int16s
     5203     14    StandardRawSaturation                int16s
     5204     15    StandardRawContrast                  int16s
     5205     16    StandardRawLinear                    int16s
     5206     17    StandardRawSharpness                 int16s
     5207     18    StandardRawHighlightPoint            int16s
     5208     19    StandardRawShadowPoint               int16s
     5209     20    StandardOutputHighlightPoint         int16s
     5210     21    StandardOutputShadowPoint            int16s
     5211     22    PortraitRawColorTone                 int16s
     5212     23    PortraitRawSaturation                int16s
     5213     24    PortraitRawContrast                  int16s
     5214     25    PortraitRawLinear                    int16s
     5215     26    PortraitRawSharpness                 int16s
     5216     27    PortraitRawHighlightPoint            int16s
     5217     28    PortraitRawShadowPoint               int16s
     5218     29    PortraitOutputHighlightPoint         int16s
     5219     30    PortraitOutputShadowPoint            int16s
     5220     31    LandscapeRawColorTone                int16s
     5221     32    LandscapeRawSaturation               int16s
     5222     33    LandscapeRawContrast                 int16s
     5223     34    LandscapeRawLinear                   int16s
     5224     35    LandscapeRawSharpness                int16s
     5225     36    LandscapeRawHighlightPoint           int16s
     5226     37    LandscapeRawShadowPoint              int16s
     5227     38    LandscapeOutputHighlightPoint        int16s
     5228     39    LandscapeOutputShadowPoint           int16s
     5229     40    NeutralRawColorTone                  int16s
     5230     41    NeutralRawSaturation                 int16s
     5231     42    NeutralRawContrast                   int16s
     5232     43    NeutralRawLinear                     int16s
     5233     44    NeutralRawSharpness                  int16s
     5234     45    NeutralRawHighlightPoint             int16s
     5235     46    NeutralRawShadowPoint                int16s
     5236     47    NeutralOutputHighlightPoint          int16s
     5237     48    NeutralOutputShadowPoint             int16s
     5238     49    FaithfulRawColorTone                 int16s
     5239     50    FaithfulRawSaturation                int16s
     5240     51    FaithfulRawContrast                  int16s
     5241     52    FaithfulRawLinear                    int16s
     5242     53    FaithfulRawSharpness                 int16s
     5243     54    FaithfulRawHighlightPoint            int16s
     5244     55    FaithfulRawShadowPoint               int16s
     5245     56    FaithfulOutputHighlightPoint         int16s
     5246     57    FaithfulOutputShadowPoint            int16s
     5247     58    MonochromeFilterEffect               int16s
     5248     59    MonochromeToningEffect               int16s
     5249     60    MonochromeContrast                   int16s
     5250     61    MonochromeLinear                     int16s
     5251     62    MonochromeSharpness                  int16s
     5252     63    MonochromeRawHighlightPoint          int16s
     5253     64    MonochromeRawShadowPoint             int16s
     5254     65    MonochromeOutputHighlightPoint       int16s
     5255     66    MonochromeOutputShadowPoint          int16s
     5256     69    UnknownContrast?                     int16s
     5257     70    UnknownLinear?                       int16s
     5258     71    UnknownSharpness?                    int16s
     5259     72    UnknownRawHighlightPoint?            int16s
     5260     73    UnknownRawShadowPoint?               int16s
     5261     74    UnknownOutputHighlightPoint?         int16s
     5262     75    UnknownOutputShadowPoint?            int16s
     5263     78    CustomContrast                       int16s
     5264     79    CustomLinear                         int16s
     5265     80    CustomSharpness                      int16s
     5266     81    CustomRawHighlightPoint              int16s
     5267     82    CustomRawShadowPoint                 int16s
     5268     83    CustomOutputHighlightPoint           int16s
     5269     84    CustomOutputShadowPoint              int16s
     5270     88    CustomPictureStyleData               N
     5271     94    ChrominanceNoiseReduction            int16s
     5272     95    LuminanceNoiseReduction              int16s
     5273     96    ChrominanceNR_TIFF_JPEG              int16s
     5274     98    ChromaticAberrationOn                int16s
     5275     99    DistortionCorrectionOn               int16s
     5276    100    PeripheralIlluminationOn             int16s
     5277    101    ColorBlur                            int16s
     5278    102    ChromaticAberration                  int16s
     5279    103    DistortionCorrection                 int16s
     5280    104    PeripheralIllumination               int16s
     5281    105    AberrationCorrectionDistance         int16s
     5282    106    ChromaticAberrationRed               int16s
     5283    107    ChromaticAberrationBlue              int16s
     5284    109    LuminanceNR_TIFF_JPEG                int16s
     5285    110    AutoLightingOptimizerOn              int16s
     5286    111    AutoLightingOptimizer                int16s
     5287    117    StandardRawHighlight                 int16s
     5288    118    PortraitRawHighlight                 int16s
     5289    119    LandscapeRawHighlight                int16s
     5290    120    NeutralRawHighlight                  int16s
     5291    121    FaithfulRawHighlight                 int16s
     5292    122    MonochromeRawHighlight               int16s
     5293    123    UnknownRawHighlight?                 int16s
     5294    124    CustomRawHighlight                   int16s
     5295    126    StandardRawShadow                    int16s
     5296    127    PortraitRawShadow                    int16s
     5297    128    LandscapeRawShadow                   int16s
     5298    129    NeutralRawShadow                     int16s
     5299    130    FaithfulRawShadow                    int16s
     5300    131    MonochromeRawShadow                  int16s
     5301    132    UnknownRawShadow?                    int16s
     5302    133    CustomRawShadow                      int16s
     5303    139    AngleAdj                             int32s
     5304    142    CheckMark2                           int16u
     5305    144    UnsharpMask                          int16s
     5306    146    UnsharpMaskStrength                  int16s
     5307    148    UnsharpMaskFineness                  int16s
     5308    150    UnsharpMaskThreshold                 int16s
     5309
     5310=head3 CanonVRD IHL Tags
     5311
     5312  Tag ID   Tag Name                             Writable
     5313  ------   --------                             --------
     5314  0x0001   IHL_EXIF                             EXIF
     5315           IHL_EXIF?                            N
     5316  0x0003   ThumbnailImage                       N
     5317  0x0004   PreviewImage                         N
     5318  0x0005   RawCodecVersion                      N
     5319  0x0006   CRCDevelParams?                      N
    27605320
    27615321=head2 Casio Tags
     
    27755335  0x000d   Saturation                           int16u
    27765336  0x0014   ISO                                  int16u
     5337  0x0015   FirmwareDate                         string[18]
    27775338  0x0016   Enhancement                          int16u
    27785339  0x0017   ColorFilter                          int16u
     
    28025363  0x2011   WhiteBalanceBias                     int16u[2]
    28035364  0x2012   WhiteBalance                         int16u
     5365  0x2021   AFPointPosition                      int16u[4]~
    28045366  0x2022   ObjectDistance                       int32u
    28055367  0x2034   FlashDistance                        int16u
     5368  0x2076   SpecialEffectMode                    int8u[3]
     5369  0x2089   FaceInfo1                            Casio FaceInfo1
     5370           FaceInfo2                            Casio FaceInfo2
     5371           FaceInfoUnknown?                     Y
     5372  0x211c   FacesDetected                        int8u
    28065373  0x3000   RecordMode                           int16u
    2807   0x3001   SelfTimer                            int16u
     5374  0x3001   ReleaseMode                          int16u
    28085375  0x3002   Quality                              int16u
    28095376  0x3003   FocusMode                            int16u
     
    28115378  0x3007   BestShotMode                         int16u
    28125379  0x3008   AutoISO                              int16u
     5380  0x3009   AFMode                               int16u
    28135381  0x3011   Sharpness                            undef[2]
    28145382  0x3012   Contrast                             undef[2]
     
    28175385  0x3015   ColorMode                            int16u
    28185386  0x3016   Enhancement                          int16u
    2819   0x3017   Filter                               int16u
     5387  0x3017   ColorFilter                          int16u
     5388  0x301b   UnknownMode?                         int16u
    28205389  0x301c   SequenceNumber                       int16u
    28215390  0x301d   BracketSequence                      int16u[2]
    28225391  0x3020   ImageStabilization                   int16u
     5392  0x302a   LightingMode                         int16u
     5393  0x302b   PortraitRefiner                      int16u
     5394  0x3030   SpecialEffectLevel                   int16u
     5395  0x3031   SpecialEffectSetting                 int16u
     5396  0x3103   DriveMode                            int16u
     5397  0x4001   CaptureFrameRate                     int16u[n]
     5398  0x4003   VideoQuality                         int16u
     5399
     5400=head3 Casio FaceInfo1 Tags
     5401
     5402Face-detect tags extracted from models such as the EX-H5.
     5403
     5404   Index   Tag Name                             Writable
     5405   -----   --------                             --------
     5406      0    FacesDetected                        int8u
     5407      1    FaceDetectFrameSize                  int16u[2]
     5408     13    Face1Position                        int16u[4]
     5409    124    Face2Position                        int16u[4]
     5410    235    Face3Position                        int16u[4]
     5411    346    Face4Position                        int16u[4]
     5412    457    Face5Position                        int16u[4]
     5413    568    Face6Position                        int16u[4]
     5414    679    Face7Position                        int16u[4]
     5415    790    Face8Position                        int16u[4]
     5416    901    Face9Position                        int16u[4]
     5417   1012    Face10Position                       int16u[4]
     5418
     5419=head3 Casio FaceInfo2 Tags
     5420
     5421Face-detect tags extracted from models such as the EX-H20G and EX-ZR100.
     5422
     5423   Index   Tag Name                             Writable
     5424   -----   --------                             --------
     5425      2    FacesDetected                        int8u
     5426      4    FaceDetectFrameSize                  int16u[2]
     5427      8    FaceOrientation                      int8u
     5428     24    Face1Position                        int16u[4]
     5429     76    Face2Position                        int16u[4]
     5430    128    Face3Position                        int16u[4]
     5431    180    Face4Position                        int16u[4]
     5432    232    Face5Position                        int16u[4]
     5433    284    Face6Position                        int16u[4]
     5434    336    Face7Position                        int16u[4]
     5435    388    Face8Position                        int16u[4]
     5436    440    Face9Position                        int16u[4]
     5437    492    Face10Position                       int16u[4]
     5438
     5439=head3 Casio QVCI Tags
     5440
     5441This information is found in the APP1 QVCI segment of JPEG images from the
     5442Casio QV-7000SX.
     5443
     5444   Index   Tag Name                             Writable
     5445   -----   --------                             --------
     5446     44    CasioQuality                         N
     5447     55    FocalRange?                          N
     5448     77    DateTimeOriginal                     N
     5449     98    ModelType                            N
     5450    114    ManufactureIndex                     N
     5451    124    ManufactureCode                      N
     5452
     5453=head3 Casio AVI Tags
     5454
     5455This information is found in Casio GV-10 AVI videos.
     5456
     5457   Index   Tag Name                             Writable
     5458   -----   --------                             --------
     5459      0    Software                             N
    28235460
    28245461=head2 FujiFilm Tags
     
    28345471  0x1004   Contrast                             int16u
    28355472  0x1005   ColorTemperature                     int16u
     5473  0x1006   Contrast                             int16u
     5474  0x100a   WhiteBalanceFineTune                 int32s[2]
     5475  0x100b   NoiseReduction                       int16u
     5476  0x100e   HighISONoiseReduction                int16u
    28365477  0x1010   FujiFlashMode                        int16u
    2837   0x1011   FlashStrength                        rational64s
     5478  0x1011   FlashExposureComp                    rational64s
    28385479  0x1020   Macro                                int16u
    28395480  0x1021   FocusMode                            int16u
     
    28415482  0x1030   SlowSync                             int16u
    28425483  0x1031   PictureMode                          int16u
     5484  0x1033   EXRAuto                              int16u
     5485  0x1034   EXRMode                              int16u
    28435486  0x1100   AutoBracketing                       int16u
    28445487  0x1101   SequenceNumber                       int16u
     
    28475490  0x1301   FocusWarning                         int16u
    28485491  0x1302   ExposureWarning                      int16u
     5492  0x1304   GEImageSize                          string
    28495493  0x1400   DynamicRange                         int16u
    28505494  0x1401   FilmMode                             int16u
     
    28555499  0x1406   MaxApertureAtMinFocal                rational64s
    28565500  0x1407   MaxApertureAtMaxFocal                rational64s
     5501  0x140b   AutoDynamicRange                     int16u
     5502  0x4100   FacesDetected                        int16u
     5503  0x4103   FacePositions                        int16u[n]
     5504  0x4282   FaceRecInfo                          FujiFilm FaceRecInfo
    28575505  0x8000   FileSource                           string
    28585506  0x8002   OrderNumber                          int32u
    28595507  0x8003   FrameNumber                          int16u
     5508  0xb211   Parallax                             rational64s
     5509
     5510=head3 FujiFilm FaceRecInfo Tags
     5511
     5512Face recognition information.
     5513
     5514  Tag Name                                      Writable
     5515  --------                                      --------
     5516  Face1Birthday                                 N
     5517  Face1Category                                 N
     5518  Face1Name                                     N
     5519  Face2Birthday                                 N
     5520  Face2Category                                 N
     5521  Face2Name                                     N
     5522  Face3Birthday                                 N
     5523  Face3Category                                 N
     5524  Face3Name                                     N
     5525  Face4Birthday                                 N
     5526  Face4Category                                 N
     5527  Face4Name                                     N
     5528  Face5Birthday                                 N
     5529  Face5Category                                 N
     5530  Face5Name                                     N
     5531  Face6Birthday                                 N
     5532  Face6Category                                 N
     5533  Face6Name                                     N
     5534  Face7Birthday                                 N
     5535  Face7Category                                 N
     5536  Face7Name                                     N
     5537  Face8Birthday                                 N
     5538  Face8Category                                 N
     5539  Face8Name                                     N
    28605540
    28615541=head3 FujiFilm RAF Tags
    28625542
    2863 Tags extracted from FujiFilm RAF-format information.
     5543FujiFilm RAF images contain meta information stored in a proprietary
     5544FujiFilm RAF format, as well as EXIF information stored inside an embedded
     5545JPEG preview image.  The table below lists tags currently decoded from the
     5546RAF-format information.
    28645547
    28655548  Tag ID   Tag Name                             Writable
     
    28705553  0x2ff0   WB_GRGBLevels                        N
    28715554
     5555=head3 FujiFilm FFMV Tags
     5556
     5557Information found in the FFMV atom of MOV videos.
     5558
     5559   Index   Tag Name                             Writable
     5560   -----   --------                             --------
     5561      0    MovieStreamName                      N
     5562
     5563=head2 GE Tags
     5564
     5565This table lists tags found in the maker notes of some General Imaging
     5566camera models.
     5567
     5568  Tag ID   Tag Name                             Writable
     5569  ------   --------                             --------
     5570  0x0202   Macro                                int16u
     5571  0x0207   GEModel                              string
     5572  0x0300   GEMake                               string
     5573
    28725574=head2 HP Tags
    28735575
     
    29165618     88    SerialNumber                         N
    29175619
     5620=head3 HP TDHD Tags
     5621
     5622These tags are extracted from the APP6 "TDHD" segment of Photosmart R837
     5623JPEG images.  Many other unknown tags exist in is data, and can be seen with
     5624the Unknown (-u) option.
     5625
     5626  Tag ID   Tag Name                             Writable
     5627  ------   --------                             --------
     5628  'CMSN'   SerialNumber                         N
     5629  'FWRV'   FirmwareVersion                      N
     5630  'LSLV'   LSLV                                 HP TDHD
     5631  'TDHD'   TDHD                                 HP TDHD
     5632
    29185633=head2 JVC Tags
    29195634
     
    29365651=head2 Kodak Tags
    29375652
    2938 The Kodak maker notes aren't in standard IFD format, and the format varies
    2939 frequently with different models.  Some information has been decoded, but
    2940 much of the Kodak information remains unknown.
     5653Many Kodak models don't store the maker notes in standard IFD format, and
     5654these formats vary with different models.  Some information has been
     5655decoded, but much of the Kodak information remains unknown.
    29415656
    29425657The table below contains the most common set of Kodak tags.  The following
     
    30655780      0    SerialNumber                         string[16]
    30665781
    3067 =head3 Kodak IFD Tags
    3068 
    3069 Newer Kodak models such as the P712, P850, P880, Z612 and Z712 use standard
    3070 TIFF IFD format for the maker notes.  There is a large amount of information
    3071 stored in these maker notes (with apparently much duplication), but
    3072 relatively few tags have so far been decoded.
     5782=head3 Kodak Type8 Tags
     5783
     5784Kodak models such as the ZD710, P712, P850, P880, V1233, V1253, V1275,
     5785V1285, Z612, Z712, Z812, Z885 use standard TIFF IFD format for the maker
     5786notes.  In keeping with Kodak's strategy of inconsistent makernotes, models
     5787such as the M380, M1033, M1093, V1073, V1273, Z1012, Z1085 and Z8612
     5788also use these tags, but these makernotes begin with a TIFF header instead
     5789of an IFD entry count and use relative instead of absolute offsets.  There
     5790is a large amount of information stored in these maker notes (apparently
     5791with much duplication), but relatively few tags have so far been decoded.
    30735792
    30745793  Tag ID   Tag Name                             Writable
    30755794  ------   --------                             --------
    30765795  0xfc00   SubIFD0                              Kodak SubIFD0
     5796                                                Kodak SubIFD0
    30775797  0xfc01   SubIFD1                              Kodak SubIFD1
     5798                                                Kodak SubIFD1
    30785799  0xfc02   SubIFD2                              Kodak SubIFD2
     5800                                                Kodak SubIFD2
    30795801  0xfc03   SubIFD3                              Kodak SubIFD3
     5802                                                Kodak SubIFD3
    30805803  0xfc04   SubIFD4                              Kodak SubIFD4
     5804                                                Kodak SubIFD4
    30815805  0xfc05   SubIFD5                              Kodak SubIFD5
     5806                                                Kodak SubIFD5
     5807  0xfc06   SubIFD6                              Kodak SubIFD6
     5808                                                Kodak SubIFD6
     5809  0xfcff   SubIFD255                            Kodak SubIFD0
    30825810  0xff00   CameraInfo                           Kodak CameraInfo
    30835811
    30845812=head3 Kodak SubIFD0 Tags
    30855813
    3086 SubIFD0 through SubIFD5 tags are used by the Z612 and Z712.
     5814SubIFD0 through SubIFD5 tags are written a number of newer Kodak models.
    30875815
    30885816  Tag ID   Tag Name                             Writable
     
    31445872  0x000f   OpticalZoom                          int16u
    31455873
     5874=head3 Kodak SubIFD6 Tags
     5875
     5876SubIFD6 is written by the M580.
     5877
     5878  Tag ID   Tag Name                             Writable
     5879  ------   --------                             --------
     5880  [no tags known]
     5881
    31465882=head3 Kodak CameraInfo Tags
    31475883
     
    31635899  0xfd06   ISO                                  int16u
    31645900
     5901=head3 Kodak Type9 Tags
     5902
     5903These tags are used by the Kodak C140, C180, C913, C1013, M320, M340 and
     5904M550, as well as various cameras marketed by other manufacturers.
     5905
     5906   Index   Tag Name                             Writable
     5907   -----   --------                             --------
     5908     12    FNumber                              int16u
     5909     16    ExposureTime                         int32u
     5910     20    DateTimeOriginal                     string[20]
     5911     52    ISO                                  int16u
     5912     87    FirmwareVersion                      string[16]
     5913    168    SerialNumber                         string[12]
     5914
     5915=head3 Kodak Type10 Tags
     5916
     5917Another variation of the IFD-format type, this time with just a byte order
     5918indicator instead of a full TIFF header.  These tags are used by the Z980.
     5919
     5920  Tag ID   Tag Name                             Writable
     5921  ------   --------                             --------
     5922  0x0002   PreviewImageSize                     int16u[2]
     5923  0x0012   ExposureTime                         int32u
     5924  0x0013   FNumber                              int16u
     5925  0x0014   ISO                                  int16u
     5926  0x001d   FocalLength                          int32u
     5927
    31655928=head3 Kodak Unknown Tags
    31665929
     
    31695932  [no tags known]
    31705933
     5934=head3 Kodak IFD Tags
     5935
     5936These tags are found in a separate IFD of JPEG, TIFF, DCR and KDC images
     5937from some older Kodak models such as the DC50, DC120, DCS760C, DCS Pro 14N,
     593814nx, SLR/n, Pro Back and Canon EOS D2000.
     5939
     5940  Tag ID   Tag Name                             Writable
     5941  ------   --------                             --------
     5942  0x0001   UnknownEV?                           rational64u
     5943  0x0003   ExposureValue                        rational64u
     5944  0x03e9   OriginalFileName                     string
     5945  0x03eb   SensorLeftBorder                     N
     5946  0x03ec   SensorTopBorder                      N
     5947  0x03ed   SensorImageWidth                     N
     5948  0x03ee   SensorImageHeight                    N
     5949  0x03f1   TextualInfo                          Kodak TextualInfo
     5950  0x03fc   WhiteBalance                         int16u
     5951  0x03fd   Processing                           Kodak Processing
     5952  0x0401   Time                                 string
     5953  0x0414   NCDFileInfo                          string
     5954  0x0846   ColorTemperature                     int16u
     5955  0x0852   WB_RGBMul0                           N
     5956  0x0853   WB_RGBMul1                           N
     5957  0x0854   WB_RGBMul2                           N
     5958  0x0855   WB_RGBMul3                           N
     5959  0x085c   WB_RGBCoeffs0                        N
     5960  0x085d   WB_RGBCoeffs1                        N
     5961  0x085e   WB_RGBCoeffs2                        N
     5962  0x085f   WB_RGBCoeffs3                        N
     5963  0x0ce5   FirmwareVersion                      string
     5964  0x1391   ToneCurveFileName                    string
     5965  0x1784   ISO                                  int32u
     5966
     5967=head3 Kodak TextualInfo Tags
     5968
     5969Below is a list of tags which have been observed in the Kodak TextualInfo
     5970data, however ExifTool will extract information from any tags found here.
     5971
     5972  Tag ID                Tag Name                Writable
     5973  ------                --------                --------
     5974  'AF Function'         AFMode                  N
     5975  'Actual Compensation' ActualCompensation      N
     5976  'Aperture'            Aperture                N
     5977  'Auto Bracket'        AutoBracket             N
     5978  'Brightness Value'    BrightnessValue         N
     5979  'Camera'              CameraModel             N
     5980  'Camera body'         CameraBody              N
     5981  'Compensation'        ExposureCompensation    N
     5982  'Date'                Date                    N
     5983  'Exposure Bias'       ExposureBias            N
     5984  'Exposure Mode'       ExposureMode            N
     5985  'Firmware Version'    FirmwareVersion         N
     5986  'Flash Compensation'  FlashExposureComp       N
     5987  'Flash Fired'         FlashFired              N
     5988  'Flash Sync Mode'     FlashSyncMode           N
     5989  'Focal Length'        FocalLength             N
     5990  'Height'              KodakImageHeight        N
     5991  'ISO'                 ISO                     N
     5992  'ISO Speed'           ISO                     N
     5993  'Image Number'        ImageNumber             N
     5994  'Max Aperture'        MaxAperture             N
     5995  'Meter Mode'          MeterMode               N
     5996  'Min Aperture'        MinAperture             N
     5997  'Popup Flash'         PopupFlash              N
     5998  'Serial Number'       SerialNumber            N
     5999  'Shooting Mode'       ShootingMode            N
     6000  'Shutter'             ShutterSpeed            N
     6001  'Temperature'         Temperature             N
     6002  'Time'                Time                    N
     6003  'White balance'       WhiteBalance            N
     6004  'Width'               KodakImageWidth         N
     6005  '_other_info'         OtherInfo               N
     6006
     6007=head3 Kodak Processing Tags
     6008
     6009   Index   Tag Name                             Writable
     6010   -----   --------                             --------
     6011     20    WB_RGBLevels                         N
     6012
    31716013=head3 Kodak Meta Tags
    31726014
    31736015These tags are found in the APP3 "Meta" segment of JPEG images from Kodak
    3174 cameras such as the DC280, DC3400, DC5000 and MC3.  The structure of this
    3175 segment is similar to the APP1 "Exif" segment, but a different set of tags
    3176 is used.
     6016cameras such as the DC280, DC3400, DC5000, MC3, M580, Z950 and Z981.  The
     6017structure of this segment is similar to the APP1 "Exif" segment, but a
     6018different set of tags is used.
    31776019
    31786020  Tag ID   Tag Name                             Writable
     
    31816023  0xc351   ImageSourceEK                        N
    31826024  0xc352   CaptureConditionsPAR                 N
    3183   0xc353   CameraOwner                          N
    3184   0xc354   SerialNumber                         N
     6025  0xc353   CameraOwner                          undef
     6026  0xc354   SerialNumber                         undef
    31856027  0xc355   UserSelectGroupTitle                 N
    31866028  0xc356   DealerIDNumber                       N
     
    32356077  0x0008   WatermarkType                        N
    32366078
     6079=head3 Kodak KDC_IFD Tags
     6080
     6081These tags are found in a separate IFD of KDC images from some newer Kodak
     6082models such as the P880 and Z1015IS.
     6083
     6084  Tag ID   Tag Name                             Writable
     6085  ------   --------                             --------
     6086  0xfa00   SerialNumber                         string
     6087  0xfa0d   WhiteBalance                         int8u
     6088  0xfa25   WB_RGBLevelsAuto                     N
     6089  0xfa27   WB_RGBLevelsTungsten                 N
     6090  0xfa28   WB_RGBLevelsFluorescent              N
     6091  0xfa29   WB_RGBLevelsDaylight                 N
     6092  0xfa2a   WB_RGBLevelsShade                    N
     6093
     6094=head3 Kodak MOV Tags
     6095
     6096This information is found in Kodak MOV videos from models such as the P880.
     6097
     6098   Index   Tag Name                             Writable
     6099   -----   --------                             --------
     6100      0    Make                                 N
     6101     22    Model                                N
     6102     64    ModelType                            N
     6103     78    ExposureTime                         N
     6104     82    FNumber                              N
     6105     90    ExposureCompensation                 N
     6106    112    FocalLength                          N
     6107
    32376108=head2 Leaf Tags
    32386109
    32396110These tags are found in .MOS images from Leaf digital camera backs as
    32406111written by Creo Leaf Capture.  They exist within the Leaf-specific directory
    3241 structure of EXIF tag 0x8606. The tables below list observed Leaf tags,
     6112structure of EXIF tag 0x8606.  The tables below list observed Leaf tags,
    32426113however ExifTool will extract any tags found in the Leaf directories even if
    32436114they don't appear in these tables.
     
    34926363=head3 Leaf SubIFD Tags
    34936364
    3494 Leaf also writes a TIFF-format sub-IFD inside IFD0 of a MOS image.  No tags
    3495 in this sub-IFD are currently known, except for tag 0x8606 which really
     6365Leaf writes a TIFF-format sub-IFD inside IFD0 of a MOS image.  No tags in
     6366this sub-IFD are currently known, except for tag 0x8606 which really
    34966367shouldn't be here anyway (so it doesn't appear in the table below) because
    34976368it duplicates a reference to the same data of tag 0x8606 in IFD0.
     
    35036374=head2 Minolta Tags
    35046375
    3505 These tags are used by Minolta and Konica/Minolta cameras.  Minolta doesn't
    3506 make things easy for decoders because the meaning of some tags and the
    3507 location where some information is stored is different for different camera
    3508 models.  (Take MinoltaQuality for example, which may be located in 5
    3509 different places.)
     6376These tags are used by Minolta, Konica/Minolta as well as some Sony cameras.
     6377Minolta doesn't make things easy for decoders because the meaning of some
     6378tags and the location where some information is stored is different for
     6379different camera models.  (Take MinoltaQuality for example, which may be
     6380located in 5 different places.)
    35106381
    35116382  Tag ID   Tag Name                             Writable
     
    35166387  0x0004   MinoltaCameraSettings7D              Minolta CameraSettings7D
    35176388  0x0018   ImageStabilization                   N
     6389  0x0020   WBInfoA100                           Minolta WBInfoA100
    35186390  0x0040   CompressedImageSize                  int32u
    35196391  0x0081   PreviewImage                         undef
    35206392  0x0088   PreviewImageStart                    int32u*
    35216393  0x0089   PreviewImageLength                   int32u*
    3522   0x0100   SceneMode                            Y
     6394  0x0100   SceneMode                            int32u
    35236395  0x0101   ColorMode                            int32u
    35246396  0x0102   MinoltaQuality                       int32u
     
    35266398           MinoltaImageSize                     int32u
    35276399  0x0104   FlashExposureComp                    rational64s
     6400  0x0105   Teleconverter                        int32u
    35286401  0x0107   ImageStabilization                   int32u
     6402  0x0109   RawAndJpgRecording                   int32u
    35296403  0x010a   ZoneMatching                         int32u
    35306404  0x010b   ColorTemperature                     int32u
    3531   0x010c   LensID                               int32u
     6405  0x010c   LensType                             int32u
     6406  0x0111   ColorCompensationFilter              int32s
     6407  0x0112   WhiteBalanceFineTune                 int32u
    35326408  0x0113   ImageStabilization                   int32u
    35336409  0x0114   MinoltaCameraSettings5D              Minolta CameraSettings5D
    3534            MinoltaCameraSettingsA100            Minolta CameraSettingsA100
     6410           CameraSettingsA100                   Minolta CameraSettingsA100
     6411  0x0115   WhiteBalance                         int32u
    35356412  0x0e00   PrintIM                              PrintIM
    35366413  0x0f00   MinoltaCameraSettings2               N
     
    35426419information may not be as reliable as it should be.  Because of this, tags
    35436420in the following tables are set to lower priority to prevent them from
    3544 superceeding the values of same-named tags in other locations when duplicate
     6421superceding the values of same-named tags in other locations when duplicate
    35456422tags are disabled.
    35466423
     
    36096486     16    AFPoints                             int16u
    36106487     21    Flash                                int16u
     6488     22    FlashMode                            int16u
    36116489     28    ISOSetting                           int16u
    36126490     30    ExposureCompensation                 int16s
     
    36176495     45    FreeMemoryCardImages                 int16u
    36186496     63    ColorTemperature                     int16s
     6497     64    HueAdjustment                        int16u
    36196498     70    Rotation                             int16u
    36206499     71    FNumber                              int16u
     
    36276506    117    ZoneMatchingOn                       int16u
    36286507
     6508=head3 Minolta WBInfoA100 Tags
     6509
     6510White balance information for the Sony DSLR-A100.
     6511
     6512   Index   Tag Name                             Writable
     6513   -----   --------                             --------
     6514    150    WB_RGBLevels                         int16u[3]
     6515    174    WB_GBRGLevels                        int16u[4]
     6516    772    WB_RBPresetFlash                     int16u[2]
     6517    776    WB_RBPresetCoolWhiteF                int16u[2]
     6518   1000    WB_RBPresetTungsten                  int16u[2]
     6519   1004    WB_RBPresetDaylight                  int16u[2]
     6520   1008    WB_RBPresetCloudy                    int16u[2]
     6521   1012    WB_RBPresetFlash                     int16u[2]
     6522   1020    WB_RedPresetsFluorescent             int16u[7]
     6523   1034    WB_BluePresetsFluorescent            int16u[7]
     6524   1048    WB_RBPresetShade                     int16u[2]
     6525   1060    WB_RBPresetCustom                    int16u[2]
     6526  18908    InternalSerialNumber                 string[12]
     6527
    36296528=head3 Minolta CameraSettings5D Tags
    36306529
     
    36366535     14    WhiteBalance                         int16u
    36376536     31    Flash                                int16u
     6537     32    FlashMode                            int16u
    36386538     37    MeteringMode                         int16u
    36396539     38    ISOSetting                           int16u
     6540     47    ColorSpace                           int16u
    36406541     48    Sharpness                            int16u
    36416542     49    Contrast                             int16u
     
    36456546     55    FreeMemoryCardImages                 int16u
    36466547     73    ColorTemperature                     int16s
     6548     74    HueAdjustment                        int16u
    36476549     80    Rotation                             int16u
    36486550     83    ExposureCompensation                 int16u
    36496551     84    FreeMemoryCardImages                 int16u
     6552    101    Rotation                             int16u
    36506553    110    ColorTemperature                     int16s
     6554    113    PictureFinish                        int16u
    36516555    174    ImageNumber                          int16u
    36526556    176    NoiseReduction                       int16u
     
    36606564   -----   --------                             --------
    36616565      0    ExposureMode                         int16u
    3662       1    ExposureCompensation                 int16u
     6566      1    ExposureCompensationSetting          int16u
     6567      5    HighSpeedSync                        int16u
     6568      6    ManualExposureTime                   int16u
     6569      7    ManualFNumber                        int16u
     6570      8    ExposureTime                         int16u
     6571      9    FNumber                              int16u
     6572     10    DriveMode2                           int16u
    36636573     11    WhiteBalance                         int16u
     6574     12    FocusMode                            int16u
     6575     13    LocalAFAreaPoint                     int16u
     6576     14    AFAreaMode                           int16u
     6577     15    FlashMode                            int16u
     6578     16    FlashExposureCompSetting             int16u
     6579     18    MeteringMode                         int16u
     6580     19    ISOSetting                           int16u
     6581     20    ZoneMatchingMode                     int16u
     6582     21    DynamicRangeOptimizer                int16u
    36646583     22    ColorMode                            int16u
     6584     23    ColorSpace                           int16u
    36656585     24    Sharpness                            int16u
    36666586     25    Contrast                             int16u
    36676587     26    Saturation                           int16u
     6588     28    FlashMetering                        int16u
     6589     29    PrioritySetupShutterRelease          int16u
    36686590     30    DriveMode                            int16u
     6591     31    SelfTimerTime                        int16u
     6592     32    ContinuousBracketing                 int16u
     6593     33    SingleFrameBracketing                int16u
     6594     34    WhiteBalanceBracketing               int16u
     6595     35    WhiteBalanceSetting                  int16u
     6596     36    PresetWhiteBalance                   int16u
     6597     37    ColorTemperatureSetting              int16u
     6598     38    CustomWBSetting                      int16u
     6599     39    DynamicRangeOptimizerSetting         int16u
     6600     50    FreeMemoryCardImages                 int16u
     6601     52    CustomWBRedLevel                     int16u
     6602     53    CustomWBGreenLevel                   int16u
     6603     54    CustomWBBlueLevel                    int16u
     6604     55    CustomWBError                        int16u
     6605     56    WhiteBalanceFineTune                 int16s
     6606     57    ColorTemperature                     int16u
     6607     58    ColorCompensationFilter              int16s
     6608     59    SonyImageSize                        int16u
     6609     60    SonyQuality                          int16u
     6610     61    InstantPlaybackTime                  int16u
     6611     62    InstantPlaybackSetup                 int16u
    36696612     63    NoiseReduction                       int16u
     6613     64    EyeStartAF                           int16u
     6614     65    RedEyeReduction                      int16u
     6615     66    FlashDefault                         int16u
     6616     67    AutoBracketOrder                     int16u
     6617     68    FocusHoldButton                      int16u
     6618     69    AELButton                            int16u
     6619     70    ControlDialSet                       int16u
     6620     71    ExposureCompensationMode             int16u
     6621     72    AFAssist                             int16u
     6622     73    CardShutterLock                      int16u
     6623     74    LensShutterLock                      int16u
     6624     75    AFAreaIllumination                   int16u
     6625     76    MonitorDisplayOff                    int16u
     6626     77    RecordDisplay                        int16u
     6627     78    PlayDisplay                          int16u
     6628     80    ExposureIndicator                    int16u
     6629     81    AELExposureIndicator                 int16u
     6630     82    ExposureBracketingIndicatorLast      int16u
     6631     83    MeteringOffScaleIndicator            int16u
     6632     84    FlashExposureIndicator               int16u
     6633     85    FlashExposureIndicatorNext           int16u
     6634     86    FlashExposureIndicatorLast           int16u
     6635     87    ImageStabilization                   int16u
     6636     88    FocusModeSwitch                      int16u
     6637     89    FlashType                            int16u
    36706638     90    Rotation                             int16u
     6639     91    AELock                               int16u
    36716640     94    ColorTemperature                     int16u
    3672     135    ImageStabilization                   int32u[0.5]
     6641     95    ColorCompensationFilter              int16s
     6642     96    BatteryLevel                         int16u
     6643
     6644=head3 Minolta MMA Tags
     6645
     6646This information is found in MOV videos from Minolta models such as the
     6647DiMAGE A2, S414 and 7Hi.
     6648
     6649   Index   Tag Name                             Writable
     6650   -----   --------                             --------
     6651      0    Make                                 N
     6652     20    SoftwareVersion                      N
     6653
     6654=head3 Minolta MOV1 Tags
     6655
     6656This information is found in MOV videos from some Konica Minolta models such
     6657as the DiMage Z10 and X50.
     6658
     6659   Index   Tag Name                             Writable
     6660   -----   --------                             --------
     6661      0    Make                                 N
     6662     32    ModelType                            N
     6663     46    ExposureTime                         N
     6664     50    FNumber                              N
     6665     58    ExposureCompensation                 N
     6666     80    FocalLength                          N
     6667
     6668=head3 Minolta MOV2 Tags
     6669
     6670This information is found in MOV videos from some Minolta models such as the
     6671DiMAGE X and Xt.
     6672
     6673   Index   Tag Name                             Writable
     6674   -----   --------                             --------
     6675      0    Make                                 N
     6676     24    ModelType                            N
     6677     38    ExposureTime                         N
     6678     42    FNumber                              N
     6679     50    ExposureCompensation                 N
     6680     72    FocalLength                          N
    36736681
    36746682=head2 Nikon Tags
     
    36846692  0x0007   FocusMode                            string
    36856693  0x0008   FlashSetting                         string
    3686   0x0009   FlashType                            string[13]
    3687   0x000b   WhiteBalanceFineTune                 int16s
    3688   0x000c   ColorBalance1                        rational64u[4]
     6694  0x0009   FlashType                            string
     6695  0x000b   WhiteBalanceFineTune                 int16s[n]
     6696  0x000c   WB_RBLevels                          rational64u[4]
    36896697  0x000d   ProgramShift                         undef[4]
    36906698  0x000e   ExposureDifference                   undef[4]
    36916699  0x000f   ISOSelection                         string
    36926700  0x0010   DataDump                             N
    3693   0x0011   NikonPreview                         Nikon PreviewImage
     6701  0x0011   PreviewIFD                           Nikon PreviewIFD
    36946702  0x0012   FlashExposureComp                    undef[4]
    36956703  0x0013   ISOSetting                           int16u[2]
     6704  0x0014   ColorBalanceA                        Nikon ColorBalanceA
     6705           NRWData?                             Y
    36966706  0x0016   ImageBoundary                        int16u[4]
     6707  0x0017   ExternalFlashExposureComp            undef[4]
    36976708  0x0018   FlashExposureBracketValue            undef[4]
    36986709  0x0019   ExposureBracketValue                 rational64s
    36996710  0x001a   ImageProcessing                      string
    37006711  0x001b   CropHiSpeed                          int16u[7]~
    3701   0x001d   SerialNumber                         N
     6712  0x001c   ExposureTuning                       undef[3]
     6713  0x001d   SerialNumber                         string!
    37026714  0x001e   ColorSpace                           int16u
     6715  0x001f   VRInfo                               Nikon VRInfo
    37036716  0x0020   ImageAuthentication                  int8u
     6717  0x0021   FaceDetect                           Nikon FaceDetect
     6718  0x0022   ActiveD-Lighting                     int16u
     6719  0x0023   PictureControlData                   Nikon PictureControl
     6720  0x0024   WorldTime                            Nikon WorldTime
     6721  0x0025   ISOInfo                              Nikon ISOInfo
     6722  0x002a   VignetteControl                      int16u
     6723  0x002b   DistortInfo                          Nikon DistortInfo
     6724  0x002c   UnknownInfo                          Nikon UnknownInfo
     6725  0x0032   UnknownInfo2                         Nikon UnknownInfo2
    37046726  0x0080   ImageAdjustment                      string
    37056727  0x0081   ToneComp                             string
     
    37116733  0x0087   FlashMode                            int8u
    37126734  0x0088   AFInfo                               Nikon AFInfo
     6735                                                Nikon AFInfo
    37136736  0x0089   ShootingMode                         int16u~
    3714   0x008a   AutoBracketRelease                   int16u
    37156737  0x008b   LensFStops                           undef[4]
    3716   0x008c   NEFCurve1                            N
     6738  0x008c   ContrastCurve                        N
    37176739  0x008d   ColorHue                             string
    37186740  0x008f   SceneMode                            string
    37196741  0x0090   LightSource                          string
    3720   0x0091   ShotInfo                             Nikon ShotInfo
    3721            ShotInfo?                            Nikon ShotInfo
     6742  0x0091   ShotInfoD40                          Nikon ShotInfoD40
     6743           ShotInfoD80                          Nikon ShotInfoD80
     6744           ShotInfoD90                          Nikon ShotInfoD90
     6745           ShotInfoD3a                          Nikon ShotInfoD3a
     6746           ShotInfoD3b                          Nikon ShotInfoD3b
     6747           ShotInfoD3X                          Nikon ShotInfoD3X
     6748           ShotInfoD3S                          Nikon ShotInfoD3S
     6749           ShotInfoD300a                        Nikon ShotInfoD300a
     6750           ShotInfoD300b                        Nikon ShotInfoD300b
     6751           ShotInfoD300S                        Nikon ShotInfoD300S
     6752           ShotInfoD700                         Nikon ShotInfoD700
     6753           ShotInfoD5000                        Nikon ShotInfoD5000
     6754           ShotInfoD7000                        Nikon ShotInfoD7000
     6755           ShotInfo02xx                         Nikon ShotInfo
     6756           ShotInfoUnknown                      Nikon ShotInfo
    37226757  0x0092   HueAdjustment                        int16s
     6758  0x0093   NEFCompression                       int16u
    37236759  0x0094   Saturation                           int16s
    37246760  0x0095   NoiseReduction                       string
    3725   0x0096   NEFCurve2                            N
     6761  0x0096   LinearizationTable                   N
    37266762  0x0097   ColorBalance0100                     Nikon ColorBalance1
    37276763           ColorBalance0102                     Nikon ColorBalance2
    37286764           ColorBalance0103                     Nikon ColorBalance3
    37296765           ColorBalance0205                     Nikon ColorBalance2
     6766           ColorBalance0209                     Nikon ColorBalance4
    37306767           ColorBalance02                       Nikon ColorBalance2
    37316768           ColorBalanceUnknown                  N
     
    37336770           LensData0101                         Nikon LensData01
    37346771           LensData0201                         Nikon LensData01
    3735            LensDataUnknown                      N
     6772           LensData0204                         Nikon LensData0204
     6773           LensDataUnknown                      Nikon LensDataUnknown
    37366774  0x0099   RawImageCenter                       int16u[2]
    37376775  0x009a   SensorPixelSize                      rational64u[2]
     6776  0x009c   SceneAssist                          string
     6777  0x009e   RetouchHistory                       int16u[10]
    37386778  0x00a0   SerialNumber                         string
    37396779  0x00a2   ImageDataSize                        int32u
    37406780  0x00a5   ImageCount                           int32u
    37416781  0x00a6   DeletedImageCount                    int32u
    3742   0x00a7   ShutterCount                         N
    3743   0x00a9   ImageOptimization                    string[16]
     6782  0x00a7   ShutterCount                         int32u!
     6783  0x00a8   FlashInfo0100                        Nikon FlashInfo0100
     6784           FlashInfo0102                        Nikon FlashInfo0102
     6785           FlashInfo0103                        Nikon FlashInfo0103
     6786           FlashInfo0104                        Nikon FlashInfo0103
     6787           FlashInfoUnknown                     Nikon FlashInfoUnknown
     6788  0x00a9   ImageOptimization                    string
    37446789  0x00aa   Saturation                           string
    37456790  0x00ab   VariProgram                          string
     
    37486793  0x00b0   MultiExposure                        Nikon MultiExposure
    37496794  0x00b1   HighISONoiseReduction                int16u
     6795  0x00b3   ToningEffect                         string
     6796  0x00b6   PowerUpTime                          undef
     6797  0x00b7   AFInfo2                              Nikon AFInfo2
     6798  0x00b8   FileInfo                             Nikon FileInfo
     6799  0x00b9   AFTune                               Nikon AFTune
     6800  0x00bd   PictureControlData                   Nikon PictureControl
    37506801  0x0e00   PrintIM                              PrintIM
    37516802  0x0e01   NikonCaptureData                     NikonCapture
     
    37536804  0x0e0e   NikonCaptureOffsets                  Nikon CaptureOffsets
    37546805  0x0e10   NikonScanIFD                         Nikon Scan
    3755 
    3756 =head3 Nikon PreviewImage Tags
     6806  0x0e13   NikonCaptureEditVersions             NikonCapture
     6807           NikonCaptureEditVersions             undef
     6808  0x0e1d   NikonICCProfile                      ICC_Profile
     6809  0x0e1e   NikonCaptureOutput                   Nikon CaptureOutput
     6810  0x0e22   NEFBitDepth                          int16u[4]!
     6811
     6812=head3 Nikon PreviewIFD Tags
    37576813
    37586814  Tag ID   Tag Name                             Writable
    37596815  ------   --------                             --------
     6816  0x00fe   SubfileType                          N
    37606817  0x0103   Compression                          N
    37616818  0x011a   XResolution                          N
     
    37666823  0x0213   YCbCrPositioning                     N
    37676824
     6825=head3 Nikon ColorBalanceA Tags
     6826
     6827   Index   Tag Name                             Writable
     6828   -----   --------                             --------
     6829    624    RedBalance                           int16u!
     6830    625    BlueBalance                          int16u!
     6831
     6832=head3 Nikon VRInfo Tags
     6833
     6834   Index   Tag Name                             Writable
     6835   -----   --------                             --------
     6836      0    VRInfoVersion                        N
     6837      4    VibrationReduction                   int8u
     6838
     6839=head3 Nikon FaceDetect Tags
     6840
     6841   Index   Tag Name                             Writable
     6842   -----   --------                             --------
     6843      1    FaceDetectFrameSize                  int16u[2]
     6844      3    FacesDetected                        int16u
     6845      4    Face1Position                        int16u[4]
     6846      8    Face2Position                        int16u[4]
     6847     12    Face3Position                        int16u[4]
     6848     16    Face4Position                        int16u[4]
     6849     20    Face5Position                        int16u[4]
     6850     24    Face6Position                        int16u[4]
     6851     28    Face7Position                        int16u[4]
     6852     32    Face8Position                        int16u[4]
     6853     36    Face9Position                        int16u[4]
     6854     40    Face10Position                       int16u[4]
     6855     44    Face11Position                       int16u[4]
     6856     48    Face12Position                       int16u[4]
     6857
     6858=head3 Nikon PictureControl Tags
     6859
     6860   Index   Tag Name                             Writable
     6861   -----   --------                             --------
     6862      0    PictureControlVersion                N
     6863      4    PictureControlName                   string[20]
     6864     24    PictureControlBase                   string[20]
     6865     48    PictureControlAdjust                 int8u
     6866     49    PictureControlQuickAdjust            int8u
     6867     50    Sharpness                            int8u
     6868     51    Contrast                             int8u
     6869     52    Brightness                           int8u
     6870     53    Saturation                           int8u
     6871     54    HueAdjustment                        int8u
     6872     55    FilterEffect                         int8u
     6873     56    ToningEffect                         int8u
     6874     57    ToningSaturation                     int8u
     6875
     6876=head3 Nikon WorldTime Tags
     6877
     6878   Index   Tag Name                             Writable
     6879   -----   --------                             --------
     6880      0    Timezone                             int16s
     6881      2    DaylightSavings                      int8u
     6882      3    DateDisplayFormat                    int8u
     6883
     6884=head3 Nikon ISOInfo Tags
     6885
     6886   Index   Tag Name                             Writable
     6887   -----   --------                             --------
     6888      0    ISO                                  int8u
     6889      4    ISOExpansion                         int16u
     6890      6    ISO2                                 int8u
     6891     10    ISOExpansion2                        int16u
     6892
     6893=head3 Nikon DistortInfo Tags
     6894
     6895   Index   Tag Name                             Writable
     6896   -----   --------                             --------
     6897      0    DistortionVersion?                   N
     6898      4    AutoDistortionControl                int8u
     6899
     6900=head3 Nikon UnknownInfo Tags
     6901
     6902   Index   Tag Name                             Writable
     6903   -----   --------                             --------
     6904      0    UnknownInfoVersion?                  N
     6905
     6906=head3 Nikon UnknownInfo2 Tags
     6907
     6908   Index   Tag Name                             Writable
     6909   -----   --------                             --------
     6910      0    UnknownInfo2Version?                 N
     6911
    37686912=head3 Nikon AFInfo Tags
    37696913
     
    37746918      2    AFPointsInFocus                      int16u
    37756919
     6920=head3 Nikon ShotInfoD40 Tags
     6921
     6922These tags are extracted from encrypted data in D40 and D40X images.
     6923
     6924   Index   Tag Name                             Writable
     6925   -----   --------                             --------
     6926      0    ShotInfoVersion                      N
     6927    582    ShutterCount                         int32u
     6928  586.1    VibrationReduction                   int8u & 0x08
     6929    729    CustomSettingsD40                    NikonCustom SettingsD40
     6930
     6931=head3 Nikon ShotInfoD80 Tags
     6932
     6933These tags are extracted from encrypted data in D80 images.
     6934
     6935   Index   Tag Name                             Writable
     6936   -----   --------                             --------
     6937      0    ShotInfoVersion                      N
     6938    586    ShutterCount                         int32u
     6939  590.1    Rotation                             int8u & 0x07
     6940  590.2    VibrationReduction                   int8u & 0x18
     6941  590.3    FlashFired                           int8u & 0xe0
     6942    708    NikonImageSize                       int8u & 0xf0
     6943  708.1    ImageQuality                         int8u & 0x0f
     6944    748    CustomSettingsD80                    NikonCustom SettingsD80
     6945
     6946=head3 Nikon ShotInfoD90 Tags
     6947
     6948These tags are extracted from encrypted data in images from the D90 with
     6949firmware 1.00.
     6950
     6951   Index   Tag Name                             Writable
     6952   -----   --------                             --------
     6953      0    ShotInfoVersion                      N
     6954      4    FirmwareVersion                      N
     6955    693    ISO2                                 int8u
     6956    725    ShutterCount                         int32u
     6957    884    CustomSettingsD90                    NikonCustom SettingsD90
     6958
     6959=head3 Nikon ShotInfoD3a Tags
     6960
     6961These tags are extracted from encrypted data in images from the D3 with
     6962firmware 1.00 and earlier.
     6963
     6964   Index   Tag Name                             Writable
     6965   -----   --------                             --------
     6966      0    ShotInfoVersion                      N
     6967    598    ISO2                                 int8u
     6968    630    ShutterCount                         int32u
     6969  723.1    NikonImageSize                       int8u & 0x18
     6970  723.2    ImageQuality                         int8u & 0x07
     6971    769    CustomSettingsD3                     NikonCustom SettingsD3
     6972
     6973=head3 Nikon ShotInfoD3b Tags
     6974
     6975These tags are extracted from encrypted data in images from the D3 with
     6976firmware 1.10, 2.00, 2.01 and 2.02.
     6977
     6978   Index   Tag Name                             Writable
     6979   -----   --------                             --------
     6980      0    ShotInfoVersion                      N
     6981      4    FirmwareVersion                      N
     6982     16    ImageArea                            int8u
     6983    605    ISO2                                 int8u
     6984    637    ShutterCount                         int32u
     6985    639    ShutterCount                         int32u
     6986    650    PreFlashReturnStrength               int8u
     6987  732.1    NikonImageSize                       int8u & 0x18
     6988  732.2    ImageQuality                         int8u & 0x07
     6989    778    CustomSettingsD3                     NikonCustom SettingsD3
     6990
     6991=head3 Nikon ShotInfoD3X Tags
     6992
     6993These tags are extracted from encrypted data in images from the D3X with
     6994firmware 1.00.
     6995
     6996   Index   Tag Name                             Writable
     6997   -----   --------                             --------
     6998      0    ShotInfoVersion                      N
     6999      4    FirmwareVersion                      N
     7000    605    ISO2                                 int8u
     7001    640    ShutterCount                         int32u
     7002    779    CustomSettingsD3X                    NikonCustom SettingsD3
     7003
     7004=head3 Nikon ShotInfoD3S Tags
     7005
     7006These tags are extracted from encrypted data in images from the D3S with
     7007firmware 1.00 and earlier.
     7008
     7009   Index   Tag Name                             Writable
     7010   -----   --------                             --------
     7011      0    ShotInfoVersion                      N
     7012      4    FirmwareVersion                      N
     7013     16    ImageArea                            int8u
     7014    545    ISO2                                 int8u
     7015    578    ShutterCount                         int32u
     7016    718    CustomSettingsD3S                    NikonCustom SettingsD3
     7017
     7018=head3 Nikon ShotInfoD300a Tags
     7019
     7020These tags are extracted from encrypted data in images from the D300 with
     7021firmware 1.00 and earlier.
     7022
     7023   Index   Tag Name                             Writable
     7024   -----   --------                             --------
     7025      0    ShotInfoVersion                      N
     7026    604    ISO2                                 int8u
     7027    633    ShutterCount                         int32u
     7028    721    AFFineTuneAdj                        int16u
     7029    790    CustomSettingsD300                   NikonCustom SettingsD3
     7030
     7031=head3 Nikon ShotInfoD300b Tags
     7032
     7033These tags are extracted from encrypted data in images from the D300 with
     7034firmware 1.10.
     7035
     7036   Index   Tag Name                             Writable
     7037   -----   --------                             --------
     7038      0    ShotInfoVersion                      N
     7039      4    FirmwareVersion                      N
     7040    613    ISO2                                 int8u
     7041    644    ShutterCount                         int32u
     7042    732    AFFineTuneAdj                        int16u
     7043    802    CustomSettingsD300                   NikonCustom SettingsD3
     7044
     7045=head3 Nikon ShotInfoD300S Tags
     7046
     7047These tags are extracted from encrypted data in images from the D300S with
     7048firmware 1.00.
     7049
     7050   Index   Tag Name                             Writable
     7051   -----   --------                             --------
     7052      0    ShotInfoVersion                      N
     7053      4    FirmwareVersion                      N
     7054    613    ISO2                                 int8u
     7055    646    ShutterCount                         int32u
     7056    804    CustomSettingsD300S                  NikonCustom SettingsD3
     7057
     7058=head3 Nikon ShotInfoD700 Tags
     7059
     7060These tags are extracted from encrypted data in images from the D700 with
     7061firmware 1.02f.
     7062
     7063   Index   Tag Name                             Writable
     7064   -----   --------                             --------
     7065      0    ShotInfoVersion                      N
     7066      4    FirmwareVersion                      N
     7067    613    ISO2                                 int8u
     7068    647    ShutterCount                         int32u
     7069    804    CustomSettingsD700                   NikonCustom SettingsD700
     7070
     7071=head3 Nikon ShotInfoD5000 Tags
     7072
     7073These tags are extracted from encrypted data in images from the D5000 with
     7074firmware 1.00.
     7075
     7076   Index   Tag Name                             Writable
     7077   -----   --------                             --------
     7078      0    ShotInfoVersion                      N
     7079      4    FirmwareVersion                      N
     7080    693    ISO2                                 int8u
     7081    726    ShutterCount                         int32u
     7082    888    CustomSettingsD5000                  NikonCustom SettingsD5000
     7083
     7084=head3 Nikon ShotInfoD7000 Tags
     7085
     7086These tags are extracted from encrypted data in images from the D7000 with
     7087firmware 1.01b.
     7088
     7089   Index   Tag Name                             Writable
     7090   -----   --------                             --------
     7091      0    ShotInfoVersion                      N
     7092      4    FirmwareVersion                      N
     7093    800    ShutterCount                         int32u
     7094   1028    CustomSettingsD7000                  NikonCustom SettingsD7000
     7095
    37767096=head3 Nikon ShotInfo Tags
    37777097
    37787098This information is encrypted for ShotInfoVersion 02xx, and some tags are
    3779 only valid for specific versions.
     7099only valid for specific models.
    37807100
    37817101   Index   Tag Name                             Writable
    37827102   -----   --------                             --------
    37837103      0    ShotInfoVersion                      N
    3784     102    VR_0x66?                             N
    3785     106    ShutterCount                         N
    3786     110    DeletedImageCount                    N
    3787     117    VibrationReduction                   N
    3788     130    VibrationReduction                   N
    3789     343    ShutterCount                         N
    3790     430    VibrationReduction                   N
    3791     586    ShutterCount                         N
    3792     590    VibrationReduction                   N
     7104      4    FirmwareVersion                      N
     7105     16    DistortionControl                    int8u
     7106    102    VR_0x66?                             int8u
     7107    106    ShutterCount                         int32u
     7108    110    DeletedImageCount                    int32u
     7109    117    VibrationReduction                   int8u
     7110    130    VibrationReduction                   int8u
     7111    343    ShutterCount                         undef[2]
     7112    430    VibrationReduction                   int8u
     7113    589    ShutterCount                         int32u
    37937114
    37947115=head3 Nikon ColorBalance1 Tags
     
    38007121=head3 Nikon ColorBalance2 Tags
    38017122
    3802 This information is encrypted for most camera models, and if encrypted is
    3803 not currently writable by exiftool.
     7123This information is encrypted for most camera models.
    38047124
    38057125   Index   Tag Name                             Writable
     
    38137133      0    WB_RGBGLevels                        int16u[4]!
    38147134
     7135=head3 Nikon ColorBalance4 Tags
     7136
     7137   Index   Tag Name                             Writable
     7138   -----   --------                             --------
     7139      0    WB_GRBGLevels                        int16u[4]!
     7140
    38157141=head3 Nikon LensData00 Tags
    38167142
     
    38197145   Index   Tag Name                             Writable
    38207146   -----   --------                             --------
    3821       0    LensDataVersion                      undef[4]
     7147      0    LensDataVersion                      N
    38227148      6    LensIDNumber                         int8u
    38237149      7    LensFStops                           int8u
     
    38327158Nikon encrypts the LensData information below if LensDataVersion is 0201 or
    38337159higher, but  the decryption algorithm is known so the information can be
    3834 extracted.  It isn't yet writable, however, because the encryption adds
    3835 complications which make writing more difficult.
     7160extracted.
    38367161
    38377162   Index   Tag Name                             Writable
    38387163   -----   --------                             --------
    38397164      0    LensDataVersion                      N
    3840       4    ExitPupilPosition                    N
    3841       5    AFAperture                           N
    3842       8    FocusPosition                        N
    3843       9    FocusDistance                        N
    3844      10    FocalLength                          N
    3845      11    LensIDNumber                         N
    3846      12    LensFStops                           N
    3847      13    MinFocalLength                       N
    3848      14    MaxFocalLength                       N
    3849      15    MaxApertureAtMinFocal                N
    3850      16    MaxApertureAtMaxFocal                N
    3851      17    MCUVersion                           N
    3852      18    EffectiveMaxAperture                 N
     7165      4    ExitPupilPosition                    int8u
     7166      5    AFAperture                           int8u
     7167      8    FocusPosition                        int8u
     7168      9    FocusDistance                        int8u
     7169     10    FocalLength                          int8u
     7170     11    LensIDNumber                         int8u
     7171     12    LensFStops                           int8u
     7172     13    MinFocalLength                       int8u
     7173     14    MaxFocalLength                       int8u
     7174     15    MaxApertureAtMinFocal                int8u
     7175     16    MaxApertureAtMaxFocal                int8u
     7176     17    MCUVersion                           int8u
     7177     18    EffectiveMaxAperture                 int8u
     7178
     7179=head3 Nikon LensData0204 Tags
     7180
     7181Nikon encrypts the LensData information below if LensDataVersion is 0201 or
     7182higher, but  the decryption algorithm is known so the information can be
     7183extracted.
     7184
     7185   Index   Tag Name                             Writable
     7186   -----   --------                             --------
     7187      0    LensDataVersion                      N
     7188      4    ExitPupilPosition                    int8u
     7189      5    AFAperture                           int8u
     7190      8    FocusPosition                        int8u
     7191     10    FocusDistance                        int8u
     7192     11    FocalLength                          int8u
     7193     12    LensIDNumber                         int8u
     7194     13    LensFStops                           int8u
     7195     14    MinFocalLength                       int8u
     7196     15    MaxFocalLength                       int8u
     7197     16    MaxApertureAtMinFocal                int8u
     7198     17    MaxApertureAtMaxFocal                int8u
     7199     18    MCUVersion                           int8u
     7200     19    EffectiveMaxAperture                 int8u
     7201
     7202=head3 Nikon LensDataUnknown Tags
     7203
     7204   Index   Tag Name                             Writable
     7205   -----   --------                             --------
     7206      0    LensDataVersion                      N
     7207
     7208=head3 Nikon FlashInfo0100 Tags
     7209
     7210These tags are used by the D2H, D2Hs, D2X, D2Xs, D50, D70, D70s, D80 and
     7211D200.
     7212
     7213   Index   Tag Name                             Writable
     7214   -----   --------                             --------
     7215      0    FlashInfoVersion                     N
     7216      4    FlashSource                          int8u
     7217      6    ExternalFlashFirmware                int8u[2]
     7218      8    ExternalFlashFlags                   int8u
     7219    9.1    FlashCommanderMode                   int8u & 0x80
     7220    9.2    FlashControlMode                     int8u & 0x7f
     7221     10    FlashOutput                          int8u
     7222           FlashCompensation                    int8s
     7223     11    FlashFocalLength                     int8u
     7224     12    RepeatingFlashRate                   int8u
     7225     13    RepeatingFlashCount                  int8u
     7226     14    FlashGNDistance                      int8u
     7227     15    FlashGroupAControlMode               int8u & 0x0f
     7228     16    FlashGroupBControlMode               int8u & 0x0f
     7229     17    FlashGroupAOutput                    int8u
     7230           FlashGroupACompensation              int8s
     7231     18    FlashGroupBOutput                    int8u
     7232           FlashGroupBCompensation              int8s
     7233
     7234=head3 Nikon FlashInfo0102 Tags
     7235
     7236These tags are used by the D3 (firmware 1.x), D40, D40X, D60 and D300
     7237(firmware 1.00).
     7238
     7239   Index   Tag Name                             Writable
     7240   -----   --------                             --------
     7241      0    FlashInfoVersion                     N
     7242      4    FlashSource                          int8u
     7243      6    ExternalFlashFirmware                int8u[2]
     7244      8    ExternalFlashFlags                   int8u
     7245    9.1    FlashCommanderMode                   int8u & 0x80
     7246    9.2    FlashControlMode                     int8u & 0x7f
     7247     10    FlashOutput                          int8u
     7248           FlashCompensation                    int8s
     7249     12    FlashFocalLength                     int8u
     7250     13    RepeatingFlashRate                   int8u
     7251     14    RepeatingFlashCount                  int8u
     7252     15    FlashGNDistance                      int8u
     7253   16.1    FlashGroupAControlMode               int8u & 0x0f
     7254   17.1    FlashGroupBControlMode               int8u & 0xf0
     7255   17.2    FlashGroupCControlMode               int8u & 0x0f
     7256     18    FlashGroupAOutput                    int8u
     7257           FlashGroupACompensation              int8s
     7258     19    FlashGroupBOutput                    int8u
     7259           FlashGroupBCompensation              int8s
     7260     20    FlashGroupCOutput                    int8u
     7261           FlashGroupCCompensation              int8s
     7262
     7263=head3 Nikon FlashInfo0103 Tags
     7264
     7265These tags are used by the D3 (firmware 2.x), D3X, D3S, D90, D300 (firmware
     72661.10), D300S, D700, D3000 and D5000.
     7267
     7268   Index   Tag Name                             Writable
     7269   -----   --------                             --------
     7270      0    FlashInfoVersion                     N
     7271      4    FlashSource                          int8u
     7272      6    ExternalFlashFirmware                int8u[2]
     7273      8    ExternalFlashFlags                   int8u
     7274    9.1    FlashCommanderMode                   int8u & 0x80
     7275    9.2    FlashControlMode                     int8u & 0x7f
     7276     10    FlashOutput                          int8u
     7277           FlashCompensation                    int8s
     7278     12    FlashFocalLength                     int8u
     7279     13    RepeatingFlashRate                   int8u
     7280     14    RepeatingFlashCount                  int8u
     7281     15    FlashGNDistance                      int8u
     7282     16    FlashColorFilter                     int8u
     7283   17.1    FlashGroupAControlMode               int8u & 0x0f
     7284   18.1    FlashGroupBControlMode               int8u & 0xf0
     7285   18.2    FlashGroupCControlMode               int8u & 0x0f
     7286     19    FlashGroupAOutput                    int8u
     7287           FlashGroupACompensation              int8s
     7288     20    FlashGroupBOutput                    int8u
     7289           FlashGroupBCompensation              int8s
     7290     21    FlashGroupCOutput                    int8u
     7291           FlashGroupCCompensation              int8s
     7292
     7293=head3 Nikon FlashInfoUnknown Tags
     7294
     7295   Index   Tag Name                             Writable
     7296   -----   --------                             --------
     7297      0    FlashInfoVersion                     N
    38537298
    38547299=head3 Nikon MultiExposure Tags
     
    38567301   Index   Tag Name                             Writable
    38577302   -----   --------                             --------
    3858       0    MultiExposureVersion                 string[4]
     7303      0    MultiExposureVersion                 N
    38597304      1    MultiExposureMode                    int32u
    38607305      2    MultiExposureShots                   int32u
    38617306      3    MultiExposureAutoGain                int32u
     7307
     7308=head3 Nikon AFInfo2 Tags
     7309
     7310These tags are written by Nikon DSLR's which have the live view feature.
     7311
     7312   Index   Tag Name                             Writable
     7313   -----   --------                             --------
     7314      0    AFInfo2Version                       N
     7315      4    ContrastDetectAF                     int8u
     7316      5    AFAreaMode                           int8u
     7317      6    PhaseDetectAF                        int8u
     7318      7    PrimaryAFPoint                       int8u
     7319      8    AFPointsUsed                         undef[7]~
     7320           AFPointsUsed                         undef[2]
     7321           AFPointsUsed                         undef[7]~
     7322     16    AFImageWidth                         int16u
     7323     18    AFImageHeight                        int16u
     7324     20    AFAreaXPosition                      int16u
     7325     22    AFAreaYPosition                      int16u
     7326     24    AFAreaWidth                          int16u
     7327     26    AFAreaHeight                         int16u
     7328     28    ContrastDetectAFInFocus              int8u
     7329
     7330=head3 Nikon FileInfo Tags
     7331
     7332   Index   Tag Name                             Writable
     7333   -----   --------                             --------
     7334      0    FileInfoVersion                      N
     7335      6    DirectoryNumber                      int16u
     7336      8    FileNumber                           int16u
     7337
     7338=head3 Nikon AFTune Tags
     7339
     7340   Index   Tag Name                             Writable
     7341   -----   --------                             --------
     7342      0    AFFineTune                           int8u
     7343      1    AFFineTuneIndex                      int8u
     7344      2    AFFineTuneAdj                        int8s
    38627345
    38637346=head3 Nikon CaptureOffsets Tags
     
    38807363  0x0050   MasterGain                           rational64s
    38817364  0x0051   ColorGain                            rational64s[3]
     7365  0x0060   ScanImageEnhancer                    int32u
    38827366  0x0100   DigitalICE                           string
    38837367  0x0110   ROCInfo                              Nikon ROC
    38847368  0x0120   GEMInfo                              Nikon GEM
     7369  0x0200   DigitalDEEShadowAdj                  int32u
     7370  0x0201   DigitalDEEThreshold                  int32u
     7371  0x0202   DigitalDEEHighlightAdj               int32u
    38857372
    38867373=head3 Nikon ROC Tags
     
    38957382   -----   --------                             --------
    38967383      0    DigitalGEM                           int32u
     7384
     7385=head3 Nikon CaptureOutput Tags
     7386
     7387   Index   Tag Name                             Writable
     7388   -----   --------                             --------
     7389      2    OutputImageWidth                     int32u
     7390      3    OutputImageHeight                    int32u
     7391      4    OutputResolution                     int32u
    38977392
    38987393=head3 Nikon Type2 Tags
     
    39097404  0x000b   Converter                            Y
    39107405
     7406=head3 Nikon NCDT Tags
     7407
     7408Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some
     7409Nikon cameras such as the Coolpix S8000.
     7410
     7411  Tag ID   Tag Name                             Writable
     7412  ------   --------                             --------
     7413  'NCHD'   MakerNoteVersion                     N
     7414  'NCTG'   NikonTags                            Nikon NCTG
     7415  'NCTH'   ThumbnailImage                       N
     7416  'NCVW'   PreviewImage                         N
     7417
     7418=head3 Nikon NCTG Tags
     7419
     7420These tags are found in proprietary-format records of the NCTG atom in MOV
     7421videos from some Nikon cameras.
     7422
     7423  Tag ID       Tag Name                         Writable
     7424  ------       --------                         --------
     7425  0x0001       Make                             N
     7426  0x0002       Model                            N
     7427  0x0003       Software                         N
     7428  0x0011       CreateDate                       N
     7429  0x0012       DateTimeOriginal                 N
     7430  0x0013       FrameCount                       N
     7431  0x0016       FrameRate                        N
     7432  0x0022       FrameWidth                       N
     7433  0x0023       FrameHeight                      N
     7434  0x0032       AudioChannels                    N
     7435  0x0033       AudioBitsPerSample               N
     7436  0x0034       AudioSampleRate                  N
     7437  0x2000001    MakerNoteVersion                 N
     7438  0x2000005    WhiteBalance                     N
     7439  0x200000b    WhiteBalanceFineTune             N
     7440  0x200001e    ColorSpace                       N
     7441  0x2000023    PictureControlData               Nikon PictureControl
     7442  0x2000024    WorldTime                        Nikon WorldTime
     7443  0x2000032    UnknownInfo                      Nikon UnknownInfo
     7444  0x2000083    LensType                         N
     7445  0x2000084    Lens                             N
     7446
    39117447=head3 Nikon MOV Tags
    39127448
    3913 This information is found in Nikon QT video images, and is very similar to
    3914 information found in Pentax MOV videos.
     7449This information is found in MOV and QT videos from some Nikon cameras.
    39157450
    39167451   Index   Tag Name                             Writable
     
    39267461    223    ISO                                  N
    39277462
     7463=head3 Nikon AVI Tags
     7464
     7465Nikon-specific RIFF tags found in AVI videos.
     7466
     7467  Tag ID   Tag Name                             Writable
     7468  ------   --------                             --------
     7469  'nctg'   NikonTags                            Nikon AVITags
     7470  'ncth'   ThumbnailImage                       N
     7471  'ncvr'   NikonVers                            Nikon AVIVers
     7472  'ncvw'   PreviewImage                         N
     7473
     7474=head3 Nikon AVITags Tags
     7475
     7476These tags and the AVIVer tags below are found in proprietary-format records
     7477of Nikon AVI videos.
     7478
     7479  Tag ID   Tag Name                             Writable
     7480  ------   --------                             --------
     7481  0x0003   Make                                 N
     7482  0x0004   Model                                N
     7483  0x0005   Software                             N
     7484  0x0006   Equipment                            N
     7485  0x0007   Orientation                          N
     7486  0x0008   ExposureTime                         N
     7487  0x0009   FNumber                              N
     7488  0x000a   ExposureCompensation                 N
     7489  0x000b   MaxApertureValue                     N
     7490  0x000c   MeteringMode                         N
     7491  0x000f   FocalLength                          N
     7492  0x0010   XResolution                          N
     7493  0x0011   YResolution                          N
     7494  0x0012   ResolutionUnit                       N
     7495  0x0013   DateTimeOriginal                     N
     7496  0x0014   CreateDate                           N
     7497  0x0016   Duration                             N
     7498  0x0018   FocusMode                            N
     7499  0x001b   DigitalZoom                          N
     7500  0x001d   ColorMode                            N
     7501  0x001e   Sharpness                            N
     7502  0x001f   WhiteBalance                         N
     7503  0x0020   NoiseReduction                       N
     7504
     7505=head3 Nikon AVIVers Tags
     7506
     7507  Tag ID   Tag Name                             Writable
     7508  ------   --------                             --------
     7509  0x0001   MakerNoteType                        N
     7510  0x0002   MakerNoteVersion                     N
     7511
     7512=head2 NikonCustom Tags
     7513
     7514=head3 NikonCustom SettingsD40 Tags
     7515
     7516Custom settings for the Nikon D40.
     7517
     7518   Index   Tag Name                             Writable
     7519   -----   --------                             --------
     7520    0.1    Beep                                 int8u & 0x80
     7521    0.2    AFAssist                             int8u & 0x40
     7522    0.3    NoMemoryCard                         int8u & 0x20
     7523    0.4    ImageReview                          int8u & 0x10
     7524    1.1    AutoISO                              int8u & 0x80
     7525    1.2    AutoISOMax                           int8u & 0x30
     7526    1.3    AutoISOMinShutterSpeed               int8u & 0x07
     7527    2.1    ImageReviewTime                      int8u & 0x07
     7528    3.1    MonitorOffTime                       int8u & 0xe0
     7529    3.2    MeteringTime                         int8u & 0x1c
     7530    3.3    SelfTimerTime                        int8u & 0x03
     7531    3.4    RemoteOnDuration                     int8u & 0xc0
     7532    4.1    AELockButton                         int8u & 0x0e
     7533    4.2    AELock                               int8u & 0x01
     7534    5.1    ShootingModeSetting                  int8u & 0x70
     7535    5.2    TimerFunctionButton                  int8u & 0x07
     7536    6.1    Metering                             int8u & 0x03
     7537    8.1    InternalFlash                        int8u & 0x10
     7538    8.2    ManualFlashOutput                    int8u & 0x07
     7539      9    FlashLevel                           int8s
     7540   10.1    FocusModeSetting                     int8u & 0xc0
     7541   11.1    AFAreaModeSetting                    int8u & 0x30
     7542
     7543=head3 NikonCustom SettingsD80 Tags
     7544
     7545Custom settings for the Nikon D80.
     7546
     7547   Index   Tag Name                             Writable
     7548   -----   --------                             --------
     7549    0.1    Beep                                 int8u & 0x80
     7550    0.2    AFAssist                             int8u & 0x40
     7551    0.3    NoMemoryCard                         int8u & 0x20
     7552    0.4    ImageReview                          int8u & 0x10
     7553    0.5    Illumination                         int8u & 0x08
     7554    0.6    MainDialExposureComp                 int8u & 0x04
     7555    0.7    EVStepSize                           int8u & 0x01
     7556    1.1    AutoISO                              int8u & 0x40
     7557    1.2    AutoISOMax                           int8u & 0x30
     7558    1.3    AutoISOMinShutterSpeed               int8u & 0x0f
     7559    2.1    AutoBracketSet                       int8u & 0xc0
     7560    2.2    AutoBracketOrder                     int8u & 0x20
     7561    3.1    MonitorOffTime                       int8u & 0xe0
     7562    3.2    MeteringTime                         int8u & 0x1c
     7563    3.3    SelfTimerTime                        int8u & 0x03
     7564    4.1    AELockButton                         int8u & 0x1e
     7565    4.2    AELock                               int8u & 0x01
     7566    4.3    RemoteOnDuration                     int8u & 0xc0
     7567    5.1    CommandDials                         int8u & 0x80
     7568    5.2    FunctionButton                       int8u & 0x78
     7569    6.1    GridDisplay                          int8u & 0x80
     7570    6.2    ViewfinderWarning                    int8u & 0x40
     7571    6.3    CenterWeightedAreaSize               int8u & 0x0c
     7572    6.4    ExposureDelayMode                    int8u & 0x20
     7573    6.5    MB-D80Batteries                      int8u & 0x03
     7574    7.1    FlashWarning                         int8u & 0x80
     7575    7.2    FlashShutterSpeed                    int8u & 0x78
     7576    7.3    AutoFP                               int8u & 0x04
     7577    7.4    ModelingFlash                        int8u & 0x02
     7578    8.1    InternalFlash                        int8u & 0xc0
     7579    8.2    ManualFlashOutput                    int8u & 0x07
     7580    9.1    RepeatingFlashOutput                 int8u & 0x70
     7581    9.2    RepeatingFlashCount                  int8u & 0x0f
     7582   10.1    RepeatingFlashRate                   int8u & 0xf0
     7583   10.2    CommanderChannel                     int8u & 0x03
     7584   11.1    CommanderInternalFlash               int8u & 0xc0
     7585   11.2    CommanderGroupAMode                  int8u & 0x30
     7586   11.3    CommanderGroupBMode                  int8u & 0x0c
     7587   12.1    CommanderInternalTTLComp             int8u & 0x1f
     7588   12.2    CommanderInternalManualOutput        int8u & 0xe0
     7589   13.1    CommanderGroupA_TTL-AAComp           int8u & 0x1f
     7590   13.2    CommanderGroupAManualOutput          int8u & 0xe0
     7591   14.1    CommanderGroupB_TTL-AAComp           int8u & 0x1f
     7592   14.2    CommanderGroupBManualOutput          int8u & 0xe0
     7593   15.1    CenterAFArea                         int8u & 0x80
     7594   15.2    FocusAreaSelection                   int8u & 0x04
     7595   15.3    AFAreaIllumination                   int8u & 0x03
     7596   16.1    AFAreaModeSetting                    int8u & 0xc0
     7597
     7598=head3 NikonCustom SettingsD90 Tags
     7599
     7600Custom settings for the D90.
     7601
     7602   Index   Tag Name                             Writable
     7603   -----   --------                             --------
     7604    0.1    LightSwitch                          int8u & 0x08
     7605    2.1    AFAreaModeSetting                    int8u & 0x60
     7606    2.2    CenterFocusPoint                     int8u & 0x10
     7607    2.3    AFAssist                             int8u & 0x01
     7608    2.4    AFPointIllumination                  int8u & 0x06
     7609    2.5    FocusPointWrap                       int8u & 0x08
     7610    3.1    AELockForMB-D80                      int8u & 0x1c
     7611    3.2    MB-D80BatteryType                    int8u & 0x03
     7612    4.1    Beep                                 int8u & 0x40
     7613    4.2    GridDisplay                          int8u & 0x02
     7614    4.3    ISODisplay                           int8u & 0x0c
     7615    4.4    ViewfinderWarning                    int8u & 0x01
     7616    4.5    NoMemoryCard                         int8u & 0x20
     7617    5.1    ScreenTips                           int8u & 0x04
     7618    5.2    FileNumberSequence                   int8u & 0x08
     7619    5.3    ShootingInfoDisplay                  int8u & 0xc0
     7620    5.4    LCDIllumination                      int8u & 0x20
     7621    6.1    EasyExposureComp                     int8u & 0x01
     7622    6.2    ReverseIndicators                    int8u & 0x80
     7623    7.1    ExposureControlStepSize              int8u & 0x40
     7624    8.1    CenterWeightedAreaSize               int8u & 0x60
     7625    8.2    FineTuneOptMatrixMetering            int8u & 0x0f
     7626    9.1    FineTuneOptCenterWeighted            int8u & 0xf0
     7627    9.2    FineTuneOptSpotMetering              int8u & 0x0f
     7628   11.1    CLModeShootingSpeed                  int8u & 0x07
     7629   11.2    ExposureDelayMode                    int8u & 0x40
     7630   13.1    AutoBracketSet                       int8u & 0xe0
     7631   13.2    AutoBracketOrder                     int8u & 0x10
     7632   14.1    FuncButton                           int8u & 0x78
     7633   16.1    OKButton                             int8u & 0x18
     7634   17.1    AELockButton                         int8u & 0x38
     7635   18.1    CommandDialsReverseRotation          int8u & 0x80
     7636   18.2    ShutterReleaseButtonAE-L             int8u & 0x02
     7637   19.1    MeteringTime                         int8u & 0xf0
     7638   19.2    RemoteOnDuration                     int8u & 0x03
     7639   20.1    SelfTimerTime                        int8u & 0xc0
     7640   20.2    SelfTimerShotCount                   int8u & 0x1e
     7641   21.1    PlaybackMonitorOffTime               int8u & 0x1c
     7642   21.2    ImageReviewTime                      int8u & 0xe0
     7643   22.1    MenuMonitorOffTime                   int8u & 0xe0
     7644   22.2    ShootingInfoMonitorOffTime           int8u & 0x1c
     7645   23.1    FlashShutterSpeed                    int8u & 0x0f
     7646   24.1    InternalFlash                        int8u & 0xc0
     7647   24.2    ManualFlashOutput                    int8u & 0x1f
     7648   25.1    RepeatingFlashOutput                 int8u & 0x70
     7649   25.2    RepeatingFlashCount                  int8u & 0x0f
     7650   26.1    RepeatingFlashRate                   int8u & 0xf0
     7651   31.1    FlashWarning                         int8u & 0x80
     7652   31.2    CommanderInternalTTLComp             int8u & 0x1f
     7653   31.3    ModelingFlash                        int8u & 0x20
     7654   31.4    AutoFP                               int8u & 0x40
     7655   32.1    CommanderGroupA_TTLComp              int8u & 0x1f
     7656   33.1    CommanderGroupB_TTLComp              int8u & 0x1f
     7657   34.1    LiveViewAF                           int8u & 0xc0
     7658
     7659=head3 NikonCustom SettingsD3 Tags
     7660
     7661Custom settings for the D3, D3S, D3X, D300 and D300S.
     7662
     7663   Index   Tag Name                             Writable
     7664   -----   --------                             --------
     7665    0.1    CustomSettingsBank                   int8u & 0x03
     7666    0.2    CustomSettingsAllDefault             int8u & 0x80
     7667    1.1    AF-CPrioritySelection                int8u & 0xc0
     7668    1.2    AF-SPrioritySelection                int8u & 0x20
     7669    1.3    AFPointSelection                     int8u & 0x10
     7670    1.4    DynamicAFArea                        int8u & 0x0c
     7671    1.5    FocusTrackingLockOn                  int8u & 0x03
     7672    2.1    AFActivation                         int8u & 0x80
     7673    2.2    FocusPointWrap                       int8u & 0x08
     7674    2.3    AFPointIllumination                  int8u & 0x60
     7675           AFPointIllumination                  int8u & 0x06
     7676    2.4    AFPointBrightness                    int8u & 0x06
     7677    2.5    AFAssist                             int8u & 0x01
     7678    3.1    AFOnButton                           int8u & 0x07
     7679    3.2    VerticalAFOnButton                   int8u & 0x70
     7680    3.3    AF-OnForMB-D10                       int8u & 0x70
     7681    4.1    FocusTrackingLockOn                  int8u & 0x07
     7682    4.2    AssignBktButton                      int8u & 0x08
     7683    4.3    MultiSelectorLiveView                int8u & 0xc0
     7684    4.4    InitialZoomLiveView                  int8u & 0x30
     7685    6.1    ISOStepSize                          int8u & 0xc0
     7686    6.2    ExposureControlStepSize              int8u & 0x30
     7687    6.3    ExposureCompStepSize                 int8u & 0x0c
     7688    6.4    EasyExposureCompensation             int8u & 0x03
     7689    7.1    CenterWeightedAreaSize               int8u & 0xe0
     7690    7.2    FineTuneOptCenterWeighted            int8u & 0x0f
     7691    8.1    FineTuneOptMatrixMetering            int8u & 0xf0
     7692    8.2    FineTuneOptSpotMetering              int8u & 0x0f
     7693    9.1    MultiSelectorShootMode               int8u & 0xc0
     7694    9.2    MultiSelectorPlaybackMode            int8u & 0x30
     7695    9.3    InitialZoomSetting                   int8u & 0x0c
     7696    9.4    MultiSelector                        int8u & 0x01
     7697   10.1    ExposureDelayMode                    int8u & 0x40
     7698   10.2    CLModeShootingSpeed                  int8u & 0x07
     7699   10.3    CHModeShootingSpeed                  int8u & 0x30
     7700     11    MaxContinuousRelease                 int8u
     7701   12.1    ReverseIndicators                    int8u & 0x20
     7702   12.2    FileNumberSequence                   int8u & 0x02
     7703           FileNumberSequence                   int8u & 0x08
     7704   12.3    RearDisplay                          int8u & 0x80
     7705   12.4    ViewfinderDisplay                    int8u & 0x40
     7706   12.5    BatteryOrder                         int8u & 0x04
     7707   12.6    MB-D10Batteries                      int8u & 0x03
     7708   12.7    ScreenTips                           int8u & 0x10
     7709   13.1    Beep                                 int8u & 0xc0
     7710   13.2    ShootingInfoDisplay                  int8u & 0x30
     7711   13.3    GridDisplay                          int8u & 0x02
     7712   13.4    ViewfinderWarning                    int8u & 0x01
     7713   13.5    MultiSelectorPlaybackMode            int8u & 0x03
     7714   14.1    PreviewButton                        int8u & 0xf8
     7715           FuncButton                           int8u & 0xf8
     7716   14.2    PreviewButtonPlusDials               int8u & 0x07
     7717           FuncButtonPlusDials                  int8u & 0x07
     7718   15.1    FuncButton                           int8u & 0xf8
     7719           PreviewButton                        int8u & 0xf8
     7720   15.2    FuncButtonPlusDials                  int8u & 0x07
     7721           PreviewButtonPlusDials               int8u & 0x07
     7722   16.1    AELockButton                         int8u & 0xf8
     7723   16.2    AELockButtonPlusDials                int8u & 0x07
     7724   17.1    CommandDialsReverseRotation          int8u & 0x80
     7725   17.2    CommandDialsChangeMainSub            int8u & 0x40
     7726   17.3    CommandDialsApertureSetting          int8u & 0x20
     7727   17.4    CommandDialsMenuAndPlayback          int8u & 0x10
     7728   17.5    LCDIllumination                      int8u & 0x08
     7729   17.6    PhotoInfoPlayback                    int8u & 0x04
     7730   17.7    ShutterReleaseButtonAE-L             int8u & 0x02
     7731   17.8    ReleaseButtonToUseDial               int8u & 0x01
     7732   18.1    SelfTimerTime                        int8u & 0x18
     7733   18.2    MonitorOffTime                       int8u & 0x07
     7734   20.1    FlashSyncSpeed                       int8u & 0xe0
     7735           FlashSyncSpeed                       int8u & 0xf0
     7736   20.2    FlashShutterSpeed                    int8u & 0x0f
     7737   21.1    AutoBracketSet                       int8u & 0xc0
     7738   21.2    AutoBracketModeM                     int8u & 0x30
     7739   21.3    AutoBracketOrder                     int8u & 0x08
     7740   21.4    ModelingFlash                        int8u & 0x01
     7741   22.1    NoMemoryCard                         int8u & 0x80
     7742   22.2    MeteringTime                         int8u & 0x0f
     7743   23.1    InternalFlash                        int8u & 0xc0
     7744
     7745=head3 NikonCustom SettingsD700 Tags
     7746
     7747Custom settings for the D700.
     7748
     7749   Index   Tag Name                             Writable
     7750   -----   --------                             --------
     7751    0.1    CustomSettingsBank                   int8u & 0x03
     7752    0.2    CustomSettingsAllDefault             int8u & 0x80
     7753    1.1    AF-CPrioritySelection                int8u & 0xc0
     7754    1.2    AF-SPrioritySelection                int8u & 0x20
     7755    1.3    AFPointSelection                     int8u & 0x10
     7756    1.4    DynamicAFArea                        int8u & 0x0c
     7757    2.1    AFActivation                         int8u & 0x80
     7758    2.2    FocusPointWrap                       int8u & 0x08
     7759    2.3    AFPointIllumination                  int8u & 0x06
     7760    2.4    AFAssist                             int8u & 0x01
     7761    3.1    FocusTrackingLockOn                  int8u & 0x07
     7762    3.2    AF-OnForMB-D10                       int8u & 0x70
     7763    4.1    ISOStepSize                          int8u & 0xc0
     7764    4.2    ExposureControlStepSize              int8u & 0x30
     7765    4.3    ExposureCompStepSize                 int8u & 0x0c
     7766    4.4    EasyExposureCompensation             int8u & 0x03
     7767    5.1    CenterWeightedAreaSize               int8u & 0x70
     7768    6.1    FineTuneOptMatrixMetering            int8u & 0xf0
     7769    6.2    FineTuneOptSpotMetering              int8u & 0x0f
     7770    7.1    ShutterReleaseButtonAE-L             int8u & 0x80
     7771    7.2    SelfTimerTime                        int8u & 0x30
     7772    7.3    MeteringTime                         int8u & 0x0f
     7773    8.1    PlaybackMonitorOffTime               int8u & 0x38
     7774    8.2    MenuMonitorOffTime                   int8u & 0x07
     7775    9.1    ShootingInfoMonitorOffTime           int8u & 0x38
     7776    9.2    ImageReviewTime                      int8u & 0x07
     7777   10.1    Beep                                 int8u & 0xc0
     7778   10.2    ShootingInfoDisplay                  int8u & 0x30
     7779   10.3    LCDIllumination                      int8u & 0x08
     7780   10.4    ExposureDelayMode                    int8u & 0x04
     7781   10.5    GridDisplay                          int8u & 0x02
     7782   11.1    FileNumberSequence                   int8u & 0x40
     7783   11.2    CLModeShootingSpeed                  int8u & 0x07
     7784     12    MaxContinuousRelease                 int8u
     7785   13.1    ScreenTips                           int8u & 0x08
     7786   13.2    BatteryOrder                         int8u & 0x04
     7787   13.3    MB-D10BatteryType                    int8u & 0x03
     7788   15.1    FlashSyncSpeed                       int8u & 0xf0
     7789   15.2    FlashShutterSpeed                    int8u & 0x0f
     7790   16.1    FlashControlBuilt-in                 int8u & 0xc0
     7791   16.2    ManualFlashOutput                    int8u & 0x1f
     7792   17.1    RepeatingFlashOutput                 int8u & 0x70
     7793   17.2    RepeatingFlashCount                  int8u & 0x0f
     7794   18.1    RepeatingFlashRate                   int8u & 0xf0
     7795   18.2    CommanderInternalTTLChannel          int8u & 0x03
     7796   20.1    CommanderInternalTTLCompBuiltin      int8u & 0x1f
     7797   21.1    CommanderInternalTTLCompGroupA       int8u & 0x1f
     7798   22.1    CommanderInternalTTLCompGroupB       int8u & 0x1f
     7799   26.1    AutoBracketSet                       int8u & 0xc0
     7800   26.2    AutoBracketModeM                     int8u & 0x30
     7801   26.3    AutoBracketOrder                     int8u & 0x08
     7802   26.4    ModelingFlash                        int8u & 0x01
     7803   27.1    MultiSelectorShootMode               int8u & 0xc0
     7804   27.2    MultiSelectorPlaybackMode            int8u & 0x30
     7805   27.3    InitialZoomSetting                   int8u & 0x0c
     7806   27.4    MultiSelector                        int8u & 0x01
     7807   28.1    FuncButton                           int8u & 0xf8
     7808   29.1    PreviewButton                        int8u & 0xf8
     7809   30.1    AELockButton                         int8u & 0xf8
     7810   31.1    FuncButtonPlusDials                  int8u & 0x70
     7811   31.2    PreviewButtonPlusDials               int8u & 0x07
     7812   32.1    AELockButtonPlusDials                int8u & 0x70
     7813   33.1    CommandDialsReverseRotation          int8u & 0x80
     7814   33.2    CommandDialsChangeMainSub            int8u & 0x40
     7815   33.3    CommandDialsApertureSetting          int8u & 0x20
     7816   33.4    CommandDialsMenuAndPlayback          int8u & 0x10
     7817   33.5    ReverseIndicators                    int8u & 0x08
     7818   33.6    PhotoInfoPlayback                    int8u & 0x04
     7819   33.7    NoMemoryCard                         int8u & 0x02
     7820   33.8    ReleaseButtonToUseDial               int8u & 0x01
     7821
     7822=head3 NikonCustom SettingsD5000 Tags
     7823
     7824Custom settings for the D5000.
     7825
     7826   Index   Tag Name                             Writable
     7827   -----   --------                             --------
     7828    0.1    AFAreaModeSetting                    int8u & 0x60
     7829    0.2    AFAssist                             int8u & 0x01
     7830    2.1    Beep                                 int8u & 0xc0
     7831    2.2    GridDisplay                          int8u & 0x02
     7832    2.3    ISODisplay                           int8u & 0x08
     7833    2.4    NoMemoryCard                         int8u & 0x20
     7834    3.1    FileNumberSequence                   int8u & 0x08
     7835    4.1    RangeFinder                          int8u & 0x10
     7836    4.2    DateImprint                          int8u & 0x08
     7837    4.3    ReverseIndicators                    int8u & 0x80
     7838    5.1    EVStepSize                           int8u & 0x40
     7839    9.1    ExposureDelayMode                    int8u & 0x40
     7840   11.1    AutoBracketSet                       int8u & 0xc0
     7841   12.1    TimerFunctionButton                  int8u & 0x38
     7842   15.1    AELockButton                         int8u & 0x38
     7843   16.1    ShutterReleaseButtonAE-L             int8u & 0x02
     7844   16.2    CommandDialsReverseRotation          int8u & 0x80
     7845   17.1    MeteringTime                         int8u & 0x70
     7846   17.2    RemoteOnDuration                     int8u & 0x03
     7847   18.1    SelfTimerTime                        int8u & 0xc0
     7848   18.2    SelfTimerShotCount                   int8u & 0x1e
     7849   19.1    ImageReviewTime                      int8u & 0xe0
     7850   20.1    PlaybackMenusTime                    int8u & 0xe0
     7851   22.1    InternalFlash                        int8u & 0xc0
     7852   22.2    ManualFlashOutput                    int8u & 0x1f
     7853   32.1    LiveViewAF                           int8u & 0x60
     7854
     7855=head3 NikonCustom SettingsD7000 Tags
     7856
     7857Custom settings for the D7000.
     7858
     7859   Index   Tag Name                             Writable
     7860   -----   --------                             --------
     7861    0.1    AF-CPrioritySelection                int8u & 0x80
     7862    0.2    AF-SPrioritySelection                int8u & 0x20
     7863    0.3    NumberOfFocusPoints                  int8u & 0x10
     7864    0.4    FocusTrackingLockOn                  int8u & 0x07
     7865    1.2    FocusPointWrap                       int8u & 0x08
     7866    1.3    AFPointIllumination                  int8u & 0x06
     7867    1.4    AFAssist                             int8u & 0x01
     7868    2.1    BatteryOrder                         int8u & 0x40
     7869    2.2    AF-OnForMB-D11                       int8u & 0x1c
     7870    2.3    MB-D11BatteryType                    int8u & 0x03
     7871    3.1    BeepPitch                            int8u & 0xc0
     7872    3.2    NoMemoryCard                         int8u & 0x20
     7873    3.3    ISODisplay                           int8u & 0x0c
     7874    3.4    GridDisplay                          int8u & 0x02
     7875    3.5    ViewfinderWarning                    int8u & 0x01
     7876    4.1    ShootingInfoDisplay                  int8u & 0xc0
     7877    4.2    LCDIllumination                      int8u & 0x20
     7878    4.3    FileNumberSequence                   int8u & 0x08
     7879    4.4    ScreenTips                           int8u & 0x04
     7880    4.5    BeepVolume                           int8u & 0x03
     7881    5.1    ReverseIndicators                    int8u & 0x80
     7882    5.2    EasyExposureCompensation             int8u & 0x03
     7883    6.1    ExposureControlStep                  int8u & 0x40
     7884    6.2    ISOSensitivityStep                   int8u & 0x10
     7885    7.1    CenterWeightedAreaSize               int8u & 0xe0
     7886   10.1    ExposureDelayMode                    int8u & 0x40
     7887   10.2    CLModeShootingSpeed                  int8u & 0x07
     7888     11    MaxContinuousRelease                 int8u
     7889   12.1    AutoBracketSet                       int8u & 0xe0
     7890   12.2    AutoBracketOrder                     int8u & 0x10
     7891   13.1    FuncButton                           int8u & 0xf8
     7892   14.1    PreviewButton                        int8u & 0xf8
     7893   15.1    OKButton                             int8u & 0x18
     7894   16.1    AELockButton                         int8u & 0x38
     7895   17.1    CommandDialsReverseRotation          int8u & 0x80
     7896   17.2    CommandDialsChangeMainSub            int8u & 0x60
     7897   17.3    CommandDialsApertureSetting          int8u & 0x04
     7898   17.4    CommandDialsMenuAndPlayback          int8u & 0x18
     7899   17.5    ShutterReleaseButtonAE-L             int8u & 0x02
     7900   17.6    ReleaseButtonToUseDial               int8u & 0x01
     7901   18.1    MeteringTime                         int8u & 0xf0
     7902   18.2    RemoteOnDuration                     int8u & 0x03
     7903   19.1    SelfTimerTime                        int8u & 0xc0
     7904   19.2    SelfTimerInterval                    int8u & 0x30
     7905   19.3    SelfTimerShotCount                   int8u & 0x0f
     7906   20.1    ImageReviewTime                      int8u & 0xe0
     7907   20.2    LiveViewMonitorOffTime               int8u & 0x1c
     7908   21.1    MenuMonitorOffTime                   int8u & 0xe0
     7909   21.2    ShootingInfoMonitorOffTime           int8u & 0x1c
     7910   22.1    FlashSyncSpeed                       int8u & 0xf0
     7911   22.2    FlashShutterSpeed                    int8u & 0x0f
     7912   23.1    FlashControlBuilt-in                 int8u & 0xc0
     7913   23.2    ManualFlashOutput                    int8u & 0x1f
     7914   24.1    RepeatingFlashOutput                 int8u & 0x70
     7915   24.2    RepeatingFlashCount                  int8u & 0x0f
     7916   25.1    RepeatingFlashRate                   int8u & 0xf0
     7917   26.1    CommanderInternalTTLCompBuiltin      int8u & 0x1f
     7918   27.1    CommanderInternalTTLCompGroupA       int8u & 0x1f
     7919   28.1    CommanderInternalTTLCompGroupB       int8u & 0x1f
     7920   30.1    FlashWarning                         int8u & 0x80
     7921   30.2    ModelingFlash                        int8u & 0x20
     7922   34.1    LiveViewAFAreaMode                   int8u & 0x60
     7923   34.2    LiveViewAFMode                       int8u & 0x02
     7924   35.1    PlaybackMonitorOffTime               int8u & 0xe0
     7925
    39287926=head2 NikonCapture Tags
    39297927
     
    39347932  ------       --------                         --------
    39357933  0x8ae85e     LCHEditor                        int8u
     7934  0x83a1a25    HistogramXML                     undef
    39367935  0xc89224b    ColorAberrationControl           int8u
     7936  0x116fea21   HighlightData                    NikonCapture HighlightData
    39377937  0x2175eb78   D-LightingHQ                     int8u
    39387938  0x2fc08431   StraightenAngle                  double
    39397939  0x374233e0   CropData                         NikonCapture CropData
     7940  0x39c456ac   PictureCtrl                      NikonCapture PictureCtrl
    39407941  0x3cfc73c6   RedEyeData                       NikonCapture RedEyeData
     7942  0x3d136244   EditVersionName                  string
     7943  0x56a54260   Exposure                         NikonCapture Exposure
    39417944  0x5f0e7d23   ColorBooster                     int8u
    39427945  0x6a6e36b6   D-LightingHQSelected             int8u
     
    39607963  0xbf3c6c20   WBAdjData                        NikonCapture WBAdjData
    39617964  0xce5554aa   D-LightingHS                     int8u
     7965  0xe2173c47   PictureControl                   int8u
    39627966  0xe37b4337   D-LightingHSData                 NikonCapture DLightingHS
    39637967  0xe42b5161   UnsharpData                      NikonCapture UnsharpData
     7968  0xe9651831   PhotoEffectHistoryXML            undef
     7969  0xfe28a44f   AutoRedEye                       int8u
    39647970  0xfe443a45   ImageDustOff                     int8u
     7971
     7972=head3 NikonCapture HighlightData Tags
     7973
     7974   Index   Tag Name                             Writable
     7975   -----   --------                             --------
     7976      0    ShadowProtection                     int8s
     7977      1    SaturationAdj                        int8s
     7978      6    HighlightProtection                  int8s
    39657979
    39667980=head3 NikonCapture CropData Tags
     
    39727986     46    CropRight                            double
    39737987     54    CropBottom                           double
    3974     142    OutputWidthInches                    double
    3975     150    OutputHeightInches                   double
    3976     158    ScaledResolution                     double
    3977     174    SourceResolution                     double
    3978     182    OutputResolution                     double
     7988    142    CropOutputWidthInches                double
     7989    150    CropOutputHeightInches               double
     7990    158    CropScaledResolution                 double
     7991    174    CropSourceResolution                 double
     7992    182    CropOutputResolution                 double
    39797993    190    CropOutputScale                      double
    3980     198    OutputWidth                          double
    3981     206    OutputHeight                         double
    3982     214    OutputPixels                         double
     7994    198    CropOutputWidth                      double
     7995    206    CropOutputHeight                     double
     7996    214    CropOutputPixels                     double
     7997
     7998=head3 NikonCapture PictureCtrl Tags
     7999
     8000   Index   Tag Name                             Writable
     8001   -----   --------                             --------
     8002      0    PictureControlActive                 int8u
     8003     19    PictureControlMode                   string[16]
     8004     42    QuickAdjust                          int8u
     8005     43    SharpeningAdj                        int8u
     8006     44    ContrastAdj                          int8u
     8007     45    BrightnessAdj                        int8u
     8008     46    SaturationAdj                        int8u
     8009     47    HueAdj                               int8u
    39838010
    39848011=head3 NikonCapture RedEyeData Tags
     
    39878014   -----   --------                             --------
    39888015      0    RedEyeCorrection                     int8u
     8016
     8017=head3 NikonCapture Exposure Tags
     8018
     8019   Index   Tag Name                             Writable
     8020   -----   --------                             --------
     8021      0    ExposureAdj                          int16s
     8022     18    ExposureAdj2                         double~
     8023     36    ActiveD-Lighting                     int8u
     8024     37    ActiveD-LightingMode                 int8u
    39898025
    39908026=head3 NikonCapture Brightness Tags
     
    39998035   Index   Tag Name                             Writable
    40008036   -----   --------                             --------
    4001       0    D-LightingHSShadow                   int32u
    4002       1    D-LightingHSHighlight                int32u
    4003       2    D-LightingHSColorBoost               int32u
     8037      0    D-LightingHQShadow                   int32u
     8038      1    D-LightingHQHighlight                int32u
     8039      2    D-LightingHQColorBoost               int32u
    40048040
    40058041=head3 NikonCapture NoiseReduction Tags
     
    40088044   -----   --------                             --------
    40098045      4    EdgeNoiseReduction                   int8u
    4010       5    ColorMoireReduction                  int8u
     8046      5    ColorMoireReductionMode              int8u
    40118047      9    NoiseReductionIntensity              int32u
    40128048     13    NoiseReductionSharpness              int32u
    40138049     17    NoiseReductionMethod                 int16u
     8050     21    ColorMoireReduction                  int8u
     8051     23    NoiseReduction                       int8u
     8052     24    ColorNoiseReductionIntensity         int32u
     8053     28    ColorNoiseReductionSharpness         int32u
    40148054
    40158055=head3 NikonCapture PhotoEffects Tags
     
    40368076      8    WBAdjBlueBalance                     double
    40378077     16    WBAdjMode                            int8u
     8078     20    WBAdjLightingSubtype                 int8u
    40388079     21    WBAdjLighting                        int8u
    40398080     24    WBAdjTemperature                     int16u
     8081     37    WBAdjTint                            int32s
    40408082
    40418083=head3 NikonCapture DLightingHS Tags
     
    40848126  0x0089   PreviewImageLength                   N
    40858127  0x0100   ThumbnailImage                       undef
    4086   0x0101   ColorMode                            int16u
    4087   0x0102   MinoltaQuality                       int16u
    4088   0x0103   MinoltaQuality                       int16u
    40898128  0x0104   BodyFirmwareVersion                  string
    40908129  0x0200   SpecialMode                          int32u[3]~
     
    41138152  0x0f00   DataDump                             N
    41148153  0x0f01   DataDump2                            N
     8154  0x0f04   ZoomedPreviewStart                   int32u*
     8155  0x0f05   ZoomedPreviewLength                  int32u*
     8156  0x0f06   ZoomedPreviewSize                    int16u[2]
    41158157  0x1000   ShutterSpeedValue                    rational64s
    41168158  0x1001   ISOValue                             rational64s
     
    41628204  0x1030   SceneDetect                          int16u
    41638205  0x1031   SceneArea?                           int32u[8]
    4164   0x1033   SceneDetectArea?                     int32u[720]
     8206  0x1033   SceneDetectData?                     int32u[720]
    41658207  0x1034   CompressionRatio                     rational64u
    41668208  0x1035   PreviewImageValid                    int32u
     
    41708212  0x1039   CCDScanMode                          int16u
    41718213  0x103a   NoiseReduction                       int16u
    4172   0x103b   InfinityLensStep                     int16u
    4173   0x103c   NearLensStep                         int16u
     8214  0x103b   FocusStepInfinity                    int16u
     8215  0x103c   FocusStepNear                        int16u
    41748216  0x103d   LightValueCenter                     rational64s
    41758217  0x103e   LightValuePeriphery                  rational64s
    41768218  0x103f   FieldCount?                          int16u
    41778219  0x2010   Equipment                            Olympus Equipment
    4178            Equipment                         Olympus Equipment
     8220           EquipmentIFD                         Olympus Equipment
    41798221  0x2020   CameraSettings                       Olympus CameraSettings
    4180            CameraSettings                    Olympus CameraSettings
     8222           CameraSettingsIFD                    Olympus CameraSettings
    41818223  0x2030   RawDevelopment                       Olympus RawDevelopment
    4182            RawDevelopment                    Olympus RawDevelopment
     8224           RawDevelopmentIFD                    Olympus RawDevelopment
    41838225  0x2031   RawDev2                              Olympus RawDevelopment2
    4184            RawDev2_2                            Olympus RawDevelopment2
     8226           RawDev2IFD                           Olympus RawDevelopment2
    41858227  0x2040   ImageProcessing                      Olympus ImageProcessing
    4186            ImageProcessing                   Olympus ImageProcessing
     8228           ImageProcessingIFD                   Olympus ImageProcessing
    41878229  0x2050   FocusInfo                            Olympus FocusInfo
    4188            FocusInfo                         Olympus FocusInfo
     8230           FocusInfoIFD                         Olympus FocusInfo
    41898231           CameraParameters                     undef
    41908232  0x2100   Olympus2100                          Olympus FE
     8233           Olympus2100IFD                       Olympus FE
    41918234  0x2200   Olympus2200                          Olympus FE
     8235           Olympus2200IFD                       Olympus FE
    41928236  0x2300   Olympus2300                          Olympus FE
     8237           Olympus2300IFD                       Olympus FE
    41938238  0x2400   Olympus2400                          Olympus FE
     8239           Olympus2400IFD                       Olympus FE
    41948240  0x2500   Olympus2500                          Olympus FE
     8241           Olympus2500IFD                       Olympus FE
    41958242  0x2600   Olympus2600                          Olympus FE
     8243           Olympus2600IFD                       Olympus FE
    41968244  0x2700   Olympus2700                          Olympus FE
     8245           Olympus2700IFD                       Olympus FE
    41978246  0x2800   Olympus2800                          Olympus FE
     8247           Olympus2800IFD                       Olympus FE
    41988248  0x2900   Olympus2900                          Olympus FE
     8249           Olympus2900IFD                       Olympus FE
    41998250  0x3000   RawInfo                              Olympus RawInfo
    4200            RawInfo2                             Olympus RawInfo
     8251           RawInfoIFD                           Olympus RawInfo
     8252  0x4000   MainInfo                             Olympus
     8253           MainInfoIFD                          Olympus
     8254  0x5000   UnknownInfo                          Olympus UnknownInfo
     8255           UnknownInfoIFD                       Olympus UnknownInfo
    42018256
    42028257=head3 Olympus TextInfo Tags
     
    42218276  0x0103   FocalPlaneDiagonal                   rational64u
    42228277  0x0104   BodyFirmwareVersion                  int32u
    4223   0x0201   LensType                             int8u[6]~
     8278  0x0201   LensType                             int8u[6]
    42248279  0x0202   LensSerialNumber                     string[32]
     8280  0x0203   LensModel                            string
    42258281  0x0204   LensFirmwareVersion                  int32u
    42268282  0x0205   MaxApertureAtMinFocal                int16u
     
    42308286  0x020a   MaxApertureAtCurrentFocal            int16u
    42318287  0x020b   LensProperties                       int16u
    4232   0x0301   Extender                             int8u[6]~
     8288  0x0301   Extender                             int8u[6]
    42338289  0x0302   ExtenderSerialNumber                 string[32]
    42348290  0x0303   ExtenderModel                        string
     
    42508306  0x0201   AELock                               int16u
    42518307  0x0202   MeteringMode                         int16u
     8308  0x0203   ExposureShift                        rational64s
    42528309  0x0300   MacroMode                            int16u
    4253   0x0301   FocusMode                            int16u
    4254   0x0302   FocusProcess                         int16u
     8310  0x0301   FocusMode                            int16u[n]
     8311  0x0302   FocusProcess                         int16u[n]
    42558312  0x0303   AFSearch                             int16u
    42568313  0x0304   AFAreas                              int32u[64]~
     8314  0x0305   AFPointSelected                      rational64s[5]~
     8315  0x0307   AFFineTuneAdj                        int16s[3]
    42578316  0x0400   FlashMode                            int16u
    4258   0x0401   FlashExposureCompensation            rational64s
     8317  0x0401   FlashExposureComp                    rational64s
     8318  0x0403   FlashRemoteControl                   int16u
     8319  0x0404   FlashControlMode                     int16u[3]
     8320  0x0405   FlashIntensity                       rational64s[3]
     8321  0x0406   ManualFlashStrength                  rational64s[3]
    42598322  0x0500   WhiteBalance2                        int16u
    42608323  0x0501   WhiteBalanceTemperature              int16u
     
    42708333  0x050c   ShadingCompensation                  int16u
    42718334  0x050d   CompressionFactor                    rational64u
    4272   0x050f   Gradation                            int16s[3]
    4273   0x0520   PictureMode                          int16u
     8335  0x050f   Gradation                            int16s[n]
     8336  0x0520   PictureMode                          int16u[n]
    42748337  0x0521   PictureModeSaturation                int16s[3]
    42758338  0x0522   PictureModeHue?                      int16s
     
    42798342  0x0526   PictureModeTone                      int16s
    42808343  0x0527   NoiseFilter                          int16s[3]
     8344  0x0529   ArtFilter                            int16u[4]
     8345  0x052c   MagicFilter                          int16u[4]
    42818346  0x0600   DriveMode                            int16u[n]~
    42828347  0x0601   PanoramaMode                         int16u~
    42838348  0x0603   ImageQuality2                        int16u
     8349  0x0604   ImageStabilization                   int32u
     8350  0x0900   ManometerPressure                    int16u
    42848351  0x0901   ManometerReading                     int32s[2]
     8352  0x0902   ExtendedWBDetect                     int16u
     8353  0x0903   LevelGaugeRoll                       int16u
     8354  0x0904   LevelGaugePitch                      int16u
    42858355
    42868356=head3 Olympus RawDevelopment Tags
     
    43278397  0x0111   RawDevPMPictureTone                  int16u
    43288398  0x0112   RawDevGradation                      int16s[3]
     8399  0x0113   RawDevSaturation3                    int16s[3]
     8400  0x0119   RawDevAutoGradation                  int16u
     8401  0x0120   RawDevPMNoiseFilter                  int16u
    43298402
    43308403=head3 Olympus ImageProcessing Tags
     
    43348407  0x0000   ImageProcessingVersion               undef[4]
    43358408  0x0100   WB_RBLevels                          int16u[2]
     8409  0x0102   WB_RBLevels3000K                     int16u[2]
     8410  0x0103   WB_RBLevels3300K                     int16u[2]
     8411  0x0104   WB_RBLevels3600K                     int16u[2]
     8412  0x0105   WB_RBLevels3900K                     int16u[2]
     8413  0x0106   WB_RBLevels4000K                     int16u[2]
     8414  0x0107   WB_RBLevels4300K                     int16u[2]
     8415  0x0108   WB_RBLevels4500K                     int16u[2]
     8416  0x0109   WB_RBLevels4800K                     int16u[2]
     8417  0x010a   WB_RBLevels5300K                     int16u[2]
     8418  0x010b   WB_RBLevels6000K                     int16u[2]
     8419  0x010c   WB_RBLevels6600K                     int16u[2]
     8420  0x010d   WB_RBLevels7500K                     int16u[2]
     8421  0x010e   WB_RBLevelsCWB1                      int16u[2]
     8422  0x010f   WB_RBLevelsCWB2                      int16u[2]
     8423  0x0110   WB_RBLevelsCWB3                      int16u[2]
     8424  0x0111   WB_RBLevelsCWB4                      int16u[2]
     8425  0x0113   WB_GLevel3000K                       int16u
     8426  0x0114   WB_GLevel3300K                       int16u
     8427  0x0115   WB_GLevel3600K                       int16u
     8428  0x0116   WB_GLevel3900K                       int16u
     8429  0x0117   WB_GLevel4000K                       int16u
     8430  0x0118   WB_GLevel4300K                       int16u
     8431  0x0119   WB_GLevel4500K                       int16u
     8432  0x011a   WB_GLevel4800K                       int16u
     8433  0x011b   WB_GLevel5300K                       int16u
     8434  0x011c   WB_GLevel6000K                       int16u
     8435  0x011d   WB_GLevel6600K                       int16u
     8436  0x011e   WB_GLevel7500K                       int16u
     8437  0x011f   WB_GLevel                            int16u
    43368438  0x0200   ColorMatrix                          int16u[9]
    4337   0x0300   SmoothingParameter1                  int16u
    4338   0x0310   SmoothingParameter2                  int16u
    4339   0x0600   SmoothingThresholds                  int16u[4]
    4340   0x0610   SmoothingThreshold2                  int16u
     8439  0x0300   Enhancer                             int16u
     8440  0x0301   EnhancerValues                       int16u[7]
     8441  0x0310   CoringFilter                         int16u
     8442  0x0311   CoringValues                         int16u[7]
     8443  0x0600   BlackLevel2                          int16u[4]
     8444  0x0610   GainBase                             int16u
    43418445  0x0611   ValidBits                            int16u[2]
    4342   0x0614   OlympusImageWidth2                   int32u
    4343   0x0615   OlympusImageHeight2                  int32u
     8446  0x0612   CropLeft                             int16u[2]
     8447  0x0613   CropTop                              int16u[2]
     8448  0x0614   CropWidth                            int32u
     8449  0x0615   CropHeight                           int32u
    43448450  0x1010   NoiseReduction2                      int16u
    43458451  0x1011   DistortionCorrection2                int16u
    43468452  0x1012   ShadingCompensation2                 int16u
     8453  0x101c   MultipleExposureMode                 int16u[2]
    43478454  0x1103   UnknownBlock?                        undef
     8455  0x1112   AspectRatio                          int8u[2]
     8456  0x1113   AspectFrame                          int16u[4]
     8457  0x1200   FacesDetected                        int32u[n]
     8458  0x1201   FaceDetectArea                       int16s[n]
     8459  0x1202   MaxFaces                             int32u[3]
     8460  0x1203   FaceDetectFrameSize                  int16u[6]
     8461  0x1207   FaceDetectFrameCrop                  int16s[12]
    43488462
    43498463=head3 Olympus FocusInfo Tags
     
    43538467  0x0000   FocusInfoVersion                     undef[4]
    43548468  0x0209   AutoFocus?                           int16u
     8469  0x0210   SceneDetect                          int16u
     8470  0x0211   SceneArea?                           int32u[8]
     8471  0x0212   SceneDetectData?                     int32u[720]
    43558472  0x0300   ZoomStepCount                        int16u
    43568473  0x0301   FocusStepCount                       int16u
     8474  0x0303   FocusStepInfinity                    int16u
     8475  0x0304   FocusStepNear                        int16u
    43578476  0x0305   FocusDistance                        rational64u
    43588477  0x0308   AFPoint                              int16u
     
    43828501  ------   --------                             --------
    43838502  0x0000   RawInfoVersion                       undef[4]
    4384   0x0100   WB_RBLevelsUsed                      int16[2]
    4385   0x0110   WB_RBLevelsAuto                      int16[2]
    4386   0x0120   WB_RBLevelsShade                     int16[2]
    4387   0x0121   WB_RBLevelsCloudy                    int16[2]
    4388   0x0122   WB_RBLevelsFineWeather               int16[2]
    4389   0x0123   WB_RBLevelsTungsten                  int16[2]
    4390   0x0124   WB_RBLevelsEveningSunlight           int16[2]
    4391   0x0130   WB_RBLevelsDaylightFluor             int16[2]
    4392   0x0131   WB_RBLevelsDayWhiteFluor             int16[2]
    4393   0x0132   WB_RBLevelsCoolWhiteFluor            int16[2]
    4394   0x0133   WB_RBLevelsWhiteFluorescent          int16[2]
     8503  0x0100   WB_RBLevelsUsed                      int16u[2]
     8504  0x0110   WB_RBLevelsAuto                      int16u[2]
     8505  0x0120   WB_RBLevelsShade                     int16u[2]
     8506  0x0121   WB_RBLevelsCloudy                    int16u[2]
     8507  0x0122   WB_RBLevelsFineWeather               int16u[2]
     8508  0x0123   WB_RBLevelsTungsten                  int16u[2]
     8509  0x0124   WB_RBLevelsEveningSunlight           int16u[2]
     8510  0x0130   WB_RBLevelsDaylightFluor             int16u[2]
     8511  0x0131   WB_RBLevelsDayWhiteFluor             int16u[2]
     8512  0x0132   WB_RBLevelsCoolWhiteFluor            int16u[2]
     8513  0x0133   WB_RBLevelsWhiteFluorescent          int16u[2]
    43958514  0x0200   ColorMatrix2                         int16u[9]
    43968515  0x0310   CoringFilter                         int16u
     
    43998518  0x0601   YCbCrCoefficients                    N
    44008519  0x0611   ValidPixelDepth                      int16u[2]
    4401   0x0612   StartOffsetX                         int16u
    4402   0x0613   StartOffsetY                         int16u
    4403   0x0614   FinalImageWidth                      int32u
    4404   0x0615   FinalImageHeight                     int32u
     8520  0x0612   CropLeft                             int16u
     8521  0x0613   CropTop                              int16u
     8522  0x0614   CropWidth                            int32u
     8523  0x0615   CropHeight                           int32u
    44058524  0x1000   LightSource                          int16u
    44068525  0x1001   WhiteBalanceComp                     int16s[3]
     
    44188537  0x2023   CMSharpness                          int16s[3]
    44198538
     8539=head3 Olympus UnknownInfo Tags
     8540
     8541  Tag ID   Tag Name                             Writable
     8542  ------   --------                             --------
     8543  [no tags known]
     8544
     8545=head3 Olympus MOV1 Tags
     8546
     8547This information is found in MOV videos from Olympus models such as the
     8548D540Z, D595Z, FE100, FE110, FE115, FE170 and FE200.
     8549
     8550   Index   Tag Name                             Writable
     8551   -----   --------                             --------
     8552      0    Make                                 N
     8553     24    Model                                N
     8554     38    ExposureUnknown?                     N
     8555     42    FNumber                              N
     8556     50    ExposureCompensation                 N
     8557     72    FocalLength                          N
     8558
     8559=head3 Olympus MOV2 Tags
     8560
     8561This information is found in MOV videos from Olympus models such as the
     8562FE120, FE140 and FE190.
     8563
     8564   Index   Tag Name                             Writable
     8565   -----   --------                             --------
     8566      0    Make                                 N
     8567     24    Model                                N
     8568     54    ExposureTime                         N
     8569     58    FNumber                              N
     8570     66    ExposureCompensation                 N
     8571     88    FocalLength                          N
     8572    193    ISO                                  N
     8573
     8574=head3 Olympus MP4 Tags
     8575
     8576This information is found in MP4 videos from Olympus models such as the
     8577u7040 and u9010.
     8578
     8579   Index   Tag Name                             Writable
     8580   -----   --------                             --------
     8581      0    Make                                 N
     8582     24    Model                                N
     8583     40    FNumber                              N
     8584     48    ExposureCompensation                 N
     8585
     8586=head3 Olympus AVI Tags
     8587
     8588This information is found in Olympus AVI videos.
     8589
     8590   Index   Tag Name                             Writable
     8591   -----   --------                             --------
     8592     18    Make                                 N
     8593     44    ModelType                            N
     8594     94    FNumber                              N
     8595    131    DateTime1                            N
     8596    157    DateTime2                            N
     8597    301    ThumbnailLength                      N
     8598    305    ThumbnailImage                       N
     8599
     8600=head3 Olympus WAV Tags
     8601
     8602This information is found in WAV files from Olympus PCM linear recorders
     8603like the LS-5, LS-10, LS-11.
     8604
     8605   Index   Tag Name                             Writable
     8606   -----   --------                             --------
     8607     12    Model                                N
     8608     28    FileNumber                           N
     8609     38    DateTimeOriginal                     N
     8610     50    DateTimeEnd                          N
     8611     62    RecordingTime                        N
     8612    512    Duration                             N
     8613    522    Index01                              N
     8614    532    Index02                              N
     8615    542    Index03                              N
     8616    552    Index04                              N
     8617    562    Index05                              N
     8618    572    Index06                              N
     8619    582    Index07                              N
     8620    592    Index08                              N
     8621    602    Index09                              N
     8622    612    Index10                              N
     8623    622    Index11                              N
     8624    632    Index12                              N
     8625    642    Index13                              N
     8626    652    Index14                              N
     8627    662    Index15                              N
     8628    672    Index16                              N
     8629
    44208630=head2 Panasonic Tags
    44218631
    4422 Panasonic tags are also used for Leica cameras.
     8632These tags are used in Panasonic/Leica cameras.
    44238633
    44248634  Tag ID   Tag Name                             Writable
     
    44288638  0x0003   WhiteBalance                         int16u
    44298639  0x0007   FocusMode                            int16u
    4430   0x000f   AFMode                               int8u[2]
     8640  0x000f   AFAreaMode                           int8u[2]
    44318641  0x001a   ImageStabilization                   int16u
    44328642  0x001c   MacroMode                            int16u
     
    44428652  0x002a   BurstMode                            int16u
    44438653  0x002b   SequenceNumber                       int32u
    4444   0x002c   Contrast                             int16u
     8654  0x002c   ContrastMode                         int16u
    44458655  0x002d   NoiseReduction                       int16u
    44468656  0x002e   SelfTimer                            int16u
    44478657  0x0030   Rotation                             int16u
     8658  0x0031   AFAssistLamp                         int16u
    44488659  0x0032   ColorMode                            int16u
    44498660  0x0033   BabyAge                              string
     
    44518662  0x0035   ConversionLens                       int16u
    44528663  0x0036   TravelDay                            int16u
     8664  0x0039   Contrast                             int16u
    44538665  0x003a   WorldTimeLocation                    int16u
     8666  0x003b   TextStamp                            int16u
    44548667  0x003c   ProgramISO                           int16u
     8668  0x003d   AdvancedSceneMode                    int16u
     8669  0x003e   TextStamp                            int16u
     8670  0x003f   FacesDetected                        int16u
     8671  0x0040   Saturation                           int16u
     8672  0x0041   Sharpness                            int16u
    44558673  0x0042   FilmMode                             int16u
    44568674  0x0046   WBAdjustAB                           int16u
    44578675  0x0047   WBAdjustGM                           int16u
     8676  0x004b   PanasonicImageWidth                  int32u
     8677  0x004c   PanasonicImageHeight                 int32u
     8678  0x004d   AFPointPosition                      rational64u[2]
     8679  0x004e   FaceDetInfo                          Panasonic FaceDetInfo
    44588680  0x0051   LensType                             string
    44598681  0x0052   LensSerialNumber                     string
    44608682  0x0053   AccessoryType                        string
     8683  0x0059   Transform                            undef[4]
     8684  0x005d   IntelligentExposure                  int16u
     8685  0x0061   FaceRecInfo                          Panasonic FaceRecInfo
     8686  0x0062   FlashWarning                         int16u
     8687  0x0063   RecognizedFaceFlags?                 undef[4]
     8688  0x0065   Title                                undef
     8689  0x0066   BabyName                             undef
     8690  0x0067   Location                             undef
     8691  0x0069   Country                              undef
     8692  0x006b   State                                undef
     8693  0x006d   City                                 undef
     8694  0x006f   Landmark                             undef
     8695  0x0070   IntelligentResolution                int8u
     8696  0x0079   IntelligentD-Range                   int16u
    44618697  0x0e00   PrintIM                              PrintIM
    44628698  0x8000   MakerNoteVersion                     undef
     
    44658701  0x8005   WBGreenLevel                         int16u
    44668702  0x8006   WBBlueLevel                          int16u
     8703  0x8007   FlashFired                           int16u
     8704  0x8008   TextStamp                            int16u
     8705  0x8009   TextStamp                            int16u
    44678706  0x8010   BabyAge                              string
     8707  0x8012   Transform                            undef[4]
     8708
     8709=head3 Panasonic FaceDetInfo Tags
     8710
     8711Face detection position information.
     8712
     8713   Index   Tag Name                             Writable
     8714   -----   --------                             --------
     8715      0    NumFacePositions                     int16u
     8716      1    Face1Position                        int16u[4]
     8717      5    Face2Position                        int16u[4]
     8718      9    Face3Position                        int16u[4]
     8719     13    Face4Position                        int16u[4]
     8720     17    Face5Position                        int16u[4]
     8721
     8722=head3 Panasonic FaceRecInfo Tags
     8723
     8724Tags written by cameras with facial recognition.  These cameras not only
     8725detect faces in an image, but also recognize specific people based a
     8726user-supplied set of known faces.
     8727
     8728   Index   Tag Name                             Writable
     8729   -----   --------                             --------
     8730      0    FacesRecognized                      int16u
     8731      4    RecognizedFace1Name                  string[20]
     8732     24    RecognizedFace1Position              int16u[4]
     8733     32    RecognizedFace1Age                   string[20]
     8734     52    RecognizedFace2Name                  string[20]
     8735     72    RecognizedFace2Position              int16u[4]
     8736     80    RecognizedFace2Age                   string[20]
     8737    100    RecognizedFace3Name                  string[20]
     8738    120    RecognizedFace3Position              int16u[4]
     8739    128    RecognizedFace3Age                   string[20]
     8740
     8741=head3 Panasonic Leica2 Tags
     8742
     8743These tags are used by the Leica M8.
     8744
     8745  Tag ID   Tag Name                             Writable
     8746  ------   --------                             --------
     8747  0x0300   Quality                              int16u
     8748  0x0302   UserProfile                          int32u
     8749  0x0303   SerialNumber                         int32u
     8750  0x0304   WhiteBalance                         int16u
     8751  0x0310   LensInfo                             Panasonic LensInfo
     8752  0x0311   ExternalSensorBrightnessValue        rational64s
     8753  0x0312   MeasuredLV                           rational64s
     8754  0x0313   ApproximateFNumber                   rational64u
     8755  0x0320   CameraTemperature                    int32s
     8756  0x0321   ColorTemperature                     int32u
     8757  0x0322   WBRedLevel                           rational64u
     8758  0x0323   WBGreenLevel                         rational64u
     8759  0x0324   WBBlueLevel                          rational64u
     8760  0x0325   UV-IRFilterCorrection                int32u
     8761  0x0330   CCDVersion                           int32u
     8762  0x0331   CCDBoardVersion                      int32u
     8763  0x0332   ControllerBoardVersion               int32u
     8764  0x0333   M16CVersion                          int32u
     8765  0x0340   ImageIDNumber                        int32u
     8766
     8767=head3 Panasonic LensInfo Tags
     8768
     8769   Index   Tag Name                             Writable
     8770   -----   --------                             --------
     8771      0    LensType                             int32u & 0xfffffffc
     8772    0.1    FrameSelector                        int32u & 0x03
     8773
     8774=head3 Panasonic Leica3 Tags
     8775
     8776These tags are used by the Leica R8 and R9 digital backs.
     8777
     8778  Tag ID   Tag Name                             Writable
     8779  ------   --------                             --------
     8780  0x000d   WB_RGBLevels                         int16u[3]
     8781
     8782=head3 Panasonic Leica4 Tags
     8783
     8784This information is written by the M9.
     8785
     8786  Tag ID   Tag Name                             Writable
     8787  ------   --------                             --------
     8788  0x3000   Subdir3000                           Panasonic Subdir
     8789  0x3100   Subdir3100                           Panasonic Subdir
     8790  0x3400   Subdir3400                           Panasonic Subdir
     8791  0x3900   Subdir3900                           Panasonic Subdir
     8792
     8793=head3 Panasonic Subdir Tags
     8794
     8795  Tag ID   Tag Name                             Writable
     8796  ------   --------                             --------
     8797  0x300a   Contrast                             int32u
     8798  0x300b   Sharpening                           int32u
     8799  0x300d   Saturation                           int32u
     8800  0x3033   WhiteBalance                         int32u
     8801  0x3034   JPEGQuality                          int32u
     8802  0x3036   WB_RGBLevels                         rational64u[3]
     8803  0x3038   UserProfile                          string
     8804  0x303a   JPEGSize                             int32u
     8805  0x3103   SerialNumber                         string
     8806  0x3109   FirmwareVersion                      string
     8807  0x312a   BaseISO                              int32u
     8808  0x312b   SensorWidth                          int32u
     8809  0x312c   SensorHeight                         int32u
     8810  0x312d   SensorBitDepth                       int32u
     8811  0x3402   CameraTemperature                    int32s
     8812  0x3405   LensType                             int32u
     8813  0x3406   ApproximateFNumber                   rational64u
     8814  0x3407   MeasuredLV                           int32s
     8815  0x3408   ExternalSensorBrightnessValue        int32s
     8816  0x3901   Data1                                Panasonic Data1
     8817  0x3902   Data2                                Panasonic Data2
     8818
     8819=head3 Panasonic Data1 Tags
     8820
     8821   Index   Tag Name                             Writable
     8822   -----   --------                             --------
     8823     22    LensType                             int32u[0.25]
     8824
     8825=head3 Panasonic Data2 Tags
     8826
     8827   Index   Tag Name                             Writable
     8828   -----   --------                             --------
     8829  [no tags known]
     8830
     8831=head3 Panasonic Leica5 Tags
     8832
     8833This information is written by the X1.
     8834
     8835  Tag ID   Tag Name                             Writable
     8836  ------   --------                             --------
     8837  0x0407   OriginalFileName                     string
     8838  0x0408   OriginalDirectory                    string
     8839  0x040d   ExposureMode                         int8u[4]
     8840  0x0412   FilmMode                             string
     8841  0x0413   WB_RGBLevels                         rational64u[3]
     8842
     8843=head3 Panasonic Leica6 Tags
     8844
     8845This information is written by the S2 (as a trailer in JPEG images).
     8846
     8847  Tag ID   Tag Name                             Writable
     8848  ------   --------                             --------
     8849  0x0300   PreviewImage                         undef
     8850  0x0301   UnknownBlock?                        N
     8851  0x0303   LensType                             string
    44688852
    44698853=head3 Panasonic Type2 Tags
     
    44788862      3    Gain                                 N
    44798863
    4480 =head3 Panasonic Raw Tags
    4481 
    4482 These tags are found in IFD0 of Panasonic RAW images.
    4483 
    4484   Tag ID   Tag Name                             Writable
    4485   ------   --------                             --------
    4486   0x0001   PanasonicRawVersion                  undef
    4487   0x0002   SensorWidth                          N
    4488   0x0003   SensorHeight                         N
    4489   0x0004   SensorTopBorder                      N
    4490   0x0005   SensorLeftBorder                     N
    4491   0x0006   ImageHeight                          N
    4492   0x0007   ImageWidth                           N
    4493   0x0011   RedBalance                           int16u
    4494   0x0012   BlueBalance                          int16u
    4495   0x0017   ISO                                  int16u
    4496   0x0024   WBRedLevel                           int16u
    4497   0x0025   WBGreenLevel                         int16u
    4498   0x0026   WBBlueLevel                          int16u
    4499   0x010f   Make                                 string
    4500   0x0110   Model                                string
    4501   0x0111   StripOffsets                         N
    4502   0x0112   Orientation                          int16u
    4503   0x0116   RowsPerStrip                         N
    4504   0x0117   StripByteCounts                      N
    4505   0x8769   ExifOffset                           EXIF
    4506   0x8825   GPSInfo                              GPS
    4507 
    45088864=head2 Pentax Tags
    45098865
    4510 The Pentax tags are also used in Asahi cameras.
     8866These tags are used in Pentax/Asahi cameras.
    45118867
    45128868  Tag ID   Tag Name                             Writable
     
    45228878  0x0008   Quality                              int16u
    45238879  0x0009   PentaxImageSize                      int16u
    4524   0x000b   PictureMode                          int16u
    4525   0x000c   FlashMode                            N
     8880  0x000b   PictureMode                          int16u[n]
     8881  0x000c   FlashMode                            int16u[n]
    45268882  0x000d   FocusMode                            int16u
    45278883  0x000e   AFPointSelected                      int16u
     
    45318887  0x0013   FNumber                              int16u
    45328888  0x0014   ISO                                  int16u
     8889  0x0015   LightReading                         int16u
    45338890  0x0016   ExposureCompensation                 int16u
    45348891  0x0017   MeteringMode                         int16u
     
    45408897  0x001d   FocalLength                          int32u
    45418898  0x001e   DigitalZoom                          int16u
    4542   0x001f   Saturation                           int16u
    4543   0x0020   Contrast                             int16u
    4544   0x0021   Sharpness                            int16u
     8899  0x001f   Saturation                           int16u[n]
     8900  0x0020   Contrast                             int16u[n]
     8901  0x0021   Sharpness                            int16u[n]
    45458902  0x0022   WorldTimeLocation                    int16u
    45468903  0x0023   HometownCity                         int16u
     
    45488905  0x0025   HometownDST                          int16u
    45498906  0x0026   DestinationDST                       int16u
     8907  0x0027   DSPFirmwareVersion                   undef
     8908  0x0028   CPUFirmwareVersion                   undef
    45508909  0x0029   FrameNumber                          int32u
    4551   0x0032   ImageProcessing                      undef[4]
     8910  0x002d   EffectiveLV                          int16u
     8911  0x0032   ImageEditing                         undef[4]
    45528912  0x0033   PictureMode                          int8u[3]
    45538913  0x0034   DriveMode                            int8u[4]
     8914  0x0035   SensorSize                           int16u[2]
    45548915  0x0037   ColorSpace                           int16u
    45558916  0x0038   ImageAreaOffset                      int16u[2]
    45568917  0x0039   RawImageSize                         int16u[2]~
    45578918  0x003c   AFPointsInFocus                      N
     8919  0x003e   PreviewImageBorders                  int8u[4]
    45588920  0x003f   LensType                             int8u[2]
     8921  0x0040   SensitivityAdjust                    int16u
     8922  0x0041   ImageEditCount                       int16u
    45598923  0x0047   CameraTemperature                    int8s
     8924  0x0048   AELock                               int16u
    45608925  0x0049   NoiseReduction                       int16u
    45618926  0x004d   FlashExposureComp                    int32s
    45628927  0x004f   ImageTone                            int16u
     8928  0x0050   ColorTemperature                     int16u
    45638929  0x005c   ShakeReductionInfo                   Pentax SRInfo
    45648930  0x005d   ShutterCount                         undef[4]
     8931  0x0060   FaceInfo                             Pentax FaceInfo
     8932  0x0067   Hue                                  int16u
     8933  0x0068   AWBInfo                              Pentax AWBInfo
     8934  0x0069   DynamicRangeExpansion                undef[4]
     8935  0x006b   TimeInfo                             Pentax TimeInfo
     8936  0x006c   HighLowKeyAdj                        int16s[2]
     8937  0x006d   ContrastHighlight                    int16s[2]
     8938  0x006e   ContrastShadow                       int16s[2]
     8939  0x006f   ContrastHighlightShadowAdj           int8u
     8940  0x0070   FineSharpness                        int8u[n]
     8941  0x0071   HighISONoiseReduction                int8u
     8942  0x0072   AFAdjustment                         int16s
     8943  0x0073   MonochromeFilterEffect               int16u
     8944  0x0074   MonochromeToning                     int16u
     8945  0x0076   FaceDetect                           int8u[2]
     8946  0x0077   FaceDetectFrameSize                  int16u[2]
     8947  0x0079   ShadowCompensation                   int8u[n]
     8948  0x007a   ISOAutoParameters                    int8u[2]
     8949  0x007b   CrossProcess                         int8u
     8950  0x007d   LensCorr                             Pentax LensCorr
     8951  0x007f   BleachBypassToning                   int16u
    45658952  0x0200   BlackPoint                           int16u[4]
    45668953  0x0201   WhitePoint                           int16u[4]
     8954  0x0203   ColorMatrixA                         int16s[9]
     8955  0x0204   ColorMatrixB                         int16s[9]
     8956  0x0205   CameraSettings                       Pentax CameraSettings
    45678957  0x0206   AEInfo                               Pentax AEInfo
    45688958  0x0207   LensInfo                             Pentax LensInfo
     8959                                                Pentax LensInfo2
     8960                                                Pentax LensInfo3
     8961                                                Pentax LensInfo4
    45698962  0x0208   FlashInfo                            Pentax FlashInfo
    4570   0x0209   AEMeteringSegments                   int8u[16]
    4571   0x020a   FlashADump?                          Y
    4572   0x020b   FlashBDump?                          Y
     8963           FlashInfoUnknown                     Pentax FlashInfoUnknown
     8964  0x0209   AEMeteringSegments                   int8u[n]
     8965  0x020a   FlashMeteringSegments                int8u[n]
     8966  0x020b   SlaveFlashMeteringSegments           int8u[n]
    45738967  0x020d   WB_RGGBLevelsDaylight                int16u[4]
    45748968  0x020e   WB_RGGBLevelsShade                   int16u[4]
     
    45818975  0x0215   CameraInfo                           Pentax CameraInfo
    45828976  0x0216   BatteryInfo                          Pentax BatteryInfo
     8977  0x021b   SaturationInfo?                      N
    45838978  0x021f   AFInfo                               Pentax AFInfo
     8979  0x0220   HuffmanTable?                        N
     8980  0x0222   ColorInfo                            Pentax ColorInfo
     8981  0x0224   EVStepInfo                           Pentax EVStepInfo
     8982  0x0226   ShotInfo                             Pentax ShotInfo
     8983  0x0227   FacePos                              Pentax FacePos
     8984  0x0228   FaceSize                             Pentax FaceSize
     8985  0x0229   SerialNumber                         string
     8986  0x022a   FilterInfo                           Pentax FilterInfo
     8987  0x022b   LevelInfo                            Pentax LevelInfo
     8988  0x022e   Artist                               string
     8989  0x022f   Copyright                            string
     8990  0x0230   FirmwareVersion                      string
     8991  0x0231   ContrastDetectAFArea                 int16u[4]
     8992  0x0235   CrossProcessParams                   undef[10]
    45848993  0x03fe   DataDump                             N
     8994  0x03ff   TempInfoK5                           Pentax TempInfoK5
     8995           UnknownInfo                          Pentax UnknownInfo
    45858996  0x0402   ToneCurve                            Y~
    45868997  0x0403   ToneCurves                           Y~
     
    45959006      0    SRResult                             int8u
    45969007      1    ShakeReduction                       int8u
    4597       2    SR_SWSToSWRTime                      int8u
     9008      2    SRHalfPressTime                      int8u
     9009      3    SRFocalLength                        int8u
     9010
     9011=head3 Pentax FaceInfo Tags
     9012
     9013   Index   Tag Name                             Writable
     9014   -----   --------                             --------
     9015      0    FacesDetected                        int8u
     9016      2    FacePosition                         int8u[2]
     9017
     9018=head3 Pentax AWBInfo Tags
     9019
     9020   Index   Tag Name                             Writable
     9021   -----   --------                             --------
     9022      0    WhiteBalanceAutoAdjustment           int8u
     9023      1    TungstenAWB                          int8u
     9024
     9025=head3 Pentax TimeInfo Tags
     9026
     9027   Index   Tag Name                             Writable
     9028   -----   --------                             --------
     9029    0.1    WorldTimeLocation                    int8u & 0x01
     9030    0.2    HometownDST                          int8u & 0x02
     9031    0.3    DestinationDST                       int8u & 0x04
     9032      2    HometownCity                         int8u
     9033      3    DestinationCity                      int8u
     9034
     9035=head3 Pentax LensCorr Tags
     9036
     9037   Index   Tag Name                             Writable
     9038   -----   --------                             --------
     9039      0    DistortionCorrection                 int8u
     9040      1    ChromaticAberrationCorrection        int8u
     9041
     9042=head3 Pentax CameraSettings Tags
     9043
     9044Shot information written by Pentax DSLR cameras.
     9045
     9046   Index   Tag Name                             Writable
     9047   -----   --------                             --------
     9048      0    PictureMode2                         int8u
     9049    1.1    ProgramLine                          int8u & 0x03
     9050    1.2    EVSteps                              int8u & 0x20
     9051    1.3    E-DialInProgram                      int8u & 0x40
     9052    1.4    ApertureRingUse                      int8u & 0x80
     9053      2    FlashOptions                         int8u & 0xf0
     9054    2.1    MeteringMode2                        int8u & 0x0f
     9055      3    AFPointMode                          int8u & 0xf0
     9056    3.1    FocusMode2                           int8u & 0x0f
     9057      4    AFPointSelected2                     int16u
     9058      6    ISOFloor                             int8u
     9059      7    DriveMode2                           int8u
     9060      8    ExposureBracketStepSize              int8u
     9061      9    BracketShotNumber                    int8u
     9062     10    WhiteBalanceSet                      int8u & 0xf0
     9063   10.1    MultipleExposureSet                  int8u & 0x0f
     9064     13    RawAndJpgRecording                   int8u
     9065   14.1    JpgRecordedPixels                    int8u & 0x03
     9066   14.2    LinkAEToAFPoint                      int8u & 0x01
     9067   14.3    SensitivitySteps                     int8u & 0x02
     9068   14.4    ISOAuto                              int8u & 0x04
     9069     16    FlashOptions2                        int8u & 0xf0
     9070   16.1    MeteringMode3                        int8u & 0x0f
     9071   17.1    SRActive                             int8u & 0x80
     9072   17.2    Rotation                             int8u & 0x60
     9073   17.3    ISOSetting                           int8u & 0x04
     9074   17.4    SensitivitySteps                     int8u & 0x02
     9075     18    TvExposureTimeSetting                int8u
     9076     19    AvApertureSetting                    int8u
     9077     20    SvISOSetting                         int8u
     9078     21    BaseExposureCompensation             int8u
    45989079
    45999080=head3 Pentax AEInfo Tags
     
    46069087      3    AEXv                                 int8u
    46079088      4    AEBXv                                int8s
    4608       5    AEFlashTv                            int8u
     9089      5    AEMinExposureTime                    int8u
    46099090      6    AEProgramMode                        int8u
    4610       7    AEExtra?                             int8u
     9091      7    AEFlags?                             N
     9092      8    AEUnknown                            N
     9093      9    AEMaxAperture                        int8u
     9094     10    AEMaxAperture2                       int8u
     9095     11    AEMinAperture                        int8u
     9096     12    AEMeteringMode                       int8u
     9097     14    FlashExposureCompSet                 int8s
    46119098
    46129099=head3 Pentax LensInfo Tags
    46139100
     9101Pentax lens information structure for models such as the *istD.
     9102
     9103   Index   Tag Name                             Writable
     9104   -----   --------                             --------
     9105      0    LensType                             int8u[2]
     9106      3    LensData                             Pentax LensData
     9107
     9108=head3 Pentax LensInfo2 Tags
     9109
     9110Pentax lens information structure for models such as the K10D and K20D.
     9111
    46149112   Index   Tag Name                             Writable
    46159113   -----   --------                             --------
    46169114      0    LensType                             N
    4617       4    LensCodes                            int8u[16]
    4618       5    LensCodes                            int8u[16]
     9115      4    LensData                             Pentax LensData
     9116
     9117=head3 Pentax LensData Tags
     9118
     9119Pentax lens data information.  Some of these tags require interesting binary
     9120gymnastics to decode them into useful values.
     9121
     9122   Index   Tag Name                             Writable
     9123   -----   --------                             --------
     9124    0.1    AutoAperture                         int8u & 0x01
     9125    0.2    MinAperture                          int8u & 0x06
     9126    0.3    LensFStops                           int8u & 0x70
     9127      1    LensKind?                            int8u
     9128      2    LC1?                                 int8u
     9129      3    LC2?                                 int8u
     9130      4    LC3?                                 int8u
     9131      5    LC4?                                 int8u
     9132      6    LC5?                                 int8u
     9133      7    LC6?                                 int8u
     9134      8    LC7?                                 int8u
     9135      9    FocalLength                          int8u
     9136     10    NominalMaxAperture                   int8u & 0xf0
     9137   10.1    NominalMinAperture                   int8u & 0x0f
     9138     11    LC10?                                int8u
     9139     12    LC11?                                int8u
     9140     13    LC12?                                int8u
     9141   14.1    MaxAperture                          int8u & 0x7f
     9142     15    LC14?                                int8u
     9143     16    LC15?                                int8u
     9144
     9145=head3 Pentax LensInfo3 Tags
     9146
     9147Pentax lens information structure for 645D.
     9148
     9149   Index   Tag Name                             Writable
     9150   -----   --------                             --------
     9151      1    LensType                             N
     9152     13    LensData                             Pentax LensData
     9153
     9154=head3 Pentax LensInfo4 Tags
     9155
     9156Pentax lens information structure for models such as the K-5 and K-r.
     9157
     9158   Index   Tag Name                             Writable
     9159   -----   --------                             --------
     9160      1    LensType                             N
     9161     12    LensData                             Pentax LensData
    46199162
    46209163=head3 Pentax FlashInfo Tags
    46219164
     9165Flash information tags for the K10D, K20D and K200D.
     9166
    46229167   Index   Tag Name                             Writable
    46239168   -----   --------                             --------
    46249169      0    FlashStatus                          int8u
    4625       1    FlashModeCode                        int8u
     9170      1    InternalFlashMode                    int8u
    46269171      2    ExternalFlashMode                    int8u
    4627       3    InternalFlashMagni                   int8u
     9172      3    InternalFlashStrength                int8u
    46289173      4    TTL_DA_AUp                           int8u
    46299174      5    TTL_DA_ADown                         int8u
    46309175      6    TTL_DA_BUp                           int8u
    46319176      7    TTL_DA_BDown                         int8u
     9177   24.1    ExternalFlashGuideNumber             int8u & 0x1f
     9178     25    ExternalFlashExposureComp            int8u
     9179     26    ExternalFlashBounce                  int8u
     9180
     9181=head3 Pentax FlashInfoUnknown Tags
     9182
     9183   Index   Tag Name                             Writable
     9184   -----   --------                             --------
     9185  [no tags known]
    46329186
    46339187=head3 Pentax CameraInfo Tags
     
    46379191      0    PentaxModelID                        int32u
    46389192      1    ManufactureDate                      int32u
    4639       2    ModelRevision                        int32u[2]
     9193      2    ProductionCode                       int32u[2]
    46409194      4    InternalSerialNumber                 int32u
    46419195
     
    46449198   Index   Tag Name                             Writable
    46459199   -----   --------                             --------
    4646       0    BatteryType                          int8u
    4647       1    BatteryBodyGripStates                int8u
    4648       2    BatteryADBodyNoLoad                  int8u
    4649       3    BatteryADBodyLoad                    int8u
    4650       4    BatteryADGripNoLoad                  int8u
    4651       5    BatteryADGripLoad                    int8u
     9200    0.1    PowerSource                          int8u & 0x0f
     9201    1.1    BodyBatteryState                     int8u & 0xf0
     9202    1.2    GripBatteryState                     int8u & 0x0f
     9203           GripBatteryState?                    int8u & 0x0f
     9204      2    BodyBatteryADNoLoad                  int8u
     9205           BodyBatteryVoltage1                  int16u
     9206      3    BodyBatteryADLoad                    int8u
     9207      4    GripBatteryADNoLoad                  int8u
     9208           BodyBatteryVoltage2                  int16u
     9209      5    GripBatteryADLoad                    int8u
     9210      6    BodyBatteryVoltage3                  int16u
     9211      8    BodyBatteryVoltage4                  int16u
    46529212
    46539213=head3 Pentax AFInfo Tags
     
    46559215   Index   Tag Name                             Writable
    46569216   -----   --------                             --------
     9217      0    AFPointsUnknown1?                    int16u
     9218      2    AFPointsUnknown2?                    int16u
     9219      4    AFPredictor                          int16s
     9220      6    AFDefocus                            int8u
     9221      7    AFIntegrationTime                    int8u
    46579222     11    AFPointsInFocus                      int8u
     9223
     9224=head3 Pentax ColorInfo Tags
     9225
     9226   Index   Tag Name                             Writable
     9227   -----   --------                             --------
     9228     16    WBShiftAB                            int8s
     9229     17    WBShiftMG                            int8s
     9230
     9231=head3 Pentax EVStepInfo Tags
     9232
     9233   Index   Tag Name                             Writable
     9234   -----   --------                             --------
     9235      0    EVSteps                              int8u
     9236      1    SensitivitySteps                     int8u
     9237
     9238=head3 Pentax ShotInfo Tags
     9239
     9240   Index   Tag Name                             Writable
     9241   -----   --------                             --------
     9242      1    CameraOrientation                    int8u
     9243
     9244=head3 Pentax FacePos Tags
     9245
     9246   Index   Tag Name                             Writable
     9247   -----   --------                             --------
     9248      0    Face1Position                        int16u[2]
     9249      2    Face2Position                        int16u[2]
     9250      4    Face3Position                        int16u[2]
     9251      6    Face4Position                        int16u[2]
     9252      8    Face5Position                        int16u[2]
     9253     10    Face6Position                        int16u[2]
     9254     12    Face7Position                        int16u[2]
     9255     14    Face8Position                        int16u[2]
     9256     16    Face9Position                        int16u[2]
     9257     18    Face10Position                       int16u[2]
     9258     20    Face11Position                       int16u[2]
     9259     22    Face12Position                       int16u[2]
     9260     24    Face13Position                       int16u[2]
     9261     26    Face14Position                       int16u[2]
     9262     28    Face15Position                       int16u[2]
     9263     30    Face16Position                       int16u[2]
     9264     32    Face17Position                       int16u[2]
     9265     34    Face18Position                       int16u[2]
     9266     36    Face19Position                       int16u[2]
     9267     38    Face20Position                       int16u[2]
     9268     40    Face21Position                       int16u[2]
     9269     42    Face22Position                       int16u[2]
     9270     44    Face23Position                       int16u[2]
     9271     46    Face24Position                       int16u[2]
     9272     48    Face25Position                       int16u[2]
     9273     50    Face26Position                       int16u[2]
     9274     52    Face27Position                       int16u[2]
     9275     54    Face28Position                       int16u[2]
     9276     56    Face29Position                       int16u[2]
     9277     58    Face30Position                       int16u[2]
     9278     60    Face31Position                       int16u[2]
     9279     62    Face32Position                       int16u[2]
     9280
     9281=head3 Pentax FaceSize Tags
     9282
     9283   Index   Tag Name                             Writable
     9284   -----   --------                             --------
     9285      0    Face1Size                            int16u[2]
     9286      2    Face2Size                            int16u[2]
     9287      4    Face3Size                            int16u[2]
     9288      6    Face4Size                            int16u[2]
     9289      8    Face5Size                            int16u[2]
     9290     10    Face6Size                            int16u[2]
     9291     12    Face7Size                            int16u[2]
     9292     14    Face8Size                            int16u[2]
     9293     16    Face9Size                            int16u[2]
     9294     18    Face10Size                           int16u[2]
     9295     20    Face11Size                           int16u[2]
     9296     22    Face12Size                           int16u[2]
     9297     24    Face13Size                           int16u[2]
     9298     26    Face14Size                           int16u[2]
     9299     28    Face15Size                           int16u[2]
     9300     30    Face16Size                           int16u[2]
     9301     32    Face17Size                           int16u[2]
     9302     34    Face18Size                           int16u[2]
     9303     36    Face19Size                           int16u[2]
     9304     38    Face20Size                           int16u[2]
     9305     40    Face21Size                           int16u[2]
     9306     42    Face22Size                           int16u[2]
     9307     44    Face23Size                           int16u[2]
     9308     46    Face24Size                           int16u[2]
     9309     48    Face25Size                           int16u[2]
     9310     50    Face26Size                           int16u[2]
     9311     52    Face27Size                           int16u[2]
     9312     54    Face28Size                           int16u[2]
     9313     56    Face29Size                           int16u[2]
     9314     58    Face30Size                           int16u[2]
     9315     60    Face31Size                           int16u[2]
     9316     62    Face32Size                           int16u[2]
     9317
     9318=head3 Pentax FilterInfo Tags
     9319
     9320The parameters associated with each type of digital filter are unique, and
     9321these settings are also extracted with the DigitalFilter tag.  Information
     9322is not extracted for filters that are "Off" unless the Unknown option is
     9323used.
     9324
     9325   Index   Tag Name                             Writable
     9326   -----   --------                             --------
     9327      0    SourceDirectoryIndex                 int16u
     9328      2    SourceFileIndex                      int16u
     9329      5    DigitalFilter01                      undef[17]
     9330     22    DigitalFilter02                      undef[17]
     9331     39    DigitalFilter03                      undef[17]
     9332     56    DigitalFilter04                      undef[17]
     9333     73    DigitalFilter05                      undef[17]
     9334     90    DigitalFilter06                      undef[17]
     9335    107    DigitalFilter07                      undef[17]
     9336    124    DigitalFilter08                      undef[17]
     9337    141    DigitalFilter09                      undef[17]
     9338    158    DigitalFilter10                      undef[17]
     9339    175    DigitalFilter11                      undef[17]
     9340    192    DigitalFilter12                      undef[17]
     9341    209    DigitalFilter13                      undef[17]
     9342    226    DigitalFilter14                      undef[17]
     9343    243    DigitalFilter15                      undef[17]
     9344    260    DigitalFilter16                      undef[17]
     9345    277    DigitalFilter17                      undef[17]
     9346    294    DigitalFilter18                      undef[17]
     9347    311    DigitalFilter19                      undef[17]
     9348    328    DigitalFilter20                      undef[17]
     9349
     9350=head3 Pentax LevelInfo Tags
     9351
     9352Tags decoded from the electronic level information.
     9353
     9354   Index   Tag Name                             Writable
     9355   -----   --------                             --------
     9356      0    LevelOrientation                     int8s & 0x0f
     9357    0.1    CompositionAdjust                    int8s & 0xf0
     9358      1    RollAngle                            int8s
     9359      2    PitchAngle                           int8s
     9360      5    CompositionAdjustX                   int8s
     9361      6    CompositionAdjustY                   int8s
     9362      7    CompositionAdjustRotation            int8s
     9363
     9364=head3 Pentax TempInfoK5 Tags
     9365
     9366A number of additional temperature readings are extracted from this 256-byte
     9367binary-data block in images from the K-5.  It is not currently known where
     9368the corresponding temperature sensors are located in the camera.
     9369
     9370   Index   Tag Name                             Writable
     9371   -----   --------                             --------
     9372     12    CameraTemperature2                   int16s
     9373     14    CameraTemperature3                   int16s
     9374     20    CameraTemperature4                   int16s
     9375     22    CameraTemperature5                   int16s
     9376
     9377=head3 Pentax UnknownInfo Tags
     9378
     9379   Index   Tag Name                             Writable
     9380   -----   --------                             --------
     9381  [no tags known]
    46589382
    46599383=head3 Pentax Type2 Tags
     
    46829406
    46839407The following few tags are extracted from the wealth of information
    4684 available in maker notes of the Optio E20.  These maker notes are stored as
    4685 ASCII text in a format very similar to some HP models.
     9408available in maker notes of the Optio E20 and E25.  These maker notes are
     9409stored as ASCII text in a format very similar to some HP models.
    46869410
    46879411  Tag ID               Tag Name                 Writable
     
    46919415=head3 Pentax MOV Tags
    46929416
    4693 This information is found in Pentax MOV video images.
     9417This information is found in Pentax MOV videos.
    46949418
    46959419   Index   Tag Name                             Writable
     
    47039427    175    ISO                                  N
    47049428
     9429=head3 Pentax Junk Tags
     9430
     9431Tags found in the JUNK chunk of AVI videos from the RS1000.
     9432
     9433   Index   Tag Name                             Writable
     9434   -----   --------                             --------
     9435     12    Model                                N
     9436
     9437=head3 Pentax AVI Tags
     9438
     9439Pentax-specific RIFF tags found in AVI videos.
     9440
     9441  Tag ID   Tag Name                             Writable
     9442  ------   --------                             --------
     9443  'hymn'   MakerNotes                           Pentax
     9444
     9445=head2 Reconyx Tags
     9446
     9447The following tags are extracted from the maker notes of Reconyx Hyperfire
     9448cameras such as the HC500, HC600 and PC900.
     9449
     9450   Index   Tag Name                             Writable
     9451   -----   --------                             --------
     9452      0    MakerNoteVersion                     N
     9453      1    FirmwareVersion                      N
     9454      4    FirmwareDate                         int16u[2]
     9455      6    TriggerMode                          string[2]
     9456      7    Sequence                             int16u[2]
     9457      9    EventNumber                          int16u[2]
     9458     11    DateTimeOriginal                     int16u[6]
     9459     18    MoonPhase                            int16u
     9460     19    AmbientTemperatureFahrenheit         int16u
     9461     20    AmbientTemperature                   int16u
     9462     21    SerialNumber                         undef[30]
     9463     36    Contrast                             int16u
     9464     37    Brightness                           int16u
     9465     38    Sharpness                            int16u
     9466     39    Saturation                           int16u
     9467     40    InfraredIlluminator                  int16u
     9468     41    MotionSensitivity                    int16u
     9469     42    BatteryVoltage                       int16u
     9470     43    UserLabel                            string[22]
     9471
    47059472=head2 Ricoh Tags
    4706 
    4707 These tags are used by Ricoh Caplio camera models.
    47089473
    47099474  Tag ID   Tag Name                             Writable
    47109475  ------   --------                             --------
    47119476  0x0001   MakerNoteType                        string
    4712   0x0002   MakerNoteVersion                     string
     9477  0x0002   FirmwareVersion                      string
     9478  0x0005   SerialNumber                         undef[16]
     9479           InternalSerialNumber                 undef[16]
    47139480  0x0e00   PrintIM                              PrintIM
    47149481  0x1001   ImageInfo                            Ricoh ImageInfo
     
    47379504  Tag ID   Tag Name                             Writable
    47389505  ------   --------                             --------
    4739   0x0004   RicohDateTime1                       N
    4740   0x0005   RicohDateTime2                       N
     9506  0x0004   ManufactureDate1                     string[20]
     9507  0x0005   ManufactureDate2                     string[20]
     9508  0x001a   FaceInfo                             Ricoh FaceInfo
     9509  0x0029   FirmwareInfo                         Ricoh FirmwareInfo
     9510  0x002a   NoiseReduction                       int32u
     9511  0x002c   SerialInfo                           Ricoh SerialInfo
     9512
     9513=head3 Ricoh FaceInfo Tags
     9514
     9515   Index   Tag Name                             Writable
     9516   -----   --------                             --------
     9517    181    FacesDetected                        int8u
     9518    182    FaceDetectFrameSize                  int16u[2]
     9519    188    Face1Position                        int16u[4]
     9520    200    Face2Position                        int16u[4]
     9521    212    Face3Position                        int16u[4]
     9522    224    Face4Position                        int16u[4]
     9523    236    Face5Position                        int16u[4]
     9524    248    Face6Position                        int16u[4]
     9525    260    Face7Position                        int16u[4]
     9526    272    Face8Position                        int16u[4]
     9527
     9528=head3 Ricoh FirmwareInfo Tags
     9529
     9530   Index   Tag Name                             Writable
     9531   -----   --------                             --------
     9532      0    FirmwareRevision                     string[12]
     9533     12    FirmwareRevision2                    string[12]
     9534
     9535=head3 Ricoh SerialInfo Tags
     9536
     9537This information is found in images from the GXR.
     9538
     9539   Index   Tag Name                             Writable
     9540   -----   --------                             --------
     9541      0    BodyFirmware                         string[16]
     9542     16    BodySerialNumber                     string[16]
     9543     32    LensFirmware                         string[16]
     9544     48    LensSerialNumber                     string[16]
    47419545
    47429546=head3 Ricoh Text Tags
    47439547
    4744 Ricoh RDC models such as the RDC-i700, RDC-5000, RDC-6000, RDC-7 and
    4745 RDC-4300 use a text-based format for their maker notes instead of the IFD
    4746 format used by the Caplio models.  Below is a list of known tags in this
    4747 information.
     9548Some Ricoh DC and RDC models use a text-based format for their maker notes
     9549instead of the IFD format used by the Caplio models.  Below is a list of known
     9550tags in this information.
    47489551
    47499552  Tag ID   Tag Name                             Writable
     
    47519554  'Bg'     BlueGain                             N
    47529555  'Gg'     GreenGain                            N
    4753   'Rev'    Revision                             N
     9556  'Rev'    FirmwareVersion                      N
    47549557  'Rg'     RedGain                              N
    4755   'Rv'     Revision                             N
     9558  'Rv'     FirmwareVersion                      N
    47569559
    47579560=head3 Ricoh RMETA Tags
     
    47689571  'Location'           Location                 N
    47699572  'Sign type'          SignType                 N
     9573
     9574=head3 Ricoh AVI Tags
     9575
     9576  Tag ID   Tag Name                             Writable
     9577  ------   --------                             --------
     9578  'mnrt'   MakerNoteRicoh                       Ricoh
     9579  'rdc2'   RicohRDC2?                           N
     9580  'thum'   ThumbnailImage                       N
     9581  'ucmt'   Comment                              N
     9582
     9583=head2 Samsung Tags
     9584
     9585=head3 Samsung Type1 Tags
     9586
     9587Tags found in the binary "STMN" format maker notes written by a number of
     9588Samsung models.
     9589
     9590   Index   Tag Name                             Writable
     9591   -----   --------                             --------
     9592      0    MakerNoteVersion                     undef[8]
     9593      2    PreviewImageStart                    int32u*
     9594      3    PreviewImageLength                   int32u*
     9595
     9596=head3 Samsung Type2 Tags
     9597
     9598Tags found in the EXIF-format maker notes of newer Samsung models.
     9599
     9600  Tag ID   Tag Name                             Writable
     9601  ------   --------                             --------
     9602  0x0001   MakerNoteVersion                     undef[4]
     9603  0x0021   PictureWizard                        int16u[5]
     9604  0x0030   LocalLocationName                    string
     9605  0x0031   LocationName                         string
     9606  0x0035   PreviewIFD                           Nikon PreviewIFD
     9607  0x0043   CameraTemperature                    rational64s
     9608  0xa001   FirmwareName                         string
     9609  0xa003   LensType                             int16u
     9610  0xa004   LensFirmware                         string
     9611  0xa010   SensorAreas                          int32u[8]
     9612  0xa011   ColorSpace                           int16u
     9613  0xa012   SmartRange                           int16u
     9614  0xa013   ExposureCompensation                 rational64s
     9615  0xa014   ISO                                  int32u
     9616  0xa018   ExposureTime                         rational64u
     9617  0xa019   FNumber                              rational64u
     9618  0xa01a   FocalLengthIn35mmFormat              int32u
     9619  0xa020   EncryptionKey                        int32u[11]!
     9620  0xa021   WB_RGGBLevelsUncorrected             int32u[4]
     9621  0xa022   WB_RGGBLevelsAuto                    int32u[4]
     9622  0xa023   WB_RGGBLevelsIlluminator1            int32u[4]
     9623  0xa024   WB_RGGBLevelsIlluminator2            int32u[4]
     9624  0xa028   WB_RGGBLevelsBlack                   int32s[4]
     9625  0xa030   ColorMatrix                          int32s[9]
     9626  0xa031   ColorMatrixSRGB                      int32s[9]
     9627  0xa032   ColorMatrixAdobeRGB                  int32s[9]
     9628  0xa040   ToneCurve1                           int32u[23]
     9629  0xa041   ToneCurve2                           int32u[23]
     9630  0xa042   ToneCurve3                           int32u[23]
     9631  0xa043   ToneCurve4                           int32u[23]
     9632
     9633=head3 Samsung INFO Tags
     9634
     9635This information is found in MP4 videos from Samsung models such as the
     9636SMX-C20N.
     9637
     9638  Tag ID   Tag Name                             Writable
     9639  ------   --------                             --------
     9640  'EFCT'   Effect                               N
     9641  'QLTY'   Quality                              N
     9642
     9643=head3 Samsung MP4 Tags
     9644
     9645This information is found in Samsung MP4 videos from models such as the
     9646WP10.
     9647
     9648   Index   Tag Name                             Writable
     9649   -----   --------                             --------
     9650      0    Make                                 N
     9651     24    Model                                N
     9652     46    ExposureTime                         N
     9653     50    FNumber                              N
     9654     58    ExposureCompensation                 N
     9655    106    ISO                                  N
     9656    125    Software                             N
     9657    248    ThumbnailWidth                       N
     9658    252    ThumbnailHeight                      N
     9659    256    ThumbnailLength                      N
     9660    260    ThumbnailOffset                      N
    47709661
    47719662=head2 Sanyo Tags
     
    47969687  0x021f   SceneSelect                          int16u
    47979688  0x0223   ManualFocusDistance                  rational64u
     9689           FaceInfo                             -
    47989690  0x0224   SequenceShotInterval                 int16u
    47999691  0x0225   FlashMode                            int16u
     
    48019693  0x0f00   DataDump                             N
    48029694
     9695=head3 Sanyo FaceInfo Tags
     9696
     9697   Index   Tag Name                             Writable
     9698   -----   --------                             --------
     9699      0    FacesDetected                        int32u
     9700      4    FacePosition                         int32u[4]
     9701
    48039702=head3 Sanyo MOV Tags
    48049703
    4805 This information is found in Sanyo MOV video images, and is very similar to
    4806 information found in Pentax MOV and Nikon QT videos.
     9704This information is found in Sanyo MOV videos.
    48079705
    48089706   Index   Tag Name                             Writable
     
    48189716=head3 Sanyo MP4 Tags
    48199717
    4820 This information is found in Sanyo MP4 video images.
     9718This information is found in Sanyo MP4 videos.
    48219719
    48229720   Index   Tag Name                             Writable
     
    48259723     24    Model                                N
    48269724     50    FNumber                              N
     9725     58    ExposureCompensation                 N
    48279726    106    ISO                                  N
    4828    2048    ThumbnailImage                       N
     9727    209    Software                             N
     9728    210    Software                             N
     9729    253    ThumbnailLength                      N
     9730    254    ThumbnailLength                      N
     9731    257    ThumbnailOffset                      N
     9732    258    ThumbnailOffset                      N
    48299733
    48309734=head2 Sigma Tags
     
    48429746  0x0008   ExposureMode                         string
    48439747  0x0009   MeteringMode                         string
    4844   0x000a   Lens                                 string
     9748  0x000a   LensFocalRange                       string
    48459749  0x000b   ColorSpace                           string
    48469750  0x000c   ExposureCompensation                 string
    4847            UnknownCompensation?                 rational64s
     9751           ExposureAdjust?                      rational64s
    48489752  0x000d   Contrast                             string
    48499753           Contrast                             rational64s
     
    48659769  0x0018   Software                             string
    48669770  0x0019   AutoBracket                          string
    4867   0x001d   MakerNoteVersion                     string
    4868   0x0022   AdjustmentMode?                      string
     9771  0x001a   PreviewImageStart                    int32u*
     9772           ChrominanceNoiseReduction            string
     9773  0x001b   PreviewImageLength                   int32u*
     9774           LuminanceNoiseReduction              string
     9775  0x001c   PreviewImageSize                     int16u[2]
     9776  0x001d   MakerNoteVersion                     undef
     9777  0x001f   AFPoint                              string
     9778  0x0022   FileFormat                           string
     9779  0x0024   Calibration                          string
     9780  0x002c   ColorMode                            int32u
    48699781  0x0030   LensApertureRange                    string
    48709782  0x0031   FNumber                              rational64u
    48719783  0x0032   ExposureTime                         rational64u
     9784  0x0033   ExposureTime2                        string
     9785  0x0034   BurstShot                            int32u
    48729786  0x0035   ExposureCompensation                 rational64s
     9787  0x0039   SensorTemperature                    string
    48739788  0x003a   FlashExposureComp                    rational64s
    48749789  0x003b   Firmware                             string
    48759790  0x003c   WhiteBalance                         string
     9791  0x003d   PictureMode                          string
    48769792
    48779793=head2 Sony Tags
    48789794
    4879 The maker notes in images from current Sony camera models contain a wealth
    4880 of information, but very little is known about these tags.  Use the ExifTool
    4881 Unknown (-u) or Verbose (-v) options to see information about the unknown
    4882 tags.
     9795The maker notes in images from most recent Sony camera models contain a
     9796wealth of information, but for some models very little has been decoded.
     9797Use the ExifTool Unknown (-u) or Verbose (-v) options to see information
     9798about the unknown tags.  Also see the Minolta tags which are used by some
     9799Sony models.
    48839800
    48849801  Tag ID   Tag Name                             Writable
    48859802  ------   --------                             --------
     9803  0x0102   Quality                              int32u
     9804  0x0104   FlashExposureComp                    rational64s
     9805  0x0105   Teleconverter                        int32u
     9806  0x0112   WhiteBalanceFineTune                 int32u
     9807  0x0114   CameraSettings                       Sony CameraSettings
     9808           CameraSettings2                      Sony CameraSettings2
     9809           CameraSettingsUnknown                Sony CameraSettingsUnknown
     9810  0x0115   WhiteBalance                         int32u
    48869811  0x0e00   PrintIM                              PrintIM
    4887   0xb021   ColorTemperature                     N
    4888   0xb023   SceneMode                            N
    4889   0xb024   ZoneMatching                         N
    4890   0xb025   DynamicRangeOptimizer                N
    4891   0xb026   ImageStabilization                   N
    4892   0xb027   LensID                               N
     9812  0x1000   MultiBurstMode                       undef
     9813  0x1001   MultiBurstImageWidth                 int16u
     9814  0x1002   MultiBurstImageHeight                int16u
     9815  0x1003   Panorama                             Sony Panorama
     9816  0x2001   PreviewImage                         undef
     9817  0x2004   Contrast                             int32s
     9818  0x2005   Saturation                           int32s
     9819  0x2006   Sharpness                            int32s
     9820  0x2007   Brightness                           int32s
     9821  0x2008   LongExposureNoiseReduction           int32u
     9822  0x2009   HighISONoiseReduction                int16u
     9823  0x200a   HDR                                  int32u
     9824  0x200b   MultiFrameNoiseReduction             int32u
     9825  0x3000   ShotInfo                             Sony ShotInfo
     9826  0xb000   FileFormat                           int8u[4]
     9827  0xb001   SonyModelID                          int16u
     9828  0xb020   ColorReproduction                    string
     9829  0xb021   ColorTemperature                     int32u
     9830  0xb022   ColorCompensationFilter              int32u
     9831  0xb023   SceneMode                            int32u
     9832  0xb024   ZoneMatching                         int32u
     9833  0xb025   DynamicRangeOptimizer                int32u
     9834  0xb026   ImageStabilization                   int32u
     9835  0xb027   LensType                             int32u
    48939836  0xb028   MinoltaMakerNote                     Minolta
    48949837  0xb029   ColorMode                            int32u
    4895   0xb040   Macro                                N
    4896   0xb041   ExposureMode                         N
    4897   0xb047   Quality                              N
    4898   0xb04e   LongExposureNoiseReduction           N
    4899 
    4900 =head3 Sony SRF Tags
    4901 
    4902 The maker notes in SRF (Sony Raw Format) images contain 7 IFD's (with family
    4903 1 group names SRF0 through SRF6).  SRF0 through SRF5 use these Sony tags,
    4904 while SRF6 uses standard EXIF tags.  All information other than SRF0 is
    4905 encrypted, but thanks to Dave Coffin the decryption algorithm is known.
     9838  0xb02b   FullImageSize                        int32u[2]
     9839  0xb02c   PreviewImageSize                     int32u[2]
     9840  0xb040   Macro                                int16u
     9841  0xb041   ExposureMode                         int16u
     9842  0xb042   FocusMode                            int16u
     9843  0xb043   AFMode                               int16u
     9844  0xb044   AFIlluminator                        int16u
     9845  0xb047   Quality                              int16u
     9846  0xb048   FlashLevel                           int16s
     9847  0xb049   ReleaseMode                          int16u
     9848  0xb04a   SequenceNumber                       int16u
     9849  0xb04b   Anti-Blur                            int16u
     9850  0xb04e   LongExposureNoiseReduction           int16u
     9851  0xb04f   DynamicRangeOptimizer                int16u
     9852  0xb052   IntelligentAuto                      int16u
     9853  0xb054   WhiteBalance                         int16u
     9854
     9855=head3 Sony CameraSettings Tags
     9856
     9857Camera settings for the A200, A230, A300, A350, A700, A850 and A900.  Some
     9858tags are only valid for certain models.
     9859
     9860   Index   Tag Name                             Writable
     9861   -----   --------                             --------
     9862      4    DriveMode                            int16u
     9863      6    WhiteBalanceFineTune                 int16s
     9864     16    FocusMode                            int16u
     9865     17    AFAreaMode                           int16u
     9866     18    LocalAFAreaPoint                     int16u
     9867     21    MeteringMode                         int16u
     9868     22    ISOSetting                           int16u
     9869     24    DynamicRangeOptimizerMode            int16u
     9870     25    DynamicRangeOptimizerLevel           int16u
     9871     26    CreativeStyle                        int16u
     9872     28    Sharpness                            int16u
     9873     29    Contrast                             int16u
     9874     30    Saturation                           int16u
     9875     31    ZoneMatchingValue                    int16u
     9876     34    Brightness                           int16u
     9877     35    FlashMode                            int16u
     9878     40    PrioritySetupShutterRelease          int16u
     9879     41    AFIlluminator                        int16u
     9880     42    AFWithShutter                        int16u
     9881     43    LongExposureNoiseReduction           int16u
     9882     44    HighISONoiseReduction                int16u
     9883     45    ImageStyle                           int16u
     9884     60    ExposureProgram                      int16u
     9885     61    ImageStabilization                   int16u
     9886     63    Rotation                             int16u
     9887     84    SonyImageSize                        int16u
     9888     85    AspectRatio                          int16u
     9889     86    Quality                              int16u
     9890     88    ExposureLevelIncrements              int16u
     9891
     9892=head3 Sony CameraSettings2 Tags
     9893
     9894Camera settings for the A330 and A380.
     9895
     9896   Index   Tag Name                             Writable
     9897   -----   --------                             --------
     9898     16    FocusMode                            int16u
     9899     17    AFAreaMode                           int16u
     9900     18    LocalAFAreaPoint                     int16u
     9901     19    MeteringMode                         int16u
     9902     20    ISOSetting                           int16u
     9903     22    DynamicRangeOptimizerMode            int16u
     9904     23    DynamicRangeOptimizerLevel           int16u
     9905     24    CreativeStyle                        int16u
     9906     25    Sharpness                            int16u
     9907     26    Contrast                             int16u
     9908     27    Saturation                           int16u
     9909     35    FlashMode                            int16u
     9910     60    ExposureProgram                      int16u
     9911     63    Rotation                             int16u
     9912     84    SonyImageSize                        int16u
     9913
     9914=head3 Sony CameraSettingsUnknown Tags
     9915
     9916   Index   Tag Name                             Writable
     9917   -----   --------                             --------
     9918  [no tags known]
     9919
     9920=head3 Sony Panorama Tags
     9921
     9922Tags found only in panorama images from Sony cameras such as the HX1, HX5
     9923and TX7.  The width/height values of these tags are not affected by camera
     9924rotation -- the width is always the longer dimension.
     9925
     9926   Index   Tag Name                             Writable
     9927   -----   --------                             --------
     9928      1    PanoramaFullWidth                    int32u
     9929      2    PanoramaFullHeight                   int32u
     9930      3    PanoramaDirection                    int32u
     9931      4    PanoramaCropLeft                     int32u
     9932      5    PanoramaCropTop                      int32u
     9933      6    PanoramaCropRight                    int32u
     9934      7    PanoramaCropBottom                   int32u
     9935      8    PanoramaFrameWidth                   int32u
     9936      9    PanoramaFrameHeight                  int32u
     9937     10    PanoramaSourceWidth                  int32u
     9938     11    PanoramaSourceHeight                 int32u
     9939
     9940=head3 Sony ShotInfo Tags
     9941
     9942   Index   Tag Name                             Writable
     9943   -----   --------                             --------
     9944      2    FaceInfoOffset                       N
     9945      6    SonyDateTime                         string[20]
     9946     48    FacesDetected                        int16u
     9947     50    FaceInfoLength                       N
     9948     72    FaceInfo1                            Sony FaceInfo1
     9949     94    FaceInfo2                            Sony FaceInfo2
     9950
     9951=head3 Sony FaceInfo1 Tags
     9952
     9953   Index   Tag Name                             Writable
     9954   -----   --------                             --------
     9955      0    Face1Position                        int16u[4]
     9956     32    Face2Position                        int16u[4]
     9957     64    Face3Position                        int16u[4]
     9958     96    Face4Position                        int16u[4]
     9959    128    Face5Position                        int16u[4]
     9960    160    Face6Position                        int16u[4]
     9961    192    Face7Position                        int16u[4]
     9962    224    Face8Position                        int16u[4]
     9963
     9964=head3 Sony FaceInfo2 Tags
     9965
     9966   Index   Tag Name                             Writable
     9967   -----   --------                             --------
     9968      0    Face1Position                        int16u[4]
     9969     37    Face2Position                        int16u[4]
     9970     74    Face3Position                        int16u[4]
     9971    111    Face4Position                        int16u[4]
     9972    148    Face5Position                        int16u[4]
     9973    185    Face6Position                        int16u[4]
     9974    222    Face7Position                        int16u[4]
     9975    259    Face8Position                        int16u[4]
     9976
     9977=head3 Sony Ericsson Tags
     9978
     9979Maker notes found in images from some Sony Ericsson phones.
    49069980
    49079981  Tag ID   Tag Name                             Writable
    49089982  ------   --------                             --------
    4909   0x0000   SRF2_Key                             N
     9983  0x0201   PreviewImageStart                    int32u*
     9984  0x0202   PreviewImageLength                   int32u*
     9985  0x2000   MakerNoteVersion                     undef[4]
     9986
     9987=head3 Sony SRF Tags
     9988
     9989The maker notes in SRF (Sony Raw Format) images contain 7 IFD's with family
     99901 group names SRF0 through SRF6.  SRF0 and SRF1 use the tags in this table,
     9991while SRF2 through SRF5 use the tags in the next table, and SRF6 uses
     9992standard EXIF tags.  All information other than SRF0 is encrypted, but
     9993thanks to Dave Coffin the decryption algorithm is known.  SRF images are
     9994written by the Sony DSC-F828 and DSC-V3.
     9995
     9996  Tag ID   Tag Name                             Writable
     9997  ------   --------                             --------
     9998  0x0000   SRF2Key                              N
    49109999  0x0001   DataKey                              N
    491110000
     10001=head3 Sony SRF2 Tags
     10002
     10003These tags are found in the SRF2 through SRF5 IFD's.
     10004
     10005  Tag ID   Tag Name                             Writable
     10006  ------   --------                             --------
     10007  0x0002   SRF6Offset                           N
     10008  0x0003   SRFDataOffset?                       N
     10009  0x0004   RawDataOffset                        N
     10010  0x0005   RawDataLength                        N
     10011
    491210012=head3 Sony SR2Private Tags
    491310013
    491410014The SR2 format uses the DNGPrivateData tag to reference a private IFD
    4915 containing these tags.
     10015containing these tags.  SR2 images are written by the Sony DSC-R1, but
     10016this information is also written to ARW images by other models.
    491610017
    491710018  Tag ID   Tag Name                             Writable
     
    492010021  0x7201   SR2SubIFDLength                      N
    492110022  0x7221   SR2SubIFDKey                         N
     10023  0x7240   IDC_IFD                              SonyIDC
     10024  0x7241   IDC2_IFD                             SonyIDC
     10025  0x7250   MRWInfo                              MinoltaRaw
    492210026
    492310027=head3 Sony SR2SubIFD Tags
     
    492810032  ------   --------                             --------
    492910033  0x7303   WB_GRBGLevels                        N
     10034  0x7313   WB_RGGBLevels                        N
    493010035  0x74a0   MaxApertureAtMaxFocal                N
    493110036  0x74a1   MaxApertureAtMinFocal                N
    493210037  0x74c0   SR2DataIFD                           Sony SR2DataIFD
     10038  0x7820   WB_RGBLevelsDaylight                 N
     10039  0x7821   WB_RGBLevelsCloudy                   N
     10040  0x7822   WB_RGBLevelsTungsten                 N
     10041  0x7825   WB_RGBLevelsShade                    N
     10042  0x7826   WB_RGBLevelsFluorescent              N
     10043  0x7828   WB_RGBLevelsFlash                    N
    493310044
    493410045=head3 Sony SR2DataIFD Tags
     
    493810049  0x7770   ColorMode                            N
    493910050
     10051=head3 Sony PMP Tags
     10052
     10053These tags are written in the proprietary-format header of PMP images from
     10054the DSC-F1.
     10055
     10056   Index   Tag Name                             Writable
     10057   -----   --------                             --------
     10058      8    JpgFromRawStart                      N
     10059     12    JpgFromRawLength                     N
     10060     22    SonyImageWidth                       N
     10061     24    SonyImageHeight                      N
     10062     27    Orientation                          N
     10063     29    ImageQuality                         N
     10064     52    Comment                              N
     10065     76    DateTimeOriginal                     N
     10066     84    ModifyDate                           N
     10067    102    ExposureTime                         N
     10068    106    FNumber                              N
     10069    108    ExposureCompensation                 N
     10070    112    FocalLength                          N
     10071    118    Flash                                N
     10072
     10073=head2 SonyIDC Tags
     10074
     10075Tags written by the Sony Image Data Converter utility in ARW images.
     10076
     10077  Tag ID   Tag Name                             Writable
     10078  ------   --------                             --------
     10079  0x0201   IDCPreviewStart                      int32u*
     10080  0x0202   IDCPreviewLength                     int32u*
     10081  0x8000   IDCCreativeStyle                     int32u
     10082  0x8001   CreativeStyleWasChanged              int32u
     10083  0x8002   PresetWhiteBalance                   int32u
     10084  0x8013   ColorTemperatureAdj                  int16u
     10085  0x8014   PresetWhiteBalanceAdj                int32s
     10086  0x8015   ColorCorrection                      int32s
     10087  0x8016   SaturationAdj                        int32s
     10088  0x8017   ContrastAdj                          int32s
     10089  0x8018   BrightnessAdj                        int32s
     10090  0x8019   HueAdj                               int32s
     10091  0x801a   SharpnessAdj                         int32s
     10092  0x801b   SharpnessOvershoot                   int32s
     10093  0x801c   SharpnessUndershoot                  int32s
     10094  0x801d   SharpnessThreshold                   int32s
     10095  0x801e   NoiseReductionMode                   int16u
     10096  0x8021   GrayPoint                            int16u[4]
     10097  0x8022   D-RangeOptimizerMode                 int16u
     10098  0x8023   D-RangeOptimizerValue                int32s
     10099  0x8024   D-RangeOptimizerHighlight            int32s
     10100  0x8026   HighlightColorDistortReduct          int16u
     10101  0x8027   NoiseReductionValue                  int32s
     10102  0x8028   EdgeNoiseReduction                   int32s
     10103  0x8029   ColorNoiseReduction                  int32s
     10104  0x802d   D-RangeOptimizerShadow               int32s
     10105  0x8030   PeripheralIllumCentralRadius         int32s
     10106  0x8031   PeripheralIllumCentralValue          int32s
     10107  0x8032   PeripheralIllumPeriphValue           int32s
     10108  0x9000   ToneCurveBrightnessX                 int16u[n]
     10109  0x9001   ToneCurveRedX                        int16u[n]
     10110  0x9002   ToneCurveGreenX                      int16u[n]
     10111  0x9003   ToneCurveBlueX                       int16u[n]
     10112  0x9004   ToneCurveBrightnessY                 int16u[n]
     10113  0x9005   ToneCurveRedY                        int16u[n]
     10114  0x9006   ToneCurveGreenY                      int16u[n]
     10115  0x9007   ToneCurveBlueY                       int16u[n]
     10116  0xd000   CurrentVersion                       int32u
     10117  0xd001   VersionIFD                           SonyIDC
     10118  0xd100   VersionCreateDate                    string
     10119  0xd101   VersionModifyDate                    string
     10120
    494010121=head2 Unknown Tags
    494110122
     
    495010131
    495110132The main DNG tags are found in the EXIF table.  The tables below define only
    4952 information found within structures of these main DNG tag values.
     10133information found within structures of these main DNG tag values.  See
     10134L<http://www.adobe.com/products/dng/> for the official DNG specification.
    495310135
    495410136=head3 DNG AdobeData Tags
     
    495810140The maker notes ('MakN') are processed by ExifTool, but some information may
    495910141have been lost by the Adobe DNG Converter.  This is because the Adobe DNG
    4960 Converter (as of version 3.3) doesn't properly handle information referenced
     10142Converter (as of version 6.3) doesn't properly handle information referenced
    496110143from inside the maker notes that lies outside the original maker notes
    4962 block, and this information is lost when only the maker note block is copied
    4963 to the DNG image.   While this isn't a big problem for most camera makes, it
    4964 is serious for some makes like Olympus.
    4965 
    4966 The CRW data is from DNG-converted CRW images, but it has been restructured
    4967 to a proprietary Adobe format (which results in a loss of the original
    4968 hierarchical information structure, and creates extra work for everyone else
    4969 who wants to use this information).
     10144block.  This information is lost when only the maker note block is copied to
     10145the DNG image.   While this doesn't effect all makes of cameras, it is a
     10146problem for some major brands such as Olympus and Sony.
     10147
     10148Other entries in this table represent proprietary information that is
     10149extracted from the original RAW image and restructured to a different (but
     10150still proprietary) Adobe format.
    497010151
    497110152  Tag ID   Tag Name                             Writable
    497210153  ------   --------                             --------
    497310154  'CRW '   AdobeCRW                             CanonRaw
     10155  'Koda'   AdobeKoda                            Kodak IFD
     10156  'Leaf'   AdobeLeaf                            Leaf SubIFD
    497410157  'MRW '   AdobeMRW                             MinoltaRaw
    497510158  'MakN'   MakerNoteCanon                       Canon
     
    497710160           MakerNoteCasio2                      Casio Type2
    497810161           MakerNoteFujiFilm                    FujiFilm
     10162           MakerNoteGE                          GE
     10163           MakerNoteGE2                         FujiFilm
    497910164           MakerNoteHP                          HP
    498010165           MakerNoteHP2                         HP Type2
    498110166           MakerNoteHP4                         HP Type4
    498210167           MakerNoteHP6                         HP Type6
     10168           MakerNoteISL                         Unknown
    498310169           MakerNoteJVC                         JVC
    498410170           MakerNoteJVCText                     JVC Text
     
    499210178           MakerNoteKodak6b                     Kodak Type6
    499310179           MakerNoteKodak7                      Kodak Type7
    4994            MakerNoteKodakIFD                    Kodak IFD
     10180           MakerNoteKodak8a                     Kodak Type8
     10181           MakerNoteKodak8b                     Kodak Type8
     10182           MakerNoteKodak9                      Kodak Type9
     10183           MakerNoteKodak10                     Kodak Type10
    499510184           MakerNoteKodakUnknown                Kodak Unknown
    499610185           MakerNoteKyocera                     Unknown
     
    500410193           MakerNoteOlympus2                    Olympus
    500510194           MakerNoteLeica                       Panasonic
     10195           MakerNoteLeica2                      Panasonic Leica2
     10196           MakerNoteLeica3                      Panasonic Leica3
     10197           MakerNoteLeica4                      Panasonic Leica4
     10198           MakerNoteLeica5                      Panasonic Leica5
     10199           MakerNoteLeica6                      Panasonic Leica6
    500610200           MakerNotePanasonic                   Panasonic
    500710201           MakerNotePanasonic2                  Panasonic Type2
     
    501010204           MakerNotePentax3                     Casio Type2
    501110205           MakerNotePentax4                     Pentax Type4
     10206           MakerNotePentax5                     Pentax
     10207           MakerNotePhaseOne                    undef
     10208           MakerNoteReconyx                     Reconyx
    501210209           MakerNoteRicoh                       Ricoh
    501310210           MakerNoteRicohText                   Ricoh Text
    5014            PreviewImage                         undef
     10211           MakerNoteSamsung1a                   undef
     10212           MakerNoteSamsung1b                   Samsung Type1
     10213           MakerNoteSamsung2                    Samsung Type2
    501510214           MakerNoteSanyo                       Sanyo
    501610215           MakerNoteSanyoC4                     Sanyo
     
    501810217           MakerNoteSigma                       Sigma
    501910218           MakerNoteSony                        Sony
     10219           MakerNoteSony2                       Olympus
     10220           MakerNoteSony3                       Olympus
     10221           MakerNoteSony4                       Sony
     10222           MakerNoteSonyEricsson                Sony Ericsson
    502010223           MakerNoteSonySRF                     Sony SRF
    5021            MakerNoteSonySR2                     Sony
     10224           MakerNoteUnknownText                 undef
    502210225           MakerNoteUnknown                     Unknown
    5023   'RAF '   AdobeRAF?                            N
     10226  'Pano'   AdobePano                            PanasonicRaw
     10227  'RAF '   AdobeRAF                             FujiFilm RAF
    502410228  'SR2 '   AdobeSR2                             Sony SR2Private
    502510229
     
    504710251or padded as required) unless B<Writable> is C<resize>. Currently, only
    504810252JpgFromRaw and ThumbnailImage are allowed to change size.
     10253
     10254CRW images also support the addition of a CanonVRD trailer, which in turn
     10255supports XMP.  This trailer is created automatically if necessary when
     10256ExifTool is used to write XMP to a CRW image.
    504910257
    505010258  Tag ID   Tag Name                             Writable
     
    507310281  0x102c   CanonColorInfo2                      N
    507410282  0x102d   CanonCameraSettings                  Canon CameraSettings
     10283  0x1030   WhiteSample                          CanonRaw WhiteSample
    507510284  0x1031   SensorInfo                           Canon SensorInfo
    507610285  0x1033   CustomFunctions10D                   CanonCustom Functions10D
     
    508910298  0x1807   TargetDistanceSetting                float
    509010299  0x180b   SerialNumber                         int32u
     10300           UnknownNumber?                       Y
    509110301  0x180e   TimeStamp                            CanonRaw TimeStamp
    509210302  0x1810   ImageInfo                            CanonRaw ImageInfo
     
    509610306  0x1818   ExposureInfo                         CanonRaw ExposureInfo
    509710307  0x1834   CanonModelID                         int32u
    5098   0x1835   DecoderTable                         N
     10308  0x1835   DecoderTable                         CanonRaw DecoderTable
    509910309  0x183b   SerialNumberFormat                   int32u
    510010310  0x2005   RawData                              N
     
    511410324   -----   --------                             --------
    511510325      0    Make                                 string[6]
    5116       6    Model                                string[$size-6]
     10326      6    Model                                string
     10327
     10328=head3 CanonRaw WhiteSample Tags
     10329
     10330   Index   Tag Name                             Writable
     10331   -----   --------                             --------
     10332      1    WhiteSampleWidth                     N
     10333      2    WhiteSampleHeight                    N
     10334      3    WhiteSampleLeftBorder                N
     10335      4    WhiteSampleTopBorder                 N
     10336      5    WhiteSampleBits                      N
    511710337
    511810338=head3 CanonRaw RawJpgInfo Tags
     
    516410384   -----   --------                             --------
    516510385      0    ExposureCompensation                 float
    5166       1    TvValue                              float
    5167       2    AvValue                              float
    5168 
    5169 =head2 MinoltaRaw Tags
    5170 
    5171 These tags are used in Minolta RAW format (MRW) images.
    5172 
    5173   Tag ID   Tag Name                             Writable
    5174   ------   --------                             --------
    5175   "\0PRD"  MinoltaPRD                           MinoltaRaw PRD
    5176   "\0RIF"  MinoltaRIF                           MinoltaRaw RIF
    5177   "\0TTW"  MinoltaTTW                           EXIF
    5178   "\0WBG"  MinoltaWBG                           MinoltaRaw WBG
    5179 
    5180 =head3 MinoltaRaw PRD Tags
    5181 
    5182    Index   Tag Name                             Writable
    5183    -----   --------                             --------
    5184       0    FirmwareID                           string[8]
    5185       8    SensorHeight                         int16u
    5186      10    SensorWidth                          int16u
    5187      12    ImageHeight                          int16u
    5188      14    ImageWidth                           int16u
    5189      16    RawDepth                             int8u
    5190      17    BitDepth                             int8u
    5191      18    StorageMethod                        int8u
    5192      23    BayerPattern                         int8u
    5193 
    5194 =head3 MinoltaRaw RIF Tags
    5195 
    5196    Index   Tag Name                             Writable
    5197    -----   --------                             --------
    5198       1    Saturation                           int8s
    5199       2    Contrast                             int8s
    5200       3    Sharpness                            int8s
    5201       4    WBMode                               int8u~
    5202       5    ProgramMode                          int8u
    5203       6    ISOSetting                           int8u
    5204       7    ColorMode                            int8u
    5205      56    ColorFilter                          int8s
    5206      57    BWFilter                             int8u
    5207      58    ZoneMatching                         int8u
    5208      59    Hue                                  int8s
    5209      60    ColorTemperature                     int8u
    5210 
    5211 =head3 MinoltaRaw WBG Tags
    5212 
    5213    Index   Tag Name                             Writable
    5214    -----   --------                             --------
    5215       0    WBScale                              int8u[4]
    5216       4    WBLevels                             int16u[4]
     10386      1    ShutterSpeedValue                    float
     10387      2    ApertureValue                        float
     10388
     10389=head3 CanonRaw DecoderTable Tags
     10390
     10391   Index   Tag Name                             Writable
     10392   -----   --------                             --------
     10393      0    DecoderTableNumber                   N
     10394      2    CompressedDataOffset                 N
     10395      3    CompressedDataLength                 N
    521710396
    521810397=head2 KyoceraRaw Tags
     
    523410413    124    Lens                                 N
    523510414
     10415=head2 MinoltaRaw Tags
     10416
     10417These tags are used in Minolta RAW format (MRW) images.
     10418
     10419  Tag ID   Tag Name                             Writable
     10420  ------   --------                             --------
     10421  "\0PRD"  MinoltaPRD                           MinoltaRaw PRD
     10422  "\0RIF"  MinoltaRIF                           MinoltaRaw RIF
     10423  "\0TTW"  MinoltaTTW                           EXIF
     10424  "\0WBG"  MinoltaWBG                           MinoltaRaw WBG
     10425
     10426=head3 MinoltaRaw PRD Tags
     10427
     10428   Index   Tag Name                             Writable
     10429   -----   --------                             --------
     10430      0    FirmwareID                           string[8]
     10431      8    SensorHeight                         int16u
     10432     10    SensorWidth                          int16u
     10433     12    ImageHeight                          int16u
     10434     14    ImageWidth                           int16u
     10435     16    RawDepth                             int8u
     10436     17    BitDepth                             int8u
     10437     18    StorageMethod                        int8u
     10438     23    BayerPattern                         int8u
     10439
     10440=head3 MinoltaRaw RIF Tags
     10441
     10442   Index   Tag Name                             Writable
     10443   -----   --------                             --------
     10444      1    Saturation                           int8s
     10445      2    Contrast                             int8s
     10446      3    Sharpness                            int8s
     10447      4    WBMode                               int8u~
     10448      5    ProgramMode                          int8u
     10449      6    ISOSetting                           int8u
     10450      7    ColorMode                            int32u[0.25]
     10451      8    WB_RBLevelsTungsten                  int16u[2]
     10452     12    WB_RBLevelsDaylight                  int16u[2]
     10453     16    WB_RBLevelsCloudy                    int16u[2]
     10454     20    WB_RBLevelsCoolWhiteF                int16u[2]
     10455     24    WB_RBLevelsFlash                     int16u[2]
     10456     28    WB_RBLevelsUnknown?                  int16u[2]
     10457     32    WB_RBLevelsShade                     int16u[2]
     10458     36    WB_RBLevelsDaylightF                 int16u[2]
     10459     40    WB_RBLevelsDayWhiteF                 int16u[2]
     10460     44    WB_RBLevelsWhiteF                    int16u[2]
     10461     56    ColorFilter                          int8s
     10462     57    BWFilter                             int8u
     10463     58    ZoneMatching                         int8u
     10464     59    Hue                                  int8s
     10465     60    ColorTemperature                     int8u
     10466     74    ZoneMatching                         int8u
     10467     76    ColorTemperature                     int8u
     10468     77    ColorFilter                          int8u
     10469     78    ColorTemperature                     int8u
     10470     79    ColorFilter                          int8u
     10471
     10472=head3 MinoltaRaw WBG Tags
     10473
     10474   Index   Tag Name                             Writable
     10475   -----   --------                             --------
     10476      0    WBScale                              int8u[4]
     10477      4    WB_GBRGLevels                        int16u[4]
     10478           WB_RGGBLevels                        int16u[4]
     10479
     10480=head2 PanasonicRaw Tags
     10481
     10482These tags are found in IFD0 of Panasonic/Leica RAW, RW2 and RWL images.
     10483
     10484  Tag ID   Tag Name                             Writable
     10485  ------   --------                             --------
     10486  0x0001   PanasonicRawVersion                  undef
     10487  0x0002   SensorWidth                          N
     10488  0x0003   SensorHeight                         N
     10489  0x0004   SensorTopBorder                      N
     10490  0x0005   SensorLeftBorder                     N
     10491  0x0006   ImageHeight                          N
     10492  0x0007   ImageWidth                           N
     10493  0x0011   RedBalance                           int16u
     10494  0x0012   BlueBalance                          int16u
     10495  0x0017   ISO                                  int16u
     10496  0x0024   WBRedLevel                           int16u
     10497  0x0025   WBGreenLevel                         int16u
     10498  0x0026   WBBlueLevel                          int16u
     10499  0x002e   JpgFromRaw                           JPEG
     10500  0x010f   Make                                 string
     10501  0x0110   Model                                string
     10502  0x0111   StripOffsets                         N
     10503  0x0112   Orientation                          int16u
     10504  0x0116   RowsPerStrip                         N
     10505  0x0117   StripByteCounts                      N
     10506  0x0118   RawDataOffset                        N
     10507  0x02bc   ApplicationNotes                     XMP
     10508  0x83bb   IPTC-NAA                             IPTC
     10509  0x8769   ExifOffset                           EXIF
     10510  0x8825   GPSInfo                              GPS
     10511
    523610512=head2 SigmaRaw Tags
    523710513
    5238 These tags are used in Sigma and Foveon RAW (.X3F) images.
     10514These tags are used in Sigma and Foveon RAW (.X3F) images.  Metadata is also
     10515extracted from the JpgFromRaw image if it exists (all models but the SD9 and
     10516SD10).  Currently, metadata may only be written to the embedded JpgFromRaw.
    523910517
    524010518  Tag ID               Tag Name                 Writable
     
    524310521  'HeaderExt'          HeaderExt                SigmaRaw HeaderExt
    524410522  'IMA2'               PreviewImage             N
     10523                       JpgFromRaw               N
    524510524  'IMAG'               PreviewImage             N
    524610525  'PROP'               Properties               SigmaRaw Properties
     
    525110530  ------   --------                             --------
    525210531  0x0001   FileVersion                          N
     10532  0x0002   ImageUniqueID                        N
     10533  0x0006   MarkBits                             N
    525310534  0x0007   ImageWidth                           N
    525410535  0x0008   ImageHeight                          N
    525510536  0x0009   Rotation                             N
    525610537  0x000a   WhiteBalance                         N
     10538  0x0012   SceneCaptureType                     N
    525710539
    525810540=head3 SigmaRaw HeaderExt Tags
     
    529010572  'CAMNAME'            CameraName               N
    529110573  'CAMSERIAL'          SerialNumber             N
     10574  'CM_DESC'            SceneCaptureType         N
    529210575  'COLORSPACE'         ColorSpace               N
    529310576  'DRIVE'              DriveMode                N
     
    530510588  'FLEQ35MM'           FocalLengthIn35mmFormat  N
    530610589  'FOCUS'              Focus                    N
     10590  'IMAGEBOARDID'       ImageBoardID             N
    530710591  'IMAGERBOARDID'      ImagerBoardID            N
    530810592  'IMAGERTEMP'         SensorTemperature        N
     
    531010594  'LENSARANGE'         LensApertureRange        N
    531110595  'LENSFRANGE'         LensFocalRange           N
    5312   'LENSMODEL'          LensID                   N
     10596  'LENSMODEL'          LensType                 N
    531310597  'PMODE'              ExposureProgram          N
    531410598  'RESOLUTION'         Quality                  N
     
    532210606=head2 JFIF Tags
    532310607
     10608The following information is extracted from the JPEG JFIF header.  See
     10609L<http://www.jpeg.org/public/jfif.pdf> for the JFIF 1.02 specification.
     10610
    532410611   Index   Tag Name                             Writable
    532510612   -----   --------                             --------
     
    534010627Hewlett-Packard and Microsoft.  Internally the FPX file structure mimics
    534110628that of an old DOS disk with fixed-sized "sectors" (usually 512 bytes) and a
    5342 "file allocation table" (FAT).  No wonder the format never became popular.
    5343 
    5344 However, some of the structures used in FlashPix streams are part of the
    5345 EXIF specification, and are still being used in the APP2 FPXR segment of
    5346 JPEG images by some Kodak and Hewlett-Packard digital cameras.
     10629"file allocation table" (FAT).  No wonder this image format never became
     10630popular.  However, some of the structures used in FlashPix streams are part
     10631of the EXIF specification, and are still being used in the APP2 FPXR segment
     10632of JPEG images by some Kodak and Hewlett-Packard digital cameras.
    534710633
    534810634ExifTool extracts FlashPix information from both FPX images and the APP2
    534910635FPXR segment of JPEG images.  As well, FlashPix information is extracted
    5350 from DOC, XLS and PPT (Microsoft Word, Excel and PowerPoint) documents since
    5351 the FlashPix file format is closely related to the formats of these files.
     10636from DOC, PPT, XLS (Microsoft Word, PowerPoint and Excel) documents, VSD
     10637(Microsoft Visio) drawings, and FLA (Macromedia/Adobe Flash project) files
     10638since these are based on the same file format as FlashPix (the Windows
     10639Compound Binary File format).  See
     10640L<http://graphcomp.com/info/specs/livepicture/fpx.pdf> for the FlashPix
     10641specification.
    535210642
    535310643  Tag ID                           Tag Name     Writable
     
    536610656  "\x05Transform"                  Transform    FlashPix Transform
    536710657  'Audio Stream'                   AudioStream  N
     10658  'Contents'                       Contents     XMP
    536810659  'Current User'                   CurrentUser  N
    536910660  'ICC Profile 0001'               ICC_Profile  ICC_Profile
     
    557910870  0x0006       Comments                         N
    558010871  0x0007       Template                         N
    5581   0x0008       LastSavedBy                      N
     10872  0x0008       LastModifiedBy                   N
    558210873  0x0009       RevisionNumber                   N
    558310874  0x000a       TotalEditTime                    N
     
    558510876  0x000c       CreateDate                       N
    558610877  0x000d       ModifyDate                       N
    5587   0x000e       PageCount                        N
    5588   0x000f       WordCount                        N
    5589   0x0010       CharCount                        N
     10878  0x000e       Pages                            N
     10879  0x000f       Words                            N
     10880  0x0010       Characters                       N
    559010881  0x0011       ThumbnailClip                    N
    559110882  0x0012       Software                         N
     
    562610917      5    SubimageTileHeight                   N
    562710918      6    NumChannels                          N
     10919
     10920=head2 MPF Tags
     10921
     10922These tags are part of the CIPA Multi-Picture Format specification, and are
     10923found in the APP2 "MPF" segment of JPEG images.  See
     10924L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-007_E.pdf> for the
     10925official specification.
     10926
     10927  Tag ID   Tag Name                             Writable
     10928  ------   --------                             --------
     10929  0xb000   MPFVersion                           N
     10930  0xb001   NumberOfImages                       N
     10931  0xb002   MPImageList                          MPF MPImage
     10932  0xb003   ImageUIDList                         N
     10933  0xb004   TotalFrames                          N
     10934  0xb101   MPIndividualNum                      N
     10935  0xb201   PanOrientation                       N
     10936  0xb202   PanOverlapH                          N
     10937  0xb203   PanOverlapV                          N
     10938  0xb204   BaseViewpointNum                     N
     10939  0xb205   ConvergenceAngle                     N
     10940  0xb206   BaselineLength                       N
     10941  0xb207   VerticalDivergence                   N
     10942  0xb208   AxisDistanceX                        N
     10943  0xb209   AxisDistanceY                        N
     10944  0xb20a   AxisDistanceZ                        N
     10945  0xb20b   YawAngle                             N
     10946  0xb20c   PitchAngle                           N
     10947  0xb20d   RollAngle                            N
     10948
     10949=head3 MPF MPImage Tags
     10950
     10951The first MPF "Large Thumbnail" image is extracted as PreviewImage, and the
     10952rest of the embedded MPF images are extracted as MPImage#.  The
     10953ExtractEmbedded (-ee) option may be used to extract information from these
     10954embedded images.
     10955
     10956   Index   Tag Name                             Writable
     10957   -----   --------                             --------
     10958    0.1    MPImageFlags                         N
     10959    0.2    MPImageFormat                        N
     10960    0.3    MPImageType                          N
     10961      4    MPImageLength                        N
     10962      8    MPImageStart                         N
     10963     12    DependentImage1EntryNumber           N
     10964     14    DependentImage2EntryNumber           N
     10965
     10966=head2 Stim Tags
     10967
     10968These tags are part of the CIPA Stereo Still Image specification, and are
     10969found in the APP3 "Stim" segment of JPEG images.  See
     10970L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-006_E.pdf> for the
     10971official specification.
     10972
     10973  Tag ID   Tag Name                             Writable
     10974  ------   --------                             --------
     10975  0x0000   StimVersion                          N
     10976  0x0001   ApplicationData                      N
     10977  0x0002   ImageArrangement                     N
     10978  0x0003   ImageRotation                        N
     10979  0x0004   ScalingFactor                        N
     10980  0x0005   CropXSize                            N
     10981  0x0006   CropYSize                            N
     10982  0x0007   CropX                                Stim CropX
     10983  0x0008   CropY                                Stim CropY
     10984  0x0009   ViewType                             N
     10985  0x000a   RepresentativeImage                  N
     10986  0x000b   ConvergenceBaseImage                 N
     10987  0x000c   AssumedDisplaySize                   N
     10988  0x000d   AssumedDistanceView                  N
     10989  0x000e   RepresentativeDisparityNear          N
     10990  0x000f   RepresentativeDisparityFar           N
     10991  0x0010   InitialDisplayEffect                 N
     10992  0x0011   ConvergenceDistance                  N
     10993  0x0012   CameraArrangementInterval            N
     10994  0x0013   ShootingCount                        N
     10995
     10996=head3 Stim CropX Tags
     10997
     10998   Index   Tag Name                             Writable
     10999   -----   --------                             --------
     11000      0    CropXCommonOffset                    N
     11001      2    CropXViewpointNumber                 N
     11002      3    CropXOffset                          N
     11003      7    CropXViewpointNumber2                N
     11004      8    CropXOffset2                         N
     11005
     11006=head3 Stim CropY Tags
     11007
     11008   Index   Tag Name                             Writable
     11009   -----   --------                             --------
     11010      0    CropYCommonOffset                    N
     11011      2    CropYViewpointNumber                 N
     11012      3    CropYOffset                          N
     11013      7    CropYViewpointNumber2                N
     11014      8    CropYOffset2                         N
    562811015
    562911016=head2 APP12 Tags
     
    568511072
    568611073ExifTool will read and write (but not create) AFCP IPTC information in JPEG
    5687 images, but not other image formats.
     11074and TIFF images.
    568811075
    568911076  Tag ID   Tag Name                             Writable
     
    569311080  'PrVw'   PreviewImage                         N
    569411081  'TEXT'   Text                                 N
    5695 
    5696 =head2 CanonVRD Tags
    5697 
    5698 Canon Digital Photo Professional writes VRD (Recipe Data) information as a
    5699 trailer record to JPEG, TIFF, CRW and CR2 images, or as a stand-alone VRD
    5700 file. The tags listed below represent information found in this record.  The
    5701 complete VRD data record may be accessed as a block using the Extra
    5702 'CanonVRD' tag, but this tag is not extracted or copied unless specified
    5703 explicitly.
    5704 
    5705    Index   Tag Name                             Writable
    5706    -----   --------                             --------
    5707       0    VRD1                                 CanonVRD Ver1
    5708       1    VRDStampTool                         CanonVRD StampTool
    5709       2    VRD2                                 CanonVRD Ver2
    5710 
    5711 =head3 CanonVRD Ver1 Tags
    5712 
    5713    Index   Tag Name                             Writable
    5714    -----   --------                             --------
    5715       2    VRDVersion                           N
    5716       8    WBAdjRGBLevels                       int16u[3]
    5717      24    WhiteBalanceAdj                      int16u
    5718      26    WBAdjColorTemp                       int16u
    5719      36    WBFineTuneActive                     int16u
    5720      40    WBFineTuneSaturation                 int16u
    5721      44    WBFineTuneTone                       int16u
    5722      46    RawColorAdj                          int16u
    5723      48    RawCustomSaturation                  int32s
    5724      52    RawCustomTone                        int32s
    5725      56    RawBrightnessAdj                     int32s
    5726      60    ToneCurveProperty                    int16u
    5727     122    DynamicRangeMin                      int16u
    5728     124    DynamicRangeMax                      int16u
    5729     272    ToneCurveActive                      int16u
    5730     276    BrightnessAdj                        int8s
    5731     277    ContrastAdj                          int8s
    5732     278    SaturationAdj                        int16s
    5733     286    ColorToneAdj                         int32s
    5734     352    RedCurvePoints                       int16u[21]
    5735     394    RedCurveLimits                       int16u[4]
    5736     410    GreenCurvePoints                     int16u[21]
    5737     452    GreenCurveLimits                     int16u[4]
    5738     468    BlueCurvePoints                      int16u[21]
    5739     510    BlueCurveLimits                      int16u[4]
    5740     526    RGBCurvePoints                       int16u[21]
    5741     568    RGBCurveLimits                       int16u[4]
    5742     580    CropActive                           int16u
    5743     582    CropLeft                             int16u
    5744     584    CropTop                              int16u
    5745     586    CropWidth                            int16u
    5746     588    CropHeight                           int16u
    5747     608    CropAspectRatio                      int16u
    5748     610    ConstrainedCropWidth                 float
    5749     614    ConstrainedCropHeight                float
    5750     618    CheckMark                            int16u
    5751     622    Rotation                             int16u
    5752     624    WorkColorSpace                       int16u
    5753 
    5754 =head3 CanonVRD StampTool Tags
    5755 
    5756    Index   Tag Name                             Writable
    5757    -----   --------                             --------
    5758       0    StampToolCount                       N
    5759 
    5760 =head3 CanonVRD Ver2 Tags
    5761 
    5762 Tags added in DPP version 2.0 and later.
    5763 
    5764    Index   Tag Name                             Writable
    5765    -----   --------                             --------
    5766       4    PictureStyle                         int16u
    5767      26    RawColorToneAdj                      int16s
    5768      28    RawSaturationAdj                     int16s
    5769      30    RawContrastAdj                       int16s
    5770      32    RawLinear                            int16u
    5771      34    RawSharpnessAdj                      int16s
    5772      36    RawHighlightPoint                    int16s
    5773      38    RawShadowPoint                       int16s
    5774     116    MonochromeFilterEffect               int16s
    5775     118    MonochromeToningEffect               int16s
    5776     120    MonochromeContrast                   int16s
    5777     122    MonochromeLinear                     int16u
    5778     124    MonochromeSharpness                  int16s
    5779     188    ChrominanceNoiseReduction            int16u
    5780     190    LuminanceNoiseReduction              int16u
    5781     192    ChrominanceNR_TIFF_JPEG              int16u
    578211082
    578311083=head2 FotoStation Tags
     
    583611136    222    ColorClass                           int32s
    583711137    223    Rating                               int32s
     11138    236    PreviewCropLeft                      int32s
     11139    237    PreviewCropTop                       int32s
     11140    238    PreviewCropRight                     int32s
     11141    239    PreviewCropBottom                    int32s
    583811142
    583911143=head3 PhotoMechanic XMP Tags
     
    584311147the "XMP-photomech" family 1 group name.
    584411148
     11149  Tag Name                                      Writable
     11150  --------                                      --------
     11151  CountryCode                                   string/
     11152  EditStatus                                    string
     11153  Prefs                                         string
     11154  TimeCreated                                   string/
     11155
     11156=head2 Microsoft Tags
     11157
     11158=head3 Microsoft XMP Tags
     11159
     11160Microsoft Photo 1.0 schema XMP tags.  This is likely not a complete list,
     11161but represents tags which have been observed in sample images.  The actual
     11162namespace prefix is "MicrosoftPhoto", but ExifTool shortens this to
     11163"XMP-microsoft" in the family 1 group name.
     11164
     11165  Tag Name                                      Writable
     11166  --------                                      --------
     11167  CameraSerialNumber                            string
     11168  DateAcquired                                  date
     11169  FlashManufacturer                             string
     11170  FlashModel                                    string
     11171  LastKeywordIPTC                               string+
     11172  LastKeywordXMP                                string+
     11173  LensManufacturer                              string
     11174  LensModel                                     string
     11175  RatingPercent                                 string
     11176
     11177=head3 Microsoft MP1 Tags
     11178
     11179Microsoft Photo 1.1 schema XMP tags which have been observed.
     11180
     11181  Tag Name                                      Writable
     11182  --------                                      --------
     11183  PanoramicStitchCameraMotion                   string
     11184  PanoramicStitchMapType                        string
     11185  PanoramicStitchPhi0                           real
     11186  PanoramicStitchPhi1                           real
     11187  PanoramicStitchTheta0                         real
     11188  PanoramicStitchTheta1                         real
     11189
     11190=head3 Microsoft MP Tags
     11191
     11192Microsoft Photo 1.2 schema XMP tags which have been observed.
     11193
     11194  Tag Name                                      Writable
     11195  --------                                      --------
     11196  RegionInfoMP                                  RegionInfoMP Struct
     11197  RegionInfoMPRegions                           Regions Struct_+
     11198  RegionPersonDisplayName                       string_+
     11199  RegionRectangle                               string_+
     11200
     11201=head3 Microsoft Stitch Tags
     11202
     11203Information found in the Microsoft custom EXIF tag 0x4748, as written by
     11204Windows Live Photo Gallery.
     11205
     11206   Index   Tag Name                             Writable
     11207   -----   --------                             --------
     11208      0    PanoramicStitchVersion               int32u
     11209      1    PanoramicStitchCameraMotion          int32u
     11210      2    PanoramicStitchMapType               int32u
     11211      3    PanoramicStitchTheta0                float
     11212      4    PanoramicStitchTheta1                float
     11213      5    PanoramicStitchPhi0                  float
     11214      6    PanoramicStitchPhi1                  float
     11215
     11216=head2 GIMP Tags
     11217
     11218The GNU Image Manipulation Program (GIMP) writes these tags in its native
     11219XCF (eXperimental Computing Facilty) images.
     11220
     11221  Tag ID   Tag Name                             Writable
     11222  ------   --------                             --------
     11223  'header' Header                               GIMP Header
     11224  0x0011   Compression                          N
     11225  0x0013   Resolution                           GIMP Resolution
     11226  0x0015   Parasites                            GIMP Parasite
     11227
     11228=head3 GIMP Header Tags
     11229
     11230   Index   Tag Name                             Writable
     11231   -----   --------                             --------
     11232      9    XCFVersion                           N
     11233     14    ImageWidth                           N
     11234     18    ImageHeight                          N
     11235     22    ColorMode                            N
     11236
     11237=head3 GIMP Resolution Tags
     11238
     11239   Index   Tag Name                             Writable
     11240   -----   --------                             --------
     11241      0    XResolution                          N
     11242      1    YResolution                          N
     11243
     11244=head3 GIMP Parasite Tags
     11245
    584511246  Tag ID               Tag Name                 Writable
    584611247  ------               --------                 --------
    5847   'CountryCode'        CountryCode              string/
    5848   'EditStatus'         EditStatus               string
    5849   'Prefs'              Prefs                    string
    5850   'TimeCreated'        TimeCreated              string/
     11248  'exif-data'          ExifData                 EXIF
     11249  'gimp-comment'       Comment                  N
     11250  'gimp-metadata'      XMP                      XMP
     11251  'icc-profile'        ICC_Profile              ICC_Profile
     11252  'icc-profile-name'   ICCProfileName           N
     11253  'iptc-data'          IPTCData                 IPTC
     11254  'jpeg-exif-data'     JPEGExifData             EXIF
    585111255
    585211256=head2 MIE Tags
     
    592311327  'Channels'           Channels                 int8u
    592411328  'Compression'        AudioCompression         string
    5925   'Duration'           Duration                 rational64u
     11329  'Duration'           Duration                 rational64u~
    592611330  'SampleBits'         SampleBits               int16u
    592711331  'SampleRate'         SampleRate               int32u
     
    609311497
    609411498MIE maker notes are contained within separate groups for each manufacturer
    6095 to avoid name conflicts.  Currently no specific manufacturer information has
    6096 been defined.
     11499to avoid name conflicts.
    609711500
    609811501  Tag ID               Tag Name                 Writable
    609911502  ------               --------                 --------
    6100   'Canon'              Canon                    MIE Unknown
     11503  'Canon'              Canon                    MIE Canon
    610111504  'Casio'              Casio                    MIE Unknown
    610211505  'FujiFilm'           FujiFilm                 MIE Unknown
     
    611111514  'Sony'               Sony                     MIE Unknown
    611211515
     11516=head3 MIE Canon Tags
     11517
     11518  Tag ID   Tag Name                             Writable
     11519  ------   --------                             --------
     11520  'VRD'    CanonVRD                             CanonVRD
     11521
    611311522=head3 MIE Unknown Tags
    611411523
     
    614211551  '1Name'      RelatedVideoFileName             string
    614311552  'Codec'      Codec                            string
    6144   'Duration'   Duration                         rational64u
     11553  'Duration'   Duration                         rational64u~
    614511554  'data'       RelatedVideoFile                 undef
    6146 
    6147 =head2 ID3 Tags
    6148 
    6149 ExifTool extracts ID3 information from MP3, MPEG, AIFF, OGG, FLAC, APE and
    6150 RealAudio files.
    6151 
    6152    Index   Tag Name                             Writable
    6153    -----   --------                             --------
    6154   'ID3v1'  ID3v1                                ID3 v1
    6155   'ID3v22' ID3v2_2                              ID3 v2_2
    6156   'ID3v23' ID3v2_3                              ID3 v2_3
    6157   'ID3v24' ID3v2_4                              ID3 v2_4
    6158 
    6159 =head3 ID3 v1 Tags
    6160 
    6161    Index   Tag Name                             Writable
    6162    -----   --------                             --------
    6163       3    Title                                N
    6164      33    Artist                               N
    6165      63    Album                                N
    6166      93    Year                                 N
    6167      97    Comment                              N
    6168     127    Genre                                N
    6169 
    6170 =head3 ID3 v2_2 Tags
    6171 
    6172 ExifTool extracts mainly text-based tags from ID3v2 information.  The tags
    6173 in the tables below are those extracted by ExifTool, and don't represent a
    6174 complete list of available ID3v2 tags.
    6175 
    6176 ID3 version 2.2 tags.  (These are the tags written by iTunes 5.0.)
    6177 
    6178   Tag ID   Tag Name                             Writable
    6179   ------   --------                             --------
    6180   'CNT'    PlayCounter                          N
    6181   'COM'    Comment                              N
    6182   'IPL'    InvolvedPeople                       N
    6183   'PIC'    Picture                              N
    6184   'TAL'    Album                                N
    6185   'TBP'    BeatsPerMinute                       N
    6186   'TCM'    Composer                             N
    6187   'TCO'    Genre                                N
    6188   'TCP'    Compilation                          N
    6189   'TCR'    Copyright                            N
    6190   'TDA'    Date                                 N
    6191   'TDY'    PlaylistDelay                        N
    6192   'TEN'    EncodedBy                            N
    6193   'TFT'    FileType                             N
    6194   'TIM'    Time                                 N
    6195   'TKE'    InitialKey                           N
    6196   'TLA'    Language                             N
    6197   'TLE'    Length                               N
    6198   'TMT'    Media                                N
    6199   'TOA'    OriginalArtist                       N
    6200   'TOF'    OriginalFilename                     N
    6201   'TOL'    OriginalLyricist                     N
    6202   'TOR'    OriginalReleaseYear                  N
    6203   'TOT'    OriginalAlbum                        N
    6204   'TP1'    Artist                               N
    6205   'TP2'    Band                                 N
    6206   'TP3'    Conductor                            N
    6207   'TP4'    InterpretedBy                        N
    6208   'TPA'    PartOfSet                            N
    6209   'TPB'    Publisher                            N
    6210   'TRC'    ISRC                                 N
    6211   'TRD'    RecordingDates                       N
    6212   'TRK'    Track                                N
    6213   'TSI'    Size                                 N
    6214   'TSS'    EncoderSettings                      N
    6215   'TT1'    Grouping                             N
    6216   'TT2'    Title                                N
    6217   'TT3'    Subtitle                             N
    6218   'TXT'    Lyricist                             N
    6219   'TXX'    UserDefinedText                      N
    6220   'TYE'    Year                                 N
    6221   'ULT'    Lyrics                               N
    6222   'WAF'    FileRUL                              N
    6223   'WAR'    ArtistURL                            N
    6224   'WAS'    SourceURL                            N
    6225   'WCM'    CommercialURL                        N
    6226   'WCP'    CopyrightURL                         N
    6227   'WPB'    PublisherURL                         N
    6228   'WXX'    UserDefinedURL                       N
    6229 
    6230 =head3 ID3 v2_3 Tags
    6231 
    6232 ID3 version 2.3 tags
    6233 
    6234   Tag ID   Tag Name                             Writable
    6235   ------   --------                             --------
    6236   'APIC'   Picture                              N
    6237   'COMM'   Comment                              N
    6238   'IPLS'   InvolvedPeople                       N
    6239   'MCDI'   MusicCDIdentifier                    N
    6240   'PCNT'   PlayCounter                          N
    6241   'PRIV'   Private                              ID3 Private
    6242   'TALB'   Album                                N
    6243   'TBPM'   BeatsPerMinute                       N
    6244   'TCOM'   Composer                             N
    6245   'TCON'   Genre                                N
    6246   'TCOP'   Copyright                            N
    6247   'TDAT'   Date                                 N
    6248   'TDLY'   PlaylistDelay                        N
    6249   'TENC'   EncodedBy                            N
    6250   'TEXT'   Lyricist                             N
    6251   'TFLT'   FileType                             N
    6252   'TIME'   Time                                 N
    6253   'TIT1'   Grouping                             N
    6254   'TIT2'   Title                                N
    6255   'TIT3'   Subtitle                             N
    6256   'TKEY'   InitialKey                           N
    6257   'TLAN'   Language                             N
    6258   'TLEN'   Length                               N
    6259   'TMED'   Media                                N
    6260   'TOAL'   OriginalAlbum                        N
    6261   'TOFN'   OriginalFilename                     N
    6262   'TOLY'   OriginalLyricist                     N
    6263   'TOPE'   OriginalArtist                       N
    6264   'TORY'   OriginalReleaseYear                  N
    6265   'TOWN'   FileOwner                            N
    6266   'TPE1'   Artist                               N
    6267   'TPE2'   Band                                 N
    6268   'TPE3'   Conductor                            N
    6269   'TPE4'   InterpretedBy                        N
    6270   'TPOS'   PartOfSet                            N
    6271   'TPUB'   Publisher                            N
    6272   'TRCK'   Track                                N
    6273   'TRDA'   RecordingDates                       N
    6274   'TRSN'   InternetRadioStationName             N
    6275   'TRSO'   InternetRadioStationOwner            N
    6276   'TSIZ'   Size                                 N
    6277   'TSRC'   ISRC                                 N
    6278   'TSSE'   EncoderSettings                      N
    6279   'TXXX'   UserDefinedText                      N
    6280   'TYER'   Year                                 N
    6281   'USER'   TermsOfUse                           N
    6282   'USLT'   Lyrics                               N
    6283   'WCOM'   CommercialURL                        N
    6284   'WCOP'   CopyrightURL                         N
    6285   'WOAF'   FileRUL                              N
    6286   'WOAR'   ArtistURL                            N
    6287   'WOAS'   SourceURL                            N
    6288   'WORS'   InternetRadioStationURL              N
    6289   'WPAY'   PaymentURL                           N
    6290   'WPUB'   PublisherURL                         N
    6291   'WXXX'   UserDefinedURL                       N
    6292 
    6293 =head3 ID3 Private Tags
    6294 
    6295 ID3 private (PRIV) tags.
    6296 
    6297   Tag ID               Tag Name                 Writable
    6298   ------               --------                 --------
    6299   'AverageLevel'       AverageLevel             N
    6300   'PeakValue'          PeakValue                N
    6301   'XMP'                XMP                      XMP
    6302 
    6303 =head3 ID3 v2_4 Tags
    6304 
    6305 ID3 version 2.4 tags
    6306 
    6307   Tag ID   Tag Name                             Writable
    6308   ------   --------                             --------
    6309   'APIC'   Picture                              N
    6310   'COMM'   Comment                              N
    6311   'MCDI'   MusicCDIdentifier                    N
    6312   'PCNT'   PlayCounter                          N
    6313   'PRIV'   Private                              ID3 Private
    6314   'TALB'   Album                                N
    6315   'TBPM'   BeatsPerMinute                       N
    6316   'TCOM'   Composer                             N
    6317   'TCON'   Genre                                N
    6318   'TCOP'   Copyright                            N
    6319   'TDEN'   EncodingTime                         N
    6320   'TDLY'   PlaylistDelay                        N
    6321   'TDOR'   OriginalReleaseTime                  N
    6322   'TDRC'   RecordingTime                        N
    6323   'TDRL'   ReleaseTime                          N
    6324   'TDTG'   TaggingTime                          N
    6325   'TENC'   EncodedBy                            N
    6326   'TEXT'   Lyricist                             N
    6327   'TFLT'   FileType                             N
    6328   'TIPL'   InvolvedPeople                       N
    6329   'TIT1'   Grouping                             N
    6330   'TIT2'   Title                                N
    6331   'TIT3'   Subtitle                             N
    6332   'TKEY'   InitialKey                           N
    6333   'TLAN'   Language                             N
    6334   'TLEN'   Length                               N
    6335   'TMCL'   MusicianCredits                      N
    6336   'TMED'   Media                                N
    6337   'TMOO'   Mood                                 N
    6338   'TOAL'   OriginalAlbum                        N
    6339   'TOFN'   OriginalFilename                     N
    6340   'TOLY'   OriginalLyricist                     N
    6341   'TOPE'   OriginalArtist                       N
    6342   'TOWN'   FileOwner                            N
    6343   'TPE1'   Artist                               N
    6344   'TPE2'   Band                                 N
    6345   'TPE3'   Conductor                            N
    6346   'TPE4'   InterpretedBy                        N
    6347   'TPOS'   PartOfSet                            N
    6348   'TPRO'   ProducedNotice                       N
    6349   'TPUB'   Publisher                            N
    6350   'TRCK'   Track                                N
    6351   'TRSN'   InternetRadioStationName             N
    6352   'TRSO'   InternetRadioStationOwner            N
    6353   'TSOA'   AlbumSortOrder                       N
    6354   'TSOP'   PerformerSortOrder                   N
    6355   'TSOT'   TitleSortOrder                       N
    6356   'TSRC'   ISRC                                 N
    6357   'TSSE'   EncoderSettings                      N
    6358   'TSST'   SetSubtitle                          N
    6359   'TXXX'   UserDefinedText                      N
    6360   'USER'   TermsOfUse                           N
    6361   'USLT'   Lyrics                               N
    6362   'WCOM'   CommercialURL                        N
    6363   'WCOP'   CopyrightURL                         N
    6364   'WOAF'   FileRUL                              N
    6365   'WOAR'   ArtistURL                            N
    6366   'WOAS'   SourceURL                            N
    6367   'WORS'   InternetRadioStationURL              N
    6368   'WPAY'   PaymentURL                           N
    6369   'WPUB'   PublisherURL                         N
    6370   'WXXX'   UserDefinedURL                       N
    637111555
    637211556=head2 Jpeg2000 Tags
     
    639611580  'free'   Free                                 N
    639711581  'ftbl'   FragmentTable                        N
    6398   'ftyp'   FileType                             N
     11582  'ftyp'   FileType                             Jpeg2000 FileType
    639911583  'gtso'   GraphicsTechnologyStandardOutput     N
    640011584  'ihdr'   ImageHeader                          Jpeg2000 ImageHeader
     
    642811612  'xml '   XML                                  XMP
    642911613
     11614=head3 Jpeg2000 FileType Tags
     11615
     11616   Index   Tag Name                             Writable
     11617   -----   --------                             --------
     11618      0    MajorBrand                           N
     11619      1    MinorVersion                         N
     11620      2    CompatibleBrands                     N
     11621
    643011622=head3 Jpeg2000 ImageHeader Tags
    643111623
     
    645511647      8    DisplayYResolutionUnit               N
    645611648      9    DisplayXResolutionUnit               N
     11649
     11650=head2 GIF Tags
     11651
     11652This table lists information extracted from GIF images. See
     11653L<http://www.w3.org/Graphics/GIF/spec-gif89a.txt> for the official GIF89a
     11654specification.
     11655
     11656  Tag Name                                      Writable
     11657  --------                                      --------
     11658  AnimationExtension                            GIF Animate
     11659  Comment                                       Y
     11660  Duration                                      N
     11661  FrameCount                                    N
     11662  GIFVersion                                    N
     11663  ScreenDescriptor                              GIF Screen
     11664  Text                                          N
     11665  XMPExtension                                  XMP
     11666
     11667=head3 GIF Animate Tags
     11668
     11669Information extracted from the "NETSCAPE2.0" animation extension.
     11670
     11671   Index   Tag Name                             Writable
     11672   -----   --------                             --------
     11673      2    AnimationIterations                  N
     11674
     11675=head3 GIF Screen Tags
     11676
     11677Information extracted from the GIF logical screen descriptor.
     11678
     11679   Index   Tag Name                             Writable
     11680   -----   --------                             --------
     11681      0    ImageWidth                           N
     11682      2    ImageHeight                          N
     11683    4.1    HasColorMap                          N
     11684    4.2    ColorResolutionDepth                 N
     11685    4.3    BitsPerPixel                         N
     11686      5    BackgroundColor                      N
    645711687
    645811688=head2 BMP Tags
     
    647311703     32    NumColors                            N
    647411704     36    NumImportantColors                   N
     11705
     11706=head3 BMP OS2 Tags
     11707
     11708Information extracted from OS/2-format BMP images.
     11709
     11710   Index   Tag Name                             Writable
     11711   -----   --------                             --------
     11712      4    ImageWidth                           N
     11713      6    ImageHeight                          N
     11714      8    Planes                               N
     11715     10    BitDepth                             N
    647511716
    647611717=head2 PICT Tags
     
    663311874=head2 PNG Tags
    663411875
     11876Tags extracted from PNG images.  See
     11877L<http://www.libpng.org/pub/png/spec/1.2/> for the official PNG 1.2
     11878specification.
     11879
    663511880  Tag ID   Tag Name                             Writable
    663611881  ------   --------                             --------
     
    663911884  'bKGD'   BackgroundColor                      N
    664011885  'cHRM'   PrimaryChromaticities                PNG PrimaryChromaticities
     11886  'dSIG'   DigitalSignature                     N
    664111887  'fRAc'   FractalParameters                    N
    664211888  'gAMA'   Gamma                                N
     
    665111897  'pHYs'   PhysicalPixel                        PNG PhysicalPixel
    665211898  'sBIT'   SignificantBits                      N
     11899  'sCAL'   SubjectScale                         PNG SubjectScale
    665311900  'sPLT'   SuggestedPalette                     N
    665411901  'sRGB'   SRGBRendering                        N
     11902  'sTER'   StereoImage                          PNG StereoImage
    665511903  'tEXt'   TextualData                          PNG TextualData
    665611904  'tIME'   ModifyDate                           Y
    665711905  'tRNS'   Transparency                         N
    665811906  'tXMP'   XMP                                  XMP
     11907  'vpAg'   VirtualPage                          PNG VirtualPage
    665911908  'zTXt'   CompressedText                       PNG TextualData
    666011909
     
    668611935=head3 PNG TextualData Tags
    668711936
    6688 The PNG TextualData format allows aribrary tag names to be used.  The tags
     11937The PNG TextualData format allows arbitrary tag names to be used.  The tags
    668911938listed below are the only ones that can be written (unless new user-defined
    669011939tags are added via the configuration file), however ExifTool will extract
    669111940any other TextualData tags that are found.
    669211941
    6693 The information for the TextualData tags may be stored as tEXt, zTXt or iTXt
    6694 chunks in the PNG image.  ExifTool will read and edit tags in their original
    6695 form, but tEXt chunks are written by default when creating new tags.
    6696 Compressed zTXt chunks are written only if Compress::Zlib is available, and
    6697 only for profile information or when the -z (Compress) option is specified.
     11942These tags may be stored as tEXt, zTXt or iTXt chunks in the PNG image.  By
     11943default ExifTool writes new string-value tags as as uncompressed tEXt, or
     11944compressed zTXt if the Compress (-z) option is used and Compress::Zlib is
     11945available.  Alternate language tags and values containing special characters
     11946(unless the Latin character set is used) are written as iTXt, and compressed
     11947if the Compress option is used and Compress::Zlib is available.  Raw profile
     11948information is always created as compressed zTXt if Compress::Zlib is
     11949available, or tEXt otherwise.  Standard XMP is written as uncompressed iTXt.
     11950
     11951Alternate languages are accessed by suffixing the tag name with a '-',
     11952followed by an RFC 3066 language code (ie. "PNG:Comment-fr", or
     11953"Title-en-US").  See L<http://www.ietf.org/rfc/rfc3066.txt> for the RFC 3066
     11954specification.
    669811955
    669911956Some of the tags below are not registered as part of the PNG specification,
     
    672811985  'Warning'               PNGWarning            string
    672911986  'XML:com.adobe.xmp'     XMP                   XMP
     11987  'create-date'           CreateDate            string
     11988  'modify-date'           ModDate               string
    673011989
    673111990=head3 PNG PhysicalPixel Tags
     
    673611995      4    PixelsPerUnitY                       N
    673711996      8    PixelUnits                           N
     11997
     11998=head3 PNG SubjectScale Tags
     11999
     12000   Index   Tag Name                             Writable
     12001   -----   --------                             --------
     12002      0    SubjectUnits                         N
     12003      1    SubjectPixelWidth                    N
     12004      2    SubjectPixelHeight                   N
     12005
     12006=head3 PNG StereoImage Tags
     12007
     12008   Index   Tag Name                             Writable
     12009   -----   --------                             --------
     12010      0    StereoMode                           N
     12011
     12012=head3 PNG VirtualPage Tags
     12013
     12014   Index   Tag Name                             Writable
     12015   -----   --------                             --------
     12016      0    VirtualImageWidth                    N
     12017      1    VirtualImageHeight                   N
     12018      2    VirtualPageUnits                     N
    673812019
    673912020=head2 MNG Tags
     
    695612237      2    Priority                             N
    695712238
     12239=head2 DjVu Tags
     12240
     12241Information is extracted from the following chunks in DjVu images.
     12242
     12243  Tag ID   Tag Name                             Writable
     12244  ------   --------                             --------
     12245  'ANTa'   ANTa                                 DjVu Ant
     12246  'ANTz'   CompressedAnnotation                 DjVu Ant
     12247  'FORM'   FORM                                 DjVu Form
     12248  'INCL'   IncludedFileID                       N
     12249  'INFO'   INFO                                 DjVu Info
     12250
     12251=head3 DjVu Ant Tags
     12252
     12253Information extracted from annotation chunks.
     12254
     12255  Tag ID       Tag Name                         Writable
     12256  ------       --------                         --------
     12257  'metadata'   Metadata                         DjVu Meta
     12258  'xmp'        XMP                              XMP
     12259
     12260=head3 DjVu Meta Tags
     12261
     12262This table lists the standard DjVu metadata tags, but ExifTool will extract
     12263any tags that exist even if they don't appear here.  The DjVu v3
     12264documentation endorses tags borrowed from two standards: 1) BibTeX
     12265bibliography system tags (all lowercase Tag ID's in the table below), and 2)
     12266PDF DocInfo tags (uppercase Tag ID's).
     12267
     12268  Tag ID               Tag Name                 Writable
     12269  ------               --------                 --------
     12270  'Author'             Author                   N
     12271  'CreationDate'       CreateDate               N
     12272  'Creator'            Creator                  N
     12273  'Keywords'           Keywords                 N
     12274  'ModDate'            ModifyDate               N
     12275  'Producer'           Producer                 N
     12276  'Subject'            Subject                  N
     12277  'Title'              Title                    N
     12278  'Trapped'            Trapped                  N
     12279  'address'            Address                  N
     12280  'annote'             Annotation               N
     12281  'author'             Author                   N
     12282  'booktitle'          BookTitle                N
     12283  'chapter'            Chapter                  N
     12284  'crossref'           CrossRef                 N
     12285  'edition'            Edition                  N
     12286  'eprint'             EPrint                   N
     12287  'howpublished'       HowPublished             N
     12288  'institution'        Institution              N
     12289  'journal'            Journal                  N
     12290  'key'                Key                      N
     12291  'month'              Month                    N
     12292  'note'               Note                     N
     12293  'number'             Number                   N
     12294  'organization'       Organization             N
     12295  'pages'              Pages                    N
     12296  'publisher'          Publisher                N
     12297  'school'             School                   N
     12298  'series'             Series                   N
     12299  'title'              Title                    N
     12300  'type'               Type                     N
     12301  'url'                URL                      N
     12302  'volume'             Volume                   N
     12303  'year'               Year                     N
     12304
     12305=head3 DjVu Form Tags
     12306
     12307   Index   Tag Name                             Writable
     12308   -----   --------                             --------
     12309      0    SubfileType                          N
     12310
     12311=head3 DjVu Info Tags
     12312
     12313   Index   Tag Name                             Writable
     12314   -----   --------                             --------
     12315      0    ImageWidth                           N
     12316      2    ImageHeight                          N
     12317      4    DjVuVersion                          N
     12318      6    SpatialResolution                    N
     12319      8    Gamma                                N
     12320      9    Orientation                          N
     12321
     12322=head2 PGF Tags
     12323
     12324The following table lists information extracted from the header of
     12325Progressive Graphics File (PGF) images.  As well, information is extracted
     12326from the embedded PNG metadata image if it exists.  See
     12327L<http://www.libpgf.org/> for the PGF specification.
     12328
     12329   Index   Tag Name                             Writable
     12330   -----   --------                             --------
     12331      3    PGFVersion                           N
     12332      8    ImageWidth                           N
     12333     12    ImageHeight                          N
     12334     16    PyramidLevels                        N
     12335     17    Quality                              N
     12336     18    BitsPerPixel                         N
     12337     19    ColorComponents                      N
     12338     20    ColorMode                            N
     12339     21    BackgroundColor                      N
     12340
    695812341=head2 MIFF Tags
    695912342
    6960 The MIFF format allows aribrary tag names to be used.  Only the standard tag
    6961 names are listed below, however ExifTool will decode any tags found in the
    6962 image.
     12343The MIFF (Magick Image File Format) format allows aribrary tag names to be
     12344used.  Only the standard tag names are listed below, however ExifTool will
     12345decode any tags found in the image.
    696312346
    696412347  Tag ID               Tag Name                 Writable
     
    700012383  'white-point'        WhitePoint               N
    700112384
     12385=head2 PSP Tags
     12386
     12387Tags extracted from Paint Shop Pro images (PSP, PSPIMAGE, PSPFRAME,
     12388PSPSHAPE, PSPTUBE and TUB extensions).
     12389
     12390  Tag ID               Tag Name                 Writable
     12391  ------               --------                 --------
     12392  'FileVersion'        FileVersion              N
     12393  0x0000               ImageInfo                PSP Image
     12394                                                PSP Image
     12395  0x0001               CreatorInfo              PSP Creator
     12396  0x000a               ExtendedInfo             PSP Ext
     12397
     12398=head3 PSP Image Tags
     12399
     12400   Index   Tag Name                             Writable
     12401   -----   --------                             --------
     12402      0    ImageWidth                           N
     12403      4    ImageHeight                          N
     12404      8    ImageResolution                      N
     12405     16    ResolutionUnit                       N
     12406     17    Compression                          N
     12407     19    BitsPerSample                        N
     12408     21    Planes                               N
     12409     23    NumColors                            N
     12410
     12411=head3 PSP Creator Tags
     12412
     12413  Tag ID   Tag Name                             Writable
     12414  ------   --------                             --------
     12415  0x0000   Title                                N
     12416  0x0001   CreateDate                           N
     12417  0x0002   ModifyDate                           N
     12418  0x0003   Artist                               N
     12419  0x0004   Copyright                            N
     12420  0x0005   Description                          N
     12421  0x0006   CreatorAppID                         N
     12422  0x0007   CreatorAppVersion                    N
     12423
     12424=head3 PSP Ext Tags
     12425
     12426  Tag ID   Tag Name                             Writable
     12427  ------   --------                             --------
     12428  0x0003   EXIFInfo                             EXIF
     12429
    700212430=head2 PDF Tags
    700312431
    700412432The tags listed in the PDF tables below are those which are used by ExifTool
    700512433to extract meta information, but they are only a small fraction of the total
    7006 number of available PDF tags.
     12434number of available PDF tags.  See
     12435L<http://www.adobe.com/devnet/pdf/pdf_reference.html> for the official PDF
     12436specification.
     12437
     12438ExifTool supports reading and writing PDF documents up to version 1.7
     12439extension level 3, including support for RC4, AES-128 and AES-256
     12440encryption.  A Password option is provided to allow processing of
     12441password-protected PDF files.
     12442
     12443When writing PDF files, ExifTool uses an incremental update.  This has the
     12444advantages of being fast and reversible.  The original PDF can be easily
     12445recovered by deleting the C<PDF-update> pseudo-group (with
     12446C<-PDF-update:all=> on the command line).  But there are two main
     12447disadvantages to this technique:
     12448
     124491) A linearized PDF file is no longer linearized after the update, so it
     12450must be subsequently re-linearized if this is required.
     12451
     124522) All metadata edits are reversible.  While this would normally be
     12453considered an advantage, it is a potential security problem because old
     12454information is never actually deleted from the file.
     12455
     12456  Tag ID               Tag Name                 Writable
     12457  ------               --------                 --------
     12458  'Encrypt'            Encrypt                  PDF Encrypt
     12459  'Info'               Info                     PDF Info
     12460  'Root'               Root                     PDF Root
     12461  '_linearized'        Linearized               N
     12462
     12463=head3 PDF Encrypt Tags
     12464
     12465Tags extracted from the document Encrypt dictionary.
    700712466
    700812467  Tag ID   Tag Name                             Writable
    700912468  ------   --------                             --------
    7010   'Info'   Info                                 PDF Info
    7011   'Root'   Root                                 PDF Root
     12469  'Filter' Encryption                           N
     12470  'P'      UserAccess                           N
    701212471
    701312472=head3 PDF Info Tags
     
    701512474As well as the tags listed below, the PDF specification allows for
    701612475user-defined tags to exist in the Info dictionary.  These tags, which should
    7017 have corresponding XMP-pdfx entries in the PDF Metadata, are also extracted
    7018 by ExifTool.
     12476have corresponding XMP-pdfx entries in the XMP of the PDF XML Metadata
     12477object, are also extracted by ExifTool.
     12478
     12479B<Writable> specifies the value format, and may be C<string>, C<date>,
     12480C<integer>, C<real>, C<boolean> or C<name> for PDF tags.
    701912481
    702012482  Tag ID               Tag Name                 Writable
    702112483  ------               --------                 --------
    7022   'Author'             Author                   N
    7023   'CreationDate'       CreateDate               N
    7024   'Creator'            Creator                  N
    7025   'Keywords'           Keywords                 N+
    7026   'ModDate'            ModifyDate               N
    7027   'Producer'           Producer                 N
    7028   'Subject'            Subject                  N
    7029   'Title'              Title                    N
    7030   'Trapped'            Trapped                  N
     12484  'AAPL:Keywords'      AppleKeywords            string+
     12485  'Author'             Author                   string
     12486  'CreationDate'       CreateDate               date
     12487  'Creator'            Creator                  string
     12488  'Keywords'           Keywords                 string+
     12489  'ModDate'            ModifyDate               date
     12490  'Producer'           Producer                 string
     12491  'Subject'            Subject                  string
     12492  'Title'              Title                    string
     12493  'Trapped'            Trapped                  string!
    703112494
    703212495=head3 PDF Root Tags
     
    703412497This is the PDF document catalog.
    703512498
    7036   Tag ID       Tag Name                         Writable
    7037   ------       --------                         --------
    7038   'Metadata'   Metadata                         PDF Metadata
    7039   'Pages'      Pages                            PDF Pages
     12499  Tag ID               Tag Name                 Writable
     12500  ------               --------                 --------
     12501  'Lang'               Language                 N
     12502  'MarkInfo'           MarkInfo                 PDF MarkInfo
     12503  'Metadata'           Metadata                 PDF Metadata
     12504  'PageLayout'         PageLayout               N
     12505  'PageMode'           PageMode                 N
     12506  'Pages'              Pages                    PDF Pages
     12507  'Perms'              Perms                    PDF Perms
     12508  'Version'            PDFVersion               N
     12509
     12510=head3 PDF MarkInfo Tags
     12511
     12512  Tag ID   Tag Name                             Writable
     12513  ------   --------                             --------
     12514  'Marked' TaggedPDF                            N
    704012515
    704112516=head3 PDF Metadata Tags
     
    706512540  ------               --------                 --------
    706612541  'AdobePhotoshop'     AdobePhotoshop           PDF AdobePhotoshop
     12542  'Illustrator'        Illustrator              PDF Illustrator
    706712543
    706812544=head3 PDF AdobePhotoshop Tags
     
    708012556=head3 PDF ImageResources Tags
    708112557
    7082   Tag ID   Tag Name                             Writable
    7083   ------   --------                             --------
    7084   'stream' Stream                               Photoshop
     12558  Tag ID       Tag Name                         Writable
     12559  ------       --------                         --------
     12560  '_stream'    _stream                          Photoshop
     12561
     12562=head3 PDF Illustrator Tags
     12563
     12564  Tag ID       Tag Name                         Writable
     12565  ------       --------                         --------
     12566  'Private'    Private                          PDF AIPrivate
     12567
     12568=head3 PDF AIPrivate Tags
     12569
     12570  Tag ID               Tag Name                 Writable
     12571  ------               --------                 --------
     12572  'AIMetaData'         AIMetaData               PDF AIMetaData
     12573  'AIPrivateData'      AIPrivateData            PostScript
     12574  'ContainerVersion'   ContainerVersion         N
     12575  'CreatorVersion'     CreatorVersion           N
     12576  'RoundTripVersion'   RoundTripVersion         N
     12577
     12578=head3 PDF AIMetaData Tags
     12579
     12580  Tag ID       Tag Name                         Writable
     12581  ------       --------                         --------
     12582  '_stream'    _stream                          PostScript
    708512583
    708612584=head3 PDF Resources Tags
     
    710412602=head3 PDF ICCBased Tags
    710512603
    7106   Tag ID   Tag Name                             Writable
    7107   ------   --------                             --------
    7108   'stream' Stream                               ICC_Profile
     12604  Tag ID       Tag Name                         Writable
     12605  ------       --------                         --------
     12606  '_stream'    _stream                          ICC_Profile
     12607
     12608=head3 PDF Perms Tags
     12609
     12610Additional document permissions imposed by digital signatures.
     12611
     12612  Tag ID       Tag Name                         Writable
     12613  ------       --------                         --------
     12614  'DocMDP'     DocMDP                           PDF Signature
     12615  'FieldMDP'   FieldMDP                         PDF Signature
     12616  'UR3'        UR3                              PDF Signature
     12617
     12618=head3 PDF Signature Tags
     12619
     12620  Tag ID               Tag Name                 Writable
     12621  ------               --------                 --------
     12622  'ContactInfo'        SignerContactInfo        N
     12623  'Location'           SigningLocation          N
     12624  'M'                  SigningDate              N
     12625  'Name'               SigningAuthority         N
     12626  'Prop_AuthTime'      AuthenticationTime       N
     12627  'Prop_AuthType'      AuthenticationType       N
     12628  'Reason'             SigningReason            N
     12629  'Reference'          Reference                PDF Reference
     12630
     12631=head3 PDF Reference Tags
     12632
     12633  Tag ID               Tag Name                 Writable
     12634  ------               --------                 --------
     12635  'TransformParams'    TransformParams          PDF TransformParams
     12636
     12637=head3 PDF TransformParams Tags
     12638
     12639  Tag ID               Tag Name                 Writable
     12640  ------               --------                 --------
     12641  'Action'             FieldPermissions         N
     12642  'Annots'             AnnotationUsageRights    N+
     12643  'Document'           DocumentUsageRights      N+
     12644  'EF'                 EmbeddedFileUsageRights  N+
     12645  'Fields'             FormFields               N+
     12646  'Form'               FormUsageRights          N+
     12647  'Msg'                UsageRightsMessage       N
     12648  'P'                  ModificationPermissions  N
     12649  'Signature'          SignatureUsageRights     N+
    710912650
    711012651=head2 PostScript Tags
     
    711312654  ------               --------                 --------
    711412655  'Author'             Author                   string
     12656  'BeginDocument'      EmbeddedFile             PostScript
    711512657  'BeginICCProfile'    ICC_Profile              ICC_Profile
    711612658  'BeginPhotoshop'     PhotoshopData            Photoshop
    711712659  'BoundingBox'        BoundingBox              N
    711812660  'Copyright'          Copyright                string
    7119   'CreationDate'       CreateDate               string
     12661  'CreationDate'       CreateDate               string~
    712012662  'Creator'            Creator                  string
     12663  'EmbeddedFileName'   EmbeddedFileName         N
    712112664  'For'                For                      string
    712212665  'ImageData'          ImageData                N
    712312666  'Keywords'           Keywords                 string
    7124   'ModDate'            ModifyDate               string
     12667  'ModDate'            ModifyDate               string~
    712512668  'Pages'              Pages                    N
    712612669  'Routing'            Routing                  string
     
    713012673  'Version'            Version                  string
    713112674  'begin_xml_packet'   XMP                      XMP
     12675
     12676=head2 ID3 Tags
     12677
     12678ExifTool extracts ID3 information from MP3, MPEG, AIFF, OGG, FLAC, APE and
     12679RealAudio files.  ID3v2 tags which support multiple languages (ie. Comment
     12680and Lyrics) are extracted by specifying the tag name, followed by a dash
     12681('-'), then a 3-character
     12682ISO 639-2
     12683language code (ie. "Comment-spa"). See L<http://www.id3.org/> for the
     12684official ID3 specification and
     12685L<http://www.loc.gov/standards/iso639-2/php/code_list.php> for a list of ISO
     12686639-2 language codes.
     12687
     12688  Tag Name                                      Writable
     12689  --------                                      --------
     12690  ID3v1                                         ID3 v1
     12691  ID3v1_Enh                                     ID3 v1_Enh
     12692  ID3v2_2                                       ID3 v2_2
     12693  ID3v2_3                                       ID3 v2_3
     12694  ID3v2_4                                       ID3 v2_4
     12695
     12696=head3 ID3 v1 Tags
     12697
     12698   Index   Tag Name                             Writable
     12699   -----   --------                             --------
     12700      3    Title                                N
     12701     33    Artist                               N
     12702     63    Album                                N
     12703     93    Year                                 N
     12704     97    Comment                              N
     12705    125    Track                                N
     12706    127    Genre                                N
     12707
     12708=head3 ID3 v1_Enh Tags
     12709
     12710ID3 version 1 "Enhanced TAG" information (not part of the official spec).
     12711
     12712   Index   Tag Name                             Writable
     12713   -----   --------                             --------
     12714      4    Title2                               N
     12715     64    Artist2                              N
     12716    124    Album2                               N
     12717    184    Speed                                N
     12718    185    Genre                                N
     12719    215    StartTime                            N
     12720    221    EndTime                              N
     12721
     12722=head3 ID3 v2_2 Tags
     12723
     12724ExifTool extracts mainly text-based tags from ID3v2 information.  The tags
     12725in the tables below are those extracted by ExifTool, and don't represent a
     12726complete list of available ID3v2 tags.
     12727
     12728ID3 version 2.2 tags.  (These are the tags written by iTunes 5.0.)
     12729
     12730  Tag ID   Tag Name                             Writable
     12731  ------   --------                             --------
     12732  'CNT'    PlayCounter                          N
     12733  'COM'    Comment                              N
     12734  'IPL'    InvolvedPeople                       N
     12735  'PIC'    Picture                              N
     12736  'PIC-1'  PictureFormat                        N
     12737  'PIC-2'  PictureType                          N
     12738  'PIC-3'  PictureDescription                   N
     12739  'SLT'    SynchronizedLyricText                N
     12740  'TAL'    Album                                N
     12741  'TBP'    BeatsPerMinute                       N
     12742  'TCM'    Composer                             N
     12743  'TCO'    Genre                                N
     12744  'TCP'    Compilation                          N
     12745  'TCR'    Copyright                            N
     12746  'TDA'    Date                                 N
     12747  'TDY'    PlaylistDelay                        N
     12748  'TEN'    EncodedBy                            N
     12749  'TFT'    FileType                             N
     12750  'TIM'    Time                                 N
     12751  'TKE'    InitialKey                           N
     12752  'TLA'    Language                             N
     12753  'TLE'    Length                               N
     12754  'TMT'    Media                                N
     12755  'TOA'    OriginalArtist                       N
     12756  'TOF'    OriginalFilename                     N
     12757  'TOL'    OriginalLyricist                     N
     12758  'TOR'    OriginalReleaseYear                  N
     12759  'TOT'    OriginalAlbum                        N
     12760  'TP1'    Artist                               N
     12761  'TP2'    Band                                 N
     12762  'TP3'    Conductor                            N
     12763  'TP4'    InterpretedBy                        N
     12764  'TPA'    PartOfSet                            N
     12765  'TPB'    Publisher                            N
     12766  'TRC'    ISRC                                 N
     12767  'TRD'    RecordingDates                       N
     12768  'TRK'    Track                                N
     12769  'TSI'    Size                                 N
     12770  'TSS'    EncoderSettings                      N
     12771  'TT1'    Grouping                             N
     12772  'TT2'    Title                                N
     12773  'TT3'    Subtitle                             N
     12774  'TXT'    Lyricist                             N
     12775  'TXX'    UserDefinedText                      N
     12776  'TYE'    Year                                 N
     12777  'ULT'    Lyrics                               N
     12778  'WAF'    FileURL                              N
     12779  'WAR'    ArtistURL                            N
     12780  'WAS'    SourceURL                            N
     12781  'WCM'    CommercialURL                        N
     12782  'WCP'    CopyrightURL                         N
     12783  'WPB'    PublisherURL                         N
     12784  'WXX'    UserDefinedURL                       N
     12785
     12786=head3 ID3 v2_3 Tags
     12787
     12788ID3 version 2.3 tags
     12789
     12790  Tag ID   Tag Name                             Writable
     12791  ------   --------                             --------
     12792  'APIC'   Picture                              N
     12793  'APIC-1' PictureMimeType                      N
     12794  'APIC-2' PictureType                          N
     12795  'APIC-3' PictureDescription                   N
     12796  'COMM'   Comment                              N
     12797  'IPLS'   InvolvedPeople                       N
     12798  'MCDI'   MusicCDIdentifier                    N
     12799  'PCNT'   PlayCounter                          N
     12800  'PRIV'   Private                              ID3 Private
     12801  'SYLT'   SynchronizedLyricText                N
     12802  'TALB'   Album                                N
     12803  'TBPM'   BeatsPerMinute                       N
     12804  'TCMP'   Compilation                          N
     12805  'TCOM'   Composer                             N
     12806  'TCON'   Genre                                N
     12807  'TCOP'   Copyright                            N
     12808  'TDAT'   Date                                 N
     12809  'TDLY'   PlaylistDelay                        N
     12810  'TENC'   EncodedBy                            N
     12811  'TEXT'   Lyricist                             N
     12812  'TFLT'   FileType                             N
     12813  'TIME'   Time                                 N
     12814  'TIT1'   Grouping                             N
     12815  'TIT2'   Title                                N
     12816  'TIT3'   Subtitle                             N
     12817  'TKEY'   InitialKey                           N
     12818  'TLAN'   Language                             N
     12819  'TLEN'   Length                               N
     12820  'TMED'   Media                                N
     12821  'TOAL'   OriginalAlbum                        N
     12822  'TOFN'   OriginalFilename                     N
     12823  'TOLY'   OriginalLyricist                     N
     12824  'TOPE'   OriginalArtist                       N
     12825  'TORY'   OriginalReleaseYear                  N
     12826  'TOWN'   FileOwner                            N
     12827  'TPE1'   Artist                               N
     12828  'TPE2'   Band                                 N
     12829  'TPE3'   Conductor                            N
     12830  'TPE4'   InterpretedBy                        N
     12831  'TPOS'   PartOfSet                            N
     12832  'TPUB'   Publisher                            N
     12833  'TRCK'   Track                                N
     12834  'TRDA'   RecordingDates                       N
     12835  'TRSN'   InternetRadioStationName             N
     12836  'TRSO'   InternetRadioStationOwner            N
     12837  'TSIZ'   Size                                 N
     12838  'TSRC'   ISRC                                 N
     12839  'TSSE'   EncoderSettings                      N
     12840  'TXXX'   UserDefinedText                      N
     12841  'TYER'   Year                                 N
     12842  'USER'   TermsOfUse                           N
     12843  'USLT'   Lyrics                               N
     12844  'WCOM'   CommercialURL                        N
     12845  'WCOP'   CopyrightURL                         N
     12846  'WOAF'   FileURL                              N
     12847  'WOAR'   ArtistURL                            N
     12848  'WOAS'   SourceURL                            N
     12849  'WORS'   InternetRadioStationURL              N
     12850  'WPAY'   PaymentURL                           N
     12851  'WPUB'   PublisherURL                         N
     12852  'WXXX'   UserDefinedURL                       N
     12853
     12854=head3 ID3 Private Tags
     12855
     12856ID3 private (PRIV) tags.
     12857
     12858  Tag ID               Tag Name                 Writable
     12859  ------               --------                 --------
     12860  'AverageLevel'       AverageLevel             N
     12861  'PeakValue'          PeakValue                N
     12862  'XMP'                XMP                      XMP
     12863
     12864=head3 ID3 v2_4 Tags
     12865
     12866ID3 version 2.4 tags
     12867
     12868  Tag ID   Tag Name                             Writable
     12869  ------   --------                             --------
     12870  'APIC'   Picture                              N
     12871  'APIC-1' PictureMimeType                      N
     12872  'APIC-2' PictureType                          N
     12873  'APIC-3' PictureDescription                   N
     12874  'COMM'   Comment                              N
     12875  'MCDI'   MusicCDIdentifier                    N
     12876  'PCNT'   PlayCounter                          N
     12877  'PRIV'   Private                              ID3 Private
     12878  'SYLT'   SynchronizedLyricText                N
     12879  'TALB'   Album                                N
     12880  'TBPM'   BeatsPerMinute                       N
     12881  'TCMP'   Compilation                          N
     12882  'TCOM'   Composer                             N
     12883  'TCON'   Genre                                N
     12884  'TCOP'   Copyright                            N
     12885  'TDEN'   EncodingTime                         N
     12886  'TDLY'   PlaylistDelay                        N
     12887  'TDOR'   OriginalReleaseTime                  N
     12888  'TDRC'   RecordingTime                        N
     12889  'TDRL'   ReleaseTime                          N
     12890  'TDTG'   TaggingTime                          N
     12891  'TENC'   EncodedBy                            N
     12892  'TEXT'   Lyricist                             N
     12893  'TFLT'   FileType                             N
     12894  'TIPL'   InvolvedPeople                       N
     12895  'TIT1'   Grouping                             N
     12896  'TIT2'   Title                                N
     12897  'TIT3'   Subtitle                             N
     12898  'TKEY'   InitialKey                           N
     12899  'TLAN'   Language                             N
     12900  'TLEN'   Length                               N
     12901  'TMCL'   MusicianCredits                      N
     12902  'TMED'   Media                                N
     12903  'TMOO'   Mood                                 N
     12904  'TOAL'   OriginalAlbum                        N
     12905  'TOFN'   OriginalFilename                     N
     12906  'TOLY'   OriginalLyricist                     N
     12907  'TOPE'   OriginalArtist                       N
     12908  'TOWN'   FileOwner                            N
     12909  'TPE1'   Artist                               N
     12910  'TPE2'   Band                                 N
     12911  'TPE3'   Conductor                            N
     12912  'TPE4'   InterpretedBy                        N
     12913  'TPOS'   PartOfSet                            N
     12914  'TPRO'   ProducedNotice                       N
     12915  'TPUB'   Publisher                            N
     12916  'TRCK'   Track                                N
     12917  'TRSN'   InternetRadioStationName             N
     12918  'TRSO'   InternetRadioStationOwner            N
     12919  'TSOA'   AlbumSortOrder                       N
     12920  'TSOP'   PerformerSortOrder                   N
     12921  'TSOT'   TitleSortOrder                       N
     12922  'TSRC'   ISRC                                 N
     12923  'TSSE'   EncoderSettings                      N
     12924  'TSST'   SetSubtitle                          N
     12925  'TXXX'   UserDefinedText                      N
     12926  'USER'   TermsOfUse                           N
     12927  'USLT'   Lyrics                               N
     12928  'WCOM'   CommercialURL                        N
     12929  'WCOP'   CopyrightURL                         N
     12930  'WOAF'   FileURL                              N
     12931  'WOAR'   ArtistURL                            N
     12932  'WOAS'   SourceURL                            N
     12933  'WORS'   InternetRadioStationURL              N
     12934  'WPAY'   PaymentURL                           N
     12935  'WPUB'   PublisherURL                         N
     12936  'WXXX'   UserDefinedURL                       N
     12937
     12938=head2 ITC Tags
     12939
     12940This information is found in iTunes Cover Flow data files.
     12941
     12942  Tag ID   Tag Name                             Writable
     12943  ------   --------                             --------
     12944  'data'   ImageData                            N
     12945  'itch'   Itch                                 ITC Header
     12946  'item'   Item                                 ITC Item
     12947
     12948=head3 ITC Header Tags
     12949
     12950   Index   Tag Name                             Writable
     12951   -----   --------                             --------
     12952     16    DataType                             N
     12953
     12954=head3 ITC Item Tags
     12955
     12956   Index   Tag Name                             Writable
     12957   -----   --------                             --------
     12958      0    LibraryID                            N
     12959      2    TrackID                              N
     12960      4    DataLocation                         N
     12961      5    ImageType                            N
     12962      7    ImageWidth                           N
     12963      8    ImageHeight                          N
    713212964
    713312965=head2 Vorbis Tags
     
    719513027  0x0000   StreamInfo                           FLAC StreamInfo
    719613028  0x0004   VorbisComment                        Vorbis Comments
     13029  0x0006   Picture                              FLAC Picture
    719713030
    719813031=head3 FLAC StreamInfo Tags
     
    721013043  'Bit103-107'         BitsPerSample            N
    721113044  'Bit108-143'         TotalSamples             N
     13045
     13046=head3 FLAC Picture Tags
     13047
     13048   Index   Tag Name                             Writable
     13049   -----   --------                             --------
     13050      0    PictureType                          N
     13051      1    PictureMIMEType                      N
     13052      2    PictureDescription                   N
     13053      3    PictureWidth                         N
     13054      4    PictureHeight                        N
     13055      5    PictureBitsPerPixel                  N
     13056      6    PictureIndexedColors                 N
     13057      7    PictureLength                        N
     13058      8    Picture                              N
    721213059
    721313060=head2 APE Tags
     
    730613153  'Bit32-49'   VideoBitrate                     N
    730713154
    7308 =head2 QuickTime Tags
    7309 
    7310 These tags are used in QuickTime MOV and MP4 videos, and QTIF images.  Tags
    7311 with a question mark after their name are not extracted unless the Unknown
    7312 option is set.
     13155=head3 MPEG Xing Tags
     13156
     13157These tags are extracted from the Xing/Info frame.
     13158
     13159  Tag Name                                      Writable
     13160  --------                                      --------
     13161  VBRFrames                                     N
     13162  VBRBytes                                      N
     13163  VBRScale                                      N
     13164  Encoder                                       N
     13165  LameVBRQuality                                N
     13166  LameQuality                                   N
     13167  LameHeader                                    MPEG Lame
     13168
     13169=head3 MPEG Lame Tags
     13170
     13171Tags extracted from Lame 3.90 or later header.
     13172
     13173   Index   Tag Name                             Writable
     13174   -----   --------                             --------
     13175      9    LameMethod                           N
     13176     10    LameLowPassFilter                    N
     13177     20    LameBitrate                          N
     13178     24    LameStereoMode                       N
     13179
     13180=head2 M2TS Tags
     13181
     13182The MPEG-2 transport stream is used as a container for many different
     13183audio/video formats (including AVCHD).  This table lists information
     13184extracted from M2TS files.
     13185
     13186  Tag Name                                      Writable
     13187  --------                                      --------
     13188  AudioStreamType                               N
     13189  Duration                                      N
     13190  VideoStreamType                               N
     13191  _AC3                                          M2TS AC3
     13192  _H264                                         H264
     13193
     13194=head3 M2TS AC3 Tags
     13195
     13196Tags extracted from AC-3 audio streams.
     13197
     13198  Tag Name                                      Writable
     13199  --------                                      --------
     13200  AudioBitrate                                  N
     13201  AudioChannels                                 N
     13202  AudioSampleRate                               N
     13203  SurroundMode                                  N
     13204
     13205=head2 H264 Tags
     13206
     13207Tags extracted from H.264 video streams.  The metadata for AVCHD videos is
     13208stored in this stream.
     13209
     13210  Tag Name                                      Writable
     13211  --------                                      --------
     13212  ImageHeight                                   N
     13213  ImageWidth                                    N
     13214  MDPM                                          H264 MDPM
     13215
     13216=head3 H264 MDPM Tags
     13217
     13218The following tags are decoded from the Modified Digital Video Pack Metadata
     13219(MDPM) of the unregistered user data with UUID
     1322017ee8c60f84d11d98cd60800200c9a66 in the H.264 Supplemental Enhancement
     13221Information (SEI).  I<[Yes, this description is confusing, but nothing
     13222compared to the challenge of actually decoding the data!]>  This information
     13223may exist at regular intervals through the entire video, but only the first
     13224occurrence is extracted unless the ExtractEmbedded (-ee) option is used (in
     13225which case subsequent occurrences are extracted as sub-documents).
    731313226
    731413227  Tag ID   Tag Name                             Writable
    731513228  ------   --------                             --------
    7316   'PICT'   PreviewPICT                          N
    7317   'free'   Free?                                N
    7318   'ftyp'   FrameType?                           N
    7319   'mdat'   Mdat?                                N
    7320   'moov'   Movie                                QuickTime Movie
    7321   'pnot'   Preview                              QuickTime Preview
    7322   'skip'   Skip?                                N
    7323   'wide'   Wide?                                N
     13229  0x0018   DateTimeOriginal                     N
     13230  0x0070   Camera1                              H264 Camera1
     13231  0x0071   Camera2                              H264 Camera2
     13232  0x007f   Shutter                              H264 Shutter
     13233  0x00a0   ExposureTime                         N
     13234  0x00a1   FNumber                              N
     13235  0x00a2   ExposureProgram                      N
     13236  0x00a3   BrightnessValue                      N
     13237  0x00a4   ExposureCompensation                 N
     13238  0x00a5   MaxApertureValue                     N
     13239  0x00a6   Flash                                N
     13240  0x00a7   CustomRendered                       N
     13241  0x00a8   WhiteBalance                         N
     13242  0x00a9   FocalLengthIn35mmFormat              N
     13243  0x00aa   SceneCaptureType                     N
     13244  0x00b0   GPSVersionID                         N
     13245  0x00b1   GPSLatitudeRef                       N
     13246  0x00b2   GPSLatitude                          N
     13247  0x00b5   GPSLongitudeRef                      N
     13248  0x00b6   GPSLongitude                         N
     13249  0x00b9   GPSAltitudeRef                       N
     13250  0x00ba   GPSAltitude                          N
     13251  0x00bb   GPSTimeStamp                         N
     13252  0x00be   GPSStatus                            N
     13253  0x00bf   GPSMeasureMode                       N
     13254  0x00c0   GPSDOP                               N
     13255  0x00c1   GPSSpeedRef                          N
     13256  0x00c2   GPSSpeed                             N
     13257  0x00c3   GPSTrackRef                          N
     13258  0x00c4   GPSTrack                             N
     13259  0x00c5   GPSImgDirectionRef                   N
     13260  0x00c6   GPSImgDirection                      N
     13261  0x00c7   GPSMapDatum                          N
     13262  0x00e0   MakeModel                            H264 MakeModel
     13263  0x00e1   RecInfo                              H264 RecInfo
     13264  0x00e4   Model                                N
     13265  0x00ee   FrameInfo                            H264 FrameInfo
     13266
     13267=head3 H264 Camera1 Tags
     13268
     13269   Index   Tag Name                             Writable
     13270   -----   --------                             --------
     13271      0    ApertureSetting                      N
     13272      1    Gain                                 N
     13273    1.1    ExposureProgram                      N
     13274    2.1    WhiteBalance                         N
     13275      3    Focus                                N
     13276
     13277=head3 H264 Camera2 Tags
     13278
     13279   Index   Tag Name                             Writable
     13280   -----   --------                             --------
     13281      1    ImageStabilization                   N
     13282
     13283=head3 H264 Shutter Tags
     13284
     13285   Index   Tag Name                             Writable
     13286   -----   --------                             --------
     13287    1.1    ExposureTime                         N
     13288
     13289=head3 H264 MakeModel Tags
     13290
     13291   Index   Tag Name                             Writable
     13292   -----   --------                             --------
     13293      0    Make                                 N
     13294
     13295=head3 H264 RecInfo Tags
     13296
     13297Recording information stored by some Canon video cameras.
     13298
     13299   Index   Tag Name                             Writable
     13300   -----   --------                             --------
     13301      0    RecordingMode                        N
     13302
     13303=head3 H264 FrameInfo Tags
     13304
     13305Frame rate information stored by some Canon video cameras.
     13306
     13307   Index   Tag Name                             Writable
     13308   -----   --------                             --------
     13309      0    CaptureFrameRate                     N
     13310      1    VideoFrameRate                       N
     13311
     13312=head2 QuickTime Tags
     13313
     13314The QuickTime format is used for many different types of audio, video and
     13315image files.  Exiftool extracts meta information from the UserData atom
     13316(including some proprietary manufacturer-specific information), as well as
     13317extracting various audio, video and image parameters.  Tags with a question
     13318mark after their name are not extracted unless the Unknown option is set.
     13319
     13320  Tag ID               Tag Name                 Writable
     13321  ------               --------                 --------
     13322  'PICT'               PreviewPICT              N
     13323  'free'               Free?                    N
     13324  'ftyp'               FileType                 QuickTime FileType
     13325  'junk'               Junk?                    N
     13326  'mdat'               MovieData?               N
     13327  'mdat-size'          MovieDataSize            N
     13328  'moov'               Movie                    QuickTime Movie
     13329  'pict'               PreviewPICT              N
     13330  'pnot'               Preview                  QuickTime Preview
     13331  'skip'               Skip?                    N
     13332  'uuid'               UUID-XMP                 XMP
     13333                       UUID-PROF                QuickTime Profile
     13334                       UUID-Flip                QuickTime Flip
     13335                       UUID-Unknown?            N
     13336  'wide'               Wide?                    N
     13337
     13338=head3 QuickTime FileType Tags
     13339
     13340   Index   Tag Name                             Writable
     13341   -----   --------                             --------
     13342      0    MajorBrand                           N
     13343      1    MinorVersion                         N
     13344      2    CompatibleBrands                     N
    732413345
    732513346=head3 QuickTime Movie Tags
     
    732713348  Tag ID   Tag Name                             Writable
    732813349  ------   --------                             --------
    7329   'mvhd'   MovieHeader                          QuickTime MovieHdr
     13350  'iods'   InitialObjectDescriptor?             N
     13351  'meta'   Meta                                 QuickTime Meta
     13352  'mvhd'   MovieHeader                          QuickTime MovieHeader
    733013353  'trak'   Track                                QuickTime Track
    733113354  'udta'   UserData                             QuickTime UserData
    7332 
    7333 =head3 QuickTime MovieHdr Tags
    7334 
    7335    Index   Tag Name                             Writable
    7336    -----   --------                             --------
    7337       0    Version                              N
     13355  'uuid'   UUID-USMT                            QuickTime UserMedia
     13356           UUID-Unknown?                        N
     13357
     13358=head3 QuickTime Meta Tags
     13359
     13360  Tag ID   Tag Name                             Writable
     13361  ------   --------                             --------
     13362  'bxml'   BinaryXML?                           N
     13363  'dinf'   DataInformation?                     N
     13364  'free'   Free?                                N
     13365  'hdlr'   Handler                              QuickTime Handler
     13366  'iinf'   ItemInformation?                     N
     13367  'iloc'   ItemLocation?                        N
     13368  'ilst'   ItemList                             QuickTime ItemList
     13369  'ipmc'   IPMPControl?                         N
     13370  'ipro'   ItemProtection?                      N
     13371  'keys'   Keys                                 QuickTime Keys
     13372  'pitm'   PrimaryItemReference?                N
     13373  'xml '   XML                                  XMP
     13374
     13375=head3 QuickTime Handler Tags
     13376
     13377   Index   Tag Name                             Writable
     13378   -----   --------                             --------
     13379      4    HandlerClass                         N
     13380      8    HandlerType                          N
     13381     12    HandlerVendorID                      N
     13382     24    HandlerDescription                   N
     13383
     13384=head3 QuickTime ItemList Tags
     13385
     13386As well as these tags, the 'mdta' handler uses numerical tag ID's which are
     13387added dynamically to this table after processing the Meta Keys information.
     13388
     13389  Tag ID       Tag Name                         Writable
     13390  ------       --------                         --------
     13391  '----'       iTunesInfo                       QuickTime iTunesInfo
     13392  'aART'       AlbumArtist                      N
     13393  'akID'       AppleStoreAccountType            N
     13394  'albm'       Album                            N
     13395  'apID'       AppleStoreAccount                N
     13396  'atID'       AlbumTitleID                     N
     13397  'auth'       Author                           N
     13398  'catg'       Category                         N
     13399  'cnID'       AppleStoreCatalogID              N
     13400  'covr'       CoverArt                         N
     13401  'cpil'       Compilation                      N
     13402  'cprt'       Copyright                        N
     13403  'desc'       Description                      N
     13404  'disk'       DiskNumber                       N
     13405  'dscp'       Description                      N
     13406  'egid'       EpisodeGlobalUniqueID            N
     13407  'geID'       GenreID                          N
     13408  'gnre'       Genre                            N
     13409  'grup'       Grouping                         N
     13410  'hdvd'       HDVideo                          N
     13411  'keyw'       Keyword                          N
     13412  'ldes'       LongDescription                  N
     13413  'pcst'       Podcast                          N
     13414  'perf'       Performer                        N
     13415  'pgap'       PlayGap                          N
     13416  'plID'       PlayListID                       N
     13417  'purd'       PurchaseDate                     N
     13418  'purl'       PodcastURL                       N
     13419  'rtng'       Rating                           N
     13420  'sfID'       AppleStoreCountry                N
     13421  'soaa'       SortAlbumArtist                  N
     13422  'soal'       SortAlbum                        N
     13423  'soar'       SortArtist                       N
     13424  'soco'       SortComposer                     N
     13425  'sonm'       SortName                         N
     13426  'sosn'       SortShow                         N
     13427  'stik'       MediaType                        N
     13428  'titl'       Title                            N
     13429  'tmpo'       BeatsPerMinute                   N
     13430  'trkn'       TrackNumber                      N
     13431  'tven'       TVEpisodeID                      N
     13432  'tves'       TVEpisode                        N
     13433  'tvnn'       TVNetworkName                    N
     13434  'tvsh'       TVShow                           N
     13435  'tvsn'       TVSeason                         N
     13436  'yrrc'       Year                             N
     13437  "\xa9ART"    Artist                           N
     13438  "\xa9alb"    Album                            N
     13439  "\xa9cmt"    Comment                          N
     13440  "\xa9com"    Composer                         N
     13441  "\xa9day"    Year                             N
     13442  "\xa9des"    Description                      N
     13443  "\xa9enc"    EncodedBy                        N
     13444  "\xa9gen"    Genre                            N
     13445  "\xa9grp"    Grouping                         N
     13446  "\xa9lyr"    Lyrics                           N
     13447  "\xa9nam"    Title                            N
     13448  "\xa9too"    Encoder                          N
     13449  "\xa9trk"    Track                            N
     13450  "\xa9wrt"    Composer                         N
     13451
     13452=head3 QuickTime iTunesInfo Tags
     13453
     13454  Tag ID   Tag Name                             Writable
     13455  ------   --------                             --------
     13456  'data'   Data?                                N
     13457  'mean'   Mean?                                N
     13458  'name'   Name?                                N
     13459
     13460=head3 QuickTime Keys Tags
     13461
     13462This directory contains a list of key names which are used to decode
     13463ItemList tags written by the "mdta" handler.  The prefix of
     13464"com.apple.quicktime." has been removed from all TagID's below.
     13465
     13466  Tag ID                       Tag Name         Writable
     13467  ------                       --------         --------
     13468  'album'                      Album            N
     13469  'artist'                     Artist           N
     13470  'artwork'                    Artwork          N
     13471  'author'                     Author           N
     13472  'camera.framereadouttimeinmicroseconds'
     13473                               FrameReadoutTime N
     13474  'camera.identifier'          CameraIdentifier N
     13475  'comment'                    Comment          N
     13476  'copyright'                  Copyright        N
     13477  'creationdate'               CreationDate     N
     13478  'description'                Description      N
     13479  'direction.facing'           CameraDirection  N
     13480  'direction.motion'           CameraMotion     N
     13481  'director'                   Director         N
     13482  'genre'                      Genre            N
     13483  'information'                Information      N
     13484  'keywords'                   Keywords         N
     13485  'location.ISO6709'           GPSCoordinates   N
     13486  'location.body'              LocationBody     N
     13487  'location.date'              LocationDate     N
     13488  'location.name'              LocationName     N
     13489  'location.note'              LocationNote     N
     13490  'location.role'              LocationRole     N
     13491  'make'                       Make             N
     13492  'model'                      Model            N
     13493  'player.movie.audio.balance' Balance          N
     13494  'player.movie.audio.bass'    Bass             N
     13495  'player.movie.audio.gain'    AudioGain        N
     13496  'player.movie.audio.mute'    Mute             N
     13497  'player.movie.audio.pitchshift' PitchShift    N
     13498  'player.movie.audio.treble'  Trebel           N
     13499  'player.movie.visual.brightness' Brightness   N
     13500  'player.movie.visual.color'  Color            N
     13501  'player.movie.visual.contrast' Contrast       N
     13502  'player.movie.visual.tint'   Tint             N
     13503  'player.version'             PlayerVersion    N
     13504  'publisher'                  Publisher        N
     13505  'software'                   Software         N
     13506  'version'                    Version          N
     13507  'year'                       Year             N
     13508
     13509=head3 QuickTime MovieHeader Tags
     13510
     13511   Index   Tag Name                             Writable
     13512   -----   --------                             --------
     13513      0    MovieHeaderVersion                   N
    733813514      1    CreateDate                           N
    733913515      2    ModifyDate                           N
     
    734213518      5    PreferredRate                        N
    734313519      6    PreferredVolume                      N
     13520      9    MatrixStructure                      N
    734413521     18    PreviewTime                          N
    734513522     19    PreviewDuration                      N
     
    735513532  ------   --------                             --------
    735613533  'mdia'   Media                                QuickTime Media
    7357   'tkhd'   TrackHeader                          QuickTime TrackHdr
     13534  'meta'   Meta                                 QuickTime Meta
     13535  'tkhd'   TrackHeader                          QuickTime TrackHeader
     13536  'tref'   TrackRef                             QuickTime TrackRef
    735813537  'udta'   UserData                             QuickTime UserData
     13538  'uuid'   UUID-USMT                            QuickTime UserMedia
     13539           UUID-Unknown?                        N
    735913540
    736013541=head3 QuickTime Media Tags
    736113542
    7362 MP4 only (most tags unknown because ISO charges for the specification).
     13543MP4 media box.
    736313544
    736413545  Tag ID   Tag Name                             Writable
    736513546  ------   --------                             --------
    7366   'minf'   Minf                                 QuickTime Minf
    7367 
    7368 =head3 QuickTime Minf Tags
    7369 
    7370 MP4 only (most tags unknown because ISO charges for the specification).
     13547  'hdlr'   Handler                              QuickTime Handler
     13548  'mdhd'   MediaHeader                          QuickTime MediaHeader
     13549  'minf'   MediaInfo                            QuickTime MediaInfo
     13550
     13551=head3 QuickTime MediaHeader Tags
     13552
     13553   Index   Tag Name                             Writable
     13554   -----   --------                             --------
     13555      0    MediaHeaderVersion                   N
     13556      1    MediaCreateDate                      N
     13557      2    MediaModifyDate                      N
     13558      3    MediaTimeScale                       N
     13559      4    MediaDuration                        N
     13560      5    MediaLanguageCode                    N
     13561
     13562=head3 QuickTime MediaInfo Tags
     13563
     13564MP4 media info box.
    737113565
    737213566  Tag ID   Tag Name                             Writable
    737313567  ------   --------                             --------
    7374   'dinf'   Dinf                                 QuickTime Dinf
    7375   'stbl'   Stbl                                 QuickTime Stbl
    7376 
    7377 =head3 QuickTime Dinf Tags
    7378 
    7379 MP4 only (most tags unknown because ISO charges for the specification).
     13568  'dinf'   DataInfo                             QuickTime DataInfo
     13569  'gmhd'   GenMediaHeader                       QuickTime GenMediaHeader
     13570  'hdlr'   Handler                              QuickTime Handler
     13571  'hmhd'   HintHeader                           QuickTime HintHeader
     13572  'nmhd'   NullMediaHeader?                     N
     13573  'smhd'   AudioHeader                          QuickTime AudioHeader
     13574  'stbl'   SampleTable                          QuickTime SampleTable
     13575  'vmhd'   VideoHeader                          QuickTime VideoHeader
     13576
     13577=head3 QuickTime DataInfo Tags
     13578
     13579MP4 data information box.
    738013580
    738113581  Tag ID   Tag Name                             Writable
    738213582  ------   --------                             --------
    7383   [no tags known]
    7384 
    7385 =head3 QuickTime Stbl Tags
    7386 
    7387 MP4 only (most tags unknown because ISO charges for the specification).
     13583  'dref'   DataRef                              QuickTime DataRef
     13584
     13585=head3 QuickTime DataRef Tags
     13586
     13587MP4 data reference box.
    738813588
    738913589  Tag ID   Tag Name                             Writable
    739013590  ------   --------                             --------
    7391   [no tags known]
    7392 
    7393 =head3 QuickTime TrackHdr Tags
    7394 
    7395    Index   Tag Name                             Writable
    7396    -----   --------                             --------
    7397       0    TrackVersion                         N
     13591  'url '   URL                                  N
     13592  'urn '   URN                                  N
     13593
     13594=head3 QuickTime GenMediaHeader Tags
     13595
     13596  Tag ID   Tag Name                             Writable
     13597  ------   --------                             --------
     13598  'gmin'   GenMediaInfo                         QuickTime GenMediaInfo
     13599  'text'   Text?                                N
     13600
     13601=head3 QuickTime GenMediaInfo Tags
     13602
     13603   Index   Tag Name                             Writable
     13604   -----   --------                             --------
     13605      0    GenMediaVersion                      N
     13606      1    GenFlags                             N
     13607      4    GenGraphicsMode                      N
     13608      6    GenOpColor                           N
     13609     12    GenBalance                           N
     13610
     13611=head3 QuickTime HintHeader Tags
     13612
     13613MP4 hint media header.
     13614
     13615   Index   Tag Name                             Writable
     13616   -----   --------                             --------
     13617      2    MaxPDUSize                           N
     13618      3    AvgPDUSize                           N
     13619      4    MaxBitrate                           N
     13620      6    AvgBitrate                           N
     13621
     13622=head3 QuickTime AudioHeader Tags
     13623
     13624MP4 audio media header.
     13625
     13626   Index   Tag Name                             Writable
     13627   -----   --------                             --------
     13628      2    Balance                              N
     13629
     13630=head3 QuickTime SampleTable Tags
     13631
     13632MP4 sample table box.
     13633
     13634  Tag ID   Tag Name                             Writable
     13635  ------   --------                             --------
     13636  'co64'   ChunkOffset64?                       N
     13637  'cslg'   CompositionToDecodeTimelineMapping?  N
     13638  'ctts'   CompositionTimeToSample?             N
     13639  'padb'   SamplePaddingBits?                   N
     13640  'sbgp'   SampleToGroup?                       N
     13641  'sdtp'   IdependentAndDisposableSamples?      N
     13642  'sgpd'   SampleGroupDescription?              N
     13643  'stco'   ChunkOffset?                         N
     13644  'stdp'   SampleDegradationPriority?           N
     13645  'stsc'   SampleToChunk?                       N
     13646  'stsd'   AudioSampleDesc                      QuickTime AudioSampleDesc
     13647           VideoSampleDesc                      QuickTime ImageDesc
     13648           HintSampleDesc                       QuickTime HintSampleDesc
     13649           OtherSampleDesc                      QuickTime OtherSampleDesc
     13650  'stsh'   ShadowSyncSampleTable?               N
     13651  'stss'   SyncSampleTable?                     N
     13652  'stsz'   SampleSizes?                         N
     13653  'stts'   VideoFrameRate                       N
     13654           TimeToSampleTable?                   N
     13655  'stz2'   CompactSampleSizes?                  N
     13656  'subs'   Sub-sampleInformation?               N
     13657
     13658=head3 QuickTime AudioSampleDesc Tags
     13659
     13660MP4 audio sample description.
     13661
     13662   Index   Tag Name                             Writable
     13663   -----   --------                             --------
     13664      2    AudioFormat                          N
     13665     10    AudioVendorID                        N
     13666     12    AudioChannels                        N
     13667     13    AudioBitsPerSample                   N
     13668     16    AudioSampleRate                      N
     13669     28    AudioFormat                          N
     13670
     13671=head3 QuickTime ImageDesc Tags
     13672
     13673   Index   Tag Name                             Writable
     13674   -----   --------                             --------
     13675      2    CompressorID                         N
     13676     10    VendorID                             N
     13677     16    SourceImageWidth                     N
     13678     17    SourceImageHeight                    N
     13679     18    XResolution                          N
     13680     20    YResolution                          N
     13681     25    CompressorName                       N
     13682     41    BitDepth                             N
     13683
     13684=head3 QuickTime HintSampleDesc Tags
     13685
     13686MP4 hint sample description.
     13687
     13688   Index   Tag Name                             Writable
     13689   -----   --------                             --------
     13690      2    HintFormat                           N
     13691
     13692=head3 QuickTime OtherSampleDesc Tags
     13693
     13694   Index   Tag Name                             Writable
     13695   -----   --------                             --------
     13696      2    OtherFormat                          N
     13697
     13698=head3 QuickTime VideoHeader Tags
     13699
     13700MP4 video media header.
     13701
     13702   Index   Tag Name                             Writable
     13703   -----   --------                             --------
     13704      2    GraphicsMode                         N
     13705      3    OpColor                              N
     13706
     13707=head3 QuickTime TrackHeader Tags
     13708
     13709   Index   Tag Name                             Writable
     13710   -----   --------                             --------
     13711      0    TrackHeaderVersion                   N
    739813712      1    TrackCreateDate                      N
    739913713      2    TrackModifyDate                      N
     
    740213716      8    TrackLayer                           N
    740313717      9    TrackVolume                          N
     13718     10    MatrixStructure                      N
    740413719     19    ImageWidth                           N
    740513720     20    ImageHeight                          N
    740613721
     13722=head3 QuickTime TrackRef Tags
     13723
     13724  Tag ID   Tag Name                             Writable
     13725  ------   --------                             --------
     13726  'chap'   ChapterList                          N
     13727
    740713728=head3 QuickTime UserData Tags
    740813729
    740913730Tag ID's beginning with the copyright symbol (hex 0xa9) are multi-language
    7410 text, but ExifTool only extracts the text from the first language in the
    7411 record.  ExifTool will extract any multi-language user data tags found, even
    7412 if they don't exist in this table.
     13731text.  Alternate language tags are accessed by adding a dash followed by the
     13732language/country code to the tag name.  ExifTool will extract any
     13733multi-language user data tags found, even if they don't exist in this table.
    741313734
    741413735  Tag ID       Tag Name                         Writable
    741513736  ------       --------                         --------
    741613737  'AllF'       PlayAllFrames                    N
     13738  'CNCV'       CompressorVersion                N
     13739  'CNFV'       FirmwareVersion                  N
     13740  'CNMN'       Model                            N
     13741  'CNTH'       CanonCNTH                        Canon CNTH
     13742  'DcMD'       DcMD                             QuickTime DcMD
     13743  'FFMV'       FujiFilmFFMV                     FujiFilm FFMV
     13744  'INFO'       SamsungINFO                      Samsung INFO
    741713745  'LOOP'       LoopStyle                        N
     13746  'MMA0'       MinoltaMMA0                      Minolta MMA
     13747  'MMA1'       MinoltaMMA1                      Minolta MMA
     13748  'MVTG'       FujiFilmMVTG                     EXIF
     13749  'NCDT'       NikonNCDT                        Nikon NCDT
     13750  'QVMI'       CasioQVMI                        EXIF
     13751  'SDLN'       PlayMode                         N
    741813752  'SelO'       PlaySelection                    N
    7419   'TAGS'       PentaxTags                       Pentax MOV
     13753  'TAGS'       KodakTags                        Kodak MOV
     13754               KonicaMinoltaTags                Minolta MOV1
     13755               MinoltaTags                      Minolta MOV2
    742013756               NikonTags                        Nikon MOV
     13757               OlympusTags1                     Olympus MOV1
     13758               OlympusTags2                     Olympus MOV2
     13759               OlympusTags3                     Olympus MP4
     13760               PentaxTags                       Pentax MOV
     13761               SamsungTags                      Samsung MP4
    742113762               SanyoMOV                         Sanyo MOV
    742213763               SanyoMP4                         Sanyo MP4
    742313764               UnknownTags?                     N
    742413765  'WLOC'       WindowLocation                   N
     13766  'XMP_'       XMP                              XMP
     13767  'hinf'       HintTrackInfo                    QuickTime HintTrackInfo
     13768  'hnti'       HintInfo                         QuickTime HintInfo
    742513769  'meta'       Meta                             QuickTime Meta
    742613770  'name'       Name                             N
    742713771  'ptv '       PrintToVideo                     QuickTime Video
     13772  'vndr'       Vendor                           N
     13773  "\xa9ART"    Artist                           N
     13774  "\xa9alb"    Album                            N
     13775  "\xa9arg"    Arranger                         N
     13776  "\xa9ark"    ArrangerKeywords                 N
     13777  "\xa9cmt"    Comment                          N
     13778  "\xa9cok"    ComposerKeywords                 N
     13779  "\xa9com"    Composer                         N
    742813780  "\xa9cpy"    Copyright                        N
    742913781  "\xa9day"    CreateDate                       N
     
    743913791  "\xa9ed9"    Edit9                            N
    744013792  "\xa9fmt"    Format                           N
     13793  "\xa9gen"    Genre                            N
     13794  "\xa9grp"    Grouping                         N
    744113795  "\xa9inf"    Information                      N
     13796  "\xa9isr"    ISRCCode                         N
     13797  "\xa9lab"    RecordLabelName                  N
     13798  "\xa9lal"    RecordLabelURL                   N
     13799  "\xa9lyr"    Lyrics                           N
     13800  "\xa9mak"    Make                             N
     13801  "\xa9mal"    MakerURL                         N
     13802  "\xa9mod"    Model                            N
     13803  "\xa9nam"    Title                            N
     13804  "\xa9pdk"    ProducerKeywords                 N
     13805  "\xa9phg"    RecordingCopyright               N
    744213806  "\xa9prd"    Producer                         N
    744313807  "\xa9prf"    Performers                       N
     13808  "\xa9prk"    PerformerKeywords                N
     13809  "\xa9prl"    PerformerURL                     N
    744413810  "\xa9req"    Requirements                     N
    7445   "\xa9src"    Source                           N
    7446   "\xa9wrt"    Writer                           N
    7447 
    7448 =head3 QuickTime Meta Tags
    7449 
    7450   Tag ID   Tag Name                             Writable
    7451   ------   --------                             --------
    7452   'ilst'   InfoList                             QuickTime InfoList
    7453 
    7454 =head3 QuickTime InfoList Tags
    7455 
    7456   Tag ID       Tag Name                         Writable
    7457   ------       --------                         --------
    7458   '----'       iTunesInfo                       QuickTime iTunesInfo
    7459   'aART'       AlbumArtist                      N
    7460   'apid'       AppleStoreID                     N
    7461   'auth'       Author                           N
    7462   'covr'       CoverArt                         N
    7463   'cpil'       Compilation                      N
    7464   'cprt'       Copyright                        N
    7465   'disk'       DiskNumber                       N
    7466   'dscp'       Description                      N
    7467   'gnre'       Genre                            N
    7468   'perf'       Performer                        N
    7469   'pgap'       PlayGap                          N
    7470   'rtng'       Rating                           N
    7471   'titl'       Title                            N
    7472   'tmpo'       BeatsPerMinute                   N
    7473   'trkn'       TrackNumber                      N
    7474   "\xa9ART"    Artist                           N
    7475   "\xa9alb"    Album                            N
    7476   "\xa9cmt"    Comment                          N
    7477   "\xa9com"    Composer                         N
    7478   "\xa9day"    Year                             N
    7479   "\xa9des"    Description                      N
    7480   "\xa9gen"    Genre                            N
    7481   "\xa9grp"    Grouping                         N
    7482   "\xa9lyr"    Lyrics                           N
    7483   "\xa9nam"    Title                            N
     13811  "\xa9snk"    SubtitleKeywords                 N
     13812  "\xa9snm"    Subtitle                         N
     13813  "\xa9src"    SourceCredits                    N
     13814  "\xa9swf"    SongWriter                       N
     13815  "\xa9swk"    SongWriterKeywords               N
     13816  "\xa9swr"    SoftwareVersion                  N
    748413817  "\xa9too"    Encoder                          N
    748513818  "\xa9trk"    Track                            N
    748613819  "\xa9wrt"    Composer                         N
    7487 
    7488 =head3 QuickTime iTunesInfo Tags
     13820  "\xa9xyz"    GPSCoordinates                   N
     13821
     13822=head3 QuickTime DcMD Tags
     13823
     13824Metadata directory found in MOV videos from some Kodak cameras.
     13825
     13826  Tag ID   Tag Name                             Writable
     13827  ------   --------                             --------
     13828  'Cmbo'   CameraByteOrder                      N
     13829  'DcME'   DcME                                 QuickTime DcME
     13830
     13831=head3 QuickTime DcME Tags
    748913832
    749013833  Tag ID   Tag Name                             Writable
     
    749213835  [no tags known]
    749313836
     13837=head3 QuickTime HintTrackInfo Tags
     13838
     13839  Tag ID   Tag Name                             Writable
     13840  ------   --------                             --------
     13841  'dimm'   ImmediateDataBytes                   N
     13842  'dmax'   LargestPacketDuration                N
     13843  'dmed'   MediaTrackBytes                      N
     13844  'drep'   RepeatedDataBytes                    N
     13845  'maxr'   MaxDataRate                          N
     13846  'npck'   NumPackets                           N
     13847  'nump'   NumPackets                           N
     13848  'payt'   PayloadType                          N
     13849  'pmax'   LargestPacketSize                    N
     13850  'tmax'   MaxTransmissionTime                  N
     13851  'tmin'   MinTransmissionTime                  N
     13852  'totl'   TotalBytes                           N
     13853  'tpaY'   TotalBytesNoRTPHeaders               N
     13854  'tpay'   TotalBytesNoRTPHeaders               N
     13855  'tpyl'   TotalBytesNoRTPHeaders               N
     13856  'trpY'   TotalBytes                           N
     13857  'trpy'   TotalBytes                           N
     13858
     13859=head3 QuickTime HintInfo Tags
     13860
     13861  Tag ID   Tag Name                             Writable
     13862  ------   --------                             --------
     13863  'rtp '   RealtimeStreamingProtocol            N
     13864  'sdp '   StreamingDataProtocol                N
     13865
    749413866=head3 QuickTime Video Tags
    749513867
     
    749813870      0    DisplaySize                          N
    749913871      6    SlideShow                            N
     13872
     13873=head3 QuickTime UserMedia Tags
     13874
     13875  Tag ID   Tag Name                             Writable
     13876  ------   --------                             --------
     13877  'MTDT'   MetaData                             QuickTime MetaData
     13878
     13879=head3 QuickTime MetaData Tags
     13880
     13881  Tag ID   Tag Name                             Writable
     13882  ------   --------                             --------
     13883  0x0001   Title                                N
     13884  0x0003   ProductionDate                       N
     13885  0x0004   Software                             N
     13886  0x0005   Product                              N
     13887  0x000a   TrackProperty                        N
     13888  0x000b   TimeZone                             N
     13889  0x000c   ModifyDate                           N
    750013890
    750113891=head3 QuickTime Preview Tags
     
    750713897      3    PreviewAtomType                      N
    750813898      5    PreviewAtomIndex                     N
     13899
     13900=head3 QuickTime Profile Tags
     13901
     13902  Tag ID   Tag Name                             Writable
     13903  ------   --------                             --------
     13904  'APRF'   AudioProfile                         QuickTime AudioProf
     13905  'FPRF'   FileGlobalProfile                    QuickTime FileProf
     13906  'VPRF'   VideoProfile                         QuickTime VideoProf
     13907
     13908=head3 QuickTime AudioProf Tags
     13909
     13910   Index   Tag Name                             Writable
     13911   -----   --------                             --------
     13912      0    AudioProfileVersion?                 N
     13913      1    AudioTrackID                         N
     13914      2    AudioCodec                           N
     13915      3    AudioCodecInfo?                      N
     13916      4    AudioAttributes                      N
     13917      5    AudioAvgBitrate                      N
     13918      6    AudioMaxBitrate                      N
     13919      7    AudioSampleRate                      N
     13920      8    AudioChannels                        N
     13921
     13922=head3 QuickTime FileProf Tags
     13923
     13924   Index   Tag Name                             Writable
     13925   -----   --------                             --------
     13926      0    FileProfileVersion?                  N
     13927      1    FileFunctionFlags                    N
     13928
     13929=head3 QuickTime VideoProf Tags
     13930
     13931   Index   Tag Name                             Writable
     13932   -----   --------                             --------
     13933      0    VideoProfileVersion?                 N
     13934      1    VideoTrackID                         N
     13935      2    VideoCodec                           N
     13936      3    VideoCodecInfo?                      N
     13937      4    VideoAttributes                      N
     13938      5    VideoAvgBitrate                      N
     13939      6    VideoMaxBitrate                      N
     13940      7    VideoAvgFrameRate                    N
     13941      8    VideoMaxFrameRate                    N
     13942      9    VideoSize                            N
     13943     10    PixelAspectRatio                     N
     13944
     13945=head3 QuickTime Flip Tags
     13946
     13947Found in MP4 files from Flip Video cameras.
     13948
     13949   Index   Tag Name                             Writable
     13950   -----   --------                             --------
     13951      1    PreviewImageWidth                    N
     13952      2    PreviewImageHeight                   N
     13953     13    PreviewImageLength                   N
     13954     14    SerialNumber                         N
     13955     28    PreviewImage                         N
    750913956
    751013957=head3 QuickTime ImageFile Tags
     
    751813965  'iicc'   ICC_Profile                          ICC_Profile
    751913966
    7520 =head3 QuickTime ImageDesc Tags
    7521 
    7522    Index   Tag Name                             Writable
    7523    -----   --------                             --------
    7524       4    CompressorID                         N
    7525      20    VendorID                             N
    7526      28    Quality                              N
    7527      32    ImageWidth                           N
    7528      34    ImageHeight                          N
    7529      36    XResolution                          N
    7530      40    YResolution                          N
    7531      48    FrameCount                           N
    7532      50    NameLength                           N
    7533      51    Compressor                           N
    7534      82    BitDepth                             N
     13967=head2 Matroska Tags
     13968
     13969The following tags are extracted from Matroska multimedia container files.
     13970This container format is used by file types such as MKA, MKV, MKS and WEBM.
     13971For speed, ExifTool extracts tags only up to the first Cluster unless the
     13972Verbose (-v) or Unknown = 2 (-U) option is used.  See
     13973L<http://www.matroska.org/technical/specs/index.html> for the official
     13974Matroska specification.
     13975
     13976  Tag ID       Tag Name                         Writable
     13977  ------       --------                         --------
     13978  0x0000       ChapterDisplay                   Matroska
     13979  0x0003       TrackType                        N
     13980  0x0005       ChapterString                    N
     13981  0x0006       VideoCodecID                     N
     13982               AudioCodecID                     N
     13983               CodecID                          N
     13984  0x0008       TrackDefault                     N
     13985  0x0009       ChapterTrackNumber?              N
     13986  0x000e       Slices                           Matroska
     13987  0x000f       ChapterTrack                     Matroska
     13988  0x0011       ChapterTimeStart                 N
     13989  0x0012       ChapterTimeEnd                   N
     13990  0x0016       CueRefTime?                      N
     13991  0x0017       CueRefCluster?                   N
     13992  0x0018       ChapterFlagHidden?               N
     13993  0x001a       VideoScanType                    N
     13994  0x001b       BlockDuration?                   N
     13995  0x001c       TrackLacing?                     N
     13996  0x001f       AudioChannels                    N
     13997  0x0020       BlockGroup                       Matroska
     13998  0x0021       Block?                           N
     13999  0x0022       BlockVirtual?                    N
     14000  0x0023       SimpleBlock?                     N
     14001  0x0024       CodecState?                      N
     14002  0x0025       BlockAdditional?                 N
     14003  0x0026       BlockMore                        Matroska
     14004  0x0027       Position                         N
     14005  0x002a       CodecDecodeAll                   N
     14006  0x002b       PrevSize                         N
     14007  0x002e       TrackEntry                       Matroska
     14008  0x002f       EncryptedBlock?                  N
     14009  0x0030       ImageWidth                       N
     14010  0x0033       CueTime?                         N
     14011  0x0035       AudioSampleRate                  N
     14012  0x0036       ChapterAtom                      Matroska
     14013  0x0037       CueTrackPositions                Matroska
     14014  0x0039       TrackUsed                        N
     14015  0x003a       ImageHeight                      N
     14016  0x003b       CuePoint                         Matroska
     14017  0x003f       CRC-32?                          N
     14018  0x004b       BlockAdditionalID?               N
     14019  0x004c       LaceNumber?                      N
     14020  0x004d       FrameNumber?                     N
     14021  0x004e       Delay?                           N
     14022  0x004f       ClusterDuration?                 N
     14023  0x0057       TrackNumber                      N
     14024  0x005b       CueReference                     Matroska
     14025  0x0060       Video                            Matroska
     14026  0x0061       Audio                            Matroska
     14027  0x0067       Timecode?                        N
     14028  0x0068       TimeSlice                        Matroska
     14029  0x006a       CueCodecState?                   N
     14030  0x006b       CueRefCodecState?                N
     14031  0x006c       Void?                            N
     14032  0x006e       BlockAddID?                      N
     14033  0x0071       CueClusterPosition?              N
     14034  0x0077       CueTrack?                        N
     14035  0x007a       ReferencePriority?               N
     14036  0x007b       ReferenceBlock?                  N
     14037  0x007d       ReferenceVirtual?                N
     14038  0x0254       ContentCompressionAlgorithm      N
     14039  0x0255       ContentCompressionSettings?      N
     14040  0x0282       DocType                          N
     14041  0x0285       DocTypeReadVersion               N
     14042  0x0286       EBMLVersion                      N
     14043  0x0287       DocTypeVersion                   N
     14044  0x02f2       EBMLMaxIDLength?                 N
     14045  0x02f3       EBMLMaxSizeLength?               N
     14046  0x02f7       EBMLReadVersion                  N
     14047  0x037c       ChapterLanguage                  N
     14048  0x037e       ChapterCountry                   N
     14049  0x0444       SegmentFamily?                   N
     14050  0x0461       DateTimeOriginal                 N
     14051  0x047a       TagLanguage                      N
     14052  0x0484       TagDefault                       N
     14053  0x0485       TagBinary                        N
     14054  0x0487       TagString                        N
     14055  0x0489       Duration                         N
     14056  0x050d       ChapterProcessPrivate?           N
     14057  0x0598       ChapterFlagEnabled?              N
     14058  0x05a3       TagName                          N
     14059  0x05b9       EditionEntry                     Matroska
     14060  0x05bc       EditionUID?                      N
     14061  0x05bd       EditionFlagHidden?               N
     14062  0x05db       EditionFlagDefault?              N
     14063  0x05dd       EditionFlagOrdered?              N
     14064  0x065c       AttachedFileData                 N
     14065  0x0660       AttachedFileMIMEType             N
     14066  0x066e       AttachedFileName                 N
     14067  0x0675       AttachedFileReferral?            N
     14068  0x067e       AttachedFileDescription          N
     14069  0x06ae       AttachedFileUID                  N
     14070  0x07e1       ContentEncryptionAlgorithm       N
     14071  0x07e2       ContentEncryptionKeyID?          N
     14072  0x07e3       ContentSignature?                N
     14073  0x07e4       ContentSignatureKeyID?           N
     14074  0x07e5       ContentSignatureAlgorithm        N
     14075  0x07e6       ContentSignatureHashAlgorithm    N
     14076  0x0d80       MuxingApp                        N
     14077  0x0dbb       Seek                             Matroska
     14078  0x1031       ContentEncodingOrder?            N
     14079  0x1032       ContentEncodingScope?            N
     14080  0x1033       ContentEncodingType              N
     14081  0x1034       ContentCompression               Matroska
     14082  0x1035       ContentEncryption                Matroska
     14083  0x135f       CueRefNumber?                    N
     14084  0x136e       TrackName                        N
     14085  0x1378       CueBlockNumber?                  N
     14086  0x137f       TrackOffset?                     N
     14087  0x13ab       SeekID?                          N
     14088  0x13ac       SeekPosition?                    N
     14089  0x13b8       Stereo3DMode                     N
     14090  0x14aa       CropBottom                       N
     14091  0x14b0       DisplayWidth                     N
     14092  0x14b2       DisplayUnit                      N
     14093  0x14b3       AspectRatioType                  N
     14094  0x14ba       DisplayHeight                    N
     14095  0x14bb       CropTop                          N
     14096  0x14cc       CropLeft                         N
     14097  0x14dd       CropRight                        N
     14098  0x15aa       TrackForced                      N
     14099  0x15ee       MaxBlockAdditionID?              N
     14100  0x1741       WritingApp                       N
     14101  0x1854       SilentTracks                     Matroska
     14102  0x18d7       SilentTrackNumber                N
     14103  0x21a7       AttachedFile                     Matroska
     14104  0x2240       ContentEncoding                  Matroska
     14105  0x2264       AudioBitsPerSample               N
     14106  0x23a2       CodecPrivate?                    N
     14107  0x23c0       Targets                          Matroska
     14108  0x23c3       ChapterPhysicalEquivalent        N
     14109  0x23c4       TagChapterUID?                   N
     14110  0x23c5       TagTrackUID?                     N
     14111  0x23c6       TagAttachmentUID?                N
     14112  0x23c9       TagEditionUID?                   N
     14113  0x23ca       TargetType                       N
     14114  0x2532       SignedElement?                   N
     14115  0x2624       TrackTranslate                   Matroska
     14116  0x26a5       TrackTranslateTrackID?           N
     14117  0x26bf       TrackTranslateCodec              N
     14118  0x26fc       TrackTranslateEditionUID?        N
     14119  0x27c8       SimpleTag                        Matroska
     14120  0x28ca       TargetTypeValue                  N
     14121  0x2911       ChapterProcessCommand            Matroska
     14122  0x2922       ChapterProcessTime?              N
     14123  0x2924       ChapterTranslate                 Matroska
     14124  0x2933       ChapterProcessData?              N
     14125  0x2944       ChapterProcess                   Matroska
     14126  0x2955       ChapterProcessCodecID?           N
     14127  0x29a5       ChapterTranslateID?              N
     14128  0x29bf       ChapterTranslateCodec            N
     14129  0x29fc       ChapterTranslateEditionUID?      N
     14130  0x2d80       ContentEncodings                 Matroska
     14131  0x2de7       MinCache?                        N
     14132  0x2df8       MaxCache?                        N
     14133  0x2e67       ChapterSegmentUID?               N
     14134  0x2ebc       ChapterSegmentEditionUID?        N
     14135  0x2fab       TrackOverlay?                    N
     14136  0x3373       Tag                              Matroska
     14137  0x3384       SegmentFileName                  N
     14138  0x33a4       SegmentUID?                      N
     14139  0x33c4       ChapterUID?                      N
     14140  0x33c5       TrackUID?                        N
     14141  0x3446       TrackAttachmentUID               N
     14142  0x35a1       BlockAdditions                   Matroska
     14143  0x38b5       OutputAudioSampleRate            N
     14144  0x3ba9       Title                            N
     14145  0x3d7b       ChannelPositions?                N
     14146  0x3e5b       SignatureElements                Matroska
     14147  0x3e7b       SignatureElementList             Matroska
     14148  0x3e8a       SignatureAlgo                    N
     14149  0x3e9a       SignatureHash                    N
     14150  0x3ea5       SignaturePublicKey?              N
     14151  0x3eb5       Signature?                       N
     14152  0x2b59c      TrackLanguage                    N
     14153  0x3314f      TrackTimecodeScale               N
     14154  0x383e3      FrameRate                        N
     14155  0x3e383      VideoFrameRate                   N
     14156               DefaultDuration                  N
     14157  0x58688      VideoCodecName                   N
     14158               AudioCodecName                   N
     14159               CodecName                        N
     14160  0x6b240      CodecDownloadURL                 N
     14161  0xad7b1      TimecodeScale                    N
     14162  0xeb524      ColorSpace?                      N
     14163  0xfb523      Gamma                            N
     14164  0x1a9697     CodecSettings                    N
     14165  0x1b4040     CodecInfoURL                     N
     14166  0x1c83ab     PrevFileName                     N
     14167  0x1cb923     PrevUID?                         N
     14168  0x1e83bb     NextFileName                     N
     14169  0x1eb923     NextUID?                         N
     14170  0x43a770     Chapters                         Matroska
     14171  0x14d9b74    SeekHead                         Matroska
     14172  0x254c367    Tags                             Matroska
     14173  0x549a966    Info                             Matroska
     14174  0x654ae6b    Tracks                           Matroska
     14175  0x8538067    SegmentHeader                    Matroska
     14176  0x941a469    Attachments                      Matroska
     14177  0xa45dfa3    EBMLHeader                       Matroska
     14178  0xb538667    SignatureSlot                    Matroska
     14179  0xc53bb6b    Cues                             Matroska
     14180  0xf43b675    Cluster                          Matroska
     14181
     14182=head2 MXF Tags
     14183
     14184Tags extracted from Material Exchange Format files.  Tag ID's are not listed
     14185because they are bulky 16-byte binary values.
     14186
     14187  Tag Name                                      Writable
     14188  --------                                      --------
     14189  OrganizationID                                N
     14190  UPID?                                         N
     14191  UPN?                                          N
     14192  IBTN?                                         N
     14193  ISAN?                                         N
     14194  ISBN?                                         N
     14195  ISSN?                                         N
     14196  ISWC?                                         N
     14197  ISMN?                                         N
     14198  ISCI?                                         N
     14199  ISRC?                                         N
     14200  ISRN?                                         N
     14201  ISBD?                                         N
     14202  ISTC?                                         N
     14203  SICI?                                         N
     14204  BICI?                                         N
     14205  AICI?                                         N
     14206  PII?                                          N
     14207  DOI?                                          N
     14208  InstanceUID?                                  N
     14209  PackageID?                                    N
     14210  DeviceDesignation                             N
     14211  DeviceModel                                   N
     14212  DeviceSerialNumber                            N
     14213  URL                                           N
     14214  URL                                           N
     14215  PURL                                          N
     14216  URN                                           N
     14217  TransmissionID                                N
     14218  ArchiveID                                     N
     14219  ItemID                                        N
     14220  AccountingReferenceNumber                     N
     14221  TrafficID                                     N
     14222  ReelOrRollNumber                              N
     14223  LocalTapeNumber                               N
     14224  LUID                                          N
     14225  PackageName                                   N
     14226  LocalFilePath                                 N
     14227  EdgeCode                                      N
     14228  FrameCode                                     N
     14229  KeyCode?                                      N
     14230  InkNumber                                     N
     14231  KeyText                                       N
     14232  KeyFrame                                      N
     14233  KeySound                                      N
     14234  KeyDataOrProgram                              N
     14235  TitleKind                                     N
     14236  MainTitle                                     N
     14237  SecondaryTitle                                N
     14238  SeriesNumber                                  N
     14239  EpisodeNumber                                 N
     14240  SceneNumber                                   N
     14241  TakeNumber                                    N
     14242  CISACLegalEntityID?                           N
     14243  AGICOAID?                                     N
     14244  SourceOrganization                            N
     14245  SupplyContractNumber                          N
     14246  OriginalProducerName                          N
     14247  TotalEpisodeCount                             N
     14248  CopyrightStatus                               N
     14249  CopyrightOwnerName                            N
     14250  IntellectualPropertyDescription               N
     14251  IntellectualPropertyRights                    N
     14252  Rightsholder                                  N
     14253  RightsManagementAuthority                     N
     14254  InterestedPartyName                           N
     14255  MaximumUseCount                               N
     14256  LicenseOptionsDescription                     N
     14257  CurrencyCode                                  N
     14258  RoyaltyPaymentInformation                     N
     14259  RoyaltyIncomeInformation                      N
     14260  RestrictionsonUse                             N
     14261  ExCCIData?                                    N
     14262  Username                                      N
     14263  Username                                      N
     14264  Password                                      N
     14265  Password                                      N
     14266  ScramblingKeyKind                             N
     14267  ScramblingKeyValue                            N
     14268  BroadcastOrganizationName                     N
     14269  BroadcastChannel                              N
     14270  BroadcastMediumKind                           N
     14271  BroadcastRegion                               N
     14272  FirstBroadcastFlag                            N
     14273  CurrentRepeatNumber                           N
     14274  PreviousRepeatNumber                          N
     14275  AudienceRating                                N
     14276  AudienceReach                                 N
     14277  NatureOfPersonality                           N
     14278  ContributionStatus                            N
     14279  SupportOrAdministrationStatus                 N
     14280  OrganizationKind                              N
     14281  ProductionOrganizationRole                    N
     14282  SupportOrganizationRole                       N
     14283  JobFunctionName                               N
     14284  RoleName                                      N
     14285  ContactKind                                   N
     14286  ContactDepartmentName                         N
     14287  FamilyName                                    N
     14288  FirstGivenName                                N
     14289  SecondGivenName                               N
     14290  ThirdGivenName                                N
     14291  MainName                                      N
     14292  SupplementaryName                             N
     14293  OrganizationMainName                          N
     14294  SupplementaryOrganizationName                 N
     14295  ISO3166CountryCode                            N
     14296  ISO639-1LanguageCode                          N
     14297  OperatingSystemInterpretations                N
     14298  ByteOrder                                     N
     14299  EssenceIsIdentified                           N
     14300  LengthSystemName                              N
     14301  LengthUnitKind                                N
     14302  AngularUnitKind                               N
     14303  TimeSystemOffset                              N
     14304  TimeUnitKind                                  N
     14305  ContentCodingSystem                           N
     14306  ProgramKind                                   N
     14307  Genre                                         N
     14308  TargetAudience                                N
     14309  CatalogDataStatus                             N
     14310  ThesaurusName                                 N
     14311  Theme                                         N
     14312  ContentClassification                         N
     14313  Keywords                                      N
     14314  KeyFrames                                     N
     14315  KeySounds                                     N
     14316  KeyData                                       N
     14317  Abstract                                      N
     14318  Purpose                                       N
     14319  Description                                   N
     14320  ColorDescriptor                               N
     14321  FormatDescriptor                              N
     14322  StratumKind                                   N
     14323  IndividualAwardName                           N
     14324  ProgramAwardName                              N
     14325  AssetValue                                    N
     14326  ContentValue                                  N
     14327  CulturalValue                                 N
     14328  AestheticValue                                N
     14329  HistoricalValue                               N
     14330  TechnicalValue                                N
     14331  OtherValues                                   N
     14332  CatalogDataStatus                             N
     14333  CatalogingSystemName                          N
     14334  ComputedKeywords                              N
     14335  ComputedKeyFrames                             N
     14336  ComputedKeySounds                             N
     14337  ComputedKeyData                               N
     14338  ComputedStratumKind                           N
     14339  PresentationAspectRatio                       N
     14340  CaptureAspectRatio                            N
     14341  CaptureGammaEquation                          N
     14342  CaptureGammaEquation                          N
     14343  LumaEquation                                  N
     14344  ColorimetryCode                               N
     14345  SignalFormCode                                N
     14346  ColorFieldCode                                N
     14347  FieldRate                                     N
     14348  FrameRate                                     N
     14349  FrameLayout                                   N
     14350  SamplingStructureCode                         N
     14351  TotalLinesperFrame                            N
     14352  ActiveLinesperFrame                           N
     14353  LeadingLines                                  N
     14354  TrailingLines                                 N
     14355  AnalogVideoSystemName                         N
     14356  LuminanceSampleRate                           N
     14357  ActiveSamplesperLine                          N
     14358  TotalSamplesperLine                           N
     14359  SamplingHierarchyCode                         N
     14360  HorizontalSubsampling                         N
     14361  ColorSiting                                   N
     14362  SampledHeight                                 N
     14363  SampledWidth                                  N
     14364  SampledXOffset                                N
     14365  SampledYOffset                                N
     14366  DisplayHeight                                 N
     14367  DisplayWidth                                  N
     14368  DisplayXOffset                                N
     14369  DisplayYOffset                                N
     14370  FilteringCode                                 N
     14371  ImageHeight                                   N
     14372  ImageWidth                                    N
     14373  BitsperPixel                                  N
     14374  RoundingMethodCode                            N
     14375  BlackReferenceLevel                           N
     14376  WhiteReferenceLevel                           N
     14377  FieldFrameTypeCode                            N
     14378  PulldownSequence?                             N
     14379  PulldownFieldDominance                        N
     14380  VideoAndFilmFrameRelationship                 N
     14381  CaptureFilmFrameRate                          N
     14382  TransferFilmFrameRate                         N
     14383  VideoTestParameter                            N
     14384  VideoTestResult                               N
     14385  VideoTestResult                               N
     14386  FilmTestParameter                             N
     14387  FilmTestResult                                N
     14388  FilmTestResult?                               N
     14389  ElectrospatialFormulation                     N
     14390  FilteringApplied                              N
     14391  AudioReferenceLevel                           N
     14392  AudioMonoChannelCount                         N
     14393  AudioStereoChannelCount                       N
     14394  AnalogSystem                                  N
     14395  AudioSampleRate                               N
     14396  BitsPerSample                                 N
     14397  RoundingLaw                                   N
     14398  Dither                                        N
     14399  OpticalTrack                                  N
     14400  MagneticTrack                                 N
     14401  Signal-to-NoiseRatio                          N
     14402  Weighting                                     N
     14403  AnalogDataCodingKind                          N
     14404  TimecodeKind                                  N
     14405  TimecodeTimebase                              N
     14406  TimecodeUserBitsFlag                          N
     14407  IncludeSync                                   N
     14408  DropFrame                                     N
     14409  TimecodeSourceKind                            N
     14410  AnalogMetadataCarrier                         N
     14411  DigitalMetadataCarrier                        N
     14412  AnalogMonitoringAndControlCodingKind          N
     14413  SampleRate                                    N
     14414  EssenceLength                                 N
     14415  FilmColorProcess                              N
     14416  EdgeCodeFormat?                               N
     14417  FilmFormatName                                N
     14418  FilmStockKind                                 N
     14419  FilmStockManufacturerName                     N
     14420  PhysicalMediaLength?                          N
     14421  FilmCaptureAperture                           N
     14422  ImageCategory                                 N
     14423  ImageSourceDeviceKind                         N
     14424  OpticalTestParameterName                      N
     14425  OpticalTestResult                             N
     14426  OpticalTestResult                             N
     14427  SensorType                                    N
     14428  PolarCharacteristic                           N
     14429  IntegrationIndication                         N
     14430  EventIndication                               N
     14431  QualityFlag                                   N
     14432  PhysicalInstanceKind                          N
     14433  DigitalOrAnalogOrigination                    N
     14434  MicrophonePlacementTechniques                 N
     14435  SimpleFlaggingCount                           N
     14436  CopyCount                                     N
     14437  CloneCount                                    N
     14438  Work-in-ProgressFlag                          N
     14439  VideoOrImageCompressionAlgorithm              N
     14440  SplicingMetadata?                             N
     14441  AudioCompressionAlgorithm                     N
     14442  VideoNoiseReductionAlgorithm                  N
     14443  AudioNoiseReductionAlgorithm                  N
     14444  EnhancementOrModificationDescription          N
     14445  VideoDeviceKind                               N
     14446  VideoDeviceParameterName                      N
     14447  VideoDeviceParameterSetting                   N
     14448  AudioEnhancementOrModificationDescription     N
     14449  AudioFirstMix-DownProcess                     N
     14450  AudioDeviceKind                               N
     14451  AudioDeviceParameter                          N
     14452  AudioDeviceParameterSetting                   N
     14453  DataEnhancementOrModificationDescription      N
     14454  DataDeviceKind                                N
     14455  DataDeviceParameterName                       N
     14456  DataDeviceParameterSetting                    N
     14457  DefaultFadeType?                              N
     14458  ActiveState                                   N
     14459  Fade-InType?                                  N
     14460  Fade-OutType?                                 N
     14461  SpeedChangeEffectFlag                         N
     14462  InputSegmentCount                             N
     14463  Bypass                                        N
     14464  VideoCompressionAlgorithm                     N
     14465  MPEGVideoRecodingDataset?                     N
     14466  UpstreamAudioCompressionAlgorithm             N
     14467  MPEGAudioRecodingDataset?                     N
     14468  ProgramSupportMaterialReference               N
     14469  AdvertisingMaterialReference                  N
     14470  ProgramCommercialMaterialReference            N
     14471  ContiguousDataFlag                            N
     14472  PositionInSequence                            N
     14473  RelativePositionInSequenceOffset              N
     14474  RelativePositionInSequenceName                N
     14475  ImageCoordinateSystem                         N
     14476  MapDatumUsed                                  N
     14477  LocalDatumAbsolutePositionAccuracy            N
     14478  DeviceAbsolutePositionalAccuracy              N
     14479  DeviceAltitude                                N
     14480  DeviceAltitude                                N
     14481  DeviceLatitude                                N
     14482  DeviceLatitude                                N
     14483  DeviceLongitude                               N
     14484  DeviceLongitude                               N
     14485  DeviceXDimension                              N
     14486  DeviceYDimension                              N
     14487  FramePositionalAccuracy                       N
     14488  FrameCenterLatitude                           N
     14489  FrameCenterLatitude                           N
     14490  FrameCenterLongitude                          N
     14491  FrameCenterLongitude                          N
     14492  FrameCenterLatitudeLongitude                  N
     14493  LocalDatumRelativePositionAccuracy            N
     14494  DeviceRelativePositionalAccuracy              N
     14495  DeviceRelativePositionX                       N
     14496  DeviceRelativePositionY                       N
     14497  DeviceRelativePositionZ                       N
     14498  SubjectRelativePositionalAccuracy             N
     14499  PositionWithinViewportImageXCoordinate        N
     14500  PositionWithinViewportImageYCoordinate        N
     14501  SourceImageCenterXCoordinate                  N
     14502  SourceImageCenterYCoordinate                  N
     14503  ViewportImageCenterCCoordinate                N
     14504  ViewportImageCenterYCoordinate                N
     14505  DeviceAbsoluteSpeed                           N
     14506  DeviceAbsoluteHeading                         N
     14507  SubjectAbsoluteSpeed                          N
     14508  SubjectAbsoluteHeading                        N
     14509  DeviceRelativeSpeed                           N
     14510  DeviceRelativeHeading                         N
     14511  SubjectRelativeSpeed                          N
     14512  SubjectRelativeHeading                        N
     14513  SlantRange                                    N
     14514  TargetWidth                                   N
     14515  ViewportHeight                                N
     14516  ViewportWidth                                 N
     14517  SensorRollAngle                               N
     14518  AngleToNorth                                  N
     14519  ObliquityAngle                                N
     14520  PlaceKeyword                                  N
     14521  ObjectCountryCode                             N
     14522  ShootingCountryCode                           N
     14523  SettingCountryCode                            N
     14524  CopyrightLicenseCountryCode                   N
     14525  IntellectualPropertyLicenseCountryCode        N
     14526  ObjectRegionCode                              N
     14527  ShootingRegionCode                            N
     14528  SettingRegionCode                             N
     14529  CopyrightLicenseRegionCode                    N
     14530  IntellectualPropertyLicenseRegionCode         N
     14531  RoomNumber                                    N
     14532  StreetNumber                                  N
     14533  StreetName                                    N
     14534  PostalTown                                    N
     14535  CityName                                      N
     14536  StateOrProvinceOrCountyName                   N
     14537  PostalCode                                    N
     14538  CountryName                                   N
     14539  SettingRoomNumber                             N
     14540  SettingStreetNumberOrBuildingName             N
     14541  SettingStreetName                             N
     14542  SettingTownName                               N
     14543  SettingCityName                               N
     14544  SettingStateOrProvinceOrCountyName            N
     14545  SettingPostalCode                             N
     14546  SettingCountryName                            N
     14547  TelephoneNumber                               N
     14548  FaxNumber                                     N
     14549  E-MailAddress                                 N
     14550  SettingDescription                            N
     14551  UTCUserDateTime                               N
     14552  LocalUserDateTime                             N
     14553  SMPTE309MUserDateTime?                        N
     14554  SMPTE12MUserDateTime?                         N
     14555  UTCStartDateTime                              N
     14556  LocalStartDateTime                            N
     14557  TimecodeStartDateTime?                        N
     14558  UTCEndDateTime                                N
     14559  LocalEndDateTime                              N
     14560  TimecodeEndDateTime?                          N
     14561  UTCLastModifyDate                             N
     14562  LocalLastModifyDate                           N
     14563  TimecodeLastModifyDate?                       N
     14564  UTCEventStartDateTime                         N
     14565  LocalEventStartDateTime                       N
     14566  TimecodeEventStartDateTime?                   N
     14567  UTCEventEndDateTime                           N
     14568  LocalEventEndDateTime                         N
     14569  TimecodeEventEndDateTime?                     N
     14570  StartTimeRelativeToReference                  N
     14571  StartTimecodeRelativeToReference?             N
     14572  MaterialEndTimeOffset                         N
     14573  MaterialEndTimecodeOffset?                    N
     14574  EventStartTimeOffset                          N
     14575  EventStartTimecodeOffset?                     N
     14576  EventEndTimeOffset                            N
     14577  EventEndTimecodeOffset?                       N
     14578  FrameCountOffset                              N
     14579  TimePeriodName                                N
     14580  LocalCreationDateTime                         N
     14581  TimecodeCreationDateTime?                     N
     14582  LocalModifyDate                               N
     14583  TimecodeModifyDate?                           N
     14584  FrameCount                                    N
     14585  MaterialAbsoluteDuration                      N
     14586  MaterialAbsoluteDuration?                     N
     14587  TextlessBlackDuration                         N
     14588  EventAbsoluteDurationFrameCount               N
     14589  EventAbsoluteDuration                         N
     14590  EventAbsoluteDuration?                        N
     14591  BufferDelay?                                  N
     14592  ProgramIdentifier                             N
     14593  ProgramIdentifierString                       N
     14594  ShimName                                      N
     14595  SignalStandard                                N
     14596  IntendedAFD                                   N
     14597  SlateTitle                                    N
     14598  NOLACode                                      N
     14599  Rating                                        N
     14600  NielsenStreamIdentifier                       N
     14601  IsRecording                                   N
     14602  IsLiveProduction                              N
     14603  IsLiveTransmission                            N
     14604  IsDubbed                                      N
     14605  IsVoiceover                                   N
     14606  HasAudioWatermark                             N
     14607  AudioWatermarkKind                            N
     14608  HasVideoWatermark                             N
     14609  VideoWatermarkKind                            N
     14610  SubtitlesPresent                              N
     14611  CaptionTitles                                 N
     14612  CaptionsViaTeletext                           N
     14613  TextlessMaterial                              N
     14614  AudioReferenceLevel                           N
     14615  StorageDeviceKind                             N
     14616  StorageMediaKind                              N
     14617  StorageMediaID                                N
     14618  BroadcastDate                                 N
     14619  BroadcastTime                                 N
     14620  IsRepeat                                      N
     14621  FirstTransmissionInfo                         N
     14622  TeletextSubtitlesAvailable                    N
     14623  SeasonEpisodeNumber                           N
     14624  SeasonEpisodeTitle                            N
     14625  EPGProgramSynopsis                            N
     14626  ContentClassification                         N
     14627  DVBParentalRating                             N
     14628  ContentMaturityRating                         N
     14629  ContentMaturityDescription                    N
     14630  ContentMaturityGraphic                        N
     14631  ContractEntity                                N
     14632  ContractTypeLink                              N
     14633  ConsumerRightsToCopy                          N
     14634  BroadcasterRightsToCopy                       N
     14635  DirectorName                                  N
     14636  ProducerName                                  N
     14637  FemaleLeadActressName                         N
     14638  MaleLeadActorName                             N
     14639  PresenterName                                 N
     14640  MainSponsorName                               N
     14641  VoiceTalentName                               N
     14642  PostboxNumber                                 N
     14643  PostCodeForPostbox                            N
     14644  ProgramNumber                                 N
     14645  DefinitionObjectID?                           N
     14646  IEEEDeviceID                                  N
     14647  ProjectNumber                                 N
     14648  EdgeCodeHeader?                               N
     14649  ChannelHandle                                 N
     14650  PhysicalMediaLocation                         N
     14651  MediaLocation                                 N
     14652  TrackNumber                                   N
     14653  EdgeCodeStart                                 N
     14654  VersionTitle                                  N
     14655  TrackID                                       N
     14656  TrackName                                     N
     14657  TrackName                                     N
     14658  DefinitionObjectName                          N
     14659  DefinitionObjectName                          N
     14660  ContentPackageMetadataLink                    N
     14661  DefinedName                                   N
     14662  DefinedName                                   N
     14663  DeviceManufacturerName                        N
     14664  DeviceManufacturerName                        N
     14665  ManufacturerID?                               N
     14666  IEEEManufacturerID                            N
     14667  AAFManufacturerID?                            N
     14668  SupplyingDepartmentName                       N
     14669  AudienceShare                                 N
     14670  AudienceAppreciation                          N
     14671  Salutation                                    N
     14672  HonorsAndQualifications                       N
     14673  ObjectModelVersion                            N
     14674  SDKVersion                                    N
     14675  IsOptional                                    N
     14676  IsSearchable                                  N
     14677  UseDefaultValue                               N
     14678  DefaultDataValue?                             N
     14679  Size                                          N
     14680  IsSigned                                      N
     14681  ElementCount                                  N
     14682  ElementNameList                               N
     14683  TypeDefinitionElementValueList                N
     14684  MemberNameList                                N
     14685  ExtendibleElementNameList                     N
     14686  TypeDefinitionExtendibleElementValues?        N
     14687  TargetSet?                                    N
     14688  FillerData?                                   N
     14689  KLVDataValue?                                 N
     14690  PackageKLVData?                               N
     14691  ComponentKLVData?                             N
     14692  AssignedCategoryName                          N
     14693  AssignedCategoryName                          N
     14694  AssignedCategoryValue                         N
     14695  AssignedCategoryValue                         N
     14696  ShotList                                      N
     14697  PackageUserComments?                          N
     14698  Cue-InWords                                   N
     14699  Cue-OutWords                                  N
     14700  ObjectKind                                    N
     14701  ObjectKind                                    N
     14702  ObjectDescription                             N
     14703  ObjectDescription                             N
     14704  ObjectName                                    N
     14705  MetadataItemName                              N
     14706  ShotCommentKind                               N
     14707  ShotComment                                   N
     14708  ComputedObjectKind                            N
     14709  ComputedObjectKind                            N
     14710  VersionNumberString                           N
     14711  VersionNumberString                           N
     14712  VersionNumber                                 N
     14713  WAVESummary?                                  N
     14714  AIFCSummary?                                  N
     14715  TIFFSummary?                                  N
     14716  ViewportAspectRatio                           N
     14717  CaptureGammaEquation?                         N
     14718  ColorimetryCode?                              N
     14719  PresentationGammaEquation                     N
     14720  PresentationGammaEquation?                    N
     14721  FieldDominance                                N
     14722  VideoLineMap                                  N
     14723  AnalogVideoSystemName?                        N
     14724  VerticalSub-sampling                          N
     14725  BitsperPixel                                  N
     14726  ColorRangeLevels                              N
     14727  PixelLayout?                                  N
     14728  AlphaSampleDepth                              N
     14729  Palette?                                      N
     14730  PaletteLayout?                                N
     14731  ComponentDepth                                N
     14732  VideoCodingSchemeID?                          N
     14733  RoundedCaptureFilmFrameRate                   N
     14734  AudioAverageBitrate                           N
     14735  AudioFixedBitrateFlag                         N
     14736  CodingLawKind                                 N
     14737  AudioCodingSchemeID?                          N
     14738  LayerNumber                                   N
     14739  TimecodeTimebase                              N
     14740  RoundedTimecodeTimebase                       N
     14741  ComponentDataDefinition                       N
     14742  StreamData?                                   N
     14743  TimecodeStreamData?                           N
     14744  RecordedFormat                                N
     14745  TapeShellKind                                 N
     14746  TapeShellKind                                 N
     14747  TapeFormulation                               N
     14748  TapeFormulation                               N
     14749  TapeCapacity                                  N
     14750  TapeManufacturer                              N
     14751  TapeManufacturer                              N
     14752  TapeStock                                     N
     14753  TapeStock                                     N
     14754  TapeBatchNumber                               N
     14755  TapeBatchNumber                               N
     14756  PerforationsPerFrame                          N
     14757  PerforationsPerFrame                          N
     14758  FilmFormatName                                N
     14759  FilmFormatName?                               N
     14760  FilmStockKind                                 N
     14761  FilmStockManufacturerName                     N
     14762  FilmBatchNumber                               N
     14763  FilmBatchNumber                               N
     14764  FilmGauge?                                    N
     14765  EdgeCodeFilmGauge?                            N
     14766  ExposedAspectRatio                            N
     14767  ImageAlignmentOffset                          N
     14768  ImageStartOffset                              N
     14769  ImageEndOffset                                N
     14770  PaddingBits                                   N
     14771  FocalLength                                   N
     14772  SensorSize                                    N
     14773  FNumber                                       N
     14774  SensorTypeCode                                N
     14775  FieldOfViewHorizontal                         N
     14776  AnamorphicLensCharacteristic                  N
     14777  UniformDataFlag                               N
     14778  JPEGTableID?                                  N
     14779  AlphaTransparency                             N
     14780  GenerationID?                                 N
     14781  ApplicationSupplierName                       N
     14782  ApplicationSupplierName                       N
     14783  ApplicationName                               N
     14784  ApplicationName                               N
     14785  ApplicationVersionNumber                      N
     14786  ApplicationVersionString                      N
     14787  ApplicationVersionString                      N
     14788  ApplicationPlatform                           N
     14789  ApplicationPlatform                           N
     14790  ApplicationProductID?                         N
     14791  LinkedGenerationID?                           N
     14792  ContainerVersion                              N
     14793  ToolkitVersion                                N
     14794  Plug-InCategoryID?                            N
     14795  Plug-InPlatformID?                            N
     14796  MinimumSupportedPlatformVersion               N
     14797  MaximumSupportedPlatformVersion               N
     14798  Plug-InEngineID?                              N
     14799  MinimumSupportedEngineVersion                 N
     14800  MaximumSupportedEngineVersion                 N
     14801  Plug-InAPIID?                                 N
     14802  MinimumAPIVersion                             N
     14803  MaximumAPIVersion                             N
     14804  Software-OnlySupportFlag                      N
     14805  HardwareAcceleratorFlag                       N
     14806  Plug-InLocatorSet?                            N
     14807  AuthenticationFlag                            N
     14808  AssociatedMetadataDefinition?                 N
     14809  EventTrackEditRate                            N
     14810  DefaultFadeEditRate                           N
     14811  EditingEventComment                           N
     14812  EditingEventComment                           N
     14813  EditRate                                      N
     14814  OperationDefinitionID?                        N
     14815  Value?                                        N
     14816  EditHint?                                     N
     14817  OperationDataDefinition?                      N
     14818  OperationCategory?                            N
     14819  DisplayUnits                                  N
     14820  DisplayUnits                                  N
     14821  BypassOverride                                N
     14822  TimepointValue?                               N
     14823  BeginAnchor                                   N
     14824  BeginAnchor                                   N
     14825  EndAnchor                                     N
     14826  EndAnchor                                     N
     14827  FilmToVideoTransferDirection?                 N
     14828  FilmToVideoTransferKind?                      N
     14829  FilmToVideoTransferPhase?                     N
     14830  TeletextSubtitlesFlag                         N
     14831  SubtitleDatafileFlag                          N
     14832  ClosedCaptionSubtitlesFlag                    N
     14833  SampleIndex?                                  N
     14834  SourcePackageID?                              N
     14835  SourceTrackID                                 N
     14836  RelativeScope                                 N
     14837  RelativeTrack                                 N
     14838  ObjectClass?                                  N
     14839  EssenceContainerFormat?                       N
     14840  CodecDefinition?                              N
     14841  ParameterDefinition?                          N
     14842  Interpolation?                                N
     14843  ParameterDataType?                            N
     14844  CodecEssenceDescriptor?                       N
     14845  ContentStorage?                               N
     14846  Dictionary?                                   N
     14847  EssenceDescription?                           N
     14848  Sequence?                                     N
     14849  TransitionEffect?                             N
     14850  EffectRendering?                              N
     14851  InputSegment?                                 N
     14852  StillFrame?                                   N
     14853  Selected?                                     N
     14854  Annotation?                                   N
     14855  ManufacturerInformationObject?                N
     14856  CodecEssenceKinds?                            N
     14857  OperationParameters?                          N
     14858  DegradedEffects?                              N
     14859  Packages?                                     N
     14860  EssenceData?                                  N
     14861  OperationDefinitions?                         N
     14862  ParameterDefinitions?                         N
     14863  DataDefinitions?                              N
     14864  Plug-InDefinitions?                           N
     14865  CodecDefinitions?                             N
     14866  ContainerDefinitions?                         N
     14867  InterpolationDefinitions?                     N
     14868  AvailableRepresentations?                     N
     14869  InputSegments?                                N
     14870  EssenceLocators?                              N
     14871  IdentificationList?                           N
     14872  Tracks?                                       N
     14873  ControlPointList?                             N
     14874  PackageTracks?                                N
     14875  Alternates?                                   N
     14876  ComponentsInSequence?                         N
     14877  Parameters?                                   N
     14878  LinkedPackageID?                              N
     14879  ParentClass?                                  N
     14880  Properties?                                   N
     14881  IsConcrete                                    N
     14882  PropertyType?                                 N
     14883  LocalID                                       N
     14884  IsUniqueIdentifier                            N
     14885  ClassDefinitions?                             N
     14886  TypeDefinitions?                              N
     14887  TargetClassOfStrongReference?                 N
     14888  TargetClassOfWeakReference?                   N
     14889  EnumerationUnderlyingIntegerType?             N
     14890  FixedArrayElementType?                        N
     14891  VariableArrayElementType?                     N
     14892  SetElementType?                               N
     14893  StringElementType?                            N
     14894  StreamElementType?                            N
     14895  MemberTypes?                                  N
     14896  RenamedType?                                  N
     14897  DictionaryIdentifier?                         N
     14898  DictionaryDescription                         N
     14899  DictionaryDescription                         N
     14900  BlockContinuityCount                          N
     14901  StreamPositionIndicator                       N
     14902  Origin                                        N
     14903  StartTimeRelativeToReference                  N
     14904  StartTimecode                                 N
     14905  CutPoint                                      N
     14906  EventStart                                    N
     14907  ControlPointTime                              N
     14908  CreateDate                                    N
     14909  ModifyDate                                    N
     14910  ContainerLastModifyDate                       N
     14911  PackageLastModifyDate                         N
     14912  Duration                                      N
     14913  DefaultFadeDuration                           N
     14914  Fade-InDuration                               N
     14915  Fade-OutDuration                              N
     14916  TapeFormat?                                   N
     14917  OrganizationID                                N
     14918  GlobalNumber                                  N
     14919  DeviceIDKind                                  N
     14920  DeviceKind                                    N
     14921  DeviceKindCode                                N
     14922  PlatformDesignation                           N
     14923  PlatformModel                                 N
     14924  PlatformSerialNumber                          N
     14925  LocalTargetID                                 N
     14926  MagneticDiskNumber                            N
     14927  OpticalDiscNumber                             N
     14928  StreamID                                      N
     14929  TransportStreamID                             N
     14930  OrganizationalProgramNumber                   N
     14931  OrganizationalProgramNumber                   N
     14932  ItemDesignatorID?                             N
     14933  LocalFilePath                                 N
     14934  TitleKind                                     N
     14935  MainTitle                                     N
     14936  SecondaryTitle                                N
     14937  SeriesNumber                                  N
     14938  EpisodeNumber                                 N
     14939  SceneNumber                                   N
     14940  VersionTitle                                  N
     14941  MissionID                                     N
     14942  MissionID                                     N
     14943  RecordingLabelName                            N
     14944  RecordingLabelName                            N
     14945  CollectionName                                N
     14946  CollectionName                                N
     14947  OriginCode                                    N
     14948  MainCatalogNumber                             N
     14949  CatalogPrefixNumber                           N
     14950  SideNumber                                    N
     14951  RecordedTrackNumber                           N
     14952  SeriesinaSeriesGroupCount                     N
     14953  ProgrammingGroupKind                          N
     14954  PurchasingOrganizationName                    N
     14955  SalesContractNumber                           N
     14956  PurchasingDepartment                          N
     14957  ContractType                                  N
     14958  ContractTypeCode                              N
     14959  ContractClauseDescription                     N
     14960  ContractLineCode                              N
     14961  ContractLineName                              N
     14962  ContractTermsOfBusiness                       N
     14963  ContractInstallmentPercentage                 N
     14964  Jurisdiction                                  N
     14965  CopyrightStatus                               N
     14966  CopyrightOwnerName                            N
     14967  IntellectualPropertyDescription               N
     14968  IntellectualPropertyRights                    N
     14969  Rightsholder                                  N
     14970  RightsManagementAuthority                     N
     14971  RightsConditionDescription                    N
     14972  RightsConditionDescription                    N
     14973  CurrencyName                                  N
     14974  TotalPayment                                  N
     14975  PayeeAccountName                              N
     14976  PayeeAccountNumber                            N
     14977  PayeeAccountSortCode                          N
     14978  TotalIncome                                   N
     14979  PayerAccountName                              N
     14980  PayerAccountNumber                            N
     14981  PayerAccountSortCode                          N
     14982  SecurityClassification                        N
     14983  SecurityClassificationCaveats                 N
     14984  ClassifiedBy                                  N
     14985  ClassificationReason                          N
     14986  DeclassificationDate                          N
     14987  DerivedFrom                                   N
     14988  ClassificationComment                         N
     14989  ClassificationAndMarkingSystem                N
     14990  BroadcastOrganizationName                     N
     14991  BroadcastServiceName                          N
     14992  BroadcastMediumCode                           N
     14993  BroadcastRegion                               N
     14994  NatureOfPersonality                           N
     14995  ContributionStatus                            N
     14996  SupportorAdministrationStatus                 N
     14997  OrganizationKind                              N
     14998  ProductionOrganizationRole                    N
     14999  SupportOrganizationRole                       N
     15000  JobFunctionName                               N
     15001  JobFunctionCode                               N
     15002  RoleName                                      N
     15003  JobTitle                                      N
     15004  JobTitle                                      N
     15005  ContactKind                                   N
     15006  ContactDepartmentName                         N
     15007  FamilyName                                    N
     15008  FirstGivenName                                N
     15009  SecondGivenName                               N
     15010  ThirdGivenName                                N
     15011  PersonDescription                             N
     15012  PersonDescription                             N
     15013  MainName                                      N
     15014  SupplementaryName                             N
     15015  OrganizationMainName                          N
     15016  SupplementaryOrganizationName                 N
     15017  RegionCode                                    N
     15018  CountryName                                   N
     15019  CountryName                                   N
     15020  RegionName                                    N
     15021  RegionName                                    N
     15022  LanguageName                                  N
     15023  LanguageName                                  N
     15024  TerminatingFillerData                         N
     15025  TimingBiasCorrection                          N
     15026  TimingBiasCorrectionDescription               N
     15027  Genre                                         N
     15028  TargetAudience                                N
     15029  ProgramMaterialClassificationCode             N
     15030  Theme                                         N
     15031  SubjectName                                   N
     15032  SubjectName                                   N
     15033  Keywords                                      N
     15034  KeyFrameSampleCount                           N
     15035  Abstract                                      N
     15036  Purpose                                       N
     15037  Description                                   N
     15038  ColorDescriptor                               N
     15039  FormatDescriptor                              N
     15040  IntentDescriptor                              N
     15041  IntentDescriptor                              N
     15042  TextualDescriptionKind                        N
     15043  TextualDescriptionKind                        N
     15044  FestivalName                                  N
     15045  ObjectDescriptionCode                         N
     15046  DescriptionKind                               N
     15047  DescriptionKind                               N
     15048  DescriptiveComment                            N
     15049  DescriptiveComment                            N
     15050  ContextDescription                            N
     15051  ComputedKeywords                              N
     15052  ObjectIdentificationConfidence                N
     15053  ObjectHorizontalAverageDimension              N
     15054  ObjectVerticalAverageDimension                N
     15055  ObjectAreaDimension                           N
     15056  HorizontalActionSafePercentage                N
     15057  VerticalActionSafePercentage                  N
     15058  HorizontalGraphicsSafePercentage              N
     15059  VerticalGraphicsSafePercentage                N
     15060  PerceivedDisplayFormatName                    N
     15061  PerceivedDisplayFormatCode                    N
     15062  VideoColorKind                                N
     15063  PictureDisplayRate                            N
     15064  VideoAverageBitrate                           N
     15065  VideoFixedBitrate                             N
     15066  DigitalVideoFileFormat                        N
     15067  CodingLawName                                 N
     15068  AudioCodingSchemeCode                         N
     15069  AudioCodingSchemeName                         N
     15070  DigitalEncodingBitrate                        N
     15071  DataEssenceCodingID?                          N
     15072  StorageKind                                   N
     15073  StorageKind                                   N
     15074  StorageKindCode                               N
     15075  TapePartitionCapacity                         N
     15076  DiscPartitionCapacity                         N
     15077  FocalLength                                   N
     15078  FieldOfViewHorizontal                         N
     15079  FieldOfViewVertical                           N
     15080  SystemNameOrNumber                            N
     15081  LogoFlag                                      N
     15082  GraphicKind                                   N
     15083  GraphicUsageKind                              N
     15084  SignatureTuneFlag                             N
     15085  BackgroundMusicFlag                           N
     15086  ProductionScriptReference                     N
     15087  ProductionScriptReference                     N
     15088  TranscriptReference                           N
     15089  TranscriptReference                           N
     15090  HorizontalDatum                               N
     15091  VerticalDatum                                 N
     15092  DeviceLatitude                                N
     15093  DeviceLongitude                               N
     15094  FrameCenterLatitude                           N
     15095  FrameCenterLongitude                          N
     15096  CornerLatitudePoint1                          N
     15097  CornerLatitudePoint1                          N
     15098  CornerLatitudePoint2                          N
     15099  CornerLatitudePoint2                          N
     15100  CornerLatitudePoint3                          N
     15101  CornerLatitudePoint3                          N
     15102  CornerLatitudePoint4                          N
     15103  CornerLatitudePoint4                          N
     15104  CornerLongitudePoint1                         N
     15105  CornerLongitudePoint1                         N
     15106  CornerLongitudePoint2                         N
     15107  CornerLongitudePoint2                         N
     15108  CornerLongitudePoint3                         N
     15109  CornerLongitudePoint3                         N
     15110  CornerLongitudePoint4                         N
     15111  CornerLongitudePoint4                         N
     15112  SubjectDistance                               N
     15113  PlaceKeyword                                  N
     15114  ObjectCountryCode                             N
     15115  ObjectCountryCodeMethod                       N
     15116  CountryCodeMethod                             N
     15117  Non-USClassifyingCountryCode                  N
     15118  ReleasableCountryCode                         N
     15119  ObjectRegionName                              N
     15120  ShootingRegionName                            N
     15121  SettingRegionName                             N
     15122  CopyrightLicenseRegionName                    N
     15123  IntellectualPropertyLicenseRegionName         N
     15124  RoomNumber                                    N
     15125  StreetNumber                                  N
     15126  StreetName                                    N
     15127  PostalTown                                    N
     15128  CityName                                      N
     15129  StateOrProvinceOrCountyName                   N
     15130  PostalCode                                    N
     15131  CountryName                                   N
     15132  SettingRoomNumber                             N
     15133  SettingStreetNumberOrBuildingName             N
     15134  SettingStreetName                             N
     15135  SettingTownName                               N
     15136  SettingCityName                               N
     15137  SettingStateOrProvinceOrCountyName            N
     15138  SettingPostalCode                             N
     15139  SettingCountryName                            N
     15140  TelephoneNumber                               N
     15141  FaxNumber                                     N
     15142  E-MailAddress                                 N
     15143  SettingDescription                            N
     15144  POSIXMicroseconds                             N
     15145  EventElapsedTimeToStart                       N
     15146  EventElapsedTimeToEnd                         N
     15147  OrganizationIDKind                            N
     15148  OrganizationIDKind                            N
     15149  SMPTEUL?                                      N
     15150  EssenceContainerArray?                        N
     15151  EssenceStreamID                               N
     15152  IndexStreamID                                 N
     15153  WorkingTitle                                  N
     15154  WorkingTitle                                  N
     15155  OriginalTitle                                 N
     15156  OriginalTitle                                 N
     15157  ClipNumber                                    N
     15158  ClipNumber                                    N
     15159  DescriptiveMetadataTrackIDs                   N
     15160  IdentifierKind                                N
     15161  IdentifierValue                               N
     15162  OrganizationCode                              N
     15163  OrganizationCode                              N
     15164  SupplierIdentificationKind                    N
     15165  SupplierIdentificationValue                   N
     15166  SupplierAccountNumber                         N
     15167  SupplierAccountName                           N
     15168  SupplierAccountName                           N
     15169  EpisodeStartNumber                            N
     15170  EpisodeEndNumber                              N
     15171  PurchaserIdentificationKind                   N
     15172  PurchaserIdentificationValue                  N
     15173  PurchaserAccountNumber                        N
     15174  PurchaserAccountName                          N
     15175  PurchaserAccountName                          N
     15176  ContractType                                  N
     15177  ContractClauseDescription                     N
     15178  ContractLineName                              N
     15179  ContractTermsOfBusiness                       N
     15180  Jurisdiction                                  N
     15181  TotalCurrencyAmount                           N
     15182  InstallmentNumber                             N
     15183  IdentifierIssuingAuthority                    N
     15184  PublishingOrganizationName                    N
     15185  PublishingOrganizationName                    N
     15186  PublishingServiceName                         N
     15187  PublishingServiceName                         N
     15188  PublishingMediumName                          N
     15189  PublishingMediumName                          N
     15190  PublishingRegionName                          N
     15191  PublishingRegionName                          N
     15192  Salutation                                    N
     15193  HonorsAndQualifications                       N
     15194  OtherGivenNames                               N
     15195  OtherGivenNames                               N
     15196  AlternateName                                 N
     15197  AlternateName                                 N
     15198  ISO639TextLanguageCode                        N
     15199  ISO639CaptionsLanguageCode                    N
     15200  PrimarySpokenLanguageCode                     N
     15201  SecondarySpokenLanguageCode                   N
     15202  PrimaryOriginalLanguageCode                   N
     15203  SecondaryOriginalLanguageCode                 N
     15204  MajorVersion                                  N
     15205  MinorVersion                                  N
     15206  SectorSize                                    N
     15207  ElementLength                                 N
     15208  ThesaurusName                                 N
     15209  Cue-InWords                                   N
     15210  Cue-OutWords                                  N
     15211  KeypointKind                                  N
     15212  KeypointKind                                  N
     15213  KeypointValue                                 N
     15214  KeypointValue                                 N
     15215  FestivalName                                  N
     15216  AwardName                                     N
     15217  AwardName                                     N
     15218  AwardCategory                                 N
     15219  AwardCategory                                 N
     15220  SlateInformation                              N
     15221  LockedIndicator                               N
     15222  BitsPerAudioSample                            N
     15223  CaptionKind                                   N
     15224  CaptionKind                                   N
     15225  SliceCount                                    N
     15226  SliceNumber                                   N
     15227  ElementDelta                                  N
     15228  PositionTableIndexing                         N
     15229  SliceOffsetList?                              N
     15230  PosTableArray?                                N
     15231  StreamOffset                                  N
     15232  EditUnitFlags                                 N
     15233  TemporalOffset                                N
     15234  AnchorOffset                                  N
     15235  EditUnitLength                                N
     15236  HeaderByteCount                               N
     15237  IndexByteCount                                N
     15238  PackLength                                    N
     15239  IntegrationIndication                         N
     15240  EventIndication                               N
     15241  GraphicUsageKind                              N
     15242  PrimaryPackage?                               N
     15243  DescriptiveMetadataSets?                      N
     15244  DescriptiveMetadataSetReferences?             N
     15245  FileDescriptors?                              N
     15246  StreamPositionIndicator                       N
     15247  StreamPositionIndicator                       N
     15248  StreamPositionIndicator                       N
     15249  OffsetToMetadata                              N
     15250  OffsetToMetadata                              N
     15251  OffsetToIndexTable                            N
     15252  OffsetToIndexTable                            N
     15253  ByteOffset                                    N
     15254  ReversePlay                                   N
     15255  FirstNumberInSequence                         N
     15256  FirstNumberInSequence                         N
     15257  PreviousNumberInSequence                      N
     15258  PreviousNumberInSequence                      N
     15259  CurrentNumberInSequence                       N
     15260  CurrentNumberInSequence                       N
     15261  NextNumberInSequence                          N
     15262  NextNumberInSequence                          N
     15263  LastNumberInSequence                          N
     15264  LastNumberInSequence                          N
     15265  CentralTelephoneNumber                        N
     15266  MobileTelephoneNumber                         N
     15267  URL                                           N
     15268  LocationDescription                           N
     15269  LocationDescription                           N
     15270  LocationKind                                  N
     15271  LocationKind                                  N
     15272  UTCEventStartDateTime                         N
     15273  LocalEventStartDateTime                       N
     15274  UTCEventEndDateTime                           N
     15275  LocalEventEndDateTime                         N
     15276  KeyTimePoint                                  N
     15277  TimePeriodName                                N
     15278  SettingDateTime                               N
     15279  ContractDateTime                              N
     15280  RightsStartDateTime                           N
     15281  RightsStopDateTime                            N
     15282  PaymentDueDateTime                            N
     15283  ClipID                                        N
     15284  DeviceKind                                    N
     15285  DeviceAssetNumber                             N
     15286  IdentificationUL?                             N
     15287  OperationalPatternUL?                         N
     15288  EssenceContainers?                            N
     15289  DescriptiveMetadataSchemes?                   N
     15290  ProjectName                                   N
     15291  ProjectName                                   N
     15292  LocalTagValue                                 N
     15293  LocalTagUniqueID?                             N
     15294  BrandMainTitle                                N
     15295  BrandMainTitle                                N
     15296  BrandOriginalTitle                            N
     15297  BrandOriginalTitle                            N
     15298  FrameworkTitle                                N
     15299  FrameworkTitle                                N
     15300  SourceTrackIDs                                N
     15301  ShotTrackIDs                                  N
     15302  ProgrammingGroupKind                          N
     15303  ProgrammingGroupTitle                         N
     15304  ProgrammingGroupTitle                         N
     15305  IdentifierIssuingAuthority                    N
     15306  LinkingName                                   N
     15307  LinkingName                                   N
     15308  NameSuffix                                    N
     15309  NameSuffix                                    N
     15310  FormerFamilyName                              N
     15311  FormerFamilyName                              N
     15312  Nationality                                   N
     15313  Nationality                                   N
     15314  Citizenship                                   N
     15315  Citizenship                                   N
     15316  FrameworkTextLanguageCode                     N
     15317  KAGSize                                       N
     15318  ReversedByteOrder                             N
     15319  ItemName                                      N
     15320  ItemName                                      N
     15321  ItemValue                                     N
     15322  ItemValue                                     N
     15323  XMLDocumentText?                              N
     15324  XMLDocumentText                               N
     15325  XMLDocumentText                               N
     15326  XMLDocumentText?                              N
     15327  FrameworkThesaurusName                        N
     15328  FrameworkThesaurusName                        N
     15329  GroupSynopsis                                 N
     15330  GroupSynopsis                                 N
     15331  AnnotationSynopsis                            N
     15332  AnnotationSynopsis                            N
     15333  AnnotationDescription                         N
     15334  AnnotationDescription                         N
     15335  ScriptingKind                                 N
     15336  ScriptingKind                                 N
     15337  ScriptingText                                 N
     15338  ScriptingText                                 N
     15339  ShotDescription                               N
     15340  ShotDescription                               N
     15341  AnnotationKind                                N
     15342  AnnotationKind                                N
     15343  RelatedMaterialDescription                    N
     15344  RelatedMaterialDescription                    N
     15345  ClipKind                                      N
     15346  DeviceUsageDescription                        N
     15347  DeviceUsageDescription                        N
     15348  DisplayF2Offset                               N
     15349  StoredF2Offset                                N
     15350  ActiveFormatDescriptor                        N
     15351  LineNumber                                    N
     15352  ScanningDirection                             N
     15353  ComponentMaximumRef                           N
     15354  ComponentMinimumRef                           N
     15355  AlphaMaximumRef                               N
     15356  AlphaMinimumRef                               N
     15357  VideoPayloadIdentifier                        N
     15358  VideoPayloadIdentifier2002                    N
     15359  SingleSequenceFlag                            N
     15360  ConstantBPictureFlag                          N
     15361  CodedContentScanningKind                      N
     15362  LowDelayIndicator                             N
     15363  ClosedGOPIndicator                            N
     15364  IdenticalGOPIndicator                         N
     15365  MaximumGOPSize                                N
     15366  MaximumBPictureCount                          N
     15367  ProfileAndLevel                               N
     15368  Bitrate                                       N
     15369  ChannelCount                                  N
     15370  AudioSampleRate                               N
     15371  PeakEnvelope                                  N
     15372  PeakEnvelopeData?                             N
     15373  BlockAlign                                    N
     15374  SequenceOffset                                N
     15375  BlockStartOffset                              N
     15376  FileSecurityReport                            N
     15377  FileSecurityWave                              N
     15378  AverageBytesPerSecond                         N
     15379  AuxiliaryBitsMode                             N
     15380  ChannelStatusMode                             N
     15381  FixedChannelStatusData?                       N
     15382  UserDataMode?                                 N
     15383  FixedUserData?                                N
     15384  Emphasis                                      N
     15385  BextCodingHistory                             N
     15386  BextCodingHistory                             N
     15387  QltyBasicData                                 N
     15388  QltyBasicData                                 N
     15389  QltyStartOfModulation                         N
     15390  QltyStartOfModulation                         N
     15391  QltyQualityEvent                              N
     15392  QltyQualityEvent                              N
     15393  QltyEndOfModulation                           N
     15394  QltyEndOfModulation                           N
     15395  QltyQualityParameter                          N
     15396  QltyQualityParameter                          N
     15397  QltyOperatorComment                           N
     15398  QltyOperatorComment                           N
     15399  QltyCueSheet                                  N
     15400  QltyCueSheet                                  N
     15401  DialNorm                                      N
     15402  DataEssenceCoding                             N
     15403  DateTimeRate                                  N
     15404  DateTimeDropFrameFlag                         N
     15405  DateTimeEmbeddedFlag                          N
     15406  DateTimeKind?                                 N
     15407  DeltaEntryArray?                              N
     15408  PositionTableCount                            N
     15409  PositionTable?                                N
     15410  IndexEntryArray?                              N
     15411  SignalStandard                                N
     15412  DataDefinition?                               N
     15413  RecordedFormat                                N
     15414  GenerationCopyNumber                          N
     15415  GenerationCloneNumber                         N
     15416  ThemeMusicFlag                                N
     15417  InsertMusicFlag                               N
     15418  IndexEditRate                                 N
     15419  LinkedTrackID                                 N
     15420  EssenceContainerFormat?                       N
     15421  CodecDefinition?                              N
     15422  DescriptiveMetadataFramework?                 N
     15423  GroupSet?                                     N
     15424  BankDetailsSet?                               N
     15425  ImageFormatSet?                               N
     15426  ProcessingSet?                                N
     15427  ProjectSet?                                   N
     15428  ContactsListSet?                              N
     15429  AnnotationCueWordsSet?                        N
     15430  ShotCueWordsSet?                              N
     15431  AwardParticipantSets?                         N
     15432  ContractParticipantSets?                      N
     15433  PersonSets?                                   N
     15434  ParticipantOrganizationSets?                  N
     15435  PersonOrganizationSets?                       N
     15436  LocationSets?                                 N
     15437  TitlesSets?                                   N
     15438  GroupSets?                                    N
     15439  IdentificationSets?                           N
     15440  EpisodicItemSets?                             N
     15441  BrandingSets?                                 N
     15442  EventSets?                                    N
     15443  PublicationSets?                              N
     15444  AwardSets?                                    N
     15445  CaptionDescriptionSets?                       N
     15446  AnnotationSets?                               N
     15447  ProductionSettingPeriodSets?                  N
     15448  SceneSettingPeriodSets?                       N
     15449  ScriptingSets?                                N
     15450  ClassificationSets?                           N
     15451  SceneShotSets?                                N
     15452  ClipShotSets?                                 N
     15453  KeyPointSets?                                 N
     15454  ShotParticipantRoleSets?                      N
     15455  ShotPersonSets?                               N
     15456  OrganizationSets?                             N
     15457  ShotLocationSets?                             N
     15458  AddressSets?                                  N
     15459  CommunicationSets?                            N
     15460  ContractSets?                                 N
     15461  RightsSets?                                   N
     15462  PaymentsSets?                                 N
     15463  DeviceParametersSets?                         N
     15464  ClassificationNameValueSets?                  N
     15465  ContactNameValueSets?                         N
     15466  DeviceParameterNameValueSets?                 N
     15467  MetadataServerLocators?                       N
     15468  RelatedMaterialLocators?                      N
     15469  LocalTagEntries?                              N
     15470  TotalNumberInSequence                         N
     15471  RoomOrSuiteName                               N
     15472  RoomOrSuiteName                               N
     15473  BuildingName                                  N
     15474  BuildingName                                  N
     15475  URL                                           N
     15476  LocalFestivalDateTime                         N
     15477  ShotStartPosition                             N
     15478  IndexingStartPosition                         N
     15479  EventOrigin                                   N
     15480  SettingPeriodDescription                      N
     15481  SettingPeriodDescription                      N
     15482  IndexDuration                                 N
     15483  ShotDuration                                  N
     15484  ExtendedClipID                                N
     15485  ClipIDArray?                                  N
     15486  ExtendedClipIDArray?                          N
     15487  TrackNumberBatch                              N
     15488  ExtendedTextLanguageCode                      N
     15489  ExtendedCaptionsLanguageCode                  N
     15490  FrameworkExtendedTextLanguageCode             N
     15491  PrimaryExtendedSpokenLanguageCode             N
     15492  SecondaryExtendedSpokenLanguageCode           N
     15493  OriginalExtendedSpokenPrimaryLanguageCode     N
     15494  SecondaryOriginalExtendedSpokenLanguageCode   N
     15495  KLVMetadataSequence?                          N
     15496  PackageAttributes?                            N
     15497  ComponentAttributes?                          N
     15498  MPEG7BiMDecoderInitFrame1?                    N
     15499  MPEG7BiMDecoderInitFrame2?                    N
     15500  MPEG7BiMDecoderInitFrame3?                    N
     15501  MPEG7BiMDecoderInitFrame4?                    N
     15502  MPEG7BiMDecoderInitFrame5?                    N
     15503  MPEG7BiMDecoderInitFrame6?                    N
     15504  MPEG7BiMDecoderInitFrame7?                    N
     15505  MPEG7BiMDecoderInitFrame8?                    N
     15506  MPEG7BiMAccessUnitFrame1?                     N
     15507  MPEG7BiMAccessUnitFrame2?                     N
     15508  MPEG7BiMAccessUnitFrame3?                     N
     15509  MPEG7BiMAccessUnitFrame4?                     N
     15510  MPEG7BiMAccessUnitFrame5?                     N
     15511  MPEG7BiMAccessUnitFrame6?                     N
     15512  MPEG7BiMAccessUnitFrame7?                     N
     15513  MPEG7BiMAccessUnitFrame8?                     N
     15514  ComponentUserComments?                        N
     15515  ShotCommentKind                               N
     15516  ShotComment                                   N
     15517  SensorMode                                    N
     15518  ChannelAssignment?                            N
     15519  ContentPackageIndexArray?                     N
     15520  VideoIndexArray?                              N
     15521  ApproximateImageContainerSize                 N
     15522  MetadataEncodingSchemeCode                    N
     15523  MIMEMediaType                                 N
     15524  MIMEMediaType                                 N
     15525  FieldOfViewVerticalFP                         N
     15526  PackageUsageKind?                             N
     15527  ChannelID                                     N
     15528  ChannelIDs                                    N
     15529  KLVDataType?                                  N
     15530  KLVDataParentProperties?                      N
     15531  TaggedValueParentProperties?                  N
     15532  AnnotationParticipantSets?                    N
     15533  KLVDataDefinitions?                           N
     15534  TaggedValueDefinitions?                       N
     15535  AddressNameValueSets?                         N
     15536  NMEADocumentText                              N
     15537  PlatformRollAngle                             N
     15538  PlatformPitchAngle                            N
     15539  PlatformHeadingAngle                          N
     15540  AddressLine                                   N
     15541  AddressLine                                   N
     15542  PlaceName                                     N
     15543  PlaceName                                     N
     15544  GeographicalCoordinates?                      N
     15545  AstronomicalBodyName                          N
     15546  AstronomicalBodyName                          N
     15547  TimecodeArray?                                N
     15548  MarkIn                                        N
     15549  UserPosition                                  N
     15550  MarkOut                                       N
     15551  ClipCreationDateTime                          N
     15552  VideoClipDuration                             N
     15553  ParticipantID?                                N
     15554  ContactID?                                    N
     15555  DefaultNamespaceURI                           N
     15556  DefaultNamespaceURI                           N
     15557  NamespaceURI                                  N
     15558  NamespaceURI                                  N
     15559  NamespaceURIs                                 N
     15560  NamespaceURIs                                 N
     15561  HTMLDOCTYPE                                   N
     15562  HTMLDOCTYPE                                   N
     15563  NamespacePrefix                               N
     15564  NamespacePrefix                               N
     15565  NamespacePrefixes                             N
     15566  NamespacePrefixes                             N
     15567  RightsComment                                 N
     15568  RightsComment                                 N
     15569  NominationCategory                            N
     15570  NominationCategory                            N
     15571  PeakEnvelopeVersion                           N
     15572  PeakEnvelopeFormat                            N
     15573  PointsPerPeakValue                            N
     15574  PeakEnvelopeBlockSize                         N
     15575  PeakChannelCount                              N
     15576  PeakFrameCount                                N
     15577  PeakOfPeaksPosition                           N
     15578  PeakEnvelopeTimestamp                         N
     15579  PeakEnvelopeData?                             N
     15580  RIFFChunkID                                   N
     15581  RIFFChunkLength                               N
     15582  RIFFChunkData?                                N
     15583  MIMECharSet                                   N
     15584  MIMECharSet                                   N
     15585  MIMEEncoding                                  N
     15586  MIMEEncoding                                  N
     15587  MonoSourceTrackIDs                            N
     15588  CompositionRendering?                         N
     15589  CaptionsDescriptionParticipantSets?           N
     15590  EventAnnotationSets?                          N
     15591  ScriptingLocators?                            N
     15592  UnknownBWFChunks?                             N
     15593  CryptographicContextID?                       N
     15594  PlatformDesignation                           N
     15595  LocalTargetID                                 N
     15596  NITFLayerTargetID                             N
     15597  NITFLayerTargetID                             N
     15598  PackageName                                   N
     15599  RP217DataStreamPID                            N
     15600  RP217VideoStreamPID                           N
     15601  SourceOrganization                            N
     15602  OriginalProducerName                          N
     15603  SecurityClassification                        N
     15604  SecurityClassificationCaveats                 N
     15605  ClassificationComment                         N
     15606  CipherAlgorithm?                              N
     15607  CryptographicKeyID?                           N
     15608  EncryptedSourceValue?                         N
     15609  MICAlgorithm?                                 N
     15610  MIC?                                          N
     15611  ISO639-1LanguageCode                          N
     15612  JFIFMarkerDescription                         N
     15613  JFIFMarkerDescription                         N
     15614  HTMLMetaDescription                           N
     15615  HTMLMetaDescription                           N
     15616  MetadataItemName                              N
     15617  ColorPrimaries                                N
     15618  ColorPrimaries?                               N
     15619  ProductFormat                                 N
     15620  ProductFormat                                 N
     15621  SourceLength                                  N
     15622  ImageSourceDeviceKind                         N
     15623  SourceContainerFormat?                        N
     15624  SourceKey?                                    N
     15625  DynamicSourcePackageID?                       N
     15626  DynamicSourceTrackIDs                         N
     15627  SourceIndex?                                  N
     15628  SourceSpecies?                                N
     15629  SourceValue?                                  N
     15630  CryptographicContextObject?                   N
     15631  Sub-descriptors?                              N
     15632  EncryptedTrackFileID?                         N
     15633  CryptographicContextLink?                     N
     15634  PlaintextOffset                               N
     15635  TripletSequenceNumber                         N
     15636  BoundingRectangle?                            N
     15637  GeographicLocation?                           N
     15638  GeographicPolygonCoordinates?                 N
     15639  GeographicAreaNorthwest?                      N
     15640  GeographicAreaSoutheast?                      N
     15641  GeographicAreaSourceDatum                     N
     15642  GeographicPolygonSourceDatum                  N
     15643  CountryCodeMethod                             N
     15644  ClassifyingCountryCode                        N
     15645  ReleasableCountryCode                         N
     15646  UTCStartDateTime                              N
     15647  UTCInstantDateTime                            N
     15648  UTCInstantDateTime                            N
     15649  UTCLastModifyDate                             N
     15650  ToleranceMode?                                N
     15651  ToleranceWindow?                              N
     15652  ToleranceInterpolationMethod?                 N
     15653  VBILineCount                                  N
     15654  StoredVBILineNumber                           N
     15655  VBIWrappingType                               N
     15656  VBIPayloadSampleCount                         N
     15657  VBIPayloadByteArray                           N
     15658  ANCPacketCount                                N
     15659  StoredANCLineNumber                           N
     15660  ANCWrappingType                               N
     15661  ANCPayloadSampleCount                         N
     15662  ANCPayloadByteArray                           N
     15663  VBIPayloadSampleCoding                        N
     15664  ANCPayloadSampleCoding                        N
     15665  Rsiz                                          N
     15666  Xsiz                                          N
     15667  Ysiz                                          N
     15668  XOsiz                                         N
     15669  YOsiz                                         N
     15670  XTsiz                                         N
     15671  YTsiz                                         N
     15672  XTOsiz                                        N
     15673  YTOsiz                                        N
     15674  Csiz                                          N
     15675  PictureComponentSizing?                       N
     15676  CodingStyleDefault?                           N
     15677  QuantizationDefault?                          N
     15678  MPEGAudioBitrate                              N
     15679  CBEStartOffset                                N
     15680  VBEEndOffset                                  N
     15681  SubDescriptor?                                N
     15682  SubDescriptors?                               N
     15683  RootMetaDictionary?                           N
     15684  RootPreface?                                  N
     15685  RootObjectDirectory?                          N
     15686  RootFormatVersion                             N
     15687  FrameCenterElevation                          N
     15688  PackageMarkInPosition                         N
     15689  PackageMarkOutPosition                        N
     15690  Ad-ID?                                        N
     15691  ResourceID?                                   N
     15692  AncillaryResourceID?                          N
     15693  ApplicationSchemeBatch?                       N
     15694  RegisterKind?                                 N
     15695  RegisterVersion                               N
     15696  RegisterEditorName                            N
     15697  RegisterStatusKind?                           N
     15698  RegisterItemName                              N
     15699  RegisterItemDefinition                        N
     15700  RegisterItemSymbol?                           N
     15701  RegisterItemDefiningDocumentName              N
     15702  RegisterItemUL?                               N
     15703  RegisterItemNotes                             N
     15704  RegisterItemIntroductionVersion               N
     15705  RegisterItemHierarchyLevel                    N
     15706  RegisterEntryStatus?                          N
     15707  RegisterAction                                N
     15708  RegisterApproverName                          N
     15709  RegisterCreationTime                          N
     15710  RegistrantName                                N
     15711  RegisterItemOriginatorName                    N
     15712  RegisterUserName                              N
     15713  RegisterUserTime                              N
     15714  RegisterAdministrationNotes                   N
     15715  AFDAndBarData?                                N
     15716  PanScanInformation?                           N
     15717  VC-1InitializationMetadata?                   N
     15718  VC-1SingleSequence                            N
     15719  VC-1CodedContentType                          N
     15720  VC-1IdenticalGOP                              N
     15721  VC-1MaximumGOP                                N
     15722  VC-1BPictureCount                             N
     15723  VC-1AverageBitrate                            N
     15724  VC-1MaximumBitrate                            N
     15725  VC-1Profile                                   N
     15726  VC-1Level                                     N
     15727  LinkedTimecodeTrackID?                        N
     15728  SMPTE337MDataStreamNumber                     N
     15729  ApplicationScheme?                            N
     15730  DescriptiveMetadataScheme?                    N
     15731  UCSEncoding                                   N
     15732  LinkedApplicationPlug-InInstanceID?           N
     15733  LinkedDescriptiveFrameworkPlug-InID?          N
     15734  ApplicationPlug-InInstanceID?                 N
     15735  DescriptiveMetadataPlug-InID?                 N
     15736  ApplicationEnvironmentID                      N
     15737  DescriptiveMetadataApplicationEnvironmentID   N
     15738  LinkedDescriptiveObjectPlug-InID?             N
     15739  TimebaseReferenceTrackID                      N
     15740  ObjectClassDefinition?                        N
     15741  ApplicationPlug-InBatch?                      N
     15742  PackageMarker?                                N
     15743  PackageTimelineMarkerRef?                     N
     15744  RegisterAdministrationObject?                 N
     15745  RegisterEntryAdministrationObject?            N
     15746  GenericPayloads?                              N
     15747  RegisterEntryArray?                           N
     15748  RegisterAdministrationArray?                  N
     15749  ApplicationInformationArray?                  N
     15750  RegisterChildEntryArray?                      N
     15751  RegisterReleaseDateTime                       N
     15752  RegisterItemStatusChangeDateTime              N
     15753  OpenHeader                                    MXF Header
     15754  ClosedHeader                                  MXF Header
     15755  OpenCompleteHeader                            MXF Header
     15756  ClosedCompleteHeader                          MXF Header
     15757  OpenBodyPartition?                            N
     15758  ClosedBodyPartition?                          N
     15759  OpenCompleteBodyPartition?                    N
     15760  ClosedCompleteBodyPartition?                  N
     15761  Footer?                                       N
     15762  CompleteFooter?                               N
     15763  Primer                                        MXF
     15764  RandomIndexMetadataV10?                       N
     15765  RandomIndexMetadata?                          N
     15766  PartitionMetadata?                            N
     15767  StructuralComponent                           MXF
     15768  SequenceSet                                   MXF
     15769  SourceClip?                                   N
     15770  TimecodeComponent                             MXF
     15771  ContentStorageSet                             MXF
     15772  EssenceContainerDataSet                       MXF
     15773  FileDescriptor                                MXF
     15774  GenericPictureEssenceDescriptor               MXF
     15775  CDCIEssenceDescriptor                         MXF
     15776  RGBAEssenceDescriptor                         MXF
     15777  Preface                                       MXF
     15778  Identification                                MXF
     15779  NetworkLocator                                MXF
     15780  TextLocator                                   MXF
     15781  GenericPackage                                MXF
     15782  MaterialPackage                               MXF
     15783  SourcePackage                                 MXF
     15784  GenericTrack                                  MXF
     15785  EventTrack                                    MXF
     15786  StaticTrack                                   MXF
     15787  Track                                         MXF
     15788  DMSegment                                     MXF
     15789  GenericSoundEssenceDescriptor                 MXF
     15790  GenericDataEssenceDescriptor                  MXF
     15791  MultipleDescriptor                            MXF
     15792  DMSourceClip                                  MXF
     15793  AES3PCMDescriptor                             MXF
     15794  WaveAudioDescriptor                           MXF
     15795  MPEG2VideoDescriptor                          MXF
     15796  JPEG2000PictureSubDescriptor                  MXF
     15797  VBIDataDescriptor                             MXF
     15798  V10IndexTableSegment?                         N
     15799  IndexTableSegment?                            N
     15800  DMSet                                         MXF
     15801  DMFramework                                   MXF
     15802  ProductionFramework                           MXF
     15803  ClipFramework                                 MXF
     15804  SceneFramework                                MXF
     15805  Titles                                        MXF
     15806  Identification                                MXF
     15807  GroupRelationship                             MXF
     15808  Branding                                      MXF
     15809  Event                                         MXF
     15810  Publication                                   MXF
     15811  Award                                         MXF
     15812  CaptionDescription                            MXF
     15813  Annotation                                    MXF
     15814  SettingPeriod                                 MXF
     15815  Scripting                                     MXF
     15816  Classification                                MXF
     15817  Shot                                          MXF
     15818  KeyPoint                                      MXF
     15819  CueWords                                      MXF
     15820  Participant                                   MXF
     15821  ContactsList                                  MXF
     15822  Person                                        MXF
     15823  Organisation                                  MXF
     15824  Location                                      MXF
     15825  Address                                       MXF
     15826  Communications                                MXF
     15827  Contract                                      MXF
     15828  Rights                                        MXF
     15829  PictureFormat                                 MXF
     15830  DeviceParameters                              MXF
     15831  NameValue                                     MXF
     15832  Processing                                    MXF
     15833  Projects                                      MXF
     15834  CryptographicFramework                        MXF
     15835  CryptographicContext                          MXF
     15836  DefaultObject?                                N
     15837  CipherAlgorithmAES128CBC?                     N
     15838  HMACAlgorithmSHA1128?                         N
     15839  EncryptedContainerLabel?                      N
     15840  CryptographicFrameworkLabel?                  N
     15841
     15842=head3 MXF Header Tags
     15843
     15844   Index   Tag Name                             Writable
     15845   -----   --------                             --------
     15846      0    MXFVersion                           N
     15847     24    FooterPosition                       N
     15848     32    HeaderSize                           N
     15849
     15850=head2 DV Tags
     15851
     15852The following tags are extracted from DV videos.
     15853
     15854  Tag Name                                      Writable
     15855  --------                                      --------
     15856  AspectRatio                                   N
     15857  AudioBitsPerSample                            N
     15858  AudioChannels                                 N
     15859  AudioSampleRate                               N
     15860  Colorimetry                                   N
     15861  DateTimeOriginal                              N
     15862  Duration                                      N
     15863  FrameRate                                     N
     15864  ImageHeight                                   N
     15865  ImageWidth                                    N
     15866  TotalBitrate                                  N
     15867  VideoFormat                                   N
     15868  VideoScanType                                 N
    753515869
    753615870=head2 Flash Tags
    753715871
    7538 The information below is extracted from the header of SWF (Shockwave Flash)
    7539 files.
     15872The information below is extracted from SWF (Shockwave Flash) files.  Tags
     15873with string ID's represent information extracted from the file header.
    754015874
    754115875  Tag ID               Tag Name                 Writable
     
    754815882  'ImageHeight'        ImageHeight              N
    754915883  'ImageWidth'         ImageWidth               N
     15884  0x0045               FileAttributes           N
     15885  0x004d               XMP                      XMP
    755015886
    755115887=head3 Flash FLV Tags
     
    756815904  'Bit0-3' AudioEncoding                        N
    756915905  'Bit4-5' AudioSampleRate                      N
    7570   'Bit6'   AudioSampleBits                      N
     15906  'Bit6'   AudioBitsPerSample                   N
    757115907  'Bit7'   AudioChannels                        N
    757215908
     
    759215928  'audiosamplesize'        AudioSampleSize      N
    759315929  'audiosize'              AudioSize            N
     15930  'bytelength'             ByteLength           N
    759415931  'canSeekToEnd'           CanSeekToEnd         N
     15932  'canseekontime'          CanSeekOnTime        N
     15933  'createdby'              CreatedBy            N
    759515934  'creationdate'           CreateDate           N
    759615935  'cuePoints'              CuePoint             Flash CuePoint
     
    760515944  'hasVideo'               HasVideo             N
    760615945  'height'                 ImageHeight          N
     15946  'httphostheader'         HTTPHostHeader       N
    760715947  'keyframesFilepositions' KeyFramePositions    N
    760815948  'keyframesTimes'         KeyFramesTimes       N
    760915949  'lastkeyframetimestamp'  LastKeyFrameTime     N
    761015950  'lasttimestamp'          LastTimeStamp        N
     15951  'liveXML'                XMP                  XMP
    761115952  'metadatacreator'        MetadataCreator      N
    761215953  'metadatadate'           MetadataDate         N
     15954  'pmsg'                   Message              N
     15955  'purl'                   URL                  N
     15956  'sourcedata'             SourceData           N
     15957  'starttime'              StartTime            N
    761315958  'stereo'                 Stereo               N
     15959  'totaldatarate'          TotalDataRate        N
     15960  'totalduration'          TotalDuration        N
    761415961  'videocodecid'           VideoCodecID         N
    761515962  'videodatarate'          VideoBitrate         N
     
    767416021  -------- --------                             --------
    767516022      0    StreamNumber                         N
    7676       1    StreamMaxBitRate                     N
    7677       2    StreamAvgBitRate                     N
     16023      1    StreamMaxBitrate                     N
     16024      2    StreamAvgBitrate                     N
    767816025      3    StreamMaxPacketSize                  N
    767916026      4    StreamAvgPacketSize                  N
     
    772216069  Sequence Tag Name                             Writable
    772316070  -------- --------                             --------
    7724       0    MaxBitRate                           N
    7725       1    AvgBitRate                           N
     16071      0    MaxBitrate                           N
     16072      1    AvgBitrate                           N
    772616073      2    MaxPacketSize                        N
    772716074      3    AvgPacketSize                        N
     
    785016197=head2 RIFF Tags
    785116198
    7852 Windows WAV and AVI files are RIFF format files.  Meta information embedded
    7853 in two types of RIFF C<LIST> chunks: C<INFO> and C<exif>.  As well, some
    7854 information about the audio content is extracted from the C<fmt > chunk.
     16199The RIFF container format is used various types of fines including WAV, AVI
     16200and WEBP.  According to the EXIF specification, Meta information is embedded
     16201in two types of RIFF C<LIST> chunks: C<INFO> and C<exif>, and information
     16202about the audio content is stored in the C<fmt > chunk.  As well as this
     16203information, some video information and proprietary manufacturer-specific
     16204information is also extracted.
    785516205
    785616206  Tag ID               Tag Name                 Writable
    785716207  ------               --------                 --------
     16208  'JUNK'               OlympusJunk              Olympus AVI
     16209                       CasioJunk                EXIF
     16210                       RicohJunk                Ricoh AVI
     16211                       PentaxJunk               Pentax Junk
     16212                       TextJunk                 N
     16213  'JUNQ'               OldXMP                   N
    785816214  'LIST_INFO'          Info                     RIFF Info
     16215  'LIST_Tdat'          Tdat                     RIFF Tdat
    785916216  'LIST_exif'          Exif                     RIFF Exif
    786016217  'LIST_hdrl'          Hdrl                     RIFF Hdrl
     16218  'LIST_hydt'          PentaxData               Pentax AVI
     16219  'LIST_ncdt'          NikonData                Nikon AVI
     16220  '_PMX'               XMP                      XMP
     16221  'bext'               BroadcastExtension       RIFF BroadcastExt
    786116222  'fmt '               AudioFormat              RIFF AudioFormat
     16223  'olym'               Olym                     Olympus WAV
    786216224
    786316225=head3 RIFF Info Tags
     16226
     16227RIFF INFO tags found in WAV audio and AVI video files.  Tags which are part
     16228of the EXIF 2.3 specification have an underlined Tag Name in the HTML
     16229version of this documentation.  Other tags are found in AVI files generated
     16230by some software.
    786416231
    786516232  Tag ID   Tag Name                             Writable
    786616233  ------   --------                             --------
     16234  'AGES'   Rated                                N
     16235  'CMNT'   Comment                              N
     16236  'CODE'   EncodedBy                            N
     16237  'COMM'   Comments                             N
     16238  'DIRC'   Directory                            N
     16239  'DISP'   SoundSchemeTitle                     N
     16240  'DTIM'   DateTimeOriginal                     N
     16241  'GENR'   Genre                                N
    786716242  'IARL'   ArchivalLocation                     N
    786816243  'IART'   Artist                               N
     16244  'IAS1'   FirstLanguage                        N
     16245  'IAS2'   SecondLanguage                       N
     16246  'IAS3'   ThirdLanguage                        N
     16247  'IAS4'   FourthLanguage                       N
     16248  'IAS5'   FifthLanguage                        N
     16249  'IAS6'   SixthLanguage                        N
     16250  'IAS7'   SeventhLanguage                      N
     16251  'IAS8'   EighthLanguage                       N
     16252  'IAS9'   NinthLanguage                        N
     16253  'IBSU'   BaseURL                              N
     16254  'ICAS'   DefaultAudioStream                   N
     16255  'ICDS'   CostumeDesigner                      N
    786916256  'ICMS'   Commissioned                         N
    787016257  'ICMT'   Comment                              N
     16258  'ICNM'   Cinematographer                      N
     16259  'ICNT'   Country                              N
    787116260  'ICOP'   Copyright                            N
    787216261  'ICRD'   DateCreated                          N
     
    787416263  'IDIM'   Dimensions                           N
    787516264  'IDPI'   DotsPerInch                          N
     16265  'IDST'   DistributedBy                        N
     16266  'IEDT'   EditedBy                             N
     16267  'IENC'   EncodedBy                            N
    787616268  'IENG'   Engineer                             N
    787716269  'IGNR'   Genre                                N
    787816270  'IKEY'   Keywords                             N
    787916271  'ILGT'   Lightness                            N
     16272  'ILGU'   LogoURL                              N
     16273  'ILIU'   LogoIconURL                          N
     16274  'ILNG'   Language                             N
     16275  'IMBI'   MoreInfoBannerImage                  N
     16276  'IMBU'   MoreInfoBannerURL                    N
    788016277  'IMED'   Medium                               N
     16278  'IMIT'   MoreInfoText                         N
     16279  'IMIU'   MoreInfoURL                          N
     16280  'IMUS'   MusicBy                              N
    788116281  'INAM'   Title                                N
     16282  'IPDS'   ProductionDesigner                   N
    788216283  'IPLT'   NumColors                            N
    788316284  'IPRD'   Product                              N
     16285  'IPRO'   ProducedBy                           N
     16286  'IRIP'   RippedBy                             N
     16287  'IRTD'   Rating                               N
    788416288  'ISBJ'   Subject                              N
    788516289  'ISFT'   Software                             N
     16290  'ISGN'   SecondaryGenre                       N
    788616291  'ISHP'   Sharpness                            N
    788716292  'ISRC'   Source                               N
    788816293  'ISRF'   SourceForm                           N
     16294  'ISTD'   ProductionStudio                     N
     16295  'ISTR'   Starring                             N
    788916296  'ITCH'   Technician                           N
     16297  'IWMU'   WatermarkURL                         N
     16298  'IWRI'   WrittenBy                            N
     16299  'LANG'   Language                             N
     16300  'LOCA'   Location                             N
     16301  'PRT1'   Part                                 N
     16302  'PRT2'   NumberOfParts                        N
     16303  'RATE'   Rate                                 N
     16304  'STAR'   Starring                             N
     16305  'STAT'   Statistics                           N
     16306  'TAPE'   TapeName                             N
     16307  'TCDO'   EndTimecode                          N
     16308  'TCOD'   StartTimecode                        N
     16309  'TITL'   Title                                N
     16310  'TLEN'   Length                               N
     16311  'TORG'   Organization                         N
     16312  'TRCK'   TrackNumber                          N
     16313  'TURL'   URL                                  N
     16314  'TVER'   Version                              N
     16315  'VMAJ'   VegasVersionMajor                    N
     16316  'VMIN'   VegasVersionMinor                    N
     16317  'YEAR'   Year                                 N
     16318
     16319=head3 RIFF Tdat Tags
     16320
     16321  Tag ID   Tag Name                             Writable
     16322  ------   --------                             --------
     16323  [no tags known]
    789016324
    789116325=head3 RIFF Exif Tags
     16326
     16327These tags are part of the EXIF 2.3 specification for WAV audio files.
    789216328
    789316329  Tag ID   Tag Name                             Writable
     
    790616342  ------               --------                 --------
    790716343  'IDIT'               DateTimeOriginal         N
    7908   'ISMP'               TimeCode                 N
     16344  'ISMP'               Timecode                 N
     16345  'LIST_odml'          OpenDML                  RIFF OpenDML
    790916346  'LIST_strl'          Stream                   RIFF Stream
    791016347  'avih'               AVIHeader                RIFF AVIHeader
     16348
     16349=head3 RIFF OpenDML Tags
     16350
     16351  Tag ID   Tag Name                             Writable
     16352  ------   --------                             --------
     16353  'dmlh'   ExtendedAVIHeader                    RIFF ExtAVIHdr
     16354
     16355=head3 RIFF ExtAVIHdr Tags
     16356
     16357   Index   Tag Name                             Writable
     16358   -----   --------                             --------
     16359      0    TotalFrameCount                      N
    791116360
    791216361=head3 RIFF Stream Tags
     
    792216371=head3 RIFF StreamData Tags
    792316372
    7924 This chunk contains EXIF information in FujiFilm F30 AVI files.
    7925 
    7926   Tag ID   Tag Name                             Writable
    7927   ------   --------                             --------
    7928   'AVIF'   AVIF                                 EXIF
     16373This chunk is used to store proprietary information in AVI videos from some
     16374cameras.  The first 4 characters of the data are used as the Tag ID below.
     16375
     16376  Tag ID       Tag Name                         Writable
     16377  ------       --------                         --------
     16378  'AVIF'       AVIF                             EXIF
     16379  'CASI'       CasioData                        Casio AVI
     16380  'Zora'       VendorName                       N
     16381  'unknown'    UnknownData                      N
    792916382
    793016383=head3 RIFF AudioFormat Tags
     
    794316396   -----   --------                             --------
    794416397      0    StreamType                           N
    7945       1    Codec                                N
     16398      1    AudioCodec                           N
     16399           VideoCodec                           N
     16400           Codec                                N
     16401      5    AudioSampleRate                      N
     16402           VideoFrameRate                       N
     16403           StreamSampleRate                     N
     16404      8    AudioSampleCount                     N
     16405           VideoFrameCount                      N
     16406           StreamSampleCount                    N
    794616407     10    Quality                              N
    794716408     11    SampleSize                           N
     
    795716418      8    ImageWidth                           N
    795816419      9    ImageHeight                          N
     16420
     16421=head3 RIFF BroadcastExt Tags
     16422
     16423Information found in the Broadcast Audio Extension chunk (see
     16424L<http://tech.ebu.ch/docs/tech/tech3285.pdf>).
     16425
     16426   Index   Tag Name                             Writable
     16427   -----   --------                             --------
     16428      0    Description                          N
     16429    256    Originator                           N
     16430    288    OriginatorReference                  N
     16431    320    DateTimeOriginal                     N
     16432    338    TimeReference                        N
     16433    346    BWFVersion                           N
     16434    602    CodingHistory                        N
    795916435
    796016436=head2 AIFF Tags
     
    799916475=head2 ASF Tags
    800016476
    8001 ASF format is used by Windows WMA and WMV files.  Tag ID's aren't listed
    8002 because they are huge 128-bit GUID's that would ruin the formatting of this
    8003 table.
     16477The ASF format is used by Windows WMA and WMV files, and DIVX videos.  Tag
     16478ID's aren't listed because they are huge 128-bit GUID's that would ruin the
     16479formatting of this table.
    800416480
    800516481  Tag Name                                      Writable
     
    800916485  Header                                        ASF Header
    801016486  Data                                          N
     16487  XMP                                           XMP
    801116488  Index                                         N
    801216489  MediaIndex                                    N
     
    809216569   -----   --------                             --------
    809316570      0    FileID                               N
    8094      16    FileSize                             N
     16571     16    FileLength                           N
    809516572     24    CreationDate                         N
    809616573     32    DataPackets                          N
     
    823616713  PeakValue                                     N
    823716714  Period                                        N
    8238   Picture                                       ASF Preview
     16715  Picture                                       ASF Picture
    823916716  PlaylistDelay                                 N
    824016717  Producer                                      N
     
    828016757  Year                                          N
    828116758
    8282 =head3 ASF Preview Tags
     16759=head3 ASF Picture Tags
    828316760
    828416761  Tag Name                                      Writable
    828516762  --------                                      --------
    8286   PreviewType                                   N
    8287   PreviewMimeType                               N
    8288   PreviewDescription                            N
    8289   PreviewImage                                  N
     16763  PictureType                                   N
     16764  PictureMimeType                               N
     16765  PictureDescription                            N
     16766  Picture                                       N
    829016767
    829116768=head2 DICOM Tags
     
    829416771header and a number of new tags.  ExifTool will extract information from
    829516772either type of file.  The Tag ID's in the following table are the tag group
    8296 and element numbers in hexadecimal, as given in the DICOM specification.
     16773and element numbers in hexadecimal, as given in the DICOM specification (see
     16774L<http://medical.nema.org/>).  The table below contains tags from the DICOM
     167752009 and earlier specifications plus some vendor-specific private tags.
    829716776
    829816777  Tag ID     Tag Name                           Writable
     
    833016809  0008,0001  LengthToEnd                        N
    833116810  0008,0005  SpecificCharacterSet               N
     16811  0008,0006  LanguageCodeSequence               N
    833216812  0008,0008  ImageType                          N
    833316813  0008,0010  RecognitionCode                    N
     
    834516825  0008,0024  OverlayDate                        N
    834616826  0008,0025  CurveDate                          N
    8347   0008,002A  AcquisitionDatetime                N
     16827  0008,002A  AcquisitionDateTime                N
    834816828  0008,0030  StudyTime                          N
    834916829  0008,0031  SeriesTime                         N
     
    835616836  0008,0042  NuclearMedicineSeriesType          N
    835716837  0008,0050  AccessionNumber                    N
    8358   0008,0052  Query-RetrieveLevel                N
     16838  0008,0052  QueryRetrieveLevel                 N
    835916839  0008,0054  RetrieveAETitle                    N
    836016840  0008,0056  InstanceAvailability               N
     
    836916849  0008,0081  InstitutionAddress                 N
    837016850  0008,0082  InstitutionCodeSequence            N
    8371   0008,0090  ReferringPhysiciansName            N
    8372   0008,0092  ReferringPhysiciansAddress         N
    8373   0008,0094  ReferringPhysiciansTelephoneNumber N
     16851  0008,0090  ReferringPhysicianName             N
     16852  0008,0092  ReferringPhysicianAddress          N
     16853  0008,0094  ReferringPhysicianTelephoneNumber N
    837416854  0008,0096  ReferringPhysicianIDSequence       N
    837516855  0008,0100  CodeValue                          N
     
    838916869  0008,0115  CodingSchemeName                   N
    839016870  0008,0116  ResponsibleOrganization            N
     16871  0008,0117  ContextUID                         N
    839116872  0008,0201  TimezoneOffsetFromUTC              N
    839216873  0008,1000  NetworkID                          N
     
    839616877  0008,103E  SeriesDescription                  N
    839716878  0008,1040  InstitutionalDepartmentName        N
    8398   0008,1048  PhysicianOfRecord                  N
    8399   0008,1049  PhysicianOfRecordIDSequence        N
    8400   0008,1050  PerformingPhysiciansName           N
     16879  0008,1048  PhysiciansOfRecord                 N
     16880  0008,1049  PhysiciansOfRecordIDSequence       N
     16881  0008,1050  PerformingPhysicianName            N
    840116882  0008,1052  PerformingPhysicianIDSequence      N
    840216883  0008,1060  NameOfPhysicianReadingStudy        N
     
    842216903  0008,115A  SOPClassesSupported                N
    842316904  0008,1160  ReferencedFrameNumber              N
     16905  0008,1161  SimpleFrameList                    N
     16906  0008,1162  CalculatedFrameList                N
     16907  0008,1163  TimeRange                          N
     16908  0008,1164  FrameExtractionSequence            N
    842416909  0008,1195  TransactionUID                     N
    842516910  0008,1197  FailureReason                      N
     
    843816923  0008,2129  NumberOfEventTimers                N
    843916924  0008,212A  NumberOfViewsInStage               N
    8440   0008,2130  EventElapsedTime                   N
    8441   0008,2132  EventTimerName                     N
     16925  0008,2130  EventElapsedTimes                  N
     16926  0008,2132  EventTimerNames                    N
     16927  0008,2133  EventTimerSequence                 N
     16928  0008,2134  EventTimeOffset                    N
     16929  0008,2135  EventCodeSequence                  N
    844216930  0008,2142  StartTrim                          N
    844316931  0008,2143  StopTrim                           N
     
    845516943  0008,2244  TransducerOrientationSequence      N
    845616944  0008,2246  TransducerOrientationModifierSeq   N
     16945  0008,2253  AnatomicEntrancePortalCodeSeqTrial N
     16946  0008,2255  AnatomicApproachDirCodeSeqTrial    N
     16947  0008,2256  AnatomicPerspectiveDescrTrial      N
     16948  0008,2257  AnatomicPerspectiveCodeSeqTrial    N
    845716949  0008,3001  AlternateRepresentationSequence    N
     16950  0008,3010  IrradiationEventUID                N
    845816951  0008,4000  IdentifyingComments                N
    845916952  0008,9007  FrameType                          N
     
    847016963  0008,9215  DerivationCodeSequence             N
    847116964  0008,9237  GrayscalePresentationStateSequence N
     16965  0008,9410  ReferencedOtherPlaneSequence       N
     16966  0008,9458  FrameDisplaySequence               N
     16967  0008,9459  RecommendedDisplayFrameRateInFloat N
     16968  0008,9460  SkipFrameRangeFlag                 N
     16969  0009,1001  FullFidelity                       N
     16970  0009,1002  SuiteID                            N
     16971  0009,1004  ProductID                          N
     16972  0009,1027  ImageActualDate                    N
     16973  0009,1030  ServiceID                          N
     16974  0009,1031  MobileLocationNumber               N
     16975  0009,10E3  EquipmentUID                       N
     16976  0009,10E6  GenesisVersionNow                  N
     16977  0009,10E7  ExamRecordChecksum                 N
     16978  0009,10E9  ActualSeriesDataTimeStamp          N
    847216979  0010,0000  PatientGroupLength                 N
    8473   0010,0010  PatientsName                       N
     16980  0010,0010  PatientName                        N
    847416981  0010,0020  PatientID                          N
    847516982  0010,0021  IssuerOfPatientID                  N
    8476   0010,0030  PatientsBirthDate                  N
    8477   0010,0032  PatientsBirthTime                  N
    8478   0010,0040  PatientsSex                        N
    8479   0010,0050  PatientsInsurancePlanCodeSequence  N
    8480   0010,0101  PatientsPrimaryLanguageCodeSeq     N
    8481   0010,0102  PatientsPrimaryLanguageCodeModSeq  N
     16983  0010,0022  TypeOfPatientID                    N
     16984  0010,0030  PatientBirthDate                   N
     16985  0010,0032  PatientBirthTime                   N
     16986  0010,0040  PatientSex                         N
     16987  0010,0050  PatientInsurancePlanCodeSequence   N
     16988  0010,0101  PatientPrimaryLanguageCodeSeq      N
     16989  0010,0102  PatientPrimaryLanguageCodeModSeq   N
    848216990  0010,1000  OtherPatientIDs                    N
    848316991  0010,1001  OtherPatientNames                  N
    8484   0010,1005  PatientsBirthName                  N
    8485   0010,1010  PatientsAge                        N
    8486   0010,1020  PatientsSize                       N
    8487   0010,1030  PatientsWeight                     N
    8488   0010,1040  PatientsAddress                    N
     16992  0010,1002  OtherPatientIDsSequence            N
     16993  0010,1005  PatientBirthName                   N
     16994  0010,1010  PatientAge                         N
     16995  0010,1020  PatientSize                        N
     16996  0010,1030  PatientWeight                      N
     16997  0010,1040  PatientAddress                     N
    848916998  0010,1050  InsurancePlanIdentification        N
    8490   0010,1060  PatientsMothersBirthName           N
     16999  0010,1060  PatientMotherBirthName             N
    849117000  0010,1080  MilitaryRank                       N
    849217001  0010,1081  BranchOfService                    N
    849317002  0010,1090  MedicalRecordLocator               N
    849417003  0010,2000  MedicalAlerts                      N
    8495   0010,2110  ContrastAllergies                  N
     17004  0010,2110  Allergies                          N
    849617005  0010,2150  CountryOfResidence                 N
    849717006  0010,2152  RegionOfResidence                  N
    8498   0010,2154  PatientsTelephoneNumbers           N
     17007  0010,2154  PatientTelephoneNumbers            N
    849917008  0010,2160  EthnicGroup                        N
    850017009  0010,2180  Occupation                         N
     
    850317012  0010,21C0  PregnancyStatus                    N
    850417013  0010,21D0  LastMenstrualDate                  N
    8505   0010,21F0  PatientsReligiousPreference        N
     17014  0010,21F0  PatientReligiousPreference         N
     17015  0010,2201  PatientSpeciesDescription          N
     17016  0010,2202  PatientSpeciesCodeSequence         N
     17017  0010,2203  PatientSexNeutered                 N
     17018  0010,2210  AnatomicalOrientationType          N
     17019  0010,2292  PatientBreedDescription            N
     17020  0010,2293  PatientBreedCodeSequence           N
     17021  0010,2294  BreedRegistrationSequence          N
     17022  0010,2295  BreedRegistrationNumber            N
     17023  0010,2296  BreedRegistryCodeSequence          N
     17024  0010,2297  ResponsiblePerson                  N
     17025  0010,2298  ResponsiblePersonRole              N
     17026  0010,2299  ResponsibleOrganization            N
    850617027  0010,4000  PatientComments                    N
     17028  0010,9431  ExaminedBodyThickness              N
     17029  0011,1010  PatientStatus                      N
    850717030  0012,0010  ClinicalTrialSponsorName           N
    850817031  0012,0020  ClinicalTrialProtocolID            N
     
    851517038  0012,0051  ClinicalTrialTimePointDescription  N
    851617039  0012,0060  ClinicalTrialCoordinatingCenter    N
     17040  0012,0062  PatientIdentityRemoved             N
     17041  0012,0063  DeidentificationMethod             N
     17042  0012,0064  DeidentificationMethodCodeSequence N
     17043  0012,0071  ClinicalTrialSeriesID              N
     17044  0012,0072  ClinicalTrialSeriesDescription     N
     17045  0012,0084  DistributionType                   N
     17046  0012,0085  ConsentForDistributionFlag         N
    851717047  0018,0000  AcquisitionGroupLength             N
    8518   0018,0010  Contrast-BolusAgent                N
    8519   0018,0012  Contrast-BolusAgentSequence        N
    8520   0018,0014  Contrast-BolusAdministrationRoute  N
     17048  0018,0010  ContrastBolusAgent                 N
     17049  0018,0012  ContrastBolusAgentSequence         N
     17050  0018,0014  ContrastBolusAdministrationRoute   N
    852117051  0018,0015  BodyPartExamined                   N
    852217052  0018,0020  ScanningSequence                   N
     
    854317073  0018,003A  InterventionDescription            N
    854417074  0018,0040  CineRate                           N
     17075  0018,0042  InitialCineRunState                N
    854517076  0018,0050  SliceThickness                     N
    854617077  0018,0060  KVP                                N
     
    856717098  0018,0095  PixelBandwidth                     N
    856817099  0018,1000  DeviceSerialNumber                 N
     17100  0018,1002  DeviceUID                          N
     17101  0018,1003  DeviceID                           N
    856917102  0018,1004  PlateID                            N
     17103  0018,1005  GeneratorID                        N
     17104  0018,1006  GridID                             N
     17105  0018,1007  CassetteID                         N
     17106  0018,1008  GantryID                           N
    857017107  0018,1010  SecondaryCaptureDeviceID           N
    857117108  0018,1011  HardcopyCreationDeviceID           N
     
    858217119  0018,1023  DigitalImageFormatAcquired         N
    858317120  0018,1030  ProtocolName                       N
    8584   0018,1040  Contrast-BolusRoute                N
    8585   0018,1041  Contrast-BolusVolume               N
    8586   0018,1042  Contrast-BolusStartTime            N
    8587   0018,1043  Contrast-BolusStopTime             N
    8588   0018,1044  Contrast-BolusTotalDose            N
     17121  0018,1040  ContrastBolusRoute                 N
     17122  0018,1041  ContrastBolusVolume                N
     17123  0018,1042  ContrastBolusStartTime             N
     17124  0018,1043  ContrastBolusStopTime              N
     17125  0018,1044  ContrastBolusTotalDose             N
    858917126  0018,1045  SyringeCounts                      N
    859017127  0018,1046  ContrastFlowRate                   N
    859117128  0018,1047  ContrastFlowDuration               N
    8592   0018,1048  Contrast-BolusIngredient           N
    8593   0018,1049  Contrast-BolusConcentration        N
     17129  0018,1048  ContrastBolusIngredient            N
     17130  0018,1049  ContrastBolusConcentration         N
    859417131  0018,1050  SpatialResolution                  N
    859517132  0018,1060  TriggerTime                        N
     
    859717134  0018,1062  NominalInterval                    N
    859817135  0018,1063  FrameTime                          N
    8599   0018,1064  FramingType                        N
     17136  0018,1064  CardiacFramingType                 N
    860017137  0018,1065  FrameTimeVector                    N
    860117138  0018,1066  FrameDelay                         N
     
    861417151  0018,1076  RadionuclidePositronFraction       N
    861517152  0018,1077  RadiopharmaceuticalSpecActivity    N
     17153  0018,1078  RadiopharmaceuticalStartDateTime   N
     17154  0018,1079  RadiopharmaceuticalStopDateTime    N
    861617155  0018,1080  BeatRejectionFlag                  N
    861717156  0018,1081  LowRRValue                         N
     
    862817167  0018,1111  DistanceSourceToPatient            N
    862917168  0018,1114  EstimatedRadiographicMagnification N
    8630   0018,1120  Gantry-DetectorTilt                N
    8631   0018,1121  Gantry-DetectorSlew                N
     17169  0018,1120  GantryDetectorTilt                 N
     17170  0018,1121  GantryDetectorSlew                 N
    863217171  0018,1130  TableHeight                        N
    863317172  0018,1131  TableTraverse                      N
     
    866217201  0018,1166  Grid                               N
    866317202  0018,1170  GeneratorPower                     N
    8664   0018,1180  Collimator-GridName                N
     17203  0018,1180  CollimatorGridName                 N
    866517204  0018,1181  CollimatorType                     N
    866617205  0018,1182  FocalDistance                      N
    866717206  0018,1183  XFocusCenter                       N
    866817207  0018,1184  YFocusCenter                       N
    8669   0018,1190  FocalSpot                          N
     17208  0018,1190  FocalSpots                         N
    867017209  0018,1191  AnodeTargetMaterial                N
    867117210  0018,11A0  BodyPartThickness                  N
     
    867417213  0018,1201  TimeOfLastCalibration              N
    867517214  0018,1210  ConvolutionKernel                  N
    8676   0018,1240  Upper-LowerPixelValues             N
     17215  0018,1240  UpperLowerPixelValues              N
    867717216  0018,1242  ActualFrameDuration                N
    867817217  0018,1243  CountRate                          N
     
    869517234  0018,1402  CassetteOrientation                N
    869617235  0018,1403  CassetteSize                       N
    8697   0018,1404  ExposuresonPlate                   N
     17236  0018,1404  ExposuresOnPlate                   N
    869817237  0018,1405  RelativeXRayExposure               N
    869917238  0018,1450  ColumnAngulation                   N
     
    872217261  0018,1622  ShutterPresentationValue           N
    872317262  0018,1623  ShutterOverlayGroup                N
     17263  0018,1624  ShutterPresentationColorCIELabVal  N
    872417264  0018,1700  CollimatorShape                    N
    872517265  0018,1702  CollimatorLeftVerticalEdge         N
     
    879117331  0018,6034  DopplerCorrectionAngle             N
    879217332  0018,6036  SteeringAngle                      N
    8793   0018,6038  DopplerSampleVolumeXPositionUL     N
     17333  0018,6038  DopplerSampleVolumeXPosRetired     N
    879417334  0018,6039  DopplerSampleVolumeXPosition       N
    8795   0018,603A  DopplerSampleVolumeYPositionUL     N
     17335  0018,603A  DopplerSampleVolumeYPosRetired     N
    879617336  0018,603B  DopplerSampleVolumeYPosition       N
    8797   0018,603C  TMLinePositionX0UL                 N
     17337  0018,603C  TMLinePositionX0Retired            N
    879817338  0018,603D  TMLinePositionX0                   N
    8799   0018,603E  TMLinePositionY0UL                 N
     17339  0018,603E  TMLinePositionY0Retired            N
    880017340  0018,603F  TMLinePositionY0                   N
    8801   0018,6040  TMLinePositionX1UL                 N
     17341  0018,6040  TMLinePositionX1Retired            N
    880217342  0018,6041  TMLinePositionX1                   N
    8803   0018,6042  TMLinePositionY1UL                 N
     17343  0018,6042  TMLinePositionY1Retired            N
    880417344  0018,6043  TMLinePositionY1                   N
    880517345  0018,6044  PixelComponentOrganization         N
     
    887717417  0018,9025  SpectrallySelectedSuppression      N
    887817418  0018,9026  SpectrallySelectedExcitation       N
    8879   0018,9027  SpatialPreSaturation               N
     17419  0018,9027  SpatialPresaturation               N
    888017420  0018,9028  Tagging                            N
    888117421  0018,9029  OversamplingPhase                  N
     
    891417454  0018,9070  CardiacRRIntervalSpecified         N
    891517455  0018,9073  AcquisitionDuration                N
    8916   0018,9074  FrameAcquisitionDatetime           N
     17456  0018,9074  FrameAcquisitionDateTime           N
    891717457  0018,9075  DiffusionDirectionality            N
    891817458  0018,9076  DiffusionGradientDirectionSequence N
     
    893317473  0018,9094  CoverageOfKSpace                   N
    893417474  0018,9095  SpectroscopyAcquisitionPhaseRows   N
     17475  0018,9096  ParallelReductFactorInPlaneRetired N
    893517476  0018,9098  TransmitterFrequency               N
    893617477  0018,9100  ResonantNucleus                    N
     
    895117492  0018,9127  SpectroscopyAcquisitionDataColumns N
    895217493  0018,9147  DiffusionAnisotropyType            N
    8953   0018,9151  FrameReferenceDatetime             N
     17494  0018,9151  FrameReferenceDateTime             N
    895417495  0018,9152  MRMetaboliteMapSequence            N
    895517496  0018,9155  ParallelReductionFactorOutOfPlane  N
     
    897317514  0018,9183  FlowCompensationDirection          N
    897417515  0018,9184  TaggingDelay                       N
     17516  0018,9185  RespiratoryMotionCompTechDescr     N
     17517  0018,9186  RespiratorySignalSourceID          N
    897517518  0018,9195  ChemicalShiftsMinIntegrateLimitHz  N
    897617519  0018,9196  ChemicalShiftsMaxIntegrateLimitHz  N
     
    902917572  0018,9334  FluoroscopyFlag                    N
    903017573  0018,9335  SourceToDataCollectionCenterDist   N
    9031   0018,9337  Contrast-BolusAgentNumber          N
    9032   0018,9338  Contrast-BolusIngredientCodeSeq    N
     17574  0018,9337  ContrastBolusAgentNumber           N
     17575  0018,9338  ContrastBolusIngredientCodeSeq     N
    903317576  0018,9340  ContrastAdministrationProfileSeq   N
    9034   0018,9341  Contrast-BolusUsageSequence        N
    9035   0018,9342  Contrast-BolusAgentAdministered    N
    9036   0018,9343  Contrast-BolusAgentDetected        N
    9037   0018,9344  Contrast-BolusAgentPhase           N
     17577  0018,9341  ContrastBolusUsageSequence         N
     17578  0018,9342  ContrastBolusAgentAdministered     N
     17579  0018,9343  ContrastBolusAgentDetected         N
     17580  0018,9344  ContrastBolusAgentPhase            N
    903817581  0018,9345  CTDIvol                            N
     17582  0018,9346  CTDIPhantomTypeCodeSequence        N
     17583  0018,9351  CalciumScoringMassFactorPatient    N
     17584  0018,9352  CalciumScoringMassFactorDevice     N
     17585  0018,9353  EnergyWeightingFactor              N
     17586  0018,9360  CTAdditionalXRaySourceSequence     N
     17587  0018,9401  ProjectionPixelCalibrationSequence N
     17588  0018,9402  DistanceSourceToIsocenter          N
     17589  0018,9403  DistanceObjectToTableTop           N
     17590  0018,9404  ObjectPixelSpacingInCenterOfBeam   N
     17591  0018,9405  PositionerPositionSequence         N
     17592  0018,9406  TablePositionSequence              N
     17593  0018,9407  CollimatorShapeSequence            N
     17594  0018,9412  XA-XRFFrameCharacteristicsSequence N
     17595  0018,9417  FrameAcquisitionSequence           N
     17596  0018,9420  XRayReceptorType                   N
     17597  0018,9423  AcquisitionProtocolName            N
     17598  0018,9424  AcquisitionProtocolDescription     N
     17599  0018,9425  ContrastBolusIngredientOpaque      N
     17600  0018,9426  DistanceReceptorPlaneToDetHousing  N
     17601  0018,9427  IntensifierActiveShape             N
     17602  0018,9428  IntensifierActiveDimensions        N
     17603  0018,9429  PhysicalDetectorSize               N
     17604  0018,9430  PositionOfIsocenterProjection      N
     17605  0018,9432  FieldOfViewSequence                N
     17606  0018,9433  FieldOfViewDescription             N
     17607  0018,9434  ExposureControlSensingRegionsSeq   N
     17608  0018,9435  ExposureControlSensingRegionShape  N
     17609  0018,9436  ExposureControlSensRegionLeftEdge  N
     17610  0018,9437  ExposureControlSensRegionRightEdge N
     17611  0018,9440  CenterOfCircExposControlSensRegion N
     17612  0018,9441  RadiusOfCircExposControlSensRegion N
     17613  0018,9447  ColumnAngulationPatient            N
     17614  0018,9449  BeamAngle                          N
     17615  0018,9451  FrameDetectorParametersSequence    N
     17616  0018,9452  CalculatedAnatomyThickness         N
     17617  0018,9455  CalibrationSequence                N
     17618  0018,9456  ObjectThicknessSequence            N
     17619  0018,9457  PlaneIdentification                N
     17620  0018,9461  FieldOfViewDimensionsInFloat       N
     17621  0018,9462  IsocenterReferenceSystemSequence   N
     17622  0018,9463  PositionerIsocenterPrimaryAngle    N
     17623  0018,9464  PositionerIsocenterSecondaryAngle  N
     17624  0018,9465  PositionerIsocenterDetRotAngle     N
     17625  0018,9466  TableXPositionToIsocenter          N
     17626  0018,9467  TableYPositionToIsocenter          N
     17627  0018,9468  TableZPositionToIsocenter          N
     17628  0018,9469  TableHorizontalRotationAngle       N
     17629  0018,9470  TableHeadTiltAngle                 N
     17630  0018,9471  TableCradleTiltAngle               N
     17631  0018,9472  FrameDisplayShutterSequence        N
     17632  0018,9473  AcquiredImageAreaDoseProduct       N
     17633  0018,9474  CArmPositionerTabletopRelationship N
     17634  0018,9476  XRayGeometrySequence               N
     17635  0018,9477  IrradiationEventIDSequence         N
     17636  0018,9504  XRay3DFrameTypeSequence            N
     17637  0018,9506  ContributingSourcesSequence        N
     17638  0018,9507  XRay3DAcquisitionSequence          N
     17639  0018,9508  PrimaryPositionerScanArc           N
     17640  0018,9509  SecondaryPositionerScanArc         N
     17641  0018,9510  PrimaryPositionerScanStartAngle    N
     17642  0018,9511  SecondaryPositionerScanStartAngle  N
     17643  0018,9514  PrimaryPositionerIncrement         N
     17644  0018,9515  SecondaryPositionerIncrement       N
     17645  0018,9516  StartAcquisitionDateTime           N
     17646  0018,9517  EndAcquisitionDateTime             N
     17647  0018,9524  ApplicationName                    N
     17648  0018,9525  ApplicationVersion                 N
     17649  0018,9526  ApplicationManufacturer            N
     17650  0018,9527  AlgorithmType                      N
     17651  0018,9528  AlgorithmDescription               N
     17652  0018,9530  XRay3DReconstructionSequence       N
     17653  0018,9531  ReconstructionDescription          N
     17654  0018,9538  PerProjectionAcquisitionSequence   N
     17655  0018,9601  DiffusionBMatrixSequence           N
     17656  0018,9602  DiffusionBValueXX                  N
     17657  0018,9603  DiffusionBValueXY                  N
     17658  0018,9604  DiffusionBValueXZ                  N
     17659  0018,9605  DiffusionBValueYY                  N
     17660  0018,9606  DiffusionBValueYZ                  N
     17661  0018,9607  DiffusionBValueZZ                  N
     17662  0018,9701  DecayCorrectionDateTime            N
     17663  0018,9715  StartDensityThreshold              N
     17664  0018,9722  TerminationTimeThreshold           N
     17665  0018,9725  DetectorGeometry                   N
     17666  0018,9727  AxialDetectorDimension             N
     17667  0018,9735  PETPositionSequence                N
     17668  0018,9739  NumberOfIterations                 N
     17669  0018,9740  NumberOfSubsets                    N
     17670  0018,9751  PETFrameTypeSequence               N
     17671  0018,9756  ReconstructionType                 N
     17672  0018,9758  DecayCorrected                     N
     17673  0018,9759  AttenuationCorrected               N
     17674  0018,9760  ScatterCorrected                   N
     17675  0018,9761  DeadTimeCorrected                  N
     17676  0018,9762  GantryMotionCorrected              N
     17677  0018,9763  PatientMotionCorrected             N
     17678  0018,9765  RandomsCorrected                   N
     17679  0018,9767  SensitivityCalibrated              N
     17680  0018,9801  DepthsOfFocus                      N
     17681  0018,9804  ExclusionStartDatetime             N
     17682  0018,9805  ExclusionDuration                  N
     17683  0018,9807  ImageDataTypeSequence              N
     17684  0018,9808  DataType                           N
     17685  0018,980B  AliasedDataType                    N
    903917686  0018,A001  ContributingEquipmentSequence      N
    904017687  0018,A002  ContributionDateTime               N
    904117688  0018,A003  ContributionDescription            N
     17689  0019,1002  NumberOfCellsIInDetector           N
     17690  0019,1003  CellNumberAtTheta                  N
     17691  0019,1004  CellSpacing                        N
     17692  0019,100F  HorizFrameOfRef                    N
     17693  0019,1011  SeriesContrast                     N
     17694  0019,1012  LastPseq                           N
     17695  0019,1013  StartNumberForBaseline             N
     17696  0019,1014  EndNumberForBaseline               N
     17697  0019,1015  StartNumberForEnhancedScans        N
     17698  0019,1016  EndNumberForEnhancedScans          N
     17699  0019,1017  SeriesPlane                        N
     17700  0019,1018  FirstScanRas                       N
     17701  0019,1019  FirstScanLocation                  N
     17702  0019,101A  LastScanRas                        N
     17703  0019,101B  LastScanLoc                        N
     17704  0019,101E  DisplayFieldOfView                 N
     17705  0019,1023  TableSpeed                         N
     17706  0019,1024  MidScanTime                        N
     17707  0019,1025  MidScanFlag                        N
     17708  0019,1026  DegreesOfAzimuth                   N
     17709  0019,1027  GantryPeriod                       N
     17710  0019,102A  XRayOnPosition                     N
     17711  0019,102B  XRayOffPosition                    N
     17712  0019,102C  NumberOfTriggers                   N
     17713  0019,102E  AngleOfFirstView                   N
     17714  0019,102F  TriggerFrequency                   N
     17715  0019,1039  ScanFOVType                        N
     17716  0019,1040  StatReconFlag                      N
     17717  0019,1041  ComputeType                        N
     17718  0019,1042  SegmentNumber                      N
     17719  0019,1043  TotalSegmentsRequested             N
     17720  0019,1044  InterscanDelay                     N
     17721  0019,1047  ViewCompressionFactor              N
     17722  0019,104A  TotalNoOfRefChannels               N
     17723  0019,104B  DataSizeForScanData                N
     17724  0019,1052  ReconPostProcflag                  N
     17725  0019,1057  CTWaterNumber                      N
     17726  0019,1058  CTBoneNumber                       N
     17727  0019,105A  AcquisitionDuration                N
     17728  0019,105E  NumberOfChannels                   N
     17729  0019,105F  IncrementBetweenChannels           N
     17730  0019,1060  StartingView                       N
     17731  0019,1061  NumberOfViews                      N
     17732  0019,1062  IncrementBetweenViews              N
     17733  0019,106A  DependantOnNoViewsProcessed        N
     17734  0019,106B  FieldOfViewInDetectorCells         N
     17735  0019,1070  ValueOfBackProjectionButton        N
     17736  0019,1071  SetIfFatqEstimatesWereUsed         N
     17737  0019,1072  ZChanAvgOverViews                  N
     17738  0019,1073  AvgOfLeftRefChansOverViews         N
     17739  0019,1074  MaxLeftChanOverViews               N
     17740  0019,1075  AvgOfRightRefChansOverViews        N
     17741  0019,1076  MaxRightChanOverViews              N
     17742  0019,107D  SecondEcho                         N
     17743  0019,107E  NumberOfEchoes                     N
     17744  0019,107F  TableDelta                         N
     17745  0019,1081  Contiguous                         N
     17746  0019,1084  PeakSAR                            N
     17747  0019,1085  MonitorSAR                         N
     17748  0019,1087  CardiacRepetitionTime              N
     17749  0019,1088  ImagesPerCardiacCycle              N
     17750  0019,108A  ActualReceiveGainAnalog            N
     17751  0019,108B  ActualReceiveGainDigital           N
     17752  0019,108D  DelayAfterTrigger                  N
     17753  0019,108F  Swappf                             N
     17754  0019,1090  PauseInterval                      N
     17755  0019,1091  PulseTime                          N
     17756  0019,1092  SliceOffsetOnFreqAxis              N
     17757  0019,1093  CenterFrequency                    N
     17758  0019,1094  TransmitGain                       N
     17759  0019,1095  AnalogReceiverGain                 N
     17760  0019,1096  DigitalReceiverGain                N
     17761  0019,1097  BitmapDefiningCVs                  N
     17762  0019,1098  CenterFreqMethod                   N
     17763  0019,109B  PulseSeqMode                       N
     17764  0019,109C  PulseSeqName                       N
     17765  0019,109D  PulseSeqDate                       N
     17766  0019,109E  InternalPulseSeqName               N
     17767  0019,109F  TransmittingCoil                   N
     17768  0019,10A0  SurfaceCoilType                    N
     17769  0019,10A1  ExtremityCoilFlag                  N
     17770  0019,10A2  RawDataRunNumber                   N
     17771  0019,10A3  CalibratedFieldStrength            N
     17772  0019,10A4  SATFatWaterBone                    N
     17773  0019,10A5  ReceiveBandwidth                   N
     17774  0019,10A7  UserData01                         N
     17775  0019,10A8  UserData02                         N
     17776  0019,10A9  UserData03                         N
     17777  0019,10AA  UserData04                         N
     17778  0019,10AB  UserData05                         N
     17779  0019,10AC  UserData06                         N
     17780  0019,10AD  UserData07                         N
     17781  0019,10AE  UserData08                         N
     17782  0019,10AF  UserData09                         N
     17783  0019,10B0  UserData10                         N
     17784  0019,10B1  UserData11                         N
     17785  0019,10B2  UserData12                         N
     17786  0019,10B3  UserData13                         N
     17787  0019,10B4  UserData14                         N
     17788  0019,10B5  UserData15                         N
     17789  0019,10B6  UserData16                         N
     17790  0019,10B7  UserData17                         N
     17791  0019,10B8  UserData18                         N
     17792  0019,10B9  UserData19                         N
     17793  0019,10BA  UserData20                         N
     17794  0019,10BB  UserData21                         N
     17795  0019,10BC  UserData22                         N
     17796  0019,10BD  UserData23                         N
     17797  0019,10BE  ProjectionAngle                    N
     17798  0019,10C0  SaturationPlanes                   N
     17799  0019,10C1  SurfaceCoilIntensity               N
     17800  0019,10C2  SATLocationR                       N
     17801  0019,10C3  SATLocationL                       N
     17802  0019,10C4  SATLocationA                       N
     17803  0019,10C5  SATLocationP                       N
     17804  0019,10C6  SATLocationH                       N
     17805  0019,10C7  SATLocationF                       N
     17806  0019,10C8  SATThicknessR-L                    N
     17807  0019,10C9  SATThicknessA-P                    N
     17808  0019,10CA  SATThicknessH-F                    N
     17809  0019,10CB  PrescribedFlowAxis                 N
     17810  0019,10CC  VelocityEncoding                   N
     17811  0019,10CD  ThicknessDisclaimer                N
     17812  0019,10CE  PrescanType                        N
     17813  0019,10CF  PrescanStatus                      N
     17814  0019,10D0  RawDataType                        N
     17815  0019,10D2  ProjectionAlgorithm                N
     17816  0019,10D3  ProjectionAlgorithm                N
     17817  0019,10D5  FractionalEcho                     N
     17818  0019,10D6  PrepPulse                          N
     17819  0019,10D7  CardiacPhases                      N
     17820  0019,10D8  VariableEchoflag                   N
     17821  0019,10D9  ConcatenatedSAT                    N
     17822  0019,10DA  ReferenceChannelUsed               N
     17823  0019,10DB  BackProjectorCoefficient           N
     17824  0019,10DC  PrimarySpeedCorrectionUsed         N
     17825  0019,10DD  OverrangeCorrectionUsed            N
     17826  0019,10DE  DynamicZAlphaValue                 N
     17827  0019,10DF  UserData                           N
     17828  0019,10E0  UserData                           N
     17829  0019,10E2  VelocityEncodeScale                N
     17830  0019,10F2  FastPhases                         N
     17831  0019,10F9  TransmissionGain                   N
    904217832  0020,0000  RelationshipGroupLength            N
    904317833  0020,000D  StudyInstanceUID                   N
     
    907417864  0020,1001  AcquisitionsInSeries               N
    907517865  0020,1002  ImagesInAcquisition                N
     17866  0020,1003  ImagesInSeries                     N
    907617867  0020,1004  AcquisitionsInStudy                N
     17868  0020,1005  ImagesInStudy                      N
    907717869  0020,1020  Reference                          N
    907817870  0020,1040  PositionReferenceIndicator         N
     
    910817900  0020,9158  FrameComments                      N
    910917901  0020,9161  ConcatenationUID                   N
    9110   0020,9162  InconcatenationNumber              N
    9111   0020,9163  InconcatenationTotalNumber         N
     17902  0020,9162  InConcatenationNumber              N
     17903  0020,9163  InConcatenationTotalNumber         N
    911217904  0020,9164  DimensionOrganizationUID           N
    911317905  0020,9165  DimensionIndexPointer              N
     
    911817910  0020,9228  ConcatenationFrameOffsetNumber     N
    911917911  0020,9238  FunctionalGroupPrivateCreator      N
     17912  0020,9241  NominalPercentageOfCardiacPhase    N
     17913  0020,9245  NominalPercentOfRespiratoryPhase   N
     17914  0020,9246  StartingRespiratoryAmplitude       N
     17915  0020,9247  StartingRespiratoryPhase           N
     17916  0020,9248  EndingRespiratoryAmplitude         N
     17917  0020,9249  EndingRespiratoryPhase             N
     17918  0020,9250  RespiratoryTriggerType             N
     17919  0020,9251  RRIntervalTimeNominal              N
     17920  0020,9252  ActualCardiacTriggerDelayTime      N
     17921  0020,9253  RespiratorySynchronizationSequence N
     17922  0020,9254  RespiratoryIntervalTime            N
     17923  0020,9255  NominalRespiratoryTriggerDelayTime N
     17924  0020,9256  RespiratoryTriggerDelayThreshold   N
     17925  0020,9257  ActualRespiratoryTriggerDelayTime  N
     17926  0020,9301  ImagePositionVolume                N
     17927  0020,9302  ImageOrientationVolume             N
     17928  0020,9308  ApexPosition                       N
     17929  0020,9421  DimensionDescriptionLabel          N
     17930  0020,9450  PatientOrientationInFrameSequence  N
     17931  0020,9453  FrameLabel                         N
     17932  0020,9518  AcquisitionIndex                   N
     17933  0020,9529  ContributingSOPInstancesRefSeq     N
     17934  0020,9536  ReconstructionIndex                N
     17935  0021,1003  SeriesFromWhichPrescribed          N
     17936  0021,1005  GenesisVersionNow                  N
     17937  0021,1007  SeriesRecordChecksum               N
     17938  0021,1018  GenesisVersionNow                  N
     17939  0021,1019  AcqreconRecordChecksum             N
     17940  0021,1020  TableStartLocation                 N
     17941  0021,1035  SeriesFromWhichPrescribed          N
     17942  0021,1036  ImageFromWhichPrescribed           N
     17943  0021,1037  ScreenFormat                       N
     17944  0021,104A  AnatomicalReferenceForScout        N
     17945  0021,104F  LocationsInAcquisition             N
     17946  0021,1050  GraphicallyPrescribed              N
     17947  0021,1051  RotationFromSourceXRot             N
     17948  0021,1052  RotationFromSourceYRot             N
     17949  0021,1053  RotationFromSourceZRot             N
     17950  0021,1054  ImagePosition                      N
     17951  0021,1055  ImageOrientation                   N
     17952  0021,1056  IntegerSlop                        N
     17953  0021,1057  IntegerSlop                        N
     17954  0021,1058  IntegerSlop                        N
     17955  0021,1059  IntegerSlop                        N
     17956  0021,105A  IntegerSlop                        N
     17957  0021,105B  FloatSlop                          N
     17958  0021,105C  FloatSlop                          N
     17959  0021,105D  FloatSlop                          N
     17960  0021,105E  FloatSlop                          N
     17961  0021,105F  FloatSlop                          N
     17962  0021,1081  AutoWindowLevelAlpha               N
     17963  0021,1082  AutoWindowLevelBeta                N
     17964  0021,1083  AutoWindowLevelWindow              N
     17965  0021,1084  ToWindowLevelLevel                 N
     17966  0021,1090  TubeFocalSpotPosition              N
     17967  0021,1091  BiopsyPosition                     N
     17968  0021,1092  BiopsyTLocation                    N
     17969  0021,1093  BiopsyRefLocation                  N
    912017970  0022,0001  LightPathFilterPassThroughWavelen  N
    912117971  0022,0002  LightPathFilterPassBand            N
     
    914917999  0022,0021  LeftImageSequence                  N
    915018000  0022,0022  RightImageSequence                 N
     18001  0022,0030  AxialLengthOfTheEye                N
     18002  0022,0031  OphthalmicFrameLocationSequence    N
     18003  0022,0032  ReferenceCoordinates               N
     18004  0022,0035  DepthSpatialResolution             N
     18005  0022,0036  MaximumDepthDistortion             N
     18006  0022,0037  AlongScanSpatialResolution         N
     18007  0022,0038  MaximumAlongScanDistortion         N
     18008  0022,0039  OphthalmicImageOrientation         N
     18009  0022,0041  DepthOfTransverseImage             N
     18010  0022,0042  MydriaticAgentConcUnitsSeq         N
     18011  0022,0048  AcrossScanSpatialResolution        N
     18012  0022,0049  MaximumAcrossScanDistortion        N
     18013  0022,004E  MydriaticAgentConcentration        N
     18014  0022,0055  IlluminationWaveLength             N
     18015  0022,0056  IlluminationPower                  N
     18016  0022,0057  IlluminationBandwidth              N
     18017  0022,0058  MydriaticAgentSequence             N
     18018  0023,1001  NumberOfSeriesInStudy              N
     18019  0023,1002  NumberOfUnarchivedSeries           N
     18020  0023,1010  ReferenceImageField                N
     18021  0023,1050  SummaryImage                       N
     18022  0023,1070  StartTimeSecsInFirstAxial          N
     18023  0023,1074  NoofUpdatesToHeader                N
     18024  0023,107D  IndicatesIfTheStudyHasCompleteInfo N
     18025  0025,1006  LastPulseSequenceUsed              N
     18026  0025,1007  ImagesInSeries                     N
     18027  0025,1010  LandmarkCounter                    N
     18028  0025,1011  NumberOfAcquisitions               N
     18029  0025,1014  IndicatesNoofUpdatesToHeader       N
     18030  0025,1017  SeriesCompleteFlag                 N
     18031  0025,1018  NumberOfImagesArchived             N
     18032  0025,1019  LastImageNumberUsed                N
     18033  0025,101A  PrimaryReceiverSuiteAndHost        N
     18034  0027,1006  ImageArchiveFlag                   N
     18035  0027,1010  ScoutType                          N
     18036  0027,101C  VmaMamp                            N
     18037  0027,101D  VmaPhase                           N
     18038  0027,101E  VmaMod                             N
     18039  0027,101F  VmaClip                            N
     18040  0027,1020  SmartScanOnOffFlag                 N
     18041  0027,1030  ForeignImageRevision               N
     18042  0027,1031  ImagingMode                        N
     18043  0027,1032  PulseSequence                      N
     18044  0027,1033  ImagingOptions                     N
     18045  0027,1035  PlaneType                          N
     18046  0027,1036  ObliquePlane                       N
     18047  0027,1040  RASLetterOfImageLocation           N
     18048  0027,1041  ImageLocation                      N
     18049  0027,1042  CenterRCoordOfPlaneImage           N
     18050  0027,1043  CenterACoordOfPlaneImage           N
     18051  0027,1044  CenterSCoordOfPlaneImage           N
     18052  0027,1045  NormalRCoord                       N
     18053  0027,1046  NormalACoord                       N
     18054  0027,1047  NormalSCoord                       N
     18055  0027,1048  RCoordOfTopRightCorner             N
     18056  0027,1049  ACoordOfTopRightCorner             N
     18057  0027,104A  SCoordOfTopRightCorner             N
     18058  0027,104B  RCoordOfBottomRightCorner          N
     18059  0027,104C  ACoordOfBottomRightCorner          N
     18060  0027,104D  SCoordOfBottomRightCorner          N
     18061  0027,1050  TableStartLocation                 N
     18062  0027,1051  TableEndLocation                   N
     18063  0027,1052  RASLetterForSideOfImage            N
     18064  0027,1053  RASLetterForAnteriorPosterior      N
     18065  0027,1054  RASLetterForScoutStartLoc          N
     18066  0027,1055  RASLetterForScoutEndLoc            N
     18067  0027,1060  ImageDimensionX                    N
     18068  0027,1061  ImageDimensionY                    N
     18069  0027,1062  NumberOfExcitations                N
    915118070  0028,0000  ImagePresentationGroupLength       N
    915218071  0028,0002  SamplesPerPixel                    N
     
    916918088  0028,0050  ManipulatedImage                   N
    917018089  0028,0051  CorrectedImage                     N
     18090  0028,005F  CompressionRecognitionCode         N
    917118091  0028,0060  CompressionCode                    N
     18092  0028,0061  CompressionOriginator              N
     18093  0028,0062  CompressionLabel                   N
     18094  0028,0063  CompressionDescription             N
     18095  0028,0065  CompressionSequence                N
     18096  0028,0066  CompressionStepPointers            N
     18097  0028,0068  RepeatInterval                     N
     18098  0028,0069  BitsGrouped                        N
     18099  0028,0070  PerimeterTable                     N
     18100  0028,0071  PerimeterValue                     N
     18101  0028,0080  PredictorRows                      N
     18102  0028,0081  PredictorColumns                   N
     18103  0028,0082  PredictorConstants                 N
     18104  0028,0090  BlockedPixels                      N
     18105  0028,0091  BlockRows                          N
     18106  0028,0092  BlockColumns                       N
     18107  0028,0093  RowOverlap                         N
     18108  0028,0094  ColumnOverlap                      N
    917218109  0028,0100  BitsAllocated                      N
    917318110  0028,0101  BitsStored                         N
     
    918318120  0028,0111  LargestImagePixelValueInPlane      N
    918418121  0028,0120  PixelPaddingValue                  N
     18122  0028,0121  PixelPaddingRangeLimit             N
    918518123  0028,0200  ImageLocation                      N
    918618124  0028,0300  QualityControlImage                N
    918718125  0028,0301  BurnedInAnnotation                 N
     18126  0028,0400  TransformLabel                     N
     18127  0028,0401  TransformVersionNumber             N
     18128  0028,0402  NumberOfTransformSteps             N
     18129  0028,0403  SequenceOfCompressedData           N
     18130  0028,0404  DetailsOfCoefficients              N
     18131  0028,04x2  CoefficientCoding                  N
     18132  0028,04x3  CoefficientCodingPointers          N
     18133  0028,0700  DCTLabel                           N
     18134  0028,0701  DataBlockDescription               N
     18135  0028,0702  DataBlock                          N
     18136  0028,0710  NormalizationFactorFormat          N
     18137  0028,0720  ZonalMapNumberFormat               N
     18138  0028,0721  ZonalMapLocation                   N
     18139  0028,0722  ZonalMapFormat                     N
     18140  0028,0730  AdaptiveMapFormat                  N
     18141  0028,0740  CodeNumberFormat                   N
     18142  0028,08x0  CodeLabel                          N
     18143  0028,08x2  NumberOfTables                     N
     18144  0028,08x3  CodeTableLocation                  N
     18145  0028,08x4  BitsForCodeWord                    N
     18146  0028,08x8  ImageDataLocation                  N
     18147  0028,0A02  PixelSpacingCalibrationType        N
     18148  0028,0A04  PixelSpacingCalibrationDescription N
    918818149  0028,1040  PixelIntensityRelationship         N
    918918150  0028,1041  PixelIntensityRelationshipSign     N
     
    919418155  0028,1054  RescaleType                        N
    919518156  0028,1055  WindowCenterAndWidthExplanation    N
     18157  0028,1056  VOI_LUTFunction                    N
    919618158  0028,1080  GrayScale                          N
    919718159  0028,1090  RecommendedViewingMode             N
     
    920018162  0028,1102  GreenPaletteColorTableDescriptor   N
    920118163  0028,1103  BluePaletteColorTableDescriptor    N
     18164  0028,1111  LargeRedPaletteColorTableDescr     N
     18165  0028,1112  LargeGreenPaletteColorTableDescr   N
     18166  0028,1113  LargeBluePaletteColorTableDescr    N
    920218167  0028,1199  PaletteColorTableUID               N
    920318168  0028,1200  GrayLookupTableData                N
     
    920518170  0028,1202  GreenPaletteColorTableData         N
    920618171  0028,1203  BluePaletteColorTableData          N
     18172  0028,1211  LargeRedPaletteColorTableData      N
     18173  0028,1212  LargeGreenPaletteColorTableData    N
     18174  0028,1213  LargeBluePaletteColorTableData     N
     18175  0028,1214  LargePaletteColorLookupTableUID    N
    920718176  0028,1221  SegmentedRedColorTableData         N
    920818177  0028,1222  SegmentedGreenColorTableData       N
    920918178  0028,1223  SegmentedBlueColorTableData        N
    9210   0028,1300  ImplantPresent                     N
     18179  0028,1300  BreastImplantPresent               N
    921118180  0028,1350  PartialView                        N
    921218181  0028,1351  PartialViewDescription             N
     18182  0028,1352  PartialViewCodeSequence            N
     18183  0028,135A  SpatialLocationsPreserved          N
     18184  0028,1402  DataPathAssignment                 N
     18185  0028,1404  BlendingLUT1Sequence               N
     18186  0028,1406  BlendingWeightConstant             N
     18187  0028,1408  BlendingLookupTableData            N
     18188  0028,140C  BlendingLUT2Sequence               N
     18189  0028,140E  DataPathID                         N
     18190  0028,140F  RGBLUTTransferFunction             N
     18191  0028,1410  AlphaLUTTransferFunction           N
     18192  0028,2000  ICCProfile                         N
    921318193  0028,2110  LossyImageCompression              N
    921418194  0028,2112  LossyImageCompressionRatio         N
     
    922418204  0028,5000  BiPlaneAcquisitionSequence         N
    922518205  0028,6010  RepresentativeFrameNumber          N
    9226   0028,6020  FrameNumbersOfInterestFOI          N
     18206  0028,6020  FrameNumbersOfInterest             N
    922718207  0028,6022  FrameOfInterestDescription         N
    922818208  0028,6023  FrameOfInterestType                N
     
    923718217  0028,6120  TIDOffset                          N
    923818218  0028,6190  MaskOperationExplanation           N
     18219  0028,7FE0  PixelDataProviderURL               N
    923918220  0028,9001  DataPointRows                      N
    924018221  0028,9002  DataPointColumns                   N
     
    924618227  0028,9145  PixelValueTransformationSequence   N
    924718228  0028,9235  SignalDomainRows                   N
     18229  0028,9411  DisplayFilterPercentage            N
     18230  0028,9415  FramePixelShiftSequence            N
     18231  0028,9416  SubtractionItemID                  N
     18232  0028,9422  PixelIntensityRelationshipLUTSeq   N
     18233  0028,9443  FramePixelDataPropertiesSequence   N
     18234  0028,9444  GeometricalProperties              N
     18235  0028,9445  GeometricMaximumDistortion         N
     18236  0028,9446  ImageProcessingApplied             N
     18237  0028,9454  MaskSelectionMode                  N
     18238  0028,9474  LUTFunction                        N
     18239  0028,9478  MaskVisibilityPercentage           N
     18240  0028,9501  PixelShiftSequence                 N
     18241  0028,9502  RegionPixelShiftSequence           N
     18242  0028,9503  VerticesOfTheRegion                N
     18243  0028,9506  PixelShiftFrameRange               N
     18244  0028,9507  LUTFrameRange                      N
     18245  0028,9520  ImageToEquipmentMappingMatrix      N
     18246  0028,9537  EquipmentCoordinateSystemID        N
     18247  0029,1004  LowerRangeOfPixels1a               N
     18248  0029,1005  LowerRangeOfPixels1b               N
     18249  0029,1006  LowerRangeOfPixels1c               N
     18250  0029,1007  LowerRangeOfPixels1d               N
     18251  0029,1008  LowerRangeOfPixels1e               N
     18252  0029,1009  LowerRangeOfPixels1f               N
     18253  0029,100A  LowerRangeOfPixels1g               N
     18254  0029,1015  LowerRangeOfPixels1h               N
     18255  0029,1016  LowerRangeOfPixels1i               N
     18256  0029,1017  LowerRangeOfPixels2                N
     18257  0029,1018  UpperRangeOfPixels2                N
     18258  0029,101A  LenOfTotHdrInBytes                 N
     18259  0029,1026  VersionOfTheHdrStruct              N
     18260  0029,1034  AdvantageCompOverflow              N
     18261  0029,1035  AdvantageCompUnderflow             N
    924818262  0032,0000  StudyGroupLength                   N
    924918263  0032,000A  StudyStatusID                      N
     
    929018304  0038,0044  DischargeDiagnosisCodeSequence     N
    929118305  0038,0050  SpecialNeeds                       N
     18306  0038,0060  ServiceEpisodeID                   N
     18307  0038,0061  IssuerOfServiceEpisodeID           N
     18308  0038,0062  ServiceEpisodeDescription          N
     18309  0038,0100  PertinentDocumentsSequence         N
    929218310  0038,0300  CurrentPatientLocation             N
    9293   0038,0400  PatientsInstitutionResidence       N
     18311  0038,0400  PatientInstitutionResidence        N
    929418312  0038,0500  PatientState                       N
     18313  0038,0502  PatientClinicalTrialParticipSeq    N
    929518314  0038,4000  VisitComments                      N
    929618315  003A,0004  WaveformOriginality                N
     
    931918338  003A,0222  NotchFilterFrequency               N
    932018339  003A,0223  NotchFilterBandwidth               N
     18340  003A,0230  WaveformDataDisplayScale           N
     18341  003A,0231  WaveformDisplayBkgCIELabValue      N
     18342  003A,0240  WaveformPresentationGroupSequence  N
     18343  003A,0241  PresentationGroupNumber            N
     18344  003A,0242  ChannelDisplaySequence             N
     18345  003A,0244  ChannelRecommendDisplayCIELabValue N
     18346  003A,0245  ChannelPosition                    N
     18347  003A,0246  DisplayShadingFlag                 N
     18348  003A,0247  FractionalChannelDisplayScale      N
     18349  003A,0248  AbsoluteChannelDisplayScale        N
    932118350  003A,0300  MultiplexAudioChannelsDescrCodeSeq N
    932218351  003A,0301  ChannelIdentificationCode          N
     
    933718366  0040,0012  PreMedication                      N
    933818367  0040,0020  ScheduledProcedureStepStatus       N
     18368  0040,0031  LocalNamespaceEntityID             N
     18369  0040,0032  UniversalEntityID                  N
     18370  0040,0033  UniversalEntityIDType              N
     18371  0040,0035  IdentifierTypeCode                 N
     18372  0040,0036  AssigningFacilitySequence          N
    933918373  0040,0100  ScheduledProcedureStepSequence     N
    934018374  0040,0220  ReferencedNonImageCompositeSOPSeq  N
     
    935118385  0040,0255  PerformedProcedureTypeDescription  N
    935218386  0040,0260  PerformedProtocolCodeSequence      N
     18387  0040,0261  PerformedProtocolType              N
    935318388  0040,0270  ScheduledStepAttributesSequence    N
    935418389  0040,0275  RequestAttributesSequence          N
     
    938018415  0040,0441  ContentItemModifierSequence        N
    938118416  0040,050A  SpecimenAccessionNumber            N
     18417  0040,0512  ContainerIdentifier                N
     18418  0040,051A  ContainerDescription               N
    938218419  0040,0550  SpecimenSequence                   N
    938318420  0040,0551  SpecimenIdentifier                 N
     18421  0040,0552  SpecimenDescriptionSequenceTrial   N
     18422  0040,0553  SpecimenDescriptionTrial           N
     18423  0040,0554  SpecimenUID                        N
    938418424  0040,0555  AcquisitionContextSequence         N
    938518425  0040,0556  AcquisitionContextDescription      N
    938618426  0040,059A  SpecimenTypeCodeSequence           N
     18427  0040,0600  SpecimenShortDescription           N
    938718428  0040,06FA  SlideIdentifier                    N
    938818429  0040,071A  ImageCenterPointCoordinatesSeq     N
     
    939318434  0040,08DA  CoordinateSystemAxisCodeSequence   N
    939418435  0040,08EA  MeasurementUnitsCodeSequence       N
     18436  0040,09F8  VitalStainCodeSequenceTrial        N
    939518437  0040,1001  RequestedProcedureID               N
    939618438  0040,1002  ReasonForRequestedProcedure        N
     
    940618448  0040,1011  IntendedRecipientsOfResultsIDSeq   N
    940718449  0040,1101  PersonIdentificationCodeSequence   N
    9408   0040,1102  PersonsAddress                     N
    9409   0040,1103  PersonsTelephoneNumbers            N
     18450  0040,1102  PersonAddress                      N
     18451  0040,1103  PersonTelephoneNumbers             N
    941018452  0040,1400  RequestedProcedureComments         N
    941118453  0040,2001  ReasonForImagingServiceRequest     N
     
    941518457  0040,2007  FillerOrderNum-ImagingServiceReq   N
    941618458  0040,2008  OrderEnteredBy                     N
    9417   0040,2009  OrderEnterersLocation              N
     18459  0040,2009  OrderEntererLocation               N
    941818460  0040,2010  OrderCallbackPhoneNumber           N
    941918461  0040,2016  PlacerOrderNum-ImagingServiceReq   N
     
    945118493  0040,4035  ActualHumanPerformersSequence      N
    945218494  0040,4036  HumanPerformersOrganization        N
    9453   0040,4037  HumanPerformersName                N
     18495  0040,4037  HumanPerformerName                 N
     18496  0040,4040  RawDataHandling                    N
    945418497  0040,8302  EntranceDoseInMilliGy              N
     18498  0040,9094  RefImageRealWorldValueMappingSeq   N
    945518499  0040,9096  RealWorldValueMappingSequence      N
     18500  0040,9098  PixelValueMappingCodeSequence      N
    945618501  0040,9210  LUTLabel                           N
    945718502  0040,9211  RealWorldValueLastValueMapped      N
     
    946918514  0040,A073  VerifyingObserverSequence          N
    947018515  0040,A075  VerifyingObserverName              N
     18516  0040,A078  AuthorObserverSequence             N
     18517  0040,A07A  ParticipantSequence                N
     18518  0040,A07C  CustodialOrganizationSequence      N
     18519  0040,A080  ParticipationType                  N
     18520  0040,A082  ParticipationDateTime              N
     18521  0040,A084  ObserverType                       N
    947118522  0040,A088  VerifyingObserverIdentCodeSequence N
     18523  0040,A090  EquivalentCDADocumentSequence      N
    947218524  0040,A0B0  ReferencedWaveformChannels         N
    947318525  0040,A120  DateTime                           N
     
    948018532  0040,A136  ReferencedFrameNumbers             N
    948118533  0040,A138  ReferencedTimeOffsets              N
    9482   0040,A13A  ReferencedDatetime                 N
     18534  0040,A13A  ReferencedDateTime                 N
    948318535  0040,A160  TextValue                          N
    948418536  0040,A168  ConceptCodeSequence                N
     
    948918541  0040,A301  NumericValueQualifierCodeSequence  N
    949018542  0040,A30A  NumericValue                       N
     18543  0040,A353  AddressTrial                       N
     18544  0040,A354  TelephoneNumberTrial               N
    949118545  0040,A360  PredecessorDocumentsSequence       N
    949218546  0040,A370  ReferencedRequestSequence          N
     
    949418548  0040,A375  CurrentRequestedProcEvidenceSeq    N
    949518549  0040,A385  PertinentOtherEvidenceSequence     N
     18550  0040,A390  HL7StructuredDocumentRefSeq        N
    949618551  0040,A491  CompletionFlag                     N
    949718552  0040,A492  CompletionFlagDescription          N
    949818553  0040,A493  VerificationFlag                   N
     18554  0040,A494  ArchiveRequested                   N
     18555  0040,A496  PreliminaryFlag                    N
    949918556  0040,A504  ContentTemplateSequence            N
    950018557  0040,A525  IdenticalDocumentsSequence         N
     
    950818565  0040,DB0D  TemplateExtensionCreatorUID        N
    950918566  0040,DB73  ReferencedContentItemIdentifier    N
     18567  0040,E001  HL7InstanceIdentifier              N
     18568  0040,E004  HL7DocumentEffectiveTime           N
     18569  0040,E006  HL7DocumentTypeCodeSequence        N
     18570  0040,E010  RetrieveURI                        N
     18571  0040,E011  RetrieveLocationUID                N
     18572  0042,0010  DocumentTitle                      N
     18573  0042,0011  EncapsulatedDocument               N
     18574  0042,0012  MIMETypeOfEncapsulatedDocument     N
     18575  0042,0013  SourceInstanceSequence             N
     18576  0042,0014  ListOfMIMETypes                    N
     18577  0043,1001  BitmapOfPrescanOptions             N
     18578  0043,1002  GradientOffsetInX                  N
     18579  0043,1003  GradientOffsetInY                  N
     18580  0043,1004  GradientOffsetInZ                  N
     18581  0043,1005  ImgIsOriginalOrUnoriginal          N
     18582  0043,1006  NumberOfEPIShots                   N
     18583  0043,1007  ViewsPerSegment                    N
     18584  0043,1008  RespiratoryRateBpm                 N
     18585  0043,1009  RespiratoryTriggerPoint            N
     18586  0043,100A  TypeOfReceiverUsed                 N
     18587  0043,100B  PeakRateOfChangeOfGradientField    N
     18588  0043,100C  LimitsInUnitsOfPercent             N
     18589  0043,100D  PSDEstimatedLimit                  N
     18590  0043,100E  PSDEstimatedLimitInTeslaPerSecond  N
     18591  0043,100F  Saravghead                         N
     18592  0043,1010  WindowValue                        N
     18593  0043,1011  TotalInputViews                    N
     18594  0043,1012  X-RayChain                         N
     18595  0043,1013  DeconKernelParameters              N
     18596  0043,1014  CalibrationParameters              N
     18597  0043,1015  TotalOutputViews                   N
     18598  0043,1016  NumberOfOverranges                 N
     18599  0043,1017  IBHImageScaleFactors               N
     18600  0043,1018  BBHCoefficients                    N
     18601  0043,1019  NumberOfBBHChainsToBlend           N
     18602  0043,101A  StartingChannelNumber              N
     18603  0043,101B  PpscanParameters                   N
     18604  0043,101C  GEImageIntegrity                   N
     18605  0043,101D  LevelValue                         N
     18606  0043,101E  DeltaStartTime                     N
     18607  0043,101F  MaxOverrangesInAView               N
     18608  0043,1020  AvgOverrangesAllViews              N
     18609  0043,1021  CorrectedAfterGlowTerms            N
     18610  0043,1025  ReferenceChannels                  N
     18611  0043,1026  NoViewsRefChansBlocked             N
     18612  0043,1027  ScanPitchRatio                     N
     18613  0043,1028  UniqueImageIden                    N
     18614  0043,1029  HistogramTables                    N
     18615  0043,102A  UserDefinedData                    N
     18616  0043,102B  PrivateScanOptions                 N
     18617  0043,102C  EffectiveEchoSpacing               N
     18618  0043,102D  StringSlopField1                   N
     18619  0043,102E  StringSlopField2                   N
     18620  0043,102F  RawDataType                        N
     18621  0043,1030  RawDataType                        N
     18622  0043,1031  RACordOfTargetReconCenter          N
     18623  0043,1032  RawDataType                        N
     18624  0043,1033  NegScanspacing                     N
     18625  0043,1034  OffsetFrequency                    N
     18626  0043,1035  UserUsageTag                       N
     18627  0043,1036  UserFillMapMSW                     N
     18628  0043,1037  UserFillMapLSW                     N
     18629  0043,1038  User25-48                          N
     18630  0043,1039  SlopInt6-9                         N
     18631  0043,1040  TriggerOnPosition                  N
     18632  0043,1041  DegreeOfRotation                   N
     18633  0043,1042  DASTriggerSource                   N
     18634  0043,1043  DASFpaGain                         N
     18635  0043,1044  DASOutputSource                    N
     18636  0043,1045  DASAdInput                         N
     18637  0043,1046  DASCalMode                         N
     18638  0043,1047  DASCalFrequency                    N
     18639  0043,1048  DASRegXm                           N
     18640  0043,1049  DASAutoZero                        N
     18641  0043,104A  StartingChannelOfView              N
     18642  0043,104B  DASXmPattern                       N
     18643  0043,104C  TGGCTriggerMode                    N
     18644  0043,104D  StartScanToXrayOnDelay             N
     18645  0043,104E  DurationOfXrayOn                   N
     18646  0043,1060  SlopInt10-17                       N
     18647  0043,1061  ScannerStudyEntityUID              N
     18648  0043,1062  ScannerStudyID                     N
     18649  0043,106f  ScannerTableEntry                  N
     18650  0044,0001  ProductPackageIdentifier           N
     18651  0044,0002  SubstanceAdministrationApproval    N
     18652  0044,0003  ApprovalStatusFurtherDescription   N
     18653  0044,0004  ApprovalStatusDateTime             N
     18654  0044,0007  ProductTypeCodeSequence            N
     18655  0044,0008  ProductName                        N
     18656  0044,0009  ProductDescription                 N
     18657  0044,000A  ProductLotIdentifier               N
     18658  0044,000B  ProductExpirationDateTime          N
     18659  0044,0010  SubstanceAdministrationDateTime    N
     18660  0044,0011  SubstanceAdministrationNotes       N
     18661  0044,0012  SubstanceAdministrationDeviceID    N
     18662  0044,0013  ProductParameterSequence           N
     18663  0044,0019  SubstanceAdminParameterSeq         N
     18664  0045,1001  NumberOfMacroRowsInDetector        N
     18665  0045,1002  MacroWidthAtISOCenter              N
     18666  0045,1003  DASType                            N
     18667  0045,1004  DASGain                            N
     18668  0045,1005  DASTemperature                     N
     18669  0045,1006  TableDirectionInOrOut              N
     18670  0045,1007  ZSmoothingFactor                   N
     18671  0045,1008  ViewWeightingMode                  N
     18672  0045,1009  SigmaRowNumberWhichRowsWereUsed    N
     18673  0045,100A  MinimumDasValueFoundInTheScanData  N
     18674  0045,100B  MaximumOffsetShiftValueUsed        N
     18675  0045,100C  NumberOfViewsShifted               N
     18676  0045,100D  ZTrackingFlag                      N
     18677  0045,100E  MeanZError                         N
     18678  0045,100F  ZTrackingMaximumError              N
     18679  0045,1010  StartingViewForRow2a               N
     18680  0045,1011  NumberOfViewsInRow2a               N
     18681  0045,1012  StartingViewForRow1a               N
     18682  0045,1013  SigmaMode                          N
     18683  0045,1014  NumberOfViewsInRow1a               N
     18684  0045,1015  StartingViewForRow2b               N
     18685  0045,1016  NumberOfViewsInRow2b               N
     18686  0045,1017  StartingViewForRow1b               N
     18687  0045,1018  NumberOfViewsInRow1b               N
     18688  0045,1019  AirFilterCalibrationDate           N
     18689  0045,101A  AirFilterCalibrationTime           N
     18690  0045,101B  PhantomCalibrationDate             N
     18691  0045,101C  PhantomCalibrationTime             N
     18692  0045,101D  ZSlopeCalibrationDate              N
     18693  0045,101E  ZSlopeCalibrationTime              N
     18694  0045,101F  CrosstalkCalibrationDate           N
     18695  0045,1020  CrosstalkCalibrationTime           N
     18696  0045,1021  IterboneOptionFlag                 N
     18697  0045,1022  PeristalticFlagOption              N
     18698  0046,0012  LensDescription                    N
     18699  0046,0014  RightLensSequence                  N
     18700  0046,0015  LeftLensSequence                   N
     18701  0046,0018  CylinderSequence                   N
     18702  0046,0028  PrismSequence                      N
     18703  0046,0030  HorizontalPrismPower               N
     18704  0046,0032  HorizontalPrismBase                N
     18705  0046,0034  VerticalPrismPower                 N
     18706  0046,0036  VerticalPrismBase                  N
     18707  0046,0038  LensSegmentType                    N
     18708  0046,0040  OpticalTransmittance               N
     18709  0046,0042  ChannelWidth                       N
     18710  0046,0044  PupilSize                          N
     18711  0046,0046  CornealSize                        N
     18712  0046,0060  DistancePupillaryDistance          N
     18713  0046,0062  NearPupillaryDistance              N
     18714  0046,0064  OtherPupillaryDistance             N
     18715  0046,0075  RadiusOfCurvature                  N
     18716  0046,0076  KeratometricPower                  N
     18717  0046,0077  KeratometricAxis                   N
     18718  0046,0092  BackgroundColor                    N
     18719  0046,0094  Optotype                           N
     18720  0046,0095  OptotypePresentation               N
     18721  0046,0100  AddNearSequence                    N
     18722  0046,0101  AddIntermediateSequence            N
     18723  0046,0102  AddOtherSequence                   N
     18724  0046,0104  AddPower                           N
     18725  0046,0106  ViewingDistance                    N
     18726  0046,0125  ViewingDistanceType                N
     18727  0046,0135  VisualAcuityModifiers              N
     18728  0046,0137  DecimalVisualAcuity                N
     18729  0046,0139  OptotypeDetailedDefinition         N
     18730  0046,0146  SpherePower                        N
     18731  0046,0147  CylinderPower                      N
    951018732  0050,0004  CalibrationImage                   N
    951118733  0050,0010  DeviceSequence                     N
    951218734  0050,0014  DeviceLength                       N
     18735  0050,0015  ContainerComponentWidth            N
    951318736  0050,0016  DeviceDiameter                     N
    951418737  0050,0017  DeviceDiameterUnits                N
    951518738  0050,0018  DeviceVolume                       N
    951618739  0050,0019  InterMarkerDistance                N
     18740  0050,001B  ContainerComponentID               N
    951718741  0050,0020  DeviceDescription                  N
    951818742  0054,0010  EnergyWindowVector                 N
     
    960218826  0060,3010  HistogramExplanation               N
    960318827  0060,3020  HistogramData                      N
     18828  0062,0001  SegmentationType                   N
     18829  0062,0002  SegmentSequence                    N
     18830  0062,0003  SegmentedPropertyCategoryCodeSeq   N
     18831  0062,0004  SegmentNumber                      N
     18832  0062,0005  SegmentLabel                       N
     18833  0062,0006  SegmentDescription                 N
     18834  0062,0008  SegmentAlgorithmType               N
     18835  0062,0009  SegmentAlgorithmName               N
     18836  0062,000A  SegmentIdentificationSequence      N
     18837  0062,000B  ReferencedSegmentNumber            N
     18838  0062,000C  RecommendedDisplayGrayscaleValue   N
     18839  0062,000D  RecommendedDisplayCIELabValue      N
     18840  0062,000E  MaximumFractionalValue             N
     18841  0062,000F  SegmentedPropertyTypeCodeSequence  N
     18842  0062,0010  SegmentationFractionalType         N
     18843  0064,0002  DeformableRegistrationSequence     N
     18844  0064,0003  SourceFrameOfReferenceUID          N
     18845  0064,0005  DeformableRegistrationGridSequence N
     18846  0064,0007  GridDimensions                     N
     18847  0064,0008  GridResolution                     N
     18848  0064,0009  VectorGridData                     N
     18849  0064,000F  PreDeformationMatrixRegistSeq      N
     18850  0064,0010  PostDeformationMatrixRegistSeq     N
     18851  0066,0001  NumberOfSurfaces                   N
     18852  0066,0002  SurfaceSequence                    N
     18853  0066,0003  SurfaceNumber                      N
     18854  0066,0004  SurfaceComments                    N
     18855  0066,0009  SurfaceProcessing                  N
     18856  0066,000A  SurfaceProcessingRatio             N
     18857  0066,000E  FiniteVolume                       N
     18858  0066,0010  Manifold                           N
     18859  0066,0011  SurfacePointsSequence              N
     18860  0066,0015  NumberOfSurfacePoints              N
     18861  0066,0016  PointCoordinatesData               N
     18862  0066,0017  PointPositionAccuracy              N
     18863  0066,0018  MeanPointDistance                  N
     18864  0066,0019  MaximumPointDistance               N
     18865  0066,001B  AxisOfRotation                     N
     18866  0066,001C  CenterOfRotation                   N
     18867  0066,001E  NumberOfVectors                    N
     18868  0066,001F  VectorDimensionality               N
     18869  0066,0020  VectorAccuracy                     N
     18870  0066,0021  VectorCoordinateData               N
     18871  0066,0023  TrianglePointIndexList             N
     18872  0066,0024  EdgePointIndexList                 N
     18873  0066,0025  VertexPointIndexList               N
     18874  0066,0026  TriangleStripSequence              N
     18875  0066,0027  TriangleFanSequence                N
     18876  0066,0028  LineSequence                       N
     18877  0066,0029  PrimitivePointIndexList            N
     18878  0066,002A  SurfaceCount                       N
     18879  0066,002F  AlgorithmFamilyCodeSequ            N
     18880  0066,0031  AlgorithmVersion                   N
     18881  0066,0032  AlgorithmParameters                N
     18882  0066,0034  FacetSequence                      N
     18883  0066,0036  AlgorithmName                      N
    960418884  0070,0001  GraphicAnnotationSequence          N
    960518885  0070,0002  GraphicLayer                       N
     
    962018900  0070,0023  GraphicType                        N
    962118901  0070,0024  GraphicFilled                      N
     18902  0070,0040  ImageRotationRetired               N
    962218903  0070,0041  ImageHorizontalFlip                N
    962318904  0070,0042  ImageRotation                      N
    9624   0070,0052  DisplayedAreaTopLeftHandCorner     N
    9625   0070,0053  DisplayedAreaBottomRightHandCorner N
     18905  0070,0050  DisplayedAreaTopLeftTrial          N
     18906  0070,0051  DisplayedAreaBottomRightTrial      N
     18907  0070,0052  DisplayedAreaTopLeft               N
     18908  0070,0053  DisplayedAreaBottomRight           N
    962618909  0070,005A  DisplayedAreaSelectionSequence     N
    962718910  0070,0060  GraphicLayerSequence               N
     
    963418917  0070,0082  PresentationCreationDate           N
    963518918  0070,0083  PresentationCreationTime           N
    9636   0070,0084  ContentCreatorsName                N
     18919  0070,0084  ContentCreatorName                 N
     18920  0070,0086  ContentCreatorIDCodeSequence       N
    963718921  0070,0100  PresentationSizeMode               N
    963818922  0070,0101  PresentationPixelSpacing           N
     
    965418938  0070,031C  FiducialSetSequence                N
    965518939  0070,031E  FiducialSequence                   N
     18940  0070,0401  GraphicLayerRecomDisplayCIELabVal  N
     18941  0070,0402  BlendingSequence                   N
     18942  0070,0403  RelativeOpacity                    N
     18943  0070,0404  ReferencedSpatialRegistrationSeq   N
     18944  0070,0405  BlendingPosition                   N
     18945  0072,0002  HangingProtocolName                N
     18946  0072,0004  HangingProtocolDescription         N
     18947  0072,0006  HangingProtocolLevel               N
     18948  0072,0008  HangingProtocolCreator             N
     18949  0072,000A  HangingProtocolCreationDateTime    N
     18950  0072,000C  HangingProtocolDefinitionSequence  N
     18951  0072,000E  HangingProtocolUserIDCodeSequence  N
     18952  0072,0010  HangingProtocolUserGroupName       N
     18953  0072,0012  SourceHangingProtocolSequence      N
     18954  0072,0014  NumberOfPriorsReferenced           N
     18955  0072,0020  ImageSetsSequence                  N
     18956  0072,0022  ImageSetSelectorSequence           N
     18957  0072,0024  ImageSetSelectorUsageFlag          N
     18958  0072,0026  SelectorAttribute                  N
     18959  0072,0028  SelectorValueNumber                N
     18960  0072,0030  TimeBasedImageSetsSequence         N
     18961  0072,0032  ImageSetNumber                     N
     18962  0072,0034  ImageSetSelectorCategory           N
     18963  0072,0038  RelativeTime                       N
     18964  0072,003A  RelativeTimeUnits                  N
     18965  0072,003C  AbstractPriorValue                 N
     18966  0072,003E  AbstractPriorCodeSequence          N
     18967  0072,0040  ImageSetLabel                      N
     18968  0072,0050  SelectorAttributeVR                N
     18969  0072,0052  SelectorSequencePointer            N
     18970  0072,0054  SelectorSeqPointerPrivateCreator   N
     18971  0072,0056  SelectorAttributePrivateCreator    N
     18972  0072,0060  SelectorATValue                    N
     18973  0072,0062  SelectorCSValue                    N
     18974  0072,0064  SelectorISValue                    N
     18975  0072,0066  SelectorLOValue                    N
     18976  0072,0068  SelectorLTValue                    N
     18977  0072,006A  SelectorPNValue                    N
     18978  0072,006C  SelectorSHValue                    N
     18979  0072,006E  SelectorSTValue                    N
     18980  0072,0070  SelectorUTValue                    N
     18981  0072,0072  SelectorDSValue                    N
     18982  0072,0074  SelectorFDValue                    N
     18983  0072,0076  SelectorFLValue                    N
     18984  0072,0078  SelectorULValue                    N
     18985  0072,007A  SelectorUSValue                    N
     18986  0072,007C  SelectorSLValue                    N
     18987  0072,007E  SelectorSSValue                    N
     18988  0072,0080  SelectorCodeSequenceValue          N
     18989  0072,0100  NumberOfScreens                    N
     18990  0072,0102  NominalScreenDefinitionSequence    N
     18991  0072,0104  NumberOfVerticalPixels             N
     18992  0072,0106  NumberOfHorizontalPixels           N
     18993  0072,0108  DisplayEnvironmentSpatialPosition  N
     18994  0072,010A  ScreenMinimumGrayscaleBitDepth     N
     18995  0072,010C  ScreenMinimumColorBitDepth         N
     18996  0072,010E  ApplicationMaximumRepaintTime      N
     18997  0072,0200  DisplaySetsSequence                N
     18998  0072,0202  DisplaySetNumber                   N
     18999  0072,0203  DisplaySetLabel                    N
     19000  0072,0204  DisplaySetPresentationGroup        N
     19001  0072,0206  DisplaySetPresentationGroupDescr   N
     19002  0072,0208  PartialDataDisplayHandling         N
     19003  0072,0210  SynchronizedScrollingSequence      N
     19004  0072,0212  DisplaySetScrollingGroup           N
     19005  0072,0214  NavigationIndicatorSequence        N
     19006  0072,0216  NavigationDisplaySet               N
     19007  0072,0218  ReferenceDisplaySets               N
     19008  0072,0300  ImageBoxesSequence                 N
     19009  0072,0302  ImageBoxNumber                     N
     19010  0072,0304  ImageBoxLayoutType                 N
     19011  0072,0306  ImageBoxTileHorizontalDimension    N
     19012  0072,0308  ImageBoxTileVerticalDimension      N
     19013  0072,0310  ImageBoxScrollDirection            N
     19014  0072,0312  ImageBoxSmallScrollType            N
     19015  0072,0314  ImageBoxSmallScrollAmount          N
     19016  0072,0316  ImageBoxLargeScrollType            N
     19017  0072,0318  ImageBoxLargeScrollAmount          N
     19018  0072,0320  ImageBoxOverlapPriority            N
     19019  0072,0330  CineRelativeToRealTime             N
     19020  0072,0400  FilterOperationsSequence           N
     19021  0072,0402  FilterByCategory                   N
     19022  0072,0404  FilterByAttributePresence          N
     19023  0072,0406  FilterByOperator                   N
     19024  0072,0432  SynchronizedImageBoxList           N
     19025  0072,0434  TypeOfSynchronization              N
     19026  0072,0500  BlendingOperationType              N
     19027  0072,0510  ReformattingOperationType          N
     19028  0072,0512  ReformattingThickness              N
     19029  0072,0514  ReformattingInterval               N
     19030  0072,0516  ReformattingOpInitialViewDir       N
     19031  0072,0520  3DRenderingType                    N
     19032  0072,0600  SortingOperationsSequence          N
     19033  0072,0602  SortByCategory                     N
     19034  0072,0604  SortingDirection                   N
     19035  0072,0700  DisplaySetPatientOrientation       N
     19036  0072,0702  VOIType                            N
     19037  0072,0704  PseudoColorType                    N
     19038  0072,0706  ShowGrayscaleInverted              N
     19039  0072,0710  ShowImageTrueSizeFlag              N
     19040  0072,0712  ShowGraphicAnnotationFlag          N
     19041  0072,0714  ShowPatientDemographicsFlag        N
     19042  0072,0716  ShowAcquisitionTechniquesFlag      N
     19043  0072,0717  DisplaySetHorizontalJustification  N
     19044  0072,0718  DisplaySetVerticalJustification    N
     19045  0074,1000  UnifiedProcedureStepState          N
     19046  0074,1002  UPSProgressInformationSequence     N
     19047  0074,1004  UnifiedProcedureStepProgress       N
     19048  0074,1006  UnifiedProcedureStepProgressDescr  N
     19049  0074,1008  UnifiedProcedureStepComURISeq      N
     19050  0074,100a  ContactURI                         N
     19051  0074,100c  ContactDisplayName                 N
     19052  0074,1020  BeamTaskSequence                   N
     19053  0074,1022  BeamTaskType                       N
     19054  0074,1024  BeamOrderIndex                     N
     19055  0074,1030  DeliveryVerificationImageSequence  N
     19056  0074,1032  VerificationImageTiming            N
     19057  0074,1034  DoubleExposureFlag                 N
     19058  0074,1036  DoubleExposureOrdering             N
     19059  0074,1038  DoubleExposureMeterset             N
     19060  0074,103A  DoubleExposureFieldDelta           N
     19061  0074,1040  RelatedReferenceRTImageSequence    N
     19062  0074,1042  GeneralMachineVerificationSequence N
     19063  0074,1044  ConventionalMachineVerificationSeq N
     19064  0074,1046  IonMachineVerificationSequence     N
     19065  0074,1048  FailedAttributesSequence           N
     19066  0074,104A  OverriddenAttributesSequence       N
     19067  0074,104C  ConventionalControlPointVerifySeq  N
     19068  0074,104E  IonControlPointVerificationSeq     N
     19069  0074,1050  AttributeOccurrenceSequence        N
     19070  0074,1052  AttributeOccurrencePointer         N
     19071  0074,1054  AttributeItemSelector              N
     19072  0074,1056  AttributeOccurrencePrivateCreator  N
     19073  0074,1200  ScheduledProcedureStepPriority     N
     19074  0074,1202  WorklistLabel                      N
     19075  0074,1204  ProcedureStepLabel                 N
     19076  0074,1210  ScheduledProcessingParametersSeq   N
     19077  0074,1212  PerformedProcessingParametersSeq   N
     19078  0074,1216  UPSPerformedProcedureSequence      N
     19079  0074,1220  RelatedProcedureStepSequence       N
     19080  0074,1222  ProcedureStepRelationshipType      N
     19081  0074,1230  DeletionLock                       N
     19082  0074,1234  ReceivingAE                        N
     19083  0074,1236  RequestingAE                       N
     19084  0074,1238  ReasonForCancellation              N
     19085  0074,1242  SCPStatus                          N
     19086  0074,1244  SubscriptionListStatus             N
     19087  0074,1246  UPSListStatus                      N
    965619088  0088,0130  StorageMediaFileSetID              N
    965719089  0088,0140  StorageMediaFileSetUID             N
     
    966019092  0088,0906  TopicSubject                       N
    966119093  0088,0910  TopicAuthor                        N
    9662   0088,0912  TopicKeyWords                      N
     19094  0088,0912  TopicKeywords                      N
    966319095  0100,0410  SOPInstanceStatus                  N
    966419096  0100,0420  SOPAuthorizationDateAndTime        N
     
    967619108  0400,0305  CertifiedTimestampType             N
    967719109  0400,0310  CertifiedTimestamp                 N
     19110  0400,0401  DigitalSignaturePurposeCodeSeq     N
     19111  0400,0402  ReferencedDigitalSignatureSeq      N
     19112  0400,0403  ReferencedSOPInstanceMACSeq        N
     19113  0400,0404  MAC                                N
    967819114  0400,0500  EncryptedAttributesSequence        N
    967919115  0400,0510  EncryptedContentTransferSyntaxUID  N
    968019116  0400,0520  EncryptedContent                   N
    968119117  0400,0550  ModifiedAttributesSequence         N
     19118  0400,0561  OriginalAttributesSequence         N
     19119  0400,0562  AttributeModificationDateTime      N
     19120  0400,0563  ModifyingSystem                    N
     19121  0400,0564  SourceOfPreviousValues             N
     19122  0400,0565  ReasonForTheAttributeModification  N
     19123  1000,xxx0  EscapeTriplet                      N
     19124  1000,xxx1  RunLengthTriplet                   N
     19125  1000,xxx2  HuffmanTableSize                   N
     19126  1000,xxx3  HuffmanTableTriplet                N
     19127  1000,xxx4  ShiftTableSize                     N
     19128  1000,xxx5  ShiftTableTriplet                  N
     19129  1010,xxxx  ZonalMap                           N
    968219130  2000,0010  NumberOfCopies                     N
    968319131  2000,001E  PrinterConfigurationSequence       N
     
    972719175  2010,0510  ReferencedImageBoxSequence         N
    972819176  2010,0520  ReferencedBasicAnnotationBoxSeq    N
    9729   2020,0010  ImagePosition                      N
     19177  2020,0010  ImageBoxPosition                   N
    973019178  2020,0020  Polarity                           N
    973119179  2020,0030  RequestedImageSize                 N
     
    973319181  2020,0050  RequestedResolutionID              N
    973419182  2020,00A0  RequestedImageSizeFlag             N
    9735   2020,00A2  Decimate-CropResult                N
     19183  2020,00A2  DecimateCropResult                 N
    973619184  2020,0110  BasicGrayscaleImageSequence        N
    973719185  2020,0111  BasicColorImageSequence            N
     
    976119209  2100,0050  CreationTime                       N
    976219210  2100,0070  Originator                         N
    9763   2100,0140  Destination                        N
     19211  2100,0140  DestinationAE                      N
    976419212  2100,0160  OwnerID                            N
    976519213  2100,0170  NumberOfFilms                      N
     
    981919267  3002,0041  FluenceDataSource                  N
    982019268  3002,0042  FluenceDataScale                   N
     19269  3002,0051  FluenceMode                        N
     19270  3002,0052  FluenceModeID                      N
    982119271  3004,0001  DVHType                            N
    982219272  3004,0002  DoseUnits                          N
     
    988319333  3006,00B2  ROIPhysicalProperty                N
    988419334  3006,00B4  ROIPhysicalPropertyValue           N
     19335  3006,00B6  ROIElementalCompositionSequence    N
     19336  3006,00B7  ROIElementalCompAtomicNumber       N
     19337  3006,00B8  ROIElementalCompAtomicMassFraction N
    988519338  3006,00C0  FrameOfReferenceRelationshipSeq    N
    988619339  3006,00C2  RelatedFrameOfReferenceUID         N
     
    989319346  3008,0016  MeasuredDoseValue                  N
    989419347  3008,0020  TreatmentSessionBeamSequence       N
     19348  3008,0021  TreatmentSessionIonBeamSequence    N
    989519349  3008,0022  CurrentFractionNumber              N
    989619350  3008,0024  TreatmentControlPointDate          N
     
    990719361  3008,003B  DeliveredTreatmentTime             N
    990819362  3008,0040  ControlPointDeliverySequence       N
     19363  3008,0041  IonControlPointDeliverySequence    N
    990919364  3008,0042  SpecifiedMeterset                  N
    991019365  3008,0044  DeliveredMeterset                  N
     19366  3008,0045  MetersetRateSet                    N
     19367  3008,0046  MetersetRateDelivered              N
     19368  3008,0047  ScanSpotMetersetsDelivered         N
    991119369  3008,0048  DoseRateDelivered                  N
    991219370  3008,0050  TreatmentSummaryCalcDoseRefSeq     N
     
    991619374  3008,005A  NumberOfFractionsDelivered         N
    991719375  3008,0060  OverrideSequence                   N
     19376  3008,0061  ParameterSequencePointer           N
    991819377  3008,0062  OverrideParameterPointer           N
     19378  3008,0063  ParameterItemIndex                 N
    991919379  3008,0064  MeasuredDoseReferenceNumber        N
     19380  3008,0065  ParameterPointer                   N
    992019381  3008,0066  OverrideReason                     N
     19382  3008,0068  CorrectedParameterSequence         N
     19383  3008,006A  CorrectionValue                    N
    992119384  3008,0070  CalculatedDoseReferenceSequence    N
    992219385  3008,0072  CalculatedDoseReferenceNumber      N
     
    993419397  3008,00D0  RecordedBlockSequence              N
    993519398  3008,00E0  TreatmentSummaryMeasuredDoseRefSeq N
     19399  3008,00F0  RecordedSnoutSequence              N
     19400  3008,00F2  RecordedRangeShifterSequence       N
     19401  3008,00F4  RecordedLateralSpreadingDeviceSeq  N
     19402  3008,00F6  RecordedRangeModulatorSequence     N
    993619403  3008,0100  RecordedSourceSequence             N
    993719404  3008,0105  SourceSerialNumber                 N
     
    997119438  300A,0007  RTPlanTime                         N
    997219439  300A,0009  TreatmentProtocols                 N
    9973   300A,000A  TreatmentIntent                    N
     19440  300A,000A  PlanIntent                         N
    997419441  300A,000B  TreatmentSites                     N
    997519442  300A,000C  RTPlanGeometry                     N
     
    1000219469  300A,0048  BeamLimitingDeviceToleranceSeq     N
    1000319470  300A,004A  BeamLimitingDevicePositionTol      N
     19471  300A,004B  SnoutPositionTolerance             N
    1000419472  300A,004C  PatientSupportAngleTolerance       N
    1000519473  300A,004E  TableTopEccentricAngleTolerance    N
     19474  300A,004F  TableTopPitchAngleTolerance        N
     19475  300A,0050  TableTopRollAngleTolerance         N
    1000619476  300A,0051  TableTopVerticalPositionTolerance  N
    1000719477  300A,0052  TableTopLongitudinalPositionTol    N
     
    1001919489  300A,0084  BeamDose                           N
    1002019490  300A,0086  BeamMeterset                       N
     19491  300A,0088  BeamDosePointDepth                 N
     19492  300A,0089  BeamDosePointEquivalentDepth       N
     19493  300A,008A  BeamDosePointSSD                   N
    1002119494  300A,00A0  NumberOfBrachyApplicationSetups    N
    1002219495  300A,00A2  BrachyAppSetupDoseSpecPoint        N
     
    1002919502  300A,00B8  RTBeamLimitingDeviceType           N
    1003019503  300A,00BA  SourceToBeamLimitingDeviceDistance N
    10031   300A,00BC  NumberOfLeaf-JawPairs              N
     19504  300A,00BB  IsocenterToBeamLimitingDeviceDist  N
     19505  300A,00BC  NumberOfLeafJawPairs               N
    1003219506  300A,00BE  LeafPositionBoundaries             N
    1003319507  300A,00C0  BeamNumber                         N
     
    1004819522  300A,00D5  WedgeAngle                         N
    1004919523  300A,00D6  WedgeFactor                        N
     19524  300A,00D7  TotalWedgeTrayWaterEquivThickness  N
    1005019525  300A,00D8  WedgeOrientation                   N
     19526  300A,00D9  IsocenterToWedgeTrayDistance       N
    1005119527  300A,00DA  SourceToWedgeTrayDistance          N
     19528  300A,00DB  WedgeThinEdgePosition              N
     19529  300A,00DC  BolusID                            N
     19530  300A,00DD  BolusDescription                   N
    1005219531  300A,00E0  NumberOfCompensators               N
    1005319532  300A,00E1  MaterialID                         N
     
    1006719546  300A,00F0  NumberOfBlocks                     N
    1006819547  300A,00F2  TotalBlockTrayFactor               N
     19548  300A,00F3  TotalBlockTrayWaterEquivThickness  N
    1006919549  300A,00F4  BlockSequence                      N
    1007019550  300A,00F5  BlockTrayID                        N
    1007119551  300A,00F6  SourceToBlockTrayDistance          N
     19552  300A,00F7  IsocenterToBlockTrayDistance       N
    1007219553  300A,00F8  BlockType                          N
    1007319554  300A,00F9  AccessoryCode                      N
     
    1009419575  300A,0118  WedgePosition                      N
    1009519576  300A,011A  BeamLimitingDevicePositionSequence N
    10096   300A,011C  Leaf-JawPositions                  N
     19577  300A,011C  LeafJawPositions                   N
    1009719578  300A,011E  GantryAngle                        N
    1009819579  300A,011F  GantryRotationDirection            N
     
    1011119592  300A,0130  SourceToSurfaceDistance            N
    1011219593  300A,0134  CumulativeMetersetWeight           N
     19594  300A,0140  TableTopPitchAngle                 N
     19595  300A,0142  TableTopPitchRotationDirection     N
     19596  300A,0144  TableTopRollAngle                  N
     19597  300A,0146  TableTopRollRotationDirection      N
     19598  300A,0148  HeadFixationAngle                  N
     19599  300A,014A  GantryPitchAngle                   N
     19600  300A,014C  GantryPitchRotationDirection       N
     19601  300A,014E  GantryPitchAngleTolerance          N
    1011319602  300A,0180  PatientSetupSequence               N
    1011419603  300A,0182  PatientSetupNumber                 N
     19604  300A,0183  PatientSetupLabel                  N
    1011519605  300A,0184  PatientAdditionalPosition          N
    1011619606  300A,0190  FixationDeviceSequence             N
     
    1011919609  300A,0196  FixationDeviceDescription          N
    1012019610  300A,0198  FixationDevicePosition             N
     19611  300A,0199  FixationDevicePitchAngle           N
     19612  300A,019A  FixationDeviceRollAngle            N
    1012119613  300A,01A0  ShieldingDeviceSequence            N
    1012219614  300A,01A2  ShieldingDeviceType                N
     
    1014819640  300A,0226  SourceIsotopeName                  N
    1014919641  300A,0228  SourceIsotopeHalfLife              N
     19642  300A,0229  SourceStrengthUnits                N
    1015019643  300A,022A  ReferenceAirKermaRate              N
    10151   300A,022C  AirKermaRateReferenceDate          N
    10152   300A,022E  AirKermaRateReferenceTime          N
     19644  300A,022B  SourceStrength                     N
     19645  300A,022C  SourceStrengthReferenceDate        N
     19646  300A,022E  SourceStrengthReferenceTime        N
    1015319647  300A,0230  ApplicationSetupSequence           N
    1015419648  300A,0232  ApplicationSetupType               N
     
    1019919693  300A,02E1  CompensatorMountingPosition        N
    1020019694  300A,02E2  SourceToCompensatorDistance        N
     19695  300A,02E3  TotalCompTrayWaterEquivThickness   N
     19696  300A,02E4  IsocenterToCompensatorTrayDistance N
     19697  300A,02E5  CompensatorColumnOffset            N
     19698  300A,02E6  IsocenterToCompensatorDistances    N
     19699  300A,02E7  CompensatorRelStoppingPowerRatio   N
     19700  300A,02E8  CompensatorMillingToolDiameter     N
     19701  300A,02EA  IonRangeCompensatorSequence        N
     19702  300A,02EB  CompensatorDescription             N
     19703  300A,0302  RadiationMassNumber                N
     19704  300A,0304  RadiationAtomicNumber              N
     19705  300A,0306  RadiationChargeState               N
     19706  300A,0308  ScanMode                           N
     19707  300A,030A  VirtualSourceAxisDistances         N
     19708  300A,030C  SnoutSequence                      N
     19709  300A,030D  SnoutPosition                      N
     19710  300A,030F  SnoutID                            N
     19711  300A,0312  NumberOfRangeShifters              N
     19712  300A,0314  RangeShifterSequence               N
     19713  300A,0316  RangeShifterNumber                 N
     19714  300A,0318  RangeShifterID                     N
     19715  300A,0320  RangeShifterType                   N
     19716  300A,0322  RangeShifterDescription            N
     19717  300A,0330  NumberOfLateralSpreadingDevices    N
     19718  300A,0332  LateralSpreadingDeviceSequence     N
     19719  300A,0334  LateralSpreadingDeviceNumber       N
     19720  300A,0336  LateralSpreadingDeviceID           N
     19721  300A,0338  LateralSpreadingDeviceType         N
     19722  300A,033A  LateralSpreadingDeviceDescription  N
     19723  300A,033C  LateralSpreadingDevWaterEquivThick N
     19724  300A,0340  NumberOfRangeModulators            N
     19725  300A,0342  RangeModulatorSequence             N
     19726  300A,0344  RangeModulatorNumber               N
     19727  300A,0346  RangeModulatorID                   N
     19728  300A,0348  RangeModulatorType                 N
     19729  300A,034A  RangeModulatorDescription          N
     19730  300A,034C  BeamCurrentModulationID            N
     19731  300A,0350  PatientSupportType                 N
     19732  300A,0352  PatientSupportID                   N
     19733  300A,0354  PatientSupportAccessoryCode        N
     19734  300A,0356  FixationLightAzimuthalAngle        N
     19735  300A,0358  FixationLightPolarAngle            N
     19736  300A,035A  MetersetRate                       N
     19737  300A,0360  RangeShifterSettingsSequence       N
     19738  300A,0362  RangeShifterSetting                N
     19739  300A,0364  IsocenterToRangeShifterDistance    N
     19740  300A,0366  RangeShifterWaterEquivThickness    N
     19741  300A,0370  LateralSpreadingDeviceSettingsSeq  N
     19742  300A,0372  LateralSpreadingDeviceSetting      N
     19743  300A,0374  IsocenterToLateralSpreadingDevDist N
     19744  300A,0380  RangeModulatorSettingsSequence     N
     19745  300A,0382  RangeModulatorGatingStartValue     N
     19746  300A,0384  RangeModulatorGatingStopValue      N
     19747  300A,038A  IsocenterToRangeModulatorDistance  N
     19748  300A,0390  ScanSpotTuneID                     N
     19749  300A,0392  NumberOfScanSpotPositions          N
     19750  300A,0394  ScanSpotPositionMap                N
     19751  300A,0396  ScanSpotMetersetWeights            N
     19752  300A,0398  ScanningSpotSize                   N
     19753  300A,039A  NumberOfPaintings                  N
     19754  300A,03A0  IonToleranceTableSequence          N
     19755  300A,03A2  IonBeamSequence                    N
     19756  300A,03A4  IonBeamLimitingDeviceSequence      N
     19757  300A,03A6  IonBlockSequence                   N
     19758  300A,03A8  IonControlPointSequence            N
     19759  300A,03AA  IonWedgeSequence                   N
     19760  300A,03AC  IonWedgePositionSequence           N
     19761  300A,0401  ReferencedSetupImageSequence       N
     19762  300A,0402  SetupImageComment                  N
     19763  300A,0410  MotionSynchronizationSequence      N
     19764  300A,0412  ControlPointOrientation            N
     19765  300A,0420  GeneralAccessorySequence           N
     19766  300A,0421  GeneralAccessoryID                 N
     19767  300A,0422  GeneralAccessoryDescription        N
     19768  300A,0423  GeneralAccessoryType               N
     19769  300A,0424  GeneralAccessoryNumber             N
    1020119770  300C,0002  ReferencedRTPlanSequence           N
    1020219771  300C,0004  ReferencedBeamSequence             N
     
    1022419793  300C,00E0  ReferencedBlockNumber              N
    1022519794  300C,00F0  ReferencedControlPointIndex        N
     19795  300C,00F2  ReferencedControlPointSequence     N
     19796  300C,00F4  ReferencedStartControlPointIndex   N
     19797  300C,00F6  ReferencedStopControlPointIndex    N
     19798  300C,0100  ReferencedRangeShifterNumber       N
     19799  300C,0102  ReferencedLateralSpreadingDevNum   N
     19800  300C,0104  ReferencedRangeModulatorNumber     N
    1022619801  300E,0002  ApprovalStatus                     N
    1022719802  300E,0004  ReviewDate                         N
     
    1030719882  60xx,0051  ImageFrameOrigin                   N
    1030819883  60xx,0052  OverlayPlaneOrigin                 N
    10309   60xx,0060  CompressionCode                    N
     19884  60xx,0060  OverlayCompressionCode             N
     19885  60xx,0061  OverlayCompressionOriginator       N
     19886  60xx,0062  OverlayCompressionLabel            N
     19887  60xx,0063  OverlayCompressionDescription      N
     19888  60xx,0066  OverlayCompressionStepPointers     N
     19889  60xx,0068  OverlayRepeatInterval              N
     19890  60xx,0069  OverlayBitsGrouped                 N
    1031019891  60xx,0100  OverlayBitsAllocated               N
    1031119892  60xx,0102  OverlayBitPosition                 N
    1031219893  60xx,0110  OverlayFormat                      N
    1031319894  60xx,0200  OverlayLocation                    N
     19895  60xx,0800  OverlayCodeLabel                   N
     19896  60xx,0802  OverlayNumberOfTables              N
     19897  60xx,0803  OverlayCodeTableLocation           N
     19898  60xx,0804  OverlayBitsForCodeWord             N
    1031419899  60xx,1001  OverlayActivationLayer             N
    1031519900  60xx,1100  OverlayDescriptorGray              N
     
    1032719912  60xx,3000  OverlayData                        N
    1032819913  60xx,4000  OverlayComments                    N
    10329   7FE0,0000  PixelDataGroupLength               N
    10330   7FE0,0010  PixelData                          N
     19914  7Fxx,0000  PixelDataGroupLength               N
     19915  7Fxx,0010  PixelData                          N
     19916  7Fxx,0011  VariableNextDataGroup              N
     19917  7Fxx,0020  VariableCoefficientsSDVN           N
     19918  7Fxx,0030  VariableCoefficientsSDHN           N
     19919  7Fxx,0040  VariableCoefficientsSDDN           N
    1033119920  FFFA,FFFA  DigitalSignaturesSequence          N
    1033219921  FFFC,FFFC  DataSetTrailingPadding             N
     
    1033819927
    1033919928Meta information extracted from the header of HTML and XHTML files.  This is
    10340 a mix of information found in the C<META> elements and the C<TITLE> element.
     19929a mix of information found in the C<META> elements, C<XML> element, and the
     19930C<TITLE> element.
    1034119931
    1034219932  Tag ID                      Tag Name          Writable
     
    1035919949  'mssmarttagspreventparsing' NoMSSmartTags     N
    1036019950  'ncc'                       NCC               HTML ncc
     19951  'o'                         Office            HTML Office
     19952  'originator'                Originator        N
    1036119953  'owner'                     Owner             N
    1036219954  'prod'                      Prod              HTML prod
     
    1042520017  Tag ID               Tag Name                 Writable
    1042620018  ------               --------                 --------
    10427   'charset'            Charset                  N
     20019  'charset'            CharacterSet             N
    1042820020  'depth'              Depth                    N
    1042920021  'files'              Files                    N
     
    1045220044  'totaltime'          Duration                 N
    1045320045
     20046=head3 HTML Office Tags
     20047
     20048Tags written by Microsoft Office applications.
     20049
     20050  Tag ID                 Tag Name               Writable
     20051  ------                 --------               --------
     20052  'Author'               Author                 N
     20053  'Category'             Category               N
     20054  'Characters'           Characters             N
     20055  'CharactersWithSpaces' CharactersWithSpaces   N
     20056  'Company'              Company                N
     20057  'Created'              CreateDate             N
     20058  'Description'          Description            N
     20059  'Keywords'             Keywords               N
     20060  'LastAuthor'           LastAuthor             N
     20061  'LastPrinted'          LastPrinted            N
     20062  'LastSaved'            ModifyDate             N
     20063  'Lines'                Lines                  N
     20064  'Manager'              Manager                N
     20065  'Pages'                Pages                  N
     20066  'Paragraphs'           Paragraphs             N
     20067  'Revision'             RevisionNumber         N
     20068  'Subject'              Subject                N
     20069  'Template'             Template               N
     20070  'TotalTime'            TotalEditTime          N
     20071  'Version'              RevisionNumber         N
     20072  'Words'                Words                  N
     20073
    1045420074=head3 HTML prod Tags
    1045520075
     
    1046520085  'objecttype'         ObjectType               N
    1046620086
     20087=head2 EXE Tags
     20088
     20089This module extracts information from various types of Windows, MacOS and
     20090Unix executable and library files.  The first table below lists information
     20091extracted from the header of Windows PE (Portable Executable) EXE files and
     20092DLL libraries.
     20093
     20094   Index   Tag Name                             Writable
     20095   -----   --------                             --------
     20096      0    MachineType                          N
     20097      2    TimeStamp                            N
     20098     10    PEType                               N
     20099     11    LinkerVersion                        N
     20100     12    CodeSize                             N
     20101     14    InitializedDataSize                  N
     20102     16    UninitializedDataSize                N
     20103     18    EntryPoint                           N
     20104     30    OSVersion                            N
     20105     32    ImageVersion                         N
     20106     34    SubsystemVersion                     N
     20107     44    Subsystem                            N
     20108
     20109=head3 EXE PEVersion Tags
     20110
     20111Information extracted from the VS_VERSION_INFO structure of Windows PE
     20112files.
     20113
     20114   Index   Tag Name                             Writable
     20115   -----   --------                             --------
     20116      2    FileVersionNumber                    N
     20117      4    ProductVersionNumber                 N
     20118      6    FileFlagsMask                        N
     20119      7    FileFlags                            N
     20120      8    FileOS                               N
     20121      9    ObjectFileType                       N
     20122     10    FileSubtype                          N
     20123
     20124=head3 EXE PEString Tags
     20125
     20126Resource strings found in Windows PE files.  The B<TagID>'s are not shown
     20127because they are the same as the B<Tag Name>.  ExifTool will extract any
     20128existing StringFileInfo tags even if not listed in this table.
     20129
     20130  Tag Name                                      Writable
     20131  --------                                      --------
     20132  BuildDate                                     N
     20133  BuildVersion                                  N
     20134  CharacterSet                                  N
     20135  Comments                                      N
     20136  CompanyName                                   N
     20137  Copyright                                     N
     20138  FileDescription                               N
     20139  FileVersion                                   N
     20140  InternalName                                  N
     20141  LanguageCode                                  N
     20142  LegalCopyright                                N
     20143  LegalTrademarks                               N
     20144  OriginalFilename                              N
     20145  PrivateBuild                                  N
     20146  ProductName                                   N
     20147  ProductVersion                                N
     20148  SpecialBuild                                  N
     20149
     20150=head3 EXE MachO Tags
     20151
     20152Information extracted from Mach-O (Mac OS X) executable files and DYLIB
     20153libraries.
     20154
     20155   Index   Tag Name                             Writable
     20156   -----   --------                             --------
     20157      0    CPUArchitecture                      N
     20158      1    CPUByteOrder                         N
     20159      2    CPUCount                             N
     20160      3    CPUType                              N+
     20161      4    CPUSubtype                           N+
     20162      5    ObjectFileType                       N
     20163
     20164=head3 EXE PEF Tags
     20165
     20166Information extracted from PEF (Classic MacOS) executable files and
     20167libraries.
     20168
     20169   Index   Tag Name                             Writable
     20170   -----   --------                             --------
     20171      2    CPUArchitecture                      N
     20172      3    PEFVersion                           N
     20173      4    TimeStamp                            N
     20174
     20175=head3 EXE ELF Tags
     20176
     20177Information extracted from ELF (Unix) executable files and SO libraries.
     20178
     20179   Index   Tag Name                             Writable
     20180   -----   --------                             --------
     20181      4    CPUArchitecture                      N
     20182      5    CPUByteOrder                         N
     20183     16    ObjectFileType                       N
     20184     18    CPUType                              N
     20185
     20186=head2 LNK Tags
     20187
     20188Information extracted from MS Shell Link (Windows shortcut) files.
     20189
     20190   Index       Tag Name                         Writable
     20191   -----       --------                         --------
     20192         20    Flags                            N
     20193         24    FileAttributes                   N
     20194         28    CreateDate                       N
     20195         36    AccessDate                       N
     20196         44    ModifyDate                       N
     20197         52    TargetFileSize                   N
     20198         56    IconIndex                        N
     20199         60    RunWindow                        N
     20200         64    HotKey                           N
     20201  0x00010000   ItemID                           LNK ItemID
     20202  0x00020000   LinkInfo                         LNK LinkInfo
     20203  0x00030004   Description                      N
     20204  0x00030008   RelativePath                     N
     20205  0x00030010   WorkingDirectory                 N
     20206  0x00030020   CommandLineArguments             N
     20207  0x00030040   IconFileName                     N
     20208  0xa0000000   UnknownData                      LNK UnknownData
     20209  0xa0000001   EnvVarData                       LNK UnknownData
     20210  0xa0000002   ConsoleData                      LNK ConsoleData
     20211  0xa0000003   TrackerData                      LNK TrackerData
     20212  0xa0000004   ConsoleFEData                    LNK ConsoleFEData
     20213  0xa0000005   SpecialFolderData                LNK UnknownData
     20214  0xa0000006   DarwinData                       LNK UnknownData
     20215  0xa0000007   IconEnvData                      LNK UnknownData
     20216  0xa0000008   ShimData                         LNK UnknownData
     20217  0xa0000009   PropertyStoreData                LNK UnknownData
     20218  0xa000000b   KnownFolderData                  LNK UnknownData
     20219  0xa000000c   VistaIDListData                  LNK UnknownData
     20220
     20221=head3 LNK ItemID Tags
     20222
     20223  Tag ID   Tag Name                             Writable
     20224  ------   --------                             --------
     20225  0x0032   Item0032                             LNK Item0032
     20226
     20227=head3 LNK Item0032 Tags
     20228
     20229   Index   Tag Name                             Writable
     20230   -----   --------                             --------
     20231     14    TargetFileDOSName                    N
     20232
     20233=head3 LNK LinkInfo Tags
     20234
     20235  Tag Name                                      Writable
     20236  --------                                      --------
     20237  CommonNetworkRelLink                          N
     20238  CommonPathSuffix                              N
     20239  DeviceName                                    N
     20240  DriveSerialNumber                             N
     20241  DriveType                                     N
     20242  LocalBasePath                                 N
     20243  NetName                                       N
     20244  NetProviderType                               N
     20245  VolumeID                                      N
     20246  VolumeLabel                                   N
     20247
     20248=head3 LNK UnknownData Tags
     20249
     20250   Index   Tag Name                             Writable
     20251   -----   --------                             --------
     20252  [no tags known]
     20253
     20254=head3 LNK ConsoleData Tags
     20255
     20256   Index   Tag Name                             Writable
     20257   -----   --------                             --------
     20258      8    FillAttributes                       N
     20259     10    PopupFillAttributes                  N
     20260     12    ScreenBufferSize                     N
     20261     16    WindowSize                           N
     20262     20    WindowOrigin                         N
     20263     32    FontSize                             N
     20264     36    FontFamily                           N
     20265     40    FontWeight                           N
     20266     44    FontName                             N
     20267    108    CursorSize                           N
     20268    112    FullScreen                           N
     20269    116    QuickEdit                            N
     20270    120    InsertMode                           N
     20271    124    WindowOriginAuto                     N
     20272    128    HistoryBufferSize                    N
     20273    132    NumHistoryBuffers                    N
     20274    136    RemoveHistoryDuplicates              N
     20275
     20276=head3 LNK TrackerData Tags
     20277
     20278   Index   Tag Name                             Writable
     20279   -----   --------                             --------
     20280     16    MachineID                            N
     20281
     20282=head3 LNK ConsoleFEData Tags
     20283
     20284   Index   Tag Name                             Writable
     20285   -----   --------                             --------
     20286      8    CodePage                             N
     20287
     20288=head2 Font Tags
     20289
     20290This table contains a collection of tags found in font files of various
     20291formats.  ExifTool current recognizes OTF, TTF, TTC, DFONT, PFA, PFB, PFM,
     20292AFM, ACFM and AMFM font files.
     20293
     20294  Tag ID       Tag Name                         Writable
     20295  ------       --------                         --------
     20296  'AFM'        AFM                              Font AFM
     20297  'PFM'        PFMHeader                        Font PFM
     20298  'PSInfo'     PSFontInfo                       Font PSInfo
     20299  'fontname'   FontName                         N
     20300  'name'       Name                             Font Name
     20301  'numfonts'   NumFonts                         N
     20302  'postfont'   PostScriptFontName               N
     20303
     20304=head3 Font AFM Tags
     20305
     20306Tags extracted from Adobe Font Metrics files (AFM, ACFM and AMFM).
     20307
     20308  Tag ID               Tag Name                 Writable
     20309  ------               --------                 --------
     20310  'Ascender'           Ascender                 N
     20311  'CapHeight'          CapHeight                N
     20312  'CharacterSet'       CharacterSet             N
     20313  'Characters'         Characters               N
     20314  'Creation Date'      CreateDate               N
     20315  'Descender'          Descender                N
     20316  'EncodingScheme'     EncodingScheme           N
     20317  'EscChar'            EscChar                  N
     20318  'FamilyName'         FontFamily               N
     20319  'FontName'           FontName                 N
     20320  'FullName'           FullName                 N
     20321  'IsBaseFont'         IsBaseFont               N
     20322  'IsFixedV'           IsFixedV                 N
     20323  'MappingScheme'      MappingScheme            N
     20324  'Notice'             Notice                   N
     20325  'Version'            Version                  N
     20326  'Weight'             Weight                   N
     20327  'XHeight'            XHeight                  N
     20328
     20329=head3 Font PFM Tags
     20330
     20331Tags extracted from the PFM file header.
     20332
     20333   Index   Tag Name                             Writable
     20334   -----   --------                             --------
     20335      0    PFMVersion                           N
     20336      6    Copyright                            N
     20337     66    FontType                             N
     20338     68    PointSize                            N
     20339     70    YResolution                          N
     20340     72    XResolution                          N
     20341     74    Ascent                               N
     20342     76    InternalLeading                      N
     20343     78    ExternalLeading                      N
     20344     80    Italic                               N
     20345     81    Underline                            N
     20346     82    Strikeout                            N
     20347     83    Weight                               N
     20348     85    CharacterSet                         N
     20349     86    PixWidth                             N
     20350     88    PixHeight                            N
     20351     90    PitchAndFamily                       N
     20352     91    AvgWidth                             N
     20353     93    MaxWidth                             N
     20354     95    FirstChar                            N
     20355     96    LastChar                             N
     20356     97    DefaultChar                          N
     20357     98    BreakChar                            N
     20358     99    WidthBytes                           N
     20359
     20360=head3 Font PSInfo Tags
     20361
     20362Tags extracted from PostScript font files (PFA and PFB).
     20363
     20364  Tag ID               Tag Name                 Writable
     20365  ------               --------                 --------
     20366  'Copyright'          Copyright                N
     20367  'FSType'             FSType                   N
     20368  'FamilyName'         FontFamily               N
     20369  'FontName'           FontName                 N
     20370  'FontType'           FontType                 N
     20371  'FullName'           FullName                 N
     20372  'ItalicAngle'        ItalicAngle              N
     20373  'Notice'             Notice                   N
     20374  'UnderlinePosition'  UnderlinePosition        N
     20375  'UnderlineThickness' UnderlineThickness       N
     20376  'Weight'             Weight                   N
     20377  'isFixedPitch'       IsFixedPitch             N
     20378  'version'            Version                  N
     20379
     20380=head3 Font Name Tags
     20381
     20382The following tags are extracted from the TrueType font "name" table found
     20383in OTF, TTF, TTC and DFONT files.  These tags support localized languages by
     20384adding a hyphen followed by a language code to the end of the tag name (ie.
     20385"Copyright-fr" or "Licence-en-US").  Tags with no language code use the
     20386default language of "en".
     20387
     20388  Tag ID   Tag Name                             Writable
     20389  ------   --------                             --------
     20390  0x0000   Copyright                            N
     20391  0x0001   FontFamily                           N
     20392  0x0002   FontSubfamily                        N
     20393  0x0003   FontSubfamilyID                      N
     20394  0x0004   FontName                             N
     20395  0x0005   NameTableVersion                     N
     20396  0x0006   PostScriptFontName                   N
     20397  0x0007   Trademark                            N
     20398  0x0008   Manufacturer                         N
     20399  0x0009   Designer                             N
     20400  0x000a   Description                          N
     20401  0x000b   VendorURL                            N
     20402  0x000c   DesignerURL                          N
     20403  0x000d   License                              N
     20404  0x000e   LicenseInfoURL                       N
     20405  0x0010   PreferredFamily                      N
     20406  0x0011   PreferredSubfamily                   N
     20407  0x0012   CompatibleFontName                   N
     20408  0x0013   SampleText                           N
     20409  0x0014   PostScriptFontName                   N
     20410  0x0015   WWSFamilyName                        N
     20411  0x0016   WWSSubfamilyName                     N
     20412
     20413=head2 RSRC Tags
     20414
     20415Tags extracted from Mac OS resource files and DFONT files.  These tags may
     20416also be extracted from the resource fork of any file in OS X, either by
     20417adding "/rsrc" to the filename to process the resource fork alone, or by
     20418using the ExtractEmbedded (-ee) option to process the resource fork as a
     20419sub-document of the main file.
     20420
     20421  Tag ID               Tag Name                 Writable
     20422  ------               --------                 --------
     20423  '8BIM'               PhotoshopInfo            Photoshop
     20424  'STR _0xbff3'        ApplicationMissingMsg    N
     20425  'STR _0xbff4'        CreatorApplication       N
     20426  'STR#_0x0080'        Keywords                 N
     20427  'TEXT_0x0080'        Description              N
     20428  'sfnt'               Font                     Font Name
     20429  'usro_0x0000'        OpenWithApplication      N
     20430  'vers_0x0001'        ApplicationVersion       N
     20431
     20432=head2 Rawzor Tags
     20433
     20434Rawzor files store compressed images of other formats. As well as the
     20435information listed below, exiftool uncompresses and extracts the meta
     20436information from the original image.
     20437
     20438  Tag Name                                      Writable
     20439  --------                                      --------
     20440  CompressionFactor                             N
     20441  OriginalFileSize                              N
     20442  OriginalFileType                              N
     20443  RawzorCreatorVersion                          N
     20444  RawzorRequiredVersion                         N
     20445
     20446=head2 ZIP Tags
     20447
     20448The following tags are extracted from ZIP archives.  ExifTool also extracts
     20449additional meta information from compressed documents inside some ZIP-based
     20450files such Office Open XML (DOCX, PPTX and XLSX), Open Document (ODP, ODS
     20451and ODT), iWork (KEY, PAGES, NUMBERS), and Capture One Enhanced Image
     20452Package (EIP).  The ExifTool family 3 groups may be used to organize the
     20453output by embedded document number (ie. the exiftool C<-g3> option).
     20454
     20455   Index   Tag Name                             Writable
     20456   -----   --------                             --------
     20457      2    ZipRequiredVersion                   N
     20458      3    ZipBitFlag                           N
     20459      4    ZipCompression                       N
     20460      5    ZipModifyDate                        N
     20461      7    ZipCRC                               N
     20462      9    ZipCompressedSize                    N
     20463     11    ZipUncompressedSize                  N
     20464     15    ZipFileName                          N
     20465
     20466=head3 ZIP GZIP Tags
     20467
     20468These tags are extracted from GZIP (GNU ZIP) archives, but currently only
     20469for the first file in the archive.
     20470
     20471   Index   Tag Name                             Writable
     20472   -----   --------                             --------
     20473      2    Compression                          N
     20474      3    Flags                                N
     20475      4    ModifyDate                           N
     20476      8    ExtraFlags                           N
     20477      9    OperatingSystem                      N
     20478     10    ArchivedFileName                     N
     20479     11    Comment                              N
     20480
     20481=head3 ZIP RAR Tags
     20482
     20483These tags are extracted from RAR archive files.
     20484
     20485   Index   Tag Name                             Writable
     20486   -----   --------                             --------
     20487      0    CompressedSize                       N
     20488      4    UncompressedSize                     N
     20489      8    OperatingSystem                      N
     20490     13    ModifyDate                           N
     20491     18    PackingMethod                        N
     20492     25    ArchivedFileName                     N
     20493
     20494=head2 RTF Tags
     20495
     20496This table lists standard tags of the RTF information group, but ExifTool
     20497will also extract any non-standard tags found in this group.  As well,
     20498ExifTool will extract any custom properties that are found.  See
     20499L<http://download.microsoft.com/download/2/f/5/2f599e18-07ee-4ec5-a1e7-f4e6a9423592/Word2007RTFSpec9.doc>
     20500for the specification.
     20501
     20502  Tag ID               Tag Name                 Writable
     20503  ------               --------                 --------
     20504  'author'             Author                   N
     20505  'buptim'             BackupTime               N
     20506  'category'           Category                 N
     20507  'comment'            Comment                  N
     20508  'company'            Company                  N
     20509  'copyright'          Copyright                N
     20510  'creatim'            CreateDate               N
     20511  'doccomm'            Comments                 N
     20512  'edmins'             TotalEditTime            N
     20513  'hlinkbase'          HyperlinkBase            N
     20514  'id'                 InternalIDNumber         N
     20515  'keywords'           Keywords                 N
     20516  'manager'            Manager                  N
     20517  'nofchars'           Characters               N
     20518  'nofcharsws'         CharactersWithSpaces     N
     20519  'nofpages'           Pages                    N
     20520  'nofwords'           Words                    N
     20521  'operator'           LastModifiedBy           N
     20522  'printim'            LastPrinted              N
     20523  'revtim'             ModifyDate               N
     20524  'subject'            Subject                  N
     20525  'title'              Title                    N
     20526  'vern'               InternalVersionNumber    N
     20527  'version'            RevisionNumber           N
     20528
     20529=head2 OOXML Tags
     20530
     20531The Office Open XML (OOXML) format was introduced with Microsoft Office 2007
     20532and is used by file types such as DOCX, PPTX and XLSX.  These are
     20533essentially ZIP archives containing XML files.  The table below lists some
     20534tags which have been observed in OOXML documents, but ExifTool will extract
     20535any tags found from XML files of the OOXML document properties ("docProps")
     20536directory.
     20537
     20538B<Tips:>
     20539
     205401) Structural ZIP tags may be ignored (if desired) with C<--ZIP:all> on the
     20541command line.
     20542
     205432) Tags may be grouped by their document number in the ZIP archive with the
     20544C<-g3> or C<-G3> option.
     20545
     20546  Tag Name                                      Writable
     20547  --------                                      --------
     20548  AppVersion                                    N
     20549  Application                                   N
     20550  Characters                                    N
     20551  CharactersWithSpaces                          N
     20552  CheckedBy                                     N
     20553  Client                                        N
     20554  Company                                       N
     20555  DateCompleted                                 N
     20556  Department                                    N
     20557  Destination                                   N
     20558  Disposition                                   N
     20559  Division                                      N
     20560  DocSecurity                                   N
     20561  DocumentNumber                                N
     20562  Editor                                        N
     20563  ForwardTo                                     N
     20564  Group                                         N
     20565  HeadingPairs                                  N
     20566  HiddenSlides                                  N
     20567  HyperlinkBase                                 N
     20568  HyperlinksChanged                             N
     20569  Language                                      N
     20570  Lines                                         N
     20571  LinksUpToDate                                 N
     20572  MMClips                                       N
     20573  Mailstop                                      N
     20574  Manager                                       N
     20575  Matter                                        N
     20576  Notes                                         N
     20577  Office                                        N
     20578  Owner                                         N
     20579  Pages                                         N
     20580  Paragraphs                                    N
     20581  PresentationFormat                            N
     20582  Project                                       N
     20583  Publisher                                     N
     20584  Purpose                                       N
     20585  ReceivedFrom                                  N
     20586  RecordedBy                                    N
     20587  RecordedDate                                  N
     20588  Reference                                     N
     20589  ScaleCrop                                     N
     20590  SharedDoc                                     N
     20591  Slides                                        N
     20592  Source                                        N
     20593  Status                                        N
     20594  TelephoneNumber                               N
     20595  Template                                      N
     20596  TitlesOfParts                                 N
     20597  TotalEditTime                                 N
     20598  Typist                                        N
     20599  Words                                         N
     20600  Category                                      N
     20601  CreateDate                                    N
     20602  Keywords                                      N
     20603  LastModifiedBy                                N
     20604  LastPrinted                                   N
     20605  ModifyDate                                    N
     20606  RevisionNumber                                N
     20607
     20608=head2 iWork Tags
     20609
     20610The Apple iWork '09 file format is a ZIP archive containing XML files
     20611similar to the Office Open XML (OOXML) format.  Metadata tags in iWork
     20612files are extracted even if they don't appear below.
     20613
     20614  Tag Name                                      Writable
     20615  --------                                      --------
     20616  Author                                        N
     20617  Comment                                       N
     20618  Copyright                                     N
     20619  Keywords                                      N
     20620  Projects                                      N+
     20621  Title                                         N
     20622
    1046720623=head2 Extra Tags
    1046820624
    10469 The extra tags represent information found in the image but not associated
    10470 with any other tag group.  The three writable "pseudo" tags (Filename,
    10471 Directory and FileModifyDate) may be written without the need to rewrite the
    10472 file since their values are not contained within the file data.
     20625The extra tags represent extra information extracted or generated by
     20626ExifTool that is not directly associated with another tag group.  The three
     20627writable "pseudo" tags (FileName, Directory and FileModifyDate) may be
     20628written without the need to rewrite the file since their values are not
     20629contained within the file data.  These "pseudo" tags belong to the family 1
     20630"System" group.
    1047320631
    1047420632  Tag Name                                      Writable
     
    1047620634  CanonVRD                                      Y!
    1047720635  Comment                                       Y
     20636  CurrentIPTCDigest                             N
    1047820637  Directory                                     Y!
    10479   EXIF                                          N
    10480   Encryption                                    N
     20638  EXIF                                          Y!
    1048120639  Error                                         N
    1048220640  ExifByteOrder                                 Y
    1048320641  ExifToolVersion                               N
    10484   FileModifyDate                                Y
     20642  ExifUnicodeByteOrder                          Y
     20643  FileModifyDate                                Y!
    1048520644  FileName                                      Y!
     20645  FilePermissions                               N
    1048620646  FileSize                                      N
    1048720647  FileType                                      N
     20648  Geosync                                       Y
     20649  Geotag                                        Y
     20650  Geotime                                       Y
    1048820651  ICC_Profile                                   Y!
     20652  ID3Size                                       N
    1048920653  ImageHeight                                   N
    1049020654  ImageWidth                                    N
     20655  JPEGDigest                                    N
    1049120656  MIMEType                                      N
    1049220657  MaxVal                                        N
     20658  Now                                           N
     20659  PreviewImage                                  Y
     20660  PreviewPNG                                    N
     20661  RAFVersion                                    N
     20662  ResourceForkSize                              N
    1049320663  Warning                                       N
    10494   XMP                                           Y
     20664  XMP                                           Y!
    1049520665  XResolution                                   N
    1049620666  YResolution                                   N
     
    1049820668=head2 Composite Tags
    1049920669
    10500 The values of the composite tags are derived from the values of other tags.
    10501 These are convenience tags which are calculated after all other information
    10502 is extracted.
     20670The values of the composite tags are B<Derived From> the values of other
     20671tags.  These are convenience tags which are calculated after all other
     20672information is extracted.
    1050320673
    1050420674  Tag Name             Derived From             Writable
     
    1050620676  Aperture             FNumber                  N
    1050720677                       ApertureValue
     20678  AudioBitrate         MPEG:MPEGAudioVersion    N
     20679                       MPEG:SampleRate
     20680                       MPEG:VBRBytes
     20681                       MPEG:VBRFrames
     20682  AutoFocus            Nikon:PhaseDetectAF      N
     20683                       Nikon:ContrastDetectAF
     20684  AvgBitrate           QuickTime::MovieDataSize N
     20685                       QuickTime::Duration
    1050820686  BlueBalance          WB_RGGBLevels            N
    1050920687                       WB_RGBGLevels
     
    1051120689                       WB_GRBGLevels
    1051220690                       WB_GRGBLevels
     20691                       WB_GBRGLevels
     20692                       WB_RGBLevels
    1051320693                       WB_RBLevels
    1051420694                       WBBlueLevel
     
    1051920699  ConditionalFEC       FlashExposureComp        N
    1052020700                       FlashBits
    10521   DOF                  FocusDistance            N
    10522                        FocalLength
     20701  DOF                  FocalLength              N
    1052320702                       Aperture
    1052420703                       CircleOfConfusion
     20704                       FocusDistance
     20705                       SubjectDistance
     20706                       ObjectDistance
    1052520707  DateCreated          Kodak:YearCreated        N
    1052620708                       Kodak:MonthDayCreated
    10527   DateTimeCreated      DateCreated              N
     20709  DateTimeCreated      IPTC:DateCreated         N
     20710                       IPTC:TimeCreated
     20711  DateTimeOriginal     DateTimeCreated          N
     20712                       DateCreated
    1052820713                       TimeCreated
    10529   DateTimeOriginal     DateTimeCreated          N
     20714  DateTimeOriginal     ID3:RecordingTime        N
     20715                       ID3:Year
     20716                       ID3:Date
     20717                       ID3:Time
     20718  DigitalCreationDateTime IPTC:DigitalCreationDate N
     20719                       IPTC:DigitalCreationTime
    1053020720  DigitalZoom          Canon:ZoomSourceWidth    N
    1053120721                       Canon:ZoomTargetWidth
    1053220722                       Canon:DigitalZoom
    1053320723  DriveMode            ContinuousDrive          N
    10534                        Self-timer
     20724                       SelfTimer
    1053520725  Duration             FLAC:SampleRate          N
    10536                        FLAC:Channels
    1053720726                       FLAC:TotalSamples
    1053820727  Duration             FileSize                 N
     20728                       ID3Size
    1053920729                       MPEG:AudioBitrate
    1054020730                       MPEG:VideoBitrate
    10541   Duration             FrameRate                N
     20731                       MPEG:VBRFrames
     20732                       MPEG:SampleRate
     20733                       MPEG:MPEGAudioVersion
     20734  Duration             RIFF:FrameRate           N
     20735                       RIFF:FrameCount
     20736                       VideoFrameRate
     20737                       VideoFrameCount
     20738  Duration             RIFF:AvgBytesPerSec      N
     20739                       FileSize
    1054220740                       FrameCount
     20741                       VideoFrameCount
    1054320742  ExtenderStatus       Olympus:Extender         N
    1054420743                       Olympus:LensType
    1054520744                       MaxApertureValue
    10546   FlashOn              FlashBits                N
    10547                        Flash
     20745  FOV                  FocalLength              N
     20746                       ScaleFactor35efl
     20747                       FocusDistance
     20748  FileNumber           DirectoryIndex           Y
     20749                       FileIndex
    1054820750  FlashType            FlashBits                N
    1054920751  FocalLength35efl     FocalLength              N
    1055020752                       ScaleFactor35efl
    10551   GPSDateTime          GPSDateStamp             N
    10552                        GPSTimeStamp
     20753  GPSAltitude          QuickTime:GPSCoordinates N
     20754  GPSAltitudeRef       QuickTime:GPSCoordinates N
     20755  GPSAltitude          GPS:GPSAltitude          N
     20756                       GPS:GPSAltitudeRef
     20757                       XMP:GPSAltitude
     20758                       XMP:GPSAltitudeRef
     20759  GPSDateTime          GPS:GPSDateStamp         N
     20760                       GPS:GPSTimeStamp
     20761  GPSLatitude          QuickTime:GPSCoordinates N
     20762  GPSLatitudeRef       XMP:GPSLatitude          N
    1055320763  GPSLatitude          GPS:GPSLatitude          N
    1055420764                       GPS:GPSLatitudeRef
    10555   GPSLatitudeRef       XMP:GPSLatitude          N
     20765  GPSLongitude         QuickTime:GPSCoordinates N
     20766  GPSLongitudeRef      XMP:GPSLongitude         N
    1055620767  GPSLongitude         GPS:GPSLongitude         N
    1055720768                       GPS:GPSLongitudeRef
    10558   GPSLongitudeRef      XMP:GPSLongitude         N
    1055920769  GPSPosition          GPSLatitude              N
    1056020770                       GPSLongitude
     
    1056220772                       Aperture
    1056320773                       CircleOfConfusion
     20774  IDCPreviewImage      IDCPreviewStart          N
     20775                       IDCPreviewLength
    1056420776  ISO                  Canon:CameraISO          N
    1056520777                       Canon:BaseISO
    1056620778                       Canon:AutoISO
    10567   ImageHeight          PostScript:ImageData    N
     20779  ImageHeight          Main:PostScript:ImageData N
    1056820780                       PostScript:BoundingBox
    1056920781  ImageSize            ImageWidth               N
    1057020782                       ImageHeight
    10571   ImageWidth           PostScript:ImageData     N
     20783                       ExifImageWidth
     20784                       ExifImageHeight
     20785  ImageWidth           Main:PostScript:ImageData N
    1057220786                       PostScript:BoundingBox
    1057320787  JpgFromRaw           JpgFromRawStart          Y
     
    1057920793                       Lens
    1058020794                       ScaleFactor35efl
     20795  LensID               LensType                 N
     20796                       FocalLength
     20797                       MaxAperture
     20798                       MaxApertureValue
     20799                       ShortFocal
     20800                       LongFocal
     20801                       LensModel
     20802                       LensFocalRange
    1058120803  LensID               Nikon:LensIDNumber       N
    1058220804                       LensFStops
     
    1058720809                       MCUVersion
    1058820810                       Nikon:LensType
     20811  LensID               Ricoh:LensFirmware       N
    1058920812  LensSpec             Nikon:Lens               N
    1059020813                       Nikon:LensType
     
    1059220815                       ShutterSpeed
    1059320816                       ISO
     20817  MPImage              MPImageStart             N
     20818                       MPImageLength
     20819                       MPImageType
     20820  OriginalDecisionData OriginalDecisionDataOffset Y!
    1059420821  OtherImage           OtherImageStart          N
    1059520822                       OtherImageLength
     
    1060720834                       WB_GRBGLevels
    1060820835                       WB_GRGBLevels
     20836                       WB_GBRGLevels
     20837                       WB_RGBLevels
    1060920838                       WB_RBLevels
    1061020839                       WBRedLevel
     
    1061220841  RedEyeReduction      CanonFlashMode           N
    1061320842                       FlashBits
     20843  Rotation             QuickTime:MatrixStructure N
     20844                       QuickTime:HandlerType
    1061420845  ScaleFactor35efl     FocalLength              N
    1061520846                       FocalLengthIn35mmFormat
     
    1062120852                       FocalPlaneXResolution
    1062220853                       FocalPlaneYResolution
     20854                       ExifImageWidth
     20855                       ExifImageHeight
    1062320856                       CanonImageWidth
    1062420857                       CanonImageHeight
    10625                        ExifImageWidth
    10626                        ExifImageLength
    1062720858                       ImageWidth
    1062820859                       ImageHeight
    1062920860  ShootingMode         CanonExposureMode        N
    1063020861                       EasyMode
     20862                       BulbDuration
    1063120863  ShutterCurtainHack   FlashBits                N
    1063220864                       ShutterCurtainSync
     
    1063420866                       ShutterSpeedValue
    1063520867                       BulbDuration
    10636   SubSecDateTimeOriginal DateTimeOriginal       N
     20868  SubSecCreateDate     EXIF:CreateDate          N
     20869                       SubSecTimeDigitized
     20870  SubSecDateTimeOriginal EXIF:DateTimeOriginal  N
    1063720871                       SubSecTimeOriginal
     20872  SubSecModifyDate     EXIF:ModifyDate          N
     20873                       SubSecTime
    1063820874  ThumbnailImage       ThumbnailOffset          Y
    1063920875                       ThumbnailLength
     20876  WB_RGBLevels         KDC_IFD:WhiteBalance     N
     20877                       WB_RGBLevelsAuto
     20878                       WB_RGBLevelsFluorescent
     20879                       WB_RGBLevelsTungsten
     20880                       WB_RGBLevelsDaylight
     20881                       WB_RGBLevels4
     20882                       WB_RGBLevels5
     20883                       WB_RGBLevelsShade
     20884  WB_RGBLevels         KodakIFD:WhiteBalance    N
     20885                       WB_RGBMul0
     20886                       WB_RGBMul1
     20887                       WB_RGBMul2
     20888                       WB_RGBMul3
     20889                       WB_RGBCoeffs0
     20890                       WB_RGBCoeffs1
     20891                       WB_RGBCoeffs2
     20892                       WB_RGBCoeffs3
     20893                       KodakIFD:ColorTemperature
     20894                       Kodak:WB_RGBLevels
    1064020895  WB_RGGBLevels        Canon:WhiteBalance       N
    1064120896                       WB_RGGBLevelsAsShot
     
    1064920904                       WB_RGGBLevelsShade
    1065020905                       WB_RGGBLevelsKelvin
     20906  WB_RGGBLevels        WB_RGGBLevelsUncorrected N
     20907                       WB_RGGBLevelsBlack
     20908  ZoomedPreviewImage   ZoomedPreviewStart       N
     20909                       ZoomedPreviewLength
    1065120910
    1065220911=head2 Shortcuts Tags
     
    1065720916
    1065820917The shortcut tags below have been pre-defined, but user-defined shortcuts
    10659 may be added via the %Image::ExifTool::Shortcuts::UserDefined lookup in the
    10660 ~/.ExifTool_config file.  See the Image::ExifTool::Shortcuts documentation
     20918may be added via the %Image::ExifTool::UserDefined::Shortcuts lookup in the
     20919=/.ExifTool_config file.  See the Image::ExifTool::Shortcuts documentation
    1066120920for more details.
    1066220921
     
    1067920938                       ImageSize
    1068020939                       Quality
    10681                        FlashOn
    10682                        FlashType
    10683                        ConditionalFEC
    10684                        RedEyeReduction
    10685                        ShutterCurtainHack
    10686                        WhiteBalance
    10687                        FocusMode
    10688                        Contrast
    10689                        Sharpness
    10690                        Saturation
    10691                        ColorTone
    10692                        FileSize
    10693                        FileNumber
    10694                        DriveMode
    10695                        OwnerName
    10696                        SerialNumber
    10697   Canon20D             FileName                 Y
    10698                        Model
    10699                        DateTimeOriginal
    10700                        ShootingMode
    10701                        ShutterSpeedValue
    10702                        ApertureValue
    10703                        MeteringMode
    10704                        ExposureCompensation
    10705                        ISO
    10706                        Lens
    10707                        FocalLength
    10708                        ExifImageWidth
    10709                        ExifImageLength
    10710                        Quality
    10711                        FlashOn
     20940                       Flash
    1071220941                       FlashType
    1071320942                       ConditionalFEC
     
    1073920968                       WhiteBalance
    1074020969                       Flash
     20970  CommonIFD0           IFD0:ImageDescription    Y
     20971                       IFD0:Make
     20972                       IFD0:Model
     20973                       IFD0:Software
     20974                       IFD0:ModifyDate
     20975                       IFD0:Artist
     20976                       IFD0:Copyright
     20977                       IFD0:Rating
     20978                       IFD0:RatingPercent
     20979                       IFD0:DNGLensInfo
     20980                       IFD0:PanasonicTitle
     20981                       IFD0:PanasonicTitle2
     20982                       IFD0:XPTitle
     20983                       IFD0:XPComment
     20984                       IFD0:XPAuthor
     20985                       IFD0:XPKeywords
     20986                       IFD0:XPSubject
    1074120987  MakerNotes           MakerNotes               Y
    1074220988                       MakerNoteCanon
     
    1074420990                       MakerNoteCasio2
    1074520991                       MakerNoteFujiFilm
     20992                       MakerNoteGE
     20993                       MakerNoteGE2
    1074620994                       MakerNoteHP
    1074720995                       MakerNoteHP2
    1074820996                       MakerNoteHP4
    1074920997                       MakerNoteHP6
     20998                       MakerNoteISL
    1075020999                       MakerNoteJVC
    1075121000                       MakerNoteJVCText
     
    1075921008                       MakerNoteKodak6b
    1076021009                       MakerNoteKodak7
    10761                        MakerNoteKodakIFD
     21010                       MakerNoteKodak8a
     21011                       MakerNoteKodak8b
     21012                       MakerNoteKodak9
     21013                       MakerNoteKodak10
    1076221014                       MakerNoteKodakUnknown
    1076321015                       MakerNoteKyocera
     
    1077121023                       MakerNoteOlympus2
    1077221024                       MakerNoteLeica
     21025                       MakerNoteLeica2
     21026                       MakerNoteLeica3
     21027                       MakerNoteLeica4
     21028                       MakerNoteLeica5
     21029                       MakerNoteLeica6
    1077321030                       MakerNotePanasonic
    1077421031                       MakerNotePanasonic2
     
    1077721034                       MakerNotePentax3
    1077821035                       MakerNotePentax4
     21036                       MakerNotePentax5
     21037                       MakerNotePhaseOne
     21038                       MakerNoteReconyx
    1077921039                       MakerNoteRicoh
    1078021040                       MakerNoteRicohText
     21041                       MakerNoteSamsung1a
     21042                       MakerNoteSamsung1b
     21043                       MakerNoteSamsung2
    1078121044                       MakerNoteSanyo
    1078221045                       MakerNoteSanyoC4
     
    1078421047                       MakerNoteSigma
    1078521048                       MakerNoteSony
     21049                       MakerNoteSony2
     21050                       MakerNoteSony3
     21051                       MakerNoteSony4
     21052                       MakerNoteSonyEricsson
    1078621053                       MakerNoteSonySRF
    10787                        MakerNoteSonySR2
     21054                       MakerNoteUnknownText
    1078821055                       MakerNoteUnknown
    1078921056  Nikon                Model                    Y
     
    1081521082                       FlashMode
    1081621083                       FlashExposureComp
     21084  Unsafe               IFD0:YCbCrPositioning    Y
     21085                       IFD0:YCbCrCoefficients
     21086                       IFD0:TransferFunction
     21087                       ExifIFD:ComponentsConfiguration
     21088                       ExifIFD:CompressedBitsPerPixel
     21089                       InteropIFD:InteropIndex
     21090                       InteropIFD:InteropVersion
     21091                       InteropIFD:RelatedImageWidth
     21092                       InteropIFD:RelatedImageHeight
     21093
     21094=head2 MWG Tags
     21095
     21096=head3 MWG Composite Tags
     21097
     21098The Metadata Working Group (MWG) recommendations provide a set of rules to
     21099allow certain overlapping EXIF, IPTC and XMP tags to be reconciled when
     21100reading, and synchronized when writing.  The ExifTool MWG module is designed
     21101to aid in the implementation of these recommendations.  (See
     21102L<http://www.metadataworkinggroup.org/> for the complete MWG technical
     21103specifications.)
     21104
     21105The table below lists special Composite tags which are used to access other
     21106tags based on the MWG 2.0 recommendations.  These tags are only accessible
     21107when the MWG module is loaded.  The MWG module is loaded automatically by
     21108the exiftool application if MWG is specified as a group for any tag on the
     21109command line, or manually with the C<-use MWG> option.  Via the API, the MWG
     21110module is loaded with "C<use Image::ExifTool::MWG>".
     21111
     21112When reading, the value of each MWG tag is B<Derived From> the specified
     21113tags based on the MWG guidelines.  When writing, the appropriate associated
     21114tags are written.  The value of the IPTCDigest tag is updated automatically
     21115when the IPTC is changed if either the IPTCDigest tag didn't exist
     21116beforehand or its value agreed with the original IPTC digest (indicating
     21117that the XMP is synchronized with the IPTC).  IPTC information is written
     21118only if the original file contained IPTC.
     21119
     21120Loading the MWG module activates "strict MWG conformance mode", which has
     21121the effect of causing EXIF, IPTC and XMP in non-standard locations to be
     21122ignored when reading, as per the MWG recommendations.  Instead, a "Warning"
     21123tag is generated when non-standard metadata is encountered.  This feature
     21124may be disabled by setting C<$Image::ExifTool::MWG::strict = 0> in the
     21125ExifTool config file (or from your Perl script when using the API).  Note
     21126that the behaviour when writing is not changed:  ExifTool always creates new
     21127records only in the standard location, but writes new tags to any
     21128EXIF/IPTC/XMP records that exist.
     21129
     21130A complication of the specification is that although the MWG:Creator
     21131property may consist of multiple values, the associated EXIF tag
     21132(EXIF:Artist) is only a simple string.  To resolve this discrepancy the MWG
     21133recommends a technique which allows a list of values to be stored in a
     21134string by using a semicolon-space separator (with quotes around values if
     21135necessary).  When the MWG module is loaded, ExifTool automatically
     21136implements this policy and changes EXIF:Artist to a list-type tag.
     21137
     21138  Tag Name             Derived From             Writable
     21139  --------             ------------             --------
     21140  City                 IPTC:City                Y
     21141                       XMP-photoshop:City
     21142                       CurrentIPTCDigest
     21143                       IPTCDigest
     21144  Copyright            EXIF:Copyright           Y
     21145                       IPTC:CopyrightNotice
     21146                       XMP-dc:Rights
     21147                       CurrentIPTCDigest
     21148                       IPTCDigest
     21149  Country              IPTC:Country-PrimaryLocationName Y
     21150                       XMP-photoshop:Country
     21151                       CurrentIPTCDigest
     21152                       IPTCDigest
     21153  CreateDate           EXIF:CreateDate          Y
     21154                       EXIF:SubSecTimeDigitized
     21155                       IPTC:DigitalCreationDate
     21156                       IPTC:DigitalCreationTime
     21157                       XMP-xmp:CreateDate
     21158                       CurrentIPTCDigest
     21159                       IPTCDigest
     21160  Creator              EXIF:Artist              Y+
     21161                       IPTC:By-line
     21162                       XMP-dc:Creator
     21163                       CurrentIPTCDigest
     21164                       IPTCDigest
     21165  DateTimeOriginal     EXIF:DateTimeOriginal    Y
     21166                       EXIF:SubSecTimeOriginal
     21167                       IPTC:DateCreated
     21168                       IPTC:TimeCreated
     21169                       XMP-photoshop:DateCreated
     21170                       CurrentIPTCDigest
     21171                       IPTCDigest
     21172  Description          EXIF:ImageDescription    Y
     21173                       IPTC:Caption-Abstract
     21174                       XMP-dc:Description
     21175                       CurrentIPTCDigest
     21176                       IPTCDigest
     21177  Keywords             IPTC:Keywords            Y+
     21178                       XMP-dc:Subject
     21179                       CurrentIPTCDigest
     21180                       IPTCDigest
     21181  Location             IPTC:Sub-location        Y
     21182                       XMP-iptcCore:Location
     21183                       CurrentIPTCDigest
     21184                       IPTCDigest
     21185  ModifyDate           EXIF:ModifyDate          Y
     21186                       EXIF:SubSecTime
     21187                       XMP-xmp:ModifyDate
     21188                       CurrentIPTCDigest
     21189                       IPTCDigest
     21190  Orientation          EXIF:Orientation         Y
     21191  Rating               XMP-xmp:Rating           Y
     21192  State                IPTC:Province-State      Y
     21193                       XMP-photoshop:State
     21194                       CurrentIPTCDigest
     21195                       IPTCDigest
    1081721196
    1081821197=head1 NOTES
     
    1082321202=head1 AUTHOR
    1082421203
    10825 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     21204Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    1082621205
    1082721206This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Unknown.pm

    r16842 r24107  
    5454=head1 AUTHOR
    5555
    56 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     56Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    5757
    5858This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Vorbis.pm

    r16842 r24107  
    1616use Image::ExifTool qw(:DataAccess :Utils);
    1717
    18 $VERSION = '1.01';
     18$VERSION = '1.03';
    1919
    2020my $MAX_PACKETS = 2;    # maximum packets to scan from each stream at start of file
     
    5555        Format => 'int32u',
    5656        RawConv => '$val || undef',
     57        PrintConv => 'ConvertBitrate($val)',
    5758    },
    5859    13 => {
     
    6061        Format => 'int32u',
    6162        RawConv => '$val || undef',
     63        PrintConv => 'ConvertBitrate($val)',
    6264    },
    6365    17 => {
     
    6567        Format => 'int32u',
    6668        RawConv => '$val || undef',
     69        PrintConv => 'ConvertBitrate($val)',
    6770    },
    6871);
     
    151154            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name });
    152155        }
    153         $exifTool->HandleTag($tagTablePtr, $tag, $val,
     156        $exifTool->HandleTag($tagTablePtr, $tag, $exifTool->Decode($val, 'UTF8'),
    154157            Index   => $index,
    155158            DataPt  => $dataPt,
     
    197200
    198201    # must first check for leading/trailing ID3 information
    199     unless ($exifTool->{DONE_ID3}) {
     202    unless ($exifTool->{DoneID3}) {
    200203        require Image::ExifTool::ID3;
    201204        Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
     
    330333=head1 AUTHOR
    331334
    332 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     335Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    333336
    334337This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteCanonRaw.pl

    r16842 r24107  
    1111use vars qw($VERSION $AUTOLOAD %crwTagFormat);
    1212use Image::ExifTool::Fixup;
     13
     14# map for adding directories to CRW
     15my %crwMap = (
     16    XMP      => 'CanonVRD',
     17    CanonVRD => 'Trailer',
     18);
    1319
    1420# mappings to from RAW tagID to MakerNotes tagID
     
    7783    # (and has the same raw tagID as CanonFileDescription)
    7884    return if $tagInfo and $$tagInfo{Name} eq 'UserComment';
    79     my $tagType = ($rawTag >> 8) & 0x38;
    8085    my $format = $Image::ExifTool::Exif::formatNumber{$formName};
    8186    my $fsiz = $Image::ExifTool::Exif::formatSize[$format];
     
    166171{
    167172    my ($exifTool, $tagInfo, $valPtr) = @_;
    168     Image::ExifTool::GenerateTagIDs($$tagInfo{Table});
    169173    my $tagName = $$tagInfo{Name};
    170174    if ($tagName eq 'JpgFromRaw' or $tagName eq 'ThumbnailImage') {
     
    193197    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    194198    my $dataPt = $$dirInfo{DataPt} or return 0;
    195     my $raf = $$dirInfo{RAF} or return 0;
    196199    my $outfile = $$dirInfo{OutFile} or return 0;
     200    $$dirInfo{RAF} or return 0;
    197201
    198202    # check CR2 signature
    199     return 0 if $$dataPt !~ /^.{8}CR\x02\0/s and
    200         $exifTool->Error("Unsupported Canon RAW file. May cause problems if rewritten", 1);
     203    if ($$dataPt !~ /^.{8}CR\x02\0/s) {
     204        my ($msg, $minor);
     205        if ($$dataPt =~ /^.{8}CR/s) {
     206            $msg = 'Unsupported Canon RAW file. May cause problems if rewritten';
     207            $minor = 1;
     208        } elsif ($$dataPt =~ /^.{8}\xba\xb0\xac\xbb/s) {
     209            $msg = 'Can not currently write Canon 1D RAW images';
     210        } else {
     211            $msg = 'Unrecognized Canon RAW file';
     212        }
     213        return 0 if $exifTool->Error($msg, $minor);
     214    }
     215
    201216    # CR2 has a 16-byte header
    202217    $$dirInfo{NewDataPos} = 16;
     
    231246# Inputs: 0) ExifTool object reference, 1) source dirInfo reference,
    232247#         2) tag table reference
    233 # Returns: true on sucess
     248# Returns: true on success
    234249# Notes: Increments ExifTool CHANGED flag for each tag changed This routine is
    235250# different from all of the other write routines because Canon RAW files are
     
    237252# writing it out.  Therefore this routine doesn't return the directory data as
    238253# the rest of the Write routines do.  Instead, it writes to the dirInfo
    239 # Outfile on the fly --> much faster, efficient, and less demanding on memory!
     254# OutFile on the fly --> much faster, efficient, and less demanding on memory!
    240255sub WriteCanonRaw($$$)
    241256{
     
    294309            my $newVal = $exifTool->GetNewValues($tagInfo);
    295310            if (defined $newVal) {
     311                # pad value to an even length (Canon ImageBrowser and ZoomBrowser
     312                # version 6.1.1 have problems with odd-sized embedded JPEG images
     313                # even if the value is padded to maintain alignment, so do this
     314                # before calculating the size for the directory entry)
     315                $newVal .= "\0" if length($newVal) & 0x01;
    296316                # add new directory entry
    297317                $newDir .= Set16u($addTag) . Set32u(length($newVal)) .
     
    307327        }
    308328        last unless defined $tag;           # all done if no more directory entries
    309         return 0 if $tag & 0x8000;      # top bit should not be set
     329        return 0 if $tag & 0x8000;          # top bit should not be set
    310330        my $tagID = $tag & 0x3fff;          # get tag ID
    311331        my $tagType = ($tag >> 8) & 0x38;   # get tag type
     
    410430                    $oldVal = $value;
    411431                }
    412                 my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
    413                 if (Image::ExifTool::IsOverwriting($newValueHash, $oldVal)) {
    414                     my $newVal = Image::ExifTool::GetNewValues($newValueHash);
     432                my $nvHash = $exifTool->GetNewValueHash($tagInfo);
     433                if (Image::ExifTool::IsOverwriting($nvHash, $oldVal)) {
     434                    my $newVal = Image::ExifTool::GetNewValues($nvHash);
    415435                    my $verboseVal;
    416436                    $verboseVal = $newVal if $verbose > 1;
     
    422442                        $value = $newVal;
    423443                        ++$exifTool->{CHANGED};
    424                         if ($verbose > 1) {
    425                             my $oldStr = $exifTool->Printable($oldVal);
    426                             my $newStr = $exifTool->Printable($verboseVal);
    427                             print $out "    - CanonRaw:$$tagInfo{Name} = '$oldStr'\n";
    428                             print $out "    + CanonRaw:$$tagInfo{Name} = '$newStr'\n";
    429                         }
     444                        $exifTool->VerboseValue("- CanonRaw:$$tagInfo{Name}", $oldVal);
     445                        $exifTool->VerboseValue("+ CanonRaw:$$tagInfo{Name}", $verboseVal);
    430446                    }
    431447                }
     
    505521    if ($exifTool->{DEL_GROUP}->{MakerNotes}) {
    506522        if ($type eq 'CCDR') {
    507             $exifTool->Error("Can't delete Makernotes group in CRW file");
     523            $exifTool->Error("Can't delete MakerNotes group in CRW file");
    508524            return 0;
    509525        } else {
     
    511527            return 1;
    512528        }
     529    }
     530    # make XMP the preferred group for CRW files
     531    if ($$exifTool{FILE_TYPE} eq 'CRW') {
     532        $exifTool->InitWriteDirs(\%crwMap, 'XMP');
    513533    }
    514534
     
    552572        # add CanonVRD trailer if writing as a block
    553573        $trailPt = $exifTool->AddNewTrailers($trailPt,'CanonVRD');
     574        if (not $trailPt and $$exifTool{ADD_DIRS}{CanonVRD}) {
     575            # create CanonVRD from scratch if necessary
     576            my $outbuff = '';
     577            my $saveOrder = GetByteOrder();
     578            require Image::ExifTool::CanonVRD;
     579            if (Image::ExifTool::CanonVRD::ProcessCanonVRD($exifTool, { OutFile => \$outbuff }) > 0) {
     580                $trailPt = \$outbuff;
     581            }
     582            SetByteOrder($saveOrder);
     583        }
    554584        # write trailer
    555585        if ($trailPt) {
     
    593623=head1 AUTHOR
    594624
    595 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     625Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    596626
    597627This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteExif.pl

    r16842 r24107  
    1111use strict;
    1212use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber
    13             %lightSource %compression %photometricInterpretation %orientation);
     13            %compression %photometricInterpretation %orientation);
    1414
    1515use Image::ExifTool::Fixup;
     
    3030        0x011a => 72,       # XResolution
    3131        0x011b => 72,       # YResolution
    32         0x0128 => 2,        # Resolution unit (inches)
     32        0x0128 => 2,        # ResolutionUnit (inches)
    3333        0x0213 => 1,        # YCbCrPositioning (centered)
    3434      # 0x8769 => ????,     # ExifOffset
     
    3838        0x011a => 72,       # XResolution
    3939        0x011b => 72,       # YResolution
    40         0x0128 => 2,        # Resolution unit (inches)
     40        0x0128 => 2,        # ResolutionUnit (inches)
    4141    },
    4242    ExifIFD => {
    43         0x9000 => '0220',   # ExifVersion
    44         0x9101 => "\1\2\3\0", # ComponentsConfiguration
     43        0x9000 => '0230',   # ExifVersion
     44        0x9101 => "1 2 3 0",# ComponentsConfiguration
    4545        0xa000 => '0100',   # FlashpixVersion
    4646        0xa001 => 0xffff,   # ColorSpace (uncalibrated)
    4747      # 0xa002 => ????,     # ExifImageWidth
    48       # 0xa003 => ????,     # ExifImageLength
     48      # 0xa003 => ????,     # ExifImageHeight
    4949    },
    5050    GPS => {
    51         0x0000 => '2 2 0 0',# GPSVersionID
     51        0x0000 => '2 3 0 0',# GPSVersionID
    5252    },
    5353    InteropIFD => {
     
    7272        Protected => 1,
    7373        Writable => 'undef',
     74        Mandatory => 1,
    7475        WriteGroup => 'InteropIFD',
    7576    },
     
    9394        WriteGroup => 'IFD0',
    9495    },
    95     0x0101 => {             # ImageHeigth
     96    0x0101 => {             # ImageHeight
    9697        Protected => 1,
    9798        Writable => 'int32u',
     
    108109        Writable => 'int16u',
    109110        WriteGroup => 'IFD0',
     111        Mandatory => 1,
    110112    },
    111113    0x0106 => {             # PhotometricInterpretation
     
    175177        Writable => 'rational64u',
    176178        WriteGroup => 'IFD0',
     179        Mandatory => 1,
    177180    },
    178181    0x011b => {             # YResolution
    179182        Writable => 'rational64u',
    180183        WriteGroup => 'IFD0',
     184        Mandatory => 1,
    181185    },
    182186    0x011c => {             # PlanarConfiguration
     
    204208        Writable => 'int16u',
    205209        WriteGroup => 'IFD0',
     210        Mandatory => 1,
    206211    },
    207212    0x0129 => {             # PageNumber
     
    210215        Count => 2,
    211216    },
     217    0x012d => {             # TransferFunction
     218        Protected => 1,
     219        Writable => 'int16u',
     220        WriteGroup => 'IFD0',
     221        Count => 768,
     222    },
    212223    0x0131 => {             # Software
    213224        Writable => 'string',
     
    218229        Shift => 'Time',
    219230        WriteGroup => 'IFD0',
    220         PrintConvInv => 'Image::ExifTool::Exif::ExifDateTime($val)',
     231        PrintConvInv => '$self->InverseDateTime($val,0)',
    221232    },
    222233    0x013b => {             # Artist
     
    286297        Writable => 'int16u',
    287298        WriteGroup => 'IFD0',
     299        Mandatory => 1,
    288300    },
    289301    0x0214 => {             # ReferenceBlackWhite
     
    302314        WriteGroup => 'InteropIFD',
    303315    },
    304     0x1002 => {             # RelatedImageLength (is really the height)
     316    0x1002 => {             # RelatedImageHeight (more commonly RelatedImageLength)
    305317        Protected => 1,
    306318        Writable => 'int16u',
     
    320332        Writable => 'string',
    321333        WriteGroup => 'IFD0',
     334        RawConvInv => q{
     335            if ($val =~ /(.*?)\s*[\n\r]+\s*(.*)/s) {
     336                return $1 . "\0" unless length $2;
     337                # photographer copyright set to ' ' if it doesn't exist, according to spec.
     338                return((length($1) ? $1 : ' ') . "\0" . $2 . "\0");
     339            }
     340            return $val . "\0";
     341        },
    322342    },
    323343#
     
    326346    0x829a => {             # ExposureTime
    327347        Writable => 'rational64u',
    328         PrintConvInv => 'eval $val',
     348        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    329349    },
    330350    0x829d => {             # FNumber
     
    332352        PrintConvInv => '$val',
    333353    },
    334     0x83bb => {             # IPTC-NAA
    335         # this should actually be written as 'undef' (see
    336         # http://www.awaresystems.be/imaging/tiff/tifftags/iptc.html),
    337         # but Photoshop writes it as int32u and Nikon Capture won't read
    338         # anything else, so we do the same thing here...  Doh!
    339         Format => 'undef',      # convert binary values as undef
    340         Writable => 'int32u',   # but write int32u format code in IFD
    341         WriteGroup => 'IFD0',
    342     },
    343354    0x8546 => {             # SEMInfo
    344355        Writable => 'string',
     
    347358    0x8822 => 'int16u',     # ExposureProgram
    348359    0x8824 => 'string',     # SpectralSensitivity
    349     0x8827 => 'int16u',     # ISO
     360    0x8827 => {             # ISO
     361        Writable => 'int16u',
     362        Count => -1,
     363        PrintConvInv => '$val=~tr/,//d; $val',
     364    },
    350365    0x882a => {             # TimeZoneOffset
    351366        Writable => 'int16s',
     
    357372    },
    358373    0x882b => 'int16u',     # SelfTimerMode
    359     0x9000 => 'undef',      # ExifVersion
     374    0x8830 => 'int16u',     # SensitivityType
     375    0x8831 => 'int32u',     # StandardOutputSensitivity
     376    0x8832 => 'int32u',     # RecommendedExposureIndex
     377    0x8833 => 'int32u',     # ISOSpeed
     378    0x8834 => 'int32u',     # ISOSpeedLatitudeyyy
     379    0x8835 => 'int32u',     # ISOSpeedLatitudezzz
     380    0x9000 => {             # ExifVersion
     381        Writable => 'undef',
     382        Mandatory => 1,
     383    },
    360384    0x9003 => {             # DateTimeOriginal
    361385        Writable => 'string',
    362386        Shift => 'Time',
    363         PrintConvInv => 'Image::ExifTool::Exif::ExifDateTime($val)',
     387        PrintConvInv => '$self->InverseDateTime($val,0)',
    364388    },
    365389    0x9004 => {             # CreateDate
    366390        Writable => 'string',
    367391        Shift => 'Time',
    368         PrintConvInv => 'Image::ExifTool::Exif::ExifDateTime($val)',
     392        PrintConvInv => '$self->InverseDateTime($val,0)',
    369393    },
    370394    0x9101 => {             # ComponentsConfiguration
     395        Protected => 1,
    371396        Writable => 'undef',
    372         PrintConv => '$_=$val;s/\0.*//s;tr/\x01-\x06/YXWRGB/;s/X/Cb/g;s/W/Cr/g;$_',
    373         PrintConvInv => q{
    374             $_=uc($val); s/CR/W/g; s/CB/X/g;
    375             return undef if /[^YXWRGB]/;
    376             tr/YXWRGB/\x01-\x06/;
    377             return $_ . "\0";
    378         },
    379     },
    380     0x9102 => 'rational64u',# CompressedBitsPerPixel
     397        Count => 4,
     398        Mandatory => 1,
     399        ValueConvInv => '$val=~tr/,//d; $val',  # (so we can copy from XMP with -n)
     400    },
     401    0x9102 => {             # CompressedBitsPerPixel
     402        Protected => 1,
     403        Writable => 'rational64u',
     404    },
    381405    0x9201 => {             # ShutterSpeedValue
    382406        Writable => 'rational64s',
    383407        ValueConvInv => '$val>0 ? -log($val)/log(2) : -100',
    384408        # do eval to convert things like '1/100'
    385         PrintConvInv => 'eval $val',
     409        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    386410    },
    387411    0x9202 => {             # ApertureValue
     
    394418        Writable => 'rational64s',
    395419        # do eval to convert things like '+2/3'
    396         PrintConvInv => 'eval $val',
     420        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    397421    },
    398422    0x9205 => {             # MaxApertureValue
     
    415439    0x9212 => 'string',     # SecurityClassification
    416440    0x9213 => 'string',     # ImageHistory
    417     0x9214 => {             # SubjectLocation
    418         Writable => 'int16u',
    419         Count => 4,  # write this SubjectLocation with 4 and the other with 2 values
     441    0x9214 => {             # SubjectArea
     442        Writable => 'int16u',
     443        Count => -1, # 2, 3 or 4 values
    420444    },
    421445#    0x927c => 'undef',      # MakerNotes
    422     0x9286 => {             # UserComment (string that starts with "ASCII\0\0\0")
     446    0x9286 => {             # UserComment
    423447        Writable => 'undef',
    424         PrintConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
    425     },
    426     0x9290 => 'string',     # SubSecTime
    427     0x9291 => 'string',     # SubSecTimeOriginal
    428     0x9292 => 'string',     # SubSecTimeDigitized
     448        #  (starts with "ASCII\0\0\0", "UNICODE\0", "JIS\0\0\0\0\0" or "\0\0\0\0\0\0\0\0")
     449        RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
     450        # SHOULD ADD SPECIAL LOGIC TO ALLOW CONDITIONAL OVERWRITE OF
     451        # "UNKNOWN" VALUES FILLED WITH SPACES
     452    },
     453    0x9290 => {             # SubSecTime
     454        Writable => 'string',
     455        # extract fractional seconds from a full date/time value
     456        ValueConvInv => '$val=~/^(\d+)\s*$/ ? $1 : ($val=~/\.(\d+)/ ? $1 : undef)',
     457    },
     458    0x9291 => {             # SubSecTimeOriginal
     459        Writable => 'string',
     460        ValueConvInv => '$val=~/^(\d+)\s*$/ ? $1 : ($val=~/\.(\d+)/ ? $1 : undef)',
     461    },
     462    0x9292 => {             # SubSecTimeDigitized
     463        Writable => 'string',
     464        ValueConvInv => '$val=~/^(\d+)\s*$/ ? $1 : ($val=~/\.(\d+)/ ? $1 : undef)',
     465    },
    429466    0x935c => {             # ImageSourceData
    430467        Writable => 'undef',
    431468        WriteGroup => 'IFD0',
     469        Protected => 1,
    432470    },
    433471#    0x9928 => 'undef',      # Opto-ElectricConversionFactor
     
    438476            tags 0x9c9b-0x9c9f are used by Windows Explorer; special characters
    439477            in these values are converted to UTF-8 by default, or Windows Latin1
    440             with the -L option. XPTitle is ignored by Windows Explorer if
     478            with the -L option.  XPTitle is ignored by Windows Explorer if
    441479            ImageDescription exists
    442480        },
    443         ValueConvInv => '$self->Charset2Unicode($val,"II") . "\0\0"',
     481        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
    444482    },
    445483    0x9c9c => {             # XPComment
    446484        Writable => 'int8u',
    447485        WriteGroup => 'IFD0',
    448         ValueConvInv => '$self->Charset2Unicode($val,"II") . "\0\0"',
     486        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
    449487    },
    450488    0x9c9d => {             # XPAuthor
     
    452490        WriteGroup => 'IFD0',
    453491        Notes => 'ignored by Windows Explorer if Artist exists',
    454         ValueConvInv => '$self->Charset2Unicode($val,"II") . "\0\0"',
     492        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
    455493    },
    456494    0x9c9e => {             # XPKeywords
    457495        Writable => 'int8u',
    458496        WriteGroup => 'IFD0',
    459         ValueConvInv => '$self->Charset2Unicode($val,"II") . "\0\0"',
     497        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
    460498    },
    461499    0x9c9f => {             # XPSubject
    462500        Writable => 'int8u',
    463501        WriteGroup => 'IFD0',
    464         ValueConvInv => '$self->Charset2Unicode($val,"II") . "\0\0"',
    465     },
    466     0xa000 => 'undef',      # FlashpixVersion
    467     0xa001 => 'int16u',     # ColorSpace
    468     0xa002 => 'int16u',     # ExifImageWidth (could also be int32u)
    469     0xa003 => 'int16u',     # ExifImageLength (could also be int32u)
     502        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
     503    },
     504    0xa000 => {             # FlashpixVersion
     505        Writable => 'undef',
     506        Mandatory => 1,
     507    },
     508    0xa001 => {             # ColorSpace
     509        Writable => 'int16u',
     510        Mandatory => 1,
     511    },
     512    0xa002 => {             # ExifImageWidth (could also be int32u)
     513        Writable => 'int16u',
     514        Mandatory => 1,
     515    },
     516    0xa003 => {             # ExifImageHeight (could also be int32u)
     517        Writable => 'int16u',
     518        Mandatory => 1,
     519    },
    470520    0xa004 => 'string',     # RelatedSoundFile
    471521    0xa20b => {             # FlashEnergy
     
    485535    0xa300 => {             # FileSource
    486536        Writable => 'undef',
    487         ValueConvInv => 'chr($val)',
    488         PrintConvInv => 3,
     537        ValueConvInv => '($val=~/^\d+$/ and $val < 256) ? chr($val) : $val',
    489538    },
    490539    0xa301 => {             # SceneType
     
    521570    0xa40c => 'int16u',     # SubjectDistanceRange
    522571    0xa420 => 'string',     # ImageUniqueID
     572    0xa430 => 'string',     # OwnerName
     573    0xa431 => 'string',     # SerialNumber
     574    0xa432 => {             # LensInfo
     575        Writable => 'rational64u',
     576        Count => 4,
     577        PrintConvInv => \&ConvertLensInfo,
     578    },
     579    0xa433 => 'string',     # LensMake
     580    0xa434 => 'string',     # LensModel
     581    0xa435 => 'string',     # LensSerialNumber
    523582    0xa500 => 'rational64u',# Gamma
    524     0xc4a5 => {             # PrintIM
    525         Writable => 'undef',
    526         WriteGroup => 'IFD0',
    527     },
    528583#
    529584# DNG stuff (back in IFD0)
     
    533588        WriteGroup => 'IFD0',
    534589        Count => 4,
     590        Protected => 1, # (confuses Apple Preview if written to a TIFF image)
     591        PrintConvInv => '$val =~ tr/./ /; $val',
    535592    },
    536593    0xc613 => {             # DNGBackwardVersion
     
    538595        WriteGroup => 'IFD0',
    539596        Count => 4,
     597        Protected => 1,
    540598    },
    541599    0xc614 => {             # UniqueCameraModel
     
    547605        WriteGroup => 'IFD0',
    548606        PrintConvInv => '$val',
     607    },
     608    0xc619 => {             # BlackLevelRepeatDim
     609        Writable => 'int16u',
     610        WriteGroup => 'SubIFD',
     611        Count => 2,
     612        Protected => 1,
     613    },
     614    0xc61a => {             # BlackLevel
     615        Writable => 'rational64u',
     616        WriteGroup => 'SubIFD',
     617        Count => -1,
     618        Protected => 1,
     619    },
     620    0xc61d => {             # WhiteLevel
     621        Writable => 'int32u',
     622        WriteGroup => 'SubIFD',
     623        Count => -1,
     624        Protected => 1,
    549625    },
    550626    0xc61e => {             # DefaultScale
     
    552628        WriteGroup => 'SubIFD',
    553629        Count => 2,
     630        Protected => 1,
    554631    },
    555632    0xc61f => {             # DefaultCropOrigin
     
    557634        WriteGroup => 'SubIFD',
    558635        Count => 2,
     636        Protected => 1,
    559637    },
    560638    0xc620 => {             # DefaultCropSize
     
    562640        WriteGroup => 'SubIFD',
    563641        Count => 2,
     642        Protected => 1,
     643    },
     644    0xc621 => {             # ColorMatrix1
     645        Writable => 'rational64s',
     646        Count => -1,
     647        WriteGroup => 'IFD0',
     648        Protected => 1,
     649    },
     650    0xc622 => {             # ColorMatrix2
     651        Writable => 'rational64s',
     652        Count => -1,
     653        WriteGroup => 'IFD0',
     654        Protected => 1,
     655    },
     656    0xc623 => {             # CameraCalibration1
     657        Writable => 'rational64s',
     658        Count => -1,
     659        WriteGroup => 'IFD0',
     660        Protected => 1,
     661    },
     662    0xc624 => {             # CameraCalibration2
     663        Writable => 'rational64s',
     664        Count => -1,
     665        WriteGroup => 'IFD0',
     666        Protected => 1,
     667    },
     668    0xc625 => {             # ReductionMatrix1
     669        Writable => 'rational64s',
     670        Count => -1,
     671        WriteGroup => 'IFD0',
     672        Protected => 1,
     673    },
     674    0xc626 => {             # ReductionMatrix2
     675        Writable => 'rational64s',
     676        Count => -1,
     677        WriteGroup => 'IFD0',
     678        Protected => 1,
     679    },
     680    0xc627 => {             # AnalogBalance
     681        Writable => 'rational64u',
     682        Count => -1,
     683        WriteGroup => 'IFD0',
     684        Protected => 1,
     685    },
     686    0xc628 => {             # AsShotNeutral
     687        Writable => 'rational64u',
     688        WriteGroup => 'IFD0',
     689        Count => -1,
     690        Protected => 1,
    564691    },
    565692    0xc629 => {             # AsShotWhiteXY
     
    567694        WriteGroup => 'IFD0',
    568695        Count => 2,
     696        Protected => 1,
    569697    },
    570698    0xc62a => {             # BaselineExposure
    571699        Writable => 'rational64s',
    572700        WriteGroup => 'IFD0',
     701        Protected => 1,
    573702    },
    574703    0xc62b => {             # BaselineNoise
    575704        Writable => 'rational64u',
    576705        WriteGroup => 'IFD0',
     706        Protected => 1,
    577707    },
    578708    0xc62c => {             # BaselineSharpness
    579709        Writable => 'rational64u',
    580710        WriteGroup => 'IFD0',
     711        Protected => 1,
    581712    },
    582713    0xc62d => {             # BayerGreenSplit
    583714        Writable => 'int32u',
    584715        WriteGroup => 'SubIFD',
     716        Protected => 1,
    585717    },
    586718    0xc62e => {             # LinearResponseLimit
    587719        Writable => 'rational64u',
    588720        WriteGroup => 'IFD0',
     721        Protected => 1,
    589722    },
    590723    0xc62f => {             # CameraSerialNumber
     
    596729        WriteGroup => 'IFD0',
    597730        Count => 4,
    598         PrintConvInv => '$_=$val;s/(-|mm f)/ /g;$_',
     731        PrintConvInv => \&ConvertLensInfo,
    599732    },
    600733    0xc631 => {             # ChromaBlurRadius
    601734        Writable => 'rational64u',
    602735        WriteGroup => 'SubIFD',
     736        Protected => 1,
    603737    },
    604738    0xc632 => {             # AntiAliasStrength
    605739        Writable => 'rational64u',
    606740        WriteGroup => 'SubIFD',
     741        Protected => 1,
    607742    },
    608743    0xc633 => {             # ShadowScale
    609744        Writable => 'rational64u',
    610745        WriteGroup => 'IFD0',
     746        Protected => 1,
    611747    },
    612748    0xc635 => {             # MakerNoteSafety
     
    617753        Writable => 'int16u',
    618754        WriteGroup => 'IFD0',
     755        Protected => 1,
    619756    },
    620757    0xc65b => {             # CalibrationIlluminant2
    621758        Writable => 'int16u',
    622759        WriteGroup => 'IFD0',
     760        Protected => 1,
    623761    },
    624762    0xc65c => {             # BestQualityScale
    625763        Writable => 'rational64u',
    626764        WriteGroup => 'SubIFD',
     765        Protected => 1,
    627766    },
    628767    0xc65d => {             # RawDataUniqueID
     
    630769        WriteGroup => 'IFD0',
    631770        Count => 16,
    632         ValueConvInv => 'pack("H*",$val)',
     771        ValueConvInv => 'pack("H*", $val)',
     772        Protected => 1,
    633773    },
    634774    0xc68b => {             # OriginalRawFileName
    635775        Writable => 'string',
    636776        WriteGroup => 'IFD0',
    637     },
    638     0xc68c => {             # OriginalRawFileData (a writable directory)
    639         Writable => 'undef',
    640         WriteGroup => 'IFD0',
     777        Protected => 1,
    641778    },
    642779    0xc68d => {             # ActiveArea
     
    644781        WriteGroup => 'SubIFD',
    645782        Count => 4,
     783        Protected => 1,
    646784    },
    647785    0xc68e => {             # MaskedAreas
     
    649787        WriteGroup => 'SubIFD',
    650788        Count => 4,
    651     },
    652     0xc68f => {             # AsShotICCProfile
    653         Writable => 'undef',
     789        Protected => 1,
     790    },
     791    0xc68f => {             # AsShotICCProfile (writable directory)
    654792        WriteGroup => 'IFD0',
    655793        Protected => 1,
     
    665803        Protected => 1,
    666804    },
    667     0xc691 => {             # CurrentICCProfile
     805    0xc691 => {             # CurrentICCProfile (writable directory)
    668806        Writable => 'undef',
    669807        WriteGroup => 'IFD0',
     
    676814    0xc692 => {             # CurrentPreProfileMatrix
    677815        Writable => 'rational64s',
     816        Count => -1,
     817        WriteGroup => 'IFD0',
     818        Protected => 1,
     819    },
     820    0xc6bf => {             # ColorimetricReference
     821        Writable => 'int16u',
     822        WriteGroup => 'IFD0',
     823        Protected => 1,
     824    },
     825    0xc6d2 => {             # PanasonicTitle (Panasonic DMC-TZ5, not a DNG tag)
     826        Writable => 'undef',
     827        WriteGroup => 'IFD0',
     828        ValueConvInv => '$self->Encode($val,"UTF8")',
     829    },
     830    0xc6d3 => {             # PanasonicTitle2 (Panasonic DMC-FS7, not a DNG tag)
     831        Writable => 'undef',
     832        WriteGroup => 'IFD0',
     833        ValueConvInv => '$self->Encode($val,"UTF8")',
     834    },
     835    0xc6f3 => {             # CameraCalibrationSig
     836        Writable => 'string',
     837        WriteGroup => 'IFD0',
     838        Protected => 1,
     839    },
     840    0xc6f4 => {             # ProfileCalibrationSig
     841        Writable => 'string',
     842        WriteGroup => 'IFD0',
     843        Protected => 1,
     844    },
     845    0xc6f6 => {             # AsShotProfileName
     846        Writable => 'string',
     847        WriteGroup => 'IFD0',
     848        Protected => 1,
     849    },
     850    0xc6f7 => {             # NoiseReductionApplied
     851        Writable => 'rational64u',
     852        WriteGroup => 'SubIFD',
     853        Protected => 1,
     854    },
     855    0xc6f8 => {             # ProfileName
     856        Writable => 'string',
     857        WriteGroup => 'IFD0',
     858        Protected => 1,
     859    },
     860    0xc6f9 => {             # ProfileHueSatMapDims
     861        Writable => 'int32u',
     862        Count => 3,
     863        WriteGroup => 'IFD0',
     864        Protected => 1,
     865    },
     866    0xc6fa => {             # ProfileHueSatMapData1
     867        Writable => 'float',
     868        Count => -1,
     869        WriteGroup => 'IFD0',
     870        Protected => 1,
     871    },
     872    0xc6fb => {             # ProfileHueSatMapData2
     873        Writable => 'float',
     874        Count => -1,
     875        WriteGroup => 'IFD0',
     876        Protected => 1,
     877    },
     878    0xc6fc => {             # ProfileToneCurve
     879        Writable => 'float',
     880        Count => -1,
     881        WriteGroup => 'IFD0',
     882        Protected => 1,
     883    },
     884    0xc6fd => {             # ProfileEmbedPolicy
     885        Writable => 'int32u',
     886        WriteGroup => 'IFD0',
     887        Protected => 1,
     888    },
     889    0xc6fe => {             # ProfileCopyright
     890        Writable => 'string',
     891        WriteGroup => 'IFD0',
     892        Protected => 1,
     893    },
     894    0xc714 => {             # ForwardMatrix1
     895        Writable => 'rational64s',
     896        Count => -1,
     897        WriteGroup => 'IFD0',
     898        Protected => 1,
     899    },
     900    0xc715 => {             # ForwardMatrix2
     901        Writable => 'rational64s',
     902        Count => -1,
     903        WriteGroup => 'IFD0',
     904        Protected => 1,
     905    },
     906    0xc716 => {             # PreviewApplicationName
     907        Writable => 'string',
     908        WriteGroup => 'IFD0',
     909        Protected => 1,
     910    },
     911    0xc717 => {             # PreviewApplicationVersion
     912        Writable => 'string',
     913        WriteGroup => 'IFD0',
     914        Protected => 1,
     915    },
     916    0xc718 => {             # PreviewSettingsName
     917        Writable => 'string',
     918        WriteGroup => 'IFD0',
     919        Protected => 1,
     920    },
     921    0xc719 => {             # PreviewSettingsDigest
     922        Writable => 'int8u',
     923        WriteGroup => 'IFD0',
     924        Protected => 1,
     925        ValueConvInv => 'pack("H*", $val)',
     926    },
     927    0xc71a => {             # PreviewColorSpace
     928        Writable => 'int32u',
     929        WriteGroup => 'IFD0',
     930        Protected => 1,
     931        PrintConv => {
     932            0 => 'Unknown',
     933            1 => 'Gray Gamma 2.2',
     934            2 => 'sRGB',
     935            3 => 'Adobe RGB',
     936            4 => 'ProPhoto RGB',
     937        },
     938    },
     939    0xc71b => {             # PreviewDateTime
     940        Writable => 'string',
     941        WriteGroup => 'IFD0',
     942        Protected => 1,
     943        ValueConvInv => q{
     944            require Image::ExifTool::XMP;
     945            return Image::ExifTool::XMP::FormatXMPDate($val);
     946        },
     947        PrintConvInv => '$self->InverseDateTime($val,1,1)',
     948    },
     949    0xc71c => {             # RawImageDigest
     950        Writable => 'int8u',
     951        WriteGroup => 'IFD0',
     952        Protected => 1,
     953        ValueConvInv => 'pack("H*", $val)',
     954    },
     955    0xc71d => {             # OriginalRawFileDigest
     956        Writable => 'int8u',
     957        WriteGroup => 'IFD0',
     958        Protected => 1,
     959        ValueConvInv => 'pack("H*", $val)',
     960    },
     961    0xc725 => {             # ProfileLookTableDims
     962        Writable => 'int32u',
     963        Count => 3,
     964        WriteGroup => 'IFD0',
     965        Protected => 1,
     966    },
     967    0xc726 => {             # ProfileLookTableData
     968        Writable => 'float',
    678969        Count => -1,
    679970        WriteGroup => 'IFD0',
     
    692983        ValueConvInv => q{"Owner's Name: $val"},
    693984        Notes => q{
    694             tags 0xfde8-0xfe58 are generated by Photoshop Camera RAW -- some
    695             names are the same as other EXIF tags, but ExifTool will avoid
    696             writing these unless they already exist in the file
     985            tags 0xfde8-0xfdea and 0xfe4c-0xfe58 are generated by Photoshop Camera RAW.
     986            Some names are the same as other EXIF tags, but ExifTool will avoid writing
     987            these unless they already exist in the file
    697988        },
    698989    },
     
    7911082
    7921083# insert our writable properties into main EXIF tag table
    793 InsertWritableProperties('Image::ExifTool::Exif::Main', \%writeTable, \&CheckExif);
     1084InsertWritableProperties(\%Image::ExifTool::Exif::Main, \%writeTable, \&CheckExif);
    7941085
    7951086#------------------------------------------------------------------------------
    796 # Change date/time string to standard EXIF formatting
    797 # Inputs: 0) Date/Time string
    798 # Returns: formatted date/time string (or undef and issues warning on error)
    799 sub ExifDateTime($)
     1087# Inverse print conversion for LensInfo
     1088# Inputs: 0) lens info string
     1089# Returns: PrintConvInv of string
     1090sub ConvertLensInfo($)
    8001091{
    8011092    my $val = shift;
    802     my $rtnVal;
    803     if ($val =~ /(\d{4})/g) {           # get YYYY
    804         my $yr = $1;
    805         my @a = ($val =~ /\d{2}/g);     # get MM, DD, and maybe hh, mm, ss
    806         if (@a >= 2) {
    807             push @a, '00' while @a < 5; # add hh, mm, ss if not given
    808             # construct properly formatted date/time string
    809             $rtnVal = "$yr:$a[0]:$a[1] $a[2]:$a[3]:$a[4]";
    810         }
    811     }
    812     $rtnVal or warn "Improperly formatted date/time\n";
    813     return $rtnVal;
     1093    my @a = GetLensInfo($val, 1); # (allow unknown "?" values)
     1094    return @a ? join(' ', @a) : $val;
    8141095}
    8151096
     
    8441125#------------------------------------------------------------------------------
    8451126# validate raw values for writing
    846 # Inputs: 0) ExifTool object reference, 1) tagInfo hash reference,
    847 #         2) raw value reference
     1127# Inputs: 0) ExifTool ref, 1) tagInfo hash ref, 2) raw value ref
    8481128# Returns: error string or undef (and possibly changes value) on success
    8491129sub CheckExif($$$)
    8501130{
    8511131    my ($exifTool, $tagInfo, $valPtr) = @_;
    852     my $format = $$tagInfo{Format} || $$tagInfo{Writable} || $tagInfo->{Table}->{WRITABLE};
     1132    my $format = $$tagInfo{Format} || $$tagInfo{Writable} || $tagInfo->{Table}{WRITABLE};
    8531133    if (not $format or $format eq '1') {
    854         if ($tagInfo->{Groups}->{0} eq 'MakerNotes') {
     1134        if ($tagInfo->{Groups}{0} eq 'MakerNotes') {
    8551135            return undef;   # OK to have no format for makernotes
    8561136        } else {
     
    8651145# Inputs: 0) ExifTool ref, 1) text string
    8661146# Returns: encoded string
     1147# Note: MUST be called Raw conversion time so the EXIF byte order is known!
    8671148sub EncodeExifText($$)
    8681149{
     
    8701151    # does the string contain special characters?
    8711152    if ($val =~ /[\x80-\xff]/) {
    872         return "UNICODE\0" . $exifTool->Charset2Unicode($val);
     1153        my $order = $exifTool->GetNewValues('ExifUnicodeByteOrder');
     1154        return "UNICODE\0" . $exifTool->Encode($val,'UCS2',$order);
    8731155    } else {
    8741156        return "ASCII\0\0\0$val";
     
    8781160#------------------------------------------------------------------------------
    8791161# insert writable properties into main tag table
    880 # Inputs: 0) tag table name, 1) reference to writable properties
     1162# Inputs: 0) tag table ref, 1) reference to writable properties
    8811163#         2) [optional] CHECK_PROC reference
    8821164sub InsertWritableProperties($$;$)
    8831165{
    884     my ($tableName, $writeTablePtr, $checkProc) = @_;
     1166    my ($tagTablePtr, $writeTablePtr, $checkProc) = @_;
    8851167    my $tag;
    886     my $tagTablePtr = GetTagTable($tableName);
    8871168    $checkProc and $tagTablePtr->{CHECK_PROC} = $checkProc;
    8881169    foreach $tag (keys %$writeTablePtr) {
     
    8951176                    my $key;
    8961177                    foreach $key (%$writeInfo) {
    897                         $$tagInfo{$key} = $$writeInfo{$key};
     1178                        $$tagInfo{$key} = $$writeInfo{$key} unless defined $$tagInfo{$key};
    8981179                    }
    8991180                } else {
    900                     $$tagInfo{Writable} = $writeInfo;
     1181                    $$tagInfo{Writable} = $writeInfo unless defined $$tagInfo{Writable};
    9011182                }
    9021183            }
     
    9101191# rebuild maker notes to properly contain all value data
    9111192# (some manufacturers put value data outside maker notes!!)
    912 # Inputs: 0) ExifTool object reference, 1) tag table reference,
    913 #         2) dirInfo reference
     1193# Inputs: 0) ExifTool object ref, 1) tag table ref, 2) dirInfo ref
    9141194# Returns: new maker note data (and creates MAKER_NOTE_FIXUP), or undef on error
    9151195sub RebuildMakerNotes($$$)
     
    9251205    delete $exifTool->{MAKER_NOTE_FIXUP};
    9261206
    927     # don't need to rebuild text or binary-data maker notes
     1207    # don't need to rebuild text, BinaryData or PreviewImage maker notes
    9281208    my $tagInfo = $$dirInfo{TagInfo};
    9291209    my $subdir = $$tagInfo{SubDirectory};
    9301210    my $proc = $$subdir{ProcessProc} || $$tagTablePtr{PROCESS_PROC} || \&ProcessExif;
    9311211    if (($proc ne \&ProcessExif and $$tagInfo{Name} =~ /Text/) or
    932          $proc eq \&Image::ExifTool::ProcessBinaryData)
     1212         $proc eq \&Image::ExifTool::ProcessBinaryData or
     1213        ($$tagInfo{PossiblePreview} and $dirLen > 6 and
     1214         substr($$dataPt, $dirStart, 3) eq "\xff\xd8\xff"))
    9331215    {
    9341216        return substr($$dataPt, $dirStart, $dirLen);
     
    9401222        # create new exiftool object to rewrite the directory without changing it
    9411223        my $newTool = new Image::ExifTool;
     1224        $newTool->Init();   # must do this before calling WriteDirectory()!
    9421225        # don't copy over preview image
    9431226        $newTool->SetNewValue(PreviewImage => '');
    9441227        # copy all transient members over in case they are used for writing
    945         # (CameraMake, CameraModel, etc)
     1228        # (Make, Model, etc)
    9461229        foreach (grep /[a-z]/, keys %$exifTool) {
    9471230            $$newTool{$_} = $$exifTool{$_};
     
    9491232        # fix base offsets if specified
    9501233        $newTool->Options(FixBase => $exifTool->Options('FixBase'));
    951         # set FILE_TYPE to JPEG so PREVIEW_INFO will be generated
    952         $newTool->{FILE_TYPE} = 'JPEG';
     1234        # set GENERATE_PREVIEW_INFO flag so PREVIEW_INFO will be generated
     1235        $newTool->{GENERATE_PREVIEW_INFO} = 1;
    9531236        # drop any large tags
    9541237        $newTool->{DROP_TAGS} = 1;
     1238        # initialize other necessary data members
     1239        $newTool->{FILE_TYPE} = $exifTool->{FILE_TYPE};
     1240        $newTool->{TIFF_TYPE} = $exifTool->{TIFF_TYPE};
    9551241        # rewrite maker notes
    9561242        $rtnValue = $newTool->WriteDirectory(\%subdirInfo, $tagTablePtr);
    9571243        if (defined $rtnValue and length $rtnValue) {
    958             # add the dummy preview image if necessary
     1244            # add the dummy/empty preview image if necessary
    9591245            if ($newTool->{PREVIEW_INFO}) {
    9601246                $makerFixup->SetMarkerPointers(\$rtnValue, 'PreviewImage', length($rtnValue));
    961                 $rtnValue .= $newTool->{PREVIEW_INFO}->{Data};
     1247                $rtnValue .= $newTool->{PREVIEW_INFO}{Data};
    9621248                delete $newTool->{PREVIEW_INFO};
    9631249            }
    9641250            # add makernote header
    965             $loc and $rtnValue = substr($$dataPt, $dirStart, $loc) . $rtnValue;
    966             # adjust fixup for shift in start position
    967             $makerFixup->{Start} += $loc;
     1251            if ($loc) {
     1252                my $hdr = substr($$dataPt, $dirStart, $loc);
     1253                # special case: convert Pentax/Samsung DNG maker notes to JPEG style
     1254                # (in JPEG, Pentax makernotes are absolute and start with "AOC\0")
     1255                if ($hdr =~ s/^(PENTAX |SAMSUNG)\0/AOC\0/) {
     1256                    # save fixup so we will adjust to absolute offsets when writing
     1257                    $exifTool->{MAKER_NOTE_FIXUP} = $makerFixup;
     1258                }
     1259                $rtnValue = $hdr . $rtnValue;
     1260                # adjust fixup for shift in start position
     1261                $makerFixup->{Start} += length $hdr;
     1262            }
    9681263            # shift offsets according to original position of maker notes,
    9691264            # and relative to the makernotes Base
     
    9741269            # fix up pointers to the specified offset
    9751270            $makerFixup->ApplyFixup(\$rtnValue);
    976         }
    977         # save fixup information unless offsets were relative
    978         unless ($subdirInfo{Relative}) {
    979             # set shift so offsets are all relative to start of maker notes
    980             $makerFixup->{Shift} -= $dataPos + $dirStart;
    981             $exifTool->{MAKER_NOTE_FIXUP} = $makerFixup;    # save fixup for later
     1271            # save fixup information unless offsets were relative
     1272            unless ($subdirInfo{Relative}) {
     1273                # set shift so offsets are all relative to start of maker notes
     1274                $makerFixup->{Shift} -= $dataPos + $dirStart;
     1275                $exifTool->{MAKER_NOTE_FIXUP} = $makerFixup;    # save fixup for later
     1276            }
    9821277        }
    9831278    }
     
    9951290    my ($index, %entries);
    9961291    # split the directory into separate entries
    997     my ($padding, $newDir) = ('','');
     1292    my $newDir = '';
    9981293    for ($index=0; $index<$numEntries; ++$index) {
    9991294        my $entry = $dirStart + 2 + 12 * $index;
     
    10031298        $tagID = 0x10000 unless $tagID or $index == 0;
    10041299        # add new entry (allow for duplicate tag ID's, which shouldn't normally happen)
    1005         $entries{$tagID} or $entries{$tagID} = '';
    1006         $entries{$tagID} .= $entryData;
     1300        if ($entries{$tagID}) {
     1301            $entries{$tagID} .= $entryData;
     1302        } else {
     1303            $entries{$tagID} = $entryData;
     1304        }
    10071305    }
    10081306    # sort the directory entries
     
    10121310    }
    10131311    # replace original directory with new, sorted one
    1014     substr($$dataPt, $dirStart + 2, 12 * $numEntries) = $newDir . $padding;
     1312    substr($$dataPt, $dirStart + 2, 12 * $numEntries) = $newDir;
    10151313}
    10161314
     
    10361334        my $entry = 12 * $index;
    10371335        my $tagID = Get16u(\$buff, $entry);
    1038         $tagID > $lastID or return 0;
     1336        $tagID > $lastID or $$dirInfo{AllowOutOfOrderTags} or return 0;
    10391337        my $format = Get16u(\$buff, $entry+2);
    10401338        $format > 0 and $format <= 13 or return 0;
     
    10441342    }
    10451343    return 1;
     1344}
     1345
     1346#------------------------------------------------------------------------------
     1347# Get sorted list of offsets used in IFD
     1348# Inputs: 0) data ref, 1) directory start, 2) dataPos, 3) IFD entries, 4) tag table ref
     1349# Returns: 0) sorted list of offsets (only offsets after the end of the IFD)
     1350#          1) hash of list indices keyed by offset value
     1351# Notes: This is used in a patch to fix the count for tags in Kodak SubIFD3
     1352sub GetOffList($$$$$)
     1353{
     1354    my ($dataPt, $dirStart, $dataPos, $numEntries, $tagTablePtr) = @_;
     1355    my $ifdEnd = $dirStart + 2 + 12 * $numEntries + $dataPos;
     1356    my ($index, $offset, %offHash);
     1357    for ($index=0; $index<$numEntries; ++$index) {
     1358        my $entry = $dirStart + 2 + 12 * $index;
     1359        my $format = Get16u($dataPt, $entry + 2);
     1360        next if $format < 1 or $format > 13;
     1361        my $count = Get16u($dataPt, $entry + 4);
     1362        my $size = $formatSize[$format] * $count;
     1363        if ($size <= 4) {
     1364            my $tagID = Get16u($dataPt, $entry);
     1365            next unless ref $$tagTablePtr{$tagID} eq 'HASH' and $$tagTablePtr{$tagID}{FixCount};
     1366        }
     1367        my $offset = Get16u($dataPt, $entry + 8);
     1368        $offHash{$offset} = 1 if $offset >= $ifdEnd;
     1369    }
     1370    # set offset hash values to indices in list
     1371    my @offList = sort keys %offHash;
     1372    $index = 0;
     1373    foreach $offset (@offList) {
     1374        $offHash{$offset} = $index++;
     1375    }
     1376    return(\@offList, \%offHash);
    10461377}
    10471378
     
    10611392#------------------------------------------------------------------------------
    10621393# Handle error while writing EXIF
    1063 # Inputs: 0) ExifTool ref, 1) error string, 2) flag set for minor error
     1394# Inputs: 0) ExifTool ref, 1) error string, 2) tag table ref
    10641395# Returns: undef on fatal error, or '' if minor error is ignored
    10651396sub ExifErr($$$)
    10661397{
    1067     my ($exifTool, $errStr, $minor) = @_;
     1398    my ($exifTool, $errStr, $tagTablePtr) = @_;
     1399    # MakerNote errors are minor by default
     1400    my $minor = ($tagTablePtr->{GROUPS}{0} eq 'MakerNotes');
     1401    if ($tagTablePtr->{VARS} and $tagTablePtr->{VARS}{MINOR_ERRORS}) {
     1402        $exifTool->Warn("$errStr. IFD dropped.") and return '' if $minor;
     1403        $minor = 1;
     1404    }
    10681405    return undef if $exifTool->Error($errStr, $minor);
    10691406    return '';
     
    10711408
    10721409#------------------------------------------------------------------------------
     1410# Read/Write IFD with TIFF-like header (used by DNG 1.2)
     1411# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
     1412# Returns: Reading: 1 on success, otherwise returns 0 and sets a Warning
     1413#          Writing: new data block or undef on error
     1414sub ProcessTiffIFD($$$)
     1415{
     1416    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     1417    $exifTool or return 1;    # allow dummy access
     1418    my $raf = $$dirInfo{RAF};
     1419    my $base = $$dirInfo{Base} || 0;
     1420    my $dirName = $$dirInfo{DirName};
     1421    my $magic = $dirInfo->{Subdir}{Magic} || 0x002a;
     1422    my $buff;
     1423
     1424    # structured with a TIFF-like header and relative offsets
     1425    $raf->Seek($base, 0) and $raf->Read($buff, 8) == 8 or return 0;
     1426    unless (SetByteOrder(substr($buff,0,2)) and Get16u(\$buff, 2) == $magic) {
     1427        my $msg = "Invalid $dirName header";
     1428        if ($$dirInfo{IsWriting}) {
     1429            $exifTool->Error($msg);
     1430            return undef;
     1431        } else {
     1432            $exifTool->Warn($msg);
     1433            return 0;
     1434        }
     1435    }
     1436    my $offset = Get32u(\$buff, 4);
     1437    my %dirInfo = (
     1438        DirName  => $$dirInfo{DirName},
     1439        Parent   => $$dirInfo{Parent},
     1440        Base     => $base,
     1441        DataPt   => \$buff,
     1442        DataLen  => length $buff,
     1443        DataPos  => 0,
     1444        DirStart => $offset,
     1445        DirLen   => length($buff) - $offset,
     1446        RAF      => $raf,
     1447        NewDataPos => 8,
     1448    );
     1449    if ($$dirInfo{IsWriting}) {
     1450        # rewrite the Camera Profile IFD
     1451        my $newDir = WriteExif($exifTool, \%dirInfo, $tagTablePtr);
     1452        # don't add header if error writing directory ($newDir is undef)
     1453        # or if directory is being deleted ($newDir is empty)
     1454        return $newDir unless $newDir;
     1455        # return directory with TIFF-like header
     1456        return GetByteOrder() . Set16u($magic) . Set32u(8) . $newDir;
     1457    }
     1458    if ($exifTool->{HTML_DUMP}) {
     1459        my $tip = sprintf("Byte order: %s endian\nIdentifier: 0x%.4x\n%s offset: 0x%.4x",
     1460                          (GetByteOrder() eq 'II') ? 'Little' : 'Big', $magic, $dirName, $offset);
     1461        $exifTool->HDump($base, 8, "$dirName header", $tip, 0);
     1462    }
     1463    return ProcessExif($exifTool, \%dirInfo, $tagTablePtr);
     1464}
     1465
     1466#------------------------------------------------------------------------------
    10731467# Write EXIF directory
    1074 # Inputs: 0) ExifTool object reference, 1) source dirInfo reference,
    1075 #         2) tag table reference
     1468# Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref
    10761469# Returns: Exif data block (may be empty if no Exif data) or undef on error
    10771470# Notes: Increments ExifTool CHANGED flag for each tag changed.  Also updates
     
    10861479{
    10871480    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    1088     $exifTool or return 1;    # allow dummy access to autoload this package
     1481    $exifTool or return 1;      # allow dummy access to autoload this package
     1482    my $origDirInfo = $dirInfo; # save original dirInfo
    10891483    my $dataPt = $$dirInfo{DataPt};
    10901484    unless ($dataPt) {
     
    11011495    my $dirName = $$dirInfo{DirName} || 'unknown';
    11021496    my $fixup = $$dirInfo{Fixup} || new Image::ExifTool::Fixup;
     1497    my $imageDataFlag = $$dirInfo{ImageData} || '';
    11031498    my $verbose = $exifTool->Options('Verbose');
    11041499    my $out = $exifTool->Options('TextOut');
     1500    my ($nextIfdPos, %offsetData, $inMakerNotes);
    11051501    my (@offsetInfo, %xDelete);
     1502    my $deleteAll = 0;
    11061503    my $newData = '';   # initialize buffer to receive new directory data
    1107     my ($nextIfdPos, %offsetData, $inMakerNotes);
    1108     my $deleteAll = 0;
     1504    my @imageData;      # image data blocks to copy later if requested
     1505    my $name = $$dirInfo{Name};
     1506    $name = $dirName unless $name and $dirName eq 'MakerNotes' and $name !~ /^MakerNote/;
    11091507
    11101508    # allow multiple IFD's in IFD0-IFD1-IFD2... chain
    1111     $$dirInfo{Multi} = 1 if $dirName eq 'IFD0' or $dirName eq 'SubIFD';
    1112     $inMakerNotes = 1 if $tagTablePtr->{GROUPS}->{0} eq 'MakerNotes';
     1509    $$dirInfo{Multi} = 1 if $dirName =~ /^(IFD0|SubIFD)$/ and not defined $$dirInfo{Multi};
     1510    $inMakerNotes = 1 if $tagTablePtr->{GROUPS}{0} eq 'MakerNotes';
    11131511    my $ifd;
    11141512#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     
    11171515    for ($ifd=0; ; ++$ifd) {  # loop through multiple IFD's
    11181516
     1517        # save pointer to start of this IFD within the newData
     1518        my $newStart = length($newData);
     1519        my @subdirs;    # list of subdirectory data and tag table pointers
     1520        # determine if directory is contained within our data
     1521        my $mustRead;
     1522        if ($dirStart < 0 or $dirStart > $dataLen-2) {
     1523            $mustRead = 1;
     1524        } elsif ($dirLen > 2) {
     1525            my $len = 2 + 12 * Get16u($dataPt, $dirStart);
     1526            $mustRead = 1 if $dirStart + $len > $dataLen;
     1527        }
     1528        # read IFD from file if necessary
     1529        if ($mustRead) {
     1530            if ($raf) {
     1531                # read the count of entries in this IFD
     1532                my $offset = $dirStart + $dataPos;
     1533                my ($buff, $buf2);
     1534                unless ($raf->Seek($offset + $base, 0) and $raf->Read($buff,2) == 2) {
     1535                    return ExifErr($exifTool, "Bad IFD or truncated file in $name", $tagTablePtr);
     1536                }
     1537                my $len = 12 * Get16u(\$buff,0);
     1538                # (also read next IFD pointer if available)
     1539                unless ($raf->Read($buf2, $len+4) >= $len) {
     1540                    return ExifErr($exifTool, "Error reading $name", $tagTablePtr);
     1541                }
     1542                $buff .= $buf2;
     1543                # make copy of dirInfo since we're going to modify it
     1544                my %newDirInfo = %$dirInfo;
     1545                $dirInfo = \%newDirInfo;
     1546                # update directory parameters for the newly loaded IFD
     1547                $dataPt = $$dirInfo{DataPt} = \$buff;
     1548                $dirStart = $$dirInfo{DirStart} = 0;
     1549                $dataPos = $$dirInfo{DataPos} = $offset;
     1550                $dataLen = $$dirInfo{DataLen} = length $buff;
     1551                $dirLen = $$dirInfo{DirLen} = $dataLen;
     1552                # only account for nextIFD pointer if we are going to use it
     1553                $len += 4 if $dataLen==$len+6 and ($$dirInfo{Multi} or $buff =~ /\0{4}$/);
     1554                UpdateTiffEnd($exifTool, $offset+$base+2+$len);
     1555            } elsif ($dirLen) {
     1556                # error if we can't load IFD (unless we are creating
     1557                # from scratch, in which case dirLen will be zero)
     1558                my $str = $exifTool->Options('IgnoreMinorErrors') ? 'Deleted bad' : 'Bad';
     1559                $exifTool->Error("$str $name directory", 1);
     1560            }
     1561        }
     1562        my ($index, $dirEnd, $numEntries);
     1563        if ($dirStart + 4 < $dataLen) {
     1564            $numEntries = Get16u($dataPt, $dirStart);
     1565            $dirEnd = $dirStart + 2 + 12 * $numEntries;
     1566            if ($dirEnd > $dataLen) {
     1567                return ExifErr($exifTool, "Truncated $name directory", $tagTablePtr);
     1568            }
     1569            # sort entries if necessary (but not in maker notes IFDs)
     1570            unless ($inMakerNotes) {
     1571                my $lastID = -1;
     1572                for ($index=0; $index<$numEntries; ++$index) {
     1573                    my $tagID = Get16u($dataPt, $dirStart + 2 + 12 * $index);
     1574                    # check for proper sequence (but ignore null entries at end)
     1575                    if ($tagID < $lastID and $tagID) {
     1576                        SortIFD($dataPt, $dirStart, $numEntries);
     1577                        $exifTool->Warn("Entries in $name were out of sequence. Fixed.",1);
     1578                        last;
     1579                    }
     1580                    $lastID = $tagID;
     1581                }
     1582            }
     1583        } else {
     1584            $numEntries = 0;
     1585            $dirEnd = $dirStart;
     1586        }
     1587
    11191588        # loop through new values and accumulate all information for this IFD
    11201589        my (%set, $tagInfo);
    1121         my $tableGroup = $tagTablePtr->{GROUPS}->{0};
    11221590        my $wrongDir = $crossDelete{$dirName};
    11231591        foreach $tagInfo ($exifTool->GetNewTagInfoList($tagTablePtr)) {
     
    11341602                    }
    11351603                    if (defined $val) {
    1136                         $curInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$val,
    1137                                         $$tagInfo{Format} || 'undef', $$tagInfo{Count} || 1);
     1604                        my $fmt = $$tagInfo{Writable} || $$tagInfo{Format} || 'undef';
     1605                        my $cnt = $$tagInfo{Count} || 1;
     1606                        # always use old format/count for Condition in maker notes
     1607                        if ($inMakerNotes) {
     1608                            for ($index=0; $index<$numEntries; ++$index) {
     1609                                my $entry = $dirStart + 2 + 12 * $index;
     1610                                my $id = Get16u($dataPt, $entry);
     1611                                if ($id eq $tagID) {
     1612                                    my $f = Get16u($dataPt, $entry + 2);
     1613                                    if ($formatName[$f]) {
     1614                                        $fmt = $formatName[$f];
     1615                                        $cnt = Get32u($dataPt, $entry + 4);
     1616                                    }
     1617                                    last;
     1618                                }
     1619                            }
     1620                        }
     1621                        $curInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$val, $fmt, $cnt);
    11381622                    }
    11391623                }
     
    11491633                }
    11501634            }
    1151             my $newValueHash = $exifTool->GetNewValueHash($tagInfo, $dirName);
    1152             unless ($newValueHash) {
     1635            my $nvHash = $exifTool->GetNewValueHash($tagInfo, $dirName);
     1636            unless ($nvHash) {
    11531637                next unless $wrongDir;
    11541638                # delete stuff from the wrong directory if setting somewhere else
    1155                 $newValueHash = $exifTool->GetNewValueHash($tagInfo, $wrongDir);
    1156                 next unless Image::ExifTool::IsOverwriting($newValueHash);
     1639                $nvHash = $exifTool->GetNewValueHash($tagInfo, $wrongDir);
     1640                next unless Image::ExifTool::IsOverwriting($nvHash);
    11571641                # don't cross delete if specifically deleting from the other directory
    1158                 my $val = Image::ExifTool::GetNewValues($newValueHash);
    1159                 next if not defined $val and $newValueHash->{WantGroup} and
    1160                         lc($newValueHash->{WantGroup}) eq lc($wrongDir);
     1642                my $val = Image::ExifTool::GetNewValues($nvHash);
     1643                next if not defined $val and $nvHash->{WantGroup} and
     1644                        lc($nvHash->{WantGroup}) eq lc($wrongDir);
    11611645                # remove this tag if found in this IFD
    11621646                $xDelete{$tagID} = 1;
    11631647            }
    1164             $set{$tagID} = $tagInfo;
    1165         }
    1166         # save pointer to start of this IFD within the newData
    1167         my $newStart = length($newData);
    1168         my @subdirs;    # list of subdirectory data and tag table pointers
    1169         # determine if directory is contained within our data
    1170         my $mustRead;
    1171         if ($dirStart < 0 or $dirStart > $dataLen-2) {
    1172             $mustRead = 1;
    1173         } elsif ($dirLen > 2) {
    1174             my $len = 2 + 12 * Get16u($dataPt, $dirStart);
    1175             $mustRead = 1 if $dirStart + $len > $dataLen;
    1176         }
    1177         # read IFD from file if necessary
    1178         if ($raf and $mustRead) {
    1179             # read the count of entries in this IFD
    1180             my $offset = $dirStart + $dataPos;
    1181             my ($buff, $buf2);
    1182             unless ($raf->Seek($offset + $base, 0) and $raf->Read($buff,2) == 2) {
    1183                 return ExifErr($exifTool, "Bad IFD or truncated file in $dirName", $inMakerNotes);
    1184             }
    1185             my $len = 12 * Get16u(\$buff,0);
    1186             # (also read next IFD pointer if available)
    1187             unless ($raf->Read($buf2, $len+4) >= $len) {
    1188                 return ExifErr($exifTool, "Error reading $dirName", $inMakerNotes);
    1189             }
    1190             $buff .= $buf2;
    1191             # make copy of dirInfo since we're going to modify it
    1192             my %newDirInfo = %$dirInfo;
    1193             $dirInfo = \%newDirInfo;
    1194             # update directory parameters for the newly loaded IFD
    1195             $dataPt = $$dirInfo{DataPt} = \$buff;
    1196             $dirStart = $$dirInfo{DirStart} = 0;
    1197             $dataPos = $$dirInfo{DataPos} = $offset;
    1198             $dataLen = $$dirInfo{DataLen} = length $buff;
    1199             $dirLen = $$dirInfo{DirLen} = $dataLen;
    1200             # only account for nextIFD pointer if we are going to use it
    1201             $len += 4 if $dataLen==$len+6 and ($$dirInfo{Multi} or $buff =~ /\0{4}$/);
    1202             UpdateTiffEnd($exifTool, $offset+$base+2+$len);
    1203         }
    1204         my ($len, $numEntries);
    1205         if ($dirStart + 4 < $dataLen) {
    1206             $numEntries = Get16u($dataPt, $dirStart);
    1207             $len = 2 + 12 * $numEntries;
    1208             if ($dirStart + $len > $dataLen) {
    1209                 return ExifErr($exifTool, "Truncated $dirName directory", $inMakerNotes);
    1210             }
    1211             # sort entries if necessary (but not in maker notes IFDs)
    1212             unless ($inMakerNotes) {
    1213                 my $index;
    1214                 my $lastID = -1;
    1215                 for ($index=0; $index<$numEntries; ++$index) {
    1216                     my $tagID = Get16u($dataPt, $dirStart + 2 + 12 * $index);
    1217                     # check for proper sequence (but ignore null entries at end)
    1218                     if ($tagID < $lastID and $tagID) {
    1219                         SortIFD($dataPt, $dirStart, $numEntries);
    1220                         $exifTool->Warn("Entries in $dirName were out of sequence. Fixed.");
    1221                         last;
    1222                     }
    1223                     $lastID = $tagID;
     1648            if ($set{$tagID}) {
     1649                # this tag is being set twice, which can happen if two Condition's
     1650                # were true for this tag.  Hopefully the only case where this can
     1651                # happen is the MakerNotes tag since it may store two very different
     1652                # types of information (MakerNotes and PreviewImage), but we want
     1653                # to store the MakerNotes if both are available
     1654                if ($tagID == 0x927c and $dirName =~ /^(ExifIFD|IFD0)$/) {
     1655                    next if $$tagInfo{Name} eq 'PreviewImage';
     1656                } else {
     1657                    $exifTool->Warn(sprintf("Multiple new values for $name tag 0x%.4x",$tagID));
    12241658                }
    12251659            }
    1226         } else {
    1227             $numEntries = $len = 0;
    1228         }
    1229 
    1230         # fix base offsets
    1231         if ($dirName eq 'MakerNotes' and $$dirInfo{Parent} eq 'ExifIFD' and
     1660            $set{$tagID} = $tagInfo;
     1661        }
     1662       
     1663        # fix base offsets (some cameras incorrectly write maker notes in IFD0)
     1664        if ($dirName eq 'MakerNotes' and $$dirInfo{Parent} =~ /^(ExifIFD|IFD0)$/ and
     1665            $$exifTool{TIFF_TYPE} !~ /^(ARW|SR2)$/ and not $$exifTool{LeicaTrailerPos} and
    12321666            Image::ExifTool::MakerNotes::FixBase($exifTool, $dirInfo))
    12331667        {
     
    12391673        # initialize variables to handle mandatory tags
    12401674        my $mandatory = $mandatory{$dirName};
    1241         my $allMandatory;
     1675        my ($allMandatory, $addMandatory);
    12421676        if ($mandatory) {
    12431677            # use X/Y resolution values from JFIF if available
     
    12491683                $mandatory = \%ifd0Vals;
    12501684            }
    1251             $allMandatory = 0; # initialize to zero
     1685            $allMandatory = $addMandatory = 0; # initialize to zero
    12521686            # add mandatory tags if creating a new directory
    12531687            unless ($numEntries) {
     
    12611695        my ($addDirs, @newTags);
    12621696        if ($inMakerNotes) {
    1263             $addDirs = { };
     1697            $addDirs = { };     # can't currently add new directories in MakerNotes
     1698            # allow non-permanent makernotes tags to be added
     1699            # (note: we may get into trouble if there are too many of these
     1700            #  because we allow out-of-order tags in MakerNote IFD's but our
     1701            #  logic to add new tags relies on ordered entries)
     1702            foreach (keys %set) {
     1703                my $perm = $set{$_}{Permanent};
     1704                push @newTags, $_ if defined $perm and not $perm;
     1705            }
     1706            @newTags = sort { $a <=> $b } @newTags if @newTags > 1;
    12641707        } else {
    12651708            # get a hash of directories we will be writing in this one
     
    12791722        my $dirFixup = new Image::ExifTool::Fixup;
    12801723        my $entryBasedFixup;
    1281         my $index = 0;
    12821724        my $lastTagID = -1;
    1283         my ($oldInfo, $oldFormat, $oldFormName, $oldCount, $oldSize, $oldValue);
     1725        my ($oldInfo, $oldFormat, $oldFormName, $oldCount, $oldSize, $oldValue, $oldImageData);
    12841726        my ($readFormat, $readFormName, $readCount); # format for reading old value(s)
    12851727        my ($entry, $valueDataPt, $valueDataPos, $valueDataLen, $valuePtr, $valEnd);
     1728        my ($offList, $offHash, $ignoreCount, $fixCount);
    12861729        my $oldID = -1;
    12871730        my $newID = -1;
     1731
     1732        # patch for Canon EOS 40D firmware 1.0.4 bug (incorrect directory counts)
     1733        if ($inMakerNotes and $$exifTool{Model} eq 'Canon EOS 40D') {
     1734            my $fmt = Get16u($dataPt, $dirStart + 2 + 12 * ($numEntries - 1) + 2);
     1735            if ($fmt < 1 or $fmt > 13) {
     1736                # adjust the number of directory entries
     1737                --$numEntries;
     1738                $dirEnd -= 12;
     1739                $ignoreCount = 1;
     1740            }
     1741        }
    12881742#..............................................................................
    12891743# loop through entries in new directory
    12901744#
     1745        $index = 0;
    12911746Entry:  for (;;) {
    12921747
     
    13001755                    $readFormat = $oldFormat = Get16u($dataPt, $entry+2);
    13011756                    $readCount = $oldCount = Get32u($dataPt, $entry+4);
     1757                    undef $oldImageData;
    13021758                    if ($oldFormat < 1 or $oldFormat > 13) {
     1759                        # patch to preserve invalid directory entries in SubIFD3 of
     1760                        # various Kodak Z-series cameras (Z812, Z1085IS, Z1275)
     1761                        if ($dirName eq 'MakerNotes' and $$exifTool{Make}=~/KODAK/i and
     1762                            $$dirInfo{Name} and $$dirInfo{Name} eq 'SubIFD3')
     1763                        {
     1764                            $dirBuff .= substr($$dataPt, $entry, 12);
     1765                            goto WroteIt;
     1766                        }
    13031767                        # don't write out null directory entry
    1304                         unless ($oldFormat or $oldCount or not $index) {
    1305                             ++$index;
    1306                             $newID = $oldID;    # pretend we wrote this
     1768                        if ($oldFormat==0 and $index and $oldCount==0) {
     1769                            $ignoreCount = ($ignoreCount || 0) + 1;
    13071770                            # must keep same directory size to avoid messing up our fixed offsets
    13081771                            $dirBuff .= ("\0" x 12) if $$dirInfo{FixBase};
     1772WroteIt:                    ++$index;
     1773                            $newID = $oldID;    # pretend we wrote this
    13091774                            next;
    13101775                        }
    1311                         return ExifErr($exifTool, "Bad format ($oldFormat) for $dirName entry $index", $inMakerNotes);
     1776                        my $msg = "Bad format ($oldFormat) for $name entry $index";
     1777                        return ExifErr($exifTool, $msg, $tagTablePtr);
    13121778                    }
    13131779                    $readFormName = $oldFormName = $formatName[$oldFormat];
     
    13161782                    $valueDataLen = $dataLen;
    13171783                    $valuePtr = $entry + 8;
    1318                     $oldSize = $oldCount * $formatSize[$oldFormat];
    1319                     # must try direct method first so we will get unknown tags too
    1320                     # (this is necessary so we don't miss a tag we want to Drop)
     1784                    # try direct method first for speed
    13211785                    $oldInfo = $$tagTablePtr{$oldID};
    13221786                    if (ref $oldInfo ne 'HASH' or $$oldInfo{Condition}) {
     1787                        # must get unknown tags too
     1788                        # (necessary so we don't miss a tag we want to Drop)
     1789                        my $unk = $exifTool->Options(Unknown => 1);
    13231790                        $oldInfo = $exifTool->GetTagInfo($tagTablePtr, $oldID);
    1324                     }
     1791                        $exifTool->Options(Unknown => $unk);
     1792                    }
     1793                    # patch incorrect count in Kodak SubIFD3 tags
     1794                    if ($oldCount < 2 and $oldInfo and $$oldInfo{FixCount}) {
     1795                        $offList or ($offList, $offHash) = GetOffList($dataPt, $dirStart, $dataPos,
     1796                                                                      $numEntries, $tagTablePtr);
     1797                        my $i = $$offHash{Get32u($dataPt, $valuePtr)};
     1798                        if (defined $i and $i < $#$offList) {
     1799                            $oldCount = int(($$offList[$i+1] - $$offList[$i]) / $formatSize[$oldFormat]);
     1800                            $fixCount = ($fixCount || 0) + 1 if $oldCount != $readCount;
     1801                        }
     1802                    }
     1803                    $oldSize = $oldCount * $formatSize[$oldFormat];
    13251804                    my $readFromFile;
    13261805                    if ($oldSize > 4) {
     
    13301809                            $valEnd or $valEnd = $dataPos + $dirStart + 2 + 12 * $numEntries + 4;
    13311810                            my ($tagID, $size, $wFlag) = ($oldID, $oldSize, 1);
    1332                             #### eval FixOffsets($valuePtr, $valEnd, $size, $tagID, $wFlag)
     1811                            #### eval FixOffsets ($valuePtr, $valEnd, $size, $tagID, $wFlag)
    13331812                            eval $$dirInfo{FixOffsets};
    13341813                            unless (defined $valuePtr) {
    13351814                                unless ($$exifTool{DROP_TAGS}) {
    13361815                                    my $tagStr = $oldInfo ? $$oldInfo{Name} : sprintf("tag 0x%x",$oldID);
    1337                                     return undef if $exifTool->Error("Bad $dirName directory pointer for $tagStr", $inMakerNotes);
     1816                                    return undef if $exifTool->Error("Bad $name offset for $tagStr", $inMakerNotes);
    13381817                                }
    13391818                                goto DropTag;
    13401819                            }
    13411820                        }
     1821                        # offset shouldn't point into TIFF or IFD header
     1822                        my $suspect = ($valuePtr < 8);
    13421823                        # convert offset to pointer in $$dataPt
    13431824                        if ($$dirInfo{EntryBased} or (ref $$tagTablePtr{$oldID} eq 'HASH' and
    1344                             $tagTablePtr->{$oldID}->{EntryBased}))
     1825                            $tagTablePtr->{$oldID}{EntryBased}))
    13451826                        {
    13461827                            $valuePtr += $entry;
     
    13481829                            $valuePtr -= $dataPos;
    13491830                        }
     1831                        # value shouldn't overlap our directory
     1832                        $suspect = 1 if $valuePtr < $dirEnd and $valuePtr+$oldSize > $dirStart;
    13501833                        # get value by seeking in file if we are allowed
    13511834                        if ($valuePtr < 0 or $valuePtr+$oldSize > $dataLen) {
    1352                             my ($pos, $tagStr, $invalidPreview);
     1835                            my ($pos, $tagStr, $invalidPreview, $tmpInfo);
    13531836                            if ($oldInfo) {
    13541837                                $tagStr = $$oldInfo{Name};
    13551838                            } elsif (defined $oldInfo) {
    1356                                 my $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $oldID, \ '', $oldFormName, $oldCount);
     1839                                $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $oldID, \ '', $oldFormName, $oldCount);
    13571840                                $tagStr = $$tmpInfo{Name} if $tmpInfo;
    13581841                            }
    13591842                            $tagStr or $tagStr = sprintf("tag 0x%x",$oldID);
    1360                             # allow PreviewImage to run outside EXIF segment
    1361                             if (not $raf and $tagStr eq 'PreviewImage') {
    1362                                 $raf = $exifTool->{RAF};
    1363                                 if ($raf) {
    1364                                     $pos = $raf->Tell();
    1365                                 } else {
    1366                                     $invalidPreview = 1;
     1843                            # allow PreviewImage to run outside EXIF segment in JPEG images
     1844                            if (not $raf) {
     1845                                if ($tagStr eq 'PreviewImage') {
     1846                                    $raf = $exifTool->{RAF};
     1847                                    if ($raf) {
     1848                                        $pos = $raf->Tell();
     1849                                        if ($oldInfo and $$oldInfo{ChangeBase}) {
     1850                                            # adjust base offset for this tag only
     1851                                            #### eval ChangeBase ($dirStart,$dataPos)
     1852                                            my $newBase = eval $$oldInfo{ChangeBase};
     1853                                            $valuePtr += $newBase;
     1854                                        }
     1855                                    } else {
     1856                                        $invalidPreview = 1;
     1857                                    }
     1858                                } elsif ($tagStr eq 'MakerNoteLeica6') {
     1859                                    # save information about Leica makernote trailer
     1860                                    $$exifTool{LeicaTrailer} = {
     1861                                        TagInfo => $oldInfo || $tmpInfo,
     1862                                        Offset  => $base + $valuePtr + $dataPos,
     1863                                        Size    => $oldSize,
     1864                                    },
     1865                                    $invalidPreview = 2;
     1866                                    # remove SubDirectory to prevent processing (for now)
     1867                                    my %copy = %{$oldInfo || $tmpInfo};
     1868                                    delete $copy{SubDirectory};
     1869                                    delete $copy{MakerNotes};
     1870                                    $oldInfo = \%copy;
    13671871                                }
    13681872                            }
    1369                             if ($raf) {
    1370                                 my $success = ($raf->Seek($base + $valuePtr + $dataPos, 0) and
     1873                            if ($oldSize > BINARY_DATA_LIMIT and $$origDirInfo{ImageData} and
     1874                                (not defined $oldInfo or ($oldInfo and not $$oldInfo{SubDirectory})))
     1875                            {
     1876                                # copy huge data blocks later instead of loading into memory
     1877                                $oldValue = ''; # dummy empty value
     1878                                # copy this value later unless writing a new value
     1879                                unless ($set{$oldID}) {
     1880                                    my $pad = $oldSize & 0x01 ? 1 : 0;
     1881                                    # save block information to copy later (set directory offset later)
     1882                                    $oldImageData = [$base+$valuePtr+$dataPos, $oldSize, $pad];
     1883                                }
     1884                            } elsif ($raf) {
     1885                                my $success = ($raf->Seek($base+$valuePtr+$dataPos, 0) and
    13711886                                               $raf->Read($oldValue, $oldSize) == $oldSize);
    13721887                                if (defined $pos) {
    13731888                                    $raf->Seek($pos, 0);
    13741889                                    undef $raf;
    1375                                     unless ($success and $oldValue =~ /^(\xff\xd8\xff|.\xd8\xff\xdb)/s) {
    1376                                         $exifTool->Error("Bad PreviewImage pointer in $dirName", 1);
     1890                                    # (sony A700 has 32-byte header on PreviewImage)
     1891                                    unless ($success and $oldValue =~ /^(\xff\xd8\xff|(.|.{33})\xd8\xff\xdb)/s) {
    13771892                                        $invalidPreview = 1;
    1378                                         $success = 1;   # continue writing directory
     1893                                        $success = 1;   # continue writing directory anyway
    13791894                                    }
    13801895                                }
    13811896                                unless ($success) {
    1382                                     return undef if $exifTool->Error("Error reading value for $dirName entry $index", $inMakerNotes);
     1897                                    return undef if $exifTool->Error("Error reading value for $name entry $index", $inMakerNotes);
    13831898                                    goto DropTag;
    13841899                                }
    13851900                            } elsif (not $invalidPreview) {
    1386                                 return undef if $exifTool->Error("Bad $dirName directory pointer for $tagStr", $inMakerNotes);
     1901                                return undef if $exifTool->Error("Bad $name offset for $tagStr", $inMakerNotes);
    13871902                                goto DropTag;
    13881903                            }
    13891904                            if ($invalidPreview) {
    1390                                 $oldValue = 'none';     # flag for missing preview
    1391                                 $oldSize = length $oldValue;
     1905                                # set value for invalid preview
     1906                                if ($exifTool->{FILE_TYPE} eq 'JPEG') {
     1907                                    # define dummy value for preview (or Leica MakerNote) to write later
     1908                                    # (value must be larger than 4 bytes to generate PREVIEW_INFO,
     1909                                    # and an even number of bytes so it won't be padded)
     1910                                    $oldValue = 'LOAD_PREVIEW';
     1911                                } else {
     1912                                    $oldValue = 'none';
     1913                                    $oldSize = length $oldValue;
     1914                                }
    13921915                                $valuePtr = 0;
    13931916                            } else {
     
    14011924                            $readFromFile = 1;
    14021925                        }
     1926                        if ($suspect) {
     1927                            my $tagStr = $oldInfo ? $$oldInfo{Name} : sprintf('tag 0x%.4x', $oldID);
     1928                            my $str = "Suspicious $name offset for $tagStr";
     1929                            if ($inMakerNotes) {
     1930                                $exifTool->Warn($str, 1);
     1931                            } else {
     1932                                return undef if $exifTool->Error($str, 1);
     1933                            }
     1934                        }
    14031935                    }
    14041936                    # read value if we haven't already
     
    14061938                    # get tagInfo using value if necessary
    14071939                    if (defined $oldInfo and not $oldInfo) {
     1940                        my $unk = $exifTool->Options(Unknown => 1);
    14081941                        $oldInfo = $exifTool->GetTagInfo($tagTablePtr, $oldID, \$oldValue, $oldFormName, $oldCount);
     1942                        $exifTool->Options(Unknown => $unk);
     1943                    }
     1944                    # make sure we are handling the 'ifd' format properly
     1945                    if (($oldFormat == 13 or $oldFormat == 18) and
     1946                        (not $oldInfo or not $$oldInfo{SubIFD}))
     1947                    {
     1948                        my $str = sprintf('%s tag 0x%.4x IFD format not handled', $name, $oldID);
     1949                        $exifTool->Error($str, $inMakerNotes);
    14091950                    }
    14101951                    # override format we use to read the value if specified
    14111952                    if ($oldInfo) {
     1953                        # check for tags which must be integers
     1954                        if (($$oldInfo{IsOffset} or $$oldInfo{SubIFD}) and
     1955                            not $intFormat{$oldFormName})
     1956                        {
     1957                            $exifTool->Error("Invalid format ($oldFormName) for $name $$oldInfo{Name}", $inMakerNotes);
     1958                            goto DropTag;
     1959                        }
    14121960                        if ($$oldInfo{Drop} and $$exifTool{DROP_TAGS}) {
    14131961                            # don't rewrite this tag
     
    14311979                        my $str = $oldInfo ? "$$oldInfo{Name} tag" : sprintf('tag 0x%x',$oldID);
    14321980                        if ($oldID == $lastTagID) {
    1433                             $exifTool->Warn("Duplicate $str in $dirName");;
     1981                            $exifTool->Warn("Duplicate $str in $name");;
    14341982                        } else {
    1435                             $exifTool->Warn("\u$str out of sequence in $dirName");
     1983                            $exifTool->Warn("\u$str out of sequence in $name");
    14361984                        }
    14371985                    }
     
    14792027                    $newInfo = $set{$newID};
    14802028                    $newCount = $$newInfo{Count};
    1481                     my ($val, $newVal);
    1482                     my $newValueHash = $exifTool->GetNewValueHash($newInfo, $dirName);
     2029                    my ($val, $newVal, $n);
     2030                    my $nvHash = $exifTool->GetNewValueHash($newInfo, $dirName);
    14832031                    if ($isNew > 0) {
    14842032                        # don't create new entry unless requested
    1485                         if ($newValueHash) {
    1486                             next unless Image::ExifTool::IsCreating($newValueHash);
    1487                             $isOverwriting = Image::ExifTool::IsOverwriting($newValueHash);
     2033                        if ($nvHash) {
     2034                            next unless Image::ExifTool::IsCreating($nvHash);
     2035                            if ($$newInfo{IsOverwriting}) {
     2036                                my $proc = $$newInfo{IsOverwriting};
     2037                                $isOverwriting = &$proc($exifTool, $nvHash, $val, \$newVal);
     2038                            } else {
     2039                                $isOverwriting = Image::ExifTool::IsOverwriting($nvHash);
     2040                            }
    14882041                        } else {
    14892042                            next if $xDelete{$newID};       # don't create if cross deleting
     
    14992052                            $newFormName = $$newInfo{Writable};
    15002053                            unless ($newFormName) {
    1501                                 warn("No format for $dirName $$newInfo{Name}\n");
     2054                                warn("No format for $name $$newInfo{Name}\n");
    15022055                                next;
    15032056                            }
    15042057                        }
    15052058                        $newFormat = $formatNumber{$newFormName};
    1506                     } elsif ($newValueHash or $xDelete{$newID}) {
    1507                         unless ($newValueHash) {
    1508                             $newValueHash = $exifTool->GetNewValueHash($newInfo, $wrongDir);
     2059                    } elsif ($nvHash or $xDelete{$newID}) {
     2060                        unless ($nvHash) {
     2061                            $nvHash = $exifTool->GetNewValueHash($newInfo, $wrongDir);
    15092062                        }
    15102063                        # read value
    15112064                        $val = ReadValue(\$oldValue, 0, $readFormName, $readCount, $oldSize);
    1512                         if ($$newInfo{Format}) {
    1513                             $newFormName = $$newInfo{Format};
    1514                             # override existing format if necessary
    1515                             $ifdFormName = $$newInfo{Writable};
    1516                             $ifdFormName = $oldFormName unless $ifdFormName and $ifdFormName ne '1';
     2065                        # determine write format (by default, use 'Writable' format)
     2066                        my $writable = $$newInfo{Writable};
     2067                        # (or use existing format if 'Writable' not specified)
     2068                        $writable = $oldFormName unless $writable and $writable ne '1';
     2069                        # (and override write format with 'Format' if specified)
     2070                        my $writeForm = $$newInfo{Format} || $writable;
     2071                        if ($writeForm ne $newFormName) {
     2072                            # write in specified format
     2073                            $newFormName = $writeForm;
    15172074                            $newFormat = $formatNumber{$newFormName};
     2075                            # use different IFD format code if necessary
     2076                            if ($inMakerNotes) {
     2077                                # always preserve IFD format in maker notes
     2078                                $ifdFormName = $oldFormName;
     2079                            } elsif ($writable ne $newFormName) {
     2080                                # use specified IFD format
     2081                                $ifdFormName = $writable;
     2082                            }
    15182083                        }
    15192084                        if ($inMakerNotes and $readFormName ne 'string' and $readFormName ne 'undef') {
     
    15212086                            $newCount = $oldCount * $formatSize[$oldFormat] / $formatSize[$newFormat];
    15222087                        }
    1523                         $isOverwriting = Image::ExifTool::IsOverwriting($newValueHash, $val);
     2088                        if ($$newInfo{IsOverwriting}) {
     2089                            my $proc = $$newInfo{IsOverwriting};
     2090                            $isOverwriting = &$proc($exifTool, $nvHash, $val, \$newVal);
     2091                        } else {
     2092                            $isOverwriting = Image::ExifTool::IsOverwriting($nvHash, $val);
     2093                        }
    15242094                    }
    15252095                    if ($isOverwriting) {
    1526                         $newVal = Image::ExifTool::GetNewValues($newValueHash) unless defined $newVal;
     2096                        $newVal = Image::ExifTool::GetNewValues($nvHash) unless defined $newVal;
    15272097                        # value undefined if deleting this tag
    15282098                        # (also delete tag if cross-deleting and this isn't a date/time shift)
    1529                         if (not defined $newVal or ($xDelete{$newID} and not defined $$newValueHash{Shift})) {
    1530                             if ($$newInfo{RawConvInv} and defined $$newValueHash{Value}) {
     2099                        if (not defined $newVal or ($xDelete{$newID} and not defined $$nvHash{Shift})) {
     2100                            if ($$newInfo{RawConvInv} and defined $$nvHash{Value}) {
    15312101                                goto NoOverwrite;   # error in RawConvInv, so rewrite existing tag
    15322102                            }
    15332103                            unless ($isNew) {
    15342104                                ++$exifTool->{CHANGED};
    1535                                 $val = $exifTool->Printable($val);
    1536                                 $verbose > 1 and print $out "    - $dirName:$$newInfo{Name} = '$val'\n";
     2105                                $exifTool->VerboseValue("- $dirName:$$newInfo{Name}", $val);
    15372106                            }
    15382107                            next;
    15392108                        }
    1540                         if (length $newVal) {
    1541                             if ($newCount and $newCount < 0) {
    1542                                 # set count to number of values if variable
    1543                                 my @vals = split ' ',$newVal;
    1544                                 $newCount = @vals;
    1545                             }
    1546                             # convert to binary format
    1547                             $newValue = WriteValue($newVal, $newFormName, $newCount);
    1548                             unless (defined $newValue) {
    1549                                 $exifTool->Warn("Error writing $dirName:$$newInfo{Name}");
     2109                        if ($newCount and $newCount < 0) {
     2110                            # set count to number of values if variable
     2111                            my @vals = split ' ',$newVal;
     2112                            $newCount = @vals;
     2113                        }
     2114                        # convert to binary format
     2115                        $newValue = WriteValue($newVal, $newFormName, $newCount);
     2116                        unless (defined $newValue) {
     2117                            $exifTool->Warn("Error writing $dirName:$$newInfo{Name}");
     2118                            goto NoOverwrite;
     2119                        }
     2120                        if (length $newValue) {
     2121                            # limit maximum value length in JPEG images
     2122                            # (max segment size is 65533 bytes and the min EXIF size is 96 incl an additional IFD entry)
     2123                            if ($$exifTool{FILE_TYPE} eq 'JPEG' and length($newValue) > 65436 and
     2124                                $$newInfo{Name} ne 'PreviewImage')
     2125                            {
     2126                                my $name = $$newInfo{MakerNotes} ? 'MakerNotes' : $$newInfo{Name};
     2127                                $exifTool->Warn("$name too large to write in JPEG segment");
    15502128                                goto NoOverwrite;
    15512129                            }
    15522130                        } else {
    1553                             $exifTool->Warn("Can't write zero length $$newInfo{Name} in $tagTablePtr->{GROUPS}->{1}");
     2131                            $exifTool->Warn("Can't write zero length $$newInfo{Name} in $tagTablePtr->{GROUPS}{1}");
    15542132                            goto NoOverwrite;
    15552133                        }
     
    15572135                            $newCount = length($newValue) / $formatSize[$newFormat];
    15582136                            ++$exifTool->{CHANGED};
     2137                            if (defined $allMandatory) {
     2138                                # not all mandatory if we are writing any tag specifically
     2139                                if ($nvHash) {
     2140                                    undef $allMandatory;
     2141                                    undef $deleteAll;
     2142                                } else {
     2143                                    ++$addMandatory;    # count mandatory tags that we added
     2144                                }
     2145                            }
    15592146                            if ($verbose > 1) {
    1560                                 $val = $exifTool->Printable($val);
    1561                                 $newVal = $exifTool->Printable($newVal);
    1562                                 print $out "    - $dirName:$$newInfo{Name} = '$val'\n" unless $isNew;
    1563                                 my $str = $newValueHash ? '' : ' (mandatory)';
    1564                                 print $out "    + $dirName:$$newInfo{Name} = '$newVal'$str\n";
     2147                                $exifTool->VerboseValue("- $dirName:$$newInfo{Name}", $val) unless $isNew;
     2148                                my $str = $nvHash ? '' : ' (mandatory)';
     2149                                $exifTool->VerboseValue("+ $dirName:$$newInfo{Name}", $newVal, $str);
    15652150                            }
    15662151                        }
     
    15792164# create new subdirectory
    15802165#
    1581                     $newInfo = $$addDirs{$newID} or warn('internal error'), next;
     2166                    # newInfo may not be defined if we try to add a mandatory tag
     2167                    # to a directory that doesn't support it (ie. IFD1 in RW2 images)
     2168                    $newInfo = $$addDirs{$newID} or next;
    15822169                    # make sure we don't try to generate a new MakerNotes directory
    15832170                    # or a SubIFD
    15842171                    next if $$newInfo{MakerNotes} or $$newInfo{Name} eq 'SubIFD';
    15852172                    my $subTable;
    1586                     if ($newInfo->{SubDirectory}->{TagTable}) {
    1587                         $subTable = GetTagTable($newInfo->{SubDirectory}->{TagTable});
     2173                    if ($newInfo->{SubDirectory}{TagTable}) {
     2174                        $subTable = Image::ExifTool::GetTagTable($newInfo->{SubDirectory}{TagTable});
    15882175                    } else {
    15892176                        $subTable = $tagTablePtr;
     
    15942181                        Fixup => new Image::ExifTool::Fixup,
    15952182                    );
    1596                     $sourceDir{DirName} = $newInfo->{Groups}->{1} if $$newInfo{SubIFD};
     2183                    $sourceDir{DirName} = $newInfo->{Groups}{1} if $$newInfo{SubIFD};
    15972184                    $newValue = $exifTool->WriteDirectory(\%sourceDir, $subTable);
    15982185                    # only add new directory if it isn't empty
     
    16142201                    } else {
    16152202                        # subdirectory goes directly into value buffer
    1616                         $sourceDir{Fixup}->{Start} += length($valBuff);
     2203                        $sourceDir{Fixup}{Start} += length($valBuff);
    16172204                        # use Writable to set format, otherwise 'undef'
    16182205                        $newFormName = $$newInfo{Writable};
     
    16352222                $newFormat = $oldFormat; # (just in case it changed)
    16362223                $newFormName = $oldFormName;
     2224                # set offset of this entry in the directory so we can update the pointer
     2225                # and save block information to copy this large block later
     2226                if ($oldImageData) {
     2227                    $$oldImageData[3] = $newStart + length($dirBuff) + 2;
     2228                    push @imageData, $oldImageData;
     2229                    $$origDirInfo{ImageData} = \@imageData;
     2230                }
    16372231            }
    16382232            if ($newInfo) {
     
    16432237                    my $dataTag = $$newInfo{DataTag};
    16442238                    # load data for this tag
    1645                     unless (defined $offsetData{$dataTag}) {
    1646                         $offsetData{$dataTag} = $exifTool->GetNewValues($dataTag);
     2239                    unless (defined $offsetData{$dataTag} or $dataTag eq 'LeicaTrailer') {
     2240                        # prefer tag from Composite table if it exists (otherwise
     2241                        # PreviewImage data would be taken from Extra tag)
     2242                        my $compInfo = $Image::ExifTool::Composite{$dataTag};
     2243                        $offsetData{$dataTag} = $exifTool->GetNewValues($compInfo || $dataTag);
    16472244                        my $err;
    16482245                        if (defined $offsetData{$dataTag}) {
    1649                             if ($exifTool->{FILE_TYPE} eq 'JPEG' and
    1650                                 $dataTag ne 'PreviewImage' and length($offsetData{$dataTag}) > 60000)
    1651                             {
     2246                            my $len = length $offsetData{$dataTag};
     2247                            if ($dataTag eq 'PreviewImage') {
     2248                                # must set DEL_PREVIEW flag now if preview fit into IFD
     2249                                $$exifTool{DEL_PREVIEW} = 1 if $len <= 4;
     2250                            } elsif ($exifTool->{FILE_TYPE} eq 'JPEG' and $len > 60000) {
    16522251                                delete $offsetData{$dataTag};
    16532252                                $err = "$dataTag not written (too large for JPEG segment)";
     
    16682267                if ($$newInfo{MakerNotes}) {
    16692268                    # don't write new makernotes if we are deleting this group
    1670                     if ($exifTool->{DEL_GROUP}->{MakerNotes} and
    1671                         ($exifTool->{DEL_GROUP}->{MakerNotes} != 2 or $isNew <= 0))
     2269                    if ($exifTool->{DEL_GROUP}{MakerNotes} and
     2270                       ($exifTool->{DEL_GROUP}{MakerNotes} != 2 or $isNew <= 0))
    16722271                    {
    16732272                        if ($isNew <= 0) {
     
    16812280                        # we are writing a whole new maker note block
    16822281                        # --> add fixup information if necessary
    1683                         my $newValueHash = $exifTool->GetNewValueHash($newInfo, $dirName);
    1684                         if ($newValueHash and $newValueHash->{MAKER_NOTE_FIXUP}) {
     2282                        my $nvHash = $exifTool->GetNewValueHash($newInfo, $dirName);
     2283                        if ($nvHash and $nvHash->{MAKER_NOTE_FIXUP}) {
    16852284                            # must clone fixup because we will be shifting it
    1686                             my $makerFixup = $newValueHash->{MAKER_NOTE_FIXUP}->Clone();
     2285                            my $makerFixup = $nvHash->{MAKER_NOTE_FIXUP}->Clone();
    16872286                            my $valLen = length($valBuff);
    16882287                            $makerFixup->{Start} += $valLen;
     
    16922291                        # update maker notes if possible
    16932292                        my %subdirInfo = (
    1694                             Base => $base,
    1695                             DataPt => $valueDataPt,
    1696                             DataPos => $valueDataPos,
    1697                             DataLen => $valueDataLen,
     2293                            Base     => $base,
     2294                            DataPt   => $valueDataPt,
     2295                            DataPos  => $valueDataPos,
     2296                            DataLen  => $valueDataLen,
    16982297                            DirStart => $valuePtr,
    1699                             DirLen => $oldSize,
    1700                             DirName => 'MakerNotes',
    1701                             Parent => $dirName,
    1702                             TagInfo => $newInfo,
    1703                             RAF => $raf,
     2298                            DirLen   => $oldSize,
     2299                            DirName  => 'MakerNotes',
     2300                            Name     => $$newInfo{Name},
     2301                            Parent   => $dirName,
     2302                            TagInfo  => $newInfo,
     2303                            RAF      => $raf,
    17042304                        );
     2305                        my ($subTable, $subdir, $loc, $writeProc, $notIFD);
    17052306                        if ($$newInfo{SubDirectory}) {
    17062307                            my $sub = $$newInfo{SubDirectory};
     
    17082309                            $subdirInfo{FixOffsets} = $$sub{FixOffsets};
    17092310                            $subdirInfo{EntryBased} = $$sub{EntryBased};
    1710                             $subdirInfo{NoFixBase} = 1 if $$sub{Base};
     2311                            $subdirInfo{NoFixBase} = 1 if defined $$sub{Base};
     2312                            $subdirInfo{AutoFix} = $$sub{AutoFix};
    17112313                        }
    17122314                        # get the proper tag table for these maker notes
    1713                         my $subTable;
    1714                         if ($oldInfo and $oldInfo->{SubDirectory}) {
    1715                             $subTable = $oldInfo->{SubDirectory}->{TagTable};
     2315                        if ($oldInfo and $$oldInfo{SubDirectory}) {
     2316                            $subTable = $$oldInfo{SubDirectory}{TagTable};
    17162317                            $subTable and $subTable = Image::ExifTool::GetTagTable($subTable);
     2318                            $writeProc = $$oldInfo{SubDirectory}{WriteProc};
     2319                            $notIFD = $$oldInfo{NotIFD};
    17172320                        } else {
    17182321                            $exifTool->Warn('Internal problem getting maker notes tag table');
    17192322                        }
    17202323                        $subTable or $subTable = $tagTablePtr;
    1721                         my $subdir;
    1722                         # look for IFD-style maker notes
    1723                         my $loc = Image::ExifTool::MakerNotes::LocateIFD($exifTool,\%subdirInfo);
     2324                        if ($writeProc and
     2325                            $writeProc eq \&Image::ExifTool::MakerNotes::WriteUnknownOrPreview and
     2326                            $oldValue =~ /^\xff\xd8\xff/)
     2327                        {
     2328                            $loc = 0;
     2329                        } elsif (not $notIFD) {
     2330                            # look for IFD-style maker notes
     2331                            $loc = Image::ExifTool::MakerNotes::LocateIFD($exifTool,\%subdirInfo);
     2332                        }
    17242333                        if (defined $loc) {
    17252334                            # we need fixup data for this subdirectory
    17262335                            $subdirInfo{Fixup} = new Image::ExifTool::Fixup;
    17272336                            # rewrite maker notes
    1728                             $subdir = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
     2337                            $subdir = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
    17292338                        } elsif ($$subTable{PROCESS_PROC} and
    17302339                                 $$subTable{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData)
    17312340                        {
    1732                             my $sub = $oldInfo->{SubDirectory};
     2341                            my $sub = $$oldInfo{SubDirectory};
    17332342                            if (defined $$sub{Start}) {
    17342343                                #### eval Start ($valuePtr)
     
    17422351                            # rewrite maker notes
    17432352                            $subdir = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
    1744                         } else {
    1745                             $exifTool->Warn('Maker notes could not be parsed',1);
     2353                        } elsif (not $notIFD) {
     2354                            my $msg = 'Maker notes could not be parsed';
     2355                            if ($$exifTool{FILE_TYPE} eq 'JPEG') {
     2356                                $exifTool->Warn($msg, 1);
     2357                            } else {
     2358                                $exifTool->Error($msg, 1);
     2359                            }
    17462360                        }
    17472361                        if (defined $subdir) {
     
    17632377                                    # remove all but PreviewImage fixup (since others shouldn't change)
    17642378                                    foreach (keys %{$makerFixup->{Pointers}}) {
    1765                                         /_PreviewImage$/ or delete $makerFixup->{Pointers}->{$_};
     2379                                        /_PreviewImage$/ or delete $makerFixup->{Pointers}{$_};
    17662380                                    }
    17672381                                    # zero pointer so we can see how it gets shifted later
     
    17742388                                    $previewInfo->{Relative} = 1;
    17752389                                }
     2390                            # don't shift anything if relative flag set to zero (Pentax patch)
    17762391                            } elsif (not defined $subdirInfo{Relative}) {
    1777                                 # don't shift anything if relative flag set to zero (Pentax patch)
     2392                                # shift offset base if shifted in the original image or if FixBase
     2393                                # was used, but be careful of automatic FixBase with negative shifts
     2394                                # since they may lead to negative (invalid) offsets (casio_edit_problem.jpg)
    17782395                                my $baseShift = $base - $subdirInfo{Base};
     2396                                if ($subdirInfo{AutoFix}) {
     2397                                    $baseShift = 0;
     2398                                } elsif ($subdirInfo{FixBase} and $baseShift < 0 and
     2399                                    # allow negative base shift if offsets are bigger (PentaxOptioWP.jpg)
     2400                                    (not $subdirInfo{MinOffset} or $subdirInfo{MinOffset} + $baseShift < 0))
     2401                                {
     2402                                    my $fixBase = $exifTool->Options('FixBase');
     2403                                    if (not defined $fixBase) {
     2404                                        my $str = $exifTool->Options('IgnoreMinorErrors') ? 'ignored' : 'fix or ignore?';
     2405                                        $exifTool->Error("MakerNotes offsets may be incorrect ($str)", 1);
     2406                                    } elsif ($fixBase eq '') {
     2407                                        $exifTool->Warn('Fixed incorrect MakerNotes offsets');
     2408                                        $baseShift = 0;
     2409                                    }
     2410                                }
    17792411                                $makerFixup->{Start} += $valLen + $loc;
    17802412                                $makerFixup->{Shift} += $baseShift;
     2413                                # permanently fix makernote offset errors
     2414                                $makerFixup->{Shift} += $subdirInfo{FixedBy} || 0;
    17812415                                push @valFixups, $makerFixup;
    17822416                                if ($previewInfo and not $previewInfo->{NoBaseShift}) {
     
    18002434# rewrite existing sub IFD's
    18012435#
    1802                         my $subdirName = $newInfo->{Groups}->{1} || $$newInfo{Name};
     2436                        my $subTable = $tagTablePtr;
     2437                        if ($$subdir{TagTable}) {
     2438                            $subTable = Image::ExifTool::GetTagTable($$subdir{TagTable});
     2439                        }
     2440                        # determine directory name for this IFD
     2441                        my $subdirName = $newInfo->{Groups}{1} || $$newInfo{Name};
     2442                        # all makernotes directory names must be 'MakerNotes'
     2443                        $subdirName = 'MakerNotes' if $subTable->{GROUPS}{0} eq 'MakerNotes';
    18032444                        # must handle sub-IFD's specially since the values
    18042445                        # are actually offsets to subdirectories
    18052446                        unless ($readCount) {   # can't have zero count
    1806                             return undef if $exifTool->Error("$dirName entry $index has zero count", 1);
     2447                            return undef if $exifTool->Error("$name entry $index has zero count", 1);
    18072448                            next;
    18082449                        }
     
    18172458                            my $subdirBase = $base;
    18182459                            if ($$subdir{Base}) {
    1819                                 my $start = $subdirStart + $valueDataPos;
    1820                                 #### eval Base ($start)
     2460                                my $start = $subdirStart + $dataPos;
     2461                                #### eval Base ($start,$base)
    18212462                                $subdirBase += eval $$subdir{Base};
    18222463                            }
     2464                            # add IFD number if more than one
     2465                            $subdirName =~ s/\d*$/$i/ if $i;
    18232466                            my %subdirInfo = (
    1824                                 Base => $subdirBase,
    1825                                 DataPt => $dataPt,
    1826                                 DataPos => $dataPos - $subdirBase + $base,
    1827                                 DataLen => $dataLen,
     2467                                Base     => $subdirBase,
     2468                                DataPt   => $dataPt,
     2469                                DataPos  => $dataPos - $subdirBase + $base,
     2470                                DataLen  => $dataLen,
    18282471                                DirStart => $subdirStart,
    1829                                 DirName => $subdirName . ($i ? $i : ''),
    1830                                 Parent => $dirName,
    1831                                 Fixup => new Image::ExifTool::Fixup,
    1832                                 RAF => $raf,
     2472                                DirName  => $subdirName,
     2473                                Name     => $$newInfo{Name},
     2474                                TagInfo  => $newInfo,
     2475                                Parent   => $dirName,
     2476                                Fixup    => new Image::ExifTool::Fixup,
     2477                                RAF      => $raf,
     2478                                Subdir   => $subdir,
     2479                                # set ImageData only for 1st level SubIFD's
     2480                                ImageData=> $imageDataFlag eq 'Main' ? 'SubIFD' : undef,
    18332481                            );
    1834                             # read IFD from file if necessary
     2482                            # pass on header pointer only for certain sub IFD's
     2483                            $subdirInfo{HeaderPtr} = $$dirInfo{HeaderPtr} if $$newInfo{SubIFD} == 2;
     2484                            if ($$subdir{RelativeBase}) {
     2485                                # apply one-time fixup if offsets are relative (Sony IDC hack)
     2486                                delete $subdirInfo{Fixup};
     2487                                delete $subdirInfo{ImageData};
     2488                            }
     2489                            # is the subdirectory outside our current data?
    18352490                            if ($subdirStart < 0 or $subdirStart + 2 > $dataLen) {
    1836                                 my ($buff, $buf2, $subSize);
    1837                                 unless ($raf and $raf->Seek($pt + $base, 0) and
    1838                                         $raf->Read($buff,2) == 2 and
    1839                                         $subSize = 12 * Get16u(\$buff, 0) and
    1840                                         $raf->Read($buf2,$subSize+4) >= $subSize)
    1841                                 {
    1842                                     if (defined $subSize and not $subSize) {
    1843                                         return undef if $exifTool->Error("$subdirName IFD has zero entries", 1);
    1844                                         next Entry;
     2491                                if ($raf) {
     2492                                    # reset SubDirectory buffer (we will load it later)
     2493                                    my $buff = '';
     2494                                    $subdirInfo{DataPt} = \$buff;
     2495                                    $subdirInfo{DataLen} = 0;
     2496                                } else {
     2497                                    my @err = ("Can't read $subdirName data", $inMakerNotes);
     2498                                    if ($$subTable{VARS} and $subTable->{VARS}{MINOR_ERRORS}) {
     2499                                        $exifTool->Warn($err[0] . '. Ignored.');
     2500                                    } elsif ($exifTool->Error(@err)) {
     2501                                        return undef;
    18452502                                    }
    1846                                     return undef if $exifTool->Error("Can't read $subdirName data", $inMakerNotes);
    1847                                     next Entry;
     2503                                    next Entry; # don't write this directory
    18482504                                }
    1849                                 $buff .= $buf2;
    1850                                 # change subdirectory information to data we just read
    1851                                 $subdirInfo{DataPt} = \$buff;
    1852                                 $subdirInfo{DirStart} = 0;
    1853                                 $subdirInfo{DataPos} = $pt;
    1854                                 $subdirInfo{DataLen} = length $buff;
    1855                                 # only account for nextIFD pointer if we will use it
    1856                                 $subSize += 4 if length($buff)==$subSize+6 and
    1857                                     ($$newInfo{Name} eq 'SubIFD' or $buff =~ /\0{4}$/);
    1858                                 UpdateTiffEnd($exifTool, $pt+$base+2+$subSize);
    18592505                            }
    1860                             my $subTable = $tagTablePtr;
    1861                             if ($$subdir{TagTable}) {
    1862                                 $subTable = GetTagTable($$subdir{TagTable});
     2506                            my $subdirData = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
     2507                            unless (defined $subdirData) {
     2508                                # WriteDirectory should have issued an error, but check just in case
     2509                                $exifTool->Error("Error writing $subdirName") unless $$exifTool{VALUE}{Error};
     2510                                return undef;
    18632511                            }
    1864                             my $subdirData = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
    1865                             return undef unless defined $subdirData;
    1866                             next unless length($subdirData);
     2512                            unless (length $subdirData) {
     2513                                next unless $inMakerNotes;
     2514                                # don't delete MakerNote Sub-IFD's, write empty IFD instead
     2515                                $subdirData = "\0" x 6;
     2516                                # reset SubIFD ImageData and Fixup just to be safe
     2517                                delete $subdirInfo{ImageData};
     2518                                delete $subdirInfo{Fixup};
     2519                            }
     2520                            # handle data blocks that we will transfer later
     2521                            if (ref $subdirInfo{ImageData}) {
     2522                                push @imageData, @{$subdirInfo{ImageData}};
     2523                                $$origDirInfo{ImageData} = \@imageData;
     2524                            }
    18672525                            # temporarily set value to subdirectory index
    18682526                            # (will set to actual offset later when we know what it is)
     
    18782536                            # add to list of subdirectories we will append later
    18792537                            push @subdirs, {
    1880                                 DataPt => \$subdirData,
    1881                                 Table => $subTable,
    1882                                 Fixup => $subdirInfo{Fixup},
    1883                                 Offset => $offset,
    1884                                 Where => $where,
     2538                                DataPt    => \$subdirData,
     2539                                Table     => $subTable,
     2540                                Fixup     => $subdirInfo{Fixup},
     2541                                Offset    => $offset,
     2542                                Where     => $where,
     2543                                ImageData => $subdirInfo{ImageData},
    18852544                            };
    18862545                            ++$writeCount;  # count number of subdirs written
     
    18902549                        # a directory and only one remains
    18912550                        if ($writeCount < $readCount and $writeCount == 1) {
    1892                             $subdirs[-1]->{Where} = 'dirBuff';
    1893                             $subdirs[-1]->{Offset} = length($dirBuff) + 8;
     2551                            $subdirs[-1]{Where} = 'dirBuff';
     2552                            $subdirs[-1]{Offset} = length($dirBuff) + 8;
    18942553                        }
    18952554                        # set new format to int32u for IFD
     
    19162575                        if ($$subdir{Base}) {
    19172576                            my $start = $subdirStart + $valueDataPos;
    1918                             #### eval Base ($start)
     2577                            #### eval Base ($start,$base)
    19192578                            $subdirBase += eval $$subdir{Base};
    19202579                        }
    19212580                        my $subFixup = new Image::ExifTool::Fixup;
    19222581                        my %subdirInfo = (
    1923                             Base => $subdirBase,
    1924                             DataPt => $valueDataPt,
    1925                             DataPos => $valueDataPos - $subdirBase + $base,
    1926                             DataLen => $valueDataLen,
     2582                            Base     => $subdirBase,
     2583                            DataPt   => $valueDataPt,
     2584                            DataPos  => $valueDataPos - $subdirBase + $base,
     2585                            DataLen  => $valueDataLen,
    19272586                            DirStart => $subdirStart,
    1928                             DirName => $$subdir{DirName},
    1929                             DirLen => $oldSize,
    1930                             Parent => $dirName,
    1931                             Fixup => $subFixup,
    1932                             RAF => $raf,
     2587                            DirName  => $$subdir{DirName},
     2588                            DirLen   => $oldSize,
     2589                            Parent   => $dirName,
     2590                            Fixup    => $subFixup,
     2591                            RAF      => $raf,
     2592                            TagInfo  => $newInfo,
    19332593                        );
    1934                         my $subTable = GetTagTable($$subdir{TagTable});
    1935                         $newValue = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
     2594                        unless ($oldSize) {
     2595                            # replace with dummy data if empty to prevent WriteDirectory
     2596                            # routines from accessing data they shouldn't
     2597                            my $tmp = '';
     2598                            $subdirInfo{DataPt} = \$tmp;
     2599                            $subdirInfo{DataLen} = 0;
     2600                            $subdirInfo{DirStart} = 0;
     2601                            $subdirInfo{DataPos} += $subdirStart;
     2602                        }
     2603                        my $subTable = Image::ExifTool::GetTagTable($$subdir{TagTable});
     2604                        my $oldOrder = GetByteOrder();
     2605                        SetByteOrder($$subdir{ByteOrder}) if $$subdir{ByteOrder};
     2606                        $newValue = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
     2607                        SetByteOrder($oldOrder);
    19362608                        if (defined $newValue) {
    19372609                            my $hdrLen = $subdirStart - $valuePtr;
     
    19462618                            return undef;
    19472619                        }
    1948                         next unless length $$newValuePt;
     2620                        unless (length $$newValuePt) {
     2621                            # don't delete a previously empty makernote directory
     2622                            next if $oldSize or not $inMakerNotes;
     2623                        }
    19492624                        if ($subFixup->{Pointers} and $subdirInfo{Base} == $base) {
    19502625                            $subFixup->{Start} += length $valBuff;
     
    19642639                        # must decide now if we will write CanonVRD information
    19652640                        my $hasVRD;
    1966                         if ($exifTool->{NEW_VALUE}->{$Image::ExifTool::Extra{CanonVRD}}) {
     2641                        if ($exifTool->{NEW_VALUE}{$Image::ExifTool::Extra{CanonVRD}}) {
    19672642                            # adding or deleting as a block
    19682643                            $hasVRD = $exifTool->GetNewValues('CanonVRD') ? 1 : 0;
    1969                         } elsif ($exifTool->{DEL_GROUP}->{CanonVRD} or
    1970                                  $exifTool->{DEL_GROUP}->{Trailer})
     2644                        } elsif ($exifTool->{DEL_GROUP}{CanonVRD} or
     2645                                 $exifTool->{DEL_GROUP}{Trailer})
    19712646                        {
    19722647                            $hasVRD = 0;    # deleting as a group
     
    19822657                            $newValuePt = \$newValue;
    19832658                        }
     2659                    } elsif ($dataTag eq 'OriginalDecisionData') {
     2660                        # handle Canon OriginalDecisionData (no associated length tag)
     2661                        # - I'm going out of my way here to preserve data which is
     2662                        #   invalidated anyway by our edits
     2663                        my $odd;
     2664                        my $oddInfo = $Image::ExifTool::Composite{OriginalDecisionData};
     2665                        if ($oddInfo and $exifTool->{NEW_VALUE}{$oddInfo}) {
     2666                            $odd = $exifTool->GetNewValues($dataTag);
     2667                            if ($verbose > 1) {
     2668                                print $out "    - $dirName:$dataTag\n" if $$newValuePt ne "\0\0\0\0";
     2669                                print $out "    + $dirName:$dataTag\n" if $odd;
     2670                            }
     2671                            ++$exifTool->{CHANGED};
     2672                        } elsif ($$newValuePt ne "\0\0\0\0") {
     2673                            if (length($$newValuePt) == 4) {
     2674                                require Image::ExifTool::Canon;
     2675                                my $offset = Get32u($newValuePt,0);
     2676                                # absolute offset in JPEG images only
     2677                                $offset += $base unless $$exifTool{FILE_TYPE} eq 'JPEG';
     2678                                $odd = Image::ExifTool::Canon::ReadODD($exifTool, $offset);
     2679                                $odd = $$odd if ref $odd;
     2680                            } else {
     2681                                $exifTool->Error("Invalid $$newInfo{Name}",1);
     2682                            }
     2683                        }
     2684                        if ($odd) {
     2685                            my $newOffset = length($valBuff);
     2686                            # (ODD offset is absolute in JPEG, so add base offset!)
     2687                            $newOffset += $base if $$exifTool{FILE_TYPE} eq 'JPEG';
     2688                            $newValue = Set32u($newOffset);
     2689                            $dirFixup->AddFixup(length($dirBuff) + 8, $dataTag);
     2690                            $valBuff .= $odd;   # add original decision data
     2691                        } else {
     2692                            $newValue = "\0\0\0\0";
     2693                        }
     2694                        $newValuePt = \$newValue;
    19842695                    } else {
    19852696                        my $offsetInfo = $offsetInfo[$ifd];
     
    19872698                        my @vals;
    19882699                        if ($isNew <= 0) {
     2700                            my $oldOrder = GetByteOrder();
     2701                            # Minolta A200 stores these in the wrong byte order!
     2702                            SetByteOrder($$newInfo{ByteOrder}) if $$newInfo{ByteOrder};
    19892703                            @vals = ReadValue(\$oldValue, 0, $readFormName, $readCount, $oldSize);
     2704                            SetByteOrder($oldOrder);
    19902705                        }
    19912706                        # only support int32 pointers (for now)
    19922707                        if ($formatSize[$newFormat] != 4 and $$newInfo{IsOffset}) {
    1993                             die "Internal error (Offset not int32)" if $isNew > 0;
    1994                             die "Wrong count!" if $newCount != $readCount;
     2708                            $isNew > 0 and warn("Internal error (Offset not int32)"), return undef;
     2709                            $newCount != $readCount and warn("Wrong count!"), return undef;
    19952710                            # change to int32
    19962711                            $newFormName = 'int32u';
    19972712                            $newFormat = $formatNumber{$newFormName};
    19982713                            $newValue = WriteValue(join(' ',@vals), $newFormName, $newCount);
    1999                             die "Internal error writing offsets\n" unless defined $newValue;
     2714                            unless (defined $newValue) {
     2715                                warn "Internal error writing offsets for $$newInfo{Name}\n";
     2716                                return undef;
     2717                            }
    20002718                        }
    20012719                        $offsetInfo or $offsetInfo = $offsetInfo[$ifd] = { };
     
    20112729                } elsif ($$newInfo{DataMember}) {
    20122730
    2013                     # save any necessary data members (CameraMake, CameraModel)
    2014                     $exifTool->{$$newInfo{DataMember}} = $$newValuePt;
     2731                    # save any necessary data members (Make, Model, etc)
     2732                    my $formatStr = $newFormName;
     2733                    my $count = $newCount;
     2734                    # change to specified format if necessary
     2735                    if ($$newInfo{Format} and $$newInfo{Format} ne $formatStr) {
     2736                        $formatStr = $$newInfo{Format};
     2737                        my $format = $formatNumber{$formatStr};
     2738                        # adjust number of items for new format size
     2739                        $count = int(length($$newValuePt) / $formatSize[$format]) if $format;
     2740                    }
     2741                    my $val = ReadValue($newValuePt,0,$formatStr,$count,length($$newValuePt));
     2742                    my $conv = $$newInfo{RawConv};
     2743                    if ($conv) {
     2744                        # let the RawConv store the (possibly converted) data member
     2745                        if (ref $conv eq 'CODE') {
     2746                            &$conv($val, $exifTool);
     2747                        } else {
     2748                            my ($self, $tag, $taginfo) = ($exifTool, $$newInfo{Name}, $newInfo);
     2749                            #### eval RawConv ($self, $val, $tag, $tagInfo)
     2750                            eval $conv;
     2751                        }
     2752                    } else {
     2753                        $$exifTool{$$newInfo{DataMember}} = $val;
     2754                    }
    20152755                }
    20162756            }
     
    20362776                    $offsetVal = Set32u(length $valBuff);
    20372777                }
    2038                 my $dataTag;
    2039                 if ($newInfo and $$newInfo{DataTag}) {
    2040                     $dataTag = $$newInfo{DataTag};
    2041                     if ($dataTag eq 'PreviewImage' and $exifTool->{FILE_TYPE} eq 'JPEG') {
     2778                my ($dataTag, $putFirst);
     2779                ($dataTag, $putFirst) = @$newInfo{'DataTag','PutFirst'} if $newInfo;
     2780                if ($dataTag) {
     2781                    if ($dataTag eq 'PreviewImage' and ($exifTool->{FILE_TYPE} eq 'JPEG' or
     2782                        $$exifTool{GENERATE_PREVIEW_INFO}))
     2783                    {
    20422784                        # hold onto the PreviewImage until we can determine if it fits
    20432785                        $exifTool->{PREVIEW_INFO} or $exifTool->{PREVIEW_INFO} = { };
    2044                         $exifTool->{PREVIEW_INFO}->{Data} = $$newValuePt;
    2045                         if ($$newInfo{Name} eq 'PreviewImage') {
    2046                             $exifTool->{PREVIEW_INFO}->{IsValue} = 1;
    2047                         }
     2786                        $exifTool->{PREVIEW_INFO}{Data} = $$newValuePt;
     2787                        $exifTool->{PREVIEW_INFO}{ChangeBase} = 1 if $$newInfo{ChangeBase};
    20482788                        if ($$newInfo{IsOffset} and $$newInfo{IsOffset} eq '2') {
    2049                             $exifTool->{PREVIEW_INFO}->{NoBaseShift} = 1;
    2050                         }
     2789                            $exifTool->{PREVIEW_INFO}{NoBaseShift} = 1;
     2790                        }
     2791                        # use original preview size if we will attempt to load it later
     2792                        $newCount = $oldCount if $$newValuePt eq 'LOAD_PREVIEW';
    20512793                        $$newValuePt = '';
     2794                    } elsif ($dataTag eq 'LeicaTrailer' and $$exifTool{LeicaTrailer}) {
     2795                        $$newValuePt = '';
    20522796                    }
    20532797                }
    2054                 $valBuff .= $$newValuePt;       # add value data to buffer
    2055                 # must save a fixup pointer for every pointer in the directory
    2056                 if ($entryBased) {
    2057                     $entryBasedFixup or $entryBasedFixup = new Image::ExifTool::Fixup;
    2058                     $entryBasedFixup->AddFixup(length($dirBuff) + 8, $dataTag);
     2798                if ($putFirst and $$dirInfo{HeaderPtr}) {
     2799                    my $hdrPtr = $$dirInfo{HeaderPtr};
     2800                    # place this value immediately after the TIFF header
     2801                    $offsetVal = Set32u(length $$hdrPtr);
     2802                    $$hdrPtr .= $$newValuePt;
    20592803                } else {
    2060                     $dirFixup->AddFixup(length($dirBuff) + 8, $dataTag);
     2804                    $valBuff .= $$newValuePt;       # add value data to buffer
     2805                    # must save a fixup pointer for every pointer in the directory
     2806                    if ($entryBased) {
     2807                        $entryBasedFixup or $entryBasedFixup = new Image::ExifTool::Fixup;
     2808                        $entryBasedFixup->AddFixup(length($dirBuff) + 8, $dataTag);
     2809                    } else {
     2810                        $dirFixup->AddFixup(length($dirBuff) + 8, $dataTag);
     2811                    }
    20612812                }
    20622813            } else {
     
    20722823                if (defined $$mandatory{$newID}) {
    20732824                    # values must correspond to mandatory values
    2074                     my $mandVal = WriteValue($$mandatory{$newID}, $newFormName, $newCount);
     2825                    my $form = $$newInfo{Format} || $newFormName;
     2826                    my $mandVal = WriteValue($$mandatory{$newID}, $form, $newCount);
    20752827                    if (defined $mandVal and $mandVal eq $$newValuePt) {
    20762828                        ++$allMandatory;        # count mandatory tags
     
    20822834            }
    20832835        }
     2836        if ($ignoreCount) {
     2837            my $y = $ignoreCount > 1 ? 'ies' : 'y';
     2838            $exifTool->Warn("Removed $ignoreCount invalid entr$y from $name", 1);
     2839        }
     2840        if ($fixCount) {
     2841            my $s = $fixCount > 1 ? 's' : '';
     2842            $exifTool->Warn("Fixed invalid count$s for $fixCount $name tag$s", 1);
     2843        }
    20842844#..............................................................................
    20852845# write directory counts and nextIFD pointer and add value data to end of IFD
    20862846#
     2847        # determine now if there is or will be another IFD after this one
     2848        my $nextIfdOffset;
     2849        if ($dirEnd + 4 <= $dataLen) {
     2850            $nextIfdOffset = Get32u($dataPt, $dirEnd);
     2851        } else {
     2852            $nextIfdOffset = 0;
     2853        }
     2854        my $isNextIFD = ($$dirInfo{Multi} and ($nextIfdOffset or
     2855                        # account for the case where we will create the next IFD
     2856                        ($dirName eq 'IFD0' and $exifTool->{ADD_DIRS}{'IFD1'})));
    20872857        # calculate number of entries in new directory
    20882858        my $newEntries = length($dirBuff) / 12;
    2089         # delete entire directory if only mandatory tags remain
    2090         if ($newEntries < $numEntries and $allMandatory) {
     2859        # delete entire directory if we deleted a tag and only mandatory tags remain or we
     2860        # attempted to create a directory with only mandatory tags and there is no nextIFD
     2861        if ($allMandatory and not $isNextIFD and ($newEntries < $numEntries or $numEntries == 0)) {
    20912862            $newEntries = 0;
    20922863            $dirBuff = '';
     
    20952866            ++$deleteAll if defined $deleteAll;
    20962867            $verbose > 1 and print $out "    - $allMandatory mandatory tag(s)\n";
     2868            $exifTool->{CHANGED} -= $addMandatory;    # didn't change these after all
    20972869        }
    20982870        if ($ifd and not $newEntries) {
     
    21272899            my $subdir;
    21282900            foreach $subdir (@subdirs) {
    2129                 my $pos = length($newData);    # position of subdirectory in data
    2130                 my $subdirFixup = $subdir->{Fixup};
    2131                 $subdirFixup->{Start} += $pos;
    2132                 $fixup->AddFixup($subdirFixup);
    2133                 $newData .= ${$subdir->{DataPt}};   # add subdirectory to our data
    2134                 undef ${$subdir->{DataPt}};         # free memory now
     2901                my $len = length($newData);         # position of subdirectory in data
     2902                my $subdirFixup = $$subdir{Fixup};
     2903                if ($subdirFixup) {
     2904                    $$subdirFixup{Start} += $len;
     2905                    $fixup->AddFixup($subdirFixup);
     2906                }
     2907                my $imageData = $$subdir{ImageData};
     2908                my $blockSize = 0;
     2909                # must also update start position for ImageData fixups
     2910                if (ref $imageData) {
     2911                    my $blockInfo;
     2912                    foreach $blockInfo (@$imageData) {
     2913                        my ($pos, $size, $pad, $entry, $subFix) = @$blockInfo;
     2914                        if ($subFix) {
     2915                            $$subFix{Start} += $len;
     2916                            # save expected image data offset for calculating shift later
     2917                            $$subFix{BlockLen} = length(${$$subdir{DataPt}}) + $blockSize;
     2918                        }
     2919                        $blockSize += $size + $pad;
     2920                    }
     2921                }
     2922                $newData .= ${$$subdir{DataPt}};    # add subdirectory to our data
     2923                undef ${$$subdir{DataPt}};          # free memory now
    21352924                # set the pointer
    2136                 my $offset = $subdir->{Offset};
     2925                my $offset = $$subdir{Offset};
    21372926                # if offset is in valBuff, it was added to the end of dirBuff
    21382927                # (plus 4 bytes for nextIFD pointer)
    2139                 $offset += length($dirBuff) + 4 if $subdir->{Where} eq 'valBuff';
     2928                $offset += length($dirBuff) + 4 if $$subdir{Where} eq 'valBuff';
    21402929                $offset += $newStart + 2;           # get offset in newData
    21412930                # check to be sure we got the right offset
    21422931                unless (Get32u(\$newData, $offset) == 0xfeedf00d) {
    2143                     $exifTool->Error("Internal error while rewriting $dirName");
     2932                    $exifTool->Error("Internal error while rewriting $name");
    21442933                    return undef;
    21452934                }
    21462935                # set the offset to the subdirectory data
    2147                 Set32u($pos, \$newData, $offset);
     2936                Set32u($len, \$newData, $offset);
    21482937                $fixup->AddFixup($offset);  # add fixup for this offset in newData
    21492938            }
     
    21632952        }
    21642953        # stop if no next IFD pointer
    2165         last unless $$dirInfo{Multi};  # stop unless scanning for multiple IFD's
    2166         my $offset;
    2167         if ($dirStart + $len + 4 <= $dataLen) {
    2168             $offset = Get32u($dataPt, $dirStart + $len);
    2169         } else {
    2170             $offset = 0;
    2171         }
    2172         if ($offset) {
     2954        last unless $isNextIFD;   # stop unless scanning for multiple IFD's
     2955        if ($nextIfdOffset) {
    21732956            # continue with next IFD
    2174             $dirStart = $offset - $dataPos;
     2957            $dirStart = $nextIfdOffset - $dataPos;
    21752958        } else {
    21762959            # create IFD1 if necessary
    2177             last unless $dirName eq 'IFD0' and $exifTool->{ADD_DIRS}->{'IFD1'};
    21782960            $verbose and print $out "  Creating IFD1\n";
    21792961            my $ifd1 = "\0" x 2;  # empty IFD1 data (zero entry count)
     
    21832965        }
    21842966        # increment IFD name
    2185         $dirName =~ s/(\d+)$//;
    2186         $dirName .= ($1 || 0) + 1;
    2187         $exifTool->{DIR_NAME} = $dirName;
    2188         next unless $offset;
     2967        my $ifdNum = $dirName =~ s/(\d+)$// ? $1 : 0;
     2968        $dirName .= $ifdNum + 1;
     2969        $$exifTool{DIR_NAME} = $$exifTool{PATH}[-1] = $dirName;
     2970        next unless $nextIfdOffset;
    21892971
    21902972        # guard against writing the same directory twice
    2191         my $addr = $offset + $base;
    2192         if ($exifTool->{PROCESSED}->{$addr}) {
    2193             $exifTool->Error("$dirName pointer references previous $exifTool->{PROCESSED}->{$addr} directory", 1);
     2973        my $addr = $nextIfdOffset + $base;
     2974        if ($exifTool->{PROCESSED}{$addr}) {
     2975            $exifTool->Error("$name pointer references previous $exifTool->{PROCESSED}{$addr} directory", 1);
    21942976            last;
    21952977        }
    2196         $exifTool->{PROCESSED}->{$addr} = $dirName;
     2978        $exifTool->{PROCESSED}{$addr} = $name;
    21972979
    21982980        if ($dirName eq 'SubIFD1' and not ValidateIFD($dirInfo, $dirStart)) {
     
    22042986            last;   # don't write bad IFD
    22052987        }
    2206         if ($exifTool->{DEL_GROUP}->{$dirName}) {
     2988        if ($exifTool->{DEL_GROUP}{$dirName}) {
    22072989            $verbose and print $out "  Deleting $dirName\n";
    22082990            $raf and $exifTool->Error("Deleting $dirName also deletes subsequent" .
    22092991                                      " IFD's and possibly image data", 1);
    22102992            ++$exifTool->{CHANGED};
    2211             if ($exifTool->{DEL_GROUP}->{$dirName} == 2 and
    2212                 $exifTool->{ADD_DIRS}->{$dirName})
     2993            if ($exifTool->{DEL_GROUP}{$dirName} == 2 and
     2994                $exifTool->{ADD_DIRS}{$dirName})
    22132995            {
    22142996                my $emptyIFD = "\0" x 2;    # start with empty IFD
     
    22203002            }
    22213003        } else {
    2222             $verbose and print $out "  Rewriting $dirName\n";
     3004            $verbose and print $out "  Rewriting $name\n";
    22233005        }
    22243006    }
     
    22283010    $fixup->ApplyFixup(\$newData);
    22293011#
     3012# determine total block size for deferred data
     3013#
     3014    my $numBlocks = scalar @imageData;  # save this so we scan only existing blocks later
     3015    my $blockSize = 0;  # total size of blocks to copy later
     3016    my $blockInfo;
     3017    foreach $blockInfo (@imageData) {
     3018        my ($pos, $size, $pad) = @$blockInfo;
     3019        $blockSize += $size + $pad;
     3020    }
     3021#
    22303022# copy over image data for IFD's, starting with the last IFD first
    22313023#
    2232     my @imageData; # image data blocks if requested
    2233     my $blockSize = 0;  # total size of blocks to copy later
    22343024    if (@offsetInfo) {
    2235         my @writeLater;  # write image data last
     3025        my $ttwLen;     # length of MRW TTW segment
     3026        my @writeLater; # write image data last
    22363027        for ($ifd=$#offsetInfo; $ifd>=-1; --$ifd) {
    22373028            # build list of offsets to process
     
    22393030            if ($ifd >= 0) {
    22403031                my $offsetInfo = $offsetInfo[$ifd] or next;
     3032                # patch Panasonic RAW/RW2 StripOffsets/StripByteCounts if necessary
     3033                my $stripOffsets = $$offsetInfo{0x111};
     3034                if ($stripOffsets and $$stripOffsets[0]{PanasonicHack}) {
     3035                    require Image::ExifTool::PanasonicRaw;
     3036                    my $err = Image::ExifTool::PanasonicRaw::PatchRawDataOffset($offsetInfo, $raf, $ifd);
     3037                    $err and $exifTool->Error($err);
     3038                }
    22413039                my $tagID;
    22423040                # loop through all tags in reverse order so we save thumbnail
    22433041                # data before main image data if both exist in the same IFD
    22443042                foreach $tagID (reverse sort keys %$offsetInfo) {
    2245                     my $tagInfo = $offsetInfo->{$tagID}->[0];
     3043                    my $tagInfo = $offsetInfo->{$tagID}[0];
    22463044                    next unless $$tagInfo{IsOffset}; # handle byte counts with offsets
    22473045                    my $sizeInfo = $offsetInfo->{$$tagInfo{OffsetPair}};
     
    22493047                    my $dataTag = $$tagInfo{DataTag};
    22503048                    # write TIFF image data (strips or tiles) later if requested
    2251                     if ($raf and defined $_[1]->{ImageData} and
    2252                         ($tagID == 0x111 or $tagID == 0x144) and
     3049                    if ($raf and defined $$origDirInfo{ImageData} and
     3050                        ($tagID == 0x111 or $tagID == 0x144 or
     3051                          # also defer writing of other big data such as JpgFromRaw in NEF
     3052                          ($$sizeInfo[3][0] and
     3053                           # (calculate approximate combined size of all blocks)
     3054                           $$sizeInfo[3][0] * scalar(@{$$sizeInfo[3]}) > 1000000)) and
     3055                        # but don't defer writing if replacing with new value
    22533056                        (not defined $dataTag or not defined $offsetData{$dataTag}))
    22543057                    {
     
    22683071                # must be the same number of offset and byte count values
    22693072                unless ($count == $count2) {
    2270                     $exifTool->Error("Offset/byteCounts disagree on count for $$tagInfo{Name}");
     3073                    $exifTool->Error("Offsets/ByteCounts disagree on count for $$tagInfo{Name}");
    22713074                    return undef;
    22723075                }
     
    22813084                }
    22823085                # get offset base and data pos (abnormal for some preview images)
    2283                 my ($dbase, $dpos);
     3086                my ($dbase, $dpos, $wrongBase, $subIfdDataFixup);
    22843087                if ($$tagInfo{IsOffset} eq '2') {
    22853088                    $dbase = $firstBase;
     
    22893092                    $dpos = $dataPos;
    22903093                }
     3094                # use different base if necessary for some offsets (Minolta A200)
     3095                if ($$tagInfo{WrongBase}) {
     3096                    my $self = $exifTool;
     3097                    #### eval WrongBase ($self)
     3098                    $wrongBase = eval $$tagInfo{WrongBase} || 0;
     3099                    $dbase += $wrongBase;
     3100                    $dpos -= $wrongBase;
     3101                } else {
     3102                    $wrongBase = 0;
     3103                }
     3104                my $oldOrder = GetByteOrder();
     3105                my $dataTag = $$tagInfo{DataTag};
     3106                # use different byte order for values of this offset pair if required (Minolta A200)
     3107                SetByteOrder($$tagInfo{ByteOrder}) if $$tagInfo{ByteOrder};
    22913108                # transfer the data referenced by all offsets of this tag
    22923109                for ($n=0; $n<$count; ++$n) {
    2293                     my $oldEnd;
     3110                    my ($oldEnd, $size);
    22943111                    if (@$oldOffset and @$oldSize) {
    22953112                        # calculate end offset of this block
     
    23003117                    my $offsetPos = $offsets + $n * 4;
    23013118                    my $byteCountPos = $byteCounts + $n * $formatSize[$format];
    2302                     my $size = ReadValue(\$newData, $byteCountPos, $formatStr, 1, 4);
    2303                     my $offset = Get32u(\$newData, $offsetPos) - $dpos;
     3119                    if ($$tagInfo{PanasonicHack}) {
     3120                        # use actual raw data length (may be different than StripByteCounts!)
     3121                        $size = $$oldSize[$n];
     3122                    } else {
     3123                        # use size of new data
     3124                        $size = ReadValue(\$newData, $byteCountPos, $formatStr, 1, 4);
     3125                    }
     3126                    my $offset = $$oldOffset[$n];
     3127                    if (defined $offset) {
     3128                        $offset -= $dpos;
     3129                    } elsif ($size != 0xfeedfeed) {
     3130                        $exifTool->Error('Internal error (no offset)');
     3131                        return undef;
     3132                    }
     3133                    my $newOffset = length($newData) - $wrongBase;
    23043134                    my $buff;
    23053135                    # look for 'feed' code to use our new data
    23063136                    if ($size == 0xfeedfeed) {
    2307                         my $dataTag = $$tagInfo{DataTag};
    23083137                        unless (defined $dataTag) {
    23093138                            $exifTool->Error("No DataTag defined for $$tagInfo{Name}");
     
    23323161                                  $oldEnd != $$oldOffset[$n+1]);
    23333162                        # preserve original image padding if specified
    2334                         if ($_[1]->{PreserveImagePadding} and $n+1 < $count and
     3163                        if ($$origDirInfo{PreserveImagePadding} and $n+1 < $count and
    23353164                            $oldEnd and $$oldOffset[$n+1] > $oldEnd)
    23363165                        {
     
    23393168                        # copy data later
    23403169                        push @imageData, [$offset+$dbase+$dpos, $size, $pad];
     3170                        $newOffset += $blockSize;   # data comes after other deferred data
     3171                        # create fixup for SubIFD ImageData
     3172                        if ($imageDataFlag eq 'SubIFD' and not $subIfdDataFixup) {
     3173                            $subIfdDataFixup = new Image::ExifTool::Fixup;
     3174                            $imageData[-1][4] = $subIfdDataFixup;
     3175                        }
    23413176                        $size += $pad; # account for pad byte if necessary
    23423177                        # return ImageData list
    2343                         $_[1]->{ImageData} = \@imageData;
     3178                        $$origDirInfo{ImageData} = \@imageData;
    23443179                    } elsif ($offset >= 0 and $offset+$size <= $dataLen) {
    23453180                        # take data from old dir data buffer
    23463181                        $buff = substr($$dataPt, $offset, $size);
     3182                    } elsif ($$exifTool{TIFF_TYPE} eq 'MRW') {
     3183                        # TTW segment must be an even 4 bytes long, so pad now if necessary
     3184                        my $n = length $newData;
     3185                        $buff = ($n & 0x03) ? "\0" x (4 - ($n & 0x03)) : '';
     3186                        $size = length($buff);
     3187                        # data exists after MRW TTW segment
     3188                        $ttwLen = length($newData) + $size unless defined $ttwLen;
     3189                        $newOffset = $offset + $dpos + $ttwLen - $dataLen;
    23473190                    } elsif ($raf and $raf->Seek($offset+$dbase+$dpos,0) and
    23483191                             $raf->Read($buff,$size) == $size)
    23493192                    {
    2350                         # data read OK
     3193                        # (data was read OK)
     3194                        # patch incorrect ThumbnailOffset in Sony A100 1.00 ARW images
     3195                        if ($$exifTool{TIFF_TYPE} eq 'ARW' and $$tagInfo{Name} eq 'ThumbnailOffset' and
     3196                            $$exifTool{Model} eq 'DSLR-A100' and $buff !~ /^\xff\xd8\xff/)
     3197                        {
     3198                            my $pos = $offset + $dbase + $dpos;
     3199                            my $try;
     3200                            if ($pos < 0x10000 and $raf->Seek($pos+0x10000,0) and
     3201                                $raf->Read($try,$size) == $size and $try =~ /^\xff\xd8\xff/)
     3202                            {
     3203                                $buff = $try;
     3204                                $exifTool->Warn('Adjusted incorrect A100 ThumbnailOffset', 1);
     3205                            } else {
     3206                                $exifTool->Error('Invalid ThumbnailImage');
     3207                            }
     3208                        }
    23513209                    } elsif ($$tagInfo{Name} eq 'ThumbnailOffset' and $offset>=0 and $offset<$dataLen) {
    23523210                        # Grrr.  The Canon 350D writes the thumbnail with an incorrect byte count
     
    23723230                            $r->Seek($tell, 0) or $exifTool->Error('Seek error'), return undef;
    23733231                        }
    2374                         $buff = 'LOAD' unless defined $buff;    # flag indicating we must load PreviewImage
     3232                        # set flag if we must load PreviewImage
     3233                        $buff = 'LOAD_PREVIEW' unless defined $buff;
    23753234                    } else {
    2376                         my $dataName = $$tagInfo{DataTag} || $$tagInfo{Name};
    2377                         return undef if $exifTool->Error("Error reading $dataName data in $dirName", $inMakerNotes);
     3235                        my $dataName = $dataTag || $$tagInfo{Name};
     3236                        return undef if $exifTool->Error("Error reading $dataName data in $name", $inMakerNotes);
    23783237                        $buff = '';
    23793238                    }
    2380                     if ($$tagInfo{Name} eq 'PreviewImageStart' and $exifTool->{FILE_TYPE} eq 'JPEG') {
    2381                         # hold onto the PreviewImage until we can determine if it fits
    2382                         $exifTool->{PREVIEW_INFO} or $exifTool->{PREVIEW_INFO} = { };
    2383                         $exifTool->{PREVIEW_INFO}->{Data} = $buff;
    2384                         if ($$tagInfo{IsOffset} and $$tagInfo{IsOffset} eq '2') {
    2385                             $exifTool->{PREVIEW_INFO}->{NoBaseShift} = 1;
    2386                         }
    2387                         $buff = '';
     3239                    if ($$tagInfo{Name} eq 'PreviewImageStart') {
     3240                        if ($$exifTool{FILE_TYPE} eq 'JPEG' and not $$tagInfo{MakerPreview}) {
     3241                            # hold onto the PreviewImage until we can determine if it fits
     3242                            $exifTool->{PREVIEW_INFO} or $exifTool->{PREVIEW_INFO} = { };
     3243                            $exifTool->{PREVIEW_INFO}{Data} = $buff;
     3244                            if ($$tagInfo{IsOffset} and $$tagInfo{IsOffset} eq '2') {
     3245                                $exifTool->{PREVIEW_INFO}{NoBaseShift} = 1;
     3246                            }
     3247                            $buff = '';
     3248                        } elsif ($$exifTool{TIFF_TYPE} eq 'ARW' and $$exifTool{Model}  eq 'DSLR-A100') {
     3249                            # the A100 double-references the same preview, so ignore the
     3250                            # second one (the offset and size will be patched later)
     3251                            next if $$exifTool{A100PreviewLength};
     3252                            $$exifTool{A100PreviewLength} = length $buff if defined $buff;
     3253                        }
    23883254                    }
    23893255                    # update offset accordingly and add to end of new data
    2390                     Set32u(length($newData)+$blockSize, \$newData, $offsetPos);
     3256                    Set32u($newOffset, \$newData, $offsetPos);
    23913257                    # add a pointer to fix up this offset value (marked with DataTag name)
    2392                     $fixup->AddFixup($offsetPos, $$tagInfo{DataTag});
     3258                    $fixup->AddFixup($offsetPos, $dataTag);
     3259                    # also add to subIfdDataFixup if necessary
     3260                    $subIfdDataFixup->AddFixup($offsetPos, $dataTag) if $subIfdDataFixup;
     3261                    # must also (sometimes) update StripOffsets in Panasonic RW2 images
     3262                    my $otherPos = $$offsetPair[0][5];
     3263                    if ($otherPos and $$tagInfo{PanasonicHack}) {
     3264                        Set32u($newOffset, \$newData, $otherPos);
     3265                        $fixup->AddFixup($otherPos, $dataTag);
     3266                    }
    23933267                    if ($ifd >= 0) {
    2394                         $buff .= "\0" if $size & 0x01;  # must be even size
     3268                        # buff length must be even (Note: may have changed since $size was set)
     3269                        $buff .= "\0" if length($buff) & 0x01;
    23953270                        $newData .= $buff;      # add this strip to the data
    23963271                    } else {
     
    23983273                    }
    23993274                }
     3275                SetByteOrder($oldOrder);
    24003276            }
    24013277        }
     3278        # verify that nothing else got written after determining TTW length
     3279        if (defined $ttwLen and $ttwLen != length($newData)) {
     3280            $exifTool->Error('Internal error writing MRW TTW');
     3281        }
    24023282    }
    24033283#
     3284# set offsets and generate fixups for tag values which were too large for memory
     3285#
     3286    $blockSize = 0;
     3287    foreach $blockInfo (@imageData) {
     3288        my ($pos, $size, $pad, $entry, $subFix) = @$blockInfo;
     3289        if (defined $entry) {
     3290            my $format = Get16u(\$newData, $entry + 2);
     3291            if ($format < 1 or $format > 13) {
     3292                $exifTool->Error('Internal error copying huge value');
     3293                last;
     3294            } else {
     3295                # set count and offset in directory entry
     3296                Set32u($size / $formatSize[$format], \$newData, $entry + 4);
     3297                Set32u(length($newData)+$blockSize, \$newData, $entry + 8);
     3298                $fixup->AddFixup($entry + 8);
     3299                # create special fixup for SubIFD data
     3300                if ($imageDataFlag eq 'SubIFD') {
     3301                    my $subIfdDataFixup = new Image::ExifTool::Fixup;
     3302                    $subIfdDataFixup->AddFixup($entry + 8);
     3303                    # save fixup in imageData list
     3304                    $$blockInfo[4] = $subIfdDataFixup;
     3305                }
     3306                # must reset entry pointer so we don't use it again in a parent IFD!
     3307                $$blockInfo[3] = undef;
     3308            }
     3309        }
     3310        # apply additional shift required for contained SubIFD image data offsets
     3311        if ($subFix and defined $$subFix{BlockLen} and $numBlocks > 0) {
     3312            # our offset expects the data at the end of the SubIFD block (BlockLen + Start),
     3313            # but it will actually be at length($newData) + $blockSize.  So adjust
     3314            # accordingly (and subtract an extra Start because this shift is applied later)
     3315            $subFix->{Shift} += length($newData) - $$subFix{BlockLen} - 2 * $$subFix{Start} + $blockSize;
     3316            $subFix->ApplyFixup(\$newData);
     3317        }
     3318        $blockSize += $size + $pad;
     3319        --$numBlocks;
     3320    }
     3321#
    24043322# apply final shift to new data position if this is the top level IFD
    24053323#
    24063324    unless ($$dirInfo{Fixup}) {
    2407         my $newDataPos = $$dirInfo{NewDataPos} || 0;
     3325        my $hdrPtr = $$dirInfo{HeaderPtr};
     3326        my $newDataPos = $hdrPtr ? length $$hdrPtr : $$dirInfo{NewDataPos} || 0;
    24083327        # adjust CanonVRD offset to point to end of regular TIFF if necessary
    24093328        # (NOTE: This will be incorrect if multiple trailers exist,
    2410         #  but it is unlikely that it could ever be correct in this case anyway)
     3329        #  but it is unlikely that it could ever be correct in this case anyway.
     3330        #  Also, this doesn't work for JPEG images (but CanonDPP doesn't set
     3331        #  this when editing JPEG images anyway))
    24113332        $fixup->SetMarkerPointers(\$newData, 'CanonVRD', length($newData) + $blockSize);
    24123333        if ($newDataPos) {
     
    24143335            $fixup->ApplyFixup(\$newData);
    24153336        }
     3337        # save fixup for adjusting Leica trailer offset if necessary
     3338        if ($$exifTool{LeicaTrailer}) {
     3339            my $trail = $$exifTool{LeicaTrailer};
     3340            $$trail{Fixup} or $$trail{Fixup} = new Image::ExifTool::Fixup;
     3341            $$trail{Fixup}->AddFixup($fixup);
     3342        }
    24163343        # save fixup for PreviewImage in JPEG file if necessary
    24173344        my $previewInfo = $exifTool->{PREVIEW_INFO};
    24183345        if ($previewInfo) {
    2419             my $pt = \$previewInfo->{Data}; # image data or 'LOAD' flag
     3346            my $pt = \$previewInfo->{Data}; # image data or 'LOAD_PREVIEW' flag
    24203347            # now that we know the size of the EXIF data, first test to see if our new image fits
    24213348            # inside the EXIF segment (remember about the TIFF and EXIF headers: 8+6 bytes)
    2422             if (($$pt ne 'LOAD' and length($$pt) + length($newData) + 14 <= 0xfffd) or
     3349            if (($$pt ne 'LOAD_PREVIEW' and length($$pt) + length($newData) + 14 <= 0xfffd and
     3350                not $previewInfo->{IsTrailer}) or
    24233351                $previewInfo->{IsShort}) # must fit in this segment if using short pointers
    24243352            {
    24253353                # It fits! (or must exist in EXIF segment), so fixup the
    24263354                # PreviewImage pointers and stuff the preview image in here
    2427                 my $newPos = length($newData) + ($newDataPos || 0);
     3355                my $newPos = length($newData) + $newDataPos;
    24283356                $newPos += ($previewInfo->{BaseShift} || 0);
    24293357                if ($previewInfo->{Relative}) {
     
    24413369                $previewInfo->{Fixup}->AddFixup($fixup);
    24423370            }
    2443         } else {
    2444             # delete both IFD0 and IFD1 if only mandatory tags remain
    2445             $newData = '' if defined $newData and $deleteAll;
     3371        } elsif (defined $newData and $deleteAll) {
     3372            $newData = '';  # delete both IFD0 and IFD1 since only mandatory tags remain
     3373        } elsif ($$exifTool{A100PreviewLength}) {
     3374            # save preview image start for patching A100 quirks later
     3375            $$exifTool{A100PreviewStart} = $fixup->GetMarkerPointers(\$newData, 'PreviewImage');
    24463376        }
    24473377        # save location of last IFD for use in Canon RAW header
    24483378        if ($newDataPos == 16) {
    24493379            my @ifdPos = $fixup->GetMarkerPointers(\$newData,'NextIFD');
    2450             $_[1]->{LastIFD} = pop @ifdPos;
     3380            $$origDirInfo{LastIFD} = pop @ifdPos;
     3381        }
     3382        # recrypt SR2 SubIFD data if necessary
     3383        my $key = $$exifTool{SR2SubIFDKey};
     3384        if ($key) {
     3385            my $start = $fixup->GetMarkerPointers(\$newData, 'SR2SubIFDOffset');
     3386            my $len = $$exifTool{SR2SubIFDLength};
     3387            # (must subtract 8 for size of TIFF header)
     3388            if ($start and $start - 8 + $len <= length $newData) {
     3389                require Image::ExifTool::Sony;
     3390                Image::ExifTool::Sony::Decrypt(\$newData, $start - 8, $len, $key);
     3391            }
    24513392        }
    24523393    }
     
    24763417=head1 AUTHOR
    24773418
    2478 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     3419Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    24793420
    24803421This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteIPTC.pl

    r16842 r24107  
    4040);
    4141
    42 my %iptcCharsetInv = ( 'UTF8' => "\x1b%G" );
     42my %iptcCharsetInv = ( 'UTF8' => "\x1b%G", 'UTF-8' => "\x1b%G" );
    4343
    4444# ISO 2022 Character Coding Notes
     
    7171#   C0 : 0x1b 0x21 F (0x21 = '!')
    7272#   C1 : 0x1b 0x22 F (0x22 = '"')
    73 # Complete codes (control+graphics, designated and involked)
     73# Complete codes (control+graphics, designated and invoked)
    7474#   0x1b 0x25 F   (0x25 = '%')
    7575#   0x1b 0x25 I F
     
    9898#------------------------------------------------------------------------------
    9999# validate raw values for writing
    100 # Inputs: 0) ExifTool object reference, 1) tagInfo hash reference,
    101 #         2) raw value reference
     100# Inputs: 0) ExifTool object ref, 1) tagInfo hash ref, 2) raw value ref
    102101# Returns: error string or undef (and possibly changes value) on success
    103102sub CheckIPTC($$$)
     
    118117        for ($n=0; $n<$bytes; ++$n) { $val >>= 8; }
    119118        return "Value too large for $bytes-byte format" if $val;
    120     } elsif ($format =~ /^(string|digits)\[?(\d+),?(\d*)\]?$/) {
     119    } elsif ($format =~ /^(string|digits|undef)\[?(\d+),?(\d*)\]?$/) {
    121120        my ($fmt, $minlen, $maxlen) = ($1, $2, $3);
    122121        my $len = length $$valPtr;
    123122        if ($fmt eq 'digits') {
    124             return 'Non-numeric characters in value' unless $$valPtr =~ /^\d+$/;
    125             # left pad with zeros if necessary
    126             $$valPtr = ('0' x ($len - $minlen)) . $$valPtr if $len < $minlen;
    127         }
    128         if ($minlen) {
     123            return 'Non-numeric characters in value' unless $$valPtr =~ /^\d*$/;
     124            if ($len < $minlen and $len) {
     125                # left pad with zeros if necessary
     126                $$valPtr = ('0' x ($minlen - $len)) . $$valPtr;
     127                $len = $minlen;
     128            }
     129        }
     130        if (defined $minlen) {
    129131            $maxlen or $maxlen = $minlen;
    130132            return "String too short (minlen is $minlen)" if $len < $minlen;
    131             return "String too long (maxlen is $maxlen)" if $len > $maxlen;
     133            if ($len > $maxlen and not $exifTool->Options('IgnoreMinorErrors')) {
     134                $$exifTool{CHECK_WARN} = "[minor] IPTC:$$tagInfo{Name} exceeds length limit (truncated)";
     135                $$valPtr = substr($$valPtr, 0, $maxlen);
     136            }
    132137        }
    133138    } else {
     
    146151{
    147152    my ($exifTool, $tagInfo, $valPtr, $xlatPtr, $rec, $read) = @_;
    148     return unless $$tagInfo{Format};
    149     if ($$tagInfo{Format} =~ /^int(\d+)/) {
     153    my $format = $$tagInfo{Format} || $$tagInfo{Table}{FORMAT};
     154    return unless $format;
     155    if ($format =~ /^int(\d+)/) {
    150156        if ($read) {
    151157            my $len = length($$valPtr);
     
    168174            }
    169175        }
    170     } elsif ($$tagInfo{Format} =~ /^string/) {
     176    } elsif ($format =~ /^string/) {
    171177        if ($rec == 1) {
    172178            if ($$tagInfo{Name} eq 'CodedCharacterSet') {
     
    181187#------------------------------------------------------------------------------
    182188# generate IPTC-format date
    183 # Inputs: 0) EXIF-format date string (YYYY:MM:DD) or date/time string
    184 # Returns: IPTC-format date string (YYYYMMDD), or undef on error
     189# Inputs: 0) EXIF-format date string (YYYY:mm:dd) or date/time string
     190# Returns: IPTC-format date string (YYYYmmdd), or undef and issue warning on error
    185191sub IptcDate($)
    186192{
    187193    my $val = shift;
    188     $val =~ s/.*(\d{4}):?(\d{2}):?(\d{2}).*/$1$2$3/ or undef $val;
     194    unless ($val =~ s/.*(\d{4}):?(\d{2}):?(\d{2}).*/$1$2$3/s) {
     195        warn "Invalid date format (use YYYY:mm:dd)\n";
     196        undef $val;
     197    }
    189198    return $val;
    190199}
     
    193202# generate IPTC-format time
    194203# Inputs: 0) EXIF-format time string (HH:MM:SS[+/-HH:MM]) or date/time string
    195 # Returns: IPTC-format time string (HHMMSS+HHMM), or undef on error
     204# Returns: IPTC-format time string (HHMMSS+HHMM), or undef and issue warning on error
    196205sub IptcTime($)
    197206{
    198207    my $val = shift;
    199     if ($val =~ /\s*\b(\d{1,2}):?(\d{1,2}):?(\d{1,2})(\S*)\s*$/) {
    200         $val = sprintf("%.2d%.2d%.2d",$1,$2,$3);
    201         my $tz = $4;
    202         if ($tz =~ /([+-]\d{1,2}):?(\d{1,2})/) {
    203             $val .= sprintf("%+.2d%.2d",$1,$2);
     208    if ($val =~ /(.*?)\b(\d{1,2})(:?)(\d{2})(:?)(\d{2})(\S*)\s*$/s and ($3 or not $5)) {
     209        $val = sprintf("%.2d%.2d%.2d",$2,$4,$6);
     210        my ($date, $tz) = ($1, $7);
     211        if ($tz =~ /([+-]\d{1,2}):?(\d{2})/) {
     212            $tz = sprintf("%+.2d%.2d",$1,$2);
     213        } elsif ($tz =~ /Z/i) {
     214            $tz = '+0000';  # UTC
    204215        } else {
    205             $val .= '+0000';    # don't know the time zone
    206         }
     216            # use local system timezone by default
     217            my (@tm, $time);
     218            if ($date and $date =~ /^(\d{4}):(\d{2}):(\d{2})\s*$/ and eval 'require Time::Local') {
     219                # we were given a date too, so determine the local timezone
     220                # offset at the specified date/time
     221                my @d = ($3,$2-1,$1-1900);
     222                $val =~ /(\d{2})(\d{2})(\d{2})/;
     223                @tm = ($3,$2,$1,@d);
     224                $time = Image::ExifTool::TimeLocal(@tm);
     225            } else {
     226                # it is difficult to get the proper local timezone offset for this
     227                # time because the date tag is written separately.  (The offset may be
     228                # different on a different date due to daylight savings time.)  In this
     229                # case the best we can do easily is to use the current timezone offset.
     230                $time = time;
     231                @tm = localtime($time);
     232            }
     233            ($tz = Image::ExifTool::TimeZoneString(\@tm, $time)) =~ tr/://d;
     234        }
     235        $val .= $tz;
    207236    } else {
     237        warn "Invalid time format (use HH:MM:SS[+/-HH:MM])\n";
    208238        undef $val;     # time format error
    209239    }
     
    257287#------------------------------------------------------------------------------
    258288# Write IPTC data record
    259 # Inputs: 0) ExifTool object reference, 1) source dirInfo reference,
    260 #         2) tag table reference
     289# Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref
    261290# Returns: IPTC data block (may be empty if no IPTC data)
    262291# Notes: Increments ExifTool CHANGED flag for each tag changed
    263 sub WriteIPTC($$$)
     292sub DoWriteIPTC($$$)
    264293{
    265294    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    266     $exifTool or return 1;    # allow dummy access to autoload this package
     295    my $verbose = $exifTool->Options('Verbose');
     296    my $out = $exifTool->Options('TextOut');
     297
     298    # avoid editing IPTC directory unless necessary:
     299    # - improves speed
     300    # - avoids changing current MD5 digest unnecessarily
     301    # - avoids adding mandatory tags unless some other IPTC is changed
     302    unless (exists $$exifTool{EDIT_DIRS}{$$dirInfo{DirName}} or
     303        # standard IPTC tags in other locations should be edited too (ie. AFCP_IPTC)
     304        ($tagTablePtr = \%Image::ExifTool::IPTC::Main and exists $$exifTool{EDIT_DIRS}{IPTC}))
     305    {
     306        print $out "$$exifTool{INDENT}  [nothing changed]\n" if $verbose;
     307        return undef;
     308    }
    267309    my $dataPt = $$dirInfo{DataPt};
    268310    unless ($dataPt) {
     
    272314    my $start = $$dirInfo{DirStart} || 0;
    273315    my $dirLen = $$dirInfo{DirLen};
    274     my $verbose = $exifTool->Options('Verbose');
    275     my $out = $exifTool->Options('TextOut');
    276316    my ($tagInfo, %iptcInfo, $tag);
    277317
    278     # begin by assuming IPTC is coded in Latin unless otherwise specified
    279     my $xlat = $exifTool->Options('Charset');
    280     undef $xlat if $xlat eq 'Latin';
     318    # start by assuming default IPTC encoding
     319    my $xlat = $exifTool->Options('CharsetIPTC');
     320    undef $xlat if $xlat eq $exifTool->Options('Charset');
    281321
    282322    # make sure our dataLen is defined (note: allow zero length directory)
     
    304344        my $subTablePtr = Image::ExifTool::GetTagTable($table);
    305345        $recordNum{$subTablePtr} = $tag;
    306         Image::ExifTool::GenerateTagIDs($subTablePtr);
    307346    }
    308347
     
    342381    my $allMandatory = 0;
    343382    my %foundRec;           # found flags: 0x01-existed before, 0x02-deleted, 0x04-created
     383    my $addNow;
    344384
    345385    for (;;$tail=$pos) {
     
    351391            if ($id == 0x1c) {
    352392                if ($rec < $lastRec) {
    353                     return undef if $exifTool->Warn("IPTC doesn't conform to spec: Records out of sequence", 1);
     393                    if ($rec == 0) {
     394                        return undef if $exifTool->Warn("IPTC record 0 encountered, subsequent records ignored", 1);
     395                        undef $rec;
     396                        $pos = $dirEnd;
     397                        $len = 0;
     398                    } else {
     399                        return undef if $exifTool->Warn("IPTC doesn't conform to spec: Records out of sequence", 1);
     400                    }
    354401                }
    355402                # handle extended IPTC entry if necessary
     
    375422            }
    376423        }
    377         if (not defined $rec or $rec != $lastRec) {
    378             # write out all our records that come before this one
     424        # write out all our records that come before this one
     425        my $writeRec = (not defined $rec or $rec != $lastRec);
     426        if ($writeRec or $addNow) {
    379427            for (;;) {
    380428                my $newRec = $recordList[0];
    381                 if (not defined $newRec or $newRec != $lastRec) {
     429                if ($addNow) {
     430                    $tagInfo = $addNow;
     431                } elsif (not defined $newRec or $newRec != $lastRec) {
    382432                    # handle mandatory tags in last record unless it was empty
    383433                    if (length $newData > $lastRecPos) {
     
    412462                                $tagInfo = $subTablePtr->{$mandTag} or warn("WriteIPTC: Internal error 2\n"), next;
    413463                                my $value = $mandatory->{$mandTag};
    414                                 $verbose > 1 and print $out "    + IPTC:$$tagInfo{Name} = '$value' (mandatory)\n";
     464                                $exifTool->VerboseValue("+ IPTC:$$tagInfo{Name}", $value, ' (mandatory)');
    415465                                # apply necessary format conversions
    416466                                FormatIPTC($exifTool, $tagInfo, \$value, \$xlat, $lastRec);
     
    419469                                my $entry = pack("CCCn", 0x1c, $lastRec, $mandTag, length($value));
    420470                                $newData .= $entry . $value;    # add entry to new IPTC data
    421                                 ++$exifTool->{CHANGED};
     471                                # (don't mark as changed if just mandatory tags changed)
     472                                # ++$exifTool->{CHANGED};
    422473                            }
    423474                        }
     
    428479                    $allMandatory = 1;
    429480                }
    430                 $tagInfo = ${$iptcInfo{$newRec}}[0];
     481                unless ($addNow) {
     482                    # compare current entry with entry next in line to write out
     483                    # (write out our tags in numerical order even though
     484                    # this isn't required by the IPTC spec)
     485                    last if defined $rec and $rec <= $newRec;
     486                    $tagInfo = ${$iptcInfo{$newRec}}[0];
     487                }
    431488                my $newTag = $$tagInfo{TagID};
    432                 # compare current entry with entry next in line to write out
    433                 # (write out our tags in numerical order even though
    434                 # this isn't required by the IPTC spec)
    435                 last if defined $rec and $rec <= $newRec;
    436                 my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
     489                my $nvHash = $exifTool->GetNewValueHash($tagInfo);
    437490                # only add new values if...
    438491                my ($doSet, @values);
    439492                my $found = $foundRec{$newRec}->{$newTag} || 0;
    440493                if ($found & 0x02) {
    441                     # ...tag existed before and was deleted
    442                     $doSet = 1;
     494                    # ...tag existed before and was deleted (unless we already added it)
     495                    $doSet = 1 unless $found & 0x04;
    443496                } elsif ($$tagInfo{List}) {
    444497                    # ...tag is List and it existed before or we are creating it
    445                     $doSet = 1 if $found or Image::ExifTool::IsCreating($newValueHash);
     498                    $doSet = 1 if $found or Image::ExifTool::IsCreating($nvHash);
    446499                } else {
    447500                    # ...tag didn't exist before and we are creating it
    448                     $doSet = 1 if not $found and Image::ExifTool::IsCreating($newValueHash);
     501                    $doSet = 1 if not $found and Image::ExifTool::IsCreating($nvHash);
    449502                }
    450503                if ($doSet) {
    451                     @values = Image::ExifTool::GetNewValues($newValueHash);
     504                    @values = Image::ExifTool::GetNewValues($nvHash);
    452505                    @values and $foundRec{$newRec}->{$newTag} = $found | 0x04;
    453506                    # write tags for each value in list
    454507                    my $value;
    455508                    foreach $value (@values) {
    456                         $verbose > 1 and print $out "    + IPTC:$$tagInfo{Name} = '$value'\n";
     509                        $exifTool->VerboseValue("+ IPTC:$$tagInfo{Name}", $value);
    457510                        # reset allMandatory flag if a non-mandatory tag is written
    458511                        if ($allMandatory) {
     
    476529                    }
    477530                }
     531                # continue on with regular programming if done adding tag now
     532                if ($addNow) {
     533                    undef $addNow;
     534                    next if $writeRec;
     535                    last;
     536                }
    478537                # remove this tagID from the sorted write list
    479538                shift @{$iptcInfo{$newRec}};
    480539                shift @recordList unless @{$iptcInfo{$newRec}};
    481540            }
    482             # all done if no more records to write
    483             last unless defined $rec;
    484             # update last record variables
    485             $lastRec = $rec;
    486             $lastRecPos = length $newData;
    487             $allMandatory = 1;
     541            if ($writeRec) {
     542                # all done if no more records to write
     543                last unless defined $rec;
     544                # update last record variables
     545                $lastRec = $rec;
     546                $lastRecPos = length $newData;
     547                $allMandatory = 1;
     548            }
    488549        }
    489550        # set flag indicating we found this tag
    490         $foundRec{$rec}->{$tag} = 1;
     551        $foundRec{$rec}->{$tag} = ($foundRec{$rec}->{$tag} || 0) || 0x01;
    491552        # write out this record unless we are setting it with a new value
    492553        $tagInfo = $set{$rec}->{$tag};
    493554        if ($tagInfo) {
    494             my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
     555            my $nvHash = $exifTool->GetNewValueHash($tagInfo);
    495556            $len = $pos - $valuePtr;
    496557            my $val = substr($$dataPt, $valuePtr, $len);
    497558            my $oldXlat = $xlat;
    498559            FormatIPTC($exifTool, $tagInfo, \$val, \$xlat, $rec, 1);
    499             if (Image::ExifTool::IsOverwriting($newValueHash, $val)) {
     560            if (Image::ExifTool::IsOverwriting($nvHash, $val)) {
    500561                $xlat = $oldXlat;   # don't change translation (not writing this value)
    501                 $verbose > 1 and print $out "    - IPTC:$$tagInfo{Name} = '$val'\n";
     562                $exifTool->VerboseValue("- IPTC:$$tagInfo{Name}", $val);
    502563                ++$exifTool->{CHANGED};
    503564                # set deleted flag to indicate we found and deleted this tag
    504565                $foundRec{$rec}->{$tag} |= 0x02;
    505                 # set allMandatory flag to 2 indicating a tag was removed
     566                # increment allMandatory flag to indicate a tag was removed
    506567                $allMandatory and ++$allMandatory;
     568                # write this tag now if overwriting an existing value
     569                if ($$nvHash{Value} and @{$$nvHash{Value}} and @recordList and
     570                    $recordList[0] == $rec and not $foundRec{$rec}->{$tag} & 0x04)
     571                {
     572                    $addNow = $tagInfo;
     573                }
    507574                next;
    508575            }
     
    532599}
    533600
     601#------------------------------------------------------------------------------
     602# Write IPTC data record and calculate NewIPTCDigest
     603# Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref
     604# Returns: IPTC data block (may be empty if no IPTC data)
     605# Notes: Increments ExifTool CHANGED flag for each tag changed
     606sub WriteIPTC($$$)
     607{
     608    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
     609    $exifTool or return 1;    # allow dummy access to autoload this package
     610
     611    my $newData = DoWriteIPTC($exifTool, $dirInfo, $tagTablePtr);
     612
     613    # calculate standard IPTC digests only if we are writing or deleting
     614    # Photoshop:IPTCDigest with a value of 'new' or 'old'
     615    while ($Image::ExifTool::Photoshop::iptcDigestInfo) {
     616        my $nvHash = $exifTool->{NEW_VALUE}{$Image::ExifTool::Photoshop::iptcDigestInfo};
     617        last unless defined $nvHash;
     618        last unless IsStandardIPTC($exifTool->MetadataPath());
     619        my @values = Image::ExifTool::GetNewValues($nvHash);
     620        push @values, @{$$nvHash{DelValue}} if $$nvHash{DelValue};
     621        my $new = grep /^new$/, @values;
     622        my $old = grep /^old$/, @values;
     623        last unless $new or $old;
     624        unless (eval 'require Digest::MD5') {
     625            $exifTool->Warn('Digest::MD5 must be installed to calculate IPTC digest');
     626            last;
     627        }
     628        my $dataPt;
     629        if ($new) {
     630            if (defined $newData) {
     631                $dataPt = \$newData;
     632            } else {
     633                $dataPt = $$dirInfo{DataPt};
     634                if ($$dirInfo{DirStart} or length($$dataPt) != $$dirInfo{DirLen}) {
     635                    my $buff = substr($$dataPt, $$dirInfo{DirStart}, $$dirInfo{DirLen});
     636                    $dataPt = \$buff;
     637                }
     638            }
     639            # set NewIPTCDigest data member unless IPTC is being deleted
     640            $$exifTool{NewIPTCDigest} = Digest::MD5::md5($$dataPt) if length $$dataPt;
     641        }
     642        if ($old) {
     643            if ($new and not defined $newData) {
     644                $$exifTool{OldIPTCDigest} = $$exifTool{NewIPTCDigest};
     645            } elsif ($$dirInfo{DataPt}) { #(may be undef if creating new IPTC)
     646                $dataPt = $$dirInfo{DataPt};
     647                if ($$dirInfo{DirStart} or length($$dataPt) != $$dirInfo{DirLen}) {
     648                    my $buff = substr($$dataPt, $$dirInfo{DirStart}, $$dirInfo{DirLen});
     649                    $dataPt = \$buff;
     650                }
     651                $$exifTool{OldIPTCDigest} = Digest::MD5::md5($$dataPt) if length $$dataPt;
     652            }
     653        }
     654        last;
     655    }
     656    return $newData;
     657}
     658
    534659
    5356601; # end
     
    552677=head1 AUTHOR
    553678
    554 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     679Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    555680
    556681This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePNG.pl

    r16842 r24107  
    115115    if ($exifTool->{ADD_DIRS}->{ICC_Profile}) {
    116116        # write new ICC data
    117         my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
     117        my $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::ICC_Profile::Main');
    118118        my %dirInfo = ( Parent => 'PNG', DirName => 'ICC_Profile' );
    119119        my $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
     
    127127
    128128#------------------------------------------------------------------------------
     129# Generate tEXt, zTXt or iTXt data for writing
     130# Inputs: 0) ExifTool ref, 1) tagID, 2) tagInfo ref, 3) value string, 4) language code
     131# Returns: chunk data (not including 8-byte chunk header)
     132# Notes: Sets ExifTool TextChunkType member to the type of chunk written
     133sub BuildTextChunk($$$$$)
     134{
     135    my ($exifTool, $tag, $tagInfo, $val, $lang) = @_;
     136    my ($xtra, $compVal, $iTXt, $comp);
     137    if ($$tagInfo{SubDirectory}) {
     138        if ($$tagInfo{Name} eq 'XMP') {
     139            $iTXt = 2;      # write as iTXt but flag to avoid encoding
     140            # (never compress XMP)
     141        } else {
     142            $comp = 2;      # compress raw profile if possible
     143        }
     144    } else {
     145        # compress if specified
     146        $comp = 1 if $exifTool->Options('Compress');
     147        if ($lang) {
     148            $iTXt = 1;      # write as iTXt if it has a language code
     149            $tag =~ s/-$lang$//;    # remove language code from tagID
     150        } elsif ($$exifTool{OPTIONS}{Charset} ne 'Latin' and $val =~  /[\x80-\xff]/) {
     151            $iTXt = 1;      # write as iTXt if it contains non-Latin special characters
     152        }
     153    }
     154    if ($comp) {
     155        my $warn;
     156        if (eval 'require Compress::Zlib') {
     157            my $deflate = Compress::Zlib::deflateInit();
     158            $compVal = $deflate->deflate($val) if $deflate;
     159            if (defined $compVal) {
     160                $compVal .= $deflate->flush();
     161                # only compress if it actually saves space
     162                unless (length($compVal) < length($val)) {
     163                    undef $compVal;
     164                    $warn = 'uncompressed data is smaller';
     165                }
     166            } else {
     167                $warn = 'deflate error';
     168            }
     169        } else {
     170            $warn = 'Compress::Zlib not available';
     171        }
     172        # warn if any user-specified compression fails
     173        if ($warn and $comp == 1) {
     174            $exifTool->Warn("PNG:$$tagInfo{Name} not compressed ($warn)", 1);
     175        }
     176    }
     177    # decide whether to write as iTXt, zTXt or tEXt
     178    if ($iTXt) {
     179        $$exifTool{TextChunkType} = 'iTXt';
     180        $xtra = (defined $compVal ? "\x01\0" : "\0\0") . ($lang || '') . "\0\0";
     181        # iTXt is encoded as UTF-8 (but note that XMP is already UTF-8)
     182        $val = $exifTool->Encode($val, 'UTF8') if $iTXt == 1;
     183    } elsif (defined $compVal) {
     184        $$exifTool{TextChunkType} = 'zTXt';
     185        $xtra = "\0";
     186    } else {
     187        $$exifTool{TextChunkType} = 'tEXt';
     188        $xtra = '';
     189    }
     190    return $tag . "\0" . $xtra . (defined $compVal ? $compVal : $val);
     191}
     192
     193#------------------------------------------------------------------------------
    129194# Add any outstanding new chunks to the PNG image
    130195# Inputs: 0) ExifTool object ref, 1) output file or scalar ref
     
    140205    foreach $tag (sort keys %$addTags) {
    141206        my $tagInfo = $$addTags{$tag};
    142         my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
     207        my $nvHash = $exifTool->GetNewValueHash($tagInfo);
    143208        # (always create native PNG information, so don't check IsCreating())
    144         next unless Image::ExifTool::IsOverwriting($newValueHash) > 0;
    145         my $val = Image::ExifTool::GetNewValues($newValueHash);
     209        next unless Image::ExifTool::IsOverwriting($nvHash) > 0;
     210        my $val = Image::ExifTool::GetNewValues($nvHash);
    146211        if (defined $val) {
    147212            my $data;
    148213            if ($$tagInfo{Table} eq \%Image::ExifTool::PNG::TextualData) {
    149                 $data = "tEXt$tag\0$val";
     214                $data = BuildTextChunk($exifTool, $tag, $tagInfo, $val, $$tagInfo{LangCode});
     215                $data = $$exifTool{TextChunkType} . $data;
     216                delete $$exifTool{TextChunkType};
    150217            } else {
    151218                $data = "$tag$val";
    152             }
    153             # write as compressed zTXt if specified
    154             if ($exifTool->Options('Compress')) {
    155                 my $warn;
    156                 if (eval 'require Compress::Zlib') {
    157                     my $buff;
    158                     my $deflate = Compress::Zlib::deflateInit();
    159                     $buff = $deflate->deflate($val) if $deflate;
    160                     if (defined $buff) {
    161                         $buff .= $deflate->flush();
    162                         # only write as zTXt if it actually saves space
    163                         if (length($buff) < length($val) - 1) {
    164                             $data = "zTXt$tag\0\0$buff";
    165                         } else {
    166                             $warn = 'uncompressed data is smaller';
    167                         }
    168                     } else {
    169                         $warn = 'deflate error';
    170                     }
    171                 } else {
    172                     $warn = 'Compress::Zlib not available';
    173                 }
    174                 $warn and $exifTool->Warn("PNG:$$tagInfo{Name} not compressed ($warn)", 1);
    175219            }
    176220            my $hdr = pack('N', length($data) - 4);
    177221            my $cbuf = pack('N', CalculateCRC(\$data, undef));
    178222            Write($outfile, $hdr, $data, $cbuf) or $err = 1;
    179             $exifTool->VPrint(1, "    + PNG:$$tagInfo{Name} = '",$exifTool->Printable($val),"'\n");
     223            $exifTool->VerboseValue("+ PNG:$$tagInfo{Name}", $val);
    180224            ++$exifTool->{CHANGED};
    181225        }
     
    192236            $exifTool->VPrint(0, "Creating EXIF profile:\n");
    193237            $exifTool->{TIFF_TYPE} = 'APP1';
    194             $tagTablePtr = GetTagTable('Image::ExifTool::Exif::Main');
    195             # use specified byte ordering or ordering from maker notes if set
    196             my $byteOrder = $exifTool->Options('ByteOrder') ||
    197                 $exifTool->GetNewValues('ExifByteOrder') || $exifTool->{MAKER_NOTE_BYTE_ORDER} || 'MM';
    198             unless (SetByteOrder($byteOrder)) {
    199                 warn "Invalid byte order '$byteOrder'\n";
    200                 $byteOrder = $exifTool->{MAKER_NOTE_BYTE_ORDER} || 'MM';
    201                 SetByteOrder($byteOrder);
    202             }
    203             $dirInfo{NewDataPos} = 8,   # new data will come after TIFF header
    204             $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
     238            $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::Exif::Main');
     239            $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr, \&Image::ExifTool::WriteTIFF);
    205240            if (defined $buff and length $buff) {
    206                 my $tiffHdr = $byteOrder . Set16u(42) . Set32u(8);
    207                 $buff = $Image::ExifTool::exifAPP1hdr . $tiffHdr . $buff;
     241                $buff = $Image::ExifTool::exifAPP1hdr . $buff;
    208242                WriteProfile($outfile, 'APP1', \$buff, 'generic') or $err = 1;
    209243            }
    210244        } elsif ($dir eq 'XMP') {
    211245            $exifTool->VPrint(0, "Creating XMP iTXt chunk:\n");
    212             $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
     246            $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::XMP::Main');
    213247            $dirInfo{ReadOnly} = 1;
    214248            $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
     
    229263            $exifTool->VPrint(0, "Creating IPTC profile:\n");
    230264            # write new IPTC data
    231             $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
     265            $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::Photoshop::Main');
    232266            $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
    233267            if (defined $buff and length $buff) {
     
    237271            $exifTool->VPrint(0, "Creating ICC profile:\n");
    238272            # write new ICC data (only done if we couldn't create iCCP chunk)
    239             $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
     273            $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::ICC_Profile::Main');
    240274            $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
    241275            if (defined $buff and length $buff) {
    242276                WriteProfile($outfile, 'icm', \$buff, 'ICC') or $err = 1;
    243                 $exifTool->Warn('Wrote ICC as generic profile (no Compress::Zlib)');
     277                $exifTool->Warn('Wrote ICC as a raw profile (no Compress::Zlib)');
    244278            }
    245279        }
     
    282316=head1 AUTHOR
    283317
    284 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     318Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    285319
    286320This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePhotoshop.pl

    r16842 r24107  
    5555    my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $start);
    5656    my $dirEnd = $start + $dirLen;
    57     my $verbose = $exifTool->Options('Verbose');
    58     my $out = $exifTool->Options('TextOut');
    5957    my $newData = '';
    6058
     
    104102            $tagInfo = $$newTags{$tagID};
    105103            delete $$newTags{$tagID};
    106             my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
     104            my $nvHash = $exifTool->GetNewValueHash($tagInfo);
    107105            # check to see if we are overwriting this tag
    108106            $value = substr($$dataPt, $pos, $size);
    109             if (Image::ExifTool::IsOverwriting($newValueHash, $value)) {
    110                 $verbose > 1 and print $out "    - Photoshop:$$tagInfo{Name} = '$value'\n";
    111                 $value = Image::ExifTool::GetNewValues($newValueHash);
     107            my $isOverwriting = Image::ExifTool::IsOverwriting($nvHash, $value);
     108            # handle special 'new' and 'old' values for IPTCDigest
     109            if (not $isOverwriting and $tagInfo eq $iptcDigestInfo) {
     110                if (grep /^new$/, @{$$nvHash{DelValue}}) {
     111                    $isOverwriting = 1 if $$exifTool{NewIPTCDigest} and
     112                                          $$exifTool{NewIPTCDigest} eq $value;
     113                }
     114                if (grep /^old$/, @{$$nvHash{DelValue}}) {
     115                    $isOverwriting = 1 if $$exifTool{OldIPTCDigest} and
     116                                          $$exifTool{OldIPTCDigest} eq $value;
     117                }
     118            }
     119            if ($isOverwriting) {
     120                $exifTool->VerboseValue("- Photoshop:$$tagInfo{Name}", $value);
     121                # handle IPTCDigest specially because we want to write it last
     122                # so the new IPTC digest will be known
     123                if ($tagInfo eq $iptcDigestInfo) {
     124                    $$newTags{$tagID} = $tagInfo;   # add later
     125                    $value = undef;
     126                } else {
     127                    $value = Image::ExifTool::GetNewValues($nvHash);
     128                }
    112129                ++$exifTool->{CHANGED};
    113130                next unless defined $value;     # next if tag is being deleted
    114131                # set resource name if necessary
    115132                SetResourceName($tagInfo, $name, \$value);
    116                 $verbose > 1 and print $out "    + Photoshop:$$tagInfo{Name} = '$value'\n";
     133                $exifTool->VerboseValue("+ Photoshop:$$tagInfo{Name}", $value);
    117134            }
    118135        } else {
     
    168185        if ($$newTags{$tagID}) {
    169186            $tagInfo = $$newTags{$tagID};
    170             my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
    171             $value = Image::ExifTool::GetNewValues($newValueHash);
     187            my $nvHash = $exifTool->GetNewValueHash($tagInfo);
     188            $value = Image::ExifTool::GetNewValues($nvHash);
     189            # handle new IPTCDigest value specially
     190            if ($tagInfo eq $iptcDigestInfo and defined $value) {
     191                if ($value eq 'new') {
     192                    $value = $$exifTool{NewIPTCDigest};
     193                } elsif ($value eq 'old') {
     194                    $value = $$exifTool{OldIPTCDigest};
     195                }
     196                # (we already know we want to create this tag)
     197            } else {
     198                # don't add this tag unless specified
     199                next unless Image::ExifTool::IsCreating($nvHash);
     200            }
    172201            next unless defined $value;     # next if tag is being deleted
    173             # don't add this tag unless specified
    174             next unless Image::ExifTool::IsCreating($newValueHash);
    175             $verbose > 1 and print $out "    + Photoshop:$$tagInfo{Name} = '$value'\n";
     202            $exifTool->VerboseValue("+ Photoshop:$$tagInfo{Name}", $value);
    176203            ++$exifTool->{CHANGED};
    177204        } else {
     
    227254=head1 AUTHOR
    228255
    229 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     256Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    230257
    231258This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePostScript.pl

    r16842 r24107  
    7474
    7575#------------------------------------------------------------------------------
    76 # Check PS tag value
    77 # Inputs: 0) ExifTool object ref, 1) tag info ref, 2) value ref
    78 # Returns: undef on success, or error string
    79 sub CheckPS($$$)
    80 {
    81     my ($exifTool, $tagInfo, $valPt) = @_;
    82     # parentheses must be balanced (or escaped)
    83     my $n = 0;
    84     pos($$valPt) = 0;
    85     while ($$valPt =~ /(\(|\))/g) {
    86         $n += ($1 eq '(') ? 1 : -1;
    87         last if $n < 0;
    88     }
    89     return 'Unmatched parentheses' unless $n == 0;
    90     return undef;   # success
    91 }
    92 
    93 #------------------------------------------------------------------------------
    9476# Write XMP directory to file, with begin/end tokens if necessary
    9577# Inputs: 0) outfile ref, 1) flags hash ref, 2-N) data to write
     
    160142        $dirInfo{DataPt} = \$xmp;
    161143    }
    162     my $tagTablePtr = GetTagTable("Image::ExifTool::${dirName}::Main");
     144    my $tagTablePtr = Image::ExifTool::GetTagTable("Image::ExifTool::${dirName}::Main");
    163145    my $val = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
    164146    if (defined $val) {
     
    264246
    265247#------------------------------------------------------------------------------
     248# Encode postscript tag/value
     249# Inputs: 0) tag ID, 1) value
     250# Returns: postscript comment
     251# - adds brackets, escapes special characters, and limits line length
     252sub EncodeTag($$)
     253{
     254    my ($tag, $val) = @_;
     255    unless ($val =~ /^\d+$/) {
     256        $val =~ s/([()\\])/\\$1/g;  # escape brackets and backslashes
     257        $val =~ s/\n/\\n/g;         # escape newlines
     258        $val =~ s/\r/\\r/g;         # escape carriage returns
     259        $val =~ s/\t/\\t/g;         # escape tabs
     260        # use octal escape codes for other control characters
     261        $val =~ s/([\x00-\x1f\x7f\xff])/sprintf("\\%.3o",ord($1))/ge;
     262        $val = "($val)";
     263    }
     264    my $line = "%%$tag: $val";
     265    # postscript line limit is 255 characters
     266    # --> split if necessary using continuation comment "%%+"
     267    my $n;
     268    for ($n=255; length($line)>$n; $n+=255+length($/)) {
     269        substr($line, $n, 0) = "$/%%+";
     270    }
     271    return $line . $/;
     272}
     273
     274#------------------------------------------------------------------------------
    266275# Write new tags information in comments section
    267276# Inputs: 0) ExifTool object ref, 1) output file ref, 2) reference to new tag hash
     
    279288    foreach $tag (sort keys %$newTags) {
    280289        my $tagInfo = $$newTags{$tag};
    281         my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
    282         next unless Image::ExifTool::IsCreating($newValueHash);
    283         my $val = Image::ExifTool::GetNewValues($newValueHash);
    284         if ($exifTool->Options('Verbose') > 1) {
    285             my $out = $exifTool->Options('TextOut');
    286             print $out "    + PostScript:$$tagInfo{Name} = '$val'\n";
    287         }
    288         $val =~ /^\d+$/ or $val = "($val)"; # add brackets around strings
    289         my $buff = "%%$tag: $val$/";
    290         if (length $buff > 255) {
    291             $exifTool->Warn("Value for too long for $tag");
    292         } else {
    293             Write($outfile, $buff) or $success = 0;
    294             ++$exifTool->{CHANGED};
    295         }
     290        my $nvHash = $exifTool->GetNewValueHash($tagInfo);
     291        next unless Image::ExifTool::IsCreating($nvHash);
     292        my $val = Image::ExifTool::GetNewValues($nvHash);
     293        $exifTool->VerboseValue("+ PostScript:$$tagInfo{Name}", $val);
     294        Write($outfile, EncodeTag($tag, $val)) or $success = 0;
     295        ++$exifTool->{CHANGED};
    296296    }
    297297    # write XMP hint if necessary
     
    436436# rewrite PostScript data
    437437#
    438     my $oldsep = SetInputRecordSeparator($raf);
    439     unless ($oldsep and $raf->ReadLine($buff)) {
     438    local $/ = GetInputRecordSeparator($raf);
     439    unless ($/ and $raf->ReadLine($buff)) {
    440440        $exifTool->Error('Invalid PostScript data');
    441441        return 1;
    442442    }
    443443    $data .= $buff;
    444     unless ($data =~ /^%!PS-Adobe-3.(0|1)/) {
     444    unless ($data =~ /^%!PS-Adobe-3\.(\d+)\b/ and $1 < 2) {
    445445        if ($exifTool->Error("Document does not conform to DSC spec. Metadata may be unreadable by other apps", 1)) {
    446446            return 1;
    447447        }
    448448    }
     449    my $psRev = $1; # save PS revision number (3.x)
    449450    Write($outfile, $data) or $err = 1;
    450451    $flags{EPS} = 1 if $data =~ /EPSF/;
     
    461462    # set XMP hint flag (1 for adding, 0 for deleting, undef for no change)
    462463    $xmpHint = 1 if $$addDirs{XMP};
    463     $xmpHint = 0 if $exifTool->{DEL_GROUP}->{XMP};
     464    $xmpHint = 0 if $$exifTool{DEL_GROUP}{XMP};
    464465    $$newTags{XMP_HINT} = $xmpHint if $xmpHint;  # add special tag to newTags list
    465466
    466     my @lines;
     467    my (@lines, $changedNL);
    467468    my $altnl = ($/ eq "\x0d") ? "\x0a" : "\x0d";
    468469
     
    474475            $dos and CheckPSEnd($raf, $psEnd, $data);
    475476            # split line if it contains other newline sequences
    476             SplitLine(\$data, \@lines) if $data =~ /$altnl/;
    477         }
     477            if ($data =~ /$altnl/) {
     478                if (length($data) > 500000 and IsPC()) {
     479                    # patch for Windows memory problem
     480                    unless ($changedNL) {
     481                        $changedNL = 1;
     482                        my $t = $/;
     483                        $/ = $altnl;
     484                        $altnl = $t;
     485                        $raf->Seek(-length($data), 1);
     486                        next;
     487                    }
     488                } else {
     489                    # split into separate lines
     490                    SplitLine(\$data, \@lines);
     491                }
     492            }
     493        }
     494        undef $changedNL;
    478495        if ($endToken) {
    479496            # look for end token
     
    537554            # rewrite information from PostScript tags in comments
    538555            my ($tag, $val) = ($1, $2);
     556            # handle Adobe Illustrator files specially
     557            # - EVENTUALLY IT WOULD BE BETTER TO FIND ANOTHER IDENTIFICATION METHOD
     558            #   (because Illustrator doesn't care if the Creator is changed)
     559            if ($tag eq 'Creator' and $val =~ /^Adobe Illustrator/) {
     560                # disable writing XMP to PS-format Adobe Illustrator files and
     561                # older Illustrator EPS files becaues it confuses Illustrator
     562                # (Illustrator 8 and older write PS-Adobe-3.0, newer write PS-Adobe-3.1)
     563                if ($$editDirs{XMP} and $psRev == 0) {
     564                    if ($flags{EPS}) {
     565                        $exifTool->Warn("Can't write XMP to Illustrator 8 or older EPS files");
     566                    } else {
     567                        $exifTool->Warn("Can't write XMP to PS-format AI files");
     568                    }
     569                    # pretend like we wrote it already so we won't try to add it later
     570                    $doneDir{XMP} = 1;
     571                }
     572                # don't allow "Creator" to be changed in Illustrator files
     573                # (we need it to be able to recognize these files)
     574                # --> find a better way to do this!
     575                if ($$newTags{$tag}) {
     576                    $exifTool->Warn("Can't change Postscript:Creator of Illustrator files");
     577                    delete $$newTags{$tag};
     578                }
     579            }
    539580            if ($$newTags{$tag}) {
    540581                my $tagInfo = $$newTags{$tag};
     582                delete $$newTags{$tag}; # write it then forget it
    541583                next unless ref $tagInfo;
    542                 delete $$newTags{$tag}; # write it then forget it
    543                 $val =~ s/\x0d*\x0a*$//;        # remove trailing CR, LF or CR/LF
    544                 if ($val =~ s/^\((.*)\)$/$1/) { # remove brackets if necessary
    545                     $val =~ s/\) \(/, /g;       # convert contained brackets too
    546                 }
    547                 my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
    548                 if (Image::ExifTool::IsOverwriting($newValueHash, $val)) {
    549                     $verbose > 1 and print $out "    - PostScript:$$tagInfo{Name} = '$val'\n";
    550                     $val = Image::ExifTool::GetNewValues($newValueHash);
     584                # decode comment string (reading continuation lines if necessary)
     585                $val = DecodeComment($val, $raf, \@lines, \$data);
     586                $val = join $exifTool->Options('ListSep'), @$val if ref $val eq 'ARRAY';
     587                my $nvHash = $exifTool->GetNewValueHash($tagInfo);
     588                if (Image::ExifTool::IsOverwriting($nvHash, $val)) {
     589                    $exifTool->VerboseValue("- PostScript:$$tagInfo{Name}", $val);
     590                    $val = Image::ExifTool::GetNewValues($nvHash);
    551591                    ++$exifTool->{CHANGED};
    552592                    next unless defined $val;   # next if tag is being deleted
    553                     $verbose > 1 and print $out "    + PostScript:$$tagInfo{Name} = '$val'\n";
    554                     $val =~ /^\d+$/ or $val = "($val)"; # add brackets around strings
    555                     $buff = "%%$tag: $val$/";
    556                     if (length $buff > 255) {
    557                         # lines in PS documents must be less than 256 characters
    558                         # (don't yet support continuation with %%+ comment)
    559                         $exifTool->Warn("Value for too long for $tag");
    560                     } else {
    561                         $data = $buff;  # write the new value
    562                     }
     593                    $exifTool->VerboseValue("+ PostScript:$$tagInfo{Name}", $val);
     594                    $data = EncodeTag($tag, $val);
    563595                }
    564596            }
     
    663695        push @notDone, 'PostScript' if %$newTags;
    664696        foreach $dir (qw{Photoshop ICC_Profile XMP}) {
    665             push @notDone, $dir if $$editDirs{$dir} and not $doneDir{$dir};
     697            push @notDone, $dir if $$editDirs{$dir} and not $doneDir{$dir} and
     698                                   not $$exifTool{DEL_GROUP}{$dir};
    666699        }
    667700        @notDone and $exifTool->Warn("Couldn't write ".join('/',@notDone).' information');
     
    698731=head1 NOTES
    699732
    700 Currently, information is written only in the outter-level document.
     733Currently, information is written only in the outer-level document.
    701734
    702735Photoshop will discard meta information in a PostScript document if it has
     
    731764=head1 AUTHOR
    732765
    733 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     766Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    734767
    735768This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteXMP.pl

    r16842 r24107  
    99
    1010use strict;
     11use vars qw(%specialStruct %dateTimeInfo $xlatNamespace);
     12
    1113use Image::ExifTool qw(:DataAccess :Utils);
    1214
    1315sub CheckXMP($$$);
    14 sub SetPropertyPath($$;$$);
    1516sub CaptureXMP($$$;$);
     17sub SetPropertyPath($$;$$$$);
    1618
    1719my $debug = 0;
    18 
    19 # XMP structures (each structure is similar to a tag table so we can
    20 # recurse through them in SetPropertyPath() as if they were tag tables)
    21 my %xmpStruct = (
    22     ResourceRef => {
    23         NAMESPACE => 'stRef',
    24         InstanceID      => { },
    25         DocumentID      => { },
    26         VersionID       => { },
    27         RenditionClass  => { },
    28         RenditionParams => { },
    29         Manager         => { },
    30         ManagerVariant  => { },
    31         ManageTo        => { },
    32         ManageUI        => { },
    33     },
    34     ResourceEvent => {
    35         NAMESPACE => 'stEvt',
    36         action          => { },
    37         instanceID      => { },
    38         parameters      => { },
    39         softwareAgent   => { },
    40         when            => { },
    41     },
    42     JobRef => {
    43         NAMESPACE => 'stJob',
    44         name        => { },
    45         id          => { },
    46         url         => { },
    47     },
    48     Version => {
    49         NAMESPACE => 'stVer',
    50         comments    => { },
    51         event       => { Struct => 'ResourceEvent' },
    52         modifyDate  => { },
    53         modifier    => { },
    54         version     => { },
    55     },
    56     Thumbnail => {
    57         NAMESPACE => 'xapGImg',
    58         height      => { },
    59         width       => { },
    60        'format'     => { },
    61         image       => { },
    62     },
    63     IdentifierScheme => {
    64         NAMESPACE => 'xmpidq',
    65         Scheme      => { }, # qualifier for xmp:Identifier only
    66     },
    67     Dimensions => {
    68         NAMESPACE => 'stDim',
    69         w           => { },
    70         h           => { },
    71         unit        => { },
    72     },
    73     Colorant => {
    74         NAMESPACE => 'xapG',
    75         swatchName  => { },
    76         mode        => { },
    77         type        => { },
    78         cyan        => { },
    79         magenta     => { },
    80         yellow      => { },
    81         black       => { },
    82         red         => { },
    83         green       => { },
    84         blue        => { },
    85         L           => { },
    86         A           => { },
    87         B           => { },
    88     },
    89     Font => {
    90         NAMESPACE => 'stFnt',
    91         fontName    => { },
    92         fontFamily  => { },
    93         fontFace    => { },
    94         fontType    => { },
    95         versionString => { },
    96         composite   => { },
    97         fontFileName=> { },
    98         childFontFiles=> { List => 'Seq' },
    99     },
    100     # the following stuctures are different:  They don't have
    101     # their own namespaces -- instead they use the parent namespace
    102     Flash => {
    103         NAMESPACE => 'exif',
    104         Fired       => { },
    105         Return      => { },
    106         Mode        => { },
    107         Function    => { },
    108         RedEyeMode  => { },
    109     },
    110     OECF => {
    111         NAMESPACE => 'exif',
    112         Columns     => { },
    113         Rows        => { },
    114         Names       => { },
    115         Values      => { },
    116     },
    117     CFAPattern => {
    118         NAMESPACE => 'exif',
    119         Columns     => { },
    120         Rows        => { },
    121         Values      => { },
    122     },
    123     DeviceSettings => {
    124         NAMESPACE => 'exif',
    125         Columns     => { },
    126         Rows        => { },
    127         Settings    => { },
    128     },
    129     # Iptc4xmpCore structures
    130     ContactInfo => {
    131         NAMESPACE => 'Iptc4xmpCore',
    132         CiAdrCity   => { },
    133         CiAdrCtry   => { },
    134         CiAdrExtadr => { },
    135         CiAdrPcode  => { },
    136         CiAdrRegion => { },
    137         CiEmailWork => { },
    138         CiTelWork   => { },
    139         CiUrlWork   => { },
    140     },
    141     # Dynamic Media structures
    142     BeatSpliceStretch => {
    143         NAMESPACE => 'xmpDM',
    144         useFileBeatsMarker  => { },
    145         riseInDecibel       => { },
    146         riseInTimeDuration  => { },
    147     },
    148     Marker => {
    149         NAMESPACE => 'xmpDM',
    150         startTime   => { },
    151         duration    => { },
    152         comment     => { },
    153         name        => { },
    154         location    => { },
    155         target      => { },
    156         type        => { },
    157     },
    158     Media => {
    159         NAMESPACE => 'xmpDM',
    160         path        => { },
    161         track       => { },
    162         startTime   => { },
    163         duration    => { },
    164         managed     => { },
    165         webStatement=> { },
    166     },
    167     ProjectLink => {
    168         NAMESPACE => 'xmpDM',
    169         type        => { },
    170         path        => { },
    171     },
    172     ResampleStretch => {
    173         NAMESPACE => 'xmpDM',
    174         quality     => { },
    175     },
    176     Time => {
    177         NAMESPACE => 'xmpDM',
    178         value       => { },
    179         scale       => { },
    180     },
    181     Timecode => {
    182         NAMESPACE => 'xmpDM',
    183         timeValue   => { },
    184         timeFormat  => { },
    185     },
    186     TimeScaleStretch => {
    187         NAMESPACE => 'xmpDM',
    188         quality     => { },
    189         frameSize   => { },
    190         frameOverlappingPercentage => { },
    191     },
     20my $numPadLines = 24;       # number of blank padding lines
     21
     22# when writing extended XMP, resources bigger than this get placed in their own
     23# rdf:Description so they can be moved to the extended segments if necessary
     24my $newDescThresh = 10240;  # 10 kB
     25
     26# individual resources and namespaces to place last in separate rdf:Description's
     27# so they can be moved to extended XMP segments if required (see Oct. 2008 XMP spec)
     28my %extendedRes = (
     29    'photoshop:History' => 1,
     30    'xap:Thumbnails' => 1,
     31    'xmp:Thumbnails' => 1,
     32    'crs' => 1,
     33    'crss' => 1,
    19234);
    19335
    194 # Lookup to translate our namespace prefixes into URI's.  This list need
    195 # not be complete, but it must contain an entry for each namespace prefix
    196 # (NAMESPACE) for writable tags in the XMP tables or the table above
    197 my %nsURI = (
    198     aux       => 'http://ns.adobe.com/exif/1.0/aux/',
    199     cc        => 'http://web.resource.org/cc/',
    200     crs       => 'http://ns.adobe.com/camera-raw-settings/1.0/',
    201     crss      => 'http://ns.adobe.com/camera-raw-saved-settings/1.0/',
    202     dc        => 'http://purl.org/dc/elements/1.1/',
    203     exif      => 'http://ns.adobe.com/exif/1.0/',
    204     iX        => 'http://ns.adobe.com/iX/1.0/',
    205     pdf       => 'http://ns.adobe.com/pdf/1.3/',
    206     pdfx      => 'http://ns.adobe.com/pdfx/1.3/',
    207     photoshop => 'http://ns.adobe.com/photoshop/1.0/',
    208     rdf       => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
    209     rdfs      => 'http://www.w3.org/2000/01/rdf-schema#',
    210     stDim     => 'http://ns.adobe.com/xap/1.0/sType/Dimensions#',
    211     stEvt     => 'http://ns.adobe.com/xap/1.0/sType/ResourceEvent#',
    212     stFnt     => 'http://ns.adobe.com/xap/1.0/sType/Font#',
    213     stJob     => 'http://ns.adobe.com/xap/1.0/sType/Job#',
    214     stRef     => 'http://ns.adobe.com/xap/1.0/sType/ResourceRef#',
    215     stVer     => 'http://ns.adobe.com/xap/1.0/sType/Version#',
    216     tiff      => 'http://ns.adobe.com/tiff/1.0/',
    217    'x'        => 'adobe:ns:meta/',
    218     xapG      => 'http://ns.adobe.com/xap/1.0/g/',
    219     xapGImg   => 'http://ns.adobe.com/xap/1.0/g/img/',
    220     xmp       => 'http://ns.adobe.com/xap/1.0/',
    221     xmpBJ     => 'http://ns.adobe.com/xap/1.0/bj/',
    222     xmpDM     => 'http://ns.adobe.com/xmp/1.0/DynamicMedia/',
    223     xmpMM     => 'http://ns.adobe.com/xap/1.0/mm/',
    224     xmpRights => 'http://ns.adobe.com/xap/1.0/rights/',
    225     xmpTPg    => 'http://ns.adobe.com/xap/1.0/t/pg/',
    226     xmpidq    => 'http://ns.adobe.com/xmp/Identifier/qual/1.0/',
    227     xmpPLUS   => 'http://ns.adobe.com/xap/1.0/PLUS/',
    228     dex       => 'http://ns.optimasc.com/dex/1.0/',
    229     mediapro  => 'http://ns.iview-multimedia.com/mediapro/1.0/',
    230     Iptc4xmpCore => 'http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/',
    231     MicrosoftPhoto => 'http://ns.microsoft.com/photo/1.0',
    232     lr        => 'http://ns.adobe.com/lightroom/1.0/',
    233     DICOM     => 'http://ns.adobe.com/DICOM/',
    234 );
    235 
    236 my $x_toolkit = "x:xmptk='Image::ExifTool $Image::ExifTool::VERSION'";
    23736my $rdfDesc = 'rdf:Description';
    23837#
     
    24140my $pktOpen = "<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'?>\n";
    24241my $xmlOpen = "<?xml version='1.0' encoding='UTF-8'?>\n";
    243 my $xmpOpen = "<x:xmpmeta xmlns:x='$nsURI{x}' $x_toolkit>\n";
     42my $xmpOpenPrefix = "<x:xmpmeta xmlns:x='$nsURI{x}'";
    24443my $rdfOpen = "<rdf:RDF xmlns:rdf='$nsURI{rdf}'>\n";
    24544my $rdfClose = "</rdf:RDF>\n";
     
    24847my $pktCloseR =  "<?xpacket end='r'?>";
    24948
    250 # Update XMP tag tables when this library is loaded:
    251 # - generate all TagID's (required when writing)
    252 # - generate PropertyPath for structure elements
    253 # - add necessary inverse conversion routines
    254 {
    255     my $mainTable = GetTagTable('Image::ExifTool::XMP::Main');
    256     GenerateTagIDs($mainTable);
    257     my ($mainTag, $ns, $tag);
    258     foreach $mainTag (keys %$mainTable) {
    259         my $mainInfo = $mainTable->{$mainTag};
    260         next unless ref $mainInfo eq 'HASH' and $mainInfo->{SubDirectory};
    261         my $table = GetTagTable($mainInfo->{SubDirectory}->{TagTable});
    262         $$table{WRITE_PROC} = \&WriteXMP;   # set WRITE_PROC for all tables
    263         GenerateTagIDs($table);
    264         $table->{CHECK_PROC} = \&CheckXMP;  # add our write check routine
    265         foreach $tag (TagTableKeys($table)) {
    266             my $tagInfo = $$table{$tag};
    267             next unless ref $tagInfo eq 'HASH';
    268             # must set PropertyPath now for all tags that are Struct elements
    269             # (normal tags will get set later if they are actually written)
    270             SetPropertyPath($table, $tag) if $$tagInfo{Struct};
    271             my $format = $$tagInfo{Writable};
    272             next unless $format and $format eq 'date';
    273             # add dummy conversion for dates (for now...)
    274             $$tagInfo{PrintConvInv} = '$val' unless $$tagInfo{PrintConvInv};
    275             $$tagInfo{ValueConvInv} = '$val' unless $$tagInfo{ValueConvInv};
    276         }
    277         # add new namespace if NAMESPACE is ns/uri pair
    278         next unless ref $$table{NAMESPACE};
    279         my $nsRef = $$table{NAMESPACE};
    280         # recognize as either a list or hash
    281         if (ref $nsRef eq 'ARRAY') {
    282             $ns = $$nsRef[0];
    283             $nsURI{$ns} = $$nsRef[1];
    284         } else { # must be a hash
    285             ($ns) = keys %$nsRef;
    286             $nsURI{$ns} = $$nsRef{$ns};
    287         }
    288         $$table{NAMESPACE} = $ns;
    289     }
     49#------------------------------------------------------------------------------
     50# Get XMP opening tag (and set x:xmptk appropriately)
     51# Inputs: 0) ExifTool object ref
     52# Returns: x:xmpmeta opening tag
     53sub XMPOpen($)
     54{
     55    my $exifTool = shift;
     56    my $nv = $exifTool->{NEW_VALUE}->{$Image::ExifTool::XMP::x{xmptk}};
     57    my $tk;
     58    if (defined $nv) {
     59        $tk = Image::ExifTool::GetNewValues($nv);
     60        $exifTool->VerboseValue(($tk ? '+' : '-') . ' XMP-x:XMPToolkit', $tk);
     61        ++$exifTool->{CHANGED};
     62    } else {
     63        $tk = "Image::ExifTool $Image::ExifTool::VERSION";
     64    }
     65    my $str = $tk ? (" x:xmptk='" . EscapeXML($tk) . "'") : '';
     66    return "$xmpOpenPrefix$str>\n";
    29067}
    29168
     
    29875    my ($xmpPt, $mode) = @_;
    29976    unless ($$xmpPt =~ /^\0*<\0*\?\0*x\0*p\0*a\0*c\0*k\0*e\0*t/) {
    300         return '' unless $$xmpPt =~ /^<x(mp)?:xmpmeta/;
     77        return '' unless $$xmpPt =~ /^<x(mp)?:x[ma]pmeta/;
    30178        # add required xpacket header/trailer
    30279        $$xmpPt = $pktOpen . $$xmpPt . $pktCloseW;
     
    31188
    31289#------------------------------------------------------------------------------
     90# Check XMP date values for validity and format accordingly
     91# Inputs: 1) date string
     92# Returns: XMP date/time string (or undef on error)
     93sub FormatXMPDate($)
     94{
     95    my $val = shift;
     96    my ($y, $m, $d, $t, $tz);
     97    if ($val =~ /(\d{4}):(\d{2}):(\d{2}) (\d{2}:\d{2}(?::\d{2}(?:\.\d*)?)?)(.*)/) {
     98        ($y, $m, $d, $t, $tz) = ($1, $2, $3, $4, $5);
     99        $val = "$y-$m-${d}T$t";
     100    } elsif ($val =~ /^\s*\d{4}(:\d{2}){0,2}\s*$/) {
     101        # this is just a date (YYYY, YYYY-mm or YYYY-mm-dd)
     102        $val =~ tr/:/-/;
     103    } elsif ($val =~ /^\s*(\d{2}:\d{2}(?::\d{2}(?:\.\d*)?)?)(.*)\s*$/) {
     104        # this is just a time
     105        ($t, $tz) = ($1, $2);
     106        $val = $t;
     107    } else {
     108        return undef;
     109    }
     110    if ($tz) {
     111        $tz =~ /^(Z|[+-]\d{2}:\d{2})$/ or return undef;
     112        $val .= $tz;
     113    }
     114    return $val;
     115}
     116
     117#------------------------------------------------------------------------------
    313118# Check XMP values for validity and format accordingly
    314 # Inputs: 0) ExifTool object reference, 1) tagInfo hash reference,
    315 #         2) raw value reference
     119# Inputs: 0) ExifTool object ref, 1) tagInfo hash ref, 2) raw value ref
    316120# Returns: error string or undef (and may change value) on success
     121# Note: copies structured information to avoid conflicts with calling code
    317122sub CheckXMP($$$)
    318123{
    319124    my ($exifTool, $tagInfo, $valPtr) = @_;
    320     # convert value from Latin if necessary
    321     if ($exifTool->{OPTIONS}->{Charset} eq 'Latin' and $$valPtr =~ /[\x80-\xff]/) {
    322         # convert from Latin to UTF-8
    323         my $val = Image::ExifTool::Latin2Unicode($$valPtr,'n');
    324         $$valPtr = Image::ExifTool::Unicode2UTF8($val,'n');
     125
     126    if ($$tagInfo{Struct}) {
     127        require 'Image/ExifTool/XMPStruct.pl';
     128        my ($item, $err, $w, $warn);
     129        unless (ref $$valPtr) {
     130            ($$valPtr, $warn) = InflateStruct($valPtr);
     131            # expect a structure HASH ref or ARRAY of structures
     132            ref $$valPtr or return 'Improperly formed structure';
     133        }
     134        if (ref $$valPtr eq 'ARRAY') {
     135            return 'Not a list tag' unless $$tagInfo{List};
     136            my @copy = ( @{$$valPtr} ); # copy the list for ExifTool to use
     137            $$valPtr = \@copy;          # return the copy
     138            foreach $item (@copy) {
     139                unless (ref $item eq 'HASH') {
     140                    ($item, $w) = InflateStruct(\$item); # deserialize structure
     141                    $w and $warn = $w;
     142                    next if ref $item eq 'HASH';
     143                    $err = 'Improperly formed structure';
     144                    last;
     145                }
     146                ($item, $err) = CheckStruct($exifTool, $item, $$tagInfo{Struct});
     147                last if $err;
     148            }
     149        } else {
     150            ($$valPtr, $err) = CheckStruct($exifTool, $$valPtr, $$tagInfo{Struct});
     151        }
     152        $warn and $$exifTool{CHECK_WARN} = $warn;
     153        return $err;
    325154    }
    326155    my $format = $tagInfo->{Writable};
    327     # if no format specified, value is a simple string
    328     return undef unless $format and $format ne 'string';
     156    # (if no format specified, value is a simple string)
     157    if (not $format or $format eq 'string' or $format eq 'lang-alt') {
     158        # convert value to UTF8 if necessary
     159        if ($exifTool->{OPTIONS}->{Charset} ne 'UTF8') {
     160            if ($$valPtr =~ /[\x80-\xff]/) {
     161                # convert from Charset to UTF-8
     162                $$valPtr = $exifTool->Encode($$valPtr,'UTF8');
     163            }
     164        } else {
     165            # translate invalid XML characters to "."
     166            $$valPtr =~ tr/\0-\x08\x0b\x0c\x0e-\x1f/./;
     167            # fix any malformed UTF-8 characters
     168            if (FixUTF8($valPtr) and not $$exifTool{WarnBadUTF8}) {
     169                $exifTool->Warn('Malformed UTF-8 character(s)');
     170                $$exifTool{WarnBadUTF8} = 1;
     171            }
     172        }
     173        return undef;   # success
     174    }
    329175    if ($format eq 'rational' or $format eq 'real') {
    330176        # make sure the value is a valid floating point number
    331         Image::ExifTool::IsFloat($$valPtr) or return 'Not a floating point number';
     177        unless (Image::ExifTool::IsFloat($$valPtr) or
     178            # allow 'inf' and 'undef' rational values
     179            ($format eq 'rational' and ($$valPtr eq 'inf' or
     180             $$valPtr eq 'undef' or Image::ExifTool::IsRational($$valPtr))))
     181        {
     182            return 'Not a floating point number'
     183        }
    332184        if ($format eq 'rational') {
    333185            $$valPtr = join('/', Image::ExifTool::Rationalize($$valPtr));
     
    343195        }
    344196    } elsif ($format eq 'date') {
    345         if ($$valPtr =~ /(\d{4}):(\d{2}):(\d{2}) (\d{2}:\d{2}(?::\d{2}(?:\.\d*)?)?)(.*)/) {
    346             my ($y, $m, $d, $t, $tz) = ($1, $2, $3, $4, $5);
    347             # use 'Z' for timezone unless otherwise specified
    348             $tz = 'Z' unless $tz and $tz =~ /([+-]\d{2}:\d{2})/;
    349             $$valPtr = "$y-$m-${d}T$t$tz";
    350         } elsif ($$valPtr =~ /^\s*\d{4}(:\d{2}){0,2}\s*$/) {
    351             # this is just a date (YYYY, YYYY-MM or YYYY-MM-DD)
    352             $$valPtr =~ tr/:/-/;
    353         } elsif ($$valPtr =~ /^\s*(\d{2}:\d{2}:\d{2})(.*)\s*$/) {
    354             # this is just a time
    355             my ($t, $tz) = ($1, $2);
    356             $tz = 'Z' unless $tz and $tz =~ /([+-]\d{2}:\d{2})/;
    357             $$valPtr = "$t$tz";
    358         } else {
    359             return "Invalid date or time format (should be YYYY:MM:DD HH:MM:SS[+/-HH:MM])";
    360         }
    361     } elsif ($format eq 'lang-alt') {
    362         # nothing to do
     197        my $newDate = FormatXMPDate($$valPtr);
     198        return "Invalid date/time (use YYYY:mm:dd HH:MM:SS[.ss][+/-HH:MM|Z])" unless $newDate;
     199        $$valPtr = $newDate;
    363200    } elsif ($format eq 'boolean') {
    364201        if (not $$valPtr or $$valPtr =~ /false/i or $$valPtr =~ /^no$/i) {
     
    383220{
    384221    my $tagInfo = shift;
    385     unless ($$tagInfo{PropertyPath}) {
    386         SetPropertyPath($$tagInfo{Table}, $$tagInfo{TagID});
    387     }
     222    SetPropertyPath($$tagInfo{Table}, $$tagInfo{TagID}) unless $$tagInfo{PropertyPath};
    388223    return $$tagInfo{PropertyPath};
    389224}
    390225
    391226#------------------------------------------------------------------------------
    392 # Set PropertyPath for specified tag (also for any structure elements)
    393 # Inputs: 0) tagTable reference, 1) tagID, 2) structure reference (or undef),
    394 #         3) property list up to this point (or undef), 4) true if tag is a list
    395 sub SetPropertyPath($$;$$)
    396 {
    397     my ($tagTablePtr, $tagID, $structPtr, $propList) = @_;
     227# Set PropertyPath for specified tag (also for associated flattened tags and structure elements)
     228# Inputs: 0) tagTable reference, 1) tagID, 2) tagID of parent structure,
     229#         3) structure definition ref (or undef), 4) property list up to this point (or undef),
     230#         5) flag set if any containing structure has a TYPE
     231# Notes: also generates flattened tags if they don't already exist
     232sub SetPropertyPath($$;$$$$)
     233{
     234    my ($tagTablePtr, $tagID, $parentID, $structPtr, $propList, $isType) = @_;
    398235    my $table = $structPtr || $tagTablePtr;
    399236    my $tagInfo = $$table{$tagID};
    400     my $ns = $$table{NAMESPACE};
     237
     238    return if ref($tagInfo) ne 'HASH' or $$tagInfo{PropertyPath};
     239
    401240    # don't override existing main table entry if already set by a Struct
    402     return if not $structPtr and $$tagInfo{PropertyPath};
     241    if ($structPtr) {
     242        $isType = 1 if $$structPtr{TYPE};
     243    } else {
     244        # use property path from original tagInfo if this is an alternate-language tag
     245        my $srcInfo = $$tagInfo{SrcTagInfo};
     246        $$tagInfo{PropertyPath} = GetPropertyPath($srcInfo) if $srcInfo;
     247        return if $$tagInfo{PropertyPath};
     248        # set property path for all flattened tags in structure if necessary
     249        if ($$tagInfo{RootTagInfo}) {
     250            SetPropertyPath($tagTablePtr, $$tagInfo{RootTagInfo}{TagID});
     251            return if $$tagInfo{PropertyPath};
     252            warn "Internal Error: Didn't set path from root for $tagID\n";
     253        }
     254    }
     255    my $ns = $$tagInfo{Namespace} || $$table{NAMESPACE};
    403256    $ns or warn("No namespace for $tagID\n"), return;
    404257    my (@propList, $listType);
     
    410263        # remove language code from property path if it exists
    411264        $propList[-1] =~ s/-$$tagInfo{LangCode}$// if $$tagInfo{LangCode};
     265        # handle lists of lang-alt lists (ie. XMP-plus:Custom tags)
     266        if ($$tagInfo{List} and $$tagInfo{List} ne '1') {
     267            push @propList, "rdf:$$tagInfo{List}", 'rdf:li 10';
     268        }
    412269    } else {
    413270        $listType = $$tagInfo{List};
    414271    }
    415272    # add required properties if this is a list
    416     push @propList, "rdf:$listType", 'rdf:li 000' if $listType and $listType ne '1';
    417     # set PropertyPath for all elements of this structure if necessary
    418     if ($$tagInfo{Struct}) {
    419         my $struct = $xmpStruct{$$tagInfo{Struct}};
    420         $struct or warn("No XMP $$tagInfo{Struct} structure!\n"), return;
     273    push @propList, "rdf:$listType", 'rdf:li 10' if $listType and $listType ne '1';
     274    # set PropertyPath for all flattened tags of this structure if necessary
     275    # (note: don't do this for variable-namespace structures (undef NAMESPACE))
     276    my $strTable = $$tagInfo{Struct};
     277    if ($strTable and $$strTable{NAMESPACE}) {
     278        # make sure the structure namespace has been registered
     279        # (user-defined namespaces may not have been)
     280        RegisterNamespace($strTable) if ref $$strTable{NAMESPACE};
    421281        my $tag;
    422         foreach $tag (keys %$struct) {
    423             next if $tag eq 'NAMESPACE';
    424             SetPropertyPath($tagTablePtr, $tag, $struct, \@propList);
    425         }
    426     }
    427     # use tagInfo for combined tag name if this was a Struct
     282        foreach $tag (keys %$strTable) {
     283            # ignore special fields and any lang-alt fields we may have added
     284            next if $specialStruct{$tag} or $$strTable{$tag}{LangCode};
     285            my $fullID = $parentID ? $parentID . ucfirst($tagID) : $tagID;
     286            SetPropertyPath($tagTablePtr, $tag, $fullID, $strTable, \@propList, $isType);
     287        }
     288    }
     289    # if this was a structure field and not a normal tag,
     290    # we set PropertyPath in the corresponding flattened tag
    428291    if ($structPtr) {
    429         my $tagName = GetXMPTagID(\@propList);
    430         $$tagTablePtr{$tagName} or warn("Tag $tagName not found!\n"), return;
    431         $tagInfo = $$tagTablePtr{$tagName};
    432         # must check again for List's at this level
    433         if ($$tagInfo{Writable} and $$tagInfo{Writable} eq 'lang-alt') {
    434             $listType = 'Alt';
    435         } else {
    436             $listType = $$tagInfo{List};
    437         }
    438         push @propList, "rdf:$listType", 'rdf:li 000' if $listType and $listType ne '1';
     292        my $flatID = $parentID . ucfirst($tagID);
     293        $tagInfo = $$tagTablePtr{$flatID};
     294        # create flattened tag now if necessary
     295        # (could happen if we were just writing a structure)
     296        unless ($tagInfo) {
     297            $tagInfo = { Name => ucfirst($flatID), Flat => 1 };
     298            Image::ExifTool::AddTagToTable($tagTablePtr, $flatID, $tagInfo);
     299        }
     300        # set StructType flag if any containing structure has a TYPE
     301        $$tagInfo{StructType} = 1 if $isType;
    439302    }
    440303    # set property path for tagInfo in main table
     
    451314    my ($exifTool, $propList, $val, $attrs) = @_;
    452315    return unless defined $val and @$propList > 2;
    453     if ($$propList[0] =~ /^x:x(a|m)pmeta$/ and
     316    if ($$propList[0] =~ /^x:x[ma]pmeta$/ and
    454317        $$propList[1] eq 'rdf:RDF' and
    455318        $$propList[2] =~ /$rdfDesc( |$)/)
     
    457320        # no properties to save yet if this is just the description
    458321        return unless @$propList > 3;
     322        # ignore empty list properties
     323        if ($$propList[-1] =~ /^rdf:(Bag|Seq|Alt)$/) {
     324            $exifTool->Warn("Ignored empty $$propList[-1] list for $$propList[-2]", 1);
     325            return;
     326        }
    459327        # save information about this property
    460328        my $capture = $exifTool->{XMP_CAPTURE};
     
    465333            $$capture{$path} = [$val, $attrs || { }];
    466334        }
     335    } elsif ($$propList[0] eq 'rdf:RDF' and
     336             $$propList[1] =~ /$rdfDesc( |$)/)
     337    {
     338        # set flag so we don't write x:xmpmeta element
     339        $exifTool->{XMP_NO_XMPMETA} = 1;
     340        # add missing x:xmpmeta element and try again
     341        unshift @$propList, 'x:xmpmeta';
     342        CaptureXMP($exifTool, $propList, $val, $attrs);
    467343    } else {
    468344        $exifTool->{XMP_ERROR} = 'Improperly enclosed XMP property: ' . join('/',@$propList);
     
    563439    my ($exifTool, $path) = @_;
    564440    my @propList = split('/',$path);
    565     my ($prop, $newKey);
    566441    my $nsUsed = $exifTool->{XMP_NS};
     442    my $prop;
    567443    foreach $prop (@propList) {
    568444        my ($ns, $tag) = $prop =~ /(.+?):(.*)/;
     
    585461
    586462#------------------------------------------------------------------------------
     463# Add necessary rdf:type element when writing structure
     464# Inputs: 0) ExifTool ref, 1) tag table ref, 2) capture hash ref, 3) path string
     465#         4) optional base path (already conformed to namespace) for elements in
     466#            variable-namespace structures
     467sub AddStructType($$$$;$)
     468{
     469    my ($exifTool, $tagTablePtr, $capture, $path, $basePath) = @_;
     470    my @props = split '/', $path;
     471    my %doneID;
     472    for (;;) {
     473        pop @props;
     474        last unless @props;
     475        my $tagID = GetXMPTagID(\@props);
     476        next if $doneID{$tagID};
     477        $doneID{$tagID} = 1;
     478        my $tagInfo = $$tagTablePtr{$tagID};
     479        last unless ref $tagInfo eq 'HASH';
     480        if ($$tagInfo{Struct}) {
     481            my $type = $$tagInfo{Struct}{TYPE};
     482            if ($type) {
     483                my $pat = $$tagInfo{PropertyPath};
     484                $pat or warn("Missing PropertyPath in AddStructType\n"), last;
     485                $pat = ConformPathToNamespace($exifTool, $pat);
     486                $pat =~  s/ \d+/ \\d\+/g;
     487                $path =~ /^($pat)/ or warn("Wrong path in AddStructType\n"), last;
     488                my $p = $1 . '/rdf:type';
     489                $p = "$basePath/$p" if $basePath;
     490                $$capture{$p} = [ '', { 'rdf:resource' => $type } ] unless $$capture{$p};
     491            }
     492        }
     493        last unless $$tagInfo{StructType};
     494    }
     495}
     496
     497#------------------------------------------------------------------------------
     498# Utility routine to encode data in base64
     499# Inputs: 0) binary data string
     500# Returns:   base64-encoded string
     501sub EncodeBase64($)
     502{
     503    # encode the data in 45-byte chunks
     504    my $chunkSize = 45;
     505    my $len = length $_[0];
     506    my $str = '';
     507    my $i;
     508    for ($i=0; $i<$len; $i+=$chunkSize) {
     509        my $n = $len - $i;
     510        $n = $chunkSize if $n > $chunkSize;
     511        # add uuencoded data to output (minus size byte, but including trailing newline)
     512        $str .= substr(pack('u', substr($_[0], $i, $n)), 1);
     513    }
     514    # convert to base64 (remember that "\0" may be encoded as ' ' or '`')
     515    $str =~ tr/` -_/AA-Za-z0-9+\//;
     516    # convert pad characters at the end (remember to account for trailing newline)
     517    my $pad = 3 - ($len % 3);
     518    substr($str, -$pad-1, $pad) = ('=' x $pad) if $pad < 3;
     519    return $str;
     520}
     521
     522#------------------------------------------------------------------------------
    587523# sort tagInfo hash references by tag name
    588524sub ByTagName
    589525{
    590526    return $$a{Name} cmp $$b{Name};
     527}
     528
     529#------------------------------------------------------------------------------
     530# sort alphabetically, but with rdf:type first in the structure
     531sub TypeFirst
     532{
     533    if ($a =~ /rdf:type$/) {
     534        return substr($a, 0, -8) cmp $b unless $b =~ /rdf:type$/;
     535    } elsif ($b =~ /rdf:type$/) {
     536        return $a cmp substr($b, 0, -8);
     537    }
     538    return $a cmp $b;
     539}
     540
     541#------------------------------------------------------------------------------
     542# Limit size of XMP
     543# Inputs: 0) ExifTool object ref, 1) XMP data ref (written up to start of $rdfClose),
     544#         2) max XMP len, 3) rdf:about string, 4) list ref for description start offsets
     545#         5) start offset of first description recommended for extended XMP
     546# Returns: 0) extended XMP ref, 1) GUID and updates $$dataPt (or undef if no extended XMP)
     547sub LimitXMPSize($$$$$$)
     548{
     549    my ($exifTool, $dataPt, $maxLen, $about, $startPt, $extStart) = @_;
     550
     551    # return straight away if it isn't too big
     552    return undef if length($$dataPt) < $maxLen;
     553
     554    push @$startPt, length($$dataPt);  # add end offset to list
     555    my $newData = substr($$dataPt, 0, $$startPt[0]);
     556    my $guid = '0' x 32;
     557    # write the required xmpNote:HasExtendedXMP property
     558    $newData .= "\n <$rdfDesc rdf:about='$about'\n  xmlns:xmpNote='$nsURI{xmpNote}'>\n" .
     559                  "  <xmpNote:HasExtendedXMP>$guid</xmpNote:HasExtendedXMP>\n" .
     560                  " </$rdfDesc>\n";
     561
     562    my ($i, %descSize, $start);
     563    # calculate all description block sizes
     564    for ($i=1; $i<@$startPt; ++$i) {
     565        $descSize{$$startPt[$i-1]} = $$startPt[$i] - $$startPt[$i-1];
     566    }
     567    pop @$startPt;    # remove end offset
     568    # write the descriptions from smallest to largest, as many in main XMP as possible
     569    my @descStart = sort { $descSize{$a} <=> $descSize{$b} } @$startPt;
     570    my $extData = XMPOpen($exifTool) . $rdfOpen;
     571    for ($i=0; $i<2; ++$i) {
     572      foreach $start (@descStart) {
     573        # write main XMP first (in order of size), then extended XMP afterwards (in order)
     574        next if $i xor $start >= $extStart;
     575        my $pt = (length($newData) + $descSize{$start} > $maxLen) ? \$extData : \$newData;
     576        $$pt .= substr($$dataPt, $start, $descSize{$start});
     577      }
     578    }
     579    $extData .= $rdfClose . $xmpClose;  # close rdf:RDF and x:xmpmeta
     580    # calculate GUID from MD5 of extended XMP data
     581    if (eval 'require Digest::MD5') {
     582        $guid = uc unpack('H*', Digest::MD5::md5($extData));
     583        $newData =~ s/0{32}/$guid/;     # update GUID in main XMP segment
     584    }
     585    $exifTool->VerboseValue('+ XMP-xmpNote:HasExtendedXMP', $guid);
     586    $$dataPt = $newData;        # return main XMP block
     587    return (\$extData, $guid);  # return extended XMP and its GUID
    591588}
    592589
     
    599596# Notes: May set dirInfo InPlace flag to rewrite with specified DirLen
    600597#        May set dirInfo ReadOnly flag to write as read-only XMP ('r' mode and no padding)
     598#        May set dirInfo Compact flag to force compact (drops 2kB of padding)
     599#        May set dirInfo MaxDataLen to limit output data length -- this causes ExtendedXMP
     600#          and ExtendedGUID to be returned in dirInfo if extended XMP was required
    601601sub WriteXMP($$;$)
    602602{
     
    604604    $exifTool or return 1;    # allow dummy access to autoload this package
    605605    my $dataPt = $$dirInfo{DataPt};
    606     my $dirStart = $$dirInfo{DirStart} || 0;
    607     my (%capture, %nsUsed, $xmpErr, $uuid);
     606    my (%capture, %nsUsed, $xmpErr, $tagInfo, $about);
    608607    my $changed = 0;
    609608    my $xmpFile = (not $tagTablePtr);   # this is an XMP data file if no $tagTablePtr
    610     my $preferred = $xmpFile;   # write XMP as preferred if this is an XMP file
     609    # prefer XMP over other metadata formats in some types of files
     610    my $preferred = $xmpFile || ($$exifTool{PreferredGroup} and $$exifTool{PreferredGroup} eq 'XMP');
    611611    my $verbose = $exifTool->Options('Verbose');
     612    my $dirLen = $$dirInfo{DirLen};
     613    $dirLen = length($$dataPt) if not defined $dirLen and $dataPt;
    612614#
    613615# extract existing XMP information into %capture hash
     
    621623    $exifTool->{XMP_CAPTURE} = \%capture;
    622624    $exifTool->{XMP_NS} = \%nsUsed;
    623 
    624     if ($dataPt or $xmpFile) {
     625    delete $exifTool->{XMP_NO_XMPMETA};
     626    delete $exifTool->{XMP_NO_XPACKET};
     627    delete $exifTool->{XMP_IS_XML};
     628    delete $exifTool->{XMP_IS_SVG};
     629
     630    if ($xmpFile or $dirLen) {
    625631        delete $exifTool->{XMP_ERROR};
    626         delete $exifTool->{XMP_UUID};
     632        delete $exifTool->{XMP_ABOUT};
    627633        # extract all existing XMP information (to the XMP_CAPTURE hash)
    628634        my $success = ProcessXMP($exifTool, $dirInfo, $tagTablePtr);
     
    649655            }
    650656        }
    651         $uuid = $exifTool->{XMP_UUID} || '';
     657        $tagInfo = $Image::ExifTool::XMP::rdf{about};
     658        if (defined $exifTool->{NEW_VALUE}->{$tagInfo}) {
     659            $about = Image::ExifTool::GetNewValues($exifTool->{NEW_VALUE}->{$tagInfo}) || '';
     660            if ($verbose > 1) {
     661                my $wasAbout = $exifTool->{XMP_ABOUT};
     662                $exifTool->VerboseValue('- XMP-rdf:About', UnescapeXML($wasAbout)) if defined $wasAbout;
     663                $exifTool->VerboseValue('+ XMP-rdf:About', $about);
     664            }
     665            $about = EscapeXML($about); # must escape for XML
     666            ++$changed;
     667        } else {
     668            $about = $exifTool->{XMP_ABOUT} || '';
     669        }
    652670        delete $exifTool->{XMP_ERROR};
    653         delete $exifTool->{XMP_UUID};
     671        delete $exifTool->{XMP_ABOUT};
    654672    } else {
    655         $uuid = '';
    656     }
     673        $about = '';
     674    }
     675#
     676# handle writing XMP as a block to XMP file
     677#
     678    if ($xmpFile) {
     679        $tagInfo = $Image::ExifTool::Extra{XMP};
     680        if ($tagInfo and $exifTool->{NEW_VALUE}->{$tagInfo}) {
     681            my $rtnVal = 1;
     682            my $newVal = Image::ExifTool::GetNewValues($exifTool->{NEW_VALUE}->{$tagInfo});
     683            if (defined $newVal and length $newVal) {
     684                $exifTool->VPrint(0, "  Writing XMP as a block\n");
     685                ++$exifTool->{CHANGED};
     686                Write($$dirInfo{OutFile}, $newVal) or $rtnVal = -1;
     687            }
     688            delete $exifTool->{XMP_CAPTURE};
     689            return $rtnVal;
     690        }
     691    }
     692#
     693# delete groups in family 1 if requested
     694#
     695    if (%{$exifTool->{DEL_GROUP}} and (grep /^XMP-.+$/, keys %{$exifTool->{DEL_GROUP}} or
     696        # (logic is a bit more complex for group names in exiftool XML files)
     697        grep m{^http://ns.exiftool.ca/}, values %nsUsed))
     698    {
     699        my $del = $exifTool->{DEL_GROUP};
     700        my $path;
     701        foreach $path (keys %capture) {
     702            my @propList = split('/',$path); # get property list
     703            my ($tag, $ns) = GetXMPTagID(\@propList);
     704            # translate namespace if necessary
     705            $ns = $$xlatNamespace{$ns} if $$xlatNamespace{$ns};
     706            my ($grp, @g);
     707            # no "XMP-" added to most groups in exiftool RDF/XML output file
     708            if ($nsUsed{$ns} and (@g = ($nsUsed{$ns} =~ m{^http://ns.exiftool.ca/(.*?)/(.*?)/}))) {
     709                if ($g[1] =~ /^\d/) {
     710                    $grp = "XML-$g[0]";
     711                    #(all XML-* groups stored as uppercase DEL_GROUP key)
     712                    my $ucg = uc $grp;
     713                    next unless $$del{$ucg} or ($$del{'XML-*'} and not $$del{"-$ucg"});
     714                } else {
     715                    $grp = $g[1];
     716                    next unless $$del{$grp} or ($$del{$g[0]} and not $$del{"-$grp"});
     717                }
     718            } else {
     719                $grp = "XMP-$ns";
     720                my $ucg = uc $grp;
     721                next unless $$del{$ucg} or ($$del{'XMP-*'} and not $$del{"-$ucg"});
     722            }
     723            $exifTool->VerboseValue("- $grp:$tag", $capture{$path}->[0]);
     724            delete $capture{$path};
     725            ++$changed;
     726        }
     727    }
     728    # delete HasExtendedXMP tag (we create it as needed)
     729    my $hasExtTag = 'xmpNote:HasExtendedXMP';
     730    if ($capture{$hasExtTag}) {
     731        $exifTool->VerboseValue("- XMP-$hasExtTag", $capture{$hasExtTag}->[0]);
     732        delete $capture{$hasExtTag};
     733    }
     734    # set $xmpOpen now to to handle xmptk tag first
     735    my $xmpOpen = $exifTool->{XMP_NO_XMPMETA} ? '' : XMPOpen($exifTool);
    657736#
    658737# add, delete or change information as specified
     
    661740    # (sorted by tag name so alternate languages come last)
    662741    my @tagInfoList = sort ByTagName $exifTool->GetNewTagInfoList();
    663     my $tagInfo;
    664742    foreach $tagInfo (@tagInfoList) {
    665743        next unless $exifTool->GetGroup($tagInfo, 0) eq 'XMP';
    666         my $tag = $tagInfo->{TagID};
     744        my $tag = $$tagInfo{TagID};
    667745        my $path = GetPropertyPath($tagInfo);
    668746        unless ($path) {
     
    670748            next;
    671749        }
     750        # skip tags that were handled specially
     751        if ($path eq 'rdf:about' or $path eq 'x:xmptk') {
     752            ++$changed;
     753            next;
     754        }
     755        my $isStruct = $$tagInfo{Struct};
    672756        # change our property path namespace prefixes to conform
    673757        # to the ones used in this file
    674758        $path = ConformPathToNamespace($exifTool, $path);
    675759        # find existing property
    676         my $capList = $capture{$path};
    677         # MicrosoftPhoto screws up the case of some tags, so test for this
    678         unless ($capList) {
    679             my ($path2) = grep /^\Q$path\E$/i, keys %capture;
    680             $path2 and $capList = $capture{$path = $path2};
    681         }
    682         my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
    683         my $overwrite = Image::ExifTool::IsOverwriting($newValueHash);
     760        my $cap = $capture{$path};
     761        # MicrosoftPhoto screws up the case of some tags, and some other software,
     762        # including Adobe software, has been known to write the wrong list type or
     763        # not properly enclose properties in a list, so we check for this
     764        # (NOTE: we don't currently do these tests when writing structures!
     765        #  --> add this to DeleteStruct() below if it turns out to be a problem)
     766        unless ($cap or $isStruct) {
     767            my $regex = quotemeta $path;
     768            # also allow for missing structure fields in lists of structures
     769            $regex =~  s/ \d+/ \\d\+/g;
     770            my $ok = $regex; # regular expression to match standard property names
     771            # also check for incorrect list types which can cause problems
     772            if ($regex =~ s{\\/rdf\\:(Bag|Seq|Alt)\\/}{/rdf:(Bag|Seq|Alt)/}g) {
     773                # also look for missing bottom-level list
     774                $regex =~ s{/rdf:\(Bag\|Seq\|Alt\)\/rdf\\:li\\ \\d\+$}{(/.*)?};
     775            }
     776            my @matches = sort grep m{^$regex$}i, keys %capture;
     777            if (@matches) {
     778                if ($matches[0] =~ /^$ok$/) {
     779                    $path = $matches[0];    # use existing property path
     780                    $cap = $capture{$path};
     781                } else {
     782                    # property list was wrong, so issue a warning and fix it
     783                    my ($match, @fixed, %fixed, $err);
     784                    foreach $match (@matches) {
     785                        my $fixed = $path;
     786                        # set list indices
     787                        while ($match =~ / (\d+)/g) {
     788                            my $idx = $1;
     789                            # insert leading "X" so we don't replace this one again
     790                            $fixed =~ s/ \d+/ X$idx/;
     791                        }
     792                        $fixed =~ s/ X/ /g if $fixed ne $path;  # remove "X"s
     793                        $err = 1 if $capture{$fixed} or $fixed{$fixed};
     794                        push @fixed, $fixed;
     795                        $fixed{$fixed} = 1;
     796                    }
     797                    my $tg = $exifTool->GetGroup($tagInfo, 1) . ':' . $$tagInfo{Name};
     798                    my $wrn = lc($path) eq lc($matches[0]) ? 'tag ID case' : 'list type';
     799                    if ($err) {
     800                        $exifTool->Warn("Incorrect $wrn for $tg conflicts with existing tag");
     801                    } else {
     802                        # fix the incorrect property paths for all values of this tag
     803                        foreach $match (@matches) {
     804                            my $fixed = shift @fixed;
     805                            $capture{$fixed} = $capture{$match};
     806                            delete $capture{$match};
     807                        }
     808                        $cap = $capture{$path} || $capture{$fixed[0]};
     809                        $exifTool->Warn("Fixed incorrect $wrn for $tg", 1);
     810                    }
     811                }
     812            }
     813        }
     814        my $nvHash = $exifTool->GetNewValueHash($tagInfo);
     815        my $overwrite = Image::ExifTool::IsOverwriting($nvHash);
    684816        my $writable = $$tagInfo{Writable} || '';
    685817        my (%attrs, $deleted, $added);
    686818        # delete existing entry if necessary
    687         if ($capList) {
     819        if ($isStruct) {
     820            require 'Image/ExifTool/XMPStruct.pl';
     821            ($deleted, $added) = DeleteStruct($exifTool, \%capture, \$path, $nvHash, \$changed);
     822        } elsif ($cap) {
    688823            # take attributes from old values if they exist
    689             %attrs = %{$capList->[1]};
     824            %attrs = %{$$cap[1]};
    690825            if ($overwrite) {
    691                 my ($delPath, @matchingPaths, $oldLang, $delLang);
     826                my ($delPath, $oldLang, $delLang, $addLang, @matchingPaths);
    692827                # check to see if this is an indexed list item
    693828                if ($path =~ / /) {
    694                     my $pathPattern;
    695                     ($pathPattern = $path) =~ s/ 000/ \\d\{3\}/g;
    696                     @matchingPaths = sort grep(/^$pathPattern$/, keys %capture);
     829                    my $pp;
     830                    ($pp = $path) =~ s/ \d+/ \\d\+/g;
     831                    @matchingPaths = sort grep(/^$pp$/, keys %capture);
    697832                } else {
    698833                    push @matchingPaths, $path;
     
    700835                foreach $path (@matchingPaths) {
    701836                    my ($val, $attrs) = @{$capture{$path}};
    702                     if ($overwrite < 0) {
    703                         # only overwrite specific values
    704                         next unless Image::ExifTool::IsOverwriting($newValueHash, $val);
    705                     }
    706837                    if ($writable eq 'lang-alt') {
     838                        unless (defined $addLang) {
     839                            # add to lang-alt list by default if creating this tag from scratch
     840                            $addLang = Image::ExifTool::IsCreating($nvHash) ? 1 : 0;
     841                        }
    707842                        # get original language code (lc for comparisons)
    708843                        $oldLang = lc($$attrs{'xml:lang'} || 'x-default');
    709                         # delete all if deleting "x-default" or writing with no LangCode
     844                        if ($overwrite < 0) {
     845                            my $newLang = lc($$tagInfo{LangCode} || 'x-default');
     846                            next unless $oldLang eq $newLang;
     847                            # only add new tag if we are overwriting this one
     848                            # (note: this won't match if original XML contains CDATA!)
     849                            $addLang = Image::ExifTool::IsOverwriting($nvHash, UnescapeXML($val));
     850                            next unless $addLang;
     851                        }
     852                        # delete all if deleting "x-default" and writing with no LangCode
    710853                        # (XMP spec requires x-default language exist and be first in list)
    711                         if ($oldLang eq 'x-default' and not ($newValueHash->{Value} or
    712                             ($$tagInfo{LangCode} and $$tagInfo{LangCode} ne 'x-default')))
    713                         {
     854                        if ($oldLang eq 'x-default' and not $$tagInfo{LangCode}) {
    714855                            $delLang = 1;   # delete all languages
    715856                            $overwrite = 1; # force overwrite
    716                         }
    717                         if ($$tagInfo{LangCode} and not $delLang) {
     857                        } elsif ($$tagInfo{LangCode} and not $delLang) {
    718858                            # only overwrite specified language
    719859                            next unless lc($$tagInfo{LangCode}) eq $oldLang;
    720860                        }
     861                    } elsif ($overwrite < 0) {
     862                        # only overwrite specific values
     863                        # (note: this won't match if original XML contains CDATA!)
     864                        next unless Image::ExifTool::IsOverwriting($nvHash, UnescapeXML($val));
    721865                    }
    722866                    if ($verbose > 1) {
     
    725869                        $tagName =~ s/-$$tagInfo{LangCode}$// if $$tagInfo{LangCode};
    726870                        $tagName .= '-' . $$attrs{'xml:lang'} if $$attrs{'xml:lang'};
    727                         $exifTool->VPrint(1, "    - $grp:$tagName = '$val'\n");
     871                        $exifTool->VerboseValue("- $grp:$tagName", $val);
    728872                    }
    729873                    # save attributes and path from first deleted property
     
    733877                        $delPath = $path;
    734878                    }
     879                    # delete this tag
    735880                    delete $capture{$path};
    736881                    ++$changed;
    737                 }
    738                 next unless $delPath or $$tagInfo{List} or $oldLang;
     882                    # delete rdf:type tag if it is the only thing left in this structure
     883                    if ($path =~ /^(.*)\// and $capture{"$1/rdf:type"}) {
     884                        my $pp = $1;
     885                        my @a = grep /^\Q$pp\E\/[^\/]+/, keys %capture;
     886                        delete $capture{"$pp/rdf:type"} if @a == 1;
     887                    }
     888                }
     889                next unless $delPath or $$tagInfo{List} or $addLang;
    739890                if ($delPath) {
    740891                    $path = $delPath;
     
    744895                    # unless this is a list or an lang-alt tag
    745896                    next unless $$tagInfo{List} or $oldLang;
    746                     $path =~ m/ (\d{3})/g or warn "Internal error: no list index!\n", next;
     897                    # (match last index to put in same lang-alt list for Bag of lang-alt items)
     898                    $path =~ m/.* (\d+)/g or warn "Internal error: no list index!\n", next;
    747899                    $added = $1;
    748900                }
    749             } elsif ($path =~ m/ (\d{3})/g) {
    750                 $added = $1;
     901            } else {
     902                # are never overwriting, so we must be adding to a list
     903                # match the last index unless this is a list of lang-alt lists
     904                my $pat = $writable eq 'lang-alt' ? '.* (\d+)(.*? \d+)' : '.* (\d+)';
     905                if ($path =~ m/$pat/g) {
     906                    $added = $1;
     907                    # set position to end of matching index number
     908                    pos($path) = pos($path) - length($2) if $2;
     909                }
    751910            }
    752911            if (defined $added) {
    753                 # add to end of list
    754                 my $pos = pos($path) - 3;
    755                 for (;;) {
    756                     substr($path, $pos, 3) = ++$added;
    757                     last unless $capture{$path};
     912                my $len = length $added;
     913                my $pos = pos($path) - $len;
     914                my $nxt = substr($added, 1) + 1;
     915                # always insert x-default lang-alt entry first (as per XMP spec)
     916                # (need to test $overwrite because this will be a new lang-alt entry otherwise)
     917                if ($overwrite and $writable eq 'lang-alt' and (not $$tagInfo{LangCode} or
     918                    $$tagInfo{LangCode} eq 'x-default'))
     919                {
     920                    my $saveCap = $capture{$path};
     921                    for (;;) {
     922                        my $p = $path;
     923                        substr($p, $pos, $len) = length($nxt) . $nxt;
     924                        # increment index in the path of the existing item
     925                        my $nextCap = $capture{$p};
     926                        $capture{$p} = $saveCap;
     927                        last unless $nextCap;
     928                        $saveCap = $nextCap;
     929                        ++$nxt;
     930                    }
     931                } else {
     932                    # add to end of list
     933                    for (;;) {
     934                        my $try = length($nxt) . $nxt;
     935                        substr($path, $pos, $len) = $try;
     936                        last unless $capture{$path};
     937                        $len = length $try;
     938                        ++$nxt;
     939                    }
    758940                }
    759941            }
     
    761943        # check to see if we want to create this tag
    762944        # (create non-avoided tags in XMP data files by default)
    763         my $isCreating = (Image::ExifTool::IsCreating($newValueHash) or
     945        my $isCreating = (Image::ExifTool::IsCreating($nvHash) or $isStruct or
    764946                          ($preferred and not $$tagInfo{Avoid} and
    765                             not defined $$newValueHash{Shift}));
     947                            not defined $$nvHash{Shift}));
    766948
    767949        # don't add new values unless...
     
    769951        next unless $deleted or defined $added or
    770952            # ...tag didn't exist before and we are creating it
    771             (not $capList and $isCreating);
     953            (not $cap and $isCreating);
    772954
    773955        # get list of new values (all done if no new values specified)
    774         my @newValues = Image::ExifTool::GetNewValues($newValueHash) or next;
     956        my @newValues = Image::ExifTool::GetNewValues($nvHash) or next;
    775957
    776958        # set language attribute for lang-alt lists
    777         if ($writable eq 'lang-alt') {
    778             $attrs{'xml:lang'} = $$tagInfo{LangCode} || 'x-default';
    779             # must generate x-default entry as first entry if it didn't exist
    780             unless ($capList or lc($attrs{'xml:lang'}) eq 'x-default') {
    781                 my $newValue = EscapeXML($newValues[0]);
    782                 $capture{$path} = [ $newValue, { %attrs, 'xml:lang' => 'x-default' } ];
     959        $attrs{'xml:lang'} = $$tagInfo{LangCode} || 'x-default' if $writable eq 'lang-alt';
     960
     961        # add new value(s) to %capture hash
     962        my $subIdx;
     963        for (;;) {
     964            my $newValue = shift @newValues;
     965            if ($isStruct) {
     966                ++$changed if AddNewStruct($exifTool, $tagInfo, \%capture,
     967                                           $path, $newValue, $$tagInfo{Struct});
     968            } else {
     969                $newValue = EscapeXML($newValue);
     970                if ($$tagInfo{Resource}) {
     971                    $capture{$path} = [ '', { %attrs, 'rdf:resource' => $newValue } ];
     972                } else {
     973                    $capture{$path} = [ $newValue, \%attrs ];
     974                }
    783975                if ($verbose > 1) {
    784                     my $tagName = $$tagInfo{Name};
    785                     $tagName =~ s/-$$tagInfo{LangCode}$/-x-default/;
    786976                    my $grp = $exifTool->GetGroup($tagInfo, 1);
    787                     $exifTool->VPrint(1, "    + $grp:$tagName = '$newValue'\n");
    788                 }
    789                 $path =~ s/ 000/ 001/ or warn "Internal error: no list index!\n", next;
    790             }
    791         }
    792        
    793         # add new value(s) to %capture hash
    794         for (;;) {
    795             my $newValue = EscapeXML(shift @newValues);
    796             $capture{$path} = [ $newValue, \%attrs ];
    797             if ($verbose > 1) {
    798                 my $grp = $exifTool->GetGroup($tagInfo, 1);
    799                 $exifTool->VPrint(1, "    + $grp:$$tagInfo{Name} = '$newValue'\n");
    800             }
    801             ++$changed;
     977                    $exifTool->VerboseValue("+ $grp:$$tagInfo{Name}", $newValue);
     978                }
     979                ++$changed;
     980                # add rdf:type if necessary
     981                if ($$tagInfo{StructType}) {
     982                    AddStructType($exifTool, $$tagInfo{Table}, \%capture, $path);
     983                }
     984            }
    802985            last unless @newValues;
    803             $path =~ m/ (\d{3})/g or warn("Internal error: no list index!\n"), next;
    804             my $listIndex = $1;
    805             my $pos = pos($path) - 3;
    806             for (;;) {
    807                 substr($path, $pos, 3) = ++$listIndex;
    808                 last unless $capture{$path};
    809             }
    810             $capture{$path} and warn("Too many entries in XMP list!\n"), next;
     986            # match last index except for lang-alt items where we want to put each
     987            # item in a different lang-alt list (so match the 2nd-last for these)
     988            my $pat = $writable eq 'lang-alt' ? '.* (\d+)(.*? \d+)' : '.* (\d+)';
     989            $path =~ m/$pat/g or warn("Internal error: no list index for $tag!\n"), next;
     990            my $idx = $1;
     991            my $len = length $1;
     992            my $pos = pos($path) - $len - ($2 ? length $2 : 0);
     993            # generate unique list sub-indices to store additional values in sequence
     994            if ($subIdx) {
     995                $idx = substr($idx, 0, -length($subIdx));   # remove old sub-index
     996                $subIdx = substr($subIdx, 1) + 1;
     997                $subIdx = length($subIdx) . $subIdx;
     998            } else {
     999                $subIdx = '10';
     1000            }
     1001            substr($path, $pos, $len) = $idx . $subIdx;
    8111002        }
    8121003    }
     
    8151006    delete $exifTool->{XMP_NS};
    8161007
     1008    my $maxDataLen = $$dirInfo{MaxDataLen};
     1009    # get DataPt again because it may have been set by ProcessXMP
     1010    $dataPt = $$dirInfo{DataPt};
    8171011    # return now if we didn't change anything
    818     unless ($changed) {
     1012    unless ($changed or ($maxDataLen and $dataPt and defined $$dataPt and
     1013        length($$dataPt) > $maxDataLen))
     1014    {
    8191015        return undef unless $xmpFile;   # just rewrite original XMP
    820         # get DataPt again because it may have been set by ProcessXMP
    821         $dataPt = $$dirInfo{DataPt};
    822         unless (defined $dataPt) {
    823             $exifTool->Error("Nothing to write");
    824             return 1;
    825         }
    826         return 1 if Write($$dirInfo{OutFile}, $$dataPt);
    827         return -1;
    828     }
    829 #
    830 # write out the new XMP information
     1016        Write($$dirInfo{OutFile}, $$dataPt) or return -1 if $dataPt and defined $$dataPt;
     1017        return 1;
     1018    }
     1019#
     1020# write out the new XMP information (serialize it)
    8311021#
    8321022    # start writing the XMP data
     
    8421032
    8431033    # initialize current property path list
    844     my @curPropList;
    845     my (%nsCur, $prop, $n);
    846     my @pathList = sort keys %capture;
    847 
    848     while (@pathList) {
    849         my $path = shift @pathList;
     1034    my (@curPropList, @writeLast, @descStart, $extStart);
     1035    my (%nsCur, $prop, $n, $path);
     1036    my @pathList = sort TypeFirst keys %capture;
     1037    # order properties to write large values last if we have a MaxDataLen limit
     1038    if ($maxDataLen and @pathList) {
     1039        my @pathTmp;
     1040        my ($lastProp, $lastNS, $propSize) = ('', '', 0);
     1041        my @pathLoop = (@pathList, ''); # add empty path to end of list for loop
     1042        undef @pathList;
     1043        foreach $path (@pathLoop) {
     1044            $path =~ /^((\w*)[^\/]*)/;  # get path element ($1) and ns ($2)
     1045            if ($1 eq $lastProp) {
     1046                push @pathTmp, $path;   # accumulate all paths with same root
     1047            } else {
     1048                # put in list to write last if recommended or values are too large
     1049                if ($extendedRes{$lastProp} or $extendedRes{$lastNS} or
     1050                    $propSize > $newDescThresh)
     1051                {
     1052                    push @writeLast, @pathTmp;
     1053                } else {
     1054                    push @pathList, @pathTmp;
     1055                }
     1056                last unless $path;      # all done if we hit empty path
     1057                @pathTmp = ( $path );
     1058                ($lastProp, $lastNS, $propSize) = ($1, $2, 0);
     1059            }
     1060            $propSize += length $capture{$path}->[0];
     1061        }
     1062    }
     1063
     1064    # write out all properties
     1065    for (;;) {
     1066        my (%nsNew, $newDesc);
     1067        unless (@pathList) {
     1068            last unless @writeLast;
     1069            @pathList = @writeLast;
     1070            undef @writeLast;
     1071            $extStart = length $newData;
     1072            $newDesc = 1;   # start with a new description
     1073        }
     1074        $path = shift @pathList;
    8501075        my @propList = split('/',$path); # get property list
    8511076        # must open/close rdf:Description too
    8521077        unshift @propList, $rdfDesc;
    8531078        # make sure we have defined all necessary namespaces
    854         my (%nsNew, $newDesc);
    8551079        foreach $prop (@propList) {
    8561080            $prop =~ /(.*):/ or next;
    857             $1 eq 'rdf' and next;   # rdf namespace already defined
    858             my $nsNew = $nsUsed{$1};
    859             unless ($nsNew) {
    860                 $nsNew = $nsURI{$1}; # we must have added a namespace
    861                 unless ($nsNew) {
    862                     $xmpErr = "Undefined XMP namespace: $1";
    863                     next;
    864                 }
    865             }
    866             $nsNew{$1} = $nsNew;
     1081            $1 eq 'rdf' and next;       # rdf namespace already defined
     1082            my $uri = $nsUsed{$1};
     1083            unless ($uri) {
     1084                $uri = $nsURI{$1};      # we must have added a namespace
     1085                $uri or $xmpErr = "Undefined XMP namespace: $1", next;
     1086            }
     1087            $nsNew{$1} = $uri;
    8671088            # need a new description if any new namespaces
    8681089            $newDesc = 1 unless $nsCur{$1};
     
    8711092        if ($newDesc) {
    8721093            # look forward to see if we will want to also open other namespaces
    873             # (this is necessary to keep lists from being broken if a property
    874             #  introduces a new namespace; plus it improves formatting)
     1094            # at this level (this is necessary to keep lists and structures from
     1095            # being broken if a property introduces a new namespace; plus it
     1096            # improves formatting)
    8751097            my ($path2, $ns2);
    8761098            foreach $path2 (@pathList) {
     
    8801102                    next if $ns2 eq 'rdf';
    8811103                    $nsNew{$ns2} and ++$opening, next;
    882                     last unless $opening and $nsURI{$ns2};
    883                     # also open this namespace
    884                     $nsNew{$ns2} = $nsURI{$ns2};
     1104                    last unless $opening;
     1105                    # get URI for this existing or new namespace
     1106                    my $uri = $nsUsed{$ns2} || $nsURI{$ns2} or last;
     1107                    $nsNew{$ns2} = $uri; # also open this namespace
    8851108                }
    8861109                last unless $opening;
     
    8991122        }
    9001123        if ($newDesc) {
     1124            # save rdf:Description start positions so we can reorder them if necessary
     1125            push @descStart, length($newData) if $maxDataLen;
    9011126            # open the new description
    9021127            $prop = $rdfDesc;
    9031128            %nsCur = %nsNew;            # save current namespaces
    904             $newData .= "\n <$prop rdf:about='$uuid'";
    905             foreach (sort keys %nsCur) {
     1129            $newData .= "\n <$prop rdf:about='$about'";
     1130            my @ns = sort keys %nsCur;
     1131            # generate et:toolkit attribute if this is an exiftool RDF/XML output file
     1132            if (@ns and $nsCur{$ns[0]} =~ m{^http://ns.exiftool.ca/}) {
     1133                $newData .= "\n  xmlns:et='http://ns.exiftool.ca/1.0/'" .
     1134                            " et:toolkit='Image::ExifTool $Image::ExifTool::VERSION'";
     1135            }
     1136            foreach (@ns) {
    9061137                $newData .= "\n  xmlns:$_='$nsCur{$_}'";
    9071138            }
     
    9101141        }
    9111142        # loop over all values for this new property
    912         my $capList = $capture{$path};
    913         my ($val, $attrs) = @$capList;
     1143        my ($val, $attrs) = @{$capture{$path}};
    9141144        $debug and print "$path = $val\n";
    9151145        # open new properties
     
    9211151            $prop =~ s/ .*//;
    9221152            $attr = '';
    923             if ($prop ne $rdfDesc and $propList[$n+1] !~ /^rdf:/) {
     1153            if ($prop ne $rdfDesc and ($propList[$n+1] !~ /^rdf:/ or
     1154                ($propList[$n+1] eq 'rdf:type' and $n+1 == $#propList)))
     1155            {
    9241156                # need parseType='Resource' to avoid new 'rdf:Description'
    9251157                $attr = " rdf:parseType='Resource'";
     
    9271159            $newData .= (' ' x scalar(@curPropList)) . "<$prop$attr>\n";
    9281160        }
    929         my $prop2 = pop @propList;   # get new property name
    930         $prop2 =~ s/ .*//;  # remove list index if it exists
     1161        my $prop2 = pop @propList;  # get new property name
     1162        $prop2 =~ s/ .*//;          # remove list index if it exists
    9311163        $newData .= (' ' x scalar(@curPropList)) . " <$prop2";
    932         # print out attributes
     1164        # write out attributes
    9331165        foreach $attr (sort keys %$attrs) {
    9341166            my $attrVal = $$attrs{$attr};
     
    9361168            $newData .= " $attr=$quot$attrVal$quot";
    9371169        }
    938         $newData .= ">$val</$prop2>\n";
     1170        $newData .= length $val ? ">$val</$prop2>\n" : "/>\n";
    9391171    }
    9401172    # close off any open elements
     
    9431175        $newData .= (' ' x scalar(@curPropList)) . " </$prop>\n";
    9441176    }
    945 #
    946 # clean up, close out the XMP, and return our data
    947 #
     1177    # limit XMP length and re-arrange if necessary to fit inside specified size
     1178    my $compact = $$dirInfo{Compact} || $exifTool->Options('Compact');
     1179    if ($maxDataLen) {
     1180        # adjust maxDataLen to allow room for closing elements
     1181        $maxDataLen -= length($rdfClose) + length($xmpClose) + length($pktCloseW);
     1182        $extStart or $extStart = length $newData;
     1183        my @rtn = LimitXMPSize($exifTool, \$newData, $maxDataLen, $about, \@descStart, $extStart);
     1184        # return extended XMP information in $dirInfo
     1185        $$dirInfo{ExtendedXMP} = $rtn[0];
     1186        $$dirInfo{ExtendedGUID} = $rtn[1];
     1187        # compact if necessary to fit
     1188        $compact = 1 if length($newData) + 101 * $numPadLines > $maxDataLen;
     1189    }
     1190#
     1191# close out the XMP, clean up, and return our data
     1192#
     1193    $newData .= $rdfClose;
     1194    $newData .= $xmpClose unless $exifTool->{XMP_NO_XMPMETA};
     1195
    9481196    # remove the ExifTool members we created
    9491197    delete $exifTool->{XMP_CAPTURE};
    9501198    delete $exifTool->{XMP_NS};
    951 
    952     $newData .= $rdfClose . $xmpClose;
     1199    delete $exifTool->{XMP_NO_XMPMETA};
    9531200
    9541201    # (the XMP standard recommends writing 2k-4k of white space before the
     
    9581205        if ($$dirInfo{InPlace}) {
    9591206            # pad to specified DirLen
    960             my $dirLen = $$dirInfo{DirLen} || length $$dataPt;
    9611207            my $len = length($newData) + length($pktCloseW);
    9621208            if ($len > $dirLen) {
     
    9701216            }
    9711217            $len < $dirLen and $newData .= (' ' x ($dirLen - $len - 1)) . "\n";
    972         } elsif (not $exifTool->Options('Compact') and
    973                  not $xmpFile and not $$dirInfo{ReadOnly})
    974         {
    975             $newData .= $pad x 24;
     1218        } elsif (not $compact and not $xmpFile and not $$dirInfo{ReadOnly}) {
     1219            $newData .= $pad x $numPadLines;
    9761220        }
    9771221        $newData .= ($$dirInfo{ReadOnly} ? $pktCloseR : $pktCloseW);
    9781222    }
    979     # return empty data if no properties exist
    980     $newData = '' unless %capture or $$dirInfo{InPlace};
    981 
     1223    # return empty data if no properties exist and this is allowed
     1224    unless (%capture or $xmpFile or $$dirInfo{InPlace} or $$dirInfo{NoDelete}) {
     1225        $newData = '';
     1226    }
    9821227    if ($xmpErr) {
    9831228        if ($xmpFile) {
     
    9911236    $debug > 1 and $newData and print $newData,"\n";
    9921237    return $newData unless $xmpFile;
    993     return 1 if Write($$dirInfo{OutFile}, $newData);
    994     return -1;
     1238    Write($$dirInfo{OutFile}, $newData) or return -1;
     1239    return 1;
    9951240}
    9961241
     
    10141259=head1 AUTHOR
    10151260
    1016 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     1261Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    10171262
    10181263This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Writer.pl

    r16842 r24107  
    2323sub RemoveNewValueHash($$$);
    2424sub RemoveNewValuesForGroup($$);
     25sub GetWriteGroup1($$);
     26sub Sanitize($$);
     27sub ConvInv($$$$$;$$);
    2528
    2629my $loadedAllTables;    # flag indicating we loaded all tables
     
    4245    InteropIFD   => 'ExifIFD',
    4346    MakerNotes   => 'ExifIFD',
     47    CanonVRD     => 'MakerNotes', # (so VRDOffset will get updated)
     48    NikonCapture => 'MakerNotes', # (to allow delete by group)
     49);
     50my %exifMap = (
     51    IFD1         => 'IFD0',
     52    EXIF         => 'IFD0', # to write EXIF as a block
     53    ExifIFD      => 'IFD0',
     54    GPS          => 'IFD0',
     55    SubIFD       => 'IFD0',
     56    GlobParamIFD => 'IFD0',
     57    PrintIM      => 'IFD0',
     58    InteropIFD   => 'ExifIFD',
     59    MakerNotes   => 'ExifIFD',
     60    NikonCapture => 'MakerNotes', # (to allow delete by group)
     61    # (no CanonVRD trailer allowed)
    4462);
    4563my %jpegMap = (
     64    %exifMap, # covers all JPEG EXIF mappings
    4665    JFIF         => 'APP0',
    4766    CIFF         => 'APP0',
     
    5574    Ducky        => 'APP12',
    5675    Photoshop    => 'APP13',
    57     IFD1         => 'IFD0',
    58     EXIF         => 'IFD0', # to write EXIF as a block
    59     ExifIFD      => 'IFD0',
    60     GPS          => 'IFD0',
    61     SubIFD       => 'IFD0',
    62     GlobParamIFD => 'IFD0',
    63     PrintIM      => 'IFD0',
    6476    IPTC         => 'Photoshop',
    65     InteropIFD   => 'ExifIFD',
    6677    MakerNotes   => ['ExifIFD', 'CIFF'], # (first parent is the default)
     78    CanonVRD     => 'MakerNotes', # (so VRDOffset will get updated)
     79    NikonCapture => 'MakerNotes', # (to allow delete by group)
    6780    Comment      => 'COM',
    6881);
     
    7285    ORF  => \%tiffMap,
    7386    RAW  => \%tiffMap,
     87    EXIF => \%exifMap,
    7488);
    7589
     
    8195    AFCP CanonVRD CIFF Ducky EXIF ExifIFD File FlashPix FotoStation GlobParamIFD
    8296    GPS ICC_Profile IFD0 IFD1 InteropIFD IPTC JFIF MakerNotes Meta MetaIFD MIE
    83     PhotoMechanic Photoshop PNG PrintIM RMETA SubIFD Trailer XMP
     97    NikonCapture PDF PDF-update PhotoMechanic Photoshop PNG PrintIM RMETA RSRC
     98    SubIFD Trailer XML XML-* XMP XMP-*
    8499);
    85100# other group names of new tag values to remove when deleting an entire group
     
    114129my %translateWriteGroup = (
    115130    EXIF => 'ExifIFD',
     131    Meta => 'MetaIFD',
    116132    File => 'Comment',
    117133    MIE  => 'MIE',
    118134);
    119 # names of valid EXIF directories:
     135# names of valid EXIF and Meta directories:
    120136my %exifDirs = (
    121137    gps          => 'GPS',
     
    125141    interopifd   => 'InteropIFD',
    126142    makernotes   => 'MakerNotes',
     143    previewifd   => 'PreviewIFD', # (in MakerNotes)
     144    metaifd      => 'MetaIFD', # Kodak APP3 Meta
    127145);
    128146# min/max values for integer formats
     
    131149    'int8s'  => [-0x80, 0x7f],
    132150    'int16u' => [0, 0xffff],
     151    'int16uRev' => [0, 0xffff],
    133152    'int16s' => [-0x8000, 0x7fff],
    134153    'int32u' => [0, 0xffffffff],
    135154    'int32s' => [-0x80000000, 0x7fffffff],
    136155);
    137 my $maxSegmentLen = 0xfffd; # maximum length of data in a JPEG segment
     156# lookup for file types with block-writable EXIF
     157my %blockExifTypes = ( JPEG=>1, PNG=>1, JP2=>1, MIE=>1, EXIF=>1 );
     158
     159my $maxSegmentLen = 0xfffd;     # maximum length of data in a JPEG segment
     160my $maxXMPLen = $maxSegmentLen; # maximum length of XMP data in JPEG
    138161
    139162# value separators when conversion list is used (in SetNewValue)
    140163my %listSep = ( PrintConv => '; ?', ValueConv => ' ' );
     164
     165# printConv hash keys to ignore when doing reverse lookup
     166my %ignorePrintConv = ( OTHER => 1, BITMASK => 1, Notes => 1 );
    141167
    142168#------------------------------------------------------------------------------
     
    153179#           Replace => 0, 1 or 2 - overwrite previous new values (2=reset)
    154180#           Protected => bitmask to write tags with specified protections
     181#           EditOnly => true to only edit existing tags (don't create new tag)
     182#           EditGroup => true to only edit existing groups (don't create new group)
    155183#           Shift => undef, 0, +1 or -1 - shift value if possible
    156184#           NoShortcut => true to prevent looking up shortcut tags
    157185#           CreateGroups => [internal use] createGroups hash ref from related tags
     186#           ListOnly => [internal use] set only list or non-list tags
     187#           SetTags => [internal use] hash ref to return tagInfo refs of set tags
    158188# Returns: number of tags set (plus error string in list context)
    159189# Notes: For tag lists (like Keywords), call repeatedly with the same tag name for
    160190#        each value in the list.  Internally, the new information is stored in
    161 #        the following members of the $self->{NEW_VALUE}->{$tagInfo} hash:
     191#        the following members of the $self->{NEW_VALUE}{$tagInfo} hash:
    162192#           TagInfo - tag info ref
    163193#           DelValue - list ref for values to delete
    164194#           Value - list ref for values to add
    165 #           IsCreating - must be set for the tag to be added. otherwise just
    166 #                        changed if it already exists
     195#           IsCreating - must be set for the tag to be added, otherwise just
     196#                        changed if it already exists.  Set to 2 to not create group
    167197#           CreateGroups - hash of all family 0 group names where tag may be created
    168198#           WriteGroup - group name where information is being written (correct case)
    169199#           WantGroup - group name as specified in call to function (case insensitive)
    170 #           Next - pointer to next newValueHash (if more than one)
     200#           Next - pointer to next new value hash (if more than one)
    171201#           Self - ExifTool object reference
    172202#           Shift - shift value
     
    177207    my ($self, $tag, $value, %options) = @_;
    178208    my ($err, $tagInfo);
    179     my $verbose = $self->Options('Verbose');
    180     my $out = $self->Options('TextOut');
     209    my $verbose = $self->{OPTIONS}{Verbose};
     210    my $out = $self->{OPTIONS}{TextOut};
    181211    my $protected = $options{Protected} || 0;
     212    my $listOnly = $options{ListOnly};
     213    my $setTags = $options{SetTags};
    182214    my $numSet = 0;
     215
    183216    unless (defined $tag) {
    184217        # remove any existing set values
     
    191224    if (ref $value) {
    192225        if (ref $value eq 'ARRAY') {
     226            # (since value is an ARRAY, it will have more than one entry)
     227            # set all list-type tags first
     228            my $replace = $options{Replace};
    193229            foreach (@$value) {
    194                 my ($n, $e) = SetNewValue($self, $tag, $_, %options);
     230                my ($n, $e) = SetNewValue($self, $tag, $_, %options, ListOnly => 1);
    195231                $err = $e if $e;
    196232                $numSet += $n;
    197233                delete $options{Replace}; # don't replace earlier values in list
    198234            }
    199 ReturnNow:  return ($numSet, $err) if wantarray;
    200             $err and warn "$err\n";
    201             return $numSet;
     235            # and now set only non-list tags
     236            $value = join $self->{OPTIONS}{ListSep}, @$value;
     237            $options{Replace} = $replace;
     238            $listOnly = $options{ListOnly} = 0;
    202239        } elsif (ref $value eq 'SCALAR') {
    203240            $value = $$value;
    204241        }
    205242    }
    206     # make sure the Perl UTF-8 flag is OFF for the value if perl 5.6 or greater
    207     # (otherwise our byte manipulations get corrupted!!)
    208     if ($] >= 5.006 and defined $value) {
    209         if (eval 'require Encode; Encode::is_utf8($value)' or $@) {
    210             $value = pack('C*', unpack('C*', $value));
    211         }
    212     }
     243    # un-escape as necessary and make sure the Perl UTF-8 flag is OFF for the value
     244    # if perl is 5.6 or greater (otherwise our byte manipulations get corrupted!!)
     245    $self->Sanitize(\$value) if defined $value and not ref $value;
     246
    213247    # set group name in options if specified
    214     if ($tag =~ /(.+?):(.+)/) {
     248    if ($tag =~ /(.*):(.+)/) {
    215249        $options{Group} = $1 if $1 ne '*' and lc($1) ne 'all';
    216250        $tag = $2;
    217251    }
     252    # allow trailing '#' for ValueConv value
     253    $options{Type} = 'ValueConv' if $tag =~ s/#$//;
    218254    # ignore leading family number if 0 or 1 specified
    219255    if ($options{Group} and $options{Group} =~ /^(\d+)(.*)/ and $1 < 2) {
     
    235271                my $remove = ($options{Replace} and $options{Replace} > 1);
    236272                if ($wantGroup) {
    237                     @del = grep /^$wantGroup$/i, @delGroups;
     273                    @del = grep /^$wantGroup$/i, @delGroups unless $wantGroup =~ /^XM[LP]-\*$/i;
    238274                    # remove associated groups when excluding from mass delete
    239275                    if (@del and $remove) {
     
    253289                        }
    254290                    }
    255                     # allow MIE groups to be deleted by number
    256                     push @del, uc($wantGroup) if $wantGroup =~ /^MIE\d+$/i;
     291                    # allow MIE groups to be deleted by number,
     292                    # and allow any XMP family 1 group to be deleted
     293                    push @del, uc($wantGroup) if $wantGroup =~ /^(MIE\d+|XM[LP]-[-\w]+)$/i;
    257294                } else {
    258295                    # push all groups plus '*', except IFD1 and a few others
    259                     push @del, (grep !/^(IFD1|SubIFD|InteropIFD|GlobParamIFD)$/, @delGroups), '*';
     296                    push @del, (grep !/^(IFD1|SubIFD|InteropIFD|GlobParamIFD|PDF-update)$/, @delGroups), '*';
    260297                }
    261298                if (@del) {
    262299                    ++$numSet;
    263300                    my @donegrps;
     301                    my $delGroup = $self->{DEL_GROUP};
    264302                    foreach $grp (@del) {
    265303                        if ($remove) {
    266                             exists $self->{DEL_GROUP}->{$grp} or next;
    267                             delete $self->{DEL_GROUP}->{$grp};
     304                            my $didExcl;
     305                            if ($grp =~ /^(XM[LP])(-.*)?$/) {
     306                                my $x = $1;
     307                                if ($grp eq $x) {
     308                                    # exclude all related family 1 groups too
     309                                    foreach (keys %$delGroup) {
     310                                        next unless /^-?$x-/;
     311                                        push @donegrps, $_ if /^$x/;
     312                                        delete $$delGroup{$_};
     313                                    }
     314                                } elsif ($$delGroup{"$x-*"} and not $$delGroup{"-$grp"}) {
     315                                    # must also exclude XMP or XML to prevent bulk delete
     316                                    if ($$delGroup{$x}) {
     317                                        push @donegrps, $x;
     318                                        delete $$delGroup{$x};
     319                                    }
     320                                    # flag XMP/XML family 1 group for exclusion with leading '-'
     321                                    $$delGroup{"-$grp"} = 1;
     322                                    $didExcl = 1;
     323                                }
     324                            }
     325                            if (exists $$delGroup{$grp}) {
     326                                delete $$delGroup{$grp};
     327                            } else {
     328                                next unless $didExcl;
     329                            }
    268330                        } else {
    269                             $self->{DEL_GROUP}->{$grp} = 1;
     331                            $$delGroup{$grp} = 1;
     332                            # add flag for XMP/XML family 1 groups if deleting all XMP
     333                            if ($grp =~ /^XM[LP]$/) {
     334                                $$delGroup{"$grp-*"} = 1;
     335                                push @donegrps, "$grp-*";
     336                            }
    270337                            # remove all of this group from previous new values
    271338                            $self->RemoveNewValuesForGroup($grp);
     
    287354            # allow language suffix of form "-en_CA" or "-<rfc3066>" on tag name
    288355            if ($tag =~ /^(\w+)-([a-z]{2})(_[a-z]{2})$/i or # MIE
    289                 $tag =~ /^(\w+)-([a-z]{2,3}|[xi])(-[a-z\d]{2,8}(-[a-z\d]{1,8})*)?$/i) # XMP
     356                $tag =~ /^(\w+)-([a-z]{2,3}|[xi])(-[a-z\d]{2,8}(-[a-z\d]{1,8})*)?$/i) # XMP/PNG
    290357            {
    291358                $tag = $1;
     359                # normalize case of language codes
    292360                $langCode = lc($2);
    293361                $langCode .= (length($3) == 3 ? uc($3) : lc($3)) if $3;
     
    296364                    # only allow language codes in tables which support them
    297365                    next unless $$tagInfo{Table};
    298                     my $langInfoProc = $tagInfo->{Table}->{LANG_INFO} or next;
     366                    my $langInfoProc = $tagInfo->{Table}{LANG_INFO} or next;
    299367                    my $langInfo = &$langInfoProc($tagInfo, $langCode);
    300368                    push @matchingTags, $langInfo if $langInfo;
     
    308376                if ($match and not $options{NoShortcut}) {
    309377                    if (@{$Image::ExifTool::Shortcuts::Main{$match}} == 1) {
    310                         $tag = $Image::ExifTool::Shortcuts::Main{$match}->[0];
     378                        $tag = $Image::ExifTool::Shortcuts::Main{$match}[0];
    311379                        @matchingTags = FindTagInfo($tag);
    312380                        last if @matchingTags;
     
    319387                        }
    320388                        undef $err if $numSet;  # no error if any set successfully
    321                         goto ReturnNow; # all done
     389                        return ($numSet, $err) if wantarray;
     390                        $err and warn "$err\n";
     391                        return $numSet;
    322392                    }
    323393                }
     
    335405            $verbose > 2 and print $out "$err\n";
    336406        }
    337         goto ReturnNow; # all done
     407        # all done
     408        return ($numSet, $err) if wantarray;
     409        $err and warn "$err\n";
     410        return $numSet;
    338411    }
    339412    # get group name that we're looking for
     
    346419        } elsif ($wantGroup =~ /^SubIFD(\d+)$/i) {
    347420            $ifdName = "SubIFD$1";
     421        } elsif ($wantGroup =~ /^Version(\d+)$/i) {
     422            $ifdName = "Version$1"; # Sony IDC VersionIFD
    348423        } elsif ($wantGroup =~ /^MIE(\d*-?)(\w+)$/i) {
    349424            $mieGroup = "MIE$1" . ucfirst(lc($2));
    350425        } else {
    351426            $ifdName = $exifDirs{lc($wantGroup)};
    352             if ($wantGroup =~ /^XMP\b/i) {
     427            if (not $ifdName and $wantGroup =~ /^XMP\b/i) {
    353428                # must load XMP table to set group1 names
    354429                my $table = GetTagTable('Image::ExifTool::XMP::Main');
     
    362437# the highest priority group
    363438#
    364     my (@tagInfoList, %writeGroup, %preferred, %tagPriority, $avoid, $wasProtected);
     439    my (@tagInfoList, @writeAlsoList, %writeGroup, %preferred, %tagPriority, $avoid, $wasProtected);
    365440    my $highestPriority = -1;
    366441    foreach $tagInfo (@matchingTags) {
     
    372447            $writeGroup = $self->GetGroup($tagInfo, 0);
    373448            unless (lc($writeGroup) eq $lcWant) {
    374                 if ($writeGroup eq 'EXIF') {
     449                if ($writeGroup eq 'EXIF' or $writeGroup eq 'SonyIDC') {
    375450                    next unless $ifdName;
     451                    # can't yet write PreviewIFD tags
     452                    $ifdName eq 'PreviewIFD' and ++$foundMatch, next;
    376453                    $writeGroup = $ifdName;  # write to the specified IFD
    377454                } elsif ($writeGroup eq 'MIE') {
     
    379456                    $writeGroup = $mieGroup; # write to specific MIE group
    380457                    # set specific write group with document number if specified
    381                     if ($writeGroup =~ /^MIE\d+$/ and $tagInfo->{Table}->{WRITE_GROUP}) {
    382                         $writeGroup = $tagInfo->{Table}->{WRITE_GROUP};
     458                    if ($writeGroup =~ /^MIE\d+$/ and $tagInfo->{Table}{WRITE_GROUP}) {
     459                        $writeGroup = $tagInfo->{Table}{WRITE_GROUP};
    383460                        $writeGroup =~ s/^MIE/$mieGroup/;
    384461                    }
    385                 } else {
     462                } elsif (not $$tagInfo{AllowGroup} or $wantGroup !~ /^$$tagInfo{AllowGroup}$/i) {
    386463                    # allow group1 name to be specified
    387464                    my $grp1 = $self->GetGroup($tagInfo, 1);
    388465                    unless ($grp1 and lc($grp1) eq $lcWant) {
    389466                        # must also check group1 name directly in case it is different
    390                         $grp1 = $tagInfo->{Groups}->{1};
     467                        $grp1 = $tagInfo->{Groups}{1};
    391468                        next unless $grp1 and lc($grp1) eq $lcWant;
    392469                    }
     
    400477        my $table = $tagInfo->{Table};
    401478        my $writeProc = $table->{WRITE_PROC};
    402         # load parent table if this was a user-defined table
    403         if ($table->{PARENT}) {
    404             my $parent = GetTagTable($table->{PARENT});
    405             $writeProc = $parent->{WRITE_PROC} unless $writeProc;
     479        # load source table if this was a user-defined table
     480        if ($$table{SRC_TABLE}) {
     481            my $src = GetTagTable($$table{SRC_TABLE});
     482            $writeProc = $$src{WRITE_PROC} unless $writeProc;
    406483        }
    407484        next unless $writeProc and &$writeProc();
     
    410487        next unless $writable or ($table->{WRITABLE} and
    411488            not defined $writable and not $$tagInfo{SubDirectory});
     489        # set specific write group (if we didn't already)
     490        if (not $writeGroup or $translateWriteGroup{$writeGroup}) {
     491            # use default write group
     492            $writeGroup = $tagInfo->{WriteGroup} || $tagInfo->{Table}{WRITE_GROUP};
     493            # use group 0 name if no WriteGroup specified
     494            my $group0 = $self->GetGroup($tagInfo, 0);
     495            $writeGroup or $writeGroup = $group0;
     496            # get priority for this group
     497            unless ($priority) {
     498                $priority = $self->{WRITE_PRIORITY}{lc($writeGroup)};
     499                unless ($priority) {
     500                    $priority = $self->{WRITE_PRIORITY}{lc($group0)} || 0;
     501                }
     502            }
     503        }
    412504        # don't write tag if protected
    413505        if ($tagInfo->{Protected}) {
     
    416508                my %lkup = ( 1=>'unsafe', 2=>'protected', 3=>'unsafe and protected');
    417509                $wasProtected = $lkup{$prot};
     510                if ($verbose > 1) {
     511                    my $wgrp1 = $self->GetWriteGroup1($tagInfo, $writeGroup);
     512                    print $out "Not writing $wgrp1:$tag ($wasProtected)\n";
     513                }
    418514                next;
    419515            }
    420516        }
    421         # set specific write group (if we didn't already)
    422         if (not $writeGroup or $translateWriteGroup{$writeGroup}) {
    423             # use default write group
    424             $writeGroup = $tagInfo->{WriteGroup} || $tagInfo->{Table}->{WRITE_GROUP};
    425             # use group 0 name if no WriteGroup specified
    426             my $group0 = $self->GetGroup($tagInfo, 0);
    427             $writeGroup or $writeGroup = $group0;
    428             # get priority for this group
    429             unless ($priority) {
    430                 $priority = $self->{WRITE_PRIORITY}->{lc($writeGroup)};
    431                 unless ($priority) {
    432                     $priority = $self->{WRITE_PRIORITY}->{lc($group0)} || 0;
    433                 }
    434             }
    435         }
     517        # set priority for this tag
    436518        $tagPriority{$tagInfo} = $priority;
    437519        if ($priority > $highestPriority) {
     
    445527            ++$avoid if $$tagInfo{Avoid};
    446528        }
    447         push @tagInfoList, $tagInfo;
     529        if ($$tagInfo{WriteAlso}) {
     530            # store WriteAlso tags separately so we can set them first
     531            push @writeAlsoList, $tagInfo;
     532        } else {
     533            push @tagInfoList, $tagInfo;
     534        }
    448535        $writeGroup{$tagInfo} = $writeGroup;
    449536    }
     537    # sort tag info list in reverse order of priority (higest number last)
     538    # so we get the highest priority error message in the end
     539    @tagInfoList = sort { $tagPriority{$a} <=> $tagPriority{$b} } @tagInfoList;
     540    # must write any tags which also write other tags first
     541    unshift @tagInfoList, @writeAlsoList if @writeAlsoList;
     542
    450543    # don't create tags with priority 0 if group priorities are set
    451544    if ($highestPriority == 0 and %{$self->{WRITE_PRIORITY}}) {
     
    487580# generate new value hash for each tag
    488581#
    489     my ($prioritySet, $createGroups);
    490     # sort tag info list in reverse order of priority (higest number last)
    491     # so we get the highest priority error message in the end
    492     @tagInfoList = sort { $tagPriority{$a} <=> $tagPriority{$b} } @tagInfoList;
     582    my ($prioritySet, $createGroups, %alsoWrote);
     583
     584    delete $$self{CHECK_WARN};  # reset CHECK_PROC warnings
     585
    493586    # loop through all valid tags to find the one(s) to write
    494     SetTagLoop: foreach $tagInfo (@tagInfoList) {
     587    foreach $tagInfo (@tagInfoList) {
     588        next if $alsoWrote{$tagInfo};   # don't rewrite tags we already wrote
     589        # only process List or non-List tags if specified
     590        next if defined $listOnly and ($listOnly xor $$tagInfo{List});
     591        my $noConv;
    495592        my $writeGroup = $writeGroup{$tagInfo};
    496593        my $permanent = $$tagInfo{Permanent};
    497594        $writeGroup eq 'MakerNotes' and $permanent = 1 unless defined $permanent;
    498         my $wgrp1;
    499         if ($writeGroup eq 'MakerNotes' or $writeGroup eq 'XMP') {
    500             $wgrp1 = $self->GetGroup($tagInfo, 1);
    501         } else {
    502             $wgrp1 = $writeGroup;
    503         }
     595        my $wgrp1 = $self->GetWriteGroup1($tagInfo, $writeGroup);
    504596        $tag = $tagInfo->{Name};    # get proper case for tag name
    505597        my $shift = $options{Shift};
    506598        if (defined $shift) {
    507             if ($tagInfo->{Shift}) {
     599            # (can't currently shift List-type tags)
     600            if ($tagInfo->{Shift} and not $tagInfo->{List}) {
    508601                unless ($shift) {
    509602                    # set shift according to AddValue/DelValue
    510603                    $shift = 1 if $options{AddValue};
    511604                    $shift = -1 if $options{DelValue};
     605                }
     606                if ($shift and (not defined $value or not length $value)) {
     607                    # (now allow -= to be used for shiftable tag - v8.05)
     608                    #$err = "No value for time shift of $wgrp1:$tag";
     609                    #$verbose > 2 and print $out "$err\n";
     610                    #next;
     611                    undef $shift;
    512612                }
    513613            } elsif ($shift) {
     
    525625                next;
    526626            }
    527         } else {
    528             # can't delete permanent tags, so set value to empty string instead
    529             $val = '' if $permanent;
    530         }
    531         # convert the value
    532         my $type;
    533         if ($shift) {
    534             # add '+' or '-' prefix to indicate shift direction
    535             $val = ($shift > 0 ? '+' : '-') . $val;
    536             # check the shift for validity
    537             require 'Image/ExifTool/Shift.pl';
    538             my $err2 = CheckShift($tagInfo->{Shift}, $val);
    539             if ($err2) {
    540                 $err = "$err2 for $wgrp1:$tag";
    541                 $verbose > 2 and print $out "$err\n";
    542                 next;
    543             }
    544         } else {
    545             $type = $options{Type};
    546             $type or $type = $self->Options('PrintConv') ? 'PrintConv' : 'ValueConv';
    547         }
    548 Conv:   while (defined $val and not $shift) {
    549             my $conv = $tagInfo->{$type};
    550             my $convInv = $tagInfo->{"${type}Inv"};
    551             my (@valList, $index, $convList, $convInvList);
    552             # handle conversion lists
    553             if (ref $conv eq 'ARRAY' or ref $convInv eq 'ARRAY') {
    554                 @valList = split /$listSep{$type}/, $val;
    555                 $val = $valList[$index = 0];
    556                 if (ref $conv eq 'ARRAY') {
    557                     $convList = $conv;
    558                     $conv = $$conv[0];
    559                 }
    560                 if (ref $convInv eq 'ARRAY') {
    561                     $convInvList = $convInv;
    562                     $convInv = $$convInv[0];
    563                 }
    564             }
    565             # loop through multiple values if necessary
    566             for (;;) {
    567                 if ($convInv) {
    568                     # capture eval warnings too
    569                     local $SIG{'__WARN__'} = \&SetWarning;
    570                     undef $evalWarning;
    571                     if (ref($convInv) eq 'CODE') {
    572                         $val = &$convInv($val, $self);
    573                     } else {
    574                         #### eval PrintConvInv/ValueConvInv ($val, $self)
    575                         $val = eval $convInv;
    576                         $@ and $evalWarning = $@;
    577                     }
    578                     if ($evalWarning) {
    579                         $err = CleanWarning() . " in $wgrp1:$tag (${type}Inv)";
    580                         $verbose > 2 and print $out "$err\n";
    581                         undef $val;
    582                         last Conv;
    583                     } elsif (not defined $val) {
    584                         $err = "Error converting value for $wgrp1:$tag (${type}Inv)";
    585                         $verbose > 2 and print $out "$err\n";
    586                         last Conv;
    587                     }
    588                 } elsif ($conv) {
    589                     if (ref $conv eq 'HASH') {
    590                         my $multi;
    591                         if ($$conv{BITMASK}) {
    592                             my $lookupBits = $$conv{BITMASK};
    593                             my ($val2, $err2) = EncodeBits($val, $lookupBits);
    594                             if ($err2) {
    595                                 # ok, try matching a straight value
    596                                 ($val, $multi) = ReverseLookup($val, $conv);
    597                                 unless (defined $val) {
    598                                     $err = "Can't encode $wgrp1:$tag ($err2)";
    599                                     $verbose > 2 and print $out "$err\n";
    600                                     last Conv;
    601                                 }
    602                             } elsif (defined $val2) {
    603                                 $val = $val2;
    604                             } else {
    605                                 delete $$conv{BITMASK};
    606                                 ($val, $multi) = ReverseLookup($val, $conv);
    607                                 $$conv{BITMASK} = $lookupBits;
    608                             }
    609                         } else {
    610                             ($val, $multi) = ReverseLookup($val, $conv);
    611                         }
    612                         unless (defined $val) {
    613                             $err = "Can't convert $wgrp1:$tag (" .
    614                                    ($multi ? 'matches more than one' : 'not in') . " $type)";
    615                             $verbose > 2 and print $out "$err\n";
    616                             last Conv;
    617                         }
    618                     } elsif (not $$tagInfo{WriteAlso}) {
    619                         $err = "Can't convert value for $wgrp1:$tag (no ${type}Inv)";
    620                         $verbose > 2 and print $out "$err\n";
    621                         undef $val;
    622                         last Conv;
    623                     }
    624                 }
    625                 last unless @valList;
    626                 $valList[$index] = $val;
    627                 if (++$index >= @valList) {
    628                     $val = join ' ', @valList;
    629                     last;
    630                 }
    631                 $conv = $$convList[$index] if $convList;
    632                 $convInv = $$convInvList[$index] if $convInvList;
    633                 $val = $valList[$index];
    634             }
    635             # cycle through PrintConv, ValueConv
    636             if ($type eq 'PrintConv') {
    637                 $type = 'ValueConv';
    638             } else {
    639                 # validate the value with WriteCheck and CHECK_PROC if they exist
    640                 my $err2;
    641                 if ($tagInfo->{WriteCheck}) {
    642                     #### eval WriteCheck ($self, $tagInfo, $val)
    643                     $err2 = eval $tagInfo->{WriteCheck};
    644                     $@ and warn($@), $err2 = 'Error evaluating WriteCheck';
    645                 }
    646                 unless ($err2) {
    647                     my $table = $tagInfo->{Table};
    648                     if ($table and $table->{CHECK_PROC} and not $$tagInfo{RawConvInv}) {
    649                         my $checkProc = $table->{CHECK_PROC};
    650                         $err2 = &$checkProc($self, $tagInfo, \$val);
    651                     }
    652                 }
     627            if ($shift) {
     628                # add '+' or '-' prefix to indicate shift direction
     629                $val = ($shift > 0 ? '+' : '-') . $val;
     630                # check the shift for validity
     631                require 'Image/ExifTool/Shift.pl';
     632                my $err2 = CheckShift($tagInfo->{Shift}, $val);
    653633                if ($err2) {
    654634                    $err = "$err2 for $wgrp1:$tag";
    655635                    $verbose > 2 and print $out "$err\n";
    656                     undef $val; # value was invalid
    657                 }
    658                 last;
     636                    next;
     637                }
     638                $noConv = 1;    # no conversions if shifting tag
     639            } elsif (not length $val and $options{DelValue}) {
     640                $noConv = 1;    # no conversions for deleting empty value
     641            } elsif (ref $val eq 'HASH' and not $$tagInfo{Struct}) {
     642                $err = "Can't write a structure to $wgrp1:$tag";
     643                $verbose > 2 and print $out "$err\n";
     644                next;
     645            }
     646        } elsif ($permanent) {
     647            # can't delete permanent tags, so set them to DelValue or empty string instead
     648            if (defined $$tagInfo{DelValue}) {
     649                $val = $$tagInfo{DelValue};
     650                $noConv = 1;    # DelValue is the raw value, so no conversion necessary
     651            } else {
     652                $val = '';
     653            }
     654        } elsif ($options{AddValue} or $options{DelValue}) {
     655            $err = "No value to add or delete in $wgrp1:$tag";
     656            $verbose > 2 and print $out "$err\n";
     657            next;
     658        } else {
     659            if ($tagInfo->{DelCheck}) {
     660                #### eval DelCheck ($self, $tagInfo, $wantGroup)
     661                my $err2 = eval $tagInfo->{DelCheck};
     662                $@ and warn($@), $err2 = 'Error evaluating DelCheck';
     663                if ($err2) {
     664                    $err2 .= ' for' unless $err2 =~ /delete$/;
     665                    $err = "$err2 $wgrp1:$tag";
     666                    $verbose > 2 and print $out "$err\n";
     667                    next;
     668                } elsif (defined $err2) {
     669                    ++$numSet;  # (allow other tags to be set using DelCheck as a hook)
     670                    goto WriteAlso;
     671                }
     672            }
     673            $noConv = 1;    # value is not defined, so don't do conversion
     674        }
     675        # apply inverse PrintConv and ValueConv conversions
     676        # save ValueConv setting for use in ConvInv()
     677        unless ($noConv) {
     678            # set default conversion type used by ConvInv() and CHECK_PROC routines
     679            $$self{ConvType} = $options{Type} || ($self->{OPTIONS}{PrintConv} ? 'PrintConv' : 'ValueConv');
     680            my $e;
     681            ($val,$e) = $self->ConvInv($val, $tagInfo, $tag, $wgrp1, $$self{ConvType}, $wantGroup);
     682            if (defined $e) {
     683                if ($e) {
     684                    ($err = $e) =~ s/\$wgrp1/$wgrp1/g;
     685                } else {
     686                    ++$numSet;  # an empty error string causes error to be ignored
     687                }
    659688            }
    660689        }
     
    680709        }
    681710
    682         # set value in NEW_VALUE hash
    683711        if (defined $val) {
    684712            # we are editing this tag, so create a NEW_VALUE hash entry
    685             my $newValueHash = $self->GetNewValueHash($tagInfo, $writeGroup, 'create');
    686             $newValueHash->{WantGroup} = $wantGroup;
     713            my $nvHash = $self->GetNewValueHash($tagInfo, $writeGroup, 'create');
     714            $nvHash->{WantGroup} = $wantGroup;
    687715            # save maker note information if writing maker notes
    688716            if ($$tagInfo{MakerNotes}) {
    689                 $newValueHash->{MAKER_NOTE_FIXUP} = $self->{MAKER_NOTE_FIXUP};
     717                $nvHash->{MAKER_NOTE_FIXUP} = $self->{MAKER_NOTE_FIXUP};
    690718            }
    691719            if ($options{DelValue} or $options{AddValue} or $shift) {
    692720                # flag any AddValue or DelValue by creating the DelValue list
    693                 $newValueHash->{DelValue} or $newValueHash->{DelValue} = [ ];
     721                $nvHash->{DelValue} or $nvHash->{DelValue} = [ ];
    694722                if ($shift) {
    695723                    # add shift value to list
    696                     $newValueHash->{Shift} = $val;
     724                    $nvHash->{Shift} = $val;
    697725                } elsif ($options{DelValue}) {
    698726                    # don't create if we are replacing a specific value
    699                     $newValueHash->{IsCreating} = 0 unless $val eq '';
     727                    $nvHash->{IsCreating} = 0 unless $val eq '' or $tagInfo->{List};
    700728                    # add delete value to list
    701                     push @{$newValueHash->{DelValue}}, $val;
     729                    push @{$nvHash->{DelValue}}, ref $val eq 'ARRAY' ? @$val : $val;
    702730                    if ($verbose > 1) {
    703731                        my $verb = $permanent ? 'Replacing' : 'Deleting';
    704732                        my $fromList = $tagInfo->{List} ? ' from list' : '';
    705                         print $out "$verb $wgrp1:$tag$fromList if value is '$val'\n";
     733                        my @vals = (ref $val eq 'ARRAY' ? @$val : $val);
     734                        foreach (@vals) {
     735                            if (ref $_ eq 'HASH') {
     736                                require 'Image/ExifTool/XMPStruct.pl';
     737                                $_ = Image::ExifTool::XMP::SerializeStruct($_);
     738                            }
     739                            print $out "$verb $wgrp1:$tag$fromList if value is '$_'\n";
     740                        }
    706741                    }
    707742                }
     
    710745            # (will only create the priority tag if it doesn't exist,
    711746            #  others get changed only if they already exist)
    712             if ($preferred{$tagInfo} or $tagInfo->{Table}->{PREFERRED}) {
     747            if ($preferred{$tagInfo} or $tagInfo->{Table}{PREFERRED}) {
    713748                if ($permanent or $shift) {
    714749                    # don't create permanent or Shift-ed tag but define IsCreating
    715750                    # so we know that it is the preferred tag
    716                     $newValueHash->{IsCreating} = 0;
    717                 } elsif (not ($newValueHash->{DelValue} and @{$newValueHash->{DelValue}}) or
     751                    $nvHash->{IsCreating} = 0;
     752                } elsif (($tagInfo->{List} and not $options{DelValue}) or
     753                         not ($nvHash->{DelValue} and @{$nvHash->{DelValue}}) or
    718754                         # also create tag if any DelValue value is empty ('')
    719                          grep(/^$/,@{$newValueHash->{DelValue}}))
     755                         grep(/^$/,@{$nvHash->{DelValue}}))
    720756                {
    721                     $newValueHash->{IsCreating} = 1;
     757                    $nvHash->{IsCreating} = $options{EditOnly} ? 0 : ($options{EditGroup} ? 2 : 1);
    722758                    # add to hash of groups where this tag is being created
    723759                    $createGroups or $createGroups = $options{CreateGroups} || { };
    724760                    $$createGroups{$self->GetGroup($tagInfo, 0)} = 1;
    725                     $newValueHash->{CreateGroups} = $createGroups;
    726                 }
    727             }
    728             if (%{$self->{DEL_GROUP}} and $newValueHash->{IsCreating}) {
     761                    $nvHash->{CreateGroups} = $createGroups;
     762                }
     763            }
     764            if (%{$self->{DEL_GROUP}} and $nvHash->{IsCreating}) {
    729765                my ($grp, @grps);
    730766                foreach $grp (keys %{$self->{DEL_GROUP}}) {
    731                     next if $self->{DEL_GROUP}->{$grp} == 2;
     767                    next if $self->{DEL_GROUP}{$grp} == 2;
    732768                    # set flag indicating tags were written after this group was deleted
    733                     $self->{DEL_GROUP}->{$grp} = 2;
     769                    $self->{DEL_GROUP}{$grp} = 2;
    734770                    push @grps, $grp;
    735771                }
     
    740776            }
    741777            if ($shift or not $options{DelValue}) {
    742                 $newValueHash->{Value} or $newValueHash->{Value} = [ ];
    743                 if ($tagInfo->{List}) {
    744                     # we can write a list of entries
    745                     push @{$newValueHash->{Value}}, $val;
     778                $nvHash->{Value} or $nvHash->{Value} = [ ];
     779                if (not $tagInfo->{List}) {
     780                    # not a List tag -- overwrite existing value
     781                    $nvHash->{Value}[0] = $val;
    746782                } else {
    747                     # not a List tag -- overwrite existing value
    748                     $newValueHash->{Value}->[0] = $val;
     783                    # add to existing list
     784                    push @{$nvHash->{Value}}, ref $val eq 'ARRAY' ? @$val : $val;
    749785                }
    750786                if ($verbose > 1) {
    751                     my $ifExists = $newValueHash->{IsCreating} ? '' : ' if tag exists';
     787                    my $ifExists = $nvHash->{IsCreating} ?
     788                                  ($nvHash->{IsCreating} == 2 ? " if $writeGroup exists" : '') :
     789                                  (($nvHash->{DelValue} and @{$nvHash->{DelValue}}) ?
     790                                   ' if tag was deleted' : ' if tag exists');
    752791                    my $verb = ($shift ? 'Shifting' : ($options{AddValue} ? 'Adding' : 'Writing'));
    753792                    print $out "$verb $wgrp1:$tag$ifExists\n";
     
    755794            }
    756795        } elsif ($permanent) {
    757             $err = "Can't delete $tag";
     796            $err = "Can't delete $wgrp1:$tag";
    758797            $verbose > 1 and print $out "$err\n";
    759798            next;
     
    764803            # create empty new value hash entry to delete this tag
    765804            $self->GetNewValueHash($tagInfo, $writeGroup, 'delete');
    766             my $newValueHash = $self->GetNewValueHash($tagInfo, $writeGroup, 'create');
    767             $newValueHash->{WantGroup} = $wantGroup;
     805            my $nvHash = $self->GetNewValueHash($tagInfo, $writeGroup, 'create');
     806            $nvHash->{WantGroup} = $wantGroup;
    768807            $verbose > 1 and print $out "Deleting $wgrp1:$tag\n";
    769808        }
    770809        ++$numSet;
     810        $$setTags{$tagInfo} = 1 if $setTags;
    771811        $prioritySet = 1 if $preferred{$tagInfo};
     812WriteAlso:
    772813        # also write related tags
    773814        my $writeAlso = $$tagInfo{WriteAlso};
    774815        if ($writeAlso) {
    775             my $wtag;
     816            my ($wtag, $n);
     817            local $SIG{'__WARN__'} = \&SetWarning;
    776818            foreach $wtag (keys %$writeAlso) {
     819                my %opts = (
     820                    Type => 'ValueConv',
     821                    Protected => $protected | 0x02,
     822                    AddValue => $options{AddValue},
     823                    DelValue => $options{DelValue},
     824                    CreateGroups => $createGroups,
     825                    SetTags => \%alsoWrote, # remember tags already written
     826                );
     827                undef $evalWarning;
    777828                #### eval WriteAlso ($val)
    778829                my $v = eval $writeAlso->{$wtag};
    779                 $@ and warn($@), next;
    780                 my ($n,$e) = $self->SetNewValue($wtag, $v, Type => 'ValueConv',
    781                                                 Protected => $protected | 0x02,
    782                                                 CreateGroups => $createGroups);
    783                 print $out "Not writing $wtag ($e)\n" if $e and $verbose > 1;
    784                 $numSet += $n;
     830                $@ and $evalWarning = $@;
     831                unless ($evalWarning) {
     832                    ($n,$evalWarning) = $self->SetNewValue($wtag, $v, %opts);
     833                    $numSet += $n;
     834                    # count this as being set if any related tag is set
     835                    $prioritySet = 1 if $n and $preferred{$tagInfo};
     836                }
     837                if ($evalWarning and (not $err or $verbose > 2)) {
     838                    my $str = CleanWarning();
     839                    if ($str) {
     840                        $str .= " for $wtag" unless $str =~ / for [-\w:]+$/;
     841                        $str .= " in $wgrp1:$tag (WriteAlso)";
     842                        $err or $err = $str;
     843                        print $out "$str\n" if $verbose > 2;
     844                    }
     845                }
    785846            }
    786847        }
    787848    }
    788849    # print warning if we couldn't set our priority tag
    789     if ($err and not $prioritySet) {
    790         warn "$err\n" unless wantarray;
     850    if (defined $err and not $prioritySet) {
     851        warn "$err\n" if $err and not wantarray;
    791852    } elsif (not $numSet) {
    792         my $pre = $wantGroup ? "$wantGroup:" : '';
     853        my $pre = $wantGroup ? ($ifdName || $wantGroup) . ':' : '';
    793854        if ($wasProtected) {
    794855            $err = "Tag '$pre$tag' is $wasProtected for writing";
     
    800861        $verbose > 2 and print $out "$err\n";
    801862        warn "$err\n" unless wantarray;
     863    } elsif ($$self{CHECK_WARN}) {
     864        $err = $$self{CHECK_WARN};
     865        $verbose > 2 and print $out "$err\n";
    802866    } elsif ($err and not $verbose) {
    803867        undef $err;
     
    810874# set new values from information in specified file
    811875# Inputs: 0) ExifTool object reference, 1) source file name or reference, etc
    812 #         2) List of tags to set (or all if none specified)
     876#         2-N) List of tags to set (or all if none specified), or reference(s) to
     877#         hash for options to pass to SetNewValue.  The Replace option defaults
     878#         to 1 for SetNewValuesFromFile -- set this to 0 to allow multiple tags
     879#         to be copied to a list
    813880# Returns: Hash of information set successfully (includes Warning or Error messages)
    814 # Notes: Tag names may contain group prefix and/or leading '-' to exclude from copy,
    815 #        and the tag name '*' may be used to represent all tags in a group.
    816 #        Also, a tag name may end with '>DSTTAG' to copy the information to a
    817 #        different tag, or a tag with a specified group.  (Also allow 'DSTTAG<TAG'.)
     881# Notes: Tag names may contain a group prefix, a leading '-' to exclude from copy,
     882#        and/or a trailing '#' to copy the ValueConv value.  The tag name '*' may
     883#        be used to represent all tags in a group.  An optional destination tag
     884#        may be specified with '>DSTTAG' ('DSTTAG<TAG' also works, but in this
     885#        case the source tag may also be an expression involving tag names).
    818886sub SetNewValuesFromFile($$;@)
    819887{
     888    local $_;
    820889    my ($self, $srcFile, @setTags) = @_;
    821 
     890    my $key;
     891
     892    # get initial SetNewValuesFromFile options
     893    my %opts = ( Replace => 1 );    # replace existing list items by default
     894    while (ref $setTags[0] eq 'HASH') {
     895        $_ = shift @setTags;
     896        foreach $key (keys %$_) {
     897            $opts{$key} = $_->{$key};
     898        }
     899    }
    822900    # expand shortcuts
    823901    @setTags and ExpandShortcuts(\@setTags);
     
    825903    my $options = $self->{OPTIONS};
    826904    # set options for our extraction tool
     905    $srcExifTool->{TAGS_FROM_FILE} = 1;
     906    # +------------------------------------------+
     907    # ! DON'T FORGET!!  Must consider each new   !
     908    # ! option to decide how it is handled here. !
     909    # +------------------------------------------+
    827910    $srcExifTool->Options(
     911        Binary      => 1,
     912        Charset     => $$options{Charset},
     913        CharsetID3  => $$options{CharsetID3},
     914        CharsetIPTC => $$options{CharsetIPTC},
     915        CharsetPhotoshop => $$options{CharsetPhotoshop},
     916        Composite   => $$options{Composite},
     917        CoordFormat => $$options{CoordFormat} || '%d %d %.8f', # copy coordinates at high resolution unless otherwise specified
     918        DateFormat  => $$options{DateFormat},
     919        Duplicates  => 1,
     920        Escape      => $$options{Escape},
     921        ExtractEmbedded => $$options{ExtractEmbedded},
     922        FastScan    => $$options{FastScan},
     923        FixBase     => $$options{FixBase},
     924        IgnoreMinorErrors => $$options{IgnoreMinorErrors},
     925        Lang        => $$options{Lang},
     926        LargeFileSupport => $$options{LargeFileSupport},
     927        List        => 1,
    828928        MakerNotes  => 1,
    829         Binary      => 1,
    830         Duplicates  => 1,
    831         List        => 1,
     929        MissingTagValue => $$options{MissingTagValue},
     930        Password    => $$options{Password},
     931        PrintConv   => $$options{PrintConv},
     932        ScanForXMP  => $$options{ScanForXMP},
    832933        StrictDate  => 1,
    833         FixBase     => $$options{FixBase},
    834         DateFormat  => $$options{DateFormat},
    835         PrintConv   => $$options{PrintConv},
    836         Composite   => $$options{Composite},
    837         MissingTagValue   => $$options{MissingTagValue},
    838         IgnoreMinorErrors => $$options{IgnoreMinorErrors},
     934        Struct      => ($$options{Struct} or not defined $$options{Struct}) ? 1 : 0,
     935        Unknown     => $$options{Unknown},
    839936    );
     937    my $printConv = $$options{PrintConv};
     938    if ($opts{Type}) {
     939        # save source type separately because it may be different than dst Type
     940        $opts{SrcType} = $opts{Type};
     941        # override PrintConv option with initial Type if given
     942        $printConv = ($opts{Type} eq 'PrintConv' ? 1 : 0);
     943        $srcExifTool->Options(PrintConv => $printConv);
     944    }
     945    my $srcType = $printConv ? 'PrintConv' : 'ValueConv';
     946
    840947    # get all tags from source file (including MakerNotes block)
    841948    my $info = $srcExifTool->ImageInfo($srcFile);
    842     return $info if $info->{Error} and $info->{Error} eq 'Error opening file';
    843     delete $srcExifTool->{VALUE}->{Error};  # delete so we can check this later
     949    return $info if $$info{Error} and $$info{Error} eq 'Error opening file';
     950    delete $srcExifTool->{VALUE}{Error};  # delete so we can check this later
    844951
    845952    # sort tags in reverse order so we get priority tag last
     
    854961        $self->{MAKER_NOTE_BYTE_ORDER} = $srcExifTool->{MAKER_NOTE_BYTE_ORDER};
    855962        foreach $tag (@tags) {
    856             # don't try to set Warning's or Error's
    857             next if $tag =~ /^Warning\b/ or $tag =~ /^Error\b/;
     963            # don't try to set errors or warnings
     964            next if $tag =~ /^(Error|Warning)\b/;
     965            # get approprite value type if necessary
     966            if ($opts{SrcType} and $opts{SrcType} ne $srcType) {
     967                $$info{$tag} = $srcExifTool->GetValue($tag, $opts{SrcType});
     968            }
    858969            # set value for this tag
    859             my ($n, $e) = $self->SetNewValue($tag, $info->{$tag}, Replace => 1);
     970            my ($n, $e) = $self->SetNewValue($tag, $$info{$tag}, %opts);
    860971            # delete this tag if we could't set it
    861             $n or delete $info->{$tag};
     972            $n or delete $$info{$tag};
    862973        }
    863974        return $info;
     
    869980    my (@setList, $set, %setMatches);
    870981    foreach (@setTags) {
    871         $tag = lc($_);  # change tag name to all lower case
    872         my ($fam, $grp, $dst, $dstGrp, $dstTag, $expr, $opt);
     982        if (ref $_ eq 'HASH') {
     983            # update current options
     984            foreach $key (keys %$_) {
     985                $opts{$key} = $_->{$key};
     986            }
     987            next;
     988        }
     989        # make a copy of the current options for this setTag
     990        # (also use this hash to store expression and wildcard flags, EXPR and WILD)
     991        my $opts = { %opts };
     992        $tag = lc($_);  # change tag/group names to all lower case
     993        my ($fam, $grp, $dst, $dstGrp, $dstTag, $isExclude);
    873994        # handle redirection to another tag
    874995        if ($tag =~ /(.+?)\s*(>|<)\s*(.+)/) {
    875996            $dstGrp = '';
     997            my $opt;
    876998            if ($2 eq '>') {
    877999                ($tag, $dstTag) = ($1, $3);
     
    8851007                    $tag = $_;  # restore original case
    8861008                    # recover leading whitespace (except for initial single space)
    887                     # and flag expression by starting with '@'
    888                     $tag =~ s/(.+?)\s*(>|<) ?/\@/;
    889                     $expr = 1;  # flag this expression
     1009                    $tag =~ s/(.+?)\s*(>|<) ?//;
     1010                    $$opts{EXPR} = 1; # flag this expression
     1011                    $grp = '';
    8901012                } else {
    8911013                    $opt = $1 if $tag =~ s/^([-+])\s*//;
     
    8931015            }
    8941016            # translate '+' and '-' to appropriate SetNewValue option
    895             $opt and $opt = { '+' => 'AddValue', '-' => 'DelValue' }->{$opt};
    896             $dstTag =~ s/\ball\b/\*/g;       # replace 'all' with '*'
    897             ($dstGrp, $dstTag) = ($1, $2) if $dstTag =~ /(.+?):(.+)/;
     1017            if ($opt) {
     1018                $$opts{{ '+' => 'AddValue', '-' => 'DelValue' }->{$opt}} = 1;
     1019                $$opts{Shift} = 0;  # shift if this is a date/time tag
     1020            }
     1021            ($dstGrp, $dstTag) = ($1, $2) if $dstTag =~ /(.*):(.+)/;
     1022            # ValueConv may be specified separately on the destination with '#'
     1023            $$opts{Type} = 'ValueConv' if $dstTag =~ s/#$//;
    8981024            # ignore leading family number
    8991025            $dstGrp = $2 if $dstGrp =~ /^(\d+)(.*)/ and $1 < 2;
    900         }
    901         $tag =~ s/\ball\b/\*/g unless $expr; # replace 'all' with '*'
    902         my $isExclude = ($tag =~ s/^-//);
    903         if ($tag =~ /^([\w-]+?|\*):(.+)/) {
    904             ($grp, $tag) = ($1, $2);
    905             # separate leading family number
    906             ($fam, $grp) = ($1, $2) if $grp =~ /^(\d+)(.+)/ and $1 < 2;
    907         } else {
    908             $grp = '';  # flag for don't care about group
     1026            # replace 'all' with '*' in tag and group names
     1027            $dstTag = '*' if $dstTag eq 'all';
     1028            $dstGrp = '*' if $dstGrp eq 'all';
     1029        }
     1030        unless ($$opts{EXPR}) {
     1031            $isExclude = ($tag =~ s/^-//);
     1032            if ($tag =~ /^([-\w]*?|\*):(.+)/) {
     1033                ($grp, $tag) = ($1, $2);
     1034                # separate leading family number
     1035                ($fam, $grp) = ($1, $2) if $grp =~ /^(\d+)(.*)/;
     1036            } else {
     1037                $grp = '';  # flag for don't care about group
     1038            }
     1039            # allow ValueConv to be specified by a '#' on the tag name
     1040            if ($tag =~ s/#$//) {
     1041                $$opts{SrcType} = 'ValueConv';
     1042                $$opts{Type} = 'ValueConv' unless $dstTag;
     1043            }
     1044            # replace 'all' with '*' in tag and group names
     1045            $tag = '*' if $tag eq 'all';
     1046            $grp = '*' if $grp eq 'all';
     1047            # allow wildcards in tag names
     1048            if ($tag =~ /[?*]/ and $tag ne '*') {
     1049                $$opts{WILD} = 1;   # set flag indicating wildcards were used
     1050                $tag =~ s/\*/[-\\w]*/g;
     1051                $tag =~ s/\?/[-\\w]/g;
     1052            }
    9091053        }
    9101054        # redirect, exclude or set this tag (Note: $grp is '' if we don't care)
     
    9121056            # redirect this tag
    9131057            $isExclude and return { Error => "Can't redirect excluded tag" };
    914             if ($tag eq '*' and $dstTag ne '*') {
    915                 return { Error => "Can't redirect from all tags to one tag" };
     1058            if ($dstTag ne '*') {
     1059                if ($dstTag =~ /[?*]/) {
     1060                    if ($dstTag eq $tag) {
     1061                        $dstTag = '*';
     1062                    } else {
     1063                        return { Error => "Invalid use of wildcards in destination tag" };
     1064                    }
     1065                } elsif ($tag eq '*') {
     1066                    return { Error => "Can't redirect from all tags to one tag" };
     1067                }
    9161068            }
    9171069            # set destination group the same as source if necessary
    918             $dstGrp = $grp if $dstGrp eq '*' and $grp;
     1070          # (removed in 7.72 so '-xmp:*>*:*' will preserve XMP family 1 groups)
     1071          # $dstGrp = $grp if $dstGrp eq '*' and $grp;
    9191072            # write to specified destination group/tag
    9201073            $dst = [ $dstGrp, $dstTag ];
    9211074        } elsif ($isExclude) {
    9221075            # implicitly assume '*' if first entry is an exclusion
    923             unshift @setList, [ undef, '*', '*', [ '', '*' ] ] unless @setList;
     1076            unshift @setList, [ undef, '*', '*', [ '', '*' ], $opts ] unless @setList;
    9241077            # exclude this tag by leaving $dst undefined
    9251078        } else {
    926             # copy to same group/tag
    927             $dst = [ $grp, $tag ];
     1079            $dst = [ $grp, $$opts{WILD} ? '*' : $tag ]; # copy to same group
    9281080        }
    9291081        $grp or $grp = '*';     # use '*' for any group
    9301082        # save in reverse order so we don't set tags before an exclude
    931         unshift @setList, [ $fam, $grp, $tag, $dst, $opt ];
    932     }
    933     # 2) initialize lists of matching tags for each condition
     1083        unshift @setList, [ $fam, $grp, $tag, $dst, $opts ];
     1084    }
     1085    # 2) initialize lists of matching tags for each setTag
    9341086    foreach $set (@setList) {
    935         $$set[3] and $setMatches{$$set[3]} = [ ];
    936     }
    937     # 3) loop through all tags in source image and save tags matching each condition
     1087        $$set[3] and $setMatches{$set} = [ ];
     1088    }
     1089    # 3) loop through all tags in source image and save tags matching each setTag
    9381090    my %rtnInfo;
    9391091    foreach $tag (@tags) {
    940         # don't try to set Warning's or Error's
    941         if ($tag =~ /^Warning\b/ or $tag =~ /^Error\b/) {
    942             $rtnInfo{$tag} = $info->{$tag};
     1092        # don't try to set errors or warnings
     1093        if ($tag =~ /^(Error|Warning)( |$)/) {
     1094            $rtnInfo{$tag} = $$info{$tag};
    9431095            next;
    9441096        }
    945         my @dstList;
    9461097        # only set specified tags
    9471098        my $lcTag = lc(GetTagName($tag));
    948         my @grp;
     1099        my (@grp, %grp);
    9491100        foreach $set (@setList) {
    9501101            # check first for matching tag
    951             next unless $$set[2] eq $lcTag or $$set[2] eq '*';
     1102            unless ($$set[2] eq $lcTag or $$set[2] eq '*') {
     1103                # handle wildcards
     1104                next unless $$set[4]{WILD} and $lcTag =~ /^$$set[2]$/;
     1105            }
    9521106            # then check for matching group
    9531107            unless ($$set[1] eq '*') {
    9541108                # get lower case group names if not done already
    955                 @grp or @grp = map(lc, $srcExifTool->GetGroup($tag));
     1109                unless (@grp) {
     1110                    @grp = map(lc, $srcExifTool->GetGroup($tag));
     1111                    $grp{$_} = 1 foreach @grp;
     1112                }
    9561113                # handle leading family number
    9571114                if (defined $$set[0]) {
    958                     next unless $$set[1] eq $grp[$$set[0]];
     1115                    next unless $grp[$$set[0]] and $$set[1] eq $grp[$$set[0]];
    9591116                } else {
    960                     next unless $$set[1] eq $grp[0] or $$set[1] eq $grp[1];
     1117                    next unless $grp{$$set[1]};
    9611118                }
    9621119            }
    9631120            last unless $$set[3];   # all done if we hit an exclude
    964             # add to the list of tags matching this condition
     1121            # add to the list of tags matching this setTag
    9651122            push @{$setMatches{$set}}, $tag;
    9661123        }
    9671124    }
    968     # 4) loop through each condition in original order, setting new tag values
     1125    # 4) loop through each setTag in original order, setting new tag values
    9691126    foreach $set (reverse @setList) {
     1127        # get options for SetNewValue
     1128        my $opts = $$set[4];
    9701129        # handle expressions
    971         if ($$set[2] =~ s/^\@//) {
     1130        if ($$opts{EXPR}) {
    9721131            my $val = $srcExifTool->InsertTagValues(\@tags, $$set[2], 'Error');
    9731132            unless (defined $val) {
     
    9751134                $tag = NextTagKey(\%rtnInfo, 'Warning');
    9761135                $rtnInfo{$tag} = $srcExifTool->GetValue('Error');
    977                 delete $srcExifTool->{VALUE}->{Error};
     1136                delete $srcExifTool->{VALUE}{Error};
    9781137                next;
    9791138            }
    9801139            my ($dstGrp, $dstTag) = @{$$set[3]};
    981             my %opts = ( Protected => 1, Replace => 1 );
    982             # add or delete value if specified
    983             $opts{$$set[4]} = 1 if $$set[4];
    984             $opts{Group} = $dstGrp if $dstGrp;
    985             my @rtnVals = $self->SetNewValue($dstTag, $val, %opts);
     1140            $$opts{Protected} = 1;
     1141            $$opts{Group} = $dstGrp if $dstGrp;
     1142            my @rtnVals = $self->SetNewValue($dstTag, $val, %$opts);
    9861143            $rtnInfo{$dstTag} = $val if $rtnVals[0]; # tag was set successfully
    9871144            next;
    9881145        }
    9891146        foreach $tag (@{$setMatches{$set}}) {
    990             my (@values, %opts, $val, $noWarn);
    991             # get all values for this tag
    992             if (ref $info->{$tag} eq 'ARRAY') {
    993                 @values = @{$info->{$tag}};
    994             } elsif (ref $info->{$tag} eq 'SCALAR') {
    995                 @values = ( ${$info->{$tag}} );
     1147            my ($val, $noWarn);
     1148            if ($$opts{SrcType} and $$opts{SrcType} ne $srcType) {
     1149                $val = $srcExifTool->GetValue($tag, $$opts{SrcType});
    9961150            } else {
    997                 @values = ( $info->{$tag} );
     1151                $val = $$info{$tag};
    9981152            }
    9991153            my ($dstGrp, $dstTag) = @{$$set[3]};
     
    10031157                    $noWarn = 1;    # don't warn on wildcard destinations
    10041158                }
    1005                 $opts{Group} = $dstGrp;
     1159                $$opts{Group} = $dstGrp;
     1160            } else {
     1161                delete $$opts{Group};
    10061162            }
    10071163            # transfer maker note information if setting this tag
    1008             if ($srcExifTool->{TAG_INFO}->{$tag}->{MakerNotes}) {
     1164            if ($srcExifTool->{TAG_INFO}{$tag}{MakerNotes}) {
    10091165                $self->{MAKER_NOTE_FIXUP} = $srcExifTool->{MAKER_NOTE_FIXUP};
    10101166                $self->{MAKER_NOTE_BYTE_ORDER} = $srcExifTool->{MAKER_NOTE_BYTE_ORDER};
     
    10141170                $noWarn = 1;
    10151171            }
    1016             # add or delete value if specified
    1017             $opts{$$set[4]} = 1 if $$set[4];
    10181172            # allow protected tags to be copied if specified explicitly
    1019             $opts{Protected} = 1 unless $$set[2] eq '*';
    1020             $opts{Replace} = 1;     # replace the first value found
    1021             # set all values for this tag
    1022             foreach $val (@values) {
    1023                 my ($rtn, $wrn) = $self->SetNewValue($dstTag, $val, %opts);
    1024                 if ($wrn and not $noWarn) {
    1025                     # return this warning
    1026                     $rtnInfo{NextTagKey(\%rtnInfo, 'Warning')} = $wrn;
    1027                     $noWarn = 1;
    1028                 }
    1029                 last unless $rtn;
    1030                 $rtnInfo{$tag} = $info->{$tag}; # tag was set successfully
    1031                 $opts{Replace} = 0;
    1032             }
     1173            $$opts{Protected} = ($$set[2] eq '*' ? undef : 1);
     1174            # set value(s) for this tag
     1175            my ($rtn, $wrn) = $self->SetNewValue($dstTag, $val, %$opts);
     1176            if ($wrn and not $noWarn) {
     1177                # return this warning
     1178                $rtnInfo{NextTagKey(\%rtnInfo, 'Warning')} = $wrn;
     1179                $noWarn = 1;
     1180            }
     1181            $rtnInfo{$tag} = $val if $rtn;  # tag was set successfully
    10331182        }
    10341183    }
     
    10381187#------------------------------------------------------------------------------
    10391188# Get new value(s) for tag
    1040 # Inputs: 0) ExifTool object reference, 1) tag key, tag name, or tagInfo hash ref
     1189# Inputs: 0) ExifTool object reference, 1) tag name or tagInfo hash ref
    10411190#         2) optional pointer to return new value hash reference (not part of public API)
    10421191#    or   0) new value hash reference (not part of public API)
     
    10441193# Notes: 1) Preferentially returns new value from Extra table if writable Extra tag exists
    10451194# 2) Must call AFTER IsOverwriting() returns 1 to get proper value for shifted times
     1195# 3) Tag name is case sensitive and may be prefixed by family 0 or 1 group name
    10461196sub GetNewValues($;$$)
    10471197{
    10481198    local $_;
    1049     my $newValueHash;
     1199    my $nvHash;
    10501200    if (ref $_[0] eq 'HASH') {
    1051         $newValueHash = shift;
     1201        $nvHash = shift;
    10521202    } else {
    10531203        my ($self, $tag, $newValueHashPt) = @_;
    10541204        if ($self->{NEW_VALUE}) {
    1055             my $tagInfo;
     1205            my ($group, $tagInfo);
    10561206            if (ref $tag) {
    1057                 $newValueHash = $self->GetNewValueHash($tag);
     1207                $nvHash = $self->GetNewValueHash($tag);
    10581208            } elsif (defined($tagInfo = $Image::ExifTool::Extra{$tag}) and
    10591209                     $$tagInfo{Writable})
    10601210            {
    1061                 $newValueHash = $self->GetNewValueHash($tagInfo);
     1211                $nvHash = $self->GetNewValueHash($tagInfo);
    10621212            } else {
     1213                # separate group from tag name
     1214                $group = $1 if $tag =~ s/(.*)://;
    10631215                my @tagInfoList = FindTagInfo($tag);
    1064                 # choose the one that we are creating
    1065                 foreach $tagInfo (@tagInfoList) {
     1216                # decide which tag we want
     1217GNV_TagInfo:    foreach $tagInfo (@tagInfoList) {
    10661218                    my $nvh = $self->GetNewValueHash($tagInfo) or next;
    1067                     $newValueHash = $nvh;
    1068                     last if defined $newValueHash->{IsCreating};
     1219                    # select tag in specified group if necessary
     1220                    while ($group and $group ne $$nvh{WriteGroup}) {
     1221                        my @grps = $self->GetGroup($tagInfo);
     1222                        if ($grps[0] eq $$nvh{WriteGroup}) {
     1223                            # check family 1 group only if WriteGroup is not specific
     1224                            last if $group eq $grps[1];
     1225                        } else {
     1226                            # otherwise check family 0 group
     1227                            last if $group eq $grps[0];
     1228                        }
     1229                        # step to next entry in list
     1230                        $nvh = $$nvh{Next} or next GNV_TagInfo;
     1231                    }
     1232                    $nvHash = $nvh;
     1233                    # give priority to the one we are creating
     1234                    last if defined $nvHash->{IsCreating};
    10691235                }
    10701236            }
    10711237        }
    10721238        # return new value hash if requested
    1073         $newValueHashPt and $$newValueHashPt = $newValueHash;
    1074     }
    1075     if ($newValueHash and $newValueHash->{Value}) {
    1076         my $vals = $newValueHash->{Value};
     1239        $newValueHashPt and $$newValueHashPt = $nvHash;
     1240    }
     1241    if ($nvHash and $nvHash->{Value}) {
     1242        my $vals = $nvHash->{Value};
    10771243        # do inverse raw conversion if necessary
    1078         if ($newValueHash->{TagInfo}->{RawConvInv}) {
    1079             my $tagInfo = $$newValueHash{TagInfo};
     1244        if ($nvHash->{TagInfo}{RawConvInv}) {
     1245            my @copyVals = @$vals;  # modify a copy of the values
     1246            $vals = \@copyVals;
     1247            my $tagInfo = $$nvHash{TagInfo};
    10801248            my $conv = $$tagInfo{RawConvInv};
    1081             my $self = $newValueHash->{Self};
     1249            my $self = $nvHash->{Self};
    10821250            my ($val, $checkProc);
    10831251            my $table = $tagInfo->{Table};
     
    10891257                    $val = &$conv($val, $self);
    10901258                } else {
    1091                     #### eval RawConvInv ($self, $val)
     1259                    #### eval RawConvInv ($self, $val, $taginfo)
    10921260                    $val = eval $conv;
    10931261                    $@ and $evalWarning = $@;
    10941262                }
    10951263                if ($evalWarning) {
    1096                     my $err = CleanWarning() . " in $$tagInfo{Name} (RawConvInv)";
    1097                     $self->Warn($err);
     1264                    # an empty warning ("\n") ignores tag with no error
     1265                    if ($evalWarning ne "\n") {
     1266                        my $err = CleanWarning() . " in $$tagInfo{Name} (RawConvInv)";
     1267                        $self->Warn($err);
     1268                    }
    10981269                    @$vals = ();
    10991270                    last;
     
    11111282        }
    11121283        # return our value(s)
    1113         if (wantarray) {
    1114             return @$vals;
    1115         } else {
    1116             return $$vals[0];
    1117         }
     1284        return @$vals if wantarray;
     1285        return $$vals[0];
    11181286    }
    11191287    return () if wantarray;  # return empty list
     
    11321300    my $newVal = $self->{NEW_VALUE};
    11331301    my $num = 0;
    1134     $num += scalar keys %$newVal if $newVal;
     1302    my $tag;
     1303    if ($newVal) {
     1304        $num += scalar keys %$newVal;
     1305        # don't count "fake" tags (only in Extra table)
     1306        foreach $tag (qw{Geotag Geosync}) {
     1307            --$num if defined $$newVal{$Image::ExifTool::Extra{$tag}};
     1308        }
     1309    }
    11351310    $num += scalar keys %{$self->{DEL_GROUP}};
    11361311    return $num unless wantarray;
    11371312    my $pseudo = 0;
    11381313    if ($newVal) {
    1139         my $tag;
    1140         # (Note: all "pseudo" tags must be found in Extra table)
     1314        # (Note: all writable "pseudo" tags must be found in Extra table)
    11411315        foreach $tag (qw{FileName Directory FileModifyDate}) {
    11421316            ++$pseudo if defined $$newVal{$Image::ExifTool::Extra{$tag}};
     
    11551329    my $key;
    11561330    foreach $key (keys %$newValues) {
    1157         my $newValueHash = $$newValues{$key};
    1158         while ($newValueHash) {
    1159             $newValueHash->{Save} = 1;  # set Save flag
    1160             $newValueHash = $newValueHash->{Next};
     1331        my $nvHash = $$newValues{$key};
     1332        while ($nvHash) {
     1333            $nvHash->{Save} = 1;  # set Save flag
     1334            $nvHash = $nvHash->{Next};
    11611335        }
    11621336    }
    11631337    # initialize hash for saving overwritten new values
    11641338    $self->{SAVE_NEW_VALUE} = { };
     1339    # make a copy of the delete group hash
     1340    if ($self->{DEL_GROUP}) {
     1341        my %delGrp = %{$self->{DEL_GROUP}};
     1342        $self->{SAVE_DEL_GROUP} = \%delGrp;
     1343    } else {
     1344        delete $self->{SAVE_DEL_GROUP};
     1345    }
    11651346}
    11661347
     
    11691350# Inputs: 0) ExifTool object reference
    11701351# Notes: Restores saved new values, but currently doesn't restore them in the
    1171 # orginal order, so there may be some minor side-effects when restoring tags
     1352# original order, so there may be some minor side-effects when restoring tags
    11721353# with overlapping groups. ie) XMP:Identifier, XMP-dc:Identifier
    11731354sub RestoreNewValues($)
     
    11821363        foreach $key (@keys) {
    11831364            my $lastHash;
    1184             my $newValueHash = $$newValues{$key};
    1185             while ($newValueHash) {
    1186                 if ($newValueHash->{Save}) {
    1187                     $lastHash = $newValueHash;
     1365            my $nvHash = $$newValues{$key};
     1366            while ($nvHash) {
     1367                if ($nvHash->{Save}) {
     1368                    $lastHash = $nvHash;
    11881369                } else {
    11891370                    # remove this entry from the list
    11901371                    if ($lastHash) {
    1191                         $lastHash->{Next} = $newValueHash->{Next};
    1192                     } elsif ($newValueHash->{Next}) {
    1193                         $$newValues{$key} = $newValueHash->{Next};
     1372                        $lastHash->{Next} = $nvHash->{Next};
     1373                    } elsif ($nvHash->{Next}) {
     1374                        $$newValues{$key} = $nvHash->{Next};
    11941375                    } else {
    11951376                        delete $$newValues{$key};
    11961377                    }
    11971378                }
    1198                 $newValueHash = $newValueHash->{Next};
     1379                $nvHash = $nvHash->{Next};
    11991380            }
    12001381        }
     
    12061387            if ($$newValues{$key}) {
    12071388                # add saved values to end of list
    1208                 my $newValueHash = LastInList($$newValues{$key});
    1209                 $newValueHash->{Next} = $$savedValues{$key};
     1389                my $nvHash = LastInList($$newValues{$key});
     1390                $nvHash->{Next} = $$savedValues{$key};
    12101391            } else {
    12111392                $$newValues{$key} = $$savedValues{$key};
     
    12131394        }
    12141395        $self->{SAVE_NEW_VALUE} = { };  # reset saved new values
     1396    }
     1397    # 3) restore delete groups
     1398    if ($self->{SAVE_DEL_GROUP}) {
     1399        my %delGrp = %{$self->{SAVE_DEL_GROUP}};
     1400        $self->{DEL_GROUP} = \%delGrp;
     1401    } else {
     1402        delete $self->{DEL_GROUP};
    12151403    }
    12161404}
     
    12251413{
    12261414    my ($self, $file, $originalTime) = @_;
    1227     my $newValueHash;
    1228     my $val = $self->GetNewValues('FileModifyDate', \$newValueHash);
     1415    my $nvHash;
     1416    my $val = $self->GetNewValues('FileModifyDate', \$nvHash);
    12291417    return 0 unless defined $val;
    1230     my $isOverwriting = IsOverwriting($newValueHash);
     1418    my $isOverwriting = IsOverwriting($nvHash);
    12311419    return 0 unless $isOverwriting;
    12321420    if ($isOverwriting < 0) {  # are we shifting time?
     
    12341422        $originalTime = -M $file unless defined $originalTime;
    12351423        return 0 unless defined $originalTime;
    1236         return 0 unless IsOverwriting($newValueHash, $^T - $originalTime*(24*3600));
    1237         $val = $newValueHash->{Value}->[0]; # get shifted value
     1424        return 0 unless IsOverwriting($nvHash, $^T - $originalTime*(24*3600));
     1425        $val = $nvHash->{Value}[0]; # get shifted value
    12381426    }
    12391427    unless (utime($val, $val, $file)) {
     
    12421430    }
    12431431    ++$self->{CHANGED};
    1244     $self->VPrint(1, "    + FileModifyDate = '$val'\n");
     1432    $self->VerboseValue('+ FileModifyDate', $val);
    12451433    return 1;
    12461434}
     
    12561444{
    12571445    my ($self, $file, $newName) = @_;
    1258     my ($newValueHash, $doName, $doDir);
     1446    my ($nvHash, $doName, $doDir);
    12591447    # determine the new file name
    12601448    unless (defined $newName) {
    1261         my $filename = $self->GetNewValues('FileName', \$newValueHash);
    1262         $doName = 1 if defined $filename and IsOverwriting($newValueHash, $file);
    1263         my $dir = $self->GetNewValues('Directory', \$newValueHash);
    1264         $doDir = 1 if defined $dir and IsOverwriting($newValueHash, $file);
     1449        my $filename = $self->GetNewValues('FileName', \$nvHash);
     1450        $doName = 1 if defined $filename and IsOverwriting($nvHash, $file);
     1451        my $dir = $self->GetNewValues('Directory', \$nvHash);
     1452        $doDir = 1 if defined $dir and IsOverwriting($nvHash, $file);
    12651453        return 0 unless $doName or $doDir;  # nothing to do
    12661454        if ($doName) {
     
    12871475    # attempt to rename the file
    12881476    unless (rename $file, $newName) {
     1477        local (*EXIFTOOL_SFN_IN, *EXIFTOOL_SFN_OUT);
    12891478        # renaming didn't work, so copy the file instead
    12901479        unless (open EXIFTOOL_SFN_IN, $file) {
     
    13181507    }
    13191508    ++$self->{CHANGED};
    1320     $self->VPrint(1, "    + FileName = '$newName'\n");
     1509    $self->VerboseValue('+ FileName', $newName);
    13211510    return 1;
    13221511}
     
    13261515# Inputs: 0) ExifTool object reference,
    13271516#         1) input filename, file ref, or scalar ref (or '' or undef to create from scratch)
    1328 #         2) output filename, file ref, or scalar ref (or undef to edit in place)
     1517#         2) output filename, file ref, or scalar ref (or undef to overwrite)
    13291518#         3) optional output file type (required only if input file is not specified
    13301519#            and output file is a reference)
     
    13321521sub WriteInfo($$;$$)
    13331522{
    1334     local $_;
     1523    local ($_, *EXIFTOOL_FILE2, *EXIFTOOL_OUTFILE);
    13351524    my ($self, $infile, $outfile, $outType) = @_;
    1336     my (@fileTypeList, $fileType, $tiffType);
     1525    my (@fileTypeList, $fileType, $tiffType, $hdr, $seekErr, $type, $tmpfile);
    13371526    my ($inRef, $outRef, $closeIn, $closeOut, $outPos, $outBuff, $eraseIn);
    13381527    my $oldRaf = $self->{RAF};
    1339     my $rtnVal = 1;
     1528    my $rtnVal = 0;
    13401529
    13411530    # initialize member variables
     
    13441533    # first, save original file modify date if necessary
    13451534    # (do this now in case we are modifying file in place and shifting date)
    1346     my ($newValueHash, $originalTime);
    1347     my $fileModifyDate =  $self->GetNewValues('FileModifyDate', \$newValueHash);
    1348     if (defined $fileModifyDate and IsOverwriting($newValueHash) < 0 and
     1535    my ($nvHash, $originalTime);
     1536    my $fileModifyDate =  $self->GetNewValues('FileModifyDate', \$nvHash);
     1537    if (defined $fileModifyDate and IsOverwriting($nvHash) < 0 and
    13491538        defined $infile and ref $infile ne 'SCALAR')
    13501539    {
     
    13541543# do quick in-place change of file dir/name or date if that is all we are doing
    13551544#
     1545    my ($numNew, $numPseudo) = $self->CountNewValues();
    13561546    if (not defined $outfile and defined $infile) {
    1357         my $newFileName =  $self->GetNewValues('FileName', \$newValueHash);
    1358         my ($numNew, $numPseudo) = $self->CountNewValues();
     1547        my $newFileName =  $self->GetNewValues('FileName', \$nvHash);
    13591548        if ($numNew == $numPseudo) {
    13601549            $rtnVal = 2;
     
    13721561                $outfile = $newFileName;
    13731562                # can't delete original
    1374             } elsif (IsOverwriting($newValueHash, $infile)) {
     1563            } elsif (IsOverwriting($nvHash, $infile)) {
    13751564                $outfile = GetNewFileName($infile, $newFileName);
    1376                 $eraseIn = 1; # delete original               
     1565                $eraseIn = 1; # delete original
    13771566            }
    13781567        }
     
    13851574        if (UNIVERSAL::isa($inRef,'GLOB')) {
    13861575            seek($inRef, 0, 0); # make sure we are at the start of the file
    1387         } elsif (eval 'require Encode; Encode::is_utf8($$inRef)') {
     1576        } elsif ($] >= 5.006 and (eval 'require Encode; Encode::is_utf8($$inRef)' or $@)) {
    13881577            # convert image data from UTF-8 to character stream if necessary
     1578            my $buff = $@ ? pack('C*',unpack('U0C*',$$inRef)) : Encode::encode('utf8',$$inRef);
    13891579            if (defined $outfile) {
    1390                 my $buff = pack('C*', unpack('U0U*', $$inRef));
    13911580                $inRef = \$buff;
    13921581            } else {
    1393                 $$inRef = pack('C*', unpack('U0U*', $$inRef));
     1582                $$inRef = $buff;
    13941583            }
    13951584        }
    13961585    } elsif (defined $infile and $infile ne '') {
    1397         if (open(EXIFTOOL_FILE2, defined $outfile ? $infile : "+<$infile")) {
     1586        # write to a temporary file if no output file given
     1587        $outfile = $tmpfile = "${infile}_exiftool_tmp" unless defined $outfile;
     1588        if (open(EXIFTOOL_FILE2, $infile)) {
    13981589            $fileType = GetFileType($infile);
    1399             $tiffType = GetFileExtension($infile);
     1590            @fileTypeList = GetFileType($infile);
     1591            $tiffType = $$self{FILE_EXT} = GetFileExtension($infile);
    14001592            $self->VPrint(0, "Rewriting $infile...\n");
    14011593            $inRef = \*EXIFTOOL_FILE2;
    14021594            $closeIn = 1;   # we must close the file since we opened it
    14031595        } else {
    1404             my $forUpdate = (defined $outfile ? '' : ' for update');
    1405             $self->Error("Error opening file$forUpdate");
     1596            $self->Error('Error opening file');
    14061597            return 0;
    14071598        }
     
    14111602    } else {
    14121603        # create file from scratch
    1413         $outType = GetFileType($outfile) unless $outType or ref $outfile;
     1604        $outType = GetFileExtension($outfile) unless $outType or ref $outfile;
    14141605        if (CanCreate($outType)) {
    14151606            $fileType = $tiffType = $outType;   # use output file type if no input file
     
    14251616        }
    14261617    }
    1427     if ($fileType) {
    1428         @fileTypeList = ( $fileType );
    1429     } else {
    1430         @fileTypeList = @fileTypes;
    1431         $tiffType = 'TIFF';
     1618    unless (@fileTypeList) {
     1619        if ($fileType) {
     1620            @fileTypeList = ( $fileType );
     1621        } else {
     1622            @fileTypeList = @fileTypes;
     1623            $tiffType = 'TIFF';
     1624        }
    14321625    }
    14331626#
     
    14461639    } elsif (not defined $outfile) {
    14471640        # editing in place, so write to memory first
     1641        # (only when infile is a file ref or scalar ref)
    14481642        $outBuff = '';
    14491643        $outRef = \$outBuff;
     
    14511645    } elsif (-e $outfile) {
    14521646        $self->Error("File already exists: $outfile");
    1453         $rtnVal = 0;
    14541647    } elsif (open(EXIFTOOL_OUTFILE, ">$outfile")) {
    14551648        $outRef = \*EXIFTOOL_OUTFILE;
     
    14581651        $outPos = 0;
    14591652    } else {
    1460         $self->Error("Error creating file: $outfile");
    1461         $rtnVal = 0;
     1653        my $tmp = $tmpfile ? ' temporary' : '';
     1654        $self->Error("Error creating$tmp file: $outfile");
    14621655    }
    14631656#
    14641657# write the file
    14651658#
    1466     if ($rtnVal) {
    1467         # create random access file object
    1468         my $raf = new File::RandomAccess($inRef);
    1469         # patch for Windows command shell pipe
    1470         $raf->{TESTED} = -1 if not ref $infile and ($infile eq '-' or $infile =~ /\|$/);
     1659    until ($self->{VALUE}{Error}) {
     1660        # create random access file object (disable seek test in case of straight copy)
     1661        my $raf = new File::RandomAccess($inRef, 1);
     1662        $raf->BinMode();
     1663        if ($numNew == $numPseudo) {
     1664            $rtnVal = 1;
     1665            # just do a straight copy of the file (no "real" tags are being changed)
     1666            my $buff;
     1667            while ($raf->Read($buff, 65536)) {
     1668                Write($outRef, $buff) or $rtnVal = -1, last;
     1669            }
     1670            last;
     1671        } elsif (not ref $infile and ($infile eq '-' or $infile =~ /\|$/)) {
     1672            # patch for Windows command shell pipe
     1673            $raf->{TESTED} = -1;    # force buffering
     1674        } else {
     1675            $raf->SeekTest();
     1676        }
    14711677       # $raf->Debug() and warn "  RAF debugging enabled!\n";
    14721678        my $inPos = $raf->Tell();
    1473         $raf->BinMode();
    14741679        $self->{RAF} = $raf;
    14751680        my %dirInfo = (
     
    14771682            OutFile => $outRef,
    14781683        );
    1479         for (;;) {
    1480             my $type = shift @fileTypeList;
     1684        $raf->Read($hdr, 1024) or $hdr = '';
     1685        $raf->Seek($inPos, 0) or $seekErr = 1;
     1686        my $wrongType;
     1687        until ($seekErr) {
     1688            $type = shift @fileTypeList;
     1689            # do quick test to see if this is the right file type
     1690            if ($magicNumber{$type} and length($hdr) and $hdr !~ /^$magicNumber{$type}/s) {
     1691                next if @fileTypeList;
     1692                $wrongType = 1;
     1693                last;
     1694            }
    14811695            # save file type in member variable
    1482             $dirInfo{Parent} = $self->{FILE_TYPE} = $type;
     1696            $dirInfo{Parent} = $self->{FILE_TYPE} = $self->{PATH}[0] = $type;
    14831697            # determine which directories we must write for this file type
    14841698            $self->InitWriteDirs($type);
     
    14871701            } elsif ($type eq 'TIFF') {
    14881702                # disallow writing of some TIFF-based RAW images:
    1489                 if ($tiffType =~ /^(SRF|SR2|ARW|RAW|DCR|K25)$/) {
     1703                if (grep /^$tiffType$/, @{$noWriteFile{TIFF}}) {
    14901704                    $fileType = $tiffType;
    14911705                    undef $rtnVal;
     
    15031717                require Image::ExifTool::MinoltaRaw;
    15041718                $rtnVal = Image::ExifTool::MinoltaRaw::ProcessMRW($self, \%dirInfo);
    1505             } elsif ($type eq 'ORF') {
     1719            } elsif ($type eq 'RAF') {
     1720                require Image::ExifTool::FujiFilm;
     1721                $rtnVal = Image::ExifTool::FujiFilm::WriteRAF($self, \%dirInfo);
     1722            } elsif ($type eq 'ORF' or $type eq 'RAW') {
    15061723                $rtnVal = $self->ProcessTIFF(\%dirInfo);
     1724            } elsif ($type eq 'X3F') {
     1725                require Image::ExifTool::SigmaRaw;
     1726                $rtnVal = Image::ExifTool::SigmaRaw::ProcessX3F($self, \%dirInfo);
    15071727            } elsif ($type eq 'PNG') {
    15081728                require Image::ExifTool::PNG;
     
    15231743                require Image::ExifTool::PostScript;
    15241744                $rtnVal = Image::ExifTool::PostScript::WritePS($self, \%dirInfo);
     1745            } elsif ($type eq 'PDF') {
     1746                require Image::ExifTool::PDF;
     1747                $rtnVal = Image::ExifTool::PDF::WritePDF($self, \%dirInfo);
    15251748            } elsif ($type eq 'ICC') {
    15261749                require Image::ExifTool::ICC_Profile;
     
    15321755                require Image::ExifTool::Jpeg2000;
    15331756                $rtnVal = Image::ExifTool::Jpeg2000::ProcessJP2($self, \%dirInfo);
    1534             } elsif ($type eq 'RAW') {
    1535                 $rtnVal = $self->ProcessTIFF(\%dirInfo);
     1757            } elsif ($type eq 'IND') {
     1758                require Image::ExifTool::InDesign;
     1759                $rtnVal = Image::ExifTool::InDesign::ProcessIND($self, \%dirInfo);
     1760            } elsif ($type eq 'EXIF') {
     1761                # go through WriteDirectory so block writes, etc are handled
     1762                my $tagTablePtr = GetTagTable('Image::ExifTool::Exif::Main');
     1763                my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr, \&WriteTIFF);
     1764                if (defined $buff) {
     1765                    $rtnVal = Write($outRef, $buff) ? 1 : -1;
     1766                } else {
     1767                    $rtnVal = 0;
     1768                }
    15361769            } else {
    15371770                undef $rtnVal;  # flag that we don't write this type of file
     
    15411774            last unless @fileTypeList;
    15421775            # seek back to original position in files for next try
    1543             unless ($raf->Seek($inPos, 0)) {
    1544                 $self->Error('Error seeking in file');
    1545                 last;
    1546             }
     1776            $raf->Seek($inPos, 0) or $seekErr = 1, last;
    15471777            if (UNIVERSAL::isa($outRef,'GLOB')) {
    15481778                seek($outRef, 0, $outPos);
     
    15531783        # print file format errors
    15541784        unless ($rtnVal) {
    1555             if ($fileType and defined $rtnVal) {
    1556                 $self->{VALUE}->{Error} or $self->Error('Format error in file');
     1785            my $err;
     1786            if ($seekErr) {
     1787                $err = 'Error seeking in file';
     1788            } elsif ($fileType and defined $rtnVal) {
     1789                if ($self->{VALUE}{Error}) {
     1790                    # existing error message will do
     1791                } elsif ($fileType eq 'RAW') {
     1792                    $err = 'Writing this type of RAW file is not supported';
     1793                } else {
     1794                    if ($wrongType) {
     1795                        $err = "Not a valid $fileType";
     1796                        # do a quick check to see what this file looks like
     1797                        foreach $type (@fileTypes) {
     1798                            next unless $magicNumber{$type};
     1799                            next unless $hdr =~ /^$magicNumber{$type}/s;
     1800                            $err .= " (looks more like a $type)";
     1801                            last;
     1802                        }
     1803                    } else {
     1804                        $err = 'Format error in file';
     1805                    }
     1806                }
    15571807            } elsif ($fileType) {
    1558                 $self->Error("ExifTool does not yet support writing of $fileType files");
     1808                # get specific type of file from extension
     1809                $fileType = GetFileExtension($infile) if $infile and GetFileType($infile);
     1810                $err = "Writing of $fileType files is not yet supported";
    15591811            } else {
    1560                 $self->Error('ExifTool does not support writing of this type of file');
    1561             }
    1562             $rtnVal = 0;
    1563         }
    1564        # $raf->Close(); # only used to force debug output
     1812                $err = 'Writing of this type of file is not supported';
     1813            }
     1814            $self->Error($err) if $err;
     1815            $rtnVal = 0;    # (in case it was undef)
     1816        }
     1817       # $raf->Close();  # only used to force debug output
     1818        last;   # (didn't really want to loop)
    15651819    }
    15661820    # don't return success code if any error occurred
    1567     $rtnVal = 0 if $rtnVal > 0 and $self->{VALUE}->{Error};
     1821    if ($rtnVal > 0) {
     1822        unless (Tell($outRef) or $self->{VALUE}{Error}) {
     1823            # don't write a file with zero length
     1824            if (defined $hdr and length $hdr) {
     1825                $self->Error("Can't delete all meta information from $type file");
     1826            } else {
     1827                $self->Error('Nothing to write');
     1828            }
     1829        }
     1830        $rtnVal = 0 if $self->{VALUE}{Error};
     1831    }
    15681832
    15691833    # rewrite original file in place if required
     
    15901854        # errors on input file are significant if we edited the file in place
    15911855        $rtnVal and $rtnVal = -1 unless close($inRef) or not defined $outBuff;
    1592         if ($eraseIn and $rtnVal > 0) {
     1856        if ($rtnVal > 0) {
     1857            # copy Mac OS resource fork if it exists
     1858            if ($^O eq 'darwin' and -s "$infile/rsrc") {
     1859                if ($$self{DEL_GROUP} and $$self{DEL_GROUP}{RSRC}) {
     1860                    $self->VPrint(0,"Deleting Mac OS resource fork\n");
     1861                    ++$$self{CHANGED};
     1862                } else {
     1863                    $self->VPrint(0,"Copying Mac OS resource fork\n");
     1864                    my ($buf, $err);
     1865                    local (*SRC, *DST);
     1866                    if (open SRC, "$infile/rsrc") {
     1867                        if (open DST, ">$outfile/rsrc") {
     1868                            binmode SRC; # (not necessary for Darwin, but let's be thorough)
     1869                            binmode DST;
     1870                            while (read SRC, $buf, 65536) {
     1871                                print DST $buf or $err = 'copying', last;
     1872                            }
     1873                            close DST or $err or $err = 'closing';
     1874                        } else {
     1875                            # (this is normal if the destination filesystem isn't Mac OS)
     1876                            $self->Warn('Error creating Mac OS resource fork');
     1877                        }
     1878                        close SRC;
     1879                    } else {
     1880                        $err = 'opening';
     1881                    }
     1882                    $rtnVal = 0 if $err and $self->Error("Error $err Mac OS resource fork", 1);
     1883                }
     1884            }
    15931885            # erase input file if renaming while editing information in place
    1594             unlink $infile or $self->Warn('Error erasing original file');
     1886            unlink $infile or $self->Warn('Error erasing original file') if $eraseIn;
    15951887        }
    15961888    }
     
    16001892        $rtnVal and $rtnVal = -1 unless close($outRef);
    16011893        # erase the output file if we weren't successful
    1602         $rtnVal > 0 or unlink $outfile;
     1894        if ($rtnVal <= 0) {
     1895            unlink $outfile;
     1896        # else rename temporary file if necessary
     1897        } elsif ($tmpfile) {
     1898            CopyFileAttrs($infile, $tmpfile);   # copy attributes to new file
     1899            unless (rename($tmpfile, $infile)) {
     1900                # some filesystems won't overwrite with 'rename', so try erasing original
     1901                if (not unlink($infile)) {
     1902                    unlink $tmpfile;
     1903                    $self->Error('Error renaming temporary file');
     1904                    $rtnVal = 0;
     1905                } elsif (not rename($tmpfile, $infile)) {
     1906                    $self->Error('Error renaming temporary file after deleting original');
     1907                    $rtnVal = 0;
     1908                }
     1909            }
     1910        }
    16031911    }
    16041912    # set FileModifyDate if requested (and if possible!)
    16051913    if (defined $fileModifyDate and $rtnVal > 0 and
    1606         ($closeOut or ($closeIn and defined $outBuff)))
     1914        ($closeOut or ($closeIn and defined $outBuff)) and
     1915        $self->SetFileModifyDate($closeOut ? $outfile : $infile, $originalTime) > 0)
    16071916    {
    1608         $self->SetFileModifyDate($closeOut ? $outfile : $infile, $originalTime);
     1917        ++$self->{CHANGED}; # we changed something
    16091918    }
    16101919    # check for write error and set appropriate error message and return value
    16111920    if ($rtnVal < 0) {
    1612         $self->Error('Error writing output file');
     1921        $self->Error('Error writing output file') unless $$self{VALUE}{Error};
    16131922        $rtnVal = 0;    # return 0 on failure
    16141923    } elsif ($rtnVal > 0) {
     
    16231932#------------------------------------------------------------------------------
    16241933# Get list of all available tags for specified group
    1625 # Inputs: 0) optional group name
     1934# Inputs: 0) optional group name (or string of names separated by colons)
    16261935# Returns: tag list (sorted alphabetically)
    16271936# Notes: Can't get tags for specific IFD
     
    16301939    local $_;
    16311940    my $group = shift;
    1632     my (%allTags, $exifTool);
    1633 
    1634     $group and $exifTool = new Image::ExifTool;
     1941    my (%allTags, @groups);
     1942    @groups = split ':', $group if $group;
     1943
     1944    my $exifTool = new Image::ExifTool;
    16351945    LoadAllTables();    # first load all our tables
    1636     my @tableNames = ( keys %allTables );
     1946    my @tableNames = keys %allTables;
    16371947
    16381948    # loop through all tables and save tag names to %allTags hash
     
    16431953            my @infoArray = GetTagInfoList($table,$tagID);
    16441954            my $tagInfo;
    1645             foreach $tagInfo (@infoArray) {
    1646                 my $tag = $$tagInfo{Name} || die "no name for tag!\n";
     1955GATInfo:    foreach $tagInfo (@infoArray) {
     1956                my $tag = $$tagInfo{Name};
     1957                $tag or warn("no name for tag!\n"), next;
    16471958                # don't list subdirectories unless they are writable
    1648                 next unless $$tagInfo{Writable} or not $$tagInfo{SubDirectory};
    1649                 if ($group) {
    1650                     my @groups = $exifTool->GetGroup($tagInfo);
    1651                     next unless grep /^$group$/i, @groups;
     1959                next if $$tagInfo{SubDirectory} and not $$tagInfo{Writable};
     1960                next if $$tagInfo{Hidden};  # ignore hidden tags
     1961                if (@groups) {
     1962                    my @tg = $exifTool->GetGroup($tagInfo);
     1963                    foreach $group (@groups) {
     1964                        next GATInfo unless grep /^$group$/i, @tg;
     1965                    }
    16521966                }
    16531967                $allTags{$tag} = 1;
     
    16601974#------------------------------------------------------------------------------
    16611975# Get list of all writable tags
    1662 # Inputs: 0) optional group name
     1976# Inputs: 0) optional group name (or names separated by colons)
    16631977# Returns: tag list (sorted alphbetically)
    16641978sub GetWritableTags(;$)
     
    16661980    local $_;
    16671981    my $group = shift;
    1668     my (%writableTags, $exifTool);
    1669 
    1670     $group and $exifTool = new Image::ExifTool;
     1982    my (%writableTags, @groups);
     1983    @groups = split ':', $group if $group;
     1984
     1985    my $exifTool = new Image::ExifTool;
    16711986    LoadAllTables();
    16721987    my @tableNames = keys %allTables;
     
    16872002            my @infoArray = GetTagInfoList($table,$tagID);
    16882003            my $tagInfo;
    1689             foreach $tagInfo (@infoArray) {
    1690                 my $tag = $$tagInfo{Name} || die "no name for tag!\n";
     2004GWTInfo:    foreach $tagInfo (@infoArray) {
     2005                my $tag = $$tagInfo{Name};
     2006                $tag or warn("no name for tag!\n"), next;
    16912007                my $writable = $$tagInfo{Writable};
    16922008                next unless $writable or ($table->{WRITABLE} and
    16932009                    not defined $writable and not $$tagInfo{SubDirectory});
    1694                 if ($group) {
    1695                     my @groups = $exifTool->GetGroup($tagInfo);
    1696                     next unless grep /^$group$/i, @groups;
     2010                next if $$tagInfo{Hidden};  # ignore hidden tags
     2011                if (@groups) {
     2012                    my @tg = $exifTool->GetGroup($tagInfo);
     2013                    foreach $group (@groups) {
     2014                        next GWTInfo unless grep /^$group$/i, @tg;
     2015                    }
    16972016                }
    16982017                $writableTags{$tag} = 1;
     
    17122031    my $family = shift || 0;
    17132032
     2033    $family == 3 and return('Doc#', 'Main');
     2034    $family == 4 and return('Copy#');
     2035
    17142036    LoadAllTables();    # first load all our tables
    17152037
    1716     my @tableNames = ( keys %allTables );
     2038    my @tableNames = keys %allTables;
    17172039
    17182040    # loop through all tag tables and get all group names
     
    17202042    while (@tableNames) {
    17212043        my $table = GetTagTable(pop @tableNames);
    1722         my $defaultGroup;
    1723         $defaultGroup = $table->{GROUPS}->{$family} if $table->{GROUPS};
    1724         $allGroups{$defaultGroup} = 1 if defined $defaultGroup;
    1725         foreach (TagTableKeys($table)) {
    1726             my @infoArray = GetTagInfoList($table,$_);
    1727             my ($tagInfo, $groups, $group);
    1728             if ($groups = $$table{GROUPS} and $group = $$groups{$family}) {
    1729                 $allGroups{$group} = 1;
    1730             }
     2044        my ($grps, $grp, $tag, $tagInfo);
     2045        $allGroups{$grp} = 1 if ($grps = $$table{GROUPS}) and ($grp = $$grps{$family});
     2046        foreach $tag (TagTableKeys($table)) {
     2047            my @infoArray = GetTagInfoList($table, $tag);
    17312048            foreach $tagInfo (@infoArray) {
    1732                 if ($groups = $$tagInfo{Groups} and $group = $$groups{$family}) {
    1733                     $allGroups{$group} = 1;
    1734                 }
     2049                next unless ($grps = $$tagInfo{Groups}) and ($grp = $$grps{$family});
     2050                $allGroups{$grp} = 1;
    17352051            }
    17362052        }
     
    17612077
    17622078#------------------------------------------------------------------------------
     2079# Un-escape string according to options settings and clear UTF-8 flag
     2080# Inputs: 0) ExifTool ref, 1) string ref or string ref ref
     2081# Notes: also de-references SCALAR values
     2082sub Sanitize($$)
     2083{
     2084    my ($self, $valPt) = @_;
     2085    # de-reference SCALAR references
     2086    $$valPt = $$$valPt if ref $$valPt eq 'SCALAR';
     2087    # make sure the Perl UTF-8 flag is OFF for the value if perl 5.6 or greater
     2088    # (otherwise our byte manipulations get corrupted!!)
     2089    if ($] >= 5.006 and (eval 'require Encode; Encode::is_utf8($$valPt)' or $@)) {
     2090        # repack by hand if Encode isn't available
     2091        $$valPt = $@ ? pack('C*',unpack('U0C*',$$valPt)) : Encode::encode('utf8',$$valPt);
     2092    }
     2093    # un-escape value if necessary
     2094    if ($$self{OPTIONS}{Escape}) {
     2095        # (XMP.pm and HTML.pm were require'd as necessary when option was set)
     2096        if ($$self{OPTIONS}{Escape} eq 'XML') {
     2097            $$valPt = Image::ExifTool::XMP::UnescapeXML($$valPt);
     2098        } elsif ($$self{OPTIONS}{Escape} eq 'HTML') {
     2099            $$valPt = Image::ExifTool::HTML::UnescapeHTML($$valPt);
     2100        }
     2101    }
     2102}
     2103
     2104#------------------------------------------------------------------------------
     2105# Apply inverse conversions
     2106# Inputs: 0) ExifTool ref, 1) value, 2) tagInfo (or Struct item) ref,
     2107#         3) tag name, 4) group 1 name, 5) conversion type (or undef),
     2108#         6) [optional] want group
     2109# Returns: 0) converted value, 1) error string (or undef on success)
     2110# Notes: Uses ExifTool "ConvType" member to specify conversion type
     2111sub ConvInv($$$$$;$$)
     2112{
     2113    my ($self, $val, $tagInfo, $tag, $wgrp1, $convType, $wantGroup) = @_;
     2114    my ($err, $type);
     2115
     2116Conv: for (;;) {
     2117        if (not defined $type) {
     2118            # split value into list if necessary
     2119            if ($$tagInfo{List}) {
     2120                my $listSplit = $$tagInfo{AutoSplit} || $self->{OPTIONS}{ListSplit};
     2121                if (defined $listSplit) {
     2122                    $listSplit = ',?\s+' if $listSplit eq '1' and $$tagInfo{AutoSplit};
     2123                    my @splitVal = split /$listSplit/, $val;
     2124                    $val = \@splitVal if @splitVal > 1;
     2125                }
     2126            }
     2127            $type = $convType || $$self{ConvType} || 'PrintConv';
     2128        } elsif ($type ne 'ValueConv') {
     2129            $type = 'ValueConv';
     2130        } else {   
     2131            # finally, do our value check
     2132            my ($err2, $v);
     2133            if ($tagInfo->{WriteCheck}) {
     2134                #### eval WriteCheck ($self, $tagInfo, $val)
     2135                $err2 = eval $tagInfo->{WriteCheck};
     2136                $@ and warn($@), $err2 = 'Error evaluating WriteCheck';
     2137            }
     2138            unless ($err2) {
     2139                my $table = $tagInfo->{Table};
     2140                if ($table and $table->{CHECK_PROC} and not $$tagInfo{RawConvInv}) {
     2141                    my $checkProc = $table->{CHECK_PROC};
     2142                    if (ref $val eq 'ARRAY') {
     2143                        # loop through array values
     2144                        foreach $v (@$val) {
     2145                            $err2 = &$checkProc($self, $tagInfo, \$v);
     2146                            last if $err2;
     2147                        }
     2148                    } else {
     2149                        $err2 = &$checkProc($self, $tagInfo, \$val);
     2150                    }
     2151                }
     2152            }
     2153            if (defined $err2) {
     2154                # skip writing this tag if error string is empty
     2155                $err2 or goto WriteAlso;
     2156                $err = "$err2 for $wgrp1:$tag";
     2157                $self->VPrint(2, "$err\n");
     2158                undef $val; # value was invalid
     2159            }
     2160            last;
     2161        }
     2162        my $conv = $tagInfo->{$type};
     2163        my $convInv = $tagInfo->{"${type}Inv"};
     2164        # nothing to do at this level if no conversion defined
     2165        next unless defined $conv or defined $convInv;
     2166
     2167        my (@valList, $index, $convList, $convInvList);
     2168        if (ref $val eq 'ARRAY') {
     2169            # handle ValueConv of ListSplit and AutoSplit values
     2170            @valList = @$val;
     2171            $val = $valList[$index = 0];
     2172        } elsif (ref $conv eq 'ARRAY' or ref $convInv eq 'ARRAY') {
     2173            # handle conversion lists
     2174            @valList = split /$listSep{$type}/, $val;
     2175            $val = $valList[$index = 0];
     2176            if (ref $conv eq 'ARRAY') {
     2177                $convList = $conv;
     2178                $conv = $$conv[0];
     2179            }
     2180            if (ref $convInv eq 'ARRAY') {
     2181                $convInvList = $convInv;
     2182                $convInv = $$convInv[0];
     2183            }
     2184        }
     2185        # loop through multiple values if necessary
     2186        for (;;) {
     2187            if ($convInv) {
     2188                # capture eval warnings too
     2189                local $SIG{'__WARN__'} = \&SetWarning;
     2190                undef $evalWarning;
     2191                if (ref($convInv) eq 'CODE') {
     2192                    $val = &$convInv($val, $self);
     2193                } else {
     2194                    #### eval PrintConvInv/ValueConvInv ($val, $self, $wantGroup)
     2195                    $val = eval $convInv;
     2196                    $@ and $evalWarning = $@;
     2197                }
     2198                if ($evalWarning) {
     2199                    # an empty warning ("\n") ignores tag with no error
     2200                    if ($evalWarning eq "\n") {
     2201                        $err = '' unless defined $err;
     2202                    } else {
     2203                        $err = CleanWarning() . " in $wgrp1:$tag (${type}Inv)";
     2204                        $self->VPrint(2, "$err\n");
     2205                    }
     2206                    undef $val;
     2207                    last Conv;
     2208                } elsif (not defined $val) {
     2209                    $err = "Error converting value for $wgrp1:$tag (${type}Inv)";
     2210                    $self->VPrint(2, "$err\n");
     2211                    last Conv;
     2212                }
     2213            } elsif ($conv) {
     2214                if (ref $conv eq 'HASH') {
     2215                    my ($multi, $lc);
     2216                    # insert alternate language print conversions if required
     2217                    if ($$self{CUR_LANG} and $type eq 'PrintConv' and
     2218                        ref($lc = $self->{CUR_LANG}{$tag}) eq 'HASH' and
     2219                        ($lc = $$lc{PrintConv}))
     2220                    {
     2221                        my %newConv;
     2222                        foreach (keys %$conv) {
     2223                            my $val = $$conv{$_};
     2224                            defined $$lc{$val} or $newConv{$_} = $val, next;
     2225                            $newConv{$_} = $self->Decode($$lc{$val}, 'UTF8');
     2226                        }
     2227                        if ($$conv{BITMASK}) {
     2228                            foreach (keys %{$$conv{BITMASK}}) {
     2229                                my $val = $$conv{BITMASK}{$_};
     2230                                defined $$lc{$val} or $newConv{BITMASK}{$_} = $val, next;
     2231                                $newConv{BITMASK}{$_} = $self->Decode($$lc{$val}, 'UTF8');
     2232                            }
     2233                        }
     2234                        $conv = \%newConv;
     2235                    }
     2236                    if ($$conv{BITMASK}) {
     2237                        my $lookupBits = $$conv{BITMASK};
     2238                        my ($val2, $err2) = EncodeBits($val, $lookupBits);
     2239                        if ($err2) {
     2240                            # ok, try matching a straight value
     2241                            ($val, $multi) = ReverseLookup($val, $conv);
     2242                            unless (defined $val) {
     2243                                $err = "Can't encode $wgrp1:$tag ($err2)";
     2244                                $self->VPrint(2, "$err\n");
     2245                                last Conv;
     2246                            }
     2247                        } elsif (defined $val2) {
     2248                            $val = $val2;
     2249                        } else {
     2250                            delete $$conv{BITMASK};
     2251                            ($val, $multi) = ReverseLookup($val, $conv);
     2252                            $$conv{BITMASK} = $lookupBits;
     2253                        }
     2254                    } else {
     2255                        ($val, $multi) = ReverseLookup($val, $conv);
     2256                    }
     2257                    unless (defined $val) {
     2258                        $err = "Can't convert $wgrp1:$tag (" .
     2259                               ($multi ? 'matches more than one' : 'not in') . " $type)";
     2260                        $self->VPrint(2, "$err\n");
     2261                        last Conv;
     2262                    }
     2263                } elsif (not $$tagInfo{WriteAlso}) {
     2264                    $err = "Can't convert value for $wgrp1:$tag (no ${type}Inv)";
     2265                    $self->VPrint(2, "$err\n");
     2266                    undef $val;
     2267                    last Conv;
     2268                }
     2269            }
     2270            last unless @valList;
     2271            $valList[$index] = $val;
     2272            if (++$index >= @valList) {
     2273                # leave AutoSplit lists in ARRAY form, or join conversion lists
     2274                $val = $$tagInfo{List} ? \@valList : join ' ', @valList;
     2275                last;
     2276            }
     2277            $conv = $$convList[$index] if $convList;
     2278            $convInv = $$convInvList[$index] if $convInvList;
     2279            $val = $valList[$index];
     2280        }
     2281    } # end ValueConv/PrintConv loop
     2282
     2283    return($val, $err);
     2284}
     2285
     2286#------------------------------------------------------------------------------
    17632287# convert tag names to values in a string (ie. "${EXIF:ISO}x $$" --> "100x $")
    17642288# Inputs: 0) ExifTool object ref, 1) reference to list of found tags
    17652289#         2) string with embedded tag names, 3) Options:
    1766 #               undef    - set missing tags to '',
    1767 #              'Error'   - issue minor error on missing tag (and return undef),
    1768 #              'Warn'    - issue minor warning on missing tag (and return undef),
     2290#               undef    - set missing tags to ''
     2291#              'Error'   - issue minor error on missing tag (and return undef)
     2292#              'Warn'    - issue minor warning on missing tag (and return undef)
    17692293#               Hash ref - hash for return of tag/value pairs
    17702294# Returns: string with embedded tag values (or '$info{TAGNAME}' entries with Hash ref option)
    1771 # Notes: tag names are not case sensitive, uses MissingTagValue option if set
     2295# Notes:
     2296# - tag names are not case sensitive and may end with '#' for ValueConv value
     2297# - uses MissingTagValue option if set
    17722298sub InsertTagValues($$$;$)
    17732299{
    17742300    my ($self, $foundTags, $line, $opt) = @_;
    17752301    my $rtnStr = '';
    1776     while ($line =~ /(.*?)\$(\{?[\w-]+|\$)(.*)/s) {
    1777         my (@tags, $pre, $var, $group, $family, $val, $tg, @vals);
    1778         ($pre, $var, $line) = ($1, $2, $3);
    1779         # "$$" represents a "$" symbol
    1780         if ($var eq '$') {
     2302    while ($line =~ /(.*?)\$(\{?)([-\w]+|\$|\/)(.*)/s) {
     2303        my (@tags, $pre, $var, $bra, $val, $tg, @vals, $type);
     2304        ($pre, $bra, $var, $line) = ($1, $2, $3, $4);
     2305        # "$$" represents a "$" symbol, and "$/" is a newline
     2306        if ($var eq '$' or $var eq '/') {
     2307            $var = "\n" if $var eq '/';
    17812308            $rtnStr .= "$pre$var";
     2309            $line =~ s/^\}// if $bra;
    17822310            next;
    17832311        }
    1784         # check to see if this is a group name
    1785         if ($line =~ /^:([\w-]+)(.*)/s) {
    1786             $group = $var;
     2312        # allow multiple group names
     2313        while ($line =~ /^:([-\w]+)(.*)/s) {
     2314            my $group = $var;
    17872315            ($var, $line) = ($1, $2);
    1788             $line =~ s/^\}// if $group =~ s/^\{//;
    17892316            $var = "$group:$var";
    1790         } else {
    1791             $line =~ s/^\}// if $var =~ s/^\{//;
    1792         }
     2317        }
     2318        # allow trailing '#' to indicate ValueConv value
     2319        $type = 'ValueConv' if $line =~ s/^#//;
     2320        # remove trailing bracket if there was a leading one
     2321        $line =~ s/^\}// if $bra;
    17932322        push @tags, $var;
    17942323        ExpandShortcuts(\@tags);
     
    17972326        for (;;) {
    17982327            my $tag = shift @tags;
    1799             my ($group, $family);
    1800             if ($tag =~ /(.+?)(\d+)?:(.+)/) {
    1801                 ($group, $family, $tag) = ($1, $2, $3);
    1802                 $group = '*' if lc($group) eq 'all';
     2328            if ($tag =~ /(.*):(.+)/) {
     2329                my $group;
     2330                ($group, $tag) = ($1, $2);
    18032331                # find the specified tag
    18042332                my @matches = grep /^$tag(\s|$)/i, @$foundTags;
     2333                @matches = $self->GroupMatches($group, \@matches);
    18052334                foreach $tg (@matches) {
    1806                     if ($group ne '*') {
    1807                         my @groups = $self->GetGroup($tg, $family);
    1808                         my ($grp) = grep /^$group$/i, @groups;
    1809                         next unless defined $grp;
    1810                     }
    18112335                    if (defined $val and $tg =~ / \((\d+)\)$/) {
    18122336                        # take the most recently extracted tag
     
    18142338                        next if $tag !~ / \((\d+)\)$/ or $1 > $tagNum;
    18152339                    }
    1816                     $val = $self->GetValue($tg);
     2340                    $val = $self->GetValue($tg, $type);
    18172341                    $tag = $tg;
    18182342                    last unless $tag =~ / /;    # all done if we got our best match
    18192343                }
    18202344            } else {
    1821                 # remove trailing bracket if we had a leading one
    1822                 $val = $self->GetValue($tag);
     2345                # get the tag value
     2346                $val = $self->GetValue($tag, $type);
    18232347                unless (defined $val) {
    18242348                    # check for tag name with different case
    18252349                    ($tg) = grep /^$tag$/i, @$foundTags;
    18262350                    if (defined $tg) {
    1827                         $val = $self->GetValue($tg);
     2351                        $val = $self->GetValue($tg, $type);
    18282352                        $tag = $tg;
    18292353                    }
     
    18312355            }
    18322356            if (ref $val eq 'ARRAY') {
    1833                 $val = join(', ', @$val);
     2357                $val = join($self->{OPTIONS}{ListSep}, @$val);
    18342358            } elsif (ref $val eq 'SCALAR') {
    1835                 $val = $$val;
     2359                if ($self->{OPTIONS}{Binary} or $$val =~ /^Binary data/) {
     2360                    $val = $$val;
     2361                } else {
     2362                    $val = 'Binary data ' . length($$val) . ' bytes';
     2363                }
    18362364            } elsif (not defined $val) {
    18372365                last unless @tags;
     
    18472375        }
    18482376        unless (defined $val or ref $opt) {
    1849             $val = $self->{OPTIONS}->{MissingTagValue};
     2377            $val = $self->{OPTIONS}{MissingTagValue};
    18502378            unless (defined $val) {
    18512379                no strict 'refs';
     
    18552383        }
    18562384        if (ref $opt eq 'HASH') {
     2385            $var .= '#' if $type;
    18572386            $rtnStr .= "$pre\$info{'$var'}";
    18582387            $$opt{$var} = $val;
     
    18712400{
    18722401    my $tag = shift;
    1873     $tag =~ s/^(.+)://; # ignore group name
     2402    $tag =~ s/^(.*)://; # ignore group name
    18742403    my @tagInfo = FindTagInfo($tag);
    1875     return undef unless @tagInfo;
     2404    unless (@tagInfo) {
     2405        return 0 if TagExists($tag);
     2406        return undef;
     2407    }
    18762408    my $tagInfo;
    18772409    foreach $tagInfo (@tagInfo) {
    1878         return 1 if $$tagInfo{Writable} or $tagInfo->{Table}->{WRITABLE};
     2410        return 1 if $$tagInfo{Writable} or $tagInfo->{Table}{WRITABLE};
     2411        # must call WRITE_PROC to autoload writer because this may set the writable tag
     2412        my $writeProc = $tagInfo->{Table}{WRITE_PROC};
     2413        next unless $writeProc;
     2414        &$writeProc();  # dummy call to autoload writer
     2415        return 1 if $$tagInfo{Writable};
    18792416    }
    18802417    return 0;
     
    19092446
    19102447#------------------------------------------------------------------------------
     2448# Copy file attributes from one file to another
     2449# Inputs: 0) source file name, 1) destination file name
     2450# Notes: eventually add support for extended attributes?
     2451sub CopyFileAttrs($$)
     2452{
     2453    my ($src, $dst) = @_;
     2454    my ($mode, $uid, $gid) = (stat($src))[2, 4, 5];
     2455    eval { chmod($mode & 07777, $dst) } if defined $mode;
     2456    eval { chown($uid, $gid, $dst) } if defined $uid and defined $gid;
     2457}
     2458
     2459#------------------------------------------------------------------------------
    19112460# Get new file name
    19122461# Inputs: 0) existing name, 1) new name
     
    19262475
    19272476#------------------------------------------------------------------------------
     2477# Get next available tag key
     2478# Inputs: 0) hash reference (keys are tag keys), 1) tag name
     2479# Returns: next available tag key
     2480sub NextTagKey($$)
     2481{
     2482    my ($info, $tag) = @_;
     2483    return $tag unless exists $$info{$tag};
     2484    my $i;
     2485    for ($i=1; ; ++$i) {
     2486        my $key = "$tag ($i)";
     2487        return $key unless exists $$info{$key};
     2488    }
     2489}
     2490
     2491#------------------------------------------------------------------------------
    19282492# Reverse hash lookup
    19292493# Inputs: 0) value, 1) hash reference
     
    19322496{
    19332497    my ($val, $conv) = @_;
     2498    return undef unless defined $val;
    19342499    my $multi;
    1935     if ($val =~ /^Unknown\s*\((.+)\)$/i) {
     2500    if ($val =~ /^Unknown\s*\((.*)\)$/i) {
    19362501        $val = $1;    # was unknown
    19372502        if ($val =~ /^0x([\da-fA-F]+)$/) {
     
    19392504        }
    19402505    } else {
     2506        my $qval = quotemeta $val;
    19412507        my @patterns = (
    1942             "^\Q$val\E\$",      # exact match
    1943             "^(?i)\Q$val\E\$",  # case-insensitive
    1944             "^(?i)\Q$val\E",    # beginning of string
    1945             "(?i)\Q$val\E",     # substring
     2508            "^$qval\$",         # exact match
     2509            "^(?i)$qval\$",     # case-insensitive
     2510            "^(?i)$qval",       # beginning of string
     2511            "(?i)$qval",        # substring
    19462512        );
     2513        # hash entries to ignore in reverse lookup
    19472514        my ($pattern, $found, $matches);
    1948         foreach $pattern (@patterns) {
     2515PAT:    foreach $pattern (@patterns) {
    19492516            $matches = scalar grep /$pattern/, values(%$conv);
    19502517            next unless $matches;
    19512518            # multiple matches are bad unless they were exact
    1952             last if $matches > 1 and $pattern !~ /\$$/;
     2519            if ($matches > 1 and $pattern !~ /\$$/) {
     2520                # don't match entries that we should ignore
     2521                foreach (keys %ignorePrintConv) {
     2522                    --$matches if defined $$conv{$_} and $$conv{$_} =~ /$pattern/;
     2523                }
     2524                last if $matches > 1;
     2525            }
    19532526            foreach (sort keys %$conv) {
    1954                 if ($$conv{$_} =~ /$pattern/) {
    1955                     $val = $_;
    1956                     $found = 1;
    1957                     last;
    1958                 }
    1959             }
    1960             last;
     2527                next if $$conv{$_} !~ /$pattern/ or $ignorePrintConv{$_};
     2528                $val = $_;
     2529                $found = 1;
     2530                last PAT;
     2531            }
    19612532        }
    19622533        unless ($found) {
    1963             undef $val;
     2534            # call OTHER conversion routine if available
     2535            $val = $$conv{OTHER} ? &{$$conv{OTHER}}($val,1,$conv) : undef;
    19642536            $multi = 1 if $matches > 1;
    19652537        }
    19662538    }
    1967     if (wantarray) {
    1968         return ($val, $multi);
    1969     } else {
    1970         return $val;
    1971     }
     2539    return ($val, $multi) if wantarray;
     2540    return $val;
    19722541}
    19732542
     
    19752544# Return true if we are deleting or overwriting the specified tag
    19762545# Inputs: 0) new value hash reference
    1977 #         2) optional tag value if deleting specific values
    1978 # Returns: >0 - tag should be deleted
     2546#         1) optional tag value (before RawConv) if deleting specific values
     2547# Returns: >0 - tag should be overwritten
    19792548#          =0 - the tag should be preserved
    19802549#          <0 - not sure, we need the value to know
    19812550sub IsOverwriting($;$)
    19822551{
    1983     my ($newValueHash, $value) = @_;
    1984     return 0 unless $newValueHash;
     2552    my ($nvHash, $val) = @_;
     2553    return 0 unless $nvHash;
    19852554    # overwrite regardless if no DelValues specified
    1986     return 1 unless $newValueHash->{DelValue};
     2555    return 1 unless $$nvHash{DelValue};
     2556    # never overwrite if DelValue list exists but is empty
     2557    my $shift = $$nvHash{Shift};
     2558    return 0 unless @{$$nvHash{DelValue}} or defined $shift;
     2559    # return "don't know" if we don't have a value to test
     2560    return -1 unless defined $val;
     2561    # apply raw conversion if necessary
     2562    my $tagInfo = $$nvHash{TagInfo};
     2563    my $conv = $$tagInfo{RawConv};
     2564    if ($conv) {
     2565        local $SIG{'__WARN__'} = \&SetWarning;
     2566        undef $evalWarning;
     2567        if (ref $conv eq 'CODE') {
     2568            $val = &$conv($val, $$nvHash{Self});
     2569        } else {
     2570            my $self = $$nvHash{Self};
     2571            my $tag = $$tagInfo{Name};
     2572            #### eval RawConv ($self, $val, $tag, $tagInfo)
     2573            $val = eval $conv;
     2574            $@ and $evalWarning = $@;
     2575        }
     2576        return -1 unless defined $val;
     2577    }
    19872578    # apply time shift if necessary
    1988     if (defined $newValueHash->{Shift}) {
    1989         return -1 unless defined $value;
    1990         my $type = $newValueHash->{TagInfo}->{Shift};
    1991         my $shift = $newValueHash->{Shift};
     2579    if (defined $shift) {
    19922580        require 'Image/ExifTool/Shift.pl';
    1993         my $err = ApplyShift($type, $shift, $value, $newValueHash);
     2581        my $err = ApplyShift($$tagInfo{Shift}, $shift, $val, $nvHash);
    19942582        if ($err) {
    1995             my $tag = $newValueHash->{TagInfo}->{Name};
    1996             $newValueHash->{Self}->Warn("$err when shifting $tag");
     2583            $nvHash->{Self}->Warn("$err when shifting $$tagInfo{Name}");
    19972584            return 0;
    19982585        }
    19992586        # don't bother overwriting if value is the same
    2000         return 0 if $value eq $newValueHash->{Value}->[0];
     2587        return 0 if $val eq $$nvHash{Value}[0];
    20012588        return 1;
    20022589    }
    2003     # never overwrite if DelValue list exists but is empty
    2004     return 0 unless @{$newValueHash->{DelValue}};
    2005     # return "don't know" if we don't have a value to test
    2006     return -1 unless defined $value;
    20072590    # return 1 if value matches a DelValue
    2008     my $val;
    2009     foreach $val (@{$newValueHash->{DelValue}}) {
    2010         return 1 if $value eq $val;
     2591    my $delVal;
     2592    foreach $delVal (@{$$nvHash{DelValue}}) {
     2593        return 1 if $val eq $delVal;
    20112594    }
    20122595    return 0;
     
    20192602sub IsCreating($)
    20202603{
    2021     return $_[0]->{IsCreating};
     2604    return $_[0]{IsCreating};
    20222605}
    20232606
     
    20282611sub GetWriteGroup($)
    20292612{
    2030     return $_[0]->{WriteGroup};
     2613    return $_[0]{WriteGroup};
     2614}
     2615
     2616#------------------------------------------------------------------------------
     2617# Get name of write group or family 1 group
     2618# Inputs: 0) ExifTool ref, 1) tagInfo ref, 2) write group name
     2619# Returns: Name of group for verbose message
     2620sub GetWriteGroup1($$)
     2621{
     2622    my ($self, $tagInfo, $writeGroup) = @_;
     2623    return $writeGroup unless $writeGroup =~ /^(MakerNotes|XMP|Composite)$/;
     2624    return $self->GetGroup($tagInfo, 1);
    20312625}
    20322626
     
    20402634{
    20412635    my ($self, $tagInfo, $writeGroup, $opts) = @_;
    2042     my $newValueHash = $self->{NEW_VALUE}->{$tagInfo};
     2636    my $nvHash = $self->{NEW_VALUE}{$tagInfo};
    20432637
    20442638    my %opts;   # quick lookup for options
     
    20482642    if ($writeGroup) {
    20492643        # find the new value in the list with the specified write group
    2050         while ($newValueHash and $newValueHash->{WriteGroup} ne $writeGroup) {
    2051             $newValueHash = $newValueHash->{Next};
     2644        while ($nvHash and $nvHash->{WriteGroup} ne $writeGroup) {
     2645            $nvHash = $nvHash->{Next};
    20522646        }
    20532647    }
    20542648    # remove this entry if deleting, or if creating a new entry and
    20552649    # this entry is marked with "Save" flag
    2056     if (defined $newValueHash and ($opts{'delete'} or
    2057         ($opts{'create'} and $newValueHash->{Save})))
     2650    if (defined $nvHash and ($opts{'delete'} or
     2651        ($opts{'create'} and $nvHash->{Save})))
    20582652    {
    2059         $self->RemoveNewValueHash($newValueHash, $tagInfo);
    2060         undef $newValueHash;
    2061     }
    2062     if (not defined $newValueHash and $opts{'create'}) {
     2653        if ($opts{'delete'}) {
     2654            $self->RemoveNewValueHash($nvHash, $tagInfo);
     2655            undef $nvHash;
     2656        } else {
     2657            # save a copy of this new value hash
     2658            my %copy = %$nvHash;
     2659            my $key;
     2660            # make copy of Value and DelValue lists
     2661            foreach $key (keys %copy) {
     2662                next unless ref $copy{$key} eq 'ARRAY';
     2663                $copy{$key} = [ @{$copy{$key}} ];
     2664            }
     2665            my $saveHash = $self->{SAVE_NEW_VALUE};
     2666            # add to linked list of saved new value hashes
     2667            $copy{Next} = $saveHash->{$tagInfo};
     2668            $saveHash->{$tagInfo} = \%copy;
     2669            delete $nvHash->{Save};   # don't save it again
     2670        }
     2671    }
     2672    if (not defined $nvHash and $opts{'create'}) {
    20632673        # create a new entry
    2064         $newValueHash = {
     2674        $nvHash = {
    20652675            TagInfo => $tagInfo,
    20662676            WriteGroup => $writeGroup,
     
    20682678        };
    20692679        # add entry to our NEW_VALUE hash
    2070         if ($self->{NEW_VALUE}->{$tagInfo}) {
     2680        if ($self->{NEW_VALUE}{$tagInfo}) {
    20712681            # add to end of linked list
    2072             my $lastHash = LastInList($self->{NEW_VALUE}->{$tagInfo});
    2073             $lastHash->{Next} = $newValueHash;
     2682            my $lastHash = LastInList($self->{NEW_VALUE}{$tagInfo});
     2683            $lastHash->{Next} = $nvHash;
    20742684        } else {
    2075             $self->{NEW_VALUE}->{$tagInfo} = $newValueHash;
    2076         }
    2077     }
    2078     return $newValueHash;
     2685            $self->{NEW_VALUE}{$tagInfo} = $nvHash;
     2686        }
     2687    }
     2688    return $nvHash;
    20792689}
    20802690
     
    20832693sub LoadAllTables()
    20842694{
    2085     unless ($loadedAllTables) {
    2086         # load all of our non-referenced tables (first our modules)
    2087         my $table;
    2088         foreach $table (@loadAllTables) {
    2089             my $tableName = "Image::ExifTool::$table";
    2090             $tableName .= '::Main' unless $table =~ /:/;
    2091             GetTagTable($tableName);
    2092         }
    2093         # (then our special tables)
    2094         GetTagTable('Image::ExifTool::Extra');
    2095         GetTagTable('Image::ExifTool::Composite');
    2096         # recursively load all tables referenced by the current tables
    2097         my @tableNames = ( keys %allTables );
    2098         my %pushedTables;
    2099         while (@tableNames) {
    2100             $table = GetTagTable(shift @tableNames);
    2101             # call write proc if it exists in case it adds tags to the table
    2102             my $writeProc = $table->{WRITE_PROC};
    2103             $writeProc and &$writeProc();
    2104             # recursively scan through tables in subdirectories
    2105             foreach (TagTableKeys($table)) {
    2106                 my @infoArray = GetTagInfoList($table,$_);
    2107                 my $tagInfo;
    2108                 foreach $tagInfo (@infoArray) {
    2109                     my $subdir = $$tagInfo{SubDirectory} or next;
    2110                     my $tableName = $$subdir{TagTable} or next;
    2111                     # next if table already loaded or queued for loading
    2112                     next if $allTables{$tableName} or $pushedTables{$tableName};
    2113                     push @tableNames, $tableName;   # must scan this one too
    2114                     $pushedTables{$tableName} = 1;
    2115                 }
    2116             }
    2117         }
    2118         $loadedAllTables = 1;
    2119     }
     2695    return if $loadedAllTables;
     2696
     2697    # load all of our non-referenced tables (first our modules)
     2698    my $table;
     2699    foreach $table (@loadAllTables) {
     2700        my $tableName = "Image::ExifTool::$table";
     2701        $tableName .= '::Main' unless $table =~ /:/;
     2702        GetTagTable($tableName);
     2703    }
     2704    # (then our special tables)
     2705    GetTagTable('Image::ExifTool::Extra');
     2706    GetTagTable('Image::ExifTool::Composite');
     2707    # recursively load all tables referenced by the current tables
     2708    my @tableNames = keys %allTables;
     2709    my %pushedTables;
     2710    while (@tableNames) {
     2711        $table = GetTagTable(shift @tableNames);
     2712        # call write proc if it exists in case it adds tags to the table
     2713        my $writeProc = $table->{WRITE_PROC};
     2714        $writeProc and &$writeProc();
     2715        # recursively scan through tables in subdirectories
     2716        foreach (TagTableKeys($table)) {
     2717            my @infoArray = GetTagInfoList($table,$_);
     2718            my $tagInfo;
     2719            foreach $tagInfo (@infoArray) {
     2720                my $subdir = $$tagInfo{SubDirectory} or next;
     2721                my $tableName = $$subdir{TagTable} or next;
     2722                # next if table already loaded or queued for loading
     2723                next if $allTables{$tableName} or $pushedTables{$tableName};
     2724                push @tableNames, $tableName;   # must scan this one too
     2725                $pushedTables{$tableName} = 1;
     2726            }
     2727        }
     2728    }
     2729    $loadedAllTables = 1;
    21202730}
    21212731
     
    21252735sub RemoveNewValueHash($$$)
    21262736{
    2127     my ($self, $newValueHash, $tagInfo) = @_;
    2128     my $firstHash = $self->{NEW_VALUE}->{$tagInfo};
    2129     if ($newValueHash eq $firstHash) {
     2737    my ($self, $nvHash, $tagInfo) = @_;
     2738    my $firstHash = $self->{NEW_VALUE}{$tagInfo};
     2739    if ($nvHash eq $firstHash) {
    21302740        # remove first entry from linked list
    2131         if ($newValueHash->{Next}) {
    2132             $self->{NEW_VALUE}->{$tagInfo} = $newValueHash->{Next};
     2741        if ($nvHash->{Next}) {
     2742            $self->{NEW_VALUE}{$tagInfo} = $nvHash->{Next};
    21332743        } else {
    2134             delete $self->{NEW_VALUE}->{$tagInfo};
     2744            delete $self->{NEW_VALUE}{$tagInfo};
    21352745        }
    21362746    } else {
    21372747        # find the list element pointing to this hash
    2138         $firstHash = $firstHash->{Next} while $firstHash->{Next} ne $newValueHash;
     2748        $firstHash = $firstHash->{Next} while $firstHash->{Next} ne $nvHash;
    21392749        # remove from linked list
    2140         $firstHash->{Next} = $newValueHash->{Next};
     2750        $firstHash->{Next} = $nvHash->{Next};
    21412751    }
    21422752    # save the existing entry if necessary
    2143     if ($newValueHash->{Save}) {
     2753    if ($nvHash->{Save}) {
    21442754        my $saveHash = $self->{SAVE_NEW_VALUE};
    21452755        # add to linked list of saved new value hashes
    2146         $newValueHash->{Next} = $saveHash->{$tagInfo};
    2147         $saveHash->{$tagInfo} = $newValueHash;
     2756        $nvHash->{Next} = $saveHash->{$tagInfo};
     2757        $saveHash->{$tagInfo} = $nvHash;
    21482758    }
    21492759}
     
    21632773
    21642774    my ($out, @keys, $hashKey);
    2165     $out = $self->{OPTIONS}->{TextOut} if $self->{OPTIONS}->{Verbose} > 1;
     2775    $out = $self->{OPTIONS}{TextOut} if $self->{OPTIONS}{Verbose} > 1;
    21662776
    21672777    # loop though all new values, and remove any in this group
    21682778    @keys = keys %{$self->{NEW_VALUE}};
    21692779    foreach $hashKey (@keys) {
    2170         my $newValueHash = $self->{NEW_VALUE}->{$hashKey};
     2780        my $nvHash = $self->{NEW_VALUE}{$hashKey};
    21712781        # loop through each entry in linked list
    21722782        for (;;) {
    2173             my $nextHash = $newValueHash->{Next};
    2174             my $tagInfo = $newValueHash->{TagInfo};
    2175             my $grp0 = $self->GetGroup($tagInfo, 0);
    2176             my $wgrp = $newValueHash->{WriteGroup};
    2177             if (grep /^($grp0|$wgrp)$/, @groups) {
     2783            my $nextHash = $nvHash->{Next};
     2784            my $tagInfo = $nvHash->{TagInfo};
     2785            my ($grp0,$grp1) = $self->GetGroup($tagInfo);
     2786            my $wgrp = $nvHash->{WriteGroup};
     2787            # use group1 if write group is not specific
     2788            $wgrp = $grp1 if $wgrp eq $grp0;
     2789            if (grep /^($grp0|$wgrp)$/i, @groups) {
    21782790                $out and print $out "Removed new value for $wgrp:$$tagInfo{Name}\n";
    21792791                # remove from linked list
    2180                 $self->RemoveNewValueHash($newValueHash, $tagInfo);
    2181             }
    2182             $newValueHash = $nextHash or last;
     2792                $self->RemoveNewValueHash($nvHash, $tagInfo);
     2793            }
     2794            $nvHash = $nextHash or last;
    21832795        }
    21842796    }
     
    21932805    my ($self, $tagTablePtr) = @_;
    21942806    my @tagInfoList;
    2195     if ($self->{NEW_VALUE}) {
     2807    my $nv = $self->{NEW_VALUE};
     2808    if ($nv) {
    21962809        my $hashKey;
    2197         foreach $hashKey (keys %{$self->{NEW_VALUE}}) {
    2198             my $tagInfo = $self->{NEW_VALUE}->{$hashKey}->{TagInfo};
     2810        foreach $hashKey (keys %$nv) {
     2811            my $tagInfo = $nv->{$hashKey}{TagInfo};
    21992812            next if $tagTablePtr and $tagTablePtr ne $tagInfo->{Table};
    22002813            push @tagInfoList, $tagInfo;
     
    22122825    my $self = shift;
    22132826    my (%tagInfoHash, $hashKey);
    2214     while ($self->{NEW_VALUE}) {
     2827    my $nv = $self->{NEW_VALUE};
     2828    while ($nv) {
    22152829        my $tagTablePtr = shift || last;
    2216         GenerateTagIDs($tagTablePtr);  # make sure IDs are generated
    2217         foreach $hashKey (keys %{$self->{NEW_VALUE}}) {
    2218             my $tagInfo = $self->{NEW_VALUE}->{$hashKey}->{TagInfo};
     2830        foreach $hashKey (keys %$nv) {
     2831            my $tagInfo = $nv->{$hashKey}{TagInfo};
    22192832            next if $tagTablePtr and $tagTablePtr ne $tagInfo->{Table};
    22202833            $tagInfoHash{$$tagInfo{TagID}} = $tagInfo;
     
    22332846{
    22342847    my ($self, $tagTablePtr, $parent) = @_;
    2235     $parent or $parent = $tagTablePtr->{GROUPS}->{0};
     2848    $parent or $parent = $tagTablePtr->{GROUPS}{0};
    22362849    my $tagID;
    22372850    my %addDirHash;
     
    22472860            # (take directory name from SubDirectory DirName if it exists,
    22482861            #  otherwise Group0 name of SubDirectory TagTable or tag Group1 name)
    2249             my $dirName = $tagInfo->{SubDirectory}->{DirName};
     2862            my $dirName = $tagInfo->{SubDirectory}{DirName};
    22502863            unless ($dirName) {
    22512864                # use tag name for directory name and save for next time
    22522865                $dirName = $$tagInfo{Name};
    2253                 $tagInfo->{SubDirectory}->{DirName} = $dirName;
     2866                $tagInfo->{SubDirectory}{DirName} = $dirName;
    22542867            }
    22552868            # save this directory information if we are writing it
     
    22602873        }
    22612874    }
    2262     if (wantarray) {
    2263         return (\%addDirHash, \%editDirHash);
    2264     } else {
    2265         return \%addDirHash;
    2266     }
    2267 }
    2268 
    2269 #------------------------------------------------------------------------------
    2270 # Get localized version of tagInfo hash (used by MIE and XMP)
     2875    return (\%addDirHash, \%editDirHash) if wantarray;
     2876    return \%addDirHash;
     2877}
     2878
     2879#------------------------------------------------------------------------------
     2880# Get localized version of tagInfo hash (used by MIE, XMP, PNG and QuickTime)
    22712881# Inputs: 0) tagInfo hash ref, 1) locale code (ie. "en_CA" for MIE)
    22722882# Returns: new tagInfo hash ref, or undef if invalid
     
    22772887    # make a new tagInfo hash for this locale
    22782888    my $table = $$tagInfo{Table};
    2279     Image::ExifTool::GenerateTagIDs($table);
    22802889    my $tagID = $$tagInfo{TagID} . '-' . $langCode;
    22812890    my $langInfo = $$table{$tagID};
     
    22992908# Inputs: 0) ExifTool object reference, 1) file type string (or map hash ref)
    23002909#         2) preferred family 0 group name for creating tags
     2910# Notes: The ADD_DIRS and EDIT_DIRS keys are the directory names, and the values
     2911#        are the names of the parent directories (undefined for a top-level directory)
    23012912sub InitWriteDirs($$;$)
    23022913{
     
    23102921    }
    23112922    my @tagInfoList = $self->GetNewTagInfoList();
    2312     my $tagInfo;
     2923    my ($tagInfo, $nvHash);
     2924
     2925    # save the preferred group
     2926    $$self{PreferredGroup} = $preferredGroup;
     2927
    23132928    foreach $tagInfo (@tagInfoList) {
    2314         my $newValueHash = $self->GetNewValueHash($tagInfo);
    2315         for (;;) {
     2929        # cycle through all hashes in linked list
     2930        for ($nvHash=$self->GetNewValueHash($tagInfo); $nvHash; $nvHash=$$nvHash{Next}) {
    23162931            # are we creating this tag? (otherwise just deleting or editing it)
    2317             my $isCreating = $newValueHash->{IsCreating};
     2932            my $isCreating = $nvHash->{IsCreating};
     2933            if ($isCreating) {
     2934                # if another group is taking priority, only create
     2935                # directory if specifically adding tags to this group
     2936                # or if this tag isn't being added to the priority group
     2937                $isCreating = 0 if $preferredGroup and
     2938                    $preferredGroup ne $self->GetGroup($tagInfo, 0) and
     2939                    $nvHash->{CreateGroups}{$preferredGroup};
     2940            } else {
     2941                # creating this directory if any tag is preferred and has a value
     2942                $isCreating = 1 if $preferredGroup and $$nvHash{Value} and
     2943                    $preferredGroup eq $self->GetGroup($tagInfo, 0);
     2944            }
    23182945            # tag belongs to directory specified by WriteGroup, or by
    23192946            # the Group0 name if WriteGroup not defined
    2320             my $dirName = $newValueHash->{WriteGroup};
     2947            my $dirName = $nvHash->{WriteGroup};
    23212948            # remove MIE copy number(s) if they exist
    23222949            if ($dirName =~ /^MIE\d*(-[a-z]+)?\d*$/i) {
     
    23312958                }
    23322959                $$editDirs{$dirName} = $parent;
    2333                 # (if another group is taking priority, only create
    2334                 # directory if specifically adding tags to this group
    2335                 # or if this tag isn't being added to the priority group
    2336                 if ($isCreating and (not $preferredGroup or
    2337                     $preferredGroup eq $self->GetGroup($tagInfo, 0) or not
    2338                     $newValueHash->{CreateGroups}->{$preferredGroup}))
    2339                 {
    2340                     $$addDirs{$dirName} = $parent;
    2341                 }
     2960                $$addDirs{$dirName} = $parent if $isCreating and $isCreating != 2;
    23422961                $dirName = $parent || shift @dirNames
    23432962            }
    2344             last unless $newValueHash->{Next};
    2345             # cycle through all hashes in linked list
    2346             $newValueHash = $newValueHash->{Next};
    23472963        }
    23482964    }
     
    23502966        # add delete groups to list of edited groups
    23512967        foreach (keys %{$self->{DEL_GROUP}}) {
     2968            next if /^-/;   # ignore excluded groups
    23522969            my $dirName = $_;
    23532970            # translate necessary group 0 names
    23542971            $dirName = $translateWriteGroup{$dirName} if $translateWriteGroup{$dirName};
     2972            # convert XMP group 1 names
     2973            $dirName = 'XMP' if $dirName =~ /^XMP-/;
    23552974            my @dirNames;
    23562975            while ($dirName) {
     
    23702989        $$editDirs{APP0} = undef;
    23712990    }
    2372  
    2373     if ($self->{OPTIONS}->{Verbose}) {
    2374         my $out = $self->{OPTIONS}->{TextOut};
     2991
     2992    if ($self->{OPTIONS}{Verbose}) {
     2993        my $out = $self->{OPTIONS}{TextOut};
    23752994        print $out "  Editing tags in: ";
    23762995        foreach (sort keys %$editDirs) { print $out "$_ "; }
    23772996        print $out "\n";
    2378         return unless $self->{OPTIONS}->{Verbose} > 1;
     2997        return unless $self->{OPTIONS}{Verbose} > 1;
    23792998        print $out "  Creating tags in: ";
    23802999        foreach (sort keys %$addDirs) { print $out "$_ "; }
     
    23913010{
    23923011    my ($self, $dirInfo, $tagTablePtr, $writeProc) = @_;
     3012    my ($out, $nvHash);
    23933013
    23943014    $tagTablePtr or return undef;
    2395     my $out;
    2396     $out = $self->{OPTIONS}->{TextOut} if $self->{OPTIONS}->{Verbose};
     3015    $out = $self->{OPTIONS}{TextOut} if $self->{OPTIONS}{Verbose};
    23973016    # set directory name from default group0 name if not done already
    23983017    my $dirName = $$dirInfo{DirName};
    2399     my $grp0 = $tagTablePtr->{GROUPS}->{0};
     3018    my $dataPt = $$dirInfo{DataPt};
     3019    my $grp0 = $tagTablePtr->{GROUPS}{0};
    24003020    $dirName or $dirName = $$dirInfo{DirName} = $grp0;
    24013021    if (%{$self->{DEL_GROUP}}) {
     
    24053025        my $delFlag = ($$delGroup{$grp0} or $$delGroup{$grp1});
    24063026        if ($delFlag) {
    2407             unless ($self->{FILE_TYPE} =~ /^(JPEG|PNG|JP2)$/) {
     3027            unless ($blockExifTypes{$$self{FILE_TYPE}}) {
    24083028                # restrict delete logic to prevent entire tiff image from being killed
    24093029                # (don't allow IFD0 to be deleted, and delete only ExifIFD if EXIF specified)
    2410                 if ($grp1 eq 'IFD0') {
     3030                if ($$self{FILE_TYPE} eq 'PSD') {
     3031                    # don't delete Photoshop directories from PSD image
     3032                    undef $grp1 if $grp0 eq 'Photoshop';
     3033                } elsif ($$self{FILE_TYPE} =~ /^(EPS|PS)$/) {
     3034                    # allow anything to be deleted from PostScript files
     3035                } elsif ($grp1 eq 'IFD0') {
    24113036                    my $type = $self->{TIFF_TYPE} || $self->{FILE_TYPE};
    2412                     $$delGroup{IFD0} and $self->Warn("Can't delete IFD0 from $type image",1);
     3037                    $$delGroup{IFD0} and $self->Warn("Can't delete IFD0 from $type",1);
    24133038                    undef $grp1;
    24143039                } elsif ($grp0 eq 'EXIF' and $$delGroup{$grp0}) {
     
    24173042            }
    24183043            if ($grp1) {
    2419                 if ($$dirInfo{DataPt} or $$dirInfo{RAF}) {
     3044                if ($dataPt or $$dirInfo{RAF}) {
    24203045                    ++$self->{CHANGED};
    24213046                    $out and print $out "  Deleting $grp1\n";
     
    24233048                    delete $self->{TIFF_END} if $dirName =~ /IFD/;
    24243049                }
    2425                 if ($delFlag == 2 and $self->{ADD_DIRS}->{$grp1}) {
    2426                     # create new empty directory
    2427                     my $data = '';
    2428                     my %dirInfo = (
    2429                         DirName => $$dirInfo{DirName},
    2430                         DirStart => 0,
    2431                         DirLen => 0,
    2432                         NewDataPos => $$dirInfo{NewDataPos},
    2433                         Fixup => $$dirInfo{Fixup},
    2434                     );
    2435                     $dirInfo = \%dirInfo;
     3050                # don't add back into the wrong location
     3051                my $right = $$self{ADD_DIRS}{$grp1};
     3052                # (take care because EXIF directory name may be either EXIF or IFD0,
     3053                #  but IFD0 will be the one that appears in the directory map)
     3054                $right = $$self{ADD_DIRS}{IFD0} if not $right and $grp1 eq 'EXIF';
     3055                if ($delFlag == 2 and $right) {
     3056                    # also check grandparent because some routines create 2 levels in 1
     3057                    my $right2 = $$self{ADD_DIRS}{$right} || '';
     3058                    if (not $$dirInfo{Parent} or $$dirInfo{Parent} eq $right or
     3059                        $$dirInfo{Parent} eq $right2)
     3060                    {
     3061                        # create new empty directory
     3062                        my $data = '';
     3063                        my %dirInfo = (
     3064                            DirName    => $$dirInfo{DirName},
     3065                            Parent     => $$dirInfo{Parent},
     3066                            DirStart   => 0,
     3067                            DirLen     => 0,
     3068                            DataPt     => \$data,
     3069                            NewDataPos => $$dirInfo{NewDataPos},
     3070                            Fixup      => $$dirInfo{Fixup},
     3071                        );
     3072                        $dirInfo = \%dirInfo;
     3073                    } else {
     3074                        $self->Warn("Not recreating $grp1 in $$dirInfo{Parent} (should be in $right)",1);
     3075                        return '';
     3076                    }
    24363077                } else {
    2437                     return '';
    2438                 }
    2439             }
    2440         }
    2441     }
    2442     # copy or delete new directory as a block if specified
    2443     my $tagInfo = $Image::ExifTool::Extra{$dirName};
    2444     if ($tagInfo and $self->{NEW_VALUE}->{$tagInfo}) {
    2445         my $newVal = GetNewValues($self->{NEW_VALUE}->{$tagInfo});
    2446         if (defined $newVal and length $newVal) {
    2447             $out and print $out "  Writing $dirName as a block\n";
    2448             ++$self->{CHANGED};
    2449             return $newVal;
    2450         } else {
    2451             $out and print $out "  Deleting $dirName as a block\n";
    2452             ++$self->{CHANGED};
    2453             return '';
     3078                    return '' unless $$dirInfo{NoDelete};
     3079                }
     3080            }
    24543081        }
    24553082    }
    24563083    # use default proc from tag table if no proc specified
    24573084    $writeProc or $writeProc = $$tagTablePtr{WRITE_PROC} or return undef;
     3085
     3086    # copy or delete new directory as a block if specified
     3087    my $blockName = $dirName;
     3088    $blockName = 'EXIF' if $blockName eq 'IFD0';
     3089    my $tagInfo = $Image::ExifTool::Extra{$blockName} || $$dirInfo{TagInfo};
     3090    while ($tagInfo and ($nvHash = $self->{NEW_VALUE}{$tagInfo}) and IsOverwriting($nvHash)) {
     3091        # protect against writing EXIF to wrong file types, etc
     3092        if ($blockName eq 'EXIF') {
     3093            unless ($blockExifTypes{$$self{FILE_TYPE}}) {
     3094                $self->Warn("Can't write EXIF as a block to $$self{FILE_TYPE} file");
     3095                last;
     3096            }
     3097            unless ($writeProc eq \&Image::ExifTool::WriteTIFF) {
     3098                # this could happen if we called WriteDirectory for an EXIF directory
     3099                # without going through WriteTIFF as the WriteProc, which would be bad
     3100                # because the EXIF block could end up with two TIFF headers
     3101                $self->Warn('Internal error writing EXIF -- please report');
     3102                last;
     3103            }
     3104        }
     3105        my $verb = 'Writing';
     3106        my $newVal = GetNewValues($nvHash);
     3107        unless (defined $newVal and length $newVal) {
     3108            $verb = 'Deleting';
     3109            $newVal = '';
     3110        }
     3111        $$dirInfo{BlockWrite} = 1;  # set flag indicating we did a block write
     3112        $out and print $out "  $verb $blockName as a block\n";
     3113        ++$self->{CHANGED};
     3114        return $newVal;
     3115    }
    24583116    # guard against writing the same directory twice
    2459     if (defined $$dirInfo{DataPt} and defined $$dirInfo{DirStart} and defined $$dirInfo{DataPos}) {
    2460         my $addr = $$dirInfo{DirStart} + $$dirInfo{DataPos} + ($$dirInfo{Base}||0);
    2461         if ($self->{PROCESSED}->{$addr}) {
    2462             if ($self->Error("$dirName pointer references previous $self->{PROCESSED}->{$addr} directory", 1)) {
     3117    if (defined $dataPt and defined $$dirInfo{DirStart} and defined $$dirInfo{DataPos}) {
     3118        my $addr = $$dirInfo{DirStart} + $$dirInfo{DataPos} + ($$dirInfo{Base}||0) + $$self{BASE};
     3119        # (Phase One P25 IIQ files have ICC_Profile duplicated in IFD0 and IFD1)
     3120        if ($self->{PROCESSED}{$addr} and ($dirName ne 'ICC_Profile' or $$self{TIFF_TYPE} ne 'IIQ')) {
     3121            if ($self->Error("$dirName pointer references previous $self->{PROCESSED}{$addr} directory", 1)) {
    24633122                return undef;
    24643123            } else {
     
    24683127            }
    24693128        }
    2470         $self->{PROCESSED}->{$addr} = $dirName;
    2471     }
    2472     # be sure the tag ID's are generated, because the write proc will need them
    2473     GenerateTagIDs($tagTablePtr);
     3129        $self->{PROCESSED}{$addr} = $dirName;
     3130    }
    24743131    my $oldDir = $self->{DIR_NAME};
    2475     if ($out and (not defined $oldDir or $oldDir ne $dirName)) {
    2476         my $verb = ($$dirInfo{DataPt} or $$dirInfo{DirLen}) ? 'Rewriting' : 'Creating';
    2477         print $out "  $verb $dirName\n";
     3132    my $isRewriting = ($$dirInfo{DirLen} or (defined $dataPt and length $$dataPt) or $$dirInfo{RAF});
     3133    my $name;
     3134    if ($out) {
     3135        $name = ($dirName eq 'MakerNotes' and $$dirInfo{TagInfo}) ?
     3136                 $dirInfo->{TagInfo}{Name} : $dirName;
     3137        if (not defined $oldDir or $oldDir ne $name) {
     3138            my $verb = $isRewriting ? 'Rewriting' : 'Creating';
     3139            print $out "  $verb $name\n";
     3140        }
    24783141    }
    24793142    my $saveOrder = GetByteOrder();
    24803143    my $oldChanged = $self->{CHANGED};
    24813144    $self->{DIR_NAME} = $dirName;
     3145    push @{$self->{PATH}}, $$dirInfo{DirName};
     3146    $$dirInfo{IsWriting} = 1;
    24823147    my $newData = &$writeProc($self, $dirInfo, $tagTablePtr);
     3148    pop @{$self->{PATH}};
     3149    # nothing changed if error occurred or nothing was created
     3150    $self->{CHANGED} = $oldChanged unless defined $newData and (length($newData) or $isRewriting);
    24833151    $self->{DIR_NAME} = $oldDir;
    2484     $self->{CHANGED} = $oldChanged unless defined $newData; # nothing changed if error occurred
    24853152    SetByteOrder($saveOrder);
    2486     print $out "  Deleting $dirName\n" if $out and defined $newData and not length $newData;
     3153    print $out "  Deleting $name\n" if $out and defined $newData and not length $newData;
    24873154    return $newData;
    24883155}
     
    25303197#          MaxLen => maximum length to dump
    25313198#          Out => output file reference
     3199#          Len => data length
    25323200sub HexDump($;$%)
    25333201{
     
    25433211    my $datLen = length($$dataPt) - $start;
    25443212    my $more;
     3213    $len = $opts{Len} if defined $opts{Len};
    25453214
    25463215    $addr = $start + ($opts{DataPos} || 0) unless defined $addr;
    2547     if (not defined $len) {
    2548         $len = $datLen;
    2549     } elsif ($len > $datLen) {
    2550         print $out "$prefix    Warning: Attempted dump outside data\n";
    2551         print $out "$prefix    ($len bytes specified, but only $datLen available)\n";
    2552         $len = $datLen;
    2553     }
     3216    $len = $datLen unless defined $len;
    25543217    if ($maxLen and $len > $maxLen) {
    25553218        # print one line less to allow for $more line below
     
    25583221        $len = $maxLen;
    25593222    }
     3223    if ($len > $datLen) {
     3224        print $out "$prefix    Warning: Attempted dump outside data\n";
     3225        print $out "$prefix    ($len bytes specified, but only $datLen available)\n";
     3226        $len = $datLen;
     3227    }
    25603228    my $format = sprintf("%%-%ds", $wid * 3);
     3229    my $tmpl = 'H2' x $wid; # ('(H2)*' would have been nice, but older perl versions don't support it)
    25613230    my $i;
    25623231    for ($i=0; $i<$len; $i+=$wid) {
    2563         $wid > $len-$i and $wid = $len-$i;
     3232        $wid > $len-$i and $wid = $len-$i, $tmpl = 'H2' x $wid;
    25643233        printf $out "$prefix%8.4x: ", $addr+$i;
    25653234        my $dat = substr($$dataPt, $i+$start, $wid);
    2566         my $s = join(' ',(unpack('H*',$dat) =~ /../g));
     3235        my $s = join(' ', unpack($tmpl, $dat));
    25673236        printf $out $format, $s;
    25683237        $dat =~ tr /\x00-\x1f\x7f-\xff/./;
     
    25903259{
    25913260    my ($self, $tagID, $tagInfo, %parms) = @_;
    2592     my $verbose = $self->{OPTIONS}->{Verbose};
    2593     my $out = $self->{OPTIONS}->{TextOut};
    2594     my ($tag, $tagDesc, $line, $hexID);
     3261    my $verbose = $self->{OPTIONS}{Verbose};
     3262    my $out = $self->{OPTIONS}{TextOut};
     3263    my ($tag, $line, $hexID);
    25953264
    25963265    # generate hex number if tagID is numerical
     
    26053274    } else {
    26063275        my $prefix;
    2607         $prefix = $parms{Table}->{TAG_PREFIX} if $parms{Table};
     3276        $prefix = $parms{Table}{TAG_PREFIX} if $parms{Table};
    26083277        if ($prefix or $hexID) {
    26093278            $prefix = 'Unknown' unless $prefix;
     
    26233292    if (defined $index) {
    26243293        $line .= $index . ') ';
    2625         $line .= ' ' if $index < 10;
     3294        $line .= ' ' if length($index) < 2;
    26263295        $indent .= '    '; # indent everything else to align with tag name
    26273296    }
     
    26293298    if ($tagInfo and $$tagInfo{SubDirectory}) {
    26303299        $line .= ' (SubDirectory) -->';
    2631     } elsif (defined $parms{Value}) {
    2632         $line .= ' = ' . $self->Printable($parms{Value});
    2633     } elsif ($dataPt) {
    2634         my $start = $parms{Start} || 0;
    2635         $line .= ' = ' . $self->Printable(substr($$dataPt,$start,$size));
     3300    } else {
     3301        my $maxLen = 90 - length($line);
     3302        if (defined $parms{Value}) {
     3303            $line .= ' = ' . $self->Printable($parms{Value}, $maxLen);
     3304        } elsif ($dataPt) {
     3305            my $start = $parms{Start} || 0;
     3306            $line .= ' = ' . $self->Printable(substr($$dataPt,$start,$size), $maxLen);
     3307        }
    26363308    }
    26373309    print $out "$line\n";
     
    26413313        $parms{DataPt} or defined $size or $tagID =~ /\//))
    26423314    {
    2643         $line = $indent;
    2644         $line .= '- Tag ' . ($hexID ? $hexID : "'$tagID'");
     3315        $line = $indent . '- Tag ';
     3316        if ($hexID) {
     3317            $line .= $hexID;
     3318        } else {
     3319            $tagID =~ s/([\0-\x1f\x7f-\xff])/sprintf('\\x%.2x',ord $1)/ge;
     3320            $line .= "'$tagID'";
     3321        }
    26453322        $line .= $parms{Extra} if defined $parms{Extra};
    26463323        my $format = $parms{Format};
     
    26653342        $parms{Out} = $out;
    26663343        $parms{Prefix} = $indent;
    2667         # limit dump length unless verbose > 3
    2668         $parms{MaxLen} = 96 unless $verbose > 3;
     3344        # limit dump length if Verbose < 5
     3345        $parms{MaxLen} = $verbose == 3 ? 96 : 2048 if $verbose < 5;
    26693346        HexDump($dataPt, $size, %parms);
    26703347    }
     
    26823359    my $trailer = $$dirInfo{DirName} || 'Unknown';
    26833360    my $pos = $$dirInfo{DataPos};
    2684     my $verbose = $self->{OPTIONS}->{Verbose};
     3361    my $verbose = $self->{OPTIONS}{Verbose};
    26853362    my $htmlDump = $self->{HTML_DUMP};
    26863363    my ($buff, $buf2);
     
    27003377            my $desc = "$trailer trailer";
    27013378            $desc = "[$desc]" if $trailer eq 'Unknown';
    2702             $self->HtmlDump($pos, $num, $desc, undef, 0x08);
     3379            $self->HDump($pos, $num, $desc, undef, 0x08);
    27033380            last;
    27043381        }
    2705         my $out = $self->{OPTIONS}->{TextOut};
     3382        my $out = $self->{OPTIONS}{TextOut};
    27063383        printf $out "$trailer trailer (%d bytes at offset 0x%.4x):\n", $size, $pos;
    27073384        last unless $verbose > 2;
     
    27253402        HexDump(\$buff, undef, Addr => $pos, Out => $out);
    27263403        if (defined $buf2) {
    2727             print "    [snip ", $size - $num * 2, " bytes]\n";
     3404            print $out "    [snip ", $size - $num * 2, " bytes]\n";
    27283405            HexDump(\$buf2, undef, Addr => $pos + $size - $num, Out => $out);
    27293406        }
     
    27423419    my $pos = $$dirInfo{DataPos};
    27433420    my $endPos = $pos + $$dirInfo{DirLen};
    2744     # account for preview image trailer
    2745     my $prePos = $self->{VALUE}->{PreviewImageStart};
    2746     my $preLen = $self->{VALUE}->{PreviewImageLength};
    2747     if ($prePos and $preLen and $prePos + $preLen > $pos) {
    2748         # dump data before preview image
    2749         if ($prePos > $pos) {
     3421    # account for preview/MPF image trailer
     3422    my $prePos = $self->{VALUE}{PreviewImageStart} || $$self{PreviewImageStart};
     3423    my $preLen = $self->{VALUE}{PreviewImageLength} || $$self{PreviewImageLength};
     3424    my $tag = 'PreviewImage';
     3425    my $mpImageNum = 0;
     3426    my (%image, $lastOne);
     3427    for (;;) {
     3428        # add to Preview block list if valid and in the trailer
     3429        $image{$prePos} = [$tag, $preLen] if $prePos and $preLen and $prePos+$preLen > $pos;
     3430        last if $lastOne;   # checked all images
     3431        # look for MPF images (in the the proper order)
     3432        ++$mpImageNum;
     3433        $prePos = $self->{VALUE}{"MPImageStart ($mpImageNum)"};
     3434        if (defined $prePos) {
     3435            $preLen = $self->{VALUE}{"MPImageLength ($mpImageNum)"};
     3436        } else {
     3437            $prePos = $self->{VALUE}{'MPImageStart'};
     3438            $preLen = $self->{VALUE}{'MPImageLength'};
     3439            $lastOne = 1;
     3440        }
     3441        $tag = "MPImage$mpImageNum";
     3442    }
     3443    # dump trailer sections in order
     3444    $image{$endPos} = [ '', 0 ];    # add terminator "image"
     3445    foreach $prePos (sort { $a <=> $b } keys %image) {
     3446        if ($pos < $prePos) {
     3447            # dump unknown trailer data
    27503448            $$dirInfo{DirName} = 'Unknown';
    2751             $$dirInfo{DirLen}  = $prePos - $pos;
     3449            $$dirInfo{DataPos} = $pos;
     3450            $$dirInfo{DirLen} = $prePos - $pos;
    27523451            $self->DumpTrailer($dirInfo);
    27533452        }
    2754         # dump preview image if verbose (it is htmlDump'd by ExtractImage)
    2755         if ($self->{OPTIONS}->{Verbose}) {
    2756             $$dirInfo{DirName} = 'PreviewImage';
     3453        ($tag, $preLen) = @{$image{$prePos}};
     3454        last unless $preLen;
     3455        # dump image if verbose (it is htmlDump'd by ExtractImage)
     3456        if ($self->{OPTIONS}{Verbose}) {
     3457            $$dirInfo{DirName} = $tag;
    27573458            $$dirInfo{DataPos} = $prePos;
    27583459            $$dirInfo{DirLen}  = $preLen;
    27593460            $self->DumpTrailer($dirInfo);
    27603461        }
    2761         return if $prePos + $preLen >= $endPos;
    2762         # set dirInfo for remaining unknown data
    2763         $$dirInfo{DataPos} = $prePos + $preLen;
    2764         $$dirInfo{DirLen} = $endPos - $$dirInfo{DataPos};
    2765     }
    2766     # dump unknown trailer
    2767     $$dirInfo{DirName} = 'Unknown';
    2768     $self->DumpTrailer($dirInfo);
     3462        $pos = $prePos + $preLen;
     3463    }
    27693464}
    27703465
     
    27903485{
    27913486    my ($self, $name, $entries, $size) = @_;
    2792     return unless $self->{OPTIONS}->{Verbose};
     3487    return unless $self->{OPTIONS}{Verbose};
    27933488    if (ref $name eq 'HASH') {
    27943489        $size = $$name{DirLen} unless $size;
     
    27963491    }
    27973492    my $indent = substr($self->{INDENT}, 0, -2);
    2798     my $out = $self->{OPTIONS}->{TextOut};
    2799     my $str;
    2800     if ($entries) {
    2801         $str = " with $entries entries";
    2802     } elsif ($size) {
    2803         $str = ", $size bytes";
    2804     } else {
    2805         $str = '';
    2806     }
     3493    my $out = $self->{OPTIONS}{TextOut};
     3494    my $str = $entries ? " with $entries entries" : '';
     3495    $str .= ", $size bytes" if $size;
    28073496    print $out "$indent+ [$name directory$str]\n";
     3497}
     3498
     3499#------------------------------------------------------------------------------
     3500# Print verbose value while writing
     3501# Inputs: 0) ExifTool object ref, 1) heading "ie. '+ IPTC:Keywords',
     3502#         2) value, 3) [optional] extra text after value
     3503sub VerboseValue($$$;$)
     3504{
     3505    return unless $_[0]{OPTIONS}{Verbose} > 1;
     3506    my ($self, $str, $val, $xtra) = @_;
     3507    my $out = $self->{OPTIONS}{TextOut};
     3508    $xtra or $xtra = '';
     3509    my $maxLen = 81 - length($str) - length($xtra);
     3510    $val = $self->Printable($val, $maxLen);
     3511    print $out "    $str = '$val'$xtra\n";
    28083512}
    28093513
     
    28873591
    28883592#------------------------------------------------------------------------------
    2889 # Convert Unicode characters to Windows Latin1 (cp1252)
    2890 # Inputs: 0) 16-bit Unicode character string, 1) unpack format
    2891 #         3) optional ExifTool ref to set warning on encoding error
    2892 # Returns: 8-bit Windows Latin1 encoded string (truncates at null terminator)
    2893 my %unicode2latin = (
    2894     0x20ac => 0x80,  0x0160 => 0x8a,  0x2013 => 0x96,
    2895     0x201a => 0x82,  0x2039 => 0x8b,  0x2014 => 0x97,
    2896     0x0192 => 0x83,  0x0152 => 0x8c,  0x02dc => 0x98,
    2897     0x201e => 0x84,  0x017d => 0x8e,  0x2122 => 0x99,
    2898     0x2026 => 0x85,  0x2018 => 0x91,  0x0161 => 0x9a,
    2899     0x2020 => 0x86,  0x2019 => 0x92,  0x203a => 0x9b,
    2900     0x2021 => 0x87,  0x201c => 0x93,  0x0153 => 0x9c,
    2901     0x02c6 => 0x88,  0x201d => 0x94,  0x017e => 0x9e,
    2902     0x2030 => 0x89,  0x2022 => 0x95,  0x0178 => 0x9f,
    2903 );
    2904 sub Unicode2Latin($$;$)
    2905 {
    2906     my ($val, $fmt) = @_;
    2907     my @uni = unpack("$fmt*",$val);
    2908     foreach (@uni) {
    2909         next if $_ <= 0xff;
    2910         $_ = $unicode2latin{$_};
    2911         next if $_;
    2912         $_ = ord('?');  # set to '?'
    2913         my $self = $_[2];
    2914         if ($self and not $$self{LatinWarning}) {
    2915             $self->Warn('Some character(s) could not be encoded in Latin');
    2916             $$self{LatinWarning} = 1;
    2917         }
    2918     }
    2919     # repack as a Latin string
    2920     my $outVal = pack('C*', @uni);
    2921     $outVal =~ s/\0.*//s;    # truncate at null terminator
    2922     return $outVal;
    2923 }
    2924 
    2925 #------------------------------------------------------------------------------
    2926 # Convert Windows Latin1 characters to Unicode
    2927 # Inputs: 0) 8-bit Windows Latin1 character string (cp1252), 1) unpack format
    2928 # Returns: 16-bit Unicode character string
    2929 my %latin2unicode;
    2930 sub Latin2Unicode($$)
    2931 {
    2932     # create reverse lookup table if necessary
    2933     unless (%latin2unicode) {
    2934         foreach (keys %unicode2latin) {
    2935             $latin2unicode{$unicode2latin{$_}} = $_;
    2936         }
    2937     }
    2938     my ($val, $fmt) = @_;
    2939     my @latin = unpack('C*', $val);
    2940     foreach (@latin) {
    2941         $_ = $latin2unicode{$_} if $latin2unicode{$_};
    2942     }
    2943     # repack as a 16-bit unicode string
    2944     my $outVal = pack("$fmt*", @latin);
    2945     return $outVal;
    2946 }
    2947 
    2948 #------------------------------------------------------------------------------
    2949 # Convert Unicode characters to UTF-8
    2950 # Inputs: 0) Unicode character string, 1) Unicode character format (n,v,N,V)
    2951 # Returns: UTF-8 encoded string (truncates at null terminator)
    2952 sub Unicode2UTF8($$)
    2953 {
    2954     my ($val, $fmt) = @_;
    2955     my $outVal;
    2956     if ($] >= 5.006001) {
    2957         # let Perl do it
    2958         $outVal = pack('C0U*',unpack("$fmt*",$val));
     3593# Inverse date/time print conversion (reformat to YYYY:mm:dd HH:MM:SS[.ss][+-HH:MM|Z])
     3594# Inputs: 0) ExifTool object ref, 1) Date/Time string, 2) timezone flag:
     3595#               0     - remove timezone and sub-seconds if they exist
     3596#               1     - add timezone if it doesn't exist
     3597#               undef - leave timezone alone
     3598#         3) flag to allow date-only (YYYY, YYYY:mm or YYYY:mm:dd) or time without seconds
     3599# Returns: formatted date/time string (or undef and issues warning on error)
     3600# Notes: currently accepts different separators, but doesn't use DateFormat yet
     3601sub InverseDateTime($$;$$)
     3602{
     3603    my ($self, $val, $tzFlag, $dateOnly) = @_;
     3604    my ($rtnVal, $tz);
     3605    # strip off timezone first if it exists
     3606    if ($val =~ s/([+-])(\d{1,2}):?(\d{2})$//i) {
     3607        $tz = sprintf("$1%.2d:$3", $2);
     3608    } elsif ($val =~ s/Z$//i) {
     3609        $tz = 'Z';
    29593610    } else {
    2960         # do it ourself
    2961         $outVal = PackUTF8(unpack("$fmt*",$val));
    2962     }
    2963     $outVal =~ s/\0.*//s;    # truncate at null terminator
    2964     return $outVal;
    2965 }
    2966 
    2967 #------------------------------------------------------------------------------
    2968 # Convert UTF-8 encoded string to Unicode string
    2969 # Input: 0) UTF-8 string, 1) Unicode format, 2) optional ExifTool ref for warnings
    2970 # Returns: Unicode character string in specified format
    2971 sub UTF82Unicode($$;$)
    2972 {
    2973     my ($str, $fmt, $exifTool) = @_;
    2974     undef $evalWarning;
    2975     if ($] >= 5.006001) {
    2976         # handle warnings from malformed UTF-8
    2977         local $SIG{'__WARN__'} = \&SetWarning;
    2978         # repack UTF-8 string in specified format
    2979         $str = pack("$fmt*", unpack('U0U*',$str));
    2980     } else {
    2981         # do it ourself
    2982         $str = pack("$fmt*", UnpackUTF8($str));
    2983     }
    2984     if ($evalWarning and $exifTool and not $$exifTool{WarnBadUTF8}) {
    2985         $exifTool->Warn('Malformed UTF-8 character(s)');
    2986         $$exifTool{WarnBadUTF8} = 1;
    2987     }
    2988     return $str;
    2989 }
    2990 
    2991 #------------------------------------------------------------------------------
    2992 # Convert 16-bit unicode character string to 8-bit (Latin or UTF-8)
    2993 # Inputs: 0) ExifTool ref, 1) 16-bit unicode string (in specified byte order)
    2994 #         2) Optional byte order (current byte order used if not specified)
    2995 # Returns: 8-bit character string (truncates at null terminator)
    2996 my %unpackShort = ( 'II' => 'v', 'MM' => 'n' );
    2997 sub Unicode2Charset($$;$) {
    2998     my ($self, $val, $byteOrder) = @_;
    2999     # check for (and remove) byte order mark and set byte order accordingly if it exists
    3000     $val =~ s/^(\xff\xfe|\xfe\xff)// and $byteOrder = ($1 eq "\xff\xfe") ? 'MM' : 'II';
    3001     my $fmt = $unpackShort{$byteOrder || GetByteOrder()};
    3002     # convert to Latin if specified or if no UTF-8 support in this Perl version
    3003     if ($self->Options('Charset') eq 'Latin') {
    3004         return Unicode2Latin($val, $fmt, $self);
    3005     } else {
    3006         return Unicode2UTF8($val, $fmt);
    3007     }
    3008 }
    3009 
    3010 #------------------------------------------------------------------------------
    3011 # Convert 8-bit character string to 16-bit unicode
    3012 # Inputs: 0) ExifTool ref, 1) Latin or UTF-8 string, 2) optional byte order
    3013 # Returns: 16-bit unicode character string (in specified byte order)
    3014 sub Charset2Unicode($$;$)
    3015 {
    3016     my ($self, $val, $byteOrder) = @_;
    3017     my $fmt = $unpackShort{$byteOrder || GetByteOrder()};
    3018     if ($self->Options('Charset') eq 'Latin') {
    3019         return Latin2Unicode($val, $fmt);
    3020     } else {
    3021         return UTF82Unicode($val, $fmt, $self);
    3022     }
     3611        $tz = '';
     3612    }
     3613    # strip of sub seconds
     3614    my $fs = $val =~ /(\.\d+)$/ ? $1 : '';
     3615    if ($val =~ /(\d{4})/g) {           # get YYYY
     3616        my $yr = $1;
     3617        my @a = ($val =~ /\d{2}/g);     # get mm, dd, HH, and maybe MM, SS
     3618        if (@a >= 3) {
     3619            my $ss = $a[4];             # get SS
     3620            push @a, '00' while @a < 5; # add MM, SS if not given
     3621            # add/remove timezone if necessary
     3622            if ($tzFlag) {
     3623                if (not $tz) {
     3624                    if (eval 'require Time::Local') {
     3625                        # determine timezone offset for this time
     3626                        my @args = ($a[4],$a[3],$a[2],$a[1],$a[0]-1,$yr-1900);
     3627                        my $diff = Time::Local::timegm(@args) - TimeLocal(@args);
     3628                        $tz = TimeZoneString($diff / 60);
     3629                    } else {
     3630                        $tz = 'Z';  # don't know time zone
     3631                    }
     3632                }
     3633            } elsif (defined $tzFlag) {
     3634                $tz = $fs = ''; # remove timezone and sub-seconds
     3635            }
     3636            if (defined $ss) {
     3637                $ss = ":$ss";
     3638            } elsif ($dateOnly) {
     3639                $ss = '';
     3640            } else {
     3641                $ss = ':00';
     3642            }
     3643            # construct properly formatted date/time string
     3644            $rtnVal = "$yr:$a[0]:$a[1] $a[2]:$a[3]$ss$fs$tz";
     3645        } elsif ($dateOnly) {
     3646            $rtnVal = join ':', $yr, @a;
     3647        }
     3648    }
     3649    $rtnVal or warn "Invalid date/time (use YYYY:mm:dd HH:MM:SS[.ss][+/-HH:MM|Z])\n";
     3650    return $rtnVal;
     3651}
     3652
     3653#------------------------------------------------------------------------------
     3654# Set byte order according to our current preferences
     3655# Inputs: 0) ExifTool object ref
     3656# Returns: new byte order ('II' or 'MM') and sets current byte order
     3657# Notes: takes the first of the following that is valid:
     3658#  1) ByteOrder option
     3659#  2) new value for ExifByteOrder
     3660#  3) makenote byte order from last file read
     3661#  4) big endian
     3662sub SetPreferredByteOrder($)
     3663{
     3664    my $self = shift;
     3665    my $byteOrder = $self->Options('ByteOrder') ||
     3666                    $self->GetNewValues('ExifByteOrder') ||
     3667                    $self->{MAKER_NOTE_BYTE_ORDER} || 'MM';
     3668    unless (SetByteOrder($byteOrder)) {
     3669        warn "Invalid byte order '$byteOrder'\n" if $self->Options('Verbose');
     3670        $byteOrder = $self->{MAKER_NOTE_BYTE_ORDER} || 'MM';
     3671        SetByteOrder($byteOrder);
     3672    }
     3673    return GetByteOrder();
    30233674}
    30243675
     
    30363687
    30373688#------------------------------------------------------------------------------
    3038 # Convert a floating point number into a rational
     3689# Convert a floating point number (or 'inf' or 'undef' or a fraction) into a rational
    30393690# Inputs: 0) floating point number, 1) optional maximum value (defaults to 0x7fffffff)
    30403691# Returns: numerator, denominator (in list context)
    3041 # Notes: these routines were a bit tricky, but fun to write!
     3692# Notes:
     3693# - the returned rational will be accurate to at least 8 significant figures if possible
     3694# - ie. an input of 3.14159265358979 returns a rational of 104348/33215,
     3695#   which equals    3.14159265392142 and is accurate to 10 significant figures
     3696# - these routines were a bit tricky, but fun to write!
    30423697sub Rationalize($;$)
    30433698{
    30443699    my $val = shift;
     3700    return (1, 0) if $val eq 'inf';
     3701    return (0, 0) if $val eq 'undef';
     3702    return ($1,$2) if $val =~ m{^([-+]?\d+)/(\d+)$}; # accept fractional values
    30453703    # Note: Just testing "if $val" doesn't work because '0.0' is true!  (ugghh!)
    30463704    return (0, 1) if $val == 0;
     
    31023760}
    31033761sub SetRational32s(@) {
    3104     my ($numer,$denom) = Rationalize($_[0],0xffff);
     3762    my ($numer,$denom) = Rationalize($_[0],0x7fff);
    31053763    my $val = Set16s($numer) . Set16u($denom);
    31063764    $_[1] and substr(${$_[1]}, $_[2], length($val)) = $val;
     
    31413799    int16s => \&Set16s,
    31423800    int16u => \&Set16u,
     3801    int16uRev => \&Set16uRev,
    31433802    int32s => \&Set32s,
    31443803    int32u => \&Set32u,
     
    31993858            if ($format =~ /^int/) {
    32003859                return undef unless IsInt($val) or IsHex($val);
    3201             } else {
    3202                 return undef unless IsFloat($val);
     3860            } elsif (not IsFloat($val)) {
     3861                return undef unless $format =~ /^rational/ and ($val eq 'inf' or
     3862                    $val eq 'undef' or IsRational($val));
    32033863            }
    32043864            $packed .= &$proc($val);
     
    32533913            if ($lookup) {
    32543914                $bit = ReverseLookup($val, $lookup);
     3915                # (Note: may get non-numerical $bit values from Unknown() tags)
    32553916                unless (defined $bit) {
    32563917                    if ($val =~ /\[(\d+)\]/) { # numerical bit specification
     
    32653926                $bit = $val;
    32663927            }
    3267             return (undef, 'bit number too high') if $bit >= $num;
     3928            unless (IsInt($bit) and $bit < $num) {
     3929                return undef unless wantarray;
     3930                return (undef, IsInt($bit) ? 'bit number too high' : 'not an integer');
     3931            }
    32683932            my $word = int($bit / $bits);
    32693933            $outVal[$word] |= (1 << ($bit - $word * $bits));
     
    33043968
    33053969#------------------------------------------------------------------------------
    3306 # Read/rewrite trailer information (including multiple trailers)
    3307 # Inputs: 0) ExifTool object ref, 1) DirInfo ref:
    3308 # - requires RAF and DirName
    3309 # - OutFile is a scalar reference for writing
    3310 # - scans from current file position if ScanForAFCP is set
    3311 # Returns: 1 if trailer was processed or couldn't be processed (or written OK)
    3312 #          0 if trailer was recognized but offsets need fixing (or write error)
    3313 # - DirName, DirLen, DataPos, Offset, Fixup and OutFile are updated
    3314 # - preserves current file position and byte order
    3315 sub ProcessTrailers($$)
    3316 {
    3317     my ($self, $dirInfo) = @_;
    3318     my $dirName = $$dirInfo{DirName};
    3319     my $outfile = $$dirInfo{OutFile};
    3320     my $offset = $$dirInfo{Offset} || 0;
    3321     my $fixup = $$dirInfo{Fixup};
    3322     my $raf = $$dirInfo{RAF};
    3323     my $pos = $raf->Tell();
    3324     my $byteOrder = GetByteOrder();
    3325     my $success = 1;
    3326 
    3327     for (;;) { # loop through all trailers
    3328         require "Image/ExifTool/$dirName.pm";
    3329         my $proc = "Image::ExifTool::${dirName}::Process$dirName";
    3330         my $outBuff;
    3331         if ($outfile) {
    3332             # write to local buffer so we can add trailer in proper order later
    3333             $$outfile and $$dirInfo{OutFile} = \$outBuff, $outBuff = '';
    3334             # must generate new fixup if necessary so we can shift
    3335             # the old fixup separately after we prepend this trailer
    3336             delete $$dirInfo{Fixup};
    3337         }
    3338         delete $$dirInfo{DirLen};       # reset trailer length
    3339         $$dirInfo{Offset} = $offset;    # set offset from end of file
    3340         $$dirInfo{Trailer} = 1;         # set Trailer flag in case proc cares
    3341 
    3342         # read or write this trailer
    3343         # (proc takes Offset as offset from end of trailer to end of file,
    3344         #  and returns DataPos and DirLen, and Fixup if applicable)
    3345         no strict 'refs';
    3346         my $result = &$proc($self, $dirInfo);
    3347         use strict 'refs';
    3348 
    3349         if ($outfile) {
    3350             if ($result > 0) {
    3351                 if ($outBuff) {
    3352                     # write trailers to OutFile in original order
    3353                     $$outfile = $outBuff . $$outfile;
    3354                     # must adjust old fixup start if it exists
    3355                     $$fixup{Start} += length($outBuff) if $fixup;
    3356                     $outBuff = '';      # free memory
    3357                 }
    3358                 if ($fixup) {
    3359                     # add new fixup information if any
    3360                     $fixup->AddFixup($$dirInfo{Fixup}) if $$dirInfo{Fixup};
    3361                 } else {
    3362                     $fixup = $$dirInfo{Fixup};  # save fixup
    3363                 }
    3364             } else {
    3365                 $success = 0 if $self->Error("Error rewriting $dirName trailer", 1);
    3366                 last;
    3367             }
    3368         } elsif ($result < 0) {
    3369             # can't continue if we must scan for this trailer
    3370             $success = 0;
    3371             last;
    3372         }
    3373         last unless $result > 0 and $$dirInfo{DirLen};
    3374         # look for next trailer
    3375         $offset += $$dirInfo{DirLen};
    3376         my $nextTrail = IdentifyTrailer($raf, $offset) or last;
    3377         $dirName = $$dirInfo{DirName} = $$nextTrail{DirName};
    3378         $raf->Seek($pos, 0);
    3379     }
    3380     SetByteOrder($byteOrder);       # restore original byte order
    3381     $raf->Seek($pos, 0);            # restore original file position
    3382     $$dirInfo{OutFile} = $outfile;  # restore original outfile
    3383     $$dirInfo{Offset} = $offset;    # return offset to start of first trailer
    3384     $$dirInfo{Fixup} = $fixup;      # return fixup information
    3385     return $success;
    3386 }
    3387 
    3388 #------------------------------------------------------------------------------
    33893970# Write trailer buffer to file (applying fixups if necessary)
    33903971# Inputs: 0) ExifTool object ref, 1) trailer dirInfo ref, 2) output file ref
     
    33933974{
    33943975    my ($self, $trailInfo, $outfile) = @_;
    3395     if ($self->{DEL_GROUP}->{Trailer}) {
     3976    if ($self->{DEL_GROUP}{Trailer}) {
    33963977        $self->VPrint(0, "  Deleting trailer ($$trailInfo{Offset} bytes)\n");
    33973978        ++$self->{CHANGED};
     
    34043985        if ($pos > 0) {
    34053986            # shift offsets to final AFCP location and write it out
    3406             $trailInfo->{Fixup}->{Shift} += $pos;
     3987            $trailInfo->{Fixup}{Shift} += $pos;
    34073988            $trailInfo->{Fixup}->ApplyFixup($trailPt);
    34083989        } else {
     
    34304011    my $type;
    34314012    foreach $type (@types) {
    3432         next unless $self->{NEW_VALUE}->{$Image::ExifTool::Extra{$type}};
     4013        next unless $self->{NEW_VALUE}{$Image::ExifTool::Extra{$type}};
    34334014        my $val = $self->GetNewValues($type) or next;
    34344015        my $verb = $trailPt ? 'Writing' : 'Adding';
     
    34804061
    34814062#------------------------------------------------------------------------------
     4063# Write XMP segment(s) to JPEG file
     4064# Inputs: 0) ExifTool object ref, 1) outfile ref, 2) XMP data ref,
     4065#         3) extended XMP data ref, 4) 32-char extended XMP GUID (or undef if no extended data)
     4066# Returns: true on success, false on write error
     4067sub WriteMultiXMP($$$$$)
     4068{
     4069    my ($self, $outfile, $dataPt, $extPt, $guid) = @_;
     4070    my $success = 1;
     4071
     4072    # write main XMP segment
     4073    my $size = length($$dataPt) + length($xmpAPP1hdr);
     4074    if ($size > $maxXMPLen) {
     4075        $self->Error("XMP block too large for JPEG segment! ($size bytes)", 1);
     4076        return 1;
     4077    }
     4078    my $app1hdr = "\xff\xe1" . pack('n', $size + 2);
     4079    Write($outfile, $app1hdr, $xmpAPP1hdr, $$dataPt) or $success = 0;
     4080    # write extended XMP segment(s) if necessary
     4081    if (defined $guid) {
     4082        $size = length($$extPt);
     4083        my $maxLen = $maxXMPLen - 75; # maximum size without 75 byte header
     4084        my $off;
     4085        for ($off=0; $off<$size; $off+=$maxLen) {
     4086            # header(75) = signature(35) + guid(32) + size(4) + offset(4)
     4087            my $len = $size - $off;
     4088            $len = $maxLen if $len > $maxLen;
     4089            $app1hdr = "\xff\xe1" . pack('n', $len + 75 + 2);
     4090            $self->VPrint(0, "Writing extended XMP segment ($len bytes)\n");
     4091            Write($outfile, $app1hdr, $xmpExtAPP1hdr, $guid, pack('N2', $size, $off),
     4092                  substr($$extPt, $off, $len)) or $success = 0;
     4093        }
     4094    }
     4095    return $success;
     4096}
     4097
     4098#------------------------------------------------------------------------------
    34824099# WriteJPEG : Write JPEG image
    34834100# Inputs: 0) ExifTool object reference, 1) dirInfo reference
     
    34904107    my $raf = $$dirInfo{RAF};
    34914108    my ($ch,$s,$length);
    3492     my $verbose = $self->{OPTIONS}->{Verbose};
    3493     my $out = $self->{OPTIONS}->{TextOut};
     4109    my $verbose = $self->{OPTIONS}{Verbose};
     4110    my $out = $self->{OPTIONS}{TextOut};
    34944111    my $rtnVal = 0;
    34954112    my ($err, %doneDir);
     
    35094126    my $editDirs = $self->{EDIT_DIRS};
    35104127    my $delGroup = $self->{DEL_GROUP};
     4128    my $path = $$self{PATH};
     4129    my $pn = scalar @$path;
    35114130
    35124131    # set input record separator to 0xff (the JPEG marker) to make reading quicker
    3513     my $oldsep = $/;
    3514     $/ = "\xff";
     4132    local $/ = "\xff";
    35154133#
    35164134# pre-scan image to determine if any create-able segment already exists
     
    35494167                $raf->Read($s, $n) == $n or last;
    35504168                $len -= $n;
     4169                # (Note: only necessary to recognize APP segments that we can create)
    35514170                if ($marker == 0xe0) {
    3552                     $s =~ /^JFIF\0/        and $dirName = 'JFIF';
    3553                     $s =~ /^JFXX\0\x10/    and $dirName = 'JFXX';
     4171                    $s =~ /^JFIF\0/         and $dirName = 'JFIF';
     4172                    $s =~ /^JFXX\0\x10/     and $dirName = 'JFXX';
    35544173                } elsif ($marker == 0xe1) {
    3555                     $s =~ /^$exifAPP1hdr/  and $dirName = 'IFD0';
    3556                     $s =~ /^$xmpAPP1hdr/   and $dirName = 'XMP';
     4174                    $s =~ /^$exifAPP1hdr/   and $dirName = 'IFD0';
     4175                    $s =~ /^$xmpAPP1hdr/    and $dirName = 'XMP';
     4176                    $s =~ /^$xmpExtAPP1hdr/ and $dirName = 'XMP';
    35574177                } elsif ($marker == 0xe2) {
    3558                     $s =~ /^ICC_PROFILE\0/ and $dirName = 'ICC_Profile';
     4178                    $s =~ /^ICC_PROFILE\0/  and $dirName = 'ICC_Profile';
    35594179                } elsif ($marker == 0xec) {
    3560                     $s =~ /^Ducky/         and $dirName = 'Ducky';
     4180                    $s =~ /^Ducky/          and $dirName = 'Ducky';
    35614181                } elsif ($marker == 0xed) {
    3562                     $s =~ /^$psAPP13hdr/   and $dirName = 'Photoshop';
     4182                    $s =~ /^$psAPP13hdr/    and $dirName = 'Photoshop';
    35634183                }
    35644184                # initialize doneDir as a flag that the directory exists
     
    35804200# re-write the image
    35814201#
    3582     my ($combinedSegData, $segPos);
     4202    my ($combinedSegData, $segPos, %extendedXMP);
    35834203    # read through each segment in the JPEG file
    35844204    Marker: for (;;) {
     
    36164236        my $markerName = JpegMarkerName($marker);
    36174237        my $dirName = shift @dirOrder;      # get directory name
     4238        $$path[$pn] = $markerName;
    36184239#
    36194240# create all segments that must come before this one
     
    36354256                    DirLen   => length $jfif,
    36364257                );
     4258                # must temporarily remove JFIF from DEL_GROUP so we can
     4259                # delete JFIF and add it back again in a single step
     4260                my $delJFIF = $$delGroup{JFIF};
     4261                delete $$delGroup{JFIF};
    36374262                my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
     4263                $$delGroup{JFIF} = $delJFIF if defined $delJFIF;
    36384264                if (defined $newData and length $newData) {
    36394265                    my $app0hdr = "\xff\xe0" . pack('n', length($newData) + 7);
     
    36504276                $self->{TIFF_TYPE} = 'APP1';
    36514277                my $tagTablePtr = GetTagTable('Image::ExifTool::Exif::Main');
    3652                 # use specified byte ordering or ordering from maker notes if set
    3653                 my $byteOrder = $self->Options('ByteOrder') ||
    3654                     $self->GetNewValues('ExifByteOrder') || $self->{MAKER_NOTE_BYTE_ORDER} || 'MM';
    3655                 unless (SetByteOrder($byteOrder)) {
    3656                     warn "Invalid byte order '$byteOrder'\n";
    3657                     $byteOrder = $self->{MAKER_NOTE_BYTE_ORDER} || 'MM';
    3658                     SetByteOrder($byteOrder);
    3659                 }
    36604278                my %dirInfo = (
    3661                     NewDataPos => 8,    # new data will come after TIFF header
    36624279                    DirName => 'IFD0',
    3663                     Parent  => $markerName,
     4280                    Parent  => 'APP1',
    36644281                );
    3665                 my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
     4282                my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr, \&WriteTIFF);
    36664283                if (defined $buff and length $buff) {
    3667                     my $tiffHdr = $byteOrder . Set16u(42) . Set32u(8); # standard TIFF header
    3668                     my $size = length($buff) + length($tiffHdr) + length($exifAPP1hdr);
     4284                    my $size = length($buff) + length($exifAPP1hdr);
    36694285                    if ($size <= $maxSegmentLen) {
    36704286                        # switch to buffered output if required
    3671                         if ($self->{PREVIEW_INFO} and not $oldOutfile) {
     4287                        if (($$self{PREVIEW_INFO} or $$self{LeicaTrailer}) and not $oldOutfile) {
    36724288                            $writeBuffer = '';
    36734289                            $oldOutfile = $outfile;
    36744290                            $outfile = \$writeBuffer;
    3675                             # account for segment,EXIF and TIFF headers
    3676                             $self->{PREVIEW_INFO}->{Fixup}->{Start} += 18;
     4291                            # account for segment, EXIF and TIFF headers
     4292                            $$self{PREVIEW_INFO}{Fixup}{Start} += 18 if $$self{PREVIEW_INFO};
     4293                            $$self{LeicaTrailer}{Fixup}{Start} += 18 if $$self{LeicaTrailer};
    36774294                        }
    36784295                        # write the new segment with appropriate header
    36794296                        my $app1hdr = "\xff\xe1" . pack('n', $size + 2);
    3680                         Write($outfile,$app1hdr,$exifAPP1hdr,$tiffHdr,$buff) or $err = 1;
     4297                        Write($outfile,$app1hdr,$exifAPP1hdr,$buff) or $err = 1;
    36814298                    } else {
    36824299                        delete $self->{PREVIEW_INFO};
     
    36934310                my $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
    36944311                my %dirInfo = (
    3695                     Parent => $markerName,
     4312                    Parent => 'APP13',
    36964313                );
    36974314                my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
     
    37094326                my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
    37104327                my %dirInfo = (
    3711                     Parent   => $markerName,
     4328                    Parent      => 'APP1',
     4329                    # specify MaxDataLen so XMP is split if required
     4330                    MaxDataLen  => $maxXMPLen - length($xmpAPP1hdr),
    37124331                );
    37134332                my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
    37144333                if (defined $buff and length $buff) {
    3715                     my $size = length($buff) + length($xmpAPP1hdr);
    3716                     if ($size <= $maxSegmentLen) {
    3717                         # write the new segment with appropriate header
    3718                         my $app1hdr = "\xff\xe1" . pack('n', $size + 2);
    3719                         Write($outfile, $app1hdr, $xmpAPP1hdr, $buff) or $err = 1;
    3720                     } else {
    3721                         $self->Warn("XMP APP1 segment too large! ($size bytes)");
    3722                     }
     4334                    WriteMultiXMP($self, $outfile, \$buff, $dirInfo{ExtendedXMP},
     4335                                  $dirInfo{ExtendedGUID}) or $err = 1;
    37234336                }
    37244337            }
     
    37324345                my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
    37334346                my %dirInfo = (
    3734                     Parent   => $markerName,
     4347                    Parent   => 'APP2',
    37354348                );
    37364349                my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
     
    37484361                my $tagTablePtr = GetTagTable('Image::ExifTool::APP12::Ducky');
    37494362                my %dirInfo = (
    3750                     Parent   => $markerName,
     4363                    Parent   => 'APP12',
    37514364                );
    37524365                my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
     
    37584371                        Write($outfile, $app12hdr, 'Ducky', $buff) or $err = 1;
    37594372                    } else {
    3760                         $self->Warn("APP12 Ducky segment too large! ($size bytes)");
     4373                        $self->Warn("Ducky APP12 segment too large! ($size bytes)");
    37614374                    }
    37624375                }
     
    37694382                my $newComment = $self->GetNewValues('Comment');
    37704383                if (defined $newComment and length($newComment)) {
    3771                     $verbose and print $out "Creating COM:\n";
    3772                     $verbose > 1 and print $out "    + Comment = '$newComment'\n";
     4384                    if ($verbose) {
     4385                        print $out "Creating COM:\n";
     4386                        $self->VerboseValue('+ Comment', $newComment);
     4387                    }
    37734388                    WriteMultiSegment($outfile, 0xfe, '', \$newComment) or $err = 1;
    37744389                    ++$self->{CHANGED};
     
    37884403            next;
    37894404        } elsif ($marker == 0xda) {             # SOS
     4405            pop @$path;
    37904406            $verbose and print $out "JPEG SOS\n";
    37914407            # write SOS segment
     
    38344450                $self->ProcessTrailers($trailInfo) or undef $trailInfo;
    38354451            }
    3836             if ($oldOutfile) {
     4452            if (not $oldOutfile) {
     4453                # do nothing special
     4454            } elsif ($$self{LeicaTrailer}) {
     4455                my $trailLen;
     4456                if ($trailInfo) {
     4457                    $trailLen = $$trailInfo{DataPos} - $endPos;
     4458                } else {
     4459                    $raf->Seek(0, 2) or $err = 1;
     4460                    $trailLen = $raf->Tell() - $endPos;
     4461                }
     4462                my $fixup = $$self{LeicaTrailer}{Fixup};
     4463                $$self{LeicaTrailer}{TrailPos} = $endPos;
     4464                $$self{LeicaTrailer}{TrailLen} = $trailLen;
     4465                # get _absolute_ position of new Leica trailer
     4466                my $absPos = Tell($oldOutfile) + length($$outfile);
     4467                require Image::ExifTool::Panasonic;
     4468                my $dat = Image::ExifTool::Panasonic::ProcessLeicaTrailer($self, $absPos);
     4469                # allow some junk before Leica trailer (just in case)
     4470                my $junk = $$self{LeicaTrailerPos} - $endPos;
     4471                # set MakerNote pointer and size (subtract 10 for segment and EXIF headers)
     4472                $fixup->SetMarkerPointers($outfile, 'LeicaTrailer', length($$outfile) - 10 + $junk);
     4473                # use this fixup to set the size too (sneaky)
     4474                my $trailSize = defined($dat) ? length($dat) - $junk : $$self{LeicaTrailer}{Size};
     4475                $fixup->{Start} -= 4;  $fixup->{Shift} += 4;
     4476                $fixup->SetMarkerPointers($outfile, 'LeicaTrailer', $trailSize);
     4477                $fixup->{Start} += 4;  $fixup->{Shift} -= 4;
     4478                # clean up and write the buffered data
     4479                $outfile = $oldOutfile;
     4480                undef $oldOutfile;
     4481                Write($outfile, $writeBuffer) or $err = 1;
     4482                undef $writeBuffer;
     4483                if (defined $dat) {
     4484                    Write($outfile, $dat) or $err = 1;  # write new Leica trailer
     4485                    $delPreview = 1;                    # delete existing Leica trailer
     4486                }
     4487            } else {
    38374488                # locate preview image and fix up preview offsets
    3838                 if (length($buff) < 1024) { # make sure we have at least 1kB of trailer
     4489                my $scanLen = $$self{Make} =~ /Sony/i ? 65536 : 1024;
     4490                if (length($buff) < $scanLen) { # make sure we have enough trailer to scan
    38394491                    my $buf2;
    3840                     $buff .= $buf2 if $raf->Read($buf2, 1024);
    3841                 }
    3842                 # get new preview image position (subtract 10 for segment and EXIF headers)
    3843                 my $newPos = length($$outfile) - 10;
     4492                    $buff .= $buf2 if $raf->Read($buf2, $scanLen - length($buff));
     4493                }
     4494                # get new preview image position, relative to EXIF base
     4495                my $newPos = length($$outfile) - 10; # (subtract 10 for segment and EXIF headers)
    38444496                my $junkLen;
    38454497                # adjust position if image isn't at the start (ie. Olympus E-1/E-300)
    38464498                if ($buff =~ m/(\xff\xd8\xff.|.\xd8\xff\xdb)/sg) {
    38474499                    $junkLen = pos($buff) - 4;
     4500                    # Sony previewimage trailer has a 32 byte header
     4501                    $junkLen -= 32 if $$self{Make} =~/SONY/i and $junkLen > 32;
    38484502                    $newPos += $junkLen;
    38494503                }
     
    38514505                my $previewInfo = $self->{PREVIEW_INFO};
    38524506                delete $self->{PREVIEW_INFO};
    3853                 my $fixup = $previewInfo->{Fixup};
    3854                 $newPos += ($previewInfo->{BaseShift} || 0);
    3855                 if ($previewInfo->{Relative}) {
     4507                my $fixup = $$previewInfo{Fixup};
     4508                $newPos += ($$previewInfo{BaseShift} || 0);
     4509                # adjust to absolute file offset if necessary (Samsung STMN)
     4510                $newPos += Tell($oldOutfile) + 10 if $$previewInfo{Absolute};
     4511                if ($$previewInfo{Relative}) {
    38564512                    # adjust for our base by looking at how far the pointer got shifted
    38574513                    $newPos -= $fixup->GetMarkerPointers($outfile, 'PreviewImage');
     4514                } elsif ($$previewInfo{ChangeBase}) {
     4515                    # Leica S2 uses relative offsets for the preview only (leica sucks)
     4516                    my $makerOffset = $fixup->GetMarkerPointers($outfile, 'LeicaTrailer');
     4517                    $newPos -= $makerOffset if $makerOffset;
    38584518                }
    38594519                $fixup->SetMarkerPointers($outfile, 'PreviewImage', $newPos);
     
    38644524                undef $writeBuffer;
    38654525                # write preview image
    3866                 if ($previewInfo->{Data} ne 'LOAD') {
     4526                if ($$previewInfo{Data} ne 'LOAD_PREVIEW') {
    38674527                    # write any junk that existed before the preview image
    38684528                    Write($outfile, substr($buff,0,$junkLen)) or $err = 1 if $junkLen;
    38694529                    # write the saved preview image
    3870                     Write($outfile, $previewInfo->{Data}) or $err = 1;
    3871                     delete $previewInfo->{Data};
     4530                    Write($outfile, $$previewInfo{Data}) or $err = 1;
     4531                    delete $$previewInfo{Data};
    38724532                    # (don't increment CHANGED because we could be rewriting existing preview)
    38734533                    $delPreview = 1;    # remove old preview
     
    38934553                        $verbose and print $out "  Preserving unknown trailer ($extra bytes)\n";
    38944554                        $raf->Seek($endPos, 0) or $err = 1;
    3895                         while ($extra) {
    3896                             my $n = $extra < 65536 ? $extra : 65536;
    3897                             $raf->Read($buff, $n) == $n or $err = 1, last;
    3898                             Write($outfile, $buff) or $err = 1, last;
    3899                             $extra -= $n;
    3900                         }
     4555                        CopyBlock($raf, $outfile, $extra) or $err = 1;
    39014556                    }
    39024557                }
     
    39294584        }
    39304585        my ($segType, $del);
    3931         # rewrite this segment only if we are changing a tag which
    3932         # is contained in its directory (or deleting '*', in which
    3933         # case we need to identify the segment type)
     4586        # rewrite this segment only if we are changing a tag which is contained in its
     4587        # directory (or deleting '*', in which case we need to identify the segment type)
    39344588        while (exists $$editDirs{$markerName} or $$delGroup{'*'}) {
    39354589            my $oldChanged = $self->{CHANGED};
     
    39384592                    $segType = 'JFIF';
    39394593                    $$delGroup{JFIF} and $del = 1, last;
     4594                    last unless $$editDirs{JFIF};
    39404595                    SetByteOrder('MM');
    39414596                    my $tagTablePtr = GetTagTable('Image::ExifTool::JFIF::Main');
     
    39584613                    $segType = 'CIFF';
    39594614                    $$delGroup{CIFF} and $del = 1, last;
     4615                    last unless $$editDirs{CIFF};
    39604616                    my $newData = '';
    39614617                    my %dirInfo = (
     
    39804636                    $doneDir{IFD0} = 1;
    39814637                    last unless $$editDirs{IFD0};
    3982                     # write new EXIF data to memory
    3983                     my $buff = $exifAPP1hdr; # start with APP1 EXIF header
     4638                    # check del groups now so we can change byte order in one step
     4639                    if ($$delGroup{IFD0} or $$delGroup{EXIF}) {
     4640                        delete $doneDir{IFD0};  # delete so we will create a new one
     4641                        $del = 1;
     4642                        last;
     4643                    }
    39844644                    # rewrite EXIF as if this were a TIFF file in memory
    39854645                    my %dirInfo = (
    3986                         DataPt => $segDataPt,
    3987                         DataPos => $segPos,
     4646                        DataPt   => $segDataPt,
     4647                        DataPos  => $segPos,
    39884648                        DirStart => 6,
    3989                         Base => $segPos + 6,
    3990                         OutFile => \$buff,
    3991                         Parent => $markerName,
     4649                        Base     => $segPos + 6,
     4650                        Parent   => $markerName,
     4651                        DirName  => 'IFD0',
    39924652                    );
    3993                     my $result = $self->ProcessTIFF(\%dirInfo);
    3994                     $segDataPt = \$buff;
    3995                     unless ($result > 0) { # check for problems writing the EXIF
     4653                    # write new EXIF data to memory
     4654                    my $tagTablePtr = GetTagTable('Image::ExifTool::Exif::Main');
     4655                    my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr, \&WriteTIFF);
     4656                    if (defined $buff) {
     4657                        # update segment with new data
     4658                        $$segDataPt = $exifAPP1hdr . $buff;
     4659                    } else {
    39964660                        last Marker unless $self->Options('IgnoreMinorErrors');
    3997                         $$segDataPt = $exifAPP1hdr . $self->{EXIF_DATA}; # restore original EXIF
    3998                         $self->{CHANGED} = $oldChanged;
     4661                        $self->{CHANGED} = $oldChanged; # nothing changed
    39994662                    }
    40004663                    # switch to buffered output if required
    4001                     if ($self->{PREVIEW_INFO} and not $oldOutfile) {
     4664                    if (($$self{PREVIEW_INFO} or $$self{LeicaTrailer}) and not $oldOutfile) {
    40024665                        $writeBuffer = '';
    40034666                        $oldOutfile = $outfile;
    40044667                        $outfile = \$writeBuffer;
    40054668                        # must account for segment, EXIF and TIFF headers
    4006                         $self->{PREVIEW_INFO}->{Fixup}->{Start} += 18;
     4669                        $$self{PREVIEW_INFO}{Fixup}{Start} += 18 if $$self{PREVIEW_INFO};
     4670                        $$self{LeicaTrailer}{Fixup}{Start} += 18 if $$self{LeicaTrailer};
    40074671                    }
    40084672                    # delete segment if IFD contains no entries
    40094673                    $del = 1 unless length($$segDataPt) > length($exifAPP1hdr);
    40104674                # check for XMP data
    4011                 } elsif ($$segDataPt =~ /^$xmpAPP1hdr/) {
     4675                } elsif ($$segDataPt =~ /^($xmpAPP1hdr|$xmpExtAPP1hdr)/) {
    40124676                    $segType = 'XMP';
    4013                     $doneDir{XMP} and $self->Warn('Multiple APP1 XMP segments');
    4014                     $doneDir{XMP} = 1;
     4677                    $$delGroup{XMP} and $del = 1, last;
     4678                    $doneDir{XMP} = ($doneDir{XMP} || 0) + 1;
    40154679                    last unless $$editDirs{XMP};
     4680                    if ($doneDir{XMP} + $dirCount{XMP} > 1) {
     4681                        # must assemble all XMP segments before writing
     4682                        my ($guid, $extXMP);
     4683                        if ($$segDataPt =~ /^$xmpExtAPP1hdr/) {
     4684                            # save extended XMP data
     4685                            if (length $$segDataPt < 75) {
     4686                                $extendedXMP{Error} = 'Truncated data';
     4687                            } else {
     4688                                my ($size, $off) = unpack('x67N2', $$segDataPt);
     4689                                $guid = substr($$segDataPt, 35, 32);
     4690                                # remember extended data for each GUID
     4691                                $extXMP = $extendedXMP{$guid};
     4692                                if ($extXMP) {
     4693                                    $size == $$extXMP{Size} or $extendedXMP{Error} = 'Invalid size';
     4694                                } else {
     4695                                    $extXMP = $extendedXMP{$guid} = { };
     4696                                }
     4697                                $$extXMP{Size} = $size;
     4698                                $$extXMP{$off} = substr($$segDataPt, 75);
     4699                            }
     4700                        } else {
     4701                            # save all main XMP segments (should normally be only one)
     4702                            $extendedXMP{Main} = [] unless $extendedXMP{Main};
     4703                            push @{$extendedXMP{Main}}, substr($$segDataPt, length $xmpAPP1hdr);
     4704                        }
     4705                        # continue processing only if we have read all the segments
     4706                        next Marker if $dirCount{XMP};
     4707                        # reconstruct an XMP super-segment
     4708                        $$segDataPt = $xmpAPP1hdr;
     4709                        $$segDataPt .= $_ foreach @{$extendedXMP{Main}};
     4710                        foreach $guid (sort keys %extendedXMP) {
     4711                            next unless length $guid == 32;     # ignore other keys
     4712                            $extXMP = $extendedXMP{$guid};
     4713                            next unless ref $extXMP eq 'HASH';  # (just to be safe)
     4714                            my $size = $$extXMP{Size};
     4715                            my (@offsets, $off);
     4716                            for ($off=0; $off<$size; ) {
     4717                                last unless defined $$extXMP{$off};
     4718                                push @offsets, $off;
     4719                                $off += length $$extXMP{$off};
     4720                            }
     4721                            if ($off == $size) {
     4722                                # add all XMP to super-segment
     4723                                $$segDataPt .= $$extXMP{$_} foreach @offsets;
     4724                            } else {
     4725                                $extendedXMP{Error} = 'Missing XMP data';
     4726                            }
     4727                        }
     4728                        $self->Error("$extendedXMP{Error} in extended XMP", 1) if $extendedXMP{Error};
     4729                    }
    40164730                    my $start = length $xmpAPP1hdr;
    40174731                    my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
    40184732                    my %dirInfo = (
    4019                         Base     => 0,
    4020                         DataPt   => $segDataPt,
    4021                         DataPos  => $segPos,
    4022                         DataLen  => $length,
    4023                         DirStart => $start,
    4024                         DirLen   => $length - $start,
    4025                         Parent   => $markerName,
     4733                        DataPt     => $segDataPt,
     4734                        DirStart   => $start,
     4735                        Parent     => $markerName,
     4736                        # limit XMP size and create extended XMP if necessary
     4737                        MaxDataLen => $maxXMPLen - length($xmpAPP1hdr),
    40264738                    );
    40274739                    my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
    40284740                    if (defined $newData) {
    4029                         undef $$segDataPt;  # free the old buffer
    4030                         # add header to new segment unless empty
    4031                         $newData = $xmpAPP1hdr . $newData if length $newData;
    4032                         $segDataPt = \$newData;
     4741                        undef %extendedXMP;
     4742                        if (length $newData) {
     4743                            # write multi-segment XMP (XMP plus extended XMP if necessary)
     4744                            WriteMultiXMP($self, $outfile, \$newData, $dirInfo{ExtendedXMP},
     4745                                          $dirInfo{ExtendedGUID}) or $err = 1;
     4746                            undef $$segDataPt;  # free the old buffer
     4747                            next Marker;
     4748                        } else {
     4749                            $$segDataPt = '';   # delete the XMP
     4750                        }
    40334751                    } else {
    40344752                        $self->{CHANGED} = $oldChanged;
     4753                        $verbose and print $out "    [XMP rewritten with no changes]\n";
     4754                        if ($doneDir{XMP} > 1) {
     4755                            # re-write original multi-segment XMP
     4756                            my ($dat, $guid, $extXMP, $off);
     4757                            foreach $dat (@{$extendedXMP{Main}}) {      # main XMP
     4758                                next unless length $dat;
     4759                                $s = pack('n', length($xmpAPP1hdr) + length($dat) + 2);
     4760                                Write($outfile, $hdr, $s, $xmpAPP1hdr, $dat) or $err = 1;
     4761                            }
     4762                            foreach $guid (sort keys %extendedXMP) {    # extended XMP
     4763                                next unless length $guid == 32;
     4764                                $extXMP = $extendedXMP{$guid};
     4765                                next unless ref $extXMP eq 'HASH';
     4766                                my $size = $$extXMP{Size} or next;
     4767                                for ($off=0; defined $$extXMP{$off}; $off += length $$extXMP{$off}) {
     4768                                    $s = pack('n', length($xmpExtAPP1hdr) + length($$extXMP{$off}) + 42);
     4769                                    Write($outfile, $hdr, $s, $xmpExtAPP1hdr, $guid,
     4770                                          pack('N2', $size, $off), $$extXMP{$off}) or $err = 1;
     4771                                }
     4772                            }
     4773                            undef $$segDataPt;  # free the old buffer
     4774                            undef %extendedXMP;
     4775                            next Marker;
     4776                        }
     4777                        # continue on to re-write original single-segment XMP
    40354778                    }
    40364779                    $del = 1 unless length $$segDataPt;
     4780                } elsif ($$segDataPt =~ /^http/ or $$segDataPt =~ /<exif:/) {
     4781                    $self->Warn('Ignored APP1 XMP segment with non-standard header', 1);
    40374782                }
    40384783            } elsif ($marker == 0xe2) {         # APP2 (ICC Profile, FPXR)
     
    40824827                if ($$segDataPt =~ /^(Meta|META|Exif)\0\0/) {
    40834828                    $segType = 'Kodak Meta';
    4084                     $$delGroup{Meta} and $del = 1;
     4829                    $$delGroup{Meta} and $del = 1, last;
     4830                    $doneDir{Meta} and $self->Warn('Multiple APP3 Meta segments');
     4831                    $doneDir{Meta} = 1;
     4832                    last unless $$editDirs{Meta};
     4833                    # rewrite Meta IFD as if this were a TIFF file in memory
     4834                    my %dirInfo = (
     4835                        DataPt   => $segDataPt,
     4836                        DataPos  => $segPos,
     4837                        DirStart => 6,
     4838                        Base     => $segPos + 6,
     4839                        Parent   => $markerName,
     4840                        DirName  => 'Meta',
     4841                    );
     4842                    # write new data to memory
     4843                    my $tagTablePtr = GetTagTable('Image::ExifTool::Kodak::Meta');
     4844                    my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr, \&WriteTIFF);
     4845                    if (defined $buff) {
     4846                        # update segment with new data
     4847                        $$segDataPt = substr($$segDataPt,0,6) . $buff;
     4848                    } else {
     4849                        last Marker unless $self->Options('IgnoreMinorErrors');
     4850                        $self->{CHANGED} = $oldChanged; # nothing changed
     4851                    }
     4852                    # delete segment if IFD contains no entries
     4853                    $del = 1 unless length($$segDataPt) > 6;
    40854854                }
    40864855            } elsif ($marker == 0xe5) {         # APP5 (Ricoh RMETA)
     
    41314900                        next Marker;    # get the next segment to combine
    41324901                    }
    4133                     $doneDir{Photoshop} and $self->Warn('Multiple Photoshop records');
     4902                    if ($doneDir{Photoshop}) {
     4903                        $self->Warn('Multiple Photoshop records');
     4904                        # only rewrite the first Photoshop segment when deleting this group
     4905                        # (to remove multiples when deleting and adding back in one step)
     4906                        $$delGroup{Photoshop} and $del = 1, last;
     4907                    }
    41344908                    $doneDir{Photoshop} = 1;
    41354909                    # process APP13 Photoshop record
     
    41634937                    unless ($$delGroup{File} and $$delGroup{File} != 2) {
    41644938                        my $tagInfo = $Image::ExifTool::Extra{Comment};
    4165                         my $newValueHash = $self->GetNewValueHash($tagInfo);
    4166                         if (IsOverwriting($newValueHash, $segData) or $$delGroup{File}) {
    4167                             $newComment = GetNewValues($newValueHash);
     4939                        my $nvHash = $self->GetNewValueHash($tagInfo);
     4940                        if (IsOverwriting($nvHash, $segData) or $$delGroup{File}) {
     4941                            $newComment = GetNewValues($nvHash);
    41684942                        } else {
    41694943                            delete $$editDirs{COM}; # we aren't editing COM after all
     
    41724946                    }
    41734947                }
    4174                 $verbose > 1 and print $out "    - Comment = '$$segDataPt'\n";
     4948                $self->VerboseValue('- Comment', $$segDataPt);
    41754949                if (defined $newComment and length $newComment) {
    41764950                    # write out the comments
    4177                     $verbose > 1 and print $out "    + Comment = '$newComment'\n";
     4951                    $self->VerboseValue('+ Comment', $newComment);
    41784952                    WriteMultiSegment($outfile, 0xfe, '', \$newComment) or $err = 1;
    41794953                } else {
     
    41984972            my $size = length($$segDataPt);
    41994973            if ($size > $maxSegmentLen) {
    4200                 $self->Error("$markerName segment too large! ($size bytes)");
     4974                $segType or $segType = 'Unknown';
     4975                $self->Error("$segType $markerName segment too large! ($size bytes)");
    42014976                $err = 1;
    42024977            } else {
     
    42074982        }
    42084983    }
     4984    pop @$path if @$path > $pn;
    42094985    # if oldOutfile is still set, there was an error copying the JPEG
    42104986    $oldOutfile and return 0;
     
    42144990        Write($outfile, $$trailPt) or $err = 1 if $trailPt;
    42154991    }
    4216     $/ = $oldsep;     # restore separator to original value
    42174992    # set return value to -1 if we only had a write error
    42184993    $rtnVal = -1 if $rtnVal and $err;
     
    42445019{
    42455020    my ($valPtr, $format, $count) = @_;
    4246     my (@vals, $n);
     5021    my (@vals, $val, $n);
    42475022
    42485023    if ($format eq 'string' or $format eq 'undef') {
     
    42665041        @vals = ( $$valPtr );
    42675042    }
    4268     return "Too many values specified ($count required)" if @vals > $count;
    4269     return "Not enough values specified ($count required)" if @vals < $count;
    4270     my $val;
     5043    if (@vals != $count) {
     5044        my $str = @vals > $count ? 'Too many' : 'Not enough';
     5045        return "$str values specified ($count required)";
     5046    }
    42715047    for ($n=0; $n<$count; ++$n) {
    42725048        $val = shift @vals;
     
    42885064        } elsif ($format =~ /^rational/ or $format eq 'float' or $format eq 'double') {
    42895065            # make sure the value is a valid floating point number
    4290             return 'Not a floating point number' unless IsFloat($val);
     5066            unless (IsFloat($val)) {
     5067                # allow 'inf', 'undef' and fractional rational values
     5068                if ($format =~ /^rational/) {
     5069                    next if $val eq 'inf' or $val eq 'undef';
     5070                    if ($val =~ m{^([-+]?\d+)/(\d+)$}) {
     5071                        next unless $1 < 0 and $format =~ /u$/;
     5072                        return 'Must be an unsigned rational';
     5073                    }
     5074                }
     5075                return 'Not a floating point number'
     5076            }
    42915077            if ($format =~ /^rational\d+u$/ and $val < 0) {
    42925078                return 'Must be a positive number';
     
    43255111
    43265112#------------------------------------------------------------------------------
     5113# Copy data block from RAF to output file in max 64kB chunks
     5114# Inputs: 0) RAF ref, 1) outfile ref, 2) block size
     5115# Returns: 1 on success, 0 on read error, undef on write error
     5116sub CopyBlock($$$)
     5117{
     5118    my ($raf, $outfile, $size) = @_;
     5119    my $buff;
     5120    for (;;) {
     5121        last unless $size > 0;
     5122        my $n = $size > 65536 ? 65536 : $size;
     5123        $raf->Read($buff, $n) == $n or return 0;
     5124        Write($outfile, $buff) or return undef;
     5125        $size -= $n;
     5126    }
     5127    return 1;
     5128}
     5129
     5130#------------------------------------------------------------------------------
    43275131# copy image data from one file to another
    43285132# Inputs: 0) ExifTool object reference
     
    43345138    my ($self, $imageDataBlocks, $outfile) = @_;
    43355139    my $raf = $self->{RAF};
    4336     my ($dataBlock, $buff, $err);
     5140    my ($dataBlock, $err);
     5141    my $num = @$imageDataBlocks;
     5142    $self->VPrint(0, "  Copying $num image data blocks\n") if $num;
    43375143    foreach $dataBlock (@$imageDataBlocks) {
    43385144        my ($pos, $size, $pad) = @$dataBlock;
    43395145        $raf->Seek($pos, 0) or $err = 'read', last;
    4340         while ($size) {
    4341             # copy in blocks of 64kB or smaller
    4342             my $n = $size > 65536 ? 65536 : $size;
    4343             $raf->Read($buff, $n) == $n or $err = 'read', last;
    4344             Write($outfile, $buff) or $err = 'writ', last;
    4345             $size -= $n;
    4346         }
     5146        my $result = CopyBlock($raf, $outfile, $size);
     5147        $result or $err = defined $result ? 'read' : 'writ';
    43475148        # pad if necessary
    43485149        Write($outfile, "\0" x $pad) or $err = 'writ' if $pad;
     
    43665167
    43675168    # get default format ('int8u' unless specified)
     5169    my $dataPt = $$dirInfo{DataPt} or return undef;
    43685170    my $defaultFormat = $$tagTablePtr{FORMAT} || 'int8u';
    43695171    my $increment = FormatSize($defaultFormat);
     
    43735175    }
    43745176    # extract data members first if necessary
     5177    my @varOffsets;
    43755178    if ($$tagTablePtr{DATAMEMBER}) {
    43765179        $$dirInfo{DataMember} = $$tagTablePtr{DATAMEMBER};
     5180        $$dirInfo{VarFormatData} = \@varOffsets;
    43775181        $self->ProcessBinaryData($dirInfo, $tagTablePtr);
    43785182        delete $$dirInfo{DataMember};
    4379     }
    4380     my $dataPt = $$dirInfo{DataPt};
     5183        delete $$dirInfo{VarFormatData};
     5184    }
    43815185    my $dirStart = $$dirInfo{DirStart} || 0;
    43825186    my $dirLen = $$dirInfo{DirLen} || length($$dataPt) - $dirStart;
    43835187    my $newData = substr($$dataPt, $dirStart, $dirLen) or return undef;
    43845188    my $dirName = $$dirInfo{DirName};
    4385     my $verbose = $self->Options('Verbose');
     5189    my $varSize = 0;
     5190    my @varInfo = @varOffsets;
    43865191    my $tagInfo;
    43875192    $dataPt = \$newData;
    43885193    foreach $tagInfo ($self->GetNewTagInfoList($tagTablePtr)) {
    43895194        my $tagID = $tagInfo->{TagID};
    4390         # must check to be sure this tagInfo applies (ie. evaluate the condition!)
    4391         my $writeInfo = $self->GetTagInfo($tagTablePtr, $tagID);
    4392         next unless $writeInfo and $writeInfo eq $tagInfo;
     5195        # evaluate conditional tags now if necessary
     5196        if (ref $$tagTablePtr{$tagID} eq 'ARRAY' or $$tagInfo{Condition}) {
     5197            my $writeInfo = $self->GetTagInfo($tagTablePtr, $tagID);
     5198            next unless $writeInfo and $writeInfo eq $tagInfo;
     5199        }
     5200        # add offsets for variable-sized tags if necessary
     5201        while (@varInfo and $varInfo[0] < $tagID) {
     5202            shift @varInfo;             # discard index
     5203            $varSize = shift @varInfo;  # get accumulated variable size
     5204        }
    43935205        my $count = 1;
    43945206        my $format = $$tagInfo{Format};
     5207        my $entry = int($tagID) * $increment + $varSize; # relative offset of this entry
    43955208        if ($format) {
    43965209            if ($format =~ /(.*)\[(.*)\]/) {
     
    43995212                my $size = $dirLen; # used in eval
    44005213                # evaluate count to allow count to be based on previous values
    4401                 #### eval Format size (%val, $size)
     5214                #### eval Format size ($size, $self) - NOTE: %val not supported for writing
    44025215                $count = eval $count;
    44035216                $@ and warn($@), next;
     5217            } elsif ($format eq 'string') {
     5218                # string with no specified count runs to end of block
     5219                $count = ($dirLen > $entry) ? $dirLen - $entry : 0;
    44045220            }
    44055221        } else {
    44065222            $format = $defaultFormat;
    44075223        }
    4408         my $entry = $tagID * $increment;        # relative offset of this entry
    44095224        my $val = ReadValue($dataPt, $entry, $format, $count, $dirLen-$entry);
    44105225        next unless defined $val;
    4411         my $newValueHash = $self->GetNewValueHash($tagInfo);
    4412         next unless IsOverwriting($newValueHash, $val);
    4413         my $newVal = GetNewValues($newValueHash);
     5226        my $nvHash = $self->GetNewValueHash($tagInfo);
     5227        next unless IsOverwriting($nvHash, $val);
     5228        my $newVal = GetNewValues($nvHash);
    44145229        next unless defined $newVal;    # can't delete from a binary table
     5230        # only write masked bits if specified
     5231        my $mask = $$tagInfo{Mask};
     5232        $newVal = ($newVal & $mask) | ($val & ~$mask) if defined $mask;
    44155233        # set the size
    44165234        if ($$tagInfo{DataTag} and not $$tagInfo{IsOffset}) {
     
    44185236            my $data = $self->GetNewValues($$tagInfo{DataTag});
    44195237            $newVal = length($data) if defined $data;
     5238            my $format = $$tagInfo{Format} || $$tagTablePtr{FORMAT} || 'int32u';
     5239            if ($format =~ /^int16/ and $newVal > 0xffff) {
     5240                $self->Error("$$tagInfo{DataTag} is too large (64 kB max. for this file)");
     5241            }
    44205242        }
    44215243        my $rtnVal = WriteValue($newVal, $format, $count, $dataPt, $entry);
    44225244        if (defined $rtnVal) {
    4423             if ($verbose > 1) {
    4424                 my $out = $self->{OPTIONS}->{TextOut};
    4425                 print $out "    - $dirName:$$tagInfo{Name} = '$val'\n";
    4426                 print $out "    + $dirName:$$tagInfo{Name} = '$newVal'\n";
    4427             }
     5245            $self->VerboseValue("- $dirName:$$tagInfo{Name}", $val);
     5246            $self->VerboseValue("+ $dirName:$$tagInfo{Name}", $newVal);
    44285247            ++$self->{CHANGED};
    44295248        }
    44305249    }
    44315250    # add necessary fixups for any offsets
    4432     if ($tagTablePtr->{IS_OFFSET} and $$dirInfo{Fixup}) {
     5251    if ($$tagTablePtr{IS_OFFSET} and $$dirInfo{Fixup}) {
     5252        $varSize = 0;
     5253        @varInfo = @varOffsets;
    44335254        my $fixup = $$dirInfo{Fixup};
    44345255        my $tagID;
    44355256        foreach $tagID (@{$tagTablePtr->{IS_OFFSET}}) {
    44365257            $tagInfo = $self->GetTagInfo($tagTablePtr, $tagID) or next;
    4437             my $entry = $tagID * $increment;    # (no offset to dirStart for new dir data)
     5258            while (@varInfo and $varInfo[0] < $tagID) {
     5259                shift @varInfo;
     5260                $varSize = shift @varInfo;
     5261            }
     5262            my $entry = $tagID * $increment + $varSize; # (no offset to dirStart for new dir data)
    44385263            next unless $entry <= $dirLen - 4;
    44395264            # (Ricoh has 16-bit preview image offsets, so can't just assume int32u)
    44405265            my $format = $$tagInfo{Format} || $$tagTablePtr{FORMAT} || 'int32u';
     5266            my $offset = ReadValue($dataPt, $entry, $format, 1, $dirLen-$entry);
     5267            # ignore if offset is zero (ie. Ricoh DNG uses this to indicate no preview)
     5268            next unless $offset;
    44415269            $fixup->AddFixup($entry, $$tagInfo{DataTag}, $format);
    44425270            # handle the preview image now if this is a JPEG file
    44435271            next unless $self->{FILE_TYPE} eq 'JPEG' and $$tagInfo{DataTag} and
    44445272                $$tagInfo{DataTag} eq 'PreviewImage' and defined $$tagInfo{OffsetPair};
    4445             my $offset = ReadValue($dataPt, $entry, $format, 1, $dirLen-$entry);
    4446             $entry = $$tagInfo{OffsetPair} * $increment;
     5273            # NOTE: here we assume there are no var-sized tags between the
     5274            # OffsetPair tags.  If this ever becomes possible we must recalculate
     5275            # $varSize for the OffsetPair tag here!
     5276            $entry = $$tagInfo{OffsetPair} * $increment + $varSize;
    44475277            my $size = ReadValue($dataPt, $entry, $format, 1, $dirLen-$entry);
    44485278            my $previewInfo = $self->{PREVIEW_INFO};
    44495279            $previewInfo or $previewInfo = $self->{PREVIEW_INFO} = { };
    44505280            # set flag indicating we are using short pointers
    4451             $previewInfo->{IsShort} = 1 unless $format eq 'int32u';
    4452             $previewInfo->{Data} = $self->GetNewValues('PreviewImage');
    4453             unless (defined $previewInfo->{Data}) {
     5281            $$previewInfo{IsShort} = 1 unless $format eq 'int32u';
     5282            $$previewInfo{Absolute} = 1 if $$tagInfo{IsOffset} and $$tagInfo{IsOffset} eq '3';
     5283            # get the value of the Composite::PreviewImage tag
     5284            $$previewInfo{Data} = $self->GetNewValues($Image::ExifTool::Composite{PreviewImage});
     5285            unless (defined $$previewInfo{Data}) {
    44545286                if ($offset >= 0 and $offset + $size <= $$dirInfo{DataLen}) {
    4455                     $previewInfo->{Data} = substr(${$$dirInfo{DataPt}},$offset,$size);
     5287                    $$previewInfo{Data} = substr(${$$dirInfo{DataPt}},$offset,$size);
    44565288                } else {
    4457                     $previewInfo->{Data} = 'LOAD'; # flag to load preview later
    4458                 }
    4459             }
     5289                    $$previewInfo{Data} = 'LOAD_PREVIEW'; # flag to load preview later
     5290                }
     5291            }
     5292        }
     5293    }
     5294    # write any necessary SubDirectories
     5295    if ($$tagTablePtr{IS_SUBDIR}) {
     5296        $varSize = 0;
     5297        @varInfo = @varOffsets;
     5298        my $tagID;
     5299        foreach $tagID (@{$$tagTablePtr{IS_SUBDIR}}) {
     5300            my $tagInfo = $self->GetTagInfo($tagTablePtr, $tagID);
     5301            next unless defined $tagInfo;
     5302            while (@varInfo and $varInfo[0] < $tagID) {
     5303                shift @varInfo;
     5304                $varSize = shift @varInfo;
     5305            }
     5306            my $entry = int($tagID) * $increment + $varSize;
     5307            last if $entry >= $dirLen;
     5308            # get value for Condition if necessary
     5309            unless ($tagInfo) {
     5310                my $more = $dirLen - $entry;
     5311                $more = 128 if $more > 128;
     5312                my $v = substr($newData, $entry, $more);
     5313                $tagInfo = $self->GetTagInfo($tagTablePtr, $tagID, \$v);
     5314                next unless $tagInfo;
     5315            }
     5316            next unless $$tagInfo{SubDirectory}; # (just to be safe)
     5317            my %subdirInfo = ( DataPt => \$newData, DirStart => $entry );
     5318            my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}{TagTable});
     5319            my $dat = $self->WriteDirectory(\%subdirInfo, $subTablePtr);
     5320            substr($newData, $entry) = $dat if defined $dat and length $dat;
    44605321        }
    44615322    }
     
    44705331{
    44715332    my ($self, $dirInfo, $tagTablePtr) = @_;
    4472     my $buff;
     5333    my $buff = '';
    44735334    $$dirInfo{OutFile} = \$buff;
    44745335    return $buff if $self->ProcessTIFF($dirInfo, $tagTablePtr) > 0;
     
    44955356=head1 AUTHOR
    44965357
    4497 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     5358Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    44985359
    44995360This library is free software; you can redistribute it and/or modify it
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/XMP.pm

    r16842 r24107  
    1111#               08/25/2006 - P. Harvey Added ability to handle blank nodes
    1212#               08/22/2007 - P. Harvey Added ability to handle alternate language tags
     13#               09/26/2008 - P. Harvey Added Iptc4xmpExt tags (version 1.0 rev 2)
    1314#
    1415# References:   1) http://www.adobe.com/products/xmp/pdfs/xmpspec.pdf
     
    1718#               4) http://www.iptc.org/IPTC4XMP/
    1819#               5) http://creativecommons.org/technology/xmp
     20#                  --> changed to http://wiki.creativecommons.org/Companion_File_metadata_specification (2007/12/21)
    1921#               6) http://www.optimasc.com/products/fileid/xmp-extensions.pdf
    2022#               7) Lou Salkind private communication
    2123#               8) http://partners.adobe.com/public/developer/en/xmp/sdk/XMPspecification.pdf
     24#               9) http://www.w3.org/TR/SVG11/
     25#               10) http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart2.pdf (Oct 2008)
    2226#
    23 # Notes:      - I am handling property qualifiers as if they were separate
     27# Notes:      - Property qualifiers are handled as if they were separate
    2428#               properties (with no associated namespace).
    2529#
     
    3640
    3741use strict;
    38 use vars qw($VERSION $AUTOLOAD @ISA @EXPORT_OK);
     42use vars qw($VERSION $AUTOLOAD @ISA @EXPORT_OK $xlatNamespace %nsURI %dateTimeInfo
     43            %xmpTableDefaults %specialStruct %sDimensions %sArea %sColorant);
    3944use Image::ExifTool qw(:Utils);
    4045use Image::ExifTool::Exif;
    4146require Exporter;
    4247
    43 $VERSION = '1.78';
     48$VERSION = '2.37';
    4449@ISA = qw(Exporter);
    4550@EXPORT_OK = qw(EscapeXML UnescapeXML);
     
    4752sub ProcessXMP($$;$);
    4853sub WriteXMP($$;$);
     54sub CheckXMP($$$);
    4955sub ParseXMPElement($$$;$$$);
    5056sub DecodeBase64($);
     
    5359sub ValidateXMP($;$);
    5460sub UnescapeChar($$);
     61sub AddFlattenedTags($$);
     62sub FormatXMPDate($);
     63sub ConvertRational($);
     64
     65my %curNS;  # namespaces currently in effect while parsing the file
     66
     67# lookup for translating to ExifTool namespaces
     68# Note: Use $xlatNamespace (only valid during processing) to do the translation
     69my %stdXlatNS = (
     70    # shorten ugly namespace prefixes
     71    'Iptc4xmpCore' => 'iptcCore',
     72    'Iptc4xmpExt' => 'iptcExt',
     73    'photomechanic'=> 'photomech',
     74    'MicrosoftPhoto' => 'microsoft',
     75    'prismusagerights' => 'pur',
     76);
     77
     78# translate ExifTool namespaces to standard XMP namespace prefixes
     79my %xmpNS = (
     80    # shorten ugly namespace prefixes
     81    'iptcCore' => 'Iptc4xmpCore',
     82    'iptcExt' => 'Iptc4xmpExt',
     83    'photomechanic'=> 'photomech',
     84    'microsoft' => 'MicrosoftPhoto',
     85    # (prism changed their spec to now use 'pur')
     86    # 'pur' => 'prismusagerights',
     87);
     88
     89# Lookup to translate our namespace prefixes into URI's.  This list need
     90# not be complete, but it must contain an entry for each namespace prefix
     91# (NAMESPACE) for writable tags in the XMP tables or in structures
     92%nsURI = (
     93    aux       => 'http://ns.adobe.com/exif/1.0/aux/',
     94    album     => 'http://ns.adobe.com/album/1.0/',
     95    cc        => 'http://creativecommons.org/ns#', # changed 2007/12/21 - PH
     96    crs       => 'http://ns.adobe.com/camera-raw-settings/1.0/',
     97    crss      => 'http://ns.adobe.com/camera-raw-saved-settings/1.0/',
     98    dc        => 'http://purl.org/dc/elements/1.1/',
     99    exif      => 'http://ns.adobe.com/exif/1.0/',
     100    iX        => 'http://ns.adobe.com/iX/1.0/',
     101    pdf       => 'http://ns.adobe.com/pdf/1.3/',
     102    pdfx      => 'http://ns.adobe.com/pdfx/1.3/',
     103    photoshop => 'http://ns.adobe.com/photoshop/1.0/',
     104    rdf       => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
     105    rdfs      => 'http://www.w3.org/2000/01/rdf-schema#',
     106    stDim     => 'http://ns.adobe.com/xap/1.0/sType/Dimensions#',
     107    stArea    => 'http://ns.adobe.com/xap/1.0/sType/Area#',
     108    stEvt     => 'http://ns.adobe.com/xap/1.0/sType/ResourceEvent#',
     109    stFnt     => 'http://ns.adobe.com/xap/1.0/sType/Font#',
     110    stJob     => 'http://ns.adobe.com/xap/1.0/sType/Job#',
     111    stRef     => 'http://ns.adobe.com/xap/1.0/sType/ResourceRef#',
     112    stVer     => 'http://ns.adobe.com/xap/1.0/sType/Version#',
     113    stMfs     => 'http://ns.adobe.com/xap/1.0/sType/ManifestItem#',
     114    tiff      => 'http://ns.adobe.com/tiff/1.0/',
     115   'x'        => 'adobe:ns:meta/',
     116    xmpG      => 'http://ns.adobe.com/xap/1.0/g/',
     117    xmpGImg   => 'http://ns.adobe.com/xap/1.0/g/img/',
     118    xmp       => 'http://ns.adobe.com/xap/1.0/',
     119    xmpBJ     => 'http://ns.adobe.com/xap/1.0/bj/',
     120    xmpDM     => 'http://ns.adobe.com/xmp/1.0/DynamicMedia/',
     121    xmpMM     => 'http://ns.adobe.com/xap/1.0/mm/',
     122    xmpRights => 'http://ns.adobe.com/xap/1.0/rights/',
     123    xmpNote   => 'http://ns.adobe.com/xmp/note/',
     124    xmpTPg    => 'http://ns.adobe.com/xap/1.0/t/pg/',
     125    xmpidq    => 'http://ns.adobe.com/xmp/Identifier/qual/1.0/',
     126    xmpPLUS   => 'http://ns.adobe.com/xap/1.0/PLUS/',
     127    dex       => 'http://ns.optimasc.com/dex/1.0/',
     128    mediapro  => 'http://ns.iview-multimedia.com/mediapro/1.0/',
     129    Iptc4xmpCore => 'http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/',
     130    Iptc4xmpExt => 'http://iptc.org/std/Iptc4xmpExt/2008-02-29/',
     131    MicrosoftPhoto => 'http://ns.microsoft.com/photo/1.0',
     132    MP1       => 'http://ns.microsoft.com/photo/1.1', #PH (MP1 is fabricated)
     133    MP        => 'http://ns.microsoft.com/photo/1.2/',
     134    MPRI      => 'http://ns.microsoft.com/photo/1.2/t/RegionInfo#',
     135    MPReg     => 'http://ns.microsoft.com/photo/1.2/t/Region#',
     136    lr        => 'http://ns.adobe.com/lightroom/1.0/',
     137    DICOM     => 'http://ns.adobe.com/DICOM/',
     138    svg       => 'http://www.w3.org/2000/svg',
     139    et        => 'http://ns.exiftool.ca/1.0/',
     140    # namespaces defined in XMP2.pl:
     141    plus      => 'http://ns.useplus.org/ldf/xmp/1.0/',
     142    prism     => 'http://prismstandard.org/namespaces/basic/2.1/',
     143    prl       => 'http://prismstandard.org/namespaces/prl/2.1/',
     144    pur       => 'http://prismstandard.org/namespaces/prismusagerights/2.1/',
     145    acdsee    => 'http://ns.acdsee.com/iptc/1.0/',
     146    digiKam   => 'http://www.digikam.org/ns/1.0/',
     147    swf       => 'http://ns.adobe.com/swf/1.0',
     148    cell      => 'http://developer.sonyericsson.com/cell/1.0/',
     149   'mwg-rs'   => 'http://www.metadataworkinggroup.com/schemas/regions/',
     150   'mwg-kw'   => 'http://www.metadataworkinggroup.com/schemas/keywords/',
     151   'mwg-coll' => 'http://www.metadataworkinggroup.com/schemas/collections/',
     152);
     153
     154# build reverse namespace lookup
     155my %uri2ns;
     156{
     157    my $ns;
     158    foreach $ns (keys %nsURI) {
     159        $uri2ns{$nsURI{$ns}} = $ns;
     160    }
     161}
    55162
    56163# conversions for GPS coordinates
     
    80187    PrintConvInv => \&ToDegrees,
    81188);
    82 my %dateTimeInfo = (
    83     Groups => { 2 => 'Time'   },
     189%dateTimeInfo = (
     190    # NOTE: Do NOT put "Groups" here because Groups hash must not be common!
    84191    Writable => 'date',
    85192    Shift => 'Time',
    86193    PrintConv => '$self->ConvertDateTime($val)',
     194    PrintConvInv => '$self->InverseDateTime($val,undef,1)',
    87195);
    88196
    89197# XMP namespaces which we don't want to contribute to generated EXIF tag names
    90 my %ignoreNamespace = ( 'x'=>1, 'rdf'=>1, 'xmlns'=>1, 'xml'=>1);
    91 
    92 # translate XMP namespaces when reading
    93 my %xlatNamespace = (
    94     # shorten ugly IPTC Core namespace prefix
    95     'Iptc4xmpCore' => 'iptcCore',
    96     'photomechanic'=> 'photomech',
    97     'MicrosoftPhoto' => 'microsoft',
    98     # also translate older 'xap...' prefixes to 'xmp...'
    99     'xap'          => 'xmp',
    100     'xapBJ'        => 'xmpBJ',
    101     'xapMM'        => 'xmpMM',
    102     'xapRights'    => 'xmpRights',
    103 );
     198# (Note: namespaces with non-standard prefixes aren't currently ignored)
     199my %ignoreNamespace = ( 'x'=>1, rdf=>1, xmlns=>1, xml=>1, svg=>1, et=>1, office=>1 );
    104200
    105201# these are the attributes that we handle for properties that contain
     
    107203# just copy them over.  These are harder since we don't store attributes
    108204# for properties without simple values.  (maybe this will change...)
     205# (special attributes are indicated by a list reference of tag information)
    109206my %recognizedAttrs = (
    110     'x:xaptk' => 1,
    111     'x:xmptk' => 1,
    112     'rdf:about' => 1,
     207    'rdf:about' => [ 'Image::ExifTool::XMP::rdf', 'about', 'About' ],
     208    'x:xmptk'   => [ 'Image::ExifTool::XMP::x',   'xmptk', 'XMPToolkit' ],
     209    'x:xaptk'   => [ 'Image::ExifTool::XMP::x',   'xmptk', 'XMPToolkit' ],
    113210    'rdf:parseType' => 1,
    114211    'rdf:nodeID' => 1,
    115 );
    116 
    117 # main XMP tag table
     212    'et:toolkit' => 1,
     213    'rdf:xmlns' => 1, # this is presumably the default namespace, which we currently ignore
     214);
     215
     216# special tags in structures below
     217# NOTE: this lookup is duplicated in TagLookup.pm!!
     218%specialStruct = (
     219    STRUCT_NAME => 1, # [optional] name of structure
     220    NAMESPACE   => 1, # [mandatory] namespace prefix used for fields of this structure
     221    NOTES       => 1, # [optional] notes for documentation about this structure
     222    TYPE        => 1, # [optional] rdf:type resource for struct (if used, the StructType flag
     223                      # will be set automatically for all derived flattened tags when writing)
     224);
     225# XMP structures (each structure is similar to a tag table so we can
     226# recurse through them in SetPropertyPath() as if they were tag tables)
     227# The main differences between structure field information and tagInfo hashes are:
     228#   1) Field information hashes do not contain Name, Groups or Table entries, and
     229#   2) The TagID entry is optional, and is used only if the key in the structure hash
     230#      is different from the TagID (currently only true for alternate language fields)
     231#   3) Field information hashes support a additional "Namespace" property.
     232my %sResourceRef = (
     233    STRUCT_NAME => 'ResourceRef',
     234    NAMESPACE   => 'stRef',
     235    documentID      => { },
     236    instanceID      => { },
     237    manager         => { },
     238    managerVariant  => { },
     239    manageTo        => { },
     240    manageUI        => { },
     241    renditionClass  => { },
     242    renditionParams => { },
     243    versionID       => { },
     244    # added Oct 2008
     245    alternatePaths  => { List => 'Seq' },
     246    filePath        => { },
     247    fromPart        => { },
     248    lastModifyDate  => { %dateTimeInfo, Groups => { 2 => 'Time' } },
     249    maskMarkers     => { PrintConv => { All => 'All', None => 'None' } },
     250    partMapping     => { },
     251    toPart          => { },
     252    # added May 2010
     253    originalDocumentID => { }, # (undocumented property written by Adobe InDesign)
     254);
     255my %sResourceEvent = (
     256    STRUCT_NAME => 'ResourceEvent',
     257    NAMESPACE   => 'stEvt',
     258    action          => { },
     259    instanceID      => { },
     260    parameters      => { },
     261    softwareAgent   => { },
     262    when            => { %dateTimeInfo, Groups => { 2 => 'Time' } },
     263    # added Oct 2008
     264    changed         => { },
     265);
     266my %sJobRef = (
     267    STRUCT_NAME => 'JobRef',
     268    NAMESPACE   => 'stJob',
     269    id          => { },
     270    name        => { },
     271    url         => { },
     272);
     273my %sVersion = (
     274    STRUCT_NAME => 'Version',
     275    NAMESPACE   => 'stVer',
     276    comments    => { },
     277    event       => { Struct => \%sResourceEvent },
     278    modifier    => { },
     279    modifyDate  => { %dateTimeInfo, Groups => { 2 => 'Time' } },
     280    version     => { },
     281);
     282my %sThumbnail = (
     283    STRUCT_NAME => 'Thumbnail',
     284    NAMESPACE   => 'xmpGImg',
     285    height      => { Writable => 'integer' },
     286    width       => { Writable => 'integer' },
     287   'format'     => { },
     288    image       => {
     289        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
     290        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
     291    },
     292);
     293my %sPageInfo = (
     294    STRUCT_NAME => 'PageInfo',
     295    NAMESPACE   => 'xmpGImg',
     296    PageNumber  => { Writable => 'integer', Namespace => 'xmpTPg' }, # override default namespace
     297    height      => { Writable => 'integer' },
     298    width       => { Writable => 'integer' },
     299   'format'     => { },
     300    image       => {
     301        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
     302        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
     303    },
     304);
     305#my %sIdentifierScheme = (
     306#    NAMESPACE   => 'xmpidq',
     307#    Scheme      => { }, # qualifier for xmp:Identifier only
     308#);
     309%sDimensions = (
     310    STRUCT_NAME => 'Dimensions',
     311    NAMESPACE   => 'stDim',
     312    w           => { Writable => 'real' },
     313    h           => { Writable => 'real' },
     314    unit        => { },
     315);
     316%sArea = (
     317    STRUCT_NAME => 'Area',
     318    NAMESPACE   => 'stArea',
     319   'x'          => { Writable => 'real' },
     320   'y'          => { Writable => 'real' },
     321    w           => { Writable => 'real' },
     322    h           => { Writable => 'real' },
     323    d           => { Writable => 'real' },
     324    unit        => { },
     325);
     326%sColorant = (
     327    STRUCT_NAME => 'Colorant',
     328    NAMESPACE   => 'xmpG',
     329    swatchName  => { },
     330    mode        => { PrintConv => { CMYK=>'CMYK', RGB=>'RGB', LAB=>'Lab' } },
     331    # note: do not implement closed choice for "type" because Adobe can't
     332    # get the case right:  spec. says "PROCESS" but Indesign writes "Process"
     333    type        => { },
     334    cyan        => { Writable => 'real' },
     335    magenta     => { Writable => 'real' },
     336    yellow      => { Writable => 'real' },
     337    black       => { Writable => 'real' },
     338    red         => { Writable => 'integer' },
     339    green       => { Writable => 'integer' },
     340    blue        => { Writable => 'integer' },
     341    L           => { Writable => 'real' },
     342    A           => { Writable => 'integer' },
     343    B           => { Writable => 'integer' },
     344);
     345my %sFont = (
     346    STRUCT_NAME => 'Font',
     347    NAMESPACE   => 'stFnt',
     348    fontName    => { },
     349    fontFamily  => { },
     350    fontFace    => { },
     351    fontType    => { },
     352    versionString => { },
     353    composite   => { Writable => 'boolean' },
     354    fontFileName=> { },
     355    childFontFiles => { List => 'Seq' },
     356);
     357my %sOECF = (
     358    NAMESPACE   => 'exif',
     359    STRUCT_NAME => 'OECF',
     360    Columns     => { Writable => 'integer' },
     361    Rows        => { Writable => 'integer' },
     362    Names       => { List => 'Seq' },
     363    Values      => { List => 'Seq', Writable => 'rational' },
     364);
     365
     366# new LR2 crs structures (PH)
     367my %sCorrectionMask = (
     368    STRUCT_NAME => 'CorrectionMask',
     369    NAMESPACE   => 'crs',
     370    What         => { },
     371    MaskValue    => { Writable => 'real' },
     372    Radius       => { Writable => 'real' },
     373    Flow         => { Writable => 'real' },
     374    CenterWeight => { Writable => 'real' },
     375    Dabs         => { List => 'Seq' },
     376    ZeroX        => { Writable => 'real' },
     377    ZeroY        => { Writable => 'real' },
     378    FullX        => { Writable => 'real' },
     379    FullY        => { Writable => 'real' },
     380);
     381my %sCorrection = (
     382    STRUCT_NAME => 'Correction',
     383    NAMESPACE   => 'crs',
     384    What => { },
     385    CorrectionAmount => { Writable => 'real' },
     386    CorrectionActive => { Writable => 'boolean' },
     387    LocalExposure    => { Writable => 'real' },
     388    LocalSaturation  => { Writable => 'real' },
     389    LocalContrast    => { Writable => 'real' },
     390    LocalClarity     => { Writable => 'real' },
     391    LocalSharpness   => { Writable => 'real' },
     392    LocalBrightness  => { Writable => 'real' },
     393    LocalToningHue   => { Writable => 'real' },
     394    LocalToningSaturation => { Writable => 'real' },
     395    CorrectionMasks  => { Struct => \%sCorrectionMask, List => 'Seq' },
     396);
     397
     398# IPTC Extension 1.0 structures
     399my %sLocationDetails = (
     400    NAMESPACE   => 'Iptc4xmpExt',
     401    STRUCT_NAME => 'LocationDetails',
     402    City         => { },
     403    CountryCode  => { },
     404    CountryName  => { },
     405    ProvinceState=> { },
     406    Sublocation  => { },
     407    WorldRegion  => { },
     408);
     409
     410# main XMP tag table (tag ID's are used for the family 1 group names)
    118411%Image::ExifTool::XMP::Main = (
    119412    GROUPS => { 2 => 'Unknown' },
     
    136429        SubDirectory => { TagTable => 'Image::ExifTool::XMP::xmpRights' },
    137430    },
     431    xmpNote => {
     432        Name => 'xmpNote',
     433        SubDirectory => { TagTable => 'Image::ExifTool::XMP::xmpNote' },
     434    },
    138435    xmpMM => {
    139436        Name => 'xmpMM',
     
    151448        Name => 'pdf',
    152449        SubDirectory => { TagTable => 'Image::ExifTool::XMP::pdf' },
     450    },
     451    pdfx => {
     452        Name => 'pdfx',
     453        SubDirectory => { TagTable => 'Image::ExifTool::XMP::pdfx' },
    153454    },
    154455    photoshop => {
     
    177478        SubDirectory => { TagTable => 'Image::ExifTool::XMP::iptcCore' },
    178479    },
     480    iptcExt => {
     481        Name => 'iptcExt',
     482        SubDirectory => { TagTable => 'Image::ExifTool::XMP::iptcExt' },
     483    },
    179484    PixelLive => {
    180485        SubDirectory => { TagTable => 'Image::ExifTool::XMP::PixelLive' },
     
    184489        SubDirectory => { TagTable => 'Image::ExifTool::XMP::xmpPLUS' },
    185490    },
     491    plus => {
     492        Name => 'plus',
     493        SubDirectory => { TagTable => 'Image::ExifTool::XMP::plus' },
     494    },
    186495    cc => {
    187496        Name => 'cc',
     
    202511    microsoft => {
    203512        Name => 'microsoft',
    204         SubDirectory => { TagTable => 'Image::ExifTool::XMP::Microsoft' },
     513        SubDirectory => { TagTable => 'Image::ExifTool::Microsoft::XMP' },
     514    },
     515    MP => {
     516        Name => 'MP',
     517        SubDirectory => { TagTable => 'Image::ExifTool::Microsoft::MP' },
     518    },
     519    MP1 => {
     520        Name => 'MP1',
     521        SubDirectory => { TagTable => 'Image::ExifTool::Microsoft::MP1' },
    205522    },
    206523    lr => {
     
    211528        Name => 'DICOM',
    212529        SubDirectory => { TagTable => 'Image::ExifTool::XMP::DICOM' },
     530    },
     531    album => {
     532        Name => 'album',
     533        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Album' },
     534    },
     535    prism => {
     536        Name => 'prism',
     537        SubDirectory => { TagTable => 'Image::ExifTool::XMP::prism' },
     538    },
     539    prl => {
     540        Name => 'prl',
     541        SubDirectory => { TagTable => 'Image::ExifTool::XMP::prl' },
     542    },
     543    pur => {
     544        Name => 'pur',
     545        SubDirectory => { TagTable => 'Image::ExifTool::XMP::pur' },
     546    },
     547    rdf => {
     548        Name => 'rdf',
     549        SubDirectory => { TagTable => 'Image::ExifTool::XMP::rdf' },
     550    },
     551   'x' => {
     552        Name => 'x',
     553        SubDirectory => { TagTable => 'Image::ExifTool::XMP::x' },
     554    },
     555    acdsee => {
     556        Name => 'acdsee',
     557        SubDirectory => { TagTable => 'Image::ExifTool::XMP::acdsee' },
     558    },
     559    digiKam => {
     560        Name => 'digiKam',
     561        SubDirectory => { TagTable => 'Image::ExifTool::XMP::digiKam' },
     562    },
     563    swf => {
     564        Name => 'swf',
     565        SubDirectory => { TagTable => 'Image::ExifTool::XMP::swf' },
     566    },
     567    cell => {
     568        Name => 'cell',
     569        SubDirectory => { TagTable => 'Image::ExifTool::XMP::cell' },
     570    },
     571   'mwg-rs' => {
     572        Name => 'mwg-rs',
     573        SubDirectory => { TagTable => 'Image::ExifTool::XMP::mwg_rs' },
     574    },
     575   'mwg-kw' => {
     576        Name => 'mwg-kw',
     577        SubDirectory => { TagTable => 'Image::ExifTool::XMP::mwg_kw' },
     578    },
     579   'mwg-coll' => {
     580        Name => 'mwg-coll',
     581        SubDirectory => { TagTable => 'Image::ExifTool::XMP::mwg_coll' },
    213582    },
    214583);
     
    219588# Writable - only need to define this for writable tags if not plain text
    220589#            (boolean, integer, rational, real, date or lang-alt)
    221 # List - XMP list type (Bag, Seq or Alt, or set to 1 for elements in Struct lists)
     590# List - XMP list type (Bag, Seq or Alt, or set to 1 for elements in Struct lists --
     591#        this is necessary to obtain proper list behaviour when reading/writing)
    222592#
    223593# (Note that family 1 group names are generated from the property namespace, not
    224594#  the group1 names below which exist so the groups will appear in the list.)
    225595#
    226 my %xmpTableDefaults = (
     596%xmpTableDefaults = (
    227597    WRITE_PROC => \&WriteXMP,
     598    CHECK_PROC => \&CheckXMP,
    228599    WRITABLE => 'string',
    229600    LANG_INFO => \&GetLangInfo,
     601);
     602
     603# rdf attributes extracted
     604%Image::ExifTool::XMP::rdf = (
     605    %xmpTableDefaults,
     606    GROUPS => { 1 => 'XMP-rdf', 2 => 'Document' },
     607    NAMESPACE   => 'rdf',
     608    NOTES => q{
     609        Most RDF attributes are handled internally, but the "about" attribute is
     610        treated specially to allow it to be set to a specific value if required.
     611    },
     612    about => { Protected => 1 },
     613);
     614
     615# x attributes extracted
     616%Image::ExifTool::XMP::x = (
     617    %xmpTableDefaults,
     618    GROUPS => { 1 => 'XMP-x', 2 => 'Document' },
     619    NAMESPACE   => 'x',
     620    NOTES => qq{
     621        The "x" namespace is used for the "xmpmeta" wrapper, and may contain an
     622        "xmptk" attribute that is extracted as the XMPToolkit tag.  When writing,
     623        the XMPToolkit tag is automatically generated by ExifTool unless
     624        specifically set to another value.
     625    },
     626    xmptk => { Name => 'XMPToolkit', Protected => 1 },
    230627);
    231628
     
    234631    %xmpTableDefaults,
    235632    GROUPS => { 1 => 'XMP-dc', 2 => 'Other' },
    236     NAMESPACE => 'dc',
     633    NAMESPACE   => 'dc',
     634    TABLE_DESC => 'XMP Dublin Core',
    237635    NOTES => 'Dublin Core schema tags.',
    238636    contributor => { Groups => { 2 => 'Author' }, List => 'Bag' },
    239637    coverage    => { },
    240638    creator     => { Groups => { 2 => 'Author' }, List => 'Seq' },
    241     date        => { %dateTimeInfo, List => 'Seq' },
     639    date        => { Groups => { 2 => 'Time' },   List => 'Seq', %dateTimeInfo },
    242640    description => { Groups => { 2 => 'Image'  }, Writable => 'lang-alt' },
    243641   'format'     => { Groups => { 2 => 'Image'  } },
     
    247645    relation    => { List => 'Bag' },
    248646    rights      => { Groups => { 2 => 'Author' }, Writable => 'lang-alt' },
    249     source      => { Groups => { 2 => 'Author' } },
     647    source      => { Groups => { 2 => 'Author' }, Avoid => 1 },
    250648    subject     => { Groups => { 2 => 'Image'  }, List => 'Bag' },
    251649    title       => { Groups => { 2 => 'Image'  }, Writable => 'lang-alt' },
     
    257655    %xmpTableDefaults,
    258656    GROUPS => { 1 => 'XMP-xmp', 2 => 'Image' },
    259     NAMESPACE => 'xmp',
     657    NAMESPACE   => 'xmp',
    260658    NOTES => q{
    261659        XMP Basic schema tags.  If the older "xap", "xapBJ", "xapMM" or "xapRights"
     
    263661        "xmpBJ", "xmpMM" and "xmpRights" prefixes for use in family 1 group names.
    264662    },
    265     Advisory    => { List => 'Bag' },
     663    Advisory    => { List => 'Bag' }, # (deprecated)
    266664    BaseURL     => { },
    267     CreateDate  => { %dateTimeInfo },
     665    # (date/time tags not as reliable as EXIF)
     666    CreateDate  => { Groups => { 2 => 'Time' }, %dateTimeInfo, Priority => 0 },
    268667    CreatorTool => { },
    269668    Identifier  => { Avoid => 1, List => 'Bag' },
    270669    Label       => { },
    271     MetadataDate=> { %dateTimeInfo },
    272     ModifyDate  => { %dateTimeInfo },
     670    MetadataDate=> { Groups => { 2 => 'Time' }, %dateTimeInfo },
     671    ModifyDate  => { Groups => { 2 => 'Time' }, %dateTimeInfo, Priority => 0 },
    273672    Nickname    => { },
    274     Rating      => { Writable => 'integer' },
    275     Thumbnails  => {
    276         SubDirectory => { },
    277         Struct => 'Thumbnail',
    278         List => 'Alt',
    279     },
    280     ThumbnailsHeight    => { List => 1 },
    281     ThumbnailsWidth     => { List => 1 },
    282     ThumbnailsFormat    => { List => 1 },
    283     ThumbnailsImage     => {
    284         # Eventually may want to handle this like a normal thumbnail image
    285         # -- but not yet!  (need to write EncodeBase64() routine....)
    286         # Name => 'ThumbnailImage',
    287         List => 1,
    288         # translate Base64-encoded thumbnail
    289         ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
    290     },
     673    Rating      => { Writable => 'real', Notes => 'a value from 0 to 5, or -1 for "rejected"' },
     674    Thumbnails  => { Struct => \%sThumbnail, List => 'Alt' },
     675    ThumbnailsHeight => { Name => 'ThumbnailHeight', Flat => 1 },
     676    ThumbnailsWidth  => { Name => 'ThumbnailWidth',  Flat => 1 },
     677    ThumbnailsFormat => { Name => 'ThumbnailFormat', Flat => 1 },
     678    ThumbnailsImage  => { Name => 'ThumbnailImage',  Flat => 1, Avoid => 1 },
     679    # the following written by Adobe InDesign, not part of XMP spec:
     680    PageInfo        => { Struct => \%sPageInfo, List => 'Seq' },
     681    PageInfoPageNumber=>{Name => 'PageImagePageNumber', Flat => 1 },
     682    PageInfoHeight  => { Name => 'PageImageHeight', Flat => 1 },
     683    PageInfoWidth   => { Name => 'PageImageWidth',  Flat => 1 },
     684    PageInfoFormat  => { Name => 'PageImageFormat', Flat => 1 },
     685    PageInfoImage   => { Name => 'PageImage',       Flat => 1 },
    291686);
    292687
     
    295690    %xmpTableDefaults,
    296691    GROUPS => { 1 => 'XMP-xmpRights', 2 => 'Author' },
    297     NAMESPACE => 'xmpRights',
     692    NAMESPACE   => 'xmpRights',
    298693    NOTES => 'XMP Rights Management schema tags.',
    299694    Certificate     => { },
     
    304699);
    305700
     701# XMP Note schema properties (xmpNote)
     702%Image::ExifTool::XMP::xmpNote = (
     703    %xmpTableDefaults,
     704    GROUPS => { 1 => 'XMP-xmpNote' },
     705    NAMESPACE   => 'xmpNote',
     706    NOTES => 'XMP Note schema tags.',
     707    HasExtendedXMP => { Writable => 'boolean', Protected => 2 },
     708);
     709
     710# XMP xmpMM ManifestItem struct (ref PH, written by Adobe PDF library 8.0)
     711my %sManifestItem = (
     712    NAMESPACE => 'stMfs',
     713    STRUCT_NAME => 'ManifestItem',
     714    linkForm            => { },
     715    placedXResolution   => { Namespace => 'xmpMM', Writable => 'real' },
     716    placedYResolution   => { Namespace => 'xmpMM', Writable => 'real' },
     717    placedResolutionUnit=> { Namespace => 'xmpMM' },
     718    reference           => { Struct => \%sResourceRef },
     719);
     720
     721# the xmpMM Pantry
     722my %sPantryItem = (
     723    NAMESPACE => undef, # stores any top-level XMP tags
     724    STRUCT_NAME => 'PantryItem',
     725    NOTES => q{
     726        This structure must have an InstanceID field, but may also contain any other
     727        XMP properties.
     728    },
     729    InstanceID => { Namespace => 'xmpMM' },
     730);
     731
    306732# XMP Media Management schema properties (xmpMM, xapMM)
    307733%Image::ExifTool::XMP::xmpMM = (
    308734    %xmpTableDefaults,
    309735    GROUPS => { 1 => 'XMP-xmpMM', 2 => 'Other' },
    310     NAMESPACE => 'xmpMM',
     736    NAMESPACE   => 'xmpMM',
     737    TABLE_DESC => 'XMP Media Management',
    311738    NOTES => 'XMP Media Management schema tags.',
    312     DerivedFrom     => {
    313         SubDirectory => { },
    314         Struct => 'ResourceRef',
    315     },
    316     DerivedFromInstanceID       => { },
    317     DerivedFromDocumentID       => { },
    318     DerivedFromVersionID        => { },
    319     DerivedFromRenditionClass   => { },
    320     DerivedFromRenditionParams  => { },
    321     DerivedFromManager          => { },
    322     DerivedFromManagerVariant   => { },
    323     DerivedFromManageTo         => { },
    324     DerivedFromManageUI         => { },
     739    DerivedFrom     => { Struct => \%sResourceRef },
    325740    DocumentID      => { },
    326     History         => {
    327         SubDirectory => { },
    328         Struct => 'ResourceEvent',
    329         List => 'Seq',
    330     },
     741    History         => { Struct => \%sResourceEvent, List => 'Seq' },
    331742    # we treat these like list items since History is a list
    332     HistoryAction           => { List => 1 },
    333     HistoryInstanceID       => { List => 1 },
    334     HistoryParameters       => { List => 1 },
    335     HistorySoftwareAgent    => { List => 1 },
    336     HistoryWhen             => { List => 1, %dateTimeInfo },
     743    Ingredients     => { Struct => \%sResourceRef, List => 'Bag' },
    337744    InstanceID      => { }, #PH (CS3)
    338     ManagedFrom     => { SubDirectory => { }, Struct => 'ResourceRef' },
    339     ManagedFromInstanceID       => { },
    340     ManagedFromDocumentID       => { },
    341     ManagedFromVersionID        => { },
    342     ManagedFromRenditionClass   => { },
    343     ManagedFromRenditionParams  => { },
    344     ManagedFromManager          => { },
    345     ManagedFromManagerVariant   => { },
    346     ManagedFromManageTo         => { },
    347     ManagedFromManageUI         => { },
     745    ManagedFrom     => { Struct => \%sResourceRef },
    348746    Manager         => { Groups => { 2 => 'Author' } },
    349747    ManageTo        => { Groups => { 2 => 'Author' } },
    350748    ManageUI        => { },
    351749    ManagerVariant  => { },
     750    Manifest        => { Struct => \%sManifestItem, List => 'Bag' },
     751    OriginalDocumentID=> { },
     752    Pantry          => { Struct => \%sPantryItem, List => 'Bag' },
    352753    PreservedFileName => { },   # undocumented
    353754    RenditionClass  => { },
    354755    RenditionParams => { },
    355756    VersionID       => { },
    356     Versions        => {
    357         SubDirectory => { },
    358         Struct => 'Version',
    359         List => 'Seq',
    360     },
    361     VersionsComments    => { List => 1 },   # we treat these like list items
    362     VersionsEvent       => { SubDirectory => { }, Struct => 'ResourceEvent' },
    363     VersionsEventAction         => { List => 1 },
    364     VersionsEventInstanceID     => { List => 1 },
    365     VersionsEventParameters     => { List => 1 },
    366     VersionsEventSoftwareAgent  => { List => 1 },
    367     VersionsEventWhen           => { List => 1, %dateTimeInfo },
    368     VersionsModifyDate          => { List => 1, %dateTimeInfo },
    369     VersionsModifier            => { List => 1 },
    370     VersionsVersion             => { List => 1 },
    371     LastURL                     => { },
    372     RenditionOf         => { SubDirectory => { }, Struct => 'ResourceRef' },
    373     RenditionOfInstanceID       => { },
    374     RenditionOfDocumentID       => { },
    375     RenditionOfVersionID        => { },
    376     RenditionOfRenditionClass   => { },
    377     RenditionOfRenditionParams  => { },
    378     RenditionOfManager          => { },
    379     RenditionOfManagerVariant   => { },
    380     RenditionOfManageTo         => { },
    381     RenditionOfManageUI         => { },
    382     SaveID          => { Writable => 'integer' },
     757    Versions        => { Struct => \%sVersion, List => 'Seq' },
     758    LastURL         => { }, # (deprecated)
     759    RenditionOf     => { Struct => \%sResourceRef }, # (deprecated)
     760    SaveID          => { Writable => 'integer' }, # (deprecated)
    383761);
    384762
     
    387765    %xmpTableDefaults,
    388766    GROUPS => { 1 => 'XMP-xmpBJ', 2 => 'Other' },
    389     NAMESPACE => 'xmpBJ',
     767    NAMESPACE   => 'xmpBJ',
     768    TABLE_DESC => 'XMP Basic Job Ticket',
    390769    NOTES => 'XMP Basic Job Ticket schema tags.',
    391770    # Note: JobRef is a List of structures.  To accomplish this, we set the XMP
    392771    # List=>'Bag', but since SubDirectory is defined, this tag isn't writable
    393772    # directly.  Then we need to set List=>1 for the members so the Writer logic
    394     # will allow us to add list elements.
    395     JobRef => {
    396         SubDirectory => { },
    397         Struct => 'JobRef',
    398         List => 'Bag',
    399     },
    400     JobRefName  => { List => 1 },   # we treat these like list items
    401     JobRefId    => { List => 1 },
    402     JobRefUrl   => { List => 1 },
     773    # will allow us to add list items.
     774    JobRef => { Struct => \%sJobRef, List => 'Bag' },
    403775);
    404776
     
    407779    %xmpTableDefaults,
    408780    GROUPS => { 1 => 'XMP-xmpTPg', 2 => 'Image' },
    409     NAMESPACE => 'xmpTPg',
     781    NAMESPACE   => 'xmpTPg',
     782    TABLE_DESC => 'XMP Paged-Text',
    410783    NOTES => 'XMP Paged-Text schema tags.',
    411     MaxPageSize => { SubDirectory => { }, Struct => 'Dimensions' },
    412     MaxPageSizeW    => { Writable => 'real' },
    413     MaxPageSizeH    => { Writable => 'real' },
    414     MaxPageSizeUnit => { },
    415     NPages      => { Writable => 'integer' },
    416     Fonts       => {
    417         SubDirectory => { },
    418         Struct => 'Font',
    419         List => 'Bag',
    420     },
    421     FontsFontName       => { List => 1 },
    422     FontsFontFamily     => { List => 1 },
    423     FontsFontFace       => { List => 1 },
    424     FontsFontType       => { List => 1 },
    425     FontsVersionString  => { List => 1 },
    426     FontsComposite      => { List => 1, Writable => 'boolean' },
    427     FontsFontFileName   => { List => 1 },
    428     FontsChildFontFiles => { List => 1 },
    429     Colorants   => {
    430         SubDirectory => { },
    431         Struct => 'Colorant',
    432         List => 'Seq',
    433     },
    434     ColorantsSwatchName => { List => 1 },
    435     ColorantsMode       => { List => 1 },
    436     ColorantsType       => { List => 1 },
    437     ColorantsCyan       => { List => 1, Writable => 'real' },
    438     ColorantsMagenta    => { List => 1, Writable => 'real' },
    439     ColorantsYellow     => { List => 1, Writable => 'real' },
    440     ColorantsBlack      => { List => 1, Writable => 'real' },
    441     ColorantsRed        => { List => 1, Writable => 'integer' },
    442     ColorantsGreen      => { List => 1, Writable => 'integer' },
    443     ColorantsBlue       => { List => 1, Writable => 'integer' },
    444     ColorantsL          => { List => 1, Writable => 'real' },
    445     ColorantsA          => { List => 1, Writable => 'integer' },
    446     ColorantsB          => { List => 1, Writable => 'integer' },
    447     PlateNames  => { List => 'Seq' },
    448 );
    449 
    450 # XMP Dynamic Media schema properties (xmpDM)
    451 %Image::ExifTool::XMP::xmpDM = (
    452     %xmpTableDefaults,
    453     GROUPS => { 1 => 'XMP-xmpDM', 2 => 'Image' },
    454     NAMESPACE => 'xmpDM',
    455     NOTES => 'XMP Dynamic Media schema tags.',
    456     projectRef => {
    457         SubDirectory => { },
    458         Struct => 'ProjectLink',
    459     },
    460     projectRefType      => { },
    461     projectRefPath      => { },
    462     videoFrameRate      => { },
    463     videoFrameSize => {
    464         SubDirectory => { },
    465         Struct => 'Dimensions',
    466     },
    467     videoFrameSizeW     => { Writable => 'real' },
    468     videoFrameSizeH     => { Writable => 'real' },
    469     videoFrameSizeUnit  => { },
    470     videoPixelAspectRatio => { Writable => 'rational' },
    471     videoPixelDepth     => { },
    472     videoColorSpace     => { },
    473     videoAlphaMode      => { },
    474     videoAlphaPremultipleColor => {
    475         SubDirectory => { },
    476         Struct => 'Colorant',
    477     },
    478     videoAlphaPremultipleColorSwatchName => { },
    479     videoAlphaPremultipleColorMode       => { },
    480     videoAlphaPremultipleColorType       => { },
    481     videoAlphaPremultipleColorCyan       => { Writable => 'real' },
    482     videoAlphaPremultipleColorMagenta    => { Writable => 'real' },
    483     videoAlphaPremultipleColorYellow     => { Writable => 'real' },
    484     videoAlphaPremultipleColorBlack      => { Writable => 'real' },
    485     videoAlphaPremultipleColorRed        => { Writable => 'integer' },
    486     videoAlphaPremultipleColorGreen      => { Writable => 'integer' },
    487     videoAlphaPremultipleColorBlue       => { Writable => 'integer' },
    488     videoAlphaPremultipleColorL          => { Writable => 'real' },
    489     videoAlphaPremultipleColorA          => { Writable => 'integer' },
    490     videoAlphaPremultipleColorB          => { Writable => 'integer' },
    491     videoAlphaUnityIsTransparent => { Writable => 'boolean' },
    492     videoCompressor     => { },
    493     videoFieldOrder     => { },
    494     pullDown            => { },
    495     audioSampleRate     => { Writable => 'integer' },
    496     audioSampleType     => { },
    497     audioChannelType    => { },
    498     audioCompressor     => { },
    499     speakerPlacement    => { },
    500     fileDataRate        => { Writable => 'rational' },
    501     tapeName            => { },
    502     altTapeName         => { },
    503     startTimecode => {
    504         SubDirectory => { },
    505         Struct => 'Timecode',
    506     },
    507     startTimecodeTimeValue  => { },
    508     startTimecodeTimeFormat => { },
    509     altTimecode => {
    510         SubDirectory => { },
    511         Struct => 'Timecode',
    512     },
    513     altTimecodeTimeValue    => { },
    514     altTimecodeTimeFormat   => { },
    515     duration            => { },
    516     scene               => { Avoid => 1 },
    517     shotName            => { },
    518     shotDate            => { %dateTimeInfo },
    519     shotLocation        => { },
    520     logComment          => { },
    521     markers => {
    522         SubDirectory => { },
    523         Struct => 'Marker',
    524         List => 'Seq',
    525     },
    526     markersStartTime    => { List => 1 },
    527     markersDuration     => { List => 1 },
    528     markersComment      => { List => 1 },
    529     markersName         => { List => 1 },
    530     markersLocation     => { List => 1 },
    531     markersTarget       => { List => 1 },
    532     markersType         => { List => 1 },
    533     contributedMedia => {
    534         SubDirectory => { },
    535         Struct => 'Media',
    536         List => 'Bag',
    537     },
    538     contributedMediaPath         => { List => 1 },
    539     contributedMediaTrack        => { List => 1 },
    540     contributedMediaStartTime    => { List => 1 },
    541     contributedMediaDuration     => { List => 1 },
    542     contributedMediaManaged      => { List => 1, Writable => 'boolean' },
    543     contributedMediaWebStatement => { List => 1 },
    544     absPeakAudioFilePath => { },
    545     relativePeakAudioFilePath => { },
    546     videoModDate    => { %dateTimeInfo },
    547     audioModDate    => { %dateTimeInfo },
    548     metadataModDate => { %dateTimeInfo },
    549     artist          => { Avoid => 1, Groups => { 2 => 'Author' } },
    550     album           => { },
    551     trackNumber     => { Writable => 'integer' },
    552     genre           => { },
    553     copyright       => { Avoid => 1, Groups => { 2 => 'Author' } },
    554     releaseDate     => { %dateTimeInfo },
    555     composer        => { Groups => { 2 => 'Author' } },
    556     engineer        => { },
    557     tempo           => { Writable => 'real' },
    558     instrument      => { },
    559     introTime       => { },
    560     outCue          => { },
    561     relativeTimestamp => { },
    562     loop            => { Writable => 'boolean' },
    563     numberOfBeats   => { Writable => 'real' },
    564     key             => { },
    565     stretchMode     => { },
    566     timeScaleParams => {
    567         SubDirectory => { },
    568         Struct => 'TimeScaleStretch',
    569     },
    570     timeScaleParamsQuality  => { },
    571     timeScaleParamsFrameSize=> { Writable => 'real' },
    572     timeScaleParamsFrameOverlappingPercentage => { Writable => 'real' },
    573     resampleParams => {
    574         SubDirectory => { },
    575         Struct => 'ResampleStretch',
    576     },
    577     resampleParamsQuality   => { },
    578     beatSpliceParams => {
    579         SubDirectory => { },
    580         Struct => 'BeatSpliceStretch',
    581     },
    582     beatSpliceParamsUseFileBeatsMarker => { Writable => 'boolean' },
    583     beatSpliceParamsRiseInDecibel      => { Writable => 'real' },
    584     beatSpliceParamsRiseInTimeDuration => { },
    585     timeSignature   => { },
    586     scaleType       => { },
     784    MaxPageSize         => { Struct => \%sDimensions },
     785    NPages              => { Writable => 'integer' },
     786    Fonts               => { Struct => \%sFont, List => 'Bag' },
     787    FontsFontName       => { Flat => 1, Name => 'FontName' },
     788    FontsFontFamily     => { Flat => 1, Name => 'FontFamily' },
     789    FontsFontFace       => { Flat => 1, Name => 'FontFace' },
     790    FontsFontType       => { Flat => 1, Name => 'FontType' },
     791    FontsVersionString  => { Flat => 1, Name => 'FontVersion' },
     792    FontsComposite      => { Flat => 1, Name => 'FontComposite' },
     793    FontsFontFileName   => { Flat => 1, Name => 'FontFileName' },
     794    FontsChildFontFiles => { Flat => 1, Name => 'ChildFontFiles' },
     795    Colorants           => { Struct => \%sColorant, List => 'Seq' },
     796    ColorantsSwatchName => { Flat => 1, Name => 'ColorantSwatchName' },
     797    ColorantsMode       => { Flat => 1, Name => 'ColorantMode' },
     798    ColorantsType       => { Flat => 1, Name => 'ColorantType' },
     799    ColorantsCyan       => { Flat => 1, Name => 'ColorantCyan' },
     800    ColorantsMagenta    => { Flat => 1, Name => 'ColorantMagenta' },
     801    ColorantsYellow     => { Flat => 1, Name => 'ColorantYellow' },
     802    ColorantsBlack      => { Flat => 1, Name => 'ColorantBlack' },
     803    ColorantsRed        => { Flat => 1, Name => 'ColorantRed' },
     804    ColorantsGreen      => { Flat => 1, Name => 'ColorantGreen' },
     805    ColorantsBlue       => { Flat => 1, Name => 'ColorantBlue' },
     806    ColorantsL          => { Flat => 1, Name => 'ColorantL' },
     807    ColorantsA          => { Flat => 1, Name => 'ColorantA' },
     808    ColorantsB          => { Flat => 1, Name => 'ColorantB' },
     809    PlateNames          => { List => 'Seq' },
    587810);
    588811
     
    591814    %xmpTableDefaults,
    592815    GROUPS => { 1 => 'XMP-pdf', 2 => 'Image' },
    593     NAMESPACE => 'pdf',
     816    NAMESPACE   => 'pdf',
     817    TABLE_DESC => 'XMP PDF',
    594818    NOTES => q{
    595819        Adobe PDF schema tags.  The official XMP specification defines only
    596         Keywords, PDFVersion and Producer.  The other tags are included because they
    597         have been observed in PDF files, but Creator, Subject and Title are avoided
    598         when writing due to name conflicts with XMP-dc tags.
     820        Keywords, PDFVersion, Producer and Trapped.  The other tags are included
     821        because they have been observed in PDF files, but some are avoided when
     822        writing due to name conflicts with other XMP namespaces.
    599823    },
    600824    Author      => { Groups => { 2 => 'Author' } }, #PH
    601     ModDate     => { %dateTimeInfo }, #PH
    602     CreationDate=> { %dateTimeInfo }, #PH
     825    ModDate     => { Groups => { 2 => 'Time' }, %dateTimeInfo }, #PH
     826    CreationDate=> { Groups => { 2 => 'Time' }, %dateTimeInfo }, #PH
    603827    Creator     => { Groups => { 2 => 'Author' }, Avoid => 1 },
     828    Copyright   => { Groups => { 2 => 'Author' }, Avoid => 1 }, #PH
     829    Marked      => { Avoid => 1, Writable => 'boolean' }, #PH
    604830    Subject     => { Avoid => 1 },
    605831    Title       => { Avoid => 1 },
     832    Trapped     => { #PH
     833        # remove leading '/' from '/True' or '/False'
     834        ValueConv => '$val=~s{^/}{}; $val',
     835        ValueConvInv => '"/$val"',
     836        PrintConv => { True => 'True', False => 'False', Unknown => 'Unknown' },
     837    },
    606838    Keywords    => { },
    607839    PDFVersion  => { },
    608840    Producer    => { Groups => { 2 => 'Author' } },
     841);
     842
     843# PDF extension schema properties (pdfx)
     844%Image::ExifTool::XMP::pdfx = (
     845    %xmpTableDefaults,
     846    GROUPS => { 1 => 'XMP-pdfx', 2 => 'Document' },
     847    NAMESPACE   => 'pdfx',
     848    NOTES => q{
     849        PDF extension tags.  This namespace is used to store application-defined PDF
     850        information, so there are no pre-defined tags.  User-defined tags must be
     851        created to enable writing of XMP-pdfx information.
     852    },
    609853);
    610854
     
    613857    %xmpTableDefaults,
    614858    GROUPS => { 1 => 'XMP-photoshop', 2 => 'Image' },
    615     NAMESPACE => 'photoshop',
     859    NAMESPACE   => 'photoshop',
     860    TABLE_DESC => 'XMP Photoshop',
    616861    NOTES => 'Adobe Photoshop schema tags.',
    617862    AuthorsPosition => { Groups => { 2 => 'Author' } },
     
    619864    Category        => { },
    620865    City            => { Groups => { 2 => 'Location' } },
     866    ColorMode       => {
     867        Writable => 'integer', # (as of July 2010 spec, courtesy of yours truly)
     868        PrintConvColumns => 2,
     869        PrintConv => {
     870            0 => 'Bitmap',
     871            1 => 'Grayscale',
     872            2 => 'Indexed',
     873            3 => 'RGB',
     874            4 => 'CMYK',
     875            7 => 'Multichannel',
     876            8 => 'Duotone',
     877            9 => 'Lab',
     878        },
     879    },
    621880    Country         => { Groups => { 2 => 'Location' } },
    622     ColorMode       => { }, #PH
    623881    Credit          => { Groups => { 2 => 'Author' } },
    624     DateCreated     => { %dateTimeInfo },
     882    DateCreated     => { Groups => { 2 => 'Time' }, %dateTimeInfo },
     883    DocumentAncestors => {
     884        List => 'bag',
     885        Struct => {
     886            STRUCT_NAME => 'Ancestor',
     887            NAMESPACE   => 'photoshop',
     888            AncestorID => { },
     889        },
     890    },
     891    DocumentAncestorsAncestorID => { Name => 'DocumentAncestorID', Flat => 1 },
     892    Headline        => { },
    625893    History         => { }, #PH (CS3)
    626     Headline        => { },
     894    ICCProfile      => { Name => 'ICCProfileName' }, #PH
    627895    Instructions    => { },
    628     ICCProfile      => { Name => 'ICCProfileName' }, #PH
    629896    LegacyIPTCDigest=> { }, #PH
    630897    SidecarForExtension => { }, #PH (CS3)
    631     Source          => { Groups => { 2 => 'Author' }, Avoid => 1 },
     898    Source          => { Groups => { 2 => 'Author' } },
    632899    State           => { Groups => { 2 => 'Location' } },
    633     # the documentation doesn't show this as a 'Bag', but that's the
    634     # way Photoshop7.0 writes it - PH
     900    # the XMP spec doesn't show SupplementalCategories as a 'Bag', but
     901    # that's the way Photoshop writes it [fixed in the June 2005 XMP spec].
     902    # Also, it is incorrectly listed as "SupplementalCategory" in the
     903    # IPTC Standard Photo Metadata docs (2008rev2 and July 2009rev1) - PH
    635904    SupplementalCategories  => { List => 'Bag' },
     905    TextLayers => {
     906        List => 'seq',
     907        Struct => {
     908            STRUCT_NAME => 'Layer',
     909            NAMESPACE   => 'photoshop',
     910            LayerName => { },
     911            LayerText => { },
     912        },
     913    },
     914    TextLayersLayerName => { Flat => 1, Name => 'TextLayerName' },
     915    TextLayersLayerText => { Flat => 1, Name => 'TextLayerText' },
    636916    TransmissionReference   => { },
    637     Urgency         => { Writable => 'integer' },
     917    Urgency         => {
     918        Writable => 'integer',
     919        Notes => 'should be in the range 1-8 to conform with the XMP spec',
     920        PrintConv => { # (same values as IPTC:Urgency)
     921            0 => '0 (reserved)',              # (not standard XMP)
     922            1 => '1 (most urgent)',
     923            2 => 2,
     924            3 => 3,
     925            4 => 4,
     926            5 => '5 (normal urgency)',
     927            6 => 6,
     928            7 => 7,
     929            8 => '8 (least urgent)',
     930            9 => '9 (user-defined priority)', # (not standard XMP)
     931        },
     932    },
    638933);
    639934
     
    642937    %xmpTableDefaults,
    643938    GROUPS => { 1 => 'XMP-crs', 2 => 'Image' },
    644     NAMESPACE => 'crs',
     939    NAMESPACE   => 'crs',
     940    TABLE_DESC => 'Photoshop Camera Raw Schema',
    645941    NOTES => 'Photoshop Camera Raw Schema tags.',
    646942    AlreadyApplied  => { Writable => 'boolean' }, #PH (written by LightRoom beta 4.1)
     
    657953    ColorNoiseReduction => { Writable => 'integer' },
    658954    Contrast        => { Writable => 'integer', Avoid => 1 },
     955    Converter       => { }, #PH guess (found in EXIF)
    659956    CropTop         => { Writable => 'real' },
    660957    CropLeft        => { Writable => 'real' },
     
    678975    HasSettings     => { Writable => 'boolean' },
    679976    LuminanceSmoothing  => { Writable => 'integer' },
     977    MoireFilter     => { PrintConv => { Off=>'Off', On=>'On' } },
    680978    RawFileName     => { },
    681979    RedHue          => { Writable => 'integer' },
     
    685983    ShadowTint      => { Writable => 'integer' },
    686984    Sharpness       => { Writable => 'integer', Avoid => 1 },
    687     Temperature     => { Writable => 'integer' },
     985    Smoothness      => { Writable => 'integer' },
     986    Temperature     => { Writable => 'integer', Avoid => 1, Name => 'ColorTemperature' },
    688987    Tint            => { Writable => 'integer' },
    689988    ToneCurve       => { List => 'Seq' },
     
    7621061    SplitToningShadowSaturation => { Writable => 'integer' },
    7631062    Vibrance                    => { Writable => 'integer' },
     1063    # new tags written by LR 1.4 (not sure in what version they first appeared)
     1064    GrayMixerRed                => { Writable => 'integer' },
     1065    GrayMixerOrange             => { Writable => 'integer' },
     1066    GrayMixerYellow             => { Writable => 'integer' },
     1067    GrayMixerGreen              => { Writable => 'integer' },
     1068    GrayMixerAqua               => { Writable => 'integer' },
     1069    GrayMixerBlue               => { Writable => 'integer' },
     1070    GrayMixerPurple             => { Writable => 'integer' },
     1071    GrayMixerMagenta            => { Writable => 'integer' },
     1072    RetouchInfo                 => { List => 'Seq' },
     1073    RedEyeInfo                  => { List => 'Seq' },
     1074    # new tags written by LR 2.0 (ref PH)
     1075    CropUnit => { # was the XMP documentation wrong with "CropUnits"??
     1076        Writable => 'integer',
     1077        PrintConv => {
     1078            0 => 'pixels',
     1079            1 => 'inches',
     1080            2 => 'cm',
     1081            # have seen a value of 3 here! - PH
     1082        },
     1083    },
     1084    PostCropVignetteAmount      => { Writable => 'integer' },
     1085    PostCropVignetteMidpoint    => { Writable => 'integer' },
     1086    PostCropVignetteFeather     => { Writable => 'integer' },
     1087    PostCropVignetteRoundness   => { Writable => 'integer' },
     1088    PostCropVignetteStyle       => { Writable => 'integer' },
     1089    # disable List behaviour of flattened Gradient/PaintBasedCorrections
     1090    # because these are nested in lists and the flattened tags can't
     1091    # do justice to this complex structure
     1092    GradientBasedCorrections => { Struct => \%sCorrection, List => 'Seq' },
     1093    GradientBasedCorrectionsWhat => {
     1094        Name => 'GradientBasedCorrWhat',
     1095        Flat => 1, List => 0,
     1096    },
     1097    GradientBasedCorrectionsCorrectionAmount => {
     1098        Name => 'GradientBasedCorrAmount',
     1099        Flat => 1, List => 0,
     1100    },
     1101    GradientBasedCorrectionsCorrectionActive => {
     1102        Name => 'GradientBasedCorrActive',
     1103        Flat => 1, List => 0,
     1104    },
     1105    GradientBasedCorrectionsLocalExposure => {
     1106        Name => 'GradientBasedCorrExposure',
     1107        Flat => 1, List => 0,
     1108    },
     1109    GradientBasedCorrectionsLocalSaturation => {
     1110        Name => 'GradientBasedCorrSaturation',
     1111        Flat => 1, List => 0,
     1112    },
     1113    GradientBasedCorrectionsLocalContrast => {
     1114        Name => 'GradientBasedCorrContrast',
     1115        Flat => 1, List => 0,
     1116    },
     1117    GradientBasedCorrectionsLocalClarity => {
     1118        Name => 'GradientBasedCorrClarity',
     1119        Flat => 1, List => 0,
     1120    },
     1121    GradientBasedCorrectionsLocalSharpness => {
     1122        Name => 'GradientBasedCorrSharpness',
     1123        Flat => 1, List => 0,
     1124    },
     1125    GradientBasedCorrectionsLocalBrightness => {
     1126        Name => 'GradientBasedCorrBrightness',
     1127        Flat => 1, List => 0,
     1128    },
     1129    GradientBasedCorrectionsLocalToningHue => {
     1130        Name => 'GradientBasedCorrHue',
     1131        Flat => 1, List => 0,
     1132    },
     1133    GradientBasedCorrectionsLocalToningSaturation => {
     1134        Name => 'GradientBasedCorrSaturation',
     1135        Flat => 1, List => 0,
     1136    },
     1137    GradientBasedCorrectionsCorrectionMasks => {
     1138        Name => 'GradientBasedCorrMasks',
     1139        Flat => 1
     1140    },
     1141    GradientBasedCorrectionsCorrectionMasksWhat => {
     1142        Name => 'GradientBasedCorrMaskWhat',
     1143        Flat => 1, List => 0,
     1144    },
     1145    GradientBasedCorrectionsCorrectionMasksMaskValue => {
     1146        Name => 'GradientBasedCorrMaskValue',
     1147        Flat => 1, List => 0,
     1148    },
     1149    GradientBasedCorrectionsCorrectionMasksRadius => {
     1150        Name => 'GradientBasedCorrMaskRadius',
     1151        Flat => 1, List => 0,
     1152    },
     1153    GradientBasedCorrectionsCorrectionMasksFlow => {
     1154        Name => 'GradientBasedCorrMaskFlow',
     1155        Flat => 1, List => 0,
     1156    },
     1157    GradientBasedCorrectionsCorrectionMasksCenterWeight => {
     1158        Name => 'GradientBasedCorrMaskCenterWeight',
     1159        Flat => 1, List => 0,
     1160    },
     1161    GradientBasedCorrectionsCorrectionMasksDabs => {
     1162        Name => 'GradientBasedCorrMaskDabs',
     1163        Flat => 1, List => 0,
     1164    },
     1165    GradientBasedCorrectionsCorrectionMasksZeroX => {
     1166        Name => 'GradientBasedCorrMaskZeroX',
     1167        Flat => 1, List => 0,
     1168    },
     1169    GradientBasedCorrectionsCorrectionMasksZeroY => {
     1170        Name => 'GradientBasedCorrMaskZeroY',
     1171        Flat => 1, List => 0,
     1172    },
     1173    GradientBasedCorrectionsCorrectionMasksFullX => {
     1174        Name => 'GradientBasedCorrMaskFullX',
     1175        Flat => 1, List => 0,
     1176    },
     1177    GradientBasedCorrectionsCorrectionMasksFullY => {
     1178        Name => 'GradientBasedCorrMaskFullY',
     1179        Flat => 1, List => 0,
     1180    },
     1181    PaintBasedCorrections => { Struct => \%sCorrection, List => 'Seq' },
     1182    PaintBasedCorrectionsWhat => {
     1183        Name => 'PaintCorrectionWhat',
     1184        Flat => 1, List => 0,
     1185    },
     1186    PaintBasedCorrectionsCorrectionAmount => {
     1187        Name => 'PaintCorrectionAmount',
     1188        Flat => 1, List => 0,
     1189    },
     1190    PaintBasedCorrectionsCorrectionActive => {
     1191        Name => 'PaintCorrectionActive',
     1192        Flat => 1, List => 0,
     1193    },
     1194    PaintBasedCorrectionsLocalExposure => {
     1195        Name => 'PaintCorrectionExposure',
     1196        Flat => 1, List => 0,
     1197    },
     1198    PaintBasedCorrectionsLocalSaturation => {
     1199        Name => 'PaintCorrectionSaturation',
     1200        Flat => 1, List => 0,
     1201    },
     1202    PaintBasedCorrectionsLocalContrast => {
     1203        Name => 'PaintCorrectionContrast',
     1204        Flat => 1, List => 0,
     1205    },
     1206    PaintBasedCorrectionsLocalClarity => {
     1207        Name => 'PaintCorrectionClarity',
     1208        Flat => 1, List => 0,
     1209    },
     1210    PaintBasedCorrectionsLocalSharpness => {
     1211        Name => 'PaintCorrectionSharpness',
     1212        Flat => 1, List => 0,
     1213    },
     1214    PaintBasedCorrectionsLocalBrightness => {
     1215        Name => 'PaintCorrectionBrightness',
     1216        Flat => 1, List => 0,
     1217    },
     1218    PaintBasedCorrectionsLocalToningHue => {
     1219        Name => 'PaintCorrectionHue',
     1220        Flat => 1, List => 0,
     1221    },
     1222    PaintBasedCorrectionsLocalToningSaturation => {
     1223        Name => 'PaintCorrectionSaturation',
     1224        Flat => 1, List => 0,
     1225    },
     1226    PaintBasedCorrectionsCorrectionMasks => {
     1227        Name => 'PaintBasedCorrectionMasks',
     1228        Flat => 1,
     1229    },
     1230    PaintBasedCorrectionsCorrectionMasksWhat => {
     1231        Name => 'PaintCorrectionMaskWhat',
     1232        Flat => 1, List => 0,
     1233    },
     1234    PaintBasedCorrectionsCorrectionMasksMaskValue => {
     1235        Name => 'PaintCorrectionMaskValue',
     1236        Flat => 1, List => 0,
     1237    },
     1238    PaintBasedCorrectionsCorrectionMasksRadius => {
     1239        Name => 'PaintCorrectionMaskRadius',
     1240        Flat => 1, List => 0,
     1241    },
     1242    PaintBasedCorrectionsCorrectionMasksFlow => {
     1243        Name => 'PaintCorrectionMaskFlow',
     1244        Flat => 1, List => 0,
     1245    },
     1246    PaintBasedCorrectionsCorrectionMasksCenterWeight => {
     1247        Name => 'PaintCorrectionMaskCenterWeight',
     1248        Flat => 1, List => 0,
     1249    },
     1250    PaintBasedCorrectionsCorrectionMasksDabs => {
     1251        Name => 'PaintCorrectionMaskDabs',
     1252        Flat => 1, List => 0,
     1253    },
     1254    PaintBasedCorrectionsCorrectionMasksZeroX => {
     1255        Name => 'PaintCorrectionMaskZeroX',
     1256        Flat => 1, List => 0,
     1257    },
     1258    PaintBasedCorrectionsCorrectionMasksZeroY => {
     1259        Name => 'PaintCorrectionMaskZeroY',
     1260        Flat => 1, List => 0,
     1261    },
     1262    PaintBasedCorrectionsCorrectionMasksFullX => {
     1263        Name => 'PaintCorrectionMaskFullX',
     1264        Flat => 1, List => 0,
     1265    },
     1266    PaintBasedCorrectionsCorrectionMasksFullY => {
     1267        Name => 'PaintCorrectionMaskFullY',
     1268        Flat => 1, List => 0,
     1269    },
     1270    # new tags written by LR 3 (thanks Wolfgang Guelcker)
     1271    ProcessVersion                       => { },
     1272    LensProfileEnable                    => { Writable => 'integer' },
     1273    LensProfileSetup                     => { },
     1274    LensProfileName                      => { },
     1275    LensProfileFilename                  => { },
     1276    LensProfileDigest                    => { },
     1277    LensProfileDistortionScale           => { Writable => 'integer' },
     1278    LensProfileChromaticAberrationScale  => { Writable => 'integer' },
     1279    LensProfileVignettingScale           => { Writable => 'integer' },
     1280    LensManualDistortionAmount           => { Writable => 'integer' },
     1281    PerspectiveVertical                  => { Writable => 'integer' },
     1282    PerspectiveHorizontal                => { Writable => 'integer' },
     1283    PerspectiveRotate                    => { Writable => 'real'    },
     1284    PerspectiveScale                     => { Writable => 'integer' },
     1285    CropConstrainToWarp                  => { Writable => 'integer' },     
     1286    LuminanceNoiseReductionDetail        => { Writable => 'integer' },
     1287    LuminanceNoiseReductionContrast      => { Writable => 'integer' },
     1288    ColorNoiseReductionDetail            => { Writable => 'integer' },
     1289    GrainAmount                          => { Writable => 'integer' },
     1290    GrainSize                            => { Writable => 'integer' },
     1291    GrainFrequency                       => { Writable => 'integer' },
    7641292);
    7651293
     
    7681296    %xmpTableDefaults,
    7691297    GROUPS => { 1 => 'XMP-tiff', 2 => 'Image' },
    770     NAMESPACE => 'tiff',
     1298    NAMESPACE   => 'tiff',
     1299    PRIORITY => 0, # not as reliable as actual TIFF tags
     1300    TABLE_DESC => 'XMP TIFF',
    7711301    NOTES => 'EXIF schema for TIFF tags.',
    772     ImageWidth  => { Writable => 'integer' },
    773     ImageLength => {
    774         Name => 'ImageHeight',
    775         Writable => 'integer',
    776     },
    777     BitsPerSample => { Writable => 'integer', List => 'Seq' },
     1302    ImageWidth    => { Writable => 'integer' },
     1303    ImageLength   => { Writable => 'integer', Name => 'ImageHeight' },
     1304    BitsPerSample => { Writable => 'integer', List => 'Seq', AutoSplit => 1 },
    7781305    Compression => {
    7791306        Writable => 'integer',
     1307        SeparateTable => 'EXIF Compression',
    7801308        PrintConv => \%Image::ExifTool::Exif::compression,
    7811309    },
     
    7961324        },
    7971325    },
    798     YCbCrSubSampling => {
    799         PrintConv => {
    800             '1 1' => 'YCbCr4:4:4',
    801             '2 1' => 'YCbCr4:2:2',
    802             '2 2' => 'YCbCr4:2:0',
    803             '4 1' => 'YCbCr4:1:1',
    804             '4 2' => 'YCbCr4:1:0',
    805             '1 2' => 'YCbCr4:4:0',
    806         },
    807     },
     1326    YCbCrSubSampling => { PrintConv => \%Image::ExifTool::JPEG::yCbCrSubSampling },
    8081327    YCbCrPositioning => {
    8091328        Writable => 'integer',
     
    8171336    ResolutionUnit => {
    8181337        Writable => 'integer',
     1338        Notes => 'the value 1 is not standard EXIF',
    8191339        PrintConv => {
    8201340            1 => 'None',
     
    8241344    },
    8251345    TransferFunction      => { Writable => 'integer',  List => 'Seq' },
    826     WhitePoint            => { Writable => 'rational', List => 'Seq' },
    827     PrimaryChromaticities => { Writable => 'rational', List => 'Seq' },
    828     YCbCrCoefficients     => { Writable => 'rational', List => 'Seq' },
    829     ReferenceBlackWhite   => { Writable => 'rational', List => 'Seq' },
    830     DateTime => {
     1346    WhitePoint            => { Writable => 'rational', List => 'Seq', AutoSplit => 1 },
     1347    PrimaryChromaticities => { Writable => 'rational', List => 'Seq', AutoSplit => 1 },
     1348    YCbCrCoefficients     => { Writable => 'rational', List => 'Seq', AutoSplit => 1 },
     1349    ReferenceBlackWhite   => { Writable => 'rational', List => 'Seq', AutoSplit => 1 },
     1350    DateTime => { # (EXIF tag named ModifyDate, but this exists in XMP-xmp)
    8311351        Description => 'Date/Time Modified',
     1352        Groups => { 2 => 'Time' },
    8321353        %dateTimeInfo,
    8331354    },
    8341355    ImageDescription => { Writable => 'lang-alt' },
    835     Make  => { Groups => { 2 => 'Camera' } },
    836     Model => {
    837         Description => 'Camera Model Name',
    838         Groups => { 2 => 'Camera' },
    839     },
     1356    Make      => { Groups => { 2 => 'Camera' } },
     1357    Model     => { Groups => { 2 => 'Camera' }, Description => 'Camera Model Name' },
    8401358    Software  => { },
    8411359    Artist    => { Groups => { 2 => 'Author' } },
    842     Copyright => {
    843         Groups => { 2 => 'Author' },
    844         Writable => 'lang-alt',
    845     },
     1360    Copyright => { Groups => { 2 => 'Author' }, Writable => 'lang-alt' },
    8461361    NativeDigest => { }, #PH
    8471362);
     
    8511366    %xmpTableDefaults,
    8521367    GROUPS => { 1 => 'XMP-exif', 2 => 'Image' },
    853     NAMESPACE => 'exif',
     1368    NAMESPACE   => 'exif',
     1369    PRIORITY => 0, # not as reliable as actual EXIF tags
    8541370    NOTES => 'EXIF schema for EXIF tags.',
    8551371    ExifVersion     => { },
     
    8571373    ColorSpace => {
    8581374        Writable => 'integer',
     1375        # (some applications incorrectly write -1 as a long integer)
     1376        ValueConv => '$val == 0xffffffff ? 0xffff : $val',
     1377        ValueConvInv => '$val',
    8591378        PrintConv => {
    8601379            1 => 'sRGB',
    8611380            2 => 'Adobe RGB',
    8621381            0xffff => 'Uncalibrated',
    863             0xffffffff => 'Uncalibrated',
    8641382        },
    8651383    },
     
    8671385        List => 'Seq',
    8681386        Writable => 'integer',
    869         PrintConv => {
    870             0 => '.',
     1387        AutoSplit => 1,
     1388        PrintConvColumns => 2,
     1389        PrintConv => {
     1390            0 => '-',
    8711391            1 => 'Y',
    8721392            2 => 'Cb',
     
    8771397        },
    8781398    },
    879     CompressedBitsPerPixel => {
    880         Writable => 'rational',
    881     },
    882     PixelXDimension => {
    883         Name => 'ExifImageWidth',
    884         Writable => 'integer',
    885     },
    886     PixelYDimension => {
    887         Name => 'ExifImageLength',
    888         Writable => 'integer',
    889     },
    890     MakerNote => { },
    891     UserComment => {
    892         Writable => 'lang-alt',
    893     },
     1399    CompressedBitsPerPixel => { Writable => 'rational' },
     1400    PixelXDimension  => { Name => 'ExifImageWidth',  Writable => 'integer' },
     1401    PixelYDimension  => { Name => 'ExifImageHeight', Writable => 'integer' },
     1402    MakerNote        => { },
     1403    UserComment      => { Writable => 'lang-alt' },
    8941404    RelatedSoundFile => { },
    8951405    DateTimeOriginal => {
    8961406        Description => 'Date/Time Original',
     1407        Groups => { 2 => 'Time' },
    8971408        %dateTimeInfo,
    8981409    },
    899     DateTimeDigitized => {
     1410    DateTimeDigitized => { # (EXIF tag named CreateDate, but this exists in XMP-xmp)
    9001411        Description => 'Date/Time Digitized',
     1412        Groups => { 2 => 'Time' },
    9011413        %dateTimeInfo,
    9021414    },
     
    9041416        Writable => 'rational',
    9051417        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    906         PrintConvInv => 'eval $val',
     1418        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    9071419    },
    9081420    FNumber => {
     
    9151427        Writable => 'integer',
    9161428        PrintConv => {
     1429            0 => 'Not Defined',
    9171430            1 => 'Manual',
    9181431            2 => 'Program AE',
     
    9251438        },
    9261439    },
    927     SpectralSensitivity => {
    928         Groups => { 2 => 'Camera' },
    929     },
     1440    SpectralSensitivity => { Groups => { 2 => 'Camera' } },
    9301441    ISOSpeedRatings => {
    9311442        Name => 'ISO',
    9321443        Writable => 'integer',
    9331444        List => 'Seq',
     1445        AutoSplit => 1,
    9341446    },
    9351447    OECF => {
    9361448        Name => 'Opto-ElectricConvFactor',
    9371449        Groups => { 2 => 'Camera' },
    938         SubDirectory => { },
    939         Struct => 'OECF',
    940     },
    941     OECFColumns => {
    942         Groups => { 2 => 'Camera' },
    943         Writable => 'integer',
    944     },
    945     OECFRows => {
    946         Groups => { 2 => 'Camera' },
    947         Writable => 'integer',
    948     },
    949     OECFNames => {
    950         Groups => { 2 => 'Camera' },
    951         List => 'Seq',
    952     },
    953     OECFValues => {
    954         Groups => { 2 => 'Camera' },
    955         Writable => 'rational',
    956         List => 'Seq',
    957     },
     1450        Struct => \%sOECF,
     1451    },
     1452    OECFColumns => { Flat => 1 },
     1453    OECFRows    => { Flat => 1 },
     1454    OECFNames   => { Flat => 1 },
     1455    OECFValues  => { Flat => 1 },
    9581456    ShutterSpeedValue => {
    9591457        Writable => 'rational',
     
    9611459        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
    9621460        ValueConvInv => '$val>0 ? -log($val)/log(2) : 0',
    963         # do eval to convert things like '1/100'
    964         PrintConvInv => 'eval $val',
     1461        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    9651462    },
    9661463    ApertureValue => {
     
    9711468        PrintConvInv => '$val',
    9721469    },
    973     BrightnessValue => {
    974         Writable => 'rational',
    975     },
     1470    BrightnessValue   => { Writable => 'rational' },
    9761471    ExposureBiasValue => {
    9771472        Name => 'ExposureCompensation',
    9781473        Writable => 'rational',
    979         PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     1474        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
    9801475        PrintConvInv => '$val',
    9811476    },
     
    9911486        Groups => { 2 => 'Camera' },
    9921487        Writable => 'rational',
    993         PrintConv => '$val eq "inf" ? $val : "$val m"',
     1488        PrintConv => '$val =~ /^(inf|undef)$/ ? $val : "$val m"',
    9941489        PrintConvInv => '$val=~s/\s*m$//;$val',
    9951490    },
     
    10091504    LightSource => {
    10101505        Groups => { 2 => 'Camera' },
     1506        SeparateTable => 'EXIF LightSource',
    10111507        PrintConv =>  \%Image::ExifTool::Exif::lightSource,
    10121508    },
    10131509    Flash => {
    10141510        Groups => { 2 => 'Camera' },
    1015         SubDirectory => { },
    1016         Struct => 'Flash',
    1017     },
    1018     FlashFired => {
    1019         Groups => { 2 => 'Camera' },
    1020         Writable => 'boolean',
    1021     },
    1022     FlashReturn => {
    1023         Groups => { 2 => 'Camera' },
    1024         Writable => 'integer',
    1025         PrintConv => {
    1026             0 => 'No return detection',
    1027             2 => 'Return not detected',
    1028             3 => 'Return detected',
    1029         },
    1030     },
    1031     FlashMode => {
    1032         Groups => { 2 => 'Camera' },
    1033         Writable => 'integer',
    1034         PrintConv => {
    1035             0 => 'Unknown',
    1036             1 => 'On',
    1037             2 => 'Off',
    1038             3 => 'Auto',
    1039         },
    1040     },
    1041     FlashFunction => {
    1042         Groups => { 2 => 'Camera' },
    1043         Writable => 'boolean',
    1044     },
    1045     FlashRedEyeMode => {
    1046         Groups => { 2 => 'Camera' },
    1047         Writable => 'boolean',
     1511        Struct => {
     1512            STRUCT_NAME => 'Flash',
     1513            NAMESPACE   => 'exif',
     1514            Fired       => { Writable => 'boolean' },
     1515            Return => {
     1516                Writable => 'integer',
     1517                PrintConv => {
     1518                    0 => 'No return detection',
     1519                    2 => 'Return not detected',
     1520                    3 => 'Return detected',
     1521                },
     1522            },
     1523            Mode => {
     1524                Writable => 'integer',
     1525                PrintConv => {
     1526                    0 => 'Unknown',
     1527                    1 => 'On',
     1528                    2 => 'Off',
     1529                    3 => 'Auto',
     1530                },
     1531            },
     1532            Function    => { Writable => 'boolean' },
     1533            RedEyeMode  => { Writable => 'boolean' },
     1534        },
    10481535    },
    10491536    FocalLength=> {
    10501537        Groups => { 2 => 'Camera' },
    10511538        Writable => 'rational',
    1052         PrintConv => 'sprintf("%.1fmm",$val)',
    1053         PrintConvInv => '$val=~s/mm$//;$val',
    1054     },
    1055     SubjectArea => {
    1056         Writable => 'integer',
    1057         List => 'Seq',
    1058     },
    1059     FlashEnergy => {
    1060         Groups => { 2 => 'Camera' },
    1061         Writable => 'rational',
    1062     },
     1539        PrintConv => 'sprintf("%.1f mm",$val)',
     1540        PrintConvInv => '$val=~s/\s*mm$//;$val',
     1541    },
     1542    SubjectArea => { Writable => 'integer', List => 'Seq', AutoSplit => 1 },
     1543    FlashEnergy => { Groups => { 2 => 'Camera' }, Writable => 'rational' },
    10631544    SpatialFrequencyResponse => {
    10641545        Groups => { 2 => 'Camera' },
    1065         SubDirectory => { },
    1066         Struct => 'OECF',
    1067     },
    1068     SpatialFrequencyResponseColumns => {
    1069         Groups => { 2 => 'Camera' },
    1070         Writable => 'integer',
    1071     },
    1072     SpatialFrequencyResponseRows => {
    1073         Groups => { 2 => 'Camera' },
    1074         Writable => 'integer',
    1075     },
    1076     SpatialFrequencyResponseNames => {
    1077         Groups => { 2 => 'Camera' },
    1078         List => 'Seq',
    1079     },
    1080     SpatialFrequencyResponseValues => {
    1081         Groups => { 2 => 'Camera' },
    1082         Writable => 'rational',
    1083         List => 'Seq',
    1084     },
    1085     FocalPlaneXResolution => {
    1086         Groups => { 2 => 'Camera' },
    1087         Writable => 'rational',
    1088     },
    1089     FocalPlaneYResolution => {
    1090         Groups => { 2 => 'Camera' },
    1091         Writable => 'rational',
    1092     },
     1546        Struct => \%sOECF,
     1547    },
     1548    FocalPlaneXResolution => { Groups => { 2 => 'Camera' }, Writable => 'rational' },
     1549    FocalPlaneYResolution => { Groups => { 2 => 'Camera' }, Writable => 'rational' },
    10931550    FocalPlaneResolutionUnit => {
    10941551        Groups => { 2 => 'Camera' },
    10951552        Writable => 'integer',
     1553        Notes => 'values 1, 4 and 5 are not standard EXIF',
    10961554        PrintConv => {
    10971555            1 => 'None', # (not standard EXIF)
     
    11021560        },
    11031561    },
    1104     SubjectLocation => {
    1105         Writable => 'integer',
    1106         List => 'Seq',
    1107     },
    1108     ExposureIndex => {
    1109         Writable => 'rational',
    1110     },
     1562    SubjectLocation => { Writable => 'integer', List => 'Seq', AutoSplit => 1 },
     1563    ExposureIndex   => { Writable => 'rational' },
    11111564    SensingMethod => {
    11121565        Groups => { 2 => 'Camera' },
    11131566        Writable => 'integer',
    1114         PrintConv => {
    1115             1 => 'Not defined',
     1567        Notes => 'values 1 and 6 are not standard EXIF',
     1568        PrintConv => {
     1569            1 => 'Monochrome area', # (not standard EXIF)
    11161570            2 => 'One-chip color area',
    11171571            3 => 'Two-chip color area',
    11181572            4 => 'Three-chip color area',
    11191573            5 => 'Color sequential area',
     1574            6 => 'Monochrome linear', # (not standard EXIF)
    11201575            7 => 'Trilinear',
    11211576            8 => 'Color sequential linear',
     
    11321587    SceneType  => { Writable => 'integer', PrintConv => { 1 => 'Directly photographed' } },
    11331588    CFAPattern => {
    1134         SubDirectory => { },
    1135         Struct => 'CFAPattern',
    1136     },
    1137     CFAPatternColumns   => { Writable => 'integer' },
    1138     CFAPatternRows      => { Writable => 'integer' },
    1139     CFAPatternValues    => { List => 'Seq', Writable => 'integer' },
     1589        Struct => {
     1590            STRUCT_NAME => 'CFAPattern',
     1591            NAMESPACE   => 'exif',
     1592            Columns     => { Writable => 'integer' },
     1593            Rows        => { Writable => 'integer' },
     1594            Values      => { Writable => 'integer', List => 'Seq' },
     1595        },
     1596    },
    11401597    CustomRendered => {
    11411598        Writable => 'integer',
     
    11671624        Writable => 'integer',
    11681625        Groups => { 2 => 'Camera' },
     1626        PrintConv => '"$val mm"',
     1627        PrintConvInv => '$val=~s/\s*mm$//;$val',
    11691628    },
    11701629    SceneCaptureType => {
     
    12211680    DeviceSettingDescription => {
    12221681        Groups => { 2 => 'Camera' },
    1223         SubDirectory => { },
    1224         Struct => 'DeviceSettings',
    1225     },
    1226     DeviceSettingDescriptionColumns => {
    1227         Groups => { 2 => 'Camera' },
    1228         Writable => 'integer',
    1229     },
    1230     DeviceSettingDescriptionRows => {
    1231         Groups => { 2 => 'Camera' },
    1232         Writable => 'integer',
    1233     },
    1234     DeviceSettingDescriptionSettings => {
    1235         Groups => { 2 => 'Camera' },
    1236         List => 'Seq',
     1682        Struct => {
     1683            STRUCT_NAME => 'DeviceSettings',
     1684            NAMESPACE   => 'exif',
     1685            Columns     => { Writable => 'integer' },
     1686            Rows        => { Writable => 'integer' },
     1687            Settings    => { List => 'Seq' },
     1688        },
    12371689    },
    12381690    SubjectDistanceRange => {
     
    12611713        Groups => { 2 => 'Location' },
    12621714        Writable => 'rational',
    1263         PrintConv => '$val eq "inf" ? $val : "$val m"',
     1715        RawConv => 'require Image::ExifTool::GPS; $val', # to load Composite tags and routines
     1716        # extricate unsigned decimal number from string
     1717        ValueConvInv => '$val=~/((?=\d|\.\d)\d*(?:\.\d*)?)/ ? $1 : undef',
     1718        PrintConv => '$val =~ /^(inf|undef)$/ ? $val : "$val m"',
    12641719        PrintConvInv => '$val=~s/\s*m$//;$val',
    12651720    },
    1266     GPSTimeStamp    => { %dateTimeInfo },
     1721    GPSTimeStamp => {
     1722        Name => 'GPSDateTime',
     1723        Description => 'GPS Date/Time',
     1724        Groups => { 2 => 'Time' },
     1725        Notes => q{
     1726            a date/time tag called GPSTimeStamp by the XMP specification.  This tag is
     1727            renamed here to prevent direct copy from EXIF:GPSTimeStamp which is a
     1728            time-only tag.  Instead, the value of this tag should be taken from
     1729            Composite:GPSDateTime when copying from EXIF
     1730        },
     1731        %dateTimeInfo,
     1732    },
    12671733    GPSSatellites   => { Groups => { 2 => 'Location' } },
    12681734    GPSStatus => {
    12691735        Groups => { 2 => 'Location' },
    12701736        PrintConv => {
    1271             A => 'Measurement In Progress',
    1272             V => 'Measurement Interoperability',
     1737            A => 'Measurement Active',
     1738            V => 'Measurement Void',
    12731739        },
    12741740    },
     
    12811747        },
    12821748    },
    1283     GPSDOP => {
    1284         Groups => { 2 => 'Location' },
    1285         Writable => 'rational',
    1286     },
     1749    GPSDOP => { Groups => { 2 => 'Location' }, Writable => 'rational' },
    12871750    GPSSpeedRef => {
    12881751        Groups => { 2 => 'Location' },
     
    12931756        },
    12941757    },
    1295     GPSSpeed => {
    1296         Groups => { 2 => 'Location' },
    1297         Writable => 'rational',
    1298     },
     1758    GPSSpeed => { Groups => { 2 => 'Location' }, Writable => 'rational' },
    12991759    GPSTrackRef => {
    13001760        Groups => { 2 => 'Location' },
     
    13041764        },
    13051765    },
    1306     GPSTrack => {
    1307         Groups => { 2 => 'Location' },
    1308         Writable => 'rational',
    1309     },
     1766    GPSTrack => { Groups => { 2 => 'Location' }, Writable => 'rational' },
    13101767    GPSImgDirectionRef => {
    13111768        PrintConv => {
     
    13141771        },
    13151772    },
    1316     GPSImgDirection => {
    1317         Groups => { 2 => 'Location' },
    1318         Writable => 'rational',
    1319     },
     1773    GPSImgDirection => { Groups => { 2 => 'Location' }, Writable => 'rational' },
    13201774    GPSMapDatum     => { Groups => { 2 => 'Location' } },
    13211775    GPSDestLatitude => { Groups => { 2 => 'Location' }, %latConv },
     
    13281782        },
    13291783    },
    1330     GPSDestBearing => {
    1331         Groups => { 2 => 'Location' },
    1332         Writable => 'rational',
    1333     },
     1784    GPSDestBearing => { Groups => { 2 => 'Location' }, Writable => 'rational' },
    13341785    GPSDestDistanceRef => {
    13351786        Groups => { 2 => 'Location' },
     
    13571808);
    13581809
    1359 # Auxiliary schema properties (aux) - not fully documented
     1810# Auxiliary schema properties (aux) - not fully documented (ref PH)
    13601811%Image::ExifTool::XMP::aux = (
    13611812    %xmpTableDefaults,
    13621813    GROUPS => { 1 => 'XMP-aux', 2 => 'Camera' },
    1363     NAMESPACE => 'aux',
     1814    NAMESPACE   => 'aux',
    13641815    NOTES => 'Photoshop Auxiliary schema tags.',
    13651816    Firmware        => { }, #7
    13661817    FlashCompensation => { Writable => 'rational' }, #7
    13671818    ImageNumber     => { }, #7
    1368     LensInfo        => { }, #7
     1819    LensInfo        => { #7
     1820        Notes => '4 rational values giving focal and aperture ranges',
     1821        # convert to floating point values (or 'inf' or 'undef')
     1822        ValueConv => sub {
     1823            my $val = shift;
     1824            my @vals = split ' ', $val;
     1825            return $val unless @vals == 4;
     1826            foreach (@vals) {
     1827                ConvertRational($_) or return $val;
     1828            }
     1829            return join ' ', @vals;
     1830        },
     1831        ValueConvInv => sub {
     1832            my $val = shift;
     1833            my @vals = split ' ', $val;
     1834            return $val unless @vals == 4;
     1835            foreach (@vals) {
     1836                $_ eq 'inf' and $_ = '1/0', next;
     1837                $_ eq 'undef' and $_ = '0/0', next;
     1838                Image::ExifTool::IsFloat($_) or return $val;
     1839                my @a = Image::ExifTool::Rationalize($_);
     1840                $_ = join '/', @a;
     1841            }
     1842            return join ' ', @vals;
     1843        },
     1844        # convert to the form "12-20mm f/3.8-4.5" or "50mm f/1.4"
     1845        PrintConv => \&Image::ExifTool::Exif::PrintLensInfo,
     1846        PrintConvInv => \&Image::ExifTool::Exif::ConvertLensInfo,
     1847    },
    13691848    Lens            => { },
    13701849    OwnerName       => { }, #7
    13711850    SerialNumber    => { },
    1372 );
    1373 
    1374 # IPTC Core schema properties (Iptc4xmpCore)
     1851    LensID          => {
     1852        Priority => 0,
     1853        # prevent this from getting set from a LensID that has been converted
     1854        ValueConvInv => q{
     1855            warn "Expected one or more integer values" if $val =~ /[^\d ]/;
     1856            return $val;
     1857        },
     1858    },
     1859    ApproximateFocusDistance => { Writable => 'rational' }, #PH (LR3)
     1860);
     1861
     1862# IPTC Core schema properties (Iptc4xmpCore) (ref 4)
    13751863%Image::ExifTool::XMP::iptcCore = (
    13761864    %xmpTableDefaults,
    13771865    GROUPS => { 1 => 'XMP-iptcCore', 2 => 'Author' },
    1378     NAMESPACE => 'Iptc4xmpCore',
     1866    NAMESPACE   => 'Iptc4xmpCore',
     1867    TABLE_DESC => 'XMP IPTC Core',
    13791868    NOTES => q{
    1380         IPTC Core schema tags.  The actual IPTC Core namespace schema prefix is
     1869        IPTC Core schema tags.  The actual IPTC Core namespace prefix is
    13811870        "Iptc4xmpCore", which is the prefix recorded in the file, but ExifTool
    1382         shortens this for the "XMP-iptcCore" family 1 group name.
     1871        shortens this for the "XMP-iptcCore" family 1 group name. (see
     1872        L<http://www.iptc.org/IPTC4XMP/>)
    13831873    },
    13841874    CountryCode         => { Groups => { 2 => 'Location' } },
    13851875    CreatorContactInfo => {
    1386         SubDirectory => { },
    1387         Struct => 'ContactInfo',
    1388     },
    1389     CreatorContactInfoCiAdrCity   => { Description => 'Creator City' },
    1390     CreatorContactInfoCiAdrCtry   => { Description => 'Creator Country' },
    1391     CreatorContactInfoCiAdrExtadr => { Description => 'Creator Address' },
    1392     CreatorContactInfoCiAdrPcode  => { Description => 'Creator Postal Code' },
    1393     CreatorContactInfoCiAdrRegion => { Description => 'Creator Region' },
    1394     CreatorContactInfoCiEmailWork => { Description => 'Creator Work Email' },
    1395     CreatorContactInfoCiTelWork   => { Description => 'Creator Work Telephone' },
    1396     CreatorContactInfoCiUrlWork   => { Description => 'Creator Work URL' },
     1876        Struct => {
     1877            STRUCT_NAME => 'ContactInfo',
     1878            NAMESPACE   => 'Iptc4xmpCore',
     1879            CiAdrCity   => { },
     1880            CiAdrCtry   => { },
     1881            CiAdrExtadr => { },
     1882            CiAdrPcode  => { },
     1883            CiAdrRegion => { },
     1884            CiEmailWork => { },
     1885            CiTelWork   => { },
     1886            CiUrlWork   => { },
     1887        },
     1888    },
     1889    CreatorContactInfoCiAdrCity   => { Flat => 1, Name => 'CreatorCity' },
     1890    CreatorContactInfoCiAdrCtry   => { Flat => 1, Name => 'CreatorCountry' },
     1891    CreatorContactInfoCiAdrExtadr => { Flat => 1, Name => 'CreatorAddress' },
     1892    CreatorContactInfoCiAdrPcode  => { Flat => 1, Name => 'CreatorPostalCode' },
     1893    CreatorContactInfoCiAdrRegion => { Flat => 1, Name => 'CreatorRegion' },
     1894    CreatorContactInfoCiEmailWork => { Flat => 1, Name => 'CreatorWorkEmail' },
     1895    CreatorContactInfoCiTelWork   => { Flat => 1, Name => 'CreatorWorkTelephone' },
     1896    CreatorContactInfoCiUrlWork   => { Flat => 1, Name => 'CreatorWorkURL' },
    13971897    IntellectualGenre   => { Groups => { 2 => 'Other' } },
    13981898    Location            => { Groups => { 2 => 'Location' } },
     
    14011901);
    14021902
    1403 # PixelLive schema properties (PixelLive) (ref 3)
    1404 %Image::ExifTool::XMP::PixelLive = (
    1405     GROUPS => { 1 => 'XMP-PixelLive', 2 => 'Image' },
    1406     NAMESPACE => 'PixelLive',
    1407     WRITE_PROC => \&WriteXMP,
     1903# IPTC Extension schema properties (Iptc4xmpExt) (ref 4)
     1904%Image::ExifTool::XMP::iptcExt = (
     1905    %xmpTableDefaults,
     1906    GROUPS => { 1 => 'XMP-iptcExt', 2 => 'Author' },
     1907    NAMESPACE   => 'Iptc4xmpExt',
     1908    TABLE_DESC => 'XMP IPTC Extension',
    14081909    NOTES => q{
    1409         PixelLive schema tags.  These tags are not writable becase they are very
    1410         uncommon and I haven't been able to locate a reference which gives the
    1411         namespace URI.
    1412     },
    1413     AUTHOR    => { Name => 'Author',   Avoid => 1, Groups => { 2 => 'Author'} },
    1414     COMMENTS  => { Name => 'Comments', Avoid => 1 },
    1415     COPYRIGHT => { Name => 'Copyright',Avoid => 1, Groups => { 2 => 'Author'} },
    1416     DATE      => { Name => 'Date',     Avoid => 1, Groups => { 2 => 'Time'} },
    1417     GENRE     => { Name => 'Genre',    Avoid => 1 },
    1418     TITLE     => { Name => 'Title',    Avoid => 1 },
    1419 );
    1420 
    1421 # Picture Licensing Universal System schema properties (xmpPLUS)
    1422 %Image::ExifTool::XMP::xmpPLUS = (
    1423     %xmpTableDefaults,
    1424     GROUPS => { 1 => 'XMP-xmpPLUS', 2 => 'Author' },
    1425     NAMESPACE => 'xmpPLUS',
    1426     NOTES => 'XMP Picture Licensing Universal System (PLUS) schema tags.',
    1427     CreditLineReq   => { Writable => 'boolean' },
    1428     ReuseAllowed    => { Writable => 'boolean' },
    1429 );
    1430 
    1431 # Creative Commons schema properties (cc) (ref 5)
    1432 %Image::ExifTool::XMP::cc = (
    1433     %xmpTableDefaults,
    1434     GROUPS => { 1 => 'XMP-cc', 2 => 'Author' },
    1435     NAMESPACE => 'cc',
    1436     NOTES => 'Creative Commons schema tags.',
    1437     license => { },
    1438 );
    1439 
    1440 # Description Explorer schema properties (dex) (ref 6)
    1441 %Image::ExifTool::XMP::dex = (
    1442     %xmpTableDefaults,
    1443     GROUPS => { 1 => 'XMP-dex', 2 => 'Image' },
    1444     NAMESPACE => 'dex',
    1445     NOTES => q{
    1446         Description Explorer schema tags.  These tags are not very common.  The
    1447         Source and Rating tags are avoided when writing due to name conflicts with
    1448         other XMP tags.
    1449     },
    1450     crc32       => { Name => 'CRC32', Writable => 'integer' },
    1451     source      => { Avoid => 1 },
    1452     shortdescription => {
    1453         Name => 'ShortDescription',
    1454         Writable => 'lang-alt',
    1455     },
    1456     licensetype => {
    1457         Name => 'LicenseType',
    1458         PrintConv => {
    1459             unknown        => 'Unknown',
    1460             shareware      => 'Shareware',
    1461             freeware       => 'Freeware',
    1462             adware         => 'Adware',
    1463             demo           => 'Demo',
    1464             commercial     => 'Commercial',
    1465            'public domain' => 'Public Domain',
    1466            'open source'   => 'Open Source',
    1467         },
    1468     },
    1469     revision    => { },
    1470     rating      => { Avoid => 1 },
    1471     os          => { Name => 'OS', Writable => 'integer' },
    1472     ffid        => { Name => 'FFID' },
    1473 );
    1474 
    1475 # IView MediaPro schema properties (mediapro) (ref PH)
    1476 %Image::ExifTool::XMP::MediaPro = (
    1477     %xmpTableDefaults,
    1478     GROUPS => { 1 => 'XMP-mediapro', 2 => 'Image' },
    1479     NAMESPACE => 'mediapro',
    1480     NOTES => 'IView MediaPro schema tags.',
    1481     Event       => { },
    1482     Location    => {
    1483         Avoid => 1,
     1910        IPTC Extension schema tags.  The actual namespace prefix is "Iptc4xmpExt",
     1911        but ExifTool shortens this for the "XMP-iptcExt" family 1 group name.
     1912        (see L<http://www.iptc.org/IPTC4XMP/>)
     1913    },
     1914    AddlModelInfo   => { Name => 'AdditionalModelInformation' },
     1915    ArtworkOrObject => {
     1916        Struct => {
     1917            STRUCT_NAME => 'ArtworkOrObjectDetails',
     1918            NAMESPACE   => 'Iptc4xmpExt',
     1919            AOCopyrightNotice => { },
     1920            AOCreator    => { List => 'Seq' },
     1921            AODateCreated=> { Groups => { 2 => 'Time' }, %dateTimeInfo },
     1922            AOSource     => { },
     1923            AOSourceInvNo=> { },
     1924            AOTitle      => { Writable => 'lang-alt' },
     1925        },
     1926        List => 'Bag',
     1927    },
     1928    ArtworkOrObjectAOCopyrightNotice=> { Flat => 1, Name => 'ArtworkCopyrightNotice' },
     1929    ArtworkOrObjectAOCreator        => { Flat => 1, Name => 'ArtworkCreator' },
     1930    ArtworkOrObjectAODateCreated    => { Flat => 1, Name => 'ArtworkDateCreated' },
     1931    ArtworkOrObjectAOSource         => { Flat => 1, Name => 'ArtworkSource' },
     1932    ArtworkOrObjectAOSourceInvNo    => { Flat => 1, Name => 'ArtworkSourceInventoryNo' },
     1933    ArtworkOrObjectAOTitle          => { Flat => 1, Name => 'ArtworkTitle' },
     1934    OrganisationInImageCode => { List => 'Bag' },
     1935    CVterm => {
     1936        Name => 'ControlledVocabularyTerm',
     1937        List => 'Bag',
     1938    },
     1939    LocationShown => {
     1940        Struct => \%sLocationDetails,
    14841941        Groups => { 2 => 'Location' },
    1485         Notes => 'avoided due to conflict with XMP-iptcCore:Location',
    1486     },
    1487     Status      => { },
    1488     People      => { List => 'Bag' },
    1489     UserFields  => { List => 'Bag' },
    1490     CatalogSets => { List => 'Bag' },
    1491 );
    1492 
    1493 # Microsoft Photo schema properties (MicrosoftPhoto) (ref PH)
    1494 %Image::ExifTool::XMP::Microsoft = (
    1495     %xmpTableDefaults,
    1496     GROUPS => { 1 => 'XMP-microsoft', 2 => 'Image' },
    1497     NAMESPACE => 'MicrosoftPhoto',
    1498     NOTES => q{
    1499         Microsoft Photo schema tags.  This is likely not a complete list, but
    1500         represents tags which have been observed in sample images.  The actual
    1501         namespace prefix is "MicrosoftPhoto", but ExifTool shortens this to
    1502         "XMP-microsoft" in the family 1 group name.
    1503     },
    1504     CameraSerialNumber => { },
    1505     DateAcquired       => { %dateTimeInfo },
    1506     FlashManufacturer  => { },
    1507     FlashModel         => { },
    1508     LastKeywordIPTC    => { List => 'Bag' },
    1509     LastKeywordXMP     => { List => 'Bag' },
    1510     LensManufacturer   => { },
    1511     LensModel          => { },
    1512     Rating => {
    1513         Name => 'RatingPercent',
    1514         Notes => q{
    1515             normal Rating values of 1,2,3,4 and 5 stars correspond to RatingPercent
    1516             values of 1,25,50,75 and 99 respectively
    1517         },
    1518     },
     1942        List => 'Bag',
     1943    },
     1944    ModelAge                => { List => 'Bag', Writable => 'integer' },
     1945    OrganisationInImageName => { List => 'Bag' },
     1946    PersonInImage           => { List => 'Bag' },
     1947    DigImageGUID            => { Name => 'DigitalImageGUID' },
     1948    DigitalSourcefileType   => {
     1949        Name => 'DigitalSourceFileType',
     1950        Notes => 'now deprecated -- replaced by DigitalSourceType',
     1951    },
     1952    DigitalSourceType       => { Name => 'DigitalSourceType' },
     1953    Event                   => { Writable => 'lang-alt' },
     1954    RegistryId => {
     1955        Struct => {
     1956            STRUCT_NAME => 'RegistryEntryDetails',
     1957            NAMESPACE   => 'Iptc4xmpExt',
     1958            RegItemId    => { },
     1959            RegOrgId     => { },
     1960        },
     1961        List => 'Bag',
     1962    },
     1963    RegistryIdRegItemId         => { Flat => 1, Name => 'RegistryItemID' },
     1964    RegistryIdRegOrgId          => { Flat => 1, Name => 'RegistryOrganisationID' },
     1965    IptcLastEdited          => { Groups => { 2 => 'Time' }, %dateTimeInfo },
     1966    LocationCreated => {
     1967        Struct => \%sLocationDetails,
     1968        Groups => { 2 => 'Location' },
     1969        List => 'Bag',
     1970    },
     1971    MaxAvailHeight  => { Writable => 'integer' },
     1972    MaxAvailWidth   => { Writable => 'integer' },
    15191973);
    15201974
     
    15231977    %xmpTableDefaults,
    15241978    GROUPS => { 1 => 'XMP-lr', 2 => 'Image' },
    1525     NAMESPACE => 'lr',
     1979    NAMESPACE   => 'lr',
     1980    TABLE_DESC => 'XMP Adobe Lightroom',
    15261981    NOTES => 'Adobe Lightroom "lr" schema tags.',
    15271982    privateRTKInfo => { },
     
    15291984);
    15301985
    1531 # DICOM schema properties (DICOM) (ref PH, written by CS3)
    1532 %Image::ExifTool::XMP::DICOM = (
     1986# Adobe Album schema properties (album) (ref PH)
     1987%Image::ExifTool::XMP::Album = (
    15331988    %xmpTableDefaults,
    1534     GROUPS => { 1 => 'XMP-DICOM', 2 => 'Image' },
    1535     NAMESPACE => 'DICOM',
    1536     NOTES => 'DICOM schema tags.',
    1537     # change some tag names to correspond with DICOM tags
    1538     PatientName             => { Name => 'PatientsName' },
    1539     PatientID               => { },
    1540     PatientSex              => { Name => 'PatientsSex' },
    1541     PatientDOB              => {
    1542         Name => 'PatientsBirthDate',
    1543         %dateTimeInfo,
    1544     },
    1545     StudyID                 => { },
    1546     StudyPhysician          => { },
    1547     StudyDateTime           => { %dateTimeInfo },
    1548     StudyDescription        => { },
    1549     SeriesNumber            => { },
    1550     SeriesModality          => { },
    1551     SeriesDateTime          => { %dateTimeInfo },
    1552     SeriesDescription       => { },
    1553     EquipmentInstitution    => { },
    1554     EquipmentManufacturer   => { },
     1989    GROUPS => { 1 => 'XMP-album', 2 => 'Image' },
     1990    NAMESPACE   => 'album',
     1991    TABLE_DESC => 'XMP Adobe Album',
     1992    NOTES => 'Adobe Album schema tags.',
     1993    Notes => { },
    15551994);
    15561995
     
    15662005    # (used to set EXIF GPS position from XMP tags)
    15672006    GPSLatitudeRef => {
    1568         Require => {
    1569             0 => 'XMP:GPSLatitude',
    1570         },
    1571         ValueConv => '$val[0] < 0 ? "S" : "N"',
     2007        Require => 'XMP:GPSLatitude',
     2008        ValueConv => q{
     2009            IsFloat($val[0]) and return $val[0] < 0 ? "S" : "N";
     2010            $val[0] =~ /.*([NS])/;
     2011            return $1;
     2012        },
    15722013        PrintConv => {
    15732014            N => 'North',
     
    15762017    },
    15772018    GPSLongitudeRef => {
    1578         Require => {
    1579             0 => 'XMP:GPSLongitude',
    1580         },
    1581         ValueConv => '$val[0] < 0 ? "W" : "E"',
     2019        Require => 'XMP:GPSLongitude',
     2020        ValueConv => q{
     2021            IsFloat($val[0]) and return $val[0] < 0 ? "W" : "E";
     2022            $val[0] =~ /.*([EW])/;
     2023            return $1;
     2024        },
    15822025        PrintConv => {
    15832026            E => 'East',
     
    16202063    my ($str, $conv) = @_;
    16212064    $conv = \%charNum unless $conv;
     2065    $str =~ s/&(#?\w+);/UnescapeChar($1,$conv)/sge;
     2066    return $str;
     2067}
     2068
     2069#------------------------------------------------------------------------------
     2070# Escape string for XML, ensuring valid XML and UTF-8
     2071# Inputs: 0) string
     2072# Returns: escaped string
     2073sub FullEscapeXML($)
     2074{
     2075    my $str = shift;
     2076    $str =~ s/([&><'"])/&$charName{$1};/sg; # escape necessary XML characters
     2077    $str =~ s/\\/&#92;/sg;                  # escape backslashes too
     2078    # then use C-escape sequences for invalid characters
     2079    if ($str =~ /[\0-\x1f]/ or IsUTF8(\$str) < 0) {
     2080        $str =~ s/([\0-\x1f\x80-\xff])/sprintf("\\x%.2x",ord $1)/sge;
     2081    }
     2082    return $str;
     2083}
     2084
     2085#------------------------------------------------------------------------------
     2086# Unescape XML/C escaped string
     2087# Inputs: 0) string
     2088# Returns: unescaped string
     2089sub FullUnescapeXML($)
     2090{
     2091    my $str = shift;
     2092    # unescape C escape sequences first
     2093    $str =~ s/\\x([\da-f]{2})/chr(hex($1))/sge;
     2094    my $conv = \%charNum;
    16222095    $str =~ s/&(#?\w+);/UnescapeChar($1,$conv)/sge;
    16232096    return $str;
     
    16392112            $val = $1;
    16402113        } else {
    1641             return "&$ch;"; # should issue a warning here?
    1642         }
    1643     }
    1644     if ($val < 0x80) {
    1645         return chr($val);   # simple ASCII
    1646     } elsif ($] >= 5.006001) {
    1647         return pack('C0U', $val);
    1648     } else {
    1649         return Image::ExifTool::PackUTF8($val);
    1650     }
     2114            return "&$ch;"; # should issue a warning here? [no]
     2115        }
     2116    }
     2117    return chr($val) if $val < 0x80;   # simple ASCII
     2118    return pack('C0U', $val) if $] >= 5.006001;
     2119    return Image::ExifTool::PackUTF8($val);
     2120}
     2121
     2122#------------------------------------------------------------------------------
     2123# Does a string contain valid UTF-8 characters?
     2124# Inputs: 0) string reference
     2125# Returns: 0=regular ASCII, -1=invalid UTF-8, 1=valid UTF-8 with maximum 16-bit
     2126#          wide characters, 2=valid UTF-8 requiring 32-bit wide characters
     2127# Notes: Changes current string position
     2128sub IsUTF8($)
     2129{
     2130    my $strPt = shift;
     2131    pos($$strPt) = 0; # start at beginning of string
     2132    return 0 unless $$strPt =~ /([\x80-\xff])/g;
     2133    my $rtnVal = 1;
     2134    for (;;) {
     2135        my $ch = ord($1);
     2136        # minimum lead byte for 2-byte sequence is 0xc2 (overlong sequences
     2137        # not allowed), 0xf8-0xfd are restricted by RFC 3629 (no 5 or 6 byte
     2138        # sequences), and 0xfe and 0xff are not valid in UTF-8 strings
     2139        return -1 if $ch < 0xc2 or $ch >= 0xf8;
     2140        # determine number of bytes remaining in sequence
     2141        my $n;
     2142        if ($ch < 0xe0) {
     2143            $n = 1;
     2144        } elsif ($ch < 0xf0) {
     2145            $n = 2;
     2146        } else {
     2147            $n = 3;
     2148            # character code is greater than 0xffff if more than 2 extra bytes
     2149            # were required in the UTF-8 character
     2150            $rtnVal = 2;
     2151        }
     2152        return -1 unless $$strPt =~ /\G[\x80-\xbf]{$n}/g;
     2153        last unless $$strPt =~ /([\x80-\xff])/g;
     2154    }
     2155    return $rtnVal;
     2156}
     2157
     2158#------------------------------------------------------------------------------
     2159# Fix malformed UTF8 (by replacing bad bytes with '?')
     2160# Inputs: 0) string reference
     2161# Returns: true if string was fixed, and updates string
     2162sub FixUTF8($)
     2163{
     2164    my $strPt = shift;
     2165    my $fixed;
     2166    pos($$strPt) = 0; # start at beginning of string
     2167    for (;;) {
     2168        last unless $$strPt =~ /([\x80-\xff])/g;
     2169        my $ch = ord($1);
     2170        my $pos = pos($$strPt);
     2171        # (see comments in IsUTF8() above)
     2172        if ($ch >= 0xc2 and $ch < 0xf8) {
     2173            my $n = $ch < 0xe0 ? 1 : ($ch < 0xf0 ? 2 : 3);
     2174            next if $$strPt =~ /\G[\x80-\xbf]{$n}/g;
     2175        }
     2176        # replace bad character with '?'
     2177        substr($$strPt, $pos-1, 1) = '?';
     2178        pos($$strPt) = $fixed = $pos;
     2179    }
     2180    return $fixed;
    16512181}
    16522182
     
    16542184# Utility routine to decode a base64 string
    16552185# Inputs: 0) base64 string
    1656 # Returns:   reference to decoded data
     2186# Returns: reference to decoded data
    16572187sub DecodeBase64($)
    16582188{
     
    16622192    # truncate at first unrecognized character (base 64 data
    16632193    # may only contain A-Z, a-z, 0-9, +, /, =, or white space)
    1664     $str =~ s/[^A-Za-z0-9+\/= \t\n\r\f].*//;
     2194    $str =~ s/[^A-Za-z0-9+\/= \t\n\r\f].*//s;
    16652195    # translate to uucoded and remove padding and white space
    16662196    $str =~ tr/A-Za-z0-9+\/= \t\n\r\f/ -_/d;
     
    16892219#------------------------------------------------------------------------------
    16902220# Generate a name for this XMP tag
    1691 # Inputs: 0) reference to tag property name list
    1692 # Returns: tagID and outtermost interesting namespace
    1693 sub GetXMPTagID($)
     2221# Inputs: 0) tag property name list ref, 1) array ref for receiving structure property list
     2222#         2) array for receiving namespace list
     2223# Returns: tagID and outtermost interesting namespace (or '' if no namespace)
     2224sub GetXMPTagID($;$$)
    16942225{
    1695     my $props = shift;
     2226    my ($props, $structProps, $nsList) = @_;
    16962227    my ($tag, $prop, $namespace);
    16972228    foreach $prop (@$props) {
     
    16992230        # (Note: namespace can be '' for property qualifiers)
    17002231        my ($ns, $nm) = ($prop =~ /(.*?):(.*)/) ? ($1, $2) : ('', $prop);
    1701         $nm =~ s/ .*//;     # remove nodeID if it exists
    17022232        if ($ignoreNamespace{$ns}) {
    17032233            # special case: don't ignore rdf numbered items
    1704             next unless $prop =~ /^rdf:(_\d+)$/;
    1705             $tag .= $1;
     2234            unless ($prop =~ /^rdf:(_\d+)$/) {
     2235                # save list index if necessary for structures
     2236                if ($structProps and @$structProps and $prop =~ /^rdf:li (\d+)$/) {
     2237                    push @{$$structProps[-1]}, $1;
     2238                }
     2239                next;
     2240            }
     2241            $tag .= $1 if defined $tag;
    17062242        } else {
     2243            $nm =~ s/ .*//; # remove nodeID if it exists
    17072244            # all uppercase is ugly, so convert it
    17082245            if ($nm !~ /[a-z]/) {
    1709                 my $xlatNS = $xlatNamespace{$ns} || $ns;
     2246                my $xlatNS = $$xlatNamespace{$ns} || $ns;
    17102247                my $info = $Image::ExifTool::XMP::Main{$xlatNS};
    17112248                my $table;
    17122249                if (ref $info eq 'HASH' and $info->{SubDirectory}) {
    1713                     $table = GetTagTable($info->{SubDirectory}->{TagTable});
     2250                    $table = GetTagTable($info->{SubDirectory}{TagTable});
    17142251                }
    17152252                unless ($table and $table->{$nm}) {
     
    17232260                $tag = $nm;
    17242261            }
     2262            # save structure information if necessary
     2263            if ($structProps) {
     2264                push @$structProps, [ $nm ];
     2265                push @$nsList, $ns if $nsList;
     2266            }
    17252267        }
    17262268        # save namespace of first property to contribute to tag name
    1727         $namespace = $ns unless defined $namespace;
     2269        $namespace = $ns unless $namespace;
    17282270    }
    17292271    if (wantarray) {
    1730         return ($tag, $namespace);
     2272        return ($tag, $namespace || '');
    17312273    } else {
    17322274        return $tag;
    17332275    }
     2276}
     2277
     2278#------------------------------------------------------------------------------
     2279# Register namespace for specified user-defined table
     2280# Inputs: 0) tag or structure table ref
     2281# Returns: namespace prefix
     2282sub RegisterNamespace($)
     2283{
     2284    my $table = shift;
     2285    return $$table{NAMESPACE} unless ref $$table{NAMESPACE};
     2286    my $nsRef = $$table{NAMESPACE};
     2287    # recognize as either a list or hash
     2288    my $ns;
     2289    if (ref $nsRef eq 'ARRAY') {
     2290        $ns = $$nsRef[0];
     2291        $nsURI{$ns} = $$nsRef[1];
     2292    } else { # must be a hash
     2293        my @ns = sort keys %$nsRef; # allow multiple namespace definitions
     2294        while (@ns) {
     2295            $ns = pop @ns;
     2296            if ($nsURI{$ns} and $nsURI{$ns} ne $$nsRef{$ns}) {
     2297                warn "User-defined namespace prefix '$ns' conflicts with existing namespace\n";
     2298            }
     2299            $nsURI{$ns} = $$nsRef{$ns};
     2300        }
     2301    }
     2302    return $$table{NAMESPACE} = $ns;
     2303}
     2304
     2305#------------------------------------------------------------------------------
     2306# Generate flattened tags and add to table
     2307# Inputs: 0) tag table ref, 1) tag ID for Struct tag in table
     2308# Returns: number of tags added (not counting those just initialized)
     2309# Notes: Must have verified that $$tagTablePtr{$tagID}{Struct} exists before calling this routine
     2310# - makes sure that the tagInfo Struct is a HASH reference
     2311sub AddFlattenedTags($$)
     2312{
     2313    local $_;
     2314    my ($tagTablePtr, $tagID) = @_;
     2315    my $tagInfo = $$tagTablePtr{$tagID};
     2316
     2317    $$tagInfo{Flattened} and return 0;  # only generate flattened tags once
     2318    $$tagInfo{Flattened} = 1;
     2319
     2320    my $strTable = $$tagInfo{Struct};
     2321    unless (ref $strTable) { # (allow a structure name for backward compatibility only)
     2322        my $strName = $strTable;
     2323        $strTable = $Image::ExifTool::UserDefined::xmpStruct{$strTable} or return 0;
     2324        $$strTable{STRUCT_NAME} or $$strTable{STRUCT_NAME} = $strName;
     2325        $$tagInfo{Struct} = $strTable;  # replace old-style name with HASH ref
     2326        delete $$tagInfo{SubDirectory}; # deprecated use of SubDirectory in Struct tags
     2327    }
     2328    # do not add flattened tags to variable-namespace structures
     2329    return 0 if exists $$strTable{NAMESPACE} and not defined $$strTable{NAMESPACE};
     2330
     2331    # get family 2 group name for this structure tag
     2332    my ($tagG2, $field);
     2333    $tagG2 = $$tagInfo{Groups}{2} if $$tagInfo{Groups};
     2334    $tagG2 or $tagG2 = $$tagTablePtr{GROUPS}{2};
     2335
     2336    my $count = 0;
     2337    foreach $field (keys %$strTable) {
     2338        next if $specialStruct{$field};
     2339        my $fieldInfo = $$strTable{$field};
     2340        next if $$fieldInfo{LangCode};  # don't flatten lang-alt tags
     2341        # build a tag ID for the corresponding flattened tag
     2342        my $fieldName = ucfirst($field);
     2343        my $flatID = $tagID . $fieldName;
     2344        my $flatInfo = $$tagTablePtr{$flatID};
     2345        if ($flatInfo) {
     2346            ref $flatInfo eq 'HASH' or warn("$flatInfo is not a HASH!\n"), next; # (to be safe)
     2347            # pre-defined flattened tags should have Flat flag set
     2348            if (not defined $$flatInfo{Flat} and $Image::ExifTool::debug) {
     2349                warn "Missing Flat flag for $$flatInfo{Name}\n";
     2350            }
     2351            $$flatInfo{Flat} = 0;
     2352            # copy all missing entries from field information
     2353            foreach (keys %$fieldInfo) {
     2354                # must not copy PropertyPath (but can't delete it afterwards
     2355                # because the flat tag may already have this set)
     2356                next if $_ eq 'PropertyPath';
     2357                $$flatInfo{$_} = $$fieldInfo{$_} unless defined $$flatInfo{$_};
     2358            }
     2359            # NOTE: Do NOT delete Groups because we need them if GotGroups was done
     2360            # --> just override group 2 later according to field group
     2361            # re-generate List flag unless it is set to 0
     2362            delete $$flatInfo{List} if $$flatInfo{List};
     2363        } else {
     2364            # generate new flattened tag information based on structure field
     2365            $flatInfo = { %$fieldInfo, Name => $$tagInfo{Name} . $fieldName, Flat => 0 };
     2366            # add new flattened tag to table
     2367            Image::ExifTool::AddTagToTable($tagTablePtr, $flatID, $flatInfo);
     2368            ++$count;
     2369        }
     2370        # propagate List flag (unless set to 0 in pre-defined flattened tag)
     2371        unless (defined $$flatInfo{List}) {
     2372            $$flatInfo{List} = $$fieldInfo{List} || 1 if $$fieldInfo{List} or $$tagInfo{List};
     2373        }
     2374        # set group 2 name from the first existing family 2 group in the:
     2375        # 1) structure field Groups, 2) structure table GROUPS, 3) structure tag Groups
     2376        if ($$fieldInfo{Groups} and $$fieldInfo{Groups}{2}) {
     2377            $$flatInfo{Groups}{2} = $$fieldInfo{Groups}{2};
     2378        } elsif ($$strTable{GROUPS} and $$strTable{GROUPS}{2}) {
     2379            $$flatInfo{Groups}{2} = $$strTable{GROUPS}{2};
     2380        } else {
     2381            $$flatInfo{Groups}{2} = $tagG2;
     2382        }
     2383        # save reference to top-level structure
     2384        $$flatInfo{RootTagInfo} = $$tagInfo{RootTagInfo} || $tagInfo;
     2385        # recursively generate flattened tags for sub-structures
     2386        next unless $$flatInfo{Struct};
     2387        length($flatID) > 150 and warn("Possible deep recursion for tag $flatID\n"), last;
     2388        # reset flattened tag just in case we flattened hierarchy in the wrong order
     2389        # because we must start from the outtermost structure to get the List flags right
     2390        # (this should only happen when building tag tables)
     2391        delete $$flatInfo{Flattened};
     2392        $count += AddFlattenedTags($tagTablePtr, $flatID);
     2393    }
     2394    return $count;
    17342395}
    17352396
     
    17442405    return undef unless $$tagInfo{Writable} and $$tagInfo{Writable} eq 'lang-alt';
    17452406    $langCode =~ tr/_/-/;   # RFC 3066 specifies '-' as a separator
    1746     return Image::ExifTool::GetLangInfo($tagInfo, $langCode);
     2407    my $langInfo = Image::ExifTool::GetLangInfo($tagInfo, $langCode);
     2408    # save reference to source tagInfo hash in case we need to set the PropertyPath later
     2409    $$langInfo{SrcTagInfo} = $tagInfo;
     2410    return $langInfo;
    17472411}
    17482412
     
    17842448            $buff = substr($lastBuff, pos($lastBuff));
    17852449        }
    1786         $xmp .= $buff;
    1787         my $pos = length($xmp) - length($buff) - 18; # 18 is length("<xpacket end...")-1
    1788         pos($xmp) = $pos if $pos > 0;
     2450        my $pos = length($xmp) - 18;    # (18 = length("<?xpacket end...") - 1)
     2451        $xmp .= $buff;                  # add new data to our XMP
     2452        pos($xmp) = $pos if $pos > 0;   # set start for "xpacket end" scan
    17892453        if ($xmp =~ /<\?xpacket end=['"][wr]['"]\?>/g) {
    1790             $xmp = substr($xmp, 0, pos($xmp));
    1791             # XMP is not valid if it contains null bytes
    1792             pos($xmp) = 0;
    1793             last unless $xmp =~ /\0/g;
    1794             my $null = pos $xmp;
    1795             while ($xmp =~ /\0/g) {
    1796                 $null = pos($xmp);
    1797             }
    1798             # re-parse beginning after last null byte
    1799             $buff = substr($xmp, $null);
    1800             $lastBuff = '';
     2454            $buff = substr($xmp, pos($xmp));    # save data after end of XMP
     2455            $xmp = substr($xmp, 0, pos($xmp));  # isolate XMP
     2456            # check XMP for validity (not valid if it contains null bytes)
     2457            $pos = rindex($xmp, "\0") + 1 or last;
     2458            $lastBuff = substr($xmp, $pos);     # re-parse beginning after last null byte
    18012459            undef $xmp;
    18022460        } else {
     
    18042462        }
    18052463    }
    1806     unless ($exifTool->{VALUE}->{FileType}) {
     2464    unless ($exifTool->{VALUE}{FileType}) {
    18072465        $exifTool->{FILE_TYPE} = $exifTool->{FILE_EXT};
    18082466        $exifTool->SetFileType('<unknown file containing XMP>');
     
    18182476
    18192477#------------------------------------------------------------------------------
     2478# Convert XMP date/time to EXIF format
     2479# Inputs: 0) XMP date/time string, 1) set if we aren't sure this is a date
     2480# Returns: EXIF date/time
     2481sub ConvertXMPDate($;$)
     2482{
     2483    my ($val, $unsure) = @_;
     2484    if ($val =~ /^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}:\d{2})(:\d{2})?\s*(\S*)$/) {
     2485        my $s = $5 || '';           # seconds may be missing
     2486        $val = "$1:$2:$3 $4$s$6";   # convert back to EXIF time format
     2487    } elsif (not $unsure and $val =~ /^(\d{4})(-\d{2}){0,2}/) {
     2488        $val =~ tr/-/:/;
     2489    }
     2490    return $val;
     2491}
     2492
     2493#------------------------------------------------------------------------------
     2494# Convert rational string value
     2495# Inputs: 0) string (converted to number, 'inf' or 'undef' on return if rational)
     2496# Returns: true if value was converted
     2497sub ConvertRational($)
     2498{
     2499    my $val = $_[0];
     2500    $val =~ m{^(-?\d+)/(-?\d+)$} or return undef;
     2501    if ($2) {
     2502        $_[0] = $1 / $2; # calculate quotient
     2503    } elsif ($1) {
     2504        $_[0] = 'inf';
     2505    } else {
     2506        $_[0] = 'undef';
     2507    }
     2508    return 1;
     2509}
     2510
     2511#------------------------------------------------------------------------------
    18202512# We found an XMP property name/value
    18212513# Inputs: 0) ExifTool object ref, 1) Pointer to tag table
    18222514#         2) reference to array of XMP property names (last is current property)
    1823 #         3) property value, 4) xml:lang attribute (or undef)
     2515#         3) property value, 4) attribute hash ref (for 'xml:lang' or 'rdf:datatype')
    18242516# Returns: 1 if valid tag was found
    18252517sub FoundXMP($$$$;$)
    18262518{
    18272519    local $_;
    1828     my ($exifTool, $tagTablePtr, $props, $val, $lang) = @_;
    1829 
    1830     my ($tag, $namespace) = GetXMPTagID($props);
     2520    my ($exifTool, $tagTablePtr, $props, $val, $attrs) = @_;
     2521    my ($lang, @structProps);
     2522    my ($tag, $ns) = GetXMPTagID($props, $exifTool->{OPTIONS}{Struct} ? \@structProps : undef);
    18312523    return 0 unless $tag;   # ignore things that aren't valid tags
    18322524
    18332525    # translate namespace if necessary
    1834     $namespace = $xlatNamespace{$namespace} if $xlatNamespace{$namespace};
    1835     my $info = $tagTablePtr->{$namespace};
    1836     my $table;
     2526    $ns = $$xlatNamespace{$ns} if $$xlatNamespace{$ns};
     2527    my $info = $tagTablePtr->{$ns};
     2528    my ($table, $added, $xns, $tagID);
    18372529    if ($info) {
    1838         $table = $info->{SubDirectory}->{TagTable} or warn "Missing TagTable for $tag!\n";
     2530        $table = $info->{SubDirectory}{TagTable} or warn "Missing TagTable for $tag!\n";
     2531    } elsif ($$props[0] eq 'svg:svg') {
     2532        if (not $ns) {
     2533            # disambiguate MetadataID by adding back the 'metadata' we ignored
     2534            $tag = 'metadataId' if $tag eq 'id' and $$props[1] eq 'svg:metadata';
     2535            # use SVG namespace in SVG files if nothing better to use
     2536            $table = 'Image::ExifTool::XMP::SVG';
     2537        } elsif (not grep /^rdf:/, @$props) {
     2538            # only other SVG information if not inside RDF (call it XMP if in RDF)
     2539            $table = 'Image::ExifTool::XMP::otherSVG';
     2540        }
     2541    }
     2542
     2543    # look up this tag in the appropriate table
     2544    $table or $table = 'Image::ExifTool::XMP::other';
     2545    $tagTablePtr = GetTagTable($table);
     2546    if ($$tagTablePtr{NAMESPACE}) {
     2547        $tagID = $tag;
    18392548    } else {
    1840         $table = 'Image::ExifTool::XMP::other';
    1841     }
    1842     # change pointer to the table for this namespace
    1843     $tagTablePtr = GetTagTable($table);
    1844 
    1845     # look up this tag in the appropriate table
    1846     my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
    1847 
    1848     unless ($tagInfo) {
    1849         if ($exifTool->{OPTIONS}->{Verbose}) {
    1850             my $group1 = $namespace ? "XMP-$namespace" : $tagTablePtr->{GROUPS}->{1};
    1851             $exifTool->VPrint(0, $exifTool->{INDENT}, "[adding $group1:$tag]\n");
     2549        # add XMP namespace prefix to avoid collisions in variable-namespace tables
     2550        $xns = $xmpNS{$ns} || $ns;
     2551        $tagID = "$xns:$tag";
     2552        # add namespace to top-level structure property
     2553        $structProps[0][0] = "$xns:" . $structProps[0][0] if @structProps;
     2554    }
     2555    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
     2556
     2557    $lang = $$attrs{'xml:lang'} if $attrs;
     2558
     2559    # must add a new tag table entry if this tag isn't pre-defined
     2560    # (or initialize from structure field if this is a pre-defined flattened tag)
     2561NoLoop:
     2562    while (not $tagInfo or $$tagInfo{Flat}) {
     2563        my (@tagList, @nsList);
     2564        GetXMPTagID($props, \@tagList, \@nsList);
     2565        my ($ta, $t, $ti, $addedFlat, $i, $j);
     2566        # build tag ID strings for each level in the property path
     2567        foreach $ta (@tagList) {
     2568            # insert tag ID in index 1 of tagList list
     2569            $t = $$ta[1] = $t ? $t . ucfirst($$ta[0]) : $$ta[0];
     2570            # generate flattened tags for top-level structure if necessary
     2571            next if defined $addedFlat;
     2572            $ti = $$tagTablePtr{$t} or next;
     2573            next unless ref $ti eq 'HASH' and $$ti{Struct};
     2574            $addedFlat = AddFlattenedTags($tagTablePtr, $t);
     2575            if ($tagInfo) {
     2576                # all done if we just wanted to initialize the flattened tag
     2577                if ($$tagInfo{Flat}) {
     2578                    warn "Orphan tagInfo with Flat flag set: $$tagInfo{Name}\n";
     2579                    delete $$tagInfo{Flat};
     2580                }
     2581                last NoLoop;
     2582            }
     2583            # all done if we generated the tag we are looking for
     2584            $tagInfo = $$tagTablePtr{$tagID} and last NoLoop if $addedFlat;
     2585        }
     2586        my $name = ucfirst($tag);
     2587
     2588        # search for the innermost containing structure
     2589        # (in case tag is an unknown field in a known structure)
     2590        # (only necessary if we found a structure above)
     2591        if (defined $addedFlat) {
     2592            my $t2 = '';
     2593            for ($i=$#tagList-1; $i>=0; --$i) {
     2594                $t = $tagList[$i][1];
     2595                $t2 = $tagList[$i+1][0] . ucfirst($t2); # build relative tag id
     2596                $ti = $$tagTablePtr{$t} or next;
     2597                next unless ref $ti eq 'HASH';
     2598                my $strTable = $$ti{Struct} or next;
     2599                $name = $$ti{Name} . ucfirst($t2);
     2600                # don't continue if structure is known but field is not
     2601                last if $$strTable{NAMESPACE} or not exists $$strTable{NAMESPACE};
     2602                # this is a variable-namespace structure, so we must:
     2603                # 1) get tagInfo from corresponding top-level XMP tag if it exists
     2604                # 2) add new entry in this tag table, but with namespace prefix on tag ID
     2605                my $n = $nsList[$i+1];  # namespace of structure field
     2606                # translate to standard ExifTool namespace
     2607                $n = $$xlatNamespace{$n} if $$xlatNamespace{$n};
     2608                my $xn = $xmpNS{$n} || $n;  # standard XMP namespace
     2609                # no need to continue with variable-namespace logic if
     2610                # we are in our own namespace (right?)
     2611                last if $xn eq ($$tagTablePtr{NAMESPACE} || '');
     2612                $tagID = "$xn:$tag";    # add namespace to avoid collisions
     2613                # change structure properties to add the standard XMP namespace
     2614                # prefix for this field (needed for variable-namespace fields)
     2615                if (@structProps) {
     2616                    $structProps[$i+1][0] = "$xn:" . $structProps[$i+1][0];
     2617                }
     2618                # copy tagInfo entries from the existing top-level XMP tag
     2619                my $tg = $Image::ExifTool::XMP::Main{$n};
     2620                last unless ref $tg eq 'HASH' and $$tg{SubDirectory};
     2621                my $tbl = GetTagTable($$tg{SubDirectory}{TagTable}) or last;
     2622                my $sti = $exifTool->GetTagInfo($tbl, $t2);
     2623                if (not $sti or $$sti{Flat}) {
     2624                    # again, we must initialize flattened tags if necessary
     2625                    # (but don't bother to recursively apply full logic to
     2626                    #  allow nest variable-namespace strucures until someone
     2627                    #  actually wants to do such a silly thing)
     2628                    my $t3 = '';
     2629                    for ($j=$i+1; $j<@tagList; ++$j) {
     2630                        $t3 = $tagList[$j][0] . ucfirst($t3);
     2631                        my $ti3 = $$tbl{$t3} or next;
     2632                        next unless ref $ti3 eq 'HASH' and $$ti3{Struct};
     2633                        last unless AddFlattenedTags($tbl, $t3);
     2634                        $sti = $$tbl{$t2};
     2635                        last;
     2636                    }
     2637                    last unless $sti;
     2638                }
     2639                $tagInfo = {
     2640                    %$sti,
     2641                    Name     => $$ti{Name} . $$sti{Name},
     2642                    WasAdded => 1,
     2643                };
     2644                # be careful not to copy elements we shouldn't...
     2645                delete $$tagInfo{Description}; # Description will be different
     2646                # can't copy group hash because group 1 will be different and
     2647                # we need to check this when writing tag to a specific group
     2648                delete $$tagInfo{Groups};
     2649                $$tagInfo{Groups}{2} = $$sti{Groups}{2} if $$sti{Groups};
     2650                last;
     2651            }
     2652        }
     2653        $tagInfo or $tagInfo = { Name => $name, WasAdded => 1 };
     2654
     2655        # add tag Namespace entry for tags in variable-namespace tables
     2656        $$tagInfo{Namespace} = $xns if $xns;
     2657        if ($curNS{$ns} and $curNS{$ns} =~ m{^http://ns.exiftool.ca/(.*?)/(.*?)/}) {
     2658            my %grps = ( 0 => $1, 1 => $2 );
     2659            # apply a little magic to recover original group names
     2660            # from this exiftool-written RDF/XML file
     2661            if ($grps{1} =~ /^\d/) {
     2662                # URI's with only family 0 are internal tags from the source file,
     2663                # so change the group name to avoid confusion with tags from this file
     2664                $grps{1} = "XML-$grps{0}";
     2665                $grps{0} = 'XML';
     2666            }
     2667            $$tagInfo{Groups} = \%grps;
     2668            # flag to avoid setting group 1 later
     2669            $$tagInfo{StaticGroup1} = 1;
    18522670        }
    18532671        # construct tag information for this unknown tag
    1854         $tagInfo = { Name => ucfirst($tag), WasAdded => 1 };
    1855         # make this a List type if necessary and not lang-alt
    1856         $$tagInfo{List} = $1 if @$props > 2 and not $lang and
    1857             $$props[-1] =~ /^rdf:li \d+$/ and $$props[-2] =~ /^rdf:(Bag|Seq|Alt)/;
    1858         Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
     2672        # -> make this a List or lang-alt tag if necessary
     2673        if (@$props > 2 and $$props[-1] =~ /^rdf:li \d+$/ and
     2674            $$props[-2] =~ /^rdf:(Bag|Seq|Alt)$/)
     2675        {
     2676            if ($lang and $1 eq 'Alt') {
     2677                $$tagInfo{Writable} = 'lang-alt';
     2678            } else {
     2679                $$tagInfo{List} = $1;
     2680            }
     2681        # tried this, but maybe not a good idea for complex structures:
     2682        #} elsif (grep / /, @$props) {
     2683        #    $$tagInfo{List} = 1;
     2684        }
     2685        Image::ExifTool::AddTagToTable($tagTablePtr, $tagID, $tagInfo);
     2686        $added = 1;
     2687        last;
     2688    }
     2689    # decode value if necessary (et:encoding was used before exiftool 7.71)
     2690    if ($attrs) {
     2691        my $enc = $$attrs{'rdf:datatype'} || $$attrs{'et:encoding'};
     2692        if ($enc and $enc =~ /base64/) {
     2693            $val = DecodeBase64($val); # (now a value ref)
     2694            $val = $$val unless length $$val > 100 or $$val =~ /[\0-\x08\x0b\0x0c\x0e-\x1f]/;
     2695        }
    18592696    }
    18602697    if (defined $lang and lc($lang) ne 'x-default') {
     
    18632700        $tagInfo = $langInfo if $langInfo;
    18642701    }
    1865     if ($exifTool->{OPTIONS}->{Charset} ne 'UTF8' and $val =~ /[\x80-\xff]/) {
    1866         # convert from UTF-8 to specified characterset
    1867         $val = $exifTool->UTF82Charset($val);
    1868     }
     2702    # un-escape XML character entities (handling CDATA)
     2703    pos($val) = 0;
     2704    if ($val =~ /<!\[CDATA\[(.*?)\]\]>/sg) {
     2705        my $p = pos $val;
     2706        # unescape everything up to the start of the CDATA section
     2707        # (the length of "<[[CDATA[]]>" is 12 characters)
     2708        my $v = UnescapeXML(substr($val, 0, $p - length($1) - 12)) . $1;
     2709        while ($val =~ /<!\[CDATA\[(.*?)\]\]>/sg) {
     2710            my $p1 = pos $val;
     2711            $v .= UnescapeXML(substr($val, $p, $p1 - length($1) - 12)) . $1;
     2712            $p = $p1;
     2713        }
     2714        $val = $v . UnescapeXML(substr($val, $p));
     2715    } else {
     2716        $val = UnescapeXML($val);
     2717    }
     2718    # decode from UTF8
     2719    $val = $exifTool->Decode($val, 'UTF8');
    18692720    # convert rational and date values to a more sensible format
    18702721    my $fmt = $$tagInfo{Writable};
    18712722    my $new = $$tagInfo{WasAdded};
    1872     if ($fmt or $new) {
    1873         if (($new or $fmt eq 'rational') and $val =~ m{^(-?\d+)/(-?\d+)$}) {
    1874             $val = $1 / $2 if $2;       # calculate quotient
    1875         } elsif ($new or $fmt eq 'date') {
    1876             if ($val =~ /^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}:\d{2})(:\d{2})?(\S*)$/) {
    1877                 my $s = $5 || ':00';        # seconds may be missing
    1878                 $val = "$1:$2:$3 $4$s$6";   # convert back to EXIF time format
    1879             } elsif ($fmt and $fmt eq 'date' and $val =~ /^(\d{4})(-\d{2}){0,2}/) {
    1880                 $val =~ tr/-/:/;
    1881             }
    1882         }
    1883     }
    1884     $tag = $exifTool->FoundTag($tagInfo, UnescapeXML($val));
    1885     $exifTool->SetGroup1($tag, "XMP-$namespace") if $namespace;
    1886 
    1887     if ($exifTool->Options('Verbose')) {
     2723    if (($fmt or $new)) {
     2724        unless (($new or $fmt eq 'rational') and ConvertRational($val)) {
     2725            $val = ConvertXMPDate($val, $new) if $new or $fmt eq 'date';
     2726        }
     2727    }
     2728    # store the value for this tag
     2729    my $key = $exifTool->FoundTag($tagInfo, $val);
     2730    # save structure/list information if necessary
     2731    if (@structProps and (@structProps > 1 or defined $structProps[0][1])) {
     2732        $exifTool->{TAG_EXTRA}{$key}{Struct} = \@structProps;
     2733        $exifTool->{IsStruct} = 1;
     2734    }
     2735    if ($ns and not $$tagInfo{StaticGroup1}) {
     2736        # set group1 dynamically according to the namespace
     2737        $exifTool->SetGroup($key, "$tagTablePtr->{GROUPS}{0}-$ns");
     2738    }
     2739    if ($exifTool->{OPTIONS}{Verbose}) {
     2740        if ($added) {
     2741            my $g1 = $exifTool->GetGroup($key, 1);
     2742            $exifTool->VPrint(0, $exifTool->{INDENT}, "[adding $g1:$tag]\n");
     2743        }
    18882744        my $tagID = join('/',@$props);
    18892745        $exifTool->VerboseInfo($tagID, $tagInfo, Value=>$val);
     
    19042760{
    19052761    my ($exifTool, $tagTablePtr, $dataPt, $start, $propListPt, $blankInfo) = @_;
    1906     my $count = 0;
     2762    my ($count, $nItems) = (0, 0);
    19072763    my $isWriting = $exifTool->{XMP_CAPTURE};
     2764    my $isSVG = $$exifTool{XMP_IS_SVG};
     2765
     2766    # get our parse procs
     2767    my ($attrProc, $foundProc);
     2768    if ($$exifTool{XMPParseOpts}) {
     2769        $attrProc = $$exifTool{XMPParseOpts}{AttrProc};
     2770        $foundProc = $$exifTool{XMPParseOpts}{FoundProc} || \&FoundXMP;
     2771    } else {
     2772        $foundProc = \&FoundXMP;
     2773    }
    19082774    $start or $start = 0;
    19092775    $propListPt or $propListPt = [ ];
     
    19202786        my $nodeID = $$blankInfo{NodeID} = $oldNodeID;
    19212787        # get next element
    1922         last unless $$dataPt =~ m/<([\w:-]+)(.*?)>/sg;
     2788        last unless $$dataPt =~ m/<([-\w:.\x80-\xff]+)(.*?)>/sg;
    19232789        my ($prop, $attrs) = ($1, $2);
    19242790        my $val = '';
     
    19332799#                my $val2 = $1;
    19342800                my $pos = pos($$dataPt);
    1935                 $$dataPt =~ m/<\/$prop>/sg or last Element;
     2801                unless ($$dataPt =~ m/<\/$prop>/sg) {
     2802                    $exifTool->Warn("XMP format error (no closing tag for $prop)");
     2803                    last Element;
     2804                }
    19362805                my $len = pos($$dataPt) - $pos - length($prop) - 3;
    19372806                my $val2 = substr($$dataPt, $pos, $len);
     
    19432812            }
    19442813        }
     2814        my $parseResource;
    19452815        if ($prop eq 'rdf:li') {
    19462816            # add index to list items so we can keep them in order
    19472817            # (this also enables us to keep structure elements grouped properly
    19482818            # for lists of structures, like JobRef)
    1949             $prop .= sprintf(' %.3d', $count);
     2819            # Note: the list index is prefixed by the number of digits so sorting
     2820            # alphabetically gives the correct order while still allowing a flexible
     2821            # number of digits -- this scheme allows up to 9 digits in the index,
     2822            # with index numbers ranging from 0 to 999999999.  The sequence is:
     2823            # 10,11,12-19,210,211-299,3100,3101-3999,41000...9999999999.
     2824            $prop .= ' ' . length($nItems) . $nItems;
     2825            ++$nItems;
    19502826        } elsif ($prop eq 'rdf:Description') {
    19512827            # trim comments and whitespace from rdf:Description properties only
    19522828            $val =~ s/<!--.*?-->//g;
    19532829            $val =~ s/^\s*(.*)\s*$/$1/;
     2830            # remove unnecessary rdf:Description elements since parseType='Resource'
     2831            # is more efficient (also necessary to make property path consistent)
     2832            $parseResource = 1 if grep /^rdf:Description$/, @$propListPt;
    19542833        } elsif ($prop eq 'xmp:xmpmeta') {
    19552834            # patch MicrosoftPhoto unconformity
     
    19592838        # extract property attributes
    19602839        my (%attrs, @attrs);
    1961         while ($attrs =~ m/(\S+?)=(['"])(.*?)\2/sg) {
     2840        while ($attrs =~ m/(\S+?)\s*=\s*(['"])(.*?)\2/sg) {
    19622841            push @attrs, $1;    # preserve order
    19632842            $attrs{$1} = $3;
    19642843        }
    19652844
     2845        # hook for special parsing of attributes
     2846        $attrProc and &$attrProc(\@attrs, \%attrs, \$prop, \$val);
     2847           
    19662848        # add nodeID to property path (with leading ' #') if it exists
    19672849        if (defined $attrs{'rdf:nodeID'}) {
     
    19692851            delete $attrs{'rdf:nodeID'};
    19702852            $prop .= ' #' . $nodeID;
     2853            undef $parseResource;   # can't ignore if this is a node
    19712854        }
    19722855
    19732856        # push this property name onto our hierarchy list
    1974         push @$propListPt, $prop;
     2857        push @$propListPt, $prop unless $parseResource;
     2858
     2859        if ($isSVG) {
     2860            # ignore everything but top level SVG tags and metadata unless Unknown set
     2861            unless ($exifTool->{OPTIONS}{Unknown} > 1 or $exifTool->{OPTIONS}{Verbose}) {
     2862                if (@$propListPt > 1 and $$propListPt[1] !~ /\b(metadata|desc|title)$/) {
     2863                    pop @$propListPt;
     2864                    next;
     2865                }
     2866            }
     2867            if ($prop eq 'svg' or $prop eq 'metadata') {
     2868                # add svg namespace prefix if missing to ignore these entries in the tag name
     2869                $$propListPt[-1] = "svg:$prop";
     2870            }
     2871        }
    19752872
    19762873        # handle properties inside element attributes (RDF shorthand format):
     
    19942891                $name = $propName;
    19952892            }
     2893            # keep track of the namespace prefixes used
     2894            if ($ns eq 'xmlns') {
     2895                unless ($attrs{$shortName}) {
     2896                    $exifTool->WarnOnce("Duplicate namespace '$shortName'");
     2897                    next;
     2898                }
     2899                $curNS{$name} = $attrs{$shortName};
     2900                my $stdNS = $uri2ns{$attrs{$shortName}};
     2901                # translate namespace if non-standard (except 'x' and 'iX')
     2902                if ($stdNS and $name ne $stdNS and $stdNS ne 'x' and $stdNS ne 'iX') {
     2903                    # make a copy of the standard translations so we can modify it
     2904                    $xlatNamespace = { %stdXlatNS } if $xlatNamespace eq \%stdXlatNS;
     2905                    # translate this namespace prefix to the standard version
     2906                    $$xlatNamespace{$name} = $stdXlatNS{$stdNS} || $stdNS;
     2907                }
     2908            }
    19962909            if ($isWriting) {
    19972910                # keep track of our namespaces when writing
    19982911                if ($ns eq 'xmlns') {
    1999                     unless ($name eq 'x' or $name eq 'iX') {
     2912                    my $stdNS = $uri2ns{$attrs{$shortName}};
     2913                    unless ($stdNS and ($stdNS eq 'x' or $stdNS eq 'iX')) {
    20002914                        my $nsUsed = $exifTool->{XMP_NS};
    20012915                        $$nsUsed{$name} = $attrs{$shortName} unless defined $$nsUsed{$name};
    20022916                    }
     2917                    delete $attrs{$shortName};  # (handled by namespace logic)
    20032918                    next;
    20042919                } elsif ($recognizedAttrs{$propName}) {
    20052920                    # save UUID to use same ID when writing
    20062921                    if ($propName eq 'rdf:about') {
    2007                         if (not $exifTool->{XMP_UUID}) {
    2008                             $exifTool->{XMP_UUID} = $attrs{$shortName};
    2009                         } elsif ($exifTool->{XMP_UUID} ne $attrs{$shortName}) {
    2010                             $exifTool->Error("Multiple XMP UUID's not handled", 1);
     2922                        if (not $exifTool->{XMP_ABOUT}) {
     2923                            $exifTool->{XMP_ABOUT} = $attrs{$shortName};
     2924                        } elsif ($exifTool->{XMP_ABOUT} ne $attrs{$shortName}) {
     2925                            $exifTool->Error("Different 'rdf:about' attributes not handled", 1);
    20112926                        }
    20122927                    }
     
    20142929                }
    20152930            }
     2931            my $shortVal = $attrs{$shortName};
    20162932            if ($ignoreNamespace{$ns}) {
    20172933                $ignored = $propName;
     2934                # handle special attributes (extract as tags only once if not empty)
     2935                if (ref $recognizedAttrs{$propName} and $shortVal) {
     2936                    my ($tbl, $id, $name) = @{$recognizedAttrs{$propName}};
     2937                    my $val = UnescapeXML($shortVal);
     2938                    unless (defined $$exifTool{VALUE}{$name} and $$exifTool{VALUE}{$name} eq $val) {
     2939                        $exifTool->HandleTag(GetTagTable($tbl), $id, $val);
     2940                    }
     2941                }
    20182942                next;
    20192943            }
    2020             my $shortVal = $attrs{$shortName};
    20212944            delete $attrs{$shortName};  # don't re-use this attribute
    20222945            push @$propListPt, $propName;
     
    20272950                CaptureXMP($exifTool, $propListPt, $shortVal);
    20282951            } else {
    2029                 FoundXMP($exifTool, $tagTablePtr, $propListPt, $shortVal);
     2952                &$foundProc($exifTool, $tagTablePtr, $propListPt, $shortVal);
    20302953            }
    20312954            pop @$propListPt;
     
    20492972            # if element value is empty, take value from 'resource' attribute
    20502973            # (preferentially) or 'about' attribute (if no 'resource')
    2051             $val = $2 if $val eq '' and ($attrs =~ /\bresource=(['"])(.*?)\1/ or
    2052                                          $attrs =~ /\babout=(['"])(.*?)\1/);
    2053 
     2974            my $wasEmpty;
     2975            if ($val eq '' and ($attrs =~ /\bresource=(['"])(.*?)\1/ or
     2976                                $attrs =~ /\babout=(['"])(.*?)\1/))
     2977            {
     2978                $val = $2;
     2979                $wasEmpty = 1;
     2980            }
    20542981            # look for additional elements contained within this one
    20552982            if (!ParseXMPElement($exifTool, $tagTablePtr, \$val, 0, $propListPt, $blankInfo)) {
     
    20572984                # (unless we already extracted shorthand values from this element)
    20582985                if (length $val or not $shorthand) {
     2986                    my $lastProp = $$propListPt[-1];
    20592987                    if (defined $nodeID) {
    20602988                        SaveBlankInfo($blankInfo, $propListPt, $val);
     2989                    } elsif ($lastProp eq 'rdf:type' and $wasEmpty) {
     2990                        # do not extract empty structure types (for now)
     2991                    } elsif ($lastProp =~ /^et:(desc|prt|val)$/ and ($count or $1 eq 'desc')) {
     2992                        # ignore et:desc, and et:val if preceeded by et:prt
     2993                        --$count;
    20612994                    } else {
    2062                         FoundXMP($exifTool, $tagTablePtr, $propListPt, $val, $attrs{'xml:lang'});
     2995                        &$foundProc($exifTool, $tagTablePtr, $propListPt, $val, \%attrs);
    20632996                    }
    20642997                }
    20652998            }
    20662999        }
    2067         pop @$propListPt;
     3000        pop @$propListPt unless $parseResource;
    20683001        ++$count;
    20693002    }
     
    20823015# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table
    20833016# Returns: 1 on success
     3017# Notes: The following flavours of XMP files are currently recognized:
     3018# - standard XMP with xpacket, x:xmpmeta and rdf:RDF elements
     3019# - XMP that is missing the xpacket and/or x:xmpmeta elements
     3020# - mutant Microsoft XMP with xmp:xmpmeta element
     3021# - XML files beginning with "<xml"
     3022# - SVG files that begin with "<svg" or "<!DOCTYPE svg"
     3023# - XMP and XML files beginning with a UTF-8 byte order mark
     3024# - UTF-8, UTF-16 and UTF-32 encoded XMP
     3025# - erroneously double-UTF8 encoded XMP
     3026# - otherwise valid files with leading XML comment
    20843027sub ProcessXMP($$;$)
    20853028{
    20863029    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    20873030    my $dataPt = $$dirInfo{DataPt};
    2088     my $dirStart = $$dirInfo{DirStart} || 0;
    2089     my $dirLen = $$dirInfo{DirLen};
    2090     my $dataLen = $$dirInfo{DataLen};
     3031    my ($dirStart, $dirLen, $dataLen);
     3032    my ($buff, $fmt, $hasXMP, $isXML, $isRDF, $isSVG);
    20913033    my $rtnVal = 0;
    20923034    my $bom = 0;
    2093     my ($buff, $fmt, $isXML);
    2094 
    2095     # read information from XMP file if necessary
    2096     unless ($dataPt) {
     3035    undef %curNS;
     3036
     3037    # ignore non-standard XMP while in strict MWG compatibility mode
     3038    if ($Image::ExifTool::MWG::strict and not $$exifTool{XMP_CAPTURE} and
     3039        $$exifTool{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/)
     3040    {
     3041        my $path = $exifTool->MetadataPath();
     3042        unless ($path =~ /^(JPEG-APP1-XMP|TIFF-IFD0-XMP|PSD-XMP)$/) {
     3043            $exifTool->Warn("Ignored non-standard XMP at $path");
     3044            return 1;
     3045        }
     3046    }
     3047    if ($dataPt) {
     3048        $dirStart = $$dirInfo{DirStart} || 0;
     3049        $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
     3050        $dataLen = $$dirInfo{DataLen} || length($$dataPt);
     3051    } else {
     3052        my $type;
     3053        # read information from XMP file
    20973054        my $raf = $$dirInfo{RAF} or return 0;
    2098         $raf->Read($buff, 128) or return 0;
    2099         my ($buf2, $double);
     3055        $raf->Read($buff, 256) or return 0;
     3056        my ($buf2, $buf3, $double);
    21003057        ($buf2 = $buff) =~ tr/\0//d;    # cheap conversion to UTF-8
     3058        # remove leading comments if they exist (ie. ImageIngester)
     3059        while ($buf2 =~ /^\s*<!--/) {
     3060            # remove the comment if it is complete
     3061            if ($buf2 =~ s/^\s*<!--.*?-->\s+//s) {
     3062                # continue with parsing if we have more than 128 bytes remaining
     3063                next if length $buf2 > 128;
     3064            } else {
     3065                # don't read more than 10k when looking for the end of comment
     3066                return 0 if length($buf2) > 10000;
     3067            }
     3068            $raf->Read($buf3, 256) or last; # read more data if available
     3069            $buff .= $buf3;
     3070            $buf3 =~ tr/\0//d;
     3071            $buf2 .= $buf3;
     3072        }
    21013073        # check to see if this is XMP format
    2102         # - CS2 writes .XMP files without the "xpacket begin"
    2103         unless ($buf2 =~ /^(<\?xpacket begin=|<x(mp)?:xmpmeta)/) {
    2104             # also recognize XML files (and .XMP files with BOM)
    2105             if ($buf2 =~ /^(\xfe\xff)(<\?xml|<x(mp)?:xmpmeta)/g) {
     3074        # (CS2 writes .XMP files without the "xpacket begin")
     3075        if ($buf2 =~ /^\s*(<\?xpacket begin=|<x(mp)?:x[ma]pmeta)/) {
     3076            $hasXMP = 1;
     3077        } else {
     3078            # also recognize XML files and .XMP files with BOM and without x:xmpmeta
     3079            if ($buf2 =~ /^(\xfe\xff)(<\?xml|<rdf:RDF|<x(mp)?:x[ma]pmeta)/g) {
    21063080                $fmt = 'n';     # UTF-16 or 32 MM with BOM
    2107             } elsif ($buf2 =~ /^(\xff\xfe)(<\?xml|<x(mp)?:xmpmeta)/g) {
     3081            } elsif ($buf2 =~ /^(\xff\xfe)(<\?xml|<rdf:RDF|<x(mp)?:x[ma]pmeta)/g) {
    21083082                $fmt = 'v';     # UTF-16 or 32 II with BOM
    2109             } elsif ($buf2 =~ /^(\xef\xbb\xbf)?(<\?xml|<x(mp)?:xmpmeta)/g) {
     3083            } elsif ($buf2 =~ /^(\xef\xbb\xbf)?(<\?xml|<rdf:RDF|<x(mp)?:x[ma]pmeta)/g) {
    21103084                $fmt = 0;       # UTF-8 with BOM or unknown encoding without BOM
    21113085            } elsif ($buf2 =~ /^(\xfe\xff|\xff\xfe|\xef\xbb\xbf)(<\?xpacket begin=)/g) {
    21123086                $double = $1;   # double-encoded UTF
    21133087            } else {
    2114                 return 0;       # not XMP or XML
     3088                return 0;       # not recognized XMP or XML
    21153089            }
    21163090            $bom = 1 if $1;
    21173091            if ($2 eq '<?xml') {
    2118                 return 0 unless $buf2 =~ /<x(mp)?:xmpmeta/;
     3092                if ($buf2 =~ /<x(mp)?:x[ma]pmeta/) {
     3093                    $hasXMP = 1;
     3094                } else {
     3095                    # identify SVG images by DOCTYPE if available
     3096                    if ($buf2 =~ /<!DOCTYPE\s+(\w+)/) {
     3097                        if ($1 eq 'svg') {
     3098                            $isSVG = 1;
     3099                        } elsif ($1 eq 'plist') {
     3100                            $type = 'PLIST';
     3101                        } else {
     3102                            return 0;
     3103                        }
     3104                    } elsif ($buf2 =~ /<svg[\s>]/) {
     3105                        $isSVG = 1;
     3106                    } elsif ($buf2 =~ /<rdf:RDF/) {
     3107                        $isRDF = 1;
     3108                    }
     3109                    if ($isSVG and $exifTool->{XMP_CAPTURE}) {
     3110                        $exifTool->Error("ExifTool does not yet support writing of SVG images");
     3111                        return 0;
     3112                    }
     3113                }
    21193114                $isXML = 1;
     3115            } elsif ($2 eq '<rdf:RDF') {
     3116                $isRDF = 1;     # recognize XMP without x:xmpmeta element
    21203117            }
    21213118            if ($buff =~ /^\0\0/) {
     
    21443141            # as characters and look for warnings indicating a false assumption
    21453142            if ($double eq "\xef\xbb\xbf") {
    2146                 $tmp = Image::ExifTool::UTF82Unicode($buff, 'C');
     3143                require Image::ExifTool::Charset;
     3144                my $uni = Image::ExifTool::Charset::Decompose(undef,$buff,'UTF8');
     3145                $tmp = pack('C*', @$uni);
    21473146            } else {
    21483147                my $fmt = ($double eq "\xfe\xff") ? 'n' : 'v';
     
    21603159        $dirStart = 0;
    21613160        $dirLen = $dataLen = $size;
    2162         $exifTool->SetFileType();
    2163     }
    2164    
     3161        unless ($type) {
     3162            if ($isSVG) {
     3163                $type = 'SVG';
     3164            } elsif ($isXML and not $hasXMP and not $isRDF) {
     3165                $type = 'XML';
     3166            }
     3167        }
     3168        $exifTool->SetFileType($type);
     3169    }
     3170
    21653171    # take substring if necessary
    21663172    if ($dataLen != $dirStart + $dirLen) {
     
    21693175        $dirStart = 0;
    21703176    }
    2171     if ($exifTool->{REQ_TAG_LOOKUP}->{xmp}) {
     3177    # extract XMP as a block if specified
     3178    if (($exifTool->{REQ_TAG_LOOKUP}{xmp} or $exifTool->{OPTIONS}{Binary}) and not $isSVG) {
    21723179        $exifTool->FoundTag('XMP', substr($$dataPt, $dirStart, $dirLen));
    21733180    }
    21743181    if ($exifTool->Options('Verbose') and not $exifTool->{XMP_CAPTURE}) {
    2175         $exifTool->VerboseDir('XMP', 0, $dirLen);
     3182        $exifTool->VerboseDir($isSVG ? 'SVG' : 'XMP', 0, $dirLen);
    21763183    }
    21773184#
     
    21813188    pos($$dataPt) = $dirStart;
    21823189    delete $$exifTool{XMP_IS_XML};
    2183     if ($isXML) {
    2184         $$exifTool{XMP_IS_XML} = 1;
     3190    delete $$exifTool{XMP_IS_SVG};
     3191    if ($isXML or $isRDF) {
     3192        $$exifTool{XMP_IS_XML} = $isXML;
     3193        $$exifTool{XMP_IS_SVG} = $isSVG;
    21853194        $$exifTool{XMP_NO_XPACKET} = 1 + $bom;
    21863195    } elsif ($$dataPt =~ /\G\Q$begin\E/gc) {
    21873196        delete $$exifTool{XMP_NO_XPACKET};
    2188     } elsif ($$dataPt =~ /<x(mp)?:xmpmeta/gc) {
     3197    } elsif ($$dataPt =~ /<x(mp)?:x[ma]pmeta/gc) {
    21893198        $$exifTool{XMP_NO_XPACKET} = 1 + $bom;
    21903199    } else {
     
    21923201        # check for UTF-16 encoding (insert one \0 between characters)
    21933202        $begin = join "\0", split //, $begin;
     3203        # must reset pos because it was killed by previous unsuccessful //g match
     3204        pos($$dataPt) = $dirStart;
    21943205        if ($$dataPt =~ /\G(\0)?\Q$begin\E\0./g) {
    21953206            # validate byte ordering by checking for U+FEFF character
     
    22033214            # check for UTF-32 encoding (with three \0's between characters)
    22043215            $begin =~ s/\0/\0\0\0/g;
    2205             # must reset pos because it was killed by previous unsuccessful //g match
    22063216            pos($$dataPt) = $dirStart;
    22073217            if ($$dataPt !~ /\G(\0\0\0)?\Q$begin\E\0\0\0./g) {
     
    22173227    }
    22183228    if ($fmt) {
    2219         # translate into UTF-8
     3229        # trim if necessary to avoid converting non-UTF data
     3230        if ($dirStart or $dirLen != length($$dataPt) - $dirStart) {
     3231            $buff = substr($$dataPt, $dirStart, $dirLen);
     3232            $dataPt = \$buff;
     3233        }
     3234        # convert into UTF-8
    22203235        if ($] >= 5.006001) {
    2221             $buff = pack('C0U*', unpack("x$dirStart$fmt*",$$dataPt));
     3236            $buff = pack('C0U*', unpack("$fmt*",$$dataPt));
    22223237        } else {
    2223             $buff = Image::ExifTool::PackUTF8(unpack("x$dirStart$fmt*",$$dataPt));
     3238            $buff = Image::ExifTool::PackUTF8(unpack("$fmt*",$$dataPt));
    22243239        }
    22253240        $dataPt = \$buff;
    22263241        $dirStart = 0;
    2227     }
     3242        $dirLen = length $$dataPt;
     3243    }
     3244    # initialize namespace translation
     3245    $xlatNamespace = \%stdXlatNS;
     3246
    22283247    # avoid scanning for XMP later in case ScanForXMP is set
    22293248    $$exifTool{FoundXMP} = 1;
     3249
     3250    # set XMP parsing options
     3251    $$exifTool{XMPParseOpts} = $$dirInfo{XMPParseOpts};
     3252
     3253    # need to preserve list indices to be able to handle multi-dimensional lists
     3254    $$exifTool{NO_LIST} = 1 if $exifTool->Options('Struct');
    22303255
    22313256    # parse the XMP
     
    22363261    $$dirInfo{DataPt} = $dataPt if $rtnVal and $$dirInfo{RAF};
    22373262
     3263    # restore structures if necessary
     3264    if ($$exifTool{IsStruct}) {
     3265        require 'Image/ExifTool/XMPStruct.pl';
     3266        RestoreStruct($exifTool);
     3267        delete $$exifTool{IsStruct};
     3268    }
     3269    # reset NO_LIST flag (must do this _after_ RestoreStruct() above)
     3270    delete $$exifTool{NO_LIST};
     3271
     3272    undef %curNS;
    22383273    return $rtnVal;
    22393274}
     
    22613296=head1 AUTHOR
    22623297
    2263 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     3298Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    22643299
    22653300This library is free software; you can redistribute it and/or modify it
     
    22703305=over 4
    22713306
    2272 =item L<http://www.adobe.com/products/xmp/pdfs/xmpspec.pdf>
     3307=item L<http://www.adobe.com/devnet/xmp/>
    22733308
    22743309=item L<http://www.w3.org/TR/rdf-syntax-grammar/>
    22753310
    2276 =item L<http://www.portfoliofaq.com/pfaq/v7mappings.htm>
    2277 
    22783311=item L<http://www.iptc.org/IPTC4XMP/>
    2279 
    2280 =item L<http://creativecommons.org/technology/xmp>
    2281 
    2282 =item L<http://www.optimasc.com/products/fileid/xmp-extensions.pdf>
    22833312
    22843313=back
Note: See TracChangeset for help on using the changeset viewer.