Changeset 24107 for main/trunk/greenstone2/perllib
- Timestamp:
- 2011-06-01T12:33:42+12:00 (13 years ago)
- 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 4 4 # Description: Buffer to support random access reading of sequential file 5 5 # 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 16 19 # 17 20 # Notes: Calls the normal file i/o routines unless SeekTest() fails, in … … 22 25 # May also be used for string i/o (just pass a scalar reference) 23 26 # 24 # Legal: Copyright (c) 200 4-2006Phil Harvey (phil at owl.phy.queensu.ca)27 # Legal: Copyright (c) 2003-2010 Phil Harvey (phil at owl.phy.queensu.ca) 25 28 # This library is free software; you can redistribute it and/or 26 29 # modify it under the same terms as Perl itself. … … 34 37 35 38 use vars qw($VERSION @ISA @EXPORT_OK); 36 $VERSION = '1. 07';39 $VERSION = '1.10'; 37 40 @ISA = qw(Exporter); 41 42 sub Read($$$); 38 43 39 44 # constants … … 64 69 # file i/o 65 70 my $buff = ''; 66 $self = { 71 $self = { 67 72 FILE_PT => $filePt, # file pointer 68 73 BUFF_PT => \$buff, # reference to file data … … 156 161 #------------------------------------------------------------------------------ 157 162 # 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 160 164 # Returns: Number of bytes read 161 165 sub Read($$$) … … 165 169 my $rtnVal; 166 170 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 170 194 if ($self->{TESTED} < 0) { 171 195 my $buff; … … 196 220 $self->{POS} += $rtnVal; 197 221 } else { 222 # read directly from file 198 223 $_[0] = '' unless defined $_[0]; 199 224 $rtnVal = read($self->{FILE_PT}, $_[0], $len) || 0; … … 204 229 $self->{DEBUG}->{$pos} = $rtnVal; 205 230 } 206 } 231 } 207 232 return $rtnVal; 208 233 } … … 217 242 my $rtnVal; 218 243 my $fp = $self->{FILE_PT}; 219 244 220 245 if ($self->{TESTED} < 0) { 221 246 my ($num, $buff); … … 231 256 # scan and read until we find the EOL (or hit EOF) 232 257 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 } 235 263 $pos = $self->{LEN}; # have scanned to end of buffer 236 264 $num = read($fp, $buff, $CHUNK_SIZE) or last; … … 240 268 } else { 241 269 # 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 } 244 277 } 245 278 # read the line from our buffer … … 260 293 $self->{DEBUG}->{$pos} = $rtnVal; 261 294 } 262 } 263 return $rtnVal; 295 } 296 return $rtnVal; 264 297 } 265 298 … … 295 328 { 296 329 my $self = shift; 297 330 298 331 if ($self->{DEBUG}) { 299 332 local $_; -
main/trunk/greenstone2/perllib/cpan/File/RandomAccess.pod
r16844 r24107 4 4 # Description: Buffer to support random access reading of sequential file 5 5 # 6 # Legal: Copyright (c) 200 4-2006Phil Harvey (phil at owl.phy.queensu.ca)6 # Legal: Copyright (c) 2003-2010 Phil Harvey (phil at owl.phy.queensu.ca) 7 7 # This library is free software; you can redistribute it and/or 8 8 # modify it under the same terms as Perl itself. … … 218 218 =head1 AUTHOR 219 219 220 Copyright 200 4-2006Phil Harvey (phil at owl.phy.queensu.ca)220 Copyright 2003-2011 Phil Harvey (phil at owl.phy.queensu.ca) 221 221 222 222 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool.pm
r23771 r24107 6 6 # URL: http://owl.phy.queensu.ca/~phil/exiftool/ 7 7 # 8 # Revisions: Nov. 12/ 03 - P. Harvey Created8 # Revisions: Nov. 12/2003 - P. Harvey Created 9 9 # (See html/history.html for revision history) 10 10 # 11 # Legal: Copyright (c) 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)11 # Legal: Copyright (c) 2003-2010, Phil Harvey (phil at owl.phy.queensu.ca) 12 12 # This library is free software; you can redistribute it and/or 13 13 # modify it under the same terms as Perl itself. … … 20 20 require Exporter; 21 21 use File::RandomAccess; 22 22 23 23 use 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'; 28 30 $RELEASE = ''; 29 31 @ISA = qw(Exporter); 30 32 %EXPORT_TAGS = ( 31 # all public non-object-oriented functions 33 # all public non-object-oriented functions: 32 34 Public => [qw( 33 35 ImageInfo GetTagName GetShortcuts GetAllTags GetWritableTags 34 36 GetAllGroups GetDeleteGroups GetFileType CanWrite CanCreate 35 37 )], 38 # exports not part of the public API, but used by ExifTool modules: 36 39 DataAccess => [qw( 37 40 ReadValue GetByteOrder SetByteOrder ToggleByteOrder Get8u Get8s Get16u 38 Get16s Get32u Get32s Get Float GetDouble GetFixed32s Write WriteValue39 Tell Set8u Set8s Set16u Set32u41 Get16s Get32u Get32s Get64u GetFloat GetDouble GetFixed32s Write 42 WriteValue Tell Set8u Set8s Set16u Set32u 40 43 )], 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)], 48 46 ); 49 47 # set all of our EXPORT_TAGS in EXPORT_OK … … 54 52 55 53 # The following functions defined in Image::ExifTool::Writer are declared 56 # here so their prototypes will be available. The Writer routines will be57 # autoloaded when any of the se arecalled.54 # here so their prototypes will be available. These Writer routines will be 55 # autoloaded when any of them is called. 58 56 sub SetNewValue($;$$%); 59 57 sub SetNewValuesFromFile($$;@); … … 74 72 sub IsWritable($); 75 73 sub GetNewFileName($$); 74 sub NextTagKey($$); 76 75 sub LoadAllTables(); 77 76 sub GetNewTagInfoList($;$); … … 88 87 sub VerboseInfo($$$%); 89 88 sub VerboseDir($$;$$); 89 sub VerboseValue($$$;$); 90 90 sub VPrint($$@); 91 91 sub Rationalize($;$); 92 92 sub Write($@); 93 sub ProcessTrailers($$);94 93 sub WriteTrailerBuffer($$$); 95 94 sub AddNewTrailers($;@); … … 100 99 sub CheckBinaryData($$$); 101 100 sub WriteTIFF($$$); 102 sub Charset2Unicode($$;$);103 sub Latin2Unicode($$);104 sub UTF82Unicode($$;$);105 sub Unicode2Charset($$;$);106 sub Unicode2Latin($$;$);107 sub Unicode2UTF8($$);108 101 sub PackUTF8(@); 109 102 sub UnpackUTF8($); 103 sub SetPreferredByteOrder($); 104 sub CopyBlock($$$); 105 sub CopyFileAttrs($$); 106 107 # other subroutine definitions 108 sub DoEscape($$); 109 sub ConvertFileSize($); 110 sub ParseArguments($;@); #(defined in attempt to avoid mod_perl problem) 110 111 111 112 # list of main tag tables to load in LoadAllTables() (sub-tables are recursed 112 113 # 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(). 114 115 @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 (ç¹é«äžæ)', 121 151 ); 122 152 123 153 # recognized file types, in the order we test unknown files 124 154 # Notes: 1) There is no need to test for like types separately here 125 # 2) Put types with no file signatureat end of list to avoid false matches155 # 2) Put types with weak file signatures at end of list to avoid false matches 126 156 @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); 129 160 130 161 # 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); 162 my @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 ); 133 170 134 171 # 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! 173 my %createTypes = (XMP=>1, ICC=>1, MIE=>1, VRD=>1, EXIF=>1); 136 174 137 175 # file type lookup for all recognized file extensions 138 176 my %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', 139 182 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', 142 188 AIFC => ['AIFF', 'Audio Interchange File Format Compressed'], 143 189 AIFF => ['AIFF', 'Audio Interchange File Format'], 190 AIT => 'AI', 144 191 APE => ['APE', "Monkey's Audio format"], 145 ARW => ['TIFF', 'Sony Alpha RAW format (TIFF-like)'],192 ARW => ['TIFF', 'Sony Alpha RAW format'], 146 193 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'], 152 201 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'], 162 229 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'], 165 240 FLAC => ['FLAC', 'Free Lossless Audio Codec'], 241 FLA => ['FPX', 'Macromedia/Adobe Flash project'], 166 242 FLV => ['FLV', 'Flash Video'], 167 243 FPX => ['FPX', 'FlashPix'], 168 244 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', 170 249 HTML => ['HTML', 'HyperText Markup Language'], 171 250 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'], 174 258 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', 176 261 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'], 181 277 MIE => ['MIE', 'Meta Information Encapsulation format'], 182 MIF => ['MIFF', 'Magick Image File Format'],278 MIF => 'MIFF', 183 279 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'], 186 286 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'], 189 289 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'], 192 294 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'], 194 306 OGG => ['OGG', 'Ogg Vorbis audio file'], 195 307 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', 198 312 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'], 201 319 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 ;) 202 322 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'], 203 326 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'], 205 333 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', 208 344 QT => ['MOV', 'QuickTime movie'], 209 QTI => ['QTIF', 'QuickTime Image File'],345 QTI => 'QTIF', 210 346 QTIF => ['QTIF', 'QuickTime Image File'], 211 347 RA => ['Real', 'Real Audio'], 212 348 RAF => ['RAF', 'FujiFilm RAW Format'], 213 349 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', 216 353 RIFF => ['RIFF', 'Resource Interchange File Format'], 217 354 RM => ['Real', 'Real Media'], 218 355 RMVB => ['Real', 'Real Media Variable Bitrate'], 219 356 RPM => ['Real', 'Real Media Plug-in Metafile'], 357 RSRC => ['RSRC', 'Mac OS Resource'], 358 RTF => ['RTF', 'Rich Text Format'], 220 359 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'], 223 368 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', 226 373 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'], 232 387 X3F => ['X3F', 'Sigma RAW format'], 388 XCF => ['XCF', 'GIMP native image format'], 233 389 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'], 236 401 ); 237 402 403 # descriptions for file types not found in above file extension lookup 404 my %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 238 413 # 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', 242 420 APE => 'audio/x-monkeys-audio', 243 421 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', 246 424 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) 250 444 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', 256 448 FLAC => 'audio/flac', 257 449 FLV => 'video/x-flv', 450 Font => 'application/x-font-type1', # covers PFA, PFB and PFM (not sure about PFM) 258 451 FPX => 'image/vnd.fpx', 259 452 GIF => 'image/gif', 453 GZIP => 'application/x-gzip', 454 HDP => 'image/vnd.ms-photo', 260 455 HTML => 'text/html', 456 ICC => 'application/vnd.iccprofile', 457 IIQ => 'image/x-raw', 458 IND => 'application/x-indesign', 459 ITC => 'application/itunes', 261 460 JNG => 'image/jng', 262 JP2 => 'image/jp eg2000',461 JP2 => 'image/jp2', 263 462 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', 267 471 MIE => 'application/x-mie', 268 472 MIFF => 'application/x-magick-image', 473 MKA => 'audio/x-matroska', 474 MKS => 'application/x-matroska', 475 MKV => 'video/x-matroska', 269 476 MNG => 'video/mng', 270 477 MOS => 'image/x-raw', … … 274 481 MPC => 'audio/x-musepack', 275 482 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', 278 490 OGG => 'audio/x-ogg', 279 ORF => 'image/x-raw', 491 ORF => 'image/x-olympus-orf', 492 OTF => 'application/x-font-otf', 280 493 PBM => 'image/x-portable-bitmap', 281 494 PDF => 'application/pdf', 282 PEF => 'image/x-raw', 495 PEF => 'image/x-pentax-pef', 496 PGF => 'image/pgf', 283 497 PGM => 'image/x-portable-graymap', 284 498 PICT => 'image/pict', 499 PLIST=> 'application/xml', 285 500 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', 286 504 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', 287 508 PPT => 'application/vnd.ms-powerpoint', 509 PPTM => 'application/vnd.ms-powerpoint.presentation.macroEnabled', 510 PPTX => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 288 511 PS => 'application/postscript', 289 PSD => 'application/photoshop', 512 PSD => 'application/vnd.adobe.photoshop', 513 PSP => 'image/x-paintshoppro', #(NC) 290 514 QTIF => 'image/x-quicktime', 291 515 RA => 'audio/x-pn-realaudio', 292 RAF => 'image/x- raw',516 RAF => 'image/x-fujifilm-raf', 293 517 RAM => 'audio/x-pn-realaudio', 518 RAR => 'application/x-rar-compressed', 294 519 RAW => 'image/x-raw', 295 520 RM => 'application/vnd.rn-realmedia', 296 521 RMVB => 'application/vnd.rn-realmedia-vbr', 297 522 RPM => 'audio/x-pn-realaudio-plugin', 523 RSRC => 'application/ResEdit', 524 RTF => 'text/rtf', 298 525 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', 301 533 SWF => 'application/x-shockwave-flash', 534 TAR => 'application/x-tar', 535 THMX => 'application/vnd.ms-officetheme', 302 536 TIFF => 'image/tiff', 537 TTC => 'application/x-font-ttf', 538 TTF => 'application/x-font-ttf', 539 VSD => 'application/x-visio', 303 540 WAV => 'audio/x-wav', 304 541 WDP => 'image/vnd.ms-photo', 542 WEBM => 'video/webm', 543 WEBP => 'image/webp', 305 544 WMA => 'audio/x-ms-wma', 306 545 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', 308 550 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', 309 558 XMP => 'application/rdf+xml', 559 ZIP => 'application/zip', 310 560 ); 311 561 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 314 566 my %moduleName = ( 315 567 BTF => 'BigTIFF', 568 BZ2 => 0, 316 569 CRW => 'CanonRaw', 317 570 DICM => 'DICOM', 571 COS => 'CaptureOne', 572 DOCX => 'OOXML', 318 573 EPS => 'PostScript', 574 EXIF => '', 319 575 ICC => 'ICC_Profile', 576 IND => 'InDesign', 320 577 FLV => 'Flash', 321 578 FPX => 'FlashPix', 579 GZIP => 'ZIP', 322 580 JP2 => 'Jpeg2000', 323 JPEG => '', # (in the current module) 581 JPEG => '', 582 # MODD => 'XML', 324 583 MOV => 'QuickTime', 584 MKV => 'Matroska', 325 585 MP3 => 'ID3', 326 586 MRW => 'MinoltaRaw', 327 587 OGG => 'Vorbis', 328 588 ORF => 'Olympus', 589 # PLIST=> 'XML', 590 PMP => 'Sony', 329 591 PS => 'PostScript', 330 592 PSD => 'Photoshop', 331 593 QTIF => 'QuickTime', 332 594 RAF => 'FujiFilm', 595 RAR => 'ZIP', 333 596 RAW => 'KyoceraRaw', 597 RWZ => 'Rawzor', 334 598 SWF => 'Flash', 599 TAR => 0, 335 600 TIFF => '', 336 601 VRD => 'CanonVRD', 337 602 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', 338 704 ); 339 705 … … 343 709 # group hash for ExifTool-generated tags 344 710 my %allGroupsExifTool = ( 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'ExifTool' ); 711 712 # special tag names (not used for tag info) 713 my %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 ); 345 720 346 721 # headers for various segment types 347 722 $exifAPP1hdr = "Exif\0\0"; 348 723 $xmpAPP1hdr = "http://ns.adobe.com/xap/1.0/\0"; 724 $xmpExtAPP1hdr = "http://ns.adobe.com/xmp/extension/\0"; 349 725 $psAPP13hdr = "Photoshop 3.0\0"; 350 726 $psAPP13old = 'Adobe_Photoshop2.5:'; 351 727 352 728 sub 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 = ( ); 353 736 354 737 # tag information for preview image -- this should be used for all … … 360 743 WriteCheck => '$val eq "none" ? undef : $self->CheckImage(\$val)', 361 744 DataTag => 'PreviewImage', 745 # accept either scalar or scalar reference 746 RawConv => '$self->ValidateImage(ref $val ? $val : \$val, $tag)', 362 747 # we allow preview image to be set to '', but we don't want a zero-length value 363 748 # in the IFD, so set it temorarily to 'none'. Note that the length is <= 4, 364 749 # so this value will fit in the IFD so the preview fixup won't be generated. 365 ValueConv => '$self->ValidateImage(\$val,$tag)',366 750 ValueConvInv => '$val eq "" and $val="none"; $val', 367 751 ); … … 372 756 %Image::ExifTool::Extra = ( 373 757 GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' }, 374 DID_TAG_ID => 1,# tag ID's aren't meaningful for these tags758 VARS => { NO_ID => 1 }, # tag ID's aren't meaningful for these tags 375 759 WRITE_PROC => \&DummyWriteProc, 760 Error => { Priority => 0, Groups => \%allGroupsExifTool }, 761 Warning => { Priority => 0, Groups => \%allGroupsExifTool }, 376 762 Comment => { 377 763 Notes => 'comment embedded in JPEG, GIF89a or PPM/PGM/PBM image', … … 381 767 }, 382 768 Directory => { 769 Groups => { 1 => 'System' }, 383 770 Writable => 1, 384 771 Protected => 1, … … 387 774 }, 388 775 FileName => { 776 Groups => { 1 => 'System' }, 389 777 Writable => 1, 390 778 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 }, 391 784 ValueConvInv => '$val=~tr/\\\\/\//; $val', 392 785 }, 393 786 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 399 796 }, 797 PrintConv => \&ConvertFileSize, 400 798 }, 401 799 FileType => { }, … … 403 801 Description => 'File Modification Date/Time', 404 802 Notes => 'the filesystem modification time', 405 Groups => { 2 => 'Time' },803 Groups => { 1 => 'System', 2 => 'Time' }, 406 804 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, 407 808 Shift => 'Time', 408 ValueConv => 'ConvertUnixTime($val, "local")',409 ValueConvInv => 'GetUnixTime($val, "local")',809 ValueConv => 'ConvertUnixTime($val,1)', 810 ValueConvInv => 'GetUnixTime($val,1)', 410 811 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 }, 412 832 }, 413 833 MIMEType => { }, … … 418 838 MaxVal => { }, # max pixel value in PPM or PGM image 419 839 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 }, 423 847 }, 424 848 ICC_Profile => { 425 849 Notes => 'the full ICC_Profile data block', 426 Groups => { 0 => 'ICC_Profile' },850 Groups => { 0 => 'ICC_Profile', 1 => 'ICC_Profile' }, 427 851 Flags => ['Writable' ,'Protected', 'Binary'], 428 852 WriteCheck => q{ … … 433 857 XMP => { 434 858 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 437 862 WriteCheck => q{ 438 863 require Image::ExifTool::XMP; … … 442 867 CanonVRD => { 443 868 Notes => 'the full Canon DPP VRD trailer block', 444 Groups => { 0 => 'CanonVRD' },869 Groups => { 0 => 'CanonVRD', 1 => 'CanonVRD' }, 445 870 Flags => ['Writable' ,'Protected', 'Binary'], 871 Permanent => 0, # (this is 1 by default for MakerNotes tags) 446 872 WriteCheck => q{ 447 873 return undef if $val =~ /^CANON OPTIONAL DATA\0/; … … 449 875 }, 450 876 }, 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 }, 452 896 ExifByteOrder => { 453 897 Writable => 1, 454 898 Notes => 'only writable for newly created EXIF segments', 455 899 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)', 458 915 }, 459 916 }, 460 917 ExifToolVersion => { 461 918 Description => 'ExifTool Version Number', 462 Groups => \%allGroupsExifTool919 Groups => \%allGroupsExifTool, 463 920 }, 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 }, 466 1012 ); 467 1013 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 470 1029 # (ref http://www.w3.org/Graphics/JPEG/itu-t81.pdf) 471 1030 %Image::ExifTool::JPEG::SOF = ( 472 1031 GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' }, 473 1032 NOTES => 'This information is extracted from the JPEG Start Of Frame segment.', 474 VARS => { NO_ID => 1 }, 475 476 477 478 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', 479 1038 0x1 => 'Extended sequential DCT, Huffman coding', 480 1039 0x2 => 'Progressive DCT, Huffman coding', … … 497 1056 YCbCrSubSampling => { 498 1057 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, 507 1059 }, 508 1060 ); 509 1061 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 525 1063 %Image::ExifTool::JFIF::Main = ( 526 1064 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, … … 532 1070 Name => 'JFIFVersion', 533 1071 Format => 'int8u[2]', 534 PrintConv => ' $val=~tr/ /./;$val',1072 PrintConv => 'sprintf("%d.%.2d", split(" ",$val))', 535 1073 }, 536 1074 2 => { … … 564 1102 0x10 => { 565 1103 Name => 'ThumbnailImage', 566 ValueConv => '$self->ValidateImage(\$val,$tag)',1104 RawConv => '$self->ValidateImage(\$val,$tag)', 567 1105 }, 568 1106 ); 569 1107 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, 577 1115 ); 1116 1117 # static private ExifTool variables 1118 1119 %allTables = ( ); # list of all tables loaded (except Composite tags) 1120 @tableOrder = ( ); # order the tables were loaded 578 1121 579 1122 #------------------------------------------------------------------------------ … … 605 1148 # New - create new ExifTool object 606 1149 # Inputs: 0) reference to exiftool object or ExifTool class name 1150 # Returns: blessed ExifTool object ref 607 1151 sub new 608 1152 { … … 617 1161 $self->ClearOptions(); # create default options hash 618 1162 $self->{VALUE} = { }; # must initialize this for warning messages 619 $self->{DEL_GROUP} = { }; # l ist ofgroups to delete when writing1163 $self->{DEL_GROUP} = { }; # lookup for groups to delete when writing 620 1164 621 1165 # initialize our new groups for writing … … 633 1177 # Notes: 634 1178 # - 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 636 1180 # - can pass a reference to list of tags to find, in which case the list will 637 1181 # be updated with the tags found in the proper case and in the specified order. … … 684 1228 while (@_) { 685 1229 my $param = shift; 686 $oldVal = $ options->{$param};1230 $oldVal = $$options{$param}; 687 1231 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 691 1250 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; 695 1253 } 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; 700 1286 } 701 1287 } … … 713 1299 # create options hash with default values 714 1300 # (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 # +-----------------------------------------------------+ 715 1305 $self->{OPTIONS} = { 716 1306 # Binary => undef, # flag to extract binary values even if tag not specified 717 1307 # ByteOrder => undef, # default byte order when creating EXIF information 718 1308 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 719 1311 # Compact => undef, # compact XMP and IPTC data 720 1312 Composite => 1, # flag to calculate Composite tags … … 723 1315 # DateFormat => undef, # format for date/time 724 1316 Duplicates => 1, # flag to save duplicate tag values 1317 # Escape => undef, # escape special characters 725 1318 # Exclude => undef, # tags to exclude 1319 # ExtractEmbedded =>undef,# flag to extract information from embedded documents 726 1320 # FastScan => undef, # flag to avoid scanning for trailer 727 1321 # 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 728 1327 # Group# => undef, # return tags for specified groups in family # 729 1328 HtmlDump => 0, # HTML dump (0-3, higher # = bigger limit) 730 1329 # HtmlDumpBase => undef, # base address for HTML dump 731 1330 # 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 732 1333 # 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 733 1336 # MakerNotes => undef, # extract maker notes as a block 734 1337 # MissingTagValue =>undef,# value for missing tags when expanded in expressions 1338 # Password => undef, # password for password-protected PDF documents 735 1339 PrintConv => 1, # flag to enable print conversion 1340 # SavePath => undef, # (undocumented) save family 5 location path 736 1341 # ScanForXMP => undef, # flag to scan for XMP information in all files 737 1342 Sort => 'Input', # order to sort found tags (Input, File, Alpha, Group#) 738 1343 # StrictDate => undef, # flag to return undef for invalid date conversions 1344 # Struct => undef, # return structures as hash references 739 1345 TextOut => \*STDOUT,# file for Verbose/HtmlDump output 740 1346 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) 742 1348 }; 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 } 743 1359 } 744 1360 … … 749 1365 # Returns: 1 if this was a valid image, 0 otherwise 750 1366 # Notes: pass an undefined value to avoid parsing arguments 1367 # Internal 'ReEntry' option allows this routine to be called recursively 751 1368 sub ExtractInfo($;@) 752 1369 { … … 754 1371 my $self = shift; 755 1372 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 768 1394 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 } 779 1416 my $filename = $self->{FILENAME}; # image file name ('' if already open) 780 1417 my $raf = $self->{RAF}; # RandomAccess object 781 1418 782 # return our version number783 $self->FoundTag('ExifToolVersion', "$VERSION$RELEASE");784 785 1419 local *EXIFTOOL_FILE; # avoid clashes with global namespace 786 1420 1421 my $realname = $filename; 787 1422 unless ($raf) { 788 1423 # save file name 789 1424 if (defined $filename and $filename ne '') { 790 1425 unless ($filename eq '-') { 791 my $name = $filename;792 1426 # 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); 795 1429 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); 798 1432 } 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/(.*)\///; 803 1436 } 804 1437 $self->FoundTag('FileName', $name); 805 1438 $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}; 806 1441 } 807 1442 # open the file 808 if (open(EXIFTOOL_FILE,$filename)) { 809 my $filePt = \*EXIFTOOL_FILE; 1443 if (open(EXIFTOOL_FILE, $filename)) { 810 1444 # create random access file object 811 $raf = new File::RandomAccess( $filePt);1445 $raf = new File::RandomAccess(\*EXIFTOOL_FILE); 812 1446 # patch to force pipe to be buffered because seek returns success 813 1447 # in Windows cmd shell pipe even though it really failed … … 823 1457 824 1458 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 827 1466 my $fileSize = -s _; 828 1467 my $fileTime = -M _; 1468 my @stat = stat _; 829 1469 $self->FoundTag('FileSize', $fileSize) if defined $fileSize; 1470 $self->FoundTag('ResourceForkSize', $rsize) if $rsize; 830 1471 $self->FoundTag('FileModifyDate', $^T - $fileTime*(24*3600)) if defined $fileTime; 1472 $self->FoundTag('FilePermissions', $stat[2]) if defined $stat[2]; 831 1473 } 832 1474 833 1475 # 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); 837 1479 if (@fileTypeList) { 838 1480 # add remaining types to end of list so we test them all … … 840 1482 push @fileTypeList, grep(!/^($pat)$/, @fileTypes); 841 1483 $tiffType = $self->{FILE_EXT}; 1484 $noMagic{MXF} = 1; # don't do magic number test on MXF or DV files 1485 $noMagic{DV} = 1; 842 1486 } else { 843 1487 # scan through all recognized file types … … 851 1495 my %dirInfo = ( RAF => $raf, Base => $pos ); 852 1496 # 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) { 855 1502 $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 { 857 1508 last unless defined $type; 858 1509 # last ditch effort to scan past unknown header for JPEG/TIFF 859 my $buff;860 $raf->Read($buff, 1024);861 1510 next unless $buff =~ /(\xff\xd8\xff|MM\0\x2a|II\x2a\0)/g; 862 1511 $type = ($1 eq "\xff\xd8\xff") ? 'JPEG' : 'TIFF'; 863 1512 my $skip = pos($buff) - length($1); 864 1513 $dirInfo{Base} = $pos + $skip; 865 $raf->Seek($pos + $skip, 0) ;1514 $raf->Seek($pos + $skip, 0) or $seekErr = 1, last; 866 1515 $self->Warn("Skipped unknown $skip byte header"); 867 1516 } 868 1517 # save file type in member variable 869 $self->{FILE_TYPE} = $ type;1518 $self->{FILE_TYPE} = $self->{PATH}[0] = $type; 870 1519 $dirInfo{Parent} = ($type eq 'TIFF') ? $tiffType : $type; 871 1520 my $module = $moduleName{$type}; … … 877 1526 require "Image/ExifTool/$module.pm"; 878 1527 $func = "Image::ExifTool::${module}::$func"; 1528 } elsif ($module eq '0') { 1529 $self->SetFileType(); 1530 $self->Warn('Unsupported file type'); 1531 last; 879 1532 } 880 1533 # process the file … … 884 1537 885 1538 # 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 893 1544 (not $self->Options('FastScan') and not $$self{FoundXMP}))) 894 1545 { 1546 # scan for XMP 895 1547 $raf->Seek($pos, 0); 896 1548 require Image::ExifTool::XMP; … … 901 1553 # must be a format error since we couldn't read it, otherwise 902 1554 # 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); 905 1565 } 906 1566 # 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 { 908 1570 $self->FoundTag('EXIF', $self->{EXIF_DATA}); 909 1571 } 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 } 927 1606 } 928 1607 … … 930 1609 %saveOptions and $self->{OPTIONS} = \%saveOptions; 931 1610 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; 933 1617 } 934 1618 … … 941 1625 # - If groups are specified, first groups take precedence if duplicate 942 1626 # tags found but Duplicates option not set. 1627 # - tag names may end in '#' to extract ValueConv value 943 1628 sub GetInfo($;@) 944 1629 { … … 955 1640 956 1641 # get reference to list of tags for which we will return info 957 my $rtnTags= $self->SetFoundTags();1642 my ($rtnTags, $byValue) = $self->SetFoundTags(); 958 1643 959 1644 # build hash of tag information 960 1645 my (%info, %ignored); 961 my $conv = $self->{OPTIONS} ->{PrintConv} ? 'PrintConv' : 'ValueConv';1646 my $conv = $self->{OPTIONS}{PrintConv} ? 'PrintConv' : 'ValueConv'; 962 1647 foreach (@$rtnTags) { 963 1648 my $val = $self->GetValue($_, $conv); 964 1649 defined $val or $ignored{$_} = 1, next; 965 1650 $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 } 966 1678 } 967 1679 … … 980 1692 # use file order by default if no tags specified 981 1693 # (no such thing as 'Input' order in this case) 982 my $sortOrder = $self->{OPTIONS} ->{Sort};1694 my $sortOrder = $self->{OPTIONS}{Sort}; 983 1695 unless (@$reqTags or ($sortOrder and $sortOrder ne 'Input')) { 984 1696 $sortOrder = 'File'; … … 1003 1715 local $_; 1004 1716 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}) { 1008 1720 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}; 1012 1723 } 1013 1724 } 1014 1725 } else { 1015 my (%haveInfo, $tag);1016 1726 while ($info = shift) { 1017 1727 foreach $tag (keys %$info) { … … 1056 1766 $foundTags = $self->{FOUND_TAGS} || $self->SetFoundTags() or return undef; 1057 1767 } 1058 $sortOrder or $sortOrder = $self->{OPTIONS} ->{Sort};1768 $sortOrder or $sortOrder = $self->{OPTIONS}{Sort}; 1059 1769 1060 1770 # return original list if no sort order specified … … 1063 1773 if ($sortOrder eq 'Alpha') { 1064 1774 return sort @$foundTags; 1065 } elsif ($sortOrder =~ /^Group(\d* )/) {1775 } elsif ($sortOrder =~ /^Group(\d*(:\d+)*)/) { 1066 1776 my $family = $1 || 0; 1067 1777 # want to maintain a basic file order with the groups … … 1086 1796 # Get list of found tags in specified sort order 1087 1797 # Inputs: 0) ExifTool object reference, 1) sort order ('File', 'Input', ...) 1088 # Returns: List of tag s in specified order1798 # Returns: List of tag keys in specified order 1089 1799 # Notes: If not specified, sort order is taken from OPTIONS 1090 1800 sub GetFoundTags($;$) … … 1099 1809 # Get list of requested tags 1100 1810 # Inputs: 0) ExifTool object reference 1101 # Returns: List of requested tag s1811 # Returns: List of requested tag keys 1102 1812 sub GetRequestedTags($) 1103 1813 { 1104 1814 local $_; 1105 return @{$_[0] ->{REQUESTED_TAGS}};1815 return @{$_[0]{REQUESTED_TAGS}}; 1106 1816 } 1107 1817 1108 1818 #------------------------------------------------------------------------------ 1109 1819 # 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) 1111 1822 # 2) [optional] Value type: PrintConv, ValueConv, Both or Raw, the default 1112 1823 # is PrintConv or ValueConv, depending on the PrintConv option setting 1824 # 3) raw field value (not part of public API) 1113 1825 # Returns: Scalar context: tag value or undefined 1114 1826 # List context: list of values or empty list … … 1116 1828 { 1117 1829 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'; 1119 1835 1120 1836 # 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 } 1131 1883 } 1132 1884 1133 1885 # do the conversions 1134 my (@val, @prt, @raw, $convType , $valueConv);1886 my (@val, @prt, @raw, $convType); 1135 1887 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'; 1137 1890 my $conv = $$tagInfo{$convType}; 1138 1891 unless (defined $conv) { … … 1141 1894 $conv = '\$val'; # return scalar reference for binary values 1142 1895 } 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}; 1145 1899 } 1146 1900 } … … 1153 1907 $conv = $$convList[0]; 1154 1908 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 } 1156 1930 } 1157 1931 # initialize array so we can iterate over values in list … … 1166 1940 for (;;) { 1167 1941 if (defined $conv) { 1168 # get values of required tags if this is a composite tag1942 # get values of required tags if this is a Composite tag 1169 1943 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}; 1170 1947 foreach (keys %$val) { 1171 $raw[$_] = $self->{VALUE} ->{$$val{$_}};1948 $raw[$_] = $self->{VALUE}{$$val{$_}}; 1172 1949 ($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; 1174 1952 return wantarray ? () : undef; 1175 1953 } 1954 $$self{ESCAPE_PROC} = $oldEscape; 1176 1955 # set $val to $val[0], or \@val for a CODE ref conversion 1177 1956 $val = ref $conv eq 'CODE' ? \@val : $val[0]; … … 1179 1958 if (ref $conv eq 'HASH') { 1180 1959 # 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 { 1182 1971 if ($$conv{BITMASK}) { 1183 1972 $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') 1187 1991 { 1188 1992 $val = sprintf('0x%x',$val); … … 1202 2006 $@ and $evalWarning = $@; 1203 2007 } 1204 if ($evalWarning) { 1205 delete $SIG{'__WARN__'}; 1206 warn "$convType $tag: " . CleanWarning() . "\n"; 1207 } 2008 $self->Warn("$convType $tag: " . CleanWarning()) if $evalWarning; 1208 2009 } 1209 2010 } else { … … 1228 2029 } 1229 2030 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 } 1232 2046 # return Both values as a list (ValueConv, PrintConv) 1233 2047 return ($valueConv, $value); 1234 2048 } 2049 # escape value if necessary 2050 DoEscape($value, $$self{ESCAPE_PROC}) if $$self{ESCAPE_PROC}; 2051 1235 2052 if (ref $value eq 'ARRAY') { 1236 2053 # return array if requested 1237 2054 return @$value if wantarray; 1238 # return list reference for Raw, ValueConv or if List o ption set1239 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]; 1240 2057 # otherwise join in comma-separated string 1241 $value = join ', ', @$value;2058 $value = join $self->{OPTIONS}{ListSep}, @$value; 1242 2059 } 1243 2060 return $value; … … 1247 2064 # Get tag identification number 1248 2065 # 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) 1250 2068 sub GetTagID($$) 1251 2069 { 1252 local $_;1253 2070 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 '' 2081 sub 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 2092 sub GetTagIndex($$) 2093 { 2094 my ($self, $tag) = @_; 2095 my $tagInfo = $self->{TAG_INFO}{$tag} or return undef; 2096 return $$tagInfo{Index}; 1262 2097 } 1263 2098 … … 1271 2106 local $_; 1272 2107 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 } 1278 2133 # just make the tag more readable if description doesn't exist 1279 2134 unless ($desc) { … … 1289 2144 # Inputs: 0) ExifTool object reference 1290 2145 # 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) 1292 2147 # Returns: Scalar context: Group name (for family 0 if not otherwise specified) 1293 2148 # 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') 1295 2151 sub GetGroup($$;$) 1296 2152 { 1297 2153 local $_; 1298 2154 my ($self, $tag, $family) = @_; 1299 my ($tagInfo, @groups, $extra);2155 my ($tagInfo, @groups, @families, $simplify, $byTagInfo); 1300 2156 if (ref $tag eq 'HASH') { 1301 2157 $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; 1303 2161 } else { 1304 $tagInfo = $self->{TAG_INFO} ->{$tag} or return '';2162 $tagInfo = $self->{TAG_INFO}{$tag} or return ''; 1305 2163 } 1306 2164 my $groups = $$tagInfo{Groups}; 1307 2165 # fill in default groups unless already done 2166 # (after this, Groups 0-2 in tagInfo are guaranteed to be defined) 1308 2167 unless ($$tagInfo{GotGroups}) { 1309 2168 my $tagTablePtr = $$tagInfo{Table}; … … 1313 2172 # fill in default groups 1314 2173 foreach (keys %{$$tagTablePtr{GROUPS}}) { 1315 $$groups{$_} or $$groups{$_} = $tagTablePtr->{GROUPS} ->{$_};2174 $$groups{$_} or $$groups{$_} = $tagTablePtr->{GROUPS}{$_}; 1316 2175 } 1317 2176 } … … 1319 2178 $$tagInfo{GotGroups} = 1; 1320 2179 } 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 } 1324 2191 } else { 1325 2192 return $$groups{0} unless wantarray; 1326 2193 foreach (0..2) { $groups[$_] = $$groups{$_}; } 1327 2194 } 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}; 1335 2204 } 1336 2205 if ($family) { 1337 return $groups[ 1] if $family == 1;2206 return $groups[$family] || '' if $family > 0; 1338 2207 # add additional matching group names to list 1339 2208 # ie) for MIE-Doc, also add MIE1, MIE1-Doc, MIE-Doc1 and MIE1-Doc1 … … 1346 2215 } 1347 2216 } 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 } 1348 2229 return @groups; 1349 2230 } … … 1353 2234 # Inputs: 0) ExifTool object reference 1354 2235 # 1) [optional] information hash reference (default all extracted info) 1355 # 2) [optional] group family number(default 0)2236 # 2) [optional] group family (default 0) 1356 2237 # Returns: List of group names in alphabetical order 1357 2238 sub GetGroups($;$$) … … 1401 2282 1402 2283 #------------------------------------------------------------------------------ 1403 # Build composite tags from required tags2284 # Build Composite tags from Require'd/Desire'd tags 1404 2285 # Inputs: 0) ExifTool object reference 1405 2286 # 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 is2287 # or Desire's another Composite tag, in which case the calculation is 1407 2288 # deferred until after the other tag is calculated. 1408 2289 sub BuildCompositeTags($) … … 1411 2292 my $self = shift; 1412 2293 1413 # first, add user-defined composite tags if necessary 2294 $$self{BuildingComposite} = 1; 2295 # first, add user-defined Composite tags if necessary 1414 2296 if (%UserDefined and $UserDefined{'Image::ExifTool::Composite'}) { 1415 AddCompositeTags($UserDefined{'Image::ExifTool::Composite'}, 1);2297 AddCompositeTags($UserDefined{'Image::ExifTool::Composite'}, 1); 1416 2298 delete $UserDefined{'Image::ExifTool::Composite'}; 1417 2299 } … … 1422 2304 for (;;) { 1423 2305 my %notBuilt; 1424 foreach (@tagList) { 1425 $notBuilt{$_} = 1; 1426 } 2306 $notBuilt{$_} = 1 foreach @tagList; 1427 2307 my @deferredTags; 1428 2308 my $tag; … … 1433 2313 next unless $tagInfo; 1434 2314 # 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); 1438 2322 # 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 } 1442 2330 # allow tag group to be specified 1443 if ($reqTag =~ / (.+?):(.+)/) {2331 if ($reqTag =~ /^(.*):(.+)/) { 1444 2332 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; 1454 2336 } 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; 1455 2347 } elsif ($notBuilt{$reqTag}) { 1456 2348 # calculate this tag later if it relies on another … … 1461 2353 if (defined $$rawValue{$reqTag}) { 1462 2354 $found = 1; 1463 } els e{1464 # don't continue if we require this tag1465 $type eq 'Require' and next COMPOSITE_TAG;2355 } elsif ($$require{$index}) { 2356 $found = 0; 2357 last; # don't continue since we require this tag 1466 2358 } 1467 2359 $tagKey{$index} = $reqTag; 1468 2360 } 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 } 1489 2396 } 1490 2397 last unless @deferredTags; … … 1497 2404 @tagList = @deferredTags; # calculate deferred tags now 1498 2405 } 2406 delete $$self{BuildingComposite}; 1499 2407 } 1500 2408 … … 1522 2430 #------------------------------------------------------------------------------ 1523 2431 # 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 1527 2437 # context, may return more than one file type if the file may be 1528 # different formats. Returns list of all recognized extensions if no2438 # different formats. Returns list of all supported extensions if no 1529 2439 # file specified 1530 2440 sub GetFileType(;$$) … … 1532 2442 local $_; 1533 2443 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 } 1535 2457 my $fileType; 1536 2458 my $fileExt = GetFileExtension($file); 1537 2459 $fileExt = uc($file) unless $fileExt; 1538 2460 $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; 1540 2472 $fileType = $$fileType[0]; # get file type (or list of types) 1541 2473 if (wantarray) { 1542 return () unless $fileType;1543 2474 return @$fileType if ref $fileType eq 'ARRAY'; 1544 2475 } elsif ($fileType) { … … 1550 2481 #------------------------------------------------------------------------------ 1551 2482 # Return true if we can write the specified file type 1552 # Inputs: 0) file name or ext ,2483 # Inputs: 0) file name or ext 1553 2484 # 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 write1555 2485 sub CanWrite($) 1556 2486 { … … 1558 2488 my $file = shift or return undef; 1559 2489 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 } 1560 2495 return scalar(grep /^$type$/, @writeTypes); 1561 2496 } … … 1563 2498 #------------------------------------------------------------------------------ 1564 2499 # Return true if we can create the specified file type 1565 # Inputs: 0) file name or ext ,2500 # Inputs: 0) file name or ext 1566 2501 # Returns: true if creatable, 0 if not writable, undef if unrecognized 1567 2502 sub CanCreate($) … … 1569 2504 local $_; 1570 2505 my $file = shift or return undef; 2506 my $ext = GetFileExtension($file) || uc($file); 1571 2507 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; 1573 2510 } 1574 2511 … … 1590 2527 delete $self->{EXIF_POS}; # EXIF position in file 1591 2528 delete $self->{FIRST_EXIF_POS}; # position of first EXIF in file 1592 delete $self->{EXIF_BYTE_ORDER};# the EXIF byte ordering1593 2529 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 1594 2533 $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 1600 2541 $self->{PROCESSED} = { }; # hash of processed directory start positions 1601 2542 $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 1602 2546 $self->{NUM_FOUND} = 0; # total number of tags found (incl. duplicates) 1603 2547 $self->{CHANGED} = 0; # number of tags changed (writer only) 1604 2548 $self->{INDENT} = ' '; # initial indent for verbose messages 1605 2549 $self->{PRIORITY_DIR} = ''; # the priority directory name 2550 $self->{LOW_PRIORITY_DIR} = { PreviewIFD => 1 }; # names of priority 0 directories 1606 2551 $self->{TIFF_TYPE} = ''; # type of TIFF data (APP1, TIFF, NEF, etc...) 1607 $self->{ CameraMake}= ''; # camera make1608 $self->{ CameraModel}= ''; # camera model2552 $self->{Make} = ''; # camera make 2553 $self->{Model} = ''; # camera model 1609 2554 $self->{CameraType} = ''; # Olympus camera type 1610 2555 if ($self->Options('HtmlDump')) { … … 1613 2558 } 1614 2559 # 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}; 1616 2561 } 1617 2562 … … 1655 2600 undef @oldGroupOpts; 1656 2601 } 1657 $ options->{$opt} = $$arg{$opt};2602 $self->Options($opt, $$arg{$opt}); 1658 2603 $opt eq 'Exclude' and $wasExcludeOpt = 1; 1659 2604 } … … 1662 2607 # convert image data from UTF-8 to character stream if necessary 1663 2608 # (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); 1666 2614 $arg = \$buff; 1667 2615 } … … 1670 2618 # we have a file but we didn't open it 1671 2619 $self->{FILENAME} = ''; 2620 } elsif (UNIVERSAL::isa($arg, 'File::RandomAccess')) { 2621 $self->{RAF} = $arg; 2622 $self->{FILENAME} = ''; 1672 2623 } else { 1673 2624 warn "Don't understand ImageInfo argument $arg\n"; … … 1688 2639 # initialize lookup for requested tags 1689 2640 foreach (@{$self->{REQUESTED_TAGS}}) { 1690 $self->{REQ_TAG_LOOKUP} ->{lc(/.+?:(.+)/ ? $1 : $_)} = 1;2641 $self->{REQ_TAG_LOOKUP}{lc(/.+:(.+)/ ? $1 : $_)} = 1; 1691 2642 } 1692 2643 } … … 1703 2654 $options->{Exclude} = \@exclude; 1704 2655 # 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 2666 sub 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 1711 2704 # 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 1713 2707 sub SetFoundTags($) 1714 2708 { … … 1721 2715 my @groupOptions = sort grep /^Group/, keys %$options; 1722 2716 my $doDups = $duplicates || $exclude || @groupOptions; 1723 my ($tag, $rtnTags );2717 my ($tag, $rtnTags, @byValue); 1724 2718 1725 2719 # only return requested tags if specified … … 1730 2724 my $reqTag; 1731 2725 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 } 1737 2735 } else { 1738 2736 $tag = $reqTag; 1739 $family = -1;1740 }2737 } 2738 $byValue = 1 if $tag =~ s/#$//; 1741 2739 if (defined $tagHash->{$reqTag} and not $doDups) { 1742 2740 $matches[0] = $tag; … … 1750 2748 next unless @matches; # don't want entry in list for '*' tag 1751 2749 $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; 1752 2758 } elsif ($doDups or defined $group) { 1753 2759 # must also look for tags like "Tag (1)" 1754 @matches = grep(/^$tag( \s|$)/i, keys %$tagHash);1755 } els e{2760 @matches = grep(/^$tag( |$)/i, keys %$tagHash); 2761 } elsif ($tag =~ /^[-\w]+$/) { 1756 2762 # find first matching value 1757 2763 # (use in list context to return value instead of count) 1758 2764 ($matches[0]) = grep /^$tag$/i, keys %$tagHash; 1759 2765 defined $matches[0] or undef @matches; 2766 } else { 2767 $self->Warn("Invalid tag name '$tag'"); 1760 2768 } 1761 2769 if (defined $group and not $allGrp) { 1762 2770 # 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); 1770 2772 next unless @matches or not $allTag; 1771 2773 } … … 1776 2778 unless ($doDups or $allTag or $allGrp) { 1777 2779 $tag = shift @matches; 1778 my $oldPriority = $self->{PRIORITY} ->{$tag} || 1;2780 my $oldPriority = $self->{PRIORITY}{$tag} || 1; 1779 2781 foreach (@matches) { 1780 my $priority = $self->{PRIORITY} ->{$_};2782 my $priority = $self->{PRIORITY}{$_}; 1781 2783 $priority = 1 unless defined $priority; 1782 2784 next unless $priority >= $oldPriority; … … 1790 2792 $matches[0] = "$tag (0)"; 1791 2793 # 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; 1794 2798 push @$rtnTags, @matches; 1795 2799 } … … 1811 2815 while (($exclude or @groupOptions) and @$rtnTags) { 1812 2816 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; 1824 2830 } 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 } 1828 2849 last if $duplicates and not @groupOptions; 1829 2850 } … … 1834 2855 my $wantOrder = 0; 1835 2856 foreach $groupOpt (@groupOptions) { 1836 $groupOpt =~ /^Group(\d* )/ or next;2857 $groupOpt =~ /^Group(\d*(:\d+)*)/ or next; 1837 2858 $family = $1 || 0; 1838 2859 $wantGroup{$family} or $wantGroup{$family} = { }; … … 1856 2877 $allGroups = 0; # don't want all groups if we requested one 1857 2878 } 1858 $wantGroup{$family} ->{$groupName} = $want;2879 $wantGroup{$family}{$groupName} = $want; 1859 2880 } 1860 2881 } … … 1865 2886 foreach $family (keys %wantGroup) { 1866 2887 my $group = $self->GetGroup($tag, $family); 1867 my $wanted = $wantGroup{$family} ->{$group};2888 my $wanted = $wantGroup{$family}{$group}; 1868 2889 next unless defined $wanted; 1869 2890 next GR_TAG unless $wanted; # skip tag if group excluded … … 1903 2924 last; 1904 2925 } 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; 1908 2930 } 1909 2931 … … 1955 2977 my ($self, $str, $ignorable) = @_; 1956 2978 if ($ignorable) { 1957 return 0 if $self->{OPTIONS} ->{IgnoreMinorErrors};2979 return 0 if $self->{OPTIONS}{IgnoreMinorErrors}; 1958 2980 $str = "[minor] $str"; 1959 2981 } 1960 2982 $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 2990 sub 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 } 1961 2998 return 1; 1962 2999 } … … 1970 3007 my ($self, $str, $ignorable) = @_; 1971 3008 if ($ignorable) { 1972 if ($self->{OPTIONS} ->{IgnoreMinorErrors}) {3009 if ($self->{OPTIONS}{IgnoreMinorErrors}) { 1973 3010 $self->Warn($str); 1974 3011 return 0; … … 1982 3019 #------------------------------------------------------------------------------ 1983 3020 # 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 3024 sub ExpandShortcuts($;$) 3025 { 3026 my ($tagList, $removeSuffix) = @_; 3027 return unless $tagList and @$tagList; 1989 3028 1990 3029 require Image::ExifTool::Shortcuts; 1991 3030 1992 3031 # expand shortcuts 3032 my $suffix = $removeSuffix ? '' : '#'; 1993 3033 my @expandedTags; 1994 3034 my ($entry, $tag, $excl); 1995 3035 foreach $entry (@$tagList) { 3036 # skip things like options hash references in list 3037 if (ref $entry) { 3038 push @expandedTags, $entry; 3039 next; 3040 } 1996 3041 # remove leading '-' 1997 3042 ($excl, $tag) = $entry =~ /^(-?)(.*)/s; 1998 my ($post, @post );3043 my ($post, @post, $pre, $v); 1999 3044 # handle redirection 2000 if ( $tag =~ /(.+?)([-+]?[<>].+)/s and not $excl) {3045 if (not $excl and $tag =~ /(.+?)([-+]?[<>].+)/s) { 2001 3046 ($tag, $post) = ($1, $2); 2002 3047 if ($post =~ /^[-+]?>/ or $post !~ /\$/) { 2003 3048 # expand shortcuts in postfix (rhs of redirection) 2004 my ($op, $p2, $t2) = ($post =~ /([-+]?[<>])(.+ ?:)?(.+)/);3049 my ($op, $p2, $t2) = ($post =~ /([-+]?[<>])(.+:)?(.+)/); 2005 3050 $p2 = '' unless defined $p2; 3051 $v = ($t2 =~ s/#$//) ? $suffix : ''; # ValueConv suffix 2006 3052 my ($match) = grep /^\Q$t2\E$/i, keys %Image::ExifTool::Shortcuts::Main; 2007 3053 if ($match) { 2008 3054 foreach (@{$Image::ExifTool::Shortcuts::Main{$match}}) { 2009 3055 /^-/ and next; # ignore excluded tags 2010 if ($p2 and /(.+ ?:)(.+)/) {2011 push @post, "$op$_ ";3056 if ($p2 and /(.+:)(.+)/) { 3057 push @post, "$op$_$v"; 2012 3058 } else { 2013 push @post, "$op$p2$_ ";3059 push @post, "$op$p2$_$v"; 2014 3060 } 2015 3061 } … … 2022 3068 } 2023 3069 # handle group names 2024 my $pre; 2025 if ($tag =~ /(.+?:)(.+)/) { 3070 if ($tag =~ /(.+:)(.+)/) { 2026 3071 ($pre, $tag) = ($1, $2); 2027 3072 } else { 2028 3073 $pre = ''; 2029 3074 } 3075 $v = ($tag =~ s/#$//) ? $suffix : ''; # ValueConv suffix 2030 3076 # loop over all postfixes 2031 3077 for (;;) { … … 2038 3084 /^-/ and next; # ignore excluded exclude tags 2039 3085 # group of expanded tag takes precedence 2040 if ($pre and /(.+ ?:)(.+)/) {3086 if ($pre and /(.+:)(.+)/) { 2041 3087 push @expandedTags, "$excl$_"; 2042 3088 } else { … … 2044 3090 } 2045 3091 } 2046 } elsif (length $pre or length $post ) {3092 } elsif (length $pre or length $post or $v) { 2047 3093 foreach (@{$Image::ExifTool::Shortcuts::Main{$match}}) { 2048 /(-?)(.+ ?:)?(.+)/;3094 /(-?)(.+:)?(.+)/; 2049 3095 if ($2) { 2050 3096 # group from expanded tag takes precedence 2051 push @expandedTags, "$_$ post";3097 push @expandedTags, "$_$v$post"; 2052 3098 } else { 2053 push @expandedTags, "$1$pre$3$ post";3099 push @expandedTags, "$1$pre$3$v$post"; 2054 3100 } 2055 3101 } … … 2058 3104 } 2059 3105 } else { 2060 push @expandedTags, "$excl$pre$tag$ post";3106 push @expandedTags, "$excl$pre$tag$v$post"; 2061 3107 } 2062 3108 last unless @post; … … 2068 3114 2069 3115 #------------------------------------------------------------------------------ 2070 # Add hash of composite tags to our composites2071 # 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, 2072 3118 # 1) overwrite existing tag 2073 3119 sub AddCompositeTags($;$) … … 2092 3138 $defaultGroups = $$add{GROUPS} = { 0 => 'Composite', 1 => 'Composite', 2 => 'Other' }; 2093 3139 } 2094 SetupTagTable($add); 3140 SetupTagTable($add); # generate tag Name, etc 2095 3141 my $tagID; 2096 foreach $tagID ( keys %$add) {3142 foreach $tagID (sort keys %$add) { 2097 3143 next if $specialTags{$tagID}; # must skip special tags 2098 3144 my $tagInfo = $$add{$tagID}; … … 2100 3146 my $tag = $$tagInfo{Name}; 2101 3147 $$tagInfo{Module} = $module if $$tagInfo{Writable}; 2102 # allow composite tags with the same name3148 # allow Composite tags with the same name 2103 3149 my ($t, $n, $type); 2104 3150 while ($Image::ExifTool::Composite{$tag} and not $overwrite) { 2105 $n ? $n += 1 : $n = 2, $t = $tag;3151 $n ? $n += 1 : ($n = 2, $t = $tag); 2106 3152 $tag = "${t}_$n"; 3153 $$tagInfo{NewTagID} = $tag; # save new ID so we can use it in TagLookup 2107 3154 } 2108 3155 # convert scalar Require/Desire entries … … 2111 3158 $$tagInfo{$type} = { 0 => $req } if ref($req) ne 'HASH'; 2112 3159 } 2113 # add this composite tag to our main composite table3160 # add this Composite tag to our main Composite table 2114 3161 $$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 2115 3165 $Image::ExifTool::Composite{$tag} = $tagInfo; 2116 3166 # set all default groups in tag … … 2127 3177 2128 3178 #------------------------------------------------------------------------------ 3179 # Add tags to TagLookup (used for writing) 3180 # Inputs: 0) source hash of tag definitions, 1) name of destination tag table 3181 sub 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 #------------------------------------------------------------------------------ 2129 3195 # Expand tagInfo Flags 2130 3196 # Inputs: 0) tagInfo hash ref … … 2152 3218 # Inputs: 0) Reference to tag table 2153 3219 # Notes: - generates 'Name' field from key if it doesn't exist 2154 # - stores 'Table' pointer 3220 # - stores 'Table' pointer and 'TagID' value 2155 3221 # - expands 'Flags' for quick lookup 2156 3222 sub SetupTagTable($) 2157 3223 { 2158 3224 my $tagTablePtr = shift; 2159 my $tagID;3225 my ($tagID, $tagInfo); 2160 3226 foreach $tagID (TagTableKeys($tagTablePtr)) { 2161 3227 my @infoArray = GetTagInfoList($tagTablePtr,$tagID); 2162 3228 # process conditional tagInfo arrays 2163 my $tagInfo;2164 3229 foreach $tagInfo (@infoArray) { 2165 3230 $$tagInfo{Table} = $tagTablePtr; 3231 $$tagInfo{TagID} = $tagID; 2166 3232 my $tag = $$tagInfo{Name}; 2167 3233 unless (defined $tag) { … … 2172 3238 $$tagInfo{Flags} and ExpandFlags($tagInfo); 2173 3239 } 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 } 2174 3246 } 2175 3247 } … … 2180 3252 # Notes: May change commas to decimals in floats for use in other locales 2181 3253 sub IsFloat($) { 2182 return 1 if $_[0] =~ /^ ([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;3254 return 1 if $_[0] =~ /^[+-]?(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/; 2183 3255 # 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+))?$/; 2185 3257 $_[0] =~ tr/,/./; # but translate ',' to '.' 2186 3258 return 1; 2187 3259 } 2188 sub IsInt($) { return scalar($_[0] =~ /^[+-]?\d+$/); } 2189 sub IsHex($) { return scalar($_[0] =~ /^(0x)?[0-9a-f]{1,8}$/i); } 3260 sub IsInt($) { return scalar($_[0] =~ /^[+-]?\d+$/); } 3261 sub IsHex($) { return scalar($_[0] =~ /^(0x)?[0-9a-f]{1,8}$/i); } 3262 sub IsRational($) { return scalar($_[0] =~ m{^[-+]?\d+/\d+$}); } 2190 3263 2191 3264 # round floating point value to specified number of significant digits … … 2201 3274 } 2202 3275 3276 # Convert strings to floating point numbers (or undef) 3277 # Inputs: 0-N) list of strings (may be undef) 3278 # Returns: last value converted 3279 sub 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 2203 3290 #------------------------------------------------------------------------------ 2204 3291 # Utility routines to for reading binary data values from file 2205 3292 2206 my $swapBytes; # set if EXIF header is not native byte ordering2207 my $swapWords; # swap 32-bit words in doubles (ARM quirk)2208 my $currentByteOrder = 'MM'; # current byte ordering ('II' or 'MM')2209 3293 my %unpackMotorola = ( S => 'n', L => 'N', C => 'C', c => 'c' ); 2210 3294 my %unpackIntel = ( S => 'v', L => 'V', C => 'C', c => 'c' ); 2211 my %unpackStd = %unpackMotorola; 3295 my %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; 2212 3304 2213 3305 # Swap bytes in data if necessary … … 2240 3332 return unpack($unpackStd{$_[0]}, ${$_[1]}); 2241 3333 } 3334 # same, but with reversed byte order 3335 sub DoUnpackRev(@) 3336 { 3337 my $fmt = $unpackRev{$unpackStd{$_[0]}}; 3338 $_[2] and return unpack("x$_[2] $fmt", ${$_[1]}); 3339 return unpack($fmt, ${$_[1]}); 3340 } 2242 3341 # Pack value 2243 3342 # Inputs: 0) template, 1) value, 2) data ref (or undef), 3) offset (if data ref) … … 2246 3345 { 2247 3346 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 3351 sub DoPackRev(@) 3352 { 3353 my $val = pack($unpackRev{$unpackStd{$_[0]}}, $_[1]); 2248 3354 $_[2] and substr(${$_[2]}, $_[3], length($val)) = $val; 2249 3355 return $val; … … 2289 3395 sub GetFloat($$) { return DoUnpack(4, 'f', @_); } 2290 3396 sub GetDouble($$) { return DoUnpackDbl('d', @_); } 2291 3397 sub Get16uRev($$) { return DoUnpackRev('S', @_); } 3398 3399 # rationals may be a floating point number, 'inf' or 'undef' 2292 3400 sub GetRational32s($$) 2293 3401 { 2294 3402 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'; 2296 3405 # round off to a reasonable number of significant figures 2297 return RoundFloat( Get16s($dataPt,$pos)/ $denom, 7);3406 return RoundFloat($numer / $denom, 7); 2298 3407 } 2299 3408 sub GetRational32u($$) 2300 3409 { 2301 3410 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); 2304 3414 } 2305 3415 sub GetRational64s($$) 2306 3416 { 2307 3417 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); 2310 3421 } 2311 3422 sub GetRational64u($$) 2312 3423 { 2313 3424 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); 2316 3428 } 2317 3429 sub GetFixed16s($$) … … 2344 3456 sub Set16u(@) { return DoPackStd('S', @_); } 2345 3457 sub Set32u(@) { return DoPackStd('L', @_); } 3458 sub Set16uRev(@) { return DoPackRev('S', @_); } 2346 3459 2347 3460 #------------------------------------------------------------------------------ … … 2351 3464 #------------------------------------------------------------------------------ 2352 3465 # Set byte ordering 2353 # Inputs: 0) ' II'=intel, 'MM'=motorola3466 # Inputs: 0) 'MM'=motorola, 'II'=intel (will translate 'BigEndian', 'LittleEndian') 2354 3467 # Returns: 1 on success 2355 3468 sub SetByteOrder($) … … 2360 3473 %unpackStd = %unpackMotorola; 2361 3474 } 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'; 2362 3481 %unpackStd = %unpackIntel; 2363 3482 } else { … … 2402 3521 int16s => 2, 2403 3522 int16u => 2, 3523 int16uRev => 2, 2404 3524 int32s => 4, 2405 3525 int32u => 4, … … 2417 3537 double => 8, 2418 3538 extended => 10, 3539 unicode => 2, 3540 complex => 8, 2419 3541 string => 1, 2420 3542 binary => 1, 2421 3543 'undef' => 1, 2422 3544 ifd => 4, 2423 ifd 8=> 8,3545 ifd64 => 8, 2424 3546 ); 2425 3547 my %readValueProc = ( … … 2428 3550 int16s => \&Get16s, 2429 3551 int16u => \&Get16u, 3552 int16uRev => \&Get16uRev, 2430 3553 int32s => \&Get32s, 2431 3554 int32u => \&Get32u, … … 2444 3567 extended => \&GetExtended, 2445 3568 ifd => \&Get32u, 2446 ifd 8=> \&Get64u,3569 ifd64 => \&Get64u, 2447 3570 ); 2448 3571 sub FormatSize($) { return $formatSize{$_[0]}; } … … 2482 3605 } 2483 3606 } 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); 2486 3609 # truncate string at null terminator if necessary 2487 3610 $vals[0] =~ s/\0.*//s if $format eq 'string'; 2488 3611 } 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) 3627 sub 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 } 2508 3649 } 2509 3650 return $val; … … 2511 3652 2512 3653 #------------------------------------------------------------------------------ 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 3658 sub Encode($$$;$) 3659 { 3660 my ($self, $val, $to, $toOrder) = @_; 3661 return $self->Decode($val, undef, undef, $to, $toOrder); 2524 3662 } 2525 3663 … … 2554 3692 #------------------------------------------------------------------------------ 2555 3693 # 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 2557 3695 # Returns: image reference or undef if it wasn't valid 3696 # Note: should be called from RawConv, not ValueConv 2558 3697 sub ValidateImage($$$) 2559 3698 { … … 2563 3702 # the first byte of the preview of some Minolta cameras is wrong, 2564 3703 # so check for this and set it back to 0xff if necessary 2565 $$imagePt =~ s/^.(\xd8\xff\xdb)/\xff$1/ or3704 $$imagePt =~ s/^.(\xd8\xff\xdb)/\xff$1/s or 2566 3705 $self->Options('IgnoreMinorErrors')) 2567 3706 { 2568 3707 # 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)}) { 2570 3709 $self->Warn("$tag is not a valid JPEG image",1); 2571 3710 return undef; … … 2584 3723 # start with the tag name and force first letter to be upper case 2585 3724 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; 2587 3729 # put a space between lower/UPPER case and lower/number combinations 2588 3730 $desc =~ s/([a-z])([A-Z\d])/$1 $2/g; … … 2591 3733 # put spaces after numbers (if more than one character following number) 2592 3734 $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 2595 3736 $desc .= ' ' . $tagID if defined $tagID; 2596 3737 return $desc; … … 2600 3741 # Return printable value 2601 3742 # Inputs: 0) ExifTool object reference 2602 # 1) value to print, 2) true for unlimited line length3743 # 1) value to print, 2) line length limit (undef defaults to 60, 0=unlimited) 2603 3744 sub Printable($;$) 2604 3745 { 2605 my ($self, $outStr, $ unlimited) = @_;3746 my ($self, $outStr, $maxLen) = @_; 2606 3747 return '(undef)' unless defined $outStr; 2607 3748 $outStr =~ tr/\x01-\x1f\x7f-\xff/./; 2608 3749 $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]'; 2612 3759 } 2613 3760 return $outStr; … … 2621 3768 { 2622 3769 my ($self, $date) = @_; 2623 my $dateFormat = $self->{OPTIONS} ->{DateFormat};3770 my $dateFormat = $self->{OPTIONS}{DateFormat}; 2624 3771 # only convert date if a format was specified and the date is recognizable 2625 3772 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}) { 2629 3783 undef $date; 2630 3784 } … … 2634 3788 2635 3789 #------------------------------------------------------------------------------ 3790 # Print conversion for time span value 3791 # Inputs: 0) time ticks, 1) number of seconds per tick (default 1) 3792 # Returns: readable time 3793 sub 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 3817 sub 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 3834 sub 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") 3853 sub 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 #------------------------------------------------------------------------------ 2636 3867 # 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 2639 3871 sub ConvertUnixTime($;$) 2640 3872 { 2641 my $time = shift;3873 my ($time, $toLocal) = @_; 2642 3874 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 2652 3892 sub GetUnixTime($;$) 2653 3893 { 2654 my $timeStr = shift;3894 my ($timeStr, $isLocal) = @_; 2655 3895 return 0 if $timeStr eq '0000:00:00 00:00:00'; 2656 3896 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 } 2659 3906 $tm[0] -= 1900; # convert year 2660 3907 $tm[1] -= 1; # convert month 2661 3908 @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 3916 sub 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" 3930 sub 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 3949 sub 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 } 2663 3960 } 2664 3961 … … 2667 3964 # Inputs: 0) ExifTool hash ref, 1) start offset, 2) data size 2668 3965 # 3) comment string, 4) tool tip (or SAME), 5) flags 2669 sub H tmlDump($$$$;$$)3966 sub HDump($$$$;$$) 2670 3967 { 2671 3968 my $self = shift; … … 2752 4049 2753 4050 #------------------------------------------------------------------------------ 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 4060 sub 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 #------------------------------------------------------------------------------ 2754 4141 # Extract EXIF information from a jpg image 2755 4142 # Inputs: 0) ExifTool object reference, 1) dirInfo ref with RAF set … … 2757 4144 sub ProcessJPEG($$) 2758 4145 { 4146 local $_; 2759 4147 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}; 2763 4152 my $raf = $$dirInfo{RAF}; 2764 4153 my $htmlDump = $self->{HTML_DUMP}; 2765 4154 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); 2767 4157 2768 4158 # check to be sure this is a valid JPG file 2769 4159 return 0 unless $raf->Read($s, 2) == 2 and $s eq "\xff\xd8"; 2770 4160 $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 } 2772 4165 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; 2777 4173 2778 4174 # 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); 2783 4178 2784 4179 # read file until we reach an end of image (EOI) or start of scan (SOS) … … 2793 4188 # read ahead to the next segment unless we have reached EOI or SOS 2794 4189 # 2795 unless ($marker and ($marker==0xd9 or ($marker==0xda and not $want Preview))) {4190 unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer))) { 2796 4191 # read up to next marker (JPEG markers begin with 0xff) 2797 4192 my $buff; … … 2821 4216 } 2822 4217 # set some useful variables for the current segment 2823 my $hdr = "\xff" . chr($marker); # header for this segment2824 4218 my $markerName = JpegMarkerName($marker); 4219 $$path[$pn] = $markerName; 2825 4220 # 2826 4221 # parse the current segment … … 2845 4240 my ($i, $hmin, $hmax, $vmin, $vmax); 2846 4241 # loop through all components to determine sampling frequency 4242 $subSampling = ''; 2847 4243 for ($i=0; $i<$n; ++$i) { 2848 4244 my $sf = Get8u($segDataPt, 7 + 3 * $i); 4245 $subSampling .= sprintf('%.2x', $sf); 2849 4246 # isolate horizontal and vertical components 2850 4247 my ($hf, $vf) = ($sf >> 4, $sf & 0x0f); … … 2866 4263 next; 2867 4264 } elsif ($marker == 0xd9) { # EOI 4265 pop @$path; 2868 4266 $verbose and print $out "JPEG EOI\n"; 2869 4267 my $pos = $raf->Tell(); 2870 4268 if ($htmlDump and $dumpEnd) { 2871 $self->H tmlDump($dumpEnd, $pos-2-$dumpEnd, '[JPEG Image Data]', undef, 0x08);2872 $self->H tmlDump($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); 2873 4271 $dumpEnd = 0; 2874 4272 } 2875 4273 $success = 1; 2876 4274 # 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 } 2890 4302 } 2891 $ self->{VALUE}->{PreviewImageStart} = $actual;4303 $raf->Seek($pos, 0); 2892 4304 } 2893 $raf->Seek($pos, 0);2894 4305 } 2895 4306 # process trailer now or finish processing trailers … … 2903 4314 undef $trailInfo; 2904 4315 } 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 } 2905 4322 # finally, dump remaining information in JPEG trailer 2906 4323 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 } 2909 4329 $self->DumpUnknownTrailer({ 2910 4330 RAF => $raf, … … 2915 4335 last; # all done parsing file 2916 4336 } elsif ($marker == 0xda) { # SOS 4337 pop @$path; 2917 4338 # all done with meta information unless we have a trailer 2918 4339 $verbose and print $out "JPEG SOS\n"; 2919 unless ($ self->Options('FastScan')) {4340 unless ($fast) { 2920 4341 $trailInfo = IdentifyTrailer($raf); 2921 4342 # process trailer now unless we are doing verbose dump … … 2925 4346 $self->ProcessTrailers($trailInfo) and undef $trailInfo; 2926 4347 } 2927 if ($want Preview) {4348 if ($wantTrailer) { 2928 4349 # seek ahead and validate preview image 2929 4350 my $buff; 2930 4351 my $curPos = $raf->Tell(); 2931 if ($raf->Seek($ self->GetValue('PreviewImageStart'), 0) and4352 if ($raf->Seek($$self{PreviewImageStart}, 0) and 2932 4353 $raf->Read($buff, 4) == 4 and 2933 4354 $buff =~ /^.\xd8\xff[\xc4\xdb\xe0-\xef]/) 2934 4355 { 2935 undef $want Preview;4356 undef $wantTrailer; 2936 4357 } 2937 4358 $raf->Seek($curPos, 0) or last; 2938 4359 } 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; 2940 4367 } 2941 4368 # nothing interesting to parse after start of scan (SOS) … … 2946 4373 $verbose and $marker and print $out "JPEG $markerName:\n"; 2947 4374 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 2948 4381 } 2949 4382 # handle all other markers … … 2958 4391 } 2959 4392 } 2960 if ($marker == 0xe0) { # APP0 (JFIF, CIFF)4393 if ($marker == 0xe0) { # APP0 (JFIF, JFXX, CIFF, AVI1, Ocad) 2961 4394 if ($$segDataPt =~ /^JFIF\0/) { 2962 4395 $dumpType = 'JFIF'; … … 2976 4409 $self->FoundTag($tagInfo, substr($$segDataPt, 6)); 2977 4410 } elsif ($$segDataPt =~ /^(II|MM).{4}HEAPJPGM/s) { 4411 next if $fast and $fast > 1; # skip processing for very fast 2978 4412 $dumpType = 'CIFF'; 2979 4413 my %dirInfo = ( … … 2984 4418 Image::ExifTool::CanonRaw::ProcessCRW($self, \%dirInfo); 2985 4419 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) 2988 4433 if ($$segDataPt =~ /^Exif\0/) { # (some Kodak cameras don't put a second \0) 2989 4434 undef $dumpType; # (will be dumped here) … … 2999 4444 ); 3000 4445 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'); 3005 4448 $dumpEnd = $segPos + $length; 3006 4449 } … … 3012 4455 my $start = $self->GetValue('PreviewImageStart'); 3013 4456 my $length = $self->GetValue('PreviewImageLength'); 4457 if (not $start or not $length and $$self{PreviewError}) { 4458 $start = $$self{PreviewImageStart}; 4459 $length = $$self{PreviewImageLength}; 4460 } 3014 4461 if ($start and $length and 3015 4462 $start + $length > $self->{EXIF_POS} + length($self->{EXIF_DATA}) and 3016 $self->{REQ_TAG_LOOKUP} ->{previewimage})4463 $self->{REQ_TAG_LOOKUP}{previewimage}) 3017 4464 { 3018 $wantPreview = 1; 4465 $$self{PreviewImageStart} = $start; 4466 $$self{PreviewImageLength} = $length; 4467 $wantTrailer = 1; 3019 4468 } 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); 3020 4519 } else { 3021 4520 # Hmmm. Could be XMP, let's see … … 3023 4522 if ($$segDataPt =~ /^http/ or $$segDataPt =~ /<exif:/) { 3024 4523 $dumpType = 'XMP'; 4524 # also try to parse XMP with a non-standard header 4525 # (note: this non-standard XMP is ignored when writing) 3025 4526 my $start = ($$segDataPt =~ /^$xmpAPP1hdr/) ? length($xmpAPP1hdr) : 0; 3026 4527 my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main'); … … 3035 4536 ); 3036 4537 $processed = $self->ProcessDirectory(\%dirInfo, $tagTablePtr); 4538 if ($processed and not $start) { 4539 $self->Warn('Non-standard header for APP1 XMP segment'); 4540 } 3037 4541 } 3038 4542 if ($verbose and not $processed) { … … 3040 4544 } 3041 4545 } 3042 } elsif ($marker == 0xe2) { # APP2 (ICC Profile, FPXR )4546 } elsif ($marker == 0xe2) { # APP2 (ICC Profile, FPXR, MPF, PreviewImage) 3043 4547 if ($$segDataPt =~ /^ICC_PROFILE\0/) { 3044 4548 $dumpType = 'ICC_Profile'; … … 3064 4568 } 3065 4569 } elsif ($$segDataPt =~ /^FPXR\0/) { 4570 next if $fast and $fast > 1; # skip processing for very fast 3066 4571 $dumpType = 'FPXR'; 3067 4572 my $tagTablePtr = GetTagTable('Image::ExifTool::FlashPix::Main'); … … 3077 4582 ); 3078 4583 $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) 3081 4614 if ($$segDataPt =~ /^(Meta|META|Exif)\0\0/) { 3082 4615 undef $dumpType; # (will be dumped here) … … 3089 4622 ); 3090 4623 if ($htmlDump) { 3091 $self->H tmlDump($segPos-4, 10, 'APP3 Meta header');4624 $self->HDump($segPos-4, 10, 'APP3 Meta header'); 3092 4625 $dumpEnd = $segPos + $length; 3093 4626 } 3094 4627 my $tagTablePtr = GetTagTable('Image::ExifTool::Kodak::Meta'); 3095 4628 $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 } 3096 4697 } 3097 4698 } elsif ($marker == 0xe5) { # APP5 (Ricoh "RMETA") … … 3108 4709 $self->ProcessDirectory(\%dirInfo, $tagTablePtr); 3109 4710 } 3110 } elsif ($marker == 0xe6) { # APP6 (Toshiba EPPIM )4711 } elsif ($marker == 0xe6) { # APP6 (Toshiba EPPIM, NITF, HP_TDHD) 3111 4712 if ($$segDataPt =~ /^EPPIM\0/) { 3112 4713 undef $dumpType; # (will be dumped here) … … 3119 4720 ); 3120 4721 if ($htmlDump) { 3121 $self->H tmlDump($segPos-4, 10, 'APP6 EPPIM header');4722 $self->HDump($segPos-4, 10, 'APP6 EPPIM header'); 3122 4723 $dumpEnd = $segPos + $length; 3123 4724 } 3124 4725 my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::EPPIM'); 3125 4726 $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); 3126 4749 } 3127 4750 } elsif ($marker == 0xe8) { # APP8 (SPIFF) … … 3141 4764 if ($$segDataPt =~ /^UNICODE\0/) { 3142 4765 $dumpType = 'PhotoStudio'; 3143 my $comment = $self-> Unicode2Charset(substr($$segDataPt,8), 'MM');4766 my $comment = $self->Decode(substr($$segDataPt,8), 'UCS2', 'MM'); 3144 4767 $self->FoundTag('Comment', $comment); 3145 4768 } … … 3165 4788 $dumpType = 'Photoshop'; 3166 4789 # add this data to the combined data if it exists 4790 my $dataPt = $segDataPt; 3167 4791 if (defined $combinedSegData) { 3168 4792 $combinedSegData .= substr($$segDataPt,length($psAPP13hdr)); 3169 $segDataPt = \$combinedSegData; 3170 $length = length $combinedSegData; # update length 4793 $dataPt = \$combinedSegData; 3171 4794 } 3172 4795 # peek ahead to see if the next segment is photoshop data too … … 3174 4797 # initialize combined data if necessary 3175 4798 $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; 3177 4814 } 3178 my $hdrlen = $isOld ? 27 : 14;3179 # process APP13 Photoshop record3180 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 identifier3186 DirLen => $length - $hdrlen,3187 Parent => $markerName,3188 );3189 $self->ProcessDirectory(\%dirInfo, $tagTablePtr);3190 undef $combinedSegData;3191 4815 } elsif ($$segDataPt =~ /^Adobe_CM/) { 3192 4816 $dumpType = 'Adobe_CM'; … … 3222 4846 } elsif ($marker == 0xfe) { # COM (JPEG comment) 3223 4847 $dumpType = 'Comment'; 4848 $$segDataPt =~ s/\0+$//; # some dumb softwares add null terminators 3224 4849 $self->FoundTag('Comment', $$segDataPt); 3225 4850 } elsif (($marker & 0xf0) != 0xe0) { … … 3227 4852 } 3228 4853 if (defined $dumpType) { 3229 if (not $dumpType and $self->{OPTIONS} ->{Unknown}) {4854 if (not $dumpType and $self->{OPTIONS}{Unknown}) { 3230 4855 $self->Warn("Unknown $markerName segment", 1); 3231 4856 } 3232 4857 if ($htmlDump) { 3233 4858 my $desc = $markerName . ($dumpType ? " $dumpType" : '') . ' segment'; 3234 $self->H tmlDump($segPos-4, $length+4, $desc, undef, 0x08);4859 $self->HDump($segPos-4, $length+4, $desc, undef, 0x08); 3235 4860 $dumpEnd = $segPos + $length; 3236 4861 } … … 3238 4863 undef $$segDataPt; 3239 4864 } 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; 3241 4872 $success or $self->Warn('JPEG format error'); 4873 pop @$path if @$path > $pn; 3242 4874 return 1; 3243 4875 } 3244 4876 3245 4877 #------------------------------------------------------------------------------ 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 4880 sub 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 3249 4889 # Returns: 1 if this looked like a valid EXIF block, 0 otherwise, or -1 on write error 3250 4890 sub 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 4908 sub DoProcessTIFF($$;$) 3251 4909 { 3252 4910 my ($self, $dirInfo, $tagTablePtr) = @_; … … 3256 4914 my $base = $$dirInfo{Base} || 0; 3257 4915 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} = ''; 3261 4920 if ($raf) { 3262 4921 if ($outfile) { … … 3269 4928 $raf->Seek($base, 0) or return 0; 3270 4929 } 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) { 3273 4947 # save a copy of the EXIF data 3274 4948 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; 3276 4952 } 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 3279 4954 } else { 3280 4955 $self->{EXIF_DATA} = ''; 3281 4956 } 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 } 3282 4965 $$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}; 3284 4967 $dataPt = \$self->{EXIF_DATA}; 3285 4968 3286 4969 # 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; 3290 4972 3291 4973 # verify the byte ordering 3292 4974 my $identifier = Get16u($dataPt, 2); 3293 4975 # 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????) 3295 4978 # return 0 unless $identifier == 0x2a; 3296 4979 … … 3305 4988 $raf->Read($canonSig, 8) == 8 or return 0; 3306 4989 $$dataPt .= $canonSig; 3307 if ($canonSig =~ /^ CR\x02\0/) {3308 $fileType = 'CR2';3309 $self->H tmlDump($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}; 3310 4993 } else { 3311 4994 undef $canonSig; 3312 4995 } 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'); 3316 5010 } elsif ($identifier == 0x2b and $fileType eq 'TIFF') { 3317 5011 # this looks like a BigTIFF image … … 3319 5013 require Image::ExifTool::BigTIFF; 3320 5014 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'; 3323 5025 } 3324 5026 # 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 } 3330 5041 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->H tmlDump($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); 3334 5045 } 3335 5046 # remember where we found the TIFF data (APP1, APP3, TIFF, NEF, etc...) … … 3346 5057 DataPos => 0, 3347 5058 DirStart => $offset, 3348 DirLen => length $$dataPt,5059 DirLen => length($$dataPt) - $offset, 3349 5060 RAF => $raf, 3350 DirName => 'IFD0',5061 DirName => $ifdName, 3351 5062 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}, 3353 5065 ); 3354 5066 … … 3358 5070 $self->ProcessDirectory(\%dirInfo, $tagTablePtr); 3359 5071 # process GeoTiff information if available 3360 if ($self->{VALUE} ->{GeoTiffDirectory}) {5072 if ($self->{VALUE}{GeoTiffDirectory}) { 3361 5073 require Image::ExifTool::GeoTiff; 3362 5074 Image::ExifTool::GeoTiff::ProcessGeoTiff($self); … … 3369 5081 $self->ProcessTrailers($trailInfo); 3370 5082 } 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'); 3371 5096 } 3372 5097 return 1; … … 3388 5113 Image::ExifTool::CanonRaw::WriteCR2($self, \%dirInfo, $tagTablePtr) or $err = 1; 3389 5114 } 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; 3392 5122 # preserve padding between image data blocks in ORF images 3393 5123 # (otherwise dcraw has problems because it assumes fixed block spacing) … … 3397 5127 $err = 1; 3398 5128 } 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 } 3402 5147 undef $newData; # free memory 3403 5148 } … … 3408 5153 } 3409 5154 } 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 3410 5159 # rewrite trailers if they exist 3411 if ($raf and $ self->{TIFF_END}and not $err) {5160 if ($raf and $tiffEnd and not $err) { 3412 5161 my ($buf, $trailInfo); 3413 5162 $raf->Seek(0, 2) or $err = 1; 3414 my $extra = $raf->Tell() - $ self->{TIFF_END};5163 my $extra = $raf->Tell() - $tiffEnd; 3415 5164 # check for trailer and process if possible 3416 5165 for (;;) { 3417 5166 last unless $extra > 12; 3418 $raf->Seek($ self->{TIFF_END}); # seek back to end of image5167 $raf->Seek($tiffEnd); # seek back to end of image 3419 5168 $trailInfo = IdentifyTrailer($raf); 3420 5169 last unless $trailInfo; … … 3429 5178 } 3430 5179 # calculate unused bytes before trailer 3431 $extra = $$trailInfo{DataPos} - $ self->{TIFF_END};5180 $extra = $$trailInfo{DataPos} - $tiffEnd; 3432 5181 last; # yes, the 'for' loop was just a cheap 'goto' 3433 5182 } 3434 5183 # 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; 3439 5186 $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; 3441 5188 } 3442 5189 if ($extra > 0) { 3443 if ($self->{DEL_GROUP}->{Trailer}) { 5190 my $known = $$self{KnownTrailer}; 5191 if ($self->{DEL_GROUP}{Trailer} and not $known) { 3444 5192 $self->VPrint(0, " Deleting unknown trailer ($extra bytes)\n"); 3445 5193 ++$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; 3446 5198 } 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; 3451 5205 $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; 3454 5218 } 3455 5219 } … … 3461 5225 Write($outfile, $$trailPt) or $err = 1 if $trailPt; 3462 5226 } 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 } 3464 5236 return $err ? -1 : 1; 3465 5237 } … … 3495 5267 { 3496 5268 my $tableName = shift or return undef; 3497 3498 5269 my $table = $allTables{$tableName}; 3499 5270 … … 3504 5275 if ($tableName =~ /(.*)::/) { 3505 5276 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 { 3507 5283 $@ and warn $@; 3508 5284 } … … 3516 5292 $table = \%$tableName; 3517 5293 use strict 'refs'; 5294 $$table{TABLE_NAME} = $tableName; # set table name 5295 ($$table{SHORT_NAME} = $tableName) =~ s/^Image::ExifTool:://; 3518 5296 # set default group 0 and 1 from module name unless already specified 3519 5297 my $defaultGroups = $$table{GROUPS}; … … 3529 5307 } 3530 5308 $$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 } 3531 5318 # generate a tag prefix for unknown tags if necessary 3532 5319 unless ($$table{TAG_PREFIX}) { … … 3545 5332 my $tagID; 3546 5333 foreach $tagID (TagTableKeys($UserDefined{$tableName})) { 3547 my $tagInfo = $UserDefined{$tableName} ->{$tagID};5334 my $tagInfo = $UserDefined{$tableName}{$tagID}; 3548 5335 if (ref $tagInfo eq 'HASH') { 3549 5336 $$tagInfo{Name} or $$tagInfo{Name} = ucfirst($tagID); … … 3560 5347 } 3561 5348 } 3562 # generate tag ID's if necessary3563 GenerateTagIDs($table) if $didTagID;3564 5349 # remember order we loaded the tables in 3565 5350 push @tableOrder, $tableName; … … 3577 5362 sub ProcessDirectory($$$;$) 3578 5363 { 3579 my ($self, $dirInfo, $tagTablePtr, $proc essProc) = @_;5364 my ($self, $dirInfo, $tagTablePtr, $proc) = @_; 3580 5365 3581 5366 return 0 unless $tagTablePtr and $dirInfo; 3582 # use default proc from tag table if no proc specified3583 $proc essProc 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; 3584 5369 # 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}; 3586 5371 # guard against cyclical recursion into the same directory 3587 5372 if (defined $$dirInfo{DirStart} and defined $$dirInfo{DataPos}) { 3588 5373 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"); 3591 5376 return 0; 3592 5377 } 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 } 3597 5380 my $oldOrder = GetByteOrder(); 3598 5381 my $oldIndent = $self->{INDENT}; 3599 5382 my $oldDir = $self->{DIR_NAME}; 5383 $self->{LIST_TAGS} = { }; # don't build lists across different directories 3600 5384 $self->{INDENT} .= '| '; 3601 5385 $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}}; 3603 5392 $self->{INDENT} = $oldIndent; 3604 5393 $self->{DIR_NAME} = $oldDir; … … 3608 5397 3609 5398 #------------------------------------------------------------------------------ 5399 # Get Metadata path 5400 # Inputs: 0) Exiftool object ref 5401 # Return: Metadata path string 5402 sub MetadataPath($) 5403 { 5404 my $self = shift; 5405 return join '-', @{$$self{PATH}} 5406 } 5407 5408 #------------------------------------------------------------------------------ 3610 5409 # Get standardized file extension 3611 5410 # Inputs: 0) file name 3612 # Returns: standardized extension (all uppercase) 5411 # Returns: standardized extension (all uppercase), or undefined if no extension 3613 5412 sub GetFileExtension($) 3614 5413 { … … 3669 5468 return '' if $condition =~ /\$(valPt|format|count)\b/ and not defined $valPt; 3670 5469 # 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]) 3673 5473 unless (eval $condition) { 3674 $@ and warn "Condition $$tagInfo{Name}: $@"; 5474 $@ and $evalWarning = $@; 5475 $self->Warn("Condition $$tagInfo{Name}: " . CleanWarning()) if $evalWarning; 3675 5476 next; 3676 5477 } 3677 5478 } 3678 if ($$tagInfo{Unknown} and not $ self->{OPTIONS}->{Unknown}) {5479 if ($$tagInfo{Unknown} and not $$self{OPTIONS}{Unknown} and not $$self{OPTIONS}{Verbose}) { 3679 5480 # don't return Unknown tags unless that option is set 3680 5481 return undef; … … 3684 5485 } 3685 5486 # generate information for unknown tags (numerical only) if required 3686 if (not $tagInfo and $self->{OPTIONS}->{Unknown} and $tagID =~ /^\d+$/and3687 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}) 3688 5489 { 3689 5490 my $printConv; … … 3714 5515 # Add new tag to table (must use this routine to add new tags to a table) 3715 5516 # Inputs: 0) reference to tag table, 1) tag ID 3716 # 2) reference to tag information hash5517 # 2) [optional] reference to tag information hash 3717 5518 # Notes: - will not overwrite existing entry in table 3718 5519 # - info need contain no entries when this routine is called 3719 sub AddTagToTable($$ $)5520 sub AddTagToTable($$;$) 3720 5521 { 3721 5522 my ($tagTablePtr, $tagID, $tagInfo) = @_; 5523 $tagInfo or $tagInfo = { }; 3722 5524 3723 5525 # define necessary entries in information hash … … 3725 5527 # fill in default groups from table GROUPS 3726 5528 foreach (keys %{$$tagTablePtr{GROUPS}}) { 3727 next if $tagInfo->{Groups} ->{$_};3728 $tagInfo->{Groups} ->{$_} = $tagTablePtr->{GROUPS}->{$_};5529 next if $tagInfo->{Groups}{$_}; 5530 $tagInfo->{Groups}{$_} = $tagTablePtr->{GROUPS}{$_}; 3729 5531 } 3730 5532 } else { 3731 $$tagInfo{Groups} = $$tagTablePtr{GROUPS};5533 $$tagInfo{Groups} = { %{$$tagTablePtr{GROUPS}} }; 3732 5534 } 3733 5535 $$tagInfo{Flags} and ExpandFlags($tagInfo); … … 3736 5538 $$tagInfo{TagID} = $tagID; 3737 5539 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 3739 5549 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; 3744 5559 # add tag to table, but never overwrite existing entries (could potentially happen 3745 5560 # if someone thinks there isn't any tagInfo because a condition wasn't satisfied) … … 3751 5566 # Inputs: 0) ExifTool object ref, 1) tag table reference, 2) tagID, 3) value, 3752 5567 # 4-N) parameters hash: Index, DataPt, DataPos, Start, Size, Parent, 3753 # TagInfo, ProcessProc 5568 # TagInfo, ProcessProc, RAF 3754 5569 # 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 3755 5572 sub HandleTag($$$$;%) 3756 5573 { 3757 5574 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); 3760 5577 my $dataPt = $parms{DataPt}; 3761 my $subdir;5578 my ($subdir, $format, $count, $size, $noTagInfo); 3762 5579 3763 5580 if ($tagInfo) { … … 3765 5582 } else { 3766 5583 return undef unless $verbose; 5584 $tagInfo = { Name => "tag $tag" }; # create temporary tagInfo hash 5585 $noTagInfo = 1; 3767 5586 } 3768 5587 # 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})) { 3770 5589 my $start = $parms{Start} || 0; 3771 5590 my $size = $parms{Size} || 0; 3772 5591 # read from data in memory if possible 3773 5592 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 } 3775 5599 } 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}"); 3778 5601 return undef; 3779 5602 } … … 3781 5604 # do verbose print if necessary 3782 5605 if ($verbose) { 5606 undef $tagInfo if $noTagInfo; 3783 5607 $parms{Value} = $val; 3784 5608 $parms{Table} = $tagTablePtr; 5609 if ($format) { 5610 $count or $count = int(($parms{Size} || 0) / ($formatSize{$format} || 1)); 5611 $parms{Format} = $format . "[$count]"; 5612 } 3785 5613 $self->VerboseInfo($tag, $tagInfo, %parms); 3786 5614 } 3787 5615 if ($tagInfo) { 3788 5616 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 } 3789 5626 $dataPt or $dataPt = \$val; 3790 5627 # process subdirectory information 3791 5628 my %dirInfo = ( 3792 DirName => $$ tagInfo{Name},5629 DirName => $$subdir{DirName} || $$tagInfo{Name}, 3793 5630 DataPt => $dataPt, 3794 5631 DataLen => length $$dataPt, 3795 5632 DataPos => $parms{DataPos}, 3796 DirStart => $ parms{Start},3797 DirLen => $ parms{Size},5633 DirStart => $subdirStart, 5634 DirLen => $subdirLen, 3798 5635 Parent => $parms{Parent}, 5636 Base => $parms{Base}, 5637 Multi => $$subdir{Multi}, 5638 TagInfo => $tagInfo, 5639 RAF => $parms{RAF}, 3799 5640 ); 5641 my $oldOrder = GetByteOrder(); 5642 SetByteOrder($$subdir{ByteOrder}) if $$subdir{ByteOrder}; 3800 5643 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); 3805 5650 } 3806 5651 return undef; … … 3809 5654 #------------------------------------------------------------------------------ 3810 5655 # Add tag to hash of extracted information 3811 # Inputs: 0) reference to ExifTool object5656 # Inputs: 0) ExifTool object reference 3812 5657 # 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) 3814 5659 # Returns: tag key or undef if no value 3815 5660 sub FoundTag($$$) … … 3828 5673 # (not advised to do this since the tag won't show in list) 3829 5674 $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); 3831 5676 } 3832 5677 my $rawValueHash = $self->{VALUE}; 3833 5678 if ($$tagInfo{RawConv}) { 3834 my $conv = $$tagInfo{RawConv};3835 my $val = $value; # must do this in case eval references $val3836 5679 # initialize @val for use in Composite RawConv expressions 3837 5680 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; 3841 5687 if (ref $conv eq 'CODE') { 3842 $value = &$conv($val , $self);5688 $value = &$conv($value, $self); 3843 5689 } 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) 3845 5693 $value = eval $conv; 3846 $@ and warn "RawConv: $@\n"; 3847 } 5694 $@ and $evalWarning = $@; 5695 } 5696 $self->Warn("RawConv $tag: " . CleanWarning()) if $evalWarning; 3848 5697 return undef unless defined $value; 3849 5698 } 3850 5699 # get tag priority 3851 5700 my $priority = $$tagInfo{Priority}; 3852 defined $priority or $priority = $tagInfo->{Table} ->{PRIORITY};5701 defined $priority or $priority = $tagInfo->{Table}{PRIORITY}; 3853 5702 # 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; 3863 5711 return $tag; # return without creating a new entry 3864 5712 } 3865 5713 # 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)"; 3867 5716 # 3868 5717 # take tag with highest priority 3869 5718 # 3870 5719 # 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) { 3874 5733 # 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 3878 5743 $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}; 3887 5754 } else { 3888 5755 $tag = $nextTag; # don't override the existing tag 3889 5756 } 3890 $self->{PRIORITY} ->{$tag} = $priority;5757 $self->{PRIORITY}{$tag} = $priority; 3891 5758 } elsif ($priority) { 3892 5759 # 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}; 3901 5782 3902 5783 return $tag; … … 3904 5785 3905 5786 #------------------------------------------------------------------------------ 3906 # Get next available tag key3907 # Inputs: 0) hash reference (keys are tag keys), 1) tag name3908 # Returns: next available tag key3909 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 #------------------------------------------------------------------------------3924 5787 # Make current directory the priority directory if not set already 3925 # Inputs: 0) reference to ExifTool object5788 # Inputs: 0) ExifTool object reference 3926 5789 sub SetPriorityDir($) 3927 5790 { … … 3931 5794 3932 5795 #------------------------------------------------------------------------------ 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) 5798 sub SetGroup($$$;$) 5799 { 5800 my ($self, $tagKey, $extra, $fam) = @_; 5801 $self->{TAG_EXTRA}{$tagKey}{defined $fam ? "G$fam" : 'G1'} = $extra; 3977 5802 } 3978 5803 3979 5804 #------------------------------------------------------------------------------ 3980 5805 # Delete specified tag 3981 # Inputs: 0) reference to ExifTool object 3982 # 1) tag key 5806 # Inputs: 0) ExifTool object ref, 1) tag key 3983 5807 sub DeleteTag($$) 3984 5808 { 3985 5809 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 5819 sub 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 } 3990 5833 } 3991 5834 … … 3994 5837 # Inputs: 0) ExifTool object reference 3995 5838 # 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) 5841 sub 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) 5859 sub 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 } 4006 5870 } 4007 5871 … … 4014 5878 my ($self, $mime) = @_; 4015 5879 $mime =~ m{/} or $mime = $mimeType{$mime} or return; 4016 my $old = $self->{VALUE} ->{MIMEType};5880 my $old = $self->{VALUE}{MIMEType}; 4017 5881 if (defined $old) { 4018 5882 my ($a, $b) = split '/', $old; 4019 5883 my ($c, $d) = split '/', $mime; 4020 5884 $d =~ s/^x-//; 4021 $self->{VALUE} ->{MIMEType} = "$c/$b-$d";5885 $self->{VALUE}{MIMEType} = "$c/$b-$d"; 4022 5886 $self->VPrint(0, " Modified MIMEType = $c/$b-$d\n"); 4023 5887 } else { … … 4033 5897 my $self = shift; 4034 5898 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}; 4037 5901 print $out @_; 4038 5902 } … … 4046 5910 my $self = shift; 4047 5911 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, 4053 5917 ); 5918 HexDump($dataPt, undef, %parms, @_); 4054 5919 } 4055 5920 } … … 4064 5929 { 4065 5930 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)}) 4069 5941 { 4070 5942 return "Binary data $length bytes"; 4071 5943 } 4072 my $buff;4073 5944 unless ($self->{RAF}->Seek($offset,0) 4074 5945 and $self->{RAF}->Read($buff, $length) == $length) 4075 5946 { 4076 5947 $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 } 4078 5953 return undef; 4079 5954 } … … 4083 5958 #------------------------------------------------------------------------------ 4084 5959 # 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 4087 5961 # 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) 4088 5964 sub ProcessBinaryData($$$) 4089 5965 { … … 4093 5969 my $size = $$dirInfo{DirLen} || (length($$dataPt) - $offset); 4094 5970 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; 4098 5974 4099 5975 # get default format ('int8u' unless specified) … … 4110 5986 # scan through entire binary table 4111 5987 @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; 4112 5991 } elsif ($$dirInfo{DataMember}) { 4113 5992 @tags = @{$$dirInfo{DataMember}}; … … 4117 5996 @tags = sort { $a <=> $b } TagTableKeys($tagTablePtr); 4118 5997 } 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); 4124 6002 my $nextIndex = 0; 4125 my %val;6003 my $varSize = 0; 4126 6004 foreach $index (@tags) { 4127 my $tagInfo;6005 my ($tagInfo, $val, $saveNextIndex, $len, $mask, $wasVar); 4128 6006 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 } 4130 6018 next if $$tagInfo{Unknown} and 4131 6019 ($$tagInfo{Unknown} > $unknown or $index < $nextIndex); … … 4137 6025 $$tagInfo{Unknown} = 2; # set unknown to 2 for binary unknowns 4138 6026 } 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 4139 6031 my $count = 1; 4140 6032 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}) { 4143 6043 if ($format =~ /(.*)\[(.*)\]/) { 6044 # handle format count field 4144 6045 $format = $1; 4145 6046 $count = $2; 4146 6047 # evaluate count to allow count to be based on previous values 4147 #### eval Format (%val, $size)6048 #### eval Format size (%val, $size, $self) 4148 6049 $count = eval $count; 4149 6050 $@ and warn("Format $$tagInfo{Name}: $@"), next; 4150 6051 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 } 4157 6107 } 4158 6108 if ($unknown > 1) { 4159 6109 # 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; 4161 6113 $nextIndex = $ni unless $nextIndex > $ni; 4162 6114 } 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 } 4168 6128 $self->VerboseInfo($index, $tagInfo, 4169 6129 Table => $tagTablePtr, … … 4175 6135 Format => $format, 4176 6136 Count => $count, 6137 Extra => $mask ? sprintf(', mask 0x%.2x',$mask) : undef, 4177 6138 ); 4178 6139 } 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 } 4180 6171 $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}; 4183 6178 return 1; 4184 6179 } 4185 6180 4186 6181 #.............................................................................. 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) 6184 until ($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; 4201 6208 } 4202 6209 -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool.pod
r16842 r24107 6 6 # URL: http://owl.phy.queensu.ca/~phil/exiftool/ 7 7 # 8 # Legal: Copyright (c) 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)8 # Legal: Copyright (c) 2003-2010, Phil Harvey (phil at owl.phy.queensu.ca) 9 9 # This library is free software; you can redistribute it and/or 10 10 # modify it under the same terms as Perl itself. … … 55 55 56 56 ExifTool provides an extensible set of perl modules to read and write meta 57 information in image, audio and video files, including the maker note58 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, R icoh, Sanyo, Sigma/Foveon and61 S ony.57 information in a wide variety of files, including the maker note information 58 of many digital cameras by various manufacturers such as Canon, Casio, 59 FujiFilm, GE, HP, JVC/Victor, Kodak, Leaf, Minolta/Konica-Minolta, Nikon, 60 Olympus/Epson, Panasonic/Leica, Pentax/Asahi, Reconyx, Ricoh, Samsung, 61 Sanyo, Sigma/Foveon and Sony. 62 62 63 63 Below is a list of file types and meta information formats currently 64 64 supported by ExifTool (r = read, w = write, c = create): 65 65 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) 93 113 94 114 =head1 CONFIGURATION 95 115 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 } 116 User-defined tags can be added via the ExifTool configuration file, or by 117 defining the %Image::ExifTool::UserDefined hash before calling any ExifTool 118 methods. See "ExifTool_config" in the ExifTool distribution for more 119 details. 120 121 By default ExifTool looks for a configuration file named ".ExifTool_config" 122 first in your home directory, then in the directory of the application 123 script, but a different file may be specified by setting the ExifTool 124 C<configFile> variable before using Image::ExifTool. For example: 125 126 BEGIN { $Image::ExifTool::configFile = '/Users/phil/myconfig.cfg' } 102 127 use Image::ExifTool; 103 128 129 or the configuration feature may be disabled by setting C<configFile> to an 130 empty string: 131 132 BEGIN { $Image::ExifTool::configFile = '' } 133 use Image::ExifTool; 134 135 =head1 EXPORTS 136 137 Exports nothing by default, but L</ImageInfo> and all static methods may be 138 exported with the C<:Public> export list. 139 104 140 =head1 METHODS 141 142 All ExifTool features are accessed through the methods of the public 143 interface listed below. Other Image::ExifTool methods and modules should 144 not be accessed directly because their interface may change with future 145 versions. 146 147 None of these methods should ever die or issue warnings to STDERR if called 148 with the proper arguments (with the exception of L</SetNewValue> which 149 returns an error string when called in list context, or sends the error to 150 STDERR otherwise). Error and warning messages that occur during processing 151 are stored in the values of the Error and Warning tags, and are accessible 152 via the L</GetValue> method. 105 153 106 154 =head2 new … … 121 169 =head2 ImageInfo 122 170 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 the126 information hash, and L</GetTagList> for the returned tag list.127 128 # Return meta information for 2 tags only (procedural)171 Read image file and return meta information. This is the one step function 172 for retrieving meta information from an image. Internally, L</ImageInfo> 173 calls L</ExtractInfo> to extract the information, L</GetInfo> to generate 174 the information hash, and L</GetTagList> for the returned tag list. 175 176 # return meta information for 2 tags only (procedural) 129 177 $info = ImageInfo($filename, $tag1, $tag2); 130 178 131 # Return information about an open image file (object-oriented)179 # return information about an open image file (object-oriented) 132 180 $info = $exifTool->ImageInfo(\*FILE); 133 181 134 # Return information from image data in memory for specified tags182 # return information from image data in memory for specified tags 135 183 %options = (PrintConv => 0); 136 184 @tagList = qw(filename imagesize xmp:creator exif:* -ifd1:*); 137 185 $info = ImageInfo(\$imageData, \@tagList, \%options); 138 186 139 # Extract information from an embedded thumbnail image187 # extract information from an embedded thumbnail image 140 188 $info = ImageInfo('image.jpg', 'thumbnailimage'); 141 189 $thumbInfo = ImageInfo($$info{ThumbnailImage}); … … 171 219 argument specified the image data via a file reference (file ref) or data 172 220 reference (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:*'). 221 for requested information. All tags are returned if no tags are specified. 222 223 Tag names are case-insensitive and may be prefixed by optional group names 224 separated 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 226 name, a '?' matches any single character and a '*' matches zero or more 227 characters. Thus 'GROUP:*' represents all tags in a specific group. 228 Wildcards may not be used in group names, with the exception that a group 229 name of '*' may be used to extract all available instances of a tag 230 regardless of the L</Duplicates> setting (ie. '*:WhiteBalance'). Multiple 231 groups may be specified (ie. 'EXIF:Time:*' extracts all EXIF Time tags). And 232 finally, a leading '-' indicates a tag to be excluded (ie. '-IFD1:*'), or a 233 trailing '#' causes the ValueConv value to be returned for this tag. 184 234 185 235 Note 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 are187 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.236 tag list are not necessarily the same as these tag names because group names 237 are removed, the case may be changed, and an instance number may be added. 238 For this reason it is best to use either the keys of the returned hash or 239 the elements of the tag array when accessing the tag values. 190 240 191 241 See L<Image::ExifTool::TagNames|Image::ExifTool::TagNames> for a complete … … 196 246 A reference to an open image file. If you use this method (or a SCALAR 197 247 reference) 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. 248 tags will not be returned. (Also, the FileSize, FileModifyDate and 249 FilePermissions tags will not be returned unless it is a plain file.) Image 250 processing begins at the current file position, and on return the file 251 position is unspecified. May be either a standard filehandle, or a 252 reference to a L<File::RandomAccess|File::RandomAccess> object. Note that 253 the file remains open and must be closed by the caller after L</ImageInfo> 254 returns. 255 256 [Advanced: To allow a non-rewindable stream (ie. a network socket) to be 257 re-read after processing with ExifTool, first wrap the file reference in a 258 L<File::RandomAccess|File::RandomAccess> object, then pass this object to 259 L</ImageInfo>. The L<File::RandomAccess|File::RandomAccess> object will 260 buffer the file if necessary, and may be used to re-read the file after 261 L</ImageInfo> returns.] 201 262 202 263 =item SCALAR ref … … 209 270 added to the list of requested tags. Tags with names beginning with '-' are 210 271 excluded. On return, this list is updated to contain an ordered list of tag 211 keys for all extracted tags. 272 keys for the returned information. 273 274 There will be 1:1 correspondence between the requested tags and the returned 275 tag 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 277 of tag keys, and with other L</Sort> settings the entries may not be in the 278 same order as requested.) 212 279 213 280 =item HASH ref … … 225 292 embedded instance number if multiple tags with the same name were extracted 226 293 from 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>: 294 argument. Use L</GetTagName [static]> to get the tag name for a given tag 295 key. Note that the case of the tag names may not be the same as requested. 296 Here is a simple example to print out the information returned by 297 L</ImageInfo>: 230 298 231 299 foreach (sort keys %$info) { … … 235 303 Values of the returned hash are usually simple scalars, but a scalar 236 304 reference 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 305 to indicate a list. Also, a hash reference may be returned if the L</Struct> 306 option is used. Lists of values are joined by commas into a single 307 string only if the PrintConv option is enabled and the List option is 239 308 disabled (which are the defaults). Note that binary values are not 240 309 necessarily extracted unless specifically requested or the Binary option is … … 268 337 } 269 338 339 =item Notes: 340 341 ExifTool returns all values as byte strings of encoded characters. Perl 342 wide characters are not used. See L</CHARACTER ENCODINGS> for details about 343 the encodings. 344 270 345 As well as tags representing information extracted from the image, 271 346 the following tags generated by ExifTool may be returned: … … 273 348 ExifToolVersion - The ExifTool version number. 274 349 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 fromthe 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. 279 354 280 355 =back … … 285 360 options for an ExifTool object. Options set this way are in effect for 286 361 all 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 362 to some functions. 363 364 The 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 290 369 $exifTool->Options(Exclude => 'OwnerName'); 291 370 292 # Only get information in EXIF or MakerNotes groups371 # only get information in EXIF or MakerNotes groups 293 372 $exifTool->Options(Group0 => ['EXIF', 'MakerNotes']); 294 373 295 # Ignore information from IFD1374 # ignore information from IFD1 296 375 $exifTool->Options(Group1 => '-IFD1'); 297 376 298 # Sort by groups in family 2, and extract unknown tags377 # sort by groups in family 2, and extract unknown tags 299 378 $exifTool->Options(Sort => 'Group2', Unknown => 1); 300 379 301 # Do not extract duplicate tag names 380 # reset DateFormat option 381 $exifTool->Options(DateFormat => undef); 382 383 # do not extract duplicate tag names 302 384 $oldSetting = $exifTool->Options(Duplicates => 0); 303 385 304 # Get currentsetting386 # get current Verbose setting 305 387 $isVerbose = $exifTool->Options('Verbose'); 306 388 … … 340 422 =item Charset 341 423 342 Character set for converting special characters. Valid values are: 343 344 UTF8 - UTF-8 characters (the default) 345 Latin - Windows Latin1 (cp1252) 424 Character set for encoding character strings passed to/from ExifTool with 425 code points above U+007F. Default is UTF8. Valid values are listed below, 426 case 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 346 449 347 450 Note that this option affects some types of information when reading/writing … … 349 452 defined for both types of access. 350 453 454 =item CharsetID3 455 456 Character encoding to assume for ID3v1 strings. By the specification ID3v1 457 strings should be encoded in ISO 8859-1 (essentially Latin), but some 458 applications may use local encoding instead. Default is Latin. 459 460 =item CharsetIPTC 461 462 Fallback IPTC character set to assume if IPTC information contains no 463 CodedCharacterSet tag. Possible values are the same as the L</Charset> 464 option. Default is Latin. 465 466 Note that this option affects some types of information when reading/writing 467 the file and other types when getting/setting tag values, so it must be 468 defined for both types of access. 469 470 =item CharsetPhotoshop 471 472 Character encoding to assume for Photoshop IRB resource names. Default is 473 Latin. 474 351 475 =item Compact 352 476 353 477 Flag 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. 478 that the data be padded with blanks to allow in-place editing. With this 479 flag set the 2kB of padding is not written. Note that this only effects 480 embedded XMP since padding is never written for stand-alone XMP files. 356 481 357 482 =item Composite … … 371 496 output for the same coordinate using various formats: 372 497 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 505 Note: To avoid loss of precision, the default coordinate format is 506 different when copying tags with L</SetNewValuesFromFile>. 378 507 379 508 =item DateFormat 380 509 381 Format for printing EXIF date/time. See C<strftime> in the L<POSIX> package382 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 un less the StrictDate option is set.510 Format for printing date/time values. See C<strftime> in the L<POSIX> 511 package for details about the format string. The default is similar to a 512 format of "%Y:%m:%d %H:%M:%S". If date can not be converted, value is left 513 unchanged unless the StrictDate option is set. Timezones are ignored. 385 514 386 515 =item Duplicates 387 516 388 Flag to preserve values of duplicate tags (instead of overwriting existing 389 value). Default is 1. 517 Flag to return values from tags with duplicate names when extracting 518 information. Default is 1. 519 520 =item Escape 521 522 Escape special characters in extracted values for HTML or XML. Also 523 unescapes HTML or XML character entities in input values passed to 524 L</SetNewValue>. Valid settings are 'HTML', 'XML' or undef. Default is 525 undef. 390 526 391 527 =item Exclude … … 397 533 name with a '-' in the arguments to L</ImageInfo>. 398 534 535 =item ExtractEmbedded 536 537 Flag to extract information from embedded documents in EPS and PDF files, 538 embedded MPF images in JPEG and MPO files, streaming metadata in AVCHD 539 videos, and the resource fork of Mac OS files. Default is 0. 540 399 541 =item FastScan 400 542 401 543 Flag 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. 544 this option set to 1, ExifTool will not scan to the end of a JPEG image to 545 check for an AFCP, CanonVRD, FotoStation, PhotoMechanic, MIE or PreviewImage 546 trailer. This also stops the parsing after the first comment in GIF images, 547 and at the audio/video data with RIFF-format files (AVI, WAV, etc), so any 548 trailing metadata (ie. XMP written by some utilities) may be missed. When 549 combined with the ScanForXMP option, prevents scanning for XMP in recognized 550 file types. With a value of 2, ExifTool will also avoid extracting any EXIF 551 MakerNote information. Default is 0. 406 552 407 553 =item FixBase … … 415 561 or undef (the default) for no base adjustment. 416 562 563 =item GeoMaxIntSecs 564 565 Maximum interpolation time in seconds for geotagging. Geotagging fails if 566 the Geotime value lies between two fixes in the same track which are 567 separated by a number of seconds greater than this. Default is 1800. 568 569 =item GeoMaxExtSecs 570 571 Maximum extrapolation time in seconds for geotagging. Geotagging fails if 572 the Geotime value lies outside a GPS track by a number of seconds greater 573 than this. Default is 1800. 574 575 =item GeoMaxHDOP 576 577 Maximum Horizontal (2D) Dilution Of Precision for geotagging. GPS fixes are 578 ignored if the HDOP is greater than this. Default is undef. 579 580 =item GeoMaxPDOP 581 582 Maximum Position (3D) Dilution Of Precision for geotagging. GPS fixes are 583 ignored if the PDOP is greater than this. Default is undef. 584 585 =item GeoMinSats 586 587 Minimum number of satellites for geotagging. GPS fixes are ignored if the 588 number of acquired satellites is less than this. Default is undef. 589 417 590 =item Group# 418 591 419 592 Extract tags only for specified groups in family # (Group0 assumed if # 420 593 not 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. 594 to a list of groups. Case is significant in group names. Specify a group 595 to be excluded by preceding group name with a '-'. See L</GetGroup> for a 596 description of group families, and L</GetAllGroups [static]> for lists of 597 group names. 424 598 425 599 =item HtmlDump … … 438 612 Flag to ignore minor errors. Causes minor errors to be downgraded to 439 613 warnings, 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. 614 to allow writing of files when minor errors occur, but by ignoring some 615 minor warnings the behaviour of ExifTool may be changed to allow some 616 questionable operations to proceed (such as extracting thumbnail and preview 617 images even if they don't have a recognizable header). Minor 618 errors/warnings are denoted by '[minor]' at the start of the message. 619 620 =item Lang 621 622 Localized language for exiftool tag descriptions, etc. Available languages 623 are given by the Image::ExifTool::Lang module names (ie. 'fr'). If the 624 specified language isn't available, the option is not changed. May be set 625 to undef to select the built-in default language. Default is 'en'. 626 627 =item LargeFileSupport 628 629 Flag to indicate that 64-bit file offsets are supported on this system. 630 Default is 0. 444 631 445 632 =item List 446 633 447 Flag to extract lists of PrintConv values into arrays instead of 448 concatenating them into comma-separated strings. Default is 0. 634 Flag to extract lists of PrintConv values into arrays instead of joining 635 them into a string of values. The L</ListSep> option specifies the 636 separator used when combining values. Default is 0. 637 638 =item ListSep 639 640 Separator string used to join lists of PrintConv values when L</List> option 641 is not set. Default is ', '. 642 643 =item ListSplit 644 645 Regular expression used to split values of list-type tags into individual 646 items when writing. (ie. use ',\\s*' to split a comma-separated list.) 647 Default is undef. 449 648 450 649 =item MakerNotes … … 456 655 are: 457 656 458 0 - Do not extract writable subdirectories [default]657 0 - Do not extract writable subdirectories (default) 459 658 1 - Extract and rebuild maker notes into self-contained block 460 659 2 - Extract without rebuilding maker notes … … 466 665 to '' if L</IgnoreMinorErrors> is set. Default is undef. 467 666 667 =item Password 668 669 Password for processing password-protected PDF documents. Ignored if a 670 password is not required. Character encoding of the password is determined 671 by the value of the Charset option at processing time. Default is undef. 672 468 673 =item PrintConv 469 674 … … 481 686 Specifies order to sort tags in returned list: 482 687 688 Input - Sort in same order as input tag arguments (default) 483 689 Alpha - Sort alphabetically 484 690 File - Sort in order that tags were found in the file 485 Group# - Sort by tag group, where # is the groupfamily486 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. 489 695 490 696 =item StrictDate 491 697 492 698 Flag to return undefined value for any date which can't be converted when 493 the DateFormat option is used. Default is 0. 699 the DateFormat option is used. Default is undef. 700 701 =item Struct 702 703 Flag to return XMP structures as hash references instead of flattening into 704 individual tags. If not defined (the default), tags are flattened when 705 reading (with L<ExtractInfo>), and structured when copying (with 706 L</SetNewValuesFromFile>). Has no effect when writing since both flattened 707 and 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 494 712 495 713 =item TextOut … … 524 742 =head2 ClearOptions 525 743 526 Reset all options to their default values. 744 Reset all options to their default values. Loads user-defined default 745 option values from the %Image::ExifTool::UserDefined::Options hash in the 746 .ExifTool_config file if it exists. 527 747 528 748 $exifTool->ClearOptions(); … … 555 775 L</ExtractInfo>: 556 776 557 Binary, Composite, DateFormat, Unknown and Verbose. 777 Binary, Charset, CharsetID3, CharsetIPTC, Composite, ExtractEmbedded, 778 FastScan, FixBase, HtmlDump, HtmlDumpBase, IgnoreMinorErrors, Lang, 779 LargeFileSupport, MakerNotes, ScanForXMP, Struct, TextOut, Unknown and 780 Verbose. 558 781 559 782 =item Return Value: 560 783 561 1 if image was valid, 0 otherwise (and 'Error' tag set).784 1 if this was a recognized file format, 0 otherwise (and 'Error' tag set). 562 785 563 786 =back … … 570 793 L</ImageInfo>. 571 794 572 # Get image width and hieght only795 # get image width and hieght only 573 796 $info = $exifTool->GetInfo('ImageWidth', 'ImageHeight'); 574 797 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) 576 799 $info = $exifTool->GetInfo(\@ioTagList); 577 800 578 # Get all information in Author or Location groups801 # get all information in Author or Location groups 579 802 $info = $exifTool->GetInfo({Group2 => ['Author', 'Location']}); 580 803 … … 586 809 image can not be specified. Options in effect are: 587 810 588 Duplicates, Exclude, Group#, PrintConv (and Sort if tag list reference is 589 given). 811 Charset, CoordFormat, DateFormat, Duplicates, Escape, Exclude, Group#, Lang, 812 List, ListSep, PrintConv, Sort (if a tag list reference is given) and 813 StrictDate. 590 814 591 815 =item Return Value: … … 610 834 $exifTool->WriteInfo(undef, $dstfile, 'XMP'); 611 835 612 # edit file in place (you do have backups, right?)836 # overwrite file (you do have backups, right?) 613 837 $exifTool->WriteInfo($srcfile); 614 838 … … 619 843 0) ExifTool object reference 620 844 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 845 1) Source file name, file reference, scalar reference, or undef to create a 846 file from scratch 847 848 2) [optional] Destination file name, file reference, scalar reference, or 849 undef to overwrite the original file 625 850 626 851 3) [optional] Destination file type … … 633 858 If an error code is returned, an Error tag is set and GetValue('Error') can 634 859 be called to obtain the error description. A Warning tag may be set even if 635 this routine is successful. 860 this routine is successful. Calling WriteInfo clears any pre-existing Error 861 and Warning tags. 636 862 637 863 $errorMessage = $exifTool->GetValue('Error'); … … 641 867 642 868 The 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 871 is required unless the type can be determined from the destination file 872 name. 873 874 If a destination file name is given, the specified file must not exist 875 because an existing destination file will not be overwritten. The 876 destination file name may be undefined to overwrite the original file (make 877 sure you have backups!). In this case, if a source file name is provided, a 878 temporary file is created and renamed to replace the source file if no 879 errors occurred while writing. Otherwise, if a source file reference or 880 scalar reference is used, the image is first written to memory then copied 881 back to replace the original if there were no errors. 651 882 652 883 The destination file type is only used if the source file is undefined. 653 884 654 =back 885 On Mac OS systems, the file resource fork is preserved if this routine is 886 called with a source file name. 887 888 =back 889 890 The following ExifTool options are effective in the call to L</WriteInfo>: 891 892 ByteOrder, Charset, CharsetID3, CharsetIPTC, Compact, Compress, FixBase, 893 IgnoreMinorErrors and Verbose. 655 894 656 895 =head2 CombineInfo … … 699 938 =item Return Values: 700 939 701 A list of tag s in the specified order.940 A list of tag keys in the specified order. 702 941 703 942 =back … … 724 963 =item Return Values: 725 964 726 A list of tag s in the specified order.965 A list of tag keys in the specified order. 727 966 728 967 =back … … 745 984 =item Return Values: 746 985 747 List of requested tag s in the same order that theywere specified.986 List of requested tag keys in the same order that the tags were specified. 748 987 Note that this list will be empty if tags were not specifically requested 749 988 (ie. If extracting all tags). … … 763 1002 Tags which represent lists of multiple values (as may happen with 'Keywords' 764 1003 for 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. 1004 PrintConv value for these tags is either a string of values or a list 1005 reference (depending on the List option setting), and the ValueConv value is 1006 always a list reference. But in list context, L</GetValue> always returns 1007 the list itself. 1008 1009 Note that L</GetValue> requires a case-sensitive tag key as an argument. To 1010 retrieve tag information based on a case-insensitive tag name (with an 1011 optional group specifier), use L</GetInfo> instead. 769 1012 770 1013 # PrintConv example … … 788 1031 my @keywords = $exifTool->GetValue('Keywords', 'ValueConv'); 789 1032 1033 The following options are in effect when <L/GetValue> is called: 1034 1035 Charset, CoordFormat, DateFormat, Escape, Lang, List, ListSep, PrintConv and 1036 StrictDate. 1037 790 1038 =over 4 791 1039 … … 805 1053 806 1054 The 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 string808 o f 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.1055 the List option is disabled then PrintConv returns a string of values, 1056 otherwise a reference to the list is returned in scalar context. The list 1057 itself is returned in list context. Values may also be scalar references to 1058 binary data, or hash references if the Struct option is set. 811 1059 812 1060 Note: It is possible for L</GetValue> to return an undefined ValueConv or … … 841 1089 $exifTool->SetNewValue('Keywords', $word, DelValue => 1); 842 1090 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 847 1098 $exifTool->SetNewValue(Keywords => $word, AddValue => 1); 848 1099 849 1100 # set a tag in a specific group 850 1101 $exifTool->SetNewValue(Headline => $val, Group => 'XMP'); 851 $exifTool->SetNewValue('XMP:Headline' => $val); # equivalent1102 $exifTool->SetNewValue('XMP:Headline' => $val); # (equivalent) 852 1103 853 1104 # shift original date/time back by 1 hour 854 1105 $exifTool->SetNewValue(DateTimeOriginal => '1:00', Shift => -1); 855 1106 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 1131 a description of the structure serialization technique.) 1132 856 1133 =over 4 857 1134 … … 860 1137 0) ExifTool object reference 861 1138 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. 1139 1) [optional] Tag key or tag name, or undef to clear all new values. A tag 1140 name of '*' can be used when deleting tags to delete all tags, or all tags 1141 in a specified group. The tag name may be prefixed by group name, separated 1142 by a colon (ie. 'EXIF:Artist'), which is equivalent to using a Group option 1143 argument. Also, a '#' may be appended to the tag name (ie. 1144 'EXIF:Orientation#'), with the same effect as setting Type to 'ValueConv'. 867 1145 868 1146 2) [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) 1147 a scalar, scalar reference, list reference to set a list of values, or hash 1148 reference for a structure. Integer values may be specified as a hexadecimal 1149 string (with a leading '0x'), and simple rational values may be specified in 1150 fractional form (ie. '4/10'). Structure tags may be specified either as a 1151 hash reference or a serialized string (see the last two examples above). 1152 1153 3-N) [optional] SetNewValue option/value pairs (see below). 872 1154 873 1155 =item SetNewValue Options: 874 1156 875 1157 =over 4 876 877 =item Type878 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, otherwise881 ValueConv.882 1158 883 1159 =item AddValue … … 890 1166 Delete the existing tag if it has the specified value. Valid values are 891 1167 0 or 1. Default is 0. 1168 1169 =item EditGroup 1170 1171 Create tags in existing groups only. Don't create new group. Valid values 1172 are 0 and 1. Default is 0. 1173 1174 =item EditOnly 1175 1176 Edit tag only if it already exists. Don't create new tag. Valid values are 1177 0 and 1. Default is 0. 892 1178 893 1179 =item Group … … 913 1199 =item Replace 914 1200 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). 1201 Flag to replace the previous new values for this tag (ie. replace the values 1202 set in previous calls to L</SetNewValue>). This option is most commonly 1203 used to replace previously-set new values for List-type tags. Valid values 1204 are 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 1206 value) or 2 (reset previous new values only). 919 1207 920 1208 =item Shift … … 922 1210 Shift the tag by the specified value. Currently only date/time tags can be 923 1211 shifted. 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 isset. Default is undef. See1212 negative shift. If 0, the shift is applied only if the tag is shiftable, 1213 and the shift is positive if AddValue is set, or negative if DelValue is 1214 set. Default is undef. See 927 1215 L<Image::ExifTool::Shift.pl|Image::ExifTool::Shift.pl> for more information. 1216 1217 =item Type 1218 1219 The type of value being set. Valid values are PrintConv, ValueConv or Raw. 1220 Default is PrintConv if the L</PrintConv> Option is set, otherwise 1221 ValueConv. 928 1222 929 1223 =back … … 935 1229 error string. 936 1230 937 =back 1231 =item Notes: 1232 1233 When deleting groups of tags, the Replace option may be used as in the last 1234 example above to exclude specific groups from a mass delete. However, this 1235 technique may not be used to exclude individual tags. Instead, use 1236 L</SetNewValuesFromFile> to recover the values of individual tags after 1237 deleting a group. 1238 1239 =back 1240 1241 The following ExifTool options are effective in the call to L</SetNewValue>: 1242 1243 Charset, Escape, IgnoreMinorErrors, Lang, ListSep, ListSplit, PrintConv and 1244 Verbose. 938 1245 939 1246 =head2 SetNewValuesFromFile … … 963 1270 'Comment<ISO=$ISO Aperture=$aperture Exposure=$shutterSpeed'); 964 1271 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 965 1280 =over 4 966 1281 … … 971 1286 1) File name, file reference, or scalar reference 972 1287 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.) 1288 2-N) [optional] List of tag names to set or options hash references. All 1289 writable tags are set if none are specified. The tag names are not case 1290 sensitive, and may be prefixed by an optional family 0 or 1 group name, 1291 separated by a colon (ie. 'exif:iso'). A leading '-' indicates tags to be 1292 excluded (ie. '-comment'), or a trailing '#' causes the ValueConv value to 1293 be copied (same as setting the Type option to 'ValueConv' for this tag 1294 only). An asterisk ('*') may be used for the tag name, and is useful when a 1295 group is specified to set all tags from a group (ie. 'XMP:*'). A special 1296 feature allows tag names of the form 'SRCTAG>DSTTAG' (or 1297 'DSTTAGE<lt>SRCTAG') to be specified to copy information to a tag with a 1298 different name or a specified group. Both 'SRCTAG' and 'DSTTAG' may use '*' 1299 and/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 1301 arguments of the form 'SRCTAG+>DSTTAG' or 'SRCTAG->DSTTAG'. Tags are 1302 evaluated in order, so exclusions apply only to tags included earlier in the 1303 list. An extension of this feature allows the tag value to be set from an 1304 expression containing tag names with leading '$' symbols (ie. 1305 'CommentE<lt>the file is $filename'). Braces '{}' may be used around the tag 1306 name to separate it from subsequent text, and a '$$' is used to to represent 1307 a '$' symbol. (The behaviour for missing tags in expressions is defined by 1308 the L</MissingTagValue> option.) Multiple options hash references may be 1309 passed to set different options for different tags. Options apply to 1310 subsequent tags in the argument list. 991 1311 992 1312 By default, this routine will commute information between same-named tags in … … 995 1315 name for extracted tags (even if '*' is used as a group name), in which case 996 1316 the 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.) 1317 different group. When '*' is used for a group name, the family 1 group of 1318 the original tag is preserved. (For example, specifying '*:*' copies all 1319 information while preserving the original family 1 groups.) 1320 1321 =item SetNewValuesFromFile Options: 1322 1323 The options are the same was for L</SetNewValue>, and are passed directly 1324 to 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. 999 1336 1000 1337 =item Return Values: … … 1009 1346 1010 1347 If a preview image exists, it is not copied. The preview image must be 1011 transferred separately if desired .1348 transferred separately if desired, in a separate call to L</WriteInfo> 1012 1349 1013 1350 When simply copying all information between files of the same type, it is … … 1015 1352 the tags to set. 1016 1353 1354 The L</Duplicates> option is always in effect for tags extracted from the 1355 source file using this routine. 1356 1357 The L</Struct> option is enabled by default for tags extracted by this 1358 routine. This allows the hierarchy of complex structures to be preserved 1359 when copying, but the Struct option may be set to 0 to override this 1360 behaviour and copy as flattened tags instead. 1361 1017 1362 =back 1018 1363 … … 1033 1378 0) ExifTool object reference 1034 1379 1035 1) Tag key or tag name1380 1) Tag name (case sensitive, may be prefixed by family 0 or 1 group name) 1036 1381 1037 1382 =item Return Values: 1038 1383 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). 1384 List of new Raw tag values, or first value in list when called in scalar 1385 context. The list may be empty either if the tag isn't being written, or if 1386 it is being deleted (ie. if L</SetNewValue> was called without a value). 1041 1387 1042 1388 =back … … 1108 1454 Set the file modification time from the new value of the FileModifyDate tag. 1109 1455 1456 $exifTool->SetNewValue(FileModifyDate => '2000:01:02 03:04:05-05:00', 1457 Protected => 1); 1110 1458 $result = $exifTool->SetFileModifyDate($file); 1111 1459 … … 1124 1472 1 if the time was changed, 0 if nothing was done, or -1 if there was an 1125 1473 error setting the time. 1474 1475 =item Notes: 1476 1477 Equivalent to, but more efficient than calling L</WriteInfo> when only the 1478 FileModifyDate tag has been set. If a timezone is not specified in the 1479 FileModifyDate value, local time is assumed. When shifting FileModifyDate, 1480 the time of the original file is used unless an optional base time is 1481 specified. 1126 1482 1127 1483 =back … … 1166 1522 first valid group of this list. This has an impact only if the group is not 1167 1523 specified 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. Any1169 family 0group name may be used. Case is not significant.1524 than one group. The default order is EXIF, IPTC then XMP. Any family 0 1525 group name may be used. Case is not significant. 1170 1526 1171 1527 $exifTool->SetNewGroups('XMP','EXIF','IPTC'); … … 1208 1564 Get the ID for the specified tag. The ID is the IFD tag number in EXIF 1209 1565 information, 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. 1566 binary data block. For some tags, such as Composite tags where there is no 1567 ID, an empty string is returned. In list context, also returns a language 1568 code for the tag if available and different from the default language (ie. 1569 with alternate language entries for XMP "lang-alt" tags). 1212 1570 1213 1571 $id = $exifTool->GetTagID($tag); 1572 ($id, $lang) = $exifTool->GetTagID($tag); 1214 1573 1215 1574 =over 4 … … 1223 1582 =item Return Values: 1224 1583 1225 Tag ID or '' of there is no ID for this tag. 1584 In scalar context, returns the tag ID or '' if there is no ID for this tag. 1585 In list context, returns the tag ID (or '') and the language code (or 1586 undef). 1226 1587 1227 1588 =back … … 1230 1591 1231 1592 Get description for specified tag. This function will always return a 1232 defined value. In the case where the description doesn't exist, the tag1233 name is returned.1593 defined value. In the case where the description doesn't exist, one is 1594 generated from the tag name. 1234 1595 1235 1596 =over 4 … … 1249 1610 =head2 GetGroup 1250 1611 1251 Get group name for specified tag. 1252 1612 Get group name(s) for a specified tag. 1613 1614 # return family 0 group name (ie. 'EXIF'); 1253 1615 $group = $exifTool->GetGroup($tag, 0); 1254 1616 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 1255 1626 =over 4 1256 1627 … … 1261 1632 1) Tag key 1262 1633 1263 2) [optional] Group family number 1634 2) [optional] Group family number, or string of numbers separated by colons 1264 1635 1265 1636 =item Return Values: 1266 1637 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. 1638 Group name (or '' if tag has no group). If no group family is specified, 1639 L</GetGroup> returns the name of the group in family 0 when called in scalar 1640 context, or the names of groups for all families in list context. Returns a 1641 string of group names separated by colons if the input group family contains 1642 a colon. The string is simplified to remove a leading 'Main:' and adjacent 1643 identical group names unless the family string begins with a colon. 1644 1645 =item Notes: 1646 1647 The 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 1655 Families 0 and 1 are based on the file structure, and are similar except 1656 that family 1 is more specific and sub-divides some groups to give more 1657 detail about the specific location where the information was found. For 1658 example, the EXIF group is split up based on the specific IFD (Image File 1659 Directory), the MakerNotes group is divided into groups for each 1660 manufacturer, and the XMP group is separated based on the XMP namespace 1661 prefix. Note that only common XMP namespaces are listed in the 1662 L<GetAllGroups documentation|/GetAllGroups [static]>, but additional 1663 namespaces may be present in some XMP data. Also note that the 'XMP-xmp...' 1664 group names may appear in the older form 'XMP-xap...' since these names 1665 evolved as the XMP standard was developed. The ICC_Profile group is broken 1666 down to give information about the specific ICC_Profile tag from which 1667 multiple values were extracted. As well, information extracted from the 1668 ICC_Profile header is separated into the ICC-header group. 1669 1670 Family 2 classifies information based on the logical category to which the 1671 information refers. 1672 1673 Family 3 gives the document number for tags extracted from embedded 1674 documents, or 'Main' for tags from the main document. (See the 1675 L</ExtractEmbedded> option for extracting tags from embedded documents.) 1676 Nested sub-documents (if they exist) are indicated by numbers separated with 1677 dashes in the group name, to an arbitrary depth. (ie. 'Doc2-3-1' is the 1st 1678 sub-sub-document of the 3rd sub-document of the 2nd embedded document of the 1679 main file.) 1680 1681 Family 4 provides a method for differentiating tags when multiple tags exist 1682 with the same name in the same location. The primary instance of a tag (the 1683 tag extracted when the Duplicates option is disabled and no group is 1684 specified) has no family 4 group name, but additional instances have have 1685 family 4 group names of 'Copy1', 'Copy2', 'Copy3', etc. 1686 1687 See L</GetAllGroups [static]> for complete lists of group names. 1271 1688 1272 1689 =back … … 1274 1691 =head2 GetGroups 1275 1692 1276 Get list of group names forspecified information.1693 Get list of group names that exist in the specified information. 1277 1694 1278 1695 @groups = $exifTool->GetGroups($info, 2); 1696 @groups = $exifTool->GetGroups('3:1'); 1279 1697 1280 1698 =over 4 … … 1286 1704 1) [optional] Info hash ref (default is all extracted info) 1287 1705 1288 2) [optional] Group family number (default 0)1706 2) [optional] Group family number, or string of numbers (default 0) 1289 1707 1290 1708 =item Return Values: 1291 1709 1292 1710 List of group names in alphabetical order. If information hash is not 1293 specified, the group names are returned for all extracted information. 1711 specified, the group names are returned for all extracted information. See 1712 L</GetGroup> for an description of family numbers and family number strings. 1294 1713 1295 1714 =back … … 1377 1796 =item Inputs: 1378 1797 1379 0) [optional] Group name 1798 0) [optional] Group name, or string of group names separated by colons 1380 1799 1381 1800 =item Return Values: 1382 1801 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). 1802 A list of all available tags in alphabetical order, or all tags in a 1803 specified group or intersection of groups. The group name is case 1804 insensitive, and any group in families 0-2 may be used except for EXIF 1805 family 1 groups (ie. the specific IFD). 1386 1806 1387 1807 =back … … 1397 1817 =item Inputs: 1398 1818 1399 0) [optional] Group name 1819 0) [optional] Group name, or string of group names separated by colons 1400 1820 1401 1821 =item Return Values: … … 1403 1823 A list of all writable tags in alphabetical order. These are the tags for 1404 1824 which 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 case1406 insensitive, and any group in any family may be used except for EXIF family1407 1 groups (ie. the specific IFD).1825 returns only writable tags in specified group(s). The group name is case 1826 insensitive, and any group in families 0-2 may be used except for EXIF 1827 family 1 groups (ie. the specific IFD). 1408 1828 1409 1829 =back … … 1419 1839 =item Inputs: 1420 1840 1421 0) Group family number (0- 2)1841 0) Group family number (0-4) 1422 1842 1423 1843 =item Return Values: … … 1427 1847 =back 1428 1848 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: 1849 Here is a complete list of groups for each of these families: 1448 1850 1449 1851 =over 4 … … 1451 1853 =item Family 0 (Information Type): 1452 1854 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 1855 AFCP, AIFF, APE, APP0, APP12, APP13, APP14, APP15, APP4, APP5, APP6, APP8, 1856 ASF, CanonVRD, Composite, DICOM, DNG, DV, DjVu, Ducky, EXE, EXIF, ExifTool, 1857 FLAC, File, Flash, FlashPix, Font, FotoStation, GIF, GIMP, GeoTiff, H264, 1858 HTML, ICC_Profile, ID3, IPTC, ITC, JFIF, JPEG, Jpeg2000, LNK, Leaf, M2TS, 1859 MIE, MIFF, MNG, MPC, MPEG, MPF, MXF, MakerNotes, Matroska, Meta, PDF, PICT, 1860 PNG, PSP, PhotoMechanic, Photoshop, PostScript, PrintIM, QuickTime, RAF, 1861 RIFF, RSRC, RTF, Rawzor, Real, SVG, SigmaRaw, Stim, Vorbis, XML, XMP, ZIP 1459 1862 1460 1863 =item Family 1 (Specific Location): 1461 1864 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 1865 AC3, AFCP, AIFF, APE, ASF, AVI1, Adobe, AdobeCM, CIFF, Canon, CanonCustom, 1866 CanonRaw, CanonVRD, Casio, Chapter#, Composite, DICOM, DNG, DV, DjVu, 1867 DjVu-Meta, Ducky, EPPIM, EXE, EXIF, ExifIFD, ExifTool, FLAC, File, Flash, 1868 FlashPix, Font, FotoStation, FujiFilm, GE, GIF, GIMP, GPS, GeoTiff, 1869 GlobParamIFD, GraphConv, H264, HP, HTML, HTML-dc, HTML-ncc, HTML-office, 1870 HTML-prod, HTML-vw96, HTTP-equiv, ICC-chrm, ICC-clrt, ICC-header, ICC-meas, 1871 ICC-meta, ICC-view, ICC_Profile, ICC_Profile#, ID3, ID3v1, ID3v1_Enh, 1872 ID3v2_2, ID3v2_3, ID3v2_4, IFD0, IFD1, IPTC, IPTC#, ITC, InteropIFD, JFIF, 1873 JPEG, JVC, Jpeg2000, KDC_IFD, Kodak, KodakBordersIFD, KodakEffectsIFD, 1874 KodakIFD, KyoceraRaw, LNK, Leaf, LeafSubIFD, Leica, M2TS, MAC, MIE-Audio, 1875 MIE-Camera, MIE-Canon, MIE-Doc, MIE-Extender, MIE-Flash, MIE-GPS, MIE-Geo, 1876 MIE-Image, MIE-Lens, MIE-Main, MIE-MakerNotes, MIE-Meta, MIE-Orient, 1877 MIE-Preview, MIE-Thumbnail, MIE-UTM, MIE-Unknown, MIE-Video, MIFF, MNG, MPC, 1878 MPEG, MPF0, MPImage, MXF, MakerNotes, MakerUnknown, Matroska, MetaIFD, 1879 Microsoft, Minolta, MinoltaRaw, NITF, Nikon, NikonCapture, NikonCustom, 1880 NikonScan, Olympus, PDF, PICT, PNG, PSP, Panasonic, Pentax, PhotoMechanic, 1881 Photoshop, PictureInfo, PostScript, PreviewIFD, PrintIM, ProfileIFD, 1882 QuickTime, RAF, RAF2, RIFF, RMETA, RSRC, RTF, Rawzor, Real, Real-CONT, 1883 Real-MDPR, Real-PROP, Real-RA3, Real-RA4, Real-RA5, Real-RJMD, Reconyx, 1884 Ricoh, SPIFF, SR2, SR2DataIFD, SR2SubIFD, SRF#, SVG, Samsung, Sanyo, 1885 Scalado, Sigma, SigmaRaw, Sony, SonyIDC, Stim, SubIFD, System, Track#, 1886 Version0, Vorbis, XML, XMP, XMP-DICOM, XMP-MP, XMP-MP1, XMP-PixelLive, 1887 XMP-acdsee, XMP-album, XMP-aux, XMP-cc, XMP-cell, XMP-crs, XMP-dc, XMP-dex, 1888 XMP-digiKam, XMP-exif, XMP-iptcCore, XMP-iptcExt, XMP-lr, XMP-mediapro, 1889 XMP-microsoft, XMP-mwg-coll, XMP-mwg-kw, XMP-mwg-rs, XMP-pdf, XMP-pdfx, 1890 XMP-photomech, XMP-photoshop, XMP-plus, XMP-prism, XMP-prl, XMP-pur, 1891 XMP-rdf, XMP-swf, XMP-tiff, XMP-x, XMP-xmp, XMP-xmpBJ, XMP-xmpDM, XMP-xmpMM, 1892 XMP-xmpNote, XMP-xmpPLUS, XMP-xmpRights, XMP-xmpTPg, ZIP 1482 1893 1483 1894 =item Family 2 (Category): … … 1485 1896 Audio, Author, Camera, Document, ExifTool, Image, Location, Other, Printing, 1486 1897 Time, Unknown, Video 1898 1899 =item Family 3 (Document Number): 1900 1901 Doc#, Main 1902 1903 =item Family 4 (Instance Number): 1904 1905 Copy# 1487 1906 1488 1907 =back … … 1531 1950 0) [optional] File name (or just an extension) 1532 1951 1533 1) [optional] Flag to return a description instead of a type 1952 1) [optional] Flag to return a description instead of a type. Set to 0 to 1953 return type for recognized but unsupported files (otherwise the return value 1954 for unsupported files is undef). 1534 1955 1535 1956 =item Return Value: 1536 1957 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. 1958 A string, based on the file extension, which indicates the basic format of 1959 the file. Note that some files may be based on other formats (like many RAW 1960 image formats are based on TIFF). In array context, may return more than 1961 one file type if the file may be based on different formats. Returns undef 1962 if files with this extension are not yet supported by ExifTool. Returns a 1963 list of extensions for all supported file types if no input extension is 1964 specified (or all recognized file types if the description flag is set to 0). 1965 Returns a more detailed description of the specific file format when the 1966 description flag is set. 1542 1967 1543 1968 =back … … 1545 1970 =head2 CanWrite [static] 1546 1971 1547 Can the specified file or file typebe written?1972 Can the specified file be written? 1548 1973 1549 1974 my $writable = Image::ExifTool::CanWrite($filename); … … 1553 1978 =item Inputs: 1554 1979 1555 0) File name , file extension, or file type1980 0) File name or extension 1556 1981 1557 1982 =item Return Value: 1558 1983 1559 True if the specified file type can be written (edited). 1984 True if ExifTool supports writing files of this type (based on the file 1985 extension). 1560 1986 1561 1987 =back … … 1563 1989 =head2 CanCreate [static] 1564 1990 1565 Can the specified file or file typebe created?1991 Can the specified file be created? 1566 1992 1567 1993 my $creatable = Image::ExifTool::CanCreate($filename); … … 1571 1997 =item Inputs: 1572 1998 1573 0) File name , file extension, or file type1999 0) File name or extension 1574 2000 1575 2001 =item Return Value: 1576 2002 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 2003 True if ExifTool can create files with this extension from scratch. 2004 Currently, this can only be done with XMP, MIE, ICC, VRD and EXIF files. 2005 2006 =back 2007 2008 =head1 CHARACTER ENCODINGS 2009 2010 Certain meta information formats allow coded character sets other than plain 2011 ASCII. When reading, 8-bit encodings are passed straight through ExifTool 2012 without re-coding unless specified otherwise below, and multi-byte encodings 2013 are converted according to the L</Charset> option ('UTF8' by default). When 2014 writing, the inverse conversions are performed. See the L</Charset> option 2015 for a list of valid character sets. 2016 2017 More specific details are given below about how character coding is handled 2018 for EXIF, IPTC, XMP, PNG, ID3, PDF and MIE information: 2019 2020 =head2 EXIF 2021 2022 Most textual information in EXIF is stored in ASCII format, and ExifTool 2023 does not convert these tags. However it is not uncommon for applications to 2024 write UTF-8 or other encodings where ASCII is expected, and ExifTool will 2025 quite happily read/write any encoding without conversion. For a few EXIF 2026 tags (UserComment, GPSProcessingMethod and GPSAreaInformation) the stored 2027 text may be encoded either in ASCII, Unicode (UCS-2) or JIS. When reading 2028 these tags, Unicode and JIS are converted to the character set specified by 2029 the L</Charset> option. Other encodings are not converted. When writing, 2030 text is stored as ASCII unless the string contains special characters, in 2031 which case it is converted from the specified character set and stored as 2032 Unicode. ExifTool writes Unicode in native EXIF byte ordering by default, 2033 but this may be changed by setting the ExifUnicodeByteOrder tag. The EXIF 2034 "XP" tags (XPTitle, XPComment, etc) are always stored as little-endian 2035 Unicode, and are read and written using the specified character set. 2036 2037 =head2 IPTC 2038 2039 The value of the IPTC:CodedCharacterSet tag determines how the internal IPTC 2040 string values are interpreted. If CodedCharacterSet exists and has a value 2041 of 'UTF8' (or 'ESC % G') then string values are assumed to be stored as 2042 UTF-8, otherwise Windows Latin1 (cp1252, 'Latin') coding is assumed by 2043 default, but this can be changed with the L</CharsetIPTC> option. When 2044 reading, these strings are converted to the character set specified by the 2045 L</Charset> option. When writing, the inverse conversions are performed. 2046 No conversion is done if the internal (IPTC) and external (ExifTool) 2047 character sets are the same. Note that ISO 2022 character set shifting is 2048 not supported. Instead, a warning is issued and the string is not converted 2049 if an ISO 2022 shift code is found. See L<http://www.iptc.org/IIM/> for the 2050 official IPTC specification. 2051 2052 =head2 XMP 2053 2054 Exiftool reads XMP encoded as UTF-8, UTF-16 or UTF-32, and converts them all 2055 to UTF-8 internally. Also, all XML character entity references and numeric 2056 character references are converted. When writing, ExifTool always encodes 2057 XMP as UTF-8, converting the following 5 characters to XML character 2058 references: E<amp> E<lt> E<gt> E<39> E<quot>. By default no further 2059 conversion is performed, however if the L</Charset> option is other than 2060 'UTF8' then text is converted to/from a specified character set when 2061 reading/writing. 2062 2063 =head2 PNG 2064 2065 L<PNG TextualData tags|Image::ExifTool::TagNames/"PNG TextualData Tags"> are 2066 stored as tEXt, zTXt and iTXt chunks in PNG images. The tEXt and zTXt 2067 chunks use ISO 8859-1 encoding, while iTXt uses UTF-8. When reading, 2068 ExifTool converts all PNG textual data to the character set specified by the 2069 L</Charset> option. When writing, ExifTool generates a tEXt chunk (or zTXt 2070 with the L</Compress> option) if the text doesn't contain special characters 2071 or if Latin encoding is specified; otherwise an iTXt chunk is used and the 2072 text is converted from the specified character set and stored as UTF-8. 2073 2074 =head2 ID3 2075 2076 The ID3v1 specification officially supports only ISO 8859-1 encoding (a 2077 subset of Windows Latin1), although some applications may incorrectly use 2078 other character sets. By default ExifTool converts ID3v1 text from Latin to 2079 the character set specified by the </Charset> option. However, the internal 2080 ID3v1 charset may be specified with the L</CharsetID3> option. The encoding 2081 for ID3v2 information is stored in the file, so ExifTool converts ID3v2 text 2082 from this encoding to the character set specified by the L</Charset> option. 2083 ExifTool does not currently write ID3 information. 2084 2085 =head2 PDF 2086 2087 PDF text strings are stored in either PDFDocEncoding (similar to Windows 2088 Latin1) or Unicode (UCS-2). When reading, ExifTool converts to the 2089 character set specified by the L</Charset> option. When writing, ExifTool 2090 encodes input text from the specified character set as Unicode only if the 2091 string contains special characters, otherwise PDFDocEncoding is used. 2092 2093 =head2 MIE 2094 2095 MIE strings are stored as either UTF-8 or ISO 8859-1. When reading, UTF-8 2096 strings are converted according to the L</Charset> option, and ISO 8859-1 2097 strings are never converted. When writing, input strings are converted from 2098 the specified character set to UTF-8. The resulting strings are stored as 2099 UTF-8 if they contain multi-byte UTF-8 character sequences, otherwise they 2100 are stored as ISO 8859-1. 1581 2101 1582 2102 =head1 AUTHOR 1583 2103 1584 Copyright 2003-20 07, Phil Harvey2104 Copyright 2003-2011, Phil Harvey 1585 2105 1586 2106 This library is free software; you can redistribute it and/or modify it 1587 2107 under the same terms as Perl itself. 1588 2108 1589 =head1 CREDITS2109 =head1 ACKNOWLEDGEMENTS 1590 2110 1591 2111 Many 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 2112 reports, comments and suggestions, and/or additions to the code. See the 2113 ACKNOWLEDGEMENTS in the individual Image::ExifTool modules and in 2114 html/index.html of the Image::ExifTool distribution package for a list of 1594 2115 people who have contributed to this project. 1595 2116 -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/AFCP.pm
r16842 r24107 15 15 use Image::ExifTool qw(:DataAccess :Utils); 16 16 17 $VERSION = '1.0 2';17 $VERSION = '1.04'; 18 18 19 19 sub ProcessAFCP($$); … … 28 28 29 29 ExifTool will read and write (but not create) AFCP IPTC information in JPEG 30 images, but not other image formats.30 and TIFF images. 31 31 }, 32 32 IPTC => { SubDirectory => { TagTable => 'Image::ExifTool::IPTC::Main' } }, … … 34 34 Nail => { 35 35 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); 39 44 }, 40 45 }, 41 46 PrVw => { 42 47 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); 46 53 }, 47 54 }, … … 252 259 =head1 AUTHOR 253 260 254 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)261 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 255 262 256 263 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/AIFF.pm
r16842 r24107 5 5 # 6 6 # Revisions: 01/06/2006 - P. Harvey Created 7 # 09/22/2008 - PH Added DjVu support 7 8 # 8 9 # References: 1) http://developer.apple.com/documentation/QuickTime/INMAC/SOUND/imsoundmgr.30.htm#pgfId=3190 … … 18 19 use Image::ExifTool::ID3; 19 20 20 $VERSION = '1.0 1';21 $VERSION = '1.03'; 21 22 22 23 # information for time/date-based tags (time zero is Jan 1, 1904) … … 29 30 # AIFF info 30 31 %Image::ExifTool::AIFF::Main = ( 31 PROCESS_PROC => \&Image::ExifTool::AIFF::ProcessSubChunks,32 32 GROUPS => { 2 => 'Audio' }, 33 33 NOTES => 'Only the tags decoded by ExifTool are listed in this table.', … … 137 137 my ($exifTool, $dirInfo) = @_; 138 138 my $raf = $$dirInfo{RAF}; 139 my $verbose = $exifTool->Options('Verbose'); 140 my ($buff, $err); 139 my ($buff, $err, $tagTablePtr, $page, $type); 141 140 142 141 # verify this is a valid AIFF file 143 142 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 } 146 163 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 151 166 # 152 167 for (;;) { … … 159 174 my $len2 = $len + ($len & 0x01); 160 175 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 } 162 185 $exifTool->HandleTag($tagTablePtr, $tag, $buff, 163 186 DataPt => \$buff, … … 171 194 $pos += $len2; 172 195 } 173 $err and $exifTool->Warn( 'Error reading AIFF file (corrupted?)');196 $err and $exifTool->Warn("Error reading $type file (corrupted?)"); 174 197 return 1; 175 198 } … … 194 217 =head1 AUTHOR 195 218 196 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)219 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 197 220 198 221 This library is free software; you can redistribute it and/or modify it … … 217 240 218 241 =cut 219 -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/APE.pm
r16842 r24107 96 96 97 97 # must first check for leading/trailing ID3 information 98 unless ($exifTool->{D ONE_ID3}) {98 unless ($exifTool->{DoneID3}) { 99 99 require Image::ExifTool::ID3; 100 100 Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1; … … 139 139 my $footPos = -32; 140 140 # (...but before the ID3v1 trailer if it exists) 141 $footPos -= 128 if $exifTool->{D ONE_ID3} == 2;141 $footPos -= 128 if $exifTool->{DoneID3} == 2; 142 142 $raf->Seek($footPos, 2) or return 1; 143 143 $raf->Read($buff, 32) == 32 or return 1; … … 231 231 =head1 AUTHOR 232 232 233 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)233 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 234 234 235 235 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/APP12.pm
r16842 r24107 15 15 use Image::ExifTool qw(:DataAccess); 16 16 17 $VERSION = '1.0 6';17 $VERSION = '1.08'; 18 18 19 19 sub ProcessAPP12($$$); … … 114 114 Avoid => 1, 115 115 # (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")', 118 118 }, 119 119 3 => { #PH … … 123 123 Groups => { 2 => 'Author' }, 124 124 # (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")', 127 127 }, 128 128 ); … … 140 140 my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr); 141 141 my @addTags = sort { $a <=> $b } keys(%$newTags); 142 my $verbose = $exifTool->Options('Verbose');143 my $out = $exifTool->Options('TextOut');144 142 my ($dirEnd, %doneTags); 145 143 if ($dataPt) { … … 173 171 my $tagInfo = $$newTags{$tag}; 174 172 if ($tagInfo) { 175 my $n ewValueHash = $exifTool->GetNewValueHash($tagInfo);173 my $nvHash = $exifTool->GetNewValueHash($tagInfo); 176 174 my $isNew; 177 175 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); 183 178 $isNew = 1; 184 179 } 185 180 } else { 186 next unless Image::ExifTool::IsCreating($n ewValueHash);181 next unless Image::ExifTool::IsCreating($nvHash); 187 182 $isNew = 1; 188 183 } 189 184 if ($isNew) { 190 $val = Image::ExifTool::GetNewValues($n ewValueHash);185 $val = Image::ExifTool::GetNewValues($nvHash); 191 186 ++$exifTool->{CHANGED}; 192 187 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); 197 189 } 198 190 } … … 283 275 unless ($tagInfo) { 284 276 # add new tag to table 285 $tagInfo = { Name => $tag };277 $tagInfo = { Name => ucfirst $tag }; 286 278 # put in Camera group if information in "Camera" section 287 279 $$tagInfo{Groups} = { 2 => 'Camera' } if $section =~ /camera/i; … … 313 305 =head1 AUTHOR 314 306 315 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)307 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 316 308 317 309 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ASF.pm
r16842 r24107 7 7 # 8 8 # References: 1) http://www.microsoft.com/windows/windowsmedia/format/asfspec.aspx 9 # 2) http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart3.pdf (Oct 2008) 9 10 #------------------------------------------------------------------------------ 10 11 … … 15 16 use Image::ExifTool qw(:DataAccess :Utils); 16 17 use Image::ExifTool::Exif; 17 18 $VERSION = '1.05'; 18 use Image::ExifTool::RIFF; 19 20 $VERSION = '1.17'; 19 21 20 22 sub ProcessMetadata($$$); 21 23 sub ProcessContentDescription($$$); 22 sub ProcessP review($$$);24 sub ProcessPicture($$$); 23 25 sub ProcessCodecList($$$); 24 26 … … 63 65 PROCESS_PROC => \&Image::ExifTool::ASF::ProcessASF, 64 66 NOTES => q{ 65 ASF format is used by Windows WMA and WMV files. Tag ID's aren't listed66 because they are huge 128-bit GUID's that would ruin the formatting of this67 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. 68 70 }, 69 71 '75B22630-668E-11CF-A6D9-00AA0062CE6C' => { … … 76 78 'FEB103F8-12AD-4C64-840F-2A1D2F7AD48C' => 'MediaIndex', 77 79 '3CB73FD0-0C4A-4803-953D-EDF7B6228F0C' => 'TimecodeIndex', 80 'BE7ACFCB-97A9-42E8-9C71-999491E3AFAC' => { #2 81 Name => 'XMP', 82 SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' }, 83 }, 78 84 ); 79 85 … … 158 164 BannerImageType => {}, 159 165 BannerImageURL => {}, 160 Bitrate => { },166 Bitrate => { PrintConv => 'ConvertBitrate($val)' }, 161 167 Broadcast => {}, 162 168 BufferAverage => {}, … … 165 171 Copyright => { Groups => { 2 => 'Author' } }, 166 172 CopyrightURL => { Groups => { 2 => 'Author' } }, 167 CurrentBitrate => { },173 CurrentBitrate => { PrintConv => 'ConvertBitrate($val)' }, 168 174 Description => {}, 169 175 DRM_ContentID => {}, … … 183 189 DRM_LicenseAcqURL => {}, 184 190 DRM_V1LicenseAcqURL => {}, 185 Duration => { },191 Duration => { PrintConv => 'ConvertDuration($val)' }, 186 192 FileSize => {}, 187 193 HasArbitraryDataStream => {}, … … 201 207 NSC_Phone => {}, 202 208 NumberOfFrames => {}, 203 OptimalBitrate => { },209 OptimalBitrate => { PrintConv => 'ConvertBitrate($val)' }, 204 210 PeakValue => {}, 205 211 Rating => {}, … … 268 274 ParentalRatingReason => {}, 269 275 PartOfSet => {}, 270 PeakBitrate => { },276 PeakBitrate => { PrintConv => 'ConvertBitrate($val)' }, 271 277 Period => {}, 272 278 Picture => { 273 279 SubDirectory => { 274 TagTable => 'Image::ExifTool::ASF::P review',280 TagTable => 'Image::ExifTool::ASF::Picture', 275 281 }, 276 282 }, … … 313 319 ); 314 320 315 %Image::ExifTool::ASF::P review= (316 PROCESS_PROC => \&ProcessP review,317 GROUPS => { 2 => ' Video' },321 %Image::ExifTool::ASF::Picture = ( 322 PROCESS_PROC => \&ProcessPicture, 323 GROUPS => { 2 => 'Image' }, 318 324 0 => { 319 Name => 'P reviewType',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 => 'Artist s 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', 330 336 9 => 'Conductor', 331 10 => 'Band or orchestra',337 10 => 'Band', 332 338 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', 336 342 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', 339 345 18 => 'Illustration', 340 19 => 'Band or artist logo',341 20 => 'Publisher or studio logo',346 19 => 'Band Logo', 347 20 => 'Publisher Logo', 342 348 }, 343 349 }, 344 1 => 'P reviewMimeType',345 2 => 'P reviewDescription',350 1 => 'PictureMimeType', 351 2 => 'PictureDescription', 346 352 3 => { 347 Name => 'P reviewImage',348 ValueConv => '$self->ValidateImage(\$val,$tag)',353 Name => 'Picture', 354 Binary => 1, 349 355 }, 350 356 ); … … 358 364 ValueConv => 'Image::ExifTool::ASF::GetGUID($val)', 359 365 }, 360 16 => { Name => 'File Size',Format => 'int64u' },366 16 => { Name => 'FileLength', Format => 'int64u' }, 361 367 24 => { 362 368 Name => 'CreationDate', … … 374 380 Format => 'int64u', 375 381 ValueConv => '$val / 1e7', 376 PrintConv => ' "$val sec"',382 PrintConv => 'ConvertDuration($val)', 377 383 }, 378 384 48 => { … … 380 386 Format => 'int64u', 381 387 ValueConv => '$val / 1e7', 382 PrintConv => ' "$val sec"',388 PrintConv => 'ConvertDuration($val)', 383 389 }, 384 390 56 => { Name => 'Preroll', Format => 'int64u' }, … … 386 392 68 => { Name => 'MinPacketSize',Format => 'int32u' }, 387 393 72 => { Name => 'MaxPacketSize',Format => 'int32u' }, 388 76 => { Name => 'MaxBitrate', Format => 'int32u' },394 76 => { Name => 'MaxBitrate', Format => 'int32u', PrintConv => 'ConvertBitrate($val)' }, 389 395 ); 390 396 … … 414 420 Format => 'int64u', 415 421 ValueConv => '$val / 1e7', 416 PrintConv => '"$val s ec"',422 PrintConv => '"$val s"', 417 423 }, 418 424 48 => { … … 427 433 Format => 'int16u', 428 434 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, 544 437 }, 545 438 { … … 624 517 { 625 518 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 626 my $verbose = $exifTool->Options('Verbose');627 519 my $dataPt = $$dirInfo{DataPt}; 628 520 my $dirLen = $$dirInfo{DirLen}; … … 635 527 next unless $len; 636 528 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'); 638 530 $exifTool->HandleTag($tagTablePtr, $tag, $val); 639 531 $pos += $len; … … 649 541 { 650 542 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 651 my $verbose = $exifTool->Options('Verbose');652 543 my $dataPt = $$dirInfo{DataPt}; 653 544 my $dirLen = $$dirInfo{DirLen}; … … 681 572 my @vals; 682 573 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'); 684 575 } elsif ($format == 2) { # 4-byte boolean 685 576 @vals = ReadValue($dataPt, $pos, 'int32u', undef, $size); … … 706 597 { 707 598 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 708 my $verbose = $exifTool->Options('Verbose');709 599 my $dataPt = $$dirInfo{DataPt}; 710 600 my $dirLen = $$dirInfo{DirLen}; … … 719 609 $pos += 2; 720 610 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'); 722 612 $tag =~ s/^WM\///; # remove leading "WM/" 723 613 $pos += $nameLen; … … 738 628 # Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table reference 739 629 # Returns: 1 on success 740 sub ProcessP review($$$)630 sub ProcessPicture($$$) 741 631 { 742 632 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 743 my $verbose = $exifTool->Options('Verbose');744 633 my $dataPt = $$dirInfo{DataPt}; 745 634 my $dirStart = $$dirInfo{DirStart}; … … 755 644 if ($str =~ /^((?:..)*?)\0\0((?:..)*?)\0\0/) { 756 645 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; 759 648 } 760 649 $exifTool->HandleTag($tagTablePtr, 3, substr($$dataPt, $dirStart+5+$n, $picLen)); … … 769 658 { 770 659 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 771 my $verbose = $exifTool->Options('Verbose');772 660 my $dataPt = $$dirInfo{DataPt}; 773 661 my $dirLen = $$dirInfo{DirLen}; … … 785 673 $pos += 4; 786 674 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'); 788 676 $exifTool->HandleTag($tagTablePtr, "${type}Name", $name); 789 677 my $descLen = Get16u($dataPt, $pos + $nameLen) * 2; 790 678 $pos += $nameLen + 2; 791 679 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'); 793 681 $exifTool->HandleTag($tagTablePtr, "${type}Description", $desc); 794 682 my $infoLen = Get16u($dataPt, $pos + $descLen); … … 805 693 { 806 694 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 807 my $verbose = $exifTool->Options('Verbose');808 695 my $dataPt = $$dirInfo{DataPt}; 809 696 my $dirLen = $$dirInfo{DirLen}; … … 818 705 $pos += 12; 819 706 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'); 821 708 my $val = ReadASF($exifTool,$dataPt,$pos+$nameLen,$dType,$dLen); 822 709 $exifTool->HandleTag($tagTablePtr, $tag, $val, … … 841 728 my $rtnVal = 0; 842 729 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 850 732 for (;;) { 851 733 last unless $raf->Read($buff, 24) == 24; … … 856 738 last unless $tag eq '75B22630-668E-11CF-A6D9-00AA0062CE6C'; 857 739 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)$/; 859 741 $exifTool->SetFileType($fileType); 860 742 SetByteOrder('II'); … … 868 750 } 869 751 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 } 871 764 last; 872 765 } … … 876 769 $tagTablePtr = pop @parentTable; 877 770 $exifTool->{INDENT} = substr($exifTool->{INDENT},0,-2); 878 $dumpParms{Prefix} = $exifTool->{INDENT};879 771 } 880 772 my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag); … … 889 781 if ($verbose > 2) { 890 782 $raf->Read($buff, $s) == $s or $err = 'Truncated file', last; 891 Image::ExifTool::HexDump(\$buff, undef, %dumpParms);783 $exifTool->VerboseDump(\$buff); 892 784 } elsif (not $raf->Seek($s, 1)) { 893 785 $err = 'Seek error'; … … 901 793 if ($verbose) { 902 794 $exifTool->{INDENT} .= '| '; 903 $dumpParms{Prefix} = $exifTool->{INDENT};904 795 $exifTool->VerboseDir($$tagInfo{Name}); 905 796 } … … 913 804 DirName => $$tagInfo{Name}, 914 805 ); 915 if ($verbose > 2) { 916 Image::ExifTool::HexDump(\$buff, undef, %dumpParms); 917 } 806 $exifTool->VerboseDump(\$buff) if $verbose > 2; 918 807 unless ($exifTool->ProcessDirectory(\%subdirInfo, $subTable)) { 919 808 $exifTool->Warn("Error processing $$tagInfo{Name} directory"); … … 929 818 if ($verbose > 2) { 930 819 $raf->Read($buff, $size) == $size or $err = 'Truncated file', last; 931 Image::ExifTool::HexDump(\$buff, undef, %dumpParms);820 $exifTool->VerboseDump(\$buff); 932 821 } elsif (not $raf->Seek($size, 1)) { # skip the block 933 822 $err = 'Seek error'; … … 960 849 =head1 AUTHOR 961 850 962 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)851 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 963 852 964 853 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BMP.pm
r16842 r24107 16 16 use Image::ExifTool qw(:DataAccess :Utils); 17 17 18 $VERSION = '1.0 2';18 $VERSION = '1.07'; 19 19 20 20 # BMP chunks 21 21 %Image::ExifTool::BMP::Main = ( 22 22 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 23 GROUPS => { 2 => 'Image' },23 GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' }, 24 24 NOTES => q{ 25 25 There really isn't much meta information in a BMP file as such, just a bit 26 26 of image related information. 27 27 }, 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', 28 35 4 => { 29 36 Name => 'ImageWidth', … … 32 39 8 => { 33 40 Name => 'ImageHeight', 34 Format => 'int32u', 41 Format => 'int32s', # (negative when stored in top-to-bottom order) 42 ValueConv => 'abs($val)', 35 43 }, 36 44 12 => { … … 54 62 4 => 'JPEG', #2 55 63 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 }, 56 71 }, 57 72 }, … … 80 95 ); 81 96 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 82 109 #------------------------------------------------------------------------------ 83 110 # Extract EXIF information from a BMP image … … 88 115 my ($exifTool, $dirInfo) = @_; 89 116 my $raf = $$dirInfo{RAF}; 90 my $buff;117 my ($buff, $tagTablePtr); 91 118 92 119 # verify this is a valid BMP file 93 return 0 unless $raf->Read($buff, 1 4) == 14;120 return 0 unless $raf->Read($buff, 18) == 18; 94 121 return 0 unless $buff =~ /^BM/; 95 return 0 unless $raf->Read($buff, 40) == 40;96 122 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; 98 126 $exifTool->SetFileType(); # set the FileType tag 99 127 my %dirInfo = ( … … 102 130 DirLen => length($buff), 103 131 ); 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 } 105 137 $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr); 106 138 return 1; … … 126 158 =head1 AUTHOR 127 159 128 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)160 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 129 161 130 162 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BigTIFF.pm
r16842 r24107 16 16 use Image::ExifTool::Exif; 17 17 18 $VERSION = '1.0 0';18 $VERSION = '1.05'; 19 19 20 20 my $maxOffset = 0x7fffffff; # currently supported maximum data offset/size … … 37 37 # loop through IFD chain 38 38 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)'); 41 41 last; 42 42 } … … 65 65 $raf->Read($nextIFD, 8) == 8 or undef $nextIFD; # try to read next IFD pointer 66 66 if ($htmlDump) { 67 $exifTool->H tmlDump($bufPos-8, 8, "$dirName entries", "Entry count: $numEntries");67 $exifTool->HDump($bufPos-8, 8, "$dirName entries", "Entry count: $numEntries"); 68 68 if (defined $nextIFD) { 69 69 my $tip = sprintf("Offset: 0x%.8x", Image::ExifTool::Get64u(\$nextIFD, 0)); 70 $exifTool->H tmlDump($bufPos + 20 * $numEntries, 8, "Next IFD", $tip, 0);70 $exifTool->HDump($bufPos + 20 * $numEntries, 8, "Next IFD", $tip, 0); 71 71 } 72 72 } … … 79 79 my $formatSize = $Image::ExifTool::Exif::formatSize[$format]; 80 80 unless (defined $formatSize) { 81 $exifTool->H tmlDump($bufPos+$entry,20,"[invalid IFD entry]",81 $exifTool->HDump($bufPos+$entry,20,"[invalid IFD entry]", 82 82 "Bad format value: $format", 1); 83 83 # warn unless the IFD was just padded with zeros … … 88 88 my $size = $count * $formatSize; 89 89 my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID); 90 next unless $tagInfo or $verbose;90 next unless defined $tagInfo or $verbose; 91 91 my $valuePtr = $entry + 12; 92 92 my ($valBuff, $valBase); 93 93 if ($size > 8) { 94 94 if ($size > $maxOffset) { 95 $exifTool->Warn("Can't yethandle $dirName entry $index (huge size)");95 $exifTool->Warn("Can't handle $dirName entry $index (huge size)"); 96 96 next; 97 97 } 98 98 $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)"); 101 101 next; 102 102 } … … 110 110 $valBase = $bufPos; 111 111 } 112 if (defined $tagInfo and not $tagInfo) { 113 # GetTagInfo() required the value for a Condition 114 $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$valBuff); 115 } 112 116 my $val = ReadValue(\$valBuff, 0, $formatStr, $count, $size); 113 117 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 } 114 125 my ($tagName, $colName); 115 126 if ($tagID == 0x927c and $dirName eq 'ExifIFD') { … … 122 133 my $dname = sprintf("$dirName-%.2d", $index); 123 134 # 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"; 126 137 if ($size > 8) { 127 $tip .= sprintf("Value offset: 0x%.8x\ \n", $valuePtr);138 $tip .= sprintf("Value offset: 0x%.8x\n", $valuePtr); 128 139 $colName = "<span class=H>$tagName</span>"; 129 140 } else { 130 141 $colName = $tagName; 131 142 } 132 my $tval = (length $val < 32) ? $val : substr($val,0,28) . '[...]';143 $tval = substr($tval,0,28) . '[...]' if length($tval) > 32; 133 144 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/./; 138 147 } elsif ($tagInfo and Image::ExifTool::IsInt($tval)) { 139 148 if ($$tagInfo{IsOffset}) { … … 144 153 } 145 154 $tip .= "Value: $tval"; 146 $exifTool->H tmlDump($entry+$bufPos, 20, "$dname $colName", $tip, 1);155 $exifTool->HDump($entry+$bufPos, 20, "$dname $colName", $tip, 1); 147 156 if ($size > 8) { 148 157 # add value data block 149 158 my $flg = ($tagInfo and $$tagInfo{SubDirectory} and $$tagInfo{MakerNotes}) ? 4 : 0; 150 $exifTool->H tmlDump($valuePtr,$size,"$tagName value",'SAME', $flg);159 $exifTool->HDump($valuePtr,$size,"$tagName value",'SAME', $flg); 151 160 } 152 161 } … … 189 198 RAF => $raf, 190 199 ); 191 $tagKey and $exifTool->SetGroup 1($tagKey, $dirName);200 $tagKey and $exifTool->SetGroup($tagKey, $dirName); 192 201 } 193 202 } … … 222 231 if ($exifTool->{HTML_DUMP}) { 223 232 my $o = (GetByteOrder() eq 'II') ? 'Little' : 'Big'; 224 $exifTool->H tmlDump(0, 8, "BigTIFF header", "Byte order: $o endian", 0);225 $exifTool->H tmlDump(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); 226 235 } 227 236 my %dirInfo = ( … … 256 265 =head1 AUTHOR 257 266 258 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)267 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 259 268 260 269 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BuildTagLookup.pm
r16842 r24107 19 19 BEGIN { 20 20 # 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 22 23 } 23 24 24 25 use vars qw($VERSION @ISA); 25 26 use Image::ExifTool qw(:Utils :Vars); 27 use Image::ExifTool::Exif; 26 28 use Image::ExifTool::Shortcuts; 27 29 use Image::ExifTool::HTML qw(EscapeHTML); 28 30 use Image::ExifTool::IPTC; 31 use Image::ExifTool::XMP; 29 32 use Image::ExifTool::Canon; 30 33 use Image::ExifTool::Nikon; 31 34 32 $VERSION = ' 1.59';35 $VERSION = '2.28'; 33 36 @ISA = qw(Exporter); 34 37 35 38 sub NumbersFirst; 39 40 my $numbersFirst = 1; # set to -1 to sort numbers last 41 42 # list of all tables in plug-in modules 43 my @pluginTables = ('Image::ExifTool::MWG::Composite'); 36 44 37 45 # colors for html pages … … 43 51 }; 44 52 53 my $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) 58 my %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 ); 45 86 46 87 my $caseInsensitive; # flag to ignore case when sorting tag names 47 88 48 89 # Descriptions for the TagNames documentation 90 # (descriptions may also be defined in tag table NOTES) 49 91 # Note: POD headers in these descriptions start with '~' instead of '=' to keep 50 92 # from confusing POD parsers which apparently parse inside quoted strings. … … 58 100 59 101 This document contains a complete list of ExifTool tag names, organized into 60 tables based on information type. Tag names are used to indicate the61 specific meta information that is extracted or written in an image.102 tables based on information type. Tag names are used to reference specific 103 meta information extracted from or written to a file. 62 104 63 105 ~head1 TAG TABLES … … 77 119 tag ID. In these cases, the actual name used depends on the context in 78 120 which 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 not80 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 some82 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>.121 question mark (C<?>) after a tag name indicates that the information is 122 either not understood, not verified, or not very useful -- these tags are 123 not extracted by ExifTool unless the Unknown (-u) option is enabled. Be 124 aware that some tag names are different than the descriptions printed out by 125 default when extracting information with exiftool. To see the tag names 126 instead of the descriptions, use C<exiftool -s>. 85 127 86 128 The B<Writable> column indicates whether the tag is writable by ExifTool. … … 93 135 (including a null terminator which is added if required). 94 136 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. 137 A 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 139 added and deleted. A slash (C</>) indicates an "avoided" tag that is not 140 created when writing if another same-named tag may be created instead. To 141 write these tags, the group should be specified. A tilde (C<~>) indicates a 142 tag this is writable only when the print conversion is disabled (by setting 143 PrintConv to 0, using the -n option, or suffixing the tag name with a C<#> 144 character). An exclamation point (C<!>) indicates a tag that is considered 145 unsafe to write under normal circumstances. These "unsafe" tags are not set 146 when calling SetNewValuesFromFile() or copied with the exiftool 147 -tagsFromFile option unless specified explicitly, and care should be taken 148 when editing them manually since they may affect the way an image is 149 rendered. An asterisk (C<*>) indicates a "protected" tag which is not 150 writable directly, but is written automatically by ExifTool (often when a 151 corresponding Composite or Extra tag is written). A colon (C<:>) indicates 152 a mandatory tag which may be added automatically when writing. 153 154 The HTML version of these tables also lists possible B<Values> for 155 discrete-valued tags, as well as B<Notes> for some tags. The B<Values> are 156 listed as the computer-readable and human-readable values on the left and 157 right hand side of an equals sign (C<=>) respectively. The human-readable 158 values are used by default when reading and writing, but the 159 computer-readable values may be accessed by disabling the value conversion 160 with the -n option on the command line, by setting the ValueConv option to 0 161 in the API, or or on a per-tag basis by appending a number symbol (C<#>) to 162 the tag name. 110 163 111 164 B<Note>: If you are familiar with common meta-information tag names, you may … … 119 172 EXIF stands for "Exchangeable Image File Format". This type of information 120 173 is 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. 174 TIFF, PNG, PGF, MIFF, HDP, PSP and XCF images, as well as many TIFF-based 175 RAW images, and even some AVI and MOV videos. 122 176 123 177 The EXIF meta information is organized into different Image File Directories … … 126 180 B<Group> listed below is used unless another group is specified. 127 181 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. 182 The table below lists all EXIF tags. Also listed are TIFF, DNG, HDP and 183 other tags which are not part of the EXIF specification, but may co-exist 184 with EXIF tags in some images. Tags which are part of the EXIF 2.3 185 specification have an underlined B<Tag Name> in the HTML version of this 186 documentation. See 187 L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-008-2010_E.pdf> for the 188 official EXIF 2.3 specification. 131 189 }, 132 190 GPS => q{ … … 144 202 automatically by ExifTool. Remember that the descriptive values are used 145 203 when 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). 204 disabled (with '-n' on the command line or the PrintConv option in the API, 205 or by suffixing the tag name with a C<#> character). 206 207 When adding GPS information to an image, it is important to set all of the 208 following tags: GPSLatitude, GPSLatitudeRef, GPSLongitude, GPSLongitudeRef, 209 GPSAltitude and GPSAltitudeRef. ExifTool will write the required 210 GPSVersionID tag automatically if new a GPS IFD is added to an image. 148 211 }, 149 212 XMP => q{ 150 213 XMP stands for "Extensible Metadata Platform", an XML/RDF-based metadata 151 214 format 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. 215 embedded in many different image file types including JPG, JP2, TIFF, GIF, 216 EPS, PDF, PSD, IND, PNG, DJVU, SVG, PGF, MIFF, XCF, CRW, DNG and a variety 217 of proprietary TIFF-based RAW images, as well as MOV, AVI, ASF, WMV, FLV, 218 SWF and MP4 videos, and WMA and audio formats supporting ID3v2 information. 155 219 156 220 The XMP B<Tag ID>'s aren't listed because in most cases they are identical 157 to the B<Tag Name>. 221 to the B<Tag Name> (aside from differences in case). Tags with different 222 ID's are mentioned in the B<Notes> column of the HTML version of this 223 document. 158 224 159 225 All 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. 226 specifies the information format: C<string> is an unformatted string, 227 C<integer> is a string of digits (possibly beginning with a '+' or '-'), 228 C<real> is a floating point number, C<rational> is entered as a floating 229 point number but stored as two C<integer> strings separated by a '/' 230 character, C<date> is a date/time string entered in the format "YYYY:mm:dd 231 HH:MM:SS[.ss][+/-HH:MM]", C<boolean> is either "True" or "False", 232 C<lang-alt> indicates that the tag supports alternate languages (see below), 233 and C<struct> is an XMP structure. When reading, structures are extracted 234 only if the Struct (-struct) option is used. Otherwise the corresponding 235 "flattened" tags, indicated by an underline (C<_>) after the B<Writable> 236 type, are extracted. When copying information, the Struct option is in 237 effect by default. When writing, the Struct option has no effect, and both 238 structured and flattened tags may be written. See 239 L<http://owl.phy.queensu.ca/~phil/exiftool/struct.html> for more details. 166 240 167 241 Individual languages for C<lang-alt> tags are accessed by suffixing the tag 168 242 name 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 the170 "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 w rite only the default language, but note that all languages are still173 deleted if "x-default" tag is deleted. When reading, "x-default" is not 174 specified.243 or "Rights-en-US"). (See L<http://www.ietf.org/rfc/rfc3066.txt> for the RFC 244 3066 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 246 when writing. The "x-default" language code may be specified when writing 247 to preserve other existing languages (ie. "XMP-dc:Description-x-default"). 248 When reading, "x-default" is not specified. 175 249 176 250 The XMP tags are organized according to schema B<Namespace> in the following … … 180 254 more than one namespace, less common namespaces are avoided when writing. 181 255 However, any namespace may be written by specifying a family 1 group name 182 for the tag, ie) XMP-exif:Contrast or XMP-crs:Contrast. 256 for the tag, ie) XMP-exif:Contrast or XMP-crs:Contrast. When deciding on 257 which tags to add to an image, using standard schemas such as 258 L<dc|/XMP dc Tags>, L<xmp|/XMP xmp Tags> or L<iptc|/XMP iptcCore Tags> is 259 recommended if possible. 260 261 For structures, the heading of the first column is B<Field Name>. Field 262 names are very similar to tag names, except they are used to identify fields 263 inside structures instead of stand-alone tags. See 264 L<the Field Name section of the Structured Information documentation|http://owl.phy.queensu.ca/~phil/exiftool/struct.html#Fields> for more 265 details. 183 266 184 267 ExifTool will extract XMP information even if it is not listed in these 185 268 tables. For example, the C<pdfx> namespace doesn't have a predefined set of 186 269 tag names because it is used to store application-defined PDF information, 187 but this information is extracted by ExifTool anyway. 270 but this information is extracted by ExifTool. 271 272 See L<http://www.adobe.com/devnet/xmp/> for the official XMP specification. 188 273 }, 189 274 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. 275 The tags listed below are part of the International Press Telecommunications 276 Council (IPTC) and the Newspaper Association of America (NAA) Information 277 Interchange Model (IIM). This is an older meta information format, slowly 278 being phased out in favor of XMP. (In fact, the newer IPTCCore 279 specification actually uses XMP format!) IPTC information may be embedded 280 in JPG, TIFF, PNG, MIFF, PS, PDF, PSD, XCF and DNG images. 200 281 201 282 IPTC information is separated into different records, each of which has its 202 own set of tags. 283 own set of tags. See 284 L<http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf> for the 285 official specification. 286 287 This specification dictates a length for ASCII (C<string> or C<digits>) and 288 binary (C<undef>) values. These lengths are given in square brackets after 289 the B<Writable> format name. For tags where a range of lengths is allowed, 290 the minimum and maximum lengths are separated by a comma within the 291 brackets. IPTC strings are not null terminated. When writing, ExifTool 292 issues a minor warning and truncates the value if it is longer than allowed 293 by the IPTC specification. Minor errors may be ignored with the 294 IgnoreMinorErrors (-m) option, allowing longer values to be written, but 295 beware that values like this may cause problems for some other IPTC readers. 296 297 Separate IPTC date and time tags may be written with a combined date/time 298 value and ExifTool automagically takes the appropriate part of the date/time 299 string depending on whether a date or time tag is being written. This is 300 very useful when copying date/time values to IPTC from other metadata 301 formats. 302 303 IPTC time values include a timezone offset. If written with a value which 304 doesn'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 306 offset at the specified date/time is used, which may be different due to 307 changes in daylight savings time). 203 308 }, 204 309 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). 310 Photoshop tags are found in PSD and PSB files, as well as inside embedded 311 Photoshop information in many other file types (JPEG, TIFF, PDF, PNG to name 312 a few). 207 313 208 314 Many Photoshop tags are marked as Unknown (indicated by a question mark 209 315 after the tag name) because the information they provide is not very useful 210 under normal circumstances (and because Adobe denied my application for316 under normal circumstances I<[and because Adobe denied my application for 211 317 their file format documentation -- apparently open source software is too 212 big a concept for them ). These unknown tags are not extracted unless the318 big a concept for them]>. These unknown tags are not extracted unless the 213 319 Unknown (-u) option is used. 214 320 }, … … 217 323 been decoded. Use the Unknown (-u) option to extract PrintIM information. 218 324 }, 325 GeoTiff => q{ 326 ExifTool extracts the following tags from GeoTIFF images. See 327 L<http://www.remotesensing.org/geotiff/spec/geotiffhome.html> for the 328 complete GeoTIFF specification. 329 }, 330 JFIF => q{ 331 The following information is extracted from the JPEG JFIF header. See 332 L<http://www.jpeg.org/public/jfif.pdf> for the JFIF 1.02 specification. 333 }, 219 334 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.335 Many Kodak models don't store the maker notes in standard IFD format, and 336 these formats vary with different models. Some information has been 337 decoded, but much of the Kodak information remains unknown. 223 338 }, 224 339 'Kodak SpecialEffects' => q{ … … 227 342 }, 228 343 Minolta => q{ 229 These tags are used by Minolta and Konica/Minolta cameras. Minolta doesn't230 make things easy for decoders because the meaning of some tags and the231 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.)344 These tags are used by Minolta, Konica/Minolta as well as some Sony cameras. 345 Minolta doesn't make things easy for decoders because the meaning of some 346 tags and the location where some information is stored is different for 347 different camera models. (Take MinoltaQuality for example, which may be 348 located in 5 different places.) 234 349 }, 235 350 Olympus => q{ … … 239 354 }, 240 355 Panasonic => q{ 241 Panasonic tags are also used forLeica cameras.356 These tags are used in Panasonic/Leica cameras. 242 357 }, 243 358 Pentax => q{ 244 The Pentax tags are also used inAsahi cameras.359 These tags are used in Pentax/Asahi cameras. 245 360 }, 246 361 Sigma => q{ … … 248 363 }, 249 364 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. 365 The maker notes in images from most recent Sony camera models contain a 366 wealth of information, but for some models very little has been decoded. 367 Use the ExifTool Unknown (-u) or Verbose (-v) options to see information 368 about the unknown tags. Also see the Minolta tags which are used by some 369 Sony models. 254 370 }, 255 371 CanonRaw => q{ … … 259 375 or padded as required) unless B<Writable> is C<resize>. Currently, only 260 376 JpgFromRaw and ThumbnailImage are allowed to change size. 377 378 CRW images also support the addition of a CanonVRD trailer, which in turn 379 supports XMP. This trailer is created automatically if necessary when 380 ExifTool is used to write XMP to a CRW image. 261 381 }, 262 382 Unknown => q{ … … 267 387 The tags listed in the PDF tables below are those which are used by ExifTool 268 388 to extract meta information, but they are only a small fraction of the total 269 number of available PDF tags. 389 number of available PDF tags. See 390 L<http://www.adobe.com/devnet/pdf/pdf_reference.html> for the official PDF 391 specification. 392 393 ExifTool supports reading and writing PDF documents up to version 1.7 394 extension level 3, including support for RC4, AES-128 and AES-256 395 encryption. A Password option is provided to allow processing of 396 password-protected PDF files. 397 398 When writing PDF files, ExifTool uses an incremental update. This has the 399 advantages of being fast and reversible. The original PDF can be easily 400 recovered by deleting the C<PDF-update> pseudo-group (with 401 C<-PDF-update:all=> on the command line). But there are two main 402 disadvantages to this technique: 403 404 1) A linearized PDF file is no longer linearized after the update, so it 405 must be subsequently re-linearized if this is required. 406 407 2) All metadata edits are reversible. While this would normally be 408 considered an advantage, it is a potential security problem because old 409 information is never actually deleted from the file. 270 410 }, 271 411 DNG => q{ 272 412 The 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. 413 information found within structures of these main DNG tag values. See 414 L<http://www.adobe.com/products/dng/> for the official DNG specification. 274 415 }, 275 416 MPEG => q{ … … 284 425 }, 285 426 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. 427 The extra tags represent extra information extracted or generated by 428 ExifTool that is not directly associated with another tag group. The three 429 writable "pseudo" tags (FileName, Directory and FileModifyDate) may be 430 written without the need to rewrite the file since their values are not 431 contained within the file data. These "pseudo" tags belong to the family 1 432 "System" group. 290 433 }, 291 434 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 i s extracted.435 The values of the composite tags are B<Derived From> the values of other 436 tags. These are convenience tags which are calculated after all other 437 information is extracted. 295 438 }, 296 439 Shortcuts => q{ … … 300 443 301 444 The shortcut tags below have been pre-defined, but user-defined shortcuts 302 may be added via the %Image::ExifTool:: Shortcuts::UserDefinedlookup in the445 may be added via the %Image::ExifTool::UserDefined::Shortcuts lookup in the 303 446 ~/.ExifTool_config file. See the Image::ExifTool::Shortcuts documentation 304 447 for more details. … … 312 455 ~head1 AUTHOR 313 456 314 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)457 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 315 458 316 459 This library is free software; you can redistribute it and/or modify it … … 325 468 ); 326 469 470 # notes for Shortcuts tags 471 my %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) 490 my %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 519 my %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 ); 327 526 328 527 #------------------------------------------------------------------------------ … … 335 534 my $class = ref($that) || $that || 'Image::ExifTool::BuildTagLookup'; 336 535 my $self = bless {}, $class; 337 my (%subdirs, %isShortcut );536 my (%subdirs, %isShortcut, %allStructs); 338 537 my %count = ( 339 538 'unique tag names' => 0, … … 344 543 # 345 544 my (%tagNameInfo, %id, %longID, %longName, %shortName, %tableNum, 346 %tagLookup, %tagExists, %tableWritable, %sepTable, %compositeModules); 545 %tagLookup, %tagExists, %tableWritable, %sepTable, %structs, 546 %compositeModules, %isPlugin, %flattened, %structLookup); 347 547 $self->{TAG_NAME_INFO} = \%tagNameInfo; 348 $self->{ TAG_ID} = \%id;548 $self->{ID_LOOKUP} = \%id; 349 549 $self->{LONG_ID} = \%longID; 350 550 $self->{LONG_NAME} = \%longName; … … 353 553 $self->{TAG_LOOKUP} = \%tagLookup; 354 554 $self->{TAG_EXISTS} = \%tagExists; 555 $self->{FLATTENED} = \%flattened; 355 556 $self->{TABLE_WRITABLE} = \%tableWritable; 356 557 $self->{SEPARATE_TABLE} = \%sepTable; 558 $self->{STRUCTURES} = \%structs; 559 $self->{STRUCT_LOOKUP} = \%structLookup; # lookup for Struct hash ref based on Struct name 357 560 $self->{COMPOSITE_MODULES} = \%compositeModules; 358 561 $self->{COUNT} = \%count; … … 360 563 Image::ExifTool::LoadAllTables(); 361 564 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 363 574 my $tableNum = 0; 364 my $tableName; 575 my $exifTool = new Image::ExifTool; 576 my ($tableName, $tag); 365 577 # create lookup for short table names 366 578 foreach $tableName (@tableNames) { … … 369 581 $short =~ s/::Main$//; 370 582 $short =~ s/::/ /; 371 $short =~ s/ (.*)Tags$/\u$1/;583 $short =~ s/^(.+)Tags$/\u$1/ unless $short eq 'Nikon AVITags'; 372 584 $short =~ s/^Exif\b/EXIF/; 373 585 $shortName{$tableName} = $short; # remember short name 374 586 $tableNum{$tableName} = $tableNum++; 375 587 } 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 } 376 593 # make lookup table to check for shortcut tags 377 my $tag;378 594 foreach $tag (keys %Image::ExifTool::Shortcuts::Main) { 379 595 my $entry = $Image::ExifTool::Shortcuts::Main{$tag}; … … 386 602 my $short = $shortName{$tableName}; 387 603 my $info = $tagNameInfo{$tableName} = [ ]; 388 my ($table, $shortcut); 604 my $isPlugin = $isPlugin{$tableName}; 605 my ($table, $shortcut, %isOffset, %datamember, %hasSubdir); 389 606 if ($short eq 'Shortcuts') { 390 607 # can't use GetTagTable() for Shortcuts (not a normal table) 391 608 $table = \%Image::ExifTool::Shortcuts::Main; 392 609 $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; 393 615 } else { 394 616 $table = GetTagTable($tableName); 395 617 } 396 618 my $tableNum = $tableNum{$tableName}; 397 my $writeProc = $table->{WRITE_PROC}; 619 my $writeProc = $$table{WRITE_PROC}; 620 my $vars = $$table{VARS} || { }; 398 621 $longID{$tableName} = 0; 399 622 $longName{$tableName} = 0; 400 623 # 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) { 408 640 $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'; 415 642 } elsif ($isIPTC and $$table{PROCESS_PROC}) { #only the main IPTC table has a PROCESS_PROC 416 643 $id{$tableName} = 'Record'; … … 418 645 $id{$tableName} = 'Tag ID'; 419 646 } 420 $caseInsensitive = ($tableName =~ /::XMP::/); 647 $caseInsensitive = $isXMP; 648 $numbersFirst = -1 if $$table{VARS} and $$table{VARS}{ALPHA_FIRST}; 421 649 my @keys = sort NumbersFirst TagTableKeys($table); 650 $numbersFirst = 1; 422 651 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 428 655 TagID: foreach $tagID (@keys) { 429 656 my ($tagInfo, @tagNames, $subdir, $format, @values); … … 431 658 if ($shortcut) { 432 659 # 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 }; 434 666 my $i; 435 667 for ($i=0; $i<@{$$table{$tagID}}; ++$i) { … … 442 674 $format = $defFormat; 443 675 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 } 444 761 if ($$tagInfo{Notes}) { 445 762 my $note = $$tagInfo{Notes}; … … 449 766 $note =~ s/(^[ \t]+|[ \t]+$)//mg; 450 767 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 } 457 775 } 458 776 my $writeGroup; … … 462 780 $writeGroup = '-' unless $writeGroup; 463 781 } 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; 470 793 push @values, $shortName{$subTable} 471 } else { 472 $subdir = 0; 794 } elsif ($struct) { 795 push @values, $struct; 796 $structs{$struct} = 1; 473 797 } 474 798 my $type; 475 799 foreach $type ('Require','Desire') { 476 800 my $require = $$tagInfo{$type}; 477 if ( $require) {801 if (ref $require) { 478 802 foreach (sort { $a <=> $b } keys %$require) { 479 803 push @require, $$require{$_}; 480 804 } 805 } elsif ($require) { 806 push @require, $require; 481 807 } 482 808 } 483 809 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 } 484 828 if (ref($printConv) =~ /^(HASH|ARRAY)$/) { 485 829 my (@printConvList, @indexList, $index); … … 487 831 for ($index=0; $index<@$printConv; ++$index) { 488 832 next if ref $$printConv[$index] ne 'HASH'; 833 next unless %{$$printConv[$index]}; 489 834 push @printConvList, $$printConv[$index]; 490 835 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 } 491 846 } 492 847 $printConv = shift @printConvList; … … 494 849 } 495 850 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 } 497 879 if ($$tagInfo{SeparateTable}) { 498 880 $subdir = 1; 499 881 my $s = $$tagInfo{SeparateTable}; 500 $s = $ $tagInfo{Name}if $s eq '1';882 $s = $name if $s eq '1'; 501 883 # add module name if not specified 502 884 $s =~ / / or ($short =~ /^(\w+)/ and $s = "$1 $s"); … … 505 887 # add PrintHex flag to PrintConv so we can check it later 506 888 $$printConv{PrintHex} = 1 if $$tagInfo{PrintHex}; 889 $$printConv{PrintString} = 1 if $$tagInfo{PrintString}; 507 890 } else { 508 891 $caseInsensitive = 0; 509 892 my @pk = sort NumbersFirst keys %$printConv; 510 my $bits; 893 my $n = scalar @values; 894 my ($bits, $cols, $i); 511 895 foreach (@pk) { 512 896 next if $_ eq ''; 513 897 $_ eq 'BITMASK' and $bits = $$printConv{$_}, next; 898 $_ eq 'OTHER' and next; 514 899 my $index; 515 if ( $$tagInfo{PrintHex}) {900 if (($$tagInfo{PrintHex} or $$printConv{BITMASK}) and /^\d+$/) { 516 901 $index = sprintf('0x%x',$_); 517 } elsif (/^[ -+]?\d+$/) {902 } elsif (/^[+-]?(?=\d|\.\d)\d*(\.\d*)?$/ and not $$tagInfo{PrintString}) { 518 903 $index = $_; 519 904 } 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 } 523 912 } 524 913 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 } 525 918 } 526 919 if ($bits) { … … 530 923 } 531 924 } 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> </td>'; 937 } 938 push @values, $v . "</tr></table>\n"; 939 } 532 940 } 533 941 last unless @printConvList; … … 536 944 } 537 945 } elsif ($printConv and $printConv =~ /DecodeBits\(\$val,\s*(\{.*\})\s*\)/s) { 946 $$self{Model} = ''; # needed for Nikon ShootingMode 538 947 my $bits = eval $1; 948 delete $$self{Model}; 539 949 if ($@) { 540 950 warn $@; … … 548 958 if ($subdir and not $$tagInfo{SeparateTable}) { 549 959 # 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; 551 963 } else { 552 964 # not writable if we can't do the inverse conversions … … 585 997 } 586 998 $writable .= '~' if $noPrintConvInv; 587 # add a '*' if this tag is protected or a ' ~' for unsafe tags999 # add a '*' if this tag is protected or a '!' for unsafe tags 588 1000 if ($$tagInfo{Protected}) { 589 1001 $writable .= '*' if $$tagInfo{Protected} & 0x02; … … 592 1004 $writable .= '/' if $$tagInfo{Avoid}; 593 1005 } 1006 $writable = "=struct" if $struct; 1007 $writable .= '_' if defined $$tagInfo{Flat}; 594 1008 $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 '-') 596 1011 $writable = "-$writable" if $subdir; 597 1012 } 598 1013 # don't duplicate a tag name unless an entry is different 599 my $name = $$tagInfo{Name};600 1014 my $lcName = lc($name); 601 1015 # check for conflicts with shortcut names … … 614 1028 } 615 1029 # 616 # add this tag to the tag lookup unless PROCESS_PROC is 0 or shortcut tag1030 # add this tag to the tag lookup unless PROCESS_PROC is 0 or shortcut or plug-in tag 617 1031 # 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}; 619 1034 # count our tags 620 1035 if ($$tagInfo{SubDirectory}) { … … 634 1049 not defined $wflag and not $$tagInfo{SubDirectory})); 635 1050 $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 } 636 1056 # remember number for this table 637 1057 my $tagIDs = $tagLookup{$lcName}->{$tableNum}; … … 659 1079 # 660 1080 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 } 664 1088 } else { 665 $tagIDstr = sprintf( "0x%.4x",$tagID);1089 $tagIDstr = sprintf('0x%.4x',$tagID); 666 1090 } 667 1091 } elsif ($short eq 'DICOM') { … … 685 1109 push @$info, [ $tagIDstr, \@tagNames, \@writable, \@values, \@require, \@writeGroup ]; 686 1110 } 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 } 687 1164 } 688 1165 return $self; … … 696 1173 sub WriteTagLookup($$) 697 1174 { 698 local $_;1175 local ($_, *INFILE, *OUTFILE); 699 1176 my ($self, $file) = @_; 700 1177 my $tagLookup = $self->{TAG_LOOKUP}; 701 1178 my $tagExists = $self->{TAG_EXISTS}; 1179 my $flattened = $self->{FLATTENED}; 702 1180 my $tableWritable = $self->{TABLE_WRITABLE}; 703 1181 # … … 705 1183 # 706 1184 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")) { 709 1187 warn "Can't create temporary file $tmpFile\n"; 710 1188 close(INFILE); … … 753 1231 my (@entries, $tableNum); 754 1232 foreach $tableNum (@tableNums) { 755 my $tagID = $$tagLookup{$tag}->{$tableNum}; 1233 my $tagID = $$tagLookup{$tag}{$tableNum}; 1234 my $rootID = $$flattened{$tag}{$tableNum}; 756 1235 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'; 758 1238 my @tagIDs = sort keys %$tagID; 759 1239 foreach (@tagIDs) { 760 1240 if (/^\d+$/) { 761 $_ = sprintf( "0x%x",$_);1241 $_ = sprintf('0x%x',$_); 762 1242 } else { 763 1243 my $quot = "'"; … … 767 1247 } 768 1248 } 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; 769 1252 $entry = '[' . join(',', @tagIDs) . ']'; 770 1253 } elsif ($tagID =~ /^\d+$/) { 771 $entry = sprintf( "0x%x",$tagID);1254 $entry = sprintf('0x%x',$tagID); 772 1255 } else { 773 1256 $entry = "'$tagID'"; … … 815 1298 # 816 1299 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 } 818 1319 } else { 819 1320 unlink($tmpFile); … … 828 1329 { 829 1330 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); 833 1334 } elsif ($bNum) { 834 $rtnVal = 1;1335 $rtnVal = $numbersFirst; 835 1336 } else { 836 1337 my ($a2, $b2) = ($a, $b); 837 1338 # 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; 840 1341 $caseInsensitive and $rtnVal = (lc($a2) cmp lc($b2)); 841 1342 $rtnVal or $rtnVal = ($a2 cmp $b2); … … 848 1349 # (funny, I know, but the pod headings must be hidden to prevent confusing 849 1350 # the pod parser) 850 # Inputs: 0 ) string851 sub Doc2Pod($ )1351 # Inputs: 0-N) documentation strings 1352 sub Doc2Pod($;@) 852 1353 { 853 1354 my $doc = shift; 1355 local $_; 1356 $doc .= shift while @_; 854 1357 $doc =~ s/\n~/\n=/g; 1358 $doc =~ s/L<[^>]+?\|(http[^>]+)>/L<$1>/g; # POD doesn't support text for http links 855 1359 return $doc; 856 1360 } … … 865 1369 $doc =~ s/B<(.*?)>/<b>$1<\/b>/sg; 866 1370 $doc =~ s/C<(.*?)>/<code>$1<\/code>/sg; 1371 $doc =~ s/I<(.*?)>/<i>$1<\/i>/sg; 1372 $doc =~ s{L<([^&]+?)\|\Q$homePage\E/TagNames/(.*?)>}{<a href="$2">$1<\/a>}sg; 1373 $doc =~ s{L<([^&]+?)\|\Q$homePage\E/(.*?)>}{<a href="../$2">$1<\/a>}sg; 1374 $doc =~ s{L<\Q$homePage\E/TagNames/(.*?)>}{<a href="$1">$1<\/a>}sg; 1375 $doc =~ s{L<\Q$homePage\E/(.*?)>}{<a href="../$1">$1<\/a>}sg; 1376 $doc =~ s{L<([^&]+?)\|/\w+ ([^/&|]+) Tags>}{<a href="#$2">$1</a>}sg; 1377 $doc =~ s/L<([^&]+?)\|(.+?)>/<a href="$2">$1<\/a>/sg; 867 1378 $doc =~ s/L<(.*?)>/<a href="$1">$1<\/a>/sg; 868 1379 return $doc; … … 875 1386 { 876 1387 my %gotTable; 877 my $count = 0;878 1388 my @tableNames = @tableOrder; 879 1389 my (@orderedTables, %mainTables, @outOfOrder); … … 894 1404 # recursively scan through tables in subdirectories 895 1405 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}; 897 1408 my @keys = sort NumbersFirst TagTableKeys($table); 1409 $numbersFirst = 1; 898 1410 foreach (@keys) { 899 1411 my @infoArray = GetTagInfoList($table,$_); … … 932 1444 } 933 1445 # insert back in better order 934 foreach $pos ( reverse sort { $a <=> $b } keys %fixPos) {1446 foreach $pos (sort { $b <=> $a } keys %fixPos) { # (reverse sort) 935 1447 my $fix = $fixPos{$pos}; 936 1448 foreach (@$fix) { … … 944 1456 GPS => 'XMP', # etc... 945 1457 GeoTiff => 'GPS', 1458 CanonVRD=> 'CanonCustom', 1459 Kodak => 'JVC', 1460 'Kodak::IFD' => 'Kodak::Unknown', 1461 'Kodak::TextualInfo' => 'Kodak::IFD', 1462 'Kodak::Processing' => 'Kodak::TextualInfo', 946 1463 Leaf => 'Kodak', 947 Unknown => 'Sony', 1464 Minolta => 'Leaf', 1465 SonyIDC => 'Sony', 1466 Unknown => 'SonyIDC', 948 1467 DNG => 'Unknown', 949 1468 PrintIM => 'ICC_Profile', 1469 ID3 => 'PostScript', 1470 MinoltaRaw => 'KyoceraRaw', 1471 KyoceraRaw => 'CanonRaw', 1472 SigmaRaw => 'PanasonicRaw', 950 1473 Olympus => 'NikonCapture', 951 Pentax => 'Panasonic',952 Ricoh => 'Pentax',953 Sanyo => 'Ricoh',954 1474 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) 955 1483 ); 956 1484 my @tweak = sort keys %tweakOrder; … … 990 1518 $class = shift @names; 991 1519 $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 } 993 1526 ($title = $head) =~ s/ .* / /; 994 1527 @names and $url = join '_', @names; … … 999 1532 } 1000 1533 if ($createdFiles{$htmlFile}) { 1001 open(HTMLFILE, ">>${htmlFile}_tmp") or return 0;1534 open(HTMLFILE, ">>${htmlFile}_tmp") or return 0; 1002 1535 } else { 1003 open(HTMLFILE, ">${htmlFile}_tmp") or return 0;1536 open(HTMLFILE, ">${htmlFile}_tmp") or return 0; 1004 1537 print HTMLFILE "$docType<html>\n<head>\n<title>$title</title>\n"; 1005 1538 print HTMLFILE "<link rel=stylesheet type='text/css' href='style.css' title='Style'>\n"; … … 1043 1576 $fileDate = $1 if @lines and $lines[-1] =~ m{<i>Last revised (.*)</i>}; 1044 1577 } 1045 open(HTMLFILE, ">>$tmpFile") or $success = 0, next;1578 open(HTMLFILE, ">>$tmpFile") or $success = 0, next; 1046 1579 # write the trailers 1047 1580 print HTMLFILE "<hr>\n"; … … 1100 1633 # 2) output html directory (ie. 'html') 1101 1634 # Returns: true on success 1635 # Notes: My apologies for the patchwork code, but this is only used to generate the docs. 1102 1636 sub WriteTagNames($$) 1103 1637 { 1104 1638 my ($self, $podFile, $htmldir) = @_; 1105 my ($tableName, $short, $url, @sepTables );1639 my ($tableName, $short, $url, @sepTables, @structs); 1106 1640 my $tagNameInfo = $self->{TAG_NAME_INFO} or return 0; 1107 my $id Title = $self->{TAG_ID};1641 my $idLabel = $self->{ID_LOOKUP}; 1108 1642 my $shortName = $self->{SHORT_NAME}; 1109 1643 my $sepTable = $self->{SEPARATE_TABLE}; 1644 my $structs = $self->{STRUCTURES}; 1645 my $structLookup = $self->{STRUCT_LOOKUP}; 1110 1646 my $success = 1; 1111 my %htmlFiles;1112 1647 my $columns = 6; # number of columns in html index 1113 1648 my $percent = int(100 / $columns); 1114 1649 1115 1650 # 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}); 1118 1653 mkdir "$htmldir/TagNames"; 1119 1654 OpenHtmlFile($htmldir) or return 0; … … 1125 1660 # write the index 1126 1661 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; 1128 1665 # get list of headings and add any missing ones 1129 1666 my $heading = 'xxx'; … … 1167 1704 print HTMLFILE '<p>',Doc2Html($docs{ExifTool2}),"</p>\n"; 1168 1705 # write all the tag tables 1169 while (@tableNames or @sepTables ) {1706 while (@tableNames or @sepTables or @structs) { 1170 1707 while (@sepTables) { 1171 1708 $tableName = shift @sepTables; … … 1183 1720 close HTMLFILE; 1184 1721 if (OpenHtmlFile($htmldir, $tableName, 1)) { 1185 print HTMLFILE Doc2Html($notes), "\n" if $notes;1722 print HTMLFILE '<p>', Doc2Html($notes), "</p>\n" if $notes; 1186 1723 print HTMLFILE "<blockquote>\n"; 1187 1724 print HTMLFILE "<table class=frame><tr><td>\n"; … … 1191 1728 my @keys; 1192 1729 foreach (sort NumbersFirst keys %$printConv) { 1193 next if /^(Notes|PrintHex )$/;1730 next if /^(Notes|PrintHex|PrintString|OTHER)$/; 1194 1731 $align = '' if $align and /[^\d]/; 1195 1732 my $w = length($_) + length($$printConv{$_}); … … 1200 1737 # print in multiple columns if there is room 1201 1738 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; 1203 1740 my $rows = int((scalar(@keys) + $cols - 1) / $cols); 1204 1741 my ($r, $c); … … 1215 1752 if (defined $key) { 1216 1753 $index = $key; 1217 $prt = "= $$printConv{$key}";1754 $prt = '= ' . EscapeHTML($$printConv{$key}); 1218 1755 if ($$printConv{PrintHex}) { 1219 1756 $index = sprintf('0x%x',$index); 1220 } elsif ($index !~ /^[-+]?\d+$/) { 1757 } elsif ($$printConv{PrintString} or 1758 $index !~ /^[+-]?(?=\d|\.\d)\d*(\.\d*)?$/) 1759 { 1221 1760 $index = "'" . EscapeHTML($index) . "'"; 1222 1761 } … … 1239 1778 } 1240 1779 } 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; 1250 1804 my $info = $$tagNameInfo{$tableName}; 1251 my $id = $$id Title{$tableName};1805 my $id = $$idLabel{$tableName}; 1252 1806 my ($hid, $showGrp); 1253 1807 # widths of the different columns in the POD documentation 1254 1808 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); 1257 1810 if ($short eq 'Shortcuts') { 1258 1811 $derived = '<th>Refers To</th>'; 1259 1812 $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 { 1264 1817 my $table = GetTagTable($tableName); 1265 1818 $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}; 1268 1828 if ($notes) { 1269 1829 # remove unnecessary whitespace … … 1284 1844 $podIdLen = $col if $podIdLen < $col; 1285 1845 } 1286 $id = '' if $short =~ /^XMP/;1287 1846 if ($id) { 1288 1847 ($hid = "<th>$id</th>") =~ s/ / /g; … … 1291 1850 my $longTag = $self->{LONG_NAME}->{$tableName}; 1292 1851 if ($wTag < $longTag) { 1293 $wID -= $longTag - $wTag;1294 $wTag = $longTag;1295 1852 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 { 1298 1862 $wTag += 9; 1299 1863 $hid = ''; 1300 } else {1301 $hid = '';1302 $wTag += $wID - $wReq if $composite;1303 1864 } 1304 1865 if ($short eq 'EXIF') { … … 1308 1869 } 1309 1870 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; 1313 1875 my $line = "\n"; 1314 1876 if ($id) { … … 1319 1881 $line .= ' '; 1320 1882 } 1321 my $tagNameHeading = ($short eq 'XMP') ? 'Namespace' : 'TagName';1883 my $tagNameHeading = ($short eq 'XMP') ? 'Namespace' : ($isStruct?'Field':'Tag').' Name'; 1322 1884 $line .= sprintf " %-${wTag}s", $tagNameHeading; 1323 1885 $line .= sprintf " %-${wReq}s", $composite == 2 ? 'Refers To' : 'Derived From' if $composite; … … 1325 1887 $line .= ' Writable'; 1326 1888 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") 1328 1890 $line =~ s/\S/-/g; 1329 1891 $line =~ s/- -/---/g; 1330 $line =~ tr/\t/ /; 1892 $line =~ tr/\t/ /; # change tab back to space 1331 1893 print PODFILE $line,"\n"; 1332 1894 close HTMLFILE; … … 1344 1906 ++$infoCount; 1345 1907 my ($tagIDstr, $tagNames, $writable, $values, $require, $writeGroup) = @$infoList; 1346 my ($align, $idStr, $w); 1908 my ($align, $idStr, $w, $tip); 1909 my $wTag2 = $wTag; 1347 1910 if (not $id) { 1348 1911 $idStr = ' '; 1349 } elsif ($tagIDstr =~ /^\d+ $/) {1912 } elsif ($tagIDstr =~ /^\d+(\.\d+)?$/) { 1350 1913 $w = $wID - 3; 1351 $idStr = sprintf " %${w} d", $tagIDstr;1914 $idStr = sprintf " %${w}g ", $tagIDstr; 1352 1915 $align = " class=r"; 1353 1916 } else { 1354 1917 $tagIDstr =~ s/^'$prefix/'/ if $prefix; 1355 1918 $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; 1363 1932 $align = ''; 1364 1933 } … … 1369 1938 my $wrStr = shift @vals; 1370 1939 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 =~ /^[-=]/) { 1373 1944 $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 } 1375 1953 # remove Notes if subdir has Notes as well 1376 1954 shift @vals if $vals[0] =~ /^\(/ and @vals >= @$writable; … … 1379 1957 for ($i=0; $i<@$writable; ++$i) { 1380 1958 $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 } 1381 1963 } 1382 1964 if ($$sepTable{$vals[0]}) { 1383 $wrStr =~ s/^ -//;1965 $wrStr =~ s/^[-=]//; 1384 1966 $wrStr = 'N' unless $wrStr; 1967 } elsif ($$structs{$vals[0]}) { 1968 my $flags = $wrStr =~ /([+_]+)$/ ? $1 : ''; 1969 $wrStr = "$vals[0] Struct$flags"; 1385 1970 } else { 1386 1971 $wrStr = $vals[0]; 1387 1972 } 1388 1973 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; 1393 1987 printf PODFILE " %-${wGrp}s", shift(@wGrp) || '-' if $showGrp; 1394 1988 if ($composite) { 1395 1989 @reqs = @$require; 1396 1990 $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; 1398 1992 printf PODFILE " %-${w}s", shift(@reqs) || ''; 1399 1993 } 1400 1994 printf PODFILE " $wrStr\n"; 1995 my $numTags = scalar @$tagNames; 1401 1996 my $n = 0; 1402 1997 while (@tags or @reqs or @vals) { … … 1404 1999 $line = ' '; 1405 2000 $line .= ' 'x($wID+1) if $id; 1406 $line .= sprintf("%-${wTag }s", shift(@tags) || '');2001 $line .= sprintf("%-${wTag2}s", shift(@tags) || ''); 1407 2002 $line .= sprintf(" %-${wReq}s", shift(@reqs) || '') if $composite; 1408 2003 $line .= sprintf(" %-${wGrp}s", shift(@wGrp) || '-') if $showGrp; … … 1412 2007 # use writable if this is a note 1413 2008 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 !~ /^[-=]/))) { 1415 2010 $val = $wrStr; 1416 2011 if (defined $val) { 1417 $val =~ s/^ -//;2012 $val =~ s/^[-=]//; 1418 2013 } else { 1419 2014 # done with tag if nothing else to print … … 1421 2016 } 1422 2017 } 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 } 1424 2025 } 1425 2026 $line =~ s/\s+$//; # trim trailing white space … … 1430 2031 push @htmlTags, EscapeHTML($_); 1431 2032 } 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 } 1432 2040 $rowClass = $rowClass ? '' : " class=b"; 1433 2041 my $isSubdir; 1434 if ($$writable[0] =~ /^ -/) {2042 if ($$writable[0] =~ /^[-=]/) { 1435 2043 $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/"©/; 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 1440 2088 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; 1442 2090 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; 1445 2093 print HTMLFILE "<td class=c>",join('<br>',@$writeGroup),"</td>\n" if $showGrp; 1446 2094 print HTMLFILE "<td>"; 1447 my $close = '';1448 my @values;1449 2095 if (@$values) { 1450 2096 if ($isSubdir) { 1451 my $smallNote;2097 my ($smallNote, @values); 1452 2098 foreach (@$values) { 1453 2099 if (/^\(/) { 1454 $smallNote = 1 if $n <= 1; 2100 # set the note font 2101 $smallNote = 1 if $numTags < 2; 1455 2102 push @values, ($smallNote ? $noteFontSmall : $noteFont) . "$_</span>"; 1456 2103 next; 1457 2104 } 2105 # make text in square brackets small 2106 /^\[/ and push(@values, "<span class=s>$_</span>"), next; 1458 2107 /=/ and push(@values, $_), next; 1459 2108 my @names = split; 1460 $url = (shift @names) . '.html';1461 @names and $url .= '#' . join '_', @names;1462 2109 my $suffix = ' Tags'; 1463 2110 if ($$sepTable{$_}) { … … 1465 2112 $suffix = ' Values'; 1466 2113 } 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; 1467 2122 push @values, "--> <a href='$url'>$_$suffix</a>"; 1468 2123 } 1469 2124 # put small note last 1470 2125 $smallNote and push @values, shift @values; 2126 print HTMLFILE join("\n <br>",@values); 1471 2127 } else { 2128 my ($close, $br) = ('', ''); 1472 2129 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; 1479 2147 } 1480 2148 } else { 1481 p ush @values,' ';1482 } 1483 print HTMLFILE join("\n <br>",@values),"$close</td></tr>\n";2149 print HTMLFILE ' '; 2150 } 2151 print HTMLFILE "</td></tr>\n"; 1484 2152 } 1485 2153 unless ($infoCount) { … … 1488 2156 ++$cols if $hid; 1489 2157 ++$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"; 1491 2159 } 1492 2160 print HTMLFILE "</table></td></tr></table></blockquote>\n\n"; … … 1514 2182 Image::ExifTool::TagNames.pod, as well as HTML tag name documentation. It 1515 2183 is used before each new ExifTool release to update the lookup tables and 1516 documentation .2184 documentation, but it is not used otherwise. 1517 2185 1518 2186 =head1 SYNOPSIS … … 1526 2194 $ok = $builder->WriteTagNames('lib/Image/ExifTool/TagNames.pod','html'); 1527 2195 2196 =head1 MEMBER VARIABLES 2197 2198 =over 4 2199 2200 =item PRESERVE_DATE 2201 2202 Flag to preserve "Last revised" date in HTML files. Set before calling 2203 WriteTagNames(). 2204 2205 =item COUNT 2206 2207 Reference to hash containing counting statistics. Keys are the 2208 descriptions, and values are the numerical counts. Valid after 2209 BuildTagLookup object is created, but additional statistics are added by 2210 WriteTagNames(). 2211 2212 =back 2213 1528 2214 =head1 AUTHOR 1529 2215 1530 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)2216 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 1531 2217 1532 2218 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Canon.pm
r16842 r24107 4 4 # Description: Canon EXIF maker notes tags 5 5 # 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! 13 15 # 14 16 # References: 1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html … … 18 20 # 5) Juha Eskelinen private communication (20D) 19 21 # 6) Richard S. Smith private communication (20D) 20 # 7) Denny Priebe private communication (1D MkII)22 # 7) Denny Priebe private communication (1DmkII) 21 23 # 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) 24 26 # 11) "cip" private communication 25 27 # 12) Rainer Honle private communication (5D) 26 28 # 13) http://www.cybercom.net/~dcoffin/dcraw/ 27 29 # 14) (bozi) http://www.cpanforum.com/threads/2476 and /2563 28 # 15) http://homepage3.nifty.com/kamisaka/makernote/makernote_canon.htm and29 # 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) 30 32 # 16) Emil Sit private communication (30D) 31 33 # 17) http://www.asahi-net.or.jp/~xp8t-ymzk/s10exif.htm … … 33 35 # 19) Warren Stockton private communication 34 36 # 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 35 66 #------------------------------------------------------------------------------ 36 67 … … 44 75 sub WriteCanon($$$); 45 76 sub ProcessSerialData($$$); 46 47 $VERSION = '1.77'; 48 77 sub ProcessFilters($$$); 78 sub 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) 49 84 my %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 60 113 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 62 121 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 74 155 39 => 'Canon EF 75-300mm f/4-5.6', 75 156 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 76 160 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 78 171 124 => 'Canon MP-E 65mm f/2.8 1-5x Macro Photo', #9 79 172 125 => 'Canon TS-E 24mm f/3.5L', 80 173 126 => 'Canon TS-E 45mm f/2.8', #15 81 174 127 => 'Canon TS-E 90mm f/2.8', #15 175 129 => 'Canon EF 300mm f/2.8L', #32 82 176 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 84 186 134 => 'Canon EF 600mm f/4L IS', #15 85 187 135 => 'Canon EF 200mm f/1.8L', 86 188 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 88 199 139 => 'Canon EF 400mm f/2.8L', 200 140 => 'Canon EF 500mm f/4.5L', #32 89 201 141 => 'Canon EF 500mm f/4.5L', 90 202 142 => 'Canon EF 300mm f/2.8L IS', #15 91 203 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 96 214 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 106 226 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 110 241 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', 113 244 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 115 252 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 121 261 176 => 'Canon EF 24-85mm f/3.5-4.5 USM', 122 262 177 => 'Canon EF 300mm f/4L IS', #9 123 263 178 => 'Canon EF 28-135mm f/3.5-5.6 IS', 264 179 => 'Canon EF 24mm f/1.4L', #20 124 265 180 => 'Canon EF 35mm f/1.4L', #9 125 181 => 'Canon EF 100-400mm f/4.5-5.6L IS + x1.4', #15126 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', 127 268 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 129 271 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 130 275 190 => 'Canon EF 100mm f/2.8 Macro', 131 276 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', 134 282 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 142 300 229 => 'Canon EF 16-35mm f/2.8L', #PH 143 301 230 => 'Canon EF 24-70mm f/2.8L', #9 144 302 231 => 'Canon EF 17-40mm f/4L', 145 303 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 146 305 234 => 'Canon EF-S 17-85mm f4-5.6 IS USM', #19 147 235 => 'Canon EF-S 10-22mm F3.5-4.5 USM', #15148 236 => 'Canon EF-S 60mm F2.8 Macro USM', #15306 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 149 308 237 => 'Canon EF 24-105mm f/4L IS', #15 150 309 238 => 'Canon EF 70-300mm f/4-5.6 IS USM', #15 151 239 => 'Canon EF 85mm f/1.2L II USM', #15310 239 => 'Canon EF 85mm f/1.2L II', #15 152 311 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 155 327 ); 156 328 … … 202 374 0x1590000 => 'PowerShot SD20 / Digital IXUS i5 / IXY Digital L2', 203 375 0x1640000 => 'PowerShot S2 IS', 204 0x1650000 => 'PowerShot SD430 / IXUS Wireless / IXYWireless',376 0x1650000 => 'PowerShot SD430 / Digital IXUS Wireless / IXY Digital Wireless', 205 377 0x1660000 => 'PowerShot SD500 / Digital IXUS 700 / IXY Digital 600', 206 378 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', 208 380 0x1740000 => 'PowerShot A430', 209 381 0x1750000 => 'PowerShot A410', … … 245 417 0x2300000 => 'PowerShot SD950 IS / Digital IXUS 960 IS / IXY Digital 2000 IS', 246 418 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', 247 467 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', 248 475 0x4040000 => 'PowerShot G1', 249 476 0x6040000 => 'PowerShot S100 / Digital IXUS / IXY Digital', 477 0x4007d673 => 'DC19/DC21/DC22', 478 0x4007d674 => 'XH A1', 250 479 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. 253 507 0x80000001 => 'EOS-1D', 254 508 0x80000167 => 'EOS-1DS', … … 258 512 0x80000174 => 'EOS-1D Mark II', 259 513 0x80000175 => 'EOS 20D', 514 0x80000176 => 'EOS Digital Rebel XSi / 450D / Kiss X2', 260 515 0x80000188 => 'EOS-1Ds Mark II', 261 516 0x80000189 => 'EOS Digital Rebel XT / 350D / Kiss Digital N', … … 263 518 0x80000213 => 'EOS 5D', 264 519 0x80000215 => 'EOS-1Ds Mark III', 520 0x80000218 => 'EOS 5D Mark II', 265 521 0x80000232 => 'EOS-1D Mark II N', 266 522 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', 268 533 ); 269 534 … … 274 539 4 => 'RAW', 275 540 5 => 'Superfine', 541 130 => 'Normal Movie', #22 276 542 ); 277 543 my %canonImageSize = ( … … 283 549 7 => 'Medium 3', #PH 284 550 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) 286 561 ); 287 562 my %canonWhiteBalance = ( 563 # -1='Click", -2='Pasted' ?? - PH 288 564 0 => 'Auto', 289 565 1 => 'Daylight', … … 303 579 16 => 'Custom 2', #PH 304 580 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? 305 593 ); 306 594 307 595 # picture styles used by the 5D 308 596 # (styles 0x4X may be downloaded from Canon) 597 # (called "ColorMatrix" in 1D owner manual) 309 598 my %pictureStyles = ( #12 310 599 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 315 608 0x21 => 'User Def. 1', 316 609 0x22 => 'User Def. 2', … … 319 612 # Twilight and Emerald. The "User Def" styles change to these "External" 320 613 # 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 324 617 0x81 => 'Standard', 325 618 0x82 => 'Portrait', … … 328 621 0x85 => 'Faithful', 329 622 0x86 => 'Monochrome', 330 ); 331 my %userDefStyles = ( #12 332 0x41 => 'Nostalgia', 333 0x42 => 'Clear', 334 0x43 => 'Twilight', 623 0x87 => 'Auto', #PH 624 ); 625 my %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', 335 634 0x81 => 'Standard', 336 635 0x82 => 'Portrait', … … 341 640 ); 342 641 642 # picture style tag information for CameraInfo550D 643 my %psConv = ( 644 -559038737 => 'n/a', # = 0xdeadbeef ! LOL 645 OTHER => sub { return shift }, 646 ); 647 my %psInfo = ( 648 Format => 'int32s', 649 PrintHex => 1, 650 PrintConv => \%psConv, 651 ); 652 343 653 # ValueConv that makes long values binary type 344 654 my %longBin = ( 345 655 ValueConv => 'length($val) > 64 ? \$val : $val', 346 656 ValueConvInv => '$val', 657 ); 658 659 # conversions, etc for CameraColorCalibration tags 660 my %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 668 my %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 675 my %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 686 my %binaryDataAttrs = ( 687 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 688 WRITE_PROC => \&Image::ExifTool::WriteBinaryData, 689 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 690 WRITABLE => 1, 347 691 ); 348 692 … … 386 730 Name => 'CanonImageType', 387 731 Writable => 'string', 732 Groups => { 2 => 'Image' }, 388 733 }, 389 734 0x7 => { … … 394 739 Name => 'FileNumber', 395 740 Writable => 'int32u', 741 Groups => { 2 => 'Image' }, 396 742 PrintConv => '$_=$val,s/(\d+)(\d{4})/$1-$2/,$_', 397 743 PrintConvInv => '$val=~s/-//g;$val', … … 400 746 Name => 'OwnerName', 401 747 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', 402 751 }, 403 752 0xa => { 404 Name => ' ColorInfoD30',753 Name => 'UnknownD30', 405 754 SubDirectory => { 406 755 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', 407 TagTable => 'Image::ExifTool::Canon:: ColorInfoD30',756 TagTable => 'Image::ExifTool::Canon::UnknownD30', 408 757 }, 409 758 }, … … 412 761 # D30 413 762 Name => 'SerialNumber', 414 Description => 'Camera Body No.', 415 Condition => '$$self{CameraModel} =~ /EOS D30\b/', 763 Condition => '$$self{Model} =~ /EOS D30\b/', 416 764 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', 419 767 }, 420 768 { … … 422 770 # displayed w/o leeding zeros (ref 7) (1D uses 6 digits - PH) 423 771 Name => 'SerialNumber', 424 Description => 'Camera Body No.', 425 Condition => '$$self{CameraModel} =~ /EOS-1D/', 772 Condition => '$$self{Model} =~ /EOS-1D/', 426 773 Writable => 'int32u', 427 774 PrintConv => 'sprintf("%.6u",$val)', … … 431 778 # all other models (D60,300D,350D,REBEL,10D,20D,etc) 432 779 Name => 'SerialNumber', 433 Description => 'Camera Body No.',434 780 Writable => 'int32u', 435 781 PrintConv => 'sprintf("%.10u",$val)', … … 439 785 0xd => [ 440 786 { 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?$/', 443 790 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', 445 806 }, 446 807 }, 447 808 { 448 809 Name => 'CanonCameraInfo1DmkIII', 449 Condition => '$$self{ CameraModel} =~ /\b1D Mark III/',810 Condition => '$$self{Model} =~ /\b1Ds? Mark III$/', 450 811 SubDirectory => { 451 812 TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIII', … … 453 814 }, 454 815 { 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', 456 894 # 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)', 458 896 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', 460 909 }, 461 910 }, 462 911 { 463 912 Name => 'CanonCameraInfoUnknown32', 464 Condition => q{ $format =~ /^int32/ }, 913 Condition => '$format =~ /^int32/', 914 # (counts of 72, 85, 86, 93, 94, 96, 104) - PH 465 915 SubDirectory => { 466 916 TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown32', … … 469 919 { 470 920 Name => 'CanonCameraInfoUnknown16', 471 Condition => q{ $format =~ /^int16/ },921 Condition => '$format =~ /^int16/', 472 922 SubDirectory => { 473 923 TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown16', … … 475 925 }, 476 926 { 477 Name => 'CanonCameraInfoUnknown 8',927 Name => 'CanonCameraInfoUnknown', 478 928 SubDirectory => { 479 TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown 8',929 TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown', 480 930 }, 481 931 }, … … 487 937 }, 488 938 0xf => [ 489 { # used by 1DmkII, 1D sMkII and 1DmkIIN939 { # used by 1DmkII, 1DSmkII and 1DmkIIN 490 940 Name => 'CustomFunctions1D', 491 Condition => '$$self{ CameraModel} =~ /EOS-1D/',941 Condition => '$$self{Model} =~ /EOS-1D/', 492 942 SubDirectory => { 493 943 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', … … 497 947 { 498 948 Name => 'CustomFunctions5D', 499 Condition => '$$self{ CameraModel} =~ /EOS 5D/',949 Condition => '$$self{Model} =~ /EOS 5D/', 500 950 SubDirectory => { 501 951 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', … … 505 955 { 506 956 Name => 'CustomFunctions10D', 507 Condition => '$$self{ CameraModel} =~ /EOS 10D/',957 Condition => '$$self{Model} =~ /EOS 10D/', 508 958 SubDirectory => { 509 959 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', … … 513 963 { 514 964 Name => 'CustomFunctions20D', 515 Condition => '$$self{ CameraModel} =~ /EOS 20D/',965 Condition => '$$self{Model} =~ /EOS 20D/', 516 966 SubDirectory => { 517 967 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', … … 521 971 { 522 972 Name => 'CustomFunctions30D', 523 Condition => '$$self{ CameraModel} =~ /EOS 30D/',973 Condition => '$$self{Model} =~ /EOS 30D/', 524 974 SubDirectory => { 525 975 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', … … 529 979 { 530 980 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/', 532 982 SubDirectory => { 533 983 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', … … 537 987 { 538 988 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/', 540 990 SubDirectory => { 541 991 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', … … 545 995 { 546 996 Name => 'CustomFunctionsD30', 547 Condition => '$$self{ CameraModel} =~ /EOS D30\b/',997 Condition => '$$self{Model} =~ /EOS D30\b/', 548 998 SubDirectory => { 549 999 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', … … 553 1003 { 554 1004 Name => 'CustomFunctionsD60', 555 Condition => '$$self{ CameraModel} =~ /EOS D60\b/',1005 Condition => '$$self{Model} =~ /EOS D60\b/', 556 1006 SubDirectory => { 557 1007 # the stored size in the D60 apparently doesn't include the size word: … … 575 1025 SeparateTable => 1, 576 1026 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 }, 577 1034 }, 578 1035 0x12 => { … … 587 1044 }, 588 1045 }, 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 }, 590 1053 0x15 => { #PH 591 1054 # display format for serial number … … 598 1061 }, 599 1062 }, 1063 0x1a => { #15 1064 Name => 'SuperMacro', 1065 Writable => 'int16u', 1066 PrintConv => { 1067 0 => 'Off', 1068 1 => 'On (1)', 1069 2 => 'On (2)', 1070 }, 1071 }, 600 1072 0x1c => { #PH (A570IS) 601 1073 Name => 'DateStampMode', 602 1074 Writable => 'int16u', 603 Notes => ' only usedin postcard mode',1075 Notes => 'used only in postcard mode', 604 1076 PrintConv => { 605 1077 0 => 'Off', … … 637 1109 # 0x1f - used for red-eye-corrected images - PH (A570IS) 638 1110 # 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 }, 639 1131 0x24 => { #PH 640 1132 Name => 'FaceDetect1', … … 652 1144 0x26 => { #PH (A570IS,1DmkIII) 653 1145 Name => 'CanonAFInfo2', 1146 Condition => '$$valPt !~ /^\0\0\0\0/', # (data may be all zeros in thumbnail of 60D MOV video) 654 1147 SubDirectory => { 655 1148 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', … … 658 1151 }, 659 1152 # 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 }, 660 1173 0x83 => { #PH 661 Name => 'OriginalDecisionData ',1174 Name => 'OriginalDecisionDataOffset', 662 1175 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', 663 1182 }, 664 1183 0x90 => { # used by 1D and 1Ds … … 684 1203 }, 685 1204 0x93 => { 686 Name => 'CanonFileInfo', 1205 Name => 'CanonFileInfo', # (ShootInfoEx) 687 1206 SubDirectory => { 688 1207 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', … … 697 1216 }, 698 1217 0x95 => { #PH (observed in 5D sample image) 699 Name => 'Lens Type',1218 Name => 'LensModel', 700 1219 Writable => 'string', 701 1220 }, 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 ], 706 1235 0x97 => { #PH 707 1236 Name => 'DustRemovalData', 708 1237 # 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 }, 710 1246 }, 711 1247 0x99 => { #PH (EOS 1D Mark III, 40D, etc) … … 716 1252 }, 717 1253 }, 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 }, 719 1260 0xa0 => { 720 Name => 'Proc cessingInfo',1261 Name => 'ProcessingInfo', 721 1262 SubDirectory => { 722 1263 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', … … 738 1279 }, 739 1280 }, 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 }, 741 1288 0xae => { 742 1289 Name => 'ColorTemperature', … … 770 1317 Name => 'PreviewImageInfo', 771 1318 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 773 1321 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size/2)', 774 1322 TagTable => 'Image::ExifTool::Canon::PreviewImageInfo', … … 793 1341 { # (int16u[582]) - 20D and 350D 794 1342 Condition => '$count == 582', 795 Name => 'Color Balance1',1343 Name => 'ColorData1', 796 1344 SubDirectory => { 797 TagTable => 'Image::ExifTool::Canon::Color Balance1',1345 TagTable => 'Image::ExifTool::Canon::ColorData1', 798 1346 }, 799 1347 }, 800 1348 { # (int16u[653]) - 1DmkII and 1DSmkII 801 1349 Condition => '$count == 653', 802 Name => 'Color Balance2',1350 Name => 'ColorData2', 803 1351 SubDirectory => { 804 TagTable => 'Image::ExifTool::Canon::Color Balance2',1352 TagTable => 'Image::ExifTool::Canon::ColorData2', 805 1353 }, 806 1354 }, 807 1355 { # (int16u[796]) - 1DmkIIN, 5D, 30D, 400D 808 1356 Condition => '$count == 796', 809 Name => 'Color Balance3',1357 Name => 'ColorData3', 810 1358 SubDirectory => { 811 TagTable => 'Image::ExifTool::Canon::Color Balance3',1359 TagTable => 'Image::ExifTool::Canon::ColorData3', 812 1360 }, 813 1361 }, 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 }, 814 1390 { 815 Name => 'ColorBalanceUnknown', 816 %longBin, 1391 Name => 'ColorDataUnknown', 1392 SubDirectory => { 1393 TagTable => 'Image::ExifTool::Canon::ColorDataUnknown', 1394 }, 817 1395 }, 818 1396 ], … … 820 1398 # unknown data block in some JPEG and CR2 images 821 1399 # (5kB for most models, but 22kb for 5D and 30D) 822 Name => ' UnknownBlock1',1400 Name => 'CRWParam', 823 1401 Format => 'undef', 824 1402 Flags => [ 'Unknown', 'Binary' ], … … 831 1409 }, 832 1410 0x4005 => { #PH 833 Name => ' UnknownBlock2',1411 Name => 'Flavor', 834 1412 Notes => 'unknown 49kB block, not copied to JPEG images', 835 1413 # 'Drop' because not found in JPEG images (too large for APP1 anyway) … … 837 1415 }, 838 1416 0x4008 => { #PH guess (1DmkIII) 839 Name => 'BlackLevel', 1417 Name => 'BlackLevel', # (BasePictStyleOfUser) 840 1418 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 } 841 1475 }, 842 1476 ); … … 846 1480 # BinaryData (keys are indices into the int16s array) 847 1481 %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, 852 1483 FORMAT => 'int16s', 853 1484 FIRST_ENTRY => 1, 854 DATAMEMBER => [ 2 5 ], # FocalUnitsnecessary for writing1485 DATAMEMBER => [ 22, 25 ], # necessary for writing 855 1486 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 856 1487 1 => { … … 862 1493 }, 863 1494 2 => { 864 Name => 'Self -timer',1495 Name => 'SelfTimer', 865 1496 # Custom timer mode if bit 0x4000 is set - PH (A570IS) 866 1497 PrintConv => q{ 867 1498 return 'Off' unless $val; 868 return (($val&0xfff) / 10) . ' s ec' . ($val & 0x4000 ? ', Custom' : '');1499 return (($val&0xfff) / 10) . ' s' . ($val & 0x4000 ? ', Custom' : ''); 869 1500 }, 870 1501 PrintConvInv => q{ 871 1502 return 0 if $val =~ /^Off/i; 872 $val =~ s/\s*s ec$//i;1503 $val =~ s/\s*s(ec)?\b//i; 873 1504 $val =~ s/,?\s*Custom$//i ? ($val*10) | 0x4000 : $val*10; 874 1505 }, … … 900 1531 4 => 'Continuous, Low', #PH 901 1532 5 => 'Continuous, High', #PH 1533 6 => 'Silent Single', #PH 1534 # 32-34 - Self-timer? 902 1535 }, 903 1536 }, … … 908 1541 1 => 'AI Servo AF', 909 1542 2 => 'AI Focus AF', 910 3 => 'Manual Focus ',1543 3 => 'Manual Focus (3)', 911 1544 4 => 'Single', 912 1545 5 => 'Continuous', 913 6 => 'Manual Focus ',1546 6 => 'Manual Focus (6)', 914 1547 16 => 'Pan Focus', #PH 1548 # 137 - Single? 915 1549 }, 916 1550 }, 917 1551 9 => { #PH 918 1552 Name => 'RecordMode', 1553 RawConv => '$val==-1 ? undef : $val', #22 919 1554 PrintConv => { 920 1555 1 => 'JPEG', … … 925 1560 6 => 'CR2', # +THM? (1D,30D,350D) 926 1561 7 => 'CR2+JPEG', # (S30) 1562 9 => 'Video', # (S95 MOV) 927 1563 }, 928 1564 }, 929 1565 10 => { 930 1566 Name => 'CanonImageSize', 1567 PrintConvColumns => 2, 931 1568 PrintConv => \%canonImageSize, 932 1569 }, 933 1570 11 => { 934 1571 Name => 'EasyMode', 1572 PrintConvColumns => 3, 935 1573 PrintConv => { 936 1574 0 => 'Full auto', … … 962 1600 26 => 'Digital Macro', #PH 963 1601 27 => 'My Colors', #PH 964 28 => 'Still Image', #15 (animation frame?) 1602 28 => 'Movie Snap', #PH 1603 29 => 'Super Macro 2', #PH 965 1604 30 => 'Color Accent', #18 966 1605 31 => 'Color Swap', #18 967 1606 32 => 'Aquarium', #18 968 1607 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 969 1636 }, 970 1637 }, … … 975 1642 1 => '2x', 976 1643 2 => '4x', 977 3 => 'Other', # value obtained from 2* #37/#361644 3 => 'Other', # value obtained from 2*$val[37]/$val[36] 978 1645 }, 979 1646 }, … … 981 1648 Name => 'Contrast', 982 1649 RawConv => '$val == 0x7fff ? undef : $val', 983 PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)', 984 PrintConvInv => '$val=~/normal/i ? 0 : $val', 1650 %Image::ExifTool::Exif::printParameter, 985 1651 }, 986 1652 14 => { 987 1653 Name => 'Saturation', 988 1654 RawConv => '$val == 0x7fff ? undef : $val', 989 PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)', 990 PrintConvInv => '$val=~/normal/i ? 0 : $val', 1655 %Image::ExifTool::Exif::printParameter, 991 1656 }, 992 1657 15 => { 993 1658 Name => 'Sharpness', 994 1659 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', 997 1666 }, 998 1667 16 => { 999 1668 Name => 'CameraISO', 1000 RawConv => '$val != 0x7fff ? $val : undef',1669 RawConv => '$val == 0x7fff ? undef : $val', 1001 1670 ValueConv => 'Image::ExifTool::Canon::CameraISO($val)', 1002 1671 ValueConvInv => 'Image::ExifTool::Canon::CameraISO($val,1)', … … 1010 1679 3 => 'Evaluative', 1011 1680 4 => 'Partial', 1012 5 => 'Center-weighted averag ing',1681 5 => 'Center-weighted average', 1013 1682 }, 1014 1683 }, … … 1055 1724 5 => 'Depth-of-field AE', 1056 1725 6 => 'M-Dep', #PH 1726 7 => 'Bulb', #30 1057 1727 }, 1058 1728 }, 1059 1729 22 => { #4 1060 1730 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', 1062 1733 SeparateTable => 1, 1734 DataMember => 'LensType', 1063 1735 PrintConv => \%canonLensTypes, 1064 1736 }, … … 1070 1742 ValueConv => '$val / ($$self{FocalUnits} || 1)', 1071 1743 ValueConvInv => '$val', 1072 PrintConv => '"$ {val}mm"',1073 PrintConvInv => '$val=~s/ mm//;$val',1744 PrintConv => '"$val mm"', 1745 PrintConvInv => '$val=~s/\s*mm//;$val', 1074 1746 }, 1075 1747 24 => { … … 1079 1751 ValueConv => '$val / ($$self{FocalUnits} || 1)', 1080 1752 ValueConvInv => '$val', 1081 PrintConv => '"$ {val}mm"',1082 PrintConvInv => '$val=~s/ mm//;$val',1753 PrintConv => '"$val mm"', 1754 PrintConvInv => '$val=~s/\s*mm//;$val', 1083 1755 }, 1084 1756 25 => { 1085 1757 Name => 'FocalUnits', 1758 # conversion from raw focal length values to mm 1086 1759 DataMember => 'FocalUnits', 1087 1760 RawConv => '$$self{FocalUnits} = $val', 1761 PrintConv => '"$val/mm"', 1762 PrintConvInv => '$val=~s/\s*\/?\s*mm//;$val', 1088 1763 }, 1089 1764 26 => { #9 … … 1109 1784 29 => { 1110 1785 Name => 'FlashBits', 1786 PrintConvColumns => 2, 1111 1787 PrintConv => { BITMASK => { 1112 1788 0 => 'Manual', #PH … … 1118 1794 11 => 'FP sync used', 1119 1795 13 => 'Built-in', 1120 14 => 'External', 1796 14 => 'External', #(may not be set in manual mode - ref 37) 1121 1797 } }, 1122 1798 }, … … 1127 1803 0 => 'Single', 1128 1804 1 => 'Continuous', 1805 8 => 'Manual', #22 1129 1806 }, 1130 1807 }, … … 1146 1823 0 => 'Off', 1147 1824 1 => 'On', 1148 2 => 'On, Shot Only', #15 1825 2 => 'On, Shot Only', #15 (panning for SX10IS) 1149 1826 3 => 'On, Panning', #PH (A570IS) 1827 4 => 'On, Video', #PH (SX30IS) 1150 1828 }, 1151 1829 }, … … 1158 1836 36 => 'ZoomSourceWidth', #PH 1159 1837 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 }, 1160 1846 40 => { #PH 1161 1847 Name => 'PhotoEffect', 1162 1848 RawConv => '$val==-1 ? undef : $val', 1849 PrintConvColumns => 2, 1163 1850 PrintConv => { 1164 1851 0 => 'Off', … … 1187 1874 Name => 'ColorTone', 1188 1875 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 }, 1191 1886 }, 1192 1887 ); … … 1194 1889 # focal length information (MakerNotes tag 0x02) 1195 1890 %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, 1200 1892 FORMAT => 'int16u', 1201 1893 FIRST_ENTRY => 0, … … 1204 1896 Name => 'FocalType', 1205 1897 RawConv => '$val ? $val : undef', # don't use if value is zero 1206 1898 PrintConv => { 1207 1899 1 => 'Fixed', 1208 1900 2 => 'Zoom', … … 1225 1917 ValueConv => '$val / ($$self{FocalUnits} || 1)', 1226 1918 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 ], 1251 1965 ); 1252 1966 … … 1254 1968 # BinaryData (keys are indices into the int16s array) 1255 1969 %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, 1260 1971 FORMAT => 'int16s', 1261 1972 FIRST_ENTRY => 1, 1973 DATAMEMBER => [ 19 ], 1262 1974 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, 1263 1975 1 => { #PH … … 1281 1993 Name => 'MeasuredEV', 1282 1994 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', 1288 2003 PrintConv => 'sprintf("%.2f",$val)', 1289 2004 PrintConvInv => '$val', … … 1299 2014 5 => { #2 1300 2015 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', 1302 2019 ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val)*log(2))', 1303 2020 ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val)/log(2))', 1304 2021 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 1305 PrintConvInv => ' eval $val',2022 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 1306 2023 }, 1307 2024 6 => { … … 1309 2026 ValueConv => 'Image::ExifTool::Canon::CanonEv($val)', 1310 2027 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)', 1313 2030 }, 1314 2031 7 => { 1315 2032 Name => 'WhiteBalance', 1316 2033 PrintConv => \%canonWhiteBalance, 2034 SeparateTable => 1, 1317 2035 }, 1318 2036 8 => { #PH 1319 2037 Name => 'SlowShutter', 1320 2038 PrintConv => { 2039 -1 => 'n/a', 1321 2040 0 => 'Off', 1322 2041 1 => 'Night Scene', … … 1335 2054 # (for many models, 0-6 represent 0-100% zoom, but it is always 8 for 1336 2055 # 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', 1337 2059 }, 1338 2060 # 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 }, 1339 2073 13 => { #PH 1340 2074 Name => 'FlashGuideNumber', 1341 RawConv => '$val ==-1 ? undef : $val',2075 RawConv => '$val==-1 ? undef : $val', 1342 2076 ValueConv => '$val / 32', 1343 2077 ValueConvInv => '$val * 32', … … 1350 2084 Flags => 'PrintHex', 1351 2085 RawConv => '$val==0 ? undef : $val', 2086 PrintConvColumns => 2, 1352 2087 PrintConv => { 1353 2088 0x3000 => 'None (MF)', … … 1366 2101 ValueConv => 'Image::ExifTool::Canon::CanonEv($val)', 1367 2102 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)', 1370 2105 }, 1371 2106 16 => { … … 1383 2118 ValueConv => 'Image::ExifTool::Canon::CanonEv($val)', 1384 2119 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 }, 1387 2130 }, 1388 2131 19 => { 1389 2132 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', 1392 2141 }, 1393 2142 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', 1397 2150 }, 1398 2151 21 => { … … 1411 2164 # encoding is different for 20D and 350D (darn!) 1412 2165 # (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/', 1414 2167 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', 1416 2172 # approximate big translation table by simple calculation - PH 1417 2173 ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val)*log(2))*1000/32', 1418 2174 ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val*32/1000)/log(2))', 1419 2175 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 1420 PrintConvInv => ' eval $val',2176 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 1421 2177 }, 1422 2178 { 1423 2179 Name => 'ExposureTime', 1424 2180 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', 1426 2185 # approximate big translation table by simple calculation - PH 1427 2186 ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val)*log(2))', 1428 2187 ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val)/log(2))', 1429 2188 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 1430 PrintConvInv => ' eval $val',2189 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 1431 2190 }, 1432 2191 ], 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 }, 1433 2199 24 => { 1434 2200 Name => 'BulbDuration', … … 1442 2208 Groups => { 2 => 'Camera' }, 1443 2209 PrintConv => { 2210 0 => 'n/a', 1444 2211 248 => 'EOS High-end', 1445 2212 250 => 'Compact', … … 1450 2217 27 => { 1451 2218 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) 1454 2222 0 => 'None', 1455 2223 1 => 'Rotate 90 CW', … … 1460 2228 28 => { #15 1461 2229 Name => 'NDFilter', 1462 PrintConv => { 0 => 'Off', 1 => 'On' },2230 PrintConv => { -1 => 'n/a', 0 => 'Off', 1 => 'On' }, 1463 2231 }, 1464 2232 29 => { 1465 Name => 'Self -timer2',2233 Name => 'SelfTimer2', 1466 2234 RawConv => '$val >= 0 ? $val : undef', 1467 2235 ValueConv => '$val / 10', … … 1470 2238 33 => { #PH (A570IS) 1471 2239 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 => 'int 8s',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', 1484 2252 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 2281 my %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 ); 2291 my %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 ); 2301 my %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 ); 2310 my %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 ); 2318 my %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 ); 2328 my %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 ); 2336 my %ciShortFocal = ( 2337 Name => 'ShortFocal', 2338 Format => 'int16uRev', # byte order is big-endian 2339 PrintConv => '"$val mm"', 2340 PrintConvInv => '$val=~s/\s*mm//;$val', 2341 ); 2342 my %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 1485 2357 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 1486 2358 NOTES => q{ … … 1488 2360 encodings are very different than in other Canon records (even sometimes 1489 2361 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 => { 1531 2367 Name => 'FocalLength', 1532 2368 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', 1541 2373 }, 1542 2374 0x0d => { #9 1543 2375 Name => 'LensType', 1544 Format => 'int 8u',2376 Format => 'int16uRev', # value is little-endian 1545 2377 SeparateTable => 1, 1546 2378 RawConv => '$val ? $val : undef', # don't use if value is zero 1547 2379 PrintConv => \%canonLensTypes, 1548 2380 }, 1549 0x 11 => { #92381 0x0e => { 1550 2382 Name => 'ShortFocal', 1551 2383 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 => { 1562 2388 Name => 'LongFocal', 1563 2389 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 1573 2497 0x2d => { #9 1574 2498 Name => 'FocalType', 1575 Format => 'int8u',1576 Condition => '$$self{CameraModel} =~ /\b1Ds? Mark II\b/',1577 Notes => '1DmkII and 1DSmkII only',1578 Priority => 0,1579 2499 PrintConv => { 1580 2500 0 => 'Fixed', … … 1582 2502 }, 1583 2503 }, 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 1584 2946 0x38 => { 1585 2947 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, 1591 2950 PrintConv => { BITMASK => { 1592 2951 0 => 'Center', … … 1607 2966 } }, 1608 2967 }, 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 }, 1609 2978 0x6c => { 1610 2979 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'], 1615 2982 PrintConv => \%pictureStyles, 1616 2983 }, 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 1618 2993 Name => 'FirmwareRevision', 1619 Condition => '$$self{CameraModel} =~ /EOS 5D/',1620 Notes => '5D only',1621 2994 Format => 'string[8]', 1622 2995 }, 1623 0xac => { #PH (5D)2996 0xac => { #PH 1624 2997 Name => 'ShortOwnerName', 1625 2998 Format => 'string[16]', 1626 Condition => '$$self{CameraModel} =~ /EOS 5D/',1627 Notes => '5D only',1628 2999 }, 1629 3000 0xd0 => { 1630 3001 Name => 'ImageNumber', 3002 Format => 'int16u', 1631 3003 Groups => { 2 => 'Image' }, 1632 Format => 'int16u',1633 Condition => '$$self{CameraModel} =~ /EOS 5D/',1634 Notes => '5D only',1635 3004 ValueConv => '$val + 1', 1636 3005 ValueConvInv => '$val - 1', 1637 3006 }, 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', 1683 3016 # sharpness values are 0-7 1684 3017 0xf1 => 'SharpnessStandard', … … 1704 3037 3 => 'Red', 1705 3038 4 => 'Green', 3039 -559038737 => 'n/a', # (0xdeadbeef) 1706 3040 }, 1707 3041 }, … … 1722 3056 3 => 'Purple', 1723 3057 4 => 'Green', 3058 -559038737 => 'n/a', # (0xdeadbeef) 1724 3059 }, 1725 3060 }, … … 1730 3065 Name => 'UserDef1PictureStyle', 1731 3066 Format => 'int16u', 1732 PrintHex => 1, 3067 PrintHex => 1, # (only needed for one tag) 3068 SeparateTable => 'UserDefStyle', 1733 3069 PrintConv => \%userDefStyles, 1734 3070 }, … … 1736 3072 Name => 'UserDef2PictureStyle', 1737 3073 Format => 'int16u', 1738 PrintHex => 1,3074 SeparateTable => 'UserDefStyle', 1739 3075 PrintConv => \%userDefStyles, 1740 3076 }, … … 1742 3078 Name => 'UserDef3PictureStyle', 1743 3079 Format => 'int16u', 1744 PrintHex => 1,3080 SeparateTable => 'UserDefStyle', 1745 3081 PrintConv => \%userDefStyles, 1746 3082 }, … … 1754 3090 ValueConvInv => 'GetUnixTime($val)', 1755 3091 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', 1767 3101 FIRST_ENTRY => 0, 3102 PRIORITY => 0, 3103 IS_SUBDIR => [ 0x15a, 0x17e ], 1768 3104 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', 1804 3145 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 => { 1815 3154 Name => 'PictureStyle', 1816 3155 Format => 'int8u', 1817 PrintHex => 1,3156 Flags => ['PrintHex','SeparateTable'], 1818 3157 PrintConv => \%pictureStyles, 1819 3158 }, 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', 1844 3220 Groups => { 2 => 'Image' }, 1845 3221 Format => 'int32u', … … 1847 3223 ValueConvInv => '$val - 1', 1848 3224 }, 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' }, 1852 3376 Format => 'int32u', 1853 3377 ValueConv => '$val + 1', 1854 3378 ValueConvInv => '$val - 1', 1855 3379 }, 1856 0x45e => { 1857 Name => 'TimeStamp', 3380 0x1d3 => { #(NC) 3381 Name => 'DirectoryIndex', 3382 Groups => { 2 => 'Image' }, 1858 3383 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, 1875 4100 FORMAT => 'int32s', 1876 4101 FIRST_ENTRY => 0, 4102 PRIORITY => 0, 1877 4103 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 }, 1879 4109 0x00 => { 1880 4110 Name => 'ISO', 1881 4111 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', 1885 4114 PrintConv => 'sprintf("%.0f",$val)', 1886 4115 PrintConvInv => '$val', … … 1889 4118 Name => 'FNumber', 1890 4119 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)', 1894 4122 PrintConv => 'sprintf("%.2g",$val)', 1895 4123 PrintConvInv => '$val', … … 1898 4126 Name => 'ExposureTime', 1899 4127 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)', 1904 4130 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 1905 PrintConvInv => ' eval $val',4131 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 1906 4132 }, 1907 4133 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 }, 1908 4234 ); 1909 4235 1910 4236 # unknown Canon camera information (MakerNotes tag 0x0d) - PH 1911 4237 %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, 1916 4239 FORMAT => 'int32s', 1917 4240 FIRST_ENTRY => 0, 4241 PRIORITY => 0, 1918 4242 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 1919 4243 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 }, 1920 4300 ); 1921 4301 1922 4302 # unknown Canon camera information (MakerNotes tag 0x0d) - PH 1923 4303 %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, 1928 4305 FORMAT => 'int16s', 1929 4306 FIRST_ENTRY => 0, 4307 PRIORITY => 0, 1930 4308 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 1931 4309 ); 1932 4310 1933 4311 # 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, 1939 4314 FORMAT => 'int8s', 1940 4315 FIRST_ENTRY => 0, 4316 PRIORITY => 0, 1941 4317 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 1942 4318 ); 1943 4319 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, 1951 4323 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 1964 4726 ); 1965 4727 … … 1967 4729 %Image::ExifTool::Canon::AFInfo = ( 1968 4730 PROCESS_PROC => \&ProcessSerialData, 4731 VARS => { ID_LABEL => 'Sequence' }, 1969 4732 FORMAT => 'int16u', 1970 4733 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, … … 2017 4780 Name => 'PrimaryAFPoint', 2018 4781 Condition => q{ 2019 $$self{ CameraModel} !~ /EOS/ and4782 $$self{Model} !~ /EOS/ and 2020 4783 (not $$self{AFInfoCount} or $$self{AFInfoCount} != 36) 2021 4784 }, … … 2024 4787 # (some PowerShot 9-point systems put PrimaryAFPoint after 8 unknown values) 2025 4788 Name => 'Canon_AFInfo_0x000b', 2026 Condition => '$$self{ CameraModel} !~ /EOS/',4789 Condition => '$$self{Model} !~ /EOS/', 2027 4790 Format => 'int16u[8]', 2028 4791 Unknown => 1, … … 2037 4800 %Image::ExifTool::Canon::AFInfo2 = ( 2038 4801 PROCESS_PROC => \&ProcessSerialData, 4802 VARS => { ID_LABEL => 'Sequence' }, 2039 4803 FORMAT => 'int16u', 2040 4804 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, … … 2049 4813 }, 2050 4814 1 => { 2051 Name => 'AF Mode',4815 Name => 'AFAreaMode', 2052 4816 PrintConv => { 2053 4817 0 => 'Off (Manual Focus)', 2054 4818 2 => 'Single-point AF', 2055 4 => 'Multi-point AF ', # AiAF on A570IS4819 4 => 'Multi-point AF or AI AF', # AiAF on A570IS 2056 4820 5 => 'Face Detect AF', 4821 7 => 'Zone AF', #46 4822 8 => 'AF Point Expansion', #46 4823 9 => 'Spot AF', #46 2057 4824 }, 2058 4825 }, … … 2070 4837 }, 2071 4838 5 => { 2072 Name => 'CanonImage Width',4839 Name => 'CanonImageHeight', 2073 4840 Groups => { 2 => 'Image' }, 2074 4841 }, … … 2102 4869 { 2103 4870 Name => 'AFPointsSelected', 2104 Condition => '$$self{ CameraModel} =~ /EOS/',4871 Condition => '$$self{Model} =~ /EOS/', 2105 4872 Format => 'int16s[int(($val{2}+15)/16)]', 2106 4873 PrintConv => 'Image::ExifTool::DecodeBits($val, undef, 16)', … … 2115 4882 # usually, but not always, the lowest number AF point in focus 2116 4883 Name => 'PrimaryAFPoint', 2117 Condition => '$$self{ CameraModel} !~ /EOS/',2118 }, 4884 Condition => '$$self{Model} !~ /EOS/', 4885 }, 2119 4886 ); 2120 4887 2121 4888 # my color mode information (MakerNotes tag 0x1d) - PH (A570IS) 2122 4889 %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, 2127 4891 FORMAT => 'int16u', 2128 4892 FIRST_ENTRY => 0, … … 2130 4894 0x02 => { 2131 4895 Name => 'MyColorMode', 4896 PrintConvColumns => 2, 2132 4897 PrintConv => { 2133 4898 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) 2134 4907 9 => 'Custom', 2135 4908 12 => 'Vivid', … … 2143 4916 # face detect information (MakerNotes tag 0x24) - PH (A570IS) 2144 4917 %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, 2149 4919 FORMAT => 'int16u', 2150 4920 FIRST_ENTRY => 0, … … 2156 4926 RawConv => '$$self{FacesDetected} = $val', 2157 4927 }, 2158 0x03 => 'FaceDetectFrameWidth', 2159 0x04 => 'FaceDetectFrameHeight', 4928 0x03 => { 4929 Name => 'FaceDetectFrameSize', 4930 Format => 'int16u[2]', 4931 }, 2160 4932 0x08 => { 2161 Name => 'Face 0Position',4933 Name => 'Face1Position', 2162 4934 Format => 'int16s[2]', 2163 4935 RawConv => '$$self{FacesDetected} < 1 ? undef: $val', … … 2169 4941 }, 2170 4942 0x0a => { 2171 Name => 'Face 1Position',4943 Name => 'Face2Position', 2172 4944 Format => 'int16s[2]', 2173 4945 RawConv => '$$self{FacesDetected} < 2 ? undef : $val', 2174 4946 }, 2175 4947 0x0c => { 2176 Name => 'Face 2Position',4948 Name => 'Face3Position', 2177 4949 Format => 'int16s[2]', 2178 4950 RawConv => '$$self{FacesDetected} < 3 ? undef : $val', 2179 4951 }, 2180 4952 0x0e => { 2181 Name => 'Face 3Position',4953 Name => 'Face4Position', 2182 4954 Format => 'int16s[2]', 2183 4955 RawConv => '$$self{FacesDetected} < 4 ? undef : $val', 2184 4956 }, 2185 4957 0x10 => { 2186 Name => 'Face 4Position',4958 Name => 'Face5Position', 2187 4959 Format => 'int16s[2]', 2188 4960 RawConv => '$$self{FacesDetected} < 5 ? undef : $val', 2189 4961 }, 2190 4962 0x12 => { 2191 Name => 'Face 5Position',4963 Name => 'Face6Position', 2192 4964 Format => 'int16s[2]', 2193 4965 RawConv => '$$self{FacesDetected} < 6 ? undef : $val', 2194 4966 }, 2195 4967 0x14 => { 2196 Name => 'Face 6Position',4968 Name => 'Face7Position', 2197 4969 Format => 'int16s[2]', 2198 4970 RawConv => '$$self{FacesDetected} < 7 ? undef : $val', 2199 4971 }, 2200 4972 0x16 => { 2201 Name => 'Face 7Position',4973 Name => 'Face8Position', 2202 4974 Format => 'int16s[2]', 2203 4975 RawConv => '$$self{FacesDetected} < 8 ? undef : $val', 2204 4976 }, 2205 4977 0x18 => { 2206 Name => 'Face 8Position',4978 Name => 'Face9Position', 2207 4979 Format => 'int16s[2]', 2208 4980 RawConv => '$$self{FacesDetected} < 9 ? undef : $val', … … 2212 4984 # more face detect information (MakerNotes tag 0x25) - PH (A570IS) 2213 4985 %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, 2218 4987 FORMAT => 'int8u', 2219 4988 FIRST_ENTRY => 0, 2220 4989 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, 4990 0x01 => 'FaceWidth', 2221 4991 0x02 => 'FacesDetected', 2222 );2223 2224 # Preview image information (MakerNotes tag 0xb6)2225 # - The 300D writes a 1536x1024 preview image that is accessed2226 # through this information - decoded by PH 12/14/032227 %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 increments2237 # 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 offset2247 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 tagID2256 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 shorts2272 # taking the values of 1,4,4 and 2 respectively - don't know what they are though2273 # 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 software2290 # if these are changed2291 1 => 'SensorWidth',2292 2 => 'SensorHeight',2293 5 => 'SensorLeftBorder', #22294 6 => 'SensorTopBorder', #22295 7 => 'SensorRightBorder', #22296 8 => 'SensorBottomBorder', #22297 4992 ); 2298 4993 2299 4994 # File number information (MakerNotes tag 0x93) 2300 4995 %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, 2305 4997 FORMAT => 'int16s', 2306 4998 FIRST_ENTRY => 1, … … 2309 5001 { #5 2310 5002 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/', 2312 5004 Format => 'int32u', 2313 5005 # Thanks to Juha Eskelinen for figuring this out: … … 2335 5027 { #16 2336 5028 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/', 2338 5030 Format => 'int32u', 2339 5031 Notes => q{ … … 2371 5063 Format => 'int32u', 2372 5064 }, 2373 { #7 (1DmkII, 1D sMkII, 1DsMkIIN)5065 { #7 (1DmkII, 1DSmkII, 1DSmkIIN) 2374 5066 Name => 'ShutterCount', 2375 Condition => '$$self{ CameraModel} =~ /\b1Ds? Mark II\b/',5067 Condition => '$$self{Model} =~ /\b1Ds? Mark II\b/', 2376 5068 Format => 'int32u', 2377 5069 ValueConv => '($val>>16)|(($val&0xffff)<<16)', … … 2404 5096 }, 2405 5097 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 }, 2407 5104 RawConv => '$val<0 ? undef : $val', 2408 5105 PrintConv => { 2409 5106 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', 2415 5110 }, 2416 5111 }, … … 2447 5142 }, 2448 5143 }, 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) 2452 5219 %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, 2457 5221 FORMAT => 'int16s', 2458 5222 FIRST_ENTRY => 1, … … 2468 5232 2 => { #12 2469 5233 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) 2472 5237 }, 2473 5238 3 => { #PH 2474 Name => 'SharpnessFrequency', 5239 Name => 'SharpnessFrequency', # PatternSharpness? 5240 PrintConvColumns => 2, 2475 5241 PrintConv => { 2476 5242 0 => 'n/a', … … 2490 5256 RawConv => '$val < 0 ? undef : $val', 2491 5257 PrintConv => \%canonWhiteBalance, 5258 SeparateTable => 1, 2492 5259 }, 2493 5260 9 => 'ColorTemperature', #6 2494 5261 10 => { #12 2495 5262 Name => 'PictureStyle', 2496 PrintHex => 1,5263 Flags => ['PrintHex','SeparateTable'], 2497 5264 PrintConv => \%pictureStyles, 2498 5265 }, … … 2504 5271 12 => { #PH 2505 5272 Name => 'WBShiftAB', 2506 Notes => 'positive is a shift toward red',5273 Notes => 'positive is a shift toward amber', 2507 5274 }, 2508 5275 13 => { #PH 2509 5276 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 }, 2525 5279 ); 2526 5280 2527 5281 # Color balance information (MakerNotes tag 0xa9) (ref PH) 2528 5282 %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', 2534 5286 FIRST_ENTRY => 0, 2535 WRITABLE => 1,2536 5287 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 2537 5288 # 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, 2555 5303 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',2697 5304 FIRST_ENTRY => 1, 2698 5305 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 2699 5306 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 2712 5312 ); 2713 5313 2714 5314 # Flags information (MakerNotes tag 0xb0) (ref PH) 2715 5315 %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, 2720 5317 FORMAT => 'int16s', 2721 5318 FIRST_ENTRY => 1, … … 2726 5323 # Modified information (MakerNotes tag 0xb1) (ref PH) 2727 5324 %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, 2732 5326 FORMAT => 'int16s', 2733 5327 FIRST_ENTRY => 1, … … 2744 5338 Name => 'ModifiedSharpness', 2745 5339 Notes => '1D and 5D only', 2746 Condition => '$$self{ CameraModel} =~ /\b(1D|5D)/',5340 Condition => '$$self{Model} =~ /\b(1D|5D)/', 2747 5341 }, 2748 5342 3 => { 2749 Name => 'ModifiedSharpnessFreq', 5343 Name => 'ModifiedSharpnessFreq', # ModifiedPatternSharpness? 2750 5344 PrintConv => { 2751 5345 0 => 'n/a', 2752 1 => ' Smoothest',2753 2 => ' Smooth',5346 1 => 'Lowest', 5347 2 => 'Low', 2754 5348 3 => 'Standard', 2755 4 => ' Sharp',2756 5 => ' Sharpest',5349 4 => 'High', 5350 5 => 'Highest', 2757 5351 }, 2758 5352 }, … … 2764 5358 Name => 'ModifiedWhiteBalance', 2765 5359 PrintConv => \%canonWhiteBalance, 5360 SeparateTable => 'WhiteBalance', 2766 5361 }, 2767 5362 9 => 'ModifiedColorTemp', … … 2769 5364 Name => 'ModifiedPictureStyle', 2770 5365 PrintHex => 1, 5366 SeparateTable => 'PictureStyle', 2771 5367 PrintConv => \%pictureStyles, 2772 5368 }, … … 2778 5374 ); 2779 5375 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 2781 6105 %Image::ExifTool::Canon::Composite = ( 2782 6106 GROUPS => { 2 => 'Camera' }, … … 2784 6108 Require => { 2785 6109 0 => 'ContinuousDrive', 2786 1 => 'Self -timer',6110 1 => 'SelfTimer', 2787 6111 }, 2788 6112 ValueConv => '$val[0] ? 0 : ($val[1] ? 1 : 2)', 2789 6113 PrintConv => { 2790 0 => 'Continuous shooting',6114 0 => 'Continuous Shooting', 2791 6115 1 => 'Self-timer Operation', 2792 2 => 'Single-frame shooting',6116 2 => 'Single-frame Shooting', 2793 6117 }, 2794 6118 }, … … 2812 6136 }, 2813 6137 ValueConv => '$val[3] * ($val[2] ? $val[2] : 1)', 2814 PrintConv => '$prt[3] . ($val[2] ? sprintf(" (35 mm equivalent: %s)",Image::ExifTool::Canon::PrintFocalRange(@val)) : "")',6138 PrintConv => '$prt[3] . ($val[2] ? sprintf(" (35 mm equivalent: %s)",Image::ExifTool::Canon::PrintFocalRange(@val)) : "")', 2815 6139 }, 2816 6140 ShootingMode => { … … 2819 6143 1 => 'EasyMode', 2820 6144 }, 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])', 2823 6153 }, 2824 6154 FlashType => { 6155 Notes => q{ 6156 may report "Built-in Flash" for some Canon cameras with external flash in 6157 manual mode 6158 }, 2825 6159 Require => { 2826 6160 0 => 'FlashBits', … … 2840 6174 RawConv => '$val[1] ? $val : undef', 2841 6175 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 only2848 FlashOn => {2849 Description => 'Flash',2850 Desire => {2851 0 => 'FlashBits',2852 1 => 'Flash',2853 },2854 ValueConv => 'Image::ExifTool::Canon::FlashOn(@val)',2855 6176 PrintConv => { 2856 6177 0 => 'Off', … … 2926 6247 }, 2927 6248 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]; 2929 6251 return $val[1] / $val[0]; 2930 6252 }, 2931 6253 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 }, 2933 6276 ); 2934 6277 … … 2936 6279 Image::ExifTool::AddCompositeTags('Image::ExifTool::Canon'); 2937 6280 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 6285 sub 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. 6309 sub 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 6375 sub SwapWords($) 6376 { 6377 my @a = split(' ', shift); 6378 $_ = (($_ >> 16) | ($_ << 16)) & 0xffffffff foreach @a; 6379 return "@a"; 6380 } 2938 6381 2939 6382 #------------------------------------------------------------------------------ … … 2981 6424 return 1 if abs(1-$f1*$f2) < 0.01; 2982 6425 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) 6432 sub 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; 2983 6525 } 2984 6526 … … 3024 6566 $scale or $scale = 1; 3025 6567 if ($short == $long) { 3026 return sprintf("%.1f mm", $short * $scale);6568 return sprintf("%.1f mm", $short * $scale); 3027 6569 } else { 3028 return sprintf("%.1f - %.1f mm", $short * $scale, $long * $scale);6570 return sprintf("%.1f - %.1f mm", $short * $scale, $long * $scale); 3029 6571 } 3030 6572 } 3031 6573 3032 6574 #------------------------------------------------------------------------------ 3033 # process a serial stream of binary data6575 # Process a serial stream of binary data 3034 6576 # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref 3035 6577 # Returns: 1 on success … … 3121 6663 # Inputs: 0) value to convert 3122 6664 # Focus point pattern: 3123 # A1 A2 A3 A4 A5 A6 A73124 # B1 B2 B3 B4 B5 B6 B7 B8 B9 B103125 # C1 C2 C3 C4 C5 C6 C7 C9 C9 C10 C113126 # D1 D2 D3 D4 D5 D6 D7 D8 D9 D103127 # E1 E2 E3 E4 E5 E6 E76665 # 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 3128 6670 sub PrintAFPoints1D($) 3129 6671 { 3130 6672 my $val = shift; 3131 6673 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) 3134 6677 my @focusPts = (0,0, 3135 6678 0x04,0x06,0x08,0x0a,0x0c,0x0e,0x10, 0,0, … … 3154 6697 $focusing or $focusing = ($focus eq 0xff) ? 'Auto' : sprintf('Unknown (0x%.2x)',$focus); 3155 6698 return "$focusing (" . join(',',@points) . ')'; 3156 }3157 3158 #------------------------------------------------------------------------------3159 # Decide whether flash was on or off3160 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;3171 6699 } 3172 6700 … … 3229 6757 3230 6758 #------------------------------------------------------------------------------ 6759 # Process a creative filter data 6760 # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref 6761 # Returns: 1 on success 6762 sub 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 #------------------------------------------------------------------------------ 3231 6815 # Write Canon maker notes 3232 6816 # Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table ref … … 3237 6821 $exifTool or return 1; # allow dummy access to autoload this package 3238 6822 my $dirData = Image::ExifTool::Exif::WriteExif($exifTool, $dirInfo, $tagTablePtr); 3239 # add trailer which is written by some Canon models (it'sa TIFF header)6823 # add footer which is written by some Canon models (format of a TIFF header) 3240 6824 if (defined $dirData and length $dirData and $$dirInfo{Fixup}) { 3241 6825 $dirData .= GetByteOrder() . Set16u(42) . Set32u(0); … … 3265 6849 =head1 AUTHOR 3266 6850 3267 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)6851 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 3268 6852 3269 6853 This library is free software; you can redistribute it and/or modify it … … 3291 6875 the Digital Ixus and PowerShot S70 cameras, Juha Eskelinen and Emil Sit for 3292 6876 figuring 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. 6877 couple of 1D tags, and Michael Tiemann, Rainer Honle, Dave Nicholson, Chris 6878 Huebsch, Ger Vermeulen, Darryl Zurn, D.J. Cristi, Bogdan and Vesa Kivisto for 6879 decoding a number of new tags. Also thanks to everyone who made contributions 6880 to the LensType lookup list or the meanings of other tag values. 3296 6881 3297 6882 =head1 SEE ALSO -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonCustom.pm
r16842 r24107 7 7 # 8 8 # 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) 11 12 #------------------------------------------------------------------------------ 12 13 … … 19 20 use Image::ExifTool::Exif; 20 21 21 $VERSION = '1. 17';22 $VERSION = '1.40'; 22 23 23 24 sub ProcessCanonCustom($$$); … … 122 123 }, 123 124 9 => { 124 Name => 'AEBSequence', 125 Name => 'AEBSequenceAutoCancel', 126 Description => 'AEB Sequence/Auto Cancel', 125 127 PrintConv => { 126 128 0 => '0,-,+/Enabled', … … 212 214 3 => 'Moderately fast', 213 215 4 => 'Fast', 216 }, 217 }, 218 21 => { 219 Name => 'AIServoContinuousShooting', 220 PrintConv => { 221 0 => 'Shooting not possible without focus', 222 1 => 'Shooting possible without focus', 214 223 }, 215 224 }, … … 291 300 }, 292 301 9 => { 293 Name => 'AEBSequence', 302 Name => 'AEBSequenceAutoCancel', 303 Description => 'AEB Sequence/Auto Cancel', 294 304 PrintConv => { 295 305 0 => '0,-,+/Enabled', … … 381 391 WRITABLE => 'int8u', 382 392 1 => { 383 Name => 'SetButton Function',384 PrintConv => { 385 0 => 'No t assigned',386 1 => ' Change quality',393 Name => 'SetButtonWhenShooting', 394 PrintConv => { 395 0 => 'Normal (disabled)', 396 1 => 'Image quality', 387 397 2 => 'Change parameters', 388 398 3 => 'Menu display', 389 4 => 'Image replay',399 4 => 'Image playback', 390 400 }, 391 401 }, … … 456 466 }, 457 467 9 => { 458 Name => 'AEBSequence', 468 Name => 'AEBSequenceAutoCancel', 469 Description => 'AEB Sequence/Auto Cancel', 459 470 PrintConv => { 460 471 0 => '0,-,+/Enabled', … … 508 519 Name => 'LensAFStopButton', 509 520 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', 513 527 }, 514 528 }, … … 579 593 }, 580 594 8 => { 581 Name => 'AEBSequence', 595 Name => 'AEBSequenceAutoCancel', 596 Description => 'AEB Sequence/Auto Cancel', 582 597 PrintConv => { 583 598 0 => '0,-,+/Enabled', … … 715 730 }, 716 731 9 => { 717 Name => 'AEBSequence', 732 Name => 'AEBSequenceAutoCancel', 733 Description => 'AEB Sequence/Auto Cancel', 718 734 PrintConv => { 719 735 0 => '0,-,+/Enabled', … … 960 976 WRITE_PROC => \&WriteCanonCustom, 961 977 CHECK_PROC => \&CheckCanonCustom, 962 NOTES => 'Custom functions for the EOS -D30 and D60.',978 NOTES => 'Custom functions for the EOS D30 and D60.', 963 979 WRITABLE => 'int8u', 964 980 1 => { … … 1003 1019 }, 1004 1020 7 => { 1005 Name => 'AEBSequence', 1021 Name => 'AEBSequenceAutoCancel', 1022 Description => 'AEB Sequence/Auto Cancel', 1006 1023 PrintConv => { 1007 1024 0 => '0,-,+/Enabled', … … 1039 1056 }, 1040 1057 12 => { 1041 Name => 'SetButton Function',1042 PrintConv => { 1043 0 => ' Not assigned',1044 1 => ' Change quality',1058 Name => 'SetButtonWhenShooting', 1059 PrintConv => { 1060 0 => 'Default (no function)', 1061 1 => 'Image quality', 1045 1062 2 => 'Change ISO speed', 1046 3 => ' Selectparameters',1063 3 => 'Change parameters', 1047 1064 }, 1048 1065 }, … … 1133 1150 ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val*8/1000)/log(2))/4', 1134 1151 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 1135 PrintConvInv => ' eval $val',1152 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 1136 1153 }, 1137 1154 5 => { … … 1141 1158 ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val*8/1000)/log(2))/4', 1142 1159 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 1143 PrintConvInv => ' eval $val',1160 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 1144 1161 }, 1145 1162 6 => { … … 1187 1204 NOTES => q{ 1188 1205 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 has1190 57 custom function tags divided into four main groups: 1. Exposure1191 (0x0101-0x010f), 2. Image (0x0201-0x0203), Flash Exposure (0x0304-0x0306)1192 and Display (0x0407-0x0409), 3. Auto Focus (0x0501-0x050e) and Drive1193 (0x060f-0x0611), and 4. Operation (0x0701-0x070a) and Others1206 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 1194 1211 (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. 1198 1213 }, 1199 1214 # grouped in 4 groups: … … 1202 1217 { 1203 1218 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', 1214 1221 PrintConv => { 1215 1222 0 => '1/3-stop set, 1/3-stop comp.', … … 1218 1225 }, 1219 1226 }, 1227 { 1228 Name => 'ExposureLevelIncrements', 1229 Notes => 'other models', 1230 PrintConv => { 1231 0 => '1/3 Stop', 1232 1 => '1/2 Stop', 1233 }, 1234 }, 1220 1235 ], 1221 1236 0x0102 => { 1222 1237 Name => 'ISOSpeedIncrements', 1223 1238 PrintConv => { 1224 0 => '1/3 -stop',1225 1 => '1 -stop',1239 0 => '1/3 Stop', 1240 1 => '1 Stop', 1226 1241 }, 1227 1242 }, 1228 1243 0x0103 => [ 1229 1244 { 1230 Name => 'ISOExpansion',1231 Condition => '$$self{CameraModel} =~ /\b40D\b/',1232 Notes => '40D',1233 PrintConv => {1234 0 => 'Off',1235 1 => 'On',1236 },1237 },1238 {1239 1245 Name => 'ISOSpeedRange', 1240 Notes => '1D Mark III', 1246 Condition => '$$self{Model} =~ /\b1D/', 1247 Notes => '1DmkIII and 1DmkIV', 1241 1248 Count => 3, 1242 1249 # (this decoding may not be valid for CR2 images?) 1243 1250 ValueConv => [ 1244 1251 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) 1247 1256 ], 1248 1257 ValueConvInv => [ 1249 1258 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)', 1252 1261 ], 1253 1262 PrintConv => [ … … 1258 1267 PrintConvInv => [ 1259 1268 undef, 1260 '$val=~/( [\d.]+)/ ? $1 : 0',1261 '$val=~/( [\d.]+)/ ? $1 : 0',1269 '$val=~/(-?[\d.]+)/ ? $1 : 0', 1270 '$val=~/(-?[\d.]+)/ ? $1 : 0', 1262 1271 ], 1272 }, 1273 { 1274 Name => 'ISOExpansion', 1275 Notes => 'other models', 1276 PrintConv => { 1277 0 => 'Off', 1278 1 => 'On', 1279 }, 1263 1280 }, 1264 1281 ], … … 1269 1286 0x0105 => { 1270 1287 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', 1272 1289 PrintConv => { 1273 1290 0 => '0,-,+', … … 1278 1295 0x0106 => { 1279 1296 Name => 'AEBShotCount', 1280 PrintConv => { 1297 Count => -1, 1298 Notes => '1 value for the 1DmkIII, 2 for the 1DmkIV', 1299 PrintConv => [{ 1281 1300 0 => 3, 1282 1301 1 => 2, 1283 1302 2 => 5, 1284 1303 3 => 7, 1285 } ,1304 }], 1286 1305 }, 1287 1306 0x0107 => { … … 1294 1313 0x0108 => { 1295 1314 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', 1297 1316 PrintConv => { 1298 1317 0 => 'Disable', … … 1386 1405 Name => 'ApplyShootingMeteringMode', 1387 1406 Count => 8, 1388 PrintConv => [ 1389 \%disableEnable, 1390 ], 1407 PrintConv => [ \%disableEnable ], 1391 1408 }, 1392 1409 0x010f => [ 1393 1410 { 1394 1411 Name => 'FlashSyncSpeedAv', 1395 Condition => '$$self{ CameraModel} =~ /\b40D\b/',1412 Condition => '$$self{Model} =~ /\b40D\b/', 1396 1413 Notes => '40D', 1397 1414 PrintConv => { … … 1402 1419 { 1403 1420 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', 1404 1460 Notes => '1D Mark III', 1405 1461 PrintConv => { … … 1409 1465 }, 1410 1466 ], 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 }, 1411 1477 #### 2a) Image 1412 1478 0x0201 => { … … 1418 1484 }, 1419 1485 }, 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 ], 1424 1504 0x0203 => { 1425 1505 Name => 'HighlightTonePriority', 1426 1506 PrintConv => \%disableEnable 1427 1507 }, 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 ], 1428 1526 #### 2b) Flash exposure 1429 1527 0x0304 => { … … 1458 1556 PrintConv => \%offOn, 1459 1557 }, 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 ], 1467 1578 #### 3a) Auto focus 1468 1579 0x0501 => { … … 1490 1601 1 => '1: AF, 2: Drive speed', 1491 1602 2 => '1: Release, 2: Drive speed', 1603 3 => '1: Release, 2: Tracking', # 7D/1DmkIV 1492 1604 }, 1493 1605 }, … … 1508 1620 0x0506 => { 1509 1621 Name => 'LensAFStopButton', 1510 Notes => 'value of 6 not used by 40D ',1622 Notes => 'value of 6 not used by 40D, 50D and 5DmkII', 1511 1623 PrintConv => { 1512 1624 0 => 'AF stop', … … 1517 1629 5 => 'IS start', 1518 1630 6 => 'Switch to registered AF point', 1631 7 => 'Spot AF', # 1DmkIV 1519 1632 }, 1520 1633 }, … … 1531 1644 ], 1532 1645 }, 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 ], 1553 1709 0x050b => { 1554 1710 Name => 'AFPointAutoSelection', … … 1574 1730 }, 1575 1731 }, 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 }, 1600 1848 }, 1601 1849 #### 3b) Drive 1602 1850 0x060f => { 1603 1851 Name => 'MirrorLockup', 1604 Notes => 'value of 2 not used by 40D',1852 Notes => 'value of 2 not used by some models', 1605 1853 PrintConv => { 1606 1854 0 => 'Disable', … … 1636 1884 }, 1637 1885 #### 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 ], 1648 1922 0x0702 => { 1649 1923 Name => 'AFOnAELockButtonSwitch', … … 1656 1930 1 => 'AF point selection', 1657 1931 2 => 'ISO speed', 1932 3 => 'AF point selection swapped with Exposure comp', #4 1933 4 => 'ISO speed swapped with Exposure comp', #4 1658 1934 }, 1659 1935 }, … … 1661 1937 { 1662 1938 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', 1665 1941 PrintConv => { 1666 1942 0 => 'Normal (disabled)', … … 1669 1945 3 => 'Menu display', 1670 1946 4 => 'Image playback', 1947 5 => 'Quick control screen', #50D 1948 6 => 'Record movie (Live View)', #5DmkII 1671 1949 }, 1672 1950 }, 1673 1951 { 1674 1952 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', 1676 2005 PrintConv => { 1677 2006 0 => 'Normal (disabled)', … … 1715 2044 Name => 'LockMicrophoneButton', 1716 2045 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 1719 2050 }, 1720 2051 }, … … 1726 2057 }, 1727 2058 }, 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 }, 1728 2080 #### 4b) Others 1729 2081 0x080b => [ 1730 2082 { 1731 2083 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', 1734 2086 PrintConv => { 1735 2087 0 => 'Ef-A', … … 1740 2092 { 1741 2093 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', 1743 2105 PrintConv => { 1744 2106 0 => 'Ec-CIV', … … 1754 2116 PrintConv => [ 1755 2117 \%disableEnable, 1756 '"6 s ec: $val"',1757 '"16 s ec: $val"',2118 '"6 s: $val"', 2119 '"16 s: $val"', 1758 2120 '"After release: $val"', 1759 2121 ], … … 1782 2144 }, 1783 2145 0x080f => { 1784 Name => 'AddOriginalDecisionData', 2146 Name => 'AddOriginalDecisionData', # called ("image verification" in 1DmkIV manual) 1785 2147 PrintConv => \%offOn, 1786 2148 }, … … 1790 2152 0 => 'Disable (LCD auto adjust)', 1791 2153 1 => 'Enable (simulates exposure)', 2154 }, 2155 }, 2156 0x0811 => { 2157 Name => 'LCDDisplayAtPowerOn', 2158 PrintConv => { 2159 0 => 'Display', 2160 1 => 'Retain power off status', 1792 2161 }, 1793 2162 }, … … 1835 2204 if ($write) { 1836 2205 $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr); 1837 $exifTool->VPrint(0, " Rewriting CanonCustom2\n") if $verbose;2206 $exifTool->VPrint(0, " Rewriting CanonCustom2\n"); 1838 2207 } elsif ($verbose) { 1839 2208 $exifTool->VerboseDir('CanonCustom2', $count); … … 1865 2234 my $tagInfo = $$newTags{$tag}; 1866 2235 next unless $tagInfo; 1867 my $n ewValueHash = $exifTool->GetNewValueHash($tagInfo);1868 next unless Image::ExifTool::IsOverwriting($n ewValueHash, $val);1869 my $newVal = Image::ExifTool::GetNewValues($n ewValueHash);2236 my $nvHash = $exifTool->GetNewValueHash($tagInfo); 2237 next unless Image::ExifTool::IsOverwriting($nvHash, $val); 2238 my $newVal = Image::ExifTool::GetNewValues($nvHash); 1870 2239 next unless defined $newVal; # can't delete from a custom table 1871 2240 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); 1876 2243 ++$exifTool->{CHANGED}; 1877 2244 } else { 1878 # extract the value2245 # save extracted tag 1879 2246 my $oldInfo = $$tagTablePtr{$tag}; 1880 2247 $exifTool->HandleTag($tagTablePtr, $tag, $val, … … 1936 2303 # first entry in array must be the size 1937 2304 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)) { 1939 2306 $exifTool->Warn("Invalid CanonCustom data"); 1940 2307 return 0; … … 1979 2346 my $dirLen = $$dirInfo{DirLen} || length($$dataPt) - $dirStart; 1980 2347 my $dirName = $$dirInfo{DirName}; 1981 my $verbose = $exifTool->Options('Verbose');1982 2348 my $newData = substr($$dataPt, $dirStart, $dirLen) or return undef; 1983 2349 $dataPt = \$newData; … … 1985 2351 # first entry in array must be the size 1986 2352 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)) { 1988 2354 $exifTool->Warn("Invalid CanonCustom data"); 1989 2355 return undef; … … 1996 2362 my $tagInfo = $$newTags{$tag}; 1997 2363 next unless $tagInfo; 1998 my $n ewValueHash = $exifTool->GetNewValueHash($tagInfo);2364 my $nvHash = $exifTool->GetNewValueHash($tagInfo); 1999 2365 $val = ($val & 0xff); 2000 next unless Image::ExifTool::IsOverwriting($n ewValueHash, $val);2001 my $newVal = Image::ExifTool::GetNewValues($n ewValueHash);2366 next unless Image::ExifTool::IsOverwriting($nvHash, $val); 2367 my $newVal = Image::ExifTool::GetNewValues($nvHash); 2002 2368 next unless defined $newVal; # can't delete from a custom table 2003 2369 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); 2008 2372 ++$exifTool->{CHANGED}; 2009 2373 } … … 2033 2397 =head1 AUTHOR 2034 2398 2035 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)2399 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 2036 2400 2037 2401 This library is free software; you can redistribute it and/or modify it … … 2049 2413 2050 2414 Thanks to Christian Koller for his work in decoding the 20D custom 2051 functions, and Rainer Honle for decoding the 5D custom functions. 2415 functions, Rainer Honle for decoding the 5D custom functions and David 2416 Pitcher for adding a few undocumented 1DmkIII settings. 2052 2417 2053 2418 =head1 SEE ALSO -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonRaw.pm
r16842 r24107 12 12 # 2) http://www.wonderland.org/crw/ 13 13 # 3) http://xyrion.org/ciff/CIFFspecV1R04.pdf 14 # 4) Dave Nicholson private communication (PowerShot S30) 14 15 #------------------------------------------------------------------------------ 15 16 … … 18 19 use strict; 19 20 use vars qw($VERSION $AUTOLOAD %crwTagFormat); 20 use Image::ExifTool qw(:DataAccess );21 use Image::ExifTool qw(:DataAccess :Utils); 21 22 use Image::ExifTool::Exif; 22 23 use Image::ExifTool::Canon; 23 24 24 $VERSION = '1. 42';25 $VERSION = '1.54'; 25 26 26 27 sub WriteCRW($$); … … 132 133 }, 133 134 }, 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 }, 135 143 0x102d => { 136 144 Name => 'CanonCameraSettings', … … 138 146 SubDirectory => { 139 147 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', 140 156 }, 141 157 }, … … 152 168 { 153 169 Name => 'CustomFunctions10D', 154 Condition => '$self->{ CameraModel} =~ /EOS 10D/',170 Condition => '$self->{Model} =~ /EOS 10D/', 155 171 SubDirectory => { 156 172 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', … … 160 176 { 161 177 Name => 'CustomFunctionsD30', 162 Condition => '$self->{ CameraModel} =~ /EOS D30\b/',178 Condition => '$self->{Model} =~ /EOS D30\b/', 163 179 SubDirectory => { 164 180 Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', … … 168 184 { 169 185 Name => 'CustomFunctionsD60', 170 Condition => '$self->{ CameraModel} =~ /EOS D60\b/',186 Condition => '$self->{Model} =~ /EOS D60\b/', 171 187 SubDirectory => { 172 188 # the stored size in the D60 apparently doesn't include the size word: … … 241 257 ValueConv => '$val / 1000', 242 258 ValueConvInv => '$val * 1000', 243 PrintConv => '"$val s ec"',244 PrintConvInv => '$val=~s/\s*s ec.*//;$val',259 PrintConv => '"$val s"', 260 PrintConvInv => '$val=~s/\s*s.*//;$val', 245 261 }, 246 262 0x1807 => { … … 250 266 PrintConvInv => '$val=~s/\s*mm$//;$val', 251 267 }, 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 ], 259 291 0x180e => { 260 292 Name => 'TimeStamp', … … 281 313 Name => 'MeasuredEV', 282 314 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 285 318 }, 286 319 Format => 'float', 320 ValueConv => '$val + 5', 321 ValueConvInv => '$val - 5', 287 322 }, 288 323 0x1817 => { … … 295 330 0x1818 => { #3 296 331 Name => 'ExposureInfo', 332 Groups => { 1 => 'CIFF' }, # (only so CIFF shows up in group lists) 297 333 Writable => 0, 298 334 SubDirectory => { … … 314 350 Name => 'DecoderTable', 315 351 Writable => 0, 352 SubDirectory => { 353 TagTable => 'Image::ExifTool::CanonRaw::DecoderTable', 354 }, 316 355 }, 317 356 0x183b => { #PH … … 334 373 Writable => 'resize', # 'resize' allows this value to change size 335 374 Permanent => 0, 336 ValueConv => '$self->ValidateImage(\$val,$tag)', 337 ValueConvInv => '$val', 375 RawConv => '$self->ValidateImage(\$val,$tag)', 338 376 }, 339 377 0x2008 => { … … 342 380 WriteCheck => '$self->CheckImage(\$val)', 343 381 Permanent => 0, 344 ValueConv => '$self->ValidateImage(\$val,$tag)', 345 ValueConvInv => '$val', 382 RawConv => '$self->ValidateImage(\$val,$tag)', 346 383 }, 347 384 # the following entries are subdirectories … … 398 435 Name => 'Make', 399 436 Format => 'string[6]', # "Canon\0" 400 DataMember => ' CameraMake',401 RawConv => '$self->{ CameraMake} = $val',437 DataMember => 'Make', 438 RawConv => '$self->{Make} = $val', 402 439 }, 403 440 6 => { 404 441 Name => 'Model', 405 Format => 'string [$size-6]',442 Format => 'string', # no size = to the end of the data 406 443 Description => 'Camera Model Name', 407 DataMember => ' CameraModel',408 RawConv => '$self->{ CameraModel} = $val',444 DataMember => 'Model', 445 RawConv => '$self->{Model} = $val', 409 446 }, 410 447 ); … … 425 462 ValueConvInv => 'GetUnixTime($val)', 426 463 PrintConv => '$self->ConvertDateTime($val)', 427 PrintConvInv => '$ val',464 PrintConvInv => '$self->InverseDateTime($val)', 428 465 }, 429 466 1 => { #3 … … 514 551 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, 515 552 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 }, 518 567 ); 519 568 … … 523 572 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 524 573 FORMAT => 'int32u', 525 FIRST_ENTRY => 1,574 FIRST_ENTRY => 0, 526 575 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, 527 576 # Note: Don't make these writable (except rotation) because it confuses … … 541 590 5 => 'ColorBitDepth', #3 542 591 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) 543 621 ); 544 622 … … 576 654 $raf->Read($buff, 10 * $entries) == 10 * $entries or return 0; 577 655 578 $verbose and $exifTool->VerboseDir(' Raw', $entries);656 $verbose and $exifTool->VerboseDir('CIFF', $entries); 579 657 my $index; 580 658 for ($index=0; $index<$entries; ++$index) { … … 649 727 $value = "Binary data $size bytes"; 650 728 if ($tagInfo) { 651 if ($exifTool->Options('Binary') ) {729 if ($exifTool->Options('Binary') or $verbose) { 652 730 # read the value anyway 653 731 unless ($raf->Seek($ptr, 0) and $raf->Read($value, $size) == $size) { … … 695 773 my $newTagTable; 696 774 if ($$subdir{TagTable}) { 697 $newTagTable = Image::ExifTool::GetTagTable($$subdir{TagTable});775 $newTagTable = GetTagTable($$subdir{TagTable}); 698 776 unless ($newTagTable) { 699 777 warn "Unknown tag table $$subdir{TagTable}\n"; … … 761 839 762 840 # set the FileType tag unless already done (ie. APP0 CIFF record in JPEG image) 763 $exifTool->SetFileType() unless $exifTool->GetValue('FileType');841 $exifTool->SetFileType(); 764 842 765 843 # build directory information for main raw directory … … 774 852 775 853 # process the raw directory 776 my $rawTagTable = Image::ExifTool::GetTagTable('Image::ExifTool::CanonRaw::Main');854 my $rawTagTable = GetTagTable('Image::ExifTool::CanonRaw::Main'); 777 855 unless ($exifTool->ProcessDirectory(\%dirInfo, $rawTagTable)) { 778 856 $exifTool->Warn('CRW file format error'); … … 782 860 $buildMakerNotes and SaveMakerNotes($exifTool); 783 861 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 } 787 867 788 868 return 1; … … 816 896 =head1 AUTHOR 817 897 818 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)898 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 819 899 820 900 This library is free software; you can redistribute it and/or modify it … … 834 914 835 915 =back 916 917 =head1 ACKNOWLEDGEMENTS 918 919 Thanks to Dave Nicholson for decoding a number of new tags. 836 920 837 921 =head1 SEE ALSO -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonVRD.pm
r16842 r24107 4 4 # Description: Read/write Canon VRD information 5 5 # 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) 7 15 #------------------------------------------------------------------------------ 8 16 … … 13 21 use Image::ExifTool qw(:DataAccess :Utils); 14 22 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 25 sub ProcessCanonVRD($$;$); 26 sub WriteCanonVRD($$;$); 27 sub ProcessEditData($$$); 28 sub ProcessIHL($$$); 29 sub ProcessIHLExif($$$); 30 31 # map for adding directories to VRD 32 my %vrdMap = ( 33 XMP => 'CanonVRD', 34 CanonVRD => 'VRD', 35 ); 20 36 21 37 my %noYes = ( 0 => 'No', 1 => 'Yes' ); 22 38 23 # main tag table IPTC-format records in CanonVRD trailer39 # main tag table blocks in CanonVRD trailer (ref PH) 24 40 %Image::ExifTool::CanonVRD::Main = ( 25 VARS => { INDEX => 1 }, 41 WRITE_PROC => \&WriteCanonVRD, 42 PROCESS_PROC => \&ProcessCanonVRD, 26 43 NOTES => q{ 27 44 Canon Digital Photo Professional writes VRD (Recipe Data) information as a 28 45 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. The30 complete VRD data record may be accessed as a block using the Extra46 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 31 48 'CanonVRD' tag, but this tag is not extracted or copied unless specified 32 49 explicitly. 33 50 }, 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.', 34 76 0 => { 35 77 Name => 'VRD1', … … 50 92 ); 51 93 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) 53 142 %Image::ExifTool::CanonVRD::Ver1 = ( 54 143 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, … … 56 145 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 57 146 WRITABLE => 1, 147 FIRST_ENTRY => 0, 58 148 GROUPS => { 2 => 'Image' }, 149 DATAMEMBER => [ 0x002 ], # necessary for writing 59 150 # 60 151 # RAW image adjustment … … 64 155 Format => 'int16u', 65 156 Writable => 0, 157 DataMember => 'VRDVersion', 158 RawConv => '$$self{VRDVersion} = $val', 66 159 PrintConv => 'sprintf("%.2f", $val / 100)', 67 160 }, … … 162 255 PrintConv => \%noYes, 163 256 }, 257 0x113 => { 258 Name => 'ToneCurveMode', 259 PrintConv => { 0 => 'RGB', 1 => 'Luminance' }, 260 }, 164 261 0x114 => { 165 262 Name => 'BrightnessAdj', … … 178 275 Notes => 'in degrees, so -1 is the same as 359', 179 276 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' }, 180 292 }, 181 293 0x160 => { … … 185 297 PrintConvInv => 'Image::ExifTool::CanonVRD::ToneCurvePrintInv($val)', 186 298 }, 299 # 0x193 same as 0x159 187 300 0x19a => { 188 301 Name => 'GreenCurvePoints', … … 191 304 PrintConvInv => 'Image::ExifTool::CanonVRD::ToneCurvePrintInv($val)', 192 305 }, 306 # 0x1cd same as 0x159 193 307 0x1d4 => { 194 308 Name => 'BlueCurvePoints', … … 199 313 0x18a => { 200 314 Name => 'RedCurveLimits', 201 Notes => '4 numbers: input and output highlight and shadow points',202 315 Format => 'int16u[4]', 203 316 }, … … 210 323 Format => 'int16u[4]', 211 324 }, 325 # 0x207 same as 0x159 212 326 0x20e => { 213 327 Name => 'RGBCurvePoints', … … 220 334 Format => 'int16u[4]', 221 335 }, 336 # 0x241 same as 0x159 222 337 0x244 => { 223 338 Name => 'CropActive', … … 240 355 0x24c => { 241 356 Name => 'CropHeight', 357 Format => 'int16u', 358 }, 359 0x25a => { 360 Name => 'SharpnessAdj', 242 361 Format => 'int16u', 243 362 }, … … 303 422 }, 304 423 }, 305 # (VRD 1.0 edit data ends here -- 0x272 bytes long)424 # (VRD 1.0 edit data ends here -- 0x272 bytes) 306 425 ); 307 426 308 # VRD Stamp Tool tags 427 # VRD Stamp Tool tags (ref PH) 309 428 %Image::ExifTool::CanonVRD::StampTool = ( 310 429 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, … … 316 435 ); 317 436 318 # VRD version 2 and 3 tags 437 # VRD version 2 and 3 tags (ref PH) 319 438 %Image::ExifTool::CanonVRD::Ver2 = ( 320 439 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, … … 322 441 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 323 442 WRITABLE => 1, 443 FIRST_ENTRY => 0, 444 FORMAT => 'int16s', 445 DATAMEMBER => [ 0x58 ], # (required for writable var-format tags) 324 446 GROUPS => { 2 => 'Image' }, 325 447 NOTES => 'Tags added in DPP version 2.0 and later.', 326 0x0 4=> {448 0x02 => { 327 449 Name => 'PictureStyle', 328 Format => 'int16u',329 450 PrintConv => { 330 451 0 => 'Standard', … … 334 455 4 => 'Faithful', 335 456 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', 353 463 PrintConv => \%noYes, 354 464 }, 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', 355 492 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 => { 368 526 Name => 'MonochromeFilterEffect', 369 Format => 'int16s',370 527 PrintConv => { 371 528 -2 => 'None', … … 376 533 }, 377 534 }, 378 0x 76=> {535 0x3b => { 379 536 Name => 'MonochromeToningEffect', 380 Format => 'int16s',381 537 PrintConv => { 382 538 -2 => 'None', … … 387 543 }, 388 544 }, 389 0x78 => { 390 Name => 'MonochromeContrast', 391 Format => 'int16s', 392 }, 393 0x7a => { 545 0x3c => 'MonochromeContrast', 546 0x3d => { 394 547 Name => 'MonochromeLinear', 395 Format => 'int16u',396 548 PrintConv => \%noYes, 397 549 }, 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 => [{ 404 586 Name => 'ChrominanceNoiseReduction', 405 Format => 'int16u', 587 Condition => '$$self{VRDVersion} < 330', 588 Notes => 'VRDVersion prior to 3.30', 406 589 PrintConv => { 407 590 0 => 'Off', … … 409 592 100 => 'High', 410 593 }, 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 => [{ 413 624 Name => 'LuminanceNoiseReduction', 414 Format => 'int16u', 625 Condition => '$$self{VRDVersion} < 330', 626 Notes => 'VRDVersion prior to 3.30', 415 627 PrintConv => { 416 628 0 => 'Off', … … 418 630 100 => 'High', 419 631 }, 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 => [{ 422 662 Name => 'ChrominanceNR_TIFF_JPEG', 423 Format => 'int16u', 663 Condition => '$$self{VRDVersion} < 330', 664 Notes => 'VRDVersion prior to 3.30', 424 665 PrintConv => { 425 666 0 => 'Off', … … 427 668 100 => 'High', 428 669 }, 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) 431 878 ); 432 879 … … 461 908 462 909 #------------------------------------------------------------------------------ 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 913 sub 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 1014 sub 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 1055 sub 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 #------------------------------------------------------------------------------ 463 1068 # Read/write Canon VRD file 464 1069 # Inputs: 0) ExifTool object reference, 1) dirInfo reference … … 470 1075 my $buff; 471 1076 my $num = $raf->Read($buff, 0x1c); 1077 1078 # initialize write directories if necessary 1079 $exifTool->InitWriteDirs(\%vrdMap, 'XMP') if $$dirInfo{OutFile}; 1080 472 1081 if (not $num and $$dirInfo{OutFile}) { 473 1082 # create new VRD file from scratch … … 478 1087 ++$exifTool->{CHANGED}; 479 1088 } 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 } 480 1098 $exifTool->Error('No CanonVRD information to write'); 481 1099 } … … 493 1111 494 1112 #------------------------------------------------------------------------------ 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 1117 sub 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 #------------------------------------------------------------------------------ 495 1130 # Read/write CanonVRD information 496 1131 # Inputs: 0) ExifTool object reference, 1) dirInfo reference … … 498 1133 # - updates DataPos to point to start of CanonVRD information 499 1134 # - updates DirLen to trailer length 500 sub ProcessCanonVRD($$ )1135 sub ProcessCanonVRD($$;$) 501 1136 { 502 my ($exifTool, $dirInfo ) = @_;1137 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 503 1138 my $raf = $$dirInfo{RAF}; 504 1139 my $offset = $$dirInfo{Offset} || 0; … … 506 1141 my $verbose = $exifTool->Options('Verbose'); 507 1142 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 } 511 1159 # read and validate the trailer footer 512 1160 $raf->Seek(-64-$offset, 2) or return 0; … … 517 1165 # read and validate the header too 518 1166 # (header is 0x1c bytes and footer is 0x40 bytes) 519 unless ( $size > 12 and($size & 0x80000000) == 0 and1167 unless (($size & 0x80000000) == 0 and 520 1168 $raf->Seek(-$size-0x5c, 1) and 521 1169 $raf->Read($header, 0x1c) == 0x1c and … … 535 1183 536 1184 if ($outfile) { 1185 $verbose and not $created and printf $out " Rewriting CanonVRD trailer\n"; 537 1186 # delete CanonVRD information if specified 538 1187 if ($exifTool->{DEL_GROUP}->{CanonVRD} or $exifTool->{DEL_GROUP}->{Trailer} or … … 564 1213 } 565 1214 } elsif ($verbose or $exifTool->{HTML_DUMP}) { 566 $exifTool->DumpTrailer($dirInfo) ;1215 $exifTool->DumpTrailer($dirInfo) if $$dirInfo{RAF}; 567 1216 } 1217 1218 $tagTablePtr = GetTagTable('Image::ExifTool::CanonVRD::Main'); 568 1219 569 1220 # validate VRD trailer and get position and length of edit record … … 571 1222 my $pos = 0; 572 1223 my $vrdPos = $$dirInfo{DataPos} + length($header); 573 Block: for (;;) { 1224 my $dataPt = \$buff; 1225 1226 # loop through the VRD blocks 1227 for (;;) { 574 1228 if ($pos + 8 > $size) { 575 1229 last if $pos == $size; 576 1230 $blockLen = $size; # mark as invalid 577 1231 } else { 578 $blockType = Get32u( \$buff, $pos);579 $blockLen = Get32u( \$buff, $pos + 4);1232 $blockType = Get32u($dataPt, $pos); 1233 $blockLen = Get32u($dataPt, $pos + 4); 580 1234 } 581 1235 $pos += 8; # move to start of block … … 584 1238 last; 585 1239 } 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}; 596 1292 } else { 597 $ recLen = Get32u(\$buff, $pos);1293 $dat = $exifTool->WriteDirectory(\%subdirInfo, $subTablePtr); 598 1294 } 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; 603 1314 } 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); 659 1318 } 660 1319 } 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 663 1323 } 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; 668 1344 return $err ? -1 : 1; 669 1345 } … … 686 1362 write VRD Recipe Data information as written by the Canon Digital Photo 687 1363 Professional software. This information is written to VRD files, and as a 688 trailer in JPEG, CRW and CR2images.1364 trailer in JPEG, CRW, CR2 and TIFF images. 689 1365 690 1366 =head1 AUTHOR 691 1367 692 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1368 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 693 1369 694 1370 This library is free software; you can redistribute it and/or modify it 695 1371 under the same terms as Perl itself. 696 1372 1373 =head1 ACKNOWLEDGEMENTS 1374 1375 Thanks to Bogdan and Gert Kello for decoding some tags. 1376 697 1377 =head1 SEE ALSO 698 1378 -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Casio.pm
r16842 r24107 11 11 # 3) http://homepage3.nifty.com/kamisaka/makernote/makernote_casio.htm 12 12 # 4) http://www.gvsoft.homedns.org/exif/makernote-casio.html 13 # 5) Robert Chi private communication (EX-F1) 14 # JD) Jens Duttke private communication 13 15 #------------------------------------------------------------------------------ 14 16 … … 19 21 use Image::ExifTool::Exif; 20 22 21 $VERSION = '1. 21';23 $VERSION = '1.32'; 22 24 23 25 # older Casio maker notes (ref 1) … … 61 63 { 62 64 Name => 'FlashMode', 63 Condition => '$self->{ CameraModel} =~ /^QV-(3500EX|8000SX)/',65 Condition => '$self->{Model} =~ /^QV-(3500EX|8000SX)/', 64 66 Writable => 'int16u', 65 67 PrintConv => { … … 168 170 Priority => 0, 169 171 }, 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 }, 170 201 0x0016 => { #4 171 202 Name => 'Enhancement', … … 197 228 Name => 'AFPoint', 198 229 Writable => 'int16u', 230 Notes => 'may not be valid for all models', #JD 199 231 PrintConv => { 200 232 1 => 'Center', … … 327 359 Name => 'FocalLength', 328 360 Writable => 'rational64u', 329 PrintConv => 'sprintf("%.1f mm",$val)',330 PrintConvInv => '$val=~s/ mm$//;$val',361 PrintConv => 'sprintf("%.1f mm",$val)', 362 PrintConvInv => '$val=~s/\s*mm$//;$val', 331 363 }, 332 364 0x001f => { … … 413 445 4 => 'Flash?', 414 446 6 => 'Fluorescent', #3 447 9 => 'Tungsten?', #PH (EX-Z77) 415 448 10 => 'Tungsten', #3 416 449 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]; 417 460 }, 418 461 }, … … 426 469 }, 427 470 # 0x2023 looks interesting (values 0,1,2,3,5 in samples) - PH 471 # - 1 for makeup mode shots (portrait?) (EX-Z450) 428 472 0x2034 => { 429 473 Name => 'FlashDistance', 430 474 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', 431 515 }, 432 516 0x3000 => { … … 439 523 5 => 'Manual', #3 440 524 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 }, 448 546 }, 449 547 0x3002 => { … … 460 558 Writable => 'int16u', 461 559 PrintConv => { 462 0 => 'Manual ?',463 1 => 'F ixation?',560 0 => 'Manual', #(guess at translation) 561 1 => 'Focus Lock', #(guess at translation) 464 562 2 => 'Macro', #3 465 563 3 => 'Single-Area Auto Focus', 564 5 => 'Infinity', #PH 466 565 6 => 'Multi-Area Auto Focus', 566 8 => 'Super Macro', #PH (EX-Z2300) 467 567 }, 468 568 }, … … 474 574 Name => 'BestShotMode', 475 575 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', 480 580 }, 481 581 0x3008 => { #3 482 582 Name => 'AutoISO', 483 583 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 }, 485 601 }, 486 602 0x3011 => { #3 … … 507 623 Name => 'ColorMode', 508 624 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 }, 510 630 }, 511 631 0x3016 => { 512 632 Name => 'Enhancement', 513 633 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 }, 515 641 }, 516 642 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 }, 520 669 }, 521 670 0x301c => { #3 … … 536 685 1 => 'On', 537 686 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 538 782 }, 539 783 }, 540 784 ); 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 541 1009 542 1010 1; # end … … 559 1027 =head1 AUTHOR 560 1028 561 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1029 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 562 1030 563 1031 This library is free software; you can redistribute it and/or modify it … … 574 1042 =head1 ACKNOWLEDGEMENTS 575 1043 576 Thanks to Joachim Loehr for adding support for the type 2 maker notes. 1044 Thanks to Joachim Loehr for adding support for the type 2 maker notes, and 1045 Jens Duttke and Robert Chi for decoding some tags. 577 1046 578 1047 =head1 SEE ALSO -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DICOM.pm
r16842 r24107 4 4 # Description: Read DICOM and ACR-NEMA medical images 5 5 # 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 7 10 # 8 # References: 1) http://medical.nema.org/ dicom/2004.html11 # References: 1) http://medical.nema.org/ 9 12 # 2) http://www.sph.sc.edu/comd/rorden/dicom.html 10 13 # 3) http://www.dclunie.com/ 14 # 4) http://www.gehealthcare.com/usen/interoperability/dicom/docs/2258357r3.pdf 11 15 #------------------------------------------------------------------------------ 12 16 … … 14 18 15 19 use strict; 16 use vars qw($VERSION );20 use vars qw($VERSION %uid); 17 21 use Image::ExifTool qw(:DataAccess :Utils); 18 22 19 $VERSION = '1. 06';23 $VERSION = '1.11'; 20 24 21 25 # DICOM VR (Value Representation) format conversions … … 51 55 header and a number of new tags. ExifTool will extract information from 52 56 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. 54 60 }, 55 61 # file meta information group (names end with VR) … … 86 92 # identifying group 87 93 '0008,0000' => { VR => 'UL', Name => 'IdentifyingGroupLength' }, 88 '0008,0001' => { VR => ' RET',Name => 'LengthToEnd' },94 '0008,0001' => { VR => 'UL', Name => 'LengthToEnd' }, 89 95 '0008,0005' => { VR => 'CS', Name => 'SpecificCharacterSet' }, 96 '0008,0006' => { VR => 'SQ', Name => 'LanguageCodeSequence' }, 90 97 '0008,0008' => { VR => 'CS', Name => 'ImageType' }, 91 '0008,0010' => { VR => ' RET',Name => 'RecognitionCode' },98 '0008,0010' => { VR => 'CS', Name => 'RecognitionCode' }, 92 99 '0008,0012' => { VR => 'DA', Name => 'InstanceCreationDate' }, 93 100 '0008,0013' => { VR => 'TM', Name => 'InstanceCreationTime' }, … … 103 110 '0008,0024' => { VR => 'DA', Name => 'OverlayDate' }, 104 111 '0008,0025' => { VR => 'DA', Name => 'CurveDate' }, 105 '0008,002A' => { VR => 'DT', Name => 'AcquisitionDate time' },112 '0008,002A' => { VR => 'DT', Name => 'AcquisitionDateTime' }, 106 113 '0008,0030' => { VR => 'TM', Name => 'StudyTime' }, 107 114 '0008,0031' => { VR => 'TM', Name => 'SeriesTime' }, … … 110 117 '0008,0034' => { VR => 'TM', Name => 'OverlayTime' }, 111 118 '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' }, 115 122 '0008,0050' => { VR => 'SH', Name => 'AccessionNumber' }, 116 '0008,0052' => { VR => 'CS', Name => 'Query -RetrieveLevel' },123 '0008,0052' => { VR => 'CS', Name => 'QueryRetrieveLevel' }, 117 124 '0008,0054' => { VR => 'AE', Name => 'RetrieveAETitle' }, 118 125 '0008,0056' => { VR => 'CS', Name => 'InstanceAvailability' }, … … 127 134 '0008,0081' => { VR => 'ST', Name => 'InstitutionAddress' }, 128 135 '0008,0082' => { VR => 'SQ', Name => 'InstitutionCodeSequence' }, 129 '0008,0090' => { VR => 'PN', Name => 'ReferringPhysician sName' },130 '0008,0092' => { VR => 'ST', Name => 'ReferringPhysician sAddress' },131 '0008,0094' => { VR => 'SH', Name => 'ReferringPhysician sTelephoneNumber' },136 '0008,0090' => { VR => 'PN', Name => 'ReferringPhysicianName' }, 137 '0008,0092' => { VR => 'ST', Name => 'ReferringPhysicianAddress' }, 138 '0008,0094' => { VR => 'SH', Name => 'ReferringPhysicianTelephoneNumber' }, 132 139 '0008,0096' => { VR => 'SQ', Name => 'ReferringPhysicianIDSequence' }, 133 140 '0008,0100' => { VR => 'SH', Name => 'CodeValue' }, … … 147 154 '0008,0115' => { VR => 'ST', Name => 'CodingSchemeName' }, 148 155 '0008,0116' => { VR => 'ST', Name => 'ResponsibleOrganization' }, 156 '0008,0117' => { VR => 'UI', Name => 'ContextUID' }, 149 157 '0008,0201' => { VR => 'SH', Name => 'TimezoneOffsetFromUTC' }, 150 '0008,1000' => { VR => ' RET',Name => 'NetworkID' },158 '0008,1000' => { VR => 'AE', Name => 'NetworkID' }, 151 159 '0008,1010' => { VR => 'SH', Name => 'StationName' }, 152 160 '0008,1030' => { VR => 'LO', Name => 'StudyDescription' }, … … 154 162 '0008,103E' => { VR => 'LO', Name => 'SeriesDescription' }, 155 163 '0008,1040' => { VR => 'LO', Name => 'InstitutionalDepartmentName' }, 156 '0008,1048' => { VR => 'PN', Name => 'Physician OfRecord' },157 '0008,1049' => { VR => 'SQ', Name => 'Physician OfRecordIDSequence' },158 '0008,1050' => { VR => 'PN', Name => 'PerformingPhysician sName' },164 '0008,1048' => { VR => 'PN', Name => 'PhysiciansOfRecord' }, 165 '0008,1049' => { VR => 'SQ', Name => 'PhysiciansOfRecordIDSequence' }, 166 '0008,1050' => { VR => 'PN', Name => 'PerformingPhysicianName' }, 159 167 '0008,1052' => { VR => 'SQ', Name => 'PerformingPhysicianIDSequence' }, 160 168 '0008,1060' => { VR => 'PN', Name => 'NameOfPhysicianReadingStudy' }, … … 180 188 '0008,115A' => { VR => 'UI', Name => 'SOPClassesSupported' }, 181 189 '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' }, 182 194 '0008,1195' => { VR => 'UI', Name => 'TransactionUID' }, 183 195 '0008,1197' => { VR => 'US', Name => 'FailureReason' }, … … 186 198 '0008,1200' => { VR => 'SQ', Name => 'OtherReferencedStudiesSequence' }, 187 199 '0008,1250' => { VR => 'SQ', Name => 'RelatedSeriesSequence' }, 188 '0008,2110' => { VR => ' RET',Name => 'LossyImageCompression' },200 '0008,2110' => { VR => 'CS', Name => 'LossyImageCompression' }, 189 201 '0008,2111' => { VR => 'ST', Name => 'DerivationDescription' }, 190 202 '0008,2112' => { VR => 'SQ', Name => 'SourceImageSequence' }, … … 196 208 '0008,2129' => { VR => 'IS', Name => 'NumberOfEventTimers' }, 197 209 '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' }, 200 215 '0008,2142' => { VR => 'IS', Name => 'StartTrim' }, 201 216 '0008,2143' => { VR => 'IS', Name => 'StopTrim' }, 202 217 '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' }, 206 221 '0008,2218' => { VR => 'SQ', Name => 'AnatomicRegionSequence' }, 207 222 '0008,2220' => { VR => 'SQ', Name => 'AnatomicRegionModifierSequence' }, … … 213 228 '0008,2244' => { VR => 'SQ', Name => 'TransducerOrientationSequence' }, 214 229 '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' }, 215 234 '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' }, 217 237 '0008,9007' => { VR => 'CS', Name => 'FrameType' }, 218 238 '0008,9092' => { VR => 'SQ', Name => 'ReferencedImageEvidenceSequence' }, … … 228 248 '0008,9215' => { VR => 'SQ', Name => 'DerivationCodeSequence' }, 229 249 '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' }, 230 265 # patient group 231 266 '0010,0000' => { VR => 'UL', Name => 'PatientGroupLength' }, 232 '0010,0010' => { VR => 'PN', Name => 'Patient sName' },267 '0010,0010' => { VR => 'PN', Name => 'PatientName' }, 233 268 '0010,0020' => { VR => 'LO', Name => 'PatientID' }, 234 269 '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' }, 241 277 '0010,1000' => { VR => 'LO', Name => 'OtherPatientIDs' }, 242 278 '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' }, 250 287 '0010,1080' => { VR => 'LO', Name => 'MilitaryRank' }, 251 288 '0010,1081' => { VR => 'LO', Name => 'BranchOfService' }, 252 289 '0010,1090' => { VR => 'LO', Name => 'MedicalRecordLocator' }, 253 290 '0010,2000' => { VR => 'LO', Name => 'MedicalAlerts' }, 254 '0010,2110' => { VR => 'LO', Name => ' ContrastAllergies' },291 '0010,2110' => { VR => 'LO', Name => 'Allergies' }, 255 292 '0010,2150' => { VR => 'LO', Name => 'CountryOfResidence' }, 256 293 '0010,2152' => { VR => 'LO', Name => 'RegionOfResidence' }, 257 '0010,2154' => { VR => 'SH', Name => 'Patient sTelephoneNumbers' },294 '0010,2154' => { VR => 'SH', Name => 'PatientTelephoneNumbers' }, 258 295 '0010,2160' => { VR => 'SH', Name => 'EthnicGroup' }, 259 296 '0010,2180' => { VR => 'SH', Name => 'Occupation' }, … … 262 299 '0010,21C0' => { VR => 'US', Name => 'PregnancyStatus' }, 263 300 '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' }, 265 314 '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 266 319 '0012,0010' => { VR => 'LO', Name => 'ClinicalTrialSponsorName' }, 267 320 '0012,0020' => { VR => 'LO', Name => 'ClinicalTrialProtocolID' }, … … 274 327 '0012,0051' => { VR => 'ST', Name => 'ClinicalTrialTimePointDescription' }, 275 328 '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' }, 276 336 # acquisition group 277 337 '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' }, 281 341 '0018,0015' => { VR => 'CS', Name => 'BodyPartExamined' }, 282 342 '0018,0020' => { VR => 'CS', Name => 'ScanningSequence' }, … … 291 351 '0018,0029' => { VR => 'SQ', Name => 'InterventionDrugSequence' }, 292 352 '0018,002A' => { VR => 'SQ', Name => 'AdditionalDrugSequence' }, 293 '0018,0030' => { VR => ' RET',Name => 'Radionuclide' },353 '0018,0030' => { VR => 'LO', Name => 'Radionuclide' }, 294 354 '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' }, 297 357 '0018,0034' => { VR => 'LO', Name => 'InterventionDrugName' }, 298 358 '0018,0035' => { VR => 'TM', Name => 'InterventionDrugStartTime' }, 299 359 '0018,0036' => { VR => 'SQ', Name => 'InterventionSequence' }, 300 '0018,0037' => { VR => ' RET',Name => 'TherapyType' },360 '0018,0037' => { VR => 'CS', Name => 'TherapyType' }, 301 361 '0018,0038' => { VR => 'CS', Name => 'InterventionStatus' }, 302 '0018,0039' => { VR => ' RET',Name => 'TherapyDescription' },362 '0018,0039' => { VR => 'CS', Name => 'TherapyDescription' }, 303 363 '0018,003A' => { VR => 'ST', Name => 'InterventionDescription' }, 304 364 '0018,0040' => { VR => 'IS', Name => 'CineRate' }, 365 '0018,0042' => { VR => 'CS', Name => 'InitialCineRunState' }, 305 366 '0018,0050' => { VR => 'DS', Name => 'SliceThickness' }, 306 367 '0018,0060' => { VR => 'DS', Name => 'KVP' }, … … 327 388 '0018,0095' => { VR => 'DS', Name => 'PixelBandwidth' }, 328 389 '0018,1000' => { VR => 'LO', Name => 'DeviceSerialNumber' }, 390 '0018,1002' => { VR => 'UI', Name => 'DeviceUID' }, 391 '0018,1003' => { VR => 'LO', Name => 'DeviceID' }, 329 392 '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' }, 330 397 '0018,1010' => { VR => 'LO', Name => 'SecondaryCaptureDeviceID' }, 331 398 '0018,1011' => { VR => 'LO', Name => 'HardcopyCreationDeviceID' }, … … 342 409 '0018,1023' => { VR => 'LO', Name => 'DigitalImageFormatAcquired' }, 343 410 '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' }, 349 416 '0018,1045' => { VR => 'IS', Name => 'SyringeCounts' }, 350 417 '0018,1046' => { VR => 'DS', Name => 'ContrastFlowRate' }, 351 418 '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' }, 354 421 '0018,1050' => { VR => 'DS', Name => 'SpatialResolution' }, 355 422 '0018,1060' => { VR => 'DS', Name => 'TriggerTime' }, … … 357 424 '0018,1062' => { VR => 'IS', Name => 'NominalInterval' }, 358 425 '0018,1063' => { VR => 'DS', Name => 'FrameTime' }, 359 '0018,1064' => { VR => 'LO', Name => ' FramingType' },426 '0018,1064' => { VR => 'LO', Name => 'CardiacFramingType' }, 360 427 '0018,1065' => { VR => 'DS', Name => 'FrameTimeVector' }, 361 428 '0018,1066' => { VR => 'DS', Name => 'FrameDelay' }, … … 374 441 '0018,1076' => { VR => 'DS', Name => 'RadionuclidePositronFraction' }, 375 442 '0018,1077' => { VR => 'DS', Name => 'RadiopharmaceuticalSpecActivity' }, 443 '0018,1078' => { VR => 'DT', Name => 'RadiopharmaceuticalStartDateTime' }, 444 '0018,1079' => { VR => 'DT', Name => 'RadiopharmaceuticalStopDateTime' }, 376 445 '0018,1080' => { VR => 'CS', Name => 'BeatRejectionFlag' }, 377 446 '0018,1081' => { VR => 'IS', Name => 'LowRRValue' }, … … 388 457 '0018,1111' => { VR => 'DS', Name => 'DistanceSourceToPatient' }, 389 458 '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' }, 392 461 '0018,1130' => { VR => 'DS', Name => 'TableHeight' }, 393 462 '0018,1131' => { VR => 'DS', Name => 'TableTraverse' }, … … 404 473 '0018,1144' => { VR => 'DS', Name => 'AngularStep' }, 405 474 '0018,1145' => { VR => 'DS', Name => 'CenterOfRotationOffset' }, 406 '0018,1146' => { VR => ' RET',Name => 'RotationOffset' },475 '0018,1146' => { VR => 'DS', Name => 'RotationOffset' }, 407 476 '0018,1147' => { VR => 'CS', Name => 'FieldOfViewShape' }, 408 477 '0018,1149' => { VR => 'IS', Name => 'FieldOfViewDimensions' }, … … 422 491 '0018,1166' => { VR => 'CS', Name => 'Grid' }, 423 492 '0018,1170' => { VR => 'IS', Name => 'GeneratorPower' }, 424 '0018,1180' => { VR => 'SH', Name => 'Collimator -GridName' },493 '0018,1180' => { VR => 'SH', Name => 'CollimatorGridName' }, 425 494 '0018,1181' => { VR => 'CS', Name => 'CollimatorType' }, 426 495 '0018,1182' => { VR => 'IS', Name => 'FocalDistance' }, 427 496 '0018,1183' => { VR => 'DS', Name => 'XFocusCenter' }, 428 497 '0018,1184' => { VR => 'DS', Name => 'YFocusCenter' }, 429 '0018,1190' => { VR => 'DS', Name => 'FocalSpot ' },498 '0018,1190' => { VR => 'DS', Name => 'FocalSpots' }, 430 499 '0018,1191' => { VR => 'CS', Name => 'AnodeTargetMaterial' }, 431 500 '0018,11A0' => { VR => 'DS', Name => 'BodyPartThickness' }, … … 434 503 '0018,1201' => { VR => 'TM', Name => 'TimeOfLastCalibration' }, 435 504 '0018,1210' => { VR => 'SH', Name => 'ConvolutionKernel' }, 436 '0018,1240' => { VR => ' RET',Name => 'Upper-LowerPixelValues' },505 '0018,1240' => { VR => 'IS', Name => 'UpperLowerPixelValues' }, 437 506 '0018,1242' => { VR => 'IS', Name => 'ActualFrameDuration' }, 438 507 '0018,1243' => { VR => 'IS', Name => 'CountRate' }, … … 455 524 '0018,1402' => { VR => 'CS', Name => 'CassetteOrientation' }, 456 525 '0018,1403' => { VR => 'CS', Name => 'CassetteSize' }, 457 '0018,1404' => { VR => 'US', Name => 'Exposures onPlate' },526 '0018,1404' => { VR => 'US', Name => 'ExposuresOnPlate' }, 458 527 '0018,1405' => { VR => 'IS', Name => 'RelativeXRayExposure' }, 459 528 '0018,1450' => { VR => 'DS', Name => 'ColumnAngulation' }, … … 482 551 '0018,1622' => { VR => 'US', Name => 'ShutterPresentationValue' }, 483 552 '0018,1623' => { VR => 'US', Name => 'ShutterOverlayGroup' }, 553 '0018,1624' => { VR => 'US', Name => 'ShutterPresentationColorCIELabVal' }, 484 554 '0018,1700' => { VR => 'CS', Name => 'CollimatorShape' }, 485 555 '0018,1702' => { VR => 'IS', Name => 'CollimatorLeftVerticalEdge' }, … … 509 579 '0018,3104' => { VR => 'IS', Name => 'IVUSPullbackStopFrameNumber' }, 510 580 '0018,3105' => { VR => 'IS', Name => 'LesionNumber' }, 511 '0018,4000' => { VR => ' RET',Name => 'AcquisitionComments' },581 '0018,4000' => { VR => 'LT', Name => 'AcquisitionComments' }, 512 582 '0018,5000' => { VR => 'SH', Name => 'OutputPower' }, 513 583 '0018,5010' => { VR => 'LO', Name => 'TransducerData' }, … … 521 591 '0018,5028' => { VR => 'DS', Name => 'SoftTissueFocusThermalIndex' }, 522 592 '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' }, 525 595 '0018,5050' => { VR => 'IS', Name => 'DepthOfScanField' }, 526 596 '0018,5100' => { VR => 'CS', Name => 'PatientPosition' }, 527 597 '0018,5101' => { VR => 'CS', Name => 'ViewPosition' }, 528 598 '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' }, 531 601 '0018,6000' => { VR => 'DS', Name => 'Sensitivity' }, 532 602 '0018,6011' => { VR => 'SQ', Name => 'SequenceOfUltrasoundRegions' }, … … 551 621 '0018,6034' => { VR => 'FD', Name => 'DopplerCorrectionAngle' }, 552 622 '0018,6036' => { VR => 'FD', Name => 'SteeringAngle' }, 553 '0018,6038' => { VR => ' RET',Name => 'DopplerSampleVolumeXPositionUL' },623 '0018,6038' => { VR => 'UL', Name => 'DopplerSampleVolumeXPosRetired' }, 554 624 '0018,6039' => { VR => 'SL', Name => 'DopplerSampleVolumeXPosition' }, 555 '0018,603A' => { VR => ' RET',Name => 'DopplerSampleVolumeYPositionUL' },625 '0018,603A' => { VR => 'UL', Name => 'DopplerSampleVolumeYPosRetired' }, 556 626 '0018,603B' => { VR => 'SL', Name => 'DopplerSampleVolumeYPosition' }, 557 '0018,603C' => { VR => ' RET',Name => 'TMLinePositionX0UL' },627 '0018,603C' => { VR => 'UL', Name => 'TMLinePositionX0Retired' }, 558 628 '0018,603D' => { VR => 'SL', Name => 'TMLinePositionX0' }, 559 '0018,603E' => { VR => ' RET',Name => 'TMLinePositionY0UL' },629 '0018,603E' => { VR => 'UL', Name => 'TMLinePositionY0Retired' }, 560 630 '0018,603F' => { VR => 'SL', Name => 'TMLinePositionY0' }, 561 '0018,6040' => { VR => ' RET',Name => 'TMLinePositionX1UL' },631 '0018,6040' => { VR => 'UL', Name => 'TMLinePositionX1Retired' }, 562 632 '0018,6041' => { VR => 'SL', Name => 'TMLinePositionX1' }, 563 '0018,6042' => { VR => ' RET',Name => 'TMLinePositionY1UL' },633 '0018,6042' => { VR => 'UL', Name => 'TMLinePositionY1Retired' }, 564 634 '0018,6043' => { VR => 'SL', Name => 'TMLinePositionY1' }, 565 635 '0018,6044' => { VR => 'US', Name => 'PixelComponentOrganization' }, … … 638 708 '0018,9025' => { VR => 'CS', Name => 'SpectrallySelectedSuppression' }, 639 709 '0018,9026' => { VR => 'CS', Name => 'SpectrallySelectedExcitation' }, 640 '0018,9027' => { VR => 'CS', Name => 'SpatialPre Saturation' },710 '0018,9027' => { VR => 'CS', Name => 'SpatialPresaturation' }, 641 711 '0018,9028' => { VR => 'CS', Name => 'Tagging' }, 642 712 '0018,9029' => { VR => 'CS', Name => 'OversamplingPhase' }, … … 675 745 '0018,9070' => { VR => 'FD', Name => 'CardiacRRIntervalSpecified' }, 676 746 '0018,9073' => { VR => 'FD', Name => 'AcquisitionDuration' }, 677 '0018,9074' => { VR => 'DT', Name => 'FrameAcquisitionDate time' },747 '0018,9074' => { VR => 'DT', Name => 'FrameAcquisitionDateTime' }, 678 748 '0018,9075' => { VR => 'CS', Name => 'DiffusionDirectionality' }, 679 749 '0018,9076' => { VR => 'SQ', Name => 'DiffusionGradientDirectionSequence' }, … … 694 764 '0018,9094' => { VR => 'CS', Name => 'CoverageOfKSpace' }, 695 765 '0018,9095' => { VR => 'UL', Name => 'SpectroscopyAcquisitionPhaseRows' }, 766 '0018,9096' => { VR => 'FD', Name => 'ParallelReductFactorInPlaneRetired' }, 696 767 '0018,9098' => { VR => 'FD', Name => 'TransmitterFrequency' }, 697 768 '0018,9100' => { VR => 'CS', Name => 'ResonantNucleus' }, … … 712 783 '0018,9127' => { VR => 'UL', Name => 'SpectroscopyAcquisitionDataColumns' }, 713 784 '0018,9147' => { VR => 'CS', Name => 'DiffusionAnisotropyType' }, 714 '0018,9151' => { VR => 'DT', Name => 'FrameReferenceDate time' },785 '0018,9151' => { VR => 'DT', Name => 'FrameReferenceDateTime' }, 715 786 '0018,9152' => { VR => 'SQ', Name => 'MRMetaboliteMapSequence' }, 716 787 '0018,9155' => { VR => 'FD', Name => 'ParallelReductionFactorOutOfPlane' }, … … 734 805 '0018,9183' => { VR => 'CS', Name => 'FlowCompensationDirection' }, 735 806 '0018,9184' => { VR => 'FD', Name => 'TaggingDelay' }, 807 '0018,9185' => { VR => 'ST', Name => 'RespiratoryMotionCompTechDescr' }, 808 '0018,9186' => { VR => 'SH', Name => 'RespiratorySignalSourceID' }, 736 809 '0018,9195' => { VR => 'FD', Name => 'ChemicalShiftsMinIntegrateLimitHz' }, 737 810 '0018,9196' => { VR => 'FD', Name => 'ChemicalShiftsMaxIntegrateLimitHz' }, … … 790 863 '0018,9334' => { VR => 'CS', Name => 'FluoroscopyFlag' }, 791 864 '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' }, 794 867 '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' }, 799 872 '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' }, 800 977 '0018,A001' => { VR => 'SQ', Name => 'ContributingEquipmentSequence' }, 801 978 '0018,A002' => { VR => 'DT', Name => 'ContributionDateTime' }, 802 979 '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' }, 803 1124 # relationship group 804 1125 '0020,0000' => { VR => 'UL', Name => 'RelationshipGroupLength' }, … … 809 1130 '0020,0012' => { VR => 'IS', Name => 'AcquisitionNumber' }, 810 1131 '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' }, 816 1137 '0020,0019' => { VR => 'IS', Name => 'ItemNumber' }, 817 1138 '0020,0020' => { VR => 'CS', Name => 'PatientOrientation' }, … … 823 1144 '0020,0035' => { VR => 'DS', Name => 'ImageOrientation' }, 824 1145 '0020,0037' => { VR => 'DS', Name => 'ImageOrientationPatient' }, 825 '0020,0050' => { VR => ' RET',Name => 'Location' },1146 '0020,0050' => { VR => 'DS', Name => 'Location' }, 826 1147 '0020,0052' => { VR => 'UI', Name => 'FrameOfReferenceUID' }, 827 1148 '0020,0060' => { VR => 'CS', Name => 'Laterality' }, 828 1149 '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' }, 831 1152 '0020,0100' => { VR => 'IS', Name => 'TemporalPositionIdentifier' }, 832 1153 '0020,0105' => { VR => 'IS', Name => 'NumberOfTemporalPositions' }, … … 834 1155 '0020,0200' => { VR => 'UI', Name => 'SynchronizationFrameOfReferenceUID' }, 835 1156 '0020,1000' => { VR => 'IS', Name => 'SeriesInStudy' }, 836 '0020,1001' => { VR => ' RET',Name => 'AcquisitionsInSeries' },1157 '0020,1001' => { VR => 'IS', Name => 'AcquisitionsInSeries' }, 837 1158 '0020,1002' => { VR => 'IS', Name => 'ImagesInAcquisition' }, 1159 '0020,1003' => { VR => 'IS', Name => 'ImagesInSeries' }, 838 1160 '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' }, 840 1163 '0020,1040' => { VR => 'LO', Name => 'PositionReferenceIndicator' }, 841 1164 '0020,1041' => { VR => 'DS', Name => 'SliceLocation' }, … … 846 1169 '0020,1206' => { VR => 'IS', Name => 'NumberOfStudyRelatedSeries' }, 847 1170 '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' }, 856 1179 '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' }, 859 1182 '0020,9056' => { VR => 'SH', Name => 'StackID' }, 860 1183 '0020,9057' => { VR => 'UL', Name => 'InStackPositionNumber' }, … … 870 1193 '0020,9158' => { VR => 'LT', Name => 'FrameComments' }, 871 1194 '0020,9161' => { VR => 'UI', Name => 'ConcatenationUID' }, 872 '0020,9162' => { VR => 'US', Name => 'In concatenationNumber' },873 '0020,9163' => { VR => 'US', Name => 'In concatenationTotalNumber' },1195 '0020,9162' => { VR => 'US', Name => 'InConcatenationNumber' }, 1196 '0020,9163' => { VR => 'US', Name => 'InConcatenationTotalNumber' }, 874 1197 '0020,9164' => { VR => 'UI', Name => 'DimensionOrganizationUID' }, 875 1198 '0020,9165' => { VR => 'AT', Name => 'DimensionIndexPointer' }, … … 880 1203 '0020,9228' => { VR => 'UL', Name => 'ConcatenationFrameOffsetNumber' }, 881 1204 '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 # ? 882 1268 '0022,0001' => { VR => 'US', Name => 'LightPathFilterPassThroughWavelen' }, 883 1269 '0022,0002' => { VR => 'US', Name => 'LightPathFilterPassBand' }, … … 911 1297 '0022,0021' => { VR => 'SQ', Name => 'LeftImageSequence' }, 912 1298 '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' }, 913 1372 # image presentation group 914 1373 '0028,0000' => { VR => 'UL', Name => 'ImagePresentationGroupLength' }, … … 929 1388 '0028,0032' => { VR => 'DS', Name => 'ZoomCenter' }, 930 1389 '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' }, 933 1392 '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' }, 935 1412 '0028,0100' => { VR => 'US', Name => 'BitsAllocated' }, 936 1413 '0028,0101' => { VR => 'US', Name => 'BitsStored' }, 937 1414 '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' }, 949 1427 '0028,0300' => { VR => 'CS', Name => 'QualityControlImage' }, 950 1428 '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' }, 951 1453 '0028,1040' => { VR => 'CS', Name => 'PixelIntensityRelationship' }, 952 1454 '0028,1041' => { VR => 'SS', Name => 'PixelIntensityRelationshipSign' }, … … 957 1459 '0028,1054' => { VR => 'LO', Name => 'RescaleType' }, 958 1460 '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' }, 960 1463 '0028,1090' => { VR => 'CS', Name => 'RecommendedViewingMode' }, 961 '0028,1100' => { VR => ' RET',Name => 'GrayLookupTableDescriptor' },1464 '0028,1100' => { VR => 'SS', Name => 'GrayLookupTableDescriptor' }, 962 1465 '0028,1101' => { VR => 'SS', Name => 'RedPaletteColorTableDescriptor' }, 963 1466 '0028,1102' => { VR => 'SS', Name => 'GreenPaletteColorTableDescriptor' }, 964 1467 '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' }, 965 1471 '0028,1199' => { VR => 'UI', Name => 'PaletteColorTableUID' }, 966 '0028,1200' => { VR => ' RET',Name => 'GrayLookupTableData' },1472 '0028,1200' => { VR => 'US', Name => 'GrayLookupTableData' }, 967 1473 '0028,1201' => { VR => 'OW', Name => 'RedPaletteColorTableData' }, 968 1474 '0028,1202' => { VR => 'OW', Name => 'GreenPaletteColorTableData' }, 969 1475 '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' }, 970 1480 '0028,1221' => { VR => 'OW', Name => 'SegmentedRedColorTableData' }, 971 1481 '0028,1222' => { VR => 'OW', Name => 'SegmentedGreenColorTableData' }, 972 1482 '0028,1223' => { VR => 'OW', Name => 'SegmentedBlueColorTableData' }, 973 '0028,1300' => { VR => 'CS', Name => ' ImplantPresent' },1483 '0028,1300' => { VR => 'CS', Name => 'BreastImplantPresent' }, 974 1484 '0028,1350' => { VR => 'CS', Name => 'PartialView' }, 975 1485 '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' }, 976 1497 '0028,2110' => { VR => 'CS', Name => 'LossyImageCompression' }, 977 1498 '0028,2112' => { VR => 'DS', Name => 'LossyImageCompressionRatio' }, 978 1499 '0028,2114' => { VR => 'CS', Name => 'LossyImageCompressionMethod' }, 979 1500 '0028,3000' => { VR => 'SQ', Name => 'ModalityLUTSequence' }, 980 '0028,3002' => { VR => ' SS', Name => 'LUTDescriptor' },1501 '0028,3002' => { VR => 'US', Name => 'LUTDescriptor' }, 981 1502 '0028,3003' => { VR => 'LO', Name => 'LUTExplanation' }, 982 1503 '0028,3004' => { VR => 'LO', Name => 'ModalityLUTType' }, … … 984 1505 '0028,3010' => { VR => 'SQ', Name => 'VOILUTSequence' }, 985 1506 '0028,3110' => { VR => 'SQ', Name => 'SoftcopyVOILUTSequence' }, 986 '0028,4000' => { VR => ' RET',Name => 'ImagePresentationComments' },1507 '0028,4000' => { VR => 'LT', Name => 'ImagePresentationComments' }, 987 1508 '0028,5000' => { VR => 'SQ', Name => 'BiPlaneAcquisitionSequence' }, 988 1509 '0028,6010' => { VR => 'US', Name => 'RepresentativeFrameNumber' }, 989 '0028,6020' => { VR => 'US', Name => 'FrameNumbersOfInterest FOI' },1510 '0028,6020' => { VR => 'US', Name => 'FrameNumbersOfInterest' }, 990 1511 '0028,6022' => { VR => 'LO', Name => 'FrameOfInterestDescription' }, 991 1512 '0028,6023' => { VR => 'CS', Name => 'FrameOfInterestType' }, 992 '0028,6030' => { VR => ' RET',Name => 'MaskPointers' },1513 '0028,6030' => { VR => 'US', Name => 'MaskPointers' }, 993 1514 '0028,6040' => { VR => 'US', Name => 'RWavePointer' }, 994 1515 '0028,6100' => { VR => 'SQ', Name => 'MaskSubtractionSequence' }, … … 1000 1521 '0028,6120' => { VR => 'SS', Name => 'TIDOffset' }, 1001 1522 '0028,6190' => { VR => 'ST', Name => 'MaskOperationExplanation' }, 1523 '0028,7FE0' => { VR => 'UT', Name => 'PixelDataProviderURL' }, 1002 1524 '0028,9001' => { VR => 'UL', Name => 'DataPointRows' }, 1003 1525 '0028,9002' => { VR => 'UL', Name => 'DataPointColumns' }, … … 1009 1531 '0028,9145' => { VR => 'SQ', Name => 'PixelValueTransformationSequence' }, 1010 1532 '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' }, 1011 1567 # study group 1012 1568 '0032,0000' => { VR => 'UL', Name => 'StudyGroupLength' }, … … 1055 1611 '0038,0044' => { VR => 'SQ', Name => 'DischargeDiagnosisCodeSequence' }, 1056 1612 '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' }, 1057 1617 '0038,0300' => { VR => 'LO', Name => 'CurrentPatientLocation' }, 1058 '0038,0400' => { VR => 'LO', Name => 'Patient sInstitutionResidence' },1618 '0038,0400' => { VR => 'LO', Name => 'PatientInstitutionResidence' }, 1059 1619 '0038,0500' => { VR => 'LO', Name => 'PatientState' }, 1620 '0038,0502' => { VR => 'SQ', Name => 'PatientClinicalTrialParticipSeq' }, 1060 1621 '0038,4000' => { VR => 'LT', Name => 'VisitComments' }, 1061 1622 '003A,0004' => { VR => 'CS', Name => 'WaveformOriginality' }, … … 1084 1645 '003A,0222' => { VR => 'DS', Name => 'NotchFilterFrequency' }, 1085 1646 '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' }, 1086 1657 '003A,0300' => { VR => 'SQ', Name => 'MultiplexAudioChannelsDescrCodeSeq' }, 1087 1658 '003A,0301' => { VR => 'IS', Name => 'ChannelIdentificationCode' }, … … 1102 1673 '0040,0012' => { VR => 'LO', Name => 'PreMedication' }, 1103 1674 '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' }, 1104 1680 '0040,0100' => { VR => 'SQ', Name => 'ScheduledProcedureStepSequence' }, 1105 1681 '0040,0220' => { VR => 'SQ', Name => 'ReferencedNonImageCompositeSOPSeq' }, … … 1116 1692 '0040,0255' => { VR => 'LO', Name => 'PerformedProcedureTypeDescription' }, 1117 1693 '0040,0260' => { VR => 'SQ', Name => 'PerformedProtocolCodeSequence' }, 1694 '0040,0261' => { VR => 'CS', Name => 'PerformedProtocolType' }, 1118 1695 '0040,0270' => { VR => 'SQ', Name => 'ScheduledStepAttributesSequence' }, 1119 1696 '0040,0275' => { VR => 'SQ', Name => 'RequestAttributesSequence' }, … … 1129 1706 '0040,0303' => { VR => 'US', Name => 'ExposedArea' }, 1130 1707 '0040,0306' => { VR => 'DS', Name => 'DistanceSourceToEntrance' }, 1131 '0040,0307' => { VR => ' RET',Name => 'DistanceSourceToSupport' },1708 '0040,0307' => { VR => 'DS', Name => 'DistanceSourceToSupport' }, 1132 1709 '0040,030E' => { VR => 'SQ', Name => 'ExposureDoseSequence' }, 1133 1710 '0040,0310' => { VR => 'ST', Name => 'CommentsOnRadiationDose' }, … … 1139 1716 '0040,0321' => { VR => 'SQ', Name => 'FilmConsumptionSequence' }, 1140 1717 '0040,0324' => { VR => 'SQ', Name => 'BillingSuppliesAndDevicesSequence' }, 1141 '0040,0330' => { VR => ' RET',Name => 'ReferencedProcedureStepSequence' },1718 '0040,0330' => { VR => 'SQ', Name => 'ReferencedProcedureStepSequence' }, 1142 1719 '0040,0340' => { VR => 'SQ', Name => 'PerformedSeriesSequence' }, 1143 1720 '0040,0400' => { VR => 'LT', Name => 'CommentsOnScheduledProcedureStep' }, … … 1145 1722 '0040,0441' => { VR => 'SQ', Name => 'ContentItemModifierSequence' }, 1146 1723 '0040,050A' => { VR => 'LO', Name => 'SpecimenAccessionNumber' }, 1724 '0040,0512' => { VR => 'LO', Name => 'ContainerIdentifier' }, 1725 '0040,051A' => { VR => 'LO', Name => 'ContainerDescription' }, 1147 1726 '0040,0550' => { VR => 'SQ', Name => 'SpecimenSequence' }, 1148 1727 '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' }, 1149 1731 '0040,0555' => { VR => 'SQ', Name => 'AcquisitionContextSequence' }, 1150 1732 '0040,0556' => { VR => 'ST', Name => 'AcquisitionContextDescription' }, 1151 1733 '0040,059A' => { VR => 'SQ', Name => 'SpecimenTypeCodeSequence' }, 1734 '0040,0600' => { VR => 'LO', Name => 'SpecimenShortDescription' }, 1152 1735 '0040,06FA' => { VR => 'LO', Name => 'SlideIdentifier' }, 1153 1736 '0040,071A' => { VR => 'SQ', Name => 'ImageCenterPointCoordinatesSeq' }, … … 1158 1741 '0040,08DA' => { VR => 'SQ', Name => 'CoordinateSystemAxisCodeSequence' }, 1159 1742 '0040,08EA' => { VR => 'SQ', Name => 'MeasurementUnitsCodeSequence' }, 1743 '0040,09F8' => { VR => 'SQ', Name => 'VitalStainCodeSequenceTrial' }, 1160 1744 '0040,1001' => { VR => 'SH', Name => 'RequestedProcedureID' }, 1161 1745 '0040,1002' => { VR => 'LO', Name => 'ReasonForRequestedProcedure' }, … … 1163 1747 '0040,1004' => { VR => 'LO', Name => 'PatientTransportArrangements' }, 1164 1748 '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' }, 1167 1751 '0040,1008' => { VR => 'LO', Name => 'ConfidentialityCode' }, 1168 1752 '0040,1009' => { VR => 'SH', Name => 'ReportingPriority' }, … … 1171 1755 '0040,1011' => { VR => 'SQ', Name => 'IntendedRecipientsOfResultsIDSeq' }, 1172 1756 '0040,1101' => { VR => 'SQ', Name => 'PersonIdentificationCodeSequence' }, 1173 '0040,1102' => { VR => 'ST', Name => 'Person sAddress' },1174 '0040,1103' => { VR => 'LO', Name => 'Person sTelephoneNumbers' },1757 '0040,1102' => { VR => 'ST', Name => 'PersonAddress' }, 1758 '0040,1103' => { VR => 'LO', Name => 'PersonTelephoneNumbers' }, 1175 1759 '0040,1400' => { VR => 'LT', Name => 'RequestedProcedureComments' }, 1176 '0040,2001' => { VR => ' RET',Name => 'ReasonForImagingServiceRequest' },1760 '0040,2001' => { VR => 'LO', Name => 'ReasonForImagingServiceRequest' }, 1177 1761 '0040,2004' => { VR => 'DA', Name => 'IssueDateOfImagingServiceRequest' }, 1178 1762 '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' }, 1181 1765 '0040,2008' => { VR => 'PN', Name => 'OrderEnteredBy' }, 1182 '0040,2009' => { VR => 'SH', Name => 'OrderEnterer sLocation' },1766 '0040,2009' => { VR => 'SH', Name => 'OrderEntererLocation' }, 1183 1767 '0040,2010' => { VR => 'SH', Name => 'OrderCallbackPhoneNumber' }, 1184 1768 '0040,2016' => { VR => 'LO', Name => 'PlacerOrderNum-ImagingServiceReq' }, … … 1216 1800 '0040,4035' => { VR => 'SQ', Name => 'ActualHumanPerformersSequence' }, 1217 1801 '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' }, 1219 1804 '0040,8302' => { VR => 'DS', Name => 'EntranceDoseInMilliGy' }, 1805 '0040,9094' => { VR => 'SQ', Name => 'RefImageRealWorldValueMappingSeq' }, 1220 1806 '0040,9096' => { VR => 'SQ', Name => 'RealWorldValueMappingSequence' }, 1807 '0040,9098' => { VR => 'SQ', Name => 'PixelValueMappingCodeSequence' }, 1221 1808 '0040,9210' => { VR => 'SH', Name => 'LUTLabel' }, 1222 1809 '0040,9211' => { VR => 'SS', Name => 'RealWorldValueLastValueMapped' }, … … 1234 1821 '0040,A073' => { VR => 'SQ', Name => 'VerifyingObserverSequence' }, 1235 1822 '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' }, 1236 1829 '0040,A088' => { VR => 'SQ', Name => 'VerifyingObserverIdentCodeSequence' }, 1830 '0040,A090' => { VR => 'SQ', Name => 'EquivalentCDADocumentSequence' }, 1237 1831 '0040,A0B0' => { VR => 'US', Name => 'ReferencedWaveformChannels' }, 1238 1832 '0040,A120' => { VR => 'DT', Name => 'DateTime' }, … … 1245 1839 '0040,A136' => { VR => 'US', Name => 'ReferencedFrameNumbers' }, 1246 1840 '0040,A138' => { VR => 'DS', Name => 'ReferencedTimeOffsets' }, 1247 '0040,A13A' => { VR => 'DT', Name => 'ReferencedDate time' },1841 '0040,A13A' => { VR => 'DT', Name => 'ReferencedDateTime' }, 1248 1842 '0040,A160' => { VR => 'UT', Name => 'TextValue' }, 1249 1843 '0040,A168' => { VR => 'SQ', Name => 'ConceptCodeSequence' }, … … 1254 1848 '0040,A301' => { VR => 'SQ', Name => 'NumericValueQualifierCodeSequence' }, 1255 1849 '0040,A30A' => { VR => 'DS', Name => 'NumericValue' }, 1850 '0040,A353' => { VR => 'ST', Name => 'AddressTrial' }, 1851 '0040,A354' => { VR => 'LO', Name => 'TelephoneNumberTrial' }, 1256 1852 '0040,A360' => { VR => 'SQ', Name => 'PredecessorDocumentsSequence' }, 1257 1853 '0040,A370' => { VR => 'SQ', Name => 'ReferencedRequestSequence' }, … … 1259 1855 '0040,A375' => { VR => 'SQ', Name => 'CurrentRequestedProcEvidenceSeq' }, 1260 1856 '0040,A385' => { VR => 'SQ', Name => 'PertinentOtherEvidenceSequence' }, 1857 '0040,A390' => { VR => 'SQ', Name => 'HL7StructuredDocumentRefSeq' }, 1261 1858 '0040,A491' => { VR => 'CS', Name => 'CompletionFlag' }, 1262 1859 '0040,A492' => { VR => 'LO', Name => 'CompletionFlagDescription' }, 1263 1860 '0040,A493' => { VR => 'CS', Name => 'VerificationFlag' }, 1861 '0040,A494' => { VR => 'CS', Name => 'ArchiveRequested' }, 1862 '0040,A496' => { VR => 'CS', Name => 'PreliminaryFlag' }, 1264 1863 '0040,A504' => { VR => 'SQ', Name => 'ContentTemplateSequence' }, 1265 1864 '0040,A525' => { VR => 'SQ', Name => 'IdenticalDocumentsSequence' }, … … 1267 1866 '0040,B020' => { VR => 'SQ', Name => 'AnnotationSequence' }, 1268 1867 '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' }, 1274 1873 '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' }, 1275 2042 # calibration group 1276 2043 '0050,0004' => { VR => 'CS', Name => 'CalibrationImage' }, 1277 2044 '0050,0010' => { VR => 'SQ', Name => 'DeviceSequence' }, 1278 2045 '0050,0014' => { VR => 'DS', Name => 'DeviceLength' }, 2046 '0050,0015' => { VR => 'FD', Name => 'ContainerComponentWidth' }, 1279 2047 '0050,0016' => { VR => 'DS', Name => 'DeviceDiameter' }, 1280 2048 '0050,0017' => { VR => 'CS', Name => 'DeviceDiameterUnits' }, 1281 2049 '0050,0018' => { VR => 'DS', Name => 'DeviceVolume' }, 1282 2050 '0050,0019' => { VR => 'DS', Name => 'InterMarkerDistance' }, 2051 '0050,001B' => { VR => 'LO', Name => 'ContainerComponentID' }, 1283 2052 '0050,0020' => { VR => 'LO', Name => 'DeviceDescription' }, 1284 2053 # nuclear acquisition group … … 1364 2133 '0060,3000' => { VR => 'SQ', Name => 'HistogramSequence' }, 1365 2134 '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' }, 1368 2137 '0060,3008' => { VR => 'US', Name => 'HistogramBinWidth' }, 1369 2138 '0060,3010' => { VR => 'LO', Name => 'HistogramExplanation' }, 1370 2139 '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' }, 1371 2196 '0070,0001' => { VR => 'SQ', Name => 'GraphicAnnotationSequence' }, 1372 2197 '0070,0002' => { VR => 'CS', Name => 'GraphicLayer' }, … … 1387 2212 '0070,0023' => { VR => 'CS', Name => 'GraphicType' }, 1388 2213 '0070,0024' => { VR => 'CS', Name => 'GraphicFilled' }, 2214 '0070,0040' => { VR => 'IS', Name => 'ImageRotationRetired' }, 1389 2215 '0070,0041' => { VR => 'CS', Name => 'ImageHorizontalFlip' }, 1390 2216 '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' }, 1393 2221 '0070,005A' => { VR => 'SQ', Name => 'DisplayedAreaSelectionSequence' }, 1394 2222 '0070,0060' => { VR => 'SQ', Name => 'GraphicLayerSequence' }, … … 1401 2229 '0070,0082' => { VR => 'DA', Name => 'PresentationCreationDate' }, 1402 2230 '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' }, 1404 2233 '0070,0100' => { VR => 'CS', Name => 'PresentationSizeMode' }, 1405 2234 '0070,0101' => { VR => 'DS', Name => 'PresentationPixelSpacing' }, … … 1421 2250 '0070,031C' => { VR => 'SQ', Name => 'FiducialSetSequence' }, 1422 2251 '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' }, 1423 2400 # storage group 1424 2401 '0088,0130' => { VR => 'SH', Name => 'StorageMediaFileSetID' }, … … 1428 2405 '0088,0906' => { VR => 'ST', Name => 'TopicSubject' }, 1429 2406 '0088,0910' => { VR => 'LO', Name => 'TopicAuthor' }, 1430 '0088,0912' => { VR => 'LO', Name => 'TopicKey Words' },2407 '0088,0912' => { VR => 'LO', Name => 'TopicKeywords' }, 1431 2408 '0100,0410' => { VR => 'CS', Name => 'SOPInstanceStatus' }, 1432 2409 '0100,0420' => { VR => 'DT', Name => 'SOPAuthorizationDateAndTime' }, … … 1444 2421 '0400,0305' => { VR => 'CS', Name => 'CertifiedTimestampType' }, 1445 2422 '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' }, 1446 2427 '0400,0500' => { VR => 'SQ', Name => 'EncryptedAttributesSequence' }, 1447 2428 '0400,0510' => { VR => 'UI', Name => 'EncryptedContentTransferSyntaxUID' }, 1448 2429 '0400,0520' => { VR => 'OB', Name => 'EncryptedContent' }, 1449 2430 '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' }, 1450 2443 '2000,0010' => { VR => 'IS', Name => 'NumberOfCopies' }, 1451 2444 '2000,001E' => { VR => 'SQ', Name => 'PrinterConfigurationSequence' }, … … 1467 2460 '2000,00A4' => { VR => 'SQ', Name => 'OtherMediaAvailableSequence' }, 1468 2461 '2000,00A8' => { VR => 'SQ', Name => 'SupportedImageDisplayFormatSeq' }, 1469 # film box group1470 2462 '2000,0500' => { VR => 'SQ', Name => 'ReferencedFilmBoxSequence' }, 1471 2463 '2000,0510' => { VR => 'SQ', Name => 'ReferencedStoredPrintSequence' }, 2464 # film box group 1472 2465 '2010,0010' => { VR => 'ST', Name => 'ImageDisplayFormat' }, 1473 2466 '2010,0030' => { VR => 'CS', Name => 'AnnotationDisplayFormatID' }, … … 1497 2490 '2010,0520' => { VR => 'SQ', Name => 'ReferencedBasicAnnotationBoxSeq' }, 1498 2491 # image box group 1499 '2020,0010' => { VR => 'US', Name => 'Image Position' },2492 '2020,0010' => { VR => 'US', Name => 'ImageBoxPosition' }, 1500 2493 '2020,0020' => { VR => 'CS', Name => 'Polarity' }, 1501 2494 '2020,0030' => { VR => 'DS', Name => 'RequestedImageSize' }, … … 1503 2496 '2020,0050' => { VR => 'CS', Name => 'RequestedResolutionID' }, 1504 2497 '2020,00A0' => { VR => 'CS', Name => 'RequestedImageSizeFlag' }, 1505 '2020,00A2' => { VR => 'CS', Name => 'Decimate -CropResult' },2498 '2020,00A2' => { VR => 'CS', Name => 'DecimateCropResult' }, 1506 2499 '2020,0110' => { VR => 'SQ', Name => 'BasicGrayscaleImageSequence' }, 1507 2500 '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' }, 1510 2503 # annotation group 1511 2504 '2030,0010' => { VR => 'US', Name => 'AnnotationPosition' }, … … 1521 2514 '2040,0080' => { VR => 'CS', Name => 'OverlayForegroundDensity' }, 1522 2515 '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' }, 1526 2519 '2050,0010' => { VR => 'SQ', Name => 'PresentationLUTSequence' }, 1527 2520 '2050,0020' => { VR => 'CS', Name => 'PresentationLUTShape' }, … … 1533 2526 '2100,0050' => { VR => 'TM', Name => 'CreationTime' }, 1534 2527 '2100,0070' => { VR => 'AE', Name => 'Originator' }, 1535 '2100,0140' => { VR => 'AE', Name => 'Destination ' },2528 '2100,0140' => { VR => 'AE', Name => 'DestinationAE' }, 1536 2529 '2100,0160' => { VR => 'SH', Name => 'OwnerID' }, 1537 2530 '2100,0170' => { VR => 'IS', Name => 'NumberOfFilms' }, … … 1593 2586 '3002,0041' => { VR => 'CS', Name => 'FluenceDataSource' }, 1594 2587 '3002,0042' => { VR => 'DS', Name => 'FluenceDataScale' }, 2588 '3002,0051' => { VR => 'CS', Name => 'FluenceMode' }, 2589 '3002,0052' => { VR => 'SH', Name => 'FluenceModeID' }, 1595 2590 '3004,0001' => { VR => 'CS', Name => 'DVHType' }, 1596 2591 '3004,0002' => { VR => 'CS', Name => 'DoseUnits' }, … … 1657 2652 '3006,00B2' => { VR => 'CS', Name => 'ROIPhysicalProperty' }, 1658 2653 '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' }, 1659 2657 '3006,00C0' => { VR => 'SQ', Name => 'FrameOfReferenceRelationshipSeq' }, 1660 2658 '3006,00C2' => { VR => 'UI', Name => 'RelatedFrameOfReferenceUID' }, … … 1667 2665 '3008,0016' => { VR => 'DS', Name => 'MeasuredDoseValue' }, 1668 2666 '3008,0020' => { VR => 'SQ', Name => 'TreatmentSessionBeamSequence' }, 2667 '3008,0021' => { VR => 'SQ', Name => 'TreatmentSessionIonBeamSequence' }, 1669 2668 '3008,0022' => { VR => 'IS', Name => 'CurrentFractionNumber' }, 1670 2669 '3008,0024' => { VR => 'DA', Name => 'TreatmentControlPointDate' }, … … 1681 2680 '3008,003B' => { VR => 'DS', Name => 'DeliveredTreatmentTime' }, 1682 2681 '3008,0040' => { VR => 'SQ', Name => 'ControlPointDeliverySequence' }, 2682 '3008,0041' => { VR => 'SQ', Name => 'IonControlPointDeliverySequence' }, 1683 2683 '3008,0042' => { VR => 'DS', Name => 'SpecifiedMeterset' }, 1684 2684 '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' }, 1685 2688 '3008,0048' => { VR => 'DS', Name => 'DoseRateDelivered' }, 1686 2689 '3008,0050' => { VR => 'SQ', Name => 'TreatmentSummaryCalcDoseRefSeq' }, … … 1690 2693 '3008,005A' => { VR => 'IS', Name => 'NumberOfFractionsDelivered' }, 1691 2694 '3008,0060' => { VR => 'SQ', Name => 'OverrideSequence' }, 2695 '3008,0061' => { VR => 'AT', Name => 'ParameterSequencePointer' }, 1692 2696 '3008,0062' => { VR => 'AT', Name => 'OverrideParameterPointer' }, 2697 '3008,0063' => { VR => 'IS', Name => 'ParameterItemIndex' }, 1693 2698 '3008,0064' => { VR => 'IS', Name => 'MeasuredDoseReferenceNumber' }, 2699 '3008,0065' => { VR => 'AT', Name => 'ParameterPointer' }, 1694 2700 '3008,0066' => { VR => 'ST', Name => 'OverrideReason' }, 2701 '3008,0068' => { VR => 'SQ', Name => 'CorrectedParameterSequence' }, 2702 '3008,006A' => { VR => 'FL', Name => 'CorrectionValue' }, 1695 2703 '3008,0070' => { VR => 'SQ', Name => 'CalculatedDoseReferenceSequence' }, 1696 2704 '3008,0072' => { VR => 'IS', Name => 'CalculatedDoseReferenceNumber' }, … … 1708 2716 '3008,00D0' => { VR => 'SQ', Name => 'RecordedBlockSequence' }, 1709 2717 '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' }, 1710 2722 '3008,0100' => { VR => 'SQ', Name => 'RecordedSourceSequence' }, 1711 2723 '3008,0105' => { VR => 'LO', Name => 'SourceSerialNumber' }, … … 1745 2757 '300A,0007' => { VR => 'TM', Name => 'RTPlanTime' }, 1746 2758 '300A,0009' => { VR => 'LO', Name => 'TreatmentProtocols' }, 1747 '300A,000A' => { VR => 'CS', Name => ' TreatmentIntent' },2759 '300A,000A' => { VR => 'CS', Name => 'PlanIntent' }, 1748 2760 '300A,000B' => { VR => 'LO', Name => 'TreatmentSites' }, 1749 2761 '300A,000C' => { VR => 'CS', Name => 'RTPlanGeometry' }, … … 1776 2788 '300A,0048' => { VR => 'SQ', Name => 'BeamLimitingDeviceToleranceSeq' }, 1777 2789 '300A,004A' => { VR => 'DS', Name => 'BeamLimitingDevicePositionTol' }, 2790 '300A,004B' => { VR => 'FL', Name => 'SnoutPositionTolerance' }, 1778 2791 '300A,004C' => { VR => 'DS', Name => 'PatientSupportAngleTolerance' }, 1779 2792 '300A,004E' => { VR => 'DS', Name => 'TableTopEccentricAngleTolerance' }, 2793 '300A,004F' => { VR => 'FL', Name => 'TableTopPitchAngleTolerance' }, 2794 '300A,0050' => { VR => 'FL', Name => 'TableTopRollAngleTolerance' }, 1780 2795 '300A,0051' => { VR => 'DS', Name => 'TableTopVerticalPositionTolerance' }, 1781 2796 '300A,0052' => { VR => 'DS', Name => 'TableTopLongitudinalPositionTol' }, … … 1793 2808 '300A,0084' => { VR => 'DS', Name => 'BeamDose' }, 1794 2809 '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' }, 1795 2813 '300A,00A0' => { VR => 'IS', Name => 'NumberOfBrachyApplicationSetups' }, 1796 2814 '300A,00A2' => { VR => 'DS', Name => 'BrachyAppSetupDoseSpecPoint' }, … … 1803 2821 '300A,00B8' => { VR => 'CS', Name => 'RTBeamLimitingDeviceType' }, 1804 2822 '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' }, 1806 2825 '300A,00BE' => { VR => 'DS', Name => 'LeafPositionBoundaries' }, 1807 2826 '300A,00C0' => { VR => 'IS', Name => 'BeamNumber' }, … … 1822 2841 '300A,00D5' => { VR => 'IS', Name => 'WedgeAngle' }, 1823 2842 '300A,00D6' => { VR => 'DS', Name => 'WedgeFactor' }, 2843 '300A,00D7' => { VR => 'FL', Name => 'TotalWedgeTrayWaterEquivThickness' }, 1824 2844 '300A,00D8' => { VR => 'DS', Name => 'WedgeOrientation' }, 2845 '300A,00D9' => { VR => 'FL', Name => 'IsocenterToWedgeTrayDistance' }, 1825 2846 '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' }, 1826 2850 '300A,00E0' => { VR => 'IS', Name => 'NumberOfCompensators' }, 1827 2851 '300A,00E1' => { VR => 'SH', Name => 'MaterialID' }, … … 1841 2865 '300A,00F0' => { VR => 'IS', Name => 'NumberOfBlocks' }, 1842 2866 '300A,00F2' => { VR => 'DS', Name => 'TotalBlockTrayFactor' }, 2867 '300A,00F3' => { VR => 'FL', Name => 'TotalBlockTrayWaterEquivThickness' }, 1843 2868 '300A,00F4' => { VR => 'SQ', Name => 'BlockSequence' }, 1844 2869 '300A,00F5' => { VR => 'SH', Name => 'BlockTrayID' }, 1845 2870 '300A,00F6' => { VR => 'DS', Name => 'SourceToBlockTrayDistance' }, 2871 '300A,00F7' => { VR => 'FL', Name => 'IsocenterToBlockTrayDistance' }, 1846 2872 '300A,00F8' => { VR => 'CS', Name => 'BlockType' }, 1847 2873 '300A,00F9' => { VR => 'LO', Name => 'AccessoryCode' }, … … 1868 2894 '300A,0118' => { VR => 'CS', Name => 'WedgePosition' }, 1869 2895 '300A,011A' => { VR => 'SQ', Name => 'BeamLimitingDevicePositionSequence' }, 1870 '300A,011C' => { VR => 'DS', Name => 'Leaf -JawPositions' },2896 '300A,011C' => { VR => 'DS', Name => 'LeafJawPositions' }, 1871 2897 '300A,011E' => { VR => 'DS', Name => 'GantryAngle' }, 1872 2898 '300A,011F' => { VR => 'CS', Name => 'GantryRotationDirection' }, … … 1885 2911 '300A,0130' => { VR => 'DS', Name => 'SourceToSurfaceDistance' }, 1886 2912 '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' }, 1887 2921 '300A,0180' => { VR => 'SQ', Name => 'PatientSetupSequence' }, 1888 2922 '300A,0182' => { VR => 'IS', Name => 'PatientSetupNumber' }, 2923 '300A,0183' => { VR => 'LO', Name => 'PatientSetupLabel' }, 1889 2924 '300A,0184' => { VR => 'LO', Name => 'PatientAdditionalPosition' }, 1890 2925 '300A,0190' => { VR => 'SQ', Name => 'FixationDeviceSequence' }, … … 1893 2928 '300A,0196' => { VR => 'ST', Name => 'FixationDeviceDescription' }, 1894 2929 '300A,0198' => { VR => 'SH', Name => 'FixationDevicePosition' }, 2930 '300A,0199' => { VR => 'FL', Name => 'FixationDevicePitchAngle' }, 2931 '300A,019A' => { VR => 'FL', Name => 'FixationDeviceRollAngle' }, 1895 2932 '300A,01A0' => { VR => 'SQ', Name => 'ShieldingDeviceSequence' }, 1896 2933 '300A,01A2' => { VR => 'CS', Name => 'ShieldingDeviceType' }, … … 1922 2959 '300A,0226' => { VR => 'LO', Name => 'SourceIsotopeName' }, 1923 2960 '300A,0228' => { VR => 'DS', Name => 'SourceIsotopeHalfLife' }, 2961 '300A,0229' => { VR => 'CS', Name => 'SourceStrengthUnits' }, 1924 2962 '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' }, 1927 2966 '300A,0230' => { VR => 'SQ', Name => 'ApplicationSetupSequence' }, 1928 2967 '300A,0232' => { VR => 'CS', Name => 'ApplicationSetupType' }, … … 1973 3012 '300A,02E1' => { VR => 'CS', Name => 'CompensatorMountingPosition' }, 1974 3013 '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' }, 1975 3089 '300C,0002' => { VR => 'SQ', Name => 'ReferencedRTPlanSequence' }, 1976 3090 '300C,0004' => { VR => 'SQ', Name => 'ReferencedBeamSequence' }, … … 1998 3112 '300C,00E0' => { VR => 'IS', Name => 'ReferencedBlockNumber' }, 1999 3113 '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' }, 2000 3120 '300E,0002' => { VR => 'CS', Name => 'ApprovalStatus' }, 2001 3121 '300E,0004' => { VR => 'DA', Name => 'ReviewDate' }, … … 2004 3124 # text group 2005 3125 '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' }, 2008 3128 # results group 2009 3129 '4008,0040' => { VR => 'SH', Name => 'ResultsID' }, … … 2056 3176 '50xx,2008' => { VR => 'UL', Name => 'SampleRate' }, 2057 3177 '50xx,200A' => { VR => 'UL', Name => 'TotalTime' }, 2058 '50xx,200C' => { VR => 'O B', Name => 'AudioSampleData' },3178 '50xx,200C' => { VR => 'OW', Name => 'AudioSampleData' }, 2059 3179 '50xx,200E' => { VR => 'LT', Name => 'AudioComments' }, 2060 3180 '50xx,2500' => { VR => 'LO', Name => 'CurveLabel' }, 2061 3181 '50xx,2600' => { VR => 'SQ', Name => 'ReferencedOverlaySequence' }, 2062 3182 '50xx,2610' => { VR => 'US', Name => 'ReferencedOverlayGroup' }, 2063 '50xx,3000' => { VR => 'O B', Name => 'CurveData' },3183 '50xx,3000' => { VR => 'OW', Name => 'CurveData' }, 2064 3184 '5200,9229' => { VR => 'SQ', Name => 'SharedFunctionalGroupsSequence' }, 2065 3185 '5200,9230' => { VR => 'SQ', Name => 'PerFrameFunctionalGroupsSequence' }, 2066 3186 '5400,0100' => { VR => 'SQ', Name => 'WaveformSequence' }, 2067 '5400,0110' => { VR => 'O W', Name => 'ChannelMinimumValue' },2068 '5400,0112' => { VR => 'O W', Name => 'ChannelMaximumValue' },3187 '5400,0110' => { VR => 'OB', Name => 'ChannelMinimumValue' }, 3188 '5400,0112' => { VR => 'OB', Name => 'ChannelMaximumValue' }, 2069 3189 '5400,1004' => { VR => 'US', Name => 'WaveformBitsAllocated' }, 2070 3190 '5400,1006' => { VR => 'CS', Name => 'WaveformSampleInterpretation' }, 2071 '5400,100A' => { VR => 'O W', Name => 'WaveformPaddingValue' },2072 '5400,1010' => { VR => 'O W', Name => 'WaveformData' },3191 '5400,100A' => { VR => 'OB', Name => 'WaveformPaddingValue' }, 3192 '5400,1010' => { VR => 'OB', Name => 'WaveformData' }, 2073 3193 '5600,0010' => { VR => 'OF', Name => 'FirstOrderPhaseCorrectionAngle' }, 2074 3194 '5600,0020' => { VR => 'OF', Name => 'SpectroscopyData' }, … … 2085 3205 '60xx,0051' => { VR => 'US', Name => 'ImageFrameOrigin' }, 2086 3206 '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' }, 2088 3214 '60xx,0100' => { VR => 'US', Name => 'OverlayBitsAllocated' }, 2089 3215 '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' }, 2092 3222 '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' }, 2101 3231 '60xx,1301' => { VR => 'IS', Name => 'ROIArea' }, 2102 3232 '60xx,1302' => { VR => 'DS', Name => 'ROIMean' }, 2103 3233 '60xx,1303' => { VR => 'DS', Name => 'ROIStandardDeviation' }, 2104 3234 '60xx,1500' => { VR => 'LO', Name => 'OverlayLabel' }, 2105 '60xx,3000' => { VR => 'O W', Name => 'OverlayData' },2106 '60xx,4000' => { VR => ' RET',Name => 'OverlayComments' },3235 '60xx,3000' => { VR => 'OB', Name => 'OverlayData' }, 3236 '60xx,4000' => { VR => 'LT',Name => 'OverlayComments' }, 2107 3237 # 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' }, 2110 3244 'FFFA,FFFA' => { VR => 'SQ', Name => 'DigitalSignaturesSequence' }, 2111 'FFFC,FFFC' => { VR => 'OB', Name => 'DataSetTrailingPadding' },3245 'FFFC,FFFC' => { VR => 'OB', Name => 'DataSetTrailingPadding', Binary => 1 }, 2112 3246 # the sequence delimiters have no VR: 2113 3247 'FFFE,E000' => 'StartOfItem', … … 2117 3251 2118 3252 # 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 = ( 2120 3255 '1.2.840.10008.1.1' => 'Verification SOP Class', 2121 3256 '1.2.840.10008.1.2' => 'Implicit VR Little Endian', … … 2145 3280 '1.2.840.10008.1.2.4.90' => 'JPEG 2000 Image Compression (Lossless Only)', 2146 3281 '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', 2147 3286 '1.2.840.10008.1.2.4.100' => 'MPEG2 Main Profile @ Main Level', 2148 3287 '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', 2149 3290 '1.2.840.10008.1.3.10' => 'Media Storage Directory Storage', 2150 3291 '1.2.840.10008.1.4.1.1' => 'Talairach Brain Atlas Frame of Reference', … … 2175 3316 '1.2.840.10008.1.40' => 'Procedural Event Logging SOP Class', 2176 3317 '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', 2178 3322 '1.2.840.10008.3.1.1.1' => 'DICOM Application Context Name', 2179 3323 '1.2.840.10008.3.1.2.1.1' => 'Detached Patient Management SOP Class', … … 2218 3362 '1.2.840.10008.5.1.1.33' => 'Media Creation Management SOP Class', 2219 3363 '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', 2226 3370 '1.2.840.10008.5.1.4.1.1.2' => 'CT Image Storage', 2227 3371 '1.2.840.10008.5.1.4.1.1.2.1' => 'Enhanced CT Image Storage', … … 2241 3385 '1.2.840.10008.5.1.4.1.1.8' => 'Standalone Overlay Storage', 2242 3386 '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)', 2243 3388 '1.2.840.10008.5.1.4.1.1.9.1.1' => '12-lead ECG Waveform Storage', 2244 3389 '1.2.840.10008.5.1.4.1.1.9.1.2' => 'General ECG Waveform Storage', … … 2250 3395 '1.2.840.10008.5.1.4.1.1.11' => 'Standalone VOI LUT Storage', 2251 3396 '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', 2252 3400 '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', 2253 3402 '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', 2254 3404 '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', 2255 3407 '1.2.840.10008.5.1.4.1.1.20' => 'Nuclear Medicine Image Storage', 2256 3408 '1.2.840.10008.5.1.4.1.1.66' => 'Raw Data Storage', 2257 3409 '1.2.840.10008.5.1.4.1.1.66.1' => 'Spatial Registration Storage', 2258 3410 '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', 2259 3414 '1.2.840.10008.5.1.4.1.1.77.1' => 'VL Image Storage ', 2260 3415 '1.2.840.10008.5.1.4.1.1.77.2' => 'VL Multi-frame Image Storage', … … 2269 3424 '1.2.840.10008.5.1.4.1.1.77.1.5.2' => 'Ophthalmic Photography 16 Bit Image Storage', 2270 3425 '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)', 2271 3431 '1.2.840.10008.5.1.4.1.1.88.11' => 'Basic Text SR', 2272 3432 '1.2.840.10008.5.1.4.1.1.88.22' => 'Enhanced SR', … … 2276 3436 '1.2.840.10008.5.1.4.1.1.88.59' => 'Key Object Selection Document', 2277 3437 '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', 2278 3441 '1.2.840.10008.5.1.4.1.1.128' => 'Positron Emission Tomography Image Storage', 2279 3442 '1.2.840.10008.5.1.4.1.1.129' => 'Standalone PET Curve Storage', … … 2285 3448 '1.2.840.10008.5.1.4.1.1.481.6' => 'RT Brachy Treatment Record Storage', 2286 3449 '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', 2293 3458 '1.2.840.10008.5.1.4.1.2.3.1' => 'Patient/Study Only Query/Retrieve Information Model - FIND', 2294 3459 '1.2.840.10008.5.1.4.1.2.3.2' => 'Patient/Study Only Query/Retrieve Information Model - MOVE', 2295 3460 '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', 2298 3463 '1.2.840.10008.5.1.4.32.2' => 'General Purpose Scheduled Procedure Step SOP Class', 2299 3464 '1.2.840.10008.5.1.4.32.3' => 'General Purpose Performed Procedure Step SOP Class', 2300 3465 '1.2.840.10008.5.1.4.32' => 'General Purpose Worklist Management Meta SOP Class', 2301 3466 '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', 2302 3476 '1.2.840.10008.5.1.4.37.1' => 'General Relevant Patient Information Query', 2303 3477 '1.2.840.10008.5.1.4.37.2' => 'Breast Imaging Relevant Patient Information Query', 2304 3478 '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', 2305 3484 '1.2.840.10008.15.0.3.1' => 'dicomDeviceName', 2306 3485 '1.2.840.10008.15.0.3.2' => 'dicomDescription', … … 2503 3682 my $tagInfo = $$tagTablePtr{$tag}; 2504 3683 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' 2506 3686 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})) 2509 3692 { 2510 3693 $tag = $xx; … … 2614 3797 =head1 NOTES 2615 3798 2616 Values of retired elements in implicit VR format files are intepreted as2617 strings, hence they may not be displayed properly. This is because the2618 specification no longer lists these VR's, but simply lists 'RET' for these2619 elements. (Doh. Who's idea was that? :P)2620 2621 3799 Images compressed using the DICOM deflated transfer syntax will be decoded 2622 3800 if Compress::Zlib is installed. … … 2626 3804 =head1 AUTHOR 2627 3805 2628 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)3806 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 2629 3807 2630 3808 This library is free software; you can redistribute it and/or modify it … … 2635 3813 =over 4 2636 3814 2637 =item L<http://medical.nema.org/ dicom/2004.html>3815 =item L<http://medical.nema.org/> 2638 3816 2639 3817 =item L<http://www.sph.sc.edu/comd/rorden/dicom.html> 2640 3818 2641 3819 =item L<http://www.dclunie.com/> 3820 3821 =item L<http://www.gehealthcare.com/usen/interoperability/dicom/docs/2258357r3.pdf> 2642 3822 2643 3823 =back -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DNG.pm
r16842 r24107 6 6 # Revisions: 01/09/2006 - P. Harvey Created 7 7 # 8 # References: 1) http://www.adobe.com/products/dng/ pdfs/dng_spec.pdf8 # References: 1) http://www.adobe.com/products/dng/ 9 9 #------------------------------------------------------------------------------ 10 10 … … 18 18 use Image::ExifTool::CanonRaw; 19 19 20 $VERSION = '1. 07';20 $VERSION = '1.15'; 21 21 22 22 sub ProcessOriginalRaw($$$); … … 24 24 sub ProcessAdobeMakN($$$); 25 25 sub ProcessAdobeCRW($$$); 26 sub ProcessAdobeRAF($$$); 26 27 sub ProcessAdobeMRW($$$); 27 28 sub ProcessAdobeSR2($$$); 29 sub ProcessAdobeIFD($$$); 28 30 sub WriteAdobeStuff($$$); 29 31 … … 55 57 The maker notes ('MakN') are processed by ExifTool, but some information may 56 58 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 referenced59 Converter (as of version 6.3) doesn't properly handle information referenced 58 60 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. 67 68 }, 68 69 MakN => [ ], # (filled in later) … … 92 93 'RAF ' => { 93 94 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 }, 95 120 }, 96 121 ); … … 107 132 my %copy = %$tagInfo; 108 133 delete $copy{Groups}; 134 delete $copy{GotGroups}; 109 135 delete $copy{Table}; 110 136 push @$list, \%copy; … … 124 150 my $pos = $start; 125 151 my ($index, $err); 152 126 153 SetByteOrder('MM'); # pointers are always big-endian in this structure 127 154 for ($index=0; $index<8; ++$index) { … … 205 232 unless ($outfile) { 206 233 $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'); 209 239 SetByteOrder('MM'); # always big endian 210 240 $pos += 6; … … 217 247 my $name = "Adobe$tag"; 218 248 $name =~ tr/ //d; 219 $exifTool->H tmlDump($dataPos + $pos - 8, 8, "$name header", "Data Size: $size bytes");249 $exifTool->HDump($dataPos + $pos - 8, 8, "$name header", "Data Size: $size bytes"); 220 250 # dump non-EXIF format data 221 251 unless ($tag =~ /^(MakN|SR2 )$/) { 222 $exifTool->H tmlDump($dataPos + $pos, $size, "$name data");252 $exifTool->HDump($dataPos + $pos, $size, "$name data"); 223 253 } 224 254 } 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 } 232 265 my $value; 233 266 while ($tagInfo) { … … 356 389 if ($subdir and $$subdir{TagTable}) { 357 390 my $name = $$tagInfo{Name}; 358 my $newTagTable = Image::ExifTool::GetTagTable($$subdir{TagTable});391 my $newTagTable = GetTagTable($$subdir{TagTable}); 359 392 return 0 unless $newTagTable; 360 393 my $subdirStart = 0; … … 385 418 } 386 419 } elsif ($$newTags{$tagID}) { 387 my $n ewValueHash = $exifTool->GetNewValueHash($tagInfo);388 if (Image::ExifTool::IsOverwriting($n ewValueHash, $val)) {389 my $newVal = Image::ExifTool::GetNewValues($n ewValueHash);420 my $nvHash = $exifTool->GetNewValueHash($tagInfo); 421 if (Image::ExifTool::IsOverwriting($nvHash, $val)) { 422 my $newVal = Image::ExifTool::GetNewValues($nvHash); 390 423 my $verboseVal; 391 424 $verboseVal = $newVal if $verbose > 1; … … 395 428 } 396 429 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); 404 432 $value = $newVal; 405 433 ++$exifTool->{CHANGED}; … … 464 492 my $dirStart = $$dirInfo{DirStart}; 465 493 my $outfile = $$dirInfo{OutFile}; 494 466 495 # construct fake MRW file 467 496 my $buff = "\0MRM" . pack('N', $dirLen - 4); … … 479 508 480 509 #------------------------------------------------------------------------------ 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 513 sub 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 #------------------------------------------------------------------------------ 481 557 # Process Adobe SR2 directory 482 558 # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref … … 486 562 { 487 563 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 564 return 0 if $$dirInfo{OutFile}; # (can't write this yet) 488 565 my $dataPt = $$dirInfo{DataPt}; 489 566 my $start = $$dirInfo{DirStart}; 490 567 my $len = $$dirInfo{DirLen}; 491 return 0 if $$dirInfo{OutFile}; # (can't write this yet)492 568 493 569 return 0 if $len < 6; … … 514 590 ); 515 591 if ($exifTool->Options('HtmlDump')) { 516 $exifTool->H tmlDump($dataPos + $start, 6, 'Adobe SR2 data');592 $exifTool->HDump($dataPos + $start, 6, 'Adobe SR2 data'); 517 593 } 518 594 # parse the SR2 directory 519 595 $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) 604 sub 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 } 520 656 return 1; 521 657 } … … 571 707 } 572 708 if ($exifTool->Options('HtmlDump')) { 573 $exifTool->H tmlDump($dataPos + $start, 6, 'Adobe MakN data');574 $exifTool->H tmlDump($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; 575 711 } 576 712 … … 606 742 $fixup->{Shift} += $originalPos; 607 743 } 744 # if we wrote the directory as a block the header is already included 745 $loc = 0 if $subdirInfo{BlockWrite}; 608 746 $fixup->{Shift} += $loc; # adjust for makernotes header 609 747 $fixup->ApplyFixup(\$buff); # fix up pointer offsets … … 673 811 =head1 AUTHOR 674 812 675 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)813 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 676 814 677 815 This library is free software; you can redistribute it and/or modify it … … 682 820 =over 4 683 821 684 =item L<http://www.adobe.com/products/dng/ pdfs/dng_spec.pdf>822 =item L<http://www.adobe.com/products/dng/> 685 823 686 824 =back -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Exif.pm
r16842 r24107 2 2 # File: Exif.pm 3 3 # 4 # Description: Read EXIF meta information4 # Description: Read EXIF/TIFF meta information 5 5 # 6 6 # Revisions: 11/25/2003 - P. Harvey Created … … 12 12 # References: 0) http://www.exif.org/Exif2-2.PDF 13 13 # 1) http://partners.adobe.com/asn/developer/pdfs/tn/TIFF6.pdf 14 # 2) http://www.adobe.com/products/dng/pdfs/dng_spec .pdf14 # 2) http://www.adobe.com/products/dng/pdfs/dng_spec_1_3_0_0.pdf 15 15 # 3) http://www.awaresystems.be/imaging/tiff/tifftags.html 16 16 # 4) http://www.remotesensing.org/libtiff/TIFFTechNote2.html 17 # 5) http://www. asmail.be/msg0054681802.html17 # 5) http://www.exif.org/dcf.PDF 18 18 # 6) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html 19 19 # 7) http://www.fine-view.com/jp/lab/doc/ps6ffspecsv2.pdf … … 24 24 # 12) http://www.broomscloset.com/closet/photo/exif/TAG2000-22_DIS12234-2.PDF 25 25 # 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 26 41 #------------------------------------------------------------------------------ 27 42 … … 29 44 30 45 use strict; 31 use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber 32 %lightSource %compression %photometricInterpretation %orientation); 46 use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat 47 %lightSource %flash %compression %photometricInterpretation %orientation 48 %subfileType); 33 49 use Image::ExifTool qw(:DataAccess :Utils); 34 50 use Image::ExifTool::MakerNotes; 35 51 36 $VERSION = ' 2.42';52 $VERSION = '3.21'; 37 53 38 54 sub ProcessExif($$$); … … 42 58 sub EncodeExifText($$); 43 59 sub ValidateIFD($;$); 60 sub ProcessTiffIFD($$$); 61 sub PrintParameter($$$); 62 sub GetOffList($$$$$); 63 sub PrintLensInfo($); 64 sub ConvertLensInfo($); 65 66 # size limit for loading binary data block into memory 67 sub BINARY_DATA_LIMIT { return 10 * 1024 * 1024; } 44 68 45 69 # 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); 47 71 48 72 @formatName = ( … … 50 74 'int32u', 'rational64u', 'int8s', 'undef', 51 75 'int16s', 'int32s', 'rational64s', 'float', 52 'double', 'ifd', undef, undef, # (14 is unicode, 15 is complex? http://remotesensing.org/libtiff/bigtiffdesign.html)53 'int64u', 'int64s', 'ifd 8', # (new BigTIFF formats)76 'double', 'ifd', 'unicode', 'complex', 77 'int64u', 'int64s', 'ifd64', # (new BigTIFF formats) 54 78 ); 55 79 … … 57 81 # (format types are all lower case) 58 82 %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, 76 121 ); 77 122 78 123 # EXIF LightSource PrintConv values 79 124 %lightSource = ( 125 0 => 'Unknown', 80 126 1 => 'Daylight', 81 127 2 => 'Fluorescent', 82 3 => 'Tungsten ',128 3 => 'Tungsten (Incandescent)', 83 129 4 => 'Flash', 84 130 9 => 'Fine Weather', 85 131 10 => 'Cloudy', 86 132 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) 91 138 17 => 'Standard Light A', 92 139 18 => 'Standard Light B', … … 100 147 ); 101 148 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) 102 188 %compression = ( 103 189 1 => 'Uncompressed', … … 111 197 9 => 'JBIG B&W', #3 112 198 10 => 'JBIG Color', #3 199 99 => 'JPEG', #16 200 262 => 'Kodak 262', #16 113 201 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 115 205 32771 => 'CCIRLEW', #3 116 206 32773 => 'PackBits', 117 207 32809 => 'Thunderscan', #3 208 32867 => 'Kodak KDC Compressed', #PH 118 209 32895 => 'IT8CTPAD', #3 119 210 32896 => 'IT8LW', #3 … … 129 220 34712 => 'JPEG 2000', #3 130 221 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 131 226 65000 => 'Kodak DCR Compressed', #PH 132 227 65535 => 'Pentax PEF Compressed', #Jens 133 134 228 ); 135 229 … … 162 256 ); 163 257 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 164 285 # ValueConv that makes long values binary type 165 286 my %longBin = ( … … 168 289 ); 169 290 291 # PrintConv for SampleFormat (0x153) 292 my %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 170 301 # main EXIF tag table 171 302 %Image::ExifTool::Exif::Main = ( … … 173 304 WRITE_PROC => \&WriteExif, 174 305 WRITE_GROUP => 'ExifIFD', # default write group 306 SET_GROUP1 => 1, # set group1 name to directory name for all tags in table 175 307 0x1 => { 176 308 Name => 'InteropIndex', … … 182 314 }, 183 315 }, 184 0x2 => { 316 0x2 => { #5 185 317 Name => 'InteropVersion', 186 318 Description => 'Interoperability Version', 319 RawConv => '$val=~s/\0+$//; $val', # (some idiots add null terminators) 187 320 }, 188 321 0x0b => { #PH … … 193 326 Name => 'SubfileType', 194 327 # 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, 206 331 }, 207 332 0xff => { 208 333 Name => 'OldSubfileType', 209 334 # 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', 211 336 PrintConv => { 212 337 1 => 'Full-resolution image', … … 220 345 # so it will show up in the group lists 221 346 Groups => { 1 => 'IFD1' }, 222 # set Priority to zero so the value found in the first IFD (IFD0) doesn't223 # 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") 224 349 Priority => 0, 225 350 }, 226 351 0x101 => { 227 352 Name => 'ImageHeight', 353 Notes => 'called ImageLength by the EXIF spec.', 228 354 Priority => 0, 229 355 }, … … 234 360 0x103 => { 235 361 Name => 'Compression', 362 DataMember => 'Compression', 363 SeparateTable => 'Compression', 364 RawConv => q{ 365 Image::ExifTool::Exif::IdentifyRawFile($self, $val); 366 return $$self{Compression} = $val; 367 }, 236 368 PrintConv => \%compression, 237 369 Priority => 0, … … 267 399 Name => 'Make', 268 400 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 272 408 }, 273 409 0x110 => { … … 275 411 Description => 'Camera Model Name', 276 412 Groups => { 2 => 'Camera' }, 277 DataMember => ' CameraModel',278 # save this value as an ExifTool member variable279 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', 280 416 }, 281 417 0x111 => [ 282 418 { 283 419 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]$/) 286 434 ], 287 435 Name => 'StripOffsets', … … 291 439 }, 292 440 { 293 Condition => '$ self->{DIR_NAME} eq "IFD0"',441 Condition => '$$self{DIR_NAME} eq "IFD0"', 294 442 Name => 'PreviewImageStart', 295 443 IsOffset => 1, … … 302 450 Writable => 'int32u', 303 451 WriteGroup => 'IFD0', 304 WriteCondition => '$ self->{TIFF_TYPE} eq "CR2"',452 WriteCondition => '$$self{TIFF_TYPE} eq "CR2"', 305 453 Protected => 2, 306 454 }, 307 455 { 308 Condition => '$ self->{DIR_NAME} eq "SubIFD1"',456 Condition => '$$self{DIR_NAME} eq "SubIFD1"', 309 457 Name => 'PreviewImageStart', 310 458 IsOffset => 1, … … 313 461 Writable => 'int32u', 314 462 WriteGroup => 'SubIFD1', 315 WriteCondition => '$ self->{TIFF_TYPE} eq "DNG"',463 WriteCondition => '$$self{TIFF_TYPE} eq "DNG"', 316 464 Protected => 2, 317 465 }, … … 323 471 Writable => 'int32u', 324 472 WriteGroup => 'SubIFD2', 325 WriteCondition => '$ self->{TIFF_TYPE} eq "DNG"',473 WriteCondition => '$$self{TIFF_TYPE} eq "DNG"', 326 474 Protected => 2, 327 475 }, … … 330 478 Name => 'Orientation', 331 479 PrintConv => \%orientation, 332 Priority => 0, # so IFD1 doesn't takeprecedence480 Priority => 0, # so PRIORITY_DIR takes precedence 333 481 }, 334 482 0x115 => { … … 343 491 { 344 492 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]$/) 347 506 ], 348 507 Name => 'StripByteCounts', … … 351 510 }, 352 511 { 353 Condition => '$ self->{DIR_NAME} eq "IFD0"',512 Condition => '$$self{DIR_NAME} eq "IFD0"', 354 513 Name => 'PreviewImageLength', 355 514 OffsetPair => 0x111, … … 361 520 Writable => 'int32u', 362 521 WriteGroup => 'IFD0', 363 WriteCondition => '$ self->{TIFF_TYPE} eq "CR2"',522 WriteCondition => '$$self{TIFF_TYPE} eq "CR2"', 364 523 Protected => 2, 365 524 }, 366 525 { 367 Condition => '$ self->{DIR_NAME} eq "SubIFD1"',526 Condition => '$$self{DIR_NAME} eq "SubIFD1"', 368 527 Name => 'PreviewImageLength', 369 528 OffsetPair => 0x111, … … 371 530 Writable => 'int32u', 372 531 WriteGroup => 'SubIFD1', 373 WriteCondition => '$ self->{TIFF_TYPE} eq "DNG"',532 WriteCondition => '$$self{TIFF_TYPE} eq "DNG"', 374 533 Protected => 2, 375 534 }, … … 380 539 Writable => 'int32u', 381 540 WriteGroup => 'SubIFD2', 382 WriteCondition => '$ self->{TIFF_TYPE} eq "DNG"',541 WriteCondition => '$$self{TIFF_TYPE} eq "DNG"', 383 542 Protected => 2, 384 543 }, … … 388 547 0x11a => { 389 548 Name => 'XResolution', 390 Priority => 0, # so IFD0 takes priority over IFD1549 Priority => 0, # so PRIORITY_DIR takes precedence 391 550 }, 392 551 0x11b => { … … 446 605 0x128 => { 447 606 Name => 'ResolutionUnit', 607 Notes => 'the value 1 is not standard EXIF', 448 608 PrintConv => { 449 609 1 => 'None', … … 461 621 0x131 => { 462 622 Name => 'Software', 623 RawConv => '$val =~ s/\s+$//; $val', # trim trailing blanks 463 624 }, 464 625 0x132 => { 465 626 Name => 'ModifyDate', 466 627 Groups => { 2 => 'Time' }, 628 Notes => 'called DateTime by the EXIF spec.', 467 629 PrintConv => '$self->ConvertDateTime($val)', 468 630 }, … … 470 632 Name => 'Artist', 471 633 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 472 636 }, 473 637 0x13c => 'HostComputer', … … 516 680 }, 517 681 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 ], 527 712 0x14c => { 528 713 Name => 'InkSet', … … 536 721 0x150 => 'DotRange', 537 722 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 }, 539 731 0x153 => { 540 732 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 ], 549 736 }, 550 737 0x154 => 'SMinSampleValue', … … 569 756 }, 570 757 }, 758 # 0x181 => 'Decode', #20 (typo! - should be 0x1b1, ref 21) 759 # 0x182 => 'DefaultImageColor', #20 (typo! - should be 0x1b2, ref 21) 571 760 0x190 => { #3 572 761 Name => 'GlobalParametersIFD', … … 592 781 5 => 'Lossless color and grayscale, L', 593 782 6 => 'Mixed raster content, M', 783 7 => 'Profile T', #20 784 255 => 'Multi Profiles', #20 594 785 }, 595 786 }, … … 609 800 0x195 => 'ModeNumber', #3 610 801 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 }, 612 808 0x200 => { 613 809 Name => 'JPEGProc', … … 620 816 { 621 817 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 }, 622 825 # thumbnail is found in IFD1 of JPEG and TIFF images, and 623 826 # IFD0 of EXIF information in FujiFilm AVI (RIFF) videos 624 827 Condition => q{ 625 $ self->{DIR_NAME} eq 'IFD1' or626 ($ 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') 627 830 }, 628 831 IsOffset => 1, … … 631 834 Writable => 'int32u', 632 835 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"', 634 874 Protected => 2, 635 875 }, 636 876 { 637 877 Name => 'PreviewImageStart', 638 Condition => '$ self->{DIR_NAME} eq "MakerNotes"',878 Condition => '$$self{DIR_NAME} eq "MakerNotes"', 639 879 IsOffset => 1, 640 880 OffsetPair => 0x202, … … 642 882 Writable => 'int32u', 643 883 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)$/', 644 897 Protected => 2, 645 898 }, 646 899 { 647 900 Name => 'JpgFromRawStart', 648 Condition => '$ self->{DIR_NAME} eq "SubIFD"',901 Condition => '$$self{DIR_NAME} eq "SubIFD"', 649 902 IsOffset => 1, 650 903 OffsetPair => 0x202, … … 652 905 Writable => 'int32u', 653 906 WriteGroup => 'SubIFD', 654 # JpgFromRaw is in SubIFD of NEF files655 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)$/', 656 909 Protected => 2, 657 910 }, 658 911 { 659 912 Name => 'JpgFromRawStart', 660 Condition => '$ self->{DIR_NAME} eq "IFD2"',913 Condition => '$$self{DIR_NAME} eq "IFD2"', 661 914 IsOffset => 1, 662 915 OffsetPair => 0x202, … … 665 918 WriteGroup => 'IFD2', 666 919 # JpgFromRaw is in IFD2 of PEF files 667 WriteCondition => '$ self->{TIFF_TYPE} eq "PEF"',920 WriteCondition => '$$self{TIFF_TYPE} eq "PEF"', 668 921 Protected => 2, 669 922 }, … … 677 930 { 678 931 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 }, 679 939 Condition => q{ 680 $ self->{DIR_NAME} eq 'IFD1' or681 ($ 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') 682 942 }, 683 943 OffsetPair => 0x201, … … 685 945 Writable => 'int32u', 686 946 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"', 688 976 Protected => 2, 689 977 }, 690 978 { 691 979 Name => 'PreviewImageLength', 692 Condition => '$ self->{DIR_NAME} eq "MakerNotes"',980 Condition => '$$self{DIR_NAME} eq "MakerNotes"', 693 981 OffsetPair => 0x201, 694 982 DataTag => 'PreviewImage', 695 983 Writable => 'int32u', 696 984 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)$/', 697 997 Protected => 2, 698 998 }, 699 999 { 700 1000 Name => 'JpgFromRawLength', 701 Condition => '$ self->{DIR_NAME} eq "SubIFD"',1001 Condition => '$$self{DIR_NAME} eq "SubIFD"', 702 1002 OffsetPair => 0x201, 703 1003 DataTag => 'JpgFromRaw', 704 1004 Writable => 'int32u', 705 1005 WriteGroup => 'SubIFD', 706 WriteCondition => '$ self->{TIFF_TYPE} eq "NEF"',1006 WriteCondition => '$$self{TIFF_TYPE} =~ /^(NEF|NRW|SRW)$/', 707 1007 Protected => 2, 708 1008 }, 709 1009 { 710 1010 Name => 'JpgFromRawLength', 711 Condition => '$ self->{DIR_NAME} eq "IFD2"',1011 Condition => '$$self{DIR_NAME} eq "IFD2"', 712 1012 OffsetPair => 0x201, 713 1013 DataTag => 'JpgFromRaw', 714 1014 Writable => 'int32u', 715 1015 WriteGroup => 'IFD2', 716 WriteCondition => '$ self->{TIFF_TYPE} eq "PEF"',1016 WriteCondition => '$$self{TIFF_TYPE} eq "PEF"', 717 1017 Protected => 2, 718 1018 }, … … 725 1025 0x205 => 'JPEGLosslessPredictors', 726 1026 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 }, 730 1045 0x211 => { 731 1046 Name => 'YCbCrCoefficients', … … 734 1049 0x212 => { 735 1050 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, 744 1053 Priority => 0, 745 1054 }, … … 758 1067 0x22f => 'StripRowCounts', 759 1068 0x2bc => { 760 Name => 'ApplicationNotes', 1069 Name => 'ApplicationNotes', # (writable directory!) 1070 Writable => 'int8u', 1071 Format => 'undef', 1072 Flags => [ 'Binary', 'Protected' ], 761 1073 # this could be an XMP block 762 1074 SubDirectory => { … … 765 1077 }, 766 1078 }, 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 }, 770 1086 # (0x474x tags written by MicrosoftPhoto) 771 1087 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 }, 772 1102 0x4749 => 'RatingPercent', #PH 773 1103 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 }, 775 1111 0x80e3 => 'Matteing', #9 776 1112 0x80e4 => 'DataType', #9 … … 778 1114 0x80e6 => 'TileDepth', #9 779 1115 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 783 1122 Name => 'BatteryLevel', 784 1123 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 }, 785 1135 }, 786 1136 0x8298 => { 787 1137 Name => 'Copyright', 788 1138 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$//; $_', 789 1153 }, 790 1154 0x829a => { … … 808 1172 0x82ac => 'MDFileUnits', #3 809 1173 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' ], 812 1190 SubDirectory => { 813 1191 DirName => 'IPTC', … … 818 1196 0x847f => 'IntergraphFlagRegisters', #3 819 1197 0x8480 => 'IntergraphMatrix', 1198 0x8481 => 'INGRReserved', #20 820 1199 0x8482 => { 821 1200 Name => 'ModelTiePoint', … … 825 1204 0x84e1 => 'ColorSequence', #9 826 1205 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 }, 828 1216 0x84e4 => 'BitsPerRunLength', #9 829 1217 0x84e5 => 'BitsPerExtendedRunLength', #9 830 1218 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 }, 833 1233 0x84e9 => 'ImageColorValue', #9 834 1234 0x84ea => 'BackgroundColorValue', #9 … … 836 1236 0x84ec => 'TransparencyIndicator', #9 837 1237 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 839 1248 0x8546 => { #11 840 1249 Name => 'SEMInfo', … … 844 1253 Name => 'AFCP_IPTC', 845 1254 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', 847 1257 TagTable => 'Image::ExifTool::IPTC::Main', 848 1258 }, 849 1259 }, 1260 0x85b8 => 'PixelMagicJBIGOptions', #20 850 1261 0x85d8 => { 851 1262 Name => 'ModelTransform', 852 1263 Groups => { 2 => 'Location' }, 853 1264 }, 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) 854 1270 0x8606 => { 855 1271 Name => 'LeafData', … … 860 1276 }, 861 1277 }, 862 0x8649 => { 1278 0x8649 => { #19 863 1279 Name => 'PhotoshopSettings', 864 1280 Format => 'binary', … … 871 1287 Name => 'ExifOffset', 872 1288 Groups => { 1 => 'ExifIFD' }, 873 Flags => 'SubIFD',1289 SubIFD => 2, 874 1290 SubDirectory => { 875 1291 DirName => 'ExifIFD', … … 883 1299 }, 884 1300 }, 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 885 1336 0x87ac => 'ImageLayer', 886 1337 0x87af => { … … 901 1352 Name => 'ExposureProgram', 902 1353 Groups => { 2 => 'Camera' }, 1354 Notes => 'the value of 9 is not standard EXIF, but is used by the Canon EOS 7D', 903 1355 PrintConv => { 1356 0 => 'Not Defined', 904 1357 1 => 'Manual', 905 1358 2 => 'Program AE', … … 910 1363 7 => 'Portrait', 911 1364 8 => 'Landscape', 1365 9 => 'Bulb', #25 912 1366 }, 913 1367 }, … … 926 1380 }, 927 1381 }, 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 }, 929 1390 0x8828 => { 930 1391 Name => 'Opto-ElectricConvFactor', 1392 Notes => 'called OECF by the EXIF spec.', 931 1393 Binary => 1, 932 1394 }, 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 }, 936 1423 0x885c => 'FaxRecvParams', #9 937 1424 0x885d => 'FaxSubAddress', #9 … … 947 1434 }, 948 1435 }, 949 0x9000 => 'ExifVersion', 1436 0x9000 => { 1437 Name => 'ExifVersion', 1438 RawConv => '$val=~s/\0+$//; $val', # (some idiots add null terminators) 1439 }, 950 1440 0x9003 => { 951 1441 Name => 'DateTimeOriginal', 952 1442 Description => 'Date/Time Original', 953 1443 Groups => { 2 => 'Time' }, 1444 Notes => 'date/time when original image was taken', 954 1445 PrintConv => '$self->ConvertDateTime($val)', 955 1446 }, … … 957 1448 Name => 'CreateDate', 958 1449 Groups => { 2 => 'Time' }, 1450 Notes => 'called DateTimeDigitized by the EXIF spec.', 959 1451 PrintConv => '$self->ConvertDateTime($val)', 960 1452 }, 961 1453 0x9101 => { 962 1454 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 }, 964 1486 }, 965 1487 0x9102 => 'CompressedBitsPerPixel', 966 1488 0x9201 => { 967 1489 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', 969 1492 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 970 1493 }, … … 977 1500 0x9204 => { 978 1501 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)', 980 1505 }, 981 1506 0x9205 => { … … 988 1513 Name => 'SubjectDistance', 989 1514 Groups => { 2 => 'Camera' }, 990 PrintConv => '$val eq "inf"? $val : "${val} m"',1515 PrintConv => '$val =~ /^(inf|undef)$/ ? $val : "${val} m"', 991 1516 }, 992 1517 0x9207 => { … … 994 1519 Groups => { 2 => 'Camera' }, 995 1520 PrintConv => { 1521 0 => 'Unknown', 996 1522 1 => 'Average', 997 1523 2 => 'Center-weighted average', … … 1006 1532 Name => 'LightSource', 1007 1533 Groups => { 2 => 'Camera' }, 1534 SeparateTable => 'LightSource', 1008 1535 PrintConv => \%lightSource, 1009 1536 }, … … 1012 1539 Groups => { 2 => 'Camera' }, 1013 1540 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, 1043 1543 }, 1044 1544 0x920a => { 1045 1545 Name => 'FocalLength', 1046 1546 Groups => { 2 => 'Camera' }, 1047 PrintConv => 'sprintf("%.1f mm",$val)',1547 PrintConv => 'sprintf("%.1f mm",$val)', 1048 1548 }, 1049 1549 # Note: tags 0x920b-0x9217 are duplicates of 0xa20b-0xa217 1050 1550 # (The TIFF standard uses 0xa2xx, but you'll find both in images) 1051 0x920b => { 1551 0x920b => { #12 1052 1552 Name => 'FlashEnergy', 1053 1553 Groups => { 2 => 'Camera' }, 1054 1554 }, 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 1060 1560 Name => 'FocalPlaneResolutionUnit', 1061 1561 Groups => { 2 => 'Camera' }, … … 1068 1568 }, 1069 1569 }, 1070 0x9211 => 'ImageNumber', 1570 0x9211 => 'ImageNumber', #12 1071 1571 0x9212 => { #12 1072 1572 Name => 'SecurityClassification', … … 1079 1579 }, 1080 1580 }, 1081 0x9213 => 'ImageHistory', 1581 0x9213 => 'ImageHistory', #12 1082 1582 0x9214 => { 1083 Name => 'Subject Location',1583 Name => 'SubjectArea', 1084 1584 Groups => { 2 => 'Camera' }, 1085 1585 }, 1086 0x9215 => 'ExposureIndex', 1087 0x9216 => 'TIFF-EPStandardID', 1088 0x9217 => { 1586 0x9215 => 'ExposureIndex', #12 1587 0x9216 => 'TIFF-EPStandardID', #12 1588 0x9217 => { #12 1089 1589 Name => 'SensingMethod', 1090 1590 Groups => { 2 => 'Camera' }, 1591 Notes => 'values 1 and 6 are not standard EXIF', 1091 1592 PrintConv => { 1092 1 => 'Monochrome area', #12 1593 1 => 'Monochrome area', #12 (not standard EXIF) 1093 1594 2 => 'One-chip color area', 1094 1595 3 => 'Two-chip color area', 1095 1596 4 => 'Three-chip color area', 1096 1597 5 => 'Color sequential area', 1097 6 => 'Monochrome linear', #12 1598 6 => 'Monochrome linear', #12 (not standard EXIF) 1098 1599 7 => 'Trilinear', 1099 1600 8 => 'Color sequential linear', … … 1101 1602 }, 1102 1603 0x9213 => 'ImageHistory', 1604 0x923a => 'CIP3DataFile', #20 1605 0x923b => 'CIP3Sheet', #20 1606 0x923c => 'CIP3Side', #20 1103 1607 0x923f => 'StoNits', #9 1104 1608 # handle maker notes as a conditional list … … 1106 1610 0x9286 => { 1107 1611 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)', 1109 1615 }, 1110 1616 0x9290 => { 1111 1617 Name => 'SubSecTime', 1112 1618 Groups => { 2 => 'Time' }, 1619 ValueConv => '$val=~s/ +$//; $val', # trim trailing blanks 1113 1620 }, 1114 1621 0x9291 => { 1115 1622 Name => 'SubSecTimeOriginal', 1116 1623 Groups => { 2 => 'Time' }, 1624 ValueConv => '$val=~s/ +$//; $val', # trim trailing blanks 1117 1625 }, 1118 1626 0x9292 => { 1119 1627 Name => 'SubSecTimeDigitized', 1120 1628 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 1123 1646 Name => 'ImageSourceData', 1124 1647 Binary => 1, … … 1127 1650 Name => 'XPTitle', 1128 1651 Format => 'undef', 1129 ValueConv => '$self-> Unicode2Charset($val,"II")',1652 ValueConv => '$self->Decode($val,"UCS2","II")', 1130 1653 }, 1131 1654 0x9c9c => { 1132 1655 Name => 'XPComment', 1133 1656 Format => 'undef', 1134 ValueConv => '$self-> Unicode2Charset($val,"II")',1657 ValueConv => '$self->Decode($val,"UCS2","II")', 1135 1658 }, 1136 1659 0x9c9d => { … … 1138 1661 Groups => { 2 => 'Author' }, 1139 1662 Format => 'undef', 1140 ValueConv => '$self-> Unicode2Charset($val,"II")',1663 ValueConv => '$self->Decode($val,"UCS2","II")', 1141 1664 }, 1142 1665 0x9c9e => { 1143 1666 Name => 'XPKeywords', 1144 1667 Format => 'undef', 1145 ValueConv => '$self-> Unicode2Charset($val,"II")',1668 ValueConv => '$self->Decode($val,"UCS2","II")', 1146 1669 }, 1147 1670 0x9c9f => { 1148 1671 Name => 'XPSubject', 1149 1672 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 }, 1153 1679 0xa001 => { 1154 1680 Name => 'ColorSpace', 1155 1681 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, 1159 1687 PrintConv => { 1160 1688 1 => 'sRGB', 1161 1689 2 => 'Adobe RGB', 1162 1690 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 }, 1167 1705 0xa004 => 'RelatedSoundFile', 1168 1706 0xa005 => { … … 1190 1728 Name => 'FocalPlaneResolutionUnit', 1191 1729 Groups => { 2 => 'Camera' }, 1730 Notes => 'values 1, 4 and 5 are not standard EXIF', 1192 1731 PrintConv => { 1193 1732 1 => 'None', # (not standard EXIF) … … 1254 1793 1 => 'Manual', 1255 1794 2 => 'Auto bracket', 1795 # have seen 3 for Samsung EX1 images - PH 1256 1796 }, 1257 1797 }, … … 1274 1814 0xa405 => { 1275 1815 Name => 'FocalLengthIn35mmFormat', 1816 Notes => 'called FocalLengthIn35mmFilm by the EXIF spec.', 1276 1817 Groups => { 2 => 'Camera' }, 1277 PrintConv => '"$ {val}mm"',1818 PrintConv => '"$val mm"', 1278 1819 }, 1279 1820 0xa406 => { … … 1328 1869 Name => 'DeviceSettingDescription', 1329 1870 Groups => { 2 => 'Camera' }, 1871 Binary => 1, 1330 1872 }, 1331 1873 0xa40c => { … … 1333 1875 Groups => { 2 => 'Camera' }, 1334 1876 PrintConv => { 1877 0 => 'Unknown', 1335 1878 1 => 'Macro', 1336 1879 2 => 'Close', … … 1338 1881 }, 1339 1882 }, 1883 # 0xa40d - int16u: 0 (GE E1486 TW) 1884 # 0xa40e - int16u: 1 (GE E1486 TW) 1340 1885 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 1341 1906 0xa480 => 'GDALMetadata', #3 1342 1907 0xa481 => 'GDALNoData', #3 1343 1908 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) 1344 1915 # 1345 # Windows Media Photo WDPtags1916 # Windows Media Photo / HD Photo (WDP/HDP) tags 1346 1917 # 1347 1918 0xbc01 => { #13 … … 1350 1921 Format => 'undef', 1351 1922 Notes => q{ 1352 tags 0xbc** are used in Windows Media Photo WDPimages. The actual1923 tags 0xbc** are used in Windows HD Photo (HDP and WDP) images. The actual 1353 1924 PixelFormat values are 16-byte GUID's but the leading 15 bytes, 1354 1925 '6fddc324-4e03-4bfe-b1853-d77768dc9', have been removed below to avoid … … 1421 1992 }, 1422 1993 }, 1423 0xbc04 => { #131424 Name => 'ImageType',1425 PrintConv => { BITMASK => {1426 0 => 'Preview',1427 1 => 'Page',1428 } },1429 },1430 1994 0xbc02 => { #13 1431 Name => 'Transfo mation',1995 Name => 'Transformation', 1432 1996 PrintConv => { 1433 1997 0 => 'Horizontal (normal)', … … 1445 2009 PrintConv => { 0 => 'No', 1 => 'Yes' }, 1446 2010 }, 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 1447 2022 0xbcc0 => { #13 1448 2023 Name => 'ImageOffset', … … 1481 2056 }, 1482 2057 }, 1483 0xbc80 => 'ImageWidth', #131484 0xbc81 => 'ImageHeight', #131485 0xbc82 => 'WidthResolution', #131486 0xbc83 => 'HeightResolution', #131487 2058 # 1488 2059 0xc427 => 'OceScanjobDesc', #3 … … 1490 2061 0xc429 => 'OceIDNumber', #3 1491 2062 0xc42a => 'OceImageLogic', #3 1492 0xc44f => 'Annotations', #72063 0xc44f => { Name => 'Annotations', Binary => 1 }, #7/19 1493 2064 0xc4a5 => { 1494 Name => 'PrintIM', 2065 Name => 'PrintIM', # (writable directory!) 1495 2066 # must set Writable here so this tag will be saved with MakerNotes option 1496 2067 Writable => 'undef', 2068 WriteGroup => 'IFD0', 1497 2069 Description => 'Print Image Matching', 1498 2070 SubDirectory => { … … 1500 2072 }, 1501 2073 }, 2074 0xc580 => { #20 2075 Name => 'USPTOOriginalContentType', 2076 PrintConv => { 2077 0 => 'Text or Drawing', 2078 1 => 'Grayscale', 2079 2 => 'Color', 2080 }, 2081 }, 1502 2082 # 1503 # DNG tags 0xc6XX (ref 2 unless otherwise stated)2083 # DNG tags 0xc6XX and 0xc7XX (ref 2 unless otherwise stated) 1504 2084 # 1505 2085 0xc612 => { 1506 2086 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', 1508 2091 }, 1509 2092 0xc613 => 'DNGBackwardVersion', … … 1512 2095 Name => 'LocalizedCameraModel', 1513 2096 Format => 'string', 1514 PrintConv => '$self->Printable($val )',2097 PrintConv => '$self->Printable($val, 0)', 1515 2098 }, 1516 2099 0xc616 => { … … 1530 2113 4 => 'Even rows offset right 1/2 column', 1531 2114 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 }, 1538 2123 0xc619 => 'BlackLevelRepeatDim', 1539 2124 0xc61a => 'BlackLevel', … … 1565 2150 Name => 'DNGLensInfo', 1566 2151 Groups => { 2 => 'Camera' }, 1567 PrintConv => '$_=$val;s/(\S+) (\S+) (\S+) (\S+)/$1-$2mm f\/$3-$4/;$_',2152 PrintConv =>\&PrintLensInfo, 1568 2153 }, 1569 2154 0xc631 => 'ChromaBlurRadius', … … 1572 2157 0xc634 => [ 1573 2158 { 1574 Condition => '$ self->{TIFF_TYPE} eq "SR2"',2159 Condition => '$$self{TIFF_TYPE} =~ /^(ARW|SR2)$/', 1575 2160 Name => 'SR2Private', 1576 2161 Groups => { 1 => 'SR2' }, 1577 2162 Flags => 'SubIFD', 1578 2163 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) 1579 2168 SubDirectory => { 1580 2169 DirName => 'SR2Private', … … 1586 2175 Condition => '$$valPt =~ /^Adobe\0/', 1587 2176 Name => 'DNGAdobeData', 1588 DNGMakerNotes=> 1,2177 NestedHtmlDump => 1, 1589 2178 SubDirectory => { TagTable => 'Image::ExifTool::DNG::AdobeData' }, 1590 2179 Format => 'undef', # written incorrectly as int8u (change to undef for speed) 1591 2180 }, 1592 2181 { 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 1596 2190 SubDirectory => { 1597 2191 TagTable => 'Image::ExifTool::Pentax::Main', … … 1615 2209 }, 1616 2210 }, 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 }, 1617 2219 0xc65a => { 1618 2220 Name => 'CalibrationIlluminant1', 2221 SeparateTable => 'LightSource', 1619 2222 PrintConv => \%lightSource, 1620 2223 }, 1621 2224 0xc65b => { 1622 2225 Name => 'CalibrationIlluminant2', 2226 SeparateTable => 'LightSource', 1623 2227 PrintConv => \%lightSource, 1624 2228 }, … … 1631 2235 0xc660 => { #3 1632 2236 Name => 'AliasLayerMetadata', 1633 Notes => 'used by Alias Sketchbook Pro , not a DNG tag',2237 Notes => 'used by Alias Sketchbook Pro', 1634 2238 }, 1635 2239 0xc68b => { … … 1638 2242 }, 1639 2243 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' ], 1641 2248 SubDirectory => { 1642 2249 TagTable => 'Image::ExifTool::DNG::OriginalRaw', … … 1665 2272 }, 1666 2273 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 }, 1670 2402 0xea1d => { 1671 2403 Name => 'OffsetSchema', 1672 2404 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. 1673 2429 }, 1674 2430 … … 1678 2434 # of tags, all tags with values above 0xf000 are handled specially 1679 2435 # 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 }, 1680 2448 ); 1681 2449 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) 1685 2451 %Image::ExifTool::Exif::Composite = ( 1686 2452 GROUPS => { 2 => 'Image' }, … … 1690 2456 1 => 'ImageHeight', 1691 2457 }, 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 }, 1693 2468 }, 1694 2469 # pick the best shutter speed value … … 1721 2496 PrintConv => 'sprintf("%.1f",$val)', 1722 2497 }, 1723 FocalLength35efl => { 2498 FocalLength35efl => { #26/PH 1724 2499 Description => 'Focal Length', 1725 2500 Notes => 'this value may be incorrect if the image has been resized', … … 1731 2506 1 => 'ScaleFactor35efl', 1732 2507 }, 1733 ValueConv => ' $val[0] * ($val[1] ? $val[1] :1)',1734 PrintConv => '$val[1] ? sprintf("%.1f mm (35mm equivalent: %.1fmm)", $val[0], $val) : sprintf("%.1fmm", $val)',1735 }, 1736 ScaleFactor35efl => { 1737 Description => 'Scale Factor To 35 mm 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', 1738 2513 Notes => 'this value and any derived values may be incorrect if image has been resized', 1739 2514 Groups => { 2 => 'Camera' }, … … 1748 2523 7 => 'FocalPlaneXResolution', 1749 2524 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', 1754 2529 13 => 'ImageWidth', 1755 2530 14 => 'ImageHeight', … … 1777 2552 }, 1778 2553 ValueConv => q{ 1779 return undef unless $val[1] and $val[2]; 2554 ToFloat(@val); 2555 return 'inf' unless $val[1] and $val[2]; 1780 2556 return $val[0] * $val[0] / ($val[1] * $val[2] * 1000); 1781 2557 }, … … 1783 2559 }, 1784 2560 DOF => { 1785 Description => 'Depth of Field',2561 Description => 'Depth Of Field', 1786 2562 Notes => 'this value may be incorrect if the image has been resized', 1787 2563 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', 1792 2572 }, 1793 2573 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)); 1799 2585 $v[1] < 0 and $v[1] = 0; # 0 means 'inf' 1800 2586 return join(' ',@v); … … 1807 2593 }, 1808 2594 }, 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 }, 1812 2601 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 1820 2633 DateTimeOriginal => { 1821 Condition => 'not defined ($oldVal)',2634 Condition => 'not defined $$self{VALUE}{DateTimeOriginal}', 1822 2635 Description => 'Date/Time Original', 1823 2636 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)', 1827 2648 }, 1828 2649 ThumbnailImage => { … … 1844 2665 Writable => 1, 1845 2666 WriteCheck => '$self->CheckImage(\$val)', 2667 DelCheck => '$val = ""; return undef', # can't delete, so set to empty string 1846 2668 WriteAlso => { 1847 2669 PreviewImageStart => 'defined $val ? 0xfeedfeed : undef', … … 1855 2677 Desire => { 1856 2678 2 => 'PreviewImageValid', 1857 # (DNG may be have 2 preview images)2679 # (DNG and A100 ARW may be have 2 preview images) 1858 2680 3 => 'PreviewImageStart (1)', 1859 2681 4 => 'PreviewImageLength (1)', 1860 2682 }, 2683 # note: extract 2nd preview, but ignore double-referenced preview 2684 # (in A100 ARW images, the 2nd PreviewImageLength from IFD0 may be wrong anyway) 1861 2685 RawConv => q{ 1862 if ($val[3] and $val[4] ) {2686 if ($val[3] and $val[4] and $val[0] ne $val[3]) { 1863 2687 my %val = ( 1864 2688 0 => 'PreviewImageStart (1)', … … 1902 2726 SubSecDateTimeOriginal => { 1903 2727 Description => 'Date/Time Original', 2728 Groups => { 2 => 'Time' }, 1904 2729 Require => { 1905 0 => ' DateTimeOriginal',2730 0 => 'EXIF:DateTimeOriginal', 1906 2731 1 => 'SubSecTimeOriginal', 1907 2732 }, 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 }, 1910 2764 PrintConv => '$self->ConvertDateTime($val)', 1911 2765 }, … … 1919 2773 my @a = split / /, $val[0]; 1920 2774 my @b = split / /, $val[1]; 1921 return undefunless @a==2 and @b==$a[0]*$a[1];2775 return '?' unless @a==2 and @b==$a[0]*$a[1]; 1922 2776 return Set16u($a[0]) . Set16u($a[1]) . pack('C*', @b); 1923 2777 }, … … 1932 2786 3 => 'WB_GRBGLevels', 1933 2787 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', 1937 2793 }, 1938 2794 ValueConv => 'Image::ExifTool::Exif::RedBlueBalance(0,@val)', … … 1947 2803 3 => 'WB_GRBGLevels', 1948 2804 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', 1952 2810 }, 1953 2811 ValueConv => 'Image::ExifTool::Exif::RedBlueBalance(1,@val)', … … 1955 2813 }, 1956 2814 GPSPosition => { 2815 Groups => { 2 => 'Location' }, 1957 2816 Require => { 1958 2817 0 => 'GPSLatitude', … … 1961 2820 ValueConv => '"$val[0] $val[1]"', 1962 2821 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)', 1963 2849 }, 1964 2850 ); … … 1983 2869 1984 2870 #------------------------------------------------------------------------------ 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 2874 sub 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 #------------------------------------------------------------------------------ 1985 2886 # Calculate LV (Light Value) 1986 2887 # Inputs: 0) Aperture, 1) ShutterSpeed, 2) ISO 1987 # Returns: LV value 2888 # Returns: LV value (and converts input values to floating point if necessary) 1988 2889 sub CalculateLV($$$) 1989 2890 { … … 1992 2893 return undef unless @_ >= 3; 1993 2894 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 1995 2897 } 1996 2898 # (A light value of 0 is defined as f/1.0 at 1 second with ISO 100) … … 1999 2901 2000 2902 #------------------------------------------------------------------------------ 2001 # Calculate scale factor for 35mm effective focal length 2903 # Calculate scale factor for 35mm effective focal length (ref 26/PH) 2002 2904 # Inputs: 0) Focal length 2003 2905 # 1) Focal length in 35mm format … … 2011 2913 sub CalcScaleFactor35efl 2012 2914 { 2915 my $res = $_[6]; # save resolution units (in case they have been converted to string) 2916 Image::ExifTool::ToFloat(@_); 2013 2917 my $focal = shift; 2014 2918 my $foc35 = shift; … … 2019 2923 my $diag = shift; 2020 2924 unless ($diag and Image::ExifTool::IsFloat($diag)) { 2925 undef $diag; 2021 2926 my $xsize = shift; 2022 2927 my $ysize = shift; 2023 2928 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) { 2026 2936 # 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; 2028 2939 my $x_res = shift || return undef; 2029 2940 my $y_res = shift || return undef; … … 2051 2962 2052 2963 #------------------------------------------------------------------------------ 2053 # Convert exposure compensation fraction2054 sub ConvertFraction($)2964 # Print exposure compensation fraction 2965 sub PrintFraction($) 2055 2966 { 2056 2967 my $val = shift; … … 2067 2978 $str = sprintf("%+d/3", int($val * 3)); 2068 2979 } else { 2069 $str = sprintf("% .3g", $val);2980 $str = sprintf("%+.3g", $val); 2070 2981 } 2071 2982 } … … 2074 2985 2075 2986 #------------------------------------------------------------------------------ 2987 # Convert fraction or number to floating point value (or 'undef' or 'inf') 2988 sub 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 #------------------------------------------------------------------------------ 2076 2998 # Convert EXIF text to something readable 2077 2999 # Inputs: 0) ExifTool object reference, 1) EXIF text 2078 # Returns: UTF8 or Latin text3000 # Returns: text encoded according to Charset option (with trailing spaces removed) 2079 3001 sub ConvertExifText($$) 2080 3002 { … … 2083 3005 my $id = substr($val, 0, 8); 2084 3006 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 ]$/) { 2090 3018 # MicrosoftPhoto writes as little-endian even in big-endian EXIF, 2091 3019 # 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'); 2101 3023 } else { 2102 # assume everything else is ASCII (Don't convert JIS... yet)2103 $str = ~ s/\0.*//s; # truncate at null terminator3024 $exifTool->Warn("Invalid EXIF text encoding"); 3025 $str = $id . $str; 2104 3026 } 3027 $str =~ s/ +$//; # trim trailing blanks 2105 3028 return $str; 2106 3029 } … … 2130 3053 #------------------------------------------------------------------------------ 2131 3054 # 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 3056 sub PrintParameter($$$) 2133 3057 { 2134 my $val = shift; 3058 my ($val, $inv, $conv) = @_; 3059 return $val if $inv; 2135 3060 if ($val > 0) { 2136 3061 if ($val > 0xfff0) { # a negative value in disguise? … … 2139 3064 $val = "+$val"; 2140 3065 } 2141 } elsif ($val == 0) {2142 $val = 'Normal';2143 3066 } 2144 3067 return $val; … … 2147 3070 #------------------------------------------------------------------------------ 2148 3071 # Convert parameter back to standard EXIF value 2149 # 0 or "Normal" => 03072 # 0,0.00,etc or "Normal" => 0 2150 3073 # -1,-2,etc or "Soft" or "Low" => 1 2151 3074 # +1,+2,1,2,etc or "Hard" or "High" => 2 … … 2153 3076 { 2154 3077 my $val = shift; 3078 my $isFloat = Image::ExifTool::IsFloat($val); 2155 3079 # 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); 2157 3081 # "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 va ilof 22160 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; 2161 3085 return undef; 2162 3086 } … … 2164 3088 #------------------------------------------------------------------------------ 2165 3089 # 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 level3090 # 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 2168 3092 my @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) 2175 3102 ); 2176 3103 sub RedBlueBalance($@) … … 2185 3112 my $g = $$lookup[1]; # get green level or index 2186 3113 if ($g < 4) { 2187 next if @levels < 4;3114 next if @levels < 3; 2188 3115 $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) 2189 3118 } 2190 3119 $val = $levels[$$lookup[$blue * 3]] / $g; … … 2237 3166 2238 3167 #------------------------------------------------------------------------------ 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" 3171 sub 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 3194 sub 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 3217 sub 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 #------------------------------------------------------------------------------ 2239 3301 # translate date into standard EXIF format 2240 3302 # Inputs: 0) date … … 2282 3344 my $image; 2283 3345 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'; 2285 3348 2286 3349 # take data from EXIF block if possible … … 2290 3353 $image = $exifTool->ExtractBinary($offset, $len, $tag); 2291 3354 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 } 2292 3367 } 2293 3368 return $exifTool->ValidateImage(\$image, $tag); … … 2315 3390 my $htmlDump = $exifTool->{HTML_DUMP}; 2316 3391 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 } 2319 3406 $verbose = -1 if $htmlDump; # mix htmlDump into verbose so we can test for both at once 2320 3407 $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/; 2323 3412 2324 3413 my ($numEntries, $dirEnd); … … 2356 3445 $dataLen = $$dirInfo{DataLen} = length $buff; 2357 3446 $dirStart = $$dirInfo{DirStart} = 0; 3447 $dirLen = $$dirInfo{DirLen} = length $buff; 2358 3448 $success = 1; 2359 3449 } … … 2361 3451 } 2362 3452 unless ($success) { 2363 $exifTool->Warn("Bad $ dirName directory");3453 $exifTool->Warn("Bad $name directory"); 2364 3454 return 0; 2365 3455 } … … 2372 3462 if ($bytesFromEnd < 4) { 2373 3463 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); 2375 3465 return 0; 2376 3466 } … … 2386 3476 } 2387 3477 if ($htmlDump) { 3478 my $longName = $name eq 'MakerNotes' ? ($$dirInfo{Name} || $name) : $name; 2388 3479 if (defined $makerAddr) { 2389 3480 my $hdrLen = $dirStart + $dataPos + $base - $makerAddr; 2390 $exifTool->H tmlDump($makerAddr, $hdrLen, "MakerNotes header", $name) if $hdrLen > 0;3481 $exifTool->HDump($makerAddr, $hdrLen, "MakerNotes header", $longName) if $hdrLen > 0; 2391 3482 } 2392 $exifTool->H tmlDump($dirStart + $dataPos + $base, 2, "$name entries",3483 $exifTool->HDump($dirStart + $dataPos + $base, 2, "$longName entries", 2393 3484 "Entry count: $numEntries"); 2394 3485 my $tip; 2395 3486 if ($bytesFromEnd >= 4) { 2396 my $nxt = ($name =~ /^ IFD(\d+)/) ? "IFD" . ($1+ 1) : 'Next IFD';3487 my $nxt = ($name =~ /^(.*?)(\d+)$/) ? $1 . ($2 + 1) : 'Next IFD'; 2397 3488 $tip = sprintf("$nxt offset: 0x%.4x", Get32u($dataPt, $dirEnd)); 2398 3489 } 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); 2401 3491 } 2402 3492 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 2403 3507 # loop through all entries in an EXIF directory (IFD) 2404 my ($index, $valEnd); 3508 my ($index, $valEnd, $offList, $offHash); 3509 my $warnCount = 0; 2405 3510 for ($index=0; $index<$numEntries; ++$index) { 3511 if ($warnCount > 10) { 3512 $exifTool->Warn("Too many warnings -- $name parsing aborted", 1) and return 0; 3513 } 2406 3514 my $entry = $dirStart + 2 + 12 * $index; 2407 3515 my $tagID = Get16u($dataPt, $entry); … … 2409 3517 my $count = Get32u($dataPt, $entry+4); 2410 3518 if ($format < 1 or $format > 13) { 2411 $exifTool->H tmlDump($entry+$dataPos+$base,12,"[invalid IFD entry]",3519 $exifTool->HDump($entry+$dataPos+$base,12,"[invalid IFD entry]", 2412 3520 "Bad format type: $format", 1); 2413 3521 # 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 } 2416 3526 return 0 unless $index; # assume corrupted IFD if this is our first entry 2417 3527 next; 2418 3528 } 2419 3529 my $formatStr = $formatName[$format]; # get name of this format 2420 my $size = $count * $formatSize[$format];2421 3530 my $valueDataPt = $dataPt; 2422 3531 my $valueDataPos = $dataPos; … … 2424 3533 my $valuePtr = $entry + 8; # pointer to value within $$dataPt 2425 3534 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; 2426 3549 if ($size > 4) { 2427 3550 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; 2429 3553 next; 2430 3554 } … … 2434 3558 my $wFlag; 2435 3559 $valEnd or $valEnd = $dataPos + $dirEnd + 4; 2436 #### eval FixOffsets ($valuePtr, $valEnd, $size, $tagID, $wFlag)3560 #### eval FixOffsets ($valuePtr, $valEnd, $size, $tagID, $wFlag) 2437 3561 eval $$dirInfo{FixOffsets}; 2438 3562 } 3563 my $suspect; 3564 # offset shouldn't point into TIFF header 3565 $valuePtr < 8 and $suspect = $warnCount; 2439 3566 # convert offset to pointer in $$dataPt 2440 3567 if ($$dirInfo{EntryBased} or (ref $$tagTablePtr{$tagID} eq 'HASH' and 2441 $tagTablePtr->{$tagID} ->{EntryBased}))3568 $tagTablePtr->{$tagID}{EntryBased})) 2442 3569 { 2443 3570 $valuePtr += $entry; … … 2445 3572 $valuePtr -= $dataPos; 2446 3573 } 3574 # value shouldn't overlap our directory 3575 $suspect = $warnCount if $valuePtr < $dirEnd and $valuePtr+$size > $dirStart; 3576 # load value from file if necessary 2447 3577 if ($valuePtr < 0 or $valuePtr+$size > $dataLen) { 2448 3578 # get value by seeking in file if we are allowed 2449 3579 my $buff; 2450 3580 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)) 2453 3610 { 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; 2461 3616 } 3617 $valueDataPt = \$buff; 3618 $valueDataPos = $valuePtr + $dataPos; 3619 $valueDataLen = length $buff; 3620 $valuePtr = 0; 2462 3621 } else { 2463 my $tagStr;3622 my ($tagStr, $tmpInfo); 2464 3623 if ($tagInfo) { 2465 3624 $tagStr = $$tagInfo{Name}; 2466 3625 } elsif (defined $tagInfo) { 2467 my$tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \ '', $formatStr, $count);3626 $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \ '', $formatStr, $count); 2468 3627 $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; 2469 3634 } 2470 3635 $tagStr or $tagStr = sprintf("tag 0x%x",$tagID); … … 2478 3643 $valueDataLen = $size; 2479 3644 $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 } 2480 3658 } else { 2481 $exifTool->Warn("Bad $dirName directory pointer for $tagStr"); 3659 $exifTool->Warn("Bad $name offset for $tagStr"); 3660 ++$warnCount; 2482 3661 } 2483 3662 unless (defined $buff) { … … 2490 3669 } 2491 3670 } 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 } 2492 3679 } 2493 3680 # treat single unknown byte as int8u 2494 3681 $formatStr = 'int8u' if $format == 7 and $count == 1; 2495 3682 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 } 2514 3704 } 2515 3705 } … … 2517 3707 if (defined $tagInfo and not $tagInfo) { 2518 3708 # 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); 2521 3713 } 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 } 2524 3719 if (defined $tagInfo) { 3720 $subdir = $$tagInfo{SubDirectory}; 3721 # override EXIF format if specified 2525 3722 if ($$tagInfo{Format}) { 2526 3723 $formatStr = $$tagInfo{Format}; 2527 # must adjust number of items for new format size2528 3724 my $newNum = $formatNumber{$formatStr}; 2529 if ($newNum ) {3725 if ($newNum and $newNum != $format) { 2530 3726 $origFormStr = $formatName[$format] . '[' . $count . ']'; 2531 3727 $format = $newNum; 2532 $count = $size / $formatSize[$format]; 3728 # adjust number of items for new format size 3729 $count = int($size / $formatSize[$format]); 2533 3730 } 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; 2534 3737 } 2535 3738 } else { … … 2537 3740 } 2538 3741 # convert according to specified format 2539 $val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$ size);3742 $val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$readSize); 2540 3743 2541 3744 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 } 2542 3752 if ($htmlDump) { 2543 3753 my ($tagName, $colName); … … 2552 3762 # build our tool tip 2553 3763 $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"; 2556 3769 if ($size > 4) { 2557 3770 my $offPt = Get32u($dataPt,$entry+8); 2558 $tip .= sprintf("Value offset: 0x%.4x\\n", $offPt);2559 3771 my $actPt = $valuePtr + $valueDataPos + $base - ($$exifTool{EXIF_POS} || 0); 3772 $tip .= sprintf("Value offset: 0x%.4x\n", $offPt); 2560 3773 # 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'; 2562 3775 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)); 2564 3779 $style = 'F' if $style eq 'H'; # purple for different offsets 2565 3780 } 2566 3781 $colName = "<span class=$style>$tagName</span>"; 3782 $colName .= ' <span class=V>(odd)</span>' if $offPt & 0x01; 2567 3783 } else { 2568 3784 $colName = $tagName; 2569 3785 } 2570 my $tval;2571 if ($valueDataLen < 0 ) {3786 $colName .= ' <span class=V>(err)</span>' if $wrongFormat; 3787 if ($valueDataLen < 0 or not defined $tval) { 2572 3788 $tval = '<bad offset>'; 2573 3789 } else { 2574 $tval = (length $val < 32) ? $val : substr($val,0,28) . '[...]';3790 $tval = substr($tval,0,28) . '[...]' if length($tval) > 32; 2575 3791 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/./; 2580 3794 } elsif ($tagInfo and Image::ExifTool::IsInt($tval)) { 2581 if ($$tagInfo{IsOffset} ) {3795 if ($$tagInfo{IsOffset} or $$tagInfo{SubIFD}) { 2582 3796 $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 } 2583 3803 } elsif ($$tagInfo{PrintHex}) { 2584 3804 $tval = sprintf('0x%x', $tval); … … 2587 3807 } 2588 3808 $tip .= "Value: $tval"; 2589 $exifTool->H tmlDump($entry+$dataPos+$base, 12, "$dname $colName", $tip, 1);3809 $exifTool->HDump($entry+$dataPos+$base, 12, "$dname $colName", $tip, 1); 2590 3810 next if $valueDataLen < 0; # don't process bad pointer entry 2591 3811 if ($size > 4) { 2592 3812 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 } 2593 3821 # 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); 2597 3823 } 2598 3824 } else { 2599 3825 my $fstr = $formatName[$format]; 2600 $ origFormStr and $fstr = "$origFormStr read as $fstr";3826 $fstr = "$origFormStr read as $fstr" if $origFormStr; 2601 3827 $exifTool->VerboseInfo($tagID, $tagInfo, 2602 3828 Table => $tagTablePtr, 2603 3829 Index => $index, 2604 Value => $ val,3830 Value => $tval, 2605 3831 DataPt => $valueDataPt, 2606 3832 DataPos => $valueDataPos + $base, … … 2611 3837 ); 2612 3838 } 2613 next unless $tagInfo;3839 next if not $tagInfo or $wrongFormat; 2614 3840 } 3841 next unless defined $val; 2615 3842 #.............................................................................. 2616 3843 # Handle SubDirectory tag types 2617 3844 # 2618 my $subdir = $$tagInfo{SubDirectory};2619 3845 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 } 2620 3853 my (@values, $newTagTable, $dirNum, $newByteOrder, $invalid); 2621 3854 my $tagStr = $$tagInfo{Name}; … … 2691 3924 # calculate subdirectory start relative to $base for eval 2692 3925 my $start = $subdirStart + $subdirDataPos; 2693 #### eval Base ($start )3926 #### eval Base ($start,$base) 2694 3927 $subdirBase = eval($$subdir{Base}) + $base; 2695 3928 } … … 2701 3934 $exifTool->Warn("Bad $tagStr OffsetPt"); 2702 3935 last; 2703 } 3936 } 2704 3937 SetByteOrder($newByteOrder); 2705 3938 $subdirStart += Get32u($subdirDataPt, $pos); … … 2708 3941 if ($subdirStart < 0 or $subdirStart + 2 > $subdirDataLen) { 2709 3942 # convert $subdirStart back to a file offset 2710 $subdirStart += $subdirDataPos;2711 my $dirOK;2712 3943 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 { 2734 3949 my $msg = "Bad $tagStr SubDirectory start"; 2735 3950 if ($verbose > 0) { … … 2760 3975 RAF => $raf, 2761 3976 Parent => $dirName, 3977 DirName => $$subdir{DirName}, 2762 3978 FixBase => $$subdir{FixBase}, 2763 3979 FixOffsets => $$subdir{FixOffsets}, … … 2765 3981 TagInfo => $tagInfo, 2766 3982 SubIFD => $$tagInfo{SubIFD}, 3983 Subdir => $subdir, 2767 3984 ); 3985 # (remember: some cameras incorrectly write maker notes in IFD0) 2768 3986 if ($$tagInfo{MakerNotes}) { 3987 # don't parse makernotes if FastScan > 1 3988 my $fast = $exifTool->Options('FastScan'); 3989 last if $fast and $fast > 1; 2769 3990 $subdirInfo{MakerNoteAddr} = $valuePtr + $valueDataPos + $base; 2770 $subdirInfo{NoFixBase} = 1 if $$subdir{Base};3991 $subdirInfo{NoFixBase} = 1 if defined $$subdir{Base}; 2771 3992 } 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}; 2776 3998 # number multiple subdirectories 2777 $ dirNum and $subdirInfo{DirName} .=$dirNum;3999 $subdirInfo{DirName} =~ s/\d*$/$dirNum/ if $dirNum; 2778 4000 } 2779 4001 SetByteOrder($newByteOrder); # set byte order for this subdir … … 2800 4022 } 2801 4023 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}; 2803 4026 # extract as a block if specified 2804 4027 if ($$tagInfo{MakerNotes}) { 2805 4028 # save maker note byte order (if it was significant and valid) 2806 4029 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}) ? 2809 4032 $exifTool->{UnknownByteOrder} : $newByteOrder; 2810 4033 } … … 2845 4068 #.............................................................................. 2846 4069 # 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}) { 2848 4072 my $offsetBase = $$tagInfo{IsOffset} eq '2' ? $firstBase : $base; 2849 4073 $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 } 2850 4080 my @vals = split(' ',$val); 2851 4081 foreach $val (@vals) { … … 2856 4086 # save the value of this tag 2857 4087 $tagKey = $exifTool->FoundTag($tagInfo, $val); 2858 # set the group 1 name for tags in main table2859 if (defined $tagKey and $ tagTablePtr eq \%Image::ExifTool::Exif::Main) {2860 $exifTool->SetGroup 1($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); 2861 4091 } 2862 4092 } … … 2873 4103 $newDirInfo{DirStart} = $subdirStart; 2874 4104 # 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; 2877 4107 # must validate SubIFD1 because the nextIFD pointer is invalid for some RAW formats 2878 4108 if ($newDirInfo{DirName} ne 'SubIFD1' or ValidateIFD(\%newDirInfo)) { 2879 4109 $exifTool->{INDENT} =~ s/..$//; # keep indent the same 4110 my $cur = pop @{$$exifTool{PATH}}; 2880 4111 $exifTool->ProcessDirectory(\%newDirInfo, $tagTablePtr) or $success = 0; 4112 push @{$$exifTool{PATH}}, $cur; 2881 4113 } elsif ($verbose or $exifTool->{TIFF_TYPE} eq 'TIFF') { 2882 4114 $exifTool->Warn('Ignored bad IFD linked from SubIFD'); … … 2893 4125 =head1 NAME 2894 4126 2895 Image::ExifTool::Exif - Read EXIF meta information4127 Image::ExifTool::Exif - Read EXIF/TIFF meta information 2896 4128 2897 4129 =head1 SYNOPSIS … … 2902 4134 2903 4135 This module contains routines required by Image::ExifTool for processing 2904 EXIF meta information.4136 EXIF and TIFF meta information. 2905 4137 2906 4138 =head1 AUTHOR 2907 4139 2908 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)4140 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 2909 4141 2910 4142 This library is free software; you can redistribute it and/or modify it … … 2917 4149 =item L<http://www.exif.org/Exif2-2.PDF> 2918 4150 4151 =item L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-008-2010_E.pdf> 4152 2919 4153 =item L<http://partners.adobe.com/asn/developer/pdfs/tn/TIFF6.pdf> 2920 4154 … … 2927 4161 =item L<http://www.remotesensing.org/libtiff/TIFFTechNote2.html> 2928 4162 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 2929 4175 =item L<http://www.asmail.be/msg0054681802.html> 2930 4176 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> 2940 4186 2941 4187 =back … … 2943 4189 =head1 ACKNOWLEDGEMENTS 2944 4190 2945 Thanks to Matt Madrid for his help with the XP character code conversions. 4191 Thanks to Jeremy Brown for the 35efl tags, and Matt Madrid for his help with 4192 the XP character code conversions. 2946 4193 2947 4194 =head1 SEE ALSO -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FLAC.pm
r16842 r24107 15 15 use Image::ExifTool qw(:DataAccess :Utils); 16 16 17 $VERSION = '1.0 0';17 $VERSION = '1.03'; 18 18 19 19 sub ProcessBitStream($$$); … … 32 32 Name => 'VorbisComment', 33 33 SubDirectory => { TagTable => 'Image::ExifTool::Vorbis::Comments' }, 34 }, 35 6 => { 36 Name => 'Picture', 37 SubDirectory => { TagTable => 'Image::ExifTool::FLAC::Picture' }, 34 38 }, 35 39 ); … … 55 59 ); 56 60 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 57 112 # FLAC composite tags 58 113 %Image::ExifTool::FLAC::Composite = ( … … 60 115 Require => { 61 116 0 => 'FLAC:SampleRate', 62 1 => 'FLAC:Channels', 63 2 => 'FLAC:TotalSamples', 117 1 => 'FLAC:TotalSamples', 64 118 }, 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)', 67 121 }, 68 122 ); … … 159 213 160 214 # must first check for leading/trailing ID3 information 161 unless ($exifTool->{D ONE_ID3}) {215 unless ($exifTool->{DoneID3}) { 162 216 require Image::ExifTool::ID3; 163 217 Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1; … … 170 224 # check FLAC signature 171 225 $raf->Read($buff, 4) == 4 and $buff eq 'fLaC' or return 0; 172 $exifTool->SetFileType() unless $exifTool->{VALUE}->{FileType};226 $exifTool->SetFileType(); 173 227 SetByteOrder('MM'); 174 228 my $tagTablePtr = GetTagTable('Image::ExifTool::FLAC::Main'); … … 214 268 =head1 AUTHOR 215 269 216 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)270 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 217 271 218 272 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Fixup.pm
r16842 r24107 322 322 =head1 AUTHOR 323 323 324 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)324 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 325 325 326 326 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Flash.pm
r16842 r24107 6 6 # Revisions: 05/16/2006 - P. Harvey Created 7 7 # 06/07/2007 - PH Added support for FLV (Flash Video) files 8 # 10/23/2008 - PH Added support for XMP in FLV and SWF 8 9 # 9 10 # References: 1) http://www.the-labs.com/MacromediaFlash/SWF-Spec/SWFfileformat.html 10 11 # 2) http://sswf.sourceforge.net/SWFalexref.html 11 12 # 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 12 18 # 13 19 # Notes: I'll add AMF3 support if someone sends me a FLV with AMF3 data … … 21 27 use Image::ExifTool::FLAC; 22 28 23 $VERSION = '1.0 2';29 $VERSION = '1.09'; 24 30 25 31 sub ProcessMeta($$$;$); 32 33 # Meta packets that we process 34 my %processMetaPacket = ( onMetaData => 1, onXMPData => 1 ); 26 35 27 36 # information extracted from SWF header 28 37 %Image::ExifTool::Flash::Main = ( 29 38 GROUPS => { 2 => 'Video' }, 39 VARS => { ALPHA_FIRST => 1 }, 30 40 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. 33 43 }, 34 44 FlashVersion => { }, … … 40 50 Duration => { 41 51 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' }, 43 65 }, 44 66 ); … … 74 96 Name => 'AudioEncoding', 75 97 PrintConv => { 76 0 => ' Uncompressed',98 0 => 'PCM-BE (uncompressed)', # PCM-BE according to ref 4 77 99 1 => 'ADPCM', 78 100 2 => 'MP3', 79 5 => 'Nellymoser 8kHz mono', 101 3 => 'PCM-LE (uncompressed)', #4 102 4 => 'Nellymoser 16kHz Mono', #8 103 5 => 'Nellymoser 8kHz Mono', 80 104 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 81 112 }, 82 113 }, … … 91 122 }, 92 123 'Bit6' => { 93 Name => 'Audio SampleBits',124 Name => 'AudioBitsPerSample', 94 125 ValueConv => '8 * ($val + 1)', 95 126 }, … … 112 143 Name => 'VideoEncoding', 113 144 PrintConv => { 145 1 => 'JPEG', #8 114 146 2 => 'Sorensen H.263', 115 3 => 'Screen video',147 3 => 'Screen Video', 116 148 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) 117 152 }, 118 153 }, … … 132 167 Groups => { 2 => 'Audio' }, 133 168 ValueConv => '$val * 1000', 134 PrintConv => ' int($val + 0.5)',169 PrintConv => 'ConvertBitrate($val)', 135 170 }, 136 171 'audiodelay' => { Name => 'AudioDelay', Groups => { 2 => 'Audio' } }, … … 138 173 'audiosamplesize'=>{ Name => 'AudioSampleSize', Groups => { 2 => 'Audio' } }, 139 174 'audiosize' => { Name => 'AudioSize', Groups => { 2 => 'Audio' } }, 175 'bytelength' => 'ByteLength', # (youtube) 176 'canseekontime' => 'CanSeekOnTime', # (youtube) 140 177 'canSeekToEnd' => 'CanSeekToEnd', 141 178 'creationdate' => { … … 145 182 ValueConv => '$val=~s/\s+$//; $val', # trim trailing whitespace 146 183 }, 184 'createdby' => 'CreatedBy', #7 147 185 'cuePoints' => { 148 186 Name => 'CuePoint', … … 152 190 'duration' => { 153 191 Name => 'Duration', 154 PrintConv => ' sprintf("%.3fs",$val)',192 PrintConv => 'ConvertDuration($val)', 155 193 }, 156 194 'filesize' => 'FileSizeBytes', … … 165 203 'hasVideo' => 'HasVideo', 166 204 'height' => 'ImageHeight', 205 'httphostheader'=> 'HTTPHostHeader', # (youtube) 167 206 'keyframesTimes'=> 'KeyFramesTimes', 168 207 'keyframesFilepositions' => 'KeyFramePositions', … … 175 214 PrintConv => '$self->ConvertDateTime($val)', 176 215 }, 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 }, 177 223 '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', 178 234 'videocodecid' => 'VideoCodecID', 179 235 'videodatarate' => { 180 236 Name => 'VideoBitrate', 181 237 ValueConv => '$val * 1000', 182 PrintConv => ' int($val + 0.5)',238 PrintConv => 'ConvertBitrate($val)', 183 239 }, 184 240 'videosize' => 'VideoSize', 185 241 'width' => 'ImageWidth', 242 # tags in 'onXMPData' packets 243 'liveXML' => { #5 244 Name => 'XMP', 245 SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' }, 246 }, 186 247 ); 187 248 … … 234 295 my $dirLen = $$dirInfo{DirLen} || length($$dataPt); 235 296 my $pos = $$dirInfo{Pos} || 0; 236 my $verbose = $exifTool->Options('Verbose');237 297 my ($type, $val, $rec); 238 298 … … 312 372 # switch to subdirectory table if necessary 313 373 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 } 316 380 } 317 381 # get object value … … 332 396 if (not $$subTablePtr{$tag} and $tag =~ /^\w+$/) { 333 397 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"); 335 399 } 336 400 $exifTool->HandleTag($subTablePtr, $tag, $v, … … 383 447 last if $single; # all done if extracting single value 384 448 unless ($isStruct{$type}) { 385 # only process "onMetaData"Meta packets449 # only process certain Meta packets 386 450 if ($type == 0x02 and not $rec) { 387 my $verb = ($val eq 'onMetaData')? 'processing' : 'ignoring';451 my $verb = $processMetaPacket{$val} ? 'processing' : 'ignoring'; 388 452 $exifTool->VPrint(0, " | ($verb $val information)\n"); 389 last unless $ val eq 'onMetaData';453 last unless $processMetaPacket{$val}; 390 454 } else { 391 455 # give verbose indication if we ignore a lone value … … 477 541 478 542 #------------------------------------------------------------------------------ 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) 549 sub 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 #------------------------------------------------------------------------------ 479 594 # Read information frame a Flash file 480 595 # Inputs: 0) ExifTool object reference, 1) Directory information reference … … 483 598 { 484 599 my ($exifTool, $dirInfo) = @_; 485 my $verbose = $exifTool->Options('Verbose');486 600 my $raf = $$dirInfo{RAF}; 487 my $buff;601 my ($buff, $hasMeta); 488 602 489 603 $raf->Read($buff, 8) == 8 or return 0; … … 491 605 my ($compressed, $vers) = ($1 eq 'C' ? 1 : 0, ord($2)); 492 606 493 # read the first bit of the file 494 $raf->Read($buff, 64) or return 0; 495 607 SetByteOrder('II'); 496 608 $exifTool->SetFileType(); 497 609 GetTagTable('Image::ExifTool::Flash::Main'); # make sure table is initialized … … 500 612 FoundFlashTag($exifTool, Compressed => $compressed); 501 613 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; 528 619 } 620 529 621 # 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) { 538 626 $exifTool->Warn('Truncated Flash file'); 539 627 return 1; … … 555 643 FoundFlashTag($exifTool, Duration => $vals[1] * 256 / $vals[0]) if $vals[0]; 556 644 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 } 557 696 return 1; 558 697 } … … 583 722 =head1 AUTHOR 584 723 585 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)724 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 586 725 587 726 This library is free software; you can redistribute it and/or modify it … … 598 737 =item L<http://osflash.org/flv/> 599 738 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 600 747 =back 601 748 -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FlashPix.pm
r16842 r24107 9 9 # 2) http://www.graphcomp.com/info/specs/livepicture/fpx.pdf 10 10 # 3) http://search.cpan.org/~jdb/libwin32/ 11 # 4) http://msdn 2.microsoft.com/en-us/library/aa380374.aspx11 # 4) http://msdn.microsoft.com/en-us/library/aa380374.aspx 12 12 #------------------------------------------------------------------------------ 13 13 … … 20 20 use Image::ExifTool::ASF; # for GetGUID() 21 21 22 $VERSION = '1. 04';22 $VERSION = '1.19'; 23 23 24 24 sub ProcessFPX($$); 25 25 sub ProcessFPXR($$$); 26 26 sub ProcessProperties($$$); 27 sub ReadFPXValue($$$$$;$); 28 sub ConvertTimeSpan($); 27 sub ReadFPXValue($$$$$;$$); 29 28 sub ProcessHyperlinks($$); 29 sub ProcessContents($$$); 30 sub SetDocNum($$;$$$); 30 31 31 32 # sector type constants … … 115 116 my @dirEntryType = qw(INVALID STORAGE STREAM LOCKBYTES PROPERTY ROOT); 116 117 118 # list of code pages used by Microsoft 119 # (ref http://msdn.microsoft.com/en-us/library/dd317756(VS.85).aspx) 120 my %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) 278 my %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 117 291 %Image::ExifTool::FlashPix::Main = ( 118 292 PROCESS_PROC => \&ProcessFPXR, … … 122 296 Hewlett-Packard and Microsoft. Internally the FPX file structure mimics 123 297 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. 129 302 130 303 ExifTool extracts FlashPix information from both FPX images and the APP2 131 304 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. 134 311 }, 135 312 "\x05SummaryInformation" => { … … 165 342 }, 166 343 }, 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 }, 167 352 "ICC Profile 0001" => { 168 353 Name => 'ICC_Profile', … … 229 414 ValueConv => 'length($val) > 0x1c and $val = substr($val, 0x1c); \$val', 230 415 }, 231 "Current User"=> { #PH416 'Current User' => { #PH 232 417 Name => 'CurrentUser', 233 418 # not sure what the rest of this data is, but extract ASCII name from it - PH … … 245 430 %Image::ExifTool::FlashPix::SummaryInfo = ( 246 431 PROCESS_PROC => \&ProcessProperties, 247 GROUPS => { 2 => ' Image' },432 GROUPS => { 2 => 'Document' }, 248 433 NOTES => q{ 249 434 The Dictionary, CodePage and LocalIndicator tags are common to all FlashPix 250 435 property tables, even though they are only listed in the SummaryInfo table. 251 436 }, 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 }, 254 443 0x02 => 'Title', 255 444 0x03 => 'Subject', 256 0x04 => { Name => 'Author', Groups => { 2 => 'Author' } },445 0x04 => { Name => 'Author', Groups => { 2 => 'Author' } }, 257 446 0x05 => 'Keywords', 258 447 0x06 => 'Comments', 259 448 0x07 => 'Template', 260 0x08 => { Name => 'Last SavedBy',Groups => { 2 => 'Author' } },449 0x08 => { Name => 'LastModifiedBy', Groups => { 2 => 'Author' } }, 261 450 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 }, 272 482 0x80000000 => { Name => 'LocaleIndicator', Groups => { 2 => 'Other' } }, 273 483 ); … … 279 489 NOTES => q{ 280 490 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. 282 492 However, ExifTool will also extract any other information found in the 283 493 UserDefined properties. … … 292 502 0x09 => 'HiddenSlides', 293 503 0x0a => 'MMClips', 294 0x0b => 'ScaleCrop', 504 0x0b => { 505 Name => 'ScaleCrop', 506 PrintConv => { 0 => 'No', 1 => 'Yes' }, 507 }, 295 508 0x0c => 'HeadingPairs', 296 509 0x0d => 'TitleOfParts', 297 510 0x0e => 'Manager', 298 511 0x0f => 'Company', 299 0x10 => 'LinksUpToDate', 512 0x10 => { 513 Name => 'LinksUpToDate', 514 PrintConv => { 0 => 'No', 1 => 'Yes' }, 515 }, 300 516 0x11 => 'CharCountWithSpaces', 301 517 # 0x12 ? 302 0x13 => 'SharedDoc', #PH (unconfirmed) 518 0x13 => { #PH (unconfirmed) 519 Name => 'SharedDoc', 520 PrintConv => { 0 => 'No', 1 => 'Yes' }, 521 }, 303 522 # 0x14 ? 304 523 # 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) 307 529 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 }, 312 536 '_PID_HLINKS' => { 313 537 Name => 'Hyperlinks', … … 364 588 0x23000004 => 'People', 365 589 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 }, 367 596 0x2300000B => 'Events', 368 597 0x2300000C => 'Places', … … 375 604 }, 376 605 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 }, 378 611 0x25000001 => { 379 612 Name => 'ExposureTime', … … 410 643 Name => 'FocalLength', 411 644 Groups => { 2 => 'Camera' }, 412 PrintConv => 'sprintf("%.1f mm",$val)',645 PrintConv => 'sprintf("%.1f mm",$val)', 413 646 }, 414 647 0x2500000A => { … … 520 753 0x28000005 => 'ServiceOrganizationName', 521 754 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 }, 524 765 0x2800000A => 'ScannerPixelSize', 525 766 ); … … 725 966 ); 726 967 968 # MacroMedia flash contents 969 %Image::ExifTool::FlashPix::Contents = ( 970 PROCESS_PROC => \&ProcessProperties, 971 GROUPS => { 2 => 'Image' }, 972 ); 973 727 974 # CompObj tags 728 975 %Image::ExifTool::FlashPix::CompObj = ( … … 731 978 FORMAT => 'int32u', 732 979 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 }, 734 985 ); 735 986 … … 784 1035 785 1036 #------------------------------------------------------------------------------ 786 # Print conversion for time span value787 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 #------------------------------------------------------------------------------805 1037 # Read FlashPix value 806 1038 # 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 UTF81039 # 4) end offset, 5) flag for no padding, 6) code page 808 1040 # Returns: converted value (or list of values in list context) and updates 809 1041 # value offset to end of value if successful, or returns undef on error 810 sub ReadFPXValue($$$$$;$ )1042 sub ReadFPXValue($$$$$;$$) 811 1043 { 812 my ($exifTool, $dataPt, $valPos, $type, $dirEnd, $opts) = @_; 813 $opts = 0 unless defined $opts; 1044 my ($exifTool, $dataPt, $valPos, $type, $dirEnd, $noPad, $codePage) = @_; 814 1045 my @vals; 815 1046 … … 821 1052 if ($flags) { 822 1053 if ($flags == VT_VECTOR) { 823 $ opts |= 0x01;# values don't seem to be padded inside vectors1054 $noPad = 1; # values don't seem to be padded inside vectors 824 1055 my $size = $oleFormatSize{VT_VECTOR}; 825 1056 last if $valPos + $size > $dirEnd; … … 847 1078 my $subType = Get32u($dataPt, $valPos); 848 1079 $valPos += $size; 849 $val = ReadFPXValue($exifTool, $dataPt, $valPos, $subType, $dirEnd, $ opts);1080 $val = ReadFPXValue($exifTool, $dataPt, $valPos, $subType, $dirEnd, $noPad, $codePage); 850 1081 last unless defined $val; 851 1082 push @vals, $val; … … 872 1103 if ($format eq 'VT_LPWSTR') { 873 1104 # 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 } 879 1113 } 880 1114 $val =~ s/\0.*//s; # truncate at null terminator … … 882 1116 # (the spec states that strings should be padded to align 883 1117 # 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; 885 1119 } elsif ($format eq 'VT_BLOB' or $format eq 'VT_CF') { 886 1120 my $len = Get32u($dataPt, $valPos); … … 897 1131 } 898 1132 # 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; 900 1134 last; # didn't really want to loop 901 1135 } … … 909 1143 return $vals[0]; 910 1144 } 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 1153 sub 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; 911 1180 } 912 1181 … … 937 1206 my $dirEnd = $pos + $dirLen; 938 1207 my $verbose = $exifTool->Options('Verbose'); 939 my ($out, $n);1208 my $n; 940 1209 941 1210 if ($dirLen < 48) { … … 956 1225 for ($n=0; $n<2; ++$n) { 957 1226 my %dictionary; # dictionary to translate user-defined properties 958 my $ opts = 0; # option flags for converting values1227 my $codePage; 959 1228 last if $pos + 8 > $dirEnd; 960 1229 # read property section header … … 991 1260 next if $$tagTablePtr{$name}; 992 1261 $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 994 1264 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 }); 996 1267 } 997 1268 next; … … 1003 1274 $custom = 1; 1004 1275 } 1005 my @vals = ReadFPXValue($exifTool, $dataPt, $valPos, $type, $dirEnd, $opts);1276 my @vals = ReadFPXValue($exifTool, $dataPt, $valPos, $type, $dirEnd, undef, $codePage); 1006 1277 @vals or $exifTool->Warn('Error reading property value'); 1007 1278 $val = @vals > 1 ? \@vals : $vals[0]; … … 1017 1288 my $summaryTable = GetTagTable('Image::ExifTool::FlashPix::SummaryInfo'); 1018 1289 $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 1023 1293 } 1024 1294 } elsif ($$tagTablePtr{$tag}) { … … 1036 1306 } 1037 1307 $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, 1043 1313 TagInfo => $tagInfo, 1044 Extra => ", type=$type",1314 Extra => ", type=$type", 1045 1315 ); 1046 1316 } … … 1064 1334 my ($buff, %loadedSect); 1065 1335 for (;;) { 1066 last if $sect == END_OF_CHAIN;1336 last if $sect >= END_OF_CHAIN; 1067 1337 return undef if $loadedSect{$sect}; # avoid infinite loop 1068 1338 $loadedSect{$sect} = 1; 1069 1339 my $offset = $sect * $sectSize + $hdrSize; 1070 return undef unless $offset <= 0x7fffffffand1340 return undef unless ($offset <= 0x7fffffff or $$raf{LargeFileSupport}) and 1071 1341 $raf->Seek($offset, 0) and 1072 1342 $raf->Read($buff, $sectSize) == $sectSize; … … 1126 1396 } 1127 1397 # convert stream pathname to ascii 1128 my $name = Image::ExifTool:: Unicode2Latin($1, 'v');1398 my $name = Image::ExifTool::Decode(undef, $1, 'UCS2', 'II', 'Latin'); 1129 1399 if ($verbose) { 1130 1400 my $psize = ($size == 0xffffffff) ? 'storage' : "$size bytes"; … … 1182 1452 } 1183 1453 } 1184 # concat inate data with this stream1454 # concatenate data with this stream 1185 1455 $$obj{Stream} .= substr($$dataPt, $dirStart+13); 1186 1456 } else { … … 1214 1484 delete $$obj{Stream}; # done with this stream 1215 1485 } 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 } 1216 1496 } 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; 1218 1499 } 1219 1500 … … 1225 1506 1226 1507 # 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 } 1235 1522 } 1236 1523 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 1530 sub 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 } 1237 1553 } 1238 1554 … … 1240 1556 # Extract information from a FlashPix (FPX) file 1241 1557 # Inputs: 0) ExifTool object ref, 1) dirInfo ref 1242 # Returns: 1 on success, 0 if this wasn't a valid FPX image1558 # Returns: 1 on success, 0 if this wasn't a valid FPX-format file 1243 1559 sub ProcessFPX($$) 1244 1560 { … … 1246 1562 my $raf = $$dirInfo{RAF}; 1247 1563 my ($buff, $out, %dumpParms, $oldIndent, $miniStreamBuff); 1564 my ($tag, %hier, %objIndex); 1248 1565 1249 1566 # read header … … 1252 1569 return 0 unless $buff =~ /^\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1/; 1253 1570 1571 # set FileType initially based on file extension (we may override this later) 1254 1572 my $fileType = $exifTool->{FILE_EXT}; 1255 $fileType = 'FPX' unless $fileType and $f ileType =~ /^(DOC|XLS|PPT)$/;1573 $fileType = 'FPX' unless $fileType and $fpxFileType{$fileType}; 1256 1574 $exifTool->SetFileType($fileType); 1257 1575 SetByteOrder(substr($buff, 0x1c, 2) eq "\xff\xfe" ? 'MM' : 'II'); 1258 1576 my $tagTablePtr = GetTagTable('Image::ExifTool::FlashPix::Main'); 1259 1577 my $verbose = $exifTool->Options('Verbose'); 1578 # copy LargeFileSupport option to RAF for use in LoadChain 1579 $$raf{LargeFileSupport} = $exifTool->Options('LargeFileSupport'); 1260 1580 1261 1581 my $sectSize = 1 << Get16u(\$buff, 0x1e); … … 1271 1591 if ($verbose) { 1272 1592 $out = $exifTool->Options('TextOut'); 1593 $dumpParms{Out} = $out; 1273 1594 $dumpParms{MaxLen} = 96 if $verbose == 3; 1274 1595 print $out " Sector size=$sectSize\n FAT: Count=$fatCount\n"; … … 1300 1621 ++$fatCountCheck; 1301 1622 } 1302 last if $difStart == END_OF_CHAIN;1623 last if $difStart >= END_OF_CHAIN; 1303 1624 # read next DIF (Dual Indirect FAT) sector 1304 1625 my $offset = $difStart * $sectSize + HDR_SIZE; … … 1308 1629 } 1309 1630 # set end of sector information in this DIF 1631 $pos = 0; 1310 1632 $endPos = $sectSize - 4; 1311 1633 # next time around we want to read next DIF in chain … … 1344 1666 my $index = 0; 1345 1667 1346 for ($pos=0; $pos<=$endPos-128; $pos+=128 ) {1668 for ($pos=0; $pos<=$endPos-128; $pos+=128, ++$index) { 1347 1669 1348 1670 # get directory entry type … … 1359 1681 my $len = Get16u(\$dir, $pos + 0x40); 1360 1682 $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'); 1362 1684 $tag =~ s/\0.*//s; # truncate at null (in case length was wrong) 1363 1685 … … 1383 1705 ($tag =~ /(.*) \d{6}$/s and $$tagTablePtr{$1}) or 1384 1706 ($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; 1385 1722 } 1386 1723 … … 1414 1751 if ($verbose) { 1415 1752 my $flags = Get8u(\$dir, $pos + 0x43); # 0=red, 1=black 1416 my $lSib = Get32u(\$dir, $pos + 0x44); # left sibling1417 my $rSib = Get32u(\$dir, $pos + 0x48); # right sibling1418 my $chld = Get32u(\$dir, $pos + 0x4c); # child directory1419 1753 my $col = { 0 => 'Red', 1 => 'Black' }->{$flags} || $flags; 1420 1754 $extra .= " Type=$typeStr Flags=$col"; … … 1423 1757 $extra .= " Child=$chld" unless $chld == FREE_SECT; 1424 1758 $exifTool->VerboseInfo($tag, $tagInfo, 1425 Index => $index++,1426 Value => $buff,1759 Index => $index, 1760 Value => $buff, 1427 1761 DataPt => \$buff, 1428 Extra => $extra,1429 Size => $size,1762 Extra => $extra, 1763 Size => $size, 1430 1764 ); 1431 1765 } 1432 1766 if ($tagInfo and $buff) { 1433 if ($$tagInfo{SubDirectory}) { 1767 my $num = $$exifTool{NUM_FOUND}; 1768 my $subdir = $$tagInfo{SubDirectory}; 1769 if ($subdir) { 1434 1770 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}, 1439 1775 ); 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}); 1442 1778 } else { 1443 1779 $exifTool->FoundTag($tagInfo, $buff); 1444 1780 } 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 } 1445 1817 } 1446 1818 } 1447 1819 $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 } 1448 1833 return 1; 1449 1834 } … … 1469 1854 =head1 AUTHOR 1470 1855 1471 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1856 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 1472 1857 1473 1858 This library is free software; you can redistribute it and/or modify it … … 1484 1869 =item L<http://search.cpan.org/~jdb/libwin32/> 1485 1870 1871 =item L<http://msdn.microsoft.com/en-us/library/aa380374.aspx> 1872 1486 1873 =back 1487 1874 … … 1489 1876 1490 1877 L<Image::ExifTool::TagNames/FlashPix Tags>, 1878 L<Image::ExifTool::TagNames/OOXML Tags>, 1491 1879 L<Image::ExifTool(3pm)|Image::ExifTool> 1492 1880 -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FotoStation.pm
r16842 r24107 40 40 Name => 'ThumbnailImage', 41 41 Writable => 1, 42 ValueConv => '$self->ValidateImage(\$val,$tag)', 43 ValueConvInv => '$val', 42 RawConv => '$self->ValidateImage(\$val,$tag)', 44 43 }, 45 44 0x04 => { 46 45 Name => 'PreviewImage', 47 46 Writable => 1, 48 ValueConv => '$self->ValidateImage(\$val,$tag)', 49 ValueConvInv => '$val', 47 RawConv => '$self->ValidateImage(\$val,$tag)', 50 48 }, 51 49 ); … … 193 191 $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTable); 194 192 } else { 195 my $n ewValueHash = $exifTool->GetNewValueHash($tagInfo);196 if (Image::ExifTool::IsOverwriting($n ewValueHash) > 0) {197 $newVal = Image::ExifTool::GetNewValues($n ewValueHash);193 my $nvHash = $exifTool->GetNewValueHash($tagInfo); 194 if (Image::ExifTool::IsOverwriting($nvHash) > 0) { 195 $newVal = Image::ExifTool::GetNewValues($nvHash); 198 196 $newVal = '' unless defined $newVal; 199 197 if ($verbose > 1) { … … 243 241 =head1 AUTHOR 244 242 245 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)243 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 246 244 247 245 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FujiFilm.pm
r16842 r24107 2 2 # File: FujiFilm.pm 3 3 # 4 # Description: FujiFilm EXIF maker notes tags4 # Description: Read/write FujiFilm maker notes and RAF images 5 5 # 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 7 8 # 8 9 # 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) 10 11 # 3) Michael Meissner private communication 11 12 # 4) Paul Samuelson private communication (S5) 12 13 # 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 13 17 #------------------------------------------------------------------------------ 14 18 … … 20 24 use Image::ExifTool::Exif; 21 25 22 $VERSION = '1.14'; 23 26 $VERSION = '1.31'; 27 28 sub ProcessFujiDir($$$); 29 sub ProcessFaceRec($$$); 30 31 # the following RAF version numbers have been tested for writing: 32 my %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 51 my %faceCategories = ( 52 Format => 'int8u', 53 PrintConv => { BITMASK => { 54 1 => 'Partner', 55 2 => 'Family', 56 3 => 'Friend', 57 }}, 58 ); 59 60 # FujiFilm MakerNotes tags 24 61 %Image::ExifTool::FujiFilm::Main = ( 25 62 WRITE_PROC => \&Image::ExifTool::Exif::WriteExif, … … 54 91 0x1001 => { 55 92 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 63 105 }, 64 106 }, … … 74 116 0x301 => 'Day White Fluorescent', 75 117 0x302 => 'White Fluorescent', 118 0x303 => 'Warm White Fluorescent', #2/PH (S5) 119 0x304 => 'Living Room Warm White Fluorescent', #2/PH (S5) 76 120 0x400 => 'Incandescent', 77 121 0x500 => 'Flash', #4 78 122 0xf00 => 'Custom', 123 0xf01 => 'Custom2', #2 124 0xf02 => 'Custom3', #2 125 0xf03 => 'Custom4', #2 126 0xf04 => 'Custom5', #2 127 # 0xfe0 => 'Gray Point?', #2 79 128 0xff0 => 'Kelvin', #4 80 129 }, … … 86 135 PrintConv => { 87 136 0x0 => 'Normal', 137 0x080 => 'Medium High', #2 88 138 0x100 => 'High', 139 0x180 => 'Medium Low', #2 89 140 0x200 => 'Low', 90 141 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 91 147 }, 92 148 }, … … 97 153 PrintConv => { 98 154 0x0 => 'Normal', 155 0x080 => 'Medium High', #2 99 156 0x100 => 'High', 157 0x180 => 'Medium Low', #2 100 158 0x200 => 'Low', 159 0x8000 => 'Film Simulation', #2 101 160 }, 102 161 }, … … 104 163 Name => 'ColorTemperature', 105 164 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 }, 106 202 }, 107 203 0x1010 => { … … 113 209 2 => 'Off', 114 210 3 => 'Red-eye reduction', 211 4 => 'External', #JD 115 212 }, 116 213 }, 117 214 0x1011 => { 118 Name => 'Flash Strength',215 Name => 'FlashExposureComp', #JD 119 216 Writable => 'rational64s', 120 217 }, … … 156 253 0x1 => 'Portrait', 157 254 0x2 => 'Landscape', 255 0x3 => 'Macro', #JD 158 256 0x4 => 'Sports', 159 257 0x5 => 'Night Scene', … … 161 259 0x7 => 'Natural Light', #3 162 260 0x8 => 'Anti-blur', #3 261 0x9 => 'Beach & Snow', #JD 163 262 0xa => 'Sunset', #3 164 263 0xb => 'Museum', #3 … … 171 270 0x12 => 'Fireworks', #3 172 271 0x13 => 'Underwater', #3 272 0x16 => 'Panorama', #PH (X100) 173 273 0x100 => 'Aperture-priority AE', 174 274 0x200 => 'Shutter speed priority AE', … … 181 281 # Writable => 'int16u', 182 282 # }, 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 }, 183 301 0x1100 => { 184 302 Name => 'AutoBracketing', … … 228 346 }, 229 347 }, 348 0x1304 => { #PH 349 Name => 'GEImageSize', 350 Condition => '$$self{Make} =~ /^GENERAL IMAGING/', 351 Format => 'string', 352 Notes => 'GE models only', 353 }, 230 354 0x1400 => { #2 231 355 Name => 'DynamicRange', … … 234 358 1 => 'Standard', 235 359 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) 239 364 Name => 'FilmMode', 240 365 Writable => 'int16u', … … 243 368 0x000 => 'F0/Standard', 244 369 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', 245 373 0x200 => 'F2/Fujichrome', 246 374 0x300 => 'F3/Studio Portrait Ex', … … 254 382 PrintConv => { 255 383 0x000 => 'Auto (100-400%)', 256 0x001 => ' RAW',384 0x001 => 'Manual', #(ref http://forum.photome.de/viewtopic.php?f=2&t=353) 257 385 0x100 => 'Standard (100%)', 258 386 0x200 => 'Wide1 (230%)', 259 387 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) 264 392 Name => 'DevelopmentDynamicRange', 265 393 Writable => 'int16u', … … 281 409 Writable => 'rational64s', 282 410 }, 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 }, 283 444 0x8000 => { #2 284 445 Name => 'FileSource', … … 293 454 Writable => 'int16u', 294 455 }, 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 => { }, 295 495 ); 296 496 297 497 # tags in RAF images (ref 5) 298 498 %Image::ExifTool::FujiFilm::RAF = ( 499 PROCESS_PROC => \&ProcessFujiDir, 299 500 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 }, 301 508 0x100 => { 302 509 Name => 'RawImageFullSize', … … 311 518 { 312 519 Name => 'RawImageSize', 313 Condition => '$$self{ CameraModel} eq "FinePixS2Pro"',520 Condition => '$$self{Model} eq "FinePixS2Pro"', 314 521 Format => 'int16u', 315 522 Count => 2, … … 350 557 ); 351 558 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 575 sub 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 352 628 #------------------------------------------------------------------------------ 353 629 # get information from FujiFilm RAF directory … … 360 636 my $offset = $$dirInfo{DirStart}; 361 637 $raf->Seek($offset, 0) or return 0; 362 my $buff;638 my ($buff, $index); 363 639 $raf->Read($buff, 4) or return 0; 364 640 my $entries = unpack 'N', $buff; 365 641 $entries < 256 or return 0; 642 $exifTool->Options('Verbose') and $exifTool->VerboseDir('Fuji', $entries); 366 643 SetByteOrder('MM'); 367 while ($entries--) { 644 my $pos = $offset + 4; 645 for ($index=0; $index<$entries; ++$index) { 368 646 $raf->Read($buff,4) or return 0; 647 $pos += 4; 369 648 my ($tag, $len) = unpack 'nn', $buff; 370 649 my ($val, $vbuf); … … 374 653 $val = ReadValue(\$vbuf, 0, $$tagInfo{Format}, $$tagInfo{Count}, $len); 375 654 next unless defined $val; 655 } elsif ($len == 4) { 656 # interpret unknown 4-byte values as int32u 657 $val = Get32u(\$vbuf, 0); 376 658 } else { 659 # treat other unknown values as binary data 377 660 $val = \$vbuf; 378 661 } 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; 380 670 } 381 671 return 1; … … 383 673 384 674 #------------------------------------------------------------------------------ 385 # get information from FujiFilm RAW file675 # write information to FujiFilm RAW file (RAF) 386 676 # 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 678 sub 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 388 776 sub ProcessRAF($$) 389 777 { 390 778 my ($exifTool, $dirInfo) = @_; 391 my ($buff, $ warn);779 my ($buff, $jpeg, $warn, $offset); 392 780 393 781 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 402 792 my %dirInfo = ( 403 793 Parent => 'RAF', 404 RAF => new File::RandomAccess(\$ buff),794 RAF => new File::RandomAccess(\$jpeg), 405 795 ); 406 $$exifTool{BASE} += $ pos;796 $$exifTool{BASE} += $jpos; 407 797 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"; 412 817 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; 431 819 delete $$exifTool{SET_GROUP1}; 432 } else { 433 $ warn =1;820 821 $num = ($num || 1) + 1; 434 822 } 435 823 $warn and $exifTool->Warn('Possibly corrupt RAF information'); … … 444 832 =head1 NAME 445 833 446 Image::ExifTool::FujiFilm - FujiFilm EXIF maker notes tags834 Image::ExifTool::FujiFilm - Read/write FujiFilm maker notes and RAF images 447 835 448 836 =head1 SYNOPSIS … … 453 841 454 842 This module contains definitions required by Image::ExifTool to interpret 455 FujiFilm maker notes in EXIF information, and to read FujiFilm RAW (RAF)456 images.843 FujiFilm maker notes in EXIF information, and to read/write FujiFilm RAW 844 (RAF) images. 457 845 458 846 =head1 AUTHOR 459 847 460 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)848 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 461 849 462 850 This library is free software; you can redistribute it and/or modify it … … 479 867 =head1 ACKNOWLEDGEMENTS 480 868 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. 869 Thanks to Michael Meissner, Paul Samuelson and Jens Duttke for help decoding 870 some FujiFilm information. 484 871 485 872 =head1 SEE ALSO -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GIF.pm
r16842 r24107 6 6 # Revisions: 10/18/2005 - P. Harvey Separated from ExifTool.pm 7 7 # 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 12 11 #------------------------------------------------------------------------------ 13 12 … … 16 15 use strict; 17 16 use vars qw($VERSION); 18 use Image::ExifTool qw(:DataAccess); 19 20 $VERSION = '1.04'; 17 use Image::ExifTool qw(:DataAccess :Utils); 18 19 $VERSION = '1.06'; 20 21 # road map of directory locations in GIF images 22 my %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 ); 21 99 22 100 #------------------------------------------------------------------------------ … … 28 106 { 29 107 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}; 32 110 my $verbose = $exifTool->Options('Verbose'); 33 111 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; 36 123 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 45 127 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}) { 48 133 $setComment = 1; 49 if ($ exifTool->{DEL_GROUP}->{File} == 2) {134 if ($$delGroup{File} == 2) { 50 135 $newComment = $exifTool->GetNewValues('Comment'); 51 136 } 52 137 } 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); 57 149 } 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 # 179 Block: 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); 96 223 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)); 109 226 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 } 120 230 # 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 164 251 } else { 165 252 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 176 391 $exifTool->FoundTag('Comment', $comment) if $comment; 177 392 } 393 178 394 # set return value to -1 if we only had a write error 179 395 $rtnVal = -1 if $rtnVal and $err; … … 197 413 198 414 This 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. 415 write GIF meta information. 201 416 202 417 =head1 AUTHOR 203 418 204 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)419 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 205 420 206 421 This library is free software; you can redistribute it and/or modify it … … 213 428 =item L<http://www.w3.org/Graphics/GIF/spec-gif89a.txt> 214 429 430 =item L<http://www.adobe.com/devnet/xmp/> 431 432 =item L<http://graphcomp.com/info/specs/ani_gif.html> 433 215 434 =back 216 435 -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GPS.pm
r16842 r24107 13 13 use Image::ExifTool::Exif; 14 14 15 $VERSION = '1. 17';15 $VERSION = '1.34'; 16 16 17 17 my %coordConv = ( … … 28 28 WRITABLE => 1, 29 29 WRITE_GROUP => 'GPS', 30 NOTES => q{31 When adding GPS information to an image, it is important to set all of the32 following tags: GPSLatitude, GPSLatitudeRef, GPSLongitude, GPSLongitudeRef,33 GPSAltitude and GPSAltitudeRef. ExifTool will write the required34 GPSVersionID tag automatically if new a GPS IFD is added to an image.35 },36 30 0x0000 => { 37 31 Name => 'GPSVersionID', 38 32 Writable => 'int8u', 33 Mandatory => 1, 39 34 Count => 4, 40 35 PrintConv => '$val =~ tr/ /./; $val', … … 46 41 Count => 2, 47 42 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 }, 48 52 N => 'North', 49 53 S => 'South', … … 61 65 Count => 2, 62 66 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 }, 63 76 E => 'East', 64 77 W => 'West', … … 82 95 Name => 'GPSAltitude', 83 96 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"', 85 100 PrintConvInv => '$val=~s/\s*m$//;$val', 86 101 }, … … 91 106 Count => 3, 92 107 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)', 108 113 ValueConvInv => '$val=~tr/:/ /;$val', 109 114 # 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) 111 116 PrintConvInv => sub { 112 117 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 } 114 124 my @a = ($v =~ /((?=\d|\.\d)\d*(?:\.\d*)?)/g); 115 125 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 } 116 134 return "$a[-3]:$a[-2]:$a[-1]"; 117 135 }, … … 126 144 Count => 2, 127 145 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 => { 133 152 Name => 'GPSMeasureMode', 134 153 Writable => 'string', … … 139 158 }, 140 159 }, 141 0x000 B=> {160 0x000b => { 142 161 Name => 'GPSDOP', 143 162 Description => 'GPS Dilution Of Precision', 144 163 Writable => 'rational64u', 145 164 }, 146 0x000 C=> {165 0x000c => { 147 166 Name => 'GPSSpeedRef', 148 167 Writable => 'string', … … 154 173 }, 155 174 }, 156 0x000 D=> {175 0x000d => { 157 176 Name => 'GPSSpeed', 158 177 Writable => 'rational64u', 159 178 }, 160 0x000 E=> {179 0x000e => { 161 180 Name => 'GPSTrackRef', 162 181 Writable => 'string', … … 167 186 }, 168 187 }, 169 0x000 F=> {188 0x000f => { 170 189 Name => 'GPSTrack', 171 190 Writable => 'rational64u', … … 241 260 }, 242 261 }, 243 0x001 A=> {262 0x001a => { 244 263 Name => 'GPSDestDistance', 245 264 Writable => 'rational64u', 246 265 }, 247 0x001 B=> {266 0x001b => { 248 267 Name => 'GPSProcessingMethod', 249 268 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 => { 254 274 Name => 'GPSAreaInformation', 255 275 Writable => 'undef', 256 PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',257 PrintConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',258 }, 259 0x001 D=> {276 RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)', 277 RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)', 278 }, 279 0x001d => { 260 280 Name => 'GPSDateStamp', 261 281 Groups => { 2 => 'Time' }, 262 282 Writable => 'string', 263 Notes => 'YYYY: MM:DD',283 Notes => 'YYYY:mm:dd', 264 284 Count => 11, 265 285 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 }, 266 290 ValueConv => 'Image::ExifTool::Exif::ExifDate($val)', 267 291 ValueConvInv => '$val', 268 292 # 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 => { 272 303 Name => 'GPSDifferential', 273 304 Writable => 'int16u', … … 277 308 }, 278 309 }, 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 }, 279 317 ); 280 318 281 319 # Composite GPS tags 282 320 %Image::ExifTool::GPS::Composite = ( 321 GROUPS => { 2 => 'Location' }, 283 322 GPSDateTime => { 284 323 Description => 'GPS Date/Time', 285 324 Groups => { 2 => 'Time' }, 325 SubDoc => 1, # generate for all sub-documents 286 326 Require => { 287 0 => 'GPS DateStamp',288 1 => 'GPS TimeStamp',289 }, 290 ValueConv => '"$val[0] $val[1] "',327 0 => 'GPS:GPSDateStamp', 328 1 => 'GPS:GPSTimeStamp', 329 }, 330 ValueConv => '"$val[0] $val[1]Z"', 291 331 PrintConv => '$self->ConvertDateTime($val)', 292 332 }, 333 # Note: The following tags are used by other modules 334 # which must therefore require this module as necessary 293 335 GPSLatitude => { 336 SubDoc => 1, # generate for all sub-documents 294 337 Require => { 295 338 0 => 'GPS:GPSLatitude', … … 300 343 }, 301 344 GPSLongitude => { 345 SubDoc => 1, # generate for all sub-documents 302 346 Require => { 303 347 0 => 'GPS:GPSLongitude', … … 307 351 PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', 308 352 }, 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 }, 309 374 ); 310 375 311 376 # add our composite tags 312 377 Image::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 383 sub 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 } 313 399 314 400 #------------------------------------------------------------------------------ … … 330 416 $ref = " $ref" unless $doPrintConv and $doPrintConv eq '2'; 331 417 } else { 418 $val = abs($val); 332 419 $ref = ''; 333 420 } … … 364 451 { 365 452 my ($val, $doSign) = @_; 366 # extract decimal values out of any other garbage367 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); 368 455 my $deg = ($d || 0) + (($m || 0) + ($s || 0)/60) / 60; 369 456 # make negative if S or W coordinate … … 392 479 =head1 AUTHOR 393 480 394 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)481 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 395 482 396 483 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GeoTiff.pm
r16842 r24107 4 4 # Description: Read GeoTiff meta information 5 5 # 6 # Revisions: 02/23/ 04 - P. Harvey Created7 # 02/25/ 04 - P. Harvey Added new codes from libgeotiff-1.2.18 # 02/01/ 07 - P. Harvey Added new codes from libgeotiff-1.2.36 # 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 9 9 # 10 10 # Reference: ftp://ftp.remotesensing.org/geotiff/libgeotiff/libgeotiff-1.1.4.tar.gz … … 15 15 use strict; 16 16 use vars qw($VERSION); 17 use Image::ExifTool qw(:DataAccess );18 19 $VERSION = '1.0 6';17 use Image::ExifTool qw(:DataAccess :Utils); 18 19 $VERSION = '1.07'; 20 20 21 21 # format codes for geoTiff directory entries … … 2065 2065 2066 2066 #------------------------------------------------------------------------------ 2067 # Inputs: 0) ExifTool object ref erence2068 # 1) tag table reference2067 # Inputs: 0) ExifTool object ref 2068 # Notes: byte order must be set before calling this routine 2069 2069 sub ProcessGeoTiff($) 2070 2070 { 2071 my ($exifTool) = @_;2071 my $exifTool = shift; 2072 2072 my $dirData = $exifTool->GetValue('GeoTiffDirectory', 'ValueConv') or return; 2073 2073 my $doubleData = $exifTool->GetValue('GeoTiffDoubleParams', 'ValueConv'); 2074 2074 my $asciiData = $exifTool->GetValue('GeoTiffAsciiParams', 'ValueConv'); 2075 2075 my $verbose = $exifTool->Options('Verbose'); 2076 my @double;2077 2076 2078 2077 # restore or original EXIF byte order setting 2079 my $byteOrder = $exifTool->{EXIF_BYTE_ORDER};2080 $byteOrder and SetByteOrder($byteOrder);2081 2078 if (length($$dirData) >= 8 and 2082 2079 length($$dirData) >= 8 * (Get16u($dirData,6) + 1)) … … 2086 2083 my $minorRev = Get16u($dirData,4); 2087 2084 my $numEntries = Get16u($dirData,6); 2088 2085 2089 2086 if ($verbose) { 2090 2087 $exifTool->{INDENT} .= '| '; … … 2092 2089 } 2093 2090 # 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"); 2095 2092 my $tagInfo = $exifTool->GetTagInfo($tagTable, 1); 2096 2093 $tagInfo and $exifTool->FoundTag($tagInfo,"$version.$revision.$minorRev"); 2097 2094 2098 2095 my $i; 2099 2096 for ($i=0; $i<$numEntries; ++$i) { … … 2170 2167 =head1 AUTHOR 2171 2168 2172 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)2169 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 2173 2170 2174 2171 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HP.pm
r16842 r24107 13 13 use Image::ExifTool qw(:DataAccess :Utils); 14 14 15 $VERSION = '1.0 1';15 $VERSION = '1.02'; 16 16 17 17 sub ProcessHP($$$); 18 sub ProcessTDHD($$$); 18 19 19 20 # HP EXIF-format maker notes (or is it Vivitar?) … … 23 24 These tables list tags found in the maker notes of some Hewlett-Packard 24 25 camera models. 25 26 26 27 The first table lists tags found in the EXIF-format maker notes of the 27 28 PhotoSmart 720 (also used by the Vivitar ViviCam 3705, 3705B and 3715). … … 43 44 'PreviewImage' => { 44 45 Name => 'PreviewImage', 45 ValueConv => '$self->ValidateImage(\$val,$tag)',46 RawConv => '$self->ValidateImage(\$val,$tag)', 46 47 }, 47 48 'Serial Number' => 'SerialNumber', … … 110 111 }, 111 112 ); 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 142 sub 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 } 112 198 113 199 #------------------------------------------------------------------------------ … … 164 250 =head1 AUTHOR 165 251 166 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)252 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 167 253 168 254 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HTML.pm
r16842 r24107 21 21 require Exporter; 22 22 23 $VERSION = '1. 03';23 $VERSION = '1.11'; 24 24 @ISA = qw(Exporter); 25 25 @EXPORT_OK = qw(EscapeHTML UnescapeHTML); 26 27 sub SetHTMLCharset($$); 28 29 # convert HTML charset (lower case) to ExifTool Charset name 30 my %htmlCharset = ( 31 macintosh => 'MacRoman', 32 'iso-8859-1' => 'Latin', 33 'utf-8' => 'UTF8', 34 'windows-1252' => 'Latin', 35 ); 26 36 27 37 # HTML 4 character entity references … … 121 131 NOTES => q{ 122 132 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. 124 135 }, 125 136 dc => { … … 142 153 Name => 'HTTP-equiv', 143 154 SubDirectory => { TagTable => 'Image::ExifTool::HTML::equiv' }, 155 }, 156 o => { 157 Name => 'Office', 158 SubDirectory => { TagTable => 'Image::ExifTool::HTML::Office' }, 144 159 }, 145 160 abstract => { }, … … 157 172 keywords => { List => 1 }, 158 173 mssmarttagspreventparsing => { Name => 'NoMSSmartTags' }, 174 originator => { }, 159 175 owner => { }, 160 176 progid => { Name => 'ProgID' }, … … 195 211 %Image::ExifTool::HTML::ncc = ( 196 212 GROUPS => { 1 => 'HTML-ncc', 2 => 'Document' }, 197 charset => { },213 charset => { Name => 'CharacterSet' }, # name changed to avoid conflict with -charset option 198 214 depth => { }, 199 215 files => { }, … … 209 225 prodnotes => { Name => 'ProdNotes' }, 210 226 producer => { }, 211 produceddate => { Name => 'ProducedDate', Groups => { 2 => 'Time' } }, # yyyy-mm-dd227 produceddate => { Name => 'ProducedDate', Groups => { 2 => 'Time' } }, # YYYY-mm-dd 212 228 revision => { }, 213 229 revisiondate => { Name => 'RevisionDate', Groups => { 2 => 'Time' } }, … … 220 236 sourcetitle => { Name => 'SourceTitle' }, 221 237 tocitems => { Name => 'TOCItems' }, 222 totaltime => { Name => 'Duration' }, # hh:mm:ss238 totaltime => { Name => 'Duration' }, # HH:MM:SS 223 239 ); 224 240 … … 245 261 'content-script-type' => { Name => 'ContentScriptType' }, 246 262 '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 }, 248 265 'default-style' => { Name => 'DefaultStyle' }, 249 266 expires => { }, … … 264 281 ); 265 282 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 335 sub SetHTMLCharset($$) 336 { 337 my ($val, $exifTool) = @_; 338 $$exifTool{HTMLCharset} = $htmlCharset{lc $1} if $val =~ /charset=['"]?([-\w]+)/; 339 return $val; 340 } 341 266 342 #------------------------------------------------------------------------------ 267 343 # Convert single UTF-8 character to HTML character reference 268 344 # Inputs: 0) UTF-8 character sequence 269 # Returns: H ML character reference (ie. """);345 # Returns: HTML character reference (ie. """); 270 346 # Note: Must be called via EscapeHTML to load name lookup 271 347 sub EscapeChar($) 272 348 { 273 349 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 } 275 357 return '?' unless defined $val; 276 358 return "&$entityName{$val};" if $entityName{$val}; … … 297 379 delete $entityName{39}; # 'apos' is not valid HTML 298 380 } 299 # sup ress warnings381 # suppress warnings 300 382 local $SIG{'__WARN__'} = sub { 1 }; 301 383 # escape any non-ascii characters for HTML … … 322 404 my ($exifTool, $dirInfo) = @_; 323 405 my $raf = $$dirInfo{RAF}; 324 my $verbose = $exifTool->Options('Verbose'); 325 my ($buff, $err); 406 my $buff; 326 407 327 408 # validate HTML or XHTML file 328 409 $raf->Read($buff, 256) or return 0; 329 $buff =~ /^<(!DOCTYPE 330 $buff =~ /<(!DOCTYPE 410 $buff =~ /^<(!DOCTYPE\s+HTML|HTML|\?xml)/i or return 0; 411 $buff =~ /<(!DOCTYPE\s+)?HTML/i or return 0 if $1 eq '?xml'; 331 412 $exifTool->SetFileType(); 332 413 333 414 $raf->Seek(0,0) or $exifTool->Warn('Seek error'), return 1; 334 415 335 my $oldsep = Image::ExifTool::PostScript::SetInputRecordSeparator($raf);336 $ oldsepor $exifTool->Warn('Invalid HTML data'), return 1;416 local $/ = Image::ExifTool::PostScript::GetInputRecordSeparator($raf); 417 $/ or $exifTool->Warn('Invalid HTML data'), return 1; 337 418 338 419 # extract header information … … 348 429 last if $buff =~ m{</head>}i; 349 430 } 431 return 1 unless defined $doc; 350 432 351 433 # process all elements in header … … 371 453 } 372 454 my $table = $tagTablePtr; 373 # parse HTML META element374 455 if ($tag eq 'meta') { 456 # parse HTML META element 375 457 undef $tag; 376 458 # tag name is in NAME or HTTP-EQUIV attribute … … 396 478 } 397 479 } 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; 398 501 } else { 399 # the only non-METAelement we process is TITLE502 # the only other element we process is TITLE 400 503 next unless $tag eq 'title'; 401 504 } … … 408 511 $exifTool->VPrint(0, " [adding $tag '$tagName']\n"); 409 512 } 513 # recode if necessary 514 $val = $exifTool->Decode($val, $$exifTool{HTMLCharset}) if $$exifTool{HTMLCharset}; 410 515 $val =~ s{\s*$/\s*}{ }sg; # replace linefeeds and indenting spaces 411 516 $val = UnescapeHTML($val); # unescape HTML character references 412 517 $exifTool->HandleTag($table, $tag, $val); 413 518 } 414 $/ = $oldsep; # restore original separator415 519 return 1; 416 520 } … … 435 539 =head1 AUTHOR 436 540 437 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)541 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 438 542 439 543 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HtmlDump.pm
r16842 r24107 12 12 use vars qw($VERSION); 13 13 use Image::ExifTool; # only for FinishTiffDump() 14 15 $VERSION = '1.17'; 16 17 sub DumpTable($$$;$$$$); 14 use Image::ExifTool::HTML qw(EscapeHTML); 15 16 $VERSION = '1.30'; 17 18 sub DumpTable($$$;$$$$$); 18 19 sub Open($$$;@); 19 20 sub Write($@); 20 21 21 my ($bkgStart, $bkgEnd, $bkgSpan);22 my ($bkgStart, $bkgEnd, @bkgSpan); 22 23 23 24 my $htmlHeader1 = <<_END_PART_1_; … … 44 45 .F { color: #aa00dd } /* actual offset differs */ 45 46 .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 } 46 69 /* table styles */ 47 70 table.dump { … … 61 84 <script language="JavaScript" type="text/JavaScript"> 62 85 <!-- Begin 63 var t = new Array; 86 // tooltip positioning constants 87 var TMAR = 4; // top/left margins 88 var BMAR = 16; // bottom/right margins (scrollbars may overhang inner dimensions) 89 var XOFF = 10; // x offset from cursor 90 var YOFF = 40; // y offset 91 var YMIN = 10; // minimum y offset 92 var YTOP = 20; // y offset when above cursor 93 // common variables 94 var safari1 = navigator.userAgent.indexOf("Safari/312.6") >= 0; 95 var ie6 = navigator.userAgent.toLowerCase().indexOf('msie 6') >= 0; 64 96 var mspan = new Array; 97 var hlist, tt, tb; 98 65 99 function GetElementsByClass(classname, tagname) { 66 100 var found = new Array(); … … 79 113 return found; 80 114 } 115 116 // move tooltip 117 function 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 81 162 function high(e,on) { 82 163 var targ; … … 86 167 if (!targ.name) targ = targ.parentNode; // go up another level if necessary 87 168 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 } 90 181 if (on) { 91 col = "#ffcc99";92 182 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 } 96 189 } 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; 112 202 } 113 break; 203 for (var j=0; j<hlist.length; ++j) { 204 hlist[j].style.background = '#ffcc99'; 205 } 114 206 } 115 207 } … … 122 214 <body><noscript><b class=V>--> 123 215 Enable 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> 125 218 <tr><td valign='top'><pre>]; 126 219 127 my $preMouse = q(<pre onmouseover="high(event,1)" onmouseout="high(event,0)" >);220 my $preMouse = q(<pre onmouseover="high(event,1)" onmouseout="high(event,0)" onmousemove="move(event)">); 128 221 129 222 #------------------------------------------------------------------------------ … … 142 235 # Inputs: 0) HTML dump hash ref, 1) absolute offset in file, 2) data size, 143 236 # 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 call237 # 5) bit flags (see below) 145 238 # Bits: 0x01 - print at start of line 146 239 # 0x02 - print red address 147 240 # 0x04 - maker notes data ('M'-class span) 148 241 # 0x08 - limit block length 242 # 0x10 - allow double references 243 # 0x100 - (reserved) 149 244 # Notes: Block will be shown in 'unused' color if comment string begins with '[' 150 sub Add($$$$;$ $)245 sub Add($$$$;$) 151 246 { 152 my ($self, $start, $size, $msg, $tip, $flag , $sameTip) = @_;247 my ($self, $start, $size, $msg, $tip, $flag) = @_; 153 248 my $block = $$self{Block}; 154 249 $$block{$start} or $$block{$start} = [ ]; 250 my $htip; 155 251 if ($tip and $tip eq 'SAME') { 156 $ tip = '';252 $htip = ''; 157 253 } 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 } 162 260 # add size if not already done 163 $ tip .= "\\n($size bytes)" unless $tip =~ /\\nSize:/;261 $htip .= "<br>($size bytes)" unless $htip =~ /<br>Size:/; 164 262 ++$self->{TipNum}; 165 263 } 166 push @{$$block{$start}}, [ $size, $msg, $ tip, $flag, $self->{TipNum} ];264 push @{$$block{$start}}, [ $size, $msg, $htip, $flag, $self->{TipNum} ]; 167 265 } 168 266 … … 172 270 # 2) data pointer, 3) data position, 4) output file or scalar reference, 173 271 # 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. 175 276 sub Print($$;$$$$$) 176 277 { 177 278 local $_; 178 279 my ($self, $raf, $dataPt, $dataPos, $outfile, $level, $title) = @_; 179 my ($i, $buff, $rtnVal );280 my ($i, $buff, $rtnVal, $limit, $err); 180 281 my $block = $$self{Block}; 181 282 $dataPos = 0 unless $dataPos; … … 184 285 $level or $level = 0; 185 286 my $tell = $raf->Tell(); 186 my @starts = sort { $a <=> $b } keys %$block;187 287 my $pos = 0; 188 288 my $dataEnd = $dataPos + ($dataPt ? length($$dataPt) : 0); … … 195 295 # set dump size limits (limits are 4x smaller if bit 0x08 set in flags) 196 296 if ($level <= 1) { 197 $ $self{Limit}= 1024;297 $limit = 1024; 198 298 } elsif ($level <= 2) { 199 $ $self{Limit}= 16384;299 $limit = 16384; 200 300 } else { 201 delete $$self{Limit}; # no limit 202 } 301 $limit = 256 * 1024 * 1024; # never dump bigger than 256 MB 302 } 303 $$self{Limit} = $limit; 203 304 # pre-initialize open/closed hashes for all columns 204 305 for ($i=0; $i<4; ++$i) { … … 207 308 } 208 309 $bkgStart = $bkgEnd = 0; 209 $bkgSpan = '';310 undef @bkgSpan; 210 311 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}; 212 315 for ($i=0; $i<@starts; ++$i) { 213 316 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; 218 334 } 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; 228 342 } 229 343 my $parms; 230 my $parmList = $$block{$start};231 344 foreach $parms (@$parmList) { 232 345 my ($len, $msg, $tip, $flag, $tipNum) = @$parms; … … 234 347 $flag = 0 unless defined $flag; 235 348 # 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; 237 351 my $idx = $index; 238 352 if ($name) { … … 240 354 $idx = substr($name, 1); 241 355 } else { 242 $name = $names[$tipNum] = "t$index"; 356 $name = "t$index"; 357 $names[$tipNum] = $name if defined $tipNum; 243 358 ++$index; 244 359 } 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}; 249 369 push @{$self->{MSpanList}}, $name; 250 370 next; 251 371 } 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 } 252 410 $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 }260 411 next unless length $buff; 261 412 # set flag to continue this line if next block is contiguous … … 267 418 } 268 419 $self->DumpTable($start-$dataPos, \$buff, $msg, $name, 269 $flag, $pos-$dataPos); 420 $flag, $len, $pos-$dataPos); 421 undef $buff; 270 422 $pos = $end if $pos < $end; 271 423 } … … 282 434 Write($outfile, qq(mspan[$i] = "$$mspan[$i]";\n)); 283 435 } 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};289 436 Write($outfile, $htmlHeader3, $self->{Cols}->[0]); 290 437 Write($outfile, '</pre></td><td valign="top">', … … 294 441 Write($outfile, '</pre></td><td valign="top">', 295 442 $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}; 297 450 $rtnVal = 1; 298 451 } 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; 301 455 } 302 456 Write($outfile, "</body></html>\n"); 303 457 for ($i=0; $i<4; ++$i) { 304 458 $self->{Cols}->[$i] = ''; # free memory 459 } 460 if ($err) { 461 $err =~ tr/()//d; 462 $$self{ERROR} = $err; 463 return -1; 305 464 } 306 465 return $rtnVal; … … 388 547 # Dump a block of data in HTML table form 389 548 # 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 551 sub DumpTable($$$;$$$$$) 392 552 { 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; 395 555 $endPos = 0 unless $endPos; 396 556 my ($f0, $dblRef, $id); 557 my $skipped = 0; 397 558 if (($endPos and $pos < $endPos) or $flag & 0x02) { 398 559 # display double-reference addresses in red … … 417 578 ++$id unless $dblRef; 418 579 } 419 $name = qq{<a name=$name class=$id>};580 $name = "<a name=$name class=$id>"; 420 581 $msg and $msg = "$name$msg</a>"; 421 582 } else { … … 446 607 # loop through each column of hex numbers 447 608 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 } 449 624 $self->Open('a', $name, 1, 2); 450 my $ch = substr($$blockPt,$p-$pos ,1);625 my $ch = substr($$blockPt,$p-$pos-$skipped,1); 451 626 $c[1] .= sprintf("%.2x", ord($ch)); 452 627 # make the character HTML-friendly … … 459 634 ++$cols; 460 635 # close necessary elements 461 if ($p >= $bkgEnd) { 636 if ($spanClose) { 637 my $spanCont = @spanCont ? "<span class='@spanCont'>" : ''; 462 638 # close without reopening if closing anchor later 463 my $arg = ($p - $pos >= $len) ? 0 : '';639 my $arg = ($p - $pos >= $len) ? 0 : $spanCont; 464 640 $self->Open('bkg', $arg, 1, 2); 465 641 } … … 496 672 if ($n > 16) { # (no use just cutting out one line) 497 673 $self->Open('bkg', '', 1, 2); # no underline 498 my $note = "[snip $n bytes]";674 my $note = sprintf "[snip %d lines]", $n / 16; 499 675 $note = (' ' x (24-length($note)/2)) . $note; 500 676 $c[0] .= " ...\n"; … … 503 679 $c[3] .= "\n"; 504 680 $p += $n; 681 $skipped += $len - length $$blockPt; 505 682 } 506 683 } … … 550 727 ImageOffset => 'ImageByteCount', 551 728 AlphaOffset => 'AlphaByteCount', 729 MPImageStart => 'MPImageLength', 730 IDCPreviewStart => 'IDCPreviewLength', 552 731 ); 553 732 … … 556 735 my $info = $exifTool->GetInfo($tag); 557 736 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) { 559 760 my $name = Image::ExifTool::GetTagName($key); 560 761 my $grp1 = $exifTool->GetGroup($key, 1); 561 762 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}; 564 766 my $offsets = $$info{$key}; 565 767 my $byteCounts = $$info2{$key2}; 768 # ignore primary MPImage (this is the whole JPEG) 769 next if $tag eq 'MPImageStart' and $offsets eq '0'; 566 770 # (long lists may be SCALAR references) 567 771 my @offsets = split ' ', (ref $offsets ? $$offsets : $offsets); … … 657 861 ExifTool 'HtmlDump' option is used. 658 862 659 Currently, only EXIF and TIFFinformation is dumped.863 Currently, only EXIF/TIFF and JPEG information is dumped. 660 864 661 865 =head1 BUGS … … 666 870 667 871 An 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. 872 page. 670 873 671 874 =head1 AUTHOR 672 875 673 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)876 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 674 877 675 878 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ICC_Profile.pm
r16842 r24107 4 4 # Description: Read ICC Profile meta information 5 5 # 6 # Revisions: 11/16/ 04 - P. Harvey Created6 # Revisions: 11/16/2004 - P. Harvey Created 7 7 # 8 8 # References: 1) http://www.color.org/icc_specs2.html (ICC.1:2003-09) … … 10 10 # 3) http://developer.apple.com/documentation/GraphicsImaging/Reference/ColorSync_Manager/ColorSync_Manager.pdf 11 11 # 4) http://www.color.org/privatetag2007-01.pdf 12 # 5) http://www.color.org/icc_specs2.xalter (approved revisions, 2010-07-16) 12 13 # 13 14 # Notes: The ICC profile information is different: the format of each … … 23 24 use Image::ExifTool qw(:DataAccess :Utils); 24 25 25 $VERSION = '1. 13';26 $VERSION = '1.22'; 26 27 27 28 sub ProcessICC($$); 28 29 sub ProcessICC_Profile($$$); 29 30 sub WriteICC_Profile($$;$); 31 sub ProcessMetadata($$$); 30 32 sub ValidateICC($); 31 33 … … 49 51 abst => 'Abstract Profile', 50 52 nmcl => 'NamedColor Profile', 53 nkpf => 'Nikon Input Device Profile (NON-STANDARD!)', # (written by Nikon utilities) 51 54 ); 52 55 … … 58 61 NOTES => q{ 59 62 ICC profile information is used in many different file types including JPEG, 60 TIFF, PDF, PostScript, Photoshop, PNG, MIFF, PICT, QuickTime and some RAW61 formats. While the tags listed below are not individually writable, the63 TIFF, PDF, PostScript, Photoshop, PNG, MIFF, PICT, QuickTime, XCF and some 64 RAW formats. While the tags listed below are not individually writable, the 62 65 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. 64 69 }, 65 70 A2B0 => 'AToB0', … … 79 84 PrintConv => '$self->ConvertDateTime($val)', 80 85 }, 81 targ => 'CharTarget', 86 targ => { 87 Name => 'CharTarget', 88 ValueConv => 'length $val > 128 ? \$val : $val', 89 }, 82 90 chad => 'ChromaticAdaptation', 83 91 chrm => { 84 92 Name => 'Chromaticity', 93 Groups => { 1 => 'ICC_Profile#' }, #(just for the group list) 85 94 SubDirectory => { 86 95 TagTable => 'Image::ExifTool::ICC_Profile::Chromaticity', … … 96 105 }, 97 106 }, 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 }, 99 115 crdi => 'CRDInfo', #2 100 116 dmnd => { … … 142 158 psd2 => 'PostScript2CRD2', #2 143 159 ps2s => 'PostScript2CSA', #2 144 ps2i => 'PS2Ren teringIntent', #2160 ps2i => 'PS2RenderingIntent', #2 145 161 rXYZ => 'RedMatrixColumn', # (called RedColorant in ref 2) 146 162 rTRC => { … … 152 168 'bfd '=> { 153 169 Name => 'UCRBG', 154 Description => 'Under Color Removal &Black Gen.',170 Description => 'Under Color Removal and Black Gen.', 155 171 }, 156 172 tech => { … … 179 195 silk => 'Silkscreen', 180 196 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 181 201 }, 182 202 }, … … 189 209 }, 190 210 }, 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 191 249 # ColorSync custom tags (ref 3) 192 250 psvm => 'PS2CRDVMSize', … … 195 253 dscm => 'ProfileDescriptionML', 196 254 ndin => 'NativeDisplayInfo', 197 255 198 256 # Microsoft custom tags (ref http://msdn2.microsoft.com/en-us/library/ms536870.aspx) 199 257 MS00 => 'WCSProfiles', … … 269 327 Name => 'DeviceManufacturer', 270 328 Format => 'string[4]', 329 # KODA = Kodak 271 330 }, 272 331 52 => { 273 332 Name => 'DeviceModel', 274 333 Format => 'string[4]', 334 # ROMM = Refrence Output Medium Metric 275 335 }, 276 336 56 => { … … 302 362 Name => 'ProfileCreator', 303 363 Format => 'string[4]', 364 # KODA = Kodak 304 365 }, 305 366 84 => { … … 441 502 ); 442 503 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 ); 443 517 444 518 #------------------------------------------------------------------------------ … … 466 540 # curveType, lut16Type, lut8Type, lutAtoBType, lutBtoAType, namedColor2Type, 467 541 # parametricCurveType, profileSeqDescType, responseCurveSet16Type 542 # The multiLocalizedUnicodeType must be handled by the calling routine. 468 543 sub FormatICCTag($$$) 469 544 { … … 498 573 Get16u($dataPt, $offset+12), Get16u($dataPt, $offset+14), 499 574 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-ascii509 return $str;510 }511 575 } 512 576 # s15Fixed16ArrayType … … 556 620 } 557 621 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 628 sub 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; 558 680 } 559 681 … … 581 703 582 704 #------------------------------------------------------------------------------ 583 # Write ICC data record705 # Write ICC data as a block 584 706 # Inputs: 0) ExifTool object reference, 1) source dirInfo reference, 585 707 # 2) tag table reference … … 593 715 # (don't write AsShotICCProfile or CurrentICCProfile here) 594 716 return undef unless $dirName eq 'ICC_Profile'; 595 my $n ewValueHash = $exifTool->GetNewValueHash($Image::ExifTool::Extra{$dirName});596 return undef unless Image::ExifTool::IsOverwriting($n ewValueHash);597 my $val = Image::ExifTool::GetNewValues($n ewValueHash);717 my $nvHash = $exifTool->GetNewValueHash($Image::ExifTool::Extra{$dirName}); 718 return undef unless Image::ExifTool::IsOverwriting($nvHash); 719 my $val = Image::ExifTool::GetNewValues($nvHash); 598 720 $val = '' unless defined $val; 599 721 ++$exifTool->{CHANGED}; … … 665 787 my $dirLen = $$dirInfo{DirLen}; 666 788 my $verbose = $exifTool->Options('Verbose'); 667 my $raf; 789 790 return 0 if $dirLen < 4; 668 791 669 792 # extract binary ICC_Profile data block if binary mode or requested … … 736 859 my $subdir = $$tagInfo{SubDirectory}; 737 860 # 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 } 739 902 $value = FormatICCTag($dataPt, $valuePtr, $size) unless $subdir; 740 my $fmt;741 $fmt = substr($$dataPt, $valuePtr, 4) if $size > 4;742 903 $verbose and $exifTool->VerboseInfo($tagID, $tagInfo, 743 904 Table => $tagTablePtr, … … 783 944 $value = substr($$dataPt, $valuePtr, $size); 784 945 # treat unsupported formats as binary data 785 my $oldValueConv = $$tagInfo{ValueConv};786 946 $$tagInfo{ValueConv} = '\$val' unless defined $$tagInfo{ValueConv}; 787 947 $exifTool->FoundTag($tagInfo, $value); … … 814 974 =head1 AUTHOR 815 975 816 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)976 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 817 977 818 978 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ID3.pm
r16842 r24107 8 8 # References: 1) http://www.id3.org/ 9 9 # 2) http://www.mp3-tech.org/ 10 # 3) http://www.fortunecity.com/underworld/sonic/3/id3tag.html 10 11 #------------------------------------------------------------------------------ 11 12 … … 16 17 use Image::ExifTool qw(:DataAccess :Utils); 17 18 18 $VERSION = '1. 11';19 $VERSION = '1.28'; 19 20 20 21 sub ProcessID3v2($$$); 21 22 sub ProcessPrivate($$$); 23 sub ConvertID3v1Text($$); 22 24 23 25 # audio formats that we process after an ID3v2 header (in order) … … 30 32 ); 31 33 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!) 36 my %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 60 my %dateTimeConv = ( 61 ValueConv => 'require Image::ExifTool::XMP; Image::ExifTool::XMP::ConvertXMPDate($val)', 62 PrintConv => '$self->ConvertDateTime($val)', 63 ); 33 64 34 65 # This table is just for documentation purposes 35 66 %Image::ExifTool::ID3::Main = ( 36 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, # (not really)67 VARS => { NO_ID => 1 }, 37 68 NOTES => q{ 38 69 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. 40 78 }, 41 79 ID3v1 => { 42 80 Name => 'ID3v1', 43 81 SubDirectory => { TagTable => 'Image::ExifTool::ID3::v1' }, 82 }, 83 ID3v1Enh => { 84 Name => 'ID3v1_Enh', 85 SubDirectory => { TagTable => 'Image::ExifTool::ID3::v1_Enh' }, 44 86 }, 45 87 ID3v22 => { … … 186 228 124 => 'Euro-House', 187 229 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', 188 253 255 => 'None', 189 254 # ID3v2 adds some text short forms... … … 200 265 Name => 'Title', 201 266 Format => 'string[30]', 202 ValueConv => 'Image::ExifTool:: Latin2Charset($self,$val)',267 ValueConv => 'Image::ExifTool::ID3::ConvertID3v1Text($self,$val)', 203 268 }, 204 269 33 => { … … 206 271 Groups => { 2 => 'Author' }, 207 272 Format => 'string[30]', 208 ValueConv => 'Image::ExifTool:: Latin2Charset($self,$val)',273 ValueConv => 'Image::ExifTool::ID3::ConvertID3v1Text($self,$val)', 209 274 }, 210 275 63 => { 211 276 Name => 'Album', 212 277 Format => 'string[30]', 213 ValueConv => 'Image::ExifTool:: Latin2Charset($self,$val)',278 ValueConv => 'Image::ExifTool::ID3::ConvertID3v1Text($self,$val)', 214 279 }, 215 280 93 => { … … 221 286 Name => 'Comment', 222 287 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', 224 295 }, 225 296 127 => { … … 228 299 Format => 'int8u', 229 300 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]', 230 349 }, 231 350 ); … … 236 355 GROUPS => { 1 => 'ID3v2_2', 2 => 'Audio' }, 237 356 NOTES => q{ 238 ExifTool extracts mainly text-based tags from ID3v2 information. The tags239 in the tables below are those extracted by ExifTool, and don't represent a240 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.) 243 362 }, 244 363 CNT => 'PlayCounter', … … 247 366 PIC => { 248 367 Name => 'Picture', 368 Groups => { 2 => 'Image' }, 249 369 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' } }, 251 380 # POP => 'Popularimeter', 381 SLT => { 382 Name => 'SynchronizedLyricText', 383 Binary => 1, 384 }, 252 385 TAL => 'Album', 253 386 TBP => 'BeatsPerMinute', … … 292 425 TYE => { Name => 'Year', Groups => { 2 => 'Time' } }, 293 426 ULT => 'Lyrics', 294 WAF => 'File RUL',427 WAF => 'FileURL', 295 428 WAR => { Name => 'ArtistURL', Groups => { 2 => 'Author' } }, 296 429 WAS => 'SourceURL', … … 306 439 APIC => { 307 440 Name => 'Picture', 441 Groups => { 2 => 'Image' }, 308 442 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' } }, 310 453 COMM => 'Comment', 311 454 # COMR => 'Commercial', … … 327 470 # RBUF => 'RecommendedBufferSize', 328 471 # RVRB => 'Reverb', 329 # SYLT => 'SynchronizedLyricText', 472 SYLT => { 473 Name => 'SynchronizedLyricText', 474 Binary => 1, 475 }, 330 476 # SYTC => 'SynchronizedTempoCodes', 331 477 TALB => 'Album', 332 478 TBPM => 'BeatsPerMinute', 479 TCMP => { Name => 'Compilation', PrintConv => { 0 => 'No', 1 => 'Yes' } }, #PH (iTunes) 333 480 TCOM => 'Composer', 334 481 TCON =>{ … … 350 497 Name => 'Length', 351 498 ValueConv => '$val / 1000', 352 PrintConv => '"$val s ec"',499 PrintConv => '"$val s"', 353 500 }, 354 501 TMED => 'Media', … … 375 522 WCOM => 'CommercialURL', 376 523 WCOP => 'CopyrightURL', 377 WOAF => 'File RUL',524 WOAF => 'FileURL', 378 525 WOAR => { Name => 'ArtistURL', Groups => { 2 => 'Author' } }, 379 526 WOAS => 'SourceURL', … … 411 558 # SEEK => 'Seek', 412 559 # 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 }, 418 565 TIPL => 'InvolvedPeople', 419 566 TMCL => 'MusicianCredits', … … 445 592 ); 446 593 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 620 Image::ExifTool::AddCompositeTags('Image::ExifTool::ID3'); 621 447 622 # can't share tagInfo hashes between two tables, so we must make 448 623 # copies of the necessary hashes … … 452 627 next unless ref $id3v2_common{$tag} eq 'HASH'; 453 628 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; 454 632 $Image::ExifTool::ID3::v2_4{$tag} = \%tagInfo; 455 633 } 634 } 635 636 #------------------------------------------------------------------------------ 637 # Convert ID3v1 text to exiftool character set 638 # Inputs: 0) ExifTool object ref, 1) text string 639 # Returns: converted text 640 sub ConvertID3v1Text($$) 641 { 642 my ($exifTool, $val) = @_; 643 return $exifTool->Decode($val, $exifTool->Options('CharsetID3')); 456 644 } 457 645 … … 485 673 ); 486 674 # set group1 name 487 $exifTool->SetGroup 1($key, $$exifTool{ID3_Ver}) if $key;675 $exifTool->SetGroup($key, $$exifTool{ID3_Ver}) if $key; 488 676 } 489 677 … … 507 695 $val =~ s/\((\d+)\)/\($genre{$1}\)/g; 508 696 $val =~ s/(^|\/)(\d+)/$1$genre{$2}/g; 697 $val =~ s/^\(([^)]+)\)\1?$/$1/; # clean up by removing brackets and duplicates 509 698 return $val; 510 699 } … … 512 701 #------------------------------------------------------------------------------ 513 702 # 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) 515 706 # Returns: Decoded string in scalar context, or list of strings in list context 516 sub DecodeString($$ )707 sub DecodeString($$;$) 517 708 { 518 my ($exifTool, $val ) = @_;709 my ($exifTool, $val, $enc) = @_; 519 710 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 } 522 715 my @vals; 523 if ($enc == 0 ) { # ISO 8859-1716 if ($enc == 0 or $enc == 3) { # ISO 8859-1 or UTF-8 524 717 $val =~ s/\0+$//; # remove any null padding 525 $val = $exifTool->Latin2Charset($val);718 # (must split before converting because conversion routines truncate at null) 526 719 @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 } 531 723 } elsif ($enc == 1 or $enc == 2) { # UTF-16 with BOM, or UTF-16BE 532 724 my $bom = "\xfe\xff"; … … 543 735 } 544 736 $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}); 546 738 } 547 739 } else { … … 554 746 555 747 #------------------------------------------------------------------------------ 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 751 sub UnSyncSafe($) 559 752 { 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); 565 759 } 760 566 761 #------------------------------------------------------------------------------ 567 762 # Process ID3v2 information … … 578 773 579 774 $verbose and $exifTool->VerboseDir($tagTablePtr->{GROUPS}->{1}, 0, $size); 580 undef %warnedOnce;581 775 582 776 for (;;$offset+=$len) { … … 595 789 last if $id eq "\0\0\0\0"; 596 790 $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 } 597 810 } 598 811 last if $offset + $len > $size; … … 625 838 } 626 839 if ($flags{Encrypt}) { 627 WarnOnce($exifTool,'Encrypted frames currently not supported');840 $exifTool->WarnOnce('Encrypted frames currently not supported'); 628 841 next; 629 842 } … … 631 844 my $val = substr($$dataPt, $offset, $len); 632 845 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 638 850 if ($flags{GroupID}) { 639 851 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; 643 856 if ($flags{DataLen} or $flags{Compress}) { 644 857 length($val) >= 4 or $exifTool->Warn("Short $id frame"), next; 645 # ignore data length word858 $dataLen = unpack('N', $val); # save the data length word 646 859 $val = substr($val, 4); 647 860 } 861 # uncompress data 648 862 if ($flags{Compress}) { 649 863 if (eval 'require Compress::Zlib') { … … 658 872 } 659 873 } else { 660 WarnOnce($exifTool,'Install Compress::Zlib to decode compressed frames');874 $exifTool->WarnOnce('Install Compress::Zlib to decode compressed frames'); 661 875 next; 662 876 } 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; 663 883 } 664 884 $verbose and $exifTool->VerboseInfo($id, $tagInfo, … … 674 894 # decode data in this frame 675 895 # 896 my $lang; 676 897 my $valLen = length($val); # actual value length (after decompression, etc) 677 898 if ($id =~ /^(TXX|TXXX)$/) { … … 694 915 $exifTool->Warn("Invalid $id frame value"); 695 916 next; 696 } 917 } 697 918 $val = DecodeString($exifTool, $val); 698 919 $url =~ s/\0.*//; … … 702 923 } elsif ($id =~ /^(COM|COMM|ULT|USLT)$/) { 703 924 $valLen > 4 or $exifTool->Warn("Short $id frame"), next; 704 substr($val, 1, 3) = ''; # remove language code705 my @vals = DecodeString($exifTool, $val);925 $lang = substr($val,1,3); 926 my @vals = DecodeString($exifTool, substr($val,4), Get8u(\$val,0)); 706 927 foreach (0..1) { $vals[$_] = '' unless defined $vals[$_]; } 707 928 $val = length($vals[0]) ? "($vals[0]) $vals[1]" : $vals[1]; 708 929 } elsif ($id eq 'USER') { 709 930 $valLen > 4 or $exifTool->Warn('Short USER frame'), next; 710 substr($val, 1, 3) = ''; # remove language code711 $val = DecodeString($exifTool, $val);931 $lang = substr($val,1,3); 932 $val = DecodeString($exifTool, substr($val,4), Get8u(\$val,0)); 712 933 } elsif ($id =~ /^(CNT|PCNT)$/) { 713 934 $valLen >= 4 or $exifTool->Warn("Short $id frame"), next; … … 720 941 } elsif ($id =~ /^(PIC|APIC)$/) { 721 942 $valLen >= 4 or $exifTool->Warn("Short $id frame"), next; 943 my ($hdr, $attr); 722 944 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 } 724 950 # 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 } 727 960 } elsif ($id eq 'PRIV') { 728 961 # save version number to set group1 name for tag later … … 734 967 next; 735 968 } 969 if ($lang and $lang =~ /^[a-z]{3}$/i and $lang ne 'eng') { 970 $tagInfo = Image::ExifTool::GetLangInfo($tagInfo, lc $lang); 971 } 736 972 $exifTool->FoundTag($tagInfo, $val); 737 973 } 738 undef %warnedOnce;739 974 } 740 975 … … 744 979 # Returns: 1 on success, 0 if this file didn't contain ID3 information 745 980 # - also processes audio data if any ID3 information was found 746 # - sets ExifTool D ONE_ID3 to 1 when called, or to 2 if an ID3v1 trailer exists981 # - sets ExifTool DoneID3 to 1 when called, or to 2 if an ID3v1 trailer exists 747 982 sub ProcessID3($$) 748 983 { 749 984 my ($exifTool, $dirInfo) = @_; 750 751 return 0 if $exifTool->{D ONE_ID3}; # avoid infinite recursion752 $exifTool->{D ONE_ID3} = 1;985 986 return 0 if $exifTool->{DoneID3}; # avoid infinite recursion 987 $exifTool->{DoneID3} = 1; 753 988 754 989 # allow this to be called with either RAF or DataPt 755 990 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); 757 992 my $rtnVal = 0; 758 993 my $hdrEnd = 0; 994 my $id3Len = 0; 759 995 760 996 # read first 3 bytes of file … … 768 1004 $raf->Read($hBuff, 7) == 7 or $exifTool->Warn('Short ID3 header'), last; 769 1005 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; 771 1008 my $verStr = sprintf("2.%d.%d", $vers >> 8, $vers & 0xff); 772 1009 if ($vers >= 0x0500) { … … 774 1011 last; 775 1012 } 776 $size = ($size & 0x0000007f) |777 (($size & 0x00007f00) >> 1) |778 (($size & 0x007f0000) >> 2) |779 (($size & 0x7f000000) >> 3);780 1013 unless ($raf->Read($hBuff, $size) == $size) { 781 1014 $exifTool->Warn('Truncated ID3 data'); 782 1015 last; 783 1016 } 784 if ($flags & 0x80) { 1017 # this flag only indicates use of unsynchronized frames in ID3v2.4 1018 if ($flags & 0x80 and $vers < 0x0400) { 785 1019 # reverse the unsynchronization 786 1020 $hBuff =~ s/\xff\x00/\xff/g; … … 810 1044 DirName => "ID3v$verStr", 811 1045 ); 1046 $id3Len += length($hBuff) + 10; 812 1047 if ($vers >= 0x0400) { 813 1048 $tagTablePtr = GetTagTable('Image::ExifTool::ID3::v2_4'); … … 824 1059 # 825 1060 if ($raf->Seek(-128, 2) and $raf->Read($tBuff, 128) == 128 and $tBuff =~ /^TAG/) { 826 $exifTool->{D ONE_ID3} = 2; # set to 2 as flag that trailer exists1061 $exifTool->{DoneID3} = 2; # set to 2 as flag that trailer exists 827 1062 %id3Trailer = ( 828 1063 DataPt => \$tBuff, … … 831 1066 DirLen => length($tBuff), 832 1067 ); 1068 $id3Len += length($tBuff); 833 1069 $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 } 834 1074 } 835 1075 # … … 839 1079 # first process audio data if it exists 840 1080 if ($$dirInfo{RAF}) { 841 my $ type = $exifTool->{FILE_TYPE};# save file type1081 my $oldType = $exifTool->{FILE_TYPE}; # save file type 842 1082 # 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; 846 1086 foreach $type (@types) { 847 1087 # seek to end of ID3 header … … 857 1097 use strict 'refs'; 858 1098 } 859 $exifTool->{FILE_TYPE} = $ type;# restore original file type1099 $exifTool->{FILE_TYPE} = $oldType; # restore original file type 860 1100 } 861 1101 # 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); 863 1105 # process ID3v2 header if it exists 864 1106 if (%id3Header) { … … 872 1114 $tagTablePtr = GetTagTable('Image::ExifTool::ID3::v1'); 873 1115 $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 } 874 1125 } 875 1126 } … … 888 1139 889 1140 # 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; 893 1143 } 894 1144 my $raf = $$dirInfo{RAF}; … … 897 1147 # 898 1148 # extract information from first audio/video frame headers 899 # (if found in the first 256bytes)1149 # (if found in the first $scanLen bytes) 900 1150 # 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)) { 902 1154 require Image::ExifTool::MPEG; 903 1155 if ($buff =~ /\0\0\x01(\xb3|\xc0)/) { 904 1156 # look for A/V headers in first 64kB 905 1157 my $buf2; 906 $raf->Read($buf2, 65280) and $buff .= $buf2;907 $rtnVal = 1 if Image::ExifTool::MPEG::P rocessMPEGAudioVideo($exifTool, \$buff);1158 $raf->Read($buf2, 0x10000 - $scanLen) and $buff .= $buf2; 1159 $rtnVal = 1 if Image::ExifTool::MPEG::ParseMPEGAudioVideo($exifTool, \$buff); 908 1160 } else { 909 # look for audio frame sync in first 256bytes910 $rtnVal = 1 if Image::ExifTool::MPEG::P rocessMPEGAudio($exifTool, \$buff);1161 # look for audio frame sync in first $scanLen bytes 1162 $rtnVal = 1 if Image::ExifTool::MPEG::ParseMPEGAudio($exifTool, \$buff); 911 1163 } 912 1164 } … … 934 1186 =head1 AUTHOR 935 1187 936 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1188 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 937 1189 938 1190 This library is free software; you can redistribute it and/or modify it … … 947 1199 =item L<http://www.mp3-tech.org/> 948 1200 1201 =item L<http://www.fortunecity.com/underworld/sonic/3/id3tag.html> 1202 949 1203 =back 950 1204 -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/IPTC.pm
r16842 r24107 4 4 # Description: Read IPTC meta information 5 5 # 6 # Revisions: Jan. 08/ 03 - P. Harvey Created7 # Feb. 05/ 04 - P. Harvey Added support for records other than 26 # Revisions: Jan. 08/2003 - P. Harvey Created 7 # Feb. 05/2004 - P. Harvey Added support for records other than 2 8 8 # 9 9 # References: 1) http://www.iptc.org/IIM/ … … 15 15 use vars qw($VERSION $AUTOLOAD %iptcCharset); 16 16 17 $VERSION = '1. 23';17 $VERSION = '1.42'; 18 18 19 19 %iptcCharset = ( 20 20 "\x1b%G" => 'UTF8', 21 21 # 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 23 23 # "\x1b,A" => 'Latin', # G0 = ISO 8859-1 (similar to Latin1, but codes 0x80-0x9f are missing) 24 24 # "\x1b-A" => 'Latin', # G1 " … … 105 105 9 => { 106 106 Name => 'IPTCPostObjectData', 107 Groups => { 1 => 'IPTC#' }, #(just so this shows up in group list) 107 108 SubDirectory => { 108 109 TagTable => 'Image::ExifTool::IPTC::PostObjectData', 110 }, 111 }, 112 240 => { 113 Name => 'IPTCFotoStation', 114 SubDirectory => { 115 TagTable => 'Image::ExifTool::IPTC::FotoStation', 109 116 }, 110 117 }, … … 120 127 Name => 'EnvelopeRecordVersion', 121 128 Format => 'int16u', 129 Mandatory => 1, 122 130 }, 123 131 5 => { … … 154 162 Name => 'EnvelopePriority', 155 163 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 }, 156 176 }, 157 177 70 => { … … 178 198 convenience. Either string may be used when writing. The value of this tag 179 199 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, 182 207 Format => 'string[0,32]', 183 208 # convert ISO 2022 escape sequences to a more readable format … … 208 233 Name => 'ApplicationRecordVersion', 209 234 Format => 'int16u', 235 Mandatory => 1, 210 236 }, 211 237 3 => { … … 229 255 Name => 'EditorialUpdate', 230 256 Format => 'digits[2]', 257 PrintConv => { 258 '01' => 'Additional language', 259 }, 231 260 }, 232 261 10 => { 233 262 Name => 'Urgency', 234 263 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 }, 235 276 }, 236 277 12 => { … … 454 495 Format => 'string[0,2000]', 455 496 }, 456 121 => { # (format not certain)497 121 => { 457 498 Name => 'LocalCaption', 458 Format => 'string[0,256]', 499 Format => 'string[0,256]', # (guess) 459 500 Notes => q{ 460 501 I haven't found a reference for the format of tags 121, 184-188 and 461 502 225-232, so I have just make them writable as strings with 462 503 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 464 505 }, 465 506 }, … … 472 513 125 => { 473 514 Name => 'RasterizedCaption', 474 Format => ' string[7360]',515 Format => 'undef[7360]', 475 516 Binary => 1, 476 517 }, … … 533 574 Format => 'string[0,64]', 534 575 }, 535 184 => { # (format not certain)576 184 => { 536 577 Name => 'JobID', 537 Format => 'string[0,64]', 538 }, 539 185 => { # (format not certain)578 Format => 'string[0,64]', # (guess) 579 }, 580 185 => { 540 581 Name => 'MasterDocumentID', 541 Format => 'string[0,256]', 542 }, 543 186 => { # (format not certain)582 Format => 'string[0,256]', # (guess) 583 }, 584 186 => { 544 585 Name => 'ShortDocumentID', 545 Format => 'string[0,64]', 546 }, 547 187 => { # (format not certain)586 Format => 'string[0,64]', # (guess) 587 }, 588 187 => { 548 589 Name => 'UniqueDocumentID', 549 Format => 'string[0,128]', 550 }, 551 188 => { # (format not certain)590 Format => 'string[0,128]', # (guess) 591 }, 592 188 => { 552 593 Name => 'OwnerID', 553 Format => 'string[0,128]', 594 Format => 'string[0,128]', # (guess) 554 595 }, 555 596 200 => { … … 567 608 Name => 'ObjectPreviewData', 568 609 Groups => { 2 => 'Image' }, 569 Format => ' string[0,256000]',610 Format => 'undef[0,256000]', 570 611 Binary => 1, 571 612 }, … … 586 627 }, 587 628 }, 588 225 => { # (format not certain)629 225 => { 589 630 Name => 'ClassifyState', 590 Format => 'string[0,64]', 591 }, 592 228 => { # (format not certain)631 Format => 'string[0,64]', # (guess) 632 }, 633 228 => { 593 634 Name => 'SimilarityIndex', 594 Format => 'string[0,32]', 595 }, 596 230 => { # (format not certain)635 Format => 'string[0,32]', # (guess) 636 }, 637 230 => { 597 638 Name => 'DocumentNotes', 598 Format => 'string[0,1024]', 599 }, 600 231 => { # (format not certain)639 Format => 'string[0,1024]', # (guess) 640 }, 641 231 => { 601 642 Name => 'DocumentHistory', 602 Format => 'string[0,256]', 603 }, 604 232 => { # (format not certain)643 Format => 'string[0,256]', # (guess) 644 }, 645 232 => { 605 646 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', 607 654 }, 608 655 ); … … 617 664 Name => 'NewsPhotoVersion', 618 665 Format => 'int16u', 666 Mandatory => 1, 619 667 }, 620 668 10 => { … … 842 890 ); 843 891 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 926 Image::ExifTool::AddCompositeTags('Image::ExifTool::IPTC'); 927 844 928 845 929 #------------------------------------------------------------------------------ … … 863 947 return $val; 864 948 } 865 949 866 950 #------------------------------------------------------------------------------ 867 951 # Handle CodedCharacterSet 868 952 # Inputs: 0) ExifTool ref, 1) CodedCharacterSet value 869 # Returns: externalcharacter set if translation required (or 'bad' if unknown)953 # Returns: IPTC character set if translation required (or 'bad' if unknown) 870 954 sub HandleCodedCharset($$) 871 955 { 872 956 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 } 883 965 } 966 # no need to translate if Charset is the same 967 undef $xlat if $xlat eq $exifTool->Options('Charset'); 884 968 return $xlat; 885 969 } … … 887 971 #------------------------------------------------------------------------------ 888 972 # 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 890 974 # 3) flag set to decode (read) value from IPTC 891 975 # Updates value on return … … 893 977 { 894 978 my ($exifTool, $valPtr, $xlatPtr, $read) = @_; 895 my $escaped;896 979 if ($$xlatPtr eq 'bad') { 897 980 $exifTool->Warn('Some IPTC characters not converted (unsupported CodedCharacterSet)'); 898 981 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 { 900 987 # 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)'); 913 989 } 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 996 sub IsStandardIPTC($) 997 { 998 my $path = shift; 999 return $path =~ /^(JPEG-APP13-Photoshop-IPTC|TIFF-IFD0-IPTC|PSD-IPTC|MIE-IPTC)$/ 914 1000 } 915 1001 … … 928 1014 my $verbose = $exifTool->Options('Verbose'); 929 1015 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 936 1018 $verbose and $dirInfo and $exifTool->VerboseDir('IPTC', 0, $$dirInfo{DirLen}); 1019 937 1020 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 938 1042 my $dirCount = ($exifTool->{DIR_COUNT}->{IPTC} || 0) + 1; 939 1043 $exifTool->{DIR_COUNT}->{IPTC} = $dirCount; 940 1044 $exifTool->{SET_GROUP1} = '+' . $dirCount if $dirCount > 1; 941 1045 } 1046 # begin by assuming default IPTC encoding 1047 my $xlat = $exifTool->Options('CharsetIPTC'); 1048 undef $xlat if $xlat eq $exifTool->Options('Charset'); 1049 942 1050 # quick check for improperly byte-swapped IPTC 943 1051 if ($dirLen >= 4 and substr($$dataPt, $pos, 1) ne "\x1c" and … … 967 1075 my $tableInfo = $tagTablePtr->{$rec}; 968 1076 unless ($tableInfo) { 969 $exifTool->Warn("Unrecognized IPTC record : $rec");1077 $exifTool->Warn("Unrecognized IPTC record $rec, subsequent records ignored"); 970 1078 last; # stop now because we're probably reading garbage 971 1079 } … … 1010 1118 my $tagInfo = $exifTool->GetTagInfo($recordPtr, $tag); 1011 1119 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) 1012 1122 $format = $$tagInfo{Format} if $tagInfo; 1013 1123 # use logic to determine format if not specified … … 1025 1135 } 1026 1136 } elsif ($format =~ /^string/) { 1137 $val =~ s/\0+$//; # some braindead softwares add null terminators 1027 1138 if ($rec == 1) { 1028 1139 # handle CodedCharacterSet tag … … 1033 1144 TranslateCodedString($exifTool, \$val, \$xlat, 1); 1034 1145 } 1035 } elsif ($format !~ /^digits/) { 1146 } elsif ($format =~ /^digits/) { 1147 $val =~ s/\0+$//; 1148 } elsif ($format !~ /^undef/) { 1036 1149 warn("Invalid IPTC format: $format"); 1037 1150 } … … 1045 1158 Start => $pos, 1046 1159 Extra => ", $recordName record", 1160 Format => $format, 1047 1161 ); 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; 1057 1163 $success = 1; 1058 1164 … … 1084 1190 =head1 AUTHOR 1085 1191 1086 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1192 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 1087 1193 1088 1194 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JPEG.pm
r16842 r24107 10 10 use strict; 11 11 use vars qw($VERSION); 12 13 $VERSION = '1.07'; 12 use Image::ExifTool qw(:DataAccess :Utils); 13 14 $VERSION = '1.13'; 15 16 sub ProcessScalado($$$); 17 sub ProcessOcad($$$); 14 18 15 19 # (this main JPEG table is for documentation purposes only) … … 28 32 Condition => '$$valPt =~ /^(II|MM).{4}HEAPJPGM/s', 29 33 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' }, 30 42 }], 31 43 APP1 => [{ … … 34 46 SubDirectory => { TagTable => 'Image::ExifTool::Exif::Main' }, 35 47 }, { 48 Name => 'ExtendedXMP', 49 Condition => '$$valPt =~ m{^http://ns.adobe.com/xmp/extension/\0}', 50 SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' }, 51 }, { 36 52 Name => 'XMP', 37 53 Condition => '$$valPt =~ /^http/ or $$valPt =~ /<exif:/', 38 54 SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' }, 55 }, { 56 Name => 'QVCI', 57 Condition => '$$valPt =~ /^QVCI\0/', 58 SubDirectory => { TagTable => 'Image::ExifTool::Casio::QVCI' }, 39 59 }], 40 60 APP2 => [{ … … 46 66 Condition => '$$valPt =~ /^FPXR\0/', 47 67 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 => [{ 50 78 Name => 'Meta', 51 79 Condition => '$$valPt =~ /^(Meta|META|Exif)\0\0/', 52 80 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 }], 54 102 APP5 => { 55 103 Name => 'RMETA', … … 57 105 SubDirectory => { TagTable => 'Image::ExifTool::Ricoh::RMETA' }, 58 106 }, 59 APP6 => {107 APP6 => [{ 60 108 Name => 'EPPIM', 61 109 Condition => '$$valPt =~ /^EPPIM\0/', 62 110 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 }], 64 120 APP8 => { 65 121 Name => 'SPIFF', … … 104 160 # note: flag as writable for documentation, but it won't show up 105 161 # in the TagLookup as writable because there is no WRITE_PROC 106 Writable => '1',162 Writable => 1, 107 163 }, 108 164 SOF => { 109 165 Name => 'StartOfFrame', 110 166 SubDirectory => { TagTable => 'Image::ExifTool::JPEG::SOF' }, 167 }, 168 DQT => { 169 Name => 'DefineQuantizationTable', 170 Notes => 'used to calculate the Extra:JPEGDigest tag value', 111 171 }, 112 172 Trailer => [{ … … 167 227 This information is found in APP8 of SPIFF-style JPEG images (the "official" 168 228 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. 170 231 }, 171 232 0 => { … … 294 355 ); 295 356 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 492 sub 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 513 sub 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 296 538 1; # end 297 539 … … 314 556 =head1 AUTHOR 315 557 316 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)558 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 317 559 318 560 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JVC.pm
r16842 r24107 13 13 use Image::ExifTool::Exif; 14 14 15 $VERSION = '1.0 1';15 $VERSION = '1.02'; 16 16 17 17 sub ProcessJVCText($$$); … … 24 24 NOTES => 'JVC EXIF maker note tags.', 25 25 #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 }, 27 31 0x0003 => { #PH 28 32 Name => 'Quality', … … 72 76 return 0; 73 77 } 74 my $pos = 0;75 78 while ($data =~ m/([A-Z]+):(.{3,4})/sg) { 76 79 my ($tag, $val) = ($1, $2); … … 114 117 =head1 AUTHOR 115 118 116 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)119 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 117 120 118 121 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Jpeg2000.pm
r16842 r24107 17 17 use Image::ExifTool qw(:DataAccess :Utils); 18 18 19 $VERSION = '1.1 2';19 $VERSION = '1.16'; 20 20 21 21 sub ProcessJpeg2000Box($$$); … … 39 39 IFD0 => 'UUID-EXIF', 40 40 XMP => 'UUID-XMP', 41 'UUID-IPTC' => 'JP2', 42 'UUID-EXIF' => 'JP2', 43 'UUID-XMP' => 'JP2', 41 44 # jp2h => 'JP2', (not yet functional) 42 45 # ICC_Profile => 'jp2h', (not yet functional) … … 61 64 ); 62 65 63 # JPEG 2000 "box" (ie. segment) names66 # JPEG 2000 "box" (ie. atom) names 64 67 %Image::ExifTool::Jpeg2000::Main = ( 65 68 GROUPS => { 2 => 'Image' }, … … 73 76 "jP\x1a\x1a" => 'JP2Signature', # (ref 2) 74 77 prfl => 'Profile', 75 ftyp => { Name => 'FileType', Priority => 0 }, 78 ftyp => { 79 Name => 'FileType', 80 SubDirectory => { TagTable => 'Image::ExifTool::Jpeg2000::FileType' }, 81 }, 76 82 rreq => 'ReaderRequirements', 77 83 jp2h => { … … 192 198 ProcessProc => \&Image::ExifTool::ProcessTIFF, 193 199 WriteProc => \&Image::ExifTool::WriteTIFF, 200 DirName => 'EXIF', 194 201 Start => '$valuePtr + 16', 195 202 }, … … 274 281 8 => 'JBIG2', 275 282 }, 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', 276 311 }, 277 312 ); … … 344 379 my $tagTable = GetTagTable($$subdir{TagTable}); 345 380 my %dirInfo = ( 346 DirName => $ dirName,381 DirName => $$subdir{DirName} || $dirName, 347 382 Parent => 'JP2', 348 383 ); … … 464 499 if (defined $tagInfo and not $tagInfo) { 465 500 # 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); 467 502 $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $boxID, \$tmpVal); 468 503 } … … 497 532 DirStart => $subdirStart, 498 533 DirLen => $subdirLen, 499 DirName => $$ tagInfo{Name},534 DirName => $$subdir{DirName} || $$tagInfo{Name}, 500 535 OutFile => $outfile, 501 536 Base => $dataPos + $subdirStart, … … 555 590 my $raf = $$dirInfo{RAF}; 556 591 my $outfile = $$dirInfo{OutFile}; 557 my $rtnVal = 0;558 592 my $hdr; 559 593 … … 570 604 $$exifTool{AddJp2Dirs} = \%addDirs; 571 605 } 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); 573 614 } 574 615 SetByteOrder('MM'); # JPEG 2000 files are big-endian … … 601 642 =head1 AUTHOR 602 643 603 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)644 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 604 645 605 646 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Kodak.pm
r16842 r24107 8 8 # References: 1) http://search.cpan.org/dist/Image-MetaData-JPEG/ 9 9 # 2) http://www.ozhiker.com/electronics/pjmt/jpeg_info/meta.html 10 # 3) http://www.cybercom.net/~dcoffin/dcraw/ 10 11 # 11 12 # Notes: There really isn't much public information about Kodak formats. … … 22 23 use Image::ExifTool::Exif; 23 24 24 $VERSION = '1. 10';25 $VERSION = '1.27'; 25 26 26 27 sub ProcessKodakIFD($$$); 28 sub ProcessKodakText($$$); 27 29 sub WriteKodakIFD($$$); 28 30 … … 103 105 Name => 'MeteringMode', 104 106 PrintConv => { #PH 105 0 => 'Multi- pattern',106 1 => 'Center- Weighted',107 0 => 'Multi-segment', 108 1 => 'Center-weighted average', 107 109 2 => 'Spot', 108 110 }, … … 121 123 ValueConvInv => '$val * 1e5', 122 124 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 123 PrintConvInv => ' eval $val',125 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 124 126 }, 125 127 0x24 => { … … 129 131 ValueConvInv => '$val * 1000', 130 132 PrintConv => '$val > 0 ? "+$val" : $val', 131 PrintConvInv => ' eval $val',133 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 132 134 }, 133 135 0x26 => { … … 255 257 Name => 'Sharpness', 256 258 Format => 'int8s', 257 PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)', 258 PrintConvInv => '$val=~/normal/i ? 0 : $val', 259 %Image::ExifTool::Exif::printParameter, 259 260 }, 260 261 ); … … 329 330 Name => 'Sharpness', 330 331 Format => 'int8s', 331 PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)', 332 PrintConvInv => '$val=~/normal/i ? 0 : $val', 332 %Image::ExifTool::Exif::printParameter, 333 333 }, 334 334 0x38 => { … … 338 338 ValueConvInv => '$val * 1e5', 339 339 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 340 PrintConvInv => ' eval $val',340 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 341 341 }, 342 342 0x3c => { … … 383 383 ValueConvInv => '$val * 1e5', 384 384 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 385 PrintConvInv => ' eval $val',385 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 386 386 }, 387 387 0x1a => { … … 447 447 ValueConvInv => '$val * 1e5', 448 448 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 449 PrintConvInv => ' eval $val',449 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 450 450 }, 451 451 0x14 => { … … 511 511 512 512 # Kodak IFD-format maker notes (ref PH) 513 %Image::ExifTool::Kodak:: IFD= (513 %Image::ExifTool::Kodak::Type8 = ( 514 514 WRITE_PROC => \&Image::ExifTool::Exif::WriteExif, 515 515 CHECK_PROC => \&Image::ExifTool::Exif::CheckExif, 516 516 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 517 517 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 => [{ 524 528 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 526 541 Flags => 'SubIFD', 527 542 SubDirectory => { 528 543 TagTable => 'Image::ExifTool::Kodak::SubIFD0', 529 544 Start => '$val', 530 }, 531 }, 545 # (odd but true: the Base for this SubIFD is different than 0xfc01-0xfc06) 546 }, 547 }], 532 548 # 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 => [{ 535 552 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 537 564 Flags => 'SubIFD', 538 565 SubDirectory => { … … 541 568 Base => '$start', 542 569 }, 543 } ,544 0xfc02 => {570 }], 571 0xfc02 => [{ 545 572 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 547 584 Flags => 'SubIFD', 548 585 SubDirectory => { … … 551 588 Base => '$start', 552 589 }, 553 } ,554 0xfc03 => {590 }], 591 0xfc03 => [{ 555 592 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 557 604 Flags => 'SubIFD', 558 605 SubDirectory => { … … 561 608 Base => '$start', 562 609 }, 563 } ,610 }], 564 611 # (SubIFD4 has the pointer zeroed in my samples, but support it 565 612 # in case it is used by future models -- ignored if pointer is zero) 566 0xfc04 => {613 0xfc04 => [{ 567 614 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 569 626 Flags => 'SubIFD', 570 627 SubDirectory => { … … 573 630 Base => '$start', 574 631 }, 575 } ,576 0xfc05 => {632 }], 633 0xfc05 => [{ 577 634 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 579 646 Flags => 'SubIFD', 580 647 SubDirectory => { … … 583 650 Base => '$start', 584 651 }, 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 }, 585 682 }, 586 683 0xff00 => { 587 684 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 589 687 Flags => 'SubIFD', 590 688 SubDirectory => { 591 689 TagTable => 'Image::ExifTool::Kodak::CameraInfo', 592 690 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] 595 837 ); 596 838 … … 600 842 CHECK_PROC => \&Image::ExifTool::Exif::CheckExif, 601 843 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.', 603 845 0xfa02 => { 604 846 Name => 'SceneMode', 605 847 Writable => 'int16u', 848 Notes => 'may not be valid for some models', # ie. M580? 606 849 PrintConv => { 607 850 1 => 'Sport', … … 667 910 ValueConvInv => '$val * 1e5', 668 911 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 669 PrintConvInv => ' eval $val',912 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 670 913 }, 671 914 0xfa2e => { … … 810 1053 ValueConvInv => '$val * 1e6', 811 1054 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 812 PrintConvInv => ' eval $val',1055 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 813 1056 }, 814 1057 0xf105 => { … … 837 1080 # 0x1002 - related to focal length (1=wide, 32=full zoom) 838 1081 # 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 }, 839 1177 ); 840 1178 … … 861 1199 PrintConvInv => '$val=~s/ ?x//; $val', 862 1200 }, 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.', 863 1210 ); 864 1211 … … 921 1268 ValueConvInv => '$val * 1e6', 922 1269 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 923 PrintConvInv => ' eval $val',1270 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 924 1271 }, 925 1272 0xfd06 => { … … 935 1282 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 936 1283 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 }, 937 1490 ); 938 1491 … … 940 1493 %Image::ExifTool::Kodak::Meta = ( 941 1494 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 942 1498 NOTES => q{ 943 1499 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 this945 s egment is similar to the APP1 "Exif" segment, but a different set of tags946 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. 947 1503 }, 948 1504 0xc350 => 'FilmProductCode', … … 951 1507 0xc353 => { 952 1508 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)', 954 1512 }, 955 1513 0xc354 => { 956 1514 Name => 'SerialNumber', 1515 Writable => 'undef', 957 1516 Groups => { 2 => 'Camera' }, 1517 RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)', #PH 1518 RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)', 958 1519 }, 959 1520 0xc355 => 'UserSelectGroupTitle', … … 969 1530 0xc35f => 'SBAInputImageColorspace', 970 1531 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 }, 973 1540 0xc363 => 'ImageRotationStatus', 974 1541 0xc364 => 'RollGuidElements', … … 981 1548 Name => 'KodakEffectsIFD', 982 1549 Flags => 'SubIFD', 1550 Groups => { 1 => 'KodakEffectsIFD' }, 983 1551 SubDirectory => { 984 1552 TagTable => 'Image::ExifTool::Kodak::SpecialEffects', … … 989 1557 Name => 'KodakBordersIFD', 990 1558 Flags => 'SubIFD', 1559 Groups => { 1 => 'KodakBordersIFD' }, 991 1560 SubDirectory => { 992 1561 TagTable => 'Image::ExifTool::Kodak::Borders', … … 1005 1574 %Image::ExifTool::Kodak::SpecialEffects = ( 1006 1575 GROUPS => { 0 => 'Meta', 1 => 'KodakEffectsIFD', 2 => 'Image'}, 1576 WRITE_PROC => \&Image::ExifTool::Exif::WriteExif, 1007 1577 0 => 'DigitalEffectsVersion', 1008 1578 1 => { … … 1016 1586 %Image::ExifTool::Kodak::Borders = ( 1017 1587 GROUPS => { 0 => 'Meta', 1 => 'KodakBordersIFD', 2 => 'Image'}, 1588 WRITE_PROC => \&Image::ExifTool::Exif::WriteExif, 1018 1589 0 => 'BordersVersion', 1019 1590 1 => { … … 1027 1598 ); 1028 1599 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 1029 1644 # Kodak composite tags 1030 1645 %Image::ExifTool::Kodak::Composite = ( 1646 GROUPS => { 2 => 'Camera' }, 1031 1647 DateCreated => { 1032 1648 Groups => { 2 => 'Time' }, … … 1037 1653 ValueConv => '"$val[0]:$val[1]"', 1038 1654 }, 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 }, 1039 1691 ); 1040 1692 1041 1693 # add our composite tags 1042 1694 Image::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 1701 sub 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 1724 sub 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 } 1043 1767 1044 1768 #------------------------------------------------------------------------------ … … 1052 1776 return 1 if $dirStart <= 0 or $dirStart + 2 > $$dirInfo{DataLen}; 1053 1777 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 } 1055 1782 $$dirInfo{DirStart} += 2; # skip byte order mark 1056 1783 $$dirInfo{DirLen} -= 2; 1057 1784 if ($exifTool->{HTML_DUMP}) { 1058 1785 my $base = $$dirInfo{Base} + $$dirInfo{DataPos}; 1059 $exifTool->H tmlDump($dirStart+$base, 2, "Byte Order Mark");1786 $exifTool->HDump($dirStart+$base, 2, "Byte Order Mark"); 1060 1787 } 1061 1788 return Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr); … … 1105 1832 =head1 AUTHOR 1106 1833 1107 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1834 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 1108 1835 1109 1836 This library is free software; you can redistribute it and/or modify it … … 1118 1845 =item L<http://www.ozhiker.com/electronics/pjmt/jpeg_info/meta.html> 1119 1846 1847 =item L<http://www.cybercom.net/~dcoffin/dcraw/> 1848 1120 1849 =item (...plus lots of testing with my daughter's CX4200!) 1121 1850 -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/KyoceraRaw.pm
r16842 r24107 13 13 use strict; 14 14 use vars qw($VERSION); 15 use Image::ExifTool qw(:DataAccess );15 use Image::ExifTool qw(:DataAccess :Utils); 16 16 17 $VERSION = '1.0 0';17 $VERSION = '1.02'; 18 18 19 19 sub ProcessRAW($$); … … 44 44 0x21 => { #1 45 45 Name => 'DateTimeOriginal', 46 Description => 'Date/Time Original', 46 47 Groups => { 2 => 'Time' }, 47 48 Format => 'string[20]', 48 49 ValueConv => \&ReverseString, 50 PrintConv => '$self->ConvertDateTime($val)', 49 51 }, 50 52 0x34 => { … … 96 98 Name => 'FocalLength', 97 99 Format => 'int32u', 98 PrintConv => '"$ {val}mm"',100 PrintConv => '"$val mm"', 99 101 }, 100 102 0x7c => { … … 127 129 DirLen => $size, 128 130 ); 129 my $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::KyoceraRaw::Main');131 my $tagTablePtr = GetTagTable('Image::ExifTool::KyoceraRaw::Main'); 130 132 $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr); 131 133 return 1; … … 151 153 =head1 AUTHOR 152 154 153 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)155 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 154 156 155 157 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Leaf.pm
r16842 r24107 14 14 use Image::ExifTool::Exif; 15 15 16 $VERSION = '1.0 1';16 $VERSION = '1.03'; 17 17 18 18 sub ProcessLeaf($$$); … … 22 22 GROUPS => { 0 => 'Leaf', 2 => 'Camera' }, 23 23 NOTES => q{ 24 These tags are found in .MOS images from Leaf digital camera backs as25 written by Creo Leaf Capture. They exist within the Leaf-specific directory26 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 if28 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. 29 29 }, 30 30 icc_camera_profile => { … … 336 336 # table for Leaf SubIFD entries 337 337 %Image::ExifTool::Leaf::SubIFD = ( 338 GROUPS => { 0 => ' EXIF', 1 => 'LeafSubIFD', 2 => 'Image'},338 GROUPS => { 0 => 'MakerNotes', 1 => 'LeafSubIFD', 2 => 'Image'}, 339 339 WRITE_PROC => \&Image::ExifTool::Exif::WriteExif, 340 340 NOTES => q{ 341 Leaf also writes a TIFF-format sub-IFD inside IFD0 of a MOS image. No tags 342 inthis sub-IFD are currently known, except for tag 0x8606 which really343 shouldn't be here anyway (so it doesn't appear in the table below) because344 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. 345 345 }, 346 346 ); … … 472 472 $exifTool->ProcessDirectory(\%subdirInfo, $subTable); 473 473 } else { 474 $val =~ tr/\n/ /; # remove newlines from value 474 $val =~ tr/\n/ /; # translate newlines to spaces 475 $val =~ s/\0+$//; # remove null terminators 475 476 $exifTool->FoundTag($tagInfo, $val); 476 477 } … … 502 503 =head1 AUTHOR 503 504 504 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)505 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 505 506 506 507 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIE.pm
r16842 r24107 15 15 use Image::ExifTool::GPS; 16 16 17 $VERSION = '1. 15';17 $VERSION = '1.34'; 18 18 19 19 sub ProcessMIE($$); … … 80 80 'MIE-GPS' => 'MIE-Geo', 81 81 'MIE-UTM' => 'MIE-Geo', 82 'MIE-Canon' => 'MIE-MakerNotes', 82 83 EXIF => 'MIE-Meta', 83 84 XMP => 'MIE-Meta', … … 85 86 ICC_Profile => 'MIE-Meta', 86 87 ID3 => 'MIE-Meta', 88 CanonVRD => 'MIE-Canon', 87 89 IFD0 => 'EXIF', 88 90 IFD1 => 'IFD0', … … 102 104 ); 103 105 my %dateInfo = ( 104 Groups => { 2 => 'Time' },105 106 Shift => 'Time', 106 107 PrintConv => '$self->ConvertDateTime($val)', 107 PrintConvInv => '$ val',108 PrintConvInv => '$self->InverseDateTime($val)', 108 109 ); 109 110 my %noYes = ( 0 => 'No', 1 => 'Yes' ); … … 155 156 Name => 'SubfileType', 156 157 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 163 161 }, 164 162 }, … … 167 165 Notes => 'version 1.1 is assumed if not specified', 168 166 }, 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 }, 171 175 '2MIME' => { Name => 'SubfileMIMEType' }, 172 176 Meta => { … … 291 295 Contributors=> { Groups => { 2 => 'Author' }, List => 1 }, 292 296 Copyright => { Groups => { 2 => 'Author' } }, 293 CreateDate => { %dateInfo },297 CreateDate => { Groups => { 2 => 'Time' }, %dateInfo }, 294 298 EMail => { Groups => { 2 => 'Author' } }, 295 299 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 }, 298 307 Phone => { Name => 'PhoneNumber', Groups => { 2 => 'Author' } }, 299 308 References => { List => 1 }, … … 406 415 Notes => q{'km/h' unless 'mi/h', 'm/s' or 'kn' specified}, 407 416 }, 408 DateTime => { Name => 'GPSDateTime', %dateInfo },417 DateTime => { Name => 'GPSDateTime', Groups => { 2 => 'Time' }, %dateInfo }, 409 418 ); 410 419 … … 456 465 Name => 'FullSizeImage', 457 466 %binaryConv, 458 ValueConv => '$self->ValidateImage(\$val,$tag)', 459 ValueConvInv => '$val', 467 RawConv => '$self->ValidateImage(\$val,$tag)', 460 468 }, 461 469 ); … … 479 487 Name => 'PreviewImage', 480 488 %binaryConv, 481 ValueConv => '$self->ValidateImage(\$val,$tag)', 482 ValueConvInv => '$val', 489 RawConv => '$self->ValidateImage(\$val,$tag)', 483 490 }, 484 491 ); … … 502 509 Name => 'ThumbnailImage', 503 510 %binaryConv, 504 ValueConv => '$self->ValidateImage(\$val,$tag)', 505 ValueConvInv => '$val', 511 RawConv => '$self->ValidateImage(\$val,$tag)', 506 512 }, 507 513 ); … … 523 529 Channels => { Writable => 'int8u' }, 524 530 Compression => { Name => 'AudioCompression' }, 525 Duration => { Writable => 'rational64u' },531 Duration => { Writable => 'rational64u', PrintConv => 'ConvertDuration($val)' }, 526 532 SampleRate => { Writable => 'int32u' }, 527 533 data => { Name => 'RelatedAudioFile', %binaryConv }, … … 536 542 '1Name' => { Name => 'RelatedVideoFileName' }, 537 543 Codec => { }, 538 Duration => { Writable => 'rational64u' },544 Duration => { Writable => 'rational64u', PrintConv => 'ConvertDuration($val)' }, 539 545 data => { Name => 'RelatedVideoFile', %binaryConv }, 540 546 ); … … 559 565 Writable => 'rational64u', 560 566 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 561 PrintConvInv => ' eval $val',567 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 562 568 }, 563 569 Flash => { … … 690 696 NOTES => q{ 691 697 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 }, 696 706 Casio => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } }, 697 707 FujiFilm => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } }, … … 705 715 Sigma => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } }, 706 716 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 }, 707 728 ); 708 729 … … 803 824 804 825 #------------------------------------------------------------------------------ 805 # Does a string contain valid UTF-8 characters?806 # Inputs: 0) string807 # Returns: 0=regular ASCII, -1=invalid UTF-8, 1=valid UTF-8 with maximum 16-bit808 # wide characters, 2=valid UTF-8 requiring 32-bit wide characters809 # Notes: Changes current string position810 sub IsUTF8($)811 {812 my $rtnVal = 0;813 pos($_[0]) = 0; # start at beginning of string814 for (;;) {815 last unless $_[0] =~ /([\x80-\xff])/g;816 my $ch = ord($1);817 # minimum lead byte for 2-byte sequence is 0xc2 (overlong sequences818 # not allowed), 0xf8-0xfd are restricted by RFC 3629 (no 5 or 6 byte819 # sequences), and 0xfe and 0xff are not valid in UTF-8 strings820 return -1 if $ch < 0xc2 or $ch >= 0xf8;821 # determine number of bytes remaining in sequence822 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 were826 # required in the UTF-8 character827 $rtnVal |= ($n > 2) ? 2 : 1;828 }829 return $rtnVal;830 }831 832 #------------------------------------------------------------------------------833 826 # ReadValue() with added support for UTF formats (utf8, utf16 and utf32) 834 827 # Inputs: 0) data reference, 1) value offset, 2) format string, … … 837 830 # Returns: converted value, or undefined if data isn't there 838 831 # or list of values in list context 832 # Notes: all string formats are converted to UTF8 839 833 sub ReadMIEValue($$$$$) 840 834 { 841 835 my ($dataPt, $offset, $format, $count, $size) = @_; 842 836 my $val; 843 if ($format =~ /^ utf(8|16|32)/) {844 if ($1 == 8) {845 # re turn UTF8string837 if ($format =~ /^(utf(8|16|32)|string)/) { 838 if ($1 eq 'utf8' or $1 eq 'string') { 839 # read the 8-bit string 846 840 $val = substr($$dataPt, $offset, $size); 841 # (as of ExifTool 7.62, leave string values unconverted) 847 842 } else { 848 843 # convert to UTF8 849 844 my $fmt; 850 845 if (GetByteOrder() eq 'MM') { 851 $fmt = ($1 == 16) ? 'n' : 'N';846 $fmt = ($1 eq 'utf16') ? 'n' : 'N'; 852 847 } else { 853 $fmt = ($1 == 16) ? 'v' : 'V';848 $fmt = ($1 eq 'utf16') ? 'v' : 'V'; 854 849 } 855 850 my @unpk = unpack("x$offset$fmt$size",$$dataPt); … … 861 856 } 862 857 # truncate at null unless this is a list 858 # (strings shouldn't have a null, but just in case) 863 859 $val =~ s/\0.*//s unless $format =~ /_list$/; 864 return $val;865 860 } 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' 868 862 return ReadValue($dataPt, $offset, $format, $count, $size); 869 863 } 864 return $val; 870 865 } 871 866 … … 893 888 return 'Units not supported'; 894 889 } 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 } 895 896 $err = Image::ExifTool::CheckValue($valPtr, $format, $$tagInfo{Count}); 896 897 } … … 1100 1101 } 1101 1102 %subdirInfo = ( 1102 DataPt => \$oldVal,1103 DataPt => \$oldVal, 1103 1104 DataLen => $valLen, 1104 1105 DirName => $$newInfo{Name}, 1105 1106 DataPos => $raf->Tell() - $valLen, 1106 DirStart 1107 DirLen => $valLen,1107 DirStart=> 0, 1108 DirLen => $valLen, 1108 1109 ); 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 } 1109 1116 } 1110 1117 $subdirInfo{Parent} = $dirName; 1111 1118 my $writeProc = $newInfo->{SubDirectory}->{WriteProc}; 1119 # reset processed lookup to avoid errors in case of multiple EXIF blocks 1120 $exifTool->{PROCESSED} = { }; 1112 1121 $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTablePtr, $writeProc); 1113 1122 if (defined $newVal) { … … 1127 1136 # get the new tag information 1128 1137 $newInfo = $$newTags{$newTag}; 1129 my $n ewValueHash = $exifTool->GetNewValueHash($newInfo);1138 my $nvHash = $exifTool->GetNewValueHash($newInfo); 1130 1139 my @newVals; 1131 1140 1132 1141 # write information only to specified group 1133 my $writeGroup = $$n ewValueHash{WriteGroup};1142 my $writeGroup = $$nvHash{WriteGroup}; 1134 1143 last unless $isWriting{$writeGroup}; 1135 1144 … … 1141 1150 $isOverwriting = -1; # force processing list elements individually 1142 1151 } else { 1143 $isOverwriting = Image::ExifTool::IsOverwriting($n ewValueHash);1152 $isOverwriting = Image::ExifTool::IsOverwriting($nvHash); 1144 1153 last unless $isOverwriting; 1145 1154 } … … 1178 1187 # keep any list items that we aren't overwriting 1179 1188 foreach $v (@vals) { 1180 next if Image::ExifTool::IsOverwriting($n ewValueHash, $v);1189 next if Image::ExifTool::IsOverwriting($nvHash, $v); 1181 1190 push @newVals, $v; 1182 1191 } 1183 1192 } else { 1184 1193 # test to see if we really want to overwrite the value 1185 $isOverwriting = Image::ExifTool::IsOverwriting($n ewValueHash, $val);1194 $isOverwriting = Image::ExifTool::IsOverwriting($nvHash, $val); 1186 1195 } 1187 1196 } … … 1194 1203 if ($verbose > 1) { 1195 1204 $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); 1198 1206 } 1199 1207 $deletedTag = $tag; # remember that we deleted this tag … … 1218 1226 # write new value if creating, or if List and list existed, or 1219 1227 # if tag was previously deleted 1220 next unless Image::ExifTool::IsCreating($n ewValueHash) or1228 next unless Image::ExifTool::IsCreating($nvHash) or 1221 1229 ($newTag eq $lastTag and ($$newInfo{List} or $deletedTag eq $lastTag)); 1222 1230 } 1223 1231 # get the new value to write (undef to delete) 1224 push @newVals, Image::ExifTool::GetNewValues($n ewValueHash);1232 push @newVals, Image::ExifTool::GetNewValues($nvHash); 1225 1233 next unless @newVals; 1226 1234 $writable = $$newInfo{Writable} || $$tagTablePtr{WRITABLE}; … … 1229 1237 $newVal = join "\0", @newVals; 1230 1238 # 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); 1232 1241 if ($isUTF8 > 0) { 1233 1242 $writable = 'utf8'; 1234 1243 # 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'; 1246 1249 } 1247 1250 } … … 1328 1331 Write($outfile, $hdr, chr($len), $newTag, $extLen, $$valPt) or $err = 1; 1329 1332 $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}; 1333 1337 } 1334 ++$exifTool->{CHANGED};1335 1338 last; # didn't want to loop anyway 1336 1339 } … … 1426 1429 my $verbose = $exifTool->Options('Verbose'); 1427 1430 my $out = $exifTool->Options('TextOut'); 1431 my $notUTF8 = ($exifTool->{OPTIONS}->{Charset} ne 'UTF8'); 1428 1432 my ($msg, $buff, $ok, $oldIndent, $mime); 1429 1433 my $lastTag = ''; … … 1450 1454 $exifTool->VerboseDir($grp1); 1451 1455 } 1456 my $wasCompressed = $$dirInfo{WasCompressed}; 1452 1457 1453 1458 # process all MIE elements … … 1532 1537 } 1533 1538 $valLen = length $value; 1539 $wasCompressed = 1; 1534 1540 } 1535 1541 } … … 1552 1558 my %subdirInfo = ( 1553 1559 DirName => $dirName || $tag, 1554 RAF => $raf, 1555 Parent => $$dirInfo{DirName}, 1560 RAF => $raf, 1561 Parent => $$dirInfo{DirName}, 1562 WasCompressed => $wasCompressed, 1556 1563 ); 1557 1564 # read from uncompressed data instead if necessary … … 1582 1589 } 1583 1590 $exifTool->VerboseInfo($lastTag, $tagInfo, 1584 DataPt => \$value,1591 DataPt => \$value, 1585 1592 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, 1590 1597 ); 1591 1598 } … … 1594 1601 my %subdirInfo = ( 1595 1602 DirName => $$tagInfo{Name}, 1596 DataPt => \$value, 1597 DataPos => $raf->Tell() - $valLen, 1603 DataPt => \$value, 1598 1604 DataLen => $valLen, 1599 DirStart => 0, 1600 DirLen => $valLen, 1605 DirStart=> 0, 1606 DirLen => $valLen, 1607 Parent => $$dirInfo{DirName}, 1608 WasCompressed => $wasCompressed, 1601 1609 ); 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} = { }; 1602 1618 my $processProc = $tagInfo->{SubDirectory}->{ProcessProc}; 1603 1619 delete $exifTool->{SET_GROUP1}; 1620 delete $exifTool->{NO_LIST}; 1604 1621 $exifTool->ProcessDirectory(\%subdirInfo, $subTablePtr, $processProc); 1605 1622 $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; 1610 1624 } 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 } 1613 1639 $exifTool->FoundTag($tagInfo, $val); 1614 1640 } … … 1653 1679 $buff =~ /(\x10|\x18)(\x08)$/s; 1654 1680 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); 1656 1682 my $curPos = $raf->Tell() or last; 1657 1683 last if $len < 12 or $len > $curPos; … … 1713 1739 # we have the ability to create a MIE file from scratch 1714 1740 $buff = ''; # start from nothing 1715 SetByteOrder('MM'); # write big-endian 1741 # set byte order according to preferences 1742 $exifTool->SetPreferredByteOrder(); 1716 1743 $isCreating = 1; 1717 1744 } … … 1728 1755 unless ($numDocs) { 1729 1756 # this is a valid MIE file (unless a trailer on another file) 1730 $exifTool->SetFileType() unless $exifTool->{VALUE}->{FileType};1757 $exifTool->SetFileType(); 1731 1758 $exifTool->{NO_LIST} = 1; # handle lists ourself 1732 1759 $exifTool->{MIE_COUNT} = { }; … … 1754 1781 UpdateMieMap() unless $doneMieMap; 1755 1782 # 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) 1756 1786 $exifTool->InitWriteDirs(\%mieMap, 'MIE'); 1757 1787 $subdirInfo{ToWrite} = '~' . MIEGroupFormat(1) . "\x04\xfe0MIE\0\0\0\0"; … … 1762 1792 last; 1763 1793 } elsif (defined $msg and $isCreating) { 1764 $exifTool->Error('Nothing to write');1765 1794 last; 1766 1795 } … … 2067 2096 comes first regardless of the byte ordering. In a signed rational value, 2068 2097 only the numerator is signed. The denominator of all rational values is 2069 unsigned (ie. a signed 32-bit rational of 0x80000000/0x80000000 evaluates to2098 unsigned (ie. a signed 64-bit rational of 0x80000000/0x80000000 evaluates to 2070 2099 -1, not +1). 2071 2100 … … 2482 2511 =head1 REVISIONS 2483 2512 2513 2010-04-05 - Fixed ÒFormat SizeÓ Note 7 to give the correct number of bits 2514 in the example rational value 2484 2515 2007-01-21 - Specified LF character (0x0a) for text newline sequence 2485 2516 2007-01-19 - Specified ISO 8859-1 character set for extended ASCII codes … … 2496 2527 =head1 AUTHOR 2497 2528 2498 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)2529 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 2499 2530 2500 2531 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIEUnits.pod
r16842 r24107 357 357 =head1 AUTHOR 358 358 359 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)359 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 360 360 361 361 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIFF.pm
r16842 r24107 16 16 use Image::ExifTool qw(:DataAccess :Utils); 17 17 18 $VERSION = '1.0 3';18 $VERSION = '1.05'; 19 19 20 20 # MIFF chunks … … 22 22 GROUPS => { 2 => 'Image' }, 23 23 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. 27 27 }, 28 28 'background-color' => 'BackgroundColor', … … 120 120 # slurp those entire files, which will be slower, but will work 121 121 # OK except that the profile information won't be decoded 122 my $oldsep = $/; 123 $/ = ":\x1a"; 122 local $/ = ":\x1a"; 124 123 125 124 my $mode = ''; … … 175 174 } 176 175 } 177 $/ = $oldsep; # restore separator to original value178 176 179 177 # process profile information … … 232 230 if ($verbose) { 233 231 $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 } 238 234 } 239 235 } … … 260 256 =head1 AUTHOR 261 257 262 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)258 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 263 259 264 260 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MNG.pm
r16842 r24107 662 662 =head1 AUTHOR 663 663 664 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)664 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 665 665 666 666 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPC.pm
r16842 r24107 82 82 83 83 # must first check for leading ID3 information 84 unless ($exifTool->{D ONE_ID3}) {84 unless ($exifTool->{DoneID3}) { 85 85 require Image::ExifTool::ID3; 86 86 Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1; … … 107 107 } else { 108 108 $exifTool->Warn('Audio info not currently extracted from this version MPC file'); 109 } 109 } 110 110 111 111 # process APE trailer if it exists … … 135 135 =head1 AUTHOR 136 136 137 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)137 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 138 138 139 139 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPEG.pm
r16842 r24107 8 8 # References: 1) http://www.mp3-tech.org/ 9 9 # 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/ 10 13 #------------------------------------------------------------------------------ 11 14 … … 16 19 use Image::ExifTool qw(:DataAccess :Utils); 17 20 18 $VERSION = '1. 04';21 $VERSION = '1.13'; 19 22 20 23 %Image::ExifTool::MPEG::Audio = ( … … 44 47 Condition => '$self->{MPEG_Vers} == 3 and $self->{MPEG_Layer} == 3', 45 48 Notes => 'version 1, layer 1', 46 PrintConv => { 49 PrintConvColumns => 3, 50 ValueConv => { 47 51 0 => 'free', 48 52 1 => 32000, … … 61 65 14 => 448000, 62 66 }, 67 PrintConv => 'ConvertBitrate($val)', 63 68 }, 64 69 { … … 66 71 Condition => '$self->{MPEG_Vers} == 3 and $self->{MPEG_Layer} == 2', 67 72 Notes => 'version 1, layer 2', 68 PrintConv => { 73 PrintConvColumns => 3, 74 ValueConv => { 69 75 0 => 'free', 70 76 1 => 32000, … … 83 89 14 => 384000, 84 90 }, 91 PrintConv => 'ConvertBitrate($val)', 85 92 }, 86 93 { … … 88 95 Condition => '$self->{MPEG_Vers} == 3 and $self->{MPEG_Layer} == 1', 89 96 Notes => 'version 1, layer 3', 90 PrintConv => { 97 PrintConvColumns => 3, 98 ValueConv => { 91 99 0 => 'free', 92 100 1 => 32000, … … 105 113 14 => 320000, 106 114 }, 115 PrintConv => 'ConvertBitrate($val)', 107 116 }, 108 117 { … … 110 119 Condition => '$self->{MPEG_Vers} != 3 and $self->{MPEG_Layer} == 3', 111 120 Notes => 'version 2 or 2.5, layer 1', 112 PrintConv => { 121 PrintConvColumns => 3, 122 ValueConv => { 113 123 0 => 'free', 114 124 1 => 32000, … … 127 137 14 => 256000, 128 138 }, 139 PrintConv => 'ConvertBitrate($val)', 129 140 }, 130 141 { … … 132 143 Condition => '$self->{MPEG_Vers} != 3 and $self->{MPEG_Layer}', 133 144 Notes => 'version 2 or 2.5, layer 2 or 3', 134 PrintConv => { 145 PrintConvColumns => 3, 146 ValueConv => { 135 147 0 => 'free', 136 148 1 => 8000, … … 149 161 14 => 160000, 150 162 }, 163 PrintConv => 'ConvertBitrate($val)', 151 164 }, 152 165 ], … … 187 200 'Bit24-25' => { 188 201 Name => 'ChannelMode', 202 RawConv => '$self->{MPEG_Mode} = $val', 189 203 PrintConv => { 190 204 0 => 'Stereo', … … 298 312 Name => 'VideoBitrate', 299 313 ValueConv => '$val eq 0x3ffff ? "Variable" : $val * 400', 314 PrintConv => 'ConvertBitrate($val)', 300 315 }, 301 316 # these tags not very interesting … … 306 321 ); 307 322 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 308 385 # composite tags 309 386 %Image::ExifTool::MPEG::Composite = ( … … 314 391 }, 315 392 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) 321 401 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]; 324 411 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)', 333 432 }, 334 433 ); … … 363 462 # Inputs: 0) ExifTool object reference, 1) Reference to audio data 364 463 # Returns: 1 on success, 0 if no audio header was found 365 sub P rocessMPEGAudio($$)464 sub ParseMPEGAudio($$) 366 465 { 367 466 my ($exifTool, $buffPt) = @_; 368 my $word; 467 my ($word, $pos); 468 my $ext = $$exifTool{FILE_EXT} || ''; 369 469 370 470 for (;;) { … … 379 479 if (($word & 0x180000) == 0x080000 or # 01 is a reserved version ID 380 480 ($word & 0x060000) == 0x000000 or # 00 is a reserved layer description 481 ($word & 0x00f000) == 0x000000 or # 0000 is the "free" bitrate index 381 482 ($word & 0x00f000) == 0x00f000 or # 1111 is a bad bitrate index 382 ($word & 0x000 600) == 0x000600 or # 11 is a reserved sampling frequency483 ($word & 0x000c00) == 0x000c00 or # 11 is a reserved sampling frequency 383 484 ($word & 0x000003) == 0x000002) # 10 is a reserved emphasis 384 485 { 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); 387 492 last; 388 493 } 389 494 # set file type if not done already 390 $exifTool->SetFileType() unless $exifTool->{VALUE}->{FileType};495 $exifTool->SetFileType(); 391 496 392 497 my $tagTablePtr = GetTagTable('Image::ExifTool::MPEG::Audio'); 393 498 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 394 579 return 1; 395 580 } … … 425 610 # Inputs: 0) ExifTool object reference, 1) Reference to audio/video data 426 611 # 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 626 sub ParseMPEGAudioVideo($$) 428 627 { 429 628 my ($exifTool, $buffPt) = @_; 430 my %found;629 my (%found, $didHdr); 431 630 my $rtnVal = 0; 432 my %proc = ( audio => \&P rocessMPEGAudio, video => \&ProcessMPEGVideo );631 my %proc = ( audio => \&ParseMPEGAudio, video => \&ProcessMPEGVideo ); 433 632 434 633 delete $exifTool->{AudioBitrate}; … … 437 636 while ($$buffPt =~ /\0\0\x01(\xb3|\xc0)/g) { 438 637 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 } 439 646 next if $found{$type}; 440 647 my $len = length($$buffPt) - pos($$buffPt); … … 454 661 455 662 #------------------------------------------------------------------------------ 456 # Read information fr amean MPEG file663 # Read information from an MPEG file 457 664 # Inputs: 0) ExifTool object reference, 1) Directory information reference 458 665 # Returns: 1 on success, 0 if this wasn't a valid MPEG file … … 470 677 $raf->Read($buff, 65536*4) or return 0; 471 678 472 return P rocessMPEGAudioVideo($exifTool, \$buff);679 return ParseMPEGAudioVideo($exifTool, \$buff); 473 680 } 474 681 … … 497 704 =head1 AUTHOR 498 705 499 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)706 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 500 707 501 708 This library is free software; you can redistribute it and/or modify it … … 510 717 =item L<http://www.getid3.org/> 511 718 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 512 725 =back 513 726 … … 515 728 516 729 L<Image::ExifTool::TagNames/MPEG Tags>, 730 L<MP3::Info(3pm)|MP3::Info>, 517 731 L<Image::ExifTool(3pm)|Image::ExifTool> 518 732 -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MakerNotes.pm
r16842 r24107 15 15 16 16 sub ProcessUnknown($$$); 17 18 $VERSION = '1.34'; 19 20 my $debug; # set to 1 to enabled debugging code 17 sub ProcessUnknownOrPreview($$$); 18 sub ProcessCanon($$$); 19 sub ProcessGE2($$$); 20 sub WriteUnknownOrPreview($$$); 21 sub FixLeicaBase($$;$); 22 23 $VERSION = '1.66'; 24 25 my $debug; # set to 1 to enable debugging code 21 26 22 27 # conditional list of maker notes … … 31 36 Name => 'MakerNoteCanon', 32 37 # (starts with an IFD) 33 Condition => '$ self->{CameraMake} =~ /^Canon/',38 Condition => '$$self{Make} =~ /^Canon/', 34 39 SubDirectory => { 35 40 TagTable => 'Image::ExifTool::Canon::Main', 41 ProcessProc => \&ProcessCanon, 36 42 ByteOrder => 'Unknown', 37 43 }, … … 42 48 # in a nice order for documentation 43 49 # (starts with an IFD) 44 Condition => '$ self->{CameraMake}=~/^CASIO(?! COMPUTER CO.,LTD)/',50 Condition => '$$self{Make}=~/^CASIO/ and $$valPt!~/^(QVC|DCI)\0/', 45 51 SubDirectory => { 46 52 TagTable => 'Image::ExifTool::Casio::Main', … … 50 56 { 51 57 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/', 54 61 SubDirectory => { 55 62 TagTable => 'Image::ExifTool::Casio::Type2', 56 63 Start => '$valuePtr + 6', 57 64 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 63 71 Name => 'MakerNoteFujiFilm', 64 72 # (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)/', 66 75 SubDirectory => { 67 76 TagTable => 'Image::ExifTool::FujiFilm::Main', … … 75 84 }, 76 85 { 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 { 77 114 Name => 'MakerNoteHP', # PhotoSmart 720 (also Vivitar 3705, 3705B and 3715) 78 115 Condition => '$$valPt =~ /^(Hewlett-Packard|Vivitar)/', … … 85 122 { 86 123 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]/', 92 126 NotIFD => 1, 93 127 SubDirectory => { … … 118 152 }, 119 153 { 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 { 120 165 Name => 'MakerNoteJVC', 121 166 Condition => '$$valPt=~/^JVC /', … … 128 173 { 129 174 Name => 'MakerNoteJVCText', 130 Condition => '$ self->{CameraMake}=~/^(JVC|Victor)/ and $$valPt=~/^VER:/',175 Condition => '$$self{Make}=~/^(JVC|Victor)/ and $$valPt=~/^VER:/', 131 176 NotIFD => 1, 132 177 SubDirectory => { … … 136 181 { 137 182 Name => 'MakerNoteKodak1a', 138 Condition => '$ self->{CameraMake}=~/^EASTMAN KODAK/ and $$valPt=~/^KDK INFO/',183 Condition => '$$self{Make}=~/^EASTMAN KODAK/ and $$valPt=~/^KDK INFO/', 139 184 NotIFD => 1, 140 185 SubDirectory => { … … 146 191 { 147 192 Name => 'MakerNoteKodak1b', 148 Condition => '$ self->{CameraMake}=~/^EASTMAN KODAK/ and $$valPt=~/^KDK/',193 Condition => '$$self{Make}=~/^EASTMAN KODAK/ and $$valPt=~/^KDK/', 149 194 NotIFD => 1, 150 195 SubDirectory => { … … 171 216 # upper byte of the year should be 0x07: 172 217 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 }, 174 223 NotIFD => 1, 175 224 SubDirectory => { … … 180 229 { 181 230 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 }, 183 236 NotIFD => 1, 184 237 SubDirectory => { … … 190 243 Name => 'MakerNoteKodak5', 191 244 Condition => q{ 192 $ self->{CameraMake}=~/^EASTMAN KODAK/ and193 ($ self->{CameraModel}=~/CX(4200|4230|4300|4310|6200|6230)/ or245 $$self{Make}=~/^EASTMAN KODAK/ and 246 ($$self{Model}=~/CX(4200|4230|4300|4310|6200|6230)/ or 194 247 # try to pick up similar models we haven't tested yet 195 248 $$valPt=~/^\0(\x1a\x18|\x3a\x08|\x59\xf8|\x14\x80)\0/) … … 204 257 Name => 'MakerNoteKodak6a', 205 258 Condition => q{ 206 $ self->{CameraMake}=~/^EASTMAN KODAK/ and207 $ self->{CameraModel}=~/DX3215/259 $$self{Make}=~/^EASTMAN KODAK/ and 260 $$self{Model}=~/DX3215/ 208 261 }, 209 262 NotIFD => 1, … … 216 269 Name => 'MakerNoteKodak6b', 217 270 Condition => q{ 218 $ self->{CameraMake}=~/^EASTMAN KODAK/ and219 $ self->{CameraModel}=~/DX3700/271 $$self{Make}=~/^EASTMAN KODAK/ and 272 $$self{Model}=~/DX3700/ 220 273 }, 221 274 NotIFD => 1, … … 231 284 # accept other strings from sample images that may be serial numbers) 232 285 Condition => q{ 233 $ self->{CameraMake}=~/Kodak/i and286 $$self{Make}=~/Kodak/i and 234 287 $$valPt =~ /^[CK][A-Z\d]{3} ?[A-Z\d]{1,2}\d{2}[A-Z\d]\d{4}[ \0]/ 235 288 }, … … 241 294 }, 242 295 { 243 Name => 'MakerNoteKodak IFD',244 # look for reasonable number of entries and check245 # format and count of first IFD entry296 Name => 'MakerNoteKodak8a', 297 # IFD-format maker notes: look for reasonable number of 298 # entries and check format and count of first IFD entry 246 299 Condition => q{ 247 $ self->{CameraMake}=~/Kodak/i and300 $$self{Make}=~/Kodak/i and 248 301 ($$valPt =~ /^\0[\x02-\x7f]..\0[\x01-\x0c]\0\0/s or 249 302 $$valPt =~ /^[\x02-\x7f]\0..[\x01-\x0c]\0..\0\0/s) 250 303 }, 251 304 SubDirectory => { 252 TagTable => 'Image::ExifTool::Kodak:: IFD',305 TagTable => 'Image::ExifTool::Kodak::Type8', 253 306 ProcessProc => \&ProcessUnknown, 254 307 ByteOrder => 'Unknown', … … 256 309 }, 257 310 { 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 { 258 352 Name => 'MakerNoteKodakUnknown', 259 Condition => '$ self->{CameraMake}=~/Kodak/i',353 Condition => '$$self{Make}=~/Kodak/i and $$valPt!~/^AOC\0/', 260 354 NotIFD => 1, 261 355 SubDirectory => { … … 267 361 Name => 'MakerNoteKyocera', 268 362 # (starts with "KYOCERA") 269 Condition => '$ self->{CameraMake}=~/^KYOCERA/',363 Condition => '$$valPt =~ /^KYOCERA/', 270 364 SubDirectory => { 271 365 TagTable => 'Image::ExifTool::Unknown::Main', … … 279 373 Name => 'MakerNoteMinolta', 280 374 Condition => q{ 281 $ self->{CameraMake}=~/^(Konica Minolta|Minolta)/i and375 $$self{Make}=~/^(Konica Minolta|Minolta)/i and 282 376 $$valPt !~ /^(MINOL|CAMER|MLY0|KC|\+M\+M|\xd7)/ 283 377 }, … … 305 399 # /^\xd7/ - DiMAGE RD3000 306 400 Name => 'MakerNoteMinolta3', 307 Condition => '$self->{CameraMake} =~ /^(Konica Minolta|Minolta)/i', 401 Condition => '$$self{Make} =~ /^(Konica Minolta|Minolta)/i', 402 Binary => 1, 308 403 Notes => 'not EXIF-based', 309 Binary => 1,310 NotIFD => 1,311 404 }, 312 405 { 313 406 # this maker notes starts with a standard TIFF header at offset 0x0a 314 407 Name => 'MakerNoteNikon', 315 Condition => '$ self->{CameraMake}=~/^NIKON/i and $$valPt=~/^Nikon\x00\x02/',408 Condition => '$$self{Make}=~/^NIKON/i and $$valPt=~/^Nikon\x00\x02/', 316 409 SubDirectory => { 317 410 TagTable => 'Image::ExifTool::Nikon::Main', … … 324 417 # older Nikon maker notes 325 418 Name => 'MakerNoteNikon2', 326 Condition => '$ self->{CameraMake}=~/^NIKON/ and $$valPt=~/^Nikon\x00\x01/',419 Condition => '$$self{Make}=~/^NIKON/ and $$valPt=~/^Nikon\x00\x01/', 327 420 SubDirectory => { 328 421 TagTable => 'Image::ExifTool::Nikon::Type2', … … 334 427 # headerless Nikon maker notes 335 428 Name => 'MakerNoteNikon3', 336 Condition => '$ self->{CameraMake}=~/^NIKON/i',429 Condition => '$$self{Make}=~/^NIKON/i', 337 430 SubDirectory => { 338 431 TagTable => 'Image::ExifTool::Nikon::Main', … … 355 448 Name => 'MakerNoteOlympus2', 356 449 # new Olympus maker notes start with "OLYMPUS\0" 357 Condition => '$$valPt =~ /^OLYMPUS\0/ and $$self{OlympusType2} = 1',450 Condition => '$$valPt =~ /^OLYMPUS\0/', 358 451 SubDirectory => { 359 452 TagTable => 'Image::ExifTool::Olympus::Main', … … 365 458 { 366 459 Name => 'MakerNoteLeica', 367 # (starts with "LEICA\0 ")368 Condition => '$ self->{CameraMake} =~ /^LEICA/',369 SubDirectory => { 370 # Leica usesthe same format as Panasonic460 # (starts with "LEICA\0\0\0") 461 Condition => '$$self{Make} eq "LEICA"', 462 SubDirectory => { 463 # many Leica models use the same format as Panasonic 371 464 TagTable => 'Image::ExifTool::Panasonic::Main', 372 465 Start => '$valuePtr + 8', … … 375 468 }, 376 469 { 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 { 377 535 Name => 'MakerNotePanasonic', 378 536 # (starts with "Panasonic\0") 379 Condition => '$ self->{CameraMake} =~ /^Panasonic/ and $$valPt!~/^MKE/',537 Condition => '$$valPt=~/^Panasonic/', 380 538 SubDirectory => { 381 539 TagTable => 'Image::ExifTool::Panasonic::Main', … … 387 545 Name => 'MakerNotePanasonic2', 388 546 # (starts with "Panasonic\0") 389 Condition => '$ self->{CameraMake} =~ /^Panasonic/',547 Condition => '$$self{Make}=~/^Panasonic/ and $$valPt=~/^MKE/', 390 548 SubDirectory => { 391 549 TagTable => 'Image::ExifTool::Panasonic::Type2', … … 399 557 Condition => q{ 400 558 $$valPt=~/^AOC\0/ and 401 $ self->{CameraModel} !~ /^PENTAX Optio ?[34]30RS\s*$/559 $$self{Model} !~ /^PENTAX Optio ?[34]30RS\s*$/ 402 560 }, 403 561 SubDirectory => { … … 416 574 # (starts with an IFD) 417 575 # 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/', 419 577 SubDirectory => { 420 578 TagTable => 'Image::ExifTool::Pentax::Type2', … … 428 586 # (starts with "AOC\0", like the more common Pentax maker notes) 429 587 # Casio maker notes used only by the Optio 330RS and 430RS 430 Condition => '$ self->{CameraMake}=~/^Asahi/',588 Condition => '$$self{Make}=~/^Asahi/', 431 589 SubDirectory => { 432 590 TagTable => 'Image::ExifTool::Casio::Type2', … … 440 598 # (starts with 3 or 4 digits) 441 599 # 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}/', 443 601 NotIFD => 1, 444 602 SubDirectory => { … … 449 607 }, 450 608 { 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 { 451 642 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', 453 645 SubDirectory => { 454 646 TagTable => 'Image::ExifTool::Ricoh::Main', … … 459 651 { 460 652 Name => 'MakerNoteRicohText', 461 Condition => '$ self->{CameraMake}=~/^RICOH/',653 Condition => '$$self{Make}=~/^RICOH/', 462 654 NotIFD => 1, 463 655 SubDirectory => { … … 467 659 }, 468 660 { 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 }, 473 690 }, 474 691 { 475 692 Name => 'MakerNoteSanyo', 476 693 # (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/', 478 695 SubDirectory => { 479 696 TagTable => 'Image::ExifTool::Sanyo::Main', … … 486 703 Name => 'MakerNoteSanyoC4', 487 704 # 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/', 489 706 SubDirectory => { 490 707 TagTable => 'Image::ExifTool::Sanyo::Main', … … 498 715 Name => 'MakerNoteSanyoPatch', 499 716 # The J1, J2, J4, S1, S3 and S4 offsets are completely screwy 500 Condition => '$ self->{CameraMake}=~/^SANYO/',717 Condition => '$$self{Make}=~/^SANYO/', 501 718 SubDirectory => { 502 719 TagTable => 'Image::ExifTool::Sanyo::Main', … … 510 727 Name => 'MakerNoteSigma', 511 728 # (starts with "SIGMA\0") 512 Condition => '$ self->{CameraMake}=~/^(SIGMA|FOVEON)/',729 Condition => '$$self{Make}=~/^(SIGMA|FOVEON)/', 513 730 SubDirectory => { 514 731 TagTable => 'Image::ExifTool::Sigma::Main', … … 521 738 Name => 'MakerNoteSony', 522 739 # (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)/', 524 741 SubDirectory => { 525 742 TagTable => 'Image::ExifTool::Sony::Main', 526 # validate the maker note because this is sometimes garbage527 Validate => 'defined($val) and $val =~ /^SONY (DSC|CAM)/',528 743 Start => '$valuePtr + 12', 529 744 ByteOrder => 'Unknown', … … 531 746 }, 532 747 { 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 { 533 787 Name => 'MakerNoteSonySRF', 534 Condition => '$ self->{CameraMake}=~/^SONY/ and $$valPt =~ /^\x01\x00/',788 Condition => '$$self{Make}=~/^SONY/', 535 789 SubDirectory => { 536 790 TagTable => 'Image::ExifTool::Sony::SRF', … … 540 794 }, 541 795 { 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', 549 802 }, 550 803 { 551 804 Name => 'MakerNoteUnknown', 805 PossiblePreview => 1, 552 806 SubDirectory => { 553 807 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 }, 557 813 }, 558 814 ); … … 565 821 $$tagInfo{Groups} = { 1 => 'MakerNotes' }; 566 822 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, 570 825 $$tagInfo{MakerNotes} = 1; 571 826 } … … 582 837 my $exifTool = shift; 583 838 # 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}; 586 841 my ($relative, @offsets); 587 842 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 589 846 if ($make =~ /^Canon/) { 590 847 push @offsets, ($model =~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/) ? 6 : 4; … … 592 849 # at the end of the IFD (2 spare IFD entries?) 593 850 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; 594 860 } elsif ($make =~ /^KYOCERA/) { 595 861 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 } 596 871 } elsif ($make =~ /^OLYMPUS/ and $model =~ /^E-(1|300|330)\b/) { 597 872 push @offsets, 16; … … 601 876 { 602 877 # no expected offset --> determine offset empirically via FixBase() 603 } elsif ($make =~ /^(Panasonic| SONY|JVC)\b/) {878 } elsif ($make =~ /^(Panasonic|JVC)\b/) { 604 879 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 } 605 887 } elsif ($make eq 'FUJIFILM') { 606 888 # some models have offset of 6, so allow that too (A345,A350,A360,A370) … … 629 911 #------------------------------------------------------------------------------ 630 912 # 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 632 915 # Returns: 0) hash reference: keys are offsets, values are block sizes 633 916 # 1) same thing, but with keys adjusted for value-based offsets 634 917 # Notes: Directory size should be validated before calling this routine 635 918 # - calculates MIN and MAX offsets in entry-based hash 636 sub GetValueBlocks($$ )919 sub GetValueBlocks($$;$) 637 920 { 638 my ($dataPt, $dirStart ) = @_;921 my ($dataPt, $dirStart, $tagPtr) = @_; 639 922 my $numEntries = Get16u($dataPt, $dirStart); 640 923 my ($index, $valPtr, %valBlock, %valBlkAdj, $end); … … 647 930 next if $size <= 4; 648 931 $valPtr = Get32u($dataPt, $entry+8); 932 $tagPtr and $$tagPtr{Get16u($dataPt, $entry)} = $valPtr; 649 933 # save location and size of longest block at this offset 650 934 unless (defined $valBlock{$valPtr} and $valBlock{$valPtr} > $size) { … … 688 972 my $fixBase = $exifTool->Options('FixBase'); 689 973 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 699 989 { 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; 704 992 if ($setBase) { 705 993 $fix = $fixBase; 706 994 } else { 707 my $oldOffset = Get32u(\$trailer, 4);708 my $newOffset = $dirStart + $dataPos;709 995 $fix = $newOffset - $oldOffset; 710 996 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 } 711 1009 } 712 $exifTool->Warn("Adjusted $dirName base by $fix", 1010 $exifTool->Warn("Adjusted $dirName base by $fix",1); 713 1011 $$dirInfo{FixedBy} = $fix; 714 1012 $$dirInfo{Base} += $fix; … … 718 1016 } 719 1017 # 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 728 1023 my $ifdLen = 2 + 12 * Get16u($$dirInfo{DataPt}, $dirStart); 729 1024 my $ifdEnd = $dirStart + $ifdLen; … … 736 1031 my $expected = $dataPos + $ifdEnd + (defined $makeDiff ? $makeDiff : 4); 737 1032 $debug and print "$expected expected\n"; 738 739 # get sorted list of value offsets740 my @valPtrs = sort { $a <=> $b } keys %$valBlock;741 my $minPt = $valPtrs[0]; # if life were simple, this would be it742 1033 743 1034 # zero our counters … … 748 1039 $valPtr - ($last || 0)) if $debug; 749 1040 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) { 752 1043 ++$countZero; 753 } elsif ($ diff== -12 and not $entryBased) {1044 } elsif ($gap == -12 and not $entryBased) { 754 1045 # you get this when value offsets are relative to the IFD entry 755 1046 ++$countNeg12; 756 } elsif ($ diff< 0) {1047 } elsif ($gap < 0) { 757 1048 # any other negative difference indicates overlapping values 758 1049 ++$countOverlap if $valPtr; # (but ignore zero value pointers) 759 } elsif ($ diff>= $ifdLen) {1050 } elsif ($gap >= $ifdLen) { 760 1051 # ignore previous minimum if we took a jump to near the expected value 761 1052 # (some values can be stored before the IFD) … … 775 1066 # which have been correcting for individual entry position 776 1067 $entryBased = 1; 777 $verbose and $exifTool->Warn("$dirName offsets are entry-based" );1068 $verbose and $exifTool->Warn("$dirName offsets are entry-based",1); 778 1069 } else { 779 # calculate difference from normal1070 # calculate offset difference from end of IFD to first value 780 1071 $diff = ($minPt - $dataPos) - $ifdEnd; 781 1072 $shift = 0; 782 1073 $countOverlap and $exifTool->Warn("Overlapping $dirName values",1); 783 1074 if ($entryBased) { 784 $exifTool->Warn("$dirName offsets do NOT look entry-based" );1075 $exifTool->Warn("$dirName offsets do NOT look entry-based",1); 785 1076 undef $entryBased; 786 1077 undef $relative; 787 1078 } 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); 788 1091 } 789 1092 # … … 871 1174 my $dataPt = $$dirInfo{DataPt}; 872 1175 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; 874 1179 my $tagInfo = $$dirInfo{TagInfo}; 875 1180 my $ifdOffsetPos; … … 886 1191 if ($tagInfo and $$tagInfo{SubDirectory}) { 887 1192 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 { 889 1197 # look for the IFD at the "Start" specified in our SubDirectory information 890 1198 my $valuePtr = $dirStart; … … 897 1205 # calculate subdirectory start relative to $base for eval 898 1206 my $start = $newStart + $$dirInfo{DataPos}; 899 #### eval Base ($start) 1207 my $base = $$dirInfo{Base} || 0; 1208 #### eval Base ($start,$base) 900 1209 my $baseShift = eval($$subdir{Base}); 901 1210 # shift directory base (note: we may do this again below … … 905 1214 $$dirInfo{DataPos} -= $baseShift; 906 1215 # 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 } 908 1226 } 909 1227 # add offset to the start of the directory if necessary … … 927 1245 # scan for something that looks like an IFD 928 1246 # 929 if ($ size>= 14 + $firstTry) { # minimum size for an IFD1247 if ($dirLen >= 14 + $firstTry) { # minimum size for an IFD 930 1248 my $offset; 931 1249 IFD_TRY: for ($offset=$firstTry; $offset<=$lastTry; $offset+=2) { 932 last if $offset + 14 > $ size; # 14 bytes is minimum size for an IFD1250 last if $offset + 14 > $dirLen; # 14 bytes is minimum size for an IFD 933 1251 my $pos = $dirStart + $offset; 934 1252 # … … 943 1261 # get pointer to IFD 944 1262 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) { 946 1264 # shift directory start and shorten dirLen accordingly 947 1265 $$dirInfo{DirStart} += $ptr + $offset; … … 983 1301 # because some manufacturers pad with null entries 984 1302 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/; 985 1305 # (would like to verify tag ID, but some manufactures don't 986 1306 # sort entries in order of tag ID so we don't have much of … … 991 1311 # cameras like the 1DmkIII use this value) 992 1312 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 } 993 1321 } 994 1322 $$dirInfo{DirStart} += $offset; # update directory start … … 1001 1329 1002 1330 #------------------------------------------------------------------------------ 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 1334 sub 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 1362 sub 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 1391 sub 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 1407 sub 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 1430 sub 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 #------------------------------------------------------------------------------ 1003 1458 # 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 1006 1460 # Returns: 1 on success, and updates $dirInfo if necessary for new directory 1007 1461 sub ProcessUnknown($$$) … … 1023 1477 } else { 1024 1478 $exifTool->{UnknownByteOrder} = ''; # indicates we tried but didn't set byte order 1025 $exifTool->Warn("Unrecognized $$dirInfo{DirName}" );1479 $exifTool->Warn("Unrecognized $$dirInfo{DirName}", 1); 1026 1480 } 1027 1481 return $success; … … 1048 1502 =head1 AUTHOR 1049 1503 1050 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1504 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 1051 1505 1052 1506 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Minolta.pm
r16842 r24107 19 19 # 11) http://www.dyxum.com/dforum/forum_posts.asp?TID=6371&PN=1 and 20 20 # http://www.dyxum.com/dAdmin/lenses/MakerNoteList_Public.asp?stro=makr 21 # http://dyxum.com/dforum/forum_posts.asp?TID=23435&PN=2 21 22 # 12) http://www.minolta-forum.de/forum/index.php?showtopic=14914 22 23 # 13) http://www.mhohner.de/minolta/lenses.php 23 24 # 14) Jeffery Small private communication (tests with 7D) 24 25 # 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 25 36 #------------------------------------------------------------------------------ 26 37 … … 28 39 29 40 use strict; 30 use vars qw($VERSION %minoltaLens IDs %minoltaColorMode);41 use vars qw($VERSION %minoltaLensTypes %minoltaColorMode %sonyColorMode %minoltaSceneMode); 31 42 use Image::ExifTool qw(:DataAccess :Utils); 32 43 use Image::ExifTool::Exif; 33 44 34 $VERSION = '1. 33';45 $VERSION = '1.76'; 35 46 36 47 # 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) 39 57 1 => 'Minolta AF 80-200mm F2.8 HS-APO G', 40 58 2 => 'Minolta AF 28-70mm F2.8 G', 41 59 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) 47 67 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) 49 69 11 => 'Minolta AF 300mm F4 HS-APO G', 50 70 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) 52 72 14 => 'Minolta AF 100-400mm F4.5-6.7 APO', 53 73 15 => 'Minolta AF 400mm F4.5 HS-APO G', … … 55 75 17 => 'Minolta AF 20-35mm F3.5-4.5', 56 76 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) 71 110 35 => 'Minolta AF 85mm F1.4 G (D) Limited', 72 111 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) 80 121 45 => 'Carl Zeiss Planar T* 85mm F1.4 ZA', 81 122 46 => 'Carl Zeiss Vario-Sonnar T* DT 16-80mm F3.5-4.5 ZA', 82 123 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 85 156 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 86 168 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 90 185 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 92 190 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) 94 193 25581 => 'Minolta AF 24-50mm F4', 95 194 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 100 211 25651 => 'Minolta AF 600mm F4', 101 212 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', 107 228 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) 110 232 25921 => 'Minolta AF 85mm F1.4 G (D)', 111 233 25931 => 'Minolta AF 200mm F2.8 G APO', 112 25941 => 'Minolta AF 3 X-1XF1.7-2.8 Macro',234 25941 => 'Minolta AF 3x-1x F1.7-2.8 Macro', 113 235 25961 => 'Minolta AF 28mm F2', 114 25971 => 'Minolta AF 35mm F2 ',236 25971 => 'Minolta AF 35mm F2 [New]', #13 115 237 25981 => 'Minolta AF 100mm F2', 116 238 26041 => 'Minolta AF 80-200mm F4.5-5.6', 117 239 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) 119 241 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) 121 243 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', 123 245 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) 128 250 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) 130 252 26241 => 'Minolta AF 35-80mm F4-5.6 Power Zoom', 131 253 26281 => 'Minolta AF 80-200mm F2.8 G', #11 132 254 26291 => 'Minolta AF 85mm F1.4 New', 133 26311 => 'Minolta AF 100-300mm F4.5-5.6 APO', #11255 26311 => 'Minolta/Sony AF 100-300mm F4.5-5.6 APO', #11 134 256 26321 => 'Minolta AF 24-50mm F4 New', 135 257 26381 => 'Minolta AF 50mm F2.8 Macro New', 136 258 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) 138 260 26421 => 'Minolta AF 24mm F2.8 New', 139 261 26441 => 'Minolta AF 100-400mm F4.5-6.7 APO', #11 … … 142 264 26681 => 'Minolta AF 28mm F2 New', 143 265 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 145 282 ); 146 283 … … 160 297 17 => 'Night Scene', #10 161 298 18 => 'Night Portrait', #10 299 0x84 => 'Embed Adobe RGB', 162 300 ); 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 343 my %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 368 my %onOff = ( 0 => 'On', 1 => 'Off' ); 369 my %offOn = ( 0 => 'Off', 1 => 'On' ); 163 370 164 371 # Minolta tag table … … 183 390 Name => 'MinoltaCameraSettings', 184 391 # These camera settings are different for the DiMAGE X31 185 Condition => '$self->{ CameraModel} ne "DiMAGE X31"',392 Condition => '$self->{Model} ne "DiMAGE X31"', 186 393 SubDirectory => { 187 394 TagTable => 'Image::ExifTool::Minolta::CameraSettings', … … 200 407 0x0018 => { 201 408 Name => 'ImageStabilization', 202 Condition => '$self->{ CameraModel} =~ /^DiMAGE (A1|A2|X1)$/',409 Condition => '$self->{Model} =~ /^DiMAGE (A1|A2|X1)$/', 203 410 Notes => q{ 204 411 a block of binary data which exists in DiMAGE A2 (and A1/X1?) images only if … … 206 413 }, 207 414 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 }, 208 424 }, 209 425 0x0040 => { … … 223 439 Writable => 'int32u', 224 440 Protected => 2, 441 # Note: Sony also uses this tag in A100 ARW images, but it points 442 # to the same data as JpgFromRaw 225 443 }, 226 444 0x0089 => { … … 231 449 Protected => 2, 232 450 }, 233 0x0100 => { #10 (needs verification - PH)451 0x0100 => { #10 234 452 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, 245 455 }, 246 456 0x0101 => [ 247 457 { 248 458 Name => 'ColorMode', 249 Condition => '$self->{ CameraMake} !~ /^SONY/',459 Condition => '$self->{Make} !~ /^SONY/', 250 460 Priority => 0, # Other ColorMode is more reliable for A2 251 461 Writable => 'int32u', … … 255 465 Name => 'ColorMode', 256 466 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, 268 469 }, 269 470 ], … … 288 489 Name => 'MinoltaQuality', 289 490 Writable => 'int32u', 290 Condition => '$self->{ CameraModel} =~ /^DiMAGE (A2|7Hi)$/',491 Condition => '$self->{Model} =~ /^DiMAGE (A2|7Hi)$/', 291 492 Notes => 'quality for DiMAGE A2/7Hi', 292 493 Priority => 0, # lower priority because this doesn't work for A200 … … 303 504 Name => 'MinoltaImageSize', 304 505 Writable => 'int32u', 305 Condition => '$self->{ CameraModel} !~ /^DiMAGE A200$/',506 Condition => '$self->{Model} !~ /^DiMAGE A200$/', 306 507 Notes => 'image size for other models except A200', 307 508 PrintConv => { … … 320 521 Writable => 'rational64s', 321 522 }, 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 }, 333 535 0x0107 => { #8 334 536 Name => 'ImageStabilization', … … 339 541 }, 340 542 }, 543 0x0109 => { #20 544 Name => 'RawAndJpgRecording', 545 Writable => 'int32u', 546 PrintConv => \%offOn, 547 }, 341 548 0x010a => { 342 549 Name => 'ZoneMatching', … … 353 560 }, 354 561 0x010c => { #3 (Alpha 7) 355 Name => 'Lens ID',562 Name => 'LensType', 356 563 Writable => 'int32u', 357 PrintConv => \%minoltaLensIDs, 564 SeparateTable => 1, 565 PrintConv => \%minoltaLensTypes, 358 566 }, 359 567 # 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 }, 360 578 0x0113 => { #PH 361 579 Name => 'ImageStabilization', 362 Condition => '$self->{ CameraModel} eq "DSLR-A100"',580 Condition => '$self->{Model} eq "DSLR-A100"', 363 581 Notes => 'valid for Sony A100 only', 364 582 Writable => 'int32u', 365 PrintConv => { 0 => 'Off', 1 => 'On' },583 PrintConv => \%offOn, 366 584 }, 367 585 0x0114 => [ 368 586 { #8 369 587 Name => 'MinoltaCameraSettings5D', 370 Condition => '$self->{ CameraModel} =~ /^(DYNAX 5D|MAXXUM 5D|ALPHA SWEET)/',588 Condition => '$self->{Model} =~ /^(DYNAX 5D|MAXXUM 5D|ALPHA SWEET)/', 371 589 SubDirectory => { 372 590 TagTable => 'Image::ExifTool::Minolta::CameraSettings5D', … … 375 593 }, 376 594 { #PH 377 Name => ' MinoltaCameraSettingsA100',378 Condition => '$self->{ CameraModel} eq "DSLR-A100"',595 Name => 'CameraSettingsA100', 596 Condition => '$self->{Model} eq "DSLR-A100"', 379 597 SubDirectory => { 380 598 TagTable => 'Image::ExifTool::Minolta::CameraSettingsA100', … … 383 601 }, 384 602 ], 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 }, 385 619 0x0e00 => { 386 620 Name => 'PrintIM', … … 394 628 Name => 'MinoltaCameraSettings2', 395 629 Writable => 0, 630 Binary => 1, 396 631 }, 397 632 ); … … 411 646 information may not be as reliable as it should be. Because of this, tags 412 647 in the following tables are set to lower priority to prevent them from 413 superce eding the values of same-named tags in other locations when duplicate648 superceding the values of same-named tags in other locations when duplicate 414 649 tags are disabled. 415 650 }, … … 430 665 2 => 'Rear flash sync', 431 666 3 => 'Wireless', 667 4 => 'Off?', #PH 432 668 }, 433 669 }, … … 475 711 PrintConv => { 476 712 0 => 'Multi-segment', 477 1 => 'Center weighted',713 1 => 'Center-weighted average', 478 714 2 => 'Spot', 479 715 }, … … 491 727 ValueConvInv => '48 - 8*log($val)/log(2)', 492 728 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 493 PrintConvInv => ' eval $val',729 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 494 730 }, 495 731 10 => { … … 519 755 ValueConv => '$val/3 - 2', 520 756 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)', 523 759 }, 524 760 14 => { … … 536 772 ValueConv => '$val / 256', 537 773 ValueConvInv => '$val * 256', 538 PrintConv => 'sprintf("%.1f mm",$val)',539 PrintConvInv => '$val=~s/ mm$//;$val',774 PrintConv => 'sprintf("%.1f mm",$val)', 775 PrintConvInv => '$val=~s/\s*mm$//;$val', 540 776 }, 541 777 19 => { … … 576 812 26 => { 577 813 Name => 'FileNumberMemory', 578 PrintConv => { 579 0 => 'Off', 580 1 => 'On', 581 }, 814 PrintConv => \%offOn, 582 815 }, 583 816 27 => 'LastFileNumber', … … 599 832 31 => { 600 833 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, 605 837 }, 606 838 32 => { 607 839 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, 612 843 }, 613 844 33 => { … … 635 866 ValueConv => '($val - 6) / 3', 636 867 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)', 639 870 }, 640 871 36 => { … … 688 919 41 => { 689 920 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)', 692 923 }, 693 924 42 => 'BWFilter', … … 742 973 51 => { 743 974 Name => 'ColorProfile', 744 Condition => '$self->{ CameraModel} eq "DiMAGE 7Hi"',975 Condition => '$self->{Model} eq "DiMAGE 7Hi"', 745 976 Notes => 'DiMAGE 7Hi only', 746 977 PrintConv => { … … 752 983 52 => { 753 984 Name => 'DataImprint', 754 Condition => '$self->{ CameraModel} eq "DiMAGE 7Hi"',985 Condition => '$self->{Model} eq "DiMAGE 7Hi"', 755 986 Notes => 'DiMAGE 7Hi only', 756 987 PrintConv => { … … 789 1020 2 => 'Shutter Priority', 790 1021 3 => 'Manual', 791 4 => 'Auto ?',1022 4 => 'Auto', 792 1023 5 => 'Program-shift A', 793 1024 6 => 'Program-shift S', … … 828 1059 Name => 'FocusMode', 829 1060 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 834 1066 }, 835 1067 }, … … 850 1082 0x15 => { 851 1083 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 }, 863 1094 0x1c => { 864 1095 Name => 'ISOSetting', … … 878 1109 ValueConv => '$val / 24', 879 1110 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)', 882 1113 }, 883 1114 0x25 => { … … 911 1142 ValueConvInv => '$val / 100', 912 1143 }, 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 }, 920 1149 0x46 => { 921 1150 Name => 'Rotation', … … 938 1167 ValueConvInv => '48 - 8*log($val)/log(2)', 939 1168 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 940 PrintConvInv => ' eval $val',1169 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 941 1170 }, 942 1171 0x4a => 'FreeMemoryCardImages', … … 952 1181 0x60 => { 953 1182 Name => 'NoiseReduction', 954 PrintConv => { 0 => 'Off', 1 => 'On' },1183 PrintConv => \%offOn, 955 1184 }, 956 1185 0x62 => { … … 961 1190 0x71 => { 962 1191 Name => 'ImageStabilization', 963 PrintConv => { 0 => 'Off', 1 => 'On' },1192 PrintConv => \%offOn, 964 1193 }, 965 1194 0x75 => { 966 1195 Name => 'ZoneMatchingOn', 967 PrintConv => { 0 => 'Off', 1 => 'On' },1196 PrintConv => \%offOn, 968 1197 }, 969 1198 ); … … 1031 1260 }, 1032 1261 }, 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 }, 1042 1270 0x25 => { 1043 1271 Name => 'MeteringMode', 1044 1272 PrintConv => { 1045 1273 0 => 'Multi-segment', 1046 1 => 'Center weighted',1274 1 => 'Center-weighted average', 1047 1275 2 => 'Spot', 1048 1276 }, … … 1068 1296 # ValueConvInv => '$val * 24', 1069 1297 # }, 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 }, 1081 1308 0x30 => { 1082 1309 Name => 'Sharpness', … … 1099 1326 ValueConvInv => '48 - 8*log($val)/log(2)', 1100 1327 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 1101 PrintConvInv => ' eval $val',1328 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 1102 1329 }, 1103 1330 0x36 => { #PH … … 1116 1343 ValueConvInv => '$val / 100', 1117 1344 }, 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 }, 1124 1350 0x50 => { 1125 1351 Name => 'Rotation', … … 1134 1360 ValueConv => '$val / 100 - 3', 1135 1361 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)', 1138 1364 }, 1139 1365 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 }, 1149 1374 # 0x66 maybe program mode or some setting like this? (PH) 1150 1375 0x6e => { #10 … … 1154 1379 ValueConvInv => '$val / 100', 1155 1380 }, 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 }, 1172 1396 # 0x95 FlashStrength? (PH) 1173 1397 # 0xa4 similar information to 0x27, except with different values … … 1179 1403 0xb0 => { 1180 1404 Name => 'NoiseReduction', 1181 PrintConv => { 0 => 'Off', 1 => 'On' },1405 PrintConv => \%offOn, 1182 1406 }, 1183 1407 0xbd => { 1184 1408 Name => 'ImageStabilization', 1185 PrintConv => { 0 => 'Off', 1 => 'On' },1409 PrintConv => \%offOn, 1186 1410 }, 1187 1411 ); … … 1194 1418 NOTES => 'Camera settings information for the Sony DSLR-A100.', 1195 1419 WRITABLE => 1, 1196 PRIORITY => 0, 1420 PRIORITY => 0, # may not be as reliable as other information 1197 1421 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 1198 1422 FORMAT => 'int16u', … … 1207 1431 3 => 'Manual', 1208 1432 4 => 'Auto', 1433 5 => 'Program Shift A', #20 1434 6 => 'Program Shift S', #20 1209 1435 0x1013 => 'Portrait', 1436 0x1023 => 'Sports', #20 1437 0x1033 => 'Sunset', #20 1438 0x1043 => 'Night View/Portrait', #20 1210 1439 0x1053 => 'Landscape', 1440 0x1083 => 'Macro', #20 1211 1441 }, 1212 1442 }, 1213 1443 0x01 => { #15 1214 Name => 'ExposureCompensation', 1444 Name => 'ExposureCompensationSetting', 1445 # (differs from ExposureCompensation for exposure bracketing shots, ref 20) 1215 1446 ValueConv => '$val / 100 - 3', 1216 1447 ValueConvInv => 'int(($val + 3) * 100 + 0.5)', 1217 1448 }, 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 }, 1219 1498 0x0b => { #15 1220 1499 Name => 'WhiteBalance', … … 1232 1511 }, 1233 1512 }, 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 }, 1238 1603 0x16 => { #15 1239 1604 Name => 'ColorMode', … … 1249 1614 }, 1250 1615 }, 1251 # 0x17 => 'ColorSpace' (ref 15) 1616 0x17 => { # 15/20 1617 Name => 'ColorSpace', 1618 PrintConv => { 1619 0 => 'sRGB', 1620 5 => 'Adobe RGB', 1621 }, 1622 }, 1252 1623 0x18 => { #15 1253 1624 Name => 'Sharpness', 1254 1625 ValueConv => '$val - 10', 1255 1626 ValueConvInv => '$val + 10', 1256 PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)', 1257 PrintConvInv => '$val=~/normal/i ? 0 : $val', 1627 %Image::ExifTool::Exif::printParameter, 1258 1628 }, 1259 1629 0x19 => { #15 … … 1261 1631 ValueConv => '$val - 10', 1262 1632 ValueConvInv => '$val + 10', 1263 PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)', 1264 PrintConvInv => '$val=~/normal/i ? 0 : $val', 1633 %Image::ExifTool::Exif::printParameter, 1265 1634 }, 1266 1635 0x1a => { #15 … … 1268 1637 ValueConv => '$val - 10', 1269 1638 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 }, 1272 1654 }, 1273 1655 0x1e => { #PH … … 1276 1658 0 => 'Single Frame', 1277 1659 1 => 'Continuous', 1278 2 => 'Self- Timer',1660 2 => 'Self-timer', 1279 1661 3 => 'Continuous Bracketing', 1280 1662 4 => 'Single-Frame Bracketing', … … 1282 1664 }, 1283 1665 }, 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 }, 1284 1801 0x3f => { #PH 1285 1802 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 }, 1287 1955 }, 1288 1956 0x5a => { #15 … … 1293 1961 2 => 'Rotate 90 CW', 1294 1962 }, 1963 }, 1964 0x5b => { #20 1965 Name => 'AELock', 1966 PrintConv => \%offOn, 1967 }, 1968 0x57 => { #15 1969 Name => 'ImageStabilization', 1970 PrintConv => \%offOn, 1295 1971 }, 1296 1972 0x5e => { #15 … … 1299 1975 ValueConvInv => '$val / 100', 1300 1976 }, 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]', 1305 2133 }, 1306 2134 ); … … 1374 2202 =head1 AUTHOR 1375 2203 1376 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)2204 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 1377 2205 1378 2206 This library is free software; you can redistribute it and/or modify it … … 1392 2220 1393 2221 Thanks to Jay Al-Saadi, Niels Kristian Bech Jensen, Shingo Noguchi, Pedro 1394 Corte-Real and Jeffery Small for the information they provided. 2222 Corte-Real, Jeffery Small, Jens Duttke, Thomas Kassner, Mladen Sever, Olaf 2223 Ulrich, Lukasz Stelmach and Igal Milchtaich for the information they 2224 provided, and for everyone who helped with the LensType list. 1395 2225 1396 2226 =head1 SEE ALSO -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MinoltaRaw.pm
r16842 r24107 8 8 # References: 1) http://www.cybercom.net/~dcoffin/dcraw/ 9 9 # 2) http://www.chauveau-central.net/mrw-format/ 10 # 3) Igal Milchtaich private communication (A100) 10 11 #------------------------------------------------------------------------------ 11 12 … … 15 16 use vars qw($VERSION); 16 17 use Image::ExifTool qw(:DataAccess :Utils); 17 18 $VERSION = '1.02'; 18 use Image::ExifTool::Minolta; 19 20 $VERSION = '1.12'; 21 22 sub ProcessMRW($$;$); 23 sub WriteMRW($$;$); 19 24 20 25 # Minolta MRW tags 21 26 %Image::ExifTool::MinoltaRaw::Main = ( 22 27 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 28 PROCESS_PROC => \&Image::ExifTool::MinoltaRaw::ProcessMRW, 29 WRITE_PROC => \&Image::ExifTool::MinoltaRaw::WriteMRW, 23 30 NOTES => 'These tags are used in Minolta RAW format (MRW) images.', 24 "\0TTW" => { 31 "\0TTW" => { # TIFF Tags 25 32 Name => 'MinoltaTTW', 26 33 SubDirectory => { … … 31 38 }, 32 39 }, 33 "\0PRD" => { 40 "\0PRD" => { # Raw Picture Dimensions 34 41 Name => 'MinoltaPRD', 35 42 SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::PRD' }, 36 43 }, 37 "\0WBG" => { 44 "\0WBG" => { # White Balance Gains 38 45 Name => 'MinoltaWBG', 39 46 SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::WBG' }, 40 47 }, 41 "\0RIF" => { 48 "\0RIF" => { # Requested Image Format 42 49 Name => 'MinoltaRIF', 43 50 SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::RIF' }, 44 51 }, 52 # "\0CSA" is padding 45 53 ); 46 54 … … 111 119 Format => 'int8u[4]', 112 120 }, 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 ], 117 134 ); 118 135 … … 150 167 4 => 'Sunset', 151 168 5 => 'Sports', 169 # have seen these values in Sony ARW images: - PH 170 # 7, 128, 129, 160 152 171 }, 153 172 }, 154 173 6 => { 155 174 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]', 174 267 }, 175 268 56 => { 176 269 Name => 'ColorFilter', 270 Condition => '$$self{Make} !~ /^SONY/', 177 271 Format => 'int8s', 272 Notes => 'Minolta models', 178 273 }, 179 274 57 => 'BWFilter', 180 275 58 => { 181 276 Name => 'ZoneMatching', 277 Condition => '$$self{Make} !~ /^SONY/', 278 Priority => 0, 279 Notes => 'Minolta models', 182 280 PrintConv => { 183 281 0 => 'ISO Setting Used', … … 192 290 60 => { 193 291 Name => 'ColorTemperature', 292 Condition => '$$self{Make} !~ /^SONY/', 293 Notes => 'Minolta models', 194 294 ValueConv => '$val * 100', 195 295 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', 196 335 }, 197 336 ); … … 223 362 224 363 #------------------------------------------------------------------------------ 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 367 sub 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 #------------------------------------------------------------------------------ 225 378 # Read or write Minolta MRW file 226 # Inputs: 0) ExifTool object ref erence, 1) dirInfo reference379 # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) optional tag table ref 227 380 # 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 382 sub ProcessMRW($$;$) 229 383 { 230 my ($exifTool, $dirInfo ) = @_;384 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 231 385 my $raf = $$dirInfo{RAF}; 232 386 my $outfile = $$dirInfo{OutFile}; … … 235 389 my ($data, $err, $outBuff); 236 390 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 } 237 397 $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'); 242 405 if ($outfile) { 243 406 $exifTool->InitWriteDirs('TIFF'); # use same write dirs as TIFF 244 407 $outBuff = ''; 245 408 } 246 my $ offset = Get32u(\$data, 4) + 8;247 my $ pos = 8;409 my $pos = $raf->Tell(); 410 my $offset = Get32u(\$data, 4) + $pos; 248 411 my $rtnVal = 1; 249 412 $verbose and printf $out " [MRW Data Offset: 0x%x]\n", $offset; … … 258 421 if ($verbose > 2) { 259 422 $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); 263 424 } 264 425 } … … 267 428 my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable}); 268 429 my $buff; 430 # save shift for values stored with wrong base offset 431 $$exifTool{MRW_WrongBase} = -($raf->Tell()); 269 432 $raf->Read($buff, $len) == $len or $err = 1, last; 270 433 my %subdirInfo = ( … … 307 470 if ($outfile) { 308 471 # 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; 310 473 # copy over image data 311 474 while ($raf->Read($outBuff, 65536)) { 312 475 Write($outfile, $outBuff) or $rtnVal = -1; 313 476 } 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"); 314 482 } 315 $err and $exifTool->Error("MRW format error");316 483 return $rtnVal; 317 484 } … … 336 503 =head1 AUTHOR 337 504 338 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)505 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 339 506 340 507 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Nikon.pm
r16842 r24107 8 8 # 09/21/2004 - P. Harvey Changed tag 2 to ISOUsed & added PrintConv 9 9 # 12/01/2004 - P. Harvey Added default PRINT_CONV 10 # 12/06/2004 - P. Harvey Added SceneMode11 10 # 01/01/2005 - P. Harvey Decode preview image and preview IFD 12 11 # 03/35/2005 - T. Christiansen additions 13 12 # 05/10/2005 - P. Harvey Decode encrypted lens data 13 # [ongoing] - P. Harvey Constantly decoding new information 14 14 # 15 15 # References: 1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html … … 22 22 # 8) Robert Rottmerhusen private communication 23 23 # 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) 25 25 # 11) http://www.rottmerhusen.com/objektives/lensid/thirdparty.html 26 26 # 12) http://libexif.sourceforge.net/internals/mnote-olympus-tag_8h-source.html 27 27 # 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) 29 29 # 15) http://tomtia.plala.jp/DigitalCamera/MakerNote/index.asp 30 30 # 16) Jeffrey Friedl private communication (D200 with firmware update) 31 31 # 17) http://www.wohlberg.net/public/software/photo/nstiffexif/ 32 # and Brendt Wohlberg private communication 32 33 # 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 36 46 #------------------------------------------------------------------------------ 37 47 … … 43 53 use Image::ExifTool::Exif; 44 54 45 $VERSION = '1.76'; 55 $VERSION = '2.47'; 56 57 sub LensIDConv($$$); 58 sub ProcessNikonAVI($$$); 59 sub ProcessNikonMOV($$$); 60 sub FormatString($); 61 sub ProcessNikonCaptureEditVersions($$$); 46 62 47 63 # nikon lens ID numbers (ref 8/11) … … 52 68 MaxApertureAtMinFocal, MaxApertureAtMaxFocal, MCUVersion and LensType, in 53 69 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 56 79 # (hex digits must be uppercase in keys below) 57 80 '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',60 81 '02 42 44 5C 2A 34 02 00' => 'AF Zoom-Nikkor 35-70mm f/3.3-4.5', 61 82 '02 42 44 5C 2A 34 08 00' => 'AF Zoom-Nikkor 35-70mm f/3.3-4.5', … … 68 89 '09 48 37 37 24 24 04 00' => 'AF Nikkor 24mm f/2.8', 69 90 '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', 70 92 '0B 48 7C 7C 24 24 05 00' => 'AF Nikkor 180mm f/2.8 IF-ED', 71 93 '0D 40 44 72 2C 34 07 00' => 'AF Zoom-Nikkor 35-135mm f/3.5-4.5', … … 78 100 '14 48 60 80 24 24 0B 00' => 'AF Zoom-Nikkor 80-200mm f/2.8 ED', 79 101 '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', 81 104 '18 40 44 72 2C 34 0E 00' => 'AF Zoom-Nikkor 35-135mm f/3.5-4.5 N', 82 105 '1A 54 44 44 18 18 11 00' => 'AF Nikkor 35mm f/2', … … 86 109 '1E 54 56 56 24 24 13 00' => 'AF Micro-Nikkor 60mm f/2.8', 87 110 '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', 89 112 '21 40 3C 5C 2C 34 16 00' => 'AF Zoom-Nikkor 28-70mm f/3.5-4.5', 90 113 '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', 92 116 '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 '2 7 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', 95 119 '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', 96 123 '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', 97 127 '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', 98 129 '2C 48 6A 6A 18 18 27 02' => 'AF DC-Nikkor 105mm f/2D', 99 130 '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', 100 132 '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', 102 138 '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', 104 140 '33 48 2D 2D 24 24 31 02' => 'AF Nikkor 18mm f/2.8D', 105 141 '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', 106 146 '36 48 37 37 24 24 34 02' => 'AF Nikkor 24mm f/2.8D', 107 147 '37 48 30 30 24 24 36 02' => 'AF Nikkor 20mm f/2.8D', 108 148 '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', 109 150 '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 110 152 '3D 3C 44 60 30 3C 3E 02' => 'AF Zoom-Nikkor 35-80mm f/4-5.6D', 111 153 '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', 112 155 '41 48 7C 7C 24 24 43 02' => 'AF Nikkor 180mm f/2.8D IF-ED', 113 156 '42 54 44 44 18 18 44 02' => 'AF Nikkor 35mm f/2D', 114 157 '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', 115 160 '46 3C 44 60 30 3C 49 02' => 'AF Zoom-Nikkor 35-80mm f/4-5.6D N', 116 161 '47 42 37 50 2A 34 4A 02' => 'AF Zoom-Nikkor 24-50mm f/3.3-4.5D', 117 162 '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', 118 170 '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', 119 175 '4C 40 37 6E 2C 3C 4F 02' => 'AF Zoom-Nikkor 24-120mm f/3.5-5.6D IF', 120 176 '4D 40 3C 80 2C 3C 62 02' => 'AF Zoom-Nikkor 28-200mm f/3.5-5.6D IF', 121 177 '4E 48 72 72 18 18 51 02' => 'AF DC-Nikkor 135mm f/2D', 122 178 '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', 123 181 '53 48 60 80 24 24 60 02' => 'AF Zoom-Nikkor 80-200mm f/2.8D ED', 124 182 '54 44 5C 7C 34 3C 58 02' => 'AF Zoom-Micro Nikkor 70-180mm f/4.5-5.6D ED', 125 183 '56 48 5C 8E 30 3C 5A 02' => 'AF Zoom-Nikkor 70-300mm f/4-5.6D ED', 126 184 '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', 127 188 '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', 128 190 '5D 48 3C 5C 24 24 63 02' => 'AF-S Zoom-Nikkor 28-70mm f/2.8D IF-ED', 129 191 '5E 48 60 80 24 24 64 02' => 'AF-S Zoom-Nikkor 80-200mm f/2.8D IF-ED', … … 142 204 '6D 48 8E 8E 24 24 73 02' => 'AF-S Nikkor 300mm f/2.8D IF-ED II', 143 205 '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', 146 208 '72 48 4C 4C 24 24 77 00' => 'Nikkor 45mm f/2.8 P', 147 209 '74 40 37 62 2C 34 78 06' => 'AF-S Zoom-Nikkor 24-85mm f/3.5-4.5G IF-ED', … … 151 213 '78 40 37 6E 2C 3C 7C 0E' => 'AF-S VR Zoom-Nikkor 24-120mm f/3.5-5.6G IF-ED', 152 214 '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', 154 216 '7B 48 80 98 30 30 80 0E' => 'AF-S VR Zoom-Nikkor 200-400mm f/4G IF-ED', 155 217 '7D 48 2B 53 24 24 82 06' => 'AF-S DX Zoom-Nikkor 17-55mm f/2.8G IF-ED', … … 158 220 '81 54 80 80 18 18 86 0E' => 'AF-S VR Nikkor 200mm f/2G IF-ED', 159 221 '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', 160 223 '89 3C 53 80 30 3C 8B 06' => 'AF-S DX Zoom-Nikkor 55-200mm f/4-5.6G ED', 161 224 '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', #21163 225 '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 164 227 '8C 40 2D 53 2C 3C 8E 06' => 'AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED', 165 228 '8D 44 5C 8E 34 3C 8F 0E' => 'AF-S VR Zoom-Nikkor 70-300mm f/4.5-5.6G IF-ED', #10 166 229 '8F 40 2D 72 2C 3C 91 06' => 'AF-S DX Zoom-Nikkor 18-135mm f/3.5-5.6G IF-ED', 167 230 '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', 169 233 '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 175 268 '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', 177 306 '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', 183 311 '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', 186 317 '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', 187 322 '26 40 2D 50 2C 3C 1C 06' => 'Sigma 18-50mm F3.5-5.6 DC', 188 323 '7A 40 2D 50 2C 3C 4B 06' => 'Sigma 18-50mm F3.5-5.6 DC HSM', 189 324 '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', 190 326 '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', 194 331 '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 195 334 '26 54 37 5C 24 24 1C 02' => 'Sigma 24-70mm F2.8 EX DG Macro', 196 335 '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', 198 338 '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', 200 341 '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', 203 343 '02 3F 3C 5C 2D 35 02 00' => 'Sigma 28-70mm F3.5-4.5 UC', 204 344 '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', 206 348 '26 40 3C 80 2C 3C 1C 02' => 'Sigma 28-200mm F3.5-5.6 Compact Aspherical Hyperzoom Macro', 207 349 '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 209 353 '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', 211 355 '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', 214 358 '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 215 360 '26 3C 54 80 30 3C 1C 06' => 'Sigma 55-200mm F4-5.6 DC', 216 361 '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', #19218 362 '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 220 367 '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 M ACRO',368 '26 3C 5C 8E 30 3C 1C 02' => 'Sigma 70-300mm F4-5.6 DG Macro', 222 369 '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', 223 372 '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', 226 375 '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', 227 377 '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', 228 381 '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', 238 386 # 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)', 240 436 # 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)', 254 468 # 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', 279 501 # 280 502 '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) 514 my %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) 536 my %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) 559 my %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 570 my %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 598 my %offOn = ( 0 => 'Off', 1 => 'On' ); 599 600 # common attributes for writable BinaryData directories 601 my %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, 284 607 ); 285 608 … … 287 610 %Image::ExifTool::Nikon::Main = ( 288 611 PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikon, 289 WRITE_PROC => \&Image::ExifTool:: Exif::WriteExif,612 WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikon, 290 613 CHECK_PROC => \&Image::ExifTool::Exif::CheckExif, 291 614 WRITABLE => 1, 292 615 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 293 PRINT_CONV => 'Image::ExifTool::Nikon::FormatString($val)',616 PRINT_CONV => \&FormatString, 294 617 0x0001 => { #2 295 618 # the format differs for different models. for D70, this is a string '0210', … … 312 635 Priority => 0, # the EXIF ISO is more reliable 313 636 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', 314 639 # first number is 1 for "Hi ISO" modes (H0.3, H0.7 and H1.0 on D80) - PH 315 640 PrintConv => '$_=$val;s/^0 //;s/^1 (\d+)/Hi $1/;$_', 316 641 PrintConvInv => '$_=$val;/^\d+/ ? "0 $_" : (s/Hi ?//i ? "1 $_" : $_)', 317 642 }, 643 # Note: we attempt to fix the case of these string values (typically written in all caps) 318 644 0x0003 => { Name => 'ColorMode', Writable => 'string' }, 319 645 0x0004 => { Name => 'Quality', Writable => 'string' }, … … 321 647 0x0006 => { Name => 'Sharpness', Writable => 'string' }, 322 648 0x0007 => { Name => 'FocusMode', Writable => 'string' }, 649 # FlashSetting (better named FlashSyncMode, ref 28) values: 650 # "Normal", "Slow", "Rear Slow", "RED-EYE", "RED-EYE SLOW" 323 651 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', 334 667 Writable => 'rational64u', 335 Count => 4, 668 Count => 4, # (not sure what the last 2 values are for) 336 669 }, 337 670 0x000d => { #15 … … 344 677 $a<-128 or $a>127 ? undef : pack("c4",$a,1,6,0); 345 678 }, 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)', 348 681 }, 349 682 0x000e => { … … 366 699 }, 367 700 0x0011 => { 368 Name => ' NikonPreview',369 Groups => { 1 => ' NikonPreview', 2 => 'Image' },701 Name => 'PreviewIFD', 702 Groups => { 1 => 'PreviewIFD', 2 => 'Image' }, 370 703 Flags => 'SubIFD', 371 704 SubDirectory => { 372 TagTable => 'Image::ExifTool::Nikon::PreviewI mage',705 TagTable => 'Image::ExifTool::Nikon::PreviewIFD', 373 706 Start => '$val', 374 707 }, 375 708 }, 376 0x0012 => { #2 709 0x0012 => { #2 (camera setting: combination of command dial and menus - PH) 377 710 Name => 'FlashExposureComp', 378 711 Description => 'Flash Exposure Compensation', 379 712 Writable => 'undef', 380 713 Count => 4, 714 Notes => 'may be set even if flash does not fire', 381 715 ValueConv => 'my ($a,$b,$c)=unpack("c3",$val); $c ? $a*($b/$c) : 0', 382 716 ValueConvInv => q{ … … 384 718 $a<-128 or $a>127 ? undef : pack("c4",$a,1,6,0); 385 719 }, 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)', 388 722 }, 389 723 # D70 - another ISO tag … … 395 729 PrintConvInv => '"0 $val"', 396 730 }, 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 ], 397 748 # D70 Image boundary?? top x,y bot-right x,y 398 749 0x0016 => { #2 … … 400 751 Writable => 'int16u', 401 752 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)', 402 765 }, 403 766 0x0018 => { #5 … … 416 779 Name => 'ExposureBracketValue', 417 780 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)', 420 783 }, 421 784 0x001a => { #PH … … 434 797 } 435 798 }, 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 }, 436 811 0x001d => { #4 437 812 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 441 820 }, 442 821 0x001e => { #14 … … 448 827 }, 449 828 }, 829 0x001f => { #PH 830 Name => 'VRInfo', 831 SubDirectory => { TagTable => 'Image::ExifTool::Nikon::VRInfo' }, 832 }, 450 833 0x0020 => { #16 451 834 Name => 'ImageAuthentication', 452 835 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 }, 454 905 }, 455 906 0x0080 => { Name => 'ImageAdjustment', Writable => 'string' }, … … 484 935 Count => 4, 485 936 # 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, 492 939 }, 493 940 0x0085 => { … … 505 952 0 => 'Did Not Fire', 506 953 1 => 'Fired, Manual', #14 954 3 => 'Not Ready', #28 507 955 7 => 'Fired, External', #14 508 956 8 => 'Fired, Commander Mode', … … 510 958 }, 511 959 }, 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 ], 518 977 0x0089 => { #5 519 978 Name => 'ShootingMode', 520 979 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', 521 982 # credit to Tom Christiansen (ref 7) for figuring this out... 522 983 # The (new?) bit 5 seriously complicates our life here: after firmwareB's … … 524 985 # noise reduction feature, probably because even not using it, it still 525 986 # 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 527 988 PrintConv => q[ 528 989 $_ = ''; … … 537 998 2 => 'PC Control', 538 999 4 => 'Exposure Bracketing', 539 5 => 'Unused LE-NR Slowdown',1000 5 => $$self{Model}=~/D70\b/ ? 'Unused LE-NR Slowdown' : 'Auto ISO', 540 1001 6 => 'White-Balance Bracketing', 541 1002 7 => 'IR Control', … … 543 1004 ], 544 1005 }, 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) 554 1009 0x008b => { #8 555 1010 Name => 'LensFStops', … … 562 1017 }, 563 1018 0x008c => { 564 Name => ' NEFCurve1',1019 Name => 'ContrastCurve', #JD 565 1020 Writable => 0, 566 1021 Binary => 1, … … 575 1030 0x0090 => { Name => 'LightSource', Writable => 'string' }, #2 576 1031 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 }, 577 1170 { 578 1171 Condition => '$$valPt =~ /^02/', 579 Name => 'ShotInfo', 580 Writable => 0, # can't yet write encrypted data 1172 Name => 'ShotInfo02xx', 581 1173 SubDirectory => { 582 1174 TagTable => 'Image::ExifTool::Nikon::ShotInfo', 583 1175 ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, 1176 WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, 584 1177 DecryptStart => 4, 585 DecryptLen => 0x24e, 1178 DecryptLen => 0x251, 1179 ByteOrder => 'BigEndian', 586 1180 }, 587 1181 }, 588 1182 { 589 Name => 'ShotInfo ',1183 Name => 'ShotInfoUnknown', 590 1184 Writable => 0, 591 Unknown => 1, # no tags known so don't process unless necessary592 1185 SubDirectory => { 593 1186 TagTable => 'Image::ExifTool::Nikon::ShotInfo', 594 DirOffset => 4,1187 ByteOrder => 'BigEndian', 595 1188 }, 596 1189 }, … … 600 1193 Writable => 'int16s', 601 1194 }, 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 }, 607 1206 0x0094 => { Name => 'Saturation', Writable => 'int16s' }, 608 1207 0x0095 => { Name => 'NoiseReduction', Writable => 'string' }, 609 1208 0x0096 => { 610 Name => ' NEFCurve2',1209 Name => 'LinearizationTable', # same table as DNG LinearizationTable (ref JD) 611 1210 Writable => 0, 612 1211 Binary => 1, 613 1212 }, 614 1213 0x0097 => [ #4 1214 # (NOTE: these are byte-swapped by NX when byte order changes) 615 1215 { 616 1216 Condition => '$$valPt =~ /^0100/', # (D100) … … 642 1242 Condition => '$$valPt =~ /^0205/', # (D50) 643 1243 Name => 'ColorBalance0205', 644 Writable => 0, # can't yet write encrypted data645 1244 SubDirectory => { 646 1245 TagTable => 'Image::ExifTool::Nikon::ColorBalance2', 647 1246 ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, 1247 WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, 648 1248 DecryptStart => 4, 649 1249 DecryptLen => 22, # 284 bytes encrypted, but don't need to decrypt it all … … 652 1252 }, 653 1253 { 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', 655 1267 Name => 'ColorBalance02', 656 Writable => 0, # can't yet write encrypted data657 1268 SubDirectory => { 658 1269 TagTable => 'Image::ExifTool::Nikon::ColorBalance2', 659 1270 ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, 1271 WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, 660 1272 DecryptStart => 284, 661 1273 DecryptLen => 14, # 324 bytes encrypted, but don't need to decrypt it all … … 663 1275 }, 664 1276 }, 665 { 1277 { # (D90/D5000=0211,D300S=0212,D3000=0213,D3S=0214,D3100=0215,D7000/D5100=0216) 666 1278 Name => 'ColorBalanceUnknown', 667 1279 Writable => 0, … … 672 1284 Condition => '$$valPt =~ /^0100/', # D100, D1X - PH 673 1285 Name => 'LensData0100', 674 SubDirectory => { 675 TagTable => 'Image::ExifTool::Nikon::LensData00', 676 }, 1286 SubDirectory => { TagTable => 'Image::ExifTool::Nikon::LensData00' }, 677 1287 }, 678 1288 { #8 679 1289 Condition => '$$valPt =~ /^0101/', # D70, D70s - PH 680 1290 Name => 'LensData0101', 681 SubDirectory => { 682 TagTable => 'Image::ExifTool::Nikon::LensData01', 683 }, 1291 SubDirectory => { TagTable => 'Image::ExifTool::Nikon::LensData01' }, 684 1292 }, 685 1293 # note: this information is encrypted if the version is 02xx … … 690 1298 Condition => '$$valPt =~ /^020[1-3]/', 691 1299 Name => 'LensData0201', 692 Writable => 0, # can't yet write encrypted data693 1300 SubDirectory => { 694 1301 TagTable => 'Image::ExifTool::Nikon::LensData01', 695 1302 ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, 1303 WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, 696 1304 DecryptStart => 4, 697 1305 }, 698 1306 }, 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 }, 699 1317 { 700 1318 Name => 'LensDataUnknown', 701 Writable => 0, 1319 SubDirectory => { 1320 TagTable => 'Image::ExifTool::Nikon::LensDataUnknown', 1321 }, 702 1322 }, 703 1323 ], … … 714 1334 PrintConvInv => '$val=~tr/a-zA-Z/ /;$val', 715 1335 }, 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 }, 717 1366 0x00a0 => { Name => 'SerialNumber', Writable => 'string' }, #2 718 1367 0x00a2 => { # size of compressed image data plus EOI segment (ref 10) … … 720 1369 Writable => 'int32u', 721 1370 }, 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 722 1375 0x00a5 => { #15 723 1376 Name => 'ImageCount', … … 731 1384 0x00a7 => { # Number of shots taken by camera so far (ref 2) 732 1385 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 742 1420 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) 744 1422 0x00ac => { Name => 'ImageStabilization',Writable=> 'string' }, #14 745 1423 0x00ad => { Name => 'AFResponse', Writable => 'string' }, #14 … … 747 1425 Name => 'MultiExposure', 748 1426 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) 754 1430 Name => 'HighISONoiseReduction', 755 1431 Writable => 'int16u', … … 763 1439 }, 764 1440 # 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 }, 765 1492 0x0e00 => { 766 1493 Name => 'PrintIM', … … 771 1498 }, 772 1499 }, 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 777 1503 0x0e01 => { 778 1504 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 }, 779 1514 SubDirectory => { 1515 DirName => 'NikonCapture', 780 1516 TagTable => 'Image::ExifTool::NikonCapture::Main', 781 1517 }, 782 1518 }, 1519 # 0x0e05 written by Nikon Capture to NEF files, values of 1 and 2 - PH 783 1520 0x0e09 => { #12 784 1521 Name => 'NikonCaptureVersion', 785 1522 Writable => 'string', 1523 PrintConv => undef, 786 1524 }, 787 1525 # 0x0e0e is in D70 Nikon Capture files (not out-of-the-camera D70 files) - PH … … 803 1541 }, 804 1542 }, 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 }, 806 1602 ); 807 1603 … … 813 1609 WRITABLE => 1, 814 1610 GROUPS => { 0 => 'MakerNotes', 1 => 'NikonScan', 2 => 'Image' }, 1611 VARS => { MINOR_ERRORS => 1 }, # this IFD is non-essential and often corrupted 815 1612 NOTES => 'This information is written by the Nikon Scan software.', 816 1613 0x02 => { Name => 'FilmType', Writable => 'string', }, … … 830 1627 PrintConvInv => '$val', 831 1628 }, 1629 0x60 => { 1630 Name => 'ScanImageEnhancer', 1631 Writable => 'int32u', 1632 PrintConv => \%offOn, 1633 }, 832 1634 0x100 => { Name => 'DigitalICE', Writable => 'string' }, 833 1635 0x110 => { … … 839 1641 SubDirectory => { TagTable => 'Image::ExifTool::Nikon::GEM' }, 840 1642 }, 1643 0x200 => { Name => 'DigitalDEEShadowAdj', Writable => 'int32u' }, 1644 0x201 => { Name => 'DigitalDEEThreshold', Writable => 'int32u' }, 1645 0x202 => { Name => 'DigitalDEEHighlightAdj',Writable => 'int32u' }, 841 1646 ); 842 1647 843 1648 # ref 17 844 1649 %Image::ExifTool::Nikon::ROC = ( 845 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 846 WRITE_PROC => \&Image::ExifTool::WriteBinaryData, 847 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 1650 %binaryDataAttrs, 848 1651 FORMAT => 'int32u', 849 WRITABLE => 1,850 FIRST_ENTRY => 0,851 1652 GROUPS => { 0 => 'MakerNotes', 1 => 'NikonScan', 2 => 'Image' }, 852 1653 0 => { … … 859 1660 # ref 17 860 1661 %Image::ExifTool::Nikon::GEM = ( 861 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 862 WRITE_PROC => \&Image::ExifTool::WriteBinaryData, 863 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 1662 %binaryDataAttrs, 864 1663 FORMAT => 'int32u', 865 WRITABLE => 1,866 FIRST_ENTRY => 0,867 1664 GROUPS => { 0 => 'MakerNotes', 1 => 'NikonScan', 2 => 'Image' }, 868 1665 0 => { … … 873 1670 ); 874 1671 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 875 2061 # Nikon AF information (ref 13) 876 2062 %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, 882 2064 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 883 2065 0 => { … … 886 2068 0 => 'Single Area', 887 2069 1 => 'Dynamic Area', 888 2 => 'Dynamic Area , Closest Subject',2070 2 => 'Dynamic Area (closest subject)', 889 2071 3 => 'Group Dynamic', 890 2072 4 => 'Single Area (wide)', … … 895 2077 Name => 'AFPoint', 896 2078 Notes => 'in some focus modes this value is not meaningful', 2079 PrintConvColumns => 2, 897 2080 PrintConv => { 898 2081 0 => 'Center', 899 2082 1 => 'Top', 900 2083 2 => 'Bottom', 901 3 => ' Left',902 4 => ' Right',2084 3 => 'Mid-left', 2085 4 => 'Mid-right', 903 2086 5 => 'Upper-left', 904 2087 6 => 'Upper-right', … … 912 2095 Name => 'AFPointsInFocus', 913 2096 Format => 'int16u', 2097 PrintConvColumns => 2, 914 2098 PrintConv => { 2099 0x7ff => 'All 11 Points', 915 2100 BITMASK => { 916 2101 0 => 'Center', 917 2102 1 => 'Top', 918 2103 2 => 'Bottom', 919 3 => ' Left',920 4 => ' Right',2104 3 => 'Mid-left', 2105 4 => 'Mid-right', 921 2106 5 => 'Upper-left', 922 2107 6 => 'Upper-right', … … 930 2115 ); 931 2116 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 932 2420 # ref PH 933 2421 %Image::ExifTool::Nikon::CaptureOffsets = ( … … 939 2427 ); 940 2428 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 941 2460 # ref 4 942 2461 %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, 947 2463 FORMAT => 'int16u', 948 FIRST_ENTRY => 0,949 2464 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 950 2465 0 => { … … 957 2472 # ref 4 958 2473 %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, 963 2475 FORMAT => 'int16u', 964 FIRST_ENTRY => 0,965 NOTES => q{966 This information is encrypted for most camera models, and if encrypted is967 not currently writable by exiftool.968 },969 2476 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 2477 NOTES => 'This information is encrypted for most camera models.', 970 2478 0 => { 971 2479 Name => 'WB_RGGBLevels', … … 977 2485 # ref 4 978 2486 %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, 983 2488 FORMAT => 'int16u', 984 FIRST_ENTRY => 0,985 2489 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 986 2490 0 => { 987 2491 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', 988 2504 Format => 'int16u[4]', 989 2505 Protected => 1, … … 1006 2522 ); 1007 2523 1008 # these are standard EXIF tags, but they are duplicated here so we 1009 # can change some names to extract the Nikon preview separately1010 %Image::ExifTool::Nikon::PreviewI mage= (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 = ( 1011 2527 WRITE_PROC => \&Image::ExifTool::Exif::WriteExif, 1012 2528 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 }, 1014 2538 0x103 => { 1015 2539 Name => 'Compression', 2540 SeparateTable => 'EXIF Compression', 1016 2541 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', 1027 2545 0x128 => { 1028 2546 Name => 'ResolutionUnit', … … 1032 2550 3 => 'cm', 1033 2551 }, 1034 Priority => 0,1035 2552 }, 1036 2553 0x201 => { 1037 2554 Name => 'PreviewImageStart', 1038 2555 Flags => [ 'IsOffset', 'Permanent' ], 1039 OffsetPair => 0x202, # point to associated byte count2556 OffsetPair => 0x202, 1040 2557 DataTag => 'PreviewImage', 1041 2558 Writable => 'int32u', 1042 WriteGroup => 'NikonPreview',1043 2559 Protected => 2, 1044 2560 }, … … 1046 2562 Name => 'PreviewImageLength', 1047 2563 Flags => 'Permanent' , 1048 OffsetPair => 0x201, # point to associated offset2564 OffsetPair => 0x201, 1049 2565 DataTag => 'PreviewImage', 1050 2566 Writable => 'int32u', 1051 WriteGroup => 'NikonPreview',1052 2567 Protected => 2, 1053 2568 }, … … 1058 2573 2 => 'Co-sited', 1059 2574 }, 1060 Priority => 0,1061 2575 }, 1062 2576 ); … … 1073 2587 ValueConv => '5 * 2**($val/24)', 1074 2588 ValueConvInv => '$val>0 ? 24*log($val/5)/log(2) : 0', 1075 PrintConv => 'sprintf("%.1f mm",$val)',2589 PrintConv => 'sprintf("%.1f mm",$val)', 1076 2590 PrintConvInv => '$val=~s/\s*mm$//;$val', 1077 2591 ); … … 1079 2593 # Version 100 Nikon lens data 1080 2594 %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, 1086 2596 NOTES => 'This structure is used by the D100, and D1X with firmware version 1.1.', 1087 2597 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 2598 # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added 1088 2599 0x00 => { 1089 2600 Name => 'LensDataVersion', 1090 2601 Format => 'undef[4]', 2602 Writable => 0, 1091 2603 }, 1092 2604 0x06 => { #8 … … 1122 2634 # Nikon lens data (note: needs decrypting if LensDataVersion is 020x) 1123 2635 %Image::ExifTool::Nikon::LensData01 = ( 1124 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 1125 FIRST_ENTRY => 0, 2636 %binaryDataAttrs, 1126 2637 NOTES => q{ 1127 2638 Nikon encrypts the LensData information below if LensDataVersion is 0201 or 1128 2639 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. 1131 2641 }, 1132 2642 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 2643 # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added 1133 2644 0x00 => { 1134 2645 Name => 'LensDataVersion', 1135 2646 Format => 'string[4]', 2647 Writable => 0, 1136 2648 }, 1137 2649 0x04 => { #8 … … 1139 2651 ValueConv => '$val ? 2048 / $val : $val', 1140 2652 ValueConvInv => '$val ? 2048 / $val : $val', 1141 PrintConv => 'sprintf("%.1f mm",$val)',1142 PrintConvInv => '$val=~s/ ?mm$//; $val',2653 PrintConv => 'sprintf("%.1f mm",$val)', 2654 PrintConvInv => '$val=~s/\s*mm$//; $val', 1143 2655 }, 1144 2656 0x05 => { #8 … … 1147 2659 }, 1148 2660 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) 1149 2665 Name => 'FocusPosition', 1150 2666 PrintConv => 'sprintf("0x%02x", $val)', … … 1201 2717 ); 1202 2718 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 = ( 1205 2807 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 1206 2808 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, 1207 2819 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 1208 2820 DATAMEMBER => [ 0 ], 1209 2821 NOTES => q{ 1210 2822 This information is encrypted for ShotInfoVersion 02xx, and some tags are 1211 only valid for specific versions.2823 only valid for specific models. 1212 2824 }, 1213 2825 0x00 => { 1214 2826 Name => 'ShotInfoVersion', 1215 RawConv => '$$self{ShotInfoVersion} = $val',1216 2827 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, 1217 2842 }, 1218 2843 0x66 => { 1219 2844 Name => 'VR_0x66', 1220 Condition => '$$self{ShotInfoVersion} =~ /^(0204)$/',2845 Condition => '$$self{ShotInfoVersion} eq "0204"', 1221 2846 Format => 'int8u', 1222 2847 Unknown => 1, … … 1231 2856 0x6a => { 1232 2857 Name => 'ShutterCount', 1233 Condition => '$$self{ShotInfoVersion} =~ /^(0204)$/',2858 Condition => '$$self{ShotInfoVersion} eq "0204"', 1234 2859 Format => 'int32u', 1235 2860 Priority => 0, … … 1238 2863 0x6e => { 1239 2864 Name => 'DeletedImageCount', 1240 Condition => '$$self{ShotInfoVersion} =~ /^(0204)$/',2865 Condition => '$$self{ShotInfoVersion} eq "0204"', 1241 2866 Format => 'int32u', 1242 2867 Priority => 0, 1243 2868 Notes => 'D2X, D2Xs', 1244 2869 }, 1245 0x75 => { # 192870 0x75 => { #JD 1246 2871 Name => 'VibrationReduction', 1247 Condition => '$$self{ShotInfoVersion} =~ /^(0207)$/',2872 Condition => '$$self{ShotInfoVersion} eq "0207"', 1248 2873 Format => 'int8u', 1249 2874 Notes => 'D200', 1250 2875 PrintConv => { 1251 2876 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) 1254 2882 }, 1255 2883 }, 1256 2884 0x82 => { # educated guess, needs verification 1257 2885 Name => 'VibrationReduction', 1258 Condition => '$$self{ShotInfoVersion} =~ /^(0204)$/',2886 Condition => '$$self{ShotInfoVersion} eq "0204"', 1259 2887 Format => 'int8u', 1260 2888 Notes => 'D2X, D2Xs', … … 1264 2892 }, 1265 2893 }, 1266 0x157 => { # 192894 0x157 => { #JD 1267 2895 Name => 'ShutterCount', 1268 Condition => '$$self{ShotInfoVersion} =~ /^(0205)$/',2896 Condition => '$$self{ShotInfoVersion} eq "0205"', 1269 2897 Format => 'undef[2]', 1270 2898 Priority => 0, … … 1274 2902 ValueConvInv => 'pack("n",$val)', 1275 2903 }, 1276 0x1ae => { # 192904 0x1ae => { #JD 1277 2905 Name => 'VibrationReduction', 1278 Condition => '$$self{ShotInfoVersion} =~ /^(0205)$/',2906 Condition => '$$self{ShotInfoVersion} eq "0205"', 1279 2907 Format => 'int8u', 1280 2908 Notes => 'D50', … … 1286 2914 }, 1287 2915 }, 1288 0x24 a => { #192916 0x24d => { #PH 1289 2917 Name => 'ShutterCount', 1290 Condition => '$$self{ShotInfoVersion} =~ /^(0208)$/', 2918 Condition => '$$self{ShotInfoVersion} eq "0211"', 2919 Notes => 'D60', 1291 2920 Format => 'int32u', 1292 2921 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 1296 2948 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', 1299 3385 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) 1300 3390 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 }, 1312 4259 ); 1313 4260 1314 4261 # Multi exposure / image overlay information (ref PH) 1315 4262 %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, 1321 4264 FORMAT => 'int32u', 1322 4265 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 4266 # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added 1323 4267 0 => { 1324 4268 Name => 'MultiExposureVersion', 1325 4269 Format => 'string[4]', 4270 Writable => 0, 1326 4271 }, 1327 4272 1 => { … … 1336 4281 3 => { 1337 4282 Name => 'MultiExposureAutoGain', 1338 PrintConv => { 0 => 'Off', 1 => 'On' },4283 PrintConv => \%offOn, 1339 4284 }, 1340 4285 ); 1341 4286 1342 4287 # tags in Nikon QuickTime videos (PH - observations with Coolpix S3) 1343 # ( note: very similar to information in Pentaxvideos)4288 # (similar information in Kodak,Minolta,Nikon,Olympus,Pentax and Sanyo videos) 1344 4289 %Image::ExifTool::Nikon::MOV = ( 1345 4290 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 1346 4291 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 4292 FIRST_ENTRY => 0, 1347 4293 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. 1350 4295 }, 1351 4296 0x00 => { 1352 4297 Name => 'Make', 1353 Format => 'string[5]', 1354 PrintConv => 'ucfirst(lc($val))', 4298 Format => 'string[24]', 1355 4299 }, 1356 4300 0x18 => { … … 1359 4303 Format => 'string[8]', 1360 4304 }, 4305 # (01 00 at offset 0x20) 1361 4306 0x26 => { 1362 4307 Name => 'ExposureTime', … … 1367 4312 0x2a => { 1368 4313 Name => 'FNumber', 1369 Format => 'int32u', 1370 ValueConv => '$val * 0.1', 4314 Format => 'rational64u', 1371 4315 PrintConv => 'sprintf("%.1f",$val)', 1372 4316 }, 1373 4317 0x32 => { 1374 4318 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)', 1378 4321 }, 1379 4322 0x44 => { … … 1391 4334 0x48 => { 1392 4335 Name => 'FocalLength', 1393 Writable => 'int32u', 1394 ValueConv => '$val * 0.1', 1395 PrintConv => 'sprintf("%.1fmm",$val)', 4336 Format => 'rational64u', 4337 PrintConv => 'sprintf("%.1f mm",$val)', 1396 4338 }, 1397 4339 0xaf => { … … 1402 4344 Name => 'ISO', 1403 4345 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 ); 1407 4668 1408 4669 # Nikon composite tags … … 1434 4695 PrintConv => \%nikonLensIDs, 1435 4696 }, 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 }, 1436 4705 ); 1437 4706 … … 1439 4708 Image::ExifTool::AddCompositeTags('Image::ExifTool::Nikon'); 1440 4709 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 4714 sub 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 4745 sub 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 4780 sub 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, ... 4796 sub 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 4809 sub 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 } 1441 4834 1442 4835 #------------------------------------------------------------------------------ … … 1452 4845 $str = substr($str,0,55) . "[...]"; 1453 4846 } 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 } 1459 4861 } 1460 4862 } … … 1503 4905 # 4) optional start offset (default 0) 1504 4906 # 5) optional number of bytes to decode (default to the end of the data) 1505 # Returns: Decrypted data block4907 # Returns: data block with specified data decrypted 1506 4908 sub Decrypt($$$;$$) 1507 4909 { 1508 4910 my ($dataPt, $serial, $count, $start, $len) = @_; 4911 my ($i, $dat); 4912 1509 4913 $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; 1512 4916 my $key = 0; 1513 4917 for ($i=0; $i<4; ++$i) { … … 1517 4921 my $cj = $xlat[1][$key]; 1518 4922 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) { 1521 4925 $cj = ($cj + $ci * $ck) & 0xff; 1522 4926 $ck = ($ck + 1) & 0xff; 1523 $dat a[$i]^= $cj;4927 $dat ^= $cj; 1524 4928 } 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; 1526 4933 } 1527 4934 1528 4935 #------------------------------------------------------------------------------ 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 4939 sub 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 1532 4951 # Returns: 1 on success 4952 sub 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) 1533 4992 sub ProcessNikonEncrypted($$$) 1534 4993 { 1535 4994 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 5093 sub 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); 1543 5151 } 1544 5152 return 1; … … 1546 5154 1547 5155 #------------------------------------------------------------------------------ 5156 # Process Nikon Capture history data 5157 # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref 5158 # Returns: 1 on success 5159 sub ProcessNikonCaptureEditVersions($$$) 5160 { 5161 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 5162 require Image::ExifTool::NikonCapture; 5163 return Image::ExifTool::NikonCapture::ProcessNikonCaptureEditVersions($exifTool, $dirInfo, $tagTablePtr); 5164 } 5165 5166 #------------------------------------------------------------------------------ 1548 5167 # 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 1551 5169 # Returns: 1 on success 1552 5170 # Notes: This isn't a normal IFD, but is close... … … 1580 5198 1581 5199 #------------------------------------------------------------------------------ 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) 1587 5204 sub ProcessNikon($$$) 1588 5205 { 1589 5206 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); 1654 5228 } 1655 delete $exifTool->{NikonInfo}; 5229 delete $$exifTool{NikonSerialKey}; 5230 delete $$exifTool{NikonCountKey}; 1656 5231 return $rtnVal; 1657 5232 } … … 1676 5251 =head1 AUTHOR 1677 5252 1678 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)5253 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 1679 5254 1680 5255 This library is free software; you can redistribute it and/or modify it … … 1702 5277 1703 5278 Thanks 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. 5279 Christiansen, Robert Rottmerhusen, Werner Kober, Roger Larsson, Jens Duttke, 5280 Gregor Dorlars, Neil Nappe, Alexandre Naaman, Brendt Wohlberg and Warren 5281 Hatch for their help figuring out some Nikon tags, and to everyone who 5282 helped contribute to the LensID list. 1707 5283 1708 5284 =head1 SEE ALSO -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/NikonCapture.pm
r16842 r24107 5 5 # 6 6 # 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 7 9 # 8 10 # References: 1) http://www.cybercom.net/~dcoffin/dcraw/ … … 16 18 use Image::ExifTool::Exif; 17 19 18 $VERSION = '1.02'; 20 $VERSION = '1.07'; 21 22 sub ProcessNikonCapture($$$); 19 23 20 24 # common print conversions … … 41 45 the maker notes of NEF images. 42 46 }, 47 # 0x007ddc9d contains contrast information 43 48 0x008ae85e => { 44 49 Name => 'LCHEditor', … … 50 55 Writable => 'int8u', 51 56 PrintConv => \%offOn, 57 }, 58 0x116fea21 => { 59 Name => 'HighlightData', 60 SubDirectory => { 61 TagTable => 'Image::ExifTool::NikonCapture::HighlightData', 62 }, 52 63 }, 53 64 0x2175eb78 => { … … 66 77 }, 67 78 }, 79 0x39c456ac => { 80 Name => 'PictureCtrl', 81 SubDirectory => { 82 TagTable => 'Image::ExifTool::NikonCapture::PictureCtrl', 83 }, 84 }, 68 85 0x3cfc73c6 => { 69 86 Name => 'RedEyeData', 70 87 SubDirectory => { 71 88 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', 72 100 }, 73 101 }, … … 126 154 Writable => 'int16u', 127 155 }, 156 0x083a1a25 => { 157 Name => 'HistogramXML', 158 Writable => 'undef', 159 Binary => 1, 160 AdjustSize => 4, # patch Nikon bug 161 }, 128 162 0x84589434 => { 129 163 Name => 'BrightnessData', … … 150 184 }, 151 185 }, 186 # 0xa7264a72, 0x88f55e48 and 0x416391c6 all change from 0 to 1 when QuickFix is turned on 152 187 0xab5eca5e => { 153 188 Name => 'PhotoEffects', … … 182 217 PrintConv => \%offOn, 183 218 }, 219 0xe2173c47 => { 220 Name => 'PictureControl', 221 Writable => 'int8u', 222 PrintConv => \%offOn, 223 }, 184 224 0xe37b4337 => { 185 225 Name => 'D-LightingHSData', … … 193 233 TagTable => 'Image::ExifTool::NikonCapture::UnsharpData', 194 234 }, 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?) 195 245 }, 196 246 0xfe443a45 => { … … 249 299 FIRST_ENTRY => 0, 250 300 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, 251 0 => 'D-LightingH SShadow',252 1 => 'D-LightingH SHighlight',253 2 => 'D-LightingH SColorBoost',301 0 => 'D-LightingHQShadow', 302 1 => 'D-LightingHQHighlight', 303 2 => 'D-LightingHQColorBoost', 254 304 ); 255 305 … … 299 349 4 => 'Calculate Automatically' 300 350 }, 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') 301 356 }, 302 357 0x15 => { … … 315 370 Format => 'int16u', 316 371 }, 372 0x25 => { 373 Name => 'WBAdjTint', 374 Format => 'int32s', 375 }, 317 376 ); 318 377 … … 376 435 FIRST_ENTRY => 0, 377 436 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, 378 4 => {437 0x04 => { 379 438 Name => 'EdgeNoiseReduction', 380 439 PrintConv => \%offOn, 381 440 }, 382 5 => {383 Name => 'ColorMoireReduction ',441 0x05 => { 442 Name => 'ColorMoireReductionMode', 384 443 PrintConv => { 385 444 0 => 'Off', … … 389 448 }, 390 449 }, 391 9 => {450 0x09 => { 392 451 Name => 'NoiseReductionIntensity', 393 452 Format => 'int32u', 394 453 }, 395 13=> {454 0x0d => { 396 455 Name => 'NoiseReductionSharpness', 397 456 Format => 'int32u', 398 457 }, 399 17=> {458 0x11 => { 400 459 Name => 'NoiseReductionMethod', 401 460 Format => 'int16u', … … 405 464 }, 406 465 }, 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 }, 407 482 ); 408 483 … … 440 515 }, 441 516 0x8e => { 442 Name => ' OutputWidthInches',517 Name => 'CropOutputWidthInches', 443 518 Format => 'double', 444 519 }, 445 520 0x96 => { 446 Name => ' OutputHeightInches',521 Name => 'CropOutputHeightInches', 447 522 Format => 'double', 448 523 }, 449 524 0x9e => { 450 Name => ' ScaledResolution',525 Name => 'CropScaledResolution', 451 526 Format => 'double', 452 527 }, 453 528 0xae => { 454 Name => ' SourceResolution',529 Name => 'CropSourceResolution', 455 530 Format => 'double', 456 531 ValueConv => '$val / 2', … … 458 533 }, 459 534 0xb6 => { 460 Name => ' OutputResolution',535 Name => 'CropOutputResolution', 461 536 Format => 'double', 462 537 }, … … 466 541 }, 467 542 0xc6 => { 468 Name => ' OutputWidth',543 Name => 'CropOutputWidth', 469 544 Format => 'double', 470 545 }, 471 546 0xce => { 472 Name => ' OutputHeight',547 Name => 'CropOutputHeight', 473 548 Format => 'double', 474 549 }, 475 550 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) 479 604 ); 480 605 … … 495 620 }, 496 621 }, 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', 497 672 ); 498 673 … … 514 689 my $dirStart = $$dirInfo{DirStart}; 515 690 my $dirLen = $$dirInfo{DirLen}; 516 my $dirEnd = $dirStart + $dirLen;517 691 if ($dirLen < 22) { 518 692 $exifTool->Warn('Short Nikon Capture Data',1); … … 522 696 SetByteOrder('II'); 523 697 my $tagID = Get32u($dataPt, $dirStart); 698 # sometimes size includes 18 header bytes, and other times it doesn't (ie. ViewNX 2.1.1) 524 699 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)) { 526 702 $exifTool->Warn('Unrecognized Nikon Capture Data header'); 527 703 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 = ''; 528 711 } 529 712 my $outBuff = ''; 530 713 my $pos; 531 714 my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr); 715 my $dirEnd = $dirStart + $dirLen; 532 716 533 717 # loop through all entries in the Nikon Capture data … … 558 742 my $format = $$tagInfo{Format} || $$tagInfo{Writable}; 559 743 my $oldVal = ReadValue($dataPt,$pos+22,$format,1,$size); 560 my $n ewValueHash = $exifTool->GetNewValueHash($tagInfo);561 if (Image::ExifTool::IsOverwriting($n ewValueHash, $oldVal)) {744 my $nvHash = $exifTool->GetNewValueHash($tagInfo); 745 if (Image::ExifTool::IsOverwriting($nvHash, $oldVal)) { 562 746 my $val = $exifTool->GetNewValues($tagInfo); 563 747 $newVal = WriteValue($val, $$tagInfo{Writable}) if defined $val; … … 583 767 } 584 768 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 } 587 777 } 588 778 # add the header and return the new directory 589 779 return substr($$dataPt, $dirStart, 18) . 590 780 Set32u(length($outBuff) + 4) . 591 $outBuff ;781 $outBuff . $pad; 592 782 } 593 783 594 784 #------------------------------------------------------------------------------ 595 785 # 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 788 sub 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 598 824 # Returns: 1 on success 599 825 sub ProcessNikonCapture($$$) … … 624 850 } 625 851 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); 627 859 } elsif ($size == 1) { 628 860 $value = substr($$dataPt, $pos, $size); … … 641 873 1; # end 642 874 875 __END__ 876 643 877 =head1 NAME 644 878 … … 656 890 =head1 AUTHOR 657 891 658 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)892 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 659 893 660 894 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Olympus.pm
r16842 r24107 19 19 # 11) http://olypedia.de/Olympus_Makernotes 20 20 # 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 21 27 #------------------------------------------------------------------------------ 22 28 … … 28 34 use Image::ExifTool::APP12; 29 35 30 $VERSION = '1.40'; 36 $VERSION = '1.79'; 37 38 sub PrintLensInfo($$$); 31 39 32 40 my %offOn = ( 0 => 'Off', 1 => 'On' ); 33 41 42 # lookup for Olympus LensType values 43 my %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) 109 my %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 125 my %indexInfo = ( 126 Format => 'int32u', 127 RawConv => '$val == 0xffffffff ? undef : $val', 128 ValueConv => '$val / 1000', 129 PrintConv => 'ConvertDuration($val)', 130 ); 131 132 # Olympus tags 34 133 %Image::ExifTool::Olympus::Main = ( 35 134 WRITE_PROC => \&Image::ExifTool::Exif::WriteExif, … … 39 138 # 40 139 # 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) 41 141 # 42 142 0x0000 => { … … 87 187 WriteCheck => '$self->CheckImage(\$val)', 88 188 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 },125 189 }, 126 190 0x0104 => { #11 … … 197 261 0x0203 => { #6 198 262 Name => 'BWMode', 199 Description => 'Black &White Mode',263 Description => 'Black And White Mode', 200 264 Writable => 'int16u', 201 265 PrintConv => \%offOn, … … 285 349 1 => 'Standard', 286 350 2 => 'Auto', 351 3 => 'Intelligent Auto', #PH (guess, u7040) 287 352 4 => 'Portrait', 288 353 5 => 'Landscape+Portrait', … … 293 358 10 => 'Self Portrait', 294 359 11 => 'Indoor', 295 12 => 'Beach &Snow',360 12 => 'Beach & Snow', 296 361 13 => 'Beach', 297 362 14 => 'Snow', … … 309 374 26 => 'Behind Glass', 310 375 27 => 'Auction', 311 28 => 'Shoot &Select1',312 29 => 'Shoot &Select2',376 28 => 'Shoot & Select1', 377 29 => 'Shoot & Select2', 313 378 30 => 'Underwater Wide2', 314 379 31 => 'Digital Image Stabilization', 315 380 32 => 'Face Portrait', 316 381 33 => 'Pet', 382 34 => 'Smile Shot', 383 101 => 'Magic Filter', #PH 317 384 }, 318 385 }, … … 343 410 Binary => 1, 344 411 }, 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 }, 345 432 0x1000 => { #6 346 433 Name => 'ShutterSpeedValue', 347 434 Writable => 'rational64s', 348 435 Priority => 0, 349 ValueConv => 'abs($val)<100 ? 1/(2**$val) : 0',436 ValueConv => 'abs($val)<100 ? 2**(-$val) : 0', 350 437 ValueConvInv => '$val>0 ? -log($val)/log(2) : -100', 351 438 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 352 PrintConvInv => ' eval $val',439 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 353 440 }, 354 441 0x1001 => { #6 … … 397 484 Writable => 'rational64s', 398 485 }, 399 0x1007 => { #6 486 0x1007 => { #6 (E-10, E-20 and C2500L - numbers usually around 30-40) 400 487 Name => 'SensorTemperature', 401 488 Writable => 'int16s', … … 631 718 # 0x1032 HAFFINAL? #11 632 719 0x1033 => { #11 633 Name => 'SceneDetect Area',720 Name => 'SceneDetectData', 634 721 Writable => 'int32u', 635 722 Count => 720, … … 655 742 }, 656 743 0x1037 => { #6 744 # (may contain data from multiple previews - PH, FE320) 657 745 Name => 'PreviewImageLength', 658 746 OffsetPair => 0x1036, # point to associated offset … … 676 764 Name => 'NoiseReduction', 677 765 Writable => 'int16u', 678 PrintConv => { 679 0 => 'Off', 680 1 => 'On', 681 }, 766 PrintConv => \%offOn, 682 767 }, 683 768 0x103b => { #6 684 Name => ' InfinityLensStep',769 Name => 'FocusStepInfinity', 685 770 Writable => 'int16u', 686 771 }, 687 772 0x103c => { #6 688 Name => ' NearLensStep',773 Name => 'FocusStepNear', 689 774 Writable => 'int16u', 690 775 }, … … 708 793 # (presumably the Olympus programmers forgot about the 2-byte entry count at the 709 794 # 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 713 801 # 714 802 0x2010 => [ #PH 715 803 { 716 804 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) 718 807 SubDirectory => { 719 808 TagTable => 'Image::ExifTool::Olympus::Equipment', … … 722 811 }, 723 812 { 724 Name => 'Equipment 2',813 Name => 'EquipmentIFD', 725 814 Groups => { 1 => 'MakerNotes' }, # SubIFD needs group 1 set 726 815 Flags => 'SubIFD', … … 735 824 { 736 825 Name => 'CameraSettings', 737 Condition => 'not $$self{OlympusType2}', 826 Condition => '$format ne "ifd" and $format ne "int32u"', 827 NestedHtmlDump => 2, 738 828 SubDirectory => { 739 829 TagTable => 'Image::ExifTool::Olympus::CameraSettings', … … 742 832 }, 743 833 { 744 Name => 'CameraSettings 2',834 Name => 'CameraSettingsIFD', 745 835 Groups => { 1 => 'MakerNotes' }, 746 836 Flags => 'SubIFD', … … 755 845 { 756 846 Name => 'RawDevelopment', 757 Condition => 'not $$self{OlympusType2}', 847 Condition => '$format ne "ifd" and $format ne "int32u"', 848 NestedHtmlDump => 2, 758 849 SubDirectory => { 759 850 TagTable => 'Image::ExifTool::Olympus::RawDevelopment', … … 762 853 }, 763 854 { 764 Name => 'RawDevelopment 2',855 Name => 'RawDevelopmentIFD', 765 856 Groups => { 1 => 'MakerNotes' }, 766 857 Flags => 'SubIFD', … … 775 866 { 776 867 Name => 'RawDev2', 777 Condition => 'not $$self{OlympusType2}', 868 Condition => '$format ne "ifd" and $format ne "int32u"', 869 NestedHtmlDump => 2, 778 870 SubDirectory => { 779 871 TagTable => 'Image::ExifTool::Olympus::RawDevelopment2', … … 782 874 }, 783 875 { 784 Name => 'RawDev2 _2',876 Name => 'RawDev2IFD', 785 877 Groups => { 1 => 'MakerNotes' }, 786 878 Flags => 'SubIFD', … … 795 887 { 796 888 Name => 'ImageProcessing', 797 Condition => 'not $$self{OlympusType2}', 889 Condition => '$format ne "ifd" and $format ne "int32u"', 890 NestedHtmlDump => 2, 798 891 SubDirectory => { 799 892 TagTable => 'Image::ExifTool::Olympus::ImageProcessing', … … 802 895 }, 803 896 { 804 Name => 'ImageProcessing 2',897 Name => 'ImageProcessingIFD', 805 898 Groups => { 1 => 'MakerNotes' }, 806 899 Flags => 'SubIFD', … … 815 908 { 816 909 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, 818 912 SubDirectory => { 819 913 TagTable => 'Image::ExifTool::Olympus::FocusInfo', … … 822 916 }, 823 917 { 824 Name => 'FocusInfo 2',918 Name => 'FocusInfoIFD', 825 919 Condition => 'not $$self{OlympusCAMER}', 826 920 Groups => { 1 => 'MakerNotes' }, … … 834 928 { 835 929 # ASCII-based camera parameters if makernotes starts with "CAMER\0" 930 # (or for Sony models starting with "SONY PI\0" or "PREMI\0") 836 931 Name => 'CameraParameters', 837 932 Writable => 'undef', … … 839 934 }, 840 935 ], 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 ], 904 1134 0x3000 => [ 905 1135 { #6 906 1136 Name => 'RawInfo', 907 Condition => 'not $$self{OlympusType2}', 1137 Condition => '$format ne "ifd" and $format ne "int32u"', 1138 NestedHtmlDump => 2, 908 1139 SubDirectory => { 909 1140 TagTable => 'Image::ExifTool::Olympus::RawInfo', … … 912 1143 }, 913 1144 { #PH 914 Name => 'RawInfo 2',1145 Name => 'RawInfoIFD', 915 1146 Groups => { 1 => 'MakerNotes' }, 916 1147 Flags => 'SubIFD', … … 918 1149 SubDirectory => { 919 1150 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', 920 1193 Start => '$val', 921 1194 }, … … 951 1224 Name => 'EquipmentVersion', 952 1225 Writable => 'undef', 1226 RawConv => '$val=~s/\0+$//; $val', # (may be null terminated) 953 1227 Count => 4, 954 1228 }, … … 987 1261 Writable => 'int8u', 988 1262 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, 991 1276 }, 992 1277 # apparently the first 3 digits of the lens s/n give the type (ref 4): … … 997 1282 # 080 = EX-25 998 1283 # 101 = FL-50 1284 # 272 = EC-20 #7 999 1285 0x202 => { #PH 1000 1286 Name => 'LensSerialNumber', … … 1004 1290 PrintConvInv => 'pack("A31",$val)', # pad with spaces to 31 chars 1005 1291 }, 1292 0x203 => { #17 1293 Name => 'LensModel', 1294 Writable => 'string', 1295 }, 1006 1296 0x204 => { #6 1007 1297 Name => 'LensFirmwareVersion', … … 1052 1342 Writable => 'int8u', 1053 1343 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 }, 1056 1356 }, 1057 1357 0x302 => { #4 … … 1084 1384 PrintConv => { 1085 1385 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) 1088 1388 3 => 'RF-11', 1089 1389 4 => 'TF-22', 1090 1390 5 => 'FL-36', 1391 6 => 'FL-50R', #11 (or Metz mecablitz digital) 1392 7 => 'FL-36R', #11 1393 # have seen value of 9 - PH 1091 1394 }, 1092 1395 }, … … 1113 1416 Name => 'CameraSettingsVersion', 1114 1417 Writable => 'undef', 1418 RawConv => '$val=~s/\0+$//; $val', # (may be null terminated) 1115 1419 Count => 4, 1116 1420 }, … … 1149 1453 Name => 'AELock', 1150 1454 Writable => 'int16u', 1151 PrintConv => { 1152 0 => 'Off', 1153 1 => 'On', 1154 }, 1455 PrintConv => \%offOn, 1155 1456 }, 1156 1457 0x202 => { #PH/4 … … 1158 1459 Writable => 'int16u', 1159 1460 PrintConv => { 1160 2 => 'Center Weighted',1461 2 => 'Center-weighted average', 1161 1462 3 => 'Spot', 1162 1463 5 => 'ESP', … … 1166 1467 }, 1167 1468 }, 1469 0x203 => { #11 (some E-models only) 1470 Name => 'ExposureShift', 1471 Writable => 'rational64s', 1472 }, 1168 1473 0x300 => { #6 1169 1474 Name => 'MacroMode', … … 1178 1483 Name => 'FocusMode', 1179 1484 Writable => 'int16u', 1180 PrintConv => { 1485 Count => -1, 1486 Notes => '1 or 2 values', 1487 PrintConv => [{ 1181 1488 0 => 'Single AF', 1182 1489 1 => 'Sequential shooting AF', 1183 1490 2 => 'Continuous AF', 1184 1491 3 => 'Multi AF', 1492 5 => 'Face detect', #11 1185 1493 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 }}], 1187 1502 }, 1188 1503 0x302 => { #6 1189 1504 Name => 'FocusProcess', 1190 1505 Writable => 'int16u', 1191 PrintConv => { 1506 Count => -1, 1507 Notes => '1 or 2 values', 1508 PrintConv => [{ 1192 1509 0 => 'AF Not Used', 1193 1510 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 1195 1516 }, 1196 1517 0x303 => { #6 … … 1204 1525 0x304 => { #PH/4 1205 1526 Name => 'AFAreas', 1527 Notes => 'coordinates range from 0 to 255', 1206 1528 Format => 'int32u', 1207 1529 Count => 64, 1208 1530 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 1209 1548 }, 1210 1549 0x400 => { #6 … … 1224 1563 }, 1225 1564 0x401 => { #6 1226 Name => 'FlashExposureComp ensation',1565 Name => 'FlashExposureComp', 1227 1566 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', 1228 1613 }, 1229 1614 0x500 => { #6 … … 1267 1652 PrintConv => q{ 1268 1653 my ($a,$b,$c)=split ' ',$val; 1269 if ($self->{ CameraModel} =~ /^E-1\b/) {1654 if ($self->{Model} =~ /^E-1\b/) { 1270 1655 $a-=$b; $c-=$b; 1271 1656 return "CS$a (min CS0, max CS$c)"; … … 1322 1707 10 => 'Landscape', 1323 1708 11 => 'Night Scene', 1709 12 => 'Self Portrait', #11 1324 1710 13 => 'Panorama', #6 1711 14 => '2 in 1', #11 1712 15 => 'Movie', #11 1325 1713 16 => 'Landscape+Portrait', #6 1326 1714 17 => 'Night+Portrait', 1715 18 => 'Indoor', #11 (Party - PH) 1327 1716 19 => 'Fireworks', 1328 1717 20 => 'Sunset', 1718 21 => 'Beauty Skin', #PH 1329 1719 22 => 'Macro', 1720 23 => 'Super Macro', #11 1721 24 => 'Food', #11 1330 1722 25 => 'Documents', 1331 1723 26 => 'Museum', 1332 28 => 'Beach&Snow', 1724 27 => 'Shoot & Select', #11 1725 28 => 'Beach & Snow', 1726 29 => 'Self Protrait+Timer', #11 1333 1727 30 => 'Candle', 1728 31 => 'Available Light', #11 1729 32 => 'Behind Glass', #11 1730 33 => 'My Mode', #11 1731 34 => 'Pet', #11 1334 1732 35 => 'Underwater Wide1', #6 1335 1733 36 => 'Underwater Macro', #6 1734 37 => 'Shoot & Select1', #11 1735 38 => 'Shoot & Select2', #11 1336 1736 39 => 'High Key', 1337 1737 40 => 'Digital Image Stabilization', #6 1738 41 => 'Auction', #11 1739 42 => 'Beach', #11 1740 43 => 'Snow', #11 1338 1741 44 => 'Underwater Wide2', #6 1339 1742 45 => 'Low Key', #6 1340 1743 46 => 'Children', #6 1744 47 => 'Vivid', #11 1341 1745 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) 1342 1757 }, 1343 1758 }, … … 1346 1761 Writable => 'int16u', 1347 1762 PrintConv => { 1348 0 => 'Off',1349 1=> 'Noise Reduction',1350 2=> 'Noise Filter',1351 3 => 'Noise Reduction + Noise Filter',1352 4 => 'Noise Filter (ISO Boost)', #61353 5 => 'Noise Reduction + Noise Filter (ISO Boost)', #61763 BITMASK => { 1764 0 => 'Noise Reduction', 1765 1 => 'Noise Filter', 1766 2 => 'Noise Filter (ISO Boost)', 1767 3 => 'Auto', #11 1768 }, 1354 1769 }, 1355 1770 }, … … 1371 1786 Name => 'Gradation', 1372 1787 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 => [{ 1375 1792 '-1 -1 1' => 'Low Key', 1376 1793 '0 -1 1' => 'Normal', 1377 1794 '1 -1 1' => 'High Key', 1378 }, 1795 },{ 1796 0 => 'User-Selected', 1797 1 => 'Auto-Override', 1798 }], 1379 1799 }, 1380 1800 0x520 => { #6 1381 1801 Name => 'PictureMode', 1382 1802 Writable => 'int16u', 1383 PrintConv => { 1803 Notes => '1 or 2 values', 1804 Count => -1, 1805 PrintConv => [{ 1384 1806 1 => 'Vivid', 1385 1807 2 => 'Natural', 1386 1808 3 => 'Muted', 1809 4 => 'Portrait', 1810 5 => 'i-Enhance', #11 1387 1811 256 => 'Monotone', 1388 1812 512 => 'Sepia', 1389 } ,1813 }], 1390 1814 }, 1391 1815 0x521 => { #6 … … 1453 1877 '1 -2 1' => 'High', 1454 1878 }, 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 ], 1455 1891 }, 1456 1892 0x600 => { #PH/4 … … 1490 1926 return 'Off' unless $a; 1491 1927 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', 1496 1932 ); 1497 1933 return ($a{$a} || "Unknown ($a)") . ', Shot ' . $b; … … 1506 1942 3 => 'SHQ', 1507 1943 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', 1509 1966 }, 1510 1967 0x901 => { #PH (u770SW) … … 1513 1970 Writable => 'int32s', 1514 1971 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, 1515 1991 }, 1516 1992 ); … … 1525 2001 Name => 'RawDevVersion', 1526 2002 Writable => 'undef', 2003 RawConv => '$val=~s/\0+$//; $val', # (may be null terminated) 1527 2004 Count => 4, 1528 2005 }, … … 1589 2066 0 => 'Noise Reduction', 1590 2067 1 => 'Noise Filter', 1591 2 => ' ISO Boost',2068 2 => 'Noise Filter (ISO Boost)', 1592 2069 }, 1593 2070 }, … … 1609 2086 BITMASK => { 1610 2087 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', 1618 2095 }, 1619 2096 }, … … 1630 2107 Name => 'RawDevVersion', 1631 2108 Writable => 'undef', 2109 RawConv => '$val=~s/\0+$//; $val', # (may be null terminated) 1632 2110 Count => 4, 1633 2111 }, … … 1692 2170 0 => 'Noise Reduction', 1693 2171 1 => 'Noise Filter', 1694 2 => ' ISO Boost',2172 2 => 'Noise Filter (ISO Boost)', 1695 2173 }, 1696 2174 }, … … 1756 2234 Writable => 'int16s', 1757 2235 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) 1758 2250 }, 1759 2251 ); … … 1768 2260 Name => 'ImageProcessingVersion', 1769 2261 Writable => 'undef', 2262 RawConv => '$val=~s/\0+$//; $val', # (may be null terminated) 1770 2263 Count => 4, 1771 2264 }, … … 1775 2268 Count => 2, 1776 2269 }, 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 }, 1777 2402 0x200 => { #6 1778 2403 Name => 'ColorMatrix', … … 1781 2406 Count => 9, 1782 2407 }, 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', 1793 2436 Writable => 'int16u', 1794 2437 Count => 4, 1795 2438 }, 1796 0x610 => { # PH/41797 Name => ' SmoothingThreshold2',2439 0x610 => { #11 2440 Name => 'GainBase', 1798 2441 Writable => 'int16u', 1799 2442 }, … … 1803 2446 Count => 2, 1804 2447 }, 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', 1807 2460 Writable => 'int32u', 1808 2461 }, 1809 0x615 => { #PH 1810 Name => ' OlympusImageHeight2',2462 0x615 => { #PH/11 2463 Name => 'CropHeight', 1811 2464 Writable => 'int32u', 1812 2465 }, 2466 # 0x800 LensDistortionParams, float[9] (ref 11) 2467 # 0x801 LensShadingParams, int16u[16] (ref 11) 1813 2468 # 0x1010-0x1012 are the processing options used in camera or in 1814 2469 # Olympus software, which 0x050a-0x050c are in-camera only (ref 6) … … 1817 2472 Writable => 'int16u', 1818 2473 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 }, 1825 2479 }, 1826 2480 }, … … 1828 2482 Name => 'DistortionCorrection2', 1829 2483 Writable => 'int16u', 1830 PrintConv => { 1831 0 => 'Off', 1832 1 => 'On', 1833 }, 2484 PrintConv => \%offOn, 1834 2485 }, 1835 2486 0x1012 => { #PH/4 … … 1837 2488 Writable => 'int16u', 1838 2489 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 }], 1839 2500 }, 1840 2501 0x1103 => { #PH … … 1844 2505 # 'Drop' because too large for APP1 in JPEG images 1845 2506 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', 1846 2563 }, 1847 2564 ); … … 1856 2573 Name => 'FocusInfoVersion', 1857 2574 Writable => 'undef', 2575 RawConv => '$val=~s/\0+$//; $val', # (may be null terminated) 1858 2576 Count => 4, 1859 2577 }, … … 1864 2582 Unknown => 1, #6 1865 2583 }, 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 }, 1866 2601 0x300 => { #6 1867 2602 Name => 'ZoomStepCount', … … 1870 2605 0x301 => { #11 1871 2606 Name => 'FocusStepCount', 2607 Writable => 'int16u', 2608 }, 2609 0x303 => { #11 2610 Name => 'FocusStepInfinity', 2611 Writable => 'int16u', 2612 }, 2613 0x304 => { #11 2614 Name => 'FocusStepNear', 1872 2615 Writable => 'int16u', 1873 2616 }, … … 1893 2636 PrintConvInv => '$val eq "inf" ? 0 : $val=~s/\s*m$//, $val', 1894 2637 }, 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 ], 1906 2717 # 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) 1907 2726 # 0x1200-0x1209 Flash information: 1908 2727 0x1201 => { #6 … … 1958 2777 Name => 'SensorTemperature', 1959 2778 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 }, 1960 2783 }, 1961 2784 0x1600 => { # ref http://fourthirdsphoto.com/vbb/showpost.php?p=107607&postcount=15 1962 2785 Name => 'ImageStabilization', 2786 # (the other value is more reliable, so ignore this totally if the other exists) 2787 Condition => 'not defined $$self{ImageStabilization}', 1963 2788 Writable => 'undef', 1964 2789 # if the first 4 bytes are non-zero, then bit 0x01 of byte 44 … … 1981 2806 Name => 'RawInfoVersion', 1982 2807 Writable => 'undef', 2808 RawConv => '$val=~s/\0+$//; $val', # (may be null terminated) 1983 2809 Count => 4, 1984 2810 }, 1985 2811 0x100 => { 1986 2812 Name => 'WB_RBLevelsUsed', 1987 Writable => 'int16 ',2813 Writable => 'int16u', 1988 2814 Count => 2, 1989 2815 }, 1990 2816 0x110 => { 1991 2817 Name => 'WB_RBLevelsAuto', 1992 Writable => 'int16 ',2818 Writable => 'int16u', 1993 2819 Count => 2, 1994 2820 }, 1995 2821 0x120 => { 1996 2822 Name => 'WB_RBLevelsShade', 1997 Writable => 'int16 ',2823 Writable => 'int16u', 1998 2824 Count => 2, 1999 2825 }, 2000 2826 0x121 => { 2001 2827 Name => 'WB_RBLevelsCloudy', 2002 Writable => 'int16 ',2828 Writable => 'int16u', 2003 2829 Count => 2, 2004 2830 }, 2005 2831 0x122 => { 2006 2832 Name => 'WB_RBLevelsFineWeather', 2007 Writable => 'int16 ',2833 Writable => 'int16u', 2008 2834 Count => 2, 2009 2835 }, 2010 2836 0x123 => { 2011 2837 Name => 'WB_RBLevelsTungsten', 2012 Writable => 'int16 ',2838 Writable => 'int16u', 2013 2839 Count => 2, 2014 2840 }, 2015 2841 0x124 => { 2016 2842 Name => 'WB_RBLevelsEveningSunlight', 2017 Writable => 'int16 ',2843 Writable => 'int16u', 2018 2844 Count => 2, 2019 2845 }, 2020 2846 0x130 => { 2021 2847 Name => 'WB_RBLevelsDaylightFluor', 2022 Writable => 'int16 ',2848 Writable => 'int16u', 2023 2849 Count => 2, 2024 2850 }, 2025 2851 0x131 => { 2026 2852 Name => 'WB_RBLevelsDayWhiteFluor', 2027 Writable => 'int16 ',2853 Writable => 'int16u', 2028 2854 Count => 2, 2029 2855 }, 2030 2856 0x132 => { 2031 2857 Name => 'WB_RBLevelsCoolWhiteFluor', 2032 Writable => 'int16 ',2858 Writable => 'int16u', 2033 2859 Count => 2, 2034 2860 }, 2035 2861 0x133 => { 2036 2862 Name => 'WB_RBLevelsWhiteFluorescent', 2037 Writable => 'int16 ',2863 Writable => 'int16u', 2038 2864 Count => 2, 2039 2865 }, … … 2075 2901 }, 2076 2902 0x612 => { #11 2077 Name => ' StartOffsetX',2903 Name => 'CropLeft', 2078 2904 Writable => 'int16u', 2079 2905 }, 2080 2906 0x613 => { #11 2081 Name => ' StartOffsetY',2907 Name => 'CropTop', 2082 2908 Writable => 'int16u', 2083 2909 }, 2084 2910 0x614 => { 2085 Name => ' FinalImageWidth',2911 Name => 'CropWidth', 2086 2912 Writable => 'int32u', 2087 2913 }, 2088 2914 0x615 => { 2089 Name => ' FinalImageHeight',2915 Name => 'CropHeight', 2090 2916 Writable => 'int32u', 2091 2917 }, … … 2098 2924 17 => 'Cloudy', 2099 2925 18 => 'Fine Weather', 2100 20 => 'Tungsten ( incandescent)',2926 20 => 'Tungsten (Incandescent)', 2101 2927 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', 2106 2932 256 => 'One Touch White Balance', 2107 2933 512 => 'Custom 1-4', … … 2172 2998 Count => 3, 2173 2999 }, 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' }, 2174 3007 ); 2175 3008 … … 2189 3022 ); 2190 3023 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 2191 3259 # Olympus composite tags 2192 3260 %Image::ExifTool::Olympus::Composite = ( … … 2209 3277 2 => 'Removed', 2210 3278 }, 3279 }, 3280 ZoomedPreviewImage => { 3281 Require => { 3282 0 => 'ZoomedPreviewStart', 3283 1 => 'ZoomedPreviewLength', 3284 }, 3285 RawConv => 'Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"ZoomedPreviewImage")', 2211 3286 }, 2212 3287 ); … … 2229 3304 my @info = split ' ', $extender; 2230 3305 # validate that extender identifier is reasonable 2231 return 0 unless @info >= 4 and $info[2];3306 return 0 unless @info >= 2 and $info[1]; 2232 3307 # if it's not an EC-14 (id 0 4) then assume it was really attached 2233 3308 # (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'; 2235 3310 # get the maximum aperture for this lens (in $1) 2236 3311 $lensType =~ / F(\d+(.\d+)?)/ or return 1; … … 2238 3313 # known max/max aperture of the lens, then the extender must be attached 2239 3314 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', #82263 '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', #92267 '0 6 0' => 'Zuiko Digital ED 50-200mm F2.8-3.5',2268 '0 6 1' => 'Zuiko Digital ED 8mm F3.5 Fisheye', #92269 '0 7 0' => 'Zuiko Digital 11-22mm F2.8-3.5',2270 '0 7 1' => 'Zuiko Digital 18-180mm F3.5-6.3', #62271 '0 21' => 'Zuiko Digital ED 7-14mm F4.0',2272 '0 23' => 'Zuiko Digital Pro ED 35-100mm F2.0', #72273 '0 24' => 'Zuiko Digital 14-45mm F3.5-5.6',2274 '0 32' => 'Zuiko Digital 35mm F3.5 Macro', #92275 '0 34' => 'Zuiko Digital 17.5-45mm F3.5-5.6', #92276 '0 35' => 'Zuiko Digital ED 14-42mm F3.5-5.6', #PH2277 '0 36' => 'Zuiko Digital ED 40-150mm F4.0-5.6', #PH2278 # Sigma lenses2279 '1 1' => '18-50mm F3.5-5.6', #82280 '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', #72283 '1 5' => '30mm F1.4', #102284 '1 7' => '105mm F2.8 DG', #PH2285 '1 8' => '150mm F2.8 DG HSM', #PH2286 '1 17' => '135-400mm F4.5-5.6 DG ASP APO RF', #112287 '1 18' => '300-800mm F5.6 EX DG APO', #112288 # 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 extenders2296 '0 4' => 'Zuiko Digital EC-14 1.4x Teleconverter',2297 '0 8' => 'EX-25 Extension Tube',2298 },2299 );2300 my %release = (2301 0 => '', # production2302 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 models2310 } else {2311 $rel = " Unknown Release ($info[3])" unless defined $rel;2312 $model = $model{$type}->{$str} || "Unknown Model ($str)";2313 }2314 return "$make $model$rel";2315 3315 } 2316 3316 … … 2372 3372 =head1 AUTHOR 2373 3373 2374 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)3374 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 2375 3375 2376 3376 This library is free software; you can redistribute it and/or modify it … … 2394 3394 2395 3395 Thanks 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. 3396 Mark Dapoz, Ioannis Panagiotopoulos and Tomasz Kawecki for their help 3397 figuring out some Olympus tags, and Lilo Huang, Chris Shaw and Viktor 3398 Lushnikov for adding to the LensType list. 2398 3399 2399 3400 =head1 SEE ALSO -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PDF.pm
r16842 r24107 4 4 # Description: Read PDF meta information 5 5 # 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 11 15 #------------------------------------------------------------------------------ 12 16 … … 14 18 15 19 use strict; 16 use vars qw($VERSION );20 use vars qw($VERSION $AUTOLOAD $lastFetched); 17 21 use Image::ExifTool qw(:DataAccess :Utils); 18 22 require Exporter; 19 23 20 $VERSION = '1.10'; 21 22 sub LocateObject($$); 24 $VERSION = '1.29'; 25 23 26 sub FetchObject($$$$); 24 27 sub ExtractObject($$;$$); 25 28 sub ReadToNested($;$); 26 sub ProcessDict($$$$;$); 27 28 my %warnedOnce; # hash of warnings we issued 29 sub ProcessDict($$$$;$$); 30 sub ReadPDFValue($); 31 sub CheckPDF($$$); 32 33 # $lastFetched - last fetched object reference (used for decryption) 34 # (undefined if fetched object was already decrypted, ie. object from stream) 35 36 my $cryptInfo; # encryption object reference (plus additional information) 37 my $cryptString; # flag that strings are encrypted 38 my $cryptStream; # flag that streams are encrypted 39 my $lastOffset; # last fetched object offset 29 40 my %streamObjs; # hash of stream objects 30 41 my %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) 42 my $pdfVer; # version of PDF file being processed 33 43 34 44 # tags in main PDF directories 35 45 %Image::ExifTool::PDF::Main = ( 46 GROUPS => { 2 => 'Document' }, 47 VARS => { CAPTURE => ['Main','Prev'] }, 36 48 Info => { 37 SubDirectory => { 38 TagTable => 'Image::ExifTool::PDF::Info', 39 }, 49 SubDirectory => { TagTable => 'Image::ExifTool::PDF::Info' }, 40 50 }, 41 51 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' }, 45 62 }, 46 63 ); … … 48 65 # tags in PDF Info directory 49 66 %Image::ExifTool::PDF::Info = ( 50 GROUPS => { 2 => 'Image' }, 67 GROUPS => { 2 => 'Document' }, 68 VARS => { CAPTURE => ['Info'] }, 51 69 EXTRACT_UNKNOWN => 1, # extract all unknown tags in this directory 70 WRITE_PROC => \&Image::ExifTool::DummyWriteProc, 71 CHECK_PROC => \&CheckPDF, 72 WRITABLE => 'string', 52 73 NOTES => q{ 53 74 As well as the tags listed below, the PDF specification allows for 54 75 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. 57 81 }, 58 82 Title => { }, 59 83 Author => { Groups => { 2 => 'Author' } }, 60 84 Subject => { }, 61 Keywords => { List => 1 }, # this is a list of tokens85 Keywords => { List => 'string' }, # this is a string list 62 86 Creator => { }, 63 87 Producer => { }, 64 88 CreationDate => { 65 89 Name => 'CreateDate', 90 Writable => 'date', 66 91 Groups => { 2 => 'Time' }, 67 ValueConv => 'Image::ExifTool::PDF::ConvertPDFDate($self, $val)', 92 Shift => 'Time', 93 PrintConv => '$self->ConvertDateTime($val)', 94 PrintConvInv => '$self->InverseDateTime($val)', 68 95 }, 69 96 ModDate => { 70 97 Name => 'ModifyDate', 98 Writable => 'date', 71 99 Groups => { 2 => 'Time' }, 72 ValueConv => 'Image::ExifTool::PDF::ConvertPDFDate($self, $val)', 100 Shift => 'Time', 101 PrintConv => '$self->ConvertDateTime($val)', 102 PrintConvInv => '$self->InverseDateTime($val)', 73 103 }, 74 104 Trapped => { 105 Protected => 1, 75 106 # remove leading '/' from '/True' or '/False' 76 107 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 }, 77 117 }, 78 118 ); … … 80 120 # tags in the PDF Root document catalog 81 121 %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'] }, 82 125 NOTES => 'This is the PDF document catalog.', 126 MarkInfo => { 127 SubDirectory => { TagTable => 'Image::ExifTool::PDF::MarkInfo' }, 128 }, 83 129 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 86 153 }, 87 154 }, 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 }}, 92 169 }, 93 170 ); … … 95 172 # tags in PDF Pages directory 96 173 %Image::ExifTool::PDF::Pages = ( 97 GROUPS => { 2 => ' Image' },174 GROUPS => { 2 => 'Document' }, 98 175 Count => 'PageCount', 99 176 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' }, 103 192 }, 104 193 ); … … 107 196 %Image::ExifTool::PDF::Kids = ( 108 197 Metadata => { 109 SubDirectory => { 110 TagTable => 'Image::ExifTool::PDF::Metadata', 111 }, 198 SubDirectory => { TagTable => 'Image::ExifTool::PDF::Metadata' }, 112 199 }, 113 200 PieceInfo => { 114 SubDirectory => { 115 TagTable => 'Image::ExifTool::PDF::PieceInfo', 116 }, 201 SubDirectory => { TagTable => 'Image::ExifTool::PDF::PieceInfo' }, 117 202 }, 118 203 Resources => { 119 SubDirectory => { 120 TagTable => 'Image::ExifTool::PDF::Resources', 121 }, 204 SubDirectory => { TagTable => 'Image::ExifTool::PDF::Resources' }, 122 205 }, 123 206 ); … … 126 209 %Image::ExifTool::PDF::Resources = ( 127 210 ColorSpace => { 128 SubDirectory => { 129 TagTable => 'Image::ExifTool::PDF::ColorSpace', 130 }, 211 SubDirectory => { TagTable => 'Image::ExifTool::PDF::ColorSpace' }, 131 212 }, 132 213 ); … … 135 216 %Image::ExifTool::PDF::ColorSpace = ( 136 217 DefaultRGB => { 137 SubDirectory => { 138 TagTable => 'Image::ExifTool::PDF::DefaultRGB', 139 }, 218 SubDirectory => { TagTable => 'Image::ExifTool::PDF::DefaultRGB' }, 140 219 }, 141 220 ); … … 144 223 %Image::ExifTool::PDF::DefaultRGB = ( 145 224 ICCBased => { 146 SubDirectory => { 147 TagTable => 'Image::ExifTool::PDF::ICCBased', 148 }, 225 SubDirectory => { TagTable => 'Image::ExifTool::PDF::ICCBased' }, 149 226 }, 150 227 ); … … 152 229 # tags in PDF ICCBased directory 153 230 %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' }, 158 233 }, 159 234 ); … … 162 237 %Image::ExifTool::PDF::PieceInfo = ( 163 238 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; 166 247 }, 248 SubDirectory => { TagTable => 'Image::ExifTool::PDF::Illustrator' }, 167 249 }, 168 250 ); … … 171 253 %Image::ExifTool::PDF::AdobePhotoshop = ( 172 254 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' }, 176 263 }, 177 264 ); … … 180 267 %Image::ExifTool::PDF::Private = ( 181 268 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 184 284 }, 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' }, 185 296 }, 186 297 ); … … 188 299 # tags in PDF ImageResources directory 189 300 %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' }, 194 313 }, 195 314 ); … … 197 316 # tags in PDF Metadata directory 198 317 %Image::ExifTool::PDF::Metadata = ( 199 GROUPS => { 2 => ' Image' },318 GROUPS => { 2 => 'Document' }, 200 319 XML_stream => { # this is the stream for a Subtype /XML dictionary (not a real tag) 201 320 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 204 392 }, 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, 205 414 }, 206 415 ); … … 212 421 213 422 #------------------------------------------------------------------------------ 214 # Issue one warning of each type215 # Inputs: 0) ExifTool object reference, 1) warning216 sub WarnOnce($$)423 # AutoLoad our writer routines when necessary 424 # 425 sub AUTOLOAD 217 426 { 218 my ($exifTool, $warn) = @_; 219 unless ($warnedOnce{$warn}) { 220 $warnedOnce{$warn} = 1; 221 $exifTool->Warn($warn); 222 } 427 return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_); 223 428 } 224 429 225 430 #------------------------------------------------------------------------------ 226 # Set PDF format error warning227 # Inputs: 0) ExifTool object reference, 1) error string228 # Returns: 1229 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) 434 sub ConvertPDFDate($) 230 435 { 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; 244 437 # remove optional 'D:' prefix 245 438 $date =~ s/^D://; 246 439 # fill in default values if necessary 247 # yyyymmddhhmmss440 # YYYYmmddHHMMSS 248 441 my $default = '00000101000000'; 249 442 if (length $date < length $default) { … … 253 446 $date = "$1:$2:$3 $4:$5:$6"; 254 447 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; 260 458 } 261 459 262 460 #------------------------------------------------------------------------------ 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 465 sub LocateAnyObject($$) 267 466 { 268 467 my ($xref, $ref) = @_; 269 468 return undef unless $xref; 270 return $$xref{$ref} if $$xref{$ref};469 return $$xref{$ref} if exists $$xref{$ref}; 271 470 # get the object number 272 471 return undef unless $ref =~ /^(\d+)/; 273 472 my $objNum = $1; 473 # return 0 if the object number has been reused (old object is free) 474 return 0 if defined $$xref{$objNum}; 274 475 # 275 476 # scan our XRef stream dictionaries for this object … … 283 484 next if $objNum < $$index[0]; 284 485 # scan the tables for the specified object 285 my $size = $$dict{ entry_size};486 my $size = $$dict{_entry_size}; 286 487 my $num = scalar(@$index) / 2; 287 488 my $tot = 0; … … 291 492 my $count = $$index[$i*2+1]; 292 493 # 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) { 295 496 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}); 298 499 # extract values from this table entry 299 500 # (can be 1, 2, 3, 4, etc.. bytes per value) 300 my (@t, $j, $k , $ref2);501 my (@t, $j, $k); 301 502 my $w = $$dict{W}; 302 503 for ($j=0; $j<3; ++$j) { 303 504 # 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; 305 507 $t[$j] = shift(@c); 306 508 for ($k=1; $k < $$w[$j]; ++$k) { … … 308 510 } 309 511 } 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"; 310 515 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 315 518 $$xref{$ref2} = $t[1]; 316 519 } elsif ($t[0] == 2) { 317 520 # compressed object reference: 521 # $t[1]=stream object number, $t[2]=index of object in stream 318 522 $ref2 = "$objNum 0 R"; 319 # xref is object index and stream object reference320 523 $$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; 321 528 } else { 322 last; 529 # treat as a null object 530 $$xref{$ref2} = undef; 323 531 } 532 $$xref{$objNum} = $t[1]; # remember offsets by object number too 324 533 return $$xref{$ref} if $ref eq $ref2; 534 return 0; # object is free or was reused 325 535 } 326 536 $tot += $count; … … 331 541 332 542 #------------------------------------------------------------------------------ 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 547 sub 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 #------------------------------------------------------------------------------ 333 556 # 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) 335 559 # 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 336 562 sub FetchObject($$$$) 337 563 { 338 564 my ($exifTool, $ref, $xref, $tag) = @_; 339 565 $lastFetched = $ref; # save this for decoding if necessary 340 my $offset = LocateObject($xref, $ref); 566 my $offset = LocateAnyObject($xref, $ref); 567 $lastOffset = $offset; 341 568 unless ($offset) { 342 $exifTool->Warn("Bad $tag reference") ;569 $exifTool->Warn("Bad $tag reference") unless defined $offset; 343 570 return undef; 344 571 } … … 348 575 my ($objNum) = split ' ', $ref; # save original object number 349 576 $ref = $offset; # now a reference to the containing stream object 350 my$obj = $streamObjs{$ref};577 $obj = $streamObjs{$ref}; 351 578 unless ($obj) { 352 579 # don't try to load the same object stream twice … … 359 586 return undef unless $$obj{First} and $$obj{N}; 360 587 return undef unless DecodeStream($exifTool, $obj); 361 # add a special ' table' entry to this dictionary which contains588 # add a special '_table' entry to this dictionary which contains 362 589 # the list of object number/offset pairs from the stream header 363 590 my $num = $$obj{N} * 2; 364 my @table = split ' ', $$obj{ stream}, $num;591 my @table = split ' ', $$obj{_stream}, $num; 365 592 return undef unless @table == $num; 366 593 # 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 number369 $$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; 370 597 # save the object stream so we don't have to re-load it later 371 598 $streamObjs{$ref} = $obj; … … 373 600 # verify that we have the specified object 374 601 my $i = 2 * $index; 375 my $table = $$obj{ table};602 my $table = $$obj{_table}; 376 603 unless ($index < $$obj{N} and $$table[$i] == $objNum) { 377 604 $exifTool->Warn("Bad index for stream object $tag"); … … 382 609 # the next offset to get the object length) 383 610 $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; 386 615 return ExtractObject($exifTool, \$data); 387 616 } … … 396 625 } 397 626 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 633 sub 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; 398 687 } 399 688 … … 408 697 # d) string, name, integer, boolean, null --> scalar value 409 698 # - updates $$dataPt on return to contain unused data 410 # - creates two bogus entries (' stream' and 'tags') in dictionaries to represent411 # 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') 412 701 # in their original order 413 702 sub ExtractObject($$;$$) … … 419 708 420 709 for (;;) { 421 if ($$dataPt =~ /^\s*(<{1,2}|\[|\()/ ) {710 if ($$dataPt =~ /^\s*(<{1,2}|\[|\()/s) { 422 711 $delim = $1; 712 $$dataPt =~ s/^\s+//; # remove leading white space 423 713 $objData = ReadToNested($dataPt, $raf); 424 714 return undef unless defined $objData; 425 715 last; 426 } elsif ($$dataPt =~ s{^\s*(\S[^[(/<>\s]*)\s*}{} ) {716 } elsif ($$dataPt =~ s{^\s*(\S[^[(/<>\s]*)\s*}{}s) { 427 717 # 428 718 # extract boolean, numerical, string, name, null object or indirect reference … … 430 720 $objData = $1; 431 721 # 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) { 433 723 $objData .= "$1 R"; 434 724 $objData = \$objData; # return scalar reference … … 440 730 } 441 731 # 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 '<') { 478 735 return $objData; 479 736 # 480 # extract hex string481 #482 } elsif ($delim eq '<') {483 # decode hex data484 $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 #490 737 # extract array 491 738 # 492 739 } elsif ($delim eq '[') { 493 $objData =~ /.*?\[(.*)\]/s or return ; # remove brackets494 my $data = $1; 740 $objData =~ /.*?\[(.*)\]/s or return undef; 741 my $data = $1; # brackets removed 495 742 my @list; 496 743 for (;;) { … … 536 783 } elsif ($val =~ /^\d/) { 537 784 my $pos = pos($objData); 538 if ($objData =~ /\G\s+(\d+)\s+R/ g) {785 if ($objData =~ /\G\s+(\d+)\s+R/sg) { 539 786 $val = \ "$val $1 R"; # make a reference 540 787 } else { … … 544 791 if ($$dict{$tag}) { 545 792 # duplicate dictionary entries are not allowed 546 $exifTool->Warn( "Duplicate $tag entry in dictionary (ignored)");793 $exifTool->Warn('Duplicate $tag entry in dictionary (ignored)'); 547 794 } else { 548 795 # save the entry … … 552 799 } 553 800 return undef unless @tags; 554 $$dict{ tags} = \@tags;801 $$dict{_tags} = \@tags; 555 802 return $dict unless $raf; # direct objects can not have streams 556 803 # … … 563 810 my $oldpos = $raf->Tell(); 564 811 # get the location of the object specifying the length 812 # (compressed objects are not allowed) 565 813 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; 567 816 # 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; 569 818 $length =~ s/R/obj/; 570 819 unless ($data =~ /^$length/) { … … 572 821 return $dict; 573 822 } 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; 576 825 $length = $1; 577 826 $raf->Seek($oldpos, 0); # restore position to start of stream … … 585 834 $$dataPt .= $data if $raf->ReadLine($data); 586 835 # remove our stream header 587 $$dataPt =~ s/^ .*stream(\x0a|\x0d\x0a)//s;836 $$dataPt =~ s/^\s*stream(\x0a|\x0d\x0a)//s; 588 837 my $more = $length - length($$dataPt); 589 838 if ($more > 0) { 590 839 unless ($raf->Read($data, $more) == $more) { 591 $exifTool->Warn( "Error reading stream data");840 $exifTool->Warn('Error reading stream data'); 592 841 $$dataPt = ''; 593 842 return $dict; 594 843 } 595 $$dict{ stream} = $$dataPt . $data;844 $$dict{_stream} = $$dataPt . $data; 596 845 $$dataPt = ''; 597 846 } elsif ($more < 0) { 598 $$dict{ stream} = substr($$dataPt, 0, $length);847 $$dict{_stream} = substr($$dataPt, 0, $length); 599 848 $$dataPt = substr($$dataPt, $length); 600 849 } else { 601 $$dict{ stream} = $$dataPt;850 $$dict{_stream} = $$dataPt; 602 851 $$dataPt = ''; 603 852 } … … 616 865 # - updates data reference with trailing data 617 866 # - unescapes characters in literal strings 867 my %closingDelim = ( # lookup for matching delimiter 868 '(' => ')', 869 '[' => ']', 870 '<' => '>', 871 '<<' => '>>', 872 ); 618 873 sub ReadToNested($;$) 619 874 { 620 875 my ($dataPt, $raf) = @_; 621 # matching closing delimiters622 my %closingDelim = (623 '<<' => '>>',624 '(' => ')',625 '[' => ']',626 '<' => '>',627 );628 876 my @delim = (''); # closing delimiter list, most deeply nested first 629 877 pos($$dataPt) = 0; # begin at start of data … … 664 912 pos($$dataPt) = pos($$dataPt) - 1; 665 913 } 666 my $delim = shift @delim;# remove from nesting list914 shift @delim; # remove from nesting list 667 915 next if $delim[0]; # keep going if we have more nested delimiters 668 916 my $pos = pos($$dataPt); … … 682 930 my ($exifTool, $dict) = @_; 683 931 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 } 703 971 } else { 704 $exifTool->Warn ('Error inflating stream');972 $exifTool->WarnOnce('Install Compress::Zlib to process filtered streams'); 705 973 return 0; 706 974 } 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"); 709 1035 return 0; 710 1036 } 711 #712 # apply anti-predictor if necessary713 #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' prediction719 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' prediction725 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 array730 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;745 1037 } 746 1038 return 1; … … 795 1087 # Inputs: 0) ExifTool object reference, 1) Encrypt dictionary reference, 796 1088 # 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) 798 1090 sub DecryptInit($$$) 799 1091 { 1092 local $_; 800 1093 my ($exifTool, $encrypt, $id) = @_; 1094 1095 undef $cryptInfo; 801 1096 unless ($encrypt and ref $encrypt eq 'HASH') { 802 1097 return 'Error loading Encrypt object'; … … 806 1101 return 'Encrypt dictionary has no Filter!'; 807 1102 } 1103 # extract some interesting tags 808 1104 my $ver = $$encrypt{V} || 0; 809 1105 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'; 814 1116 } 815 1117 unless ($$encrypt{O} and $$encrypt{P} and $$encrypt{U}) { 816 1118 return 'Incomplete Encrypt specification'; 817 1119 } 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"; 820 1155 } 821 1156 $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 825 1169 # calculate file-level en/decryption key 826 1170 my $pad = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08". 827 1171 "\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 868 1277 return undef; # success! 869 1278 } 870 1279 871 1280 #------------------------------------------------------------------------------ 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) 1286 sub Crypt($$;$) 875 1287 { 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 1326 sub 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 1348 sub 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; 884 1359 } 885 1360 … … 888 1363 # Inputs: 0) ExifTool object reference, 1) tag table reference 889 1364 # 2) dictionary reference, 3) cross-reference table reference, 890 # 4) nesting depth 891 sub ProcessDict($$$$;$ )1365 # 4) nesting depth, 5) dictionary capture type 1366 sub ProcessDict($$$$;$$) 892 1367 { 893 my ($exifTool, $tagTablePtr, $dict, $xref, $nesting ) = @_;1368 my ($exifTool, $tagTablePtr, $dict, $xref, $nesting, $type) = @_; 894 1369 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); 896 1374 my $index = 0; 897 my $next;898 1375 899 1376 $nesting = ($nesting || 0) + 1; 900 1377 if ($nesting > 50) { 901 WarnOnce($exifTool,'Nesting too deep (directory ignored)');1378 $exifTool->WarnOnce('Nesting too deep (directory ignored)'); 902 1379 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 } 903 1393 } 904 1394 # … … 915 1405 last; 916 1406 } 1407 my $val = $$dict{$tag}; 917 1408 if ($$tagTablePtr{$tag}) { 918 1409 $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 } 921 1422 if ($verbose) { 922 1423 my ($val2, $extra); … … 932 1433 $fetched{$$val} = 1; 933 1434 $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 } 935 1446 } 936 1447 } elsif (ref $val eq 'HASH') { … … 962 1473 }, 963 1474 }; 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) . ']'; 968 1482 } 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 } 970 1487 } 971 1488 $exifTool->VerboseInfo($tag, $tagInfo, … … 974 1491 Index => $index++, 975 1492 ); 1493 next unless defined $val; 976 1494 } 977 1495 unless ($tagInfo) { 978 1496 # 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); 982 1499 } 983 1500 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'; 984 1517 # convert from UTF-16 (big endian) to UTF-8 or Latin if necessary 985 1518 # 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 993 1539 $exifTool->FoundTag($tagInfo, $val); 994 1540 } 995 } else {996 # a tag value997 $exifTool->FoundTag($tagInfo, $val);998 1541 } 999 1542 next; … … 1009 1552 for (;;) { 1010 1553 my $subDict = shift @subDicts or last; 1554 # save last fetched object in case we fetch another one here 1555 my $prevFetched = $lastFetched; 1011 1556 if (ref $subDict eq 'SCALAR') { 1557 # only fetch once (other copies are obsolete) 1558 next if $fetched{$$subDict}; 1012 1559 # load dictionary via an indirect reference 1013 1560 $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; 1016 1569 } 1017 1570 if (ref $subDict eq 'ARRAY') { 1018 1571 # convert array of key/value pairs to a hash 1019 1572 next if @$subDict < 2; 1020 my %hash = ( tags => [] );1573 my %hash = ( _tags => [] ); 1021 1574 while (@$subDict >= 2) { 1022 1575 my $key = shift @$subDict; 1023 1576 $key =~ s/^\///; 1024 push @{$hash{ tags}}, $key;1577 push @{$hash{_tags}}, $key; 1025 1578 $hash{$key} = shift @$subDict; 1026 1579 } … … 1029 1582 next unless ref $subDict eq 'HASH'; 1030 1583 } 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; 1031 1587 my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable}); 1032 1588 if (not $verbose) { 1033 ProcessDict($exifTool, $subTablePtr, $subDict, $xref, $nesting); 1589 my $proc = $$subTablePtr{PROCESS_PROC} || \&ProcessDict; 1590 &$proc($exifTool, $subTablePtr, $subDict, $xref, $nesting); 1034 1591 } elsif ($next) { 1035 1592 # handle 'Next' links at this level to avoid deep recursion … … 1038 1595 $tagTablePtr = $subTablePtr; 1039 1596 $dict = $subDict; 1040 @tags = @{$$subDict{ tags}};1597 @tags = @{$$subDict{_tags}}; 1041 1598 $exifTool->VerboseDir($tag, scalar(@tags)); 1042 1599 } else { … … 1045 1602 $exifTool->{INDENT} .= '| '; 1046 1603 $exifTool->{DIR_NAME} = $tag; 1047 $exifTool->VerboseDir($tag, scalar(@{$$subDict{ tags}}));1604 $exifTool->VerboseDir($tag, scalar(@{$$subDict{_tags}})); 1048 1605 ProcessDict($exifTool, $subTablePtr, $subDict, $xref, $nesting); 1049 1606 $exifTool->{INDENT} = $oldIndent; 1050 1607 $exifTool->{DIR_NAME} = $oldDir; 1051 1608 } 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'; 1059 1634 # 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}; 1061 1636 return unless $$tagTablePtr{$tag}; 1062 1637 my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag); … … 1065 1640 # extract information from stream 1066 1641 my %dirInfo = ( 1067 DataPt => \$$dict{stream},1068 DataLen => length $$dict{stream},1642 DataPt => \$$dict{_stream}, 1643 DataLen => length $$dict{_stream}, 1069 1644 DirStart => 0, 1070 DirLen => length $$dict{stream},1071 Parent => 'PDF',1645 DirLen => length $$dict{_stream}, 1646 Parent => 'PDF', 1072 1647 ); 1073 1648 my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable}); … … 1086 1661 my $raf = $$dirInfo{RAF}; 1087 1662 my $verbose = $exifTool->Options('Verbose'); 1088 my ($ data, $encrypt, $id);1663 my ($buff, $encrypt, $id); 1089 1664 # 1090 1665 # validate PDF file 1091 1666 # 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; 1094 1671 $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 } 1096 1696 # 1097 1697 # read the xref tables referenced from startxref at the end of the file … … 1103 1703 $len = 1024 if $len > 1024; 1104 1704 $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 } 1110 1718 while (@xrefOffsets) { 1111 1719 my $offset = shift @xrefOffsets; 1720 my $type = shift @xrefOffsets; 1112 1721 next if $loaded{$offset}; # avoid infinite recursion 1113 1722 unless ($raf->Seek($offset, 0)) { … … 1116 1725 next; 1117 1726 } 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)) { 1119 1730 %loaded or return -6; 1120 1731 $exifTool->Warn('Bad offset for secondary xref table'); … … 1122 1733 } 1123 1734 my $loadXRefStream; 1124 if ($ data eq "xref$/") {1735 if ($buff =~ s/^xref\s+//s) { 1125 1736 # load xref table 1126 1737 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; 1131 1744 my $i; 1132 1745 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 } 1139 1762 } 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) { 1144 1769 # this is a PDF-1.5 cross-reference stream dictionary 1145 1770 $loadXRefStream = 1; … … 1149 1774 next; 1150 1775 } 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') { 1153 1778 %loaded or return -8; 1154 1779 $exifTool->Warn('Error loading secondary dictionary'); … … 1157 1782 if ($loadXRefStream) { 1158 1783 # 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. 1160 1790 if ($$mainDict{Type} eq '/XRef' and $$mainDict{W} and 1161 1791 @{$$mainDict{W}} > 2 and $$mainDict{Size} and … … 1164 1794 # create Index entry if it doesn't exist 1165 1795 $$mainDict{Index} or $$mainDict{Index} = [ 0, $$mainDict{Size} ]; 1166 # create ' entry_size' entry for internal use1796 # create '_entry_size' entry for internal use 1167 1797 my $w = $$mainDict{W}; 1168 1798 my $size = 0; 1169 1799 foreach (@$w) { $size += $_; } 1170 $$mainDict{ entry_size} = $size;1800 $$mainDict{_entry_size} = $size; 1171 1801 # save this stream dictionary to use later if required 1172 1802 $xref{dicts} = [] unless $xref{dicts}; … … 1179 1809 $loaded{$offset} = 1; 1180 1810 # 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}; 1182 1812 $encrypt = $$mainDict{Encrypt} if $$mainDict{Encrypt}; 1183 1813 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; 1187 1817 # load previous xref table if it exists 1188 push @xrefOffsets, $$mainDict{Prev} if $$mainDict{Prev};1818 push @xrefOffsets, $$mainDict{Prev}, 'Prev' if $$mainDict{Prev}; 1189 1819 } 1190 1820 # … … 1197 1827 # generate Encryption tag information 1198 1828 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 } 1200 1834 } 1201 1835 # 1202 1836 # extract the information beginning with each of the main dictionaries 1203 1837 # 1204 my $dict; 1205 foreach $dict (@mainDicts) { 1838 while (@mainDicts) { 1839 my $dict = shift @mainDicts; 1840 my $type = shift @mainDicts; 1206 1841 if ($verbose) { 1207 my $n = scalar(@{$$dict{ tags}});1842 my $n = scalar(@{$$dict{_tags}}); 1208 1843 $exifTool->VPrint(0, "PDF dictionary with $n entries:\n"); 1209 1844 } 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 } 1211 1855 } 1212 1856 return 1; … … 1235 1879 my ($exifTool, $dirInfo) = @_; 1236 1880 1237 my $oldsep = $/; 1881 undef $cryptInfo; # (must not delete after returning so writer can use it) 1882 undef $cryptStream; 1883 undef $cryptString; 1238 1884 my $result = ReadPDF($exifTool, $dirInfo); 1239 $/ = $oldsep; # restore input record separator in case it was changed1240 1885 if ($result < 0) { 1241 1886 $exifTool->Warn($pdfWarning{$result}) if $pdfWarning{$result}; … … 1243 1888 } 1244 1889 # clean up and return 1245 undef %warnedOnce;1246 1890 undef %streamObjs; 1247 1891 undef %fetched; 1248 undef $cryptInfo;1249 1892 return $result; 1250 1893 } … … 1267 1910 This code reads meta information from PDF (Adobe Portable Document Format) 1268 1911 files. 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. 1912 limited set of Filter and Predictor algorithms, however all standard 1913 encryption methods through PDF-1.7 extension level 3 are supported, 1914 including AESV2 (AES-128) and AESV3 (AES-256). 1271 1915 1272 1916 =head1 AUTHOR 1273 1917 1274 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1918 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 1275 1919 1276 1920 This library is free software; you can redistribute it and/or modify it … … 1283 1927 =item L<http://partners.adobe.com/public/developer/pdf/index_reference.html> 1284 1928 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> 1286 1938 1287 1939 =back -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PICT.pm
r16842 r24107 1237 1237 =head1 AUTHOR 1238 1238 1239 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1239 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 1240 1240 1241 1241 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PNG.pm
r16842 r24107 12 12 # 3) http://www.libpng.org/pub/mng/ 13 13 # 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 19 17 # for a number of reasons: One biggie is that you have to 20 18 # decompress then decode the ASCII/hex profile information before … … 29 27 use Image::ExifTool qw(:DataAccess :Utils); 30 28 31 $VERSION = '1. 15';29 $VERSION = '1.24'; 32 30 33 31 sub ProcessPNG_tEXt($$$); … … 38 36 sub AddChunks($$); 39 37 sub Add_iCCP($$); 38 sub GetLangInfo($$); 39 sub BuildTextChunk($$$$$); 40 40 41 41 my $noCompressLib; … … 48 48 ); 49 49 50 # map for directories in PNG images 51 my %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 50 69 # color type of current image 51 70 $Image::ExifTool::PNG::colorType = -1; … … 55 74 WRITE_PROC => \&Image::ExifTool::DummyWriteProc, 56 75 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 }, 57 82 bKGD => { 58 83 Name => 'BackgroundColor', … … 62 87 Name => 'PrimaryChromaticities', 63 88 SubDirectory => { TagTable => 'Image::ExifTool::PNG::PrimaryChromaticities' }, 89 }, 90 dSIG => { 91 Name => 'DigitalSignature', 92 Binary => 1, 64 93 }, 65 94 fRAc => { … … 130 159 Name => 'SignificantBits', 131 160 ValueConv => 'join(" ",unpack("C*",$val))', 161 }, 162 sCAL => { # png 1.4.0 163 Name => 'SubjectScale', 164 SubDirectory => { TagTable => 'Image::ExifTool::PNG::SubjectScale' }, 132 165 }, 133 166 sPLT => { … … 145 178 3 => 'Absolute Colorimetric', 146 179 }, 180 }, 181 sTER => { # png 1.4.0 182 Name => 'StereoImage', 183 SubDirectory => { TagTable => 'Image::ExifTool::PNG::StereoImage' }, 147 184 }, 148 185 tEXt => { … … 162 199 }, 163 200 PrintConv => '$self->ConvertDateTime($val)', 164 PrintConvInv => '$ val',201 PrintConvInv => '$self->InverseDateTime($val)', 165 202 }, 166 203 tRNS => { … … 175 212 Notes => 'obsolete location specified by older XMP draft', 176 213 SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' }, 214 }, 215 vpAg => { # private imagemagick chunk 216 Name => 'VirtualPage', 217 SubDirectory => { TagTable => 'Image::ExifTool::PNG::VirtualPage' }, 177 218 }, 178 219 zTXt => { … … 256 297 ); 257 298 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 258 344 my %unreg = ( Notes => 'unregistered' ); 259 345 … … 266 352 PREFERRED => 1, # always add these tags when writing 267 353 GROUPS => { 2 => 'Image' }, 354 LANG_INFO => \&GetLangInfo, 268 355 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. 283 378 }, 284 379 Title => { }, … … 306 401 Make => { %unreg, Groups => { 2 => 'Camera' } }, 307 402 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 }, 308 423 TimeStamp => { %unreg, Groups => { 2 => 'Time' }, Shift => 'Time' }, 309 424 URL => { %unreg }, … … 311 426 Name => 'XMP', 312 427 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 315 431 }, 316 432 SubDirectory => { … … 323 439 # (No condition because this is just for BuildTagLookup) 324 440 Name => 'APP1_Profile', 441 %unreg, 325 442 SubDirectory => { 326 443 TagTable=>'Image::ExifTool::Exif::Main', … … 338 455 'Raw profile type exif' => { 339 456 Name => 'EXIF_Profile', 457 %unreg, 340 458 SubDirectory => { 341 459 TagTable=>'Image::ExifTool::Exif::Main', … … 345 463 'Raw profile type icc' => { 346 464 Name => 'ICC_Profile', 465 %unreg, 347 466 SubDirectory => { 348 467 TagTable => 'Image::ExifTool::ICC_Profile::Main', … … 352 471 'Raw profile type icm' => { 353 472 Name => 'ICC_Profile', 473 %unreg, 354 474 SubDirectory => { 355 475 TagTable => 'Image::ExifTool::ICC_Profile::Main', … … 359 479 'Raw profile type iptc' => { 360 480 Name => 'IPTC_Profile', 481 %unreg, 361 482 SubDirectory => { 362 483 TagTable => 'Image::ExifTool::Photoshop::Main', … … 366 487 'Raw profile type xmp' => { 367 488 Name => 'XMP_Profile', 489 %unreg, 368 490 SubDirectory => { 369 491 TagTable => 'Image::ExifTool::XMP::Main', … … 379 501 { 380 502 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 509 sub 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 521 sub 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)); 381 529 } 382 530 … … 386 534 # 2) Tag ID, 3) Tag value, 4) [optional] compressed data flag: 387 535 # 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 389 538 # Returns: 1 on success 390 sub FoundPNG($$$$;$$ )539 sub FoundPNG($$$$;$$$$) 391 540 { 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 # 393 562 my ($wasCompressed, $deflateErr); 394 return 0 unless defined $val;395 #396 # First, uncompress data if requested397 #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 404 563 if ($compressed and $compressed > 1) { 405 564 if ($compressed == 2) { # Inflate/Deflate compression … … 416 575 } 417 576 } 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"; 421 578 } else { 422 579 $deflateErr = ''; # flag deflate error but no warning … … 429 586 $exifTool->VerboseDir("Unable to decompress $$tagInfo{Name}", 0, length($val)); 430 587 } 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); 432 599 } 433 600 # … … 444 611 $wasCompressed and $name = "Decompressed $name"; 445 612 $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); 449 614 } 450 615 # don't indent next directory (since it is really the same data) … … 457 622 return 1 if $outBuff and not $$subTable{WRITE_PROC}; 458 623 my %subdirInfo = ( 459 DataPt => \$val,624 DataPt => \$val, 460 625 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, 465 630 ReadOnly => 1, # (only used by WriteXMP) 466 OutBuff => $outBuff,631 OutBuff => $outBuff, 467 632 ); 468 633 # no need to re-decompress if already done … … 482 647 if ($outBuff) { 483 648 my $writable = $tagInfo->{Writable}; 649 my $isOverwriting; 484 650 if ($writable or ($$tagTablePtr{WRITABLE} and 485 651 not defined $writable and not $$tagInfo{SubDirectory})) 486 652 { 487 653 # write new value for this tag if necessary 488 my ($isOverwriting, $newVal);654 my $newVal; 489 655 if ($exifTool->{DEL_GROUP}->{PNG}) { 490 656 # remove this tag now, but keep in ADD_PNG list to add back later … … 492 658 } else { 493 659 # remove this from the list of PNG tags to add 494 delete $exifTool->{ADD_PNG}->{$ tag};660 delete $exifTool->{ADD_PNG}->{$id}; 495 661 # (also handle case of tEXt tags written with lowercase first letter) 496 delete $exifTool->{ADD_PNG}->{ucfirst($ tag)};497 my $n ewValueHash = $exifTool->GetNewValueHash($tagInfo);498 $isOverwriting = Image::ExifTool::IsOverwriting($n ewValueHash);662 delete $exifTool->{ADD_PNG}->{ucfirst($id)}; 663 my $nvHash = $exifTool->GetNewValueHash($tagInfo); 664 $isOverwriting = Image::ExifTool::IsOverwriting($nvHash); 499 665 if (defined $deflateErr) { 500 $newVal = Image::ExifTool::GetNewValues($n ewValueHash);501 # can only write tag now if unconditionally deleting it502 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) { 503 669 $val = '<deflate error>'; 504 } els e{505 $isOverwriting = 0; # can't rewrite this compressed text670 } elsif ($isOverwriting) { 671 $isOverwriting = 0; # can't overwrite 506 672 $exifTool->Warn($deflateErr) if $deflateErr; 507 673 } 508 674 } else { 509 675 if ($isOverwriting < 0) { 510 $isOverwriting = Image::ExifTool::IsOverwriting($n ewValueHash, $val);676 $isOverwriting = Image::ExifTool::IsOverwriting($nvHash, $val); 511 677 } 512 678 # (must get new value after IsOverwriting() in case it was shifted) 513 $newVal = Image::ExifTool::GetNewValues($n ewValueHash);679 $newVal = Image::ExifTool::GetNewValues($nvHash); 514 680 } 515 681 } 516 682 if ($isOverwriting) { 517 $$outBuff = 683 $$outBuff = (defined $newVal) ? $newVal : ''; 518 684 ++$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; 523 687 } 524 688 } 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) { 527 693 # re-compress the output data 528 694 my $deflate; … … 537 703 } 538 704 $$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);541 705 } 542 706 } … … 548 712 ($name = $tag) =~ s/\s+(.)/\u$1/g; # remove white space from tag name 549 713 $tagInfo = { Name => $name }; 714 $$tagInfo{LangCode} = $lang if $lang; 550 715 # make unknown profiles binary data type 551 $$tagInfo{ ValueConv} = '\$val'if $tag =~ /^Raw profile type /;716 $$tagInfo{Binary} = 1 if $tag =~ /^Raw profile type /; 552 717 Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo); 553 718 } … … 605 770 if ($verbose > 2) { 606 771 $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); 613 773 } 614 774 # don't indent next directory (since it is really the same data) … … 647 807 $dirInfo{DirStart} += $hdrLen; 648 808 $dirInfo{DirLen} -= $hdrLen; 649 $processed = $exifTool->ProcessTIFF(\%dirInfo);650 809 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; 656 813 delete $$addDirs{IFD0}; 814 } else { 815 $processed = $exifTool->ProcessTIFF(\%dirInfo); 657 816 } 658 817 } elsif ($buff =~ /^$Image::ExifTool::xmpAPP1hdr/) { … … 673 832 # TIFF information (haven't seen this, but what the heck...) 674 833 return 1 if $outBuff and not $$editDirs{IFD0}; 675 $processed = $exifTool->ProcessTIFF(\%dirInfo);676 834 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; 682 838 delete $$addDirs{IFD0}; 839 } else { 840 $processed = $exifTool->ProcessTIFF(\%dirInfo); 683 841 } 684 842 } else { … … 687 845 $exifTool->Warn("Unknown raw profile '$profName'"); 688 846 } 689 if ($outBuff and $$outBuff) {847 if ($outBuff and defined $$outBuff and length $$outBuff) { 690 848 if ($exifTool->{CHANGED} != $oldChanged) { 691 849 my $hdr = sprintf("\n%s\n%8d\n", $profileType, length($$outBuff)); … … 703 861 # Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table 704 862 # Returns: 1 on success 863 # Notes: writes new chunk data to ${$$dirInfo{OutBuff}} if writing tag 705 864 sub ProcessPNG_Compressed($$$) 706 865 { … … 712 871 my $hdr = $tag . "\0" . substr($val, 0, 1); 713 872 $val = substr($val, 1); # remove compression method byte 873 my $success; 874 my $outBuff = $$dirInfo{OutBuff}; 714 875 # use the PNG chunk tag instead of the embedded tag name for iCCP chunks 715 876 if ($$dirInfo{TagInfo} and $$dirInfo{TagInfo}->{Name} eq 'ICC_Profile') { 716 877 $tag = 'iCCP'; 717 878 $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 writing722 $$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; 724 885 } 725 886 … … 728 889 # Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table 729 890 # Returns: 1 on success 891 # Notes: writes new chunk data to ${$$dirInfo{OutBuff}} if writing tag 730 892 sub ProcessPNG_tEXt($$$) 731 893 { … … 733 895 my ($tag, $val) = split /\0/, ${$$dirInfo{DataPt}}, 2; 734 896 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'); 739 898 } 740 899 … … 743 902 # Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table 744 903 # Returns: 1 on success 904 # Notes: writes new chunk data to ${$$dirInfo{OutBuff}} if writing tag 745 905 sub ProcessPNG_iTXt($$$) 746 906 { … … 753 913 $compressed and $compressed = 2 + $meth; 754 914 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); 760 916 } 761 917 … … 777 933 return 0 unless $raf->Read($sig,8) == 8 and $pngLookup{$sig}; 778 934 if ($outfile) { 935 delete $$exifTool{TextChunkType}; 779 936 Write($outfile, $sig) or $err = 1 if $outfile; 780 937 # can only add tags in Main and TextualData tables … … 782 939 \%Image::ExifTool::PNG::Main, 783 940 \%Image::ExifTool::PNG::TextualData); 784 # initialize with same directories as JPEG, but PNG tags takepriority785 $exifTool->InitWriteDirs( 'JPEG','PNG');941 # initialize with same directories, with PNG tags taking priority 942 $exifTool->InitWriteDirs(\%pngMap,'PNG'); 786 943 } 787 944 my ($fileType, $hdrChunk, $endChunk) = @{$pngLookup{$sig}}; … … 847 1004 if ($chunk eq $hdrChunk) { 848 1005 $foundHdr = 1; 1006 } elsif ($hdrChunk eq 'IHDR' and $chunk eq 'CgBI') { 1007 $exifTool->Warn('Non-standard PNG image (Apple iPhone format)'); 849 1008 } else { 850 1009 $exifTool->Warn("$fileType image did not start with $hdrChunk"); … … 862 1021 } 863 1022 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; 869 1024 } 870 1025 # only extract information from chunks in our tables … … 877 1032 } 878 1033 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); 881 1042 $dbuf = $theBuff; 882 1043 my $crc = CalculateCRC(\$hbuf, undef, 4); 883 1044 $crc = CalculateCRC(\$dbuf, $crc); 884 1045 $cbuf = pack('N', $crc); 885 } elsif (defined $theBuff) {886 next; # empty if we deleted the information887 1046 } 888 1047 Write($outfile, $hbuf, $dbuf, $cbuf) or $err = 1; … … 913 1072 =head1 AUTHOR 914 1073 915 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1074 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 916 1075 917 1076 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PPM.pm
r16842 r24107 17 17 use Image::ExifTool qw(:DataAccess :Utils); 18 18 19 $VERSION = '1.0 4';19 $VERSION = '1.05'; 20 20 21 21 #------------------------------------------------------------------------------ … … 85 85 # 86 86 if ($outfile) { 87 my $n ewValueHash;88 my $newComment = $exifTool->GetNewValues('Comment', \$n ewValueHash);87 my $nvHash; 88 my $newComment = $exifTool->GetNewValues('Comment', \$nvHash); 89 89 my $oldComment = $info{Comment}; 90 if (Image::ExifTool::IsOverwriting($n ewValueHash, $oldComment)) {90 if (Image::ExifTool::IsOverwriting($nvHash, $oldComment)) { 91 91 ++$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; 96 94 } else { 97 95 $newComment = $oldComment; # use existing comment … … 146 144 =head1 AUTHOR 147 145 148 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)146 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 149 147 150 148 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Panasonic.pm
r16842 r24107 10 10 # 3) http://johnst.org/sw/exiftags/ 11 11 # 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) 15 13 # 8) Marcel Coenen private communication (DMC-FZ50) 16 14 # 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) 18 22 #------------------------------------------------------------------------------ 19 23 … … 22 26 use strict; 23 27 use vars qw($VERSION); 28 use Image::ExifTool qw(:DataAccess :Utils); 24 29 use Image::ExifTool::Exif; 25 30 26 $VERSION = '1. 26';31 $VERSION = '1.59'; 27 32 28 33 sub ProcessPanasonicType2($$$); 34 sub WhiteBalanceConv($;$$); 35 36 # Leica lens types (ref 10) 37 my %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 115 my %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 ); 29 153 30 154 # conversions for ShootingMode and SceneMode … … 39 163 8 => 'Shutter Priority', 40 164 9 => 'Macro', 165 10 => 'Spot', #7 41 166 11 => 'Manual', 42 167 12 => 'Movie Preview', #PH (LZ6) 43 168 13 => 'Panning', 44 169 14 => 'Simple', #PH (LZ6) 170 15 => 'Color Effects', #7 171 16 => 'Self Portrait', #PH (TZ5) 172 17 => 'Economy', #7 45 173 18 => 'Fireworks', 46 174 19 => 'Party', … … 48 176 21 => 'Night Scenery', 49 177 22 => 'Food', #7 50 23 => 'Baby', # 10178 23 => 'Baby', #JD 51 179 24 => 'Soft Skin', #PH (LZ6) 52 180 25 => 'Candlelight', #PH (LZ6) 53 181 26 => 'Starry Night', #PH (LZ6) 54 182 27 => 'High Sensitivity', #7 (LZ6) 183 28 => 'Panorama Assist', #7 55 184 29 => 'Underwater', #7 56 185 30 => 'Beach', #PH (LZ6) 57 186 31 => 'Aerial Photo', #PH (LZ6) 58 187 32 => 'Sunset', #PH (LZ6) 59 33 => 'Pet', # 10188 33 => 'Pet', #JD 60 189 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 61 201 ); 62 202 … … 101 241 2 => 'Daylight', 102 242 3 => 'Cloudy', 103 4 => ' Halogen',243 4 => 'Incandescent', #PH 104 244 5 => 'Manual', 105 245 8 => 'Flash', 106 246 10 => 'Black & White', #3 (Leica) 107 247 11 => 'Manual', #PH (FZ8) 248 12 => 'Shade', #PH (FS7) 108 249 }, 109 250 }, … … 116 257 4 => 'Auto, Focus button', #4 117 258 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 ], 138 294 0x1a => { 139 295 Name => 'ImageStabilization', … … 143 299 3 => 'Off', 144 300 4 => 'On, Mode 2', 301 # GF1 also has a mode 3 145 302 }, 146 303 }, … … 152 309 2 => 'Off', 153 310 0x101 => 'Tele-Macro', #7 311 0x201 => 'Macro Zoom', #PH (FS7) 154 312 }, 155 313 }, … … 157 315 Name => 'ShootingMode', 158 316 Writable => 'int16u', 317 PrintConvColumns => 2, 159 318 PrintConv => \%shootingMode, 160 319 }, … … 175 334 Writable => 'int16s', 176 335 ValueConv => '$val / 3', 177 PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',178 336 ValueConvInv => '$val * 3', 179 PrintConvInv => 'eval $val', 337 PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)', 338 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 180 339 }, 181 340 0x24 => { … … 214 373 4 => 'Black & White', 215 374 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 219 379 Name => 'TimeSincePowerOn', 220 380 Writable => 'int32u', 221 381 Notes => q{ 222 time in 1/100 s ecfrom when the camera was powered on to when the image is382 time in 1/100 s from when the camera was powered on to when the image is 223 383 written to memory card 224 384 }, … … 255 415 Name => 'BurstMode', 256 416 Writable => 'int16u', 417 Notes => 'decoding may be different for some models', 257 418 PrintConv => { 258 419 0 => 'Off', 259 1 => ' Low/High Quality',420 1 => 'On', #PH (TZ5) [was "Low/High Quality" from ref 4] 260 421 2 => 'Infinite', 422 4 => 'Unlimited', #PH (TZ5) 261 423 }, 262 424 }, … … 265 427 Writable => 'int32u', 266 428 }, 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 ], 282 493 0x2d => { 283 494 Name => 'NoiseReduction', … … 285 496 PrintConv => { 286 497 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 289 502 }, 290 503 }, … … 294 507 PrintConv => { 295 508 1 => 'Off', 296 2 => '10 s',297 3 => '2 s',509 2 => '10 s', 510 3 => '2 s', 298 511 }, 299 512 }, … … 304 517 PrintConv => { 305 518 1 => 'Horizontal (normal)', 519 3 => 'Rotate 180', #PH 306 520 6 => 'Rotate 90 CW', #PH (ref 7 gives 270 CW) 307 521 8 => 'Rotate 270 CW', #PH (ref 7 gives 90 CW) 308 522 }, 309 523 }, 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 }, 311 536 0x32 => { #7 312 537 Name => 'ColorMode', … … 315 540 0 => 'Normal', 316 541 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 321 547 Name => 'BabyAge', 322 548 Writable => 'string', … … 330 556 PrintConv => { 331 557 1 => 'Standard', 332 2 => 'E X Optics',558 2 => 'Extended', 333 559 }, 334 560 }, … … 349 575 PrintConvInv => '$val =~ /(\d+)/ ? $1 : $val', 350 576 }, 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 }, 353 585 0x3a => { 354 586 Name => 'WorldTimeLocation', … … 359 591 }, 360 592 }, 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 }, 362 599 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 }, 369 657 0x42 => { #7 (DMC-L1) 370 658 Name => 'FilmMode', 371 659 Writable => 'int16u', 372 660 PrintConv => { 661 0 => 'n/a', #PH (ie. FZ100 "Photo Frame" ShootingMode) 373 662 1 => 'Standard (color)', 374 663 2 => 'Dynamic (color)', … … 380 669 # 8 => 'My Film 1'? (from owner manual) 381 670 # 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 385 680 Name => 'WBAdjustAB', 386 681 Format => 'int16s', … … 388 683 Notes => 'positive is a shift toward blue', 389 684 }, 390 0x47 => { #PH/ 10685 0x47 => { #PH/JD 391 686 Name => 'WBAdjustGM', 392 687 Format => 'int16s', … … 394 689 Notes => 'positive is a shift toward green', 395 690 }, 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 396 722 0x51 => { 397 723 Name => 'LensType', … … 406 732 Writable => 'string', 407 733 }, 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 408 857 0x0e00 => { 409 858 Name => 'PrintIM', … … 418 867 Format => 'undef', 419 868 }, 420 0x8001 => { #7/PH/ 10869 0x8001 => { #7/PH/JD 421 870 Name => 'SceneMode', 422 871 Writable => 'int16u', 872 PrintConvColumns => 2, 423 873 PrintConv => { 424 874 0 => 'Off', … … 426 876 }, 427 877 }, 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 431 882 Name => 'WBRedLevel', 432 883 Writable => 'int16u', 433 884 }, 434 0x8005 => { #PH/ 10885 0x8005 => { #PH/JD 435 886 Name => 'WBGreenLevel', 436 887 Writable => 'int16u', 437 888 }, 438 0x8006 => { #PH/ 10889 0x8006 => { #PH/JD 439 890 Name => 'WBBlueLevel', 440 891 Writable => 'int16u', 441 892 }, 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 }, 443 910 0x8010 => { #PH 444 911 Name => 'BabyAge', … … 448 915 PrintConvInv => '$val =~ /^\d/ ? $val : "9999:99:99 00:00:00"', 449 916 }, 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 450 1333 ); 451 1334 … … 470 1353 ); 471 1354 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', 574 1380 }, 575 1381 }, 576 1382 ); 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 1509 sub 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 1527 sub 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 1550 sub 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 } 577 1695 578 1696 1; # end … … 595 1713 =head1 AUTHOR 596 1714 597 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1715 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 598 1716 599 1717 This library is free software; you can redistribute it and/or modify it … … 608 1726 =item L<http://johnst.org/sw/exiftags/> 609 1727 610 =item L<http://www.cybercom.net/~dcoffin/dcraw/>611 612 1728 =item L<http://homepage3.nifty.com/kamisaka/makernote/makernote_pana.htm> 613 1729 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 614 1736 =back 615 1737 … … 617 1739 618 1740 Thanks to Tels for the information he provided on decoding some tags, and to 619 Marcel Coenen and Jens Duttkefor their contributions.1741 Marcel Coenen, Jens Duttke and Michael Byczkowski for their contributions. 620 1742 621 1743 =head1 SEE ALSO -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Pentax.pm
r16842 r24107 8 8 # 02/16/2004 - W. Smith Updated (see ref 3) 9 9 # 11/10/2004 - P. Harvey Added support for Asahi cameras 10 # 01/10/2005 - P. Harvey Added NikonLenswith values from ref 410 # 01/10/2005 - P. Harvey Added LensType with values from ref 4 11 11 # 03/30/2005 - P. Harvey Added new tags from ref 5 12 12 # 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!) 13 15 # 14 16 # References: 1) Image::MakerNotes::Pentax … … 24 26 # 11) http://forums.dpreview.com/forums/read.asp?forum=1036&message=17465929 25 27 # 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) 27 29 # 14) Ger Vermeulen private communication (Optio S6) 28 30 # 15) Barney Garrett private communication (Samsung GX-1S) … … 30 32 # 17) Cvetan Ivanov private communication (K100D) 31 33 # 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 33 42 # 34 43 # Notes: See POD documentation at the bottom of this file … … 42 51 use Image::ExifTool::HP; 43 52 44 $VERSION = ' 1.61';53 $VERSION = '2.30'; 45 54 46 55 sub CryptShutterCount($$); 56 sub PrintFilter($$$); 47 57 48 58 # 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 62 my %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 }, 50 71 '0 0' => 'M-42 or No Lens', #17 51 '1 0' => 'K ,M Lens',72 '1 0' => 'K or M Lens', 52 73 '2 0' => 'A Series Lens', #7 (from smc PENTAX-A 400mm F5.6) 53 '3 0' => 'S IGMA',74 '3 0' => 'Sigma', # (includes 'Sigma 30mm F1.4 EX DC' - PH) 54 75 '3 17' => 'smc PENTAX-FA SOFT 85mm F2.8', 55 76 '3 18' => 'smc PENTAX-F 1.7X AF ADAPTER', … … 58 79 '3 21' => 'smc PENTAX-F 80-200mm F4.7-5.6', 59 80 '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 61 84 '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 66 91 '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 71 99 '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 74 103 '3 32' => 'smc PENTAX-F 50mm F1.4', 75 104 '3 33' => 'smc PENTAX-F 50mm F1.7', 76 105 '3 34' => 'smc PENTAX-F 135mm F2.8 [IF]', 77 106 '3 35' => 'smc PENTAX-F 28mm F2.8', 78 '3 36' => 'S IGMA 20mm F1.8 EX DG ASPHERICALRF',107 '3 36' => 'Sigma 20mm F1.8 EX DG Aspherical RF', 79 108 '3 38' => 'smc PENTAX-F* 300mm F4.5 ED[IF]', 80 109 '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 88 122 '3 50' => 'smc PENTAX-FA 28-70mm F4 AL', 89 '3 51' => 'S IGMA 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), #19123 '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 92 126 '3 53' => 'smc PENTAX-FA 28-80mm F3.5-5.6 AL', 93 127 '3 247' => 'smc PENTAX-DA FISH-EYE 10-17mm F3.5-4.5 ED[IF]', … … 98 132 '3 253' => 'smc PENTAX-DA 14mm F2.8 ED[IF]', 99 133 '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 106 144 '4 1' => 'smc PENTAX-FA SOFT 28mm F2.8', 107 145 '4 2' => 'smc PENTAX-FA 80-320mm F4.5-5.6', … … 110 148 '4 12' => 'smc PENTAX-FA 50mm F1.4', #17 111 149 '4 15' => 'smc PENTAX-FA 28-105mm F4-5.6 [IF]', 112 '4 16' => 'T AMRONAF 80-210mm F4-5.6 (178D)', #13113 '4 19' => 'T AMRONSP 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)', 114 152 '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 116 155 '4 23' => 'smc PENTAX-FA 20-35mm F4 AL', 117 156 '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)', 121 161 '4 28' => 'smc PENTAX-FA 35mm F2 AL', 122 '4 29' => 'T AMRON AF 28-200mm F/3.8-5.6 LD Super II MACRO (371D)', #19162 '4 29' => 'Tamron AF 28-200mm F3.8-5.6 LD Super II Macro (371D)', #JD 123 163 '4 34' => 'smc PENTAX-FA 24-90mm F3.5-4.5 AL[IF]', 124 164 '4 35' => 'smc PENTAX-FA 100-300mm F4.7-5.8', 125 '4 36' => 'T AMRON AF70-300mm F/4-5.6 LD MACRO', # both 572D and A17 (Di) - ref 19126 '4 37' => 'T AMRONSP AF 24-135mm F3.5-5.6 AD AL (190D)', #13165 '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 127 167 '4 38' => 'smc PENTAX-FA 28-105mm F3.2-4.5 AL[IF]', 128 '4 39' => 'smc PENTAX-FA 31mm F1.8 AL Limited',129 '4 41' => 'T AMRON 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)', 130 170 '4 43' => 'smc PENTAX-FA 28-90mm F3.5-5.6', 131 171 '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 133 175 '4 46' => 'smc PENTAX-FA J 28-80mm F3.5-5.6 AL', 134 176 '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 138 187 '4 244' => 'smc PENTAX-DA 21mm F3.2 AL Limited', #9 139 '4 245' => 'Schneider D-XENON 50-200mm ', #15140 '4 246' => 'Schneider D-XENON 18-55mm ', #15141 '4 247' => 'smc PENTAX-DA 10-17mm F3.5-4.5 ED [IF] Fisheye zoom', #10188 '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 142 191 '4 248' => 'smc PENTAX-DA 12-24mm F4 ED AL [IF]', #10 143 '4 249' => 'T AMRONXR DiII 18-200mm F3.5-6.3 (A14)',192 '4 249' => 'Tamron XR DiII 18-200mm F3.5-6.3 (A14)', 144 193 '4 250' => 'smc PENTAX-DA 50-200mm F4-5.6 ED', #8 145 194 '4 251' => 'smc PENTAX-DA 40mm F2.8 Limited', #9 … … 154 203 '5 6' => 'smc PENTAX-FA* 300mm F4.5 ED[IF]', 155 204 '5 7' => 'smc PENTAX-FA 135mm F2.8 [IF]', 156 '5 8' => 'smc PENTAX-FA M ACRO50mm F2.8',157 '5 9' => 'smc PENTAX-FA M ACRO100mm F2.8',205 '5 8' => 'smc PENTAX-FA Macro 50mm F2.8', 206 '5 9' => 'smc PENTAX-FA Macro 100mm F2.8', 158 207 '5 10' => 'smc PENTAX-FA* 85mm F1.4 [IF]', 159 208 '5 11' => 'smc PENTAX-FA* 200mm F2.8 ED[IF]', … … 163 212 '5 15' => 'smc PENTAX-FA 28-105mm F4-5.6', 164 213 '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]', 166 216 '6 2' => 'smc PENTAX-FA* 200mm F2.8 ED[IF]', 167 217 '6 3' => 'smc PENTAX-FA* 300mm F2.8 ED[IF]', … … 174 224 '6 10' => 'smc PENTAX-FA* 400mm F5.6 ED[IF]', 175 225 '6 13' => 'smc PENTAX-FA* 400mm F5.6 ED[IF]', 176 '6 14' => 'smc PENTAX-FA* M ACRO200mm F4 ED[IF]',226 '6 14' => 'smc PENTAX-FA* Macro 200mm F4 ED[IF]', 177 227 '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 180 253 '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 183 273 ); 184 274 185 # Pentax model ID codes (PH)275 # Pentax model ID codes - PH 186 276 my %pentaxModelID = ( 187 277 0x0000d => 'Optio 330/430', … … 190 280 0x12962 => 'Optio 450/550', 191 281 0x1296c => 'Optio S', 282 0x12971 => 'Optio S V1.01', 192 283 0x12994 => '*ist D', 193 284 0x129b2 => 'Optio 33L', … … 225 316 0x12b9c => 'K100D', 226 317 0x12b9d => 'K110D', 227 0x12ba2 => 'K100D Super', # 19318 0x12ba2 => 'K100D Super', #JD 228 319 0x12bb0 => 'Optio T10/T20', 229 320 0x12be2 => 'Optio W10', … … 238 329 0x12c8c => 'Optio M30', 239 330 0x12c78 => 'Optio E30', 331 0x12c7d => 'Optio E35', 240 332 0x12c82 => 'Optio T30', 333 0x12c91 => 'Optio L30', 241 334 0x12c96 => 'Optio W30', 242 335 0x12ca0 => 'Optio A30', 243 336 0x12cb4 => 'Optio E40', 244 337 0x12cbe => 'Optio M40', 338 0x12cc3 => 'Optio L40', 339 0x12cc5 => 'Optio L36', 245 340 0x12cc8 => 'Optio Z10', 341 0x12cd2 => 'K20D', 342 0x12cd4 => 'Samsung GX20', #8 246 343 0x12cdc => 'Optio S10', 247 344 0x12ce6 => 'Optio A40', 248 345 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', 249 378 ); 250 379 … … 322 451 69 => 'Stockholm', 323 452 70 => 'Lisbon', #14 453 71 => 'Copenhagen', #25 454 72 => 'Warsaw', 455 73 => 'Prague', 456 74 => 'Budapest', 324 457 ); 325 458 459 # digital filter tag information (ref PH, K-5) 460 # (also see %filterSettings below for decoding of filter parameters) 461 my %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 497 my %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 542 my %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 565 my %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 575 my %lensCode = ( 576 Unknown => 1, 577 PrintConv => 'sprintf("0x%.2x", $val)', 578 PrintConvInv => 'hex($val)', 579 ); 580 581 # common attributes for writable BinaryData directories 582 my %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 326 591 %Image::ExifTool::Pentax::Main = ( 327 592 WRITE_PROC => \&Image::ExifTool::Exif::WriteExif, … … 376 641 Name => 'Date', 377 642 Groups => { 2 => 'Time' }, 643 Notes => 'changing either Date or Time will affect ShutterCount decryption', 378 644 Writable => 'undef', 379 645 Count => 4, … … 382 648 RawConv => '$$self{PentaxDate} = $val', # save to decrypt ShutterCount 383 649 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 }, 385 655 }, 386 656 0x0007 => { #5 … … 393 663 RawConv => '$$self{PentaxTime} = $val', # save to decrypt ShutterCount 394 664 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 }, 396 669 }, 397 670 0x0008 => { #2 398 671 Name => 'Quality', 399 672 Writable => 'int16u', 673 PrintConvColumns => 2, 400 674 PrintConv => { 401 675 0 => 'Good', … … 404 678 3 => 'TIFF', #5 405 679 4 => 'RAW', #5 680 5 => 'Premium', #PH (K20D) 406 681 }, 407 682 }, … … 410 685 Groups => { 2 => 'Image' }, 411 686 Writable => 'int16u', 687 PrintConvColumns => 2, 412 688 PrintConv => { 413 689 0 => '640x480', … … 427 703 25 => '2816x2212 or 2816x2112', #13 or #14 428 704 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) 429 709 '0 0' => '2304x1728', #13 430 710 '4 0' => '1600x1200', #PH (Optio MX4) … … 439 719 }, 440 720 }, 441 # 0x000a - (See note below)442 721 0x000b => { #3 443 722 Name => 'PictureMode', 444 723 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 => [{ 446 733 0 => 'Program', #PH 734 0.1 => 'Av', #PH (Optio 555) 735 1 => 'Shutter Speed Priority', #JD 736 1.1 => 'M', #PH (Optio 555) 447 737 2 => 'Program AE', #13 738 2.1 => 'Tv', #PH (Optio 555) 448 739 3 => 'Manual', #13 740 3.1 => 'USER', #PH (Optio 555) 449 741 5 => 'Portrait', 450 742 6 => 'Landscape', 451 743 8 => 'Sport', #PH 452 744 9 => 'Night Scene', 745 # 10 "full mode"? #13 453 746 11 => 'Soft', #PH 454 747 12 => 'Surf & Snow', 455 13 => ' Sunset or Candlelight', #14 (Candlelight)748 13 => 'Candlelight', #13 456 749 14 => 'Autumn', 457 750 15 => 'Macro', … … 459 752 18 => 'Text', 460 753 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) 461 763 30 => 'Self Portrait', #PH 462 764 31 => 'Illustrations', #13 463 765 33 => 'Digital Filter', #13 766 35 => 'Night Scene Portrait', #25 464 767 37 => 'Museum', #PH 465 768 38 => 'Food', #PH 769 39 => 'Underwater', #25 466 770 40 => 'Green Mode', #PH 467 771 49 => 'Light Pet', #PH … … 473 777 56 => 'Synchro Sound Record', #PH 474 778 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 }], 484 786 }, 485 787 0x000c => { #PH 486 788 Name => 'FlashMode', 487 789 Writable => 'int16u', 790 Count => -1, 488 791 PrintHex => 1, 489 ValueConv => '$val=~s/ .*//; $val', # ignore 2nd value 490 PrintConv => { 792 PrintConv => [{ 491 793 0x000 => 'Auto, Did not fire', 492 0x001 => 'Off', 794 0x001 => 'Off, Did not fire', 795 0x002 => 'On, Did not fire', #19 493 796 0x003 => 'Auto, Did not fire, Red-eye reduction', 797 0x005 => 'On, Did not fire, Wireless (Master)', #19 494 798 0x100 => 'Auto, Fired', 495 0x102 => 'On ',799 0x102 => 'On, Fired', 496 800 0x103 => 'Auto, Fired, Red-eye reduction', 497 801 0x104 => 'On, Red-eye reduction', 498 0x105 => 'On, Wireless', 802 0x105 => 'On, Wireless (Master)', #19 803 0x106 => 'On, Wireless (Control)', #19 499 804 0x108 => 'On, Soft', 500 805 0x109 => 'On, Slow-sync', 501 806 0x10a => 'On, Slow-sync, Red-eye reduction', 502 807 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 }], 504 820 }, 505 821 0x000d => [ #2 506 822 { 507 Condition => '$self->{CameraMake} =~ /^PENTAX/',508 823 Name => 'FocusMode', 824 Condition => '$self->{Make} =~ /^PENTAX/', 509 825 Notes => 'Pentax models', 510 826 Writable => 'int16u', 827 PrintConvColumns => 2, 511 828 PrintConv => { #PH 512 829 0 => 'Normal', … … 514 831 2 => 'Infinity', 515 832 3 => 'Manual', 833 4 => 'Super Macro', #JD 516 834 5 => 'Pan Focus', 517 835 16 => 'AF-S', #17 518 836 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) 519 840 }, 520 841 }, … … 534 855 Name => 'AFPointSelected', 535 856 Writable => 'int16u', 536 PrintConv => { 857 PrintConvColumns => 2, 858 PrintConv => { 859 # 0 - Contrast-detect AF? - PH (K-5) 537 860 0xffff => 'Auto', 538 861 0xfffe => 'Fixed Center', 862 0xfffd => 'Automatic Tracking AF', #JD 863 0xfffc => 'Face Detect AF', #JD 539 864 1 => 'Upper-left', 540 865 2 => 'Top', … … 579 904 ValueConv => '$val * 1e-5', 580 905 ValueConvInv => '$val * 1e5', 581 # value may be 0xffffffff in Bulb mode (ref 19)906 # value may be 0xffffffff in Bulb mode (ref JD) 582 907 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)', 584 909 }, 585 910 0x0013 => { #PH … … 596 921 Name => 'ISO', 597 922 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, 601 928 4 => 64, 602 5 => 80, #(NC)929 5 => 80, 603 930 6 => 100, 604 931 7 => 125, #PH 605 932 8 => 160, #PH 606 933 9 => 200, 607 10 => 250, #(NC)934 10 => 250, 608 935 11 => 320, #PH 609 936 12 => 400, 610 13 => 500, #(NC)611 14 => 640, #(NC)937 13 => 500, 938 14 => 640, 612 939 15 => 800, 613 16 => 1000, #(NC)614 17 => 1250, #(NC)940 16 => 1000, 941 17 => 1250, 615 942 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) 617 959 50 => 50, #PH 618 960 100 => 100, #PH … … 622 964 1600 => 1600, #PH 623 965 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 }, 628 1000 0x0016 => { #PH 629 1001 Name => 'ExposureCompensation', … … 631 1003 ValueConv => '($val - 50) / 10', 632 1004 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)', 635 1007 }, 636 1008 0x0017 => { #3 … … 638 1010 Writable => 'int16u', 639 1011 PrintConv => { 640 0 => 'Multi Segment',641 1 => 'Center Weighted',1012 0 => 'Multi-segment', 1013 1 => 'Center-weighted average', 642 1014 2 => 'Spot', 1015 # have seen value of 16 for E70 643 1016 }, 644 1017 }, … … 648 1021 Count => -1, 649 1022 Notes => q{ 650 one or two numbers: exposure bracket step in EV, then extended bracket if1023 1 or 2 values: exposure bracket step in EV, then extended bracket if 651 1024 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)' ], 673 1031 PrintConv => sub { 674 1032 my @v = split(' ', shift); 675 1033 $v[0] = sprintf('%.1f', $v[0]) if $v[0]; 676 1034 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'); 678 1037 my $t = $v[1] >> 8; 679 1038 $v[1] = sprintf('%s+%d', $s{$t} || "Unknown($t)", $v[1] & 0xff); … … 687 1046 $v[0] =~ s/ ?EV//i; 688 1047 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); 690 1050 if ($v[1] =~ /^No\b/i) { 691 1051 $v[1] = 0; … … 704 1064 Name => 'WhiteBalance', 705 1065 Writable => 'int16u', 1066 PrintConvColumns => 2, 706 1067 PrintConv => { 707 1068 0 => 'Auto', … … 711 1072 4 => 'Tungsten', 712 1073 5 => 'Manual', 713 6 => 'Daylight Fluorescent', #13714 7 => 'Day whiteFluorescent', #13715 8 => 'White Fluorescent', #131074 6 => 'Daylight Fluorescent', #13 1075 7 => 'Day White Fluorescent', #13 1076 8 => 'White Fluorescent', #13 716 1077 9 => 'Flash', #13 717 1078 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 720 1083 }, 721 1084 }, … … 728 1091 3 => 'Auto (Flash)', 729 1092 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) 732 1096 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) 733 1099 0xffff => 'User-Selected', 734 0xfffe => 'Preset (Fireworks?)', #PH735 # 0xfffd observed in K100D (ref 17)736 1100 }, 737 1101 }, … … 753 1117 # Optio 30, 33WR, 43WR, 450, 550, 555, 750Z, X 754 1118 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/', 756 1120 Writable => 'int32u', 757 1121 Priority => 0, 758 1122 ValueConv => '$val / 10', 759 1123 ValueConvInv => '$val * 10', 760 PrintConv => 'sprintf("%.1f mm",$val)',761 PrintConvInv => '$val=~s/ mm//;$val',1124 PrintConv => 'sprintf("%.1f mm",$val)', 1125 PrintConvInv => '$val=~s/\s*mm//;$val', 762 1126 }, 763 1127 { … … 771 1135 ValueConv => '$val / 100', 772 1136 ValueConvInv => '$val * 100', 773 PrintConv => 'sprintf("%.1f mm",$val)',774 PrintConvInv => '$val=~s/ mm//;$val',1137 PrintConv => 'sprintf("%.1f mm",$val)', 1138 PrintConvInv => '$val=~s/\s*mm//;$val', 775 1139 }, 776 1140 ], … … 784 1148 Name => 'Saturation', 785 1149 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 787 1154 0 => 'Low', #PH 788 1155 1 => 'Normal', #PH … … 792 1159 5 => 'Very Low', #(NC) 793 1160 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 }], 799 1165 }, 800 1166 0x0020 => { 801 1167 Name => 'Contrast', 802 1168 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 804 1173 0 => 'Low', #PH 805 1174 1 => 'Normal', #PH … … 808 1177 4 => 'Med High', #2 809 1178 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 }], 816 1183 }, 817 1184 0x0021 => { 818 1185 Name => 'Sharpness', 819 1186 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 821 1191 0 => 'Soft', #PH 822 1192 1 => 'Normal', #PH … … 826 1196 5 => 'Very Soft', #(NC) 827 1197 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 }], 833 1201 }, 834 1202 0x0022 => { #PH … … 867 1235 PrintConv => { 0 => 'No', 1 => 'Yes' }, 868 1236 }, 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 }, 871 1249 0x0029 => { #5 872 1250 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 873 1255 Writable => 'int32u', 874 1256 }, 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 }, 876 1267 0x0032 => { #13 877 Name => 'Image Processing',1268 Name => 'ImageEditing', 878 1269 Writable => 'undef', 879 1270 Format => 'int8u', 880 1271 Count => 4, 881 1272 PrintConv => { 882 '0 0' => ' Unprocessed', #PH883 '0 0 0 0' => ' Unprocessed',1273 '0 0' => 'None', #PH 1274 '0 0 0 0' => 'None', 884 1275 '0 0 0 4' => 'Digital Filter', 1276 '1 0 0 0' => 'Resized', #PH (K-5) 885 1277 '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) 887 1281 '16 0 0 0' => 'Frame Synthesis?', 888 1282 }, 889 1283 }, 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) 893 1285 Name => 'PictureMode', 894 1286 Writable => 'int8u', 895 1287 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', 915 1315 # 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 928 1321 # *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 }], 953 1354 }, 954 1355 0x0034 => { #7/PH … … 956 1357 Writable => 'int8u', 957 1358 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', 966 1401 }, 967 1402 0x0037 => { #13 … … 995 1430 Notes => '*istD only', 996 1431 ValueConv => '$val & 0x7ff', # ignore other bits for now 1432 PrintConvColumns => 2, 997 1433 PrintConv => { BITMASK => { 998 1434 0 => 'Upper-left', … … 1009 1445 } }, 1010 1446 }, 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 }, 1012 1455 0x003f => { #PH 1013 1456 Name => 'LensType', … … 1015 1458 Count => 2, 1016 1459 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', 1018 1462 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 }, 1023 1477 0x0047 => { #PH 1024 1478 Name => 'CameraTemperature', … … 1026 1480 PrintConv => '"$val C"', 1027 1481 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 }, 1028 1490 }, 1029 1491 0x0049 => { #13 … … 1038 1500 ValueConvInv => 'int($val * 256 + ($val > 0 ? 0.5 : -0.5))', 1039 1501 PrintConv => '$val ? sprintf("%+.1f", $val) : 0', 1040 PrintConvInv => ' $val',1502 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 1041 1503 }, 1042 1504 0x004f => { #PH 1043 Name => 'ImageTone', 1044 Writable => 'int16u', 1505 Name => 'ImageTone', # (Called CustomImageMode in K20D manual) 1506 Writable => 'int16u', 1507 PrintConvColumns => 2, 1045 1508 PrintConv => { 1046 1509 0 => 'Natural', 1047 1510 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 1050 1528 0x005c => { #PH 1051 1529 Name => 'ShakeReductionInfo', 1052 Format => 'undef', 1053 SubDirectory => { 1054 TagTable => 'Image::ExifTool::Pentax::SRInfo',1055 },1056 },1057 0x005d => { #19/PH1058 # (used by all Pentax DSLR's except *istD and *istDS - PH)1059 # The lowest decrypted values observed are 246 for the first image from a1060 # 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 an1062 # offset of ~200 which is applied to this value before encryption1530 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 1063 1541 Name => 'ShutterCount', 1064 1542 Writable => 'undef', 1065 1543 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 1067 1549 RawConv => 'length($val) == 4 ? unpack("N",$val) : undef', 1068 1550 RawConvInv => q{ … … 1073 1555 ValueConvInv => '$val', 1074 1556 }, 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 }, 1075 1820 0x0200 => { #5 1076 1821 Name => 'BlackPoint', … … 1079 1824 }, 1080 1825 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 1081 1830 Name => 'WhitePoint', 1082 1831 Writable => 'int16u', 1083 1832 Count => 4, 1084 1833 }, 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 }, 1086 1860 0x0206 => { #PH 1087 1861 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 1105 1901 Name => 'AEMeteringSegments', 1106 1902 Format => 'int8u', 1107 Count => 16,1903 Count => -1, 1108 1904 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) 1112 1911 # +-------------------------+ 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 | +----------------------------------+ 1122 1921 # +-------------------------+ 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, 1148 1935 }, 1149 1936 0x020d => { #PH … … 1189 1976 0x0215 => { #PH 1190 1977 Name => 'CameraInfo', 1191 SubDirectory => { 1192 TagTable => 'Image::ExifTool::Pentax::CameraInfo', 1193 }, 1978 Format => 'undef', # (written as int32u) 1979 SubDirectory => { TagTable => 'Image::ExifTool::Pentax::CameraInfo' }, 1194 1980 }, 1195 1981 0x0216 => { #PH … … 1197 1983 SubDirectory => { 1198 1984 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 1202 2007 Name => 'AFInfo', 1203 2008 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', 1204 2014 TagTable => 'Image::ExifTool::Pentax::AFInfo', 1205 2015 }, 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, 1206 2099 }, 1207 2100 0x03fe => { #PH … … 1210 2103 PrintConv => '\$val', 1211 2104 }, 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 ], 1212 2115 0x0402 => { #5 1213 2116 Name => 'ToneCurve', … … 1218 2121 PrintConv => '\$val', 1219 2122 }, 2123 # 0x0404 - undef[2086] (K-5) 2124 # 0x0405 - undef[24200] (K-5 PEF/DNG only) 2125 # 0x0406 - undef[4116] (K-5) 1220 2126 0x0e00 => { 1221 2127 Name => 'PrintIM', … … 1230 2136 # shake reduction information (ref PH) 1231 2137 %Image::ExifTool::Pentax::SRInfo = ( 1232 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 1233 WRITE_PROC => \&Image::ExifTool::WriteBinaryData, 1234 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 2138 %binaryDataAttrs, 1235 2139 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 1236 WRITABLE => 1,1237 FIRST_ENTRY => 0,1238 2140 NOTES => 'Shake reduction information.', 1239 2141 0 => { 1240 2142 Name => 'SRResult', 1241 PrintConv => { #PH/ 192143 PrintConv => { #PH/JD 1242 2144 0 => 'Not stabilized', 1243 2145 BITMASK => { 1244 2146 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 1245 2149 6 => 'Not ready', 1246 2150 }, … … 1249 2153 1 => { 1250 2154 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 }, 1252 2165 }, 1253 2166 2 => { 1254 Name => 'SR _SWSToSWRTime',1255 # SWS=photometering switch, SWR=shutter release switch2167 Name => 'SRHalfPressTime', 2168 # (was SR_SWSToSWRTime: SWS=photometering switch, SWR=shutter release switch) 1256 2169 # (from http://www.patentstorm.us/patents/6597867-description.html) 2170 # (here, SR could more accurately mean Shutter Release, not Shake Reduction) 1257 2171 Notes => q{ 1258 2172 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)', 1261 2703 }, 1262 2704 ); … … 1264 2706 # auto-exposure information (ref PH) 1265 2707 %Image::ExifTool::Pentax::AEInfo = ( 1266 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 1267 WRITE_PROC => \&Image::ExifTool::WriteBinaryData, 1268 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 2708 %binaryDataAttrs, 1269 2709 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 1272 2712 0 => { 1273 2713 Name => 'AEExposureTime', … … 1276 2716 ValueConvInv => '-log($val/24)*8/log(2)+32', 1277 2717 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 1278 PrintConvInv => ' eval $val',2718 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 1279 2719 }, 1280 2720 1 => { 1281 2721 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', 1286 2725 PrintConv => 'sprintf("%.1f",$val)', 1287 2726 PrintConvInv => '$val', … … 1305 2744 Format => 'int8s', 1306 2745 Notes => 'val = raw / 8', 1307 ValueConv => '$val /8',2746 ValueConv => '$val / 8', 1308 2747 ValueConvInv => '$val * 8', 1309 2748 }, 1310 2749 5 => { 1311 Name => 'AE FlashTv',2750 Name => 'AEMinExposureTime', #19 1312 2751 Notes => 'val = 24 * 2**((32-raw)/8)', 1313 ValueConv => '24*exp(-($val-32)*log(2)/8)', # 192752 ValueConv => '24*exp(-($val-32)*log(2)/8)', #JD 1314 2753 ValueConvInv => '-log($val/24)*8/log(2)+32', 1315 2754 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 1316 PrintConvInv => ' eval $val',2755 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 1317 2756 }, 1318 2757 6 => { 1319 2758 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 1325 2771 35 => 'Standard', 1326 2772 43 => 'Portrait', … … 1338 2784 139 => 'Candlelight', 1339 2785 147 => 'Museum', 2786 184 => 'Shallow DOF Program', # (K-5) 1340 2787 }, 1341 2788 }, 1342 2789 7 => { 1343 Name => 'AE Extra',2790 Name => 'AEFlags', 1344 2791 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)', 1345 2869 }, 1346 2870 ); … … 1348 2872 # lens information (ref PH) 1349 2873 %Image::ExifTool::Pentax::LensInfo = ( 1350 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 1351 WRITE_PROC => \&Image::ExifTool::WriteBinaryData, 1352 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 2874 %binaryDataAttrs, 1353 2875 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.', 1357 2898 0 => { 1358 2899 Name => 'LensType', 1359 2900 Format => 'int8u[4]', 1360 2901 Priority => 0, 1361 Notes => q{1362 for most models the first 2 bytes are LensType, but for the K10D the1363 decoding is a bit different1364 },1365 # this is a bit funny and needs testing with more lenses on the K10D1366 2902 ValueConv => q{ 1367 2903 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); 1371 3028 } 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, 1388 3111 }, 1389 3112 ); … … 1391 3114 # flash information (ref PH) 1392 3115 %Image::ExifTool::Pentax::FlashInfo = ( 1393 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 1394 WRITE_PROC => \&Image::ExifTool::WriteBinaryData, 1395 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 3116 %binaryDataAttrs, 1396 3117 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 }, 1400 3132 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 }, 1418 3180 4 => 'TTL_DA_AUp', 1419 3181 5 => 'TTL_DA_ADown', 1420 3182 6 => 'TTL_DA_BUp', 1421 3183 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 1424 3249 ); 1425 3250 1426 3251 # camera manufacture information (ref PH) 1427 3252 %Image::ExifTool::Pentax::CameraInfo = ( 1428 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 1429 WRITE_PROC => \&Image::ExifTool::WriteBinaryData, 1430 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 3253 %binaryDataAttrs, 1431 3254 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 1432 WRITABLE => 1,1433 FIRST_ENTRY => 0,1434 3255 FORMAT => 'int32u', 1435 3256 0 => { … … 1437 3258 Priority => 0, # (Optio SVi uses incorrect Optio SV ID here) 1438 3259 SeparateTable => 1, 3260 PrintHex => 1, 1439 3261 PrintConv => \%pentaxModelID, 1440 3262 }, 1441 3263 1 => { 1442 3264 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 }, 1443 3270 ValueConv => q{ 1444 3271 $val =~ /^(\d{4})(\d{2})(\d{2})$/ and return "$1:$2:$3"; … … 1450 3277 }, 1451 3278 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) 1453 3281 Format => 'int32u[2]', 3282 Note => 'values of 8.x indicate that the camera has been serviced', 1454 3283 ValueConv => '$val=~tr/ /./; $val', 1455 3284 ValueConvInv => '$val=~tr/./ /; $val', 3285 PrintConv => '$val=~/^8\./ ? "$val (camera has been serviced)" : $val', 3286 PrintConvInv => '$val=~s/\s+.*//s; $val', 1456 3287 }, 1457 3288 4 => 'InternalSerialNumber', … … 1460 3291 # battery information (ref PH) 1461 3292 %Image::ExifTool::Pentax::BatteryInfo = ( 1462 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 1463 WRITE_PROC => \&Image::ExifTool::WriteBinaryData, 1464 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 3293 %binaryDataAttrs, 1465 3294 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 ], 1479 3365 # internal and grip battery voltage Analogue to Digital measurements, 1480 3366 # 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 }, 1485 3457 ); 1486 3458 1487 # auto focus information (ref 19)3459 # auto focus information 1488 3460 %Image::ExifTool::Pentax::AFInfo = ( 1489 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 1490 WRITE_PROC => \&Image::ExifTool::WriteBinaryData, 1491 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 3461 %binaryDataAttrs, 1492 3462 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 1496 3534 Name => 'AFPointsInFocus', 1497 3535 Notes => q{ … … 1499 3537 selected, in which case the selected AFPoint is the first reported 1500 3538 }, 3539 PrintConvColumns => 2, 1501 3540 PrintConv => { 1502 3541 0 => 'None', … … 1505 3544 3 => 'Lower-right, Bottom', 1506 3545 4 => 'Mid-left, Center', 1507 5 => 'Center (horizontal)', #PH (K10D)3546 5 => 'Center (horizontal)', #PH 1508 3547 6 => 'Mid-right, Center', 1509 3548 7 => 'Upper-left, Top', … … 1519 3558 17 => 'Left', 1520 3559 18 => 'Mid-left', 1521 19 => 'Center (vertical)', #PH (K10D)3560 19 => 'Center (vertical)', #PH 1522 3561 20 => 'Mid-right', 1523 3562 }, … … 1525 3564 ); 1526 3565 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, 1531 3584 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', 1547 4089 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', 1553 4097 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 1578 4125 ); 1579 4126 … … 1706 4253 ); 1707 4254 1708 # ASCII-based maker notes of Optio E20 - PH4255 # ASCII-based maker notes of Optio E20 and E25 - PH 1709 4256 %Image::ExifTool::Pentax::Type4 = ( 1710 4257 PROCESS_PROC => \&Image::ExifTool::HP::ProcessHP, … … 1712 4259 NOTES => q{ 1713 4260 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 as1715 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. 1716 4263 }, 1717 4264 'F/W Version' => 'FirmwareVersion', 1718 4265 ); 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 4348 sub 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 4418 sub 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 4437 sub 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 } 1719 4451 1720 4452 #------------------------------------------------------------------------------ … … 1755 4487 1756 4488 I 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 pictures1758 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 (see1760 L< ACKNOWLEDGEMENTS>).4489 managed to discover a fair bit of information by analyzing sample images 4490 downloaded from the internet, and through tests with my own Optio WP, 4491 K10D, and K-5, and with help provided by other ExifTool users (see 4492 L</ACKNOWLEDGEMENTS>). 1761 4493 1762 4494 The Pentax maker notes are stored in standard EXIF format, but the offsets … … 1783 4515 =item L<http://www.cybercom.net/~dcoffin/dcraw/> 1784 4516 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!) 1786 4518 1787 4519 =back … … 1789 4521 =head1 ACKNOWLEDGEMENTS 1790 4522 1791 Thanks to Wayne Smith, John Francis, Douglas O'Brien Cvetan Ivanov andJens1792 Duttke for help figuring out some Pentax tags, Denis Bourez, Kazumichi1793 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.4523 Thanks to Wayne Smith, John Francis, Douglas O'Brien Cvetan Ivanov, Jens 4524 Duttke and Dave Nicholson for help figuring out some Pentax tags, Ger 4525 Vermeulen and Niels Kristian Bech Jensen for contributing print conversion 4526 values for some tags, and everyone who helped contribute to the LensType 4527 values. 1796 4528 1797 4529 =head1 AUTHOR 1798 4530 1799 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)4531 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 1800 4532 1801 4533 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PhotoMechanic.pm
r16842 r24107 16 16 use Image::ExifTool::XMP; 17 17 18 $VERSION = '1.0 0';18 $VERSION = '1.02'; 19 19 20 20 sub ProcessPhotoMechanic($$); … … 50 50 ); 51 51 52 # raw Crop coordinate conversions52 # raw/preview crop coordinate conversions 53 53 my %rawCropConv = ( 54 54 ValueConv => '$val / 655.36', … … 65 65 WRITABLE => 1, 66 66 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 }, 83 71 213 => 'ConstrainedCropWidth', 84 72 214 => 'ConstrainedCropHeight', … … 106 94 }, 107 95 223 => 'Rating', 96 236 => { Name => 'PreviewCropLeft', %rawCropConv }, 97 237 => { Name => 'PreviewCropTop', %rawCropConv }, 98 238 => { Name => 'PreviewCropRight', %rawCropConv }, 99 239 => { Name => 'PreviewCropBottom', %rawCropConv }, 108 100 ); 109 101 … … 122 114 EditStatus => { }, 123 115 Prefs => { 116 Notes => 'format is "Tagged:0, ColorClass:1, Rating:2, FrameNum:3"', 124 117 PrintConv => q{ 125 118 $val =~ s[\s*(\d+):\s*(\d+):\s*(\d+):\s*(\S*)] … … 164 157 last unless $footer =~ /cbipcbbl$/; 165 158 my $size = unpack('N', $footer); 166 159 167 160 if ($size & 0x80000000 or not $raf->Seek(-$size-12, 1)) { 168 161 $exifTool->Warn('Bad PhotoMechanic trailer'); … … 178 171 $$dirInfo{DataPos} = $raf->Tell() - $size; 179 172 $$dirInfo{DirLen} = $size + 12; 180 173 181 174 my %dirInfo = ( 182 175 DataPt => \$buff, … … 238 231 =head1 AUTHOR 239 232 240 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)233 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 241 234 242 235 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Photoshop.pm
r16842 r24107 4 4 # Description: Read/write Photoshop IRB meta information 5 5 # 6 # Revisions: 02/06/ 04 - P. Harvey Created7 # 02/25/ 04 - P. Harvey Added hack for problem with old photoshops8 # 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 enough10 # information to write PrintConv routines for them to11 # display something useful12 # 07/08/ 05 - P. Harvey Added support for reading PSD files13 # 01/07/ 06 - P. Harvey Added PSD write support14 # 11/04/ 06 - P. Harvey Added handling of resource name6 # 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 15 15 # 16 16 # References: 1) http://www.fine-view.com/jp/lab/doc/ps6ffspecsv2.pdf … … 18 18 # 3) Matt Mueller private communication (tests with PS CS2) 19 19 # 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 20 22 #------------------------------------------------------------------------------ 21 23 … … 23 25 24 26 use strict; 25 use vars qw($VERSION $AUTOLOAD );26 use Image::ExifTool qw(:DataAccess );27 28 $VERSION = '1. 32';27 use vars qw($VERSION $AUTOLOAD $iptcDigestInfo); 28 use Image::ExifTool qw(:DataAccess :Utils); 29 30 $VERSION = '1.41'; 29 31 30 32 sub ProcessPhotoshop($$$); … … 56 58 0x03e8 => { Unknown => 1, Name => 'Photoshop2Info' }, 57 59 0x03e9 => { Unknown => 1, Name => 'MacintoshPrintInfo' }, 58 0x03ea => { Unknown => 1, Name => 'XMLData' }, #PH60 0x03ea => { Unknown => 1, Name => 'XMLData', Binary => 1 }, #PH 59 61 0x03eb => { Unknown => 1, Name => 'Photoshop2ColorTable' }, 60 62 0x03ed => { … … 66 68 0x03ee => { 67 69 Name => 'AlphaChannelsNames', 68 PrintConv => 'Image::ExifTool::Photoshop::ConvertPascalString($val)',70 ValueConv => 'Image::ExifTool::Photoshop::ConvertPascalString($self,$val)', 69 71 }, 70 72 0x03ef => { Unknown => 1, Name => 'DisplayInfo' }, … … 107 109 Name => 'PhotoshopBGRThumbnail', 108 110 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)', 110 112 }, 111 113 0x040a => { … … 127 129 0x040c => { 128 130 Name => 'PhotoshopThumbnail', 129 ValueConv => 'my $img=substr($val,0x1c);$self->ValidateImage(\$img,$tag)',131 RawConv => 'my $img=substr($val,0x1c);$self->ValidateImage(\$img,$tag)', 130 132 }, 131 133 0x040d => { … … 146 148 0x0412 => { Unknown => 1, Name => 'EffectsVisible' }, 147 149 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' }, 149 151 0x0415 => { Unknown => 1, Name => 'UnicodeAlphaNames' }, 150 152 0x0416 => { Unknown => 1, Name => 'IndexedColourTableCount' }, … … 170 172 }, 171 173 }, 174 0x0423 => { Unknown => 1, Name => 'ExifInfo2', Binary => 1 }, #5 172 175 0x0424 => { 173 176 Name => 'XMP', … … 176 179 }, 177 180 }, 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 178 211 # 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 }, 180 221 0x2710 => { Unknown => 1, Name => 'PrintFlagsInfo' }, 181 222 ); … … 267 308 12 => { 268 309 Name => 'ColorMode', 310 PrintConvColumns => 2, 269 311 PrintConv => { 270 312 0 => 'Bitmap', … … 285 327 ); 286 328 329 # define reference to IPTCDigest tagInfo hash for convenience 330 $iptcDigestInfo = $Image::ExifTool::Photoshop::Main{0x0425}; 331 332 287 333 #------------------------------------------------------------------------------ 288 334 # AutoLoad our writer routines when necessary … … 297 343 # Inputs: 1) Pascal string data 298 344 # Returns: Strings, concatenated with ', ' 299 sub ConvertPascalString($ )345 sub ConvertPascalString($$) 300 346 { 301 my $inStr = shift;347 my ($exifTool, $inStr) = @_; 302 348 my $outStr = ''; 303 349 my $len = length($inStr); … … 310 356 $i += $n + 1; 311 357 } 312 return $outStr; 358 my $charset = $exifTool->Options('CharsetPhotoshop') || 'Latin'; 359 return $exifTool->Decode($outStr, $charset); 313 360 } 314 361 … … 342 389 $ttPtr = $tagTablePtr; 343 390 } elsif ($type =~ /^(PHUT|DCSR|AgHg)$/) { 344 $ttPtr = Image::ExifTool::GetTagTable('Image::ExifTool::Photoshop::Unknown');391 $ttPtr = GetTagTable('Image::ExifTool::Photoshop::Unknown'); 345 392 } else { 346 393 $type =~ s/([^\w])/sprintf("\\x%.2x",ord($1))/ge; … … 406 453 407 454 $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; 409 456 SetByteOrder('MM'); 410 $exifTool->SetFileType( );# set the FileType tag457 $exifTool->SetFileType($1 eq "\x01" ? 'PSD' : 'PSB'); # set the FileType tag 411 458 my %dirInfo = ( 412 459 DataPt => \$data, 413 460 DirStart => 0, 414 DirName => 'P SD',461 DirName => 'Photoshop', 415 462 ); 416 463 my $len = Get32u(\$data, 26); … … 423 470 } else { 424 471 # process the header 425 $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::Photoshop::Header');472 $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Header'); 426 473 $dirInfo{DirLen} = 30; 427 474 $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr); … … 431 478 $len = Get32u(\$data, 0); 432 479 $raf->Read($data, $len) == $len or $err = 1; 433 $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::Photoshop::Main');480 $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main'); 434 481 $dirInfo{DirLen} = $len; 435 482 my $rtnVal = 1; … … 520 567 =head1 AUTHOR 521 568 522 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)569 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 523 570 524 571 This library is free software; you can redistribute it and/or modify it … … 534 581 535 582 =item L<http://www.fileformat.info/format/psd/egff.htm> 583 584 =item L<http://libpsd.graphest.com/files/Photoshop%20File%20Formats.pdf> 536 585 537 586 =back -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PostScript.pm
r16842 r24107 4 4 # Description: Read PostScript meta information 5 5 # 6 # Revisions: 07/08/ 05 - P. Harvey Created6 # Revisions: 07/08/2005 - P. Harvey Created 7 7 # 8 8 # References: 1) http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf … … 17 17 use Image::ExifTool qw(:DataAccess :Utils); 18 18 19 $VERSION = '1. 19';19 $VERSION = '1.33'; 20 20 21 21 sub WritePS($$); 22 sub CheckPS($$$);22 sub ProcessPS($$;$); 23 23 24 24 # PostScript tag table 25 25 %Image::ExifTool::PostScript::Main = ( 26 PROCESS_PROC => \&ProcessPS, 26 27 WRITE_PROC => \&WritePS, 27 CHECK_PROC => \&CheckPS,28 28 PREFERRED => 1, # always add these tags when writing 29 29 GROUPS => { 2 => 'Image' }, … … 38 38 Groups => { 2 => 'Time' }, 39 39 Writable => 'string', 40 PrintConv => '$self->ConvertDateTime($val)', 40 41 }, 41 42 Creator => { Priority => 0, Writable => 'string' }, … … 48 49 Groups => { 2 => 'Time' }, 49 50 Writable => 'string', 51 PrintConv => '$self->ConvertDateTime($val)', 50 52 }, 51 53 Pages => { Priority => 0 }, … … 80 82 }, 81 83 }, 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 }, 82 97 ); 83 98 … … 89 104 ImageWidth => { 90 105 Desire => { 91 0 => ' PostScript:ImageData',106 0 => 'Main:PostScript:ImageData', 92 107 1 => 'PostScript:BoundingBox', 93 108 }, … … 96 111 ImageHeight => { 97 112 Desire => { 98 0 => ' PostScript:ImageData',113 0 => 'Main:PostScript:ImageData', 99 114 1 => 'PostScript:BoundingBox', 100 115 }, … … 112 127 { 113 128 return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_); 129 } 130 131 #------------------------------------------------------------------------------ 132 # Is this a PC system 133 # Returns: true for PC systems 134 my %isPC = (MSWin32 => 1, os2 => 1, dos => 1, NetWare => 1, symbian => 1, cygwin => 1); 135 sub IsPC() 136 { 137 return $isPC{$^O}; 114 138 } 115 139 … … 137 161 my ($exifTool, $str) = @_; 138 162 # 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'); 140 165 $exifTool->Warn("PostScript format error ($str)"); 141 166 return 1; … … 143 168 144 169 #------------------------------------------------------------------------------ 145 # set $/ according to the currentfile170 # Return input record separator to use for the specified file 146 171 # Inputs: 0) RAF reference 147 # Returns: Original separator or undefined if on error148 sub SetInputRecordSeparator($)172 # Returns: Input record separator or undef on error 173 sub GetInputRecordSeparator($) 149 174 { 150 175 my $raf = shift; 151 my $oldsep = $/;152 176 my $pos = $raf->Tell(); # save current position 153 my $data;177 my ($data, $sep); 154 178 $raf->Read($data,256) or return undef; 155 179 my ($a, $d) = (999,999); … … 158 182 my $diff = $a - $d; 159 183 if ($diff eq 1) { 160 $ /= "\x0d\x0a";184 $sep = "\x0d\x0a"; 161 185 } elsif ($diff eq -1) { 162 $ /= "\x0a\x0d";186 $sep = "\x0a\x0d"; 163 187 } elsif ($diff > 0) { 164 $ /= "\x0d";188 $sep = "\x0d"; 165 189 } elsif ($diff < 0) { 166 $/ = "\x0a"; 167 } else { 168 return undef; # error 169 } 190 $sep = "\x0a"; 191 } # else error 170 192 $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 202 sub 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 282 sub 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; 172 311 } 173 312 174 313 #------------------------------------------------------------------------------ 175 314 # 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 177 316 # Returns: 1 if this was a valid PostScript file 178 sub ProcessPS($$ )179 { 180 my ($exifTool, $dirInfo ) = @_;317 sub ProcessPS($$;$) 318 { 319 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 181 320 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; 183 326 # 184 327 # determine if this is a postscript file … … 186 329 $raf->Read($data, 4) == 4 or return 0; 187 330 # 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)/; 189 332 if ($data =~ /^%!Ad/) { 190 333 # I've seen PS files start with "%!Adobe-PS"... … … 200 343 return PSErr($exifTool, 'invalid header'); 201 344 } 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); 202 357 } 203 358 # 204 359 # set the newline type based on the first newline found in the file 205 360 # 206 my $oldsep = SetInputRecordSeparator($raf);207 $ oldsepor return PSErr($exifTool, 'invalid PS data');361 local $/ = GetInputRecordSeparator($raf); 362 $/ or return PSErr($exifTool, 'invalid PS data'); 208 363 209 364 # 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); 212 381 # 213 382 # extract TIFF information from DOS header 214 383 # 215 my$tagTablePtr = GetTagTable('Image::ExifTool::PostScript::Main');384 $tagTablePtr or $tagTablePtr = GetTagTable('Image::ExifTool::PostScript::Main'); 216 385 if ($dos) { 217 386 my $base = Get32u(\$dos, 16); … … 241 410 # parse the postscript 242 411 # 243 my ($buff, $mode, $ endToken);412 my ($buff, $mode, $beginToken, $endToken, $docNum, $subDocNum, $changedNL); 244 413 my (@lines, $altnl); 245 414 if ($/ eq "\x0d") { … … 256 425 # check for alternate newlines as efficiently as possible 257 426 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; 268 452 if ($mode) { 269 453 if (not $endToken) { … … 274 458 $buff .= $data; 275 459 } elsif ($mode eq 'Document') { 276 # ignore embedded documents 460 # ignore embedded documents, but keep track of nesting level 461 $docNum .= '-1' if $data =~ /^$beginToken/; 277 462 } else { 278 463 # data is ASCII-hex encoded … … 281 466 } 282 467 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) { 285 481 # the beginning of a data block 286 482 my %modeLookup = ( 287 483 _xml_packet => 'XMP', 484 photoshop => 'Photoshop', 288 485 iccprofile => 'ICC_Profile', 289 photoshop => 'Photoshop', 486 document => 'Document', 487 binary => undef, # (we will try to skip this) 290 488 ); 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 } 295 494 next; 296 495 } 297 496 $buff = ''; 497 $beginToken = $1 . $2 . $3; 298 498 $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 } 302 526 next; 303 527 } elsif ($data =~ /^<\?xpacket begin=.{7,13}W5M0MpCehiHzreSzNTczkc9d/) { … … 312 536 # only allow 'ImageData' to have single leading '%' 313 537 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); 319 540 $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 } 320 614 next; 321 615 } else { … … 323 617 } 324 618 # 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; 339 631 undef $mode; 340 632 } 341 $ / = $oldsep; # restore original separator342 $mode and $mode ne 'Document' andPSErr($exifTool, "unterminated $mode data");633 $mode = 'Document' if $endDoc and not $mode; 634 $mode and PSErr($exifTool, "unterminated $mode data"); 343 635 return 1; 344 636 } … … 371 663 (PostScript) and AI (Adobe Illustrator) files. 372 664 373 =head1 NOTES374 375 Currently doesn't handle continued lines ("%+" syntax).376 377 665 =head1 AUTHOR 378 666 379 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)667 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 380 668 381 669 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PrintIM.pm
r16842 r24107 13 13 use Image::ExifTool qw(:DataAccess); 14 14 15 $VERSION = '1.0 3';15 $VERSION = '1.06'; 16 16 17 17 sub ProcessPrintIM($$$); 18 18 19 # PrintIM table ( is this proprietary? I can't find any documentation on this)19 # PrintIM table (proprietary specification by Epson) 20 20 %Image::ExifTool::PrintIM::Main = ( 21 21 PROCESS_PROC => \&ProcessPrintIM, … … 23 23 PRINT_CONV => 'sprintf("0x%.8x", $val)', 24 24 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 25 36 ); 26 37 … … 28 39 #------------------------------------------------------------------------------ 29 40 # 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 32 42 # Returns: 1 on success 33 43 sub ProcessPrintIM($$$) … … 39 49 my $verbose = $exifTool->Options('Verbose'); 40 50 51 unless ($size) { 52 $exifTool->Warn('Empty PrintIM data', 1); 53 return 0; 54 } 41 55 unless ($size > 15) { 42 56 $exifTool->Warn('Bad PrintIM data'); 43 57 return 0; 44 58 } 45 my $header = substr($$dataPt, $offset, 7); 46 unless ($header eq 'PrintIM') { 59 unless (substr($$dataPt, $offset, 7) eq 'PrintIM') { 47 60 $exifTool->Warn('Invalid PrintIM header'); 48 61 return 0; … … 60 73 } 61 74 $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 ); 62 80 my $n; 63 81 for ($n=0; $n<$num; ++$n) { … … 68 86 Index => $n, 69 87 DataPt => $dataPt, 88 Start => $pos + 2, 70 89 Size => 4, 71 Start => $pos + 2,72 90 ); 73 91 } 74 92 return 1; 75 93 } 76 77 94 78 95 … … 96 113 =head1 AUTHOR 97 114 98 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)115 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 99 116 100 117 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/QuickTime.pm
r16842 r24107 7 7 # 12/19/2005 - P. Harvey Added MP4 support 8 8 # 09/22/2006 - P. Harvey Added M4A support 9 # 07/27/2010 - P. Harvey Updated to 2010-05-03 QuickTime spec 9 10 # 10 # References: 1) http://developer.apple.com/ documentation/QuickTime/11 # References: 1) http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html 11 12 # 2) http://search.cpan.org/dist/MP4-Info-1.04/ 12 13 # 3) http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt 13 14 # 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 14 25 #------------------------------------------------------------------------------ 15 26 … … 21 32 use Image::ExifTool::Exif; 22 33 23 $VERSION = '1. 12';34 $VERSION = '1.48'; 24 35 25 36 sub FixWrongFormat($); 26 37 sub ProcessMOV($$;$); 38 sub ProcessKeys($$$); 39 sub ProcessMetaData($$$); 40 sub ConvertISO6709($); 41 sub PrintGPSCoordinates($); 27 42 28 43 # information for time/date-based tags (time zero is Jan 1, 1904) 29 44 my %timeInfo = ( 30 Groups => { 2 => 'Time' },31 45 # Note: This value will be in UTC if generated by a system that is aware of the time zone 32 46 ValueConv => 'ConvertUnixTime($val - ((66 * 365 + 17) * 24 * 3600))', 33 47 PrintConv => '$self->ConvertDateTime($val)', 48 # (can't put Groups here because they aren't constant!) 34 49 ); 35 50 # information for duration tags 36 51 my %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) 57 my %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) 77 my %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) 87 my %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 104 my %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/) 142 my %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', 39 229 ); 40 230 41 231 # QuickTime atoms 42 232 %Image::ExifTool::QuickTime::Main = ( 43 PROCESS_PROC => \& Image::ExifTool::QuickTime::ProcessMOV,233 PROCESS_PROC => \&ProcessMOV, 44 234 GROUPS => { 2 => 'Video' }, 45 235 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. 49 241 }, 50 242 free => { Unknown => 1, Binary => 1 }, … … 52 244 wide => { Unknown => 1, Binary => 1 }, 53 245 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' }, 58 248 }, 59 249 pnot => { … … 65 255 Binary => 1, 66 256 }, 257 pict => { #8 258 Name => 'PreviewPICT', 259 Binary => 1, 260 }, 67 261 moov => { 68 262 Name => 'Movie', 69 263 SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Movie' }, 70 264 }, 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 }, 72 330 ); 73 331 74 332 # atoms used in QTIF files 75 333 %Image::ExifTool::QuickTime::ImageFile = ( 76 PROCESS_PROC => \& Image::ExifTool::QuickTime::ProcessMOV,334 PROCESS_PROC => \&ProcessMOV, 77 335 GROUPS => { 2 => 'Image' }, 78 336 NOTES => 'Tags used in QTIF QuickTime Image Files.', … … 95 353 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 96 354 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', 108 412 ); 109 413 … … 116 420 Name => 'PreviewDate', 117 421 Format => 'int32u', 422 Groups => { 2 => 'Time' }, 118 423 %timeInfo, 119 424 }, … … 128 433 # movie atoms 129 434 %Image::ExifTool::QuickTime::Movie = ( 130 PROCESS_PROC => \& Image::ExifTool::QuickTime::ProcessMOV,435 PROCESS_PROC => \&ProcessMOV, 131 436 GROUPS => { 2 => 'Video' }, 132 437 mvhd => { 133 438 Name => 'MovieHeader', 134 SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::MovieH dr' },439 SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::MovieHeader' }, 135 440 }, 136 441 trak => { … … 142 447 SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::UserData' }, 143 448 }, 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) 144 475 ); 145 476 146 477 # movie header data block 147 %Image::ExifTool::QuickTime::MovieH dr = (478 %Image::ExifTool::QuickTime::MovieHeader = ( 148 479 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 149 480 GROUPS => { 2 => 'Video' }, 150 481 FORMAT => 'int32u', 151 0 => { Name => 'Version', Format => 'int8u' }, 482 0 => { 483 Name => 'MovieHeaderVersion', 484 Format => 'int8u', 485 RawConv => '$$self{MovieHeaderVersion} = $val', 486 }, 152 487 1 => { 153 488 Name => 'CreateDate', 489 Groups => { 2 => 'Time' }, 154 490 %timeInfo, 491 # this is int64u if MovieHeaderVersion == 1 (ref 13) 492 Hook => '$$self{MovieHeaderVersion} and $format = "int64u", $varSize += 4', 155 493 }, 156 494 2 => { 157 495 Name => 'ModifyDate', 496 Groups => { 2 => 'Time' }, 158 497 %timeInfo, 498 # this is int64u if MovieHeaderVersion == 1 (ref 13) 499 Hook => '$$self{MovieHeaderVersion} and $format = "int64u", $varSize += 4', 159 500 }, 160 501 3 => { 161 502 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 }, 165 511 5 => { 166 512 Name => 'PreferredRate', … … 172 518 ValueConv => '$val / 256', 173 519 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 }, 174 530 }, 175 531 18 => { Name => 'PreviewTime', %durationInfo }, … … 184 540 # track atoms 185 541 %Image::ExifTool::QuickTime::Track = ( 186 PROCESS_PROC => \& Image::ExifTool::QuickTime::ProcessMOV,542 PROCESS_PROC => \&ProcessMOV, 187 543 GROUPS => { 2 => 'Video' }, 188 544 tkhd => { 189 545 Name => 'TrackHeader', 190 SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TrackH dr' },546 SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TrackHeader' }, 191 547 }, 192 548 udta => { … … 198 554 SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Media' }, 199 555 }, 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) 200 587 ); 201 588 202 589 # track header data block 203 %Image::ExifTool::QuickTime::TrackH dr = (590 %Image::ExifTool::QuickTime::TrackHeader = ( 204 591 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 205 592 GROUPS => { 1 => 'Track#', 2 => 'Video' }, 206 593 FORMAT => 'int32u', 207 594 0 => { 208 Name => 'Track Version',595 Name => 'TrackHeaderVersion', 209 596 Format => 'int8u', 210 597 Priority => 0, 598 RawConv => '$$self{TrackHeaderVersion} = $val', 211 599 }, 212 600 1 => { 213 601 Name => 'TrackCreateDate', 214 602 Priority => 0, 603 Groups => { 2 => 'Time' }, 215 604 %timeInfo, 605 # this is int64u if TrackHeaderVersion == 1 (ref 13) 606 Hook => '$$self{TrackHeaderVersion} and $format = "int64u", $varSize += 4', 216 607 }, 217 608 2 => { 218 609 Name => 'TrackModifyDate', 219 610 Priority => 0, 611 Groups => { 2 => 'Time' }, 220 612 %timeInfo, 613 # this is int64u if TrackHeaderVersion == 1 (ref 13) 614 Hook => '$$self{TrackHeaderVersion} and $format = "int64u", $varSize += 4', 221 615 }, 222 616 3 => { … … 228 622 Priority => 0, 229 623 %durationInfo, 624 # this is int64u if TrackHeaderVersion == 1 (ref 13) 625 Hook => '$$self{TrackHeaderVersion} and $format = "int64u", $varSize += 4', 230 626 }, 231 627 8 => { … … 241 637 PrintConv => 'sprintf("%.2f%%", $val * 100)', 242 638 }, 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 }, 243 649 19 => { 244 650 Name => 'ImageWidth', … … 255 661 # user data atoms 256 662 %Image::ExifTool::QuickTime::UserData = ( 257 PROCESS_PROC => \& Image::ExifTool::QuickTime::ProcessMOV,663 PROCESS_PROC => \&ProcessMOV, 258 664 GROUPS => { 2 => 'Video' }, 259 665 NOTES => q{ 260 666 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 268 692 "\xa9ed1" => 'Edit1', 269 693 "\xa9ed2" => 'Edit2', … … 276 700 "\xa9ed9" => 'Edit9', 277 701 "\xa9fmt" => 'Format', 702 "\xa9gen" => 'Genre', #PH (iTunes 8.0.2) 703 "\xa9grp" => 'Grouping', #PH (NC) 278 704 "\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 279 715 "\xa9prd" => 'Producer', 280 716 "\xa9prf" => 'Performers', 717 "\xa9prk" => 'PerformerKeywords', #12 718 "\xa9prl" => 'PerformerURL', 719 "\xa9dir" => 'Director', #12 281 720 "\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 }, 284 736 name => 'Name', 285 737 WLOC => { … … 307 759 SubDirectory => { 308 760 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', 310 768 }, 311 769 }, … … 314 772 SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Video' }, 315 773 }, 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 319 785 { 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 { 322 842 Name => 'PentaxTags', 323 843 Condition => '$$valPt =~ /^PENTAX DIGITAL CAMERA\0/', … … 328 848 }, 329 849 { 330 Name => ' NikonTags',331 Condition => '$$valPt =~ /^ NIKONDIGITAL CAMERA\0/',850 Name => 'SamsungTags', 851 Condition => '$$valPt =~ /^SAMSUNG DIGITAL CAMERA\0/', 332 852 SubDirectory => { 333 TagTable => 'Image::ExifTool:: Nikon::MOV',853 TagTable => 'Image::ExifTool::Samsung::MP4', 334 854 ByteOrder => 'LittleEndian', 335 855 }, … … 363 883 }, 364 884 ], 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 }, 365 1127 ); 366 1128 367 1129 # meta atoms 368 1130 %Image::ExifTool::QuickTime::Meta = ( 369 PROCESS_PROC => \& Image::ExifTool::QuickTime::ProcessMOV,1131 PROCESS_PROC => \&ProcessMOV, 370 1132 GROUPS => { 2 => 'Video' }, 371 1133 ilst => { 372 Name => 'I nfoList',1134 Name => 'ItemList', 373 1135 SubDirectory => { 374 TagTable => 'Image::ExifTool::QuickTime::I nfoList',1136 TagTable => 'Image::ExifTool::QuickTime::ItemList', 375 1137 HasData => 1, # process atoms as containers with 'data' elements 376 1138 }, 377 1139 }, 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 381 1196 # -> these atoms are unique, and contain one or more 'data' atoms 382 %Image::ExifTool::QuickTime::I nfoList = (383 PROCESS_PROC => \& Image::ExifTool::QuickTime::ProcessMOV,1197 %Image::ExifTool::QuickTime::ItemList = ( 1198 PROCESS_PROC => \&ProcessMOV, 384 1199 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 385 1206 "\xa9ART" => 'Artist', 386 1207 "\xa9alb" => 'Album', 387 1208 "\xa9cmt" => 'Comment', 388 1209 "\xa9com" => 'Composer', 389 "\xa9day" => 'Year',1210 "\xa9day" => { Name => 'Year', Groups => { 2 => 'Time' } }, 390 1211 "\xa9des" => 'Description', #4 1212 "\xa9enc" => 'EncodedBy', #10 391 1213 "\xa9gen" => 'Genre', 392 1214 "\xa9grp" => 'Grouping', 393 1215 "\xa9lyr" => 'Lyrics', 394 1216 "\xa9nam" => 'Title', 1217 # "\xa9st3" ? #10 395 1218 "\xa9too" => 'Encoder', 396 1219 "\xa9trk" => 'Track', … … 401 1224 }, 402 1225 aART => 'AlbumArtist', 403 apid => 'AppleStoreID',404 auth => 'Author',405 1226 covr => 'CoverArt', 406 cpil => { 1227 cpil => { #10 407 1228 Name => 'Compilation', 408 1229 PrintConv => { 0 => 'No', 1 => 'Yes' }, 409 1230 }, 410 cprt => 'Copyright',411 1231 disk => { 412 1232 Name => 'DiskNumber', 413 1233 ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val', 414 1234 }, 415 dscp => 'Description', 416 gnre => 'Genre', 417 perf => 'Performer', 418 pgap => { 1235 pgap => { #10 419 1236 Name => 'PlayGap', 420 1237 PrintConv => { … … 423 1240 }, 424 1241 }, 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 }, 428 1246 trkn => { 429 1247 Name => 'TrackNumber', 430 1248 ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val', 431 1249 }, 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 435 1472 %Image::ExifTool::QuickTime::iTunesInfo = ( 436 PROCESS_PROC => \& Image::ExifTool::QuickTime::ProcessMOV,1473 PROCESS_PROC => \&ProcessMOV, 437 1474 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 }, 438 1492 ); 439 1493 … … 461 1515 ); 462 1516 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) 464 1602 %Image::ExifTool::QuickTime::Media = ( 465 PROCESS_PROC => \& Image::ExifTool::QuickTime::ProcessMOV,1603 PROCESS_PROC => \&ProcessMOV, 466 1604 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 }, 468 1614 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, 476 1623 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 }, 478 1689 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' }, 481 1700 }, 482 1701 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, 490 1710 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, 496 1745 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 2103 Image::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 2110 sub 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) 2145 sub 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 } 499 2158 500 2159 #------------------------------------------------------------------------------ … … 511 2170 512 2171 #------------------------------------------------------------------------------ 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? 2176 sub 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 2205 sub 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 2222 sub 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 2243 sub 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 2295 sub 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 #------------------------------------------------------------------------------ 513 2362 # 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 516 2364 # Returns: 1 on success 517 2365 sub ProcessMOV($$;$) … … 526 2374 # more convenient to package data as a RandomAccess file 527 2375 $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 } 530 2381 # read size/tag name atom header 531 2382 $raf->Read($buff,8) == 8 or return 0; … … 539 2390 $$tagTablePtr{$tag} or return 0; 540 2391 if ($tag eq 'ftyp') { 541 # read ahead 4 bytes to see if this is an M4A file542 my $f typ = 'MP4';2392 # read ahead 4 bytes to see what type of file this is 2393 my $fileType; 543 2394 if ($raf->Read($buff, 4) == 4) { 544 2395 $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+)/; 546 2398 } 547 $exifTool->SetFileType($ftyp); # MP4 or M4A 2399 $fileType or $fileType = 'MP4'; # default to MP4 2400 $exifTool->SetFileType($fileType, $mimeLookup{$fileType} || 'video/mp4'); 548 2401 } else { 549 2402 $exifTool->SetFileType(); # MOV … … 558 2411 $dataPos += 8; 559 2412 my ($hi, $lo) = unpack('NN', $buff); 2413 $size = $lo; 560 2414 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 } 563 2422 } 564 $size = $ lo;2423 $size = $hi * 4294967296 + $lo; 565 2424 } 566 2425 $size -= 8; 567 2426 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 } 568 2435 # generate tagInfo if Unknown option set 569 2436 if (not defined $tagInfo and ($exifTool->{OPTIONS}->{Unknown} or 570 $ tag =~ /^\xa9/))2437 $verbose or $tag =~ /^\xa9/)) 571 2438 { 572 2439 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; 574 2443 if ($name =~ /^xa9(.*)/) { 575 2444 $tagInfo = { … … 587 2456 Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo); 588 2457 } 2458 # save required tag sizes 2459 $exifTool->HandleTag($tagTablePtr, "$tag-size", $size) if $$tagTablePtr{"$tag-size"}; 589 2460 # load values only if associated with a tag (or verbose) and < 16MB long 590 2461 if ((defined $tagInfo or $verbose) and $size < 0x1000000) { … … 596 2467 # use value to get tag info if necessary 597 2468 $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); 599 2470 if ($verbose and not $hasData) { 600 2471 $exifTool->VerboseInfo($tag, $tagInfo, … … 607 2478 my $subdir = $$tagInfo{SubDirectory}; 608 2479 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 } 609 2486 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, 616 2495 # Base needed for IsOffset tags in binary data 617 Base => $dataPos,2496 Base => $base, 618 2497 ); 619 2498 if ($$subdir{ByteOrder} and $$subdir{ByteOrder} =~ /^Little/) { 620 2499 SetByteOrder('II'); 621 2500 } 2501 my $oldGroup1 = $exifTool->{SET_GROUP1}; 622 2502 if ($$tagInfo{Name} eq 'Track') { 623 2503 $track or $track = 0; … … 625 2505 } 626 2506 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; 629 2510 SetByteOrder('MM'); 630 2511 } elsif ($hasData) { 631 2512 # handle atoms containing 'data' tags 2513 # (currently ignore contained atoms: 'itif', 'name', etc.) 632 2514 my $pos = 0; 633 2515 for (;;) { 634 2516 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); 636 2518 last if $pos + $len > $size; 637 2519 my $value; 2520 my $format = $$tagInfo{Format}; 638 2521 if ($type eq 'data' and $len >= 16) { 639 2522 $pos += 16; 640 2523 $len -= 16; 641 2524 $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 } 649 2558 } 650 2559 } 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, 654 2582 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) 658 2587 ) 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); 660 2630 $pos += $len; 661 2631 } 662 2632 } 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}) { 671 2634 $val = ReadValue(\$val, 0, $$tagInfo{Format}, $$tagInfo{Count}, length($val)); 672 2635 } … … 690 2653 sub ProcessQTIF($$) 691 2654 { 2655 my ($exifTool, $dirInfo) = @_; 692 2656 my $table = GetTagTable('Image::ExifTool::QuickTime::ImageFile'); 693 return ProcessMOV($ _[0], $_[1], $table);2657 return ProcessMOV($exifTool, $dirInfo, $table); 694 2658 } 695 2659 … … 711 2675 information from QuickTime and MP4 video, and M4A audio files. 712 2676 713 =head1 BUGS714 715 The MP4 support is rather pathetic since the specification documentation is716 not freely available (yes, ISO sucks).717 718 2677 =head1 AUTHOR 719 2678 720 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)2679 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 721 2680 722 2681 This library is free software; you can redistribute it and/or modify it … … 727 2686 =over 4 728 2687 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> 730 2705 731 2706 =back -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/README
r16842 r24107 4 4 Description: ExifTool support modules documentation 5 5 6 The ExifTool support modules are loaded by ExifTool to interpret various formats7 of meta information.6 The ExifTool support modules are loaded by ExifTool to allow processing of 7 various meta information formats. 8 8 9 9 The tables in these files are used as lookups based on the tag ID values. The … … 11 11 with EXIF tables, or the tag name if the ID is ASCII as with XMP tables). In 12 12 the 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: 13 the binary data block (floating point IDs allow multiple tags for the same 14 offset, with the integer part being used for the offset). The corresponding 15 hash value provides information about the tag (explained later). 16 17 Twenty-five special keys (TABLE_NAME, SHORT_NAME, PROCESS_PROC, WRITE_PROC, 18 CHECK_PROC, GROUPS, FORMAT, FIRST_ENTRY, TAG_PREFIX, PRINT_CONV, WRITABLE, 19 TABLE_DESC, NOTES, IS_OFFSET, IS_SUBDIR, EXTRACT_UNKNOWN, NAMESPACE, PREFERRED, 20 SRC_TABLE, PRIORITY, WRITE_GROUP, LANG_INFO, VARS, DATAMEMBER and SET_GROUP1) 21 are used to provide additional information about a table. The special keys have 22 names that are all capitalized to avoid possible conflicts with tag keys. Below 23 is 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. 22 28 23 29 PROCESS_PROC : Reference to a function used to process the directory for this … … 56 62 reference, 2) value reference, and returns undefined (and possibly modifies 57 63 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. 59 65 60 66 GROUPS : A hash lookup for the default group names for all entries in this … … 64 70 FORMAT : Specifies the default tag Format and corresponding pointer increment 65 71 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: 67 75 68 76 int8s - Signed 8-bit integer (EXIF 'SBYTE') … … 70 78 int16s - Signed 16-bit integer (EXIF 'SSHORT') 71 79 int16u - Unsigned 16-bit integer (EXIF 'SHORT') 80 int16uRev - Unsigned 16-bit integer, reversed byte order 72 81 int32s - Signed 32-bit integer (EXIF 'SLONG') 73 82 int32u - Unsigned 32-bit integer (EXIF 'LONG') … … 86 95 extended - 80-bit extended floating float 87 96 ifd - Unsigned 32-bit integer sub-IFD pointer (EXIF 'IFD') 88 ifd 8- Unsigned 64-bit integer sub-IFD pointer (BigTIFF 'IFD8')97 ifd64 - Unsigned 64-bit integer sub-IFD pointer (BigTIFF 'IFD8') 89 98 string - Series of 8-bit ASCII characters (EXIF 'ASCII') 99 pstring - Pascal string [BinaryData tables only] 90 100 undef - Undefined-format binary data (EXIF 'UNDEFINED') 91 101 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] 92 107 93 108 FIRST_ENTRY : Specifies the index for the first tag entry in a binary table. … … 97 112 TAG_PREFIX : Prefix for names of unknown tags. 98 113 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. 104 117 105 118 WRITABLE : Indicates that all tags in this table are writable. This is the … … 107 120 for SubDirectory tags which are not made Writable. 108 121 122 TABLE_DESC : Short description for this table. Plain text only. Used only 123 for XML tag database output. 124 109 125 NOTES : Notes to introduce the table in the TagNames documentation. Pod 110 126 formatting codes B<> and C<> may be used in this text. 111 127 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. 114 133 115 134 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. 117 137 118 138 NAMESPACE : Namespace prefix for tags in the XMP table. If this isn't a … … 120 140 this, the NAMESPACE value is a reference to either a list or a hash, where the 121 141 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. 123 144 124 145 PREFERRED : Set to true if the tags in this table should always be added when … … 128 149 directories for tags which are already being creating in the preferred group. 129 150 130 PARENT : Used internally to store the parent table name of a user-defined tag131 ta ble 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. 132 153 133 154 PRIORITY : Default Priority for all tags in this table. … … 138 159 language-specific tag information hash. The routine takes two arguments: a 139 160 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). 141 163 142 164 VARS : Hash used to store additional parameters. Individual modules may use … … 144 166 have been defined, and may be used by any module: 145 167 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. 152 194 153 195 The remaining entries in a tag table are the tag IDs with their associated … … 161 203 162 204 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. 171 215 172 216 Description : A more readable description of tag name. If a tag doesn't … … 181 225 or EXIF table, this gives the format that is used to convert 182 226 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, 187 237 '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. 192 245 193 246 Count : Used when writing EXIF information to specify the number … … 199 252 count written to the file will be different. 200 253 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 201 258 Flags : Flags to specify characteristics for this tag. May be a 202 259 simple scalar flag name, a reference to a list of flag names, … … 207 264 available flag names are: 208 265 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. 210 272 211 273 'Binary' - set to 1 for binary data. This has the same effect 212 274 as setting ValueConv to '\$val', but it it a bit cleaner and 213 275 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. 215 283 216 284 'DataMember' - name of exiftool data member associated with … … 218 286 writing information. Necessary only if the value of the tag 219 287 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. 221 291 222 292 'DataTag' - associated tag name containing data for offset or … … 231 301 Casio PrintIM information). 232 302 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 233 318 'IsOffset' - flag set if the tag represents an offset to some 234 319 data, and causes value will be adjusted to an absolute file 235 320 offset. If set to 2, the offset base of the parent directory 236 321 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). 243 337 244 338 'MakerNotes' - set if this tag is maker note data. 245 339 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 246 352 '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 249 356 'OffsetPair' - set if the tag represents half of an offset/ 250 357 byte count pair. Data for these tags must be handled … … 252 359 253 360 '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 255 363 MakerNotes tags are permanent unless otherwise specified. 256 364 257 365 '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. 259 372 260 373 'Priority' - gives the priority of this tag while reading. If … … 265 378 special feature is that Priority 0 tags are automatically 266 379 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. 268 383 269 384 'Protected' - bit mask to protect tags from writing: … … 273 388 directly by the user. 274 389 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 275 398 'SeparateTable' - set to list PrintConv values in a separate 276 399 table in the HTML documentation. Value is 1 for a table name 277 400 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. 279 403 280 404 'SetResourceName' - [Photoshop tags only] set to 1 to append … … 285 409 provided. 286 410 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 287 422 'SubIFD' - used in writing to determine that the tag specifies 288 423 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. 290 428 291 429 'Unknown' - this is an unknown tag (only extracted when the 292 430 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. 293 435 294 436 RawConv : Used to convert the Raw value at extraction time (while the … … 296 438 which are done later only if the value is requested). May be 297 439 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, 301 444 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. 312 458 313 459 ValueConv : Used to convert the Raw value to a useable form. May be a hash … … 319 465 list. If a hash reference is used and the Raw value doesn't 320 466 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 324 476 expression, $self is a reference to the current ExifTool 325 object, $val is the Raw value, and $tag is the tag name. The477 object, $val is the Raw value, and $tag is the tag key. The 326 478 subroutine takes 2 arguments: the Raw value and a reference to 327 479 the current ExifTool object. The expression or subroutine is … … 333 485 to cyclical dependencies so they should be avoided). When 334 486 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. 348 504 349 505 PrintConv : This entry is similar to ValueConv above, except that it is … … 375 531 that DataMember tags may NOT be used in the inverse 376 532 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). 379 543 380 544 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. 382 567 383 568 Condition : If given, specifies scalar which is evaluated as a Perl … … 386 571 first list entry with a true condition is taken. If no 387 572 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. 398 587 399 588 Require : [Composite tags only] A hash reference specifying the tags … … 436 625 information, this flag is only defined if the SubDirectory is 437 626 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). 439 633 440 634 WriteAlso : Used for writable tag to specify other tags to write when this … … 442 636 are the names of the tags to write, and the values are 443 637 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. 447 650 448 651 WriteCheck : If given, specifies a scalar which is evaluated as a Perl … … 451 654 the value to be written, $self is the ExifTool object, and 452 655 $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). 454 666 455 667 WriteCondition: [Writable EXIF tags only] Specifies a condition to be 456 668 evaluated before the tag can be written to a specific file. 457 669 The condition may use $self to reference the ExifTool object, 458 and returns true if it is OK for writing. Unlike WriteCheck670 and returns true if it is OK for writing. Unlike WriteCheck 459 671 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). 465 688 466 689 OffsetPair : Used in EXIF table to specify the tagID for the corresponding … … 470 693 associated with offset/length tags. 471 694 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. 474 716 475 717 Units : [MIE tags only] Reference to a list of valid units strings. 476 718 The default units are the first item in the list. 477 719 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. 480 737 481 738 Table : [reserved] Reference to parent tag table. 482 739 483 740 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. 485 750 486 751 Module : [reserved] Used internally to store module name for writable … … 488 753 489 754 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). 491 757 492 758 SubDirectory { If it exists, this specifies the start of a new subdirectory. … … 514 780 same as the current directory, which is normally the case. 515 781 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 521 789 directory entry position, so offsets are incremented by 12 522 790 times the corresponding entry index. … … 526 794 tag value ($val) is used as-is. If MaxSubdirs is specified, 527 795 then one subdirectory is parsed for each value found up to the 528 maximum number specified. 796 maximum number specified. Ignored when writing. 529 797 530 798 ByteOrder : Specifies byte ordering if different than than the rest of the … … 538 806 the expression: $val (value of the tag), $dirData (reference 539 807 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. 541 810 542 811 ProcessProc: If given, specifies processing procedure used to decode this 543 812 subdirectory data. This overrides the default procedure 544 813 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. 545 818 546 819 DirName : Name of this subdirectory. If not specified, the name is … … 551 824 FixBase : Flag set if base offsets should be fixed. Used to add a 552 825 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. 554 832 555 833 FixOffsets : Expression to evaluate for each value pointer to patch … … 557 835 following variables: $valuePtr, $valEnd, $size, $tagID and 558 836 $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. 559 847 } 560 848 849 STRUCTURES 850 851 Structure hashes are very similar to tag tables in that their keys are structure 852 field ID's and their values are structure field information hashes. The special 853 keys 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 869 The contained structure field information hashes are similar to tag information 870 hashes, 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 875 But note that for PropertyPath, only the element of the path corresponding to 876 the specific field is stored (including any necessary list properties). The 877 full property path is obtained by walking the structure tree. 878 879 Flattened tags corresponding to each field in a structure are automatically 880 generated (using an on-demand approach to avoid spending time generating them 881 unless necessary). Pre-defined flattened tags are allowed, and are used when it 882 is necessary to change the Name or Description of a flattened tag. The 883 flattened tag information hash entries are copied from the corresponding 884 structure field definitions, even for pre-defined flattened tags. The exception 885 that the List tag is generated automatically unless explicity set to 0 in a 886 pre-defined flattened tag. 887 561 888 -------------------------------------------------------------------------------- -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/RIFF.pm
r16842 r24107 15 15 # 8) http://graphics.cs.uni-sb.de/NMM/dist-0.9.1/Docs/Doxygen/html/mmreg_8h-source.html 16 16 # 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 17 21 #------------------------------------------------------------------------------ 18 22 … … 23 27 use Image::ExifTool qw(:DataAccess :Utils); 24 28 25 $VERSION = '1.10'; 29 $VERSION = '1.28'; 30 31 sub ConvertTimecode($); 26 32 27 33 # type of current stream 28 34 $Image::ExifTool::RIFF::streamType = ''; 29 35 30 my %riffEncoding = ( #2 36 %Image::ExifTool::RIFF::audioEncoding = ( #2 37 Notes => 'These "TwoCC" audio encoding codes are used in RIFF and ASF files.', 31 38 0x01 => 'Microsoft PCM', 32 39 0x02 => 'Microsoft ADPCM', … … 39 46 0x09 => 'DRM', #4 40 47 0x0a => 'WMA 9 Speech', #9 48 0x0b => 'Microsoft Windows Media RT Voice', #10 41 49 0x10 => 'OKI-ADPCM', 42 50 0x11 => 'Intel IMA/DVI-ADPCM', … … 49 57 0x18 => 'Media Vision ADPCM', #6 50 58 0x19 => 'HP CU', #7 59 0x1a => 'HP Dynamic Voice', #10 51 60 0x20 => 'Yamaha ADPCM', #6 52 61 0x21 => 'SONARC Speech Compression', #6 … … 75 84 0x41 => 'Antex G.728 CELP', 76 85 0x42 => 'Microsoft MSG723', #7 86 0x43 => 'IBM AVC ADPCM', #10 77 87 0x45 => 'ITU-T G.726', #9 78 88 0x50 => 'Microsoft MPEG', … … 101 111 0x78 => 'Voxware VR18', #7 102 112 0x79 => 'Voxware TQ40', #7 113 0x7a => 'Voxware SC3', #10 114 0x7b => 'Voxware SC3', #10 103 115 0x80 => 'Soundsoft', #6 104 116 0x81 => 'Voxware TQ60', #7 … … 110 122 0x88 => 'Iterated Systems Audio', #7 111 123 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 112 128 0x91 => 'Siemens SBC24', #7 113 129 0x92 => 'Sonic Foundry Dolby AC3 APDIF', #7 … … 118 134 0x99 => 'Studer Professional Audio Packed', #7 119 135 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 120 142 0x100 => 'Rhetorex ADPCM', #6 121 143 0x101 => 'IBM u-Law', #3 … … 124 146 0x111 => 'Vivo G.723', #7 125 147 0x112 => 'Vivo Siren', #7 148 0x120 => 'Philips Speech Processing CELP', #10 149 0x121 => 'Philips Speech Processing GRUNDIG', #10 126 150 0x123 => 'Digital G.723', #7 127 151 0x125 => 'Sanyo LD ADPCM', #8 … … 132 156 0x134 => 'Sipro Lab G.729A', #8 133 157 0x135 => 'Sipro Lab Kelvin', #8 158 0x136 => 'VoiceAge AMR', #10 134 159 0x140 => 'Dictaphone G.726 ADPCM', #8 135 160 0x150 => 'Qualcomm PureVoice', #8 … … 137 162 0x155 => 'Ring Zero Systems TUBGSM', #8 138 163 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 139 179 0x200 => 'Creative Labs ADPCM', #6 140 180 0x202 => 'Creative Labs FASTSPEECH8', #6 141 181 0x203 => 'Creative Labs FASTSPEECH10', #6 142 182 0x210 => 'UHER ADPCM', #8 183 0x215 => 'Ulead DV ACM', #10 184 0x216 => 'Ulead DV ACM', #10 143 185 0x220 => 'Quarterdeck Corp.', #6 144 186 0x230 => 'I-Link VC', #8 145 187 0x240 => 'Aureal Semiconductor Raw Sport', #8 188 0x241 => 'ESST AC3', #10 146 189 0x250 => 'Interactive Products HSX', #8 147 190 0x251 => 'Interactive Products RPELP', #8 148 191 0x260 => 'Consistent CS2', #8 149 192 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 150 199 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 151 210 0x400 => 'Brooktree Digital', #6 211 0x401 => 'Intel Music Coder (IMC)', #10 212 0x402 => 'Ligos Indeo Audio', #10 152 213 0x450 => 'QDesign Music', #8 214 0x500 => 'On2 VP7 On2 Technologies', #10 215 0x501 => 'On2 VP6 On2 Technologies', #10 153 216 0x680 => 'AT&T VME VMPCM', #7 154 217 0x681 => 'AT&T TCP', #8 218 0x700 => 'YMPEG Alpha (dummy for MPEG-2 compressor)', #10 219 0x8ae => 'ClearJump LiteWave (lossless)', #10 155 220 0x1000 => 'Olivetti GSM', #6 156 221 0x1001 => 'Olivetti ADPCM', #6 … … 159 224 0x1004 => 'Olivetti OPR', #6 160 225 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 161 230 0x1400 => 'Norris Comm. Inc.', #6 162 231 0x1401 => 'ISIAudio', #7 163 232 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 164 241 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 165 279 0xfffe => 'Extensible', #7 166 280 0xffff => 'Development', #4 … … 171 285 PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks, 172 286 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. 176 293 }, 177 294 'fmt ' => { … … 179 296 SubDirectory => { TagTable => 'Image::ExifTool::RIFF::AudioFormat' }, 180 297 }, 298 'bext' => { 299 Name => 'BroadcastExtension', 300 SubDirectory => { TagTable => 'Image::ExifTool::RIFF::BroadcastExt' }, 301 }, 181 302 LIST_INFO => { 182 303 Name => 'Info', … … 191 312 SubDirectory => { TagTable => 'Image::ExifTool::RIFF::Hdrl' }, 192 313 }, 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' }, 193 390 ); 194 391 … … 201 398 Name => 'Encoding', 202 399 PrintHex => 1, 203 PrintConv => \%riffEncoding, 400 PrintConv => \%Image::ExifTool::RIFF::audioEncoding, 401 SeparateTable => 'AudioEncoding', 204 402 }, 205 403 1 => 'NumChannels', … … 217 415 ); 218 416 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 219 463 # Sub chunks of INFO LIST chunk 220 464 %Image::ExifTool::RIFF::Info = ( 221 465 PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks, 222 466 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 }, 223 473 IARL => 'ArchivalLocation', 224 474 IART => { Name => 'Artist', Groups => { 2 => 'Author' } }, … … 229 479 Name => 'DateCreated', 230 480 Groups => { 2 => 'Time' }, 231 ValueConv => '$_=$val; s/-/:/g; s/\0.*//s;$_',481 ValueConv => '$_=$val; s/-/:/g; $_', 232 482 }, 233 483 ICRP => 'Cropped', … … 243 493 IPRD => 'Product', 244 494 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 }, 246 501 ISHP => 'Sharpness', 247 502 ISRC => 'Source', 248 503 ISRF => 'SourceForm', 249 504 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 }, 250 625 ); 251 626 … … 254 629 PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks, 255 630 GROUPS => { 2 => 'Audio' }, 631 NOTES => 'These tags are part of the EXIF 2.3 specification for WAV audio files.', 256 632 ever => 'ExifVersion', 257 633 erel => 'RelatedImageFile', … … 281 657 PrintConv => '$self->ConvertDateTime($val)', 282 658 }, 283 ISMP => 'Time Code',659 ISMP => 'Timecode', 284 660 LIST_strl => { 285 661 Name => 'Stream', 286 662 SubDirectory => { TagTable => 'Image::ExifTool::RIFF::Stream' }, 287 663 }, 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) 288 675 ); 289 676 … … 295 682 0 => { 296 683 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', 298 686 PrintConv => 'int($val * 1000 + 0.5) / 1000', 299 687 }, … … 338 726 ); 339 727 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 340 746 %Image::ExifTool::RIFF::StreamHeader = ( 341 747 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, … … 343 749 FORMAT => 'int32u', 344 750 FIRST_ENTRY => 0, 751 PRIORITY => 0, # so we get values from the first stream 345 752 0 => { 346 753 Name => 'StreamType', … … 354 761 }, 355 762 }, 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 ], 360 779 # 2 => 'StreamFlags', 361 780 # 3 => 'StreamPriority', 362 781 # 3.5 => 'Language', 363 782 # 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 ], 366 806 # 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 ], 368 820 # 9 => 'SuggestedBufferSize', 369 10 => 'Quality', 821 10 => { 822 Name => 'Quality', 823 PrintConv => '$val eq 0xffffffff ? "Default" : $val', 824 }, 370 825 11 => { 371 826 Name => 'SampleSize', … … 378 833 PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessStreamData, 379 834 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 }, 381 839 AVIF => { 382 840 Name => 'AVIF', … … 385 843 DirName => 'IFD0', 386 844 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', 389 857 }, 390 858 ); … … 394 862 Duration => { 395 863 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)', 401 900 }, 402 901 ); … … 430 929 431 930 #------------------------------------------------------------------------------ 931 # Print time 932 # Inputs: 0) time in seconds 933 # Returns: time string 934 sub 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 #------------------------------------------------------------------------------ 432 945 # Process stream data 433 946 # Inputs: 0) ExifTool object ref, 1) dirInfo reference, 2) tag table ref … … 445 958 my $tag = substr($$dataPt, $start, 4); 446 959 my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag); 960 unless ($tagInfo) { 961 $tagInfo = $exifTool->GetTagInfo($tagTablePtr, 'unknown'); 962 return 1 unless $tagInfo; 963 } 447 964 my $subdir = $$tagInfo{SubDirectory}; 448 if ($ subdir) {965 if ($$tagInfo{SubDirectory}) { 449 966 my $offset = $$subdir{Start} || 0; 450 967 my $baseShift = $$dirInfo{DataPos} + $$dirInfo{DirStart} + $offset; … … 459 976 Parent => $$dirInfo{DirName}, 460 977 ); 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 } 461 983 # (we could set FIRST_EXIF_POS to $subdirInfo{Base} here to make 462 984 # htmlDump offsets relative to EXIF base if we wanted...) 463 985 my $subTable = GetTagTable($$subdir{TagTable}); 464 986 $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 ); 465 995 } 466 996 return 1; … … 479 1009 my $size = $$dirInfo{DirLen}; 480 1010 my $end = $start + $size; 1011 my $base = $$dirInfo{Base}; 481 1012 482 1013 if ($exifTool->Options('Verbose')) { … … 496 1027 $start += 4; 497 1028 } 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, 503 1056 ); 504 1057 ++$len if $len & 0x01; # must account for padding if odd number of bytes … … 517 1070 my $raf = $$dirInfo{RAF}; 518 1071 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'); 520 1074 521 1075 # verify this is a valid RIFF file 522 1076 return 0 unless $raf->Read($buff, 12) == 12; 523 1077 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' 525 1079 $Image::ExifTool::RIFF::streamType = ''; # initialize stream type 526 1080 SetByteOrder('II'); … … 528 1082 my $pos = 12; 529 1083 # 530 # Read chunks in RIFF image until we get to the 'data' chunk1084 # Read chunks in RIFF image 531 1085 # 532 1086 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 } 534 1092 $pos += 8; 535 1093 my ($tag, $len) = unpack('a4V', $buff); … … 543 1101 $exifTool->VPrint(0, "RIFF '$tag' chunk ($len bytes of data):\n"); 544 1102 # 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 { 546 1108 $exifTool->VPrint(0, "(end of parsing)\n"); 547 1109 last; 548 1110 } 549 my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);550 1111 # RIFF chunks are padded to an even number of bytes 551 1112 my $len2 = $len + ($len & 0x01); 552 if ($ tagInfo and $$tagInfo{SubDirectory}) {1113 if ($$tagTablePtr{$tag} or ($verbose and $tag !~ /^(data|idx1|LIST_movi)$/)) { 553 1114 $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, 559 1121 ); 560 my $tagTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});561 $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);562 1122 } else { 563 1123 $raf->Seek($len2, 1) or $err=1, last; … … 589 1149 =head1 AUTHOR 590 1150 591 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1151 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 592 1152 593 1153 This library is free software; you can redistribute it and/or modify it … … 608 1168 =item L<http://msdn.microsoft.com/archive/en-us/directx9_c/directx/htm/avirifffilereference.asp> 609 1169 1170 =item L<http://wiki.multimedia.cx/index.php?title=TwoCC> 1171 610 1172 =back 611 1173 -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Real.pm
r16842 r24107 17 17 use Image::ExifTool::Canon; 18 18 19 $VERSION = '1.0 1';19 $VERSION = '1.04'; 20 20 21 21 sub ProcessRealMeta($$$); … … 89 89 GROUPS => { 1 => 'Real-PROP', 2 => 'Video' }, 90 90 PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData, 91 VARS => { ID_LABEL => 'Sequence' }, 91 92 FORMAT => 'int32u', 92 0 => 'MaxBitRate',93 1 => 'AvgBitRate',93 0 => { Name => 'MaxBitrate', PrintConv => 'ConvertBitrate($val)' }, 94 1 => { Name => 'AvgBitrate', PrintConv => 'ConvertBitrate($val)' }, 94 95 2 => 'MaxPacketSize', 95 96 3 => 'AvgPacketSize', 96 97 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)' }, 99 100 7 => { Name => 'IndexOffset', Unknown => 1 }, 100 101 8 => { Name => 'DataOffset', Unknown => 1 }, … … 115 116 GROUPS => { 1 => 'Real-MDPR', 2 => 'Video' }, 116 117 PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData, 118 VARS => { ID_LABEL => 'Sequence' }, 117 119 FORMAT => 'int32u', 118 120 PRIORITY => 0, # first stream takes priority 119 121 0 => { Name => 'StreamNumber', Format => 'int16u' }, 120 1 => { Name => 'StreamMaxBit Rate' },121 2 => { Name => 'StreamAvgBit Rate' },122 1 => { Name => 'StreamMaxBitrate', PrintConv => 'ConvertBitrate($val)' }, 123 2 => { Name => 'StreamAvgBitrate', PrintConv => 'ConvertBitrate($val)' }, 122 124 3 => { Name => 'StreamMaxPacketSize' }, 123 125 4 => { Name => 'StreamAvgPacketSize' }, 124 126 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)' }, 127 129 8 => { Name => 'StreamNameLen', Format => 'int8u', Unknown => 1 }, 128 130 9 => { Name => 'StreamName', Format => 'string[$val{8}]' }, … … 235 237 GROUPS => { 1 => 'Real-CONT', 2 => 'Video' }, 236 238 PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData, 239 VARS => { ID_LABEL => 'Sequence' }, 237 240 FORMAT => 'int16u', 238 241 0 => { Name => 'TitleLen', Unknown => 1 }, … … 268 271 GROUPS => { 1 => 'Real-RA3', 2 => 'Audio' }, 269 272 PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData, 273 VARS => { ID_LABEL => 'Sequence' }, 270 274 FORMAT => 'int8u', 271 275 0 => { Name => 'Channels', Format => 'int16u' }, … … 286 290 GROUPS => { 1 => 'Real-RA4', 2 => 'Audio' }, 287 291 PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData, 292 VARS => { ID_LABEL => 'Sequence' }, 288 293 FORMAT => 'int16u', 289 294 0 => { Name => 'FourCC1', Format => 'undef[4]', Unknown => 1 }, … … 323 328 GROUPS => { 1 => 'Real-RA5', 2 => 'Audio' }, 324 329 PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData, 330 VARS => { ID_LABEL => 'Sequence' }, 325 331 FORMAT => 'int16u', 326 332 0 => { Name => 'FourCC1', Format => 'undef[4]', Unknown => 1 }, … … 529 535 $type = ($ext and $ext eq 'RPM') ? 'RPM' : 'RAM'; 530 536 require Image::ExifTool::PostScript; 531 my $oldSep = Image::ExifTool::PostScript::SetInputRecordSeparator($raf);537 local $/ = Image::ExifTool::PostScript::GetInputRecordSeparator($raf) || "\n"; 532 538 $raf->Seek(0,0); 533 539 while ($raf->ReadLine($buff)) { … … 545 551 $exifTool->HandleTag($tagTablePtr, $tag, $buff); 546 552 } 547 $/ = $oldSep if $oldSep;548 553 return 1; 549 554 } … … 646 651 if (@mimeTypes == 1 and length $mimeTypes[0]) { 647 652 $exifTool->{VALUE}->{MIMEType} = $mimeTypes[0]; 648 $ verbose and $exifTool->VPrint(0, " MIMEType = $mimeTypes[0]\n");653 $exifTool->VPrint(0, " MIMEType = $mimeTypes[0]\n"); 649 654 } 650 655 # … … 708 713 =head1 AUTHOR 709 714 710 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)715 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 711 716 712 717 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Ricoh.pm
r16842 r24107 17 17 use Image::ExifTool::Exif; 18 18 19 $VERSION = '1. 05';19 $VERSION = '1.17'; 20 20 21 21 sub ProcessRicohText($$$); 22 22 sub ProcessRicohRMETA($$$); 23 24 # lens types for Ricoh GXR 25 my %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 ); 23 37 24 38 %Image::ExifTool::Ricoh::Main = ( … … 27 41 CHECK_PROC => \&Image::ExifTool::Exif::CheckExif, 28 42 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 ], 32 72 0x0e00 => { 33 73 Name => 'PrintIM', 34 74 Writable => 0, 35 75 Description => 'Print Image Matching', 36 SubDirectory => { 37 TagTable => 'Image::ExifTool::PrintIM::Main', 38 }, 76 SubDirectory => { TagTable => 'Image::ExifTool::PrintIM::Main' }, 39 77 }, 40 78 0x1001 => { 41 79 Name => 'ImageInfo', 42 SubDirectory => { 43 TagTable => 'Image::ExifTool::Ricoh::ImageInfo', 44 }, 80 SubDirectory => { TagTable => 'Image::ExifTool::Ricoh::ImageInfo' }, 45 81 }, 46 82 0x1003 => { … … 56 92 { 57 93 Name => 'RicohSubdir', 58 Condition => '$self->{ CameraModel} !~ /^Caplio RR1\b/',94 Condition => '$self->{Model} !~ /^Caplio RR1\b/', 59 95 SubDirectory => { 60 96 Validate => '$val =~ /^\[Ricoh Camera Info\]/', … … 119 155 DataTag => 'PreviewImage', 120 156 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 }, 121 163 }, 122 164 30 => { … … 126 168 DataTag => 'PreviewImage', 127 169 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 }, 128 175 }, 129 176 32 => { … … 155 202 3 => 'Tungsten', 156 203 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) 159 207 }, 160 208 }, … … 169 217 7 => 800, 170 218 8 => 1600, 219 9 => 'Auto', #PH (? CX3) 171 220 }, 172 221 }, … … 177 226 1 => 'Normal', 178 227 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) 184 237 # NOTE: this subdir is not currently writable because the offsets would require 185 238 # special code to handle the funny start location and base offset … … 188 241 WRITE_PROC => \&Image::ExifTool::Exif::WriteExif, 189 242 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 }, 193 400 ); 194 401 … … 198 405 PROCESS_PROC => \&ProcessRicohText, 199 406 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 }, 207 421 Rg => 'RedGain', 208 422 Gg => 'GreenGain', … … 259 473 ); 260 474 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 517 Image::ExifTool::AddCompositeTags('Image::ExifTool::Ricoh'); 518 519 261 520 #------------------------------------------------------------------------------ 262 521 # Process Ricoh text-based maker notes … … 281 540 return 0; 282 541 } 283 my $pos = 0;284 542 while ($data =~ m/([A-Z][a-z]{1,2})([0-9A-F]+);/sg) { 285 543 my $tag = $1; … … 419 677 =head1 AUTHOR 420 678 421 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)679 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 422 680 423 681 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sanyo.pm
r16842 r24107 15 15 use Image::ExifTool::Exif; 16 16 17 $VERSION = '1.1 0';17 $VERSION = '1.14'; 18 18 19 19 my %offOn = ( … … 36 36 Writable => 'undef', 37 37 WriteCheck => '$self->CheckImage(\$val)', 38 ValueConv => '$self->ValidateImage(\$val,$tag)', 39 ValueConvInv => '$val', 38 RawConv => '$self->ValidateImage(\$val,$tag)', 40 39 }, 41 40 0x0200 => { … … 57 56 0x0006 => 'Normal/Very High', 58 57 0x0007 => 'Normal/Super High', 58 # have seen 0x11 with HD2000 in '8M-H JPEG' mode - PH 59 59 0x0100 => 'Fine/Very Low', 60 60 0x0101 => 'Fine/Low', … … 122 122 PrintConv => \%offOn, 123 123 }, 124 # 0x0215 - Flash? 124 125 0x0216 => { 125 126 Name => 'VoiceMemo', … … 176 177 }, 177 178 }, 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 ], 182 189 0x0224 => { 183 190 Name => 'SequenceShotInterval', 184 191 Writable => 'int16u', 185 192 PrintConv => { 186 0 => '5 frames/s ec',187 1 => '10 frames/s ec',188 2 => '15 frames/s ec',189 3 => '20 frames/s ec',193 0 => '5 frames/s', 194 1 => '10 frames/s', 195 2 => '15 frames/s', 196 3 => '20 frames/s', 190 197 }, 191 198 }, … … 215 222 ); 216 223 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 217 244 # tags in Sanyo MOV videos (PH - observations from an E6 sample) 218 # ( note: very similar to information in Nikon/Pentaxvideos)245 # (similar information in Kodak,Minolta,Nikon,Olympus,Pentax and Sanyo videos) 219 246 %Image::ExifTool::Sanyo::MOV = ( 220 247 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 221 248 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.', 226 250 0x00 => { 227 251 Name => 'Make', 228 Format => 'string[5]', 229 PrintConv => 'ucfirst(lc($val))', 252 Format => 'string[24]', 230 253 }, 231 254 0x18 => { … … 234 257 Format => 'string[8]', 235 258 }, 259 # (01 00 at offset 0x20) 236 260 0x26 => { 237 261 Name => 'ExposureTime', … … 243 267 Name => 'FNumber', 244 268 Format => 'int32u', 245 ValueConv => '$val * 0.1',269 ValueConv => '$val / 10', 246 270 PrintConv => 'sprintf("%.1f",$val)', 247 271 }, … … 249 273 Name => 'ExposureCompensation', 250 274 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)', 253 277 }, 254 278 0x44 => { … … 266 290 0x48 => { 267 291 Name => 'FocalLength', 268 Writable=> 'int32u',269 ValueConv => '$val * 0.1',270 PrintConv => 'sprintf("%.1f mm",$val)',292 Format => 'int32u', 293 ValueConv => '$val / 10', 294 PrintConv => 'sprintf("%.1f mm",$val)', 271 295 }, 272 296 ); 273 297 274 298 # tags in Sanyo MP4 videos (PH - from C4, C5 and HD1A samples) 299 # --> very similar to Samsung MP4 information 275 300 # (there is still a lot more information here that could be decoded!) 276 301 %Image::ExifTool::Sanyo::MP4 = ( 277 302 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 278 303 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.', 280 305 0x00 => { 281 306 Name => 'Make', … … 288 313 Format => 'string[8]', 289 314 }, 315 # (01 00 at offset 0x28) 290 316 # (0x2e has values 0x31, 0x33 and 0x3c in my samples, but 291 317 # some of the shutter speeds should be around 1/500 or so) 292 318 0x32 => { 293 319 Name => 'FNumber', 294 Format => 'int32u', 295 ValueConv => '$val / 10', 320 Format => 'rational64u', 296 321 PrintConv => 'sprintf("%.1f",$val)', 322 }, 323 0x3a => { # (NC) 324 Name => 'ExposureCompensation', 325 Format => 'rational64s', 326 PrintConv => '$val ? sprintf("%+.1f", $val) : 0', 297 327 }, 298 328 0x6a => { … … 300 330 Format => 'int32u', 301 331 }, 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', 319 376 }, 320 377 ); … … 357 414 =head1 AUTHOR 358 415 359 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)416 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 360 417 361 418 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Shift.pl
r16842 r24107 15 15 #------------------------------------------------------------------------------ 16 16 # apply shift to value in new value hash 17 # Inputs: 0) shift type, 1) shift string, 2) value to shift, 3) new value hash ref17 # Inputs: 0) shift type, 1) shift string, 2) raw date/time value, 3) new value hash ref 18 18 # Returns: error string or undef on success and updates value in new value hash 19 19 sub ApplyShift($$$;$) 20 20 { 21 my ($func, $shift, $val, $n ewValueHash) = @_;21 my ($func, $shift, $val, $nvHash) = @_; 22 22 23 23 # get shift direction from first character in shift string … … 25 25 my $pre = $1; 26 26 my $dir = ($pre eq '+') ? 1 : -1; 27 my $tagInfo = $$n ewValueHash{TagInfo};27 my $tagInfo = $$nvHash{TagInfo}; 28 28 my $tag = $$tagInfo{Name}; 29 my $self = $$n ewValueHash{Self}; # (used in eval)29 my $self = $$nvHash{Self}; # (used in eval) 30 30 my $shiftOffset; 31 if ($$n ewValueHash{ShiftOffset}) {32 $shiftOffset = $$n ewValueHash{ShiftOffset};31 if ($$nvHash{ShiftOffset}) { 32 $shiftOffset = $$nvHash{ShiftOffset}; 33 33 } else { 34 $shiftOffset = $$n ewValueHash{ShiftOffset} = { };34 $shiftOffset = $$nvHash{ShiftOffset} = { }; 35 35 } 36 36 … … 63 63 } 64 64 # update value in new value hash 65 $n ewValueHash->{Value} = [ $val ];65 $nvHash->{Value} = [ $val ]; 66 66 return undef; # success 67 67 } … … 105 105 106 106 #------------------------------------------------------------------------------ 107 # split times into corresponding components: YYYY MM DD hh mm sstzh tzm107 # split times into corresponding components: YYYY mm dd HH MM SS tzh tzm 108 108 # Inputs: 0) date/time or shift string 1) reference to list for returned components 109 109 # 2) optional reference to list of time components (if shift string) … … 152 152 # this is a time (can't come after timezone) 153 153 (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; 155 155 $v[3] = shift(@vals); # take hour first if only one specified 156 156 $v[4] = shift(@vals) || 0; … … 175 175 # 2) shift direction, 3) reference to output list of shifted components 176 176 # 4) number of decimal points in seconds 177 # 5) reference to return time difference due to rounding 177 178 # Returns: error string or undef on success 178 sub ShiftComponents($$$$$ )179 sub ShiftComponents($$$$$;$) 179 180 { 180 my ($time, $shift, $dir, $toTime, $dec ) = @_;181 my ($time, $shift, $dir, $toTime, $dec, $rndPt) = @_; 181 182 # min/max for Y, M, D, h, m, s 182 183 my @min = ( 0, 1, 1, 0, 0, 0); … … 203 204 if (defined $sec and $sec != int($sec)) { 204 205 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; 206 209 } 207 210 # … … 303 306 $time[6] = $time[7] = 0 if $val =~ s/Z$/\+00:00/; 304 307 } 305 my $err = ShiftComponents(\@time, \@shift, $dir, \@toTime, $dec); 308 my $rndDiff; 309 my $err = ShiftComponents(\@time, \@shift, $dir, \@toTime, $dec, \$rndDiff); 306 310 $err and return $err; 307 311 # … … 324 328 # handle fractional seconds separately 325 329 $diff = $tm2[0] - int($tm2[0]) - ($tm1[0] - int($tm1[0])); 330 $diff += $rndDiff if defined $rndDiff; # un-do rounding 326 331 $tm1[0] = int($tm1[0]); 327 332 $tm2[0] = int($tm2[0]); … … 376 381 $tm += $$shiftOffset{$mode}; # apply the shift 377 382 $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 380 384 $frac = $tm - int($tm); 381 385 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; 386 389 } 387 390 @tm = gmtime($tm); … … 491 494 '2:0' - shift 2 hours (time, date/time), or 2 months (date) 492 495 '5:0:0' - shift 5 hours (time, date/time), or 5 years (date) 493 '0:0:1' - shift 1 s ec(time, date/time), or 1 day (date)496 '0:0:1' - shift 1 s (time, date/time), or 1 day (date) 494 497 495 498 If two arguments are given, the date shift is first, followed by the time … … 561 564 philosophy). 562 565 566 =head1 BUGS 567 568 This feature uses the standard time library functions, which typically are 569 limited to dates in the range 1970 to 2038. 570 563 571 =head1 AUTHOR 564 572 565 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)573 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 566 574 567 575 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Shortcuts.pm
r16842 r24107 16 16 use vars qw($VERSION); 17 17 18 $VERSION = '1. 16';18 $VERSION = '1.41'; 19 19 20 20 # this is a special table used to define command-line shortcuts … … 56 56 'ImageSize', 57 57 'Quality', 58 'Flash On',58 'Flash', 59 59 'FlashType', 60 60 'ConditionalFEC', … … 67 67 'Saturation', 68 68 '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', 105 71 'FileSize', 106 72 'FileNumber', … … 147 113 'MakerNoteCasio2', 148 114 'MakerNoteFujiFilm', 115 'MakerNoteGE', 116 'MakerNoteGE2', 149 117 'MakerNoteHP', 150 118 'MakerNoteHP2', 151 119 'MakerNoteHP4', 152 120 'MakerNoteHP6', 121 'MakerNoteISL', 153 122 'MakerNoteJVC', 154 123 'MakerNoteJVCText', … … 162 131 'MakerNoteKodak6b', 163 132 'MakerNoteKodak7', 164 'MakerNoteKodakIFD', 133 'MakerNoteKodak8a', 134 'MakerNoteKodak8b', 135 'MakerNoteKodak9', 136 'MakerNoteKodak10', 165 137 'MakerNoteKodakUnknown', 166 138 'MakerNoteKyocera', … … 174 146 'MakerNoteOlympus2', 175 147 'MakerNoteLeica', 148 'MakerNoteLeica2', 149 'MakerNoteLeica3', 150 'MakerNoteLeica4', 151 'MakerNoteLeica5', 152 'MakerNoteLeica6', 176 153 'MakerNotePanasonic', 177 154 'MakerNotePanasonic2', … … 180 157 'MakerNotePentax3', 181 158 'MakerNotePentax4', 159 'MakerNotePentax5', 160 'MakerNotePhaseOne', 161 'MakerNoteReconyx', 182 162 'MakerNoteRicoh', 183 163 'MakerNoteRicohText', 164 'MakerNoteSamsung1a', 165 'MakerNoteSamsung1b', 166 'MakerNoteSamsung2', 184 167 'MakerNoteSanyo', 185 168 'MakerNoteSanyoC4', … … 187 170 'MakerNoteSigma', 188 171 'MakerNoteSony', 172 'MakerNoteSony2', 173 'MakerNoteSony3', 174 'MakerNoteSony4', 175 'MakerNoteSonyEricsson', 189 176 'MakerNoteSonySRF', 190 'MakerNote SonySR2',177 'MakerNoteUnknownText', 191 178 'MakerNoteUnknown', 192 179 ], 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 ], 193 215 ); 194 216 217 #------------------------------------------------------------------------------ 195 218 # load user-defined shortcuts if available 196 if (defined %Image::ExifTool::Shortcuts::UserDefined) { 219 # Inputs: reference to user-defined shortcut hash 220 sub LoadShortcuts($) 221 { 222 my $shortcuts = shift; 197 223 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}; 200 226 # also allow simple aliases 201 227 $val = [ $val ] unless ref $val eq 'ARRAY'; … … 204 230 } 205 231 } 232 # (for backward compatibility, renamed in ExifTool 7.75) 233 if (%Image::ExifTool::Shortcuts::UserDefined) { 234 LoadShortcuts(\%Image::ExifTool::Shortcuts::UserDefined); 235 } 236 if (%Image::ExifTool::UserDefined::Shortcuts) { 237 LoadShortcuts(\%Image::ExifTool::UserDefined::Shortcuts); 238 } 206 239 207 240 … … 226 259 file in their home directory (or the directory specified by the 227 260 EXIFTOOL_HOME environment variable). The shortcuts are defined in a hash 228 called %Image::ExifTool:: Shortcuts::UserDefined. The keys of the hash are261 called %Image::ExifTool::UserDefined::Shortcuts. The keys of the hash are 229 262 the shortcut names, and the elements are either tag names or references to 230 263 lists of tag names. … … 232 265 An example shortcut definition in .ExifTool_config: 233 266 234 %Image::ExifTool:: Shortcuts::UserDefined= (267 %Image::ExifTool::UserDefined::Shortcuts = ( 235 268 MyShortcut => ['createdate','exif:exposuretime','aperture'], 236 269 MyAlias => 'FocalLengthIn35mmFormat', … … 243 276 =head1 AUTHOR 244 277 245 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)278 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 246 279 247 280 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sigma.pm
r16842 r24107 6 6 # Revisions: 04/06/2004 - P. Harvey Created 7 7 # 02/20/2007 - PH added SD14 tags 8 # 24/06/2010 - PH decode some SD15 tags 8 9 # 9 10 # Reference: http://www.x3f.info/technotes/FileDocs/MakerNoteDoc.html … … 16 17 use Image::ExifTool::Exif; 17 18 18 $VERSION = '1.0 4';19 $VERSION = '1.09'; 19 20 20 21 %Image::ExifTool::Sigma::Main = ( … … 46 47 }, 47 48 }, 48 0x000a => 'Lens ',49 0x000a => 'LensFocalRange', 49 50 0x000b => 'ColorSpace', 51 # SIGMA PhotoPro writes these tags as strings, but some cameras (at least) write them as rational 50 52 0x000c => [ 51 53 { 52 54 Name => 'ExposureCompensation', 53 Condition => '$ $self{CameraModel} !~ /SD14$/',55 Condition => '$format eq "string"', 54 56 ValueConv => '$val =~ s/Expo:\s*//, $val', 55 57 ValueConvInv => 'IsFloat($val) ? sprintf("Expo:%+.1f",$val) : undef', 56 58 }, 57 59 { #PH 58 Name => ' UnknownCompensation',60 Name => 'ExposureAdjust', 59 61 Writable => 'rational64s', 60 62 Unknown => 1, … … 64 66 { 65 67 Name => 'Contrast', 66 Condition => '$ $self{CameraModel} !~ /SD14$/',68 Condition => '$format eq "string"', 67 69 ValueConv => '$val =~ s/Cont:\s*//, $val', 68 70 ValueConvInv => 'IsFloat($val) ? sprintf("Cont:%+.1f",$val) : undef', … … 76 78 { 77 79 Name => 'Shadow', 78 Condition => '$ $self{CameraModel} !~ /SD14$/',80 Condition => '$format eq "string"', 79 81 ValueConv => '$val =~ s/Shad:\s*//, $val', 80 82 ValueConvInv => 'IsFloat($val) ? sprintf("Shad:%+.1f",$val) : undef', … … 88 90 { 89 91 Name => 'Highlight', 90 Condition => '$ $self{CameraModel} !~ /SD14$/',92 Condition => '$format eq "string"', 91 93 ValueConv => '$val =~ s/High:\s*//, $val', 92 94 ValueConvInv => 'IsFloat($val) ? sprintf("High:%+.1f",$val) : undef', … … 100 102 { 101 103 Name => 'Saturation', 102 Condition => '$ $self{CameraModel} !~ /SD14$/',104 Condition => '$format eq "string"', 103 105 ValueConv => '$val =~ s/Satu:\s*//, $val', 104 106 ValueConvInv => 'IsFloat($val) ? sprintf("Satu:%+.1f",$val) : undef', … … 112 114 { 113 115 Name => 'Sharpness', 114 Condition => '$ $self{CameraModel} !~ /SD14$/',116 Condition => '$format eq "string"', 115 117 ValueConv => '$val =~ s/Shar:\s*//, $val', 116 118 ValueConvInv => 'IsFloat($val) ? sprintf("Shar:%+.1f",$val) : undef', … … 124 126 { 125 127 Name => 'X3FillLight', 126 Condition => '$ $self{CameraModel} !~ /SD14$/',128 Condition => '$format eq "string"', 127 129 ValueConv => '$val =~ s/Fill:\s*//, $val', 128 130 ValueConvInv => 'IsFloat($val) ? sprintf("Fill:%+.1f",$val) : undef', … … 136 138 { 137 139 Name => 'ColorAdjustment', 138 Condition => '$ $self{CameraModel} !~ /SD14$/',140 Condition => '$format eq "string"', 139 141 ValueConv => '$val =~ s/CC:\s*//, $val', 140 142 ValueConvInv => 'IsInt($val) ? "CC:$val" : undef', … … 155 157 0x0018 => 'Software', 156 158 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 }, 160 193 0x001d => { #PH 161 194 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 }, 166 202 # 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?) 175 227 # 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 }, 177 232 0x0031 => { #PH 178 233 Name => 'FNumber', … … 185 240 Writable => 'rational64u', 186 241 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 191 257 0x0035 => { #PH 192 258 Name => 'ExposureCompensation', 193 259 Writable => 'rational64s', 260 # add a '+' sign to positive values 261 PrintConv => '$val and $val =~ s/^(\d)/\+$1/; $val', 262 PrintConvInv => '$val', 194 263 }, 195 264 # 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 198 273 Name => 'FlashExposureComp', 199 274 Writable => 'rational64s', … … 204 279 }, 205 280 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 }, 206 285 ); 207 286 … … 225 304 =head1 AUTHOR 226 305 227 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)306 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 228 307 229 308 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/SigmaRaw.pm
r16842 r24107 4 4 # Description: Read Sigma/Foveon RAW (X3F) meta information 5 5 # 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 7 8 # 8 9 # References: 1) http://www.x3f.info/technotes/FileDocs/X3F_Format.pdf … … 15 16 use Image::ExifTool qw(:DataAccess :Utils); 16 17 17 $VERSION = '1. 03';18 $VERSION = '1.14'; 18 19 19 20 sub ProcessX3FHeader($$$); … … 21 22 sub ProcessX3FProperties($$$); 22 23 24 # sigma LensType lookup (ref PH) 25 my %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 23 45 # main X3F sections (plus header stuff) 24 46 %Image::ExifTool::SigmaRaw::Main = ( 25 47 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 }, 27 53 Header => { 28 54 SubDirectory => { TagTable => 'Image::ExifTool::SigmaRaw::Header' }, … … 39 65 Binary => 1, 40 66 }, 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 ] 45 78 ); 46 79 … … 53 86 ValueConv => '($val >> 16) . "." . ($val & 0xffff)', 54 87 }, 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 }, 55 99 7 => 'ImageWidth', 56 100 8 => 'ImageHeight', … … 60 104 Format => 'string[32]', 61 105 }, 106 18 => { #PH (DP2, FileVersion 2.3) 107 Name => 'SceneCaptureType', 108 Format => 'string[32]', 109 }, 62 110 ); 63 111 … … 67 115 NOTES => 'Extended header data found in version 2.1 and 2.2 files', 68 116 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)' }, 79 127 ); 80 128 … … 106 154 CAMNAME => 'CameraName', 107 155 CAMSERIAL => 'SerialNumber', 156 CM_DESC => 'SceneCaptureType', #PH (DP2) 108 157 COLORSPACE => 'ColorSpace', # observed: sRGB 109 158 DRIVE => { … … 112 161 SINGLE => 'Single Shot', 113 162 MULTI => 'Multi Shot', 114 '2S' => '2 -secTimer',115 '10S' => '10 -secTimer',163 '2S' => '2 s Timer', 164 '10S' => '10 s Timer', 116 165 UP => 'Mirror Up', 117 166 AB => 'Auto Bracket', … … 123 172 Name => 'ExposureCompensation', 124 173 Groups => { 2 => 'Image' }, 125 PrintConv => 'Image::ExifTool::Exif:: ConvertFraction($val)',174 PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)', 126 175 }, 127 176 EXPNET => { 128 177 Name => 'NetExposureCompensation', 129 178 Groups => { 2 => 'Image' }, 130 PrintConv => 'Image::ExifTool::Exif:: ConvertFraction($val)',179 PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)', 131 180 }, 132 181 EXPTIME => { … … 147 196 FLENGTH => { 148 197 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 }, 152 204 FOCUS => { 153 205 Name => 'Focus', … … 159 211 }, 160 212 IMAGERBOARDID => 'ImagerBoardID', 161 IMAGERTEMP => 'SensorTemperature', 213 IMAGERTEMP => { 214 Name => 'SensorTemperature', 215 PrintConv => '"$val C"', 216 }, 217 IMAGEBOARDID=> 'ImageBoardID', #PH (DP2) 162 218 ISO => 'ISO', 163 219 LENSARANGE => 'LensApertureRange', 164 220 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 }, 166 230 PMODE => { 167 231 Name => 'ExposureProgram', … … 210 274 last unless $$chars[$i]; 211 275 } 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'); 215 278 } 216 279 … … 222 285 { 223 286 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 287 my $dataPt = $$dirInfo{DataPt}; 288 my $hdrLen = $$dirInfo{DirLen}; 224 289 my $verbose = $exifTool->Options('Verbose'); 225 290 … … 228 293 229 294 # 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 } 232 305 $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); 235 307 my $i; 236 308 my $unused = 0; … … 250 322 } 251 323 $exifTool->HandleTag($tagTablePtr, $vals[$i], $val, 252 Index => $i,324 Index => $i, 253 325 DataPt => $dataPt, 254 Start => 104+ $i * 4,255 Size => 4,326 Start => $hdrLen + 32 + $i * 4, 327 Size => 4, 256 328 ); 257 329 } … … 305 377 Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo); 306 378 } 307 379 308 380 $exifTool->HandleTag($tagTablePtr, $tag, $val, 309 381 Index => $index, … … 314 386 } 315 387 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 395 sub 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; 316 491 } 317 492 … … 329 504 330 505 # parse the X3F directory structure 331 my ($buff, $ver, $entries, $index );506 my ($buff, $ver, $entries, $index, $dir); 332 507 $raf->Read($buff, 12) == 12 or return 'Truncated X3F image'; 333 508 $buff =~ /^SECd/ or return 'Bad section header'; 334 509 ($ver, $entries) = unpack('x4V2', $buff); 335 510 $verbose and $exifTool->VerboseDir('X3F Subsection', $entries); 336 my $dir;337 511 $raf->Read($dir, $entries * 12) == $entries * 12 or return 'Truncated X3F directory'; 338 512 for ($index=0; $index<$entries; ++$index) { … … 344 518 if ($verbose > 2) { 345 519 $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); 353 522 } 354 523 } … … 358 527 # check image header to see if this is a JPEG preview image 359 528 $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; 362 538 $len -= 28; 363 539 } … … 369 545 $exifTool->ProcessDirectory(\%dirInfo, $subTable); 370 546 } 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 } 371 558 $exifTool->FoundTag($tagInfo, $buff); 372 559 } … … 376 563 377 564 #------------------------------------------------------------------------------ 378 # Extractinformation from a Sigma raw (X3F) image565 # Read/write information from a Sigma raw (X3F) image 379 566 # 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 381 568 sub ProcessX3F($$) 382 569 { 383 570 my ($exifTool, $dirInfo) = @_; 571 my $outfile = $$dirInfo{OutFile}; 384 572 my $raf = $$dirInfo{RAF}; 385 my $buff; 573 my $warn = $outfile ? \&Image::ExifTool::Error : \&Image::ExifTool::Warn; 574 my ($buff, $err); 386 575 387 576 return 0 unless $raf->Read($buff, 40) == 40; … … 395 584 $ver = ($ver >> 16) . '.' . ($ver & 0xffff); 396 585 if ($ver >= 3) { 397 $exifTool->Warn("Can't read version $ver X3F image");586 &$warn($exifTool, "Can't read version $ver X3F image"); 398 587 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 401 593 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) 402 596 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'); 405 599 return 1; 406 600 } 407 601 $buff .= $buf2; 408 602 } 603 # extract ImageWidth for later 604 $$exifTool{ImageWidth} = Get32u(\$buff, 28); 409 605 # process header information 410 606 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); 413 620 my %dirInfo = ( 414 DataPt => \$buff,415 DirStart => 0,416 DirLen => length($buff),417 );418 $exifTool->ProcessDirectory(\%dirInfo, $subdir);419 # read the directory pointer420 $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 = (427 621 RAF => $raf, 428 622 DirStart => $offset, 429 623 ); 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); 433 633 return 1; 434 634 } … … 453 653 =head1 AUTHOR 454 654 455 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)655 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 456 656 457 657 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sony.pm
r16842 r24107 7 7 # 8 8 # 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) 10 10 # 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 11 20 #------------------------------------------------------------------------------ 12 21 … … 19 28 use Image::ExifTool::Minolta; 20 29 21 $VERSION = '1. 10';30 $VERSION = '1.50'; 22 31 23 32 sub ProcessSRF($$$); 24 33 sub ProcessSR2($$$); 25 26 my %sonyLensIDs; # filled in based on Minolta LensID's 34 sub WriteSR2($$$); 35 36 my %sonyLensTypes; # filled in based on Minolta LensType's 37 38 # ExposureProgram values (ref PH, mainly decoded from A200) 39 my %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 56 my %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 ); 27 63 28 64 %Image::ExifTool::Sony::Main = ( … … 30 66 CHECK_PROC => \&Image::ExifTool::Exif::CheckExif, 31 67 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 }, 32 146 0x0e00 => { 33 147 Name => 'PrintIM', … … 37 151 }, 38 152 }, 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 }, 40 337 0xb021 => { #2 41 338 Name => 'ColorTemperature', 339 Writable => 'int32u', 42 340 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) 45 350 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, 56 353 }, 57 354 0xb024 => { #PH (A100) 58 355 Name => 'ZoneMatching', 356 Writable => 'int32u', 59 357 PrintConv => { 60 358 0 => 'ISO Setting Used', … … 65 363 0xb025 => { #PH (A100) 66 364 Name => 'DynamicRangeOptimizer', 365 Writable => 'int32u', 67 366 PrintConv => { 68 367 0 => 'Off', 69 368 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', 71 381 }, 72 382 }, 73 383 0xb026 => { #PH (A100) 74 384 Name => 'ImageStabilization', 385 Writable => 'int32u', 75 386 PrintConv => { 0 => 'Off', 1 => 'On' }, 76 387 }, 77 388 0xb027 => { #2 78 Name => 'LensID', 79 PrintConv => \%sonyLensIDs, 389 Name => 'LensType', 390 Writable => 'int32u', 391 SeparateTable => 1, 392 PrintConv => \%sonyLensTypes, 80 393 }, 81 394 0xb028 => { #2 82 395 # (used by the DSLR-A100) 83 396 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"', 84 400 Flags => 'SubIFD', 85 401 SubDirectory => { … … 88 404 }, 89 405 }, 90 0xb029 => { #2 406 0xb029 => { #2 (set by creative style menu) 91 407 Name => 'ColorMode', 92 408 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', 103 429 }, 104 430 0xb040 => { #2 105 431 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 }, 107 440 }, 108 441 0xb041 => { #2 109 442 Name => 'ExposureMode', 443 Writable => 'int16u', 444 RawConv => '$val == 65535 ? undef : $val', 110 445 PrintConv => { 111 446 0 => 'Auto', 447 1 => 'Portrait', #PH (HX1) 448 2 => 'Beach', #9 449 4 => 'Snow', #9 112 450 5 => 'Landscape', 113 451 6 => 'Program', 114 452 7 => 'Aperture Priority', 115 453 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) 117 460 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) 118 508 }, 119 509 }, 120 510 0xb047 => { #2 121 511 Name => 'Quality', 512 Writable => 'int16u', 513 RawConv => '$val == 65535 ? undef : $val', 122 514 PrintConv => { 123 515 0 => 'Normal', 124 516 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', 125 563 }, 126 564 }, 127 565 0xb04e => { #2 128 566 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', 129 834 PrintConv => { 0 => 'Off', 1 => 'On' }, 130 835 }, 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 }, 131 911 ); 132 912 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) 134 1253 %Image::ExifTool::Sony::SRF = ( 135 1254 PROCESS_PROC => \&ProcessSRF, 136 1255 GROUPS => { 0 => 'MakerNotes', 1 => 'SRF#', 2 => 'Camera' }, 137 1256 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 143 1265 0 => { 144 Name => 'SRF2 _Key',1266 Name => 'SRF2Key', 145 1267 Notes => 'key to decrypt maker notes from the start of SRF2', 146 RawConv => '$self->{SRF2 _Key} = $val',1268 RawConv => '$self->{SRF2Key} = $val', 147 1269 }, 148 1270 1 => { … … 151 1273 RawConv => '$self->{SRFDataKey} = $val', 152 1274 }, 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 153 1289 ); 154 1290 … … 156 1292 %Image::ExifTool::Sony::SR2Private = ( 157 1293 PROCESS_PROC => \&ProcessSR2, 1294 WRITE_PROC => \&WriteSR2, 158 1295 GROUPS => { 0 => 'MakerNotes', 1 => 'SR2', 2 => 'Camera' }, 159 1296 NOTES => q{ 160 1297 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. 162 1300 }, 163 1301 0x7200 => { … … 165 1303 # (adjusting offset messes up calculations for AdobeSR2 in DNG images) 166 1304 # 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', 169 1309 }, 170 1310 0x7201 => { 171 1311 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', 174 1316 }, 175 1317 0x7221 => { … … 177 1319 Format => 'int32u', 178 1320 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 }, 180 1356 }, 181 1357 ); 182 1358 183 1359 %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 185 1364 NOTES => 'Tags in the encrypted SR2SubIFD', 186 1365 0x7303 => 'WB_GRBGLevels', #1 187 1366 0x74c0 => { #PH 188 1367 Name => 'SR2DataIFD', 1368 Groups => { 1 => 'SR2DataIFD' }, # (needed to set SubIFD DirName) 189 1369 Flags => 'SubIFD', 190 1370 SubDirectory => { 191 1371 TagTable => 'Image::ExifTool::Sony::SR2DataIFD', 192 1372 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 196 1377 0x74a0 => 'MaxApertureAtMaxFocal', #PH 197 1378 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 198 1385 ); 199 1386 200 1387 %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 }, 203 1397 ); 204 1398 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 206 1499 { 1500 my $minoltaTypes = \%Image::ExifTool::Minolta::minoltaLensTypes; 1501 %sonyLensTypes = %$minoltaTypes; 1502 my $notes = $$minoltaTypes{Notes}; 1503 delete $$minoltaTypes{Notes}; 207 1504 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; 212 1525 } 1526 $$minoltaTypes{Notes} = $sonyLensTypes{Notes} = $notes; 213 1527 } 214 1528 215 1529 #------------------------------------------------------------------------------ 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 1533 sub 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) 217 1558 # Inputs: 0) data reference, 1) start offset, 2) data length, 3) decryption key 218 1559 # Returns: nothing (original data buffer is updated with decrypted data) 1560 # Notes: data length should be a multiple of 4 219 1561 sub Decrypt($$$$) 220 1562 { 221 1563 my ($dataPt, $start, $len, $key) = @_; 222 1564 my ($i, $j, @pad); 223 my $words = $len / 4;1565 my $words = int ($len / 4); 224 1566 225 1567 for ($i=0; $i<4; ++$i) { … … 241 1583 242 1584 #------------------------------------------------------------------------------ 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 1588 sub 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) 1616 sub 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 #------------------------------------------------------------------------------ 243 1682 # 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 246 1684 # Returns: 1 on success 247 1685 sub ProcessSRF($$$) … … 249 1687 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 250 1688 my $dataPt = $$dirInfo{DataPt}; 251 my $dirLen = $$dirInfo{DirLen};252 1689 my $start = $$dirInfo{DirStart}; 253 1690 my $verbose = $exifTool->Options('Verbose'); … … 256 1693 my ($ifd, $success); 257 1694 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 } 258 1702 my $srf = $$dirInfo{DirName} = "SRF$ifd"; 259 my $srfTable = $tagTablePtr;260 # SRF6 uses standard EXIF tags261 $srfTable = GetTagTable('Image::ExifTool::Exif::Main') if $ifd == 6;262 1703 $exifTool->{SET_GROUP1} = $srf; 263 $success = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $ srfTable);1704 $success = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr); 264 1705 delete $exifTool->{SET_GROUP1}; 265 1706 last unless $success; … … 287 1728 } elsif ($ifd == 2) { 288 1729 # get the key to decrypt IFD2 289 $key = $exifTool->{SRF2 _Key};1730 $key = $exifTool->{SRF2Key}; 290 1731 $len = length($$dataPt) - $nextIFD; # decrypt rest of maker notes 291 1732 } else { … … 297 1738 # display decrypted data in verbose mode 298 1739 $exifTool->VerboseDir("Decrypted SRF$ifd", 0, $nextIFD + $len); 299 my %parms = (1740 $exifTool->VerboseDump($dataPt, 300 1741 Prefix => "$exifTool->{INDENT} ", 301 1742 Start => $nextIFD, 302 1743 DataPos => $$dirInfo{DataPos}, 303 Out => $exifTool->Options('TextOut'),304 1744 ); 305 $parms{MaxLen} = 96 unless $verbose > 3;306 Image::ExifTool::HexDump($dataPt, $len, %parms);307 1745 } 308 1746 } 309 1747 310 1748 #------------------------------------------------------------------------------ 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 1752 sub 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 315 1765 sub ProcessSR2($$$) 316 1766 { 317 1767 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 1768 my $raf = $$dirInfo{RAF}; 318 1769 my $dataPt = $$dirInfo{DataPt}; 319 1770 my $dataPos = $$dirInfo{DataPos}; 320 1771 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 } 322 1833 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; 326 1847 my $length = $exifTool->{SR2SubIFDLength}; 327 1848 my $key = $exifTool->{SR2SubIFDKey}; 328 my $raf = $$dirInfo{RAF}; 329 my $base = $$dirInfo{Base} || 0; 1849 my @subifdPos; 330 1850 if ($offset and $length and defined $key) { 331 1851 my $buff; … … 334 1854 $raf->Read($buff, $length) == $length) or 335 1855 # 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 337 1857 ($buff = substr($$dataPt, $offset - $dataPos, $length)))) 338 1858 { 339 1859 Decrypt(\$buff, 0, $length, $key); 340 1860 # display decrypted data in verbose mode 341 if ($verbose > 2 ) {1861 if ($verbose > 2 and not $outfile) { 342 1862 $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, 347 1875 ); 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; 350 1894 } 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);361 1895 362 1896 } else { … … 364 1898 } 365 1899 } 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; 370 1946 } 371 1947 … … 384 1960 =head1 DESCRIPTION 385 1961 386 This module contains definitions required by Image::ExifTool to 387 interpretSony maker notes EXIF meta information.1962 This module contains definitions required by Image::ExifTool to interpret 1963 Sony maker notes EXIF meta information. 388 1964 389 1965 =head1 NOTES 390 1966 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. 1967 Also see Minolta.pm since Sony DSLR models use structures originating from 1968 Minolta. 394 1969 395 1970 =head1 AUTHOR 396 1971 397 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1972 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 398 1973 399 1974 This library is free software; you can redistribute it and/or modify it … … 408 1983 =item L<http://homepage3.nifty.com/kamisaka/makernote/makernote_sony.htm> 409 1984 1985 =item L<http://www.klingebiel.com/tempest/hd/pmp.html> 1986 410 1987 =back 411 1988 412 1989 =head1 ACKNOWLEDGEMENTS 413 1990 414 Thanks to Thomas Bodenmann for providing information about the LensID's. 1991 Thanks to Thomas Bodenmann, Philippe Devaux, Jens Duttke, Marcus 1992 Holland-Moritz, Andrey Tverdokhleb, Rudiger Lange, Igal Milchtaich and 1993 Michael Reitinger for help decoding some tags. 415 1994 416 1995 =head1 SEE ALSO 417 1996 418 1997 L<Image::ExifTool::TagNames/Sony Tags>, 1998 L<Image::ExifTool::TagNames/Minolta Tags>, 419 1999 L<Image::ExifTool(3pm)|Image::ExifTool> 420 2000 -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/TagLookup.pm
r23771 r24107 17 17 use Image::ExifTool qw(:Utils); 18 18 19 $VERSION = '1.0 4';19 $VERSION = '1.07'; 20 20 @ISA = qw(Exporter); 21 21 @EXPORT_OK = qw(FindTagInfo TagExists); 22 23 sub AddTags($$); 24 sub AddFields($$$$$$;$$); 22 25 23 26 # … … 30 33 my @tableList = ( 31 34 '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', 33 41 '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', 35 58 'Image::ExifTool::Canon::CameraSettings', 36 59 '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', 40 68 'Image::ExifTool::Canon::ColorInfo', 41 'Image::ExifTool::Canon::C olorInfoD30',69 'Image::ExifTool::Canon::CropInfo', 42 70 'Image::ExifTool::Canon::FaceDetect1', 43 71 'Image::ExifTool::Canon::FaceDetect2', … … 45 73 'Image::ExifTool::Canon::Flags', 46 74 'Image::ExifTool::Canon::FocalLength', 75 'Image::ExifTool::Canon::LensInfo', 76 'Image::ExifTool::Canon::LightingOpt', 47 77 'Image::ExifTool::Canon::Main', 78 'Image::ExifTool::Canon::MeasuredColor', 48 79 'Image::ExifTool::Canon::ModifiedInfo', 80 'Image::ExifTool::Canon::MovieInfo', 49 81 'Image::ExifTool::Canon::MyColors', 82 'Image::ExifTool::Canon::PSInfo', 83 'Image::ExifTool::Canon::PSInfo2', 50 84 'Image::ExifTool::Canon::Panorama', 51 85 'Image::ExifTool::Canon::PreviewImageInfo', 52 86 'Image::ExifTool::Canon::Processing', 87 'Image::ExifTool::Canon::SerialInfo', 53 88 'Image::ExifTool::Canon::ShotInfo', 89 'Image::ExifTool::Canon::VignettingCorr', 90 'Image::ExifTool::Canon::VignettingCorr2', 54 91 'Image::ExifTool::CanonCustom::Functions10D', 55 92 'Image::ExifTool::CanonCustom::Functions1D', … … 71 108 'Image::ExifTool::CanonRaw::RawJpgInfo', 72 109 'Image::ExifTool::CanonRaw::TimeStamp', 110 'Image::ExifTool::CanonVRD::Main', 73 111 'Image::ExifTool::CanonVRD::Ver1', 74 112 'Image::ExifTool::CanonVRD::Ver2', 113 'Image::ExifTool::Casio::FaceInfo1', 114 'Image::ExifTool::Casio::FaceInfo2', 75 115 'Image::ExifTool::Casio::Main', 76 116 'Image::ExifTool::Casio::Type2', … … 82 122 'Image::ExifTool::FotoStation::SoftEdit', 83 123 'Image::ExifTool::FujiFilm::Main', 124 'Image::ExifTool::GE::Main', 84 125 'Image::ExifTool::GPS::Main', 85 126 'Image::ExifTool::IPTC::ApplicationRecord', … … 88 129 'Image::ExifTool::JFIF::Main', 89 130 'Image::ExifTool::Kodak::CameraInfo', 131 'Image::ExifTool::Kodak::IFD', 132 'Image::ExifTool::Kodak::KDC_IFD', 90 133 'Image::ExifTool::Kodak::Main', 134 'Image::ExifTool::Kodak::Meta', 91 135 'Image::ExifTool::Kodak::SubIFD0', 92 136 'Image::ExifTool::Kodak::SubIFD1', … … 94 138 'Image::ExifTool::Kodak::SubIFD3', 95 139 'Image::ExifTool::Kodak::SubIFD5', 140 'Image::ExifTool::Kodak::Type10', 96 141 'Image::ExifTool::Kodak::Type2', 97 142 'Image::ExifTool::Kodak::Type3', 98 143 'Image::ExifTool::Kodak::Type4', 99 144 'Image::ExifTool::Kodak::Type7', 145 'Image::ExifTool::Kodak::Type9', 100 146 'Image::ExifTool::MIE::Audio', 101 147 'Image::ExifTool::MIE::Camera', … … 113 159 'Image::ExifTool::MIE::UTM', 114 160 'Image::ExifTool::MIE::Video', 161 'Image::ExifTool::Microsoft::MP', 162 'Image::ExifTool::Microsoft::MP1', 163 'Image::ExifTool::Microsoft::Stitch', 164 'Image::ExifTool::Microsoft::XMP', 115 165 'Image::ExifTool::Minolta::CameraSettings', 116 166 'Image::ExifTool::Minolta::CameraSettings5D', … … 118 168 'Image::ExifTool::Minolta::CameraSettingsA100', 119 169 'Image::ExifTool::Minolta::Main', 170 'Image::ExifTool::Minolta::WBInfoA100', 120 171 'Image::ExifTool::MinoltaRaw::PRD', 121 172 'Image::ExifTool::MinoltaRaw::RIF', 122 173 'Image::ExifTool::MinoltaRaw::WBG', 123 174 'Image::ExifTool::Nikon::AFInfo', 175 'Image::ExifTool::Nikon::AFInfo2', 176 'Image::ExifTool::Nikon::AFTune', 177 'Image::ExifTool::Nikon::CaptureOutput', 124 178 'Image::ExifTool::Nikon::ColorBalance1', 125 179 'Image::ExifTool::Nikon::ColorBalance2', 126 180 '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', 127 189 'Image::ExifTool::Nikon::GEM', 190 'Image::ExifTool::Nikon::ISOInfo', 128 191 'Image::ExifTool::Nikon::LensData00', 192 'Image::ExifTool::Nikon::LensData01', 193 'Image::ExifTool::Nikon::LensData0204', 129 194 'Image::ExifTool::Nikon::Main', 130 195 'Image::ExifTool::Nikon::MultiExposure', 131 'Image::ExifTool::Nikon::PreviewImage', 196 'Image::ExifTool::Nikon::PictureControl', 197 'Image::ExifTool::Nikon::PreviewIFD', 132 198 'Image::ExifTool::Nikon::ROC', 133 199 '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', 134 214 'Image::ExifTool::Nikon::Type2', 215 'Image::ExifTool::Nikon::VRInfo', 216 'Image::ExifTool::Nikon::WorldTime', 135 217 'Image::ExifTool::NikonCapture::Brightness', 136 218 'Image::ExifTool::NikonCapture::ColorBoost', … … 138 220 'Image::ExifTool::NikonCapture::DLightingHQ', 139 221 'Image::ExifTool::NikonCapture::DLightingHS', 222 'Image::ExifTool::NikonCapture::Exposure', 223 'Image::ExifTool::NikonCapture::HighlightData', 140 224 'Image::ExifTool::NikonCapture::Main', 141 225 'Image::ExifTool::NikonCapture::NoiseReduction', 142 226 'Image::ExifTool::NikonCapture::PhotoEffects', 227 'Image::ExifTool::NikonCapture::PictureCtrl', 143 228 'Image::ExifTool::NikonCapture::RedEyeData', 144 229 'Image::ExifTool::NikonCapture::UnsharpData', 145 230 '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', 146 238 'Image::ExifTool::Olympus::CameraSettings', 147 239 'Image::ExifTool::Olympus::Equipment', … … 153 245 'Image::ExifTool::Olympus::RawDevelopment2', 154 246 'Image::ExifTool::Olympus::RawInfo', 247 'Image::ExifTool::PDF::Info', 155 248 'Image::ExifTool::PNG::Main', 156 249 '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', 157 258 'Image::ExifTool::Panasonic::Main', 158 'Image::ExifTool::Panasonic::Raw', 259 'Image::ExifTool::Panasonic::Subdir', 260 'Image::ExifTool::PanasonicRaw::Main', 159 261 'Image::ExifTool::Pentax::AEInfo', 160 262 'Image::ExifTool::Pentax::AFInfo', 263 'Image::ExifTool::Pentax::AWBInfo', 161 264 'Image::ExifTool::Pentax::BatteryInfo', 162 265 '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', 163 273 'Image::ExifTool::Pentax::FlashInfo', 274 'Image::ExifTool::Pentax::LensCorr', 275 'Image::ExifTool::Pentax::LensData', 164 276 'Image::ExifTool::Pentax::LensInfo', 277 'Image::ExifTool::Pentax::LensInfo2', 278 'Image::ExifTool::Pentax::LensInfo3', 279 'Image::ExifTool::Pentax::LensInfo4', 280 'Image::ExifTool::Pentax::LevelInfo', 165 281 'Image::ExifTool::Pentax::Main', 166 282 'Image::ExifTool::Pentax::SRInfo', 283 'Image::ExifTool::Pentax::ShotInfo', 284 'Image::ExifTool::Pentax::TempInfoK5', 285 'Image::ExifTool::Pentax::TimeInfo', 167 286 'Image::ExifTool::Pentax::Type2', 168 287 'Image::ExifTool::PhotoMechanic::SoftEdit', … … 172 291 'Image::ExifTool::Photoshop::Resolution', 173 292 'Image::ExifTool::PostScript::Main', 293 'Image::ExifTool::Reconyx::Main', 294 'Image::ExifTool::Ricoh::FaceInfo', 295 'Image::ExifTool::Ricoh::FirmwareInfo', 174 296 'Image::ExifTool::Ricoh::ImageInfo', 175 297 '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', 176 303 'Image::ExifTool::Sanyo::Main', 177 304 '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', 178 310 'Image::ExifTool::Sony::Main', 311 'Image::ExifTool::Sony::Panorama', 312 'Image::ExifTool::Sony::ShotInfo', 313 'Image::ExifTool::SonyIDC::Main', 314 'Image::ExifTool::XMP::Album', 179 315 'Image::ExifTool::XMP::DICOM', 180 316 'Image::ExifTool::XMP::Lightroom', 181 317 'Image::ExifTool::XMP::MediaPro', 182 'Image::ExifTool::XMP:: Microsoft',318 'Image::ExifTool::XMP::acdsee', 183 319 'Image::ExifTool::XMP::aux', 184 320 'Image::ExifTool::XMP::cc', 321 'Image::ExifTool::XMP::cell', 185 322 'Image::ExifTool::XMP::crs', 186 323 'Image::ExifTool::XMP::dc', 187 324 'Image::ExifTool::XMP::dex', 325 'Image::ExifTool::XMP::digiKam', 188 326 'Image::ExifTool::XMP::exif', 189 327 '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', 190 332 'Image::ExifTool::XMP::pdf', 191 333 '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', 192 340 'Image::ExifTool::XMP::tiff', 341 'Image::ExifTool::XMP::x', 193 342 'Image::ExifTool::XMP::xmp', 194 343 'Image::ExifTool::XMP::xmpBJ', 195 344 'Image::ExifTool::XMP::xmpDM', 196 345 'Image::ExifTool::XMP::xmpMM', 346 'Image::ExifTool::XMP::xmpNote', 197 347 'Image::ExifTool::XMP::xmpPLUS', 198 348 'Image::ExifTool::XMP::xmpRights', … … 202 352 # lookup for all writable tags 203 353 my %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 }, 1949 3517 ); 1950 3518 1951 3519 # lookup for non-writable tags to check if the name exists 1952 3520 my %tagExists = ( 3521 '_ac3' => 1, 3522 '_h264' => 1, 3523 '_stream' => 1, 3524 'a100dataoffset' => 1, 1953 3525 'abstract' => 1, 3526 'accessdate' => 1, 3527 'acdsee' => 1, 3528 'actualcompensation' => 1, 1954 3529 'adobe' => 1, 1955 3530 'adobe_cm' => 1, 1956 3531 'adobecmtype' => 1, 1957 3532 'adobecrw' => 1, 3533 'adobekoda' => 1, 3534 'adobeleaf' => 1, 1958 3535 'adobemrw' => 1, 3536 'adobepano' => 1, 1959 3537 'adobephotoshop' => 1, 1960 3538 'adoberaf' => 1, … … 1962 3540 'advancedcontentencryption' => 1, 1963 3541 'advancedmutualexcl' => 1, 3542 'adventrevision' => 1, 3543 'adventscale' => 1, 3544 'aeflags' => 1, 1964 3545 'aeinfo' => 1, 1965 'a faperture' => 1,3546 'aeunknown' => 1, 1966 3547 'afarea' => 1, 1967 'afareaheight' => 1,1968 3548 'afareaheights' => 1, 1969 'afareawidth' => 1,1970 3549 'afareawidths' => 1, 1971 3550 'afareaxpositions' => 1, … … 1973 3552 'afcp' => 1, 1974 3553 'afcp_iptc' => 1, 1975 'afimageheight' => 1,1976 'afimagewidth' => 1,1977 3554 'afinfo' => 1, 3555 'afinfo2' => 1, 3556 'afinfo2version' => 1, 1978 3557 'afinfocus' => 1, 1979 3558 'afinfosize' => 1, 3559 'afm' => 1, 3560 'afmicroadj' => 1, 1980 3561 'afpointsinfocus1d' => 1, 1981 3562 'afpointsselected' => 1, 3563 'aftune' => 1, 3564 'aimetadata' => 1, 3565 'aiprivatedata' => 1, 3566 'album2' => 1, 1982 3567 'albumartist' => 1, 1983 3568 'albumcoverurl' => 1, … … 1985 3570 'albumsortorder' => 1, 1986 3571 'albumtitle' => 1, 3572 'albumtitleid' => 1, 1987 3573 'aliaslayermetadata' => 1, 1988 3574 'alphabitdepth' => 1, … … 1996 3582 'alphaoffset' => 1, 1997 3583 'alphasample' => 1, 1998 'analogbalance' => 1, 3584 'alternateduotonecolors' => 1, 3585 'alternatespotcolors' => 1, 3586 'ambienceinfo' => 1, 3587 'animationextension' => 1, 3588 'animationiterations' => 1, 1999 3589 'annotation' => 1, 2000 3590 'annotations' => 1, 3591 'annotationusagerights' => 1, 3592 'anta' => 1, 2001 3593 'aperture' => 1, 2002 3594 'aperturedisplayed' => 1, 3595 'aperturesetting' => 1, 2003 3596 'apeversion' => 1, 2004 3597 'app14flags0' => 1, 2005 3598 'app14flags1' => 1, 2006 3599 '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, 2009 3608 'appversion' => 1, 2010 3609 'archivallocation' => 1, 3610 'archivedfilename' => 1, 3611 'arranger' => 1, 3612 'arrangerkeywords' => 1, 3613 'artist2' => 1, 2011 3614 'artistlen' => 1, 2012 3615 'artisturl' => 1, 3616 'artwork' => 1, 3617 'ascender' => 1, 3618 'ascent' => 1, 2013 3619 'asfleakybucketpairs' => 1, 2014 3620 'asfpacketcount' => 1, 2015 3621 'asfsecurityobjectssize' => 1, 2016 'aspectratio' => 1, 3622 'aspectinfo' => 1, 3623 'aspectratiotype' => 1, 2017 3624 'aspectratiox' => 1, 2018 3625 'aspectratioy' => 1, 2019 'asshotneutral' => 1,2020 3626 'association' => 1, 3627 'assumeddisplaysize' => 1, 3628 'assumeddistanceview' => 1, 2021 3629 'atob0' => 1, 2022 3630 'atob1' => 1, 2023 3631 '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, 2024 3640 'audiences' => 1, 2025 'audiobitrate' => 1, 3641 'audioattributes' => 1, 3642 'audioavgbitrate' => 1, 3643 'audiobitspersample' => 1, 2026 3644 'audiobytes' => 1, 2027 'audioc hannels' => 1,3645 'audiocodec' => 1, 2028 3646 'audiocodecdescription' => 1, 2029 3647 'audiocodecid' => 1, 3648 'audiocodecinfo' => 1, 2030 3649 'audiocodecname' => 1, 2031 3650 'audiodelay' => 1, … … 2035 3654 'audioformat' => 1, 2036 3655 'audioframesize' => 1, 3656 'audiogain' => 1, 3657 'audioheader' => 1, 2037 3658 'audioinfo' => 1, 2038 3659 'audiolayer' => 1, 3660 'audiomaxbitrate' => 1, 2039 3661 'audiomode' => 1, 2040 'audiosamplebits' => 1, 3662 'audioprofile' => 1, 3663 'audioprofileversion' => 1, 3664 'audiosamplecount' => 1, 3665 'audiosampledesc' => 1, 2041 3666 'audiosamplesize' => 1, 2042 3667 'audiosize' => 1, 2043 3668 'audiosourceurl' => 1, 2044 3669 'audiostream' => 1, 3670 'audiostreamtype' => 1, 3671 'audiotrackid' => 1, 3672 'audiovendorid' => 1, 3673 'authenticationtime' => 1, 3674 'authenticationtype' => 1, 2045 3675 'authorlen' => 1, 2046 3676 'authorship' => 1, … … 2051 3681 'avgbytespersec' => 1, 2052 3682 'avgpacketsize' => 1, 3683 'avgpdusize' => 1, 3684 'avgwidth' => 1, 3685 'avi1' => 1, 2053 3686 'avif' => 1, 2054 3687 'aviheader' => 1, 3688 'awbinfo' => 1, 3689 'axisdistancex' => 1, 3690 'axisdistancey' => 1, 3691 'axisdistancez' => 1, 2055 3692 'background' => 1, 2056 3693 'backgroundcolor' => 1, … … 2061 3698 'backlight' => 1, 2062 3699 'backserial' => 1, 3700 'backuptime' => 1, 2063 3701 'badfaxlines' => 1, 3702 'balance' => 1, 2064 3703 'band' => 1, 2065 3704 'bandwidthsharing' => 1, … … 2068 3707 'bannerimagetype' => 1, 2069 3708 'bannerimageurl' => 1, 3709 'baselinelength' => 1, 3710 'baseviewpointnum' => 1, 2070 3711 'basisobject' => 1, 3712 'bass' => 1, 2071 3713 'batteryinfo' => 1, 2072 'batterylevel' => 1,2073 3714 'beatsperminute' => 1, 2074 3715 'binaryfilter' => 1, 3716 'binaryxml' => 1, 2075 3717 'bitrate' => 1, 2076 3718 'bitratemutualexclusion' => 1, 2077 3719 'bitsperextendedrunlength' => 1, 3720 'bitsperpixel' => 1, 2078 3721 'bitsperrunlength' => 1, 2079 3722 'blackleveldeltah' => 1, 2080 3723 '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, 2082 3735 'blocklocation' => 1, 3736 'blockmore' => 1, 2083 3737 'blocksize' => 1, 2084 3738 'blocksizemax' => 1, 2085 3739 'blocksizemin' => 1, 3740 'blockspercolumn' => 1, 2086 3741 'blocksperframe' => 1, 3742 'blocksperrow' => 1, 3743 'blockvirtual' => 1, 2087 3744 'blueadjust' => 1, 2088 3745 'bluegain' => 1, … … 2093 3750 'bluex' => 1, 2094 3751 'bluey' => 1, 3752 'booktitle' => 1, 2095 3753 'bordercolor' => 1, 2096 3754 'borderid' => 1, … … 2104 3762 'boundingbox' => 1, 2105 3763 'bracketshot' => 1, 3764 'breakchar' => 1, 2106 3765 'brightnessdata' => 1, 2107 3766 'broadcast' => 1, 3767 'broadcastextension' => 1, 2108 3768 'btoa0' => 1, 2109 3769 'btoa1' => 1, 2110 3770 'btoa2' => 1, 3771 'btod0' => 1, 3772 'btod1' => 1, 3773 'btod2' => 1, 3774 'btod3' => 1, 2111 3775 'bufferaverage' => 1, 2112 'burstshot' => 1, 3776 'builddate' => 1, 3777 'buildversion' => 1, 2113 3778 'bw_halftoninginfo' => 1, 2114 3779 'bw_transferfunc' => 1, 3780 'bwfversion' => 1, 3781 'bytelength' => 1, 2115 3782 'bytes' => 1, 2116 3783 'bytesperminute' => 1, … … 2120 3787 'calibrationdatetime' => 1, 2121 3788 'camera' => 1, 3789 'camera1' => 1, 3790 'camera2' => 1, 3791 'cameraarrangementinterval' => 1, 2122 3792 'camerabacktype' => 1, 2123 'camera calibration1' => 1,2124 'camera calibration2' => 1,3793 'camerabody' => 1, 3794 'camerabyteorder' => 1, 2125 3795 'cameradatetime' => 1, 3796 'cameradirection' => 1, 3797 'cameraidentifier' => 1, 2126 3798 'camerainfo' => 1, 3799 'camerainfo5dmkii_2a' => 1, 3800 'camerainfo5dmkii_2b' => 1, 3801 'camerainfo7d_2a' => 1, 3802 'camerainfo7d_2b' => 1, 3803 'cameramotion' => 1, 2127 3804 'cameraname' => 1, 2128 3805 'cameraobjbacktype' => 1, … … 2131 3808 'cameraobjtype' => 1, 2132 3809 'cameraobjversion' => 1, 2133 'cameraowner' => 1,2134 3810 'cameraprofileversion' => 1, 2135 3811 'camerasettings' => 1, 2136 3812 'camerasettings2' => 1, 3813 'camerasettingsa100' => 1, 3814 'camerasettingsifd' => 1, 3815 'camerasettingsunknown' => 1, 2137 3816 'camerasetup' => 1, 2138 3817 'cameraspecification' => 1, … … 2144 3823 'canonafinfo' => 1, 2145 3824 'canonafinfo2' => 1, 2146 'canoncamerainfo' => 1, 3825 'canoncamerainfo1000d' => 1, 3826 'canoncamerainfo1d' => 1, 3827 'canoncamerainfo1dmkii' => 1, 2147 3828 '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, 2149 3843 'canoncamerainfounknown16' => 1, 2150 3844 'canoncamerainfounknown32' => 1, 2151 'canoncamerainfounknown8' => 1,2152 3845 'canoncamerasettings' => 1, 3846 'canoncnth' => 1, 2153 3847 'canoncolorinfo1' => 1, 2154 3848 'canoncolorinfo2' => 1, … … 2161 3855 'canonrawmakemodel' => 1, 2162 3856 'canonshotinfo' => 1, 3857 'canseekontime' => 1, 2163 3858 'canseektoend' => 1, 3859 'capheight' => 1, 2164 3860 'captiontext' => 1, 2165 3861 'captprofbacktype' => 1, … … 2182 3878 'captureyresolutionunit' => 1, 2183 3879 'casio' => 1, 3880 'casiodata' => 1, 3881 'casiojunk' => 1, 3882 'casioquality' => 1, 3883 'casioqvmi' => 1, 2184 3884 'cc' => 1, 2185 3885 'ccdrect' => 1, 2186 3886 'ccdvalidrect' => 1, 2187 3887 'ccdvideorect' => 1, 3888 'cell' => 1, 2188 3889 'centerdarkrect' => 1, 2189 3890 'cfalayout' => 1, … … 2192 3893 'cfarepeatpatterndim' => 1, 2193 3894 '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, 2195 3927 'charcountwithspaces' => 1, 2196 'charset' => 1,2197 3928 'chartarget' => 1, 3929 'checkedby' => 1, 2198 3930 'chromaticadaptation' => 1, 2199 3931 'chromaticity' => 1, … … 2204 3936 'chromaticitychannels' => 1, 2205 3937 'chromaticitycolorant' => 1, 3938 'chunkoffset' => 1, 3939 'chunkoffset64' => 1, 2206 3940 'ciff' => 1, 3941 'cinematographer' => 1, 3942 'cip3datafile' => 1, 3943 'cip3sheet' => 1, 3944 'cip3side' => 1, 2207 3945 'circleofconfusion' => 1, 2208 3946 'class' => 1, … … 2217 3955 'cloneobject' => 1, 2218 3956 'clonetype' => 1, 3957 'cluster' => 1, 3958 'clusterduration' => 1, 2219 3959 'cmmflags' => 1, 3960 'cmykequivalent' => 1, 3961 'codecdecodeall' => 1, 3962 'codecdownloadurl' => 1, 2220 3963 'codecflavorid' => 1, 3964 'codecid' => 1, 3965 'codecinfourl' => 1, 2221 3966 'codeclist' => 1, 3967 'codecname' => 1, 3968 'codecprivate' => 1, 3969 'codecsettings' => 1, 3970 'codecstate' => 1, 2222 3971 'codedframesize' => 1, 2223 3972 'codepage' => 1, 3973 'codesize' => 1, 2224 3974 'codestreamheader' => 1, 2225 3975 'codestreamregistration' => 1, 3976 'codinghistory' => 1, 2226 3977 'codingmethods' => 1, 3978 'color' => 1, 2227 3979 'colorant1coordinates' => 1, 2228 3980 'colorant1name' => 1, … … 2234 3986 'colorantorder' => 1, 2235 3987 'coloranttable' => 1, 3988 'coloranttableout' => 1, 2236 3989 'coloraverages' => 1, 2237 3990 'colorbalance0100' => 1, … … 2240 3993 'colorbalance02' => 1, 2241 3994 'colorbalance0205' => 1, 2242 'colorbalance 2' => 1,2243 'colorbalance 3' => 1,3995 'colorbalance0209' => 1, 3996 'colorbalancea' => 1, 2244 3997 'colorbalanceunknown' => 1, 2245 3998 'colorbitdepth' => 1, 2246 3999 'colorboostdata' => 1, 2247 4000 'colorbw' => 1, 4001 'colorcalib' => 1, 2248 4002 'colorcalibrationmatrix' => 1, 2249 4003 'colorcasts' => 1, 2250 4004 'colorcharacterization' => 1, 4005 'colorcoefs' => 1, 2251 4006 'colorcomponents' => 1, 4007 'colordata1' => 1, 4008 'colordata2' => 1, 4009 'colordata3' => 1, 4010 'colordata4' => 1, 4011 'colordata5' => 1, 4012 'colordata6' => 1, 4013 'colordataunknown' => 1, 2252 4014 'colorgroup' => 1, 2253 4015 'colorhalftoninginfo' => 1, 4016 'colorimetricintentimagestate' => 1, 4017 'colorimetry' => 1, 2254 4018 'colorinfo' => 1, 2255 'colorinfod30' => 1,2256 4019 'colormap' => 1, 2257 'colormatrix1' => 1,2258 4020 'colorobjbacktype' => 1, 2259 4021 'colorobjname' => 1, … … 2261 4023 'colorobjversion' => 1, 2262 4024 'colorpalette' => 1, 4025 'colorresolutiondepth' => 1, 2263 4026 'colorresponseunit' => 1, 2264 4027 'colors' => 1, … … 2272 4035 'colortwistmatrix' => 1, 2273 4036 'colortype' => 1, 4037 'commandlinearguments' => 1, 2274 4038 'commentlen' => 1, 2275 4039 'comments' => 1, … … 2278 4042 'commissioned' => 1, 2279 4043 'common' => 1, 4044 'commonnetworkrellink' => 1, 4045 'commonpathsuffix' => 1, 4046 'compactsamplesizes' => 1, 2280 4047 'company' => 1, 4048 'companyname' => 1, 2281 4049 'compatibility' => 1, 4050 'compatiblebrands' => 1, 4051 'compatiblefontname' => 1, 2282 4052 'compilation' => 1, 2283 4053 'compobj' => 1, … … 2287 4057 'componentdefinition' => 1, 2288 4058 'componentmapping' => 1, 4059 'composerkeywords' => 1, 2289 4060 'compositinglayerheader' => 1, 2290 4061 'composition' => 1, 2291 4062 'compositionmode' => 1, 2292 4063 'compositionoptions' => 1, 4064 'compositiontimetosample' => 1, 4065 'compositiontodecodetimelinemapping' => 1, 2293 4066 'compressed' => 1, 4067 'compressedannotation' => 1, 4068 'compresseddatalength' => 1, 4069 'compresseddataoffset' => 1, 4070 'compressedsize' => 1, 2294 4071 'compressedtext' => 1, 2295 4072 'compressionlevel' => 1, 2296 4073 'compressiontype' => 1, 2297 'compressor' => 1,2298 4074 'compressorid' => 1, 4075 'compressorname' => 1, 4076 'compressorversion' => 1, 2299 4077 'concreteflag' => 1, 2300 4078 'condition' => 1, … … 2304 4082 'connectionspaceilluminant' => 1, 2305 4083 'consecutivebadfaxlines' => 1, 4084 'consoledata' => 1, 4085 'consolefedata' => 1, 2306 4086 'cont' => 1, 2307 4087 'containerformat' => 1, 4088 'containerversion' => 1, 2308 4089 'contake' => 1, 2309 4090 'contentbranding' => 1, 4091 'contentcompression' => 1, 4092 'contentcompressionalgorithm' => 1, 4093 'contentcompressionsettings' => 1, 2310 4094 'contentdescription' => 1, 2311 4095 'contentdescriptionnotes' => 1, 2312 4096 'contentdisposition' => 1, 2313 4097 'contentdistributor' => 1, 4098 'contentencoding' => 1, 4099 'contentencodingorder' => 1, 4100 'contentencodings' => 1, 4101 'contentencodingscope' => 1, 4102 'contentencodingtype' => 1, 2314 4103 'contentencryption' => 1, 4104 'contentencryptionalgorithm' => 1, 4105 'contentencryptionkeyid' => 1, 2315 4106 'contentgroupdescription' => 1, 2316 4107 'contentlanguage' => 1, 2317 4108 'contentrating' => 1, 4109 'contents' => 1, 2318 4110 'contentscripttype' => 1, 4111 'contentsignature' => 1, 4112 'contentsignaturealgorithm' => 1, 4113 'contentsignaturehashalgorithm' => 1, 4114 'contentsignaturekeyid' => 1, 2319 4115 'contentstyletype' => 1, 2320 4116 'contenttype' => 1, 2321 4117 'contiguouscodestream' => 1, 2322 4118 'contrastadjustment' => 1, 4119 'contrastcurve' => 1, 4120 'convergenceangle' => 1, 4121 'convergencebaseimage' => 1, 4122 'convergencedistance' => 1, 2323 4123 'copyrightlen' => 1, 2324 4124 'copyrighturl' => 1, 4125 'costumedesigner' => 1, 2325 4126 'coverart' => 1, 2326 4127 'coverartmimetype' => 1, 4128 'cpuarchitecture' => 1, 4129 'cpubyteorder' => 1, 4130 'cpucount' => 1, 4131 'cpusubtype' => 1, 4132 'cputype' => 1, 2327 4133 'cpuversions' => 1, 4134 'crc-32' => 1, 4135 'crcdevelparams' => 1, 2328 4136 'crdinfo' => 1, 4137 'createdby' => 1, 2329 4138 'creatingapplication' => 1, 2330 4139 'creatingtransform' => 1, 2331 4140 'creationpathvector' => 1, 4141 'creatorappid' => 1, 4142 'creatorapplication' => 1, 4143 'creatorappversion' => 1, 4144 'creatorinfo' => 1, 4145 'creatorversion' => 1, 2332 4146 'cropdata' => 1, 4147 'cropinfo' => 1, 2333 4148 '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, 2334 4163 'cross-reference' => 1, 4164 'crossref' => 1, 2335 4165 'crs' => 1, 4166 'crwparam' => 1, 4167 'cueblocknumber' => 1, 4168 'cueclusterposition' => 1, 4169 'cuecodecstate' => 1, 2336 4170 '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, 2337 4180 'currentbitrate' => 1, 4181 'currentiptcdigest' => 1, 2338 4182 'currenttime' => 1, 2339 4183 'currentuser' => 1, 4184 'cursorsize' => 1, 2340 4185 'customfunctions10d' => 1, 2341 4186 'customfunctions1d' => 1, … … 2349 4194 'customfunctionsd60' => 1, 2350 4195 '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, 2351 4208 'd-lightinghqdata' => 1, 2352 4209 'd-lightinghsdata' => 1, 2353 4210 'darkcorrectiontype' => 1, 4211 'darwindata' => 1, 2354 4212 'data' => 1, 4213 'data1' => 1, 4214 'data2' => 1, 2355 4215 'datacreatedate' => 1, 2356 4216 'datadump' => 1, 2357 4217 'datadump2' => 1, 4218 'datainfo' => 1, 4219 'datainformation' => 1, 2358 4220 'datakey' => 1, 2359 4221 'datalen' => 1, 4222 'datalength' => 1, 4223 'datalocation' => 1, 2360 4224 'datamodifydate' => 1, 2361 4225 'dataobject' => 1, … … 2366 4230 'dataoffsets' => 1, 2367 4231 'datapackets' => 1, 4232 'dataref' => 1, 2368 4233 'datareference' => 1, 2369 4234 'datasize' => 1, 2370 4235 'datatype' => 1, 4236 'datecompleted' => 1, 4237 'datetime1' => 1, 4238 'datetime2' => 1, 2371 4239 'datetimecreated' => 1, 4240 'datetimeend' => 1, 2372 4241 'dc' => 1, 4242 'dcmd' => 1, 4243 'dcme' => 1, 2373 4244 'dctencodeversion' => 1, 2374 4245 'dealeridnumber' => 1, … … 2377 4248 'decode' => 1, 2378 4249 'decodertable' => 1, 4250 'decodertablenumber' => 1, 4251 'defaultaudiostream' => 1, 4252 'defaultchar' => 1, 2379 4253 'defaultdisplayheight' => 1, 2380 4254 'defaultdisplaywidth' => 1, 4255 'defaultduration' => 1, 2381 4256 'defaultimagecolor' => 1, 2382 4257 'defaultrgb' => 1, 2383 4258 'defaultstyle' => 1, 2384 4259 'defineobject' => 1, 4260 'definequantizationtable' => 1, 2385 4261 'delay' => 1, 2386 4262 'deltapngheader' => 1, 2387 4263 'deltatype' => 1, 2388 4264 'deltaxy' => 1, 4265 'department' => 1, 4266 'dependentimage1entrynumber' => 1, 4267 'dependentimage2entrynumber' => 1, 2389 4268 'depth' => 1, 4269 'descender' => 1, 4270 'designer' => 1, 4271 'designerurl' => 1, 2390 4272 'desiredreproductions' => 1, 2391 4273 'destinationid' => 1, … … 2395 4277 'devicemodel' => 1, 2396 4278 'devicemodeldesc' => 1, 2397 'device settingdescription' => 1,4279 'devicename' => 1, 2398 4280 'devicesettings' => 1, 2399 4281 'dex' => 1, 2400 4282 'dicom' => 1, 2401 4283 'dictionary' => 1, 4284 'digikam' => 1, 4285 'digitalcreationdatetime' => 1, 2402 4286 'digitaleffectsname' => 1, 2403 4287 'digitaleffectstype' => 1, … … 2406 4290 'digitalsignature' => 1, 2407 4291 'dimensions' => 1, 2408 'dinf' => 1,2409 'director' => 1,2410 4292 'discardobjects' => 1, 2411 4293 'disknumber' => 1, 4294 'displayheight' => 1, 2412 4295 'displayinfo' => 1, 2413 4296 'displayresolution' => 1, 2414 4297 'displaysize' => 1, 4298 'displayunit' => 1, 2415 4299 'displayunits' => 1, 4300 'displaywidth' => 1, 2416 4301 'displayxresolution' => 1, 2417 4302 'displayxresolutionunit' => 1, … … 2419 4304 'displayyresolutionunit' => 1, 2420 4305 'dispose' => 1, 4306 'disposition' => 1, 4307 'distortinfo' => 1, 4308 'distortionversion' => 1, 4309 'distributedby' => 1, 2421 4310 'distribution' => 1, 4311 'division' => 1, 4312 'djvuversion' => 1, 2422 4313 'dngadobedata' => 1, 2423 'dngpentaxdata' => 1,2424 4314 'dngprivatedata' => 1, 2425 4315 'docclass' => 1, 4316 'docmdp' => 1, 2426 4317 'docrights' => 1, 4318 'docsecurity' => 1, 2427 4319 'doctype' => 1, 4320 'doctypereadversion' => 1, 4321 'doctypeversion' => 1, 2428 4322 'documentinfo' => 1, 4323 'documentnumber' => 1, 4324 'documentusagerights' => 1, 2429 4325 'dof' => 1, 2430 4326 'donotshow' => 1, 2431 4327 'dotsperinch' => 1, 4328 'driveserialnumber' => 1, 4329 'drivetype' => 1, 2432 4330 'drm' => 1, 2433 4331 'drm_contentid' => 1, … … 2449 4347 'dropbykeyword' => 1, 2450 4348 'dropchunks' => 1, 4349 'dtob0' => 1, 4350 'dtob1' => 1, 4351 'dtob2' => 1, 4352 'dtob3' => 1, 2451 4353 'ducky' => 1, 2452 4354 'duotonehalftoninginfo' => 1, 2453 4355 'duotoneimageinfo' => 1, 2454 4356 'duotonetransferfuncs' => 1, 2455 'dustremovaldata' => 1,2456 4357 'dvdid' => 1, 2457 'dynamicrangeoptimizer' => 1, 4358 'ebmlheader' => 1, 4359 'ebmlmaxidlength' => 1, 4360 'ebmlmaxsizelength' => 1, 4361 'ebmlreadversion' => 1, 4362 'ebmlversion' => 1, 2458 4363 'edit1' => 1, 2459 4364 'edit2' => 1, … … 2465 4370 'edit8' => 1, 2466 4371 '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, 2467 4380 'edittagarray' => 1, 4381 'effect' => 1, 2468 4382 'effectivebw' => 1, 2469 'effectivemaxaperture' => 1,2470 4383 'effectsvisible' => 1, 4384 'eighthlanguage' => 1, 4385 'embeddedfile' => 1, 4386 'embeddedfilename' => 1, 4387 'embeddedfileusagerights' => 1, 2471 4388 'emphasis' => 1, 2472 4389 'encodedby' => 1, … … 2477 4394 'encoding' => 1, 2478 4395 'encodingprocess' => 1, 4396 'encodingscheme' => 1, 2479 4397 'encodingsettings' => 1, 2480 4398 'encodingtime' => 1, 4399 'encrypt' => 1, 4400 'encryptedblock' => 1, 2481 4401 'encryption' => 1, 2482 4402 'endpoints' => 1, 4403 'endtime' => 1, 4404 'endtimecode' => 1, 4405 'entrypoint' => 1, 4406 'envvardata' => 1, 4407 'episodeglobaluniqueid' => 1, 2483 4408 'eppim' => 1, 4409 'eprint' => 1, 2484 4410 'epsoptions' => 1, 2485 4411 'equipment' => 1, 2486 'equipment 2' => 1,4412 'equipmentifd' => 1, 2487 4413 'error' => 1, 2488 4414 'errorcorrection' => 1, 2489 4415 'errorcorrectiontype' => 1, 4416 'escchar' => 1, 2490 4417 'evalstate' => 1, 2491 4418 'events' => 1, 2492 'e xif' => 1,4419 'evstepinfo' => 1, 2493 4420 'exif_profile' => 1, 4421 'exifdata' => 1, 2494 4422 'exifinfo' => 1, 4423 'exifinfo2' => 1, 2495 4424 'exifinformation' => 1, 2496 4425 'exifoffset' => 1, 2497 4426 'exiftoolversion' => 1, 2498 'exitpupilposition' => 1, 4427 'expandfilm' => 1, 4428 'expandfilterlens' => 1, 4429 'expandflashlamp' => 1, 4430 'expandlens' => 1, 4431 'expandscanner' => 1, 4432 'expandsoftware' => 1, 2499 4433 'expires' => 1, 2500 4434 'exportimage' => 1, 2501 'exposure adjust' => 1,4435 'exposurebias' => 1, 2502 4436 'exposureinfo' => 1, 4437 'exposureunknown' => 1, 2503 4438 'extcache' => 1, 4439 'extendedaviheader' => 1, 2504 4440 'extendedcontentdescr' => 1, 2505 4441 'extendedcontentencryption' => 1, 4442 'extendedinfo' => 1, 2506 4443 'extendedstreamprops' => 1, 4444 'extendedxmp' => 1, 2507 4445 'extenderstatus' => 1, 2508 4446 'extensionclassid' => 1, … … 2513 4451 'extensionpersistence' => 1, 2514 4452 'extensions' => 1, 4453 'externalleading' => 1, 4454 'extraflags' => 1, 2515 4455 '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, 2516 4480 'facedetect1' => 1, 2517 4481 '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, 2518 4491 'fastseek' => 1, 2519 4492 'faxprofile' => 1, … … 2521 4494 'faxrecvtime' => 1, 2522 4495 '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, 2523 4505 'fileid' => 1, 4506 'fileinfo' => 1, 2524 4507 'fileinfolen' => 1, 2525 4508 'fileinfolen2' => 1, 2526 4509 'fileinfoproperties' => 1, 2527 4510 'fileinfoversion' => 1, 4511 'filelength' => 1, 4512 'fileos' => 1, 2528 4513 'fileowner' => 1, 4514 'filepermissions' => 1, 4515 'fileprofileversion' => 1, 2529 4516 'fileproperties' => 1, 2530 'filerul' => 1,2531 4517 'files' => 1, 2532 4518 'filesize' => 1, 2533 4519 'filesizebytes' => 1, 4520 'filesubtype' => 1, 2534 4521 'filetype' => 1, 4522 'fileurl' => 1, 4523 'fileversionnumber' => 1, 4524 'fillattributes' => 1, 2535 4525 'fillmethod' => 1, 2536 4526 'filmbrand' => 1, … … 2541 4531 'filmrollnumber' => 1, 2542 4532 'filmsize' => 1, 4533 'filter' => 1, 4534 'filterinfo' => 1, 2543 4535 'filtering' => 1, 2544 4536 'finalframeblocks' => 1, 4537 'firmwareinfo' => 1, 4538 'firstchar' => 1, 4539 'firstlanguage' => 1, 2545 4540 'firstobject' => 1, 2546 4541 'firstobjectid' => 1, … … 2548 4543 'flashexpcomp' => 1, 2549 4544 'flashinfo' => 1, 2550 'flashon' => 1, 4545 'flashinfo0100' => 1, 4546 'flashinfo0102' => 1, 4547 'flashinfo0103' => 1, 4548 'flashinfo0104' => 1, 4549 'flashinfounknown' => 1, 4550 'flashinfoversion' => 1, 2551 4551 'flashpixstreamfieldoffset' => 1, 2552 4552 'flashpixstreampathname' => 1, 2553 4553 'flashpower' => 1, 4554 'flashsyncmode' => 1, 2554 4555 'flashttlmode' => 1, 2555 4556 'flashversion' => 1, 4557 'flavor' => 1, 2556 4558 'focallength35efl' => 1, 4559 'focalplanecolorimetryestimates' => 1, 4560 'focalrange' => 1, 2557 4561 'focusinfo' => 1, 2558 'focusinfo 2' => 1,4562 'focusinfoifd' => 1, 2559 4563 'focuspos' => 1, 4564 'font' => 1, 4565 'fontsize' => 1, 4566 'fontsubfamily' => 1, 4567 'fontsubfamilyid' => 1, 4568 'fontweight' => 1, 4569 'footerposition' => 1, 2560 4570 'footnotes' => 1, 4571 'form' => 1, 2561 4572 'formatter' => 1, 2562 4573 'formatversion' => 1, 2563 4574 'formatversiontime' => 1, 4575 'formfields' => 1, 4576 'formusagerights' => 1, 4577 'forwardto' => 1, 2564 4578 'fotostation' => 1, 2565 4579 'fourcc1' => 1, … … 2568 4582 'fourcc3' => 1, 2569 4583 'fourcc3len' => 1, 4584 'fourthlanguage' => 1, 4585 'fov' => 1, 2570 4586 'fpxr' => 1, 2571 4587 'fractalparameters' => 1, … … 2573 4589 'fragmenttable' => 1, 2574 4590 'frame' => 1, 2575 'framecount' => 1, 4591 'frameheight' => 1, 4592 'frameinfo' => 1, 2576 4593 'framepriority' => 1, 2577 'framer ate' => 1,4594 'framereadouttime' => 1, 2578 4595 'framesize' => 1, 2579 4596 'framesizemax' => 1, 2580 4597 'framesizemin' => 1, 2581 'frame type' => 1,4598 'framewidth' => 1, 2582 4599 'free' => 1, 2583 4600 'freebytecounts' => 1, 2584 4601 'freeoffsets' => 1, 4602 'fstype' => 1, 2585 4603 'fujifilm' => 1, 4604 'fujifilmffmv' => 1, 4605 'fujifilmmvtg' => 1, 2586 4606 'fujilayout' => 1, 4607 'fullname' => 1, 4608 'fullscreen' => 1, 2587 4609 'gain' => 1, 2588 4610 'gamut' => 1, … … 2591 4613 'gdalnodata' => 1, 2592 4614 'geminfo' => 1, 4615 'genbalance' => 1, 2593 4616 'generator' => 1, 4617 'genflags' => 1, 4618 'gengraphicsmode' => 1, 4619 'genmediaheader' => 1, 4620 'genmediainfo' => 1, 4621 'genmediaversion' => 1, 4622 'genopcolor' => 1, 2594 4623 'genr' => 1, 2595 4624 'genreid' => 1, … … 2616 4645 'gifgraphiccontrolextension' => 1, 2617 4646 'gifplaintextextension' => 1, 4647 'gifversion' => 1, 2618 4648 'globalinfo' => 1, 2619 4649 'globalparametersifd' => 1, … … 2621 4651 'googlebot' => 1, 2622 4652 'gps' => 1, 4653 'gpscoordinates' => 1, 2623 4654 'gpsinfo' => 1, 2624 4655 'gpsposition' => 1, 4656 'grainybwfilter' => 1, 2625 4657 'graphicconverter' => 1, 4658 'graphicsmode' => 1, 2626 4659 'graphicstechnologystandardoutput' => 1, 2627 4660 'grayresponsecurve' => 1, … … 2636 4669 'greeny' => 1, 2637 4670 'gridguidesinfo' => 1, 4671 'group' => 1, 2638 4672 'groupcaption' => 1, 2639 4673 'grouping' => 1, … … 2642 4676 'gtmodeltype' => 1, 2643 4677 'gtrastertype' => 1, 4678 'handler' => 1, 4679 'handlerclass' => 1, 4680 'handlerdescription' => 1, 4681 'handlertype' => 1, 4682 'handlervendorid' => 1, 2644 4683 'hasarbitrarydatastream' => 1, 2645 4684 'hasattachedimages' => 1, 2646 4685 'hasaudio' => 1, 4686 'hascolormap' => 1, 2647 4687 'hascuepoints' => 1, 2648 4688 'hasfiletransferstream' => 1, … … 2655 4695 'hcusage' => 1, 2656 4696 'hdrl' => 1, 4697 'hdvideo' => 1, 2657 4698 'header' => 1, 2658 4699 'headerext' => 1, … … 2662 4703 'heightresolution' => 1, 2663 4704 'hiddenslides' => 1, 4705 'highlightdata' => 1, 2664 4706 '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, 2665 4716 'http-equiv' => 1, 4717 'httphostheader' => 1, 4718 'huffmantable' => 1, 2666 4719 'hyperfocaldistance' => 1, 2667 4720 'hyperlinkbase' => 1, … … 2670 4723 'icc_untagged' => 1, 2671 4724 'iccbased' => 1, 4725 'iconenvdata' => 1, 4726 'iconfilename' => 1, 4727 'iconindex' => 1, 2672 4728 'id' => 1, 2673 4729 'id3' => 1, 4730 'id3size' => 1, 2674 4731 'id3v1' => 1, 4732 'id3v1_enh' => 1, 2675 4733 'id3v2_2' => 1, 2676 4734 'id3v2_3' => 1, 2677 4735 'id3v2_4' => 1, 4736 'idc2_ifd' => 1, 4737 'idc_ifd' => 1, 4738 'idcpreviewimage' => 1, 2678 4739 'identification' => 1, 4740 'idependentanddisposablesamples' => 1, 2679 4741 'idsbasevalue' => 1, 2680 4742 'ifd0_offset' => 1, 4743 'ihl_exif' => 1, 4744 'ihldata' => 1, 4745 'illustrator' => 1, 2681 4746 'image' => 1, 4747 'imagearrangement' => 1, 4748 'imageboardid' => 1, 2682 4749 'imagebounds' => 1, 2683 4750 'imagebytecount' => 1, 4751 'imageclass' => 1, 4752 'imagecolor' => 1, 2684 4753 'imagecolorindicator' => 1, 2685 4754 'imagecolorvalue' => 1, … … 2696 4765 'imageoffset' => 1, 2697 4766 'imageprintstatus' => 1, 2698 'imageprocessing 2' => 1,4767 'imageprocessingifd' => 1, 2699 4768 'imageprofile' => 1, 2700 4769 'imageprops' => 1, 2701 4770 'imagerboardid' => 1, 4771 'imageresolution' => 1, 2702 4772 'imageresources' => 1, 2703 4773 'imagerotated' => 1, 4774 'imagerotation' => 1, 2704 4775 'imagerotationstatus' => 1, 2705 4776 'imagesourceek' => 1, 2706 4777 'imagestatus' => 1, 2707 4778 'imagetoolbar' => 1, 4779 'imageuidlist' => 1, 4780 'imageversion' => 1, 2708 4781 'imgprofbacktype' => 1, 2709 4782 'imgprofname' => 1, 2710 4783 'imgproftype' => 1, 2711 4784 'imgprofversion' => 1, 4785 'immediatedatabytes' => 1, 4786 'includedfileid' => 1, 2712 4787 '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, 2713 4804 'indexable' => 1, 2714 4805 'indexed' => 1, … … 2717 4808 'indexparameters' => 1, 2718 4809 'info' => 1, 2719 'infolist' => 1,2720 4810 'information' => 1, 4811 'ingrreserved' => 1, 4812 'initialdisplayeffect' => 1, 4813 'initializeddatasize' => 1, 2721 4814 'initialkey' => 1, 4815 'initialobjectdescriptor' => 1, 2722 4816 'inknames' => 1, 2723 4817 'inputdataobjectlist' => 1, 2724 4818 'inputprofile' => 1, 4819 'insertmode' => 1, 4820 'institution' => 1, 2725 4821 'instructionset' => 1, 2726 4822 'integrationtime' => 1, … … 2732 4828 'intergraphpacketdata' => 1, 2733 4829 'interlace' => 1, 4830 'interleavedfield' => 1, 4831 'internalidnumber' => 1, 4832 'internalleading' => 1, 4833 'internalname' => 1, 4834 'internalversionnumber' => 1, 2734 4835 'internationaltext' => 1, 2735 4836 'internetradiostationname' => 1, … … 2739 4840 'interpretedby' => 1, 2740 4841 'involvedpeople' => 1, 4842 'ipmpcontrol' => 1, 2741 4843 'iptc' => 1, 2742 4844 'iptc_profile' => 1, … … 2745 4847 'iptcdata' => 1, 2746 4848 'iptcenvelope' => 1, 4849 'iptcext' => 1, 4850 'iptcfotostation' => 1, 2747 4851 'iptcnewsphoto' => 1, 2748 4852 'iptcobjectdata' => 1, … … 2751 4855 'is_protected' => 1, 2752 4856 'is_trusted' => 1, 2753 'isospeed' => 1, 4857 'isbasefont' => 1, 4858 'isfixedpitch' => 1, 4859 'isfixedv' => 1, 4860 'isoinfo' => 1, 2754 4861 'isrc' => 1, 4862 'isrccode' => 1, 2755 4863 'isrcnumber' => 1, 2756 4864 'isvbr' => 1, 2757 4865 '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, 2758 4876 'iterationcount' => 1, 2759 4877 'iterationendaction' => 1, … … 2766 4884 'jfxx' => 1, 2767 4885 'jngheader' => 1, 4886 'journal' => 1, 2768 4887 'jp2header' => 1, 2769 4888 'jp2signature' => 1, … … 2771 4890 'jpegactables' => 1, 2772 4891 'jpegdctables' => 1, 4892 'jpegdigest' => 1, 4893 'jpegexifdata' => 1, 2773 4894 'jpeglosslesspredictors' => 1, 2774 4895 'jpegpointtransforms' => 1, 2775 4896 'jpegproc' => 1, 4897 'jpegprocess' => 1, 2776 4898 'jpegqtables' => 1, 2777 4899 'jpegrestartinterval' => 1, 2778 4900 'jpegtables' => 1, 2779 4901 'jumptoxpep' => 1, 4902 'junk' => 1, 2780 4903 'kbytesize' => 1, 4904 'kdc_ifd' => 1, 2781 4905 'keyframepositions' => 1, 2782 4906 'keyframestimes' => 1, 4907 'keys' => 1, 2783 4908 'kids' => 1, 4909 'knownfolderdata' => 1, 2784 4910 'kodak' => 1, 2785 4911 'kodakbordersifd' => 1, 2786 4912 'kodakeffectsifd' => 1, 4913 'kodakifd' => 1, 4914 'kodaktags' => 1, 2787 4915 '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, 2788 4926 'languagelist' => 1, 4927 'largestpacketduration' => 1, 4928 'largestpacketsize' => 1, 4929 'lastauthor' => 1, 4930 'lastchar' => 1, 2789 4931 'lastkeyframetime' => 1, 4932 'lastmodifiedby' => 1, 2790 4933 'lastmodifier' => 1, 2791 4934 'lastobject' => 1, 2792 4935 'lastobjectid' => 1, 2793 4936 'lastprinted' => 1, 2794 'lastsavedby' => 1,2795 4937 'lasttimestamp' => 1, 4938 'layercomps' => 1, 2796 4939 'layersgroupinfo' => 1, 2797 4940 'layerstateinfo' => 1, … … 2806 4949 'leftdarkrect' => 1, 2807 4950 'leftmag' => 1, 4951 'legalcopyright' => 1, 4952 'legaltrademarks' => 1, 2808 4953 'length' => 1, 2809 4954 'lens35efl' => 1, 4955 'lenscorr' => 1, 4956 'lensdata' => 1, 2810 4957 'lensdata0100' => 1, 2811 4958 'lensdata0101' => 1, 2812 4959 'lensdata0201' => 1, 4960 'lensdata0204' => 1, 2813 4961 'lensdataunknown' => 1, 2814 'lens focalrange' => 1,4962 'lensdataversion' => 1, 2815 4963 'lensshading' => 1, 2816 4964 'lensspec' => 1, 4965 'levelinfo' => 1, 4966 'libraryid' => 1, 4967 'licenseinfourl' => 1, 4968 'lightingopt' => 1, 2817 4969 'lightness' => 1, 2818 4970 'lights' => 1, 2819 4971 'lightvalue' => 1, 2820 4972 'linearizationtable' => 1, 4973 'linearized' => 1, 2821 4974 'lines' => 1, 4975 'linkerversion' => 1, 4976 'linkinfo' => 1, 2822 4977 'linksuptodate' => 1, 2823 4978 'lit' => 1, 4979 'localbasepath' => 1, 2824 4980 'localdeltatype' => 1, 2825 4981 'localeindicator' => 1, 4982 'locationbody' => 1, 4983 'locationdate' => 1, 4984 'locationnote' => 1, 4985 'locationrole' => 1, 2826 4986 'lockedpropertylist' => 1, 2827 4987 'locks' => 1, 4988 'logoiconurl' => 1, 4989 'logourl' => 1, 4990 'longdescription' => 1, 2828 4991 'lookheadbacktype' => 1, 2829 4992 'lookheader' => 1, … … 2835 4998 'lotus' => 1, 2836 4999 'lr' => 1, 5000 'lslv' => 1, 2837 5001 'luminance' => 1, 2838 5002 'luminanceconsts' => 1, … … 2840 5004 'lyrics' => 1, 2841 5005 'lyrics_synchronised' => 1, 5006 'machineid' => 1, 5007 'machinetype' => 1, 2842 5008 'macintoshprintinfo' => 1, 2843 5009 'magnification' => 1, 2844 5010 'magnifyobject' => 1, 5011 'mailstop' => 1, 5012 'maininfo' => 1, 5013 'maininfoifd' => 1, 5014 'majorbrand' => 1, 2845 5015 'makeandmodel' => 1, 5016 'makemodel' => 1, 2846 5017 'makernotes' => 1, 5018 'makerurl' => 1, 2847 5019 'mandatorybackground' => 1, 5020 'manufacturecode' => 1, 5021 'manufactureindex' => 1, 5022 'manufacturer' => 1, 5023 'manufacturername' => 1, 5024 'mappingscheme' => 1, 5025 'markbits' => 1, 2848 5026 'marker' => 1, 2849 5027 'markerid' => 1, 5028 'markinfo' => 1, 5029 'matrixstructure' => 1, 2850 5030 'mattcolor' => 1, 2851 5031 'matte' => 1, 2852 5032 'matteing' => 1, 5033 'matter' => 1, 2853 5034 'maxband' => 1, 2854 5035 'maxbitrate' => 1, 5036 'maxblockadditionid' => 1, 5037 'maxcache' => 1, 2855 5038 'maxdatarate' => 1, 2856 5039 'maximumbitrate' => 1, … … 2862 5045 'maxpacketsize' => 1, 2863 5046 'maxpagenormal' => 1, 5047 'maxpdusize' => 1, 2864 5048 'maxsubfilesize' => 1, 5049 'maxtransmissiontime' => 1, 2865 5050 'maxval' => 1, 5051 'maxwidth' => 1, 2866 5052 'mcdi' => 1, 2867 'mdat' => 1,2868 5053 'mdcolortable' => 1, 2869 5054 'mdfiletag' => 1, 2870 5055 'mdfileunits' => 1, 2871 5056 'mdlabname' => 1, 5057 'mdpm' => 1, 2872 5058 'mdpr' => 1, 2873 5059 'mdprepdate' => 1, … … 2875 5061 'mdsampleinfo' => 1, 2876 5062 'mdscalepixel' => 1, 5063 'mean' => 1, 5064 'measuredcolor' => 1, 2877 5065 'measuredinfo' => 1, 2878 5066 'measurement' => 1, … … 2886 5074 'mediaclassprimaryid' => 1, 2887 5075 'mediaclasssecondaryid' => 1, 5076 'mediacolor' => 1, 5077 'mediacreatedate' => 1, 2888 5078 'mediacredits' => 1, 2889 5079 'mediadata' => 1, 5080 'mediaduration' => 1, 5081 'mediaheader' => 1, 5082 'mediaheaderversion' => 1, 2890 5083 'mediaindex' => 1, 5084 'mediainfo' => 1, 2891 5085 'mediaisdelay' => 1, 2892 5086 'mediaisfinale' => 1, … … 2898 5092 'mediaissubtitled' => 1, 2899 5093 'mediaistape' => 1, 5094 'medialanguagecode' => 1, 5095 'mediamodifydate' => 1, 2900 5096 'medianetworkaffiliation' => 1, 2901 5097 'mediaoriginalbroadcastdatetime' => 1, … … 2904 5100 'mediastationcallsign' => 1, 2905 5101 'mediastationname' => 1, 5102 'mediatimescale' => 1, 5103 'mediatrackbytes' => 1, 5104 'mediatype' => 1, 5105 'mediaweight' => 1, 2906 5106 'mediawhitepoint' => 1, 2907 5107 'medium' => 1, 5108 'message' => 1, 2908 5109 'meta' => 1, 2909 5110 'metadata' => 1, 2910 5111 'metadatacreator' => 1, 5112 'metadataid' => 1, 2911 5113 'metadatalibrary' => 1, 2912 5114 'metadatanumber' => 1, 5115 'metermode' => 1, 2913 5116 'microsoft' => 1, 2914 5117 'mie' => 1, 2915 5118 'mimetype' => 1, 2916 'minf' => 1, 5119 'mincache' => 1, 5120 'miniaturefilter' => 1, 5121 'miniaturefilterorientation' => 1, 5122 'miniaturefilterposition' => 1, 2917 5123 'minimumbitrate' => 1, 2918 5124 'minoltacamerasettings' => 1, … … 2920 5126 'minoltacamerasettings5d' => 1, 2921 5127 'minoltacamerasettings7d' => 1, 2922 'minoltacamerasettingsa100' => 1,2923 5128 'minoltacamerasettingsold' => 1, 2924 5129 'minoltamakernote' => 1, 5130 'minoltamma0' => 1, 5131 'minoltamma1' => 1, 2925 5132 'minoltaprd' => 1, 2926 5133 'minoltarif' => 1, 5134 'minoltatags' => 1, 2927 5135 'minoltattw' => 1, 2928 5136 'minoltawbg' => 1, 5137 'minorversion' => 1, 2929 5138 'minpacketsize' => 1, 5139 'mintransmissiontime' => 1, 2930 5140 'mmclips' => 1, 2931 5141 'mngheader' => 1, … … 2935 5145 'modeltiepoint' => 1, 2936 5146 'modeltransform' => 1, 5147 'modeltype' => 1, 2937 5148 'modenumber' => 1, 5149 'modificationpermissions' => 1, 2938 5150 'modifiedby' => 1, 2939 5151 'modifiedinfo' => 1, 2940 5152 'montage' => 1, 5153 'month' => 1, 2941 5154 'mood' => 1, 5155 'moreinfobannerimage' => 1, 5156 'moreinfobannerurl' => 1, 5157 'moreinfotext' => 1, 5158 'moreinfourl' => 1, 2942 5159 'mosaicpattern' => 1, 2943 5160 'moveobjects' => 1, 2944 5161 'movie' => 1, 5162 'moviedata' => 1, 5163 'moviedatasize' => 1, 2945 5164 'movieheader' => 1, 5165 'movieheaderversion' => 1, 5166 'movieinfo' => 1, 5167 'moviestreamname' => 1, 5168 'mp' => 1, 5169 'mp1' => 1, 2946 5170 'mpeg7binary' => 1, 2947 5171 '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, 2948 5186 'msstereo' => 1, 2949 5187 'multiexposure' => 1, 5188 'multiexposureversion' => 1, 2950 5189 'multimediatype' => 1, 5190 'multiprofiles' => 1, 2951 5191 'multiquality' => 1, 5192 'musicby' => 1, 2952 5193 'musiccdidentifier' => 1, 2953 5194 'musiciancredits' => 1, 5195 'mute' => 1, 5196 'muxingapp' => 1, 5197 'mwg-coll' => 1, 5198 'mwg-kw' => 1, 5199 'mwg-rs' => 1, 5200 'mxfversion' => 1, 2954 5201 'mycolors' => 1, 2955 5202 'name' => 1, 2956 5203 'namedcolor' => 1, 2957 5204 'namedcolor2' => 1, 2958 'name length' => 1,5205 'nametableversion' => 1, 2959 5206 'narrator' => 1, 2960 5207 'nativedisplayinfo' => 1, … … 2963 5210 'nativeyresolution' => 1, 2964 5211 'ncc' => 1, 2965 'nefcurve1' => 1,2966 'nefcurve2' => 1,2967 5212 'nestlevel' => 1, 2968 5213 'netexposurecompensation' => 1, 5214 'netname' => 1, 5215 'netprovidertype' => 1, 2969 5216 'neutals' => 1, 2970 5217 'neutobjbacktype' => 1, … … 2975 5222 'newbitdepth' => 1, 2976 5223 'newcolortype' => 1, 5224 'nextfilename' => 1, 2977 5225 'nexttrackid' => 1, 5226 'nextuid' => 1, 2978 5227 'nikon' => 1, 2979 'nikoncapturedata' => 1,2980 5228 'nikoncaptureoffsets' => 1, 2981 'nikonpreview' => 1, 5229 'nikondata' => 1, 5230 'nikonncdt' => 1, 2982 5231 'nikonscanifd' => 1, 2983 5232 'nikontags' => 1, 5233 'nikonvers' => 1, 5234 'ninthlanguage' => 1, 5235 'nitf' => 1, 5236 'nitfversion' => 1, 2984 5237 'noise' => 1, 5238 'noiseprofile' => 1, 2985 5239 'noisereductiondata' => 1, 2986 5240 'nominalbitrate' => 1, … … 2989 5243 'nominalplaytime' => 1, 2990 5244 'nomssmarttags' => 1, 2991 'notes' => 1, 5245 'note' => 1, 5246 'notice' => 1, 5247 'now' => 1, 2992 5248 'npts' => 1, 2993 5249 'nsc_address' => 1, … … 2996 5252 'nsc_name' => 1, 2997 5253 'nsc_phone' => 1, 5254 'nullmediaheader' => 1, 2998 5255 'numafpoints' => 1, 2999 5256 'numberlist' => 1, 3000 5257 'numberofcomponents' => 1, 3001 5258 'numberofframes' => 1, 5259 'numberofimages' => 1, 3002 5260 'numberofinks' => 1, 5261 'numberofparts' => 1, 3003 5262 'numberofplanes' => 1, 3004 5263 'numberofresolutions' => 1, 3005 5264 'numchannels' => 1, 3006 5265 'numcolors' => 1, 5266 'numfonts' => 1, 5267 'numhistorybuffers' => 1, 3007 5268 'numimportantcolors' => 1, 3008 5269 'numpackets' => 1, … … 3011 5272 'numsampleframes' => 1, 3012 5273 'numstreams' => 1, 5274 'objectfiletype' => 1, 3013 5275 'objectid' => 1, 3014 5276 'objectsizeannounced' => 1, … … 3017 5279 'obsoletephotoshoptag2' => 1, 3018 5280 'obsoletephotoshoptag3' => 1, 5281 'ocad' => 1, 5282 'ocadrevision' => 1, 3019 5283 'oceapplicationselector' => 1, 3020 5284 'oceidnumber' => 1, 3021 5285 'oceimagelogic' => 1, 3022 5286 'ocescanjobdesc' => 1, 5287 'office' => 1, 3023 5288 'offsetorigin' => 1, 3024 5289 'offsetxy' => 1, 5290 'oldxmp' => 1, 5291 'olym' => 1, 3025 5292 'olympus' => 1, 3026 5293 'olympus2100' => 1, 5294 'olympus2100ifd' => 1, 3027 5295 'olympus2200' => 1, 5296 'olympus2200ifd' => 1, 3028 5297 'olympus2300' => 1, 5298 'olympus2300ifd' => 1, 3029 5299 'olympus2400' => 1, 5300 'olympus2400ifd' => 1, 3030 5301 'olympus2500' => 1, 5302 'olympus2500ifd' => 1, 3031 5303 'olympus2600' => 1, 5304 'olympus2600ifd' => 1, 3032 5305 'olympus2700' => 1, 5306 'olympus2700ifd' => 1, 3033 5307 'olympus2800' => 1, 5308 'olympus2800ifd' => 1, 3034 5309 'olympus2900' => 1, 5310 'olympus2900ifd' => 1, 5311 'olympusjunk' => 1, 5312 'olympustags1' => 1, 5313 'olympustags2' => 1, 5314 'olympustags3' => 1, 3035 5315 'opacity' => 1, 5316 'opcodelist1' => 1, 5317 'opcodelist2' => 1, 5318 'opcodelist3' => 1, 5319 'opcolor' => 1, 5320 'opendml' => 1, 5321 'openwithapplication' => 1, 5322 'operatingsystem' => 1, 3036 5323 'operation' => 1, 3037 5324 'operationclassid' => 1, … … 3040 5327 'opiproxy' => 1, 3041 5328 'optimalbitrate' => 1, 3042 'opto-electricconvfactor' => 1,3043 5329 'orderingrestrictions' => 1, 3044 'organization' => 1,3045 5330 'originalalbum' => 1, 3046 5331 'originalalbumtitle' => 1, 3047 5332 'originalartist' => 1, 3048 5333 'originaldocumentsize' => 1, 5334 'originalfilesize' => 1, 5335 'originalfiletype' => 1, 3049 5336 'originalimagebroker' => 1, 3050 5337 'originallyricist' => 1, … … 3062 5349 'originalthmimage' => 1, 3063 5350 'originalthmresource' => 1, 5351 'originator' => 1, 5352 'originatorreference' => 1, 5353 'osversion' => 1, 3064 5354 'othercodecdescription' => 1, 3065 5355 'othercodecname' => 1, 5356 'otherformat' => 1, 3066 5357 'otherimage' => 1, 3067 5358 'otherimagelength' => 1, 3068 5359 'otherimagestart' => 1, 5360 'otherinfo' => 1, 5361 'othersampledesc' => 1, 5362 'outputaudiosamplerate' => 1, 3069 5363 'outputdataobjectlist' => 1, 3070 5364 'outputprofile' => 1, 3071 5365 'outputresponse' => 1, 3072 5366 'packets' => 1, 3073 'pa dding' => 1,5367 'packingmethod' => 1, 3074 5368 'page' => 1, 3075 5369 'pagecount' => 1, … … 3077 5371 'pageexit' => 1, 3078 5372 'pagefront' => 1, 5373 'pagelayout' => 1, 5374 'pagemode' => 1, 3079 5375 'pagenormal' => 1, 3080 5376 'pages' => 1, … … 3083 5379 'palettehistogram' => 1, 3084 5380 'panasonic' => 1, 5381 'panorama' => 1, 5382 'panorientation' => 1, 5383 'panoverlaph' => 1, 5384 'panoverlapv' => 1, 3085 5385 'paragraphs' => 1, 3086 5386 'parameter' => 1, 5387 'parasites' => 1, 3087 5388 'parentalrating' => 1, 3088 5389 'parentalratingreason' => 1, 5390 'part' => 1, 3089 5391 'partialpalette' => 1, 3090 5392 'partofset' => 1, … … 3092 5394 'pasteimage' => 1, 3093 5395 'patternangle' => 1, 5396 'payloadtype' => 1, 3094 5397 'paymenturl' => 1, 3095 5398 'pcscitation' => 1, 3096 5399 'pdahistogram' => 1, 3097 5400 'pdf' => 1, 5401 'pdfx' => 1, 3098 5402 'peakbitrate' => 1, 3099 5403 'peakvalue' => 1, 5404 'pefversion' => 1, 3100 5405 'pentax' => 1, 5406 'pentaxdata' => 1, 5407 'pentaxjunk' => 1, 3101 5408 'pentaxtags' => 1, 5409 'perceptualrenderingintentgamut' => 1, 3102 5410 'performer' => 1, 5411 'performerkeywords' => 1, 3103 5412 'performers' => 1, 3104 5413 'performersortorder' => 1, 5414 'performerurl' => 1, 3105 5415 'period' => 1, 5416 'perms' => 1, 3106 5417 'perpicturenotes' => 1, 3107 5418 'personalfunctions' => 1, 3108 5419 'personalfunctionvalues' => 1, 5420 'petype' => 1, 5421 'pfmheader' => 1, 5422 'pfmversion' => 1, 5423 'pgfversion' => 1, 3109 5424 'photoeffectsdata' => 1, 3110 5425 'photomech' => 1, … … 3116 5431 'photoshopdata' => 1, 3117 5432 'photoshopformat' => 1, 5433 'photoshopinfo' => 1, 3118 5434 'photoshopsettings' => 1, 3119 5435 'photoshopthumbnail' => 1, … … 3124 5440 'picslabel' => 1, 3125 5441 'picture' => 1, 5442 'picturebitsperpixel' => 1, 5443 'picturecontrolversion' => 1, 5444 'picturectrl' => 1, 5445 'picturedescription' => 1, 5446 'pictureformat' => 1, 5447 'pictureheight' => 1, 5448 'pictureindexedcolors' => 1, 3126 5449 'pictureinfo' => 1, 5450 'picturelength' => 1, 5451 'picturemimetype' => 1, 5452 'picturestyleinfo' => 1, 5453 'picturestyleinfo2' => 1, 5454 'picturetype' => 1, 5455 'picturewidth' => 1, 3127 5456 'pieceinfo' => 1, 5457 'pitchandfamily' => 1, 5458 'pitchshift' => 1, 3128 5459 'pixelaspectratio' => 1, 3129 5460 'pixelcalibration' => 1, … … 3131 5462 'pixelintensityrange' => 1, 3132 5463 'pixellive' => 1, 5464 'pixelmagicjbigoptions' => 1, 3133 5465 'pixelscale' => 1, 3134 5466 'pixelspermeterx' => 1, … … 3137 5469 'pixelsperunity' => 1, 3138 5470 'pixelunits' => 1, 5471 'pixheight' => 1, 5472 'pixwidth' => 1, 3139 5473 'places' => 1, 3140 5474 'planes' => 1, … … 3142 5476 'playcounter' => 1, 3143 5477 'playduration' => 1, 5478 'playerversion' => 1, 3144 5479 'playgap' => 1, 3145 5480 'playlistdelay' => 1, 5481 'playlistid' => 1, 5482 'playmode' => 1, 3146 5483 'playselection' => 1, 5484 'plus' => 1, 5485 'podcast' => 1, 5486 'podcasturl' => 1, 5487 'pointsize' => 1, 5488 'popupfillattributes' => 1, 5489 'popupflash' => 1, 5490 'position' => 1, 3147 5491 'postertime' => 1, 3148 5492 'postscript2crd0' => 1, … … 3150 5494 'postscript2crd2' => 1, 3151 5495 'postscript2csa' => 1, 5496 'postscriptfontname' => 1, 3152 5497 'pragma' => 1, 5498 'preferredfamily' => 1, 3153 5499 'preferredrate' => 1, 5500 'preferredsubfamily' => 1, 3154 5501 'preferredvolume' => 1, 3155 5502 'preroll' => 1, 5503 'presentationformat' => 1, 3156 5504 'presentationtarget' => 1, 5505 'prevfilename' => 1, 3157 5506 'preview' => 1, 3158 5507 'preview0' => 1, … … 3162 5511 'previewatomtype' => 1, 3163 5512 'previewdate' => 1, 3164 'previewdescription' => 1,3165 5513 'previewduration' => 1, 5514 'previewifd' => 1, 3166 5515 'previewifd_offset' => 1, 3167 5516 'previewimagedata' => 1, 3168 5517 'previewimageinfo' => 1, 3169 5518 'previewinfo' => 1, 3170 'previewmimetype' => 1,3171 5519 'previewpict' => 1, 5520 'previewpng' => 1, 3172 5521 'previewtime' => 1, 3173 'previewtype' => 1,3174 5522 'previewversion' => 1, 3175 'primaryafpoint' => 1, 5523 'prevsize' => 1, 5524 'prevuid' => 1, 5525 'primaryitemreference' => 1, 3176 5526 'primaryplatform' => 1, 3177 5527 'printflags' => 1, 3178 5528 'printflagsinfo' => 1, 5529 'printimversion' => 1, 3179 5530 'printquality' => 1, 5531 'printscale' => 1, 3180 5532 'printtovideo' => 1, 3181 5533 'priority' => 1, 5534 'prism' => 1, 3182 5535 'private' => 1, 3183 'proccessinginfo' => 1, 5536 'privatebuild' => 1, 5537 'prl' => 1, 5538 'processing' => 1, 5539 'processinginfo' => 1, 3184 5540 'prod' => 1, 3185 5541 'prodnotes' => 1, 5542 'producedby' => 1, 3186 5543 'produceddate' => 1, 3187 5544 'producednotice' => 1, 5545 'producerkeywords' => 1, 3188 5546 'product' => 1, 5547 'productiondate' => 1, 5548 'productiondesigner' => 1, 5549 'productionstudio' => 1, 5550 'productname' => 1, 5551 'productversion' => 1, 5552 'productversionnumber' => 1, 3189 5553 'profile' => 1, 3190 5554 'profileclass' => 1, 3191 5555 'profilecmmtype' => 1, 3192 5556 'profileconnectionspace' => 1, 3193 'profilecopyright' => 1,3194 5557 'profilecreator' => 1, 3195 5558 'profiledatetime' => 1, … … 3199 5562 'profileheader' => 1, 3200 5563 'profileid' => 1, 5564 'profileifd' => 1, 3201 5565 'profilesequencedesc' => 1, 5566 'profilesequenceidentifier' => 1, 3202 5567 'profiletype' => 1, 3203 5568 'profileversion' => 1, … … 3210 5575 'projcenternorthing' => 1, 3211 5576 'projcoordtrans' => 1, 5577 'project' => 1, 3212 5578 'projectedcstype' => 1, 3213 5579 'projection' => 1, 5580 'projects' => 1, 3214 5581 'projfalseeasting' => 1, 3215 5582 'projfalsenorthing' => 1, … … 3234 5601 'propertysetidcodes' => 1, 3235 5602 'propertysetpathname' => 1, 5603 'propertystoredata' => 1, 3236 5604 'propertyvectorelements' => 1, 3237 5605 'protect' => 1, … … 3242 5610 'providerstyle' => 1, 3243 5611 'ps2crdvmsize' => 1, 3244 'ps2renteringintent' => 1, 5612 'ps2renderingintent' => 1, 5613 'psfontinfo' => 1, 3245 5614 'pstringcaption' => 1, 3246 5615 'publisherurl' => 1, 5616 'pur' => 1, 5617 'purchasedate' => 1, 5618 'purpose' => 1, 5619 'pyramidlevels' => 1, 5620 'quickedit' => 1, 3247 5621 'quickmaskinfo' => 1, 5622 'qvci' => 1, 3248 5623 'ra3' => 1, 3249 5624 'ra4' => 1, … … 3251 5626 'radiostationname' => 1, 3252 5627 'radiostationowner' => 1, 5628 'rafversion' => 1, 3253 5629 'rasterpadding' => 1, 5630 'rate' => 1, 5631 'rated' => 1, 5632 'rawcodecversion' => 1, 3254 5633 'rawdata' => 1, 5634 'rawdatalength' => 1, 5635 'rawdataoffset' => 1, 3255 5636 'rawdatarotation' => 1, 3256 5637 'rawdev2' => 1, 3257 'rawdev2 _2' => 1,5638 'rawdev2ifd' => 1, 3258 5639 'rawdevelopment' => 1, 3259 'rawdevelopment 2' => 1,5640 'rawdevelopmentifd' => 1, 3260 5641 'rawimagefullsize' => 1, 3261 5642 'rawimagemode' => 1, 5643 'rawimagesegmentation' => 1, 3262 5644 'rawinfo' => 1, 3263 'rawinfo 2' => 1,5645 'rawinfoifd' => 1, 3264 5646 'rawjpginfo' => 1, 5647 'rawzorcreatorversion' => 1, 5648 'rawzorrequiredversion' => 1, 5649 'rdf' => 1, 3265 5650 'readerrequirements' => 1, 5651 'realtimestreamingprotocol' => 1, 5652 'receivedfrom' => 1, 3266 5653 'recengineer' => 1, 5654 'recinfo' => 1, 3267 5655 'reclocation' => 1, 3268 5656 'reconstructiontype' => 1, 5657 'recordedby' => 1, 5658 'recordeddate' => 1, 5659 'recordingcopyright' => 1, 3269 5660 'recordingdates' => 1, 3270 5661 'recordingtime' => 1, 5662 'recordlabelname' => 1, 5663 'recordlabelurl' => 1, 3271 5664 'rect' => 1, 3272 5665 'rectangleofinterest' => 1, 3273 5666 'redadjust' => 1, 3274 5667 'redeyedata' => 1, 3275 'redeyereduction' => 1,3276 5668 'redgain' => 1, 3277 5669 'redmatrixcolumn' => 1, … … 3279 5671 'redsample' => 1, 3280 5672 'redtrc' => 1, 3281 'reductionmatrix1' => 1,3282 'reductionmatrix2' => 1,3283 5673 'redx' => 1, 3284 5674 'redy' => 1, 5675 'reference' => 1, 5676 'referenceblock' => 1, 5677 'referencepriority' => 1, 5678 'referencevirtual' => 1, 5679 'reflectionhardcopyorigcolorimetry' => 1, 5680 'reflectionprintoutputcolorimetry' => 1, 3285 5681 'refresh' => 1, 3286 5682 'relatedimagefile' => 1, 5683 'relativepath' => 1, 5684 'removehistoryduplicates' => 1, 3287 5685 'renderingintent' => 1, 5686 'repeateddatabytes' => 1, 3288 5687 'replaygainalbumgain' => 1, 3289 5688 'replaygainalbumpeak' => 1, … … 3291 5690 'replaygaintrackpeak' => 1, 3292 5691 'replyto' => 1, 5692 'representativedisparityfar' => 1, 5693 'representativedisparitynear' => 1, 5694 'representativeimage' => 1, 3293 5695 'requirements' => 1, 3294 5696 'reserved1' => 1, 3295 5697 'resolutioninfo' => 1, 5698 'resourceforksize' => 1, 3296 5699 'resources' => 1, 3297 5700 'resourcesneeded' => 1, … … 3303 5706 'rgb_profile' => 1, 3304 5707 'ricoh' => 1, 3305 'ricoh datetime1' => 1,3306 'ricoh datetime2' => 1,5708 'ricohjunk' => 1, 5709 'ricohrdc2' => 1, 3307 5710 'ricohrr1subdir' => 1, 3308 5711 'ricohsubdir' => 1, 3309 5712 'rightdarkrect' => 1, 3310 5713 'rightmag' => 1, 5714 'rippedby' => 1, 3311 5715 'rjmd' => 1, 3312 5716 'rmeta' => 1, … … 3317 5721 'root' => 1, 3318 5722 'rotationangle' => 1, 5723 'roundtripversion' => 1, 5724 'rowinterleavefactor' => 1, 5725 'runwindow' => 1, 5726 'sampledegradationpriority' => 1, 3319 5727 'sampleformat' => 1, 5728 'samplegroupdescription' => 1, 5729 'samplepaddingbits' => 1, 3320 5730 'samplerate2' => 1, 3321 5731 'samplesize' => 1, 5732 'samplesizes' => 1, 5733 'sampletable' => 1, 5734 'sampletext' => 1, 5735 'sampletochunk' => 1, 5736 'sampletogroup' => 1, 5737 'samsunginfo' => 1, 5738 'samsungtags' => 1, 3322 5739 'sanyomov' => 1, 3323 5740 'sanyomp4' => 1, 5741 'saturationinfo' => 1, 5742 'saturationrenderingintentgamut' => 1, 3324 5743 'saveobjbacktype' => 1, 3325 5744 'saveobjects' => 1, … … 3332 5751 'sbainputimagebitdepth' => 1, 3333 5752 'sbainputimagecolorspace' => 1, 5753 'scalado' => 1, 3334 5754 'scale' => 1, 3335 5755 'scalecrop' => 1, 3336 5756 'scalefactor35efl' => 1, 5757 'scalingfactor' => 1, 3337 5758 'scandate' => 1, 3338 5759 'scannermake' => 1, … … 3343 5764 'scansoftware' => 1, 3344 5765 'scansoftwarerevisiondate' => 1, 5766 'sceneappearanceestimates' => 1, 5767 'scenecolorimetryestimates' => 1, 5768 'school' => 1, 5769 'screenbuffersize' => 1, 5770 'screendescriptor' => 1, 3345 5771 'screening' => 1, 3346 5772 'screeningdesc' => 1, 3347 5773 'screennail' => 1, 3348 5774 'scriptcommand' => 1, 5775 'secondarygenre' => 1, 5776 'secondlanguage' => 1, 3349 5777 'security' => 1, 5778 'seek' => 1, 3350 5779 'seekable' => 1, 5780 'seekhead' => 1, 5781 'seekid' => 1, 3351 5782 'seekpoint' => 1, 5783 'seekposition' => 1, 5784 'segmentfamily' => 1, 5785 'segmentfilename' => 1, 5786 'segmentheader' => 1, 5787 'segmentuid' => 1, 3352 5788 'selection' => 1, 3353 5789 'selectionduration' => 1, … … 3360 5796 'sensorbottomborder' => 1, 3361 5797 'sensorid' => 1, 5798 'sensorimageheight' => 1, 5799 'sensorimagewidth' => 1, 3362 5800 'sensorinfo' => 1, 3363 5801 'sensorleftborder' => 1, 3364 5802 'sensorrightborder' => 1, 3365 5803 'sensortopborder' => 1, 5804 'serialinfo' => 1, 5805 'series' => 1, 3366 5806 'serviceorganizationname' => 1, 3367 5807 'setcookie' => 1, 3368 5808 'setinfo' => 1, 3369 5809 'setsubtitle' => 1, 5810 'seventhlanguage' => 1, 3370 5811 'shadowendpoints' => 1, 5812 'shadowsyncsampletable' => 1, 3371 5813 'shakereductioninfo' => 1, 5814 'shareddata' => 1, 3372 5815 'shareddoc' => 1, 3373 5816 'shareduserrating' => 1, … … 3381 5824 'sharpobjtype' => 1, 3382 5825 'sharpobjversion' => 1, 5826 'shimdata' => 1, 5827 'shootingcount' => 1, 3383 5828 'shootingrecord' => 1, 3384 5829 'shootobjbacktype' => 1, … … 3388 5833 'shootsetup' => 1, 3389 5834 '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, 3390 5850 'shotinfoversion' => 1, 3391 5851 'showmode' => 1, 3392 5852 'showobjects' => 1, 5853 'shutter' => 1, 3393 5854 'shuttercurtainhack' => 1, 3394 5855 'shutterspeed' => 1, … … 3399 5860 'signature' => 1, 3400 5861 '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, 3401 5871 'significantbits' => 1, 5872 'signingauthority' => 1, 5873 'signingdate' => 1, 5874 'signinglocation' => 1, 5875 'signingreason' => 1, 3402 5876 'signtype' => 1, 5877 'silenttracknumber' => 1, 5878 'silenttracks' => 1, 5879 'simpleblock' => 1, 3403 5880 'simpleindex' => 1, 5881 'simpletag' => 1, 3404 5882 'simplicityprofile' => 1, 3405 5883 'singlequality' => 1, … … 3407 5885 'siteenter' => 1, 3408 5886 'siteexit' => 1, 5887 'sixthlanguage' => 1, 3409 5888 'size' => 1, 3410 5889 'sizemode' => 1, … … 3418 5897 'snapshotname' => 1, 3419 5898 'softedit' => 1, 5899 'softfocusfilter' => 1, 3420 5900 'softwarerelease' => 1, 5901 'songwriter' => 1, 5902 'songwriterkeywords' => 1, 3421 5903 '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, 3422 5915 'sourcedate' => 1, 3423 5916 'sourceedition' => 1, … … 3426 5919 'sourceimagedirectory' => 1, 3427 5920 'sourceimagefilename' => 1, 5921 'sourceimageheight' => 1, 3428 5922 'sourceimagevolumename' => 1, 5923 'sourceimagewidth' => 1, 3429 5924 'sourcepublisher' => 1, 3430 5925 'sourcerights' => 1, 3431 5926 'sourcetitle' => 1, 3432 5927 'sourceurl' => 1, 3433 'spatialfrequencyresponse' => 1,3434 5928 'spatialorientation' => 1, 5929 'spatialresolution' => 1, 5930 'specialbuild' => 1, 3435 5931 'specialeffectsopticalfilter' => 1, 5932 'specialfolderdata' => 1, 5933 'speed' => 1, 3436 5934 'spiff' => 1, 3437 5935 'spiffversion' => 1, … … 3442 5940 'sr2subifdlength' => 1, 3443 5941 'sr2subifdoffset' => 1, 3444 'srf2_key' => 1, 5942 'srf2key' => 1, 5943 'srf6offset' => 1, 5944 'srfdataoffset' => 1, 3445 5945 'srgbrendering' => 1, 3446 5946 'stamptoolcount' => 1, 5947 'starring' => 1, 3447 5948 'startofframe' => 1, 3448 'stbl' => 1, 5949 'starttime' => 1, 5950 'statistics' => 1, 3449 5951 'stdautoactive' => 1, 3450 5952 'stdbasename' => 1, … … 3459 5961 'stdsharpenoutput' => 1, 3460 5962 'stereo' => 1, 5963 'stereo3dmode' => 1, 5964 'stereoimage' => 1, 5965 'stereomode' => 1, 5966 'stim' => 1, 5967 'stimversion' => 1, 5968 'stitchinfo' => 1, 3461 5969 'stonits' => 1, 3462 5970 'storage-streampathname' => 1, … … 3464 5972 'streamavgbitrate' => 1, 3465 5973 'streamavgpacketsize' => 1, 5974 'streambitdepth' => 1, 3466 5975 'streambitrateprops' => 1, 5976 'streamcolor' => 1, 3467 5977 'streamcount' => 1, 3468 5978 'streamdata' => 1, … … 3470 5980 'streamheader' => 1, 3471 5981 'streaminfo' => 1, 5982 'streamingdataprotocol' => 1, 3472 5983 'streammaxbitrate' => 1, 3473 5984 'streammaxpacketsize' => 1, … … 3480 5991 'streamprioritization' => 1, 3481 5992 'streamproperties' => 1, 5993 'streamsamplecount' => 1, 5994 'streamsamplerate' => 1, 3482 5995 'streamstarttime' => 1, 3483 5996 'streamtype' => 1, 3484 5997 'streamtypeinfo' => 1, 3485 5998 'stridable' => 1, 5999 'strikeout' => 1, 3486 6000 'stripbytecounts' => 1, 3487 6001 'stripoffsets' => 1, … … 3489 6003 'strobe' => 1, 3490 6004 'strobetime' => 1, 6005 'sub-sampleinformation' => 1, 6006 'subdir3000' => 1, 6007 'subdir3100' => 1, 6008 'subdir3400' => 1, 6009 'subdir3900' => 1, 3491 6010 'subfile' => 1, 3492 6011 'subifd' => 1, … … 3494 6013 'subifd1' => 1, 3495 6014 'subifd2' => 1, 6015 'subifd255' => 1, 3496 6016 'subifd3' => 1, 3497 6017 'subifd4' => 1, 3498 6018 'subifd5' => 1, 6019 'subifd6' => 1, 3499 6020 'subifd_offset' => 1, 3500 6021 'subimagecolor' => 1, … … 3508 6029 'subimagetilewidth' => 1, 3509 6030 'subimagewidth' => 1, 6031 'subjectpixelheight' => 1, 6032 'subjectpixelwidth' => 1, 6033 'subjectscale' => 1, 6034 'subjectunits' => 1, 3510 6035 'subpacketh' => 1, 3511 6036 'subpacketsize' => 1, 3512 6037 'subscriptioncontentid' => 1, 6038 'subseccreatedate' => 1, 3513 6039 'subsecdatetimeoriginal' => 1, 6040 'subsecmodifydate' => 1, 6041 'subsystem' => 1, 6042 'subsystemversion' => 1, 6043 'subtileblocksize' => 1, 3514 6044 'subtitle' => 1, 3515 6045 'subtitledescription' => 1, 6046 'subtitlekeywords' => 1, 3516 6047 'suggestedpalette' => 1, 3517 6048 'summaryinfo' => 1, 6049 'surroundmode' => 1, 6050 'svgversion' => 1, 6051 'swf' => 1, 6052 'synchronizedlyrictext' => 1, 6053 'syncsampletable' => 1, 3518 6054 't4options' => 1, 3519 6055 '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, 3520 6065 'taggingtime' => 1, 6066 'taglanguage' => 1, 6067 'tagname' => 1, 6068 'tags' => 1, 6069 'tagstring' => 1, 6070 'tagtrackuid' => 1, 3521 6071 'targetaudiences' => 1, 3522 6072 'targetdeltatype' => 1, 6073 'targetfiledosname' => 1, 6074 'targetfilesize' => 1, 3523 6075 'targetprinter' => 1, 6076 'targets' => 1, 6077 'targettype' => 1, 6078 'targettypevalue' => 1, 3524 6079 'targetxy' => 1, 6080 'tdat' => 1, 6081 'tdhd' => 1, 3525 6082 'technician' => 1, 3526 6083 'technology' => 1, 6084 'telephonenumber' => 1, 6085 'temperature' => 1, 6086 'tempinfok5' => 1, 3527 6087 'template' => 1, 3528 6088 'terminationaction' => 1, … … 3532 6092 'text' => 1, 3533 6093 'textinfo' => 1, 6094 'textjunk' => 1, 3534 6095 'textualdata' => 1, 6096 'textualinfo' => 1, 3535 6097 'things' => 1, 6098 'thirdlanguage' => 1, 3536 6099 'thumbnail' => 1, 3537 6100 'thumbnailclip' => 1, … … 3539 6102 'tiff' => 1, 3540 6103 'tiff-epstandardid' => 1, 6104 'tiff_fxextensions' => 1, 3541 6105 'tiffpreview' => 1, 3542 6106 'tilebytecounts' => 1, … … 3546 6110 'timecodeindex' => 1, 3547 6111 'timecodeindexparms' => 1, 6112 'timecodescale' => 1, 6113 'timeinfo' => 1, 3548 6114 'timeoffset' => 1, 6115 'timereference' => 1, 3549 6116 'timescale' => 1, 6117 'timeslice' => 1, 6118 'timetosampletable' => 1, 6119 'title2' => 1, 3550 6120 'titlelen' => 1, 3551 6121 'titleofparts' => 1, 6122 'titlesofparts' => 1, 3552 6123 'titlesortorder' => 1, 3553 6124 'tocitems' => 1, … … 3564 6135 'toolversion' => 1, 3565 6136 'topmag' => 1, 6137 'totalbitrate' => 1, 6138 'totalbytes' => 1, 6139 'totalbytesnortpheaders' => 1, 6140 'totaldatarate' => 1, 6141 'totalduration' => 1, 3566 6142 'totaledittime' => 1, 6143 'totalframecount' => 1, 3567 6144 'totalframes' => 1, 3568 6145 'totalsamples' => 1, 6146 'toycamerafilter' => 1, 3569 6147 'track' => 1, 6148 'trackattachmentuid' => 1, 3570 6149 'trackcategory' => 1, 3571 6150 'trackcomments' => 1, 3572 6151 'trackcreatedate' => 1, 6152 'trackdefault' => 1, 3573 6153 'trackduration' => 1, 6154 'trackentry' => 1, 6155 'trackerdata' => 1, 6156 'trackforced' => 1, 3574 6157 'trackheader' => 1, 6158 'trackheaderversion' => 1, 3575 6159 'trackid' => 1, 6160 'tracklacing' => 1, 6161 'tracklanguage' => 1, 3576 6162 'tracklayer' => 1, 3577 6163 'tracklyrics' => 1, 3578 6164 '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, 3580 6178 'trackvolume' => 1, 6179 'trademark' => 1, 3581 6180 'transferrange' => 1, 3582 'transfomation' => 1, 3583 'transform' => 1, 6181 'transformation' => 1, 3584 6182 'transformcreatedate' => 1, 3585 6183 'transformedimagetitle' => 1, 3586 6184 'transformmodifydate' => 1, 3587 6185 'transformnodeid' => 1, 6186 'transformparams' => 1, 3588 6187 'transformtitle' => 1, 3589 6188 'transparency' => 1, 3590 6189 'transparencyindicator' => 1, 3591 6190 '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, 3593 6198 'typeoforiginal' => 1, 6199 'typist' => 1, 3594 6200 'ucrbg' => 1, 6201 'uic1tag' => 1, 6202 'uic2tag' => 1, 6203 'uic3tag' => 1, 6204 'uic4tag' => 1, 3595 6205 'uncompressed' => 1, 6206 'uncompressedsize' => 1, 6207 'underline' => 1, 6208 'underlineposition' => 1, 6209 'underlinethickness' => 1, 3596 6210 'unicodealphanames' => 1, 6211 'uninitializeddatasize' => 1, 3597 6212 'uniquefileidentifier' => 1, 3598 6213 'units' => 1, 3599 6214 '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, 3602 6222 'unknowntags' => 1, 3603 6223 'unsharpdata' => 1, 3604 6224 'unused' => 1, 6225 'ur3' => 1, 3605 6226 'url_list' => 1, 6227 'urn' => 1, 6228 'usagerightsmessage' => 1, 3606 6229 'usedextensionnumbers' => 1, 6230 'useraccess' => 1, 3607 6231 'useradjsba_rgbshifts' => 1, 3608 6232 'userdata' => 1, … … 3613 6237 'userweburl' => 1, 3614 6238 'usingtransforms' => 1, 6239 'usptomiscellaneous' => 1, 6240 'usptooriginalcontenttype' => 1, 3615 6241 'utm' => 1, 3616 6242 'uuid-exif' => 1, 6243 'uuid-flip' => 1, 3617 6244 'uuid-geojp2' => 1, 3618 6245 'uuid-iptc' => 1, 6246 'uuid-prof' => 1, 3619 6247 'uuid-unknown' => 1, 6248 'uuid-usmt' => 1, 3620 6249 'uuid-xmp' => 1, 3621 6250 'uuidinfo' => 1, … … 3623 6252 'validafpoints' => 1, 3624 6253 'vary' => 1, 6254 'vbrbytes' => 1, 6255 'vbrframes' => 1, 3625 6256 'vbrpeak' => 1, 6257 'vbrscale' => 1, 6258 'vegasversionmajor' => 1, 6259 'vegasversionminor' => 1, 3626 6260 'vendor' => 1, 3627 6261 'vendorid' => 1, 6262 'vendorname' => 1, 6263 'vendorurl' => 1, 3628 6264 'version2' => 1, 3629 6265 'versionbf' => 1, 6266 'versionifd' => 1, 3630 6267 'versioninfo' => 1, 3631 6268 'versionyear' => 1, … … 3633 6270 'verticalcstype' => 1, 3634 6271 'verticaldatum' => 1, 6272 'verticaldivergence' => 1, 3635 6273 'verticalunits' => 1, 3636 'vibrationreduction' => 1,3637 6274 'video' => 1, 6275 'videoattributes' => 1, 6276 'videoavgbitrate' => 1, 6277 'videoavgframerate' => 1, 3638 6278 'videobitrate' => 1, 3639 6279 'videocardgamma' => 1, … … 3641 6281 'videocodecdescription' => 1, 3642 6282 'videocodecid' => 1, 6283 'videocodecinfo' => 1, 3643 6284 'videocodecname' => 1, 3644 6285 'videoencoding' => 1, 3645 6286 'videoformat' => 1, 6287 'videoframecount' => 1, 6288 'videoheader' => 1, 3646 6289 'videoheight' => 1, 6290 'videomaxbitrate' => 1, 6291 'videomaxframerate' => 1, 3647 6292 'videomode' => 1, 3648 'videoquality' => 1, 6293 'videoprofile' => 1, 6294 'videoprofileversion' => 1, 6295 'videosampledesc' => 1, 6296 'videoscantype' => 1, 3649 6297 'videosize' => 1, 6298 'videostreamtype' => 1, 6299 'videotrackid' => 1, 3650 6300 'videowidth' => 1, 3651 6301 'viewable' => 1, … … 3655 6305 'viewingconditions' => 1, 3656 6306 'viewingcondsurround' => 1, 6307 'viewtype' => 1, 6308 'vignettingcorr' => 1, 6309 'vignettingcorr2' => 1, 6310 'virtualimageheight' => 1, 6311 'virtualimagewidth' => 1, 6312 'virtualpage' => 1, 6313 'virtualpageunits' => 1, 3657 6314 'visibleoutputs' => 1, 6315 'vistaidlistdata' => 1, 6316 'void' => 1, 6317 'volumeid' => 1, 6318 'volumelabel' => 1, 3658 6319 'vorbiscomment' => 1, 3659 6320 'vorbisversion' => 1, 3660 'vr_0x66' => 1,3661 6321 'vrd1' => 1, 3662 6322 'vrd2' => 1, 3663 6323 'vrdstamptool' => 1, 3664 6324 'vrdversion' => 1, 6325 'vrinfo' => 1, 6326 'vrinfoversion' => 1, 3665 6327 'vw96' => 1, 3666 6328 'wangannotation' => 1, 6329 'wangtag1' => 1, 6330 'wangtag3' => 1, 6331 'wangtag4' => 1, 3667 6332 'warning' => 1, 3668 6333 'watermark' => 1, 3669 6334 'watermarktype' => 1, 3670 'w b_grbglevels' => 1,6335 'watermarkurl' => 1, 3671 6336 '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, 3672 6352 'wbadjdata' => 1, 6353 'wbinfoa100' => 1, 3673 6354 'wcsprofiles' => 1, 6355 'weight' => 1, 3674 6356 'whitebalancematching' => 1, 3675 6357 'whitebalancetable' => 1, 3676 'whitelevel' => 1,3677 6358 'whitepointx' => 1, 3678 6359 'whitepointy' => 1, 6360 'whitesample' => 1, 6361 'whitesamplebits' => 1, 6362 'whitesampleheight' => 1, 6363 'whitesampleleftborder' => 1, 6364 'whitesampletopborder' => 1, 6365 'whitesamplewidth' => 1, 3679 6366 'wide' => 1, 6367 'widthbytes' => 1, 3680 6368 'widthresolution' => 1, 3681 6369 'windowlocation' => 1, 6370 'windoworigin' => 1, 6371 'windoworiginauto' => 1, 6372 'windowsize' => 1, 3682 6373 'windowtarget' => 1, 3683 6374 'wmadrcaveragereference' => 1, … … 3688 6379 'wmcollectionid' => 1, 3689 6380 'wmcontentid' => 1, 3690 'word count' => 1,6381 'words' => 1, 3691 6382 'workflowurl' => 1, 6383 'workingdirectory' => 1, 3692 6384 'workingpath' => 1, 6385 'worldtime' => 1, 3693 6386 'writer' => 1, 6387 'writingapp' => 1, 6388 'writtenby' => 1, 6389 'wwsfamilyname' => 1, 6390 'wwssubfamilyname' => 1, 6391 'x' => 1, 6392 'xcfversion' => 1, 3694 6393 'xclippathunits' => 1, 6394 'xheight' => 1, 3695 6395 'xmag' => 1, 3696 6396 'xmethod' => 1, … … 3700 6400 'xmpbj' => 1, 3701 6401 'xmpdm' => 1, 6402 'xmpextension' => 1, 3702 6403 'xmpmm' => 1, 6404 'xmpnote' => 1, 3703 6405 'xmpplus' => 1, 3704 6406 'xmprights' => 1, 3705 6407 'xmptpg' => 1, 6408 'xp_dip_xml' => 1, 3706 6409 'xylocation' => 1, 3707 6410 'xyoffsetinfo' => 1, 6411 'yawangle' => 1, 3708 6412 'yclippathunits' => 1, 3709 6413 'year' => 1, … … 3712 6416 'ymethod' => 1, 3713 6417 '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, 3714 6426 'zoom' => 1, 6427 'zoomedpreviewimage' => 1, 3715 6428 'zoompos' => 1, 3716 6429 ); … … 3718 6431 # module names for writable Composite tags 3719 6432 my %compositeModules = ( 6433 'filenumber' => 'Image::ExifTool::Canon', 3720 6434 'jpgfromraw' => 'Image::ExifTool::Exif', 6435 'originaldecisiondata' => 'Image::ExifTool::Canon', 3721 6436 'previewimage' => 'Image::ExifTool::Exif', 3722 6437 'thumbnailimage' => 'Image::ExifTool::Exif', … … 3725 6440 #++++ End automatically generated code ++++ 3726 6441 6442 my %specialStruct = ( 6443 NAMESPACE => 1, 6444 STRUCT_NAME => 1, 6445 TYPE => 1, 6446 NOTES => 1, 6447 ); 6448 3727 6449 # insert any user-defined tags into our tag lookup 3728 6450 if (%Image::ExifTool::UserDefined) { 3729 my ($table, %tableNum, $tagID);3730 my $tnum = 0; # make hash lookup to get table numbers3731 foreach $table (@tableList) {3732 $tableNum{$table} = $tnum++;3733 }3734 6451 my @userTables = sort keys %Image::ExifTool::UserDefined; 3735 6452 while (@userTables) { 3736 6453 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 6459 if (@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 6475 sub 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 6512 my %tableNumHash; 6513 sub 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 3739 6530 $tnum = scalar @tableList; 3740 6531 push @tableList, $table; 3741 6532 } 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}; 3745 6536 if (ref $newInfo eq 'HASH') { 3746 6537 $$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}; 3747 6540 } else { 3748 $newInfo = $$ userTable{$tagID} = { Name => $newInfo };6541 $newInfo = $$tagTablePtr{$tagID} = { Name => $newInfo }; 3749 6542 } 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 3752 6550 # (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; 6551 Tags: 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; 3764 6581 } 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}; 3770 6587 no strict 'refs'; 3771 6588 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; 3776 6594 } 6595 $table = shift @moreTables or last; 6596 $tagTablePtr = $moreTableRefs{$table}; 3777 6597 } 3778 6598 } … … 3804 6624 foreach $tableNum (keys %$lookup) { 3805 6625 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 } 3810 6639 } else { 3811 push @tagIDs, $tagID;6640 $tagIDs = [ $le ]; 3812 6641 } 3813 foreach $tagID (@ tagIDs) {6642 foreach $tagID (@$tagIDs) { 3814 6643 my @infoList = GetTagInfoList($table,$tagID); 3815 6644 unless (@infoList) { … … 3862 6691 =head1 AUTHOR 3863 6692 3864 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)6693 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 3865 6694 3866 6695 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/TagNames.pod
r16842 r24107 7 7 8 8 This document contains a complete list of ExifTool tag names, organized into 9 tables based on information type. Tag names are used to indicate the10 specific meta information that is extracted or written in an image.9 tables based on information type. Tag names are used to reference specific 10 meta information extracted from or written to a file. 11 11 12 12 =head1 TAG TABLES … … 24 24 tag ID. In these cases, the actual name used depends on the context in 25 25 which 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 not27 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 some29 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>.26 question mark (C<?>) after a tag name indicates that the information is 27 either not understood, not verified, or not very useful -- these tags are 28 not extracted by ExifTool unless the Unknown (-u) option is enabled. Be 29 aware that some tag names are different than the descriptions printed out by 30 default when extracting information with exiftool. To see the tag names 31 instead of the descriptions, use C<exiftool -s>. 32 32 33 33 The B<Writable> column indicates whether the tag is writable by ExifTool. … … 40 40 (including a null terminator which is added if required). 41 41 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. 42 A 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 44 added and deleted. A slash (C</>) indicates an "avoided" tag that is not 45 created when writing if another same-named tag may be created instead. To 46 write these tags, the group should be specified. A tilde (C<~>) indicates a 47 tag this is writable only when the print conversion is disabled (by setting 48 PrintConv to 0, using the -n option, or suffixing the tag name with a C<#> 49 character). An exclamation point (C<!>) indicates a tag that is considered 50 unsafe to write under normal circumstances. These "unsafe" tags are not set 51 when calling SetNewValuesFromFile() or copied with the exiftool 52 -tagsFromFile option unless specified explicitly, and care should be taken 53 when editing them manually since they may affect the way an image is 54 rendered. An asterisk (C<*>) indicates a "protected" tag which is not 55 writable directly, but is written automatically by ExifTool (often when a 56 corresponding Composite or Extra tag is written). A colon (C<:>) indicates 57 a mandatory tag which may be added automatically when writing. 58 59 The HTML version of these tables also lists possible B<Values> for 60 discrete-valued tags, as well as B<Notes> for some tags. The B<Values> are 61 listed as the computer-readable and human-readable values on the left and 62 right hand side of an equals sign (C<=>) respectively. The human-readable 63 values are used by default when reading and writing, but the 64 computer-readable values may be accessed by disabling the value conversion 65 with the -n option on the command line, by setting the ValueConv option to 0 66 in the API, or or on a per-tag basis by appending a number symbol (C<#>) to 67 the tag name. 57 68 58 69 B<Note>: If you are familiar with common meta-information tag names, you may … … 72 83 JFXX JFIF Extension 73 84 CIFF CanonRaw 85 AVI1 JPEG AVI1 86 Ocad JPEG Ocad 74 87 'APP1' EXIF EXIF 88 ExtendedXMP XMP 75 89 XMP XMP 90 QVCI Casio QVCI 76 91 'APP2' ICC_Profile ICC_Profile 77 92 FPXR FlashPix 93 MPF MPF 94 PreviewImage N 78 95 'APP3' Meta Kodak Meta 96 Stim Stim 97 PreviewImage N 98 'APP4' Scalado JPEG Scalado 99 FPXR FlashPix 100 PreviewImage N 79 101 'APP5' RMETA Ricoh RMETA 80 102 'APP6' EPPIM JPEG EPPIM 103 NITF JPEG NITF 104 HP_TDHD HP TDHD 81 105 'APP8' SPIFF JPEG SPIFF 82 106 'APP10' Comment N … … 88 112 'APP15' GraphicConverter JPEG GraphConv 89 113 'COM' Comment Y 114 'DQT' DefineQuantizationTable N 90 115 'SOF' StartOfFrame JPEG SOF 91 116 'Trailer' AFCP AFCP … … 96 121 PreviewImage Y 97 122 123 =head3 JPEG AVI1 Tags 124 125 This 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 133 Tags extracted from the JPEG APP0 "Ocad" segment (found in Photobucket 134 images). 135 136 Tag ID Tag Name Writable 137 ------ -------- -------- 138 'Rev' OcadRevision N 139 140 =head3 JPEG Scalado Tags 141 142 Tags extracted from the JPEG APP4 "SCALADO" segment (presumably written by 143 Scalado 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 98 152 =head3 JPEG EPPIM Tags 99 153 … … 105 159 0xc4a5 PrintIM PrintIM 106 160 161 =head3 JPEG NITF Tags 162 163 Information in APP6 used by the National Imagery Transmission Format. See 164 L<http://www.gwg.nga.mil/ntb/baseline/docs/n010697/bwcguide25aug98.pdf> for 165 the 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 107 182 =head3 JPEG SPIFF Tags 108 183 109 184 This information is found in APP8 of SPIFF-style JPEG images (the "official" 110 185 yet rarely used JPEG file format standard: Still Picture Interchange File 111 Format). 186 Format). See L<http://www.jpeg.org/public/spiff.pdf> for the official 187 specification. 112 188 113 189 Index Tag Name Writable … … 171 247 EXIF stands for "Exchangeable Image File Format". This type of information 172 248 is 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. 249 TIFF, PNG, PGF, MIFF, HDP, PSP and XCF images, as well as many TIFF-based 250 RAW images, and even some AVI and MOV videos. 174 251 175 252 The EXIF meta information is organized into different Image File Directories … … 178 255 B<Group> listed below is used unless another group is specified. 179 256 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. 257 The table below lists all EXIF tags. Also listed are TIFF, DNG, HDP and 258 other tags which are not part of the EXIF specification, but may co-exist 259 with EXIF tags in some images. Tags which are part of the EXIF 2.3 260 specification have an underlined B<Tag Name> in the HTML version of this 261 documentation. See 262 L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-008-2010_E.pdf> for the 263 official EXIF 2.3 specification. 183 264 184 265 Tag ID Tag Name Group Writable 185 266 ------ -------- ----- -------- 186 267 0x0001 InteropIndex InteropIFD string! 187 0x0002 InteropVersion InteropIFD undef! 268 0x0002 InteropVersion InteropIFD undef!: 188 269 0x000b ProcessingSoftware IFD0 string 189 270 0x00fe SubfileType IFD0 int32u! … … 192 273 0x0101 ImageHeight IFD0 int32u! 193 274 0x0102 BitsPerSample IFD0 int16u[n]! 194 0x0103 Compression IFD0 int16u! 275 0x0103 Compression IFD0 int16u!: 195 276 0x0106 PhotometricInterpretation IFD0 int16u! 196 277 0x0107 Thresholding IFD0 int16u! … … 215 296 0x0118 MinSampleValue IFD0 int16u 216 297 0x0119 MaxSampleValue IFD0 int16u 217 0x011a XResolution IFD0 rational64u 218 0x011b YResolution IFD0 rational64u 298 0x011a XResolution IFD0 rational64u: 299 0x011b YResolution IFD0 rational64u: 219 300 0x011c PlanarConfiguration IFD0 int16u! 220 301 0x011d PageName IFD0 string … … 227 308 0x0124 T4Options - N 228 309 0x0125 T6Options - N 229 0x0128 ResolutionUnit IFD0 int16u 310 0x0128 ResolutionUnit IFD0 int16u: 230 311 0x0129 PageNumber IFD0 int16u[2] 231 312 0x012c ColorResponseUnit - N 232 0x012d TransferFunction - N313 0x012d TransferFunction IFD0 int16u[768]! 233 314 0x0131 Software IFD0 string 234 315 0x0132 ModifyDate IFD0 string … … 248 329 0x0148 ConsecutiveBadFaxLines - N 249 330 0x014a SubIFD - EXIF 331 A100DataOffset - N 250 332 0x014c InkSet IFD0 int16u 251 333 0x014d InkNames - N … … 272 354 0x01b1 Decode - N 273 355 0x01b2 DefaultImageColor - N 356 0x01b3 T82Options - N 357 0x01b5 JPEGTables - N 274 358 0x0200 JPEGProc - N 275 359 0x0201 ThumbnailOffset IFD1 int32u* 360 ThumbnailOffset IFD0 int32u* 361 ThumbnailOffset SubIFD int32u* 276 362 PreviewImageStart MakerNotes int32u* 363 PreviewImageStart IFD0 int32u* 277 364 JpgFromRawStart SubIFD int32u* 278 365 JpgFromRawStart IFD2 int32u* 279 366 OtherImageStart - N 280 367 0x0202 ThumbnailLength IFD1 int32u* 368 ThumbnailLength IFD0 int32u* 369 ThumbnailLength SubIFD int32u* 281 370 PreviewImageLength MakerNotes int32u* 371 PreviewImageLength IFD0 int32u* 282 372 JpgFromRawLength SubIFD int32u* 283 373 JpgFromRawLength IFD2 int32u* … … 291 381 0x0211 YCbCrCoefficients IFD0 rational64u[3]! 292 382 0x0212 YCbCrSubSampling IFD0 int16u[2]! 293 0x0213 YCbCrPositioning IFD0 int16u! 383 0x0213 YCbCrPositioning IFD0 int16u!: 294 384 0x0214 ReferenceBlackWhite IFD0 rational64u[6] 295 385 0x022f StripRowCounts - N 296 0x02bc ApplicationNotes - XMP 386 0x02bc ApplicationNotes ExifIFD XMP 387 0x03e7 USPTOMiscellaneous - N 297 388 0x1000 RelatedImageFileFormat InteropIFD string! 298 389 0x1001 RelatedImageWidth InteropIFD int16u! 299 0x1002 RelatedImage LengthInteropIFD int16u!390 0x1002 RelatedImageHeight InteropIFD int16u! 300 391 0x4746 Rating IFD0 int16u/ 392 0x4747 XP_DIP_XML - N 393 0x4748 StitchInfo - Microsoft Stitch 301 394 0x4749 RatingPercent IFD0 int16u/ 302 395 0x800d ImageID - N 396 0x80a3 WangTag1 - N 303 397 0x80a4 WangAnnotation - N 398 0x80a5 WangTag3 - N 399 0x80a6 WangTag4 - N 304 400 0x80e3 Matteing - N 305 401 0x80e4 DataType - N … … 310 406 0x828e CFAPattern2 - N 311 407 0x828f BatteryLevel - N 408 0x8290 KodakIFD - Kodak IFD 312 409 0x8298 Copyright IFD0 string 313 410 0x829a ExposureTime ExifIFD rational64u … … 322 419 0x82ac MDFileUnits - N 323 420 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 324 427 0x83bb IPTC-NAA IFD0 IPTC 325 428 0x847e IntergraphPacketData - N 326 429 0x847f IntergraphFlagRegisters - N 327 430 0x8480 IntergraphMatrix - N 431 0x8481 INGRReserved - N 328 432 0x8482 ModelTiePoint - N 329 433 0x84e0 Site - N … … 342 446 0x84ed ColorCharacterization - N 343 447 0x84ee HCUsage - N 448 0x84ef TrapIndicator - N 449 0x84f0 CMYKEquivalent - N 344 450 0x8546 SEMInfo IFD0 string 345 451 0x8568 AFCP_IPTC - IPTC 452 0x85b8 PixelMagicJBIGOptions - N 346 453 0x85d8 ModelTransform - N 454 0x8602 WB_GRGBLevels - N 347 455 0x8606 LeafData - Leaf 348 456 0x8649 PhotoshopSettings - Photoshop 349 457 0x8769 ExifOffset - EXIF 350 458 0x8773 ICC_Profile - ICC_Profile 459 0x877f TIFF_FXExtensions - N 460 0x8780 MultiProfiles - N 461 0x8781 SharedData - N 462 0x8782 T88Options - N 351 463 0x87ac ImageLayer - N 352 464 0x87af GeoTiffDirectory - N … … 356 468 0x8824 SpectralSensitivity ExifIFD string 357 469 0x8825 GPSInfo - GPS 358 0x8827 ISO ExifIFD int16u 470 0x8827 ISO ExifIFD int16u[n] 359 471 0x8828 Opto-ElectricConvFactor - N 360 472 0x8829 Interlace - N 361 473 0x882a TimeZoneOffset ExifIFD int16s[n] 362 474 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 363 481 0x885c FaxRecvParams - N 364 482 0x885d FaxSubAddress - N 365 483 0x885e FaxRecvTime - N 366 484 0x888a LeafSubIFD - Leaf SubIFD 367 0x9000 ExifVersion ExifIFD undef 485 0x9000 ExifVersion ExifIFD undef: 368 486 0x9003 DateTimeOriginal ExifIFD string 369 487 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! 372 490 0x9201 ShutterSpeedValue ExifIFD rational64s 373 491 0x9202 ApertureValue ExifIFD rational64u … … 389 507 0x9212 SecurityClassification ExifIFD string 390 508 0x9213 ImageHistory ExifIFD string 391 0x9214 Subject Location ExifIFD int16u[4]509 0x9214 SubjectArea ExifIFD int16u[n] 392 510 0x9215 ExposureIndex - N 393 511 0x9216 TIFF-EPStandardID - N 394 512 0x9217 SensingMethod - N 513 0x923a CIP3DataFile - N 514 0x923b CIP3Sheet - N 515 0x923c CIP3Side - N 395 516 0x923f StoNits - N 396 517 0x927c MakerNoteCanon ExifIFD Canon … … 398 519 MakerNoteCasio2 ExifIFD Casio Type2 399 520 MakerNoteFujiFilm ExifIFD FujiFilm 521 MakerNoteGE ExifIFD GE 522 MakerNoteGE2 ExifIFD FujiFilm 400 523 MakerNoteHP ExifIFD HP 401 524 MakerNoteHP2 ExifIFD HP Type2 402 525 MakerNoteHP4 ExifIFD HP Type4 403 526 MakerNoteHP6 ExifIFD HP Type6 527 MakerNoteISL ExifIFD Unknown 404 528 MakerNoteJVC ExifIFD JVC 405 529 MakerNoteJVCText ExifIFD JVC Text … … 413 537 MakerNoteKodak6b ExifIFD Kodak Type6 414 538 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 416 543 MakerNoteKodakUnknown ExifIFD Kodak Unknown 417 544 MakerNoteKyocera ExifIFD Unknown … … 425 552 MakerNoteOlympus2 ExifIFD Olympus 426 553 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 427 559 MakerNotePanasonic ExifIFD Panasonic 428 560 MakerNotePanasonic2 ExifIFD Panasonic Type2 … … 431 563 MakerNotePentax3 ExifIFD Casio Type2 432 564 MakerNotePentax4 ExifIFD Pentax Type4 565 MakerNotePentax5 ExifIFD Pentax 566 MakerNotePhaseOne ExifIFD undef 567 MakerNoteReconyx ExifIFD Reconyx 433 568 MakerNoteRicoh ExifIFD Ricoh 434 569 MakerNoteRicohText ExifIFD Ricoh Text 435 PreviewImage ExifIFD undef 570 MakerNoteSamsung1a ExifIFD undef 571 MakerNoteSamsung1b ExifIFD Samsung Type1 572 MakerNoteSamsung2 ExifIFD Samsung Type2 436 573 MakerNoteSanyo ExifIFD Sanyo 437 574 MakerNoteSanyoC4 ExifIFD Sanyo … … 439 576 MakerNoteSigma ExifIFD Sigma 440 577 MakerNoteSony ExifIFD Sony 578 MakerNoteSony2 ExifIFD Olympus 579 MakerNoteSony3 ExifIFD Olympus 580 MakerNoteSony4 ExifIFD Sony 581 MakerNoteSonyEricsson ExifIFD Sony Ericsson 441 582 MakerNoteSonySRF ExifIFD Sony SRF 442 MakerNote SonySR2 ExifIFD Sony583 MakerNoteUnknownText ExifIFD undef 443 584 MakerNoteUnknown ExifIFD Unknown 444 585 0x9286 UserComment ExifIFD undef … … 446 587 0x9291 SubSecTimeOriginal ExifIFD string 447 588 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! 449 593 0x9c9b XPTitle IFD0 int8u 450 594 0x9c9c XPComment IFD0 int8u … … 452 596 0x9c9e XPKeywords IFD0 int8u 453 597 0x9c9f XPSubject IFD0 int8u 454 0xa000 FlashpixVersion ExifIFD undef 455 0xa001 ColorSpace ExifIFD int16u 456 0xa002 ExifImageWidth ExifIFD int16u 457 0xa003 ExifImage Length ExifIFD int16u598 0xa000 FlashpixVersion ExifIFD undef: 599 0xa001 ColorSpace ExifIFD int16u: 600 0xa002 ExifImageWidth ExifIFD int16u: 601 0xa003 ExifImageHeight ExifIFD int16u: 458 602 0xa004 RelatedSoundFile ExifIFD string 459 603 0xa005 InteropOffset - EXIF … … 487 631 0xa40c SubjectDistanceRange ExifIFD int16u 488 632 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 489 639 0xa480 GDALMetadata - N 490 640 0xa481 GDALNoData - N 491 641 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 492 648 0xbc01 PixelFormat - N 493 0xbc02 Transfo mation- N649 0xbc02 Transformation - N 494 650 0xbc03 Uncompressed - N 495 651 0xbc04 ImageType - N … … 510 666 0xc44f Annotations - N 511 667 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]! 514 671 0xc614 UniqueCameraModel IFD0 string 515 672 0xc615 LocalizedCameraModel IFD0 string … … 517 674 0xc617 CFALayout - N 518 675 0xc618 LinearizationTable - N 519 0xc619 BlackLevelRepeatDim - N520 0xc61a BlackLevel - N676 0xc619 BlackLevelRepeatDim SubIFD int16u[2]! 677 0xc61a BlackLevel SubIFD rational64u[n]! 521 678 0xc61b BlackLevelDeltaH - N 522 679 0xc61c BlackLevelDeltaV - N 523 0xc61d WhiteLevel - N524 0xc61e DefaultScale SubIFD rational64u[2] 525 0xc61f DefaultCropOrigin SubIFD int32u[2] 526 0xc620 DefaultCropSize SubIFD int32u[2] 527 0xc621 ColorMatrix1 - N528 0xc622 ColorMatrix2 - N529 0xc623 CameraCalibration1 - N530 0xc624 CameraCalibration2 - N531 0xc625 ReductionMatrix1 - N532 0xc626 ReductionMatrix2 - N533 0xc627 AnalogBalance - N534 0xc628 AsShotNeutral - N535 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! 541 698 0xc62f CameraSerialNumber IFD0 string 542 699 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! 546 703 0xc634 SR2Private - Sony SR2Private 547 704 DNGAdobeData - DNG AdobeData 548 DNGPentaxData- Pentax705 MakerNotePentax - Pentax 549 706 DNGPrivateData - N 550 707 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]! 555 713 0xc660 AliasLayerMetadata - N 556 0xc68b OriginalRawFileName IFD0 string 714 0xc68b OriginalRawFileName IFD0 string! 557 715 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]! 560 718 0xc68f AsShotICCProfile IFD0 ICC_Profile 561 719 0xc690 AsShotPreProfileMatrix IFD0 rational64s[n]! 562 720 0xc691 CurrentICCProfile IFD0 ICC_Profile 563 721 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 564 756 0xea1d OffsetSchema ExifIFD int32s 565 757 0xfde8 OwnerName ExifIFD string/ 566 758 0xfde9 SerialNumber ExifIFD string/ 567 759 0xfdea Lens ExifIFD string/ 760 0xfe00 KDC_IFD - Kodak KDC_IFD 568 761 0xfe4c RawFile ExifIFD string/ 569 762 0xfe4d Converter ExifIFD string/ … … 580 773 =head2 IPTC Tags 581 774 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. 775 The tags listed below are part of the International Press Telecommunications 776 Council (IPTC) and the Newspaper Association of America (NAA) Information 777 Interchange Model (IIM). This is an older meta information format, slowly 778 being phased out in favor of XMP. (In fact, the newer IPTCCore 779 specification actually uses XMP format!) IPTC information may be embedded 780 in JPG, TIFF, PNG, MIFF, PS, PDF, PSD, XCF and DNG images. 592 781 593 782 IPTC information is separated into different records, each of which has its 594 own set of tags. 783 own set of tags. See 784 L<http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf> for the 785 official specification. 786 787 This specification dictates a length for ASCII (C<string> or C<digits>) and 788 binary (C<undef>) values. These lengths are given in square brackets after 789 the B<Writable> format name. For tags where a range of lengths is allowed, 790 the minimum and maximum lengths are separated by a comma within the 791 brackets. IPTC strings are not null terminated. When writing, ExifTool 792 issues a minor warning and truncates the value if it is longer than allowed 793 by the IPTC specification. Minor errors may be ignored with the 794 IgnoreMinorErrors (-m) option, allowing longer values to be written, but 795 beware that values like this may cause problems for some other IPTC readers. 796 797 Separate IPTC date and time tags may be written with a combined date/time 798 value and ExifTool automagically takes the appropriate part of the date/time 799 string depending on whether a date or time tag is being written. This is 800 very useful when copying date/time values to IPTC from other metadata 801 formats. 802 803 IPTC time values include a timezone offset. If written with a value which 804 doesn'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 806 offset at the specified date/time is used, which may be different due to 807 changes in daylight savings time). 595 808 596 809 Record Tag Name Writable … … 602 815 8 IPTCObjectData IPTC ObjectData 603 816 9 IPTCPostObjectData IPTC PostObjectData 817 240 IPTCFotoStation IPTC FotoStation 604 818 605 819 =head3 IPTC EnvelopeRecord Tags … … 607 821 Tag ID Tag Name Writable 608 822 ------ -------- -------- 609 0 EnvelopeRecordVersion int16u 823 0 EnvelopeRecordVersion int16u: 610 824 5 Destination string[0,1024]+ 611 825 20 FileFormat int16u … … 617 831 70 DateSent digits[8] 618 832 80 TimeSent string[11] 619 90 CodedCharacterSet string[0,32] 833 90 CodedCharacterSet string[0,32]! 620 834 100 UniqueObjectName string[14,80] 621 835 120 ARMIdentifier int16u … … 626 840 Tag ID Tag Name Writable 627 841 ------ -------- -------- 628 0 ApplicationRecordVersion int16u 842 0 ApplicationRecordVersion int16u: 629 843 3 ObjectTypeReference string[3,67] 630 844 4 ObjectAttributeReference string[4,68]+ … … 672 886 121 LocalCaption string[0,256] 673 887 122 Writer-Editor string[0,32]+ 674 125 RasterizedCaption string[7360]888 125 RasterizedCaption undef[7360] 675 889 130 ImageType string[2] 676 890 131 ImageOrientation string[1] … … 688 902 200 ObjectPreviewFileFormat int16u 689 903 201 ObjectPreviewFileVersion int16u 690 202 ObjectPreviewData string[0,256000]904 202 ObjectPreviewData undef[0,256000] 691 905 221 Prefs string[0,64] 692 906 225 ClassifyState string[0,64] … … 695 909 231 DocumentHistory string[0,256] 696 910 232 ExifCameraInfo string[0,4096] 911 255 CatalogSets string[0,256]+ 697 912 698 913 =head3 IPTC NewsPhoto Tags … … 700 915 Tag ID Tag Name Writable 701 916 ------ -------- -------- 702 0 NewsPhotoVersion int16u 917 0 NewsPhotoVersion int16u: 703 918 10 IPTCPictureNumber string[16] 704 919 20 IPTCImageWidth int16u … … 748 963 10 ConfirmedObjectSize N 749 964 965 =head3 IPTC FotoStation Tags 966 967 Tag ID Tag Name Writable 968 ------ -------- -------- 969 [no tags known] 970 750 971 =head2 XMP Tags 751 972 752 973 XMP stands for "Extensible Metadata Platform", an XML/RDF-based metadata 753 974 format 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. 975 embedded in many different image file types including JPG, JP2, TIFF, GIF, 976 EPS, PDF, PSD, IND, PNG, DJVU, SVG, PGF, MIFF, XCF, CRW, DNG and a variety 977 of proprietary TIFF-based RAW images, as well as MOV, AVI, ASF, WMV, FLV, 978 SWF and MP4 videos, and WMA and audio formats supporting ID3v2 information. 757 979 758 980 The XMP B<Tag ID>'s aren't listed because in most cases they are identical 759 to the B<Tag Name>. 981 to the B<Tag Name> (aside from differences in case). Tags with different 982 ID's are mentioned in the B<Notes> column of the HTML version of this 983 document. 760 984 761 985 All 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. 986 specifies the information format: C<string> is an unformatted string, 987 C<integer> is a string of digits (possibly beginning with a '+' or '-'), 988 C<real> is a floating point number, C<rational> is entered as a floating 989 point number but stored as two C<integer> strings separated by a '/' 990 character, C<date> is a date/time string entered in the format "YYYY:mm:dd 991 HH:MM:SS[.ss][+/-HH:MM]", C<boolean> is either "True" or "False", 992 C<lang-alt> indicates that the tag supports alternate languages (see below), 993 and C<struct> is an XMP structure. When reading, structures are extracted 994 only if the Struct (-struct) option is used. Otherwise the corresponding 995 "flattened" tags, indicated by an underline (C<_>) after the B<Writable> 996 type, are extracted. When copying information, the Struct option is in 997 effect by default. When writing, the Struct option has no effect, and both 998 structured and flattened tags may be written. See 999 L<http://owl.phy.queensu.ca/~phil/exiftool/struct.html> for more details. 768 1000 769 1001 Individual languages for C<lang-alt> tags are accessed by suffixing the tag 770 1002 name 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 the772 "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 w rite only the default language, but note that all languages are still775 deleted if "x-default" tag is deleted. When reading, "x-default" is not 776 specified.1003 or "Rights-en-US"). (See L<http://www.ietf.org/rfc/rfc3066.txt> for the RFC 1004 3066 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 1006 when writing. The "x-default" language code may be specified when writing 1007 to preserve other existing languages (ie. "XMP-dc:Description-x-default"). 1008 When reading, "x-default" is not specified. 777 1009 778 1010 The XMP tags are organized according to schema B<Namespace> in the following … … 782 1014 more than one namespace, less common namespaces are avoided when writing. 783 1015 However, any namespace may be written by specifying a family 1 group name 784 for the tag, ie) XMP-exif:Contrast or XMP-crs:Contrast. 1016 for the tag, ie) XMP-exif:Contrast or XMP-crs:Contrast. When deciding on 1017 which tags to add to an image, using standard schemas such as 1018 L<dc|/XMP dc Tags>, L<xmp|/XMP xmp Tags> or L<iptc|/XMP iptcCore Tags> is 1019 recommended if possible. 1020 1021 For structures, the heading of the first column is B<Field Name>. Field 1022 names are very similar to tag names, except they are used to identify fields 1023 inside structures instead of stand-alone tags. See 1024 L<http://owl.phy.queensu.ca/~phil/exiftool/struct.html#Fields> for more 1025 details. 785 1026 786 1027 ExifTool will extract XMP information even if it is not listed in these 787 1028 tables. For example, the C<pdfx> namespace doesn't have a predefined set of 788 1029 tag names because it is used to store application-defined PDF information, 789 but this information is extracted by ExifTool anyway. 1030 but this information is extracted by ExifTool. 1031 1032 See L<http://www.adobe.com/devnet/xmp/> for the official XMP specification. 790 1033 791 1034 Namespace Writable 792 1035 --------- -------- 1036 acdsee XMP acdsee 1037 album XMP Album 793 1038 aux XMP aux 794 1039 cc XMP cc 1040 cell XMP cell 795 1041 crs XMP crs 796 1042 dc XMP dc 797 1043 dex XMP dex 798 1044 DICOM XMP DICOM 1045 digiKam XMP digiKam 799 1046 exif XMP exif 800 1047 iptcCore XMP iptcCore 1048 iptcExt XMP iptcExt 801 1049 lr XMP Lightroom 802 1050 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 804 1057 pdf XMP pdf 1058 pdfx XMP pdfx 805 1059 photomech PhotoMechanic XMP 806 1060 photoshop XMP photoshop 807 1061 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 808 1068 tiff XMP tiff 1069 x XMP x 809 1070 xmp XMP xmp 810 1071 xmpBJ XMP xmpBJ 811 1072 xmpDM XMP xmpDM 812 1073 xmpMM XMP xmpMM 1074 xmpNote XMP xmpNote 813 1075 xmpPLUS XMP xmpPLUS 814 1076 xmpRights XMP xmpRights 815 1077 xmpTPg XMP xmpTPg 816 1078 817 =head3 XMP aux Tags 818 819 Photoshop Auxiliary schema tags. 1079 =head3 XMP acdsee Tags 1080 1081 ACD Systems ACDSee schema tags. 1082 1083 (A note to software developers: Re-inventing your own private tags instead 1084 of using the equivalent tags in standard XMP schemas defeats one of the most 1085 valuable features of metadata: interoperability. Your applications mumble 1086 to themselves instead of speaking out for the rest of the world to hear.) 820 1087 821 1088 Tag Name Writable 822 1089 -------- -------- 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 1102 Adobe Album schema tags. 1103 1104 Tag Name Writable 1105 -------- -------- 1106 Notes string 1107 1108 =head3 XMP aux Tags 1109 1110 Photoshop Auxiliary schema tags. 1111 1112 Tag Name Writable 1113 -------- -------- 1114 ApproximateFocusDistance rational 823 1115 Firmware string 824 1116 FlashCompensation rational 825 1117 ImageNumber string 826 1118 Lens string 1119 LensID string 827 1120 LensInfo string 828 1121 OwnerName string … … 831 1124 =head3 XMP cc Tags 832 1125 833 Creative Commons schema tags. 1126 Creative Commons schema tags. (see 1127 L<http://creativecommons.org/technology/xmp>) 834 1128 835 1129 Tag Name Writable 836 1130 -------- -------- 1131 AttributionName string 1132 AttributionURL string 837 1133 License string 1134 MorePermissions string 1135 1136 =head3 XMP cell Tags 1137 1138 Location 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 838 1148 839 1149 =head3 XMP crs Tags … … 857 1167 Clarity integer 858 1168 ColorNoiseReduction integer 1169 ColorNoiseReductionDetail integer 859 1170 Contrast integer/ 1171 Converter string 860 1172 ConvertToGrayscale boolean 861 1173 CropAngle real 862 1174 CropBottom real 1175 CropConstrainToWarp integer 863 1176 CropHeight real 864 1177 CropLeft real 865 1178 CropRight real 866 1179 CropTop real 1180 CropUnit integer 867 1181 CropUnits integer 868 1182 CropWidth real … … 870 1184 Exposure real 871 1185 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 872 1220 GreenHue integer 873 1221 GreenSaturation integer … … 885 1233 IncrementalTemperature integer 886 1234 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 887 1244 LuminanceAdjustmentAqua integer 888 1245 LuminanceAdjustmentBlue integer … … 893 1250 LuminanceAdjustmentRed integer 894 1251 LuminanceAdjustmentYellow integer 1252 LuminanceNoiseReductionContrast integer 1253 LuminanceNoiseReductionDetail integer 895 1254 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_ 896 1279 ParametricDarks integer 897 1280 ParametricHighlights integer … … 901 1284 ParametricShadows integer 902 1285 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 903 1296 RawFileName string 1297 RedEyeInfo string+ 904 1298 RedHue integer 905 1299 RedSaturation integer 1300 RetouchInfo string+ 906 1301 Saturation integer/ 907 1302 SaturationAdjustmentAqua integer … … 919 1314 SharpenRadius real 920 1315 Sharpness integer/ 1316 Smoothness integer 921 1317 SplitToningBalance integer 922 1318 SplitToningHighlightHue integer … … 924 1320 SplitToningShadowHue integer 925 1321 SplitToningShadowSaturation integer 926 Temperature integer1322 ColorTemperature integer/ 927 1323 Tint integer 928 1324 ToneCurve string+ … … 933 1329 VignetteMidpoint integer 934 1330 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 935 1363 936 1364 =head3 XMP dc Tags … … 951 1379 Relation string+ 952 1380 Rights lang-alt 953 Source string 1381 Source string/ 954 1382 Subject string+ 955 1383 Title lang-alt … … 960 1388 Description Explorer schema tags. These tags are not very common. The 961 1389 Source and Rating tags are avoided when writing due to name conflicts with 962 other XMP tags. 1390 other XMP tags. (see L<http://www.optimasc.com/products/fileid/>) 963 1391 964 1392 Tag Name Writable … … 981 1409 EquipmentInstitution string 982 1410 EquipmentManufacturer string 983 Patient sBirthDatedate1411 PatientBirthDate date 984 1412 PatientID string 985 Patient sNamestring986 Patient sSexstring1413 PatientName string 1414 PatientSex string 987 1415 SeriesDateTime date 988 1416 SeriesDescription string … … 994 1422 StudyPhysician string 995 1423 1424 =head3 XMP digiKam Tags 1425 1426 DigiKam schema tags. 1427 1428 Tag Name Writable 1429 -------- -------- 1430 CaptionsAuthorNames lang-alt 1431 CaptionsDateTimeStamps lang-alt 1432 TagsList string+ 1433 996 1434 =head3 XMP exif Tags 997 1435 … … 1002 1440 ApertureValue rational 1003 1441 BrightnessValue rational 1004 CFAPatternColumns integer 1005 CFAPatternRows integer 1006 CFAPatternValues integer+ 1442 CFAPattern CFAPattern Struct 1443 CFAPatternColumns integer_ 1444 CFAPatternRows integer_ 1445 CFAPatternValues integer_+ 1007 1446 ColorSpace integer 1008 1447 ComponentsConfiguration integer+ … … 1012 1451 DateTimeDigitized date 1013 1452 DateTimeOriginal date 1014 DeviceSettingDescriptionColumns integer 1015 DeviceSettingDescriptionRows integer 1016 DeviceSettingDescriptionSettings string+ 1453 DeviceSettingDescription DeviceSettings Struct 1454 DeviceSettingDescriptionColumns integer_ 1455 DeviceSettingDescriptionRows integer_ 1456 DeviceSettingDescriptionSettings string_+ 1017 1457 DigitalZoomRatio rational 1018 1458 ExifVersion string … … 1023 1463 ExposureTime rational 1024 1464 FileSource integer 1465 Flash Flash Struct 1025 1466 FlashEnergy rational 1026 FlashFired boolean 1027 FlashFunction boolean 1028 FlashMode integer 1467 FlashFired boolean_ 1468 FlashFunction boolean_ 1469 FlashMode integer_ 1029 1470 FlashpixVersion string 1030 FlashRedEyeMode boolean 1031 FlashReturn integer 1471 FlashRedEyeMode boolean_ 1472 FlashReturn integer_ 1032 1473 FNumber rational 1033 1474 FocalLength rational … … 1059 1500 GPSSpeedRef string 1060 1501 GPSStatus string 1061 GPS TimeStampdate1502 GPSDateTime date 1062 1503 GPSTrack rational 1063 1504 GPSTrackRef string … … 1070 1511 MeteringMode integer 1071 1512 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_+ 1076 1518 ExifImageWidth integer 1077 ExifImage Lengthinteger1519 ExifImageHeight integer 1078 1520 RelatedSoundFile string 1079 1521 Saturation integer … … 1083 1525 Sharpness integer 1084 1526 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_+ 1089 1532 SpectralSensitivity string 1090 1533 SubjectArea integer+ … … 1095 1538 WhiteBalance integer 1096 1539 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 1097 1575 =head3 XMP iptcCore Tags 1098 1576 1099 IPTC Core schema tags. The actual IPTC Core namespace schemaprefix is1577 IPTC Core schema tags. The actual IPTC Core namespace prefix is 1100 1578 "Iptc4xmpCore", which is the prefix recorded in the file, but ExifTool 1101 shortens this for the "XMP-iptcCore" family 1 group name. 1579 shortens this for the "XMP-iptcCore" family 1 group name. (see 1580 L<http://www.iptc.org/IPTC4XMP/>) 1102 1581 1103 1582 Tag Name Writable 1104 1583 -------- -------- 1105 1584 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_ 1114 1594 IntellectualGenre string 1115 1595 Location string … … 1117 1597 SubjectCode string+ 1118 1598 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 1614 IPTC Extension schema tags. The actual namespace prefix is "Iptc4xmpExt", 1615 but 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 1119 1687 =head3 XMP Lightroom Tags 1120 1688 … … 1128 1696 =head3 XMP MediaPro Tags 1129 1697 1130 IView MediaPro schema tags.1698 iView MediaPro schema tags. 1131 1699 1132 1700 Tag Name Writable … … 1139 1707 UserFields string+ 1140 1708 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 1711 Collections metadata defined by the MWG 2.0 specification. See 1712 L<http://www.metadataworkinggroup.org/> for the official specification. 1147 1713 1148 1714 Tag Name Writable 1149 1715 -------- -------- 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 1729 Hierarchical keywords metadata defined by the MWG 2.0 specification. 1730 ExifTool unrolls keyword structures to an arbitrary depth of 4 to allow 1731 individual levels to be accessed with different tag names, and to avoid 1732 infinite recursion. See L<http://www.metadataworkinggroup.org/> for the 1733 official 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 1790 Image region metadata defined by the MWG 2.0 specification. See 1791 L<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 1857 This structure may contain any top-level XMP tags, but none have been 1858 pre-defined in ExifTool. Without pre-defined flattened tag names, 1859 RegionExtensions may be written only as a structure (ie. 1860 C<{xmp-dc:creator=me,rating=5}>). Fields for this structure are identified 1861 using the standard ExifTool tag name (with optional leading group name, 1862 and/or trailing language code, and/or trailing C<#> symbol to disable print 1863 conversion). 1864 1865 Field Name Writable 1866 ---------- -------- 1867 [no tags known] 1159 1868 1160 1869 =head3 XMP pdf Tags 1161 1870 1162 1871 Adobe PDF schema tags. The official XMP specification defines only 1163 Keywords, PDFVersion and Producer. The other tags are included because they1164 have been observed in PDF files, but Creator, Subject and Title are avoided 1165 w hen writing due to name conflicts with XMP-dc tags.1872 Keywords, PDFVersion, Producer and Trapped. The other tags are included 1873 because they have been observed in PDF files, but some are avoided when 1874 writing due to name conflicts with other XMP namespaces. 1166 1875 1167 1876 Tag Name Writable 1168 1877 -------- -------- 1169 1878 Author string 1879 Copyright string/ 1170 1880 CreationDate date 1171 1881 Creator string/ 1172 1882 Keywords string 1883 Marked boolean/ 1173 1884 ModDate date 1174 1885 PDFVersion string … … 1176 1887 Subject string/ 1177 1888 Title string/ 1889 Trapped string 1890 1891 =head3 XMP pdfx Tags 1892 1893 PDF extension tags. This namespace is used to store application-defined PDF 1894 information, so there are no pre-defined tags. User-defined tags must be 1895 created to enable writing of XMP-pdfx information. 1896 1897 Tag Name Writable 1898 -------- -------- 1899 [no tags known] 1178 1900 1179 1901 =head3 XMP photoshop Tags … … 1187 1909 Category string 1188 1910 City string 1189 ColorMode string1911 ColorMode integer 1190 1912 Country string 1191 1913 Credit string 1192 1914 DateCreated date 1915 DocumentAncestors Ancestor Struct+ 1916 DocumentAncestorID string_+ 1193 1917 Headline string 1194 1918 History string … … 1197 1921 LegacyIPTCDigest string 1198 1922 SidecarForExtension string 1199 Source string /1923 Source string 1200 1924 State string 1201 1925 SupplementalCategories string+ 1926 TextLayers Layer Struct+ 1927 TextLayerName string_+ 1928 TextLayerText string_+ 1202 1929 TransmissionReference string 1203 1930 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 1204 1944 1205 1945 =head3 XMP PixelLive Tags … … 1217 1957 Genre N 1218 1958 Title N 1959 1960 =head3 XMP plus Tags 1961 1962 PLUS License Data Format 1.2.0 schema tags. Note that all 1963 controlled-vocabulary tags in this table (ie. tags with a fixed set of 1964 values) have raw values which begin with "http://ns.useplus.org/ldf/vocab/", 1965 but to reduce clutter this prefix has been removed from the values shown 1966 below. (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 2112 Publishing Requirements for Industry Standard Metadata 2.1 schema tags. (see 2113 L<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 2177 PRISM Rights Language 2.1 schema tags. (see 2178 L<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 2188 Prism 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 2210 Most RDF attributes are handled internally, but the "about" attribute is 2211 treated 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 2219 Adobe SWF schema tags. 2220 2221 Tag Name Writable 2222 -------- -------- 2223 BackgroundAlpha integer 2224 ForwardLock boolean 2225 MaxStorage integer 2226 Type string/ 1219 2227 1220 2228 =head3 XMP tiff Tags … … 1251 2259 YResolution rational 1252 2260 2261 =head3 XMP x Tags 2262 2263 The "x" namespace is used for the "xmpmeta" wrapper, and may contain an 2264 "xmptk" attribute that is extracted as the XMPToolkit tag. When writing, 2265 the XMPToolkit tag is automatically generated by ExifTool unless 2266 specifically set to another value. 2267 2268 Tag Name Writable 2269 -------- -------- 2270 XMPToolkit string! 2271 1253 2272 =head3 XMP xmp Tags 1254 2273 … … 1268 2287 ModifyDate date 1269 2288 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 1275 2320 1276 2321 =head3 XMP xmpBJ Tags … … 1280 2325 Tag Name Writable 1281 2326 -------- -------- 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 1285 2339 1286 2340 =head3 XMP xmpDM Tags … … 1293 2347 Album string 1294 2348 AltTapeName string 1295 AltTimecodeTimeFormat string 1296 AltTimecodeTimeValue string 2349 AltTimecode Timecode Struct 2350 AltTimecodeTimeFormat string_ 2351 AltTimecodeTimeValue string_ 2352 AltTimecodeValue integer_ 1297 2353 Artist string/ 1298 2354 AudioChannelType string … … 1301 2357 AudioSampleRate integer 1302 2358 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 1306 2371 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_+ 1313 2383 Copyright string/ 1314 Duration string 2384 Director string 2385 DirectorPhotography string 2386 Duration Time Struct 2387 DurationScale rational_ 2388 DurationValue integer_ 1315 2389 Engineer string 1316 2390 FileDataRate rational 1317 2391 Genre string 2392 Good boolean 1318 2393 Instrument string 1319 IntroTime string 2394 IntroTime Time Struct 2395 IntroTimeScale rational_ 2396 IntroTimeValue integer_ 1320 2397 Key string 1321 2398 LogComment string 1322 2399 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_+ 1330 2414 MetadataModDate date 1331 2415 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_ 1335 2423 PullDown string 1336 2424 RelativePeakAudioFilePath string 1337 RelativeTimestamp string 2425 RelativeTimestamp Time Struct 2426 RelativeTimestampScale rational_ 2427 RelativeTimestampValue integer_ 1338 2428 ReleaseDate date 1339 ResampleParamsQuality string 2429 ResampleParams ResampleStretch Struct 2430 ResampleParamsQuality string_ 1340 2431 ScaleType string 1341 2432 Scene string/ 1342 2433 ShotDate date 2434 ShotDay string 1343 2435 ShotLocation string 1344 2436 ShotName string 2437 ShotNumber string 2438 ShotSize string 1345 2439 SpeakerPlacement string 1346 StartTimecodeTimeFormat string 1347 StartTimecodeTimeValue string 2440 StartTimecode Timecode Struct 2441 StartTimecodeTimeFormat string_ 2442 StartTimecodeTimeValue string_ 2443 StartTimecodeValue integer_ 1348 2444 StretchMode string 2445 TakeNumber integer 1349 2446 TapeName string 1350 2447 Tempo real 1351 TimeScaleParamsFrameOverlappingPercentage real 1352 TimeScaleParamsFrameSize real 1353 TimeScaleParamsQuality string 2448 TimeScaleParams TimeScaleStretch Struct 2449 TimeScaleParamsFrameOverlappingPercentage real_ 2450 TimeScaleParamsFrameSize real_ 2451 TimeScaleParamsQuality string_ 1354 2452 TimeSignature string 1355 2453 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_+ 1356 2472 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_ 1370 2487 VideoAlphaUnityIsTransparent boolean 1371 2488 VideoColorSpace string … … 1373 2490 VideoFieldOrder string 1374 2491 VideoFrameRate string 1375 VideoFrameSizeH real 1376 VideoFrameSizeUnit string 1377 VideoFrameSizeW real 2492 VideoFrameSize Dimensions Struct 2493 VideoFrameSizeH real_ 2494 VideoFrameSizeUnit string_ 2495 VideoFrameSizeW real_ 1378 2496 VideoModDate date 1379 2497 VideoPixelAspectRatio rational 1380 2498 VideoPixelDepth string 1381 2499 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 1382 2605 =head3 XMP xmpMM Tags 1383 2606 … … 1386 2609 Tag Name Writable 1387 2610 -------- -------- 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_ 1397 2629 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_+ 1403 2655 InstanceID string 1404 2656 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_ 1414 2675 Manager string 1415 2676 ManagerVariant string 1416 2677 ManageTo string 1417 2678 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+ 1418 2704 PreservedFileName string 1419 2705 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_ 1429 2724 RenditionParams string 1430 2725 SaveID integer 1431 2726 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 2785 This structure must have an InstanceID field, but may also contain any other 2786 XMP 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 2804 XMP Note schema tags. 2805 2806 Tag Name Writable 2807 -------- -------- 2808 HasExtendedXMP boolean* 1441 2809 1442 2810 =head3 XMP xmpPLUS Tags … … 1467 2835 Tag Name Writable 1468 2836 -------- -------- 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_ 1493 2864 NPages integer 1494 2865 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 2882 SVG (Scalable Vector Graphics) image tags. By default, only the top-level 2883 SVG and Metadata tags are extracted from these images, but all graphics tags 2884 may be extracted by setting the Unknown option to 2 (-U on the command 2885 line). The SVG tags are not part of XMP as such, but are included with the 2886 XMP 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 1495 2895 1496 2896 =head2 GPS Tags … … 1509 2909 automatically by ExifTool. Remember that the descriptive values are used 1510 2910 when 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 the1512 API).2911 disabled (with '-n' on the command line or the PrintConv option in the API, 2912 or by suffixing the tag name with a C<#> character). 1513 2913 1514 2914 When adding GPS information to an image, it is important to set all of the … … 1519 2919 Tag ID Tag Name Writable 1520 2920 ------ -------- -------- 1521 0x0000 GPSVersionID int8u[4] 2921 0x0000 GPSVersionID int8u[4]: 1522 2922 0x0001 GPSLatitudeRef string[2] 1523 2923 0x0002 GPSLatitude rational64u[3] … … 1550 2950 0x001d GPSDateStamp string[11] 1551 2951 0x001e GPSDifferential int16u 2952 0x001f GPSHPositioningError rational64u 1552 2953 1553 2954 =head2 GeoTiff Tags 2955 2956 ExifTool extracts the following tags from GeoTIFF images. See 2957 L<http://www.remotesensing.org/geotiff/spec/geotiffhome.html> for the 2958 complete GeoTIFF specification. 1554 2959 1555 2960 Tag ID Tag Name Writable … … 1606 3011 1607 3012 ICC profile information is used in many different file types including JPEG, 1608 TIFF, PDF, PostScript, Photoshop, PNG, MIFF, PICT, QuickTime and some RAW1609 formats. While the tags listed below are not individually writable, the3013 TIFF, PDF, PostScript, Photoshop, PNG, MIFF, PICT, QuickTime, XCF and some 3014 RAW formats. While the tags listed below are not individually writable, the 1610 3015 entire profile itself can be accessed via the extra 'ICC_Profile' tag, but 1611 this tag is neither extracted nor written unless specified explicitly. 3016 this tag is neither extracted nor written unless specified explicitly. See 3017 L<http://www.color.org/icc_specs2.xalter> for the official ICC 3018 specification. 1612 3019 1613 3020 Tag ID Tag Name Writable … … 1619 3026 'B2A1' BToA1 N 1620 3027 '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 1621 3036 'Header' ProfileHeader ICC_Profile Header 1622 3037 'MS00' WCSProfiles N … … 1628 3043 'chad' ChromaticAdaptation N 1629 3044 'chrm' Chromaticity ICC_Profile Chromaticity 3045 'ciis' ColorimetricIntentImageState N 3046 'clot' ColorantTableOut N 1630 3047 'clro' ColorantOrder N 1631 3048 'clrt' ColorantTable ICC_Profile ColorantTable … … 1637 3054 'dmnd' DeviceMfgDesc N 1638 3055 'dscm' ProfileDescriptionML N 3056 'fpce' FocalPlaneColorimetryEstimates N 1639 3057 'gTRC' GreenTRC N 1640 3058 'gXYZ' GreenMatrixColumn N … … 1643 3061 'lumi' Luminance N 1644 3062 'meas' Measurement ICC_Profile Measurement 3063 'meta' Metadata ICC_Profile Metadata 1645 3064 'mmod' MakeAndModel N 1646 3065 'ncl2' NamedColor2 N … … 1650 3069 'pre1' Preview1 N 1651 3070 'pre2' Preview2 N 1652 'ps2i' PS2Ren teringIntent N3071 'ps2i' PS2RenderingIntent N 1653 3072 'ps2s' PostScript2CSA N 1654 3073 'psd0' PostScript2CRD0 N … … 1656 3075 'psd2' PostScript2CRD2 N 1657 3076 'pseq' ProfileSequenceDesc N 3077 'psid' ProfileSequenceIdentifier N 1658 3078 'psvm' PS2CRDVMSize N 1659 3079 'rTRC' RedTRC N 1660 3080 'rXYZ' RedMatrixColumn N 1661 3081 '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 1662 3088 'scrd' ScreeningDesc N 1663 3089 'scrn' Screening N … … 1723 3149 32 MeasurementIlluminant N 1724 3150 3151 =head3 ICC_Profile Metadata Tags 3152 3153 Only these few tags have been pre-defined, but ExifTool will extract any 3154 Metadata tags that exist. 3155 3156 Tag Name Writable 3157 -------- -------- 3158 ManufacturerName N 3159 MediaColor N 3160 MediaWeight N 3161 1725 3162 =head3 ICC_Profile ViewingConditions Tags 1726 3163 … … 1736 3173 been decoded. Use the Unknown (-u) option to extract PrintIM information. 1737 3174 1738 Tag ID Tag NameWritable1739 ------ ----------------1740 [no tags known]3175 Tag ID Tag Name Writable 3176 ------ -------- -------- 3177 'PrintIMVersion' PrintIMVersion N 1741 3178 1742 3179 =head2 Photoshop Tags 1743 3180 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). 3181 Photoshop tags are found in PSD and PSB files, as well as inside embedded 3182 Photoshop information in many other file types (JPEG, TIFF, PDF, PNG to name 3183 a few). 1746 3184 1747 3185 Many Photoshop tags are marked as Unknown (indicated by a question mark 1748 3186 after the tag name) because the information they provide is not very useful 1749 under normal circumstances (and because Adobe denied my application for3187 under normal circumstances I<[and because Adobe denied my application for 1750 3188 their file format documentation -- apparently open source software is too 1751 big a concept for them ). These unknown tags are not extracted unless the3189 big a concept for them]>. These unknown tags are not extracted unless the 1752 3190 Unknown (-u) option is used. 1753 3191 … … 1808 3246 0x0421 VersionInfo? N 1809 3247 0x0422 EXIFInfo EXIF 3248 0x0423 ExifInfo2? N 1810 3249 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 1812 3257 0x2710 PrintFlagsInfo? N 1813 3258 … … 1854 3299 0x0008 FileNumber int32u 1855 3300 0x0009 OwnerName string 1856 0x000a ColorInfoD30 Canon ColorInfoD303301 0x000a UnknownD30 Canon UnknownD30 1857 3302 0x000c SerialNumber int32u 1858 0x000d CanonCameraInfo Canon CameraInfo 3303 0x000d CanonCameraInfo1D Canon CameraInfo1D 3304 CanonCameraInfo1DmkII Canon CameraInfo1DmkII 3305 CanonCameraInfo1DmkIIN Canon CameraInfo1DmkIIN 1859 3306 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 1861 3320 CanonCameraInfoUnknown32 Canon CameraInfoUnknown32 1862 3321 CanonCameraInfoUnknown16 Canon CameraInfoUnknown16 1863 CanonCameraInfoUnknown 8 Canon CameraInfoUnknown83322 CanonCameraInfoUnknown Canon CameraInfoUnknown 1864 3323 0x000e CanonFileLength int32u 1865 3324 0x000f CustomFunctions1D CanonCustom Functions1D … … 1874 3333 CustomFunctionsUnknown CanonCustom FuncsUnknown 1875 3334 0x0010 CanonModelID int32u 3335 0x0011 MovieInfo Canon MovieInfo 1876 3336 0x0012 CanonAFInfo Canon AFInfo 3337 0x0013 ThumbnailImageValidArea int16u[4] 1877 3338 0x0015 SerialNumberFormat int32u 3339 0x001a SuperMacro int16u 1878 3340 0x001c DateStampMode int16u 1879 3341 0x001d MyColors Canon MyColors 1880 3342 0x001e FirmwareRevision int32u 3343 0x0023 Categories int32u[2] 1881 3344 0x0024 FaceDetect1 Canon FaceDetect1 1882 3345 0x0025 FaceDetect2 Canon FaceDetect2 1883 3346 0x0026 CanonAFInfo2 Canon AFInfo2 1884 0x0083 OriginalDecisionData int32u 3347 0x0028 ImageUniqueID int8u 3348 0x0081 RawDataOffset N 3349 0x0083 OriginalDecisionDataOffset int32u* 1885 3350 0x0090 CustomFunctions1D CanonCustom Functions1D 1886 3351 0x0091 PersonalFunctions CanonCustom PersonalFuncs … … 1888 3353 0x0093 CanonFileInfo Canon FileInfo 1889 3354 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 1893 3360 0x0099 CustomFunctions2 CanonCustom Functions2 1894 0x00a0 ProccessingInfo Canon Processing 3361 0x009a AspectInfo Canon AspectInfo 3362 0x00a0 ProcessingInfo Canon Processing 1895 3363 0x00a1 ToneCurveTable N 1896 3364 0x00a2 SharpnessTable N … … 1898 3366 0x00a4 WhiteBalanceTable N 1899 3367 0x00a9 ColorBalance Canon ColorBalance 3368 0x00aa MeasuredColor Canon MeasuredColor 1900 3369 0x00ae ColorTemperature int16u 1901 3370 0x00b0 CanonFlags Canon Flags … … 1907 3376 0x00d0 VRDOffset int32u* 1908 3377 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 1914 3386 0x4003 ColorInfo Canon ColorInfo 1915 0x4005 UnknownBlock2?N3387 0x4005 Flavor? N 1916 3388 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 1917 3397 1918 3398 =head3 Canon CameraSettings Tags … … 1921 3401 ----- -------- -------- 1922 3402 1 MacroMode int16s 1923 2 Self -timerint16s3403 2 SelfTimer int16s 1924 3404 3 Quality int16s 1925 3405 4 CanonFlashMode int16s … … 1952 3432 36 ZoomSourceWidth int16s 1953 3433 37 ZoomTargetWidth int16s 3434 39 SpotMeteringMode int16s 1954 3435 40 PhotoEffect int16s 1955 3436 41 ManualFlashOutput int16s 1956 3437 42 ColorTone int16s 3438 46 SRAWQuality int16s 1957 3439 1958 3440 =head3 Canon FocalLength Tags … … 1963 3445 1 FocalLength int16u 1964 3446 2 FocalPlaneXSize int16u 3447 FocalPlaneXUnknown? int16u 1965 3448 3 FocalPlaneYSize int16u 3449 FocalPlaneYUnknown? int16u 1966 3450 1967 3451 =head3 Canon ShotInfo Tags … … 1979 3463 9 SequenceNumber int16s 1980 3464 10 OpticalZoomCode int16s 3465 12 CameraTemperature int16s 1981 3466 13 FlashGuideNumber int16s 1982 3467 14 AFPointsInFocus int16s … … 1984 3469 16 AutoExposureBracketing int16s 1985 3470 17 AEBBracketValue int16s 1986 19 FocusDistanceUpper int16s 1987 20 FocusDistanceLower int16s 3471 18 ControlMode int16s 3472 19 FocusDistanceUpper int16u 3473 20 FocusDistanceLower int16u 1988 3474 21 FNumber int16s 1989 3475 22 ExposureTime int16s 3476 23 MeasuredEV2 int16s 1990 3477 24 BulbDuration int16s 1991 3478 26 CameraType int16s 1992 3479 27 AutoRotate int16s 1993 3480 28 NDFilter int16s 1994 29 Self -timer2int16s3481 29 SelfTimer2 int16s 1995 3482 33 FlashOutput int16s 1996 3483 … … 1999 3486 Index Tag Name Writable 2000 3487 ----- -------- -------- 2001 2 PanoramaFrame 3488 2 PanoramaFrameNumber int16s 2002 3489 5 PanoramaDirection int16s 2003 3490 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 2012 3498 2013 3499 Information in the "CameraInfo" records is tricky to decode because the 2014 3500 encodings are very different than in other Canon records (even sometimes 2015 3501 switching 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. 3502 considerable variation in format from model to model. The first table below 3503 lists 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 3525 CameraInfo 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 3548 CameraInfo 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 3568 CameraInfo tags for the 1DmkIII and 1DSmkIII. 2019 3569 2020 3570 Index Tag Name Writable … … 2023 3573 4 ExposureTime int8u 2024 3574 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 3597 Custom 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 3661 CameraInfo 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 3698 CameraInfo 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 2032 3717 164 FirmwareRevision string[8] 2033 3718 172 ShortOwnerName string[16] … … 2074 3759 284 TimeStamp int32u 2075 3760 2076 =head3 Canon CameraInfo 1DmkIII Tags2077 2078 CameraInfo tags valid for the EOS 1D Mark III.3761 =head3 Canon CameraInfo5DmkII Tags 3762 3763 CameraInfo tags for the EOS 5D Mark II. 2079 3764 2080 3765 Index Tag Name Writable … … 2083 3768 4 ExposureTime int8u 2084 3769 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 3791 More 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 3802 CameraInfo 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 3820 More 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 3840 CameraInfo 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 3867 CameraInfo 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 3900 CameraInfo 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 3923 Custom 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 3993 CameraInfo 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 4019 CameraInfo 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 4048 CameraInfo 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 4075 CameraInfo 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 4100 CameraInfo tags for PowerShot models such as the A450, A460, A550, A560, 4101 A570, A630, A640, A650, A710, A720, G7, G9, S5, SD40, SD750, SD800, SD850, 4102 SD870, SD900, SD950, SD1000, SX100 and TX1. 2096 4103 2097 4104 Index Tag Name Writable … … 2101 4108 6 ExposureTime int32s 2102 4109 23 Rotation int32s 4110 135 CameraTemperature int32s 4111 145 CameraTemperature int32s 4112 4113 =head3 Canon CameraInfoPowerShot2 Tags 4114 4115 CameraInfo tags for PowerShot models such as the A470, A480, A490, A495, 4116 A580, A590, A1000, A1100, A2000, A2100, A3000, A3100, D10, E1, G10, G11, 4117 S90, S95, SD770, SD780, SD790, SD880, SD890, SD940, SD960, SD970, SD980, 4118 SD990, SD1100, SD1200, SD1300, SD1400, SD3500, SD4000, SD4500, SX1, SX10, 4119 SX20, 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 2103 4132 2104 4133 =head3 Canon CameraInfoUnknown32 Tags … … 2108 4137 Index Tag Name Writable 2109 4138 ----- -------- -------- 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 ----- -------- -------- 2110 4152 [no tags known] 2111 4153 2112 =head3 Canon CameraInfoUnknown 16Tags4154 =head3 Canon CameraInfoUnknown Tags 2113 4155 2114 4156 Index Tag Name Writable … … 2116 4158 [no tags known] 2117 4159 2118 =head3 Canon CameraInfoUnknown8 Tags 2119 2120 Index Tag Name Writable 2121 ----- -------- -------- 2122 [no tags known] 4160 =head3 Canon MovieInfo Tags 4161 4162 Tags 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] 2123 4175 2124 4176 =head3 Canon AFInfo Tags … … 2160 4212 ----- -------- -------- 2161 4213 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] 2173 4224 2174 4225 =head3 Canon FaceDetect2 Tags … … 2176 4227 Index Tag Name Writable 2177 4228 ----- -------- -------- 4229 1 FaceWidth int8u 2178 4230 2 FacesDetected int8u 2179 4231 … … 2187 4239 -------- -------- -------- 2188 4240 0 AFInfoSize? N 2189 1 AF ModeN4241 1 AFAreaMode N 2190 4242 2 NumAFPoints N 2191 4243 3 ValidAFPoints N 2192 4244 4 CanonImageWidth N 2193 5 CanonImage WidthN4245 5 CanonImageHeight N 2194 4246 6 AFImageWidth N 2195 4247 7 AFImageHeight N … … 2214 4266 6 RawJpgQuality int16s 2215 4267 7 RawJpgSize int16s 2216 8 NoiseReductionint16s4268 8 LongExposureNoiseReduction2 int16s 2217 4269 9 WBBracketMode int16s 2218 4270 12 WBBracketValueAB int16s … … 2220 4272 14 FilterEffect int16s 2221 4273 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 2222 4300 2223 4301 =head3 Canon Processing Tags … … 2241 4319 =head3 Canon ColorBalance Tags 2242 4320 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] 4321 These 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] 2256 4340 2257 4341 =head3 Canon Flags Tags … … 2286 4370 4 PreviewImageHeight int32u 2287 4371 5 PreviewImageStart int32u* 2288 6 PreviewFocalPlaneXResolution rational64s2289 8 PreviewFocalPlaneYResolution rational64s2290 4372 2291 4373 =head3 Canon SensorInfo Tags … … 2299 4381 7 SensorRightBorder N 2300 4382 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 4390 These 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 4418 Camera color calibration data. For the 20D, 350D, 1DmkII and 1DSmkII the 4419 order of the cooefficients is A, B, C, Temperature, but for newer models it 4420 is B, C, A, Temperature. These tags are extracted only when the Unknown 4421 option 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 4443 These 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 4508 These 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 4549 These tags are used by the 1DmkIII, 1DSmkIII, 1DmkIV, 5DmkII, 7D, 40D, 50D, 4550 450D, 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 4612 These 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 4635 These 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] 2426 4698 2427 4699 =head3 Canon ColorInfo Tags … … 2430 4702 ----- -------- -------- 2431 4703 1 Saturation int16s 2432 2 Color Hueint16s4704 2 ColorTone int16s 2433 4705 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 4716 This information is found in images from the 1DmkIV, 5DmkII, 7D, 50D, 500D 4717 and 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 4734 This 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 4754 Information 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 4767 Canon-specific QuickTime tags found in the CNTH atom of MOV videos from some 4768 cameras such as the PowerShot S95. 4769 4770 Tag ID Tag Name Writable 4771 ------ -------- -------- 4772 'CNDA' ThumbnailImage N 2434 4773 2435 4774 =head2 CanonCustom Tags … … 2451 4790 7 USMLensElectronicMF int8u 2452 4791 8 LCDPanels int8u 2453 9 AEBSequence 4792 9 AEBSequenceAutoCancel int8u 2454 4793 10 AFPointIllumination int8u 2455 4794 11 AFPointSelection int8u … … 2463 4802 19 LensAFStopButton int8u 2464 4803 20 AIServoTrackingSensitivity int8u 4804 21 AIServoContinuousShooting int8u 2465 4805 2466 4806 =head3 CanonCustom Functions5D Tags … … 2477 4817 7 FlashFiring int8u 2478 4818 8 ISOExpansion int8u 2479 9 AEBSequence 4819 9 AEBSequenceAutoCancel int8u 2480 4820 10 SuperimposedDisplay int8u 2481 4821 11 MenuButtonDisplayPosition int8u … … 2494 4834 Tag ID Tag Name Writable 2495 4835 ------ -------- -------- 2496 1 SetButton Functionint8u4836 1 SetButtonWhenShooting int8u 2497 4837 2 ShutterReleaseNoCFCard int8u 2498 4838 3 FlashSyncSpeedAv int8u … … 2502 4842 7 AFPointRegistration int8u 2503 4843 8 RawAndJpgRecording int8u 2504 9 AEBSequence 4844 9 AEBSequenceAutoCancel int8u 2505 4845 10 SuperimposedDisplay int8u 2506 4846 11 MenuButtonDisplayPosition int8u … … 2524 4864 6 FlashFiring int8u 2525 4865 7 ISOExpansion int8u 2526 8 AEBSequence 4866 8 AEBSequenceAutoCancel int8u 2527 4867 9 SuperimposedDisplay int8u 2528 4868 10 MenuButtonDisplayPosition int8u … … 2547 4887 7 FlashFiring int8u 2548 4888 8 ISOExpansion int8u 2549 9 AEBSequence 4889 9 AEBSequenceAutoCancel int8u 2550 4890 10 SuperimposedDisplay int8u 2551 4891 11 MenuButtonDisplayPosition int8u … … 2591 4931 =head3 CanonCustom FunctionsD30 Tags 2592 4932 2593 Custom functions for the EOS -D30 and D60.4933 Custom functions for the EOS D30 and D60. 2594 4934 2595 4935 Tag ID Tag Name Writable … … 2601 4941 5 AFAssist int8u 2602 4942 6 FlashSyncSpeedAv int8u 2603 7 AEBSequence 4943 7 AEBSequenceAutoCancel int8u 2604 4944 8 ShutterCurtainSync int8u 2605 4945 9 LensAFStopButton int8u 2606 4946 10 FillFlashAutoReduction int8u 2607 4947 11 MenuButtonReturn int8u 2608 12 SetButton Functionint8u4948 12 SetButtonWhenShooting int8u 2609 4949 13 SensorCleaning int8u 2610 4950 14 SuperimposedDisplay int8u … … 2685 5025 2686 5026 Beginning 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 has2688 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 Others5027 function tags which are (reasonably) consistent across models. The EOS 1D 5028 Mark III has 57 custom function tags divided into four main groups: 1. 5029 Exposure (0x0101-0x010f), 2. Image (0x0201-0x0203), Flash Exposure 5030 (0x0304-0x0306) and Display (0x0407-0x0409), 3. Auto Focus (0x0501-0x050e) 5031 and Drive (0x060f-0x0611), and 4. Operation (0x0701-0x070a) and Others 2692 5032 (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. 5033 well as newer tags and values added by later models. 2696 5034 2697 5035 Tag ID Tag Name Writable … … 2699 5037 0x0101 ExposureLevelIncrements int32s 2700 5038 0x0102 ISOSpeedIncrements int32s 2701 0x0103 ISO Expansion int32s2702 ISO SpeedRange int32s[3]5039 0x0103 ISOSpeedRange int32s[3] 5040 ISOExpansion int32s 2703 5041 0x0104 AEBAutoCancel int32s 2704 5042 0x0105 AEBSequence int32s 2705 0x0106 AEBShotCount int32s 5043 0x0106 AEBShotCount int32s[n] 2706 5044 0x0107 SpotMeterLinkToAFPoint int32s 2707 5045 0x0108 SafetyShift int32s … … 2713 5051 0x010e ApplyShootingMeteringMode int32s[8] 2714 5052 0x010f FlashSyncSpeedAv int32s 5053 0x0110 FEMicroadjustment int32s[3] 5054 0x0111 AEMicroadjustment int32s[3] 2715 5055 0x0201 LongExposureNoiseReduction int32s 2716 5056 0x0202 HighISONoiseReduction int32s 2717 5057 0x0203 HighlightTonePriority int32s 5058 0x0204 AutoLightingOptimizer int32s 2718 5059 0x0304 ETTLII int32s 2719 5060 0x0305 ShutterCurtainSync int32s … … 2729 5070 0x0506 LensAFStopButton int32s 2730 5071 0x0507 AFMicroadjustment int32s[5] 2731 0x0508 AF ExpansionWithSelectedPointint32s5072 0x0508 AFPointAreaExpansion int32s 2732 5073 0x0509 SelectableAFPoint int32s 2733 5074 0x050a SwitchToRegisteredAFPoint int32s … … 2737 5078 0x050e AFAssistBeam int32s 2738 5079 0x050f AFPointSelectionMethod int32s 2739 0x0510 SuperimposedDisplay int32s 5080 0x0510 VFDisplayIllumination int32s 5081 SuperimposedDisplay int32s 2740 5082 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 2741 5089 0x060f MirrorLockup int32s 2742 5090 0x0610 ContinuousShootingSpeed int32s[3] 2743 5091 0x0611 ContinuousShotLimit int32s[2] 2744 0x0701 ShutterButtonAFOnButton int32s 5092 0x0701 Shutter-AELock int32s 5093 AFAndMeteringButtons int32s 5094 ShutterButtonAFOnButton int32s 2745 5095 0x0702 AFOnAELockButtonSwitch int32s 2746 5096 0x0703 QuickControlDialInMeter int32s … … 2752 5102 0x0709 LockMicrophoneButton int32s 2753 5103 0x070a ButtonFunctionControlOff int32s 5104 0x070b AssignFuncButton int32s 5105 0x070c CustomControls int32s 5106 0x070d StartMovieShooting int32s 2754 5107 0x080b FocusingScreen int32s 2755 5108 0x080c TimerLength int32s[4] … … 2758 5111 0x080f AddOriginalDecisionData int32s 2759 5112 0x0810 LiveViewExposureSimulation int32s 5113 0x0811 LCDDisplayAtPowerOn int32s 5114 5115 =head2 CanonVRD Tags 5116 5117 Canon Digital Photo Professional writes VRD (Recipe Data) information as a 5118 trailer record to JPEG, TIFF, CRW and CR2 images, or as a stand-alone VRD 5119 file. The tags listed below represent information found in this record. 5120 The 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 5122 explicitly. 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 5132 Canon 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 5196 Tags 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 2760 5320 2761 5321 =head2 Casio Tags … … 2775 5335 0x000d Saturation int16u 2776 5336 0x0014 ISO int16u 5337 0x0015 FirmwareDate string[18] 2777 5338 0x0016 Enhancement int16u 2778 5339 0x0017 ColorFilter int16u … … 2802 5363 0x2011 WhiteBalanceBias int16u[2] 2803 5364 0x2012 WhiteBalance int16u 5365 0x2021 AFPointPosition int16u[4]~ 2804 5366 0x2022 ObjectDistance int32u 2805 5367 0x2034 FlashDistance int16u 5368 0x2076 SpecialEffectMode int8u[3] 5369 0x2089 FaceInfo1 Casio FaceInfo1 5370 FaceInfo2 Casio FaceInfo2 5371 FaceInfoUnknown? Y 5372 0x211c FacesDetected int8u 2806 5373 0x3000 RecordMode int16u 2807 0x3001 SelfTimerint16u5374 0x3001 ReleaseMode int16u 2808 5375 0x3002 Quality int16u 2809 5376 0x3003 FocusMode int16u … … 2811 5378 0x3007 BestShotMode int16u 2812 5379 0x3008 AutoISO int16u 5380 0x3009 AFMode int16u 2813 5381 0x3011 Sharpness undef[2] 2814 5382 0x3012 Contrast undef[2] … … 2817 5385 0x3015 ColorMode int16u 2818 5386 0x3016 Enhancement int16u 2819 0x3017 Filter int16u 5387 0x3017 ColorFilter int16u 5388 0x301b UnknownMode? int16u 2820 5389 0x301c SequenceNumber int16u 2821 5390 0x301d BracketSequence int16u[2] 2822 5391 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 5402 Face-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 5421 Face-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 5441 This information is found in the APP1 QVCI segment of JPEG images from the 5442 Casio 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 5455 This information is found in Casio GV-10 AVI videos. 5456 5457 Index Tag Name Writable 5458 ----- -------- -------- 5459 0 Software N 2823 5460 2824 5461 =head2 FujiFilm Tags … … 2834 5471 0x1004 Contrast int16u 2835 5472 0x1005 ColorTemperature int16u 5473 0x1006 Contrast int16u 5474 0x100a WhiteBalanceFineTune int32s[2] 5475 0x100b NoiseReduction int16u 5476 0x100e HighISONoiseReduction int16u 2836 5477 0x1010 FujiFlashMode int16u 2837 0x1011 Flash Strengthrational64s5478 0x1011 FlashExposureComp rational64s 2838 5479 0x1020 Macro int16u 2839 5480 0x1021 FocusMode int16u … … 2841 5482 0x1030 SlowSync int16u 2842 5483 0x1031 PictureMode int16u 5484 0x1033 EXRAuto int16u 5485 0x1034 EXRMode int16u 2843 5486 0x1100 AutoBracketing int16u 2844 5487 0x1101 SequenceNumber int16u … … 2847 5490 0x1301 FocusWarning int16u 2848 5491 0x1302 ExposureWarning int16u 5492 0x1304 GEImageSize string 2849 5493 0x1400 DynamicRange int16u 2850 5494 0x1401 FilmMode int16u … … 2855 5499 0x1406 MaxApertureAtMinFocal rational64s 2856 5500 0x1407 MaxApertureAtMaxFocal rational64s 5501 0x140b AutoDynamicRange int16u 5502 0x4100 FacesDetected int16u 5503 0x4103 FacePositions int16u[n] 5504 0x4282 FaceRecInfo FujiFilm FaceRecInfo 2857 5505 0x8000 FileSource string 2858 5506 0x8002 OrderNumber int32u 2859 5507 0x8003 FrameNumber int16u 5508 0xb211 Parallax rational64s 5509 5510 =head3 FujiFilm FaceRecInfo Tags 5511 5512 Face 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 2860 5540 2861 5541 =head3 FujiFilm RAF Tags 2862 5542 2863 Tags extracted from FujiFilm RAF-format information. 5543 FujiFilm RAF images contain meta information stored in a proprietary 5544 FujiFilm RAF format, as well as EXIF information stored inside an embedded 5545 JPEG preview image. The table below lists tags currently decoded from the 5546 RAF-format information. 2864 5547 2865 5548 Tag ID Tag Name Writable … … 2870 5553 0x2ff0 WB_GRGBLevels N 2871 5554 5555 =head3 FujiFilm FFMV Tags 5556 5557 Information 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 5565 This table lists tags found in the maker notes of some General Imaging 5566 camera models. 5567 5568 Tag ID Tag Name Writable 5569 ------ -------- -------- 5570 0x0202 Macro int16u 5571 0x0207 GEModel string 5572 0x0300 GEMake string 5573 2872 5574 =head2 HP Tags 2873 5575 … … 2916 5618 88 SerialNumber N 2917 5619 5620 =head3 HP TDHD Tags 5621 5622 These tags are extracted from the APP6 "TDHD" segment of Photosmart R837 5623 JPEG images. Many other unknown tags exist in is data, and can be seen with 5624 the 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 2918 5633 =head2 JVC Tags 2919 5634 … … 2936 5651 =head2 Kodak Tags 2937 5652 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.5653 Many Kodak models don't store the maker notes in standard IFD format, and 5654 these formats vary with different models. Some information has been 5655 decoded, but much of the Kodak information remains unknown. 2941 5656 2942 5657 The table below contains the most common set of Kodak tags. The following … … 3065 5780 0 SerialNumber string[16] 3066 5781 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 5784 Kodak models such as the ZD710, P712, P850, P880, V1233, V1253, V1275, 5785 V1285, Z612, Z712, Z812, Z885 use standard TIFF IFD format for the maker 5786 notes. In keeping with Kodak's strategy of inconsistent makernotes, models 5787 such as the M380, M1033, M1093, V1073, V1273, Z1012, Z1085 and Z8612 5788 also use these tags, but these makernotes begin with a TIFF header instead 5789 of an IFD entry count and use relative instead of absolute offsets. There 5790 is a large amount of information stored in these maker notes (apparently 5791 with much duplication), but relatively few tags have so far been decoded. 3073 5792 3074 5793 Tag ID Tag Name Writable 3075 5794 ------ -------- -------- 3076 5795 0xfc00 SubIFD0 Kodak SubIFD0 5796 Kodak SubIFD0 3077 5797 0xfc01 SubIFD1 Kodak SubIFD1 5798 Kodak SubIFD1 3078 5799 0xfc02 SubIFD2 Kodak SubIFD2 5800 Kodak SubIFD2 3079 5801 0xfc03 SubIFD3 Kodak SubIFD3 5802 Kodak SubIFD3 3080 5803 0xfc04 SubIFD4 Kodak SubIFD4 5804 Kodak SubIFD4 3081 5805 0xfc05 SubIFD5 Kodak SubIFD5 5806 Kodak SubIFD5 5807 0xfc06 SubIFD6 Kodak SubIFD6 5808 Kodak SubIFD6 5809 0xfcff SubIFD255 Kodak SubIFD0 3082 5810 0xff00 CameraInfo Kodak CameraInfo 3083 5811 3084 5812 =head3 Kodak SubIFD0 Tags 3085 5813 3086 SubIFD0 through SubIFD5 tags are used by the Z612 and Z712.5814 SubIFD0 through SubIFD5 tags are written a number of newer Kodak models. 3087 5815 3088 5816 Tag ID Tag Name Writable … … 3144 5872 0x000f OpticalZoom int16u 3145 5873 5874 =head3 Kodak SubIFD6 Tags 5875 5876 SubIFD6 is written by the M580. 5877 5878 Tag ID Tag Name Writable 5879 ------ -------- -------- 5880 [no tags known] 5881 3146 5882 =head3 Kodak CameraInfo Tags 3147 5883 … … 3163 5899 0xfd06 ISO int16u 3164 5900 5901 =head3 Kodak Type9 Tags 5902 5903 These tags are used by the Kodak C140, C180, C913, C1013, M320, M340 and 5904 M550, 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 5917 Another variation of the IFD-format type, this time with just a byte order 5918 indicator 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 3165 5928 =head3 Kodak Unknown Tags 3166 5929 … … 3169 5932 [no tags known] 3170 5933 5934 =head3 Kodak IFD Tags 5935 5936 These tags are found in a separate IFD of JPEG, TIFF, DCR and KDC images 5937 from some older Kodak models such as the DC50, DC120, DCS760C, DCS Pro 14N, 5938 14nx, 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 5969 Below is a list of tags which have been observed in the Kodak TextualInfo 5970 data, 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 3171 6013 =head3 Kodak Meta Tags 3172 6014 3173 6015 These 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 this3175 s egment is similar to the APP1 "Exif" segment, but a different set of tags3176 is used.6016 cameras such as the DC280, DC3400, DC5000, MC3, M580, Z950 and Z981. The 6017 structure of this segment is similar to the APP1 "Exif" segment, but a 6018 different set of tags is used. 3177 6019 3178 6020 Tag ID Tag Name Writable … … 3181 6023 0xc351 ImageSourceEK N 3182 6024 0xc352 CaptureConditionsPAR N 3183 0xc353 CameraOwner N3184 0xc354 SerialNumber N6025 0xc353 CameraOwner undef 6026 0xc354 SerialNumber undef 3185 6027 0xc355 UserSelectGroupTitle N 3186 6028 0xc356 DealerIDNumber N … … 3235 6077 0x0008 WatermarkType N 3236 6078 6079 =head3 Kodak KDC_IFD Tags 6080 6081 These tags are found in a separate IFD of KDC images from some newer Kodak 6082 models 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 6096 This 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 3237 6108 =head2 Leaf Tags 3238 6109 3239 6110 These tags are found in .MOS images from Leaf digital camera backs as 3240 6111 written by Creo Leaf Capture. They exist within the Leaf-specific directory 3241 structure of EXIF tag 0x8606. The tables below list observed Leaf tags,6112 structure of EXIF tag 0x8606. The tables below list observed Leaf tags, 3242 6113 however ExifTool will extract any tags found in the Leaf directories even if 3243 6114 they don't appear in these tables. … … 3492 6363 =head3 Leaf SubIFD Tags 3493 6364 3494 Leaf also writes a TIFF-format sub-IFD inside IFD0 of a MOS image. No tags3495 inthis sub-IFD are currently known, except for tag 0x8606 which really6365 Leaf writes a TIFF-format sub-IFD inside IFD0 of a MOS image. No tags in 6366 this sub-IFD are currently known, except for tag 0x8606 which really 3496 6367 shouldn't be here anyway (so it doesn't appear in the table below) because 3497 6368 it duplicates a reference to the same data of tag 0x8606 in IFD0. … … 3503 6374 =head2 Minolta Tags 3504 6375 3505 These tags are used by Minolta and Konica/Minolta cameras. Minolta doesn't3506 make things easy for decoders because the meaning of some tags and the3507 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.)6376 These tags are used by Minolta, Konica/Minolta as well as some Sony cameras. 6377 Minolta doesn't make things easy for decoders because the meaning of some 6378 tags and the location where some information is stored is different for 6379 different camera models. (Take MinoltaQuality for example, which may be 6380 located in 5 different places.) 3510 6381 3511 6382 Tag ID Tag Name Writable … … 3516 6387 0x0004 MinoltaCameraSettings7D Minolta CameraSettings7D 3517 6388 0x0018 ImageStabilization N 6389 0x0020 WBInfoA100 Minolta WBInfoA100 3518 6390 0x0040 CompressedImageSize int32u 3519 6391 0x0081 PreviewImage undef 3520 6392 0x0088 PreviewImageStart int32u* 3521 6393 0x0089 PreviewImageLength int32u* 3522 0x0100 SceneMode Y6394 0x0100 SceneMode int32u 3523 6395 0x0101 ColorMode int32u 3524 6396 0x0102 MinoltaQuality int32u … … 3526 6398 MinoltaImageSize int32u 3527 6399 0x0104 FlashExposureComp rational64s 6400 0x0105 Teleconverter int32u 3528 6401 0x0107 ImageStabilization int32u 6402 0x0109 RawAndJpgRecording int32u 3529 6403 0x010a ZoneMatching int32u 3530 6404 0x010b ColorTemperature int32u 3531 0x010c LensID int32u 6405 0x010c LensType int32u 6406 0x0111 ColorCompensationFilter int32s 6407 0x0112 WhiteBalanceFineTune int32u 3532 6408 0x0113 ImageStabilization int32u 3533 6409 0x0114 MinoltaCameraSettings5D Minolta CameraSettings5D 3534 MinoltaCameraSettingsA100 Minolta CameraSettingsA100 6410 CameraSettingsA100 Minolta CameraSettingsA100 6411 0x0115 WhiteBalance int32u 3535 6412 0x0e00 PrintIM PrintIM 3536 6413 0x0f00 MinoltaCameraSettings2 N … … 3542 6419 information may not be as reliable as it should be. Because of this, tags 3543 6420 in the following tables are set to lower priority to prevent them from 3544 superce eding the values of same-named tags in other locations when duplicate6421 superceding the values of same-named tags in other locations when duplicate 3545 6422 tags are disabled. 3546 6423 … … 3609 6486 16 AFPoints int16u 3610 6487 21 Flash int16u 6488 22 FlashMode int16u 3611 6489 28 ISOSetting int16u 3612 6490 30 ExposureCompensation int16s … … 3617 6495 45 FreeMemoryCardImages int16u 3618 6496 63 ColorTemperature int16s 6497 64 HueAdjustment int16u 3619 6498 70 Rotation int16u 3620 6499 71 FNumber int16u … … 3627 6506 117 ZoneMatchingOn int16u 3628 6507 6508 =head3 Minolta WBInfoA100 Tags 6509 6510 White 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 3629 6528 =head3 Minolta CameraSettings5D Tags 3630 6529 … … 3636 6535 14 WhiteBalance int16u 3637 6536 31 Flash int16u 6537 32 FlashMode int16u 3638 6538 37 MeteringMode int16u 3639 6539 38 ISOSetting int16u 6540 47 ColorSpace int16u 3640 6541 48 Sharpness int16u 3641 6542 49 Contrast int16u … … 3645 6546 55 FreeMemoryCardImages int16u 3646 6547 73 ColorTemperature int16s 6548 74 HueAdjustment int16u 3647 6549 80 Rotation int16u 3648 6550 83 ExposureCompensation int16u 3649 6551 84 FreeMemoryCardImages int16u 6552 101 Rotation int16u 3650 6553 110 ColorTemperature int16s 6554 113 PictureFinish int16u 3651 6555 174 ImageNumber int16u 3652 6556 176 NoiseReduction int16u … … 3660 6564 ----- -------- -------- 3661 6565 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 3663 6573 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 3664 6583 22 ColorMode int16u 6584 23 ColorSpace int16u 3665 6585 24 Sharpness int16u 3666 6586 25 Contrast int16u 3667 6587 26 Saturation int16u 6588 28 FlashMetering int16u 6589 29 PrioritySetupShutterRelease int16u 3668 6590 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 3669 6612 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 3670 6638 90 Rotation int16u 6639 91 AELock int16u 3671 6640 94 ColorTemperature int16u 3672 135 ImageStabilization int32u[0.5] 6641 95 ColorCompensationFilter int16s 6642 96 BatteryLevel int16u 6643 6644 =head3 Minolta MMA Tags 6645 6646 This information is found in MOV videos from Minolta models such as the 6647 DiMAGE 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 6656 This information is found in MOV videos from some Konica Minolta models such 6657 as 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 6670 This information is found in MOV videos from some Minolta models such as the 6671 DiMAGE 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 3673 6681 3674 6682 =head2 Nikon Tags … … 3684 6692 0x0007 FocusMode string 3685 6693 0x0008 FlashSetting string 3686 0x0009 FlashType string [13]3687 0x000b WhiteBalanceFineTune int16s 3688 0x000c ColorBalance1rational64u[4]6694 0x0009 FlashType string 6695 0x000b WhiteBalanceFineTune int16s[n] 6696 0x000c WB_RBLevels rational64u[4] 3689 6697 0x000d ProgramShift undef[4] 3690 6698 0x000e ExposureDifference undef[4] 3691 6699 0x000f ISOSelection string 3692 6700 0x0010 DataDump N 3693 0x0011 NikonPreview Nikon PreviewImage6701 0x0011 PreviewIFD Nikon PreviewIFD 3694 6702 0x0012 FlashExposureComp undef[4] 3695 6703 0x0013 ISOSetting int16u[2] 6704 0x0014 ColorBalanceA Nikon ColorBalanceA 6705 NRWData? Y 3696 6706 0x0016 ImageBoundary int16u[4] 6707 0x0017 ExternalFlashExposureComp undef[4] 3697 6708 0x0018 FlashExposureBracketValue undef[4] 3698 6709 0x0019 ExposureBracketValue rational64s 3699 6710 0x001a ImageProcessing string 3700 6711 0x001b CropHiSpeed int16u[7]~ 3701 0x001d SerialNumber N 6712 0x001c ExposureTuning undef[3] 6713 0x001d SerialNumber string! 3702 6714 0x001e ColorSpace int16u 6715 0x001f VRInfo Nikon VRInfo 3703 6716 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 3704 6726 0x0080 ImageAdjustment string 3705 6727 0x0081 ToneComp string … … 3711 6733 0x0087 FlashMode int8u 3712 6734 0x0088 AFInfo Nikon AFInfo 6735 Nikon AFInfo 3713 6736 0x0089 ShootingMode int16u~ 3714 0x008a AutoBracketRelease int16u3715 6737 0x008b LensFStops undef[4] 3716 0x008c NEFCurve1N6738 0x008c ContrastCurve N 3717 6739 0x008d ColorHue string 3718 6740 0x008f SceneMode string 3719 6741 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 3722 6757 0x0092 HueAdjustment int16s 6758 0x0093 NEFCompression int16u 3723 6759 0x0094 Saturation int16s 3724 6760 0x0095 NoiseReduction string 3725 0x0096 NEFCurve2N6761 0x0096 LinearizationTable N 3726 6762 0x0097 ColorBalance0100 Nikon ColorBalance1 3727 6763 ColorBalance0102 Nikon ColorBalance2 3728 6764 ColorBalance0103 Nikon ColorBalance3 3729 6765 ColorBalance0205 Nikon ColorBalance2 6766 ColorBalance0209 Nikon ColorBalance4 3730 6767 ColorBalance02 Nikon ColorBalance2 3731 6768 ColorBalanceUnknown N … … 3733 6770 LensData0101 Nikon LensData01 3734 6771 LensData0201 Nikon LensData01 3735 LensDataUnknown N 6772 LensData0204 Nikon LensData0204 6773 LensDataUnknown Nikon LensDataUnknown 3736 6774 0x0099 RawImageCenter int16u[2] 3737 6775 0x009a SensorPixelSize rational64u[2] 6776 0x009c SceneAssist string 6777 0x009e RetouchHistory int16u[10] 3738 6778 0x00a0 SerialNumber string 3739 6779 0x00a2 ImageDataSize int32u 3740 6780 0x00a5 ImageCount int32u 3741 6781 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 3744 6789 0x00aa Saturation string 3745 6790 0x00ab VariProgram string … … 3748 6793 0x00b0 MultiExposure Nikon MultiExposure 3749 6794 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 3750 6801 0x0e00 PrintIM PrintIM 3751 6802 0x0e01 NikonCaptureData NikonCapture … … 3753 6804 0x0e0e NikonCaptureOffsets Nikon CaptureOffsets 3754 6805 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 3757 6813 3758 6814 Tag ID Tag Name Writable 3759 6815 ------ -------- -------- 6816 0x00fe SubfileType N 3760 6817 0x0103 Compression N 3761 6818 0x011a XResolution N … … 3766 6823 0x0213 YCbCrPositioning N 3767 6824 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 3768 6912 =head3 Nikon AFInfo Tags 3769 6913 … … 3774 6918 2 AFPointsInFocus int16u 3775 6919 6920 =head3 Nikon ShotInfoD40 Tags 6921 6922 These 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 6933 These 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 6948 These tags are extracted from encrypted data in images from the D90 with 6949 firmware 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 6961 These tags are extracted from encrypted data in images from the D3 with 6962 firmware 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 6975 These tags are extracted from encrypted data in images from the D3 with 6976 firmware 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 6993 These tags are extracted from encrypted data in images from the D3X with 6994 firmware 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 7006 These tags are extracted from encrypted data in images from the D3S with 7007 firmware 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 7020 These tags are extracted from encrypted data in images from the D300 with 7021 firmware 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 7033 These tags are extracted from encrypted data in images from the D300 with 7034 firmware 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 7047 These tags are extracted from encrypted data in images from the D300S with 7048 firmware 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 7060 These tags are extracted from encrypted data in images from the D700 with 7061 firmware 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 7073 These tags are extracted from encrypted data in images from the D5000 with 7074 firmware 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 7086 These tags are extracted from encrypted data in images from the D7000 with 7087 firmware 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 3776 7096 =head3 Nikon ShotInfo Tags 3777 7097 3778 7098 This information is encrypted for ShotInfoVersion 02xx, and some tags are 3779 only valid for specific versions.7099 only valid for specific models. 3780 7100 3781 7101 Index Tag Name Writable 3782 7102 ----- -------- -------- 3783 7103 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 3793 7114 3794 7115 =head3 Nikon ColorBalance1 Tags … … 3800 7121 =head3 Nikon ColorBalance2 Tags 3801 7122 3802 This information is encrypted for most camera models, and if encrypted is 3803 not currently writable by exiftool. 7123 This information is encrypted for most camera models. 3804 7124 3805 7125 Index Tag Name Writable … … 3813 7133 0 WB_RGBGLevels int16u[4]! 3814 7134 7135 =head3 Nikon ColorBalance4 Tags 7136 7137 Index Tag Name Writable 7138 ----- -------- -------- 7139 0 WB_GRBGLevels int16u[4]! 7140 3815 7141 =head3 Nikon LensData00 Tags 3816 7142 … … 3819 7145 Index Tag Name Writable 3820 7146 ----- -------- -------- 3821 0 LensDataVersion undef[4]7147 0 LensDataVersion N 3822 7148 6 LensIDNumber int8u 3823 7149 7 LensFStops int8u … … 3832 7158 Nikon encrypts the LensData information below if LensDataVersion is 0201 or 3833 7159 higher, 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. 7160 extracted. 3836 7161 3837 7162 Index Tag Name Writable 3838 7163 ----- -------- -------- 3839 7164 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 7181 Nikon encrypts the LensData information below if LensDataVersion is 0201 or 7182 higher, but the decryption algorithm is known so the information can be 7183 extracted. 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 7210 These tags are used by the D2H, D2Hs, D2X, D2Xs, D50, D70, D70s, D80 and 7211 D200. 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 7236 These 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 7265 These tags are used by the D3 (firmware 2.x), D3X, D3S, D90, D300 (firmware 7266 1.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 3853 7298 3854 7299 =head3 Nikon MultiExposure Tags … … 3856 7301 Index Tag Name Writable 3857 7302 ----- -------- -------- 3858 0 MultiExposureVersion string[4]7303 0 MultiExposureVersion N 3859 7304 1 MultiExposureMode int32u 3860 7305 2 MultiExposureShots int32u 3861 7306 3 MultiExposureAutoGain int32u 7307 7308 =head3 Nikon AFInfo2 Tags 7309 7310 These 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 3862 7345 3863 7346 =head3 Nikon CaptureOffsets Tags … … 3880 7363 0x0050 MasterGain rational64s 3881 7364 0x0051 ColorGain rational64s[3] 7365 0x0060 ScanImageEnhancer int32u 3882 7366 0x0100 DigitalICE string 3883 7367 0x0110 ROCInfo Nikon ROC 3884 7368 0x0120 GEMInfo Nikon GEM 7369 0x0200 DigitalDEEShadowAdj int32u 7370 0x0201 DigitalDEEThreshold int32u 7371 0x0202 DigitalDEEHighlightAdj int32u 3885 7372 3886 7373 =head3 Nikon ROC Tags … … 3895 7382 ----- -------- -------- 3896 7383 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 3897 7392 3898 7393 =head3 Nikon Type2 Tags … … 3909 7404 0x000b Converter Y 3910 7405 7406 =head3 Nikon NCDT Tags 7407 7408 Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some 7409 Nikon 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 7420 These tags are found in proprietary-format records of the NCTG atom in MOV 7421 videos 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 3911 7447 =head3 Nikon MOV Tags 3912 7448 3913 This information is found in Nikon QT video images, and is very similar to 3914 information found in Pentax MOV videos. 7449 This information is found in MOV and QT videos from some Nikon cameras. 3915 7450 3916 7451 Index Tag Name Writable … … 3926 7461 223 ISO N 3927 7462 7463 =head3 Nikon AVI Tags 7464 7465 Nikon-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 7476 These tags and the AVIVer tags below are found in proprietary-format records 7477 of 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 7516 Custom 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 7545 Custom 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 7600 Custom 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 7661 Custom 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 7747 Custom 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 7824 Custom 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 7857 Custom 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 3928 7926 =head2 NikonCapture Tags 3929 7927 … … 3934 7932 ------ -------- -------- 3935 7933 0x8ae85e LCHEditor int8u 7934 0x83a1a25 HistogramXML undef 3936 7935 0xc89224b ColorAberrationControl int8u 7936 0x116fea21 HighlightData NikonCapture HighlightData 3937 7937 0x2175eb78 D-LightingHQ int8u 3938 7938 0x2fc08431 StraightenAngle double 3939 7939 0x374233e0 CropData NikonCapture CropData 7940 0x39c456ac PictureCtrl NikonCapture PictureCtrl 3940 7941 0x3cfc73c6 RedEyeData NikonCapture RedEyeData 7942 0x3d136244 EditVersionName string 7943 0x56a54260 Exposure NikonCapture Exposure 3941 7944 0x5f0e7d23 ColorBooster int8u 3942 7945 0x6a6e36b6 D-LightingHQSelected int8u … … 3960 7963 0xbf3c6c20 WBAdjData NikonCapture WBAdjData 3961 7964 0xce5554aa D-LightingHS int8u 7965 0xe2173c47 PictureControl int8u 3962 7966 0xe37b4337 D-LightingHSData NikonCapture DLightingHS 3963 7967 0xe42b5161 UnsharpData NikonCapture UnsharpData 7968 0xe9651831 PhotoEffectHistoryXML undef 7969 0xfe28a44f AutoRedEye int8u 3964 7970 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 3965 7979 3966 7980 =head3 NikonCapture CropData Tags … … 3972 7986 46 CropRight double 3973 7987 54 CropBottom double 3974 142 OutputWidthInchesdouble3975 150 OutputHeightInchesdouble3976 158 ScaledResolutiondouble3977 174 SourceResolutiondouble3978 182 OutputResolutiondouble7988 142 CropOutputWidthInches double 7989 150 CropOutputHeightInches double 7990 158 CropScaledResolution double 7991 174 CropSourceResolution double 7992 182 CropOutputResolution double 3979 7993 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 3983 8010 3984 8011 =head3 NikonCapture RedEyeData Tags … … 3987 8014 ----- -------- -------- 3988 8015 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 3989 8025 3990 8026 =head3 NikonCapture Brightness Tags … … 3999 8035 Index Tag Name Writable 4000 8036 ----- -------- -------- 4001 0 D-LightingH SShadow int32u4002 1 D-LightingH SHighlight int32u4003 2 D-LightingH SColorBoost int32u8037 0 D-LightingHQShadow int32u 8038 1 D-LightingHQHighlight int32u 8039 2 D-LightingHQColorBoost int32u 4004 8040 4005 8041 =head3 NikonCapture NoiseReduction Tags … … 4008 8044 ----- -------- -------- 4009 8045 4 EdgeNoiseReduction int8u 4010 5 ColorMoireReduction 8046 5 ColorMoireReductionMode int8u 4011 8047 9 NoiseReductionIntensity int32u 4012 8048 13 NoiseReductionSharpness int32u 4013 8049 17 NoiseReductionMethod int16u 8050 21 ColorMoireReduction int8u 8051 23 NoiseReduction int8u 8052 24 ColorNoiseReductionIntensity int32u 8053 28 ColorNoiseReductionSharpness int32u 4014 8054 4015 8055 =head3 NikonCapture PhotoEffects Tags … … 4036 8076 8 WBAdjBlueBalance double 4037 8077 16 WBAdjMode int8u 8078 20 WBAdjLightingSubtype int8u 4038 8079 21 WBAdjLighting int8u 4039 8080 24 WBAdjTemperature int16u 8081 37 WBAdjTint int32s 4040 8082 4041 8083 =head3 NikonCapture DLightingHS Tags … … 4084 8126 0x0089 PreviewImageLength N 4085 8127 0x0100 ThumbnailImage undef 4086 0x0101 ColorMode int16u4087 0x0102 MinoltaQuality int16u4088 0x0103 MinoltaQuality int16u4089 8128 0x0104 BodyFirmwareVersion string 4090 8129 0x0200 SpecialMode int32u[3]~ … … 4113 8152 0x0f00 DataDump N 4114 8153 0x0f01 DataDump2 N 8154 0x0f04 ZoomedPreviewStart int32u* 8155 0x0f05 ZoomedPreviewLength int32u* 8156 0x0f06 ZoomedPreviewSize int16u[2] 4115 8157 0x1000 ShutterSpeedValue rational64s 4116 8158 0x1001 ISOValue rational64s … … 4162 8204 0x1030 SceneDetect int16u 4163 8205 0x1031 SceneArea? int32u[8] 4164 0x1033 SceneDetect Area? int32u[720]8206 0x1033 SceneDetectData? int32u[720] 4165 8207 0x1034 CompressionRatio rational64u 4166 8208 0x1035 PreviewImageValid int32u … … 4170 8212 0x1039 CCDScanMode int16u 4171 8213 0x103a NoiseReduction int16u 4172 0x103b InfinityLensStepint16u4173 0x103c NearLensStepint16u8214 0x103b FocusStepInfinity int16u 8215 0x103c FocusStepNear int16u 4174 8216 0x103d LightValueCenter rational64s 4175 8217 0x103e LightValuePeriphery rational64s 4176 8218 0x103f FieldCount? int16u 4177 8219 0x2010 Equipment Olympus Equipment 4178 Equipment 2Olympus Equipment8220 EquipmentIFD Olympus Equipment 4179 8221 0x2020 CameraSettings Olympus CameraSettings 4180 CameraSettings 2Olympus CameraSettings8222 CameraSettingsIFD Olympus CameraSettings 4181 8223 0x2030 RawDevelopment Olympus RawDevelopment 4182 RawDevelopment 2Olympus RawDevelopment8224 RawDevelopmentIFD Olympus RawDevelopment 4183 8225 0x2031 RawDev2 Olympus RawDevelopment2 4184 RawDev2 _2Olympus RawDevelopment28226 RawDev2IFD Olympus RawDevelopment2 4185 8227 0x2040 ImageProcessing Olympus ImageProcessing 4186 ImageProcessing 2Olympus ImageProcessing8228 ImageProcessingIFD Olympus ImageProcessing 4187 8229 0x2050 FocusInfo Olympus FocusInfo 4188 FocusInfo 2Olympus FocusInfo8230 FocusInfoIFD Olympus FocusInfo 4189 8231 CameraParameters undef 4190 8232 0x2100 Olympus2100 Olympus FE 8233 Olympus2100IFD Olympus FE 4191 8234 0x2200 Olympus2200 Olympus FE 8235 Olympus2200IFD Olympus FE 4192 8236 0x2300 Olympus2300 Olympus FE 8237 Olympus2300IFD Olympus FE 4193 8238 0x2400 Olympus2400 Olympus FE 8239 Olympus2400IFD Olympus FE 4194 8240 0x2500 Olympus2500 Olympus FE 8241 Olympus2500IFD Olympus FE 4195 8242 0x2600 Olympus2600 Olympus FE 8243 Olympus2600IFD Olympus FE 4196 8244 0x2700 Olympus2700 Olympus FE 8245 Olympus2700IFD Olympus FE 4197 8246 0x2800 Olympus2800 Olympus FE 8247 Olympus2800IFD Olympus FE 4198 8248 0x2900 Olympus2900 Olympus FE 8249 Olympus2900IFD Olympus FE 4199 8250 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 4201 8256 4202 8257 =head3 Olympus TextInfo Tags … … 4221 8276 0x0103 FocalPlaneDiagonal rational64u 4222 8277 0x0104 BodyFirmwareVersion int32u 4223 0x0201 LensType int8u[6] ~8278 0x0201 LensType int8u[6] 4224 8279 0x0202 LensSerialNumber string[32] 8280 0x0203 LensModel string 4225 8281 0x0204 LensFirmwareVersion int32u 4226 8282 0x0205 MaxApertureAtMinFocal int16u … … 4230 8286 0x020a MaxApertureAtCurrentFocal int16u 4231 8287 0x020b LensProperties int16u 4232 0x0301 Extender int8u[6] ~8288 0x0301 Extender int8u[6] 4233 8289 0x0302 ExtenderSerialNumber string[32] 4234 8290 0x0303 ExtenderModel string … … 4250 8306 0x0201 AELock int16u 4251 8307 0x0202 MeteringMode int16u 8308 0x0203 ExposureShift rational64s 4252 8309 0x0300 MacroMode int16u 4253 0x0301 FocusMode int16u 4254 0x0302 FocusProcess int16u 8310 0x0301 FocusMode int16u[n] 8311 0x0302 FocusProcess int16u[n] 4255 8312 0x0303 AFSearch int16u 4256 8313 0x0304 AFAreas int32u[64]~ 8314 0x0305 AFPointSelected rational64s[5]~ 8315 0x0307 AFFineTuneAdj int16s[3] 4257 8316 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] 4259 8322 0x0500 WhiteBalance2 int16u 4260 8323 0x0501 WhiteBalanceTemperature int16u … … 4270 8333 0x050c ShadingCompensation int16u 4271 8334 0x050d CompressionFactor rational64u 4272 0x050f Gradation int16s[ 3]4273 0x0520 PictureMode int16u 8335 0x050f Gradation int16s[n] 8336 0x0520 PictureMode int16u[n] 4274 8337 0x0521 PictureModeSaturation int16s[3] 4275 8338 0x0522 PictureModeHue? int16s … … 4279 8342 0x0526 PictureModeTone int16s 4280 8343 0x0527 NoiseFilter int16s[3] 8344 0x0529 ArtFilter int16u[4] 8345 0x052c MagicFilter int16u[4] 4281 8346 0x0600 DriveMode int16u[n]~ 4282 8347 0x0601 PanoramaMode int16u~ 4283 8348 0x0603 ImageQuality2 int16u 8349 0x0604 ImageStabilization int32u 8350 0x0900 ManometerPressure int16u 4284 8351 0x0901 ManometerReading int32s[2] 8352 0x0902 ExtendedWBDetect int16u 8353 0x0903 LevelGaugeRoll int16u 8354 0x0904 LevelGaugePitch int16u 4285 8355 4286 8356 =head3 Olympus RawDevelopment Tags … … 4327 8397 0x0111 RawDevPMPictureTone int16u 4328 8398 0x0112 RawDevGradation int16s[3] 8399 0x0113 RawDevSaturation3 int16s[3] 8400 0x0119 RawDevAutoGradation int16u 8401 0x0120 RawDevPMNoiseFilter int16u 4329 8402 4330 8403 =head3 Olympus ImageProcessing Tags … … 4334 8407 0x0000 ImageProcessingVersion undef[4] 4335 8408 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 4336 8438 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 4341 8445 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 4344 8450 0x1010 NoiseReduction2 int16u 4345 8451 0x1011 DistortionCorrection2 int16u 4346 8452 0x1012 ShadingCompensation2 int16u 8453 0x101c MultipleExposureMode int16u[2] 4347 8454 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] 4348 8462 4349 8463 =head3 Olympus FocusInfo Tags … … 4353 8467 0x0000 FocusInfoVersion undef[4] 4354 8468 0x0209 AutoFocus? int16u 8469 0x0210 SceneDetect int16u 8470 0x0211 SceneArea? int32u[8] 8471 0x0212 SceneDetectData? int32u[720] 4355 8472 0x0300 ZoomStepCount int16u 4356 8473 0x0301 FocusStepCount int16u 8474 0x0303 FocusStepInfinity int16u 8475 0x0304 FocusStepNear int16u 4357 8476 0x0305 FocusDistance rational64u 4358 8477 0x0308 AFPoint int16u … … 4382 8501 ------ -------- -------- 4383 8502 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] 4395 8514 0x0200 ColorMatrix2 int16u[9] 4396 8515 0x0310 CoringFilter int16u … … 4399 8518 0x0601 YCbCrCoefficients N 4400 8519 0x0611 ValidPixelDepth int16u[2] 4401 0x0612 StartOffsetXint16u4402 0x0613 StartOffsetYint16u4403 0x0614 FinalImageWidthint32u4404 0x0615 FinalImageHeightint32u8520 0x0612 CropLeft int16u 8521 0x0613 CropTop int16u 8522 0x0614 CropWidth int32u 8523 0x0615 CropHeight int32u 4405 8524 0x1000 LightSource int16u 4406 8525 0x1001 WhiteBalanceComp int16s[3] … … 4418 8537 0x2023 CMSharpness int16s[3] 4419 8538 8539 =head3 Olympus UnknownInfo Tags 8540 8541 Tag ID Tag Name Writable 8542 ------ -------- -------- 8543 [no tags known] 8544 8545 =head3 Olympus MOV1 Tags 8546 8547 This information is found in MOV videos from Olympus models such as the 8548 D540Z, 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 8561 This information is found in MOV videos from Olympus models such as the 8562 FE120, 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 8576 This information is found in MP4 videos from Olympus models such as the 8577 u7040 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 8588 This 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 8602 This information is found in WAV files from Olympus PCM linear recorders 8603 like 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 4420 8630 =head2 Panasonic Tags 4421 8631 4422 Panasonic tags are also used forLeica cameras.8632 These tags are used in Panasonic/Leica cameras. 4423 8633 4424 8634 Tag ID Tag Name Writable … … 4428 8638 0x0003 WhiteBalance int16u 4429 8639 0x0007 FocusMode int16u 4430 0x000f AF Modeint8u[2]8640 0x000f AFAreaMode int8u[2] 4431 8641 0x001a ImageStabilization int16u 4432 8642 0x001c MacroMode int16u … … 4442 8652 0x002a BurstMode int16u 4443 8653 0x002b SequenceNumber int32u 4444 0x002c Contrast 8654 0x002c ContrastMode int16u 4445 8655 0x002d NoiseReduction int16u 4446 8656 0x002e SelfTimer int16u 4447 8657 0x0030 Rotation int16u 8658 0x0031 AFAssistLamp int16u 4448 8659 0x0032 ColorMode int16u 4449 8660 0x0033 BabyAge string … … 4451 8662 0x0035 ConversionLens int16u 4452 8663 0x0036 TravelDay int16u 8664 0x0039 Contrast int16u 4453 8665 0x003a WorldTimeLocation int16u 8666 0x003b TextStamp int16u 4454 8667 0x003c ProgramISO int16u 8668 0x003d AdvancedSceneMode int16u 8669 0x003e TextStamp int16u 8670 0x003f FacesDetected int16u 8671 0x0040 Saturation int16u 8672 0x0041 Sharpness int16u 4455 8673 0x0042 FilmMode int16u 4456 8674 0x0046 WBAdjustAB int16u 4457 8675 0x0047 WBAdjustGM int16u 8676 0x004b PanasonicImageWidth int32u 8677 0x004c PanasonicImageHeight int32u 8678 0x004d AFPointPosition rational64u[2] 8679 0x004e FaceDetInfo Panasonic FaceDetInfo 4458 8680 0x0051 LensType string 4459 8681 0x0052 LensSerialNumber string 4460 8682 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 4461 8697 0x0e00 PrintIM PrintIM 4462 8698 0x8000 MakerNoteVersion undef … … 4465 8701 0x8005 WBGreenLevel int16u 4466 8702 0x8006 WBBlueLevel int16u 8703 0x8007 FlashFired int16u 8704 0x8008 TextStamp int16u 8705 0x8009 TextStamp int16u 4467 8706 0x8010 BabyAge string 8707 0x8012 Transform undef[4] 8708 8709 =head3 Panasonic FaceDetInfo Tags 8710 8711 Face 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 8724 Tags written by cameras with facial recognition. These cameras not only 8725 detect faces in an image, but also recognize specific people based a 8726 user-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 8743 These 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 8776 These 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 8784 This 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 8833 This 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 8845 This 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 4468 8852 4469 8853 =head3 Panasonic Type2 Tags … … 4478 8862 3 Gain N 4479 8863 4480 =head3 Panasonic Raw Tags4481 4482 These tags are found in IFD0 of Panasonic RAW images.4483 4484 Tag ID Tag Name Writable4485 ------ -------- --------4486 0x0001 PanasonicRawVersion undef4487 0x0002 SensorWidth N4488 0x0003 SensorHeight N4489 0x0004 SensorTopBorder N4490 0x0005 SensorLeftBorder N4491 0x0006 ImageHeight N4492 0x0007 ImageWidth N4493 0x0011 RedBalance int16u4494 0x0012 BlueBalance int16u4495 0x0017 ISO int16u4496 0x0024 WBRedLevel int16u4497 0x0025 WBGreenLevel int16u4498 0x0026 WBBlueLevel int16u4499 0x010f Make string4500 0x0110 Model string4501 0x0111 StripOffsets N4502 0x0112 Orientation int16u4503 0x0116 RowsPerStrip N4504 0x0117 StripByteCounts N4505 0x8769 ExifOffset EXIF4506 0x8825 GPSInfo GPS4507 4508 8864 =head2 Pentax Tags 4509 8865 4510 The Pentax tags are also used inAsahi cameras.8866 These tags are used in Pentax/Asahi cameras. 4511 8867 4512 8868 Tag ID Tag Name Writable … … 4522 8878 0x0008 Quality int16u 4523 8879 0x0009 PentaxImageSize int16u 4524 0x000b PictureMode int16u 4525 0x000c FlashMode N8880 0x000b PictureMode int16u[n] 8881 0x000c FlashMode int16u[n] 4526 8882 0x000d FocusMode int16u 4527 8883 0x000e AFPointSelected int16u … … 4531 8887 0x0013 FNumber int16u 4532 8888 0x0014 ISO int16u 8889 0x0015 LightReading int16u 4533 8890 0x0016 ExposureCompensation int16u 4534 8891 0x0017 MeteringMode int16u … … 4540 8897 0x001d FocalLength int32u 4541 8898 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] 4545 8902 0x0022 WorldTimeLocation int16u 4546 8903 0x0023 HometownCity int16u … … 4548 8905 0x0025 HometownDST int16u 4549 8906 0x0026 DestinationDST int16u 8907 0x0027 DSPFirmwareVersion undef 8908 0x0028 CPUFirmwareVersion undef 4550 8909 0x0029 FrameNumber int32u 4551 0x0032 ImageProcessing undef[4] 8910 0x002d EffectiveLV int16u 8911 0x0032 ImageEditing undef[4] 4552 8912 0x0033 PictureMode int8u[3] 4553 8913 0x0034 DriveMode int8u[4] 8914 0x0035 SensorSize int16u[2] 4554 8915 0x0037 ColorSpace int16u 4555 8916 0x0038 ImageAreaOffset int16u[2] 4556 8917 0x0039 RawImageSize int16u[2]~ 4557 8918 0x003c AFPointsInFocus N 8919 0x003e PreviewImageBorders int8u[4] 4558 8920 0x003f LensType int8u[2] 8921 0x0040 SensitivityAdjust int16u 8922 0x0041 ImageEditCount int16u 4559 8923 0x0047 CameraTemperature int8s 8924 0x0048 AELock int16u 4560 8925 0x0049 NoiseReduction int16u 4561 8926 0x004d FlashExposureComp int32s 4562 8927 0x004f ImageTone int16u 8928 0x0050 ColorTemperature int16u 4563 8929 0x005c ShakeReductionInfo Pentax SRInfo 4564 8930 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 4565 8952 0x0200 BlackPoint int16u[4] 4566 8953 0x0201 WhitePoint int16u[4] 8954 0x0203 ColorMatrixA int16s[9] 8955 0x0204 ColorMatrixB int16s[9] 8956 0x0205 CameraSettings Pentax CameraSettings 4567 8957 0x0206 AEInfo Pentax AEInfo 4568 8958 0x0207 LensInfo Pentax LensInfo 8959 Pentax LensInfo2 8960 Pentax LensInfo3 8961 Pentax LensInfo4 4569 8962 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] 4573 8967 0x020d WB_RGGBLevelsDaylight int16u[4] 4574 8968 0x020e WB_RGGBLevelsShade int16u[4] … … 4581 8975 0x0215 CameraInfo Pentax CameraInfo 4582 8976 0x0216 BatteryInfo Pentax BatteryInfo 8977 0x021b SaturationInfo? N 4583 8978 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] 4584 8993 0x03fe DataDump N 8994 0x03ff TempInfoK5 Pentax TempInfoK5 8995 UnknownInfo Pentax UnknownInfo 4585 8996 0x0402 ToneCurve Y~ 4586 8997 0x0403 ToneCurves Y~ … … 4595 9006 0 SRResult int8u 4596 9007 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 9044 Shot 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 4598 9079 4599 9080 =head3 Pentax AEInfo Tags … … 4606 9087 3 AEXv int8u 4607 9088 4 AEBXv int8s 4608 5 AE FlashTvint8u9089 5 AEMinExposureTime int8u 4609 9090 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 4611 9098 4612 9099 =head3 Pentax LensInfo Tags 4613 9100 9101 Pentax 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 9110 Pentax lens information structure for models such as the K10D and K20D. 9111 4614 9112 Index Tag Name Writable 4615 9113 ----- -------- -------- 4616 9114 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 9119 Pentax lens data information. Some of these tags require interesting binary 9120 gymnastics 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 9147 Pentax 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 9156 Pentax 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 4619 9162 4620 9163 =head3 Pentax FlashInfo Tags 4621 9164 9165 Flash information tags for the K10D, K20D and K200D. 9166 4622 9167 Index Tag Name Writable 4623 9168 ----- -------- -------- 4624 9169 0 FlashStatus int8u 4625 1 FlashModeCodeint8u9170 1 InternalFlashMode int8u 4626 9171 2 ExternalFlashMode int8u 4627 3 InternalFlash Magniint8u9172 3 InternalFlashStrength int8u 4628 9173 4 TTL_DA_AUp int8u 4629 9174 5 TTL_DA_ADown int8u 4630 9175 6 TTL_DA_BUp int8u 4631 9176 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] 4632 9186 4633 9187 =head3 Pentax CameraInfo Tags … … 4637 9191 0 PentaxModelID int32u 4638 9192 1 ManufactureDate int32u 4639 2 ModelRevisionint32u[2]9193 2 ProductionCode int32u[2] 4640 9194 4 InternalSerialNumber int32u 4641 9195 … … 4644 9198 Index Tag Name Writable 4645 9199 ----- -------- -------- 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 4652 9212 4653 9213 =head3 Pentax AFInfo Tags … … 4655 9215 Index Tag Name Writable 4656 9216 ----- -------- -------- 9217 0 AFPointsUnknown1? int16u 9218 2 AFPointsUnknown2? int16u 9219 4 AFPredictor int16s 9220 6 AFDefocus int8u 9221 7 AFIntegrationTime int8u 4657 9222 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 9320 The parameters associated with each type of digital filter are unique, and 9321 these settings are also extracted with the DigitalFilter tag. Information 9322 is not extracted for filters that are "Off" unless the Unknown option is 9323 used. 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 9352 Tags 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 9366 A number of additional temperature readings are extracted from this 256-byte 9367 binary-data block in images from the K-5. It is not currently known where 9368 the 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] 4658 9382 4659 9383 =head3 Pentax Type2 Tags … … 4682 9406 4683 9407 The following few tags are extracted from the wealth of information 4684 available in maker notes of the Optio E20 . These maker notes are stored as4685 ASCII text in a format very similar to some HP models.9408 available in maker notes of the Optio E20 and E25. These maker notes are 9409 stored as ASCII text in a format very similar to some HP models. 4686 9410 4687 9411 Tag ID Tag Name Writable … … 4691 9415 =head3 Pentax MOV Tags 4692 9416 4693 This information is found in Pentax MOV video images.9417 This information is found in Pentax MOV videos. 4694 9418 4695 9419 Index Tag Name Writable … … 4703 9427 175 ISO N 4704 9428 9429 =head3 Pentax Junk Tags 9430 9431 Tags 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 9439 Pentax-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 9447 The following tags are extracted from the maker notes of Reconyx Hyperfire 9448 cameras 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 4705 9472 =head2 Ricoh Tags 4706 4707 These tags are used by Ricoh Caplio camera models.4708 9473 4709 9474 Tag ID Tag Name Writable 4710 9475 ------ -------- -------- 4711 9476 0x0001 MakerNoteType string 4712 0x0002 MakerNoteVersion string 9477 0x0002 FirmwareVersion string 9478 0x0005 SerialNumber undef[16] 9479 InternalSerialNumber undef[16] 4713 9480 0x0e00 PrintIM PrintIM 4714 9481 0x1001 ImageInfo Ricoh ImageInfo … … 4737 9504 Tag ID Tag Name Writable 4738 9505 ------ -------- -------- 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 9537 This 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] 4741 9545 4742 9546 =head3 Ricoh Text Tags 4743 9547 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. 9548 Some Ricoh DC and RDC models use a text-based format for their maker notes 9549 instead of the IFD format used by the Caplio models. Below is a list of known 9550 tags in this information. 4748 9551 4749 9552 Tag ID Tag Name Writable … … 4751 9554 'Bg' BlueGain N 4752 9555 'Gg' GreenGain N 4753 'Rev' RevisionN9556 'Rev' FirmwareVersion N 4754 9557 'Rg' RedGain N 4755 'Rv' RevisionN9558 'Rv' FirmwareVersion N 4756 9559 4757 9560 =head3 Ricoh RMETA Tags … … 4768 9571 'Location' Location N 4769 9572 '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 9587 Tags found in the binary "STMN" format maker notes written by a number of 9588 Samsung 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 9598 Tags 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 9635 This information is found in MP4 videos from Samsung models such as the 9636 SMX-C20N. 9637 9638 Tag ID Tag Name Writable 9639 ------ -------- -------- 9640 'EFCT' Effect N 9641 'QLTY' Quality N 9642 9643 =head3 Samsung MP4 Tags 9644 9645 This information is found in Samsung MP4 videos from models such as the 9646 WP10. 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 4770 9661 4771 9662 =head2 Sanyo Tags … … 4796 9687 0x021f SceneSelect int16u 4797 9688 0x0223 ManualFocusDistance rational64u 9689 FaceInfo - 4798 9690 0x0224 SequenceShotInterval int16u 4799 9691 0x0225 FlashMode int16u … … 4801 9693 0x0f00 DataDump N 4802 9694 9695 =head3 Sanyo FaceInfo Tags 9696 9697 Index Tag Name Writable 9698 ----- -------- -------- 9699 0 FacesDetected int32u 9700 4 FacePosition int32u[4] 9701 4803 9702 =head3 Sanyo MOV Tags 4804 9703 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. 9704 This information is found in Sanyo MOV videos. 4807 9705 4808 9706 Index Tag Name Writable … … 4818 9716 =head3 Sanyo MP4 Tags 4819 9717 4820 This information is found in Sanyo MP4 video images.9718 This information is found in Sanyo MP4 videos. 4821 9719 4822 9720 Index Tag Name Writable … … 4825 9723 24 Model N 4826 9724 50 FNumber N 9725 58 ExposureCompensation N 4827 9726 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 4829 9733 4830 9734 =head2 Sigma Tags … … 4842 9746 0x0008 ExposureMode string 4843 9747 0x0009 MeteringMode string 4844 0x000a Lens 9748 0x000a LensFocalRange string 4845 9749 0x000b ColorSpace string 4846 9750 0x000c ExposureCompensation string 4847 UnknownCompensation?rational64s9751 ExposureAdjust? rational64s 4848 9752 0x000d Contrast string 4849 9753 Contrast rational64s … … 4865 9769 0x0018 Software string 4866 9770 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 4869 9781 0x0030 LensApertureRange string 4870 9782 0x0031 FNumber rational64u 4871 9783 0x0032 ExposureTime rational64u 9784 0x0033 ExposureTime2 string 9785 0x0034 BurstShot int32u 4872 9786 0x0035 ExposureCompensation rational64s 9787 0x0039 SensorTemperature string 4873 9788 0x003a FlashExposureComp rational64s 4874 9789 0x003b Firmware string 4875 9790 0x003c WhiteBalance string 9791 0x003d PictureMode string 4876 9792 4877 9793 =head2 Sony Tags 4878 9794 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. 9795 The maker notes in images from most recent Sony camera models contain a 9796 wealth of information, but for some models very little has been decoded. 9797 Use the ExifTool Unknown (-u) or Verbose (-v) options to see information 9798 about the unknown tags. Also see the Minolta tags which are used by some 9799 Sony models. 4883 9800 4884 9801 Tag ID Tag Name Writable 4885 9802 ------ -------- -------- 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 4886 9811 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 4893 9836 0xb028 MinoltaMakerNote Minolta 4894 9837 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 9857 Camera settings for the A200, A230, A300, A350, A700, A850 and A900. Some 9858 tags 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 9894 Camera 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 9922 Tags found only in panorama images from Sony cameras such as the HX1, HX5 9923 and TX7. The width/height values of these tags are not affected by camera 9924 rotation -- 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 9979 Maker notes found in images from some Sony Ericsson phones. 4906 9980 4907 9981 Tag ID Tag Name Writable 4908 9982 ------ -------- -------- 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 9989 The maker notes in SRF (Sony Raw Format) images contain 7 IFD's with family 9990 1 group names SRF0 through SRF6. SRF0 and SRF1 use the tags in this table, 9991 while SRF2 through SRF5 use the tags in the next table, and SRF6 uses 9992 standard EXIF tags. All information other than SRF0 is encrypted, but 9993 thanks to Dave Coffin the decryption algorithm is known. SRF images are 9994 written by the Sony DSC-F828 and DSC-V3. 9995 9996 Tag ID Tag Name Writable 9997 ------ -------- -------- 9998 0x0000 SRF2Key N 4910 9999 0x0001 DataKey N 4911 10000 10001 =head3 Sony SRF2 Tags 10002 10003 These 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 4912 10012 =head3 Sony SR2Private Tags 4913 10013 4914 10014 The SR2 format uses the DNGPrivateData tag to reference a private IFD 4915 containing these tags. 10015 containing these tags. SR2 images are written by the Sony DSC-R1, but 10016 this information is also written to ARW images by other models. 4916 10017 4917 10018 Tag ID Tag Name Writable … … 4920 10021 0x7201 SR2SubIFDLength N 4921 10022 0x7221 SR2SubIFDKey N 10023 0x7240 IDC_IFD SonyIDC 10024 0x7241 IDC2_IFD SonyIDC 10025 0x7250 MRWInfo MinoltaRaw 4922 10026 4923 10027 =head3 Sony SR2SubIFD Tags … … 4928 10032 ------ -------- -------- 4929 10033 0x7303 WB_GRBGLevels N 10034 0x7313 WB_RGGBLevels N 4930 10035 0x74a0 MaxApertureAtMaxFocal N 4931 10036 0x74a1 MaxApertureAtMinFocal N 4932 10037 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 4933 10044 4934 10045 =head3 Sony SR2DataIFD Tags … … 4938 10049 0x7770 ColorMode N 4939 10050 10051 =head3 Sony PMP Tags 10052 10053 These tags are written in the proprietary-format header of PMP images from 10054 the 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 10075 Tags 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 4940 10121 =head2 Unknown Tags 4941 10122 … … 4950 10131 4951 10132 The 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. 10133 information found within structures of these main DNG tag values. See 10134 L<http://www.adobe.com/products/dng/> for the official DNG specification. 4953 10135 4954 10136 =head3 DNG AdobeData Tags … … 4958 10140 The maker notes ('MakN') are processed by ExifTool, but some information may 4959 10141 have 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 referenced10142 Converter (as of version 6.3) doesn't properly handle information referenced 4961 10143 from 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). 10144 block. This information is lost when only the maker note block is copied to 10145 the DNG image. While this doesn't effect all makes of cameras, it is a 10146 problem for some major brands such as Olympus and Sony. 10147 10148 Other entries in this table represent proprietary information that is 10149 extracted from the original RAW image and restructured to a different (but 10150 still proprietary) Adobe format. 4970 10151 4971 10152 Tag ID Tag Name Writable 4972 10153 ------ -------- -------- 4973 10154 'CRW ' AdobeCRW CanonRaw 10155 'Koda' AdobeKoda Kodak IFD 10156 'Leaf' AdobeLeaf Leaf SubIFD 4974 10157 'MRW ' AdobeMRW MinoltaRaw 4975 10158 'MakN' MakerNoteCanon Canon … … 4977 10160 MakerNoteCasio2 Casio Type2 4978 10161 MakerNoteFujiFilm FujiFilm 10162 MakerNoteGE GE 10163 MakerNoteGE2 FujiFilm 4979 10164 MakerNoteHP HP 4980 10165 MakerNoteHP2 HP Type2 4981 10166 MakerNoteHP4 HP Type4 4982 10167 MakerNoteHP6 HP Type6 10168 MakerNoteISL Unknown 4983 10169 MakerNoteJVC JVC 4984 10170 MakerNoteJVCText JVC Text … … 4992 10178 MakerNoteKodak6b Kodak Type6 4993 10179 MakerNoteKodak7 Kodak Type7 4994 MakerNoteKodakIFD Kodak IFD 10180 MakerNoteKodak8a Kodak Type8 10181 MakerNoteKodak8b Kodak Type8 10182 MakerNoteKodak9 Kodak Type9 10183 MakerNoteKodak10 Kodak Type10 4995 10184 MakerNoteKodakUnknown Kodak Unknown 4996 10185 MakerNoteKyocera Unknown … … 5004 10193 MakerNoteOlympus2 Olympus 5005 10194 MakerNoteLeica Panasonic 10195 MakerNoteLeica2 Panasonic Leica2 10196 MakerNoteLeica3 Panasonic Leica3 10197 MakerNoteLeica4 Panasonic Leica4 10198 MakerNoteLeica5 Panasonic Leica5 10199 MakerNoteLeica6 Panasonic Leica6 5006 10200 MakerNotePanasonic Panasonic 5007 10201 MakerNotePanasonic2 Panasonic Type2 … … 5010 10204 MakerNotePentax3 Casio Type2 5011 10205 MakerNotePentax4 Pentax Type4 10206 MakerNotePentax5 Pentax 10207 MakerNotePhaseOne undef 10208 MakerNoteReconyx Reconyx 5012 10209 MakerNoteRicoh Ricoh 5013 10210 MakerNoteRicohText Ricoh Text 5014 PreviewImage undef 10211 MakerNoteSamsung1a undef 10212 MakerNoteSamsung1b Samsung Type1 10213 MakerNoteSamsung2 Samsung Type2 5015 10214 MakerNoteSanyo Sanyo 5016 10215 MakerNoteSanyoC4 Sanyo … … 5018 10217 MakerNoteSigma Sigma 5019 10218 MakerNoteSony Sony 10219 MakerNoteSony2 Olympus 10220 MakerNoteSony3 Olympus 10221 MakerNoteSony4 Sony 10222 MakerNoteSonyEricsson Sony Ericsson 5020 10223 MakerNoteSonySRF Sony SRF 5021 MakerNote SonySR2 Sony10224 MakerNoteUnknownText undef 5022 10225 MakerNoteUnknown Unknown 5023 'RAF ' AdobeRAF? N 10226 'Pano' AdobePano PanasonicRaw 10227 'RAF ' AdobeRAF FujiFilm RAF 5024 10228 'SR2 ' AdobeSR2 Sony SR2Private 5025 10229 … … 5047 10251 or padded as required) unless B<Writable> is C<resize>. Currently, only 5048 10252 JpgFromRaw and ThumbnailImage are allowed to change size. 10253 10254 CRW images also support the addition of a CanonVRD trailer, which in turn 10255 supports XMP. This trailer is created automatically if necessary when 10256 ExifTool is used to write XMP to a CRW image. 5049 10257 5050 10258 Tag ID Tag Name Writable … … 5073 10281 0x102c CanonColorInfo2 N 5074 10282 0x102d CanonCameraSettings Canon CameraSettings 10283 0x1030 WhiteSample CanonRaw WhiteSample 5075 10284 0x1031 SensorInfo Canon SensorInfo 5076 10285 0x1033 CustomFunctions10D CanonCustom Functions10D … … 5089 10298 0x1807 TargetDistanceSetting float 5090 10299 0x180b SerialNumber int32u 10300 UnknownNumber? Y 5091 10301 0x180e TimeStamp CanonRaw TimeStamp 5092 10302 0x1810 ImageInfo CanonRaw ImageInfo … … 5096 10306 0x1818 ExposureInfo CanonRaw ExposureInfo 5097 10307 0x1834 CanonModelID int32u 5098 0x1835 DecoderTable N10308 0x1835 DecoderTable CanonRaw DecoderTable 5099 10309 0x183b SerialNumberFormat int32u 5100 10310 0x2005 RawData N … … 5114 10324 ----- -------- -------- 5115 10325 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 5117 10337 5118 10338 =head3 CanonRaw RawJpgInfo Tags … … 5164 10384 ----- -------- -------- 5165 10385 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 5217 10396 5218 10397 =head2 KyoceraRaw Tags … … 5234 10413 124 Lens N 5235 10414 10415 =head2 MinoltaRaw Tags 10416 10417 These 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 10482 These 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 5236 10512 =head2 SigmaRaw Tags 5237 10513 5238 These tags are used in Sigma and Foveon RAW (.X3F) images. 10514 These tags are used in Sigma and Foveon RAW (.X3F) images. Metadata is also 10515 extracted from the JpgFromRaw image if it exists (all models but the SD9 and 10516 SD10). Currently, metadata may only be written to the embedded JpgFromRaw. 5239 10517 5240 10518 Tag ID Tag Name Writable … … 5243 10521 'HeaderExt' HeaderExt SigmaRaw HeaderExt 5244 10522 'IMA2' PreviewImage N 10523 JpgFromRaw N 5245 10524 'IMAG' PreviewImage N 5246 10525 'PROP' Properties SigmaRaw Properties … … 5251 10530 ------ -------- -------- 5252 10531 0x0001 FileVersion N 10532 0x0002 ImageUniqueID N 10533 0x0006 MarkBits N 5253 10534 0x0007 ImageWidth N 5254 10535 0x0008 ImageHeight N 5255 10536 0x0009 Rotation N 5256 10537 0x000a WhiteBalance N 10538 0x0012 SceneCaptureType N 5257 10539 5258 10540 =head3 SigmaRaw HeaderExt Tags … … 5290 10572 'CAMNAME' CameraName N 5291 10573 'CAMSERIAL' SerialNumber N 10574 'CM_DESC' SceneCaptureType N 5292 10575 'COLORSPACE' ColorSpace N 5293 10576 'DRIVE' DriveMode N … … 5305 10588 'FLEQ35MM' FocalLengthIn35mmFormat N 5306 10589 'FOCUS' Focus N 10590 'IMAGEBOARDID' ImageBoardID N 5307 10591 'IMAGERBOARDID' ImagerBoardID N 5308 10592 'IMAGERTEMP' SensorTemperature N … … 5310 10594 'LENSARANGE' LensApertureRange N 5311 10595 'LENSFRANGE' LensFocalRange N 5312 'LENSMODEL' Lens IDN10596 'LENSMODEL' LensType N 5313 10597 'PMODE' ExposureProgram N 5314 10598 'RESOLUTION' Quality N … … 5322 10606 =head2 JFIF Tags 5323 10607 10608 The following information is extracted from the JPEG JFIF header. See 10609 L<http://www.jpeg.org/public/jfif.pdf> for the JFIF 1.02 specification. 10610 5324 10611 Index Tag Name Writable 5325 10612 ----- -------- -------- … … 5340 10627 Hewlett-Packard and Microsoft. Internally the FPX file structure mimics 5341 10628 that 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 10630 popular. However, some of the structures used in FlashPix streams are part 10631 of the EXIF specification, and are still being used in the APP2 FPXR segment 10632 of JPEG images by some Kodak and Hewlett-Packard digital cameras. 5347 10633 5348 10634 ExifTool extracts FlashPix information from both FPX images and the APP2 5349 10635 FPXR 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. 10636 from DOC, PPT, XLS (Microsoft Word, PowerPoint and Excel) documents, VSD 10637 (Microsoft Visio) drawings, and FLA (Macromedia/Adobe Flash project) files 10638 since these are based on the same file format as FlashPix (the Windows 10639 Compound Binary File format). See 10640 L<http://graphcomp.com/info/specs/livepicture/fpx.pdf> for the FlashPix 10641 specification. 5352 10642 5353 10643 Tag ID Tag Name Writable … … 5366 10656 "\x05Transform" Transform FlashPix Transform 5367 10657 'Audio Stream' AudioStream N 10658 'Contents' Contents XMP 5368 10659 'Current User' CurrentUser N 5369 10660 'ICC Profile 0001' ICC_Profile ICC_Profile … … 5579 10870 0x0006 Comments N 5580 10871 0x0007 Template N 5581 0x0008 Last SavedByN10872 0x0008 LastModifiedBy N 5582 10873 0x0009 RevisionNumber N 5583 10874 0x000a TotalEditTime N … … 5585 10876 0x000c CreateDate N 5586 10877 0x000d ModifyDate N 5587 0x000e Page CountN5588 0x000f Word CountN5589 0x0010 Char CountN10878 0x000e Pages N 10879 0x000f Words N 10880 0x0010 Characters N 5590 10881 0x0011 ThumbnailClip N 5591 10882 0x0012 Software N … … 5626 10917 5 SubimageTileHeight N 5627 10918 6 NumChannels N 10919 10920 =head2 MPF Tags 10921 10922 These tags are part of the CIPA Multi-Picture Format specification, and are 10923 found in the APP2 "MPF" segment of JPEG images. See 10924 L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-007_E.pdf> for the 10925 official 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 10951 The first MPF "Large Thumbnail" image is extracted as PreviewImage, and the 10952 rest of the embedded MPF images are extracted as MPImage#. The 10953 ExtractEmbedded (-ee) option may be used to extract information from these 10954 embedded 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 10968 These tags are part of the CIPA Stereo Still Image specification, and are 10969 found in the APP3 "Stim" segment of JPEG images. See 10970 L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-006_E.pdf> for the 10971 official 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 5628 11015 5629 11016 =head2 APP12 Tags … … 5685 11072 5686 11073 ExifTool will read and write (but not create) AFCP IPTC information in JPEG 5687 images, but not other image formats.11074 and TIFF images. 5688 11075 5689 11076 Tag ID Tag Name Writable … … 5693 11080 'PrVw' PreviewImage N 5694 11081 'TEXT' Text N 5695 5696 =head2 CanonVRD Tags5697 5698 Canon Digital Photo Professional writes VRD (Recipe Data) information as a5699 trailer record to JPEG, TIFF, CRW and CR2 images, or as a stand-alone VRD5700 file. The tags listed below represent information found in this record. The5701 complete VRD data record may be accessed as a block using the Extra5702 'CanonVRD' tag, but this tag is not extracted or copied unless specified5703 explicitly.5704 5705 Index Tag Name Writable5706 ----- -------- --------5707 0 VRD1 CanonVRD Ver15708 1 VRDStampTool CanonVRD StampTool5709 2 VRD2 CanonVRD Ver25710 5711 =head3 CanonVRD Ver1 Tags5712 5713 Index Tag Name Writable5714 ----- -------- --------5715 2 VRDVersion N5716 8 WBAdjRGBLevels int16u[3]5717 24 WhiteBalanceAdj int16u5718 26 WBAdjColorTemp int16u5719 36 WBFineTuneActive int16u5720 40 WBFineTuneSaturation int16u5721 44 WBFineTuneTone int16u5722 46 RawColorAdj int16u5723 48 RawCustomSaturation int32s5724 52 RawCustomTone int32s5725 56 RawBrightnessAdj int32s5726 60 ToneCurveProperty int16u5727 122 DynamicRangeMin int16u5728 124 DynamicRangeMax int16u5729 272 ToneCurveActive int16u5730 276 BrightnessAdj int8s5731 277 ContrastAdj int8s5732 278 SaturationAdj int16s5733 286 ColorToneAdj int32s5734 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 int16u5743 582 CropLeft int16u5744 584 CropTop int16u5745 586 CropWidth int16u5746 588 CropHeight int16u5747 608 CropAspectRatio int16u5748 610 ConstrainedCropWidth float5749 614 ConstrainedCropHeight float5750 618 CheckMark int16u5751 622 Rotation int16u5752 624 WorkColorSpace int16u5753 5754 =head3 CanonVRD StampTool Tags5755 5756 Index Tag Name Writable5757 ----- -------- --------5758 0 StampToolCount N5759 5760 =head3 CanonVRD Ver2 Tags5761 5762 Tags added in DPP version 2.0 and later.5763 5764 Index Tag Name Writable5765 ----- -------- --------5766 4 PictureStyle int16u5767 26 RawColorToneAdj int16s5768 28 RawSaturationAdj int16s5769 30 RawContrastAdj int16s5770 32 RawLinear int16u5771 34 RawSharpnessAdj int16s5772 36 RawHighlightPoint int16s5773 38 RawShadowPoint int16s5774 116 MonochromeFilterEffect int16s5775 118 MonochromeToningEffect int16s5776 120 MonochromeContrast int16s5777 122 MonochromeLinear int16u5778 124 MonochromeSharpness int16s5779 188 ChrominanceNoiseReduction int16u5780 190 LuminanceNoiseReduction int16u5781 192 ChrominanceNR_TIFF_JPEG int16u5782 11082 5783 11083 =head2 FotoStation Tags … … 5836 11136 222 ColorClass int32s 5837 11137 223 Rating int32s 11138 236 PreviewCropLeft int32s 11139 237 PreviewCropTop int32s 11140 238 PreviewCropRight int32s 11141 239 PreviewCropBottom int32s 5838 11142 5839 11143 =head3 PhotoMechanic XMP Tags … … 5843 11147 the "XMP-photomech" family 1 group name. 5844 11148 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 11160 Microsoft Photo 1.0 schema XMP tags. This is likely not a complete list, 11161 but represents tags which have been observed in sample images. The actual 11162 namespace 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 11179 Microsoft 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 11192 Microsoft 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 11203 Information found in the Microsoft custom EXIF tag 0x4748, as written by 11204 Windows 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 11218 The GNU Image Manipulation Program (GIMP) writes these tags in its native 11219 XCF (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 5845 11246 Tag ID Tag Name Writable 5846 11247 ------ -------- -------- 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 5851 11255 5852 11256 =head2 MIE Tags … … 5923 11327 'Channels' Channels int8u 5924 11328 'Compression' AudioCompression string 5925 'Duration' Duration rational64u 11329 'Duration' Duration rational64u~ 5926 11330 'SampleBits' SampleBits int16u 5927 11331 'SampleRate' SampleRate int32u … … 6093 11497 6094 11498 MIE maker notes are contained within separate groups for each manufacturer 6095 to avoid name conflicts. Currently no specific manufacturer information has 6096 been defined. 11499 to avoid name conflicts. 6097 11500 6098 11501 Tag ID Tag Name Writable 6099 11502 ------ -------- -------- 6100 'Canon' Canon MIE Unknown11503 'Canon' Canon MIE Canon 6101 11504 'Casio' Casio MIE Unknown 6102 11505 'FujiFilm' FujiFilm MIE Unknown … … 6111 11514 'Sony' Sony MIE Unknown 6112 11515 11516 =head3 MIE Canon Tags 11517 11518 Tag ID Tag Name Writable 11519 ------ -------- -------- 11520 'VRD' CanonVRD CanonVRD 11521 6113 11522 =head3 MIE Unknown Tags 6114 11523 … … 6142 11551 '1Name' RelatedVideoFileName string 6143 11552 'Codec' Codec string 6144 'Duration' Duration rational64u 11553 'Duration' Duration rational64u~ 6145 11554 'data' RelatedVideoFile undef 6146 6147 =head2 ID3 Tags6148 6149 ExifTool extracts ID3 information from MP3, MPEG, AIFF, OGG, FLAC, APE and6150 RealAudio files.6151 6152 Index Tag Name Writable6153 ----- -------- --------6154 'ID3v1' ID3v1 ID3 v16155 'ID3v22' ID3v2_2 ID3 v2_26156 'ID3v23' ID3v2_3 ID3 v2_36157 'ID3v24' ID3v2_4 ID3 v2_46158 6159 =head3 ID3 v1 Tags6160 6161 Index Tag Name Writable6162 ----- -------- --------6163 3 Title N6164 33 Artist N6165 63 Album N6166 93 Year N6167 97 Comment N6168 127 Genre N6169 6170 =head3 ID3 v2_2 Tags6171 6172 ExifTool extracts mainly text-based tags from ID3v2 information. The tags6173 in the tables below are those extracted by ExifTool, and don't represent a6174 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 Writable6179 ------ -------- --------6180 'CNT' PlayCounter N6181 'COM' Comment N6182 'IPL' InvolvedPeople N6183 'PIC' Picture N6184 'TAL' Album N6185 'TBP' BeatsPerMinute N6186 'TCM' Composer N6187 'TCO' Genre N6188 'TCP' Compilation N6189 'TCR' Copyright N6190 'TDA' Date N6191 'TDY' PlaylistDelay N6192 'TEN' EncodedBy N6193 'TFT' FileType N6194 'TIM' Time N6195 'TKE' InitialKey N6196 'TLA' Language N6197 'TLE' Length N6198 'TMT' Media N6199 'TOA' OriginalArtist N6200 'TOF' OriginalFilename N6201 'TOL' OriginalLyricist N6202 'TOR' OriginalReleaseYear N6203 'TOT' OriginalAlbum N6204 'TP1' Artist N6205 'TP2' Band N6206 'TP3' Conductor N6207 'TP4' InterpretedBy N6208 'TPA' PartOfSet N6209 'TPB' Publisher N6210 'TRC' ISRC N6211 'TRD' RecordingDates N6212 'TRK' Track N6213 'TSI' Size N6214 'TSS' EncoderSettings N6215 'TT1' Grouping N6216 'TT2' Title N6217 'TT3' Subtitle N6218 'TXT' Lyricist N6219 'TXX' UserDefinedText N6220 'TYE' Year N6221 'ULT' Lyrics N6222 'WAF' FileRUL N6223 'WAR' ArtistURL N6224 'WAS' SourceURL N6225 'WCM' CommercialURL N6226 'WCP' CopyrightURL N6227 'WPB' PublisherURL N6228 'WXX' UserDefinedURL N6229 6230 =head3 ID3 v2_3 Tags6231 6232 ID3 version 2.3 tags6233 6234 Tag ID Tag Name Writable6235 ------ -------- --------6236 'APIC' Picture N6237 'COMM' Comment N6238 'IPLS' InvolvedPeople N6239 'MCDI' MusicCDIdentifier N6240 'PCNT' PlayCounter N6241 'PRIV' Private ID3 Private6242 'TALB' Album N6243 'TBPM' BeatsPerMinute N6244 'TCOM' Composer N6245 'TCON' Genre N6246 'TCOP' Copyright N6247 'TDAT' Date N6248 'TDLY' PlaylistDelay N6249 'TENC' EncodedBy N6250 'TEXT' Lyricist N6251 'TFLT' FileType N6252 'TIME' Time N6253 'TIT1' Grouping N6254 'TIT2' Title N6255 'TIT3' Subtitle N6256 'TKEY' InitialKey N6257 'TLAN' Language N6258 'TLEN' Length N6259 'TMED' Media N6260 'TOAL' OriginalAlbum N6261 'TOFN' OriginalFilename N6262 'TOLY' OriginalLyricist N6263 'TOPE' OriginalArtist N6264 'TORY' OriginalReleaseYear N6265 'TOWN' FileOwner N6266 'TPE1' Artist N6267 'TPE2' Band N6268 'TPE3' Conductor N6269 'TPE4' InterpretedBy N6270 'TPOS' PartOfSet N6271 'TPUB' Publisher N6272 'TRCK' Track N6273 'TRDA' RecordingDates N6274 'TRSN' InternetRadioStationName N6275 'TRSO' InternetRadioStationOwner N6276 'TSIZ' Size N6277 'TSRC' ISRC N6278 'TSSE' EncoderSettings N6279 'TXXX' UserDefinedText N6280 'TYER' Year N6281 'USER' TermsOfUse N6282 'USLT' Lyrics N6283 'WCOM' CommercialURL N6284 'WCOP' CopyrightURL N6285 'WOAF' FileRUL N6286 'WOAR' ArtistURL N6287 'WOAS' SourceURL N6288 'WORS' InternetRadioStationURL N6289 'WPAY' PaymentURL N6290 'WPUB' PublisherURL N6291 'WXXX' UserDefinedURL N6292 6293 =head3 ID3 Private Tags6294 6295 ID3 private (PRIV) tags.6296 6297 Tag ID Tag Name Writable6298 ------ -------- --------6299 'AverageLevel' AverageLevel N6300 'PeakValue' PeakValue N6301 'XMP' XMP XMP6302 6303 =head3 ID3 v2_4 Tags6304 6305 ID3 version 2.4 tags6306 6307 Tag ID Tag Name Writable6308 ------ -------- --------6309 'APIC' Picture N6310 'COMM' Comment N6311 'MCDI' MusicCDIdentifier N6312 'PCNT' PlayCounter N6313 'PRIV' Private ID3 Private6314 'TALB' Album N6315 'TBPM' BeatsPerMinute N6316 'TCOM' Composer N6317 'TCON' Genre N6318 'TCOP' Copyright N6319 'TDEN' EncodingTime N6320 'TDLY' PlaylistDelay N6321 'TDOR' OriginalReleaseTime N6322 'TDRC' RecordingTime N6323 'TDRL' ReleaseTime N6324 'TDTG' TaggingTime N6325 'TENC' EncodedBy N6326 'TEXT' Lyricist N6327 'TFLT' FileType N6328 'TIPL' InvolvedPeople N6329 'TIT1' Grouping N6330 'TIT2' Title N6331 'TIT3' Subtitle N6332 'TKEY' InitialKey N6333 'TLAN' Language N6334 'TLEN' Length N6335 'TMCL' MusicianCredits N6336 'TMED' Media N6337 'TMOO' Mood N6338 'TOAL' OriginalAlbum N6339 'TOFN' OriginalFilename N6340 'TOLY' OriginalLyricist N6341 'TOPE' OriginalArtist N6342 'TOWN' FileOwner N6343 'TPE1' Artist N6344 'TPE2' Band N6345 'TPE3' Conductor N6346 'TPE4' InterpretedBy N6347 'TPOS' PartOfSet N6348 'TPRO' ProducedNotice N6349 'TPUB' Publisher N6350 'TRCK' Track N6351 'TRSN' InternetRadioStationName N6352 'TRSO' InternetRadioStationOwner N6353 'TSOA' AlbumSortOrder N6354 'TSOP' PerformerSortOrder N6355 'TSOT' TitleSortOrder N6356 'TSRC' ISRC N6357 'TSSE' EncoderSettings N6358 'TSST' SetSubtitle N6359 'TXXX' UserDefinedText N6360 'USER' TermsOfUse N6361 'USLT' Lyrics N6362 'WCOM' CommercialURL N6363 'WCOP' CopyrightURL N6364 'WOAF' FileRUL N6365 'WOAR' ArtistURL N6366 'WOAS' SourceURL N6367 'WORS' InternetRadioStationURL N6368 'WPAY' PaymentURL N6369 'WPUB' PublisherURL N6370 'WXXX' UserDefinedURL N6371 11555 6372 11556 =head2 Jpeg2000 Tags … … 6396 11580 'free' Free N 6397 11581 'ftbl' FragmentTable N 6398 'ftyp' FileType N11582 'ftyp' FileType Jpeg2000 FileType 6399 11583 'gtso' GraphicsTechnologyStandardOutput N 6400 11584 'ihdr' ImageHeader Jpeg2000 ImageHeader … … 6428 11612 'xml ' XML XMP 6429 11613 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 6430 11622 =head3 Jpeg2000 ImageHeader Tags 6431 11623 … … 6455 11647 8 DisplayYResolutionUnit N 6456 11648 9 DisplayXResolutionUnit N 11649 11650 =head2 GIF Tags 11651 11652 This table lists information extracted from GIF images. See 11653 L<http://www.w3.org/Graphics/GIF/spec-gif89a.txt> for the official GIF89a 11654 specification. 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 11669 Information 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 11677 Information 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 6457 11687 6458 11688 =head2 BMP Tags … … 6473 11703 32 NumColors N 6474 11704 36 NumImportantColors N 11705 11706 =head3 BMP OS2 Tags 11707 11708 Information 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 6475 11716 6476 11717 =head2 PICT Tags … … 6633 11874 =head2 PNG Tags 6634 11875 11876 Tags extracted from PNG images. See 11877 L<http://www.libpng.org/pub/png/spec/1.2/> for the official PNG 1.2 11878 specification. 11879 6635 11880 Tag ID Tag Name Writable 6636 11881 ------ -------- -------- … … 6639 11884 'bKGD' BackgroundColor N 6640 11885 'cHRM' PrimaryChromaticities PNG PrimaryChromaticities 11886 'dSIG' DigitalSignature N 6641 11887 'fRAc' FractalParameters N 6642 11888 'gAMA' Gamma N … … 6651 11897 'pHYs' PhysicalPixel PNG PhysicalPixel 6652 11898 'sBIT' SignificantBits N 11899 'sCAL' SubjectScale PNG SubjectScale 6653 11900 'sPLT' SuggestedPalette N 6654 11901 'sRGB' SRGBRendering N 11902 'sTER' StereoImage PNG StereoImage 6655 11903 'tEXt' TextualData PNG TextualData 6656 11904 'tIME' ModifyDate Y 6657 11905 'tRNS' Transparency N 6658 11906 'tXMP' XMP XMP 11907 'vpAg' VirtualPage PNG VirtualPage 6659 11908 'zTXt' CompressedText PNG TextualData 6660 11909 … … 6686 11935 =head3 PNG TextualData Tags 6687 11936 6688 The PNG TextualData format allows ar ibrary tag names to be used. The tags11937 The PNG TextualData format allows arbitrary tag names to be used. The tags 6689 11938 listed below are the only ones that can be written (unless new user-defined 6690 11939 tags are added via the configuration file), however ExifTool will extract 6691 11940 any other TextualData tags that are found. 6692 11941 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. 11942 These tags may be stored as tEXt, zTXt or iTXt chunks in the PNG image. By 11943 default ExifTool writes new string-value tags as as uncompressed tEXt, or 11944 compressed zTXt if the Compress (-z) option is used and Compress::Zlib is 11945 available. Alternate language tags and values containing special characters 11946 (unless the Latin character set is used) are written as iTXt, and compressed 11947 if the Compress option is used and Compress::Zlib is available. Raw profile 11948 information is always created as compressed zTXt if Compress::Zlib is 11949 available, or tEXt otherwise. Standard XMP is written as uncompressed iTXt. 11950 11951 Alternate languages are accessed by suffixing the tag name with a '-', 11952 followed 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 11954 specification. 6698 11955 6699 11956 Some of the tags below are not registered as part of the PNG specification, … … 6728 11985 'Warning' PNGWarning string 6729 11986 'XML:com.adobe.xmp' XMP XMP 11987 'create-date' CreateDate string 11988 'modify-date' ModDate string 6730 11989 6731 11990 =head3 PNG PhysicalPixel Tags … … 6736 11995 4 PixelsPerUnitY N 6737 11996 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 6738 12019 6739 12020 =head2 MNG Tags … … 6956 12237 2 Priority N 6957 12238 12239 =head2 DjVu Tags 12240 12241 Information 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 12253 Information 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 12262 This table lists the standard DjVu metadata tags, but ExifTool will extract 12263 any tags that exist even if they don't appear here. The DjVu v3 12264 documentation endorses tags borrowed from two standards: 1) BibTeX 12265 bibliography system tags (all lowercase Tag ID's in the table below), and 2) 12266 PDF 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 12324 The following table lists information extracted from the header of 12325 Progressive Graphics File (PGF) images. As well, information is extracted 12326 from the embedded PNG metadata image if it exists. See 12327 L<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 6958 12341 =head2 MIFF Tags 6959 12342 6960 The MIFF format allows aribrary tag names to be used. Only the standard tag6961 names are listed below, however ExifTool will decode any tags found in the 6962 image.12343 The MIFF (Magick Image File Format) format allows aribrary tag names to be 12344 used. Only the standard tag names are listed below, however ExifTool will 12345 decode any tags found in the image. 6963 12346 6964 12347 Tag ID Tag Name Writable … … 7000 12383 'white-point' WhitePoint N 7001 12384 12385 =head2 PSP Tags 12386 12387 Tags extracted from Paint Shop Pro images (PSP, PSPIMAGE, PSPFRAME, 12388 PSPSHAPE, 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 7002 12430 =head2 PDF Tags 7003 12431 7004 12432 The tags listed in the PDF tables below are those which are used by ExifTool 7005 12433 to extract meta information, but they are only a small fraction of the total 7006 number of available PDF tags. 12434 number of available PDF tags. See 12435 L<http://www.adobe.com/devnet/pdf/pdf_reference.html> for the official PDF 12436 specification. 12437 12438 ExifTool supports reading and writing PDF documents up to version 1.7 12439 extension level 3, including support for RC4, AES-128 and AES-256 12440 encryption. A Password option is provided to allow processing of 12441 password-protected PDF files. 12442 12443 When writing PDF files, ExifTool uses an incremental update. This has the 12444 advantages of being fast and reversible. The original PDF can be easily 12445 recovered by deleting the C<PDF-update> pseudo-group (with 12446 C<-PDF-update:all=> on the command line). But there are two main 12447 disadvantages to this technique: 12448 12449 1) A linearized PDF file is no longer linearized after the update, so it 12450 must be subsequently re-linearized if this is required. 12451 12452 2) All metadata edits are reversible. While this would normally be 12453 considered an advantage, it is a potential security problem because old 12454 information 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 12465 Tags extracted from the document Encrypt dictionary. 7007 12466 7008 12467 Tag ID Tag Name Writable 7009 12468 ------ -------- -------- 7010 ' Info' Info PDF Info7011 ' Root' Root PDF Root12469 'Filter' Encryption N 12470 'P' UserAccess N 7012 12471 7013 12472 =head3 PDF Info Tags … … 7015 12474 As well as the tags listed below, the PDF specification allows for 7016 12475 user-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. 12476 have corresponding XMP-pdfx entries in the XMP of the PDF XML Metadata 12477 object, are also extracted by ExifTool. 12478 12479 B<Writable> specifies the value format, and may be C<string>, C<date>, 12480 C<integer>, C<real>, C<boolean> or C<name> for PDF tags. 7019 12481 7020 12482 Tag ID Tag Name Writable 7021 12483 ------ -------- -------- 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! 7031 12494 7032 12495 =head3 PDF Root Tags … … 7034 12497 This is the PDF document catalog. 7035 12498 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 7040 12515 7041 12516 =head3 PDF Metadata Tags … … 7065 12540 ------ -------- -------- 7066 12541 'AdobePhotoshop' AdobePhotoshop PDF AdobePhotoshop 12542 'Illustrator' Illustrator PDF Illustrator 7067 12543 7068 12544 =head3 PDF AdobePhotoshop Tags … … 7080 12556 =head3 PDF ImageResources Tags 7081 12557 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 7085 12583 7086 12584 =head3 PDF Resources Tags … … 7104 12602 =head3 PDF ICCBased Tags 7105 12603 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 12610 Additional 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+ 7109 12650 7110 12651 =head2 PostScript Tags … … 7113 12654 ------ -------- -------- 7114 12655 'Author' Author string 12656 'BeginDocument' EmbeddedFile PostScript 7115 12657 'BeginICCProfile' ICC_Profile ICC_Profile 7116 12658 'BeginPhotoshop' PhotoshopData Photoshop 7117 12659 'BoundingBox' BoundingBox N 7118 12660 'Copyright' Copyright string 7119 'CreationDate' CreateDate string 12661 'CreationDate' CreateDate string~ 7120 12662 'Creator' Creator string 12663 'EmbeddedFileName' EmbeddedFileName N 7121 12664 'For' For string 7122 12665 'ImageData' ImageData N 7123 12666 'Keywords' Keywords string 7124 'ModDate' ModifyDate string 12667 'ModDate' ModifyDate string~ 7125 12668 'Pages' Pages N 7126 12669 'Routing' Routing string … … 7130 12673 'Version' Version string 7131 12674 'begin_xml_packet' XMP XMP 12675 12676 =head2 ID3 Tags 12677 12678 ExifTool extracts ID3 information from MP3, MPEG, AIFF, OGG, FLAC, APE and 12679 RealAudio files. ID3v2 tags which support multiple languages (ie. Comment 12680 and Lyrics) are extracted by specifying the tag name, followed by a dash 12681 ('-'), then a 3-character 12682 ISO 639-2 12683 language code (ie. "Comment-spa"). See L<http://www.id3.org/> for the 12684 official ID3 specification and 12685 L<http://www.loc.gov/standards/iso639-2/php/code_list.php> for a list of ISO 12686 639-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 12710 ID3 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 12724 ExifTool extracts mainly text-based tags from ID3v2 information. The tags 12725 in the tables below are those extracted by ExifTool, and don't represent a 12726 complete list of available ID3v2 tags. 12727 12728 ID3 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 12788 ID3 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 12856 ID3 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 12866 ID3 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 12940 This 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 7132 12964 7133 12965 =head2 Vorbis Tags … … 7195 13027 0x0000 StreamInfo FLAC StreamInfo 7196 13028 0x0004 VorbisComment Vorbis Comments 13029 0x0006 Picture FLAC Picture 7197 13030 7198 13031 =head3 FLAC StreamInfo Tags … … 7210 13043 'Bit103-107' BitsPerSample N 7211 13044 '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 7212 13059 7213 13060 =head2 APE Tags … … 7306 13153 'Bit32-49' VideoBitrate N 7307 13154 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 13157 These 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 13171 Tags 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 13182 The MPEG-2 transport stream is used as a container for many different 13183 audio/video formats (including AVCHD). This table lists information 13184 extracted 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 13196 Tags 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 13207 Tags extracted from H.264 video streams. The metadata for AVCHD videos is 13208 stored 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 13218 The following tags are decoded from the Modified Digital Video Pack Metadata 13219 (MDPM) of the unregistered user data with UUID 13220 17ee8c60f84d11d98cd60800200c9a66 in the H.264 Supplemental Enhancement 13221 Information (SEI). I<[Yes, this description is confusing, but nothing 13222 compared to the challenge of actually decoding the data!]> This information 13223 may exist at regular intervals through the entire video, but only the first 13224 occurrence is extracted unless the ExtractEmbedded (-ee) option is used (in 13225 which case subsequent occurrences are extracted as sub-documents). 7313 13226 7314 13227 Tag ID Tag Name Writable 7315 13228 ------ -------- -------- 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 13297 Recording 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 13305 Frame 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 13314 The QuickTime format is used for many different types of audio, video and 13315 image files. Exiftool extracts meta information from the UserData atom 13316 (including some proprietary manufacturer-specific information), as well as 13317 extracting various audio, video and image parameters. Tags with a question 13318 mark 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 7324 13345 7325 13346 =head3 QuickTime Movie Tags … … 7327 13348 Tag ID Tag Name Writable 7328 13349 ------ -------- -------- 7329 'mvhd' MovieHeader QuickTime MovieHdr 13350 'iods' InitialObjectDescriptor? N 13351 'meta' Meta QuickTime Meta 13352 'mvhd' MovieHeader QuickTime MovieHeader 7330 13353 'trak' Track QuickTime Track 7331 13354 '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 13386 As well as these tags, the 'mdta' handler uses numerical tag ID's which are 13387 added 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 13462 This directory contains a list of key names which are used to decode 13463 ItemList 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 7338 13514 1 CreateDate N 7339 13515 2 ModifyDate N … … 7342 13518 5 PreferredRate N 7343 13519 6 PreferredVolume N 13520 9 MatrixStructure N 7344 13521 18 PreviewTime N 7345 13522 19 PreviewDuration N … … 7355 13532 ------ -------- -------- 7356 13533 'mdia' Media QuickTime Media 7357 'tkhd' TrackHeader QuickTime TrackHdr 13534 'meta' Meta QuickTime Meta 13535 'tkhd' TrackHeader QuickTime TrackHeader 13536 'tref' TrackRef QuickTime TrackRef 7358 13537 'udta' UserData QuickTime UserData 13538 'uuid' UUID-USMT QuickTime UserMedia 13539 UUID-Unknown? N 7359 13540 7360 13541 =head3 QuickTime Media Tags 7361 13542 7362 MP4 only (most tags unknown because ISO charges for the specification).13543 MP4 media box. 7363 13544 7364 13545 Tag ID Tag Name Writable 7365 13546 ------ -------- -------- 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 13564 MP4 media info box. 7371 13565 7372 13566 Tag ID Tag Name Writable 7373 13567 ------ -------- -------- 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 13579 MP4 data information box. 7380 13580 7381 13581 Tag ID Tag Name Writable 7382 13582 ------ -------- -------- 7383 [no tags known]7384 7385 =head3 QuickTime StblTags7386 7387 MP4 only (most tags unknown because ISO charges for the specification).13583 'dref' DataRef QuickTime DataRef 13584 13585 =head3 QuickTime DataRef Tags 13586 13587 MP4 data reference box. 7388 13588 7389 13589 Tag ID Tag Name Writable 7390 13590 ------ -------- -------- 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 13613 MP4 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 13624 MP4 audio media header. 13625 13626 Index Tag Name Writable 13627 ----- -------- -------- 13628 2 Balance N 13629 13630 =head3 QuickTime SampleTable Tags 13631 13632 MP4 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 13660 MP4 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 13686 MP4 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 13700 MP4 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 7398 13712 1 TrackCreateDate N 7399 13713 2 TrackModifyDate N … … 7402 13716 8 TrackLayer N 7403 13717 9 TrackVolume N 13718 10 MatrixStructure N 7404 13719 19 ImageWidth N 7405 13720 20 ImageHeight N 7406 13721 13722 =head3 QuickTime TrackRef Tags 13723 13724 Tag ID Tag Name Writable 13725 ------ -------- -------- 13726 'chap' ChapterList N 13727 7407 13728 =head3 QuickTime UserData Tags 7408 13729 7409 13730 Tag ID's beginning with the copyright symbol (hex 0xa9) are multi-language 7410 text , but ExifTool only extracts the text from the first language inthe7411 record. ExifTool will extract any multi-language user data tags found, even 7412 if they don't exist in this table.13731 text. Alternate language tags are accessed by adding a dash followed by the 13732 language/country code to the tag name. ExifTool will extract any 13733 multi-language user data tags found, even if they don't exist in this table. 7413 13734 7414 13735 Tag ID Tag Name Writable 7415 13736 ------ -------- -------- 7416 13737 '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 7417 13745 '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 7418 13752 'SelO' PlaySelection N 7419 'TAGS' PentaxTags Pentax MOV 13753 'TAGS' KodakTags Kodak MOV 13754 KonicaMinoltaTags Minolta MOV1 13755 MinoltaTags Minolta MOV2 7420 13756 NikonTags Nikon MOV 13757 OlympusTags1 Olympus MOV1 13758 OlympusTags2 Olympus MOV2 13759 OlympusTags3 Olympus MP4 13760 PentaxTags Pentax MOV 13761 SamsungTags Samsung MP4 7421 13762 SanyoMOV Sanyo MOV 7422 13763 SanyoMP4 Sanyo MP4 7423 13764 UnknownTags? N 7424 13765 'WLOC' WindowLocation N 13766 'XMP_' XMP XMP 13767 'hinf' HintTrackInfo QuickTime HintTrackInfo 13768 'hnti' HintInfo QuickTime HintInfo 7425 13769 'meta' Meta QuickTime Meta 7426 13770 'name' Name N 7427 13771 '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 7428 13780 "\xa9cpy" Copyright N 7429 13781 "\xa9day" CreateDate N … … 7439 13791 "\xa9ed9" Edit9 N 7440 13792 "\xa9fmt" Format N 13793 "\xa9gen" Genre N 13794 "\xa9grp" Grouping N 7441 13795 "\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 7442 13806 "\xa9prd" Producer N 7443 13807 "\xa9prf" Performers N 13808 "\xa9prk" PerformerKeywords N 13809 "\xa9prl" PerformerURL N 7444 13810 "\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 7484 13817 "\xa9too" Encoder N 7485 13818 "\xa9trk" Track N 7486 13819 "\xa9wrt" Composer N 7487 7488 =head3 QuickTime iTunesInfo Tags 13820 "\xa9xyz" GPSCoordinates N 13821 13822 =head3 QuickTime DcMD Tags 13823 13824 Metadata 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 7489 13832 7490 13833 Tag ID Tag Name Writable … … 7492 13835 [no tags known] 7493 13836 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 7494 13866 =head3 QuickTime Video Tags 7495 13867 … … 7498 13870 0 DisplaySize N 7499 13871 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 7500 13890 7501 13891 =head3 QuickTime Preview Tags … … 7507 13897 3 PreviewAtomType N 7508 13898 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 13947 Found 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 7509 13956 7510 13957 =head3 QuickTime ImageFile Tags … … 7518 13965 'iicc' ICC_Profile ICC_Profile 7519 13966 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 13969 The following tags are extracted from Matroska multimedia container files. 13970 This container format is used by file types such as MKA, MKV, MKS and WEBM. 13971 For speed, ExifTool extracts tags only up to the first Cluster unless the 13972 Verbose (-v) or Unknown = 2 (-U) option is used. See 13973 L<http://www.matroska.org/technical/specs/index.html> for the official 13974 Matroska 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 14184 Tags extracted from Material Exchange Format files. Tag ID's are not listed 14185 because 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 15852 The 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 7535 15869 7536 15870 =head2 Flash Tags 7537 15871 7538 The information below is extracted from the header of SWF (Shockwave Flash)7539 files.15872 The information below is extracted from SWF (Shockwave Flash) files. Tags 15873 with string ID's represent information extracted from the file header. 7540 15874 7541 15875 Tag ID Tag Name Writable … … 7548 15882 'ImageHeight' ImageHeight N 7549 15883 'ImageWidth' ImageWidth N 15884 0x0045 FileAttributes N 15885 0x004d XMP XMP 7550 15886 7551 15887 =head3 Flash FLV Tags … … 7568 15904 'Bit0-3' AudioEncoding N 7569 15905 'Bit4-5' AudioSampleRate N 7570 'Bit6' Audio SampleBitsN15906 'Bit6' AudioBitsPerSample N 7571 15907 'Bit7' AudioChannels N 7572 15908 … … 7592 15928 'audiosamplesize' AudioSampleSize N 7593 15929 'audiosize' AudioSize N 15930 'bytelength' ByteLength N 7594 15931 'canSeekToEnd' CanSeekToEnd N 15932 'canseekontime' CanSeekOnTime N 15933 'createdby' CreatedBy N 7595 15934 'creationdate' CreateDate N 7596 15935 'cuePoints' CuePoint Flash CuePoint … … 7605 15944 'hasVideo' HasVideo N 7606 15945 'height' ImageHeight N 15946 'httphostheader' HTTPHostHeader N 7607 15947 'keyframesFilepositions' KeyFramePositions N 7608 15948 'keyframesTimes' KeyFramesTimes N 7609 15949 'lastkeyframetimestamp' LastKeyFrameTime N 7610 15950 'lasttimestamp' LastTimeStamp N 15951 'liveXML' XMP XMP 7611 15952 'metadatacreator' MetadataCreator N 7612 15953 'metadatadate' MetadataDate N 15954 'pmsg' Message N 15955 'purl' URL N 15956 'sourcedata' SourceData N 15957 'starttime' StartTime N 7613 15958 'stereo' Stereo N 15959 'totaldatarate' TotalDataRate N 15960 'totalduration' TotalDuration N 7614 15961 'videocodecid' VideoCodecID N 7615 15962 'videodatarate' VideoBitrate N … … 7674 16021 -------- -------- -------- 7675 16022 0 StreamNumber N 7676 1 StreamMaxBit Rate N7677 2 StreamAvgBit Rate N16023 1 StreamMaxBitrate N 16024 2 StreamAvgBitrate N 7678 16025 3 StreamMaxPacketSize N 7679 16026 4 StreamAvgPacketSize N … … 7722 16069 Sequence Tag Name Writable 7723 16070 -------- -------- -------- 7724 0 MaxBit Rate N7725 1 AvgBit Rate N16071 0 MaxBitrate N 16072 1 AvgBitrate N 7726 16073 2 MaxPacketSize N 7727 16074 3 AvgPacketSize N … … 7850 16197 =head2 RIFF Tags 7851 16198 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. 16199 The RIFF container format is used various types of fines including WAV, AVI 16200 and WEBP. According to the EXIF specification, Meta information is embedded 16201 in two types of RIFF C<LIST> chunks: C<INFO> and C<exif>, and information 16202 about the audio content is stored in the C<fmt > chunk. As well as this 16203 information, some video information and proprietary manufacturer-specific 16204 information is also extracted. 7855 16205 7856 16206 Tag ID Tag Name Writable 7857 16207 ------ -------- -------- 16208 'JUNK' OlympusJunk Olympus AVI 16209 CasioJunk EXIF 16210 RicohJunk Ricoh AVI 16211 PentaxJunk Pentax Junk 16212 TextJunk N 16213 'JUNQ' OldXMP N 7858 16214 'LIST_INFO' Info RIFF Info 16215 'LIST_Tdat' Tdat RIFF Tdat 7859 16216 'LIST_exif' Exif RIFF Exif 7860 16217 '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 7861 16222 'fmt ' AudioFormat RIFF AudioFormat 16223 'olym' Olym Olympus WAV 7862 16224 7863 16225 =head3 RIFF Info Tags 16226 16227 RIFF INFO tags found in WAV audio and AVI video files. Tags which are part 16228 of the EXIF 2.3 specification have an underlined Tag Name in the HTML 16229 version of this documentation. Other tags are found in AVI files generated 16230 by some software. 7864 16231 7865 16232 Tag ID Tag Name Writable 7866 16233 ------ -------- -------- 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 7867 16242 'IARL' ArchivalLocation N 7868 16243 '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 7869 16256 'ICMS' Commissioned N 7870 16257 'ICMT' Comment N 16258 'ICNM' Cinematographer N 16259 'ICNT' Country N 7871 16260 'ICOP' Copyright N 7872 16261 'ICRD' DateCreated N … … 7874 16263 'IDIM' Dimensions N 7875 16264 'IDPI' DotsPerInch N 16265 'IDST' DistributedBy N 16266 'IEDT' EditedBy N 16267 'IENC' EncodedBy N 7876 16268 'IENG' Engineer N 7877 16269 'IGNR' Genre N 7878 16270 'IKEY' Keywords N 7879 16271 'ILGT' Lightness N 16272 'ILGU' LogoURL N 16273 'ILIU' LogoIconURL N 16274 'ILNG' Language N 16275 'IMBI' MoreInfoBannerImage N 16276 'IMBU' MoreInfoBannerURL N 7880 16277 'IMED' Medium N 16278 'IMIT' MoreInfoText N 16279 'IMIU' MoreInfoURL N 16280 'IMUS' MusicBy N 7881 16281 'INAM' Title N 16282 'IPDS' ProductionDesigner N 7882 16283 'IPLT' NumColors N 7883 16284 'IPRD' Product N 16285 'IPRO' ProducedBy N 16286 'IRIP' RippedBy N 16287 'IRTD' Rating N 7884 16288 'ISBJ' Subject N 7885 16289 'ISFT' Software N 16290 'ISGN' SecondaryGenre N 7886 16291 'ISHP' Sharpness N 7887 16292 'ISRC' Source N 7888 16293 'ISRF' SourceForm N 16294 'ISTD' ProductionStudio N 16295 'ISTR' Starring N 7889 16296 '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] 7890 16324 7891 16325 =head3 RIFF Exif Tags 16326 16327 These tags are part of the EXIF 2.3 specification for WAV audio files. 7892 16328 7893 16329 Tag ID Tag Name Writable … … 7906 16342 ------ -------- -------- 7907 16343 'IDIT' DateTimeOriginal N 7908 'ISMP' TimeCode N 16344 'ISMP' Timecode N 16345 'LIST_odml' OpenDML RIFF OpenDML 7909 16346 'LIST_strl' Stream RIFF Stream 7910 16347 '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 7911 16360 7912 16361 =head3 RIFF Stream Tags … … 7922 16371 =head3 RIFF StreamData Tags 7923 16372 7924 This chunk contains EXIF information in FujiFilm F30 AVI files. 7925 7926 Tag ID Tag Name Writable 7927 ------ -------- -------- 7928 'AVIF' AVIF EXIF 16373 This chunk is used to store proprietary information in AVI videos from some 16374 cameras. 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 7929 16382 7930 16383 =head3 RIFF AudioFormat Tags … … 7943 16396 ----- -------- -------- 7944 16397 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 7946 16407 10 Quality N 7947 16408 11 SampleSize N … … 7957 16418 8 ImageWidth N 7958 16419 9 ImageHeight N 16420 16421 =head3 RIFF BroadcastExt Tags 16422 16423 Information found in the Broadcast Audio Extension chunk (see 16424 L<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 7959 16435 7960 16436 =head2 AIFF Tags … … 7999 16475 =head2 ASF Tags 8000 16476 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.16477 The ASF format is used by Windows WMA and WMV files, and DIVX videos. Tag 16478 ID's aren't listed because they are huge 128-bit GUID's that would ruin the 16479 formatting of this table. 8004 16480 8005 16481 Tag Name Writable … … 8009 16485 Header ASF Header 8010 16486 Data N 16487 XMP XMP 8011 16488 Index N 8012 16489 MediaIndex N … … 8092 16569 ----- -------- -------- 8093 16570 0 FileID N 8094 16 File SizeN16571 16 FileLength N 8095 16572 24 CreationDate N 8096 16573 32 DataPackets N … … 8236 16713 PeakValue N 8237 16714 Period N 8238 Picture ASF P review16715 Picture ASF Picture 8239 16716 PlaylistDelay N 8240 16717 Producer N … … 8280 16757 Year N 8281 16758 8282 =head3 ASF P reviewTags16759 =head3 ASF Picture Tags 8283 16760 8284 16761 Tag Name Writable 8285 16762 -------- -------- 8286 P reviewType N8287 P reviewMimeType N8288 P reviewDescription N8289 P reviewImageN16763 PictureType N 16764 PictureMimeType N 16765 PictureDescription N 16766 Picture N 8290 16767 8291 16768 =head2 DICOM Tags … … 8294 16771 header and a number of new tags. ExifTool will extract information from 8295 16772 either 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. 16773 and element numbers in hexadecimal, as given in the DICOM specification (see 16774 L<http://medical.nema.org/>). The table below contains tags from the DICOM 16775 2009 and earlier specifications plus some vendor-specific private tags. 8297 16776 8298 16777 Tag ID Tag Name Writable … … 8330 16809 0008,0001 LengthToEnd N 8331 16810 0008,0005 SpecificCharacterSet N 16811 0008,0006 LanguageCodeSequence N 8332 16812 0008,0008 ImageType N 8333 16813 0008,0010 RecognitionCode N … … 8345 16825 0008,0024 OverlayDate N 8346 16826 0008,0025 CurveDate N 8347 0008,002A AcquisitionDate time N16827 0008,002A AcquisitionDateTime N 8348 16828 0008,0030 StudyTime N 8349 16829 0008,0031 SeriesTime N … … 8356 16836 0008,0042 NuclearMedicineSeriesType N 8357 16837 0008,0050 AccessionNumber N 8358 0008,0052 Query -RetrieveLevelN16838 0008,0052 QueryRetrieveLevel N 8359 16839 0008,0054 RetrieveAETitle N 8360 16840 0008,0056 InstanceAvailability N … … 8369 16849 0008,0081 InstitutionAddress N 8370 16850 0008,0082 InstitutionCodeSequence N 8371 0008,0090 ReferringPhysician sNameN8372 0008,0092 ReferringPhysician sAddressN8373 0008,0094 ReferringPhysician sTelephoneNumberN16851 0008,0090 ReferringPhysicianName N 16852 0008,0092 ReferringPhysicianAddress N 16853 0008,0094 ReferringPhysicianTelephoneNumber N 8374 16854 0008,0096 ReferringPhysicianIDSequence N 8375 16855 0008,0100 CodeValue N … … 8389 16869 0008,0115 CodingSchemeName N 8390 16870 0008,0116 ResponsibleOrganization N 16871 0008,0117 ContextUID N 8391 16872 0008,0201 TimezoneOffsetFromUTC N 8392 16873 0008,1000 NetworkID N … … 8396 16877 0008,103E SeriesDescription N 8397 16878 0008,1040 InstitutionalDepartmentName N 8398 0008,1048 Physician OfRecordN8399 0008,1049 Physician OfRecordIDSequenceN8400 0008,1050 PerformingPhysician sNameN16879 0008,1048 PhysiciansOfRecord N 16880 0008,1049 PhysiciansOfRecordIDSequence N 16881 0008,1050 PerformingPhysicianName N 8401 16882 0008,1052 PerformingPhysicianIDSequence N 8402 16883 0008,1060 NameOfPhysicianReadingStudy N … … 8422 16903 0008,115A SOPClassesSupported N 8423 16904 0008,1160 ReferencedFrameNumber N 16905 0008,1161 SimpleFrameList N 16906 0008,1162 CalculatedFrameList N 16907 0008,1163 TimeRange N 16908 0008,1164 FrameExtractionSequence N 8424 16909 0008,1195 TransactionUID N 8425 16910 0008,1197 FailureReason N … … 8438 16923 0008,2129 NumberOfEventTimers N 8439 16924 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 8442 16930 0008,2142 StartTrim N 8443 16931 0008,2143 StopTrim N … … 8455 16943 0008,2244 TransducerOrientationSequence N 8456 16944 0008,2246 TransducerOrientationModifierSeq N 16945 0008,2253 AnatomicEntrancePortalCodeSeqTrial N 16946 0008,2255 AnatomicApproachDirCodeSeqTrial N 16947 0008,2256 AnatomicPerspectiveDescrTrial N 16948 0008,2257 AnatomicPerspectiveCodeSeqTrial N 8457 16949 0008,3001 AlternateRepresentationSequence N 16950 0008,3010 IrradiationEventUID N 8458 16951 0008,4000 IdentifyingComments N 8459 16952 0008,9007 FrameType N … … 8470 16963 0008,9215 DerivationCodeSequence N 8471 16964 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 8472 16979 0010,0000 PatientGroupLength N 8473 0010,0010 Patient sNameN16980 0010,0010 PatientName N 8474 16981 0010,0020 PatientID N 8475 16982 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 8482 16990 0010,1000 OtherPatientIDs N 8483 16991 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 8489 16998 0010,1050 InsurancePlanIdentification N 8490 0010,1060 Patient sMothersBirthNameN16999 0010,1060 PatientMotherBirthName N 8491 17000 0010,1080 MilitaryRank N 8492 17001 0010,1081 BranchOfService N 8493 17002 0010,1090 MedicalRecordLocator N 8494 17003 0010,2000 MedicalAlerts N 8495 0010,2110 ContrastAllergiesN17004 0010,2110 Allergies N 8496 17005 0010,2150 CountryOfResidence N 8497 17006 0010,2152 RegionOfResidence N 8498 0010,2154 Patient sTelephoneNumbersN17007 0010,2154 PatientTelephoneNumbers N 8499 17008 0010,2160 EthnicGroup N 8500 17009 0010,2180 Occupation N … … 8503 17012 0010,21C0 PregnancyStatus N 8504 17013 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 8506 17027 0010,4000 PatientComments N 17028 0010,9431 ExaminedBodyThickness N 17029 0011,1010 PatientStatus N 8507 17030 0012,0010 ClinicalTrialSponsorName N 8508 17031 0012,0020 ClinicalTrialProtocolID N … … 8515 17038 0012,0051 ClinicalTrialTimePointDescription N 8516 17039 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 8517 17047 0018,0000 AcquisitionGroupLength N 8518 0018,0010 Contrast -BolusAgentN8519 0018,0012 Contrast -BolusAgentSequenceN8520 0018,0014 Contrast -BolusAdministrationRouteN17048 0018,0010 ContrastBolusAgent N 17049 0018,0012 ContrastBolusAgentSequence N 17050 0018,0014 ContrastBolusAdministrationRoute N 8521 17051 0018,0015 BodyPartExamined N 8522 17052 0018,0020 ScanningSequence N … … 8543 17073 0018,003A InterventionDescription N 8544 17074 0018,0040 CineRate N 17075 0018,0042 InitialCineRunState N 8545 17076 0018,0050 SliceThickness N 8546 17077 0018,0060 KVP N … … 8567 17098 0018,0095 PixelBandwidth N 8568 17099 0018,1000 DeviceSerialNumber N 17100 0018,1002 DeviceUID N 17101 0018,1003 DeviceID N 8569 17102 0018,1004 PlateID N 17103 0018,1005 GeneratorID N 17104 0018,1006 GridID N 17105 0018,1007 CassetteID N 17106 0018,1008 GantryID N 8570 17107 0018,1010 SecondaryCaptureDeviceID N 8571 17108 0018,1011 HardcopyCreationDeviceID N … … 8582 17119 0018,1023 DigitalImageFormatAcquired N 8583 17120 0018,1030 ProtocolName N 8584 0018,1040 Contrast -BolusRouteN8585 0018,1041 Contrast -BolusVolumeN8586 0018,1042 Contrast -BolusStartTimeN8587 0018,1043 Contrast -BolusStopTimeN8588 0018,1044 Contrast -BolusTotalDoseN17121 0018,1040 ContrastBolusRoute N 17122 0018,1041 ContrastBolusVolume N 17123 0018,1042 ContrastBolusStartTime N 17124 0018,1043 ContrastBolusStopTime N 17125 0018,1044 ContrastBolusTotalDose N 8589 17126 0018,1045 SyringeCounts N 8590 17127 0018,1046 ContrastFlowRate N 8591 17128 0018,1047 ContrastFlowDuration N 8592 0018,1048 Contrast -BolusIngredientN8593 0018,1049 Contrast -BolusConcentrationN17129 0018,1048 ContrastBolusIngredient N 17130 0018,1049 ContrastBolusConcentration N 8594 17131 0018,1050 SpatialResolution N 8595 17132 0018,1060 TriggerTime N … … 8597 17134 0018,1062 NominalInterval N 8598 17135 0018,1063 FrameTime N 8599 0018,1064 FramingTypeN17136 0018,1064 CardiacFramingType N 8600 17137 0018,1065 FrameTimeVector N 8601 17138 0018,1066 FrameDelay N … … 8614 17151 0018,1076 RadionuclidePositronFraction N 8615 17152 0018,1077 RadiopharmaceuticalSpecActivity N 17153 0018,1078 RadiopharmaceuticalStartDateTime N 17154 0018,1079 RadiopharmaceuticalStopDateTime N 8616 17155 0018,1080 BeatRejectionFlag N 8617 17156 0018,1081 LowRRValue N … … 8628 17167 0018,1111 DistanceSourceToPatient N 8629 17168 0018,1114 EstimatedRadiographicMagnification N 8630 0018,1120 Gantry -DetectorTiltN8631 0018,1121 Gantry -DetectorSlewN17169 0018,1120 GantryDetectorTilt N 17170 0018,1121 GantryDetectorSlew N 8632 17171 0018,1130 TableHeight N 8633 17172 0018,1131 TableTraverse N … … 8662 17201 0018,1166 Grid N 8663 17202 0018,1170 GeneratorPower N 8664 0018,1180 Collimator -GridNameN17203 0018,1180 CollimatorGridName N 8665 17204 0018,1181 CollimatorType N 8666 17205 0018,1182 FocalDistance N 8667 17206 0018,1183 XFocusCenter N 8668 17207 0018,1184 YFocusCenter N 8669 0018,1190 FocalSpot 17208 0018,1190 FocalSpots N 8670 17209 0018,1191 AnodeTargetMaterial N 8671 17210 0018,11A0 BodyPartThickness N … … 8674 17213 0018,1201 TimeOfLastCalibration N 8675 17214 0018,1210 ConvolutionKernel N 8676 0018,1240 Upper -LowerPixelValuesN17215 0018,1240 UpperLowerPixelValues N 8677 17216 0018,1242 ActualFrameDuration N 8678 17217 0018,1243 CountRate N … … 8695 17234 0018,1402 CassetteOrientation N 8696 17235 0018,1403 CassetteSize N 8697 0018,1404 Exposures onPlate N17236 0018,1404 ExposuresOnPlate N 8698 17237 0018,1405 RelativeXRayExposure N 8699 17238 0018,1450 ColumnAngulation N … … 8722 17261 0018,1622 ShutterPresentationValue N 8723 17262 0018,1623 ShutterOverlayGroup N 17263 0018,1624 ShutterPresentationColorCIELabVal N 8724 17264 0018,1700 CollimatorShape N 8725 17265 0018,1702 CollimatorLeftVerticalEdge N … … 8791 17331 0018,6034 DopplerCorrectionAngle N 8792 17332 0018,6036 SteeringAngle N 8793 0018,6038 DopplerSampleVolumeXPos itionULN17333 0018,6038 DopplerSampleVolumeXPosRetired N 8794 17334 0018,6039 DopplerSampleVolumeXPosition N 8795 0018,603A DopplerSampleVolumeYPos itionULN17335 0018,603A DopplerSampleVolumeYPosRetired N 8796 17336 0018,603B DopplerSampleVolumeYPosition N 8797 0018,603C TMLinePositionX0 ULN17337 0018,603C TMLinePositionX0Retired N 8798 17338 0018,603D TMLinePositionX0 N 8799 0018,603E TMLinePositionY0 ULN17339 0018,603E TMLinePositionY0Retired N 8800 17340 0018,603F TMLinePositionY0 N 8801 0018,6040 TMLinePositionX1 ULN17341 0018,6040 TMLinePositionX1Retired N 8802 17342 0018,6041 TMLinePositionX1 N 8803 0018,6042 TMLinePositionY1 ULN17343 0018,6042 TMLinePositionY1Retired N 8804 17344 0018,6043 TMLinePositionY1 N 8805 17345 0018,6044 PixelComponentOrganization N … … 8877 17417 0018,9025 SpectrallySelectedSuppression N 8878 17418 0018,9026 SpectrallySelectedExcitation N 8879 0018,9027 SpatialPre Saturation N17419 0018,9027 SpatialPresaturation N 8880 17420 0018,9028 Tagging N 8881 17421 0018,9029 OversamplingPhase N … … 8914 17454 0018,9070 CardiacRRIntervalSpecified N 8915 17455 0018,9073 AcquisitionDuration N 8916 0018,9074 FrameAcquisitionDate time N17456 0018,9074 FrameAcquisitionDateTime N 8917 17457 0018,9075 DiffusionDirectionality N 8918 17458 0018,9076 DiffusionGradientDirectionSequence N … … 8933 17473 0018,9094 CoverageOfKSpace N 8934 17474 0018,9095 SpectroscopyAcquisitionPhaseRows N 17475 0018,9096 ParallelReductFactorInPlaneRetired N 8935 17476 0018,9098 TransmitterFrequency N 8936 17477 0018,9100 ResonantNucleus N … … 8951 17492 0018,9127 SpectroscopyAcquisitionDataColumns N 8952 17493 0018,9147 DiffusionAnisotropyType N 8953 0018,9151 FrameReferenceDate time N17494 0018,9151 FrameReferenceDateTime N 8954 17495 0018,9152 MRMetaboliteMapSequence N 8955 17496 0018,9155 ParallelReductionFactorOutOfPlane N … … 8973 17514 0018,9183 FlowCompensationDirection N 8974 17515 0018,9184 TaggingDelay N 17516 0018,9185 RespiratoryMotionCompTechDescr N 17517 0018,9186 RespiratorySignalSourceID N 8975 17518 0018,9195 ChemicalShiftsMinIntegrateLimitHz N 8976 17519 0018,9196 ChemicalShiftsMaxIntegrateLimitHz N … … 9029 17572 0018,9334 FluoroscopyFlag N 9030 17573 0018,9335 SourceToDataCollectionCenterDist N 9031 0018,9337 Contrast -BolusAgentNumberN9032 0018,9338 Contrast -BolusIngredientCodeSeqN17574 0018,9337 ContrastBolusAgentNumber N 17575 0018,9338 ContrastBolusIngredientCodeSeq N 9033 17576 0018,9340 ContrastAdministrationProfileSeq N 9034 0018,9341 Contrast -BolusUsageSequenceN9035 0018,9342 Contrast -BolusAgentAdministeredN9036 0018,9343 Contrast -BolusAgentDetectedN9037 0018,9344 Contrast -BolusAgentPhaseN17577 0018,9341 ContrastBolusUsageSequence N 17578 0018,9342 ContrastBolusAgentAdministered N 17579 0018,9343 ContrastBolusAgentDetected N 17580 0018,9344 ContrastBolusAgentPhase N 9038 17581 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 9039 17686 0018,A001 ContributingEquipmentSequence N 9040 17687 0018,A002 ContributionDateTime N 9041 17688 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 9042 17832 0020,0000 RelationshipGroupLength N 9043 17833 0020,000D StudyInstanceUID N … … 9074 17864 0020,1001 AcquisitionsInSeries N 9075 17865 0020,1002 ImagesInAcquisition N 17866 0020,1003 ImagesInSeries N 9076 17867 0020,1004 AcquisitionsInStudy N 17868 0020,1005 ImagesInStudy N 9077 17869 0020,1020 Reference N 9078 17870 0020,1040 PositionReferenceIndicator N … … 9108 17900 0020,9158 FrameComments N 9109 17901 0020,9161 ConcatenationUID N 9110 0020,9162 In concatenationNumber N9111 0020,9163 In concatenationTotalNumber N17902 0020,9162 InConcatenationNumber N 17903 0020,9163 InConcatenationTotalNumber N 9112 17904 0020,9164 DimensionOrganizationUID N 9113 17905 0020,9165 DimensionIndexPointer N … … 9118 17910 0020,9228 ConcatenationFrameOffsetNumber N 9119 17911 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 9120 17970 0022,0001 LightPathFilterPassThroughWavelen N 9121 17971 0022,0002 LightPathFilterPassBand N … … 9149 17999 0022,0021 LeftImageSequence N 9150 18000 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 9151 18070 0028,0000 ImagePresentationGroupLength N 9152 18071 0028,0002 SamplesPerPixel N … … 9169 18088 0028,0050 ManipulatedImage N 9170 18089 0028,0051 CorrectedImage N 18090 0028,005F CompressionRecognitionCode N 9171 18091 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 9172 18109 0028,0100 BitsAllocated N 9173 18110 0028,0101 BitsStored N … … 9183 18120 0028,0111 LargestImagePixelValueInPlane N 9184 18121 0028,0120 PixelPaddingValue N 18122 0028,0121 PixelPaddingRangeLimit N 9185 18123 0028,0200 ImageLocation N 9186 18124 0028,0300 QualityControlImage N 9187 18125 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 9188 18149 0028,1040 PixelIntensityRelationship N 9189 18150 0028,1041 PixelIntensityRelationshipSign N … … 9194 18155 0028,1054 RescaleType N 9195 18156 0028,1055 WindowCenterAndWidthExplanation N 18157 0028,1056 VOI_LUTFunction N 9196 18158 0028,1080 GrayScale N 9197 18159 0028,1090 RecommendedViewingMode N … … 9200 18162 0028,1102 GreenPaletteColorTableDescriptor N 9201 18163 0028,1103 BluePaletteColorTableDescriptor N 18164 0028,1111 LargeRedPaletteColorTableDescr N 18165 0028,1112 LargeGreenPaletteColorTableDescr N 18166 0028,1113 LargeBluePaletteColorTableDescr N 9202 18167 0028,1199 PaletteColorTableUID N 9203 18168 0028,1200 GrayLookupTableData N … … 9205 18170 0028,1202 GreenPaletteColorTableData N 9206 18171 0028,1203 BluePaletteColorTableData N 18172 0028,1211 LargeRedPaletteColorTableData N 18173 0028,1212 LargeGreenPaletteColorTableData N 18174 0028,1213 LargeBluePaletteColorTableData N 18175 0028,1214 LargePaletteColorLookupTableUID N 9207 18176 0028,1221 SegmentedRedColorTableData N 9208 18177 0028,1222 SegmentedGreenColorTableData N 9209 18178 0028,1223 SegmentedBlueColorTableData N 9210 0028,1300 ImplantPresentN18179 0028,1300 BreastImplantPresent N 9211 18180 0028,1350 PartialView N 9212 18181 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 9213 18193 0028,2110 LossyImageCompression N 9214 18194 0028,2112 LossyImageCompressionRatio N … … 9224 18204 0028,5000 BiPlaneAcquisitionSequence N 9225 18205 0028,6010 RepresentativeFrameNumber N 9226 0028,6020 FrameNumbersOfInterest FOIN18206 0028,6020 FrameNumbersOfInterest N 9227 18207 0028,6022 FrameOfInterestDescription N 9228 18208 0028,6023 FrameOfInterestType N … … 9237 18217 0028,6120 TIDOffset N 9238 18218 0028,6190 MaskOperationExplanation N 18219 0028,7FE0 PixelDataProviderURL N 9239 18220 0028,9001 DataPointRows N 9240 18221 0028,9002 DataPointColumns N … … 9246 18227 0028,9145 PixelValueTransformationSequence N 9247 18228 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 9248 18262 0032,0000 StudyGroupLength N 9249 18263 0032,000A StudyStatusID N … … 9290 18304 0038,0044 DischargeDiagnosisCodeSequence N 9291 18305 0038,0050 SpecialNeeds N 18306 0038,0060 ServiceEpisodeID N 18307 0038,0061 IssuerOfServiceEpisodeID N 18308 0038,0062 ServiceEpisodeDescription N 18309 0038,0100 PertinentDocumentsSequence N 9292 18310 0038,0300 CurrentPatientLocation N 9293 0038,0400 Patient sInstitutionResidenceN18311 0038,0400 PatientInstitutionResidence N 9294 18312 0038,0500 PatientState N 18313 0038,0502 PatientClinicalTrialParticipSeq N 9295 18314 0038,4000 VisitComments N 9296 18315 003A,0004 WaveformOriginality N … … 9319 18338 003A,0222 NotchFilterFrequency N 9320 18339 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 9321 18350 003A,0300 MultiplexAudioChannelsDescrCodeSeq N 9322 18351 003A,0301 ChannelIdentificationCode N … … 9337 18366 0040,0012 PreMedication N 9338 18367 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 9339 18373 0040,0100 ScheduledProcedureStepSequence N 9340 18374 0040,0220 ReferencedNonImageCompositeSOPSeq N … … 9351 18385 0040,0255 PerformedProcedureTypeDescription N 9352 18386 0040,0260 PerformedProtocolCodeSequence N 18387 0040,0261 PerformedProtocolType N 9353 18388 0040,0270 ScheduledStepAttributesSequence N 9354 18389 0040,0275 RequestAttributesSequence N … … 9380 18415 0040,0441 ContentItemModifierSequence N 9381 18416 0040,050A SpecimenAccessionNumber N 18417 0040,0512 ContainerIdentifier N 18418 0040,051A ContainerDescription N 9382 18419 0040,0550 SpecimenSequence N 9383 18420 0040,0551 SpecimenIdentifier N 18421 0040,0552 SpecimenDescriptionSequenceTrial N 18422 0040,0553 SpecimenDescriptionTrial N 18423 0040,0554 SpecimenUID N 9384 18424 0040,0555 AcquisitionContextSequence N 9385 18425 0040,0556 AcquisitionContextDescription N 9386 18426 0040,059A SpecimenTypeCodeSequence N 18427 0040,0600 SpecimenShortDescription N 9387 18428 0040,06FA SlideIdentifier N 9388 18429 0040,071A ImageCenterPointCoordinatesSeq N … … 9393 18434 0040,08DA CoordinateSystemAxisCodeSequence N 9394 18435 0040,08EA MeasurementUnitsCodeSequence N 18436 0040,09F8 VitalStainCodeSequenceTrial N 9395 18437 0040,1001 RequestedProcedureID N 9396 18438 0040,1002 ReasonForRequestedProcedure N … … 9406 18448 0040,1011 IntendedRecipientsOfResultsIDSeq N 9407 18449 0040,1101 PersonIdentificationCodeSequence N 9408 0040,1102 Person sAddressN9409 0040,1103 Person sTelephoneNumbersN18450 0040,1102 PersonAddress N 18451 0040,1103 PersonTelephoneNumbers N 9410 18452 0040,1400 RequestedProcedureComments N 9411 18453 0040,2001 ReasonForImagingServiceRequest N … … 9415 18457 0040,2007 FillerOrderNum-ImagingServiceReq N 9416 18458 0040,2008 OrderEnteredBy N 9417 0040,2009 OrderEnterer sLocationN18459 0040,2009 OrderEntererLocation N 9418 18460 0040,2010 OrderCallbackPhoneNumber N 9419 18461 0040,2016 PlacerOrderNum-ImagingServiceReq N … … 9451 18493 0040,4035 ActualHumanPerformersSequence N 9452 18494 0040,4036 HumanPerformersOrganization N 9453 0040,4037 HumanPerformersName N 18495 0040,4037 HumanPerformerName N 18496 0040,4040 RawDataHandling N 9454 18497 0040,8302 EntranceDoseInMilliGy N 18498 0040,9094 RefImageRealWorldValueMappingSeq N 9455 18499 0040,9096 RealWorldValueMappingSequence N 18500 0040,9098 PixelValueMappingCodeSequence N 9456 18501 0040,9210 LUTLabel N 9457 18502 0040,9211 RealWorldValueLastValueMapped N … … 9469 18514 0040,A073 VerifyingObserverSequence N 9470 18515 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 9471 18522 0040,A088 VerifyingObserverIdentCodeSequence N 18523 0040,A090 EquivalentCDADocumentSequence N 9472 18524 0040,A0B0 ReferencedWaveformChannels N 9473 18525 0040,A120 DateTime N … … 9480 18532 0040,A136 ReferencedFrameNumbers N 9481 18533 0040,A138 ReferencedTimeOffsets N 9482 0040,A13A ReferencedDate time N18534 0040,A13A ReferencedDateTime N 9483 18535 0040,A160 TextValue N 9484 18536 0040,A168 ConceptCodeSequence N … … 9489 18541 0040,A301 NumericValueQualifierCodeSequence N 9490 18542 0040,A30A NumericValue N 18543 0040,A353 AddressTrial N 18544 0040,A354 TelephoneNumberTrial N 9491 18545 0040,A360 PredecessorDocumentsSequence N 9492 18546 0040,A370 ReferencedRequestSequence N … … 9494 18548 0040,A375 CurrentRequestedProcEvidenceSeq N 9495 18549 0040,A385 PertinentOtherEvidenceSequence N 18550 0040,A390 HL7StructuredDocumentRefSeq N 9496 18551 0040,A491 CompletionFlag N 9497 18552 0040,A492 CompletionFlagDescription N 9498 18553 0040,A493 VerificationFlag N 18554 0040,A494 ArchiveRequested N 18555 0040,A496 PreliminaryFlag N 9499 18556 0040,A504 ContentTemplateSequence N 9500 18557 0040,A525 IdenticalDocumentsSequence N … … 9508 18565 0040,DB0D TemplateExtensionCreatorUID N 9509 18566 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 9510 18732 0050,0004 CalibrationImage N 9511 18733 0050,0010 DeviceSequence N 9512 18734 0050,0014 DeviceLength N 18735 0050,0015 ContainerComponentWidth N 9513 18736 0050,0016 DeviceDiameter N 9514 18737 0050,0017 DeviceDiameterUnits N 9515 18738 0050,0018 DeviceVolume N 9516 18739 0050,0019 InterMarkerDistance N 18740 0050,001B ContainerComponentID N 9517 18741 0050,0020 DeviceDescription N 9518 18742 0054,0010 EnergyWindowVector N … … 9602 18826 0060,3010 HistogramExplanation N 9603 18827 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 9604 18884 0070,0001 GraphicAnnotationSequence N 9605 18885 0070,0002 GraphicLayer N … … 9620 18900 0070,0023 GraphicType N 9621 18901 0070,0024 GraphicFilled N 18902 0070,0040 ImageRotationRetired N 9622 18903 0070,0041 ImageHorizontalFlip N 9623 18904 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 9626 18909 0070,005A DisplayedAreaSelectionSequence N 9627 18910 0070,0060 GraphicLayerSequence N … … 9634 18917 0070,0082 PresentationCreationDate N 9635 18918 0070,0083 PresentationCreationTime N 9636 0070,0084 ContentCreatorsName N 18919 0070,0084 ContentCreatorName N 18920 0070,0086 ContentCreatorIDCodeSequence N 9637 18921 0070,0100 PresentationSizeMode N 9638 18922 0070,0101 PresentationPixelSpacing N … … 9654 18938 0070,031C FiducialSetSequence N 9655 18939 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 9656 19088 0088,0130 StorageMediaFileSetID N 9657 19089 0088,0140 StorageMediaFileSetUID N … … 9660 19092 0088,0906 TopicSubject N 9661 19093 0088,0910 TopicAuthor N 9662 0088,0912 TopicKey Words N19094 0088,0912 TopicKeywords N 9663 19095 0100,0410 SOPInstanceStatus N 9664 19096 0100,0420 SOPAuthorizationDateAndTime N … … 9676 19108 0400,0305 CertifiedTimestampType N 9677 19109 0400,0310 CertifiedTimestamp N 19110 0400,0401 DigitalSignaturePurposeCodeSeq N 19111 0400,0402 ReferencedDigitalSignatureSeq N 19112 0400,0403 ReferencedSOPInstanceMACSeq N 19113 0400,0404 MAC N 9678 19114 0400,0500 EncryptedAttributesSequence N 9679 19115 0400,0510 EncryptedContentTransferSyntaxUID N 9680 19116 0400,0520 EncryptedContent N 9681 19117 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 9682 19130 2000,0010 NumberOfCopies N 9683 19131 2000,001E PrinterConfigurationSequence N … … 9727 19175 2010,0510 ReferencedImageBoxSequence N 9728 19176 2010,0520 ReferencedBasicAnnotationBoxSeq N 9729 2020,0010 Image PositionN19177 2020,0010 ImageBoxPosition N 9730 19178 2020,0020 Polarity N 9731 19179 2020,0030 RequestedImageSize N … … 9733 19181 2020,0050 RequestedResolutionID N 9734 19182 2020,00A0 RequestedImageSizeFlag N 9735 2020,00A2 Decimate -CropResultN19183 2020,00A2 DecimateCropResult N 9736 19184 2020,0110 BasicGrayscaleImageSequence N 9737 19185 2020,0111 BasicColorImageSequence N … … 9761 19209 2100,0050 CreationTime N 9762 19210 2100,0070 Originator N 9763 2100,0140 Destination 19211 2100,0140 DestinationAE N 9764 19212 2100,0160 OwnerID N 9765 19213 2100,0170 NumberOfFilms N … … 9819 19267 3002,0041 FluenceDataSource N 9820 19268 3002,0042 FluenceDataScale N 19269 3002,0051 FluenceMode N 19270 3002,0052 FluenceModeID N 9821 19271 3004,0001 DVHType N 9822 19272 3004,0002 DoseUnits N … … 9883 19333 3006,00B2 ROIPhysicalProperty N 9884 19334 3006,00B4 ROIPhysicalPropertyValue N 19335 3006,00B6 ROIElementalCompositionSequence N 19336 3006,00B7 ROIElementalCompAtomicNumber N 19337 3006,00B8 ROIElementalCompAtomicMassFraction N 9885 19338 3006,00C0 FrameOfReferenceRelationshipSeq N 9886 19339 3006,00C2 RelatedFrameOfReferenceUID N … … 9893 19346 3008,0016 MeasuredDoseValue N 9894 19347 3008,0020 TreatmentSessionBeamSequence N 19348 3008,0021 TreatmentSessionIonBeamSequence N 9895 19349 3008,0022 CurrentFractionNumber N 9896 19350 3008,0024 TreatmentControlPointDate N … … 9907 19361 3008,003B DeliveredTreatmentTime N 9908 19362 3008,0040 ControlPointDeliverySequence N 19363 3008,0041 IonControlPointDeliverySequence N 9909 19364 3008,0042 SpecifiedMeterset N 9910 19365 3008,0044 DeliveredMeterset N 19366 3008,0045 MetersetRateSet N 19367 3008,0046 MetersetRateDelivered N 19368 3008,0047 ScanSpotMetersetsDelivered N 9911 19369 3008,0048 DoseRateDelivered N 9912 19370 3008,0050 TreatmentSummaryCalcDoseRefSeq N … … 9916 19374 3008,005A NumberOfFractionsDelivered N 9917 19375 3008,0060 OverrideSequence N 19376 3008,0061 ParameterSequencePointer N 9918 19377 3008,0062 OverrideParameterPointer N 19378 3008,0063 ParameterItemIndex N 9919 19379 3008,0064 MeasuredDoseReferenceNumber N 19380 3008,0065 ParameterPointer N 9920 19381 3008,0066 OverrideReason N 19382 3008,0068 CorrectedParameterSequence N 19383 3008,006A CorrectionValue N 9921 19384 3008,0070 CalculatedDoseReferenceSequence N 9922 19385 3008,0072 CalculatedDoseReferenceNumber N … … 9934 19397 3008,00D0 RecordedBlockSequence N 9935 19398 3008,00E0 TreatmentSummaryMeasuredDoseRefSeq N 19399 3008,00F0 RecordedSnoutSequence N 19400 3008,00F2 RecordedRangeShifterSequence N 19401 3008,00F4 RecordedLateralSpreadingDeviceSeq N 19402 3008,00F6 RecordedRangeModulatorSequence N 9936 19403 3008,0100 RecordedSourceSequence N 9937 19404 3008,0105 SourceSerialNumber N … … 9971 19438 300A,0007 RTPlanTime N 9972 19439 300A,0009 TreatmentProtocols N 9973 300A,000A TreatmentIntentN19440 300A,000A PlanIntent N 9974 19441 300A,000B TreatmentSites N 9975 19442 300A,000C RTPlanGeometry N … … 10002 19469 300A,0048 BeamLimitingDeviceToleranceSeq N 10003 19470 300A,004A BeamLimitingDevicePositionTol N 19471 300A,004B SnoutPositionTolerance N 10004 19472 300A,004C PatientSupportAngleTolerance N 10005 19473 300A,004E TableTopEccentricAngleTolerance N 19474 300A,004F TableTopPitchAngleTolerance N 19475 300A,0050 TableTopRollAngleTolerance N 10006 19476 300A,0051 TableTopVerticalPositionTolerance N 10007 19477 300A,0052 TableTopLongitudinalPositionTol N … … 10019 19489 300A,0084 BeamDose N 10020 19490 300A,0086 BeamMeterset N 19491 300A,0088 BeamDosePointDepth N 19492 300A,0089 BeamDosePointEquivalentDepth N 19493 300A,008A BeamDosePointSSD N 10021 19494 300A,00A0 NumberOfBrachyApplicationSetups N 10022 19495 300A,00A2 BrachyAppSetupDoseSpecPoint N … … 10029 19502 300A,00B8 RTBeamLimitingDeviceType N 10030 19503 300A,00BA SourceToBeamLimitingDeviceDistance N 10031 300A,00BC NumberOfLeaf-JawPairs N 19504 300A,00BB IsocenterToBeamLimitingDeviceDist N 19505 300A,00BC NumberOfLeafJawPairs N 10032 19506 300A,00BE LeafPositionBoundaries N 10033 19507 300A,00C0 BeamNumber N … … 10048 19522 300A,00D5 WedgeAngle N 10049 19523 300A,00D6 WedgeFactor N 19524 300A,00D7 TotalWedgeTrayWaterEquivThickness N 10050 19525 300A,00D8 WedgeOrientation N 19526 300A,00D9 IsocenterToWedgeTrayDistance N 10051 19527 300A,00DA SourceToWedgeTrayDistance N 19528 300A,00DB WedgeThinEdgePosition N 19529 300A,00DC BolusID N 19530 300A,00DD BolusDescription N 10052 19531 300A,00E0 NumberOfCompensators N 10053 19532 300A,00E1 MaterialID N … … 10067 19546 300A,00F0 NumberOfBlocks N 10068 19547 300A,00F2 TotalBlockTrayFactor N 19548 300A,00F3 TotalBlockTrayWaterEquivThickness N 10069 19549 300A,00F4 BlockSequence N 10070 19550 300A,00F5 BlockTrayID N 10071 19551 300A,00F6 SourceToBlockTrayDistance N 19552 300A,00F7 IsocenterToBlockTrayDistance N 10072 19553 300A,00F8 BlockType N 10073 19554 300A,00F9 AccessoryCode N … … 10094 19575 300A,0118 WedgePosition N 10095 19576 300A,011A BeamLimitingDevicePositionSequence N 10096 300A,011C Leaf -JawPositionsN19577 300A,011C LeafJawPositions N 10097 19578 300A,011E GantryAngle N 10098 19579 300A,011F GantryRotationDirection N … … 10111 19592 300A,0130 SourceToSurfaceDistance N 10112 19593 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 10113 19602 300A,0180 PatientSetupSequence N 10114 19603 300A,0182 PatientSetupNumber N 19604 300A,0183 PatientSetupLabel N 10115 19605 300A,0184 PatientAdditionalPosition N 10116 19606 300A,0190 FixationDeviceSequence N … … 10119 19609 300A,0196 FixationDeviceDescription N 10120 19610 300A,0198 FixationDevicePosition N 19611 300A,0199 FixationDevicePitchAngle N 19612 300A,019A FixationDeviceRollAngle N 10121 19613 300A,01A0 ShieldingDeviceSequence N 10122 19614 300A,01A2 ShieldingDeviceType N … … 10148 19640 300A,0226 SourceIsotopeName N 10149 19641 300A,0228 SourceIsotopeHalfLife N 19642 300A,0229 SourceStrengthUnits N 10150 19643 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 10153 19647 300A,0230 ApplicationSetupSequence N 10154 19648 300A,0232 ApplicationSetupType N … … 10199 19693 300A,02E1 CompensatorMountingPosition N 10200 19694 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 10201 19770 300C,0002 ReferencedRTPlanSequence N 10202 19771 300C,0004 ReferencedBeamSequence N … … 10224 19793 300C,00E0 ReferencedBlockNumber N 10225 19794 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 10226 19801 300E,0002 ApprovalStatus N 10227 19802 300E,0004 ReviewDate N … … 10307 19882 60xx,0051 ImageFrameOrigin N 10308 19883 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 10310 19891 60xx,0100 OverlayBitsAllocated N 10311 19892 60xx,0102 OverlayBitPosition N 10312 19893 60xx,0110 OverlayFormat N 10313 19894 60xx,0200 OverlayLocation N 19895 60xx,0800 OverlayCodeLabel N 19896 60xx,0802 OverlayNumberOfTables N 19897 60xx,0803 OverlayCodeTableLocation N 19898 60xx,0804 OverlayBitsForCodeWord N 10314 19899 60xx,1001 OverlayActivationLayer N 10315 19900 60xx,1100 OverlayDescriptorGray N … … 10327 19912 60xx,3000 OverlayData N 10328 19913 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 10331 19920 FFFA,FFFA DigitalSignaturesSequence N 10332 19921 FFFC,FFFC DataSetTrailingPadding N … … 10338 19927 10339 19928 Meta 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. 19929 a mix of information found in the C<META> elements, C<XML> element, and the 19930 C<TITLE> element. 10341 19931 10342 19932 Tag ID Tag Name Writable … … 10359 19949 'mssmarttagspreventparsing' NoMSSmartTags N 10360 19950 'ncc' NCC HTML ncc 19951 'o' Office HTML Office 19952 'originator' Originator N 10361 19953 'owner' Owner N 10362 19954 'prod' Prod HTML prod … … 10425 20017 Tag ID Tag Name Writable 10426 20018 ------ -------- -------- 10427 'charset' Char setN20019 'charset' CharacterSet N 10428 20020 'depth' Depth N 10429 20021 'files' Files N … … 10452 20044 'totaltime' Duration N 10453 20045 20046 =head3 HTML Office Tags 20047 20048 Tags 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 10454 20074 =head3 HTML prod Tags 10455 20075 … … 10465 20085 'objecttype' ObjectType N 10466 20086 20087 =head2 EXE Tags 20088 20089 This module extracts information from various types of Windows, MacOS and 20090 Unix executable and library files. The first table below lists information 20091 extracted from the header of Windows PE (Portable Executable) EXE files and 20092 DLL 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 20111 Information extracted from the VS_VERSION_INFO structure of Windows PE 20112 files. 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 20126 Resource strings found in Windows PE files. The B<TagID>'s are not shown 20127 because they are the same as the B<Tag Name>. ExifTool will extract any 20128 existing 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 20152 Information extracted from Mach-O (Mac OS X) executable files and DYLIB 20153 libraries. 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 20166 Information extracted from PEF (Classic MacOS) executable files and 20167 libraries. 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 20177 Information 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 20188 Information 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 20290 This table contains a collection of tags found in font files of various 20291 formats. ExifTool current recognizes OTF, TTF, TTC, DFONT, PFA, PFB, PFM, 20292 AFM, 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 20306 Tags 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 20331 Tags 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 20362 Tags 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 20382 The following tags are extracted from the TrueType font "name" table found 20383 in OTF, TTF, TTC and DFONT files. These tags support localized languages by 20384 adding 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 20386 default 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 20415 Tags extracted from Mac OS resource files and DFONT files. These tags may 20416 also be extracted from the resource fork of any file in OS X, either by 20417 adding "/rsrc" to the filename to process the resource fork alone, or by 20418 using the ExtractEmbedded (-ee) option to process the resource fork as a 20419 sub-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 20434 Rawzor files store compressed images of other formats. As well as the 20435 information listed below, exiftool uncompresses and extracts the meta 20436 information 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 20448 The following tags are extracted from ZIP archives. ExifTool also extracts 20449 additional meta information from compressed documents inside some ZIP-based 20450 files such Office Open XML (DOCX, PPTX and XLSX), Open Document (ODP, ODS 20451 and ODT), iWork (KEY, PAGES, NUMBERS), and Capture One Enhanced Image 20452 Package (EIP). The ExifTool family 3 groups may be used to organize the 20453 output 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 20468 These tags are extracted from GZIP (GNU ZIP) archives, but currently only 20469 for 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 20483 These 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 20496 This table lists standard tags of the RTF information group, but ExifTool 20497 will also extract any non-standard tags found in this group. As well, 20498 ExifTool will extract any custom properties that are found. See 20499 L<http://download.microsoft.com/download/2/f/5/2f599e18-07ee-4ec5-a1e7-f4e6a9423592/Word2007RTFSpec9.doc> 20500 for 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 20531 The Office Open XML (OOXML) format was introduced with Microsoft Office 2007 20532 and is used by file types such as DOCX, PPTX and XLSX. These are 20533 essentially ZIP archives containing XML files. The table below lists some 20534 tags which have been observed in OOXML documents, but ExifTool will extract 20535 any tags found from XML files of the OOXML document properties ("docProps") 20536 directory. 20537 20538 B<Tips:> 20539 20540 1) Structural ZIP tags may be ignored (if desired) with C<--ZIP:all> on the 20541 command line. 20542 20543 2) Tags may be grouped by their document number in the ZIP archive with the 20544 C<-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 20610 The Apple iWork '09 file format is a ZIP archive containing XML files 20611 similar to the Office Open XML (OOXML) format. Metadata tags in iWork 20612 files 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 10467 20623 =head2 Extra Tags 10468 20624 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. 20625 The extra tags represent extra information extracted or generated by 20626 ExifTool that is not directly associated with another tag group. The three 20627 writable "pseudo" tags (FileName, Directory and FileModifyDate) may be 20628 written without the need to rewrite the file since their values are not 20629 contained within the file data. These "pseudo" tags belong to the family 1 20630 "System" group. 10473 20631 10474 20632 Tag Name Writable … … 10476 20634 CanonVRD Y! 10477 20635 Comment Y 20636 CurrentIPTCDigest N 10478 20637 Directory Y! 10479 EXIF N 10480 Encryption N 20638 EXIF Y! 10481 20639 Error N 10482 20640 ExifByteOrder Y 10483 20641 ExifToolVersion N 10484 FileModifyDate Y 20642 ExifUnicodeByteOrder Y 20643 FileModifyDate Y! 10485 20644 FileName Y! 20645 FilePermissions N 10486 20646 FileSize N 10487 20647 FileType N 20648 Geosync Y 20649 Geotag Y 20650 Geotime Y 10488 20651 ICC_Profile Y! 20652 ID3Size N 10489 20653 ImageHeight N 10490 20654 ImageWidth N 20655 JPEGDigest N 10491 20656 MIMEType N 10492 20657 MaxVal N 20658 Now N 20659 PreviewImage Y 20660 PreviewPNG N 20661 RAFVersion N 20662 ResourceForkSize N 10493 20663 Warning N 10494 XMP Y 20664 XMP Y! 10495 20665 XResolution N 10496 20666 YResolution N … … 10498 20668 =head2 Composite Tags 10499 20669 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 i s extracted.20670 The values of the composite tags are B<Derived From> the values of other 20671 tags. These are convenience tags which are calculated after all other 20672 information is extracted. 10503 20673 10504 20674 Tag Name Derived From Writable … … 10506 20676 Aperture FNumber N 10507 20677 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 10508 20686 BlueBalance WB_RGGBLevels N 10509 20687 WB_RGBGLevels … … 10511 20689 WB_GRBGLevels 10512 20690 WB_GRGBLevels 20691 WB_GBRGLevels 20692 WB_RGBLevels 10513 20693 WB_RBLevels 10514 20694 WBBlueLevel … … 10519 20699 ConditionalFEC FlashExposureComp N 10520 20700 FlashBits 10521 DOF FocusDistance N 10522 FocalLength 20701 DOF FocalLength N 10523 20702 Aperture 10524 20703 CircleOfConfusion 20704 FocusDistance 20705 SubjectDistance 20706 ObjectDistance 10525 20707 DateCreated Kodak:YearCreated N 10526 20708 Kodak:MonthDayCreated 10527 DateTimeCreated DateCreated N 20709 DateTimeCreated IPTC:DateCreated N 20710 IPTC:TimeCreated 20711 DateTimeOriginal DateTimeCreated N 20712 DateCreated 10528 20713 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 10530 20720 DigitalZoom Canon:ZoomSourceWidth N 10531 20721 Canon:ZoomTargetWidth 10532 20722 Canon:DigitalZoom 10533 20723 DriveMode ContinuousDrive N 10534 Self -timer20724 SelfTimer 10535 20725 Duration FLAC:SampleRate N 10536 FLAC:Channels10537 20726 FLAC:TotalSamples 10538 20727 Duration FileSize N 20728 ID3Size 10539 20729 MPEG:AudioBitrate 10540 20730 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 10542 20740 FrameCount 20741 VideoFrameCount 10543 20742 ExtenderStatus Olympus:Extender N 10544 20743 Olympus:LensType 10545 20744 MaxApertureValue 10546 FlashOn FlashBits N 10547 Flash 20745 FOV FocalLength N 20746 ScaleFactor35efl 20747 FocusDistance 20748 FileNumber DirectoryIndex Y 20749 FileIndex 10548 20750 FlashType FlashBits N 10549 20751 FocalLength35efl FocalLength N 10550 20752 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 10553 20763 GPSLatitude GPS:GPSLatitude N 10554 20764 GPS:GPSLatitudeRef 10555 GPSLatitudeRef XMP:GPSLatitude N 20765 GPSLongitude QuickTime:GPSCoordinates N 20766 GPSLongitudeRef XMP:GPSLongitude N 10556 20767 GPSLongitude GPS:GPSLongitude N 10557 20768 GPS:GPSLongitudeRef 10558 GPSLongitudeRef XMP:GPSLongitude N10559 20769 GPSPosition GPSLatitude N 10560 20770 GPSLongitude … … 10562 20772 Aperture 10563 20773 CircleOfConfusion 20774 IDCPreviewImage IDCPreviewStart N 20775 IDCPreviewLength 10564 20776 ISO Canon:CameraISO N 10565 20777 Canon:BaseISO 10566 20778 Canon:AutoISO 10567 ImageHeight PostScript:ImageDataN20779 ImageHeight Main:PostScript:ImageData N 10568 20780 PostScript:BoundingBox 10569 20781 ImageSize ImageWidth N 10570 20782 ImageHeight 10571 ImageWidth PostScript:ImageData N 20783 ExifImageWidth 20784 ExifImageHeight 20785 ImageWidth Main:PostScript:ImageData N 10572 20786 PostScript:BoundingBox 10573 20787 JpgFromRaw JpgFromRawStart Y … … 10579 20793 Lens 10580 20794 ScaleFactor35efl 20795 LensID LensType N 20796 FocalLength 20797 MaxAperture 20798 MaxApertureValue 20799 ShortFocal 20800 LongFocal 20801 LensModel 20802 LensFocalRange 10581 20803 LensID Nikon:LensIDNumber N 10582 20804 LensFStops … … 10587 20809 MCUVersion 10588 20810 Nikon:LensType 20811 LensID Ricoh:LensFirmware N 10589 20812 LensSpec Nikon:Lens N 10590 20813 Nikon:LensType … … 10592 20815 ShutterSpeed 10593 20816 ISO 20817 MPImage MPImageStart N 20818 MPImageLength 20819 MPImageType 20820 OriginalDecisionData OriginalDecisionDataOffset Y! 10594 20821 OtherImage OtherImageStart N 10595 20822 OtherImageLength … … 10607 20834 WB_GRBGLevels 10608 20835 WB_GRGBLevels 20836 WB_GBRGLevels 20837 WB_RGBLevels 10609 20838 WB_RBLevels 10610 20839 WBRedLevel … … 10612 20841 RedEyeReduction CanonFlashMode N 10613 20842 FlashBits 20843 Rotation QuickTime:MatrixStructure N 20844 QuickTime:HandlerType 10614 20845 ScaleFactor35efl FocalLength N 10615 20846 FocalLengthIn35mmFormat … … 10621 20852 FocalPlaneXResolution 10622 20853 FocalPlaneYResolution 20854 ExifImageWidth 20855 ExifImageHeight 10623 20856 CanonImageWidth 10624 20857 CanonImageHeight 10625 ExifImageWidth10626 ExifImageLength10627 20858 ImageWidth 10628 20859 ImageHeight 10629 20860 ShootingMode CanonExposureMode N 10630 20861 EasyMode 20862 BulbDuration 10631 20863 ShutterCurtainHack FlashBits N 10632 20864 ShutterCurtainSync … … 10634 20866 ShutterSpeedValue 10635 20867 BulbDuration 10636 SubSecDateTimeOriginal DateTimeOriginal N 20868 SubSecCreateDate EXIF:CreateDate N 20869 SubSecTimeDigitized 20870 SubSecDateTimeOriginal EXIF:DateTimeOriginal N 10637 20871 SubSecTimeOriginal 20872 SubSecModifyDate EXIF:ModifyDate N 20873 SubSecTime 10638 20874 ThumbnailImage ThumbnailOffset Y 10639 20875 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 10640 20895 WB_RGGBLevels Canon:WhiteBalance N 10641 20896 WB_RGGBLevelsAsShot … … 10649 20904 WB_RGGBLevelsShade 10650 20905 WB_RGGBLevelsKelvin 20906 WB_RGGBLevels WB_RGGBLevelsUncorrected N 20907 WB_RGGBLevelsBlack 20908 ZoomedPreviewImage ZoomedPreviewStart N 20909 ZoomedPreviewLength 10651 20910 10652 20911 =head2 Shortcuts Tags … … 10657 20916 10658 20917 The shortcut tags below have been pre-defined, but user-defined shortcuts 10659 may be added via the %Image::ExifTool:: Shortcuts::UserDefinedlookup in the10660 ~/.ExifTool_config file. See the Image::ExifTool::Shortcuts documentation20918 may be added via the %Image::ExifTool::UserDefined::Shortcuts lookup in the 20919 =/.ExifTool_config file. See the Image::ExifTool::Shortcuts documentation 10661 20920 for more details. 10662 20921 … … 10679 20938 ImageSize 10680 20939 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 10712 20941 FlashType 10713 20942 ConditionalFEC … … 10739 20968 WhiteBalance 10740 20969 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 10741 20987 MakerNotes MakerNotes Y 10742 20988 MakerNoteCanon … … 10744 20990 MakerNoteCasio2 10745 20991 MakerNoteFujiFilm 20992 MakerNoteGE 20993 MakerNoteGE2 10746 20994 MakerNoteHP 10747 20995 MakerNoteHP2 10748 20996 MakerNoteHP4 10749 20997 MakerNoteHP6 20998 MakerNoteISL 10750 20999 MakerNoteJVC 10751 21000 MakerNoteJVCText … … 10759 21008 MakerNoteKodak6b 10760 21009 MakerNoteKodak7 10761 MakerNoteKodakIFD 21010 MakerNoteKodak8a 21011 MakerNoteKodak8b 21012 MakerNoteKodak9 21013 MakerNoteKodak10 10762 21014 MakerNoteKodakUnknown 10763 21015 MakerNoteKyocera … … 10771 21023 MakerNoteOlympus2 10772 21024 MakerNoteLeica 21025 MakerNoteLeica2 21026 MakerNoteLeica3 21027 MakerNoteLeica4 21028 MakerNoteLeica5 21029 MakerNoteLeica6 10773 21030 MakerNotePanasonic 10774 21031 MakerNotePanasonic2 … … 10777 21034 MakerNotePentax3 10778 21035 MakerNotePentax4 21036 MakerNotePentax5 21037 MakerNotePhaseOne 21038 MakerNoteReconyx 10779 21039 MakerNoteRicoh 10780 21040 MakerNoteRicohText 21041 MakerNoteSamsung1a 21042 MakerNoteSamsung1b 21043 MakerNoteSamsung2 10781 21044 MakerNoteSanyo 10782 21045 MakerNoteSanyoC4 … … 10784 21047 MakerNoteSigma 10785 21048 MakerNoteSony 21049 MakerNoteSony2 21050 MakerNoteSony3 21051 MakerNoteSony4 21052 MakerNoteSonyEricsson 10786 21053 MakerNoteSonySRF 10787 MakerNote SonySR221054 MakerNoteUnknownText 10788 21055 MakerNoteUnknown 10789 21056 Nikon Model Y … … 10815 21082 FlashMode 10816 21083 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 21098 The Metadata Working Group (MWG) recommendations provide a set of rules to 21099 allow certain overlapping EXIF, IPTC and XMP tags to be reconciled when 21100 reading, and synchronized when writing. The ExifTool MWG module is designed 21101 to aid in the implementation of these recommendations. (See 21102 L<http://www.metadataworkinggroup.org/> for the complete MWG technical 21103 specifications.) 21104 21105 The table below lists special Composite tags which are used to access other 21106 tags based on the MWG 2.0 recommendations. These tags are only accessible 21107 when the MWG module is loaded. The MWG module is loaded automatically by 21108 the exiftool application if MWG is specified as a group for any tag on the 21109 command line, or manually with the C<-use MWG> option. Via the API, the MWG 21110 module is loaded with "C<use Image::ExifTool::MWG>". 21111 21112 When reading, the value of each MWG tag is B<Derived From> the specified 21113 tags based on the MWG guidelines. When writing, the appropriate associated 21114 tags are written. The value of the IPTCDigest tag is updated automatically 21115 when the IPTC is changed if either the IPTCDigest tag didn't exist 21116 beforehand or its value agreed with the original IPTC digest (indicating 21117 that the XMP is synchronized with the IPTC). IPTC information is written 21118 only if the original file contained IPTC. 21119 21120 Loading the MWG module activates "strict MWG conformance mode", which has 21121 the effect of causing EXIF, IPTC and XMP in non-standard locations to be 21122 ignored when reading, as per the MWG recommendations. Instead, a "Warning" 21123 tag is generated when non-standard metadata is encountered. This feature 21124 may be disabled by setting C<$Image::ExifTool::MWG::strict = 0> in the 21125 ExifTool config file (or from your Perl script when using the API). Note 21126 that the behaviour when writing is not changed: ExifTool always creates new 21127 records only in the standard location, but writes new tags to any 21128 EXIF/IPTC/XMP records that exist. 21129 21130 A complication of the specification is that although the MWG:Creator 21131 property may consist of multiple values, the associated EXIF tag 21132 (EXIF:Artist) is only a simple string. To resolve this discrepancy the MWG 21133 recommends a technique which allows a list of values to be stored in a 21134 string by using a semicolon-space separator (with quotes around values if 21135 necessary). When the MWG module is loaded, ExifTool automatically 21136 implements 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 10817 21196 10818 21197 =head1 NOTES … … 10823 21202 =head1 AUTHOR 10824 21203 10825 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)21204 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 10826 21205 10827 21206 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Unknown.pm
r16842 r24107 54 54 =head1 AUTHOR 55 55 56 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)56 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 57 57 58 58 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Vorbis.pm
r16842 r24107 16 16 use Image::ExifTool qw(:DataAccess :Utils); 17 17 18 $VERSION = '1.0 1';18 $VERSION = '1.03'; 19 19 20 20 my $MAX_PACKETS = 2; # maximum packets to scan from each stream at start of file … … 55 55 Format => 'int32u', 56 56 RawConv => '$val || undef', 57 PrintConv => 'ConvertBitrate($val)', 57 58 }, 58 59 13 => { … … 60 61 Format => 'int32u', 61 62 RawConv => '$val || undef', 63 PrintConv => 'ConvertBitrate($val)', 62 64 }, 63 65 17 => { … … 65 67 Format => 'int32u', 66 68 RawConv => '$val || undef', 69 PrintConv => 'ConvertBitrate($val)', 67 70 }, 68 71 ); … … 151 154 Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name }); 152 155 } 153 $exifTool->HandleTag($tagTablePtr, $tag, $ val,156 $exifTool->HandleTag($tagTablePtr, $tag, $exifTool->Decode($val, 'UTF8'), 154 157 Index => $index, 155 158 DataPt => $dataPt, … … 197 200 198 201 # must first check for leading/trailing ID3 information 199 unless ($exifTool->{D ONE_ID3}) {202 unless ($exifTool->{DoneID3}) { 200 203 require Image::ExifTool::ID3; 201 204 Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1; … … 330 333 =head1 AUTHOR 331 334 332 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)335 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 333 336 334 337 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteCanonRaw.pl
r16842 r24107 11 11 use vars qw($VERSION $AUTOLOAD %crwTagFormat); 12 12 use Image::ExifTool::Fixup; 13 14 # map for adding directories to CRW 15 my %crwMap = ( 16 XMP => 'CanonVRD', 17 CanonVRD => 'Trailer', 18 ); 13 19 14 20 # mappings to from RAW tagID to MakerNotes tagID … … 77 83 # (and has the same raw tagID as CanonFileDescription) 78 84 return if $tagInfo and $$tagInfo{Name} eq 'UserComment'; 79 my $tagType = ($rawTag >> 8) & 0x38;80 85 my $format = $Image::ExifTool::Exif::formatNumber{$formName}; 81 86 my $fsiz = $Image::ExifTool::Exif::formatSize[$format]; … … 166 171 { 167 172 my ($exifTool, $tagInfo, $valPtr) = @_; 168 Image::ExifTool::GenerateTagIDs($$tagInfo{Table});169 173 my $tagName = $$tagInfo{Name}; 170 174 if ($tagName eq 'JpgFromRaw' or $tagName eq 'ThumbnailImage') { … … 193 197 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 194 198 my $dataPt = $$dirInfo{DataPt} or return 0; 195 my $raf = $$dirInfo{RAF} or return 0;196 199 my $outfile = $$dirInfo{OutFile} or return 0; 200 $$dirInfo{RAF} or return 0; 197 201 198 202 # 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 201 216 # CR2 has a 16-byte header 202 217 $$dirInfo{NewDataPos} = 16; … … 231 246 # Inputs: 0) ExifTool object reference, 1) source dirInfo reference, 232 247 # 2) tag table reference 233 # Returns: true on suc ess248 # Returns: true on success 234 249 # Notes: Increments ExifTool CHANGED flag for each tag changed This routine is 235 250 # different from all of the other write routines because Canon RAW files are … … 237 252 # writing it out. Therefore this routine doesn't return the directory data as 238 253 # the rest of the Write routines do. Instead, it writes to the dirInfo 239 # Out file on the fly --> much faster, efficient, and less demanding on memory!254 # OutFile on the fly --> much faster, efficient, and less demanding on memory! 240 255 sub WriteCanonRaw($$$) 241 256 { … … 294 309 my $newVal = $exifTool->GetNewValues($tagInfo); 295 310 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; 296 316 # add new directory entry 297 317 $newDir .= Set16u($addTag) . Set32u(length($newVal)) . … … 307 327 } 308 328 last unless defined $tag; # all done if no more directory entries 309 return 0 if $tag & 0x8000; # top bit should not be set329 return 0 if $tag & 0x8000; # top bit should not be set 310 330 my $tagID = $tag & 0x3fff; # get tag ID 311 331 my $tagType = ($tag >> 8) & 0x38; # get tag type … … 410 430 $oldVal = $value; 411 431 } 412 my $n ewValueHash = $exifTool->GetNewValueHash($tagInfo);413 if (Image::ExifTool::IsOverwriting($n ewValueHash, $oldVal)) {414 my $newVal = Image::ExifTool::GetNewValues($n ewValueHash);432 my $nvHash = $exifTool->GetNewValueHash($tagInfo); 433 if (Image::ExifTool::IsOverwriting($nvHash, $oldVal)) { 434 my $newVal = Image::ExifTool::GetNewValues($nvHash); 415 435 my $verboseVal; 416 436 $verboseVal = $newVal if $verbose > 1; … … 422 442 $value = $newVal; 423 443 ++$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); 430 446 } 431 447 } … … 505 521 if ($exifTool->{DEL_GROUP}->{MakerNotes}) { 506 522 if ($type eq 'CCDR') { 507 $exifTool->Error("Can't delete Maker notes group in CRW file");523 $exifTool->Error("Can't delete MakerNotes group in CRW file"); 508 524 return 0; 509 525 } else { … … 511 527 return 1; 512 528 } 529 } 530 # make XMP the preferred group for CRW files 531 if ($$exifTool{FILE_TYPE} eq 'CRW') { 532 $exifTool->InitWriteDirs(\%crwMap, 'XMP'); 513 533 } 514 534 … … 552 572 # add CanonVRD trailer if writing as a block 553 573 $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 } 554 584 # write trailer 555 585 if ($trailPt) { … … 593 623 =head1 AUTHOR 594 624 595 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)625 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 596 626 597 627 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteExif.pl
r16842 r24107 11 11 use strict; 12 12 use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber 13 % lightSource %compression %photometricInterpretation %orientation);13 %compression %photometricInterpretation %orientation); 14 14 15 15 use Image::ExifTool::Fixup; … … 30 30 0x011a => 72, # XResolution 31 31 0x011b => 72, # YResolution 32 0x0128 => 2, # Resolution unit (inches)32 0x0128 => 2, # ResolutionUnit (inches) 33 33 0x0213 => 1, # YCbCrPositioning (centered) 34 34 # 0x8769 => ????, # ExifOffset … … 38 38 0x011a => 72, # XResolution 39 39 0x011b => 72, # YResolution 40 0x0128 => 2, # Resolution unit (inches)40 0x0128 => 2, # ResolutionUnit (inches) 41 41 }, 42 42 ExifIFD => { 43 0x9000 => '02 20', # ExifVersion44 0x9101 => " \1\2\3\0",# ComponentsConfiguration43 0x9000 => '0230', # ExifVersion 44 0x9101 => "1 2 3 0",# ComponentsConfiguration 45 45 0xa000 => '0100', # FlashpixVersion 46 46 0xa001 => 0xffff, # ColorSpace (uncalibrated) 47 47 # 0xa002 => ????, # ExifImageWidth 48 # 0xa003 => ????, # ExifImage Length48 # 0xa003 => ????, # ExifImageHeight 49 49 }, 50 50 GPS => { 51 0x0000 => '2 20 0',# GPSVersionID51 0x0000 => '2 3 0 0',# GPSVersionID 52 52 }, 53 53 InteropIFD => { … … 72 72 Protected => 1, 73 73 Writable => 'undef', 74 Mandatory => 1, 74 75 WriteGroup => 'InteropIFD', 75 76 }, … … 93 94 WriteGroup => 'IFD0', 94 95 }, 95 0x0101 => { # ImageHeig th96 0x0101 => { # ImageHeight 96 97 Protected => 1, 97 98 Writable => 'int32u', … … 108 109 Writable => 'int16u', 109 110 WriteGroup => 'IFD0', 111 Mandatory => 1, 110 112 }, 111 113 0x0106 => { # PhotometricInterpretation … … 175 177 Writable => 'rational64u', 176 178 WriteGroup => 'IFD0', 179 Mandatory => 1, 177 180 }, 178 181 0x011b => { # YResolution 179 182 Writable => 'rational64u', 180 183 WriteGroup => 'IFD0', 184 Mandatory => 1, 181 185 }, 182 186 0x011c => { # PlanarConfiguration … … 204 208 Writable => 'int16u', 205 209 WriteGroup => 'IFD0', 210 Mandatory => 1, 206 211 }, 207 212 0x0129 => { # PageNumber … … 210 215 Count => 2, 211 216 }, 217 0x012d => { # TransferFunction 218 Protected => 1, 219 Writable => 'int16u', 220 WriteGroup => 'IFD0', 221 Count => 768, 222 }, 212 223 0x0131 => { # Software 213 224 Writable => 'string', … … 218 229 Shift => 'Time', 219 230 WriteGroup => 'IFD0', 220 PrintConvInv => ' Image::ExifTool::Exif::ExifDateTime($val)',231 PrintConvInv => '$self->InverseDateTime($val,0)', 221 232 }, 222 233 0x013b => { # Artist … … 286 297 Writable => 'int16u', 287 298 WriteGroup => 'IFD0', 299 Mandatory => 1, 288 300 }, 289 301 0x0214 => { # ReferenceBlackWhite … … 302 314 WriteGroup => 'InteropIFD', 303 315 }, 304 0x1002 => { # RelatedImage Length (is really the height)316 0x1002 => { # RelatedImageHeight (more commonly RelatedImageLength) 305 317 Protected => 1, 306 318 Writable => 'int16u', … … 320 332 Writable => 'string', 321 333 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 }, 322 342 }, 323 343 # … … 326 346 0x829a => { # ExposureTime 327 347 Writable => 'rational64u', 328 PrintConvInv => ' eval $val',348 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 329 349 }, 330 350 0x829d => { # FNumber … … 332 352 PrintConvInv => '$val', 333 353 }, 334 0x83bb => { # IPTC-NAA335 # this should actually be written as 'undef' (see336 # http://www.awaresystems.be/imaging/tiff/tifftags/iptc.html),337 # but Photoshop writes it as int32u and Nikon Capture won't read338 # anything else, so we do the same thing here... Doh!339 Format => 'undef', # convert binary values as undef340 Writable => 'int32u', # but write int32u format code in IFD341 WriteGroup => 'IFD0',342 },343 354 0x8546 => { # SEMInfo 344 355 Writable => 'string', … … 347 358 0x8822 => 'int16u', # ExposureProgram 348 359 0x8824 => 'string', # SpectralSensitivity 349 0x8827 => 'int16u', # ISO 360 0x8827 => { # ISO 361 Writable => 'int16u', 362 Count => -1, 363 PrintConvInv => '$val=~tr/,//d; $val', 364 }, 350 365 0x882a => { # TimeZoneOffset 351 366 Writable => 'int16s', … … 357 372 }, 358 373 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 }, 360 384 0x9003 => { # DateTimeOriginal 361 385 Writable => 'string', 362 386 Shift => 'Time', 363 PrintConvInv => ' Image::ExifTool::Exif::ExifDateTime($val)',387 PrintConvInv => '$self->InverseDateTime($val,0)', 364 388 }, 365 389 0x9004 => { # CreateDate 366 390 Writable => 'string', 367 391 Shift => 'Time', 368 PrintConvInv => ' Image::ExifTool::Exif::ExifDateTime($val)',392 PrintConvInv => '$self->InverseDateTime($val,0)', 369 393 }, 370 394 0x9101 => { # ComponentsConfiguration 395 Protected => 1, 371 396 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 }, 381 405 0x9201 => { # ShutterSpeedValue 382 406 Writable => 'rational64s', 383 407 ValueConvInv => '$val>0 ? -log($val)/log(2) : -100', 384 408 # do eval to convert things like '1/100' 385 PrintConvInv => ' eval $val',409 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 386 410 }, 387 411 0x9202 => { # ApertureValue … … 394 418 Writable => 'rational64s', 395 419 # do eval to convert things like '+2/3' 396 PrintConvInv => ' eval $val',420 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 397 421 }, 398 422 0x9205 => { # MaxApertureValue … … 415 439 0x9212 => 'string', # SecurityClassification 416 440 0x9213 => 'string', # ImageHistory 417 0x9214 => { # Subject Location418 Writable => 'int16u', 419 Count => 4, # write this SubjectLocation with 4 and the other with 2values441 0x9214 => { # SubjectArea 442 Writable => 'int16u', 443 Count => -1, # 2, 3 or 4 values 420 444 }, 421 445 # 0x927c => 'undef', # MakerNotes 422 0x9286 => { # UserComment (string that starts with "ASCII\0\0\0")446 0x9286 => { # UserComment 423 447 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 }, 429 466 0x935c => { # ImageSourceData 430 467 Writable => 'undef', 431 468 WriteGroup => 'IFD0', 469 Protected => 1, 432 470 }, 433 471 # 0x9928 => 'undef', # Opto-ElectricConversionFactor … … 438 476 tags 0x9c9b-0x9c9f are used by Windows Explorer; special characters 439 477 in these values are converted to UTF-8 by default, or Windows Latin1 440 with the -L option. XPTitle is ignored by Windows Explorer if478 with the -L option. XPTitle is ignored by Windows Explorer if 441 479 ImageDescription exists 442 480 }, 443 ValueConvInv => '$self-> Charset2Unicode($val,"II") . "\0\0"',481 ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"', 444 482 }, 445 483 0x9c9c => { # XPComment 446 484 Writable => 'int8u', 447 485 WriteGroup => 'IFD0', 448 ValueConvInv => '$self-> Charset2Unicode($val,"II") . "\0\0"',486 ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"', 449 487 }, 450 488 0x9c9d => { # XPAuthor … … 452 490 WriteGroup => 'IFD0', 453 491 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"', 455 493 }, 456 494 0x9c9e => { # XPKeywords 457 495 Writable => 'int8u', 458 496 WriteGroup => 'IFD0', 459 ValueConvInv => '$self-> Charset2Unicode($val,"II") . "\0\0"',497 ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"', 460 498 }, 461 499 0x9c9f => { # XPSubject 462 500 Writable => 'int8u', 463 501 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 }, 470 520 0xa004 => 'string', # RelatedSoundFile 471 521 0xa20b => { # FlashEnergy … … 485 535 0xa300 => { # FileSource 486 536 Writable => 'undef', 487 ValueConvInv => 'chr($val)', 488 PrintConvInv => 3, 537 ValueConvInv => '($val=~/^\d+$/ and $val < 256) ? chr($val) : $val', 489 538 }, 490 539 0xa301 => { # SceneType … … 521 570 0xa40c => 'int16u', # SubjectDistanceRange 522 571 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 523 582 0xa500 => 'rational64u',# Gamma 524 0xc4a5 => { # PrintIM525 Writable => 'undef',526 WriteGroup => 'IFD0',527 },528 583 # 529 584 # DNG stuff (back in IFD0) … … 533 588 WriteGroup => 'IFD0', 534 589 Count => 4, 590 Protected => 1, # (confuses Apple Preview if written to a TIFF image) 591 PrintConvInv => '$val =~ tr/./ /; $val', 535 592 }, 536 593 0xc613 => { # DNGBackwardVersion … … 538 595 WriteGroup => 'IFD0', 539 596 Count => 4, 597 Protected => 1, 540 598 }, 541 599 0xc614 => { # UniqueCameraModel … … 547 605 WriteGroup => 'IFD0', 548 606 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, 549 625 }, 550 626 0xc61e => { # DefaultScale … … 552 628 WriteGroup => 'SubIFD', 553 629 Count => 2, 630 Protected => 1, 554 631 }, 555 632 0xc61f => { # DefaultCropOrigin … … 557 634 WriteGroup => 'SubIFD', 558 635 Count => 2, 636 Protected => 1, 559 637 }, 560 638 0xc620 => { # DefaultCropSize … … 562 640 WriteGroup => 'SubIFD', 563 641 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, 564 691 }, 565 692 0xc629 => { # AsShotWhiteXY … … 567 694 WriteGroup => 'IFD0', 568 695 Count => 2, 696 Protected => 1, 569 697 }, 570 698 0xc62a => { # BaselineExposure 571 699 Writable => 'rational64s', 572 700 WriteGroup => 'IFD0', 701 Protected => 1, 573 702 }, 574 703 0xc62b => { # BaselineNoise 575 704 Writable => 'rational64u', 576 705 WriteGroup => 'IFD0', 706 Protected => 1, 577 707 }, 578 708 0xc62c => { # BaselineSharpness 579 709 Writable => 'rational64u', 580 710 WriteGroup => 'IFD0', 711 Protected => 1, 581 712 }, 582 713 0xc62d => { # BayerGreenSplit 583 714 Writable => 'int32u', 584 715 WriteGroup => 'SubIFD', 716 Protected => 1, 585 717 }, 586 718 0xc62e => { # LinearResponseLimit 587 719 Writable => 'rational64u', 588 720 WriteGroup => 'IFD0', 721 Protected => 1, 589 722 }, 590 723 0xc62f => { # CameraSerialNumber … … 596 729 WriteGroup => 'IFD0', 597 730 Count => 4, 598 PrintConvInv => '$_=$val;s/(-|mm f)/ /g;$_',731 PrintConvInv => \&ConvertLensInfo, 599 732 }, 600 733 0xc631 => { # ChromaBlurRadius 601 734 Writable => 'rational64u', 602 735 WriteGroup => 'SubIFD', 736 Protected => 1, 603 737 }, 604 738 0xc632 => { # AntiAliasStrength 605 739 Writable => 'rational64u', 606 740 WriteGroup => 'SubIFD', 741 Protected => 1, 607 742 }, 608 743 0xc633 => { # ShadowScale 609 744 Writable => 'rational64u', 610 745 WriteGroup => 'IFD0', 746 Protected => 1, 611 747 }, 612 748 0xc635 => { # MakerNoteSafety … … 617 753 Writable => 'int16u', 618 754 WriteGroup => 'IFD0', 755 Protected => 1, 619 756 }, 620 757 0xc65b => { # CalibrationIlluminant2 621 758 Writable => 'int16u', 622 759 WriteGroup => 'IFD0', 760 Protected => 1, 623 761 }, 624 762 0xc65c => { # BestQualityScale 625 763 Writable => 'rational64u', 626 764 WriteGroup => 'SubIFD', 765 Protected => 1, 627 766 }, 628 767 0xc65d => { # RawDataUniqueID … … 630 769 WriteGroup => 'IFD0', 631 770 Count => 16, 632 ValueConvInv => 'pack("H*",$val)', 771 ValueConvInv => 'pack("H*", $val)', 772 Protected => 1, 633 773 }, 634 774 0xc68b => { # OriginalRawFileName 635 775 Writable => 'string', 636 776 WriteGroup => 'IFD0', 637 }, 638 0xc68c => { # OriginalRawFileData (a writable directory) 639 Writable => 'undef', 640 WriteGroup => 'IFD0', 777 Protected => 1, 641 778 }, 642 779 0xc68d => { # ActiveArea … … 644 781 WriteGroup => 'SubIFD', 645 782 Count => 4, 783 Protected => 1, 646 784 }, 647 785 0xc68e => { # MaskedAreas … … 649 787 WriteGroup => 'SubIFD', 650 788 Count => 4, 651 },652 0xc68f => { # AsShotICCProfile653 Writable => 'undef',789 Protected => 1, 790 }, 791 0xc68f => { # AsShotICCProfile (writable directory) 654 792 WriteGroup => 'IFD0', 655 793 Protected => 1, … … 665 803 Protected => 1, 666 804 }, 667 0xc691 => { # CurrentICCProfile 805 0xc691 => { # CurrentICCProfile (writable directory) 668 806 Writable => 'undef', 669 807 WriteGroup => 'IFD0', … … 676 814 0xc692 => { # CurrentPreProfileMatrix 677 815 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', 678 969 Count => -1, 679 970 WriteGroup => 'IFD0', … … 692 983 ValueConvInv => q{"Owner's Name: $val"}, 693 984 Notes => q{ 694 tags 0xfde8-0xf e58 are generated by Photoshop Camera RAW -- some695 names are the same as other EXIF tags, but ExifTool will avoid696 writingthese unless they already exist in the file985 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 697 988 }, 698 989 }, … … 791 1082 792 1083 # insert our writable properties into main EXIF tag table 793 InsertWritableProperties( 'Image::ExifTool::Exif::Main', \%writeTable, \&CheckExif);1084 InsertWritableProperties(\%Image::ExifTool::Exif::Main, \%writeTable, \&CheckExif); 794 1085 795 1086 #------------------------------------------------------------------------------ 796 # Change date/time string to standard EXIF formatting797 # Inputs: 0) Date/Timestring798 # 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 1090 sub ConvertLensInfo($) 800 1091 { 801 1092 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; 814 1095 } 815 1096 … … 844 1125 #------------------------------------------------------------------------------ 845 1126 # 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 848 1128 # Returns: error string or undef (and possibly changes value) on success 849 1129 sub CheckExif($$$) 850 1130 { 851 1131 my ($exifTool, $tagInfo, $valPtr) = @_; 852 my $format = $$tagInfo{Format} || $$tagInfo{Writable} || $tagInfo->{Table} ->{WRITABLE};1132 my $format = $$tagInfo{Format} || $$tagInfo{Writable} || $tagInfo->{Table}{WRITABLE}; 853 1133 if (not $format or $format eq '1') { 854 if ($tagInfo->{Groups} ->{0} eq 'MakerNotes') {1134 if ($tagInfo->{Groups}{0} eq 'MakerNotes') { 855 1135 return undef; # OK to have no format for makernotes 856 1136 } else { … … 865 1145 # Inputs: 0) ExifTool ref, 1) text string 866 1146 # Returns: encoded string 1147 # Note: MUST be called Raw conversion time so the EXIF byte order is known! 867 1148 sub EncodeExifText($$) 868 1149 { … … 870 1151 # does the string contain special characters? 871 1152 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); 873 1155 } else { 874 1156 return "ASCII\0\0\0$val"; … … 878 1160 #------------------------------------------------------------------------------ 879 1161 # insert writable properties into main tag table 880 # Inputs: 0) tag table name, 1) reference to writable properties1162 # Inputs: 0) tag table ref, 1) reference to writable properties 881 1163 # 2) [optional] CHECK_PROC reference 882 1164 sub InsertWritableProperties($$;$) 883 1165 { 884 my ($ta bleName, $writeTablePtr, $checkProc) = @_;1166 my ($tagTablePtr, $writeTablePtr, $checkProc) = @_; 885 1167 my $tag; 886 my $tagTablePtr = GetTagTable($tableName);887 1168 $checkProc and $tagTablePtr->{CHECK_PROC} = $checkProc; 888 1169 foreach $tag (keys %$writeTablePtr) { … … 895 1176 my $key; 896 1177 foreach $key (%$writeInfo) { 897 $$tagInfo{$key} = $$writeInfo{$key} ;1178 $$tagInfo{$key} = $$writeInfo{$key} unless defined $$tagInfo{$key}; 898 1179 } 899 1180 } else { 900 $$tagInfo{Writable} = $writeInfo ;1181 $$tagInfo{Writable} = $writeInfo unless defined $$tagInfo{Writable}; 901 1182 } 902 1183 } … … 910 1191 # rebuild maker notes to properly contain all value data 911 1192 # (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 914 1194 # Returns: new maker note data (and creates MAKER_NOTE_FIXUP), or undef on error 915 1195 sub RebuildMakerNotes($$$) … … 925 1205 delete $exifTool->{MAKER_NOTE_FIXUP}; 926 1206 927 # don't need to rebuild text or binary-datamaker notes1207 # don't need to rebuild text, BinaryData or PreviewImage maker notes 928 1208 my $tagInfo = $$dirInfo{TagInfo}; 929 1209 my $subdir = $$tagInfo{SubDirectory}; 930 1210 my $proc = $$subdir{ProcessProc} || $$tagTablePtr{PROCESS_PROC} || \&ProcessExif; 931 1211 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")) 933 1215 { 934 1216 return substr($$dataPt, $dirStart, $dirLen); … … 940 1222 # create new exiftool object to rewrite the directory without changing it 941 1223 my $newTool = new Image::ExifTool; 1224 $newTool->Init(); # must do this before calling WriteDirectory()! 942 1225 # don't copy over preview image 943 1226 $newTool->SetNewValue(PreviewImage => ''); 944 1227 # copy all transient members over in case they are used for writing 945 # ( CameraMake, CameraModel, etc)1228 # (Make, Model, etc) 946 1229 foreach (grep /[a-z]/, keys %$exifTool) { 947 1230 $$newTool{$_} = $$exifTool{$_}; … … 949 1232 # fix base offsets if specified 950 1233 $newTool->Options(FixBase => $exifTool->Options('FixBase')); 951 # set FILE_TYPE to JPEGso PREVIEW_INFO will be generated952 $newTool->{ FILE_TYPE} = 'JPEG';1234 # set GENERATE_PREVIEW_INFO flag so PREVIEW_INFO will be generated 1235 $newTool->{GENERATE_PREVIEW_INFO} = 1; 953 1236 # drop any large tags 954 1237 $newTool->{DROP_TAGS} = 1; 1238 # initialize other necessary data members 1239 $newTool->{FILE_TYPE} = $exifTool->{FILE_TYPE}; 1240 $newTool->{TIFF_TYPE} = $exifTool->{TIFF_TYPE}; 955 1241 # rewrite maker notes 956 1242 $rtnValue = $newTool->WriteDirectory(\%subdirInfo, $tagTablePtr); 957 1243 if (defined $rtnValue and length $rtnValue) { 958 # add the dummy preview image if necessary1244 # add the dummy/empty preview image if necessary 959 1245 if ($newTool->{PREVIEW_INFO}) { 960 1246 $makerFixup->SetMarkerPointers(\$rtnValue, 'PreviewImage', length($rtnValue)); 961 $rtnValue .= $newTool->{PREVIEW_INFO} ->{Data};1247 $rtnValue .= $newTool->{PREVIEW_INFO}{Data}; 962 1248 delete $newTool->{PREVIEW_INFO}; 963 1249 } 964 1250 # 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 } 968 1263 # shift offsets according to original position of maker notes, 969 1264 # and relative to the makernotes Base … … 974 1269 # fix up pointers to the specified offset 975 1270 $makerFixup->ApplyFixup(\$rtnValue); 976 }977 # save fixup information unless offsets were relative978 unless ($subdirInfo{Relative}) {979 # set shift so offsets are all relative to start of maker notes980 $makerFixup->{Shift} -= $dataPos + $dirStart;981 $exifTool->{MAKER_NOTE_FIXUP} = $makerFixup; # save fixup for later1271 # 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 } 982 1277 } 983 1278 } … … 995 1290 my ($index, %entries); 996 1291 # split the directory into separate entries 997 my ($padding, $newDir) = ('','');1292 my $newDir = ''; 998 1293 for ($index=0; $index<$numEntries; ++$index) { 999 1294 my $entry = $dirStart + 2 + 12 * $index; … … 1003 1298 $tagID = 0x10000 unless $tagID or $index == 0; 1004 1299 # 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 } 1007 1305 } 1008 1306 # sort the directory entries … … 1012 1310 } 1013 1311 # replace original directory with new, sorted one 1014 substr($$dataPt, $dirStart + 2, 12 * $numEntries) = $newDir . $padding;1312 substr($$dataPt, $dirStart + 2, 12 * $numEntries) = $newDir; 1015 1313 } 1016 1314 … … 1036 1334 my $entry = 12 * $index; 1037 1335 my $tagID = Get16u(\$buff, $entry); 1038 $tagID > $lastID or return 0;1336 $tagID > $lastID or $$dirInfo{AllowOutOfOrderTags} or return 0; 1039 1337 my $format = Get16u(\$buff, $entry+2); 1040 1338 $format > 0 and $format <= 13 or return 0; … … 1044 1342 } 1045 1343 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 1352 sub 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); 1046 1377 } 1047 1378 … … 1061 1392 #------------------------------------------------------------------------------ 1062 1393 # Handle error while writing EXIF 1063 # Inputs: 0) ExifTool ref, 1) error string, 2) flag set for minor error1394 # Inputs: 0) ExifTool ref, 1) error string, 2) tag table ref 1064 1395 # Returns: undef on fatal error, or '' if minor error is ignored 1065 1396 sub ExifErr($$$) 1066 1397 { 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 } 1068 1405 return undef if $exifTool->Error($errStr, $minor); 1069 1406 return ''; … … 1071 1408 1072 1409 #------------------------------------------------------------------------------ 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 1414 sub 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 #------------------------------------------------------------------------------ 1073 1467 # 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 1076 1469 # Returns: Exif data block (may be empty if no Exif data) or undef on error 1077 1470 # Notes: Increments ExifTool CHANGED flag for each tag changed. Also updates … … 1086 1479 { 1087 1480 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 1089 1483 my $dataPt = $$dirInfo{DataPt}; 1090 1484 unless ($dataPt) { … … 1101 1495 my $dirName = $$dirInfo{DirName} || 'unknown'; 1102 1496 my $fixup = $$dirInfo{Fixup} || new Image::ExifTool::Fixup; 1497 my $imageDataFlag = $$dirInfo{ImageData} || ''; 1103 1498 my $verbose = $exifTool->Options('Verbose'); 1104 1499 my $out = $exifTool->Options('TextOut'); 1500 my ($nextIfdPos, %offsetData, $inMakerNotes); 1105 1501 my (@offsetInfo, %xDelete); 1502 my $deleteAll = 0; 1106 1503 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/; 1109 1507 1110 1508 # 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'; 1113 1511 my $ifd; 1114 1512 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 1117 1515 for ($ifd=0; ; ++$ifd) { # loop through multiple IFD's 1118 1516 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 1119 1588 # loop through new values and accumulate all information for this IFD 1120 1589 my (%set, $tagInfo); 1121 my $tableGroup = $tagTablePtr->{GROUPS}->{0};1122 1590 my $wrongDir = $crossDelete{$dirName}; 1123 1591 foreach $tagInfo ($exifTool->GetNewTagInfoList($tagTablePtr)) { … … 1134 1602 } 1135 1603 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); 1138 1622 } 1139 1623 } … … 1149 1633 } 1150 1634 } 1151 my $n ewValueHash = $exifTool->GetNewValueHash($tagInfo, $dirName);1152 unless ($n ewValueHash) {1635 my $nvHash = $exifTool->GetNewValueHash($tagInfo, $dirName); 1636 unless ($nvHash) { 1153 1637 next unless $wrongDir; 1154 1638 # delete stuff from the wrong directory if setting somewhere else 1155 $n ewValueHash = $exifTool->GetNewValueHash($tagInfo, $wrongDir);1156 next unless Image::ExifTool::IsOverwriting($n ewValueHash);1639 $nvHash = $exifTool->GetNewValueHash($tagInfo, $wrongDir); 1640 next unless Image::ExifTool::IsOverwriting($nvHash); 1157 1641 # don't cross delete if specifically deleting from the other directory 1158 my $val = Image::ExifTool::GetNewValues($n ewValueHash);1159 next if not defined $val and $n ewValueHash->{WantGroup} and1160 lc($n ewValueHash->{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); 1161 1645 # remove this tag if found in this IFD 1162 1646 $xDelete{$tagID} = 1; 1163 1647 } 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)); 1224 1658 } 1225 1659 } 1226 } else {1227 $numEntries = $len = 0;1228 }1229 1230 # fix base offsets1231 if ($dirName eq 'MakerNotes' and $$dirInfo{Parent} eq 'ExifIFD'and1660 $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 1232 1666 Image::ExifTool::MakerNotes::FixBase($exifTool, $dirInfo)) 1233 1667 { … … 1239 1673 # initialize variables to handle mandatory tags 1240 1674 my $mandatory = $mandatory{$dirName}; 1241 my $allMandatory;1675 my ($allMandatory, $addMandatory); 1242 1676 if ($mandatory) { 1243 1677 # use X/Y resolution values from JFIF if available … … 1249 1683 $mandatory = \%ifd0Vals; 1250 1684 } 1251 $allMandatory = 0;# initialize to zero1685 $allMandatory = $addMandatory = 0; # initialize to zero 1252 1686 # add mandatory tags if creating a new directory 1253 1687 unless ($numEntries) { … … 1261 1695 my ($addDirs, @newTags); 1262 1696 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; 1264 1707 } else { 1265 1708 # get a hash of directories we will be writing in this one … … 1279 1722 my $dirFixup = new Image::ExifTool::Fixup; 1280 1723 my $entryBasedFixup; 1281 my $index = 0;1282 1724 my $lastTagID = -1; 1283 my ($oldInfo, $oldFormat, $oldFormName, $oldCount, $oldSize, $oldValue );1725 my ($oldInfo, $oldFormat, $oldFormName, $oldCount, $oldSize, $oldValue, $oldImageData); 1284 1726 my ($readFormat, $readFormName, $readCount); # format for reading old value(s) 1285 1727 my ($entry, $valueDataPt, $valueDataPos, $valueDataLen, $valuePtr, $valEnd); 1728 my ($offList, $offHash, $ignoreCount, $fixCount); 1286 1729 my $oldID = -1; 1287 1730 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 } 1288 1742 #.............................................................................. 1289 1743 # loop through entries in new directory 1290 1744 # 1745 $index = 0; 1291 1746 Entry: for (;;) { 1292 1747 … … 1300 1755 $readFormat = $oldFormat = Get16u($dataPt, $entry+2); 1301 1756 $readCount = $oldCount = Get32u($dataPt, $entry+4); 1757 undef $oldImageData; 1302 1758 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 } 1303 1767 # 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; 1307 1770 # must keep same directory size to avoid messing up our fixed offsets 1308 1771 $dirBuff .= ("\0" x 12) if $$dirInfo{FixBase}; 1772 WroteIt: ++$index; 1773 $newID = $oldID; # pretend we wrote this 1309 1774 next; 1310 1775 } 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); 1312 1778 } 1313 1779 $readFormName = $oldFormName = $formatName[$oldFormat]; … … 1316 1782 $valueDataLen = $dataLen; 1317 1783 $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 1321 1785 $oldInfo = $$tagTablePtr{$oldID}; 1322 1786 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); 1323 1790 $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]; 1325 1804 my $readFromFile; 1326 1805 if ($oldSize > 4) { … … 1330 1809 $valEnd or $valEnd = $dataPos + $dirStart + 2 + 12 * $numEntries + 4; 1331 1810 my ($tagID, $size, $wFlag) = ($oldID, $oldSize, 1); 1332 #### eval FixOffsets ($valuePtr, $valEnd, $size, $tagID, $wFlag)1811 #### eval FixOffsets ($valuePtr, $valEnd, $size, $tagID, $wFlag) 1333 1812 eval $$dirInfo{FixOffsets}; 1334 1813 unless (defined $valuePtr) { 1335 1814 unless ($$exifTool{DROP_TAGS}) { 1336 1815 my $tagStr = $oldInfo ? $$oldInfo{Name} : sprintf("tag 0x%x",$oldID); 1337 return undef if $exifTool->Error("Bad $ dirName directory pointerfor $tagStr", $inMakerNotes);1816 return undef if $exifTool->Error("Bad $name offset for $tagStr", $inMakerNotes); 1338 1817 } 1339 1818 goto DropTag; 1340 1819 } 1341 1820 } 1821 # offset shouldn't point into TIFF or IFD header 1822 my $suspect = ($valuePtr < 8); 1342 1823 # convert offset to pointer in $$dataPt 1343 1824 if ($$dirInfo{EntryBased} or (ref $$tagTablePtr{$oldID} eq 'HASH' and 1344 $tagTablePtr->{$oldID} ->{EntryBased}))1825 $tagTablePtr->{$oldID}{EntryBased})) 1345 1826 { 1346 1827 $valuePtr += $entry; … … 1348 1829 $valuePtr -= $dataPos; 1349 1830 } 1831 # value shouldn't overlap our directory 1832 $suspect = 1 if $valuePtr < $dirEnd and $valuePtr+$oldSize > $dirStart; 1350 1833 # get value by seeking in file if we are allowed 1351 1834 if ($valuePtr < 0 or $valuePtr+$oldSize > $dataLen) { 1352 my ($pos, $tagStr, $invalidPreview );1835 my ($pos, $tagStr, $invalidPreview, $tmpInfo); 1353 1836 if ($oldInfo) { 1354 1837 $tagStr = $$oldInfo{Name}; 1355 1838 } elsif (defined $oldInfo) { 1356 my$tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $oldID, \ '', $oldFormName, $oldCount);1839 $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $oldID, \ '', $oldFormName, $oldCount); 1357 1840 $tagStr = $$tmpInfo{Name} if $tmpInfo; 1358 1841 } 1359 1842 $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; 1367 1871 } 1368 1872 } 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 1371 1886 $raf->Read($oldValue, $oldSize) == $oldSize); 1372 1887 if (defined $pos) { 1373 1888 $raf->Seek($pos, 0); 1374 1889 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) { 1377 1892 $invalidPreview = 1; 1378 $success = 1; # continue writing directory 1893 $success = 1; # continue writing directory anyway 1379 1894 } 1380 1895 } 1381 1896 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); 1383 1898 goto DropTag; 1384 1899 } 1385 1900 } elsif (not $invalidPreview) { 1386 return undef if $exifTool->Error("Bad $ dirName directory pointerfor $tagStr", $inMakerNotes);1901 return undef if $exifTool->Error("Bad $name offset for $tagStr", $inMakerNotes); 1387 1902 goto DropTag; 1388 1903 } 1389 1904 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 } 1392 1915 $valuePtr = 0; 1393 1916 } else { … … 1401 1924 $readFromFile = 1; 1402 1925 } 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 } 1403 1935 } 1404 1936 # read value if we haven't already … … 1406 1938 # get tagInfo using value if necessary 1407 1939 if (defined $oldInfo and not $oldInfo) { 1940 my $unk = $exifTool->Options(Unknown => 1); 1408 1941 $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); 1409 1950 } 1410 1951 # override format we use to read the value if specified 1411 1952 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 } 1412 1960 if ($$oldInfo{Drop} and $$exifTool{DROP_TAGS}) { 1413 1961 # don't rewrite this tag … … 1431 1979 my $str = $oldInfo ? "$$oldInfo{Name} tag" : sprintf('tag 0x%x',$oldID); 1432 1980 if ($oldID == $lastTagID) { 1433 $exifTool->Warn("Duplicate $str in $ dirName");;1981 $exifTool->Warn("Duplicate $str in $name");; 1434 1982 } else { 1435 $exifTool->Warn("\u$str out of sequence in $ dirName");1983 $exifTool->Warn("\u$str out of sequence in $name"); 1436 1984 } 1437 1985 } … … 1479 2027 $newInfo = $set{$newID}; 1480 2028 $newCount = $$newInfo{Count}; 1481 my ($val, $newVal );1482 my $n ewValueHash = $exifTool->GetNewValueHash($newInfo, $dirName);2029 my ($val, $newVal, $n); 2030 my $nvHash = $exifTool->GetNewValueHash($newInfo, $dirName); 1483 2031 if ($isNew > 0) { 1484 2032 # 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 } 1488 2041 } else { 1489 2042 next if $xDelete{$newID}; # don't create if cross deleting … … 1499 2052 $newFormName = $$newInfo{Writable}; 1500 2053 unless ($newFormName) { 1501 warn("No format for $ dirName $$newInfo{Name}\n");2054 warn("No format for $name $$newInfo{Name}\n"); 1502 2055 next; 1503 2056 } 1504 2057 } 1505 2058 $newFormat = $formatNumber{$newFormName}; 1506 } elsif ($n ewValueHash or $xDelete{$newID}) {1507 unless ($n ewValueHash) {1508 $n ewValueHash = $exifTool->GetNewValueHash($newInfo, $wrongDir);2059 } elsif ($nvHash or $xDelete{$newID}) { 2060 unless ($nvHash) { 2061 $nvHash = $exifTool->GetNewValueHash($newInfo, $wrongDir); 1509 2062 } 1510 2063 # read value 1511 2064 $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; 1517 2074 $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 } 1518 2083 } 1519 2084 if ($inMakerNotes and $readFormName ne 'string' and $readFormName ne 'undef') { … … 1521 2086 $newCount = $oldCount * $formatSize[$oldFormat] / $formatSize[$newFormat]; 1522 2087 } 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 } 1524 2094 } 1525 2095 if ($isOverwriting) { 1526 $newVal = Image::ExifTool::GetNewValues($n ewValueHash) unless defined $newVal;2096 $newVal = Image::ExifTool::GetNewValues($nvHash) unless defined $newVal; 1527 2097 # value undefined if deleting this tag 1528 2098 # (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 $$n ewValueHash{Shift})) {1530 if ($$newInfo{RawConvInv} and defined $$n ewValueHash{Value}) {2099 if (not defined $newVal or ($xDelete{$newID} and not defined $$nvHash{Shift})) { 2100 if ($$newInfo{RawConvInv} and defined $$nvHash{Value}) { 1531 2101 goto NoOverwrite; # error in RawConvInv, so rewrite existing tag 1532 2102 } 1533 2103 unless ($isNew) { 1534 2104 ++$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); 1537 2106 } 1538 2107 next; 1539 2108 } 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"); 1550 2128 goto NoOverwrite; 1551 2129 } 1552 2130 } 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}"); 1554 2132 goto NoOverwrite; 1555 2133 } … … 1557 2135 $newCount = length($newValue) / $formatSize[$newFormat]; 1558 2136 ++$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 } 1559 2146 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); 1565 2150 } 1566 2151 } … … 1579 2164 # create new subdirectory 1580 2165 # 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; 1582 2169 # make sure we don't try to generate a new MakerNotes directory 1583 2170 # or a SubIFD 1584 2171 next if $$newInfo{MakerNotes} or $$newInfo{Name} eq 'SubIFD'; 1585 2172 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}); 1588 2175 } else { 1589 2176 $subTable = $tagTablePtr; … … 1594 2181 Fixup => new Image::ExifTool::Fixup, 1595 2182 ); 1596 $sourceDir{DirName} = $newInfo->{Groups} ->{1} if $$newInfo{SubIFD};2183 $sourceDir{DirName} = $newInfo->{Groups}{1} if $$newInfo{SubIFD}; 1597 2184 $newValue = $exifTool->WriteDirectory(\%sourceDir, $subTable); 1598 2185 # only add new directory if it isn't empty … … 1614 2201 } else { 1615 2202 # subdirectory goes directly into value buffer 1616 $sourceDir{Fixup} ->{Start} += length($valBuff);2203 $sourceDir{Fixup}{Start} += length($valBuff); 1617 2204 # use Writable to set format, otherwise 'undef' 1618 2205 $newFormName = $$newInfo{Writable}; … … 1635 2222 $newFormat = $oldFormat; # (just in case it changed) 1636 2223 $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 } 1637 2231 } 1638 2232 if ($newInfo) { … … 1643 2237 my $dataTag = $$newInfo{DataTag}; 1644 2238 # 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); 1647 2244 my $err; 1648 2245 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) { 1652 2251 delete $offsetData{$dataTag}; 1653 2252 $err = "$dataTag not written (too large for JPEG segment)"; … … 1668 2267 if ($$newInfo{MakerNotes}) { 1669 2268 # don't write new makernotes if we are deleting this group 1670 if ($exifTool->{DEL_GROUP} ->{MakerNotes} and1671 ($exifTool->{DEL_GROUP}->{MakerNotes} != 2 or $isNew <= 0))2269 if ($exifTool->{DEL_GROUP}{MakerNotes} and 2270 ($exifTool->{DEL_GROUP}{MakerNotes} != 2 or $isNew <= 0)) 1672 2271 { 1673 2272 if ($isNew <= 0) { … … 1681 2280 # we are writing a whole new maker note block 1682 2281 # --> add fixup information if necessary 1683 my $n ewValueHash = $exifTool->GetNewValueHash($newInfo, $dirName);1684 if ($n ewValueHash and $newValueHash->{MAKER_NOTE_FIXUP}) {2282 my $nvHash = $exifTool->GetNewValueHash($newInfo, $dirName); 2283 if ($nvHash and $nvHash->{MAKER_NOTE_FIXUP}) { 1685 2284 # must clone fixup because we will be shifting it 1686 my $makerFixup = $n ewValueHash->{MAKER_NOTE_FIXUP}->Clone();2285 my $makerFixup = $nvHash->{MAKER_NOTE_FIXUP}->Clone(); 1687 2286 my $valLen = length($valBuff); 1688 2287 $makerFixup->{Start} += $valLen; … … 1692 2291 # update maker notes if possible 1693 2292 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, 1698 2297 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, 1704 2304 ); 2305 my ($subTable, $subdir, $loc, $writeProc, $notIFD); 1705 2306 if ($$newInfo{SubDirectory}) { 1706 2307 my $sub = $$newInfo{SubDirectory}; … … 1708 2309 $subdirInfo{FixOffsets} = $$sub{FixOffsets}; 1709 2310 $subdirInfo{EntryBased} = $$sub{EntryBased}; 1710 $subdirInfo{NoFixBase} = 1 if $$sub{Base}; 2311 $subdirInfo{NoFixBase} = 1 if defined $$sub{Base}; 2312 $subdirInfo{AutoFix} = $$sub{AutoFix}; 1711 2313 } 1712 2314 # 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}; 1716 2317 $subTable and $subTable = Image::ExifTool::GetTagTable($subTable); 2318 $writeProc = $$oldInfo{SubDirectory}{WriteProc}; 2319 $notIFD = $$oldInfo{NotIFD}; 1717 2320 } else { 1718 2321 $exifTool->Warn('Internal problem getting maker notes tag table'); 1719 2322 } 1720 2323 $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 } 1724 2333 if (defined $loc) { 1725 2334 # we need fixup data for this subdirectory 1726 2335 $subdirInfo{Fixup} = new Image::ExifTool::Fixup; 1727 2336 # rewrite maker notes 1728 $subdir = $exifTool->WriteDirectory(\%subdirInfo, $subTable );2337 $subdir = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $writeProc); 1729 2338 } elsif ($$subTable{PROCESS_PROC} and 1730 2339 $$subTable{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData) 1731 2340 { 1732 my $sub = $ oldInfo->{SubDirectory};2341 my $sub = $$oldInfo{SubDirectory}; 1733 2342 if (defined $$sub{Start}) { 1734 2343 #### eval Start ($valuePtr) … … 1742 2351 # rewrite maker notes 1743 2352 $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 } 1746 2360 } 1747 2361 if (defined $subdir) { … … 1763 2377 # remove all but PreviewImage fixup (since others shouldn't change) 1764 2378 foreach (keys %{$makerFixup->{Pointers}}) { 1765 /_PreviewImage$/ or delete $makerFixup->{Pointers} ->{$_};2379 /_PreviewImage$/ or delete $makerFixup->{Pointers}{$_}; 1766 2380 } 1767 2381 # zero pointer so we can see how it gets shifted later … … 1774 2388 $previewInfo->{Relative} = 1; 1775 2389 } 2390 # don't shift anything if relative flag set to zero (Pentax patch) 1776 2391 } 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) 1778 2395 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 } 1779 2411 $makerFixup->{Start} += $valLen + $loc; 1780 2412 $makerFixup->{Shift} += $baseShift; 2413 # permanently fix makernote offset errors 2414 $makerFixup->{Shift} += $subdirInfo{FixedBy} || 0; 1781 2415 push @valFixups, $makerFixup; 1782 2416 if ($previewInfo and not $previewInfo->{NoBaseShift}) { … … 1800 2434 # rewrite existing sub IFD's 1801 2435 # 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'; 1803 2444 # must handle sub-IFD's specially since the values 1804 2445 # are actually offsets to subdirectories 1805 2446 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); 1807 2448 next; 1808 2449 } … … 1817 2458 my $subdirBase = $base; 1818 2459 if ($$subdir{Base}) { 1819 my $start = $subdirStart + $ valueDataPos;1820 #### eval Base ($start )2460 my $start = $subdirStart + $dataPos; 2461 #### eval Base ($start,$base) 1821 2462 $subdirBase += eval $$subdir{Base}; 1822 2463 } 2464 # add IFD number if more than one 2465 $subdirName =~ s/\d*$/$i/ if $i; 1823 2466 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, 1828 2471 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, 1833 2481 ); 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? 1835 2490 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; 1845 2502 } 1846 return undef if $exifTool->Error("Can't read $subdirName data", $inMakerNotes); 1847 next Entry; 2503 next Entry; # don't write this directory 1848 2504 } 1849 $buff .= $buf2;1850 # change subdirectory information to data we just read1851 $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 it1856 $subSize += 4 if length($buff)==$subSize+6 and1857 ($$newInfo{Name} eq 'SubIFD' or $buff =~ /\0{4}$/);1858 UpdateTiffEnd($exifTool, $pt+$base+2+$subSize);1859 2505 } 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; 1863 2511 } 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 } 1867 2525 # temporarily set value to subdirectory index 1868 2526 # (will set to actual offset later when we know what it is) … … 1878 2536 # add to list of subdirectories we will append later 1879 2537 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}, 1885 2544 }; 1886 2545 ++$writeCount; # count number of subdirs written … … 1890 2549 # a directory and only one remains 1891 2550 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; 1894 2553 } 1895 2554 # set new format to int32u for IFD … … 1916 2575 if ($$subdir{Base}) { 1917 2576 my $start = $subdirStart + $valueDataPos; 1918 #### eval Base ($start )2577 #### eval Base ($start,$base) 1919 2578 $subdirBase += eval $$subdir{Base}; 1920 2579 } 1921 2580 my $subFixup = new Image::ExifTool::Fixup; 1922 2581 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, 1927 2586 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, 1933 2593 ); 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); 1936 2608 if (defined $newValue) { 1937 2609 my $hdrLen = $subdirStart - $valuePtr; … … 1946 2618 return undef; 1947 2619 } 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 } 1949 2624 if ($subFixup->{Pointers} and $subdirInfo{Base} == $base) { 1950 2625 $subFixup->{Start} += length $valBuff; … … 1964 2639 # must decide now if we will write CanonVRD information 1965 2640 my $hasVRD; 1966 if ($exifTool->{NEW_VALUE} ->{$Image::ExifTool::Extra{CanonVRD}}) {2641 if ($exifTool->{NEW_VALUE}{$Image::ExifTool::Extra{CanonVRD}}) { 1967 2642 # adding or deleting as a block 1968 2643 $hasVRD = $exifTool->GetNewValues('CanonVRD') ? 1 : 0; 1969 } elsif ($exifTool->{DEL_GROUP} ->{CanonVRD} or1970 $exifTool->{DEL_GROUP} ->{Trailer})2644 } elsif ($exifTool->{DEL_GROUP}{CanonVRD} or 2645 $exifTool->{DEL_GROUP}{Trailer}) 1971 2646 { 1972 2647 $hasVRD = 0; # deleting as a group … … 1982 2657 $newValuePt = \$newValue; 1983 2658 } 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; 1984 2695 } else { 1985 2696 my $offsetInfo = $offsetInfo[$ifd]; … … 1987 2698 my @vals; 1988 2699 if ($isNew <= 0) { 2700 my $oldOrder = GetByteOrder(); 2701 # Minolta A200 stores these in the wrong byte order! 2702 SetByteOrder($$newInfo{ByteOrder}) if $$newInfo{ByteOrder}; 1989 2703 @vals = ReadValue(\$oldValue, 0, $readFormName, $readCount, $oldSize); 2704 SetByteOrder($oldOrder); 1990 2705 } 1991 2706 # only support int32 pointers (for now) 1992 2707 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; 1995 2710 # change to int32 1996 2711 $newFormName = 'int32u'; 1997 2712 $newFormat = $formatNumber{$newFormName}; 1998 2713 $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 } 2000 2718 } 2001 2719 $offsetInfo or $offsetInfo = $offsetInfo[$ifd] = { }; … … 2011 2729 } elsif ($$newInfo{DataMember}) { 2012 2730 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 } 2015 2755 } 2016 2756 } … … 2036 2776 $offsetVal = Set32u(length $valBuff); 2037 2777 } 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 { 2042 2784 # hold onto the PreviewImage until we can determine if it fits 2043 2785 $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}; 2048 2788 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'; 2051 2793 $$newValuePt = ''; 2794 } elsif ($dataTag eq 'LeicaTrailer' and $$exifTool{LeicaTrailer}) { 2795 $$newValuePt = ''; 2052 2796 } 2053 2797 } 2054 $valBuff .= $$newValuePt; # add value data to buffer2055 # must save a fixup pointer for every pointer in the directory2056 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; 2059 2803 } 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 } 2061 2812 } 2062 2813 } else { … … 2072 2823 if (defined $$mandatory{$newID}) { 2073 2824 # 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); 2075 2827 if (defined $mandVal and $mandVal eq $$newValuePt) { 2076 2828 ++$allMandatory; # count mandatory tags … … 2082 2834 } 2083 2835 } 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 } 2084 2844 #.............................................................................. 2085 2845 # write directory counts and nextIFD pointer and add value data to end of IFD 2086 2846 # 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'}))); 2087 2857 # calculate number of entries in new directory 2088 2858 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)) { 2091 2862 $newEntries = 0; 2092 2863 $dirBuff = ''; … … 2095 2866 ++$deleteAll if defined $deleteAll; 2096 2867 $verbose > 1 and print $out " - $allMandatory mandatory tag(s)\n"; 2868 $exifTool->{CHANGED} -= $addMandatory; # didn't change these after all 2097 2869 } 2098 2870 if ($ifd and not $newEntries) { … … 2127 2899 my $subdir; 2128 2900 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 2135 2924 # set the pointer 2136 my $offset = $ subdir->{Offset};2925 my $offset = $$subdir{Offset}; 2137 2926 # if offset is in valBuff, it was added to the end of dirBuff 2138 2927 # (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'; 2140 2929 $offset += $newStart + 2; # get offset in newData 2141 2930 # check to be sure we got the right offset 2142 2931 unless (Get32u(\$newData, $offset) == 0xfeedf00d) { 2143 $exifTool->Error("Internal error while rewriting $ dirName");2932 $exifTool->Error("Internal error while rewriting $name"); 2144 2933 return undef; 2145 2934 } 2146 2935 # set the offset to the subdirectory data 2147 Set32u($ pos, \$newData, $offset);2936 Set32u($len, \$newData, $offset); 2148 2937 $fixup->AddFixup($offset); # add fixup for this offset in newData 2149 2938 } … … 2163 2952 } 2164 2953 # 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) { 2173 2956 # continue with next IFD 2174 $dirStart = $ offset - $dataPos;2957 $dirStart = $nextIfdOffset - $dataPos; 2175 2958 } else { 2176 2959 # create IFD1 if necessary 2177 last unless $dirName eq 'IFD0' and $exifTool->{ADD_DIRS}->{'IFD1'};2178 2960 $verbose and print $out " Creating IFD1\n"; 2179 2961 my $ifd1 = "\0" x 2; # empty IFD1 data (zero entry count) … … 2183 2965 } 2184 2966 # 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; 2189 2971 2190 2972 # 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); 2194 2976 last; 2195 2977 } 2196 $exifTool->{PROCESSED} ->{$addr} = $dirName;2978 $exifTool->{PROCESSED}{$addr} = $name; 2197 2979 2198 2980 if ($dirName eq 'SubIFD1' and not ValidateIFD($dirInfo, $dirStart)) { … … 2204 2986 last; # don't write bad IFD 2205 2987 } 2206 if ($exifTool->{DEL_GROUP} ->{$dirName}) {2988 if ($exifTool->{DEL_GROUP}{$dirName}) { 2207 2989 $verbose and print $out " Deleting $dirName\n"; 2208 2990 $raf and $exifTool->Error("Deleting $dirName also deletes subsequent" . 2209 2991 " IFD's and possibly image data", 1); 2210 2992 ++$exifTool->{CHANGED}; 2211 if ($exifTool->{DEL_GROUP} ->{$dirName} == 2 and2212 $exifTool->{ADD_DIRS} ->{$dirName})2993 if ($exifTool->{DEL_GROUP}{$dirName} == 2 and 2994 $exifTool->{ADD_DIRS}{$dirName}) 2213 2995 { 2214 2996 my $emptyIFD = "\0" x 2; # start with empty IFD … … 2220 3002 } 2221 3003 } else { 2222 $verbose and print $out " Rewriting $ dirName\n";3004 $verbose and print $out " Rewriting $name\n"; 2223 3005 } 2224 3006 } … … 2228 3010 $fixup->ApplyFixup(\$newData); 2229 3011 # 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 # 2230 3022 # copy over image data for IFD's, starting with the last IFD first 2231 3023 # 2232 my @imageData; # image data blocks if requested2233 my $blockSize = 0; # total size of blocks to copy later2234 3024 if (@offsetInfo) { 2235 my @writeLater; # write image data last 3025 my $ttwLen; # length of MRW TTW segment 3026 my @writeLater; # write image data last 2236 3027 for ($ifd=$#offsetInfo; $ifd>=-1; --$ifd) { 2237 3028 # build list of offsets to process … … 2239 3030 if ($ifd >= 0) { 2240 3031 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 } 2241 3039 my $tagID; 2242 3040 # loop through all tags in reverse order so we save thumbnail 2243 3041 # data before main image data if both exist in the same IFD 2244 3042 foreach $tagID (reverse sort keys %$offsetInfo) { 2245 my $tagInfo = $offsetInfo->{$tagID} ->[0];3043 my $tagInfo = $offsetInfo->{$tagID}[0]; 2246 3044 next unless $$tagInfo{IsOffset}; # handle byte counts with offsets 2247 3045 my $sizeInfo = $offsetInfo->{$$tagInfo{OffsetPair}}; … … 2249 3047 my $dataTag = $$tagInfo{DataTag}; 2250 3048 # 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 2253 3056 (not defined $dataTag or not defined $offsetData{$dataTag})) 2254 3057 { … … 2268 3071 # must be the same number of offset and byte count values 2269 3072 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}"); 2271 3074 return undef; 2272 3075 } … … 2281 3084 } 2282 3085 # get offset base and data pos (abnormal for some preview images) 2283 my ($dbase, $dpos );3086 my ($dbase, $dpos, $wrongBase, $subIfdDataFixup); 2284 3087 if ($$tagInfo{IsOffset} eq '2') { 2285 3088 $dbase = $firstBase; … … 2289 3092 $dpos = $dataPos; 2290 3093 } 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}; 2291 3108 # transfer the data referenced by all offsets of this tag 2292 3109 for ($n=0; $n<$count; ++$n) { 2293 my $oldEnd;3110 my ($oldEnd, $size); 2294 3111 if (@$oldOffset and @$oldSize) { 2295 3112 # calculate end offset of this block … … 2300 3117 my $offsetPos = $offsets + $n * 4; 2301 3118 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; 2304 3134 my $buff; 2305 3135 # look for 'feed' code to use our new data 2306 3136 if ($size == 0xfeedfeed) { 2307 my $dataTag = $$tagInfo{DataTag};2308 3137 unless (defined $dataTag) { 2309 3138 $exifTool->Error("No DataTag defined for $$tagInfo{Name}"); … … 2332 3161 $oldEnd != $$oldOffset[$n+1]); 2333 3162 # preserve original image padding if specified 2334 if ($ _[1]->{PreserveImagePadding} and $n+1 < $count and3163 if ($$origDirInfo{PreserveImagePadding} and $n+1 < $count and 2335 3164 $oldEnd and $$oldOffset[$n+1] > $oldEnd) 2336 3165 { … … 2339 3168 # copy data later 2340 3169 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 } 2341 3176 $size += $pad; # account for pad byte if necessary 2342 3177 # return ImageData list 2343 $ _[1]->{ImageData} = \@imageData;3178 $$origDirInfo{ImageData} = \@imageData; 2344 3179 } elsif ($offset >= 0 and $offset+$size <= $dataLen) { 2345 3180 # take data from old dir data buffer 2346 3181 $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; 2347 3190 } elsif ($raf and $raf->Seek($offset+$dbase+$dpos,0) and 2348 3191 $raf->Read($buff,$size) == $size) 2349 3192 { 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 } 2351 3209 } elsif ($$tagInfo{Name} eq 'ThumbnailOffset' and $offset>=0 and $offset<$dataLen) { 2352 3210 # Grrr. The Canon 350D writes the thumbnail with an incorrect byte count … … 2372 3230 $r->Seek($tell, 0) or $exifTool->Error('Seek error'), return undef; 2373 3231 } 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; 2375 3234 } 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); 2378 3237 $buff = ''; 2379 3238 } 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 } 2388 3254 } 2389 3255 # update offset accordingly and add to end of new data 2390 Set32u( length($newData)+$blockSize, \$newData, $offsetPos);3256 Set32u($newOffset, \$newData, $offsetPos); 2391 3257 # 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 } 2393 3267 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; 2395 3270 $newData .= $buff; # add this strip to the data 2396 3271 } else { … … 2398 3273 } 2399 3274 } 3275 SetByteOrder($oldOrder); 2400 3276 } 2401 3277 } 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 } 2402 3282 } 2403 3283 # 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 # 2404 3322 # apply final shift to new data position if this is the top level IFD 2405 3323 # 2406 3324 unless ($$dirInfo{Fixup}) { 2407 my $newDataPos = $$dirInfo{NewDataPos} || 0; 3325 my $hdrPtr = $$dirInfo{HeaderPtr}; 3326 my $newDataPos = $hdrPtr ? length $$hdrPtr : $$dirInfo{NewDataPos} || 0; 2408 3327 # adjust CanonVRD offset to point to end of regular TIFF if necessary 2409 3328 # (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)) 2411 3332 $fixup->SetMarkerPointers(\$newData, 'CanonVRD', length($newData) + $blockSize); 2412 3333 if ($newDataPos) { … … 2414 3335 $fixup->ApplyFixup(\$newData); 2415 3336 } 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 } 2416 3343 # save fixup for PreviewImage in JPEG file if necessary 2417 3344 my $previewInfo = $exifTool->{PREVIEW_INFO}; 2418 3345 if ($previewInfo) { 2419 my $pt = \$previewInfo->{Data}; # image data or 'LOAD ' flag3346 my $pt = \$previewInfo->{Data}; # image data or 'LOAD_PREVIEW' flag 2420 3347 # now that we know the size of the EXIF data, first test to see if our new image fits 2421 3348 # 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 2423 3351 $previewInfo->{IsShort}) # must fit in this segment if using short pointers 2424 3352 { 2425 3353 # It fits! (or must exist in EXIF segment), so fixup the 2426 3354 # PreviewImage pointers and stuff the preview image in here 2427 my $newPos = length($newData) + ($newDataPos || 0);3355 my $newPos = length($newData) + $newDataPos; 2428 3356 $newPos += ($previewInfo->{BaseShift} || 0); 2429 3357 if ($previewInfo->{Relative}) { … … 2441 3369 $previewInfo->{Fixup}->AddFixup($fixup); 2442 3370 } 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'); 2446 3376 } 2447 3377 # save location of last IFD for use in Canon RAW header 2448 3378 if ($newDataPos == 16) { 2449 3379 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 } 2451 3392 } 2452 3393 } … … 2476 3417 =head1 AUTHOR 2477 3418 2478 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)3419 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 2479 3420 2480 3421 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteIPTC.pl
r16842 r24107 40 40 ); 41 41 42 my %iptcCharsetInv = ( 'UTF8' => "\x1b%G" );42 my %iptcCharsetInv = ( 'UTF8' => "\x1b%G", 'UTF-8' => "\x1b%G" ); 43 43 44 44 # ISO 2022 Character Coding Notes … … 71 71 # C0 : 0x1b 0x21 F (0x21 = '!') 72 72 # C1 : 0x1b 0x22 F (0x22 = '"') 73 # Complete codes (control+graphics, designated and invo lked)73 # Complete codes (control+graphics, designated and invoked) 74 74 # 0x1b 0x25 F (0x25 = '%') 75 75 # 0x1b 0x25 I F … … 98 98 #------------------------------------------------------------------------------ 99 99 # 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 102 101 # Returns: error string or undef (and possibly changes value) on success 103 102 sub CheckIPTC($$$) … … 118 117 for ($n=0; $n<$bytes; ++$n) { $val >>= 8; } 119 118 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*)\]?$/) { 121 120 my ($fmt, $minlen, $maxlen) = ($1, $2, $3); 122 121 my $len = length $$valPtr; 123 122 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) { 129 131 $maxlen or $maxlen = $minlen; 130 132 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 } 132 137 } 133 138 } else { … … 146 151 { 147 152 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+)/) { 150 156 if ($read) { 151 157 my $len = length($$valPtr); … … 168 174 } 169 175 } 170 } elsif ($ $tagInfo{Format}=~ /^string/) {176 } elsif ($format =~ /^string/) { 171 177 if ($rec == 1) { 172 178 if ($$tagInfo{Name} eq 'CodedCharacterSet') { … … 181 187 #------------------------------------------------------------------------------ 182 188 # generate IPTC-format date 183 # Inputs: 0) EXIF-format date string (YYYY: MM:DD) or date/time string184 # Returns: IPTC-format date string (YYYY MMDD), or undefon error189 # 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 185 191 sub IptcDate($) 186 192 { 187 193 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 } 189 198 return $val; 190 199 } … … 193 202 # generate IPTC-format time 194 203 # 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 error204 # Returns: IPTC-format time string (HHMMSS+HHMM), or undef and issue warning on error 196 205 sub IptcTime($) 197 206 { 198 207 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 204 215 } 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; 207 236 } else { 237 warn "Invalid time format (use HH:MM:SS[+/-HH:MM])\n"; 208 238 undef $val; # time format error 209 239 } … … 257 287 #------------------------------------------------------------------------------ 258 288 # 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 261 290 # Returns: IPTC data block (may be empty if no IPTC data) 262 291 # Notes: Increments ExifTool CHANGED flag for each tag changed 263 sub WriteIPTC($$$)292 sub DoWriteIPTC($$$) 264 293 { 265 294 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 } 267 309 my $dataPt = $$dirInfo{DataPt}; 268 310 unless ($dataPt) { … … 272 314 my $start = $$dirInfo{DirStart} || 0; 273 315 my $dirLen = $$dirInfo{DirLen}; 274 my $verbose = $exifTool->Options('Verbose');275 my $out = $exifTool->Options('TextOut');276 316 my ($tagInfo, %iptcInfo, $tag); 277 317 278 # begin by assuming IPTC is coded in Latin unless otherwise specified279 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'); 281 321 282 322 # make sure our dataLen is defined (note: allow zero length directory) … … 304 344 my $subTablePtr = Image::ExifTool::GetTagTable($table); 305 345 $recordNum{$subTablePtr} = $tag; 306 Image::ExifTool::GenerateTagIDs($subTablePtr);307 346 } 308 347 … … 342 381 my $allMandatory = 0; 343 382 my %foundRec; # found flags: 0x01-existed before, 0x02-deleted, 0x04-created 383 my $addNow; 344 384 345 385 for (;;$tail=$pos) { … … 351 391 if ($id == 0x1c) { 352 392 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 } 354 401 } 355 402 # handle extended IPTC entry if necessary … … 375 422 } 376 423 } 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) { 379 427 for (;;) { 380 428 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) { 382 432 # handle mandatory tags in last record unless it was empty 383 433 if (length $newData > $lastRecPos) { … … 412 462 $tagInfo = $subTablePtr->{$mandTag} or warn("WriteIPTC: Internal error 2\n"), next; 413 463 my $value = $mandatory->{$mandTag}; 414 $ verbose > 1 and print $out " + IPTC:$$tagInfo{Name} = '$value' (mandatory)\n";464 $exifTool->VerboseValue("+ IPTC:$$tagInfo{Name}", $value, ' (mandatory)'); 415 465 # apply necessary format conversions 416 466 FormatIPTC($exifTool, $tagInfo, \$value, \$xlat, $lastRec); … … 419 469 my $entry = pack("CCCn", 0x1c, $lastRec, $mandTag, length($value)); 420 470 $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}; 422 473 } 423 474 } … … 428 479 $allMandatory = 1; 429 480 } 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 } 431 488 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); 437 490 # only add new values if... 438 491 my ($doSet, @values); 439 492 my $found = $foundRec{$newRec}->{$newTag} || 0; 440 493 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; 443 496 } elsif ($$tagInfo{List}) { 444 497 # ...tag is List and it existed before or we are creating it 445 $doSet = 1 if $found or Image::ExifTool::IsCreating($n ewValueHash);498 $doSet = 1 if $found or Image::ExifTool::IsCreating($nvHash); 446 499 } else { 447 500 # ...tag didn't exist before and we are creating it 448 $doSet = 1 if not $found and Image::ExifTool::IsCreating($n ewValueHash);501 $doSet = 1 if not $found and Image::ExifTool::IsCreating($nvHash); 449 502 } 450 503 if ($doSet) { 451 @values = Image::ExifTool::GetNewValues($n ewValueHash);504 @values = Image::ExifTool::GetNewValues($nvHash); 452 505 @values and $foundRec{$newRec}->{$newTag} = $found | 0x04; 453 506 # write tags for each value in list 454 507 my $value; 455 508 foreach $value (@values) { 456 $ verbose > 1 and print $out " + IPTC:$$tagInfo{Name} = '$value'\n";509 $exifTool->VerboseValue("+ IPTC:$$tagInfo{Name}", $value); 457 510 # reset allMandatory flag if a non-mandatory tag is written 458 511 if ($allMandatory) { … … 476 529 } 477 530 } 531 # continue on with regular programming if done adding tag now 532 if ($addNow) { 533 undef $addNow; 534 next if $writeRec; 535 last; 536 } 478 537 # remove this tagID from the sorted write list 479 538 shift @{$iptcInfo{$newRec}}; 480 539 shift @recordList unless @{$iptcInfo{$newRec}}; 481 540 } 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 } 488 549 } 489 550 # set flag indicating we found this tag 490 $foundRec{$rec}->{$tag} = 1;551 $foundRec{$rec}->{$tag} = ($foundRec{$rec}->{$tag} || 0) || 0x01; 491 552 # write out this record unless we are setting it with a new value 492 553 $tagInfo = $set{$rec}->{$tag}; 493 554 if ($tagInfo) { 494 my $n ewValueHash = $exifTool->GetNewValueHash($tagInfo);555 my $nvHash = $exifTool->GetNewValueHash($tagInfo); 495 556 $len = $pos - $valuePtr; 496 557 my $val = substr($$dataPt, $valuePtr, $len); 497 558 my $oldXlat = $xlat; 498 559 FormatIPTC($exifTool, $tagInfo, \$val, \$xlat, $rec, 1); 499 if (Image::ExifTool::IsOverwriting($n ewValueHash, $val)) {560 if (Image::ExifTool::IsOverwriting($nvHash, $val)) { 500 561 $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); 502 563 ++$exifTool->{CHANGED}; 503 564 # set deleted flag to indicate we found and deleted this tag 504 565 $foundRec{$rec}->{$tag} |= 0x02; 505 # set allMandatory flag to 2 indicatinga tag was removed566 # increment allMandatory flag to indicate a tag was removed 506 567 $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 } 507 574 next; 508 575 } … … 532 599 } 533 600 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 606 sub 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 534 659 535 660 1; # end … … 552 677 =head1 AUTHOR 553 678 554 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)679 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 555 680 556 681 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePNG.pl
r16842 r24107 115 115 if ($exifTool->{ADD_DIRS}->{ICC_Profile}) { 116 116 # write new ICC data 117 my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');117 my $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::ICC_Profile::Main'); 118 118 my %dirInfo = ( Parent => 'PNG', DirName => 'ICC_Profile' ); 119 119 my $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr); … … 127 127 128 128 #------------------------------------------------------------------------------ 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 133 sub 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 #------------------------------------------------------------------------------ 129 194 # Add any outstanding new chunks to the PNG image 130 195 # Inputs: 0) ExifTool object ref, 1) output file or scalar ref … … 140 205 foreach $tag (sort keys %$addTags) { 141 206 my $tagInfo = $$addTags{$tag}; 142 my $n ewValueHash = $exifTool->GetNewValueHash($tagInfo);207 my $nvHash = $exifTool->GetNewValueHash($tagInfo); 143 208 # (always create native PNG information, so don't check IsCreating()) 144 next unless Image::ExifTool::IsOverwriting($n ewValueHash) > 0;145 my $val = Image::ExifTool::GetNewValues($n ewValueHash);209 next unless Image::ExifTool::IsOverwriting($nvHash) > 0; 210 my $val = Image::ExifTool::GetNewValues($nvHash); 146 211 if (defined $val) { 147 212 my $data; 148 213 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}; 150 217 } else { 151 218 $data = "$tag$val"; 152 }153 # write as compressed zTXt if specified154 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 space163 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);175 219 } 176 220 my $hdr = pack('N', length($data) - 4); 177 221 my $cbuf = pack('N', CalculateCRC(\$data, undef)); 178 222 Write($outfile, $hdr, $data, $cbuf) or $err = 1; 179 $exifTool->V Print(1, " + PNG:$$tagInfo{Name} = '",$exifTool->Printable($val),"'\n");223 $exifTool->VerboseValue("+ PNG:$$tagInfo{Name}", $val); 180 224 ++$exifTool->{CHANGED}; 181 225 } … … 192 236 $exifTool->VPrint(0, "Creating EXIF profile:\n"); 193 237 $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); 205 240 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; 208 242 WriteProfile($outfile, 'APP1', \$buff, 'generic') or $err = 1; 209 243 } 210 244 } elsif ($dir eq 'XMP') { 211 245 $exifTool->VPrint(0, "Creating XMP iTXt chunk:\n"); 212 $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');246 $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::XMP::Main'); 213 247 $dirInfo{ReadOnly} = 1; 214 248 $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr); … … 229 263 $exifTool->VPrint(0, "Creating IPTC profile:\n"); 230 264 # write new IPTC data 231 $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');265 $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::Photoshop::Main'); 232 266 $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr); 233 267 if (defined $buff and length $buff) { … … 237 271 $exifTool->VPrint(0, "Creating ICC profile:\n"); 238 272 # 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'); 240 274 $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr); 241 275 if (defined $buff and length $buff) { 242 276 WriteProfile($outfile, 'icm', \$buff, 'ICC') or $err = 1; 243 $exifTool->Warn('Wrote ICC as genericprofile (no Compress::Zlib)');277 $exifTool->Warn('Wrote ICC as a raw profile (no Compress::Zlib)'); 244 278 } 245 279 } … … 282 316 =head1 AUTHOR 283 317 284 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)318 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 285 319 286 320 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePhotoshop.pl
r16842 r24107 55 55 my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $start); 56 56 my $dirEnd = $start + $dirLen; 57 my $verbose = $exifTool->Options('Verbose');58 my $out = $exifTool->Options('TextOut');59 57 my $newData = ''; 60 58 … … 104 102 $tagInfo = $$newTags{$tagID}; 105 103 delete $$newTags{$tagID}; 106 my $n ewValueHash = $exifTool->GetNewValueHash($tagInfo);104 my $nvHash = $exifTool->GetNewValueHash($tagInfo); 107 105 # check to see if we are overwriting this tag 108 106 $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 } 112 129 ++$exifTool->{CHANGED}; 113 130 next unless defined $value; # next if tag is being deleted 114 131 # set resource name if necessary 115 132 SetResourceName($tagInfo, $name, \$value); 116 $ verbose > 1 and print $out " + Photoshop:$$tagInfo{Name} = '$value'\n";133 $exifTool->VerboseValue("+ Photoshop:$$tagInfo{Name}", $value); 117 134 } 118 135 } else { … … 168 185 if ($$newTags{$tagID}) { 169 186 $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 } 172 201 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); 176 203 ++$exifTool->{CHANGED}; 177 204 } else { … … 227 254 =head1 AUTHOR 228 255 229 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)256 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 230 257 231 258 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePostScript.pl
r16842 r24107 74 74 75 75 #------------------------------------------------------------------------------ 76 # Check PS tag value77 # Inputs: 0) ExifTool object ref, 1) tag info ref, 2) value ref78 # Returns: undef on success, or error string79 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; # success91 }92 93 #------------------------------------------------------------------------------94 76 # Write XMP directory to file, with begin/end tokens if necessary 95 77 # Inputs: 0) outfile ref, 1) flags hash ref, 2-N) data to write … … 160 142 $dirInfo{DataPt} = \$xmp; 161 143 } 162 my $tagTablePtr = GetTagTable("Image::ExifTool::${dirName}::Main");144 my $tagTablePtr = Image::ExifTool::GetTagTable("Image::ExifTool::${dirName}::Main"); 163 145 my $val = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr); 164 146 if (defined $val) { … … 264 246 265 247 #------------------------------------------------------------------------------ 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 252 sub 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 #------------------------------------------------------------------------------ 266 275 # Write new tags information in comments section 267 276 # Inputs: 0) ExifTool object ref, 1) output file ref, 2) reference to new tag hash … … 279 288 foreach $tag (sort keys %$newTags) { 280 289 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}; 296 296 } 297 297 # write XMP hint if necessary … … 436 436 # rewrite PostScript data 437 437 # 438 my $oldsep = SetInputRecordSeparator($raf);439 unless ($ oldsepand $raf->ReadLine($buff)) {438 local $/ = GetInputRecordSeparator($raf); 439 unless ($/ and $raf->ReadLine($buff)) { 440 440 $exifTool->Error('Invalid PostScript data'); 441 441 return 1; 442 442 } 443 443 $data .= $buff; 444 unless ($data =~ /^%!PS-Adobe-3 .(0|1)/) {444 unless ($data =~ /^%!PS-Adobe-3\.(\d+)\b/ and $1 < 2) { 445 445 if ($exifTool->Error("Document does not conform to DSC spec. Metadata may be unreadable by other apps", 1)) { 446 446 return 1; 447 447 } 448 448 } 449 my $psRev = $1; # save PS revision number (3.x) 449 450 Write($outfile, $data) or $err = 1; 450 451 $flags{EPS} = 1 if $data =~ /EPSF/; … … 461 462 # set XMP hint flag (1 for adding, 0 for deleting, undef for no change) 462 463 $xmpHint = 1 if $$addDirs{XMP}; 463 $xmpHint = 0 if $ exifTool->{DEL_GROUP}->{XMP};464 $xmpHint = 0 if $$exifTool{DEL_GROUP}{XMP}; 464 465 $$newTags{XMP_HINT} = $xmpHint if $xmpHint; # add special tag to newTags list 465 466 466 my @lines;467 my (@lines, $changedNL); 467 468 my $altnl = ($/ eq "\x0d") ? "\x0a" : "\x0d"; 468 469 … … 474 475 $dos and CheckPSEnd($raf, $psEnd, $data); 475 476 # 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; 478 495 if ($endToken) { 479 496 # look for end token … … 537 554 # rewrite information from PostScript tags in comments 538 555 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 } 539 580 if ($$newTags{$tag}) { 540 581 my $tagInfo = $$newTags{$tag}; 582 delete $$newTags{$tag}; # write it then forget it 541 583 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); 551 591 ++$exifTool->{CHANGED}; 552 592 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); 563 595 } 564 596 } … … 663 695 push @notDone, 'PostScript' if %$newTags; 664 696 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}; 666 699 } 667 700 @notDone and $exifTool->Warn("Couldn't write ".join('/',@notDone).' information'); … … 698 731 =head1 NOTES 699 732 700 Currently, information is written only in the out ter-level document.733 Currently, information is written only in the outer-level document. 701 734 702 735 Photoshop will discard meta information in a PostScript document if it has … … 731 764 =head1 AUTHOR 732 765 733 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)766 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 734 767 735 768 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteXMP.pl
r16842 r24107 9 9 10 10 use strict; 11 use vars qw(%specialStruct %dateTimeInfo $xlatNamespace); 12 11 13 use Image::ExifTool qw(:DataAccess :Utils); 12 14 13 15 sub CheckXMP($$$); 14 sub SetPropertyPath($$;$$);15 16 sub CaptureXMP($$$;$); 17 sub SetPropertyPath($$;$$$$); 16 18 17 19 my $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 }, 20 my $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 24 my $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) 28 my %extendedRes = ( 29 'photoshop:History' => 1, 30 'xap:Thumbnails' => 1, 31 'xmp:Thumbnails' => 1, 32 'crs' => 1, 33 'crss' => 1, 192 34 ); 193 35 194 # Lookup to translate our namespace prefixes into URI's. This list need195 # not be complete, but it must contain an entry for each namespace prefix196 # (NAMESPACE) for writable tags in the XMP tables or the table above197 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'";237 36 my $rdfDesc = 'rdf:Description'; 238 37 # … … 241 40 my $pktOpen = "<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'?>\n"; 242 41 my $xmlOpen = "<?xml version='1.0' encoding='UTF-8'?>\n"; 243 my $xmpOpen = "<x:xmpmeta xmlns:x='$nsURI{x}' $x_toolkit>\n";42 my $xmpOpenPrefix = "<x:xmpmeta xmlns:x='$nsURI{x}'"; 244 43 my $rdfOpen = "<rdf:RDF xmlns:rdf='$nsURI{rdf}'>\n"; 245 44 my $rdfClose = "</rdf:RDF>\n"; … … 248 47 my $pktCloseR = "<?xpacket end='r'?>"; 249 48 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 53 sub 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"; 290 67 } 291 68 … … 298 75 my ($xmpPt, $mode) = @_; 299 76 unless ($$xmpPt =~ /^\0*<\0*\?\0*x\0*p\0*a\0*c\0*k\0*e\0*t/) { 300 return '' unless $$xmpPt =~ /^<x(mp)?:x mpmeta/;77 return '' unless $$xmpPt =~ /^<x(mp)?:x[ma]pmeta/; 301 78 # add required xpacket header/trailer 302 79 $$xmpPt = $pktOpen . $$xmpPt . $pktCloseW; … … 311 88 312 89 #------------------------------------------------------------------------------ 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) 93 sub 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 #------------------------------------------------------------------------------ 313 118 # 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 316 120 # Returns: error string or undef (and may change value) on success 121 # Note: copies structured information to avoid conflicts with calling code 317 122 sub CheckXMP($$$) 318 123 { 319 124 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; 325 154 } 326 155 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 } 329 175 if ($format eq 'rational' or $format eq 'real') { 330 176 # 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 } 332 184 if ($format eq 'rational') { 333 185 $$valPtr = join('/', Image::ExifTool::Rationalize($$valPtr)); … … 343 195 } 344 196 } 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; 363 200 } elsif ($format eq 'boolean') { 364 201 if (not $$valPtr or $$valPtr =~ /false/i or $$valPtr =~ /^no$/i) { … … 383 220 { 384 221 my $tagInfo = shift; 385 unless ($$tagInfo{PropertyPath}) { 386 SetPropertyPath($$tagInfo{Table}, $$tagInfo{TagID}); 387 } 222 SetPropertyPath($$tagInfo{Table}, $$tagInfo{TagID}) unless $$tagInfo{PropertyPath}; 388 223 return $$tagInfo{PropertyPath}; 389 224 } 390 225 391 226 #------------------------------------------------------------------------------ 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 232 sub SetPropertyPath($$;$$$$) 233 { 234 my ($tagTablePtr, $tagID, $parentID, $structPtr, $propList, $isType) = @_; 398 235 my $table = $structPtr || $tagTablePtr; 399 236 my $tagInfo = $$table{$tagID}; 400 my $ns = $$table{NAMESPACE}; 237 238 return if ref($tagInfo) ne 'HASH' or $$tagInfo{PropertyPath}; 239 401 240 # 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}; 403 256 $ns or warn("No namespace for $tagID\n"), return; 404 257 my (@propList, $listType); … … 410 263 # remove language code from property path if it exists 411 264 $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 } 412 269 } else { 413 270 $listType = $$tagInfo{List}; 414 271 } 415 272 # 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}; 421 281 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 428 291 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 level433 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; 439 302 } 440 303 # set property path for tagInfo in main table … … 451 314 my ($exifTool, $propList, $val, $attrs) = @_; 452 315 return unless defined $val and @$propList > 2; 453 if ($$propList[0] =~ /^x:x (a|m)pmeta$/ and316 if ($$propList[0] =~ /^x:x[ma]pmeta$/ and 454 317 $$propList[1] eq 'rdf:RDF' and 455 318 $$propList[2] =~ /$rdfDesc( |$)/) … … 457 320 # no properties to save yet if this is just the description 458 321 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 } 459 327 # save information about this property 460 328 my $capture = $exifTool->{XMP_CAPTURE}; … … 465 333 $$capture{$path} = [$val, $attrs || { }]; 466 334 } 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); 467 343 } else { 468 344 $exifTool->{XMP_ERROR} = 'Improperly enclosed XMP property: ' . join('/',@$propList); … … 563 439 my ($exifTool, $path) = @_; 564 440 my @propList = split('/',$path); 565 my ($prop, $newKey);566 441 my $nsUsed = $exifTool->{XMP_NS}; 442 my $prop; 567 443 foreach $prop (@propList) { 568 444 my ($ns, $tag) = $prop =~ /(.+?):(.*)/; … … 585 461 586 462 #------------------------------------------------------------------------------ 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 467 sub 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 501 sub 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 #------------------------------------------------------------------------------ 587 523 # sort tagInfo hash references by tag name 588 524 sub ByTagName 589 525 { 590 526 return $$a{Name} cmp $$b{Name}; 527 } 528 529 #------------------------------------------------------------------------------ 530 # sort alphabetically, but with rdf:type first in the structure 531 sub 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) 547 sub 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 591 588 } 592 589 … … 599 596 # Notes: May set dirInfo InPlace flag to rewrite with specified DirLen 600 597 # 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 601 601 sub WriteXMP($$;$) 602 602 { … … 604 604 $exifTool or return 1; # allow dummy access to autoload this package 605 605 my $dataPt = $$dirInfo{DataPt}; 606 my $dirStart = $$dirInfo{DirStart} || 0; 607 my (%capture, %nsUsed, $xmpErr, $uuid); 606 my (%capture, %nsUsed, $xmpErr, $tagInfo, $about); 608 607 my $changed = 0; 609 608 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'); 611 611 my $verbose = $exifTool->Options('Verbose'); 612 my $dirLen = $$dirInfo{DirLen}; 613 $dirLen = length($$dataPt) if not defined $dirLen and $dataPt; 612 614 # 613 615 # extract existing XMP information into %capture hash … … 621 623 $exifTool->{XMP_CAPTURE} = \%capture; 622 624 $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) { 625 631 delete $exifTool->{XMP_ERROR}; 626 delete $exifTool->{XMP_ UUID};632 delete $exifTool->{XMP_ABOUT}; 627 633 # extract all existing XMP information (to the XMP_CAPTURE hash) 628 634 my $success = ProcessXMP($exifTool, $dirInfo, $tagTablePtr); … … 649 655 } 650 656 } 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 } 652 670 delete $exifTool->{XMP_ERROR}; 653 delete $exifTool->{XMP_ UUID};671 delete $exifTool->{XMP_ABOUT}; 654 672 } 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); 657 736 # 658 737 # add, delete or change information as specified … … 661 740 # (sorted by tag name so alternate languages come last) 662 741 my @tagInfoList = sort ByTagName $exifTool->GetNewTagInfoList(); 663 my $tagInfo;664 742 foreach $tagInfo (@tagInfoList) { 665 743 next unless $exifTool->GetGroup($tagInfo, 0) eq 'XMP'; 666 my $tag = $ tagInfo->{TagID};744 my $tag = $$tagInfo{TagID}; 667 745 my $path = GetPropertyPath($tagInfo); 668 746 unless ($path) { … … 670 748 next; 671 749 } 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}; 672 756 # change our property path namespace prefixes to conform 673 757 # to the ones used in this file 674 758 $path = ConformPathToNamespace($exifTool, $path); 675 759 # 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); 684 816 my $writable = $$tagInfo{Writable} || ''; 685 817 my (%attrs, $deleted, $added); 686 818 # 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) { 688 823 # take attributes from old values if they exist 689 %attrs = %{$ capList->[1]};824 %attrs = %{$$cap[1]}; 690 825 if ($overwrite) { 691 my ($delPath, @matchingPaths, $oldLang, $delLang);826 my ($delPath, $oldLang, $delLang, $addLang, @matchingPaths); 692 827 # check to see if this is an indexed list item 693 828 if ($path =~ / /) { 694 my $p athPattern;695 ($p athPattern = $path) =~ s/ 000/ \\d\{3\}/g;696 @matchingPaths = sort grep(/^$p athPattern$/, keys %capture);829 my $pp; 830 ($pp = $path) =~ s/ \d+/ \\d\+/g; 831 @matchingPaths = sort grep(/^$pp$/, keys %capture); 697 832 } else { 698 833 push @matchingPaths, $path; … … 700 835 foreach $path (@matchingPaths) { 701 836 my ($val, $attrs) = @{$capture{$path}}; 702 if ($overwrite < 0) {703 # only overwrite specific values704 next unless Image::ExifTool::IsOverwriting($newValueHash, $val);705 }706 837 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 } 707 842 # get original language code (lc for comparisons) 708 843 $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 710 853 # (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}) { 714 855 $delLang = 1; # delete all languages 715 856 $overwrite = 1; # force overwrite 716 } 717 if ($$tagInfo{LangCode} and not $delLang) { 857 } elsif ($$tagInfo{LangCode} and not $delLang) { 718 858 # only overwrite specified language 719 859 next unless lc($$tagInfo{LangCode}) eq $oldLang; 720 860 } 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)); 721 865 } 722 866 if ($verbose > 1) { … … 725 869 $tagName =~ s/-$$tagInfo{LangCode}$// if $$tagInfo{LangCode}; 726 870 $tagName .= '-' . $$attrs{'xml:lang'} if $$attrs{'xml:lang'}; 727 $exifTool->V Print(1, " - $grp:$tagName = '$val'\n");871 $exifTool->VerboseValue("- $grp:$tagName", $val); 728 872 } 729 873 # save attributes and path from first deleted property … … 733 877 $delPath = $path; 734 878 } 879 # delete this tag 735 880 delete $capture{$path}; 736 881 ++$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; 739 890 if ($delPath) { 740 891 $path = $delPath; … … 744 895 # unless this is a list or an lang-alt tag 745 896 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; 747 899 $added = $1; 748 900 } 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 } 751 910 } 752 911 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 } 758 940 } 759 941 } … … 761 943 # check to see if we want to create this tag 762 944 # (create non-avoided tags in XMP data files by default) 763 my $isCreating = (Image::ExifTool::IsCreating($n ewValueHash)or945 my $isCreating = (Image::ExifTool::IsCreating($nvHash) or $isStruct or 764 946 ($preferred and not $$tagInfo{Avoid} and 765 not defined $$n ewValueHash{Shift}));947 not defined $$nvHash{Shift})); 766 948 767 949 # don't add new values unless... … … 769 951 next unless $deleted or defined $added or 770 952 # ...tag didn't exist before and we are creating it 771 (not $cap Listand $isCreating);953 (not $cap and $isCreating); 772 954 773 955 # get list of new values (all done if no new values specified) 774 my @newValues = Image::ExifTool::GetNewValues($n ewValueHash) or next;956 my @newValues = Image::ExifTool::GetNewValues($nvHash) or next; 775 957 776 958 # 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 } 783 975 if ($verbose > 1) { 784 my $tagName = $$tagInfo{Name};785 $tagName =~ s/-$$tagInfo{LangCode}$/-x-default/;786 976 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 } 802 985 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; 811 1002 } 812 1003 } … … 815 1006 delete $exifTool->{XMP_NS}; 816 1007 1008 my $maxDataLen = $$dirInfo{MaxDataLen}; 1009 # get DataPt again because it may have been set by ProcessXMP 1010 $dataPt = $$dirInfo{DataPt}; 817 1011 # 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 { 819 1015 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) 831 1021 # 832 1022 # start writing the XMP data … … 842 1032 843 1033 # 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; 850 1075 my @propList = split('/',$path); # get property list 851 1076 # must open/close rdf:Description too 852 1077 unshift @propList, $rdfDesc; 853 1078 # make sure we have defined all necessary namespaces 854 my (%nsNew, $newDesc);855 1079 foreach $prop (@propList) { 856 1080 $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; 867 1088 # need a new description if any new namespaces 868 1089 $newDesc = 1 unless $nsCur{$1}; … … 871 1092 if ($newDesc) { 872 1093 # 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) 875 1097 my ($path2, $ns2); 876 1098 foreach $path2 (@pathList) { … … 880 1102 next if $ns2 eq 'rdf'; 881 1103 $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 885 1108 } 886 1109 last unless $opening; … … 899 1122 } 900 1123 if ($newDesc) { 1124 # save rdf:Description start positions so we can reorder them if necessary 1125 push @descStart, length($newData) if $maxDataLen; 901 1126 # open the new description 902 1127 $prop = $rdfDesc; 903 1128 %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) { 906 1137 $newData .= "\n xmlns:$_='$nsCur{$_}'"; 907 1138 } … … 910 1141 } 911 1142 # loop over all values for this new property 912 my $capList = $capture{$path}; 913 my ($val, $attrs) = @$capList; 1143 my ($val, $attrs) = @{$capture{$path}}; 914 1144 $debug and print "$path = $val\n"; 915 1145 # open new properties … … 921 1151 $prop =~ s/ .*//; 922 1152 $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 { 924 1156 # need parseType='Resource' to avoid new 'rdf:Description' 925 1157 $attr = " rdf:parseType='Resource'"; … … 927 1159 $newData .= (' ' x scalar(@curPropList)) . "<$prop$attr>\n"; 928 1160 } 929 my $prop2 = pop @propList; 930 $prop2 =~ s/ .*//; # remove list index if it exists1161 my $prop2 = pop @propList; # get new property name 1162 $prop2 =~ s/ .*//; # remove list index if it exists 931 1163 $newData .= (' ' x scalar(@curPropList)) . " <$prop2"; 932 # printout attributes1164 # write out attributes 933 1165 foreach $attr (sort keys %$attrs) { 934 1166 my $attrVal = $$attrs{$attr}; … … 936 1168 $newData .= " $attr=$quot$attrVal$quot"; 937 1169 } 938 $newData .= ">$val</$prop2>\n";1170 $newData .= length $val ? ">$val</$prop2>\n" : "/>\n"; 939 1171 } 940 1172 # close off any open elements … … 943 1175 $newData .= (' ' x scalar(@curPropList)) . " </$prop>\n"; 944 1176 } 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 948 1196 # remove the ExifTool members we created 949 1197 delete $exifTool->{XMP_CAPTURE}; 950 1198 delete $exifTool->{XMP_NS}; 951 952 $newData .= $rdfClose . $xmpClose; 1199 delete $exifTool->{XMP_NO_XMPMETA}; 953 1200 954 1201 # (the XMP standard recommends writing 2k-4k of white space before the … … 958 1205 if ($$dirInfo{InPlace}) { 959 1206 # pad to specified DirLen 960 my $dirLen = $$dirInfo{DirLen} || length $$dataPt;961 1207 my $len = length($newData) + length($pktCloseW); 962 1208 if ($len > $dirLen) { … … 970 1216 } 971 1217 $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; 976 1220 } 977 1221 $newData .= ($$dirInfo{ReadOnly} ? $pktCloseR : $pktCloseW); 978 1222 } 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 } 982 1227 if ($xmpErr) { 983 1228 if ($xmpFile) { … … 991 1236 $debug > 1 and $newData and print $newData,"\n"; 992 1237 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; 995 1240 } 996 1241 … … 1014 1259 =head1 AUTHOR 1015 1260 1016 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1261 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 1017 1262 1018 1263 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Writer.pl
r16842 r24107 23 23 sub RemoveNewValueHash($$$); 24 24 sub RemoveNewValuesForGroup($$); 25 sub GetWriteGroup1($$); 26 sub Sanitize($$); 27 sub ConvInv($$$$$;$$); 25 28 26 29 my $loadedAllTables; # flag indicating we loaded all tables … … 42 45 InteropIFD => 'ExifIFD', 43 46 MakerNotes => 'ExifIFD', 47 CanonVRD => 'MakerNotes', # (so VRDOffset will get updated) 48 NikonCapture => 'MakerNotes', # (to allow delete by group) 49 ); 50 my %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) 44 62 ); 45 63 my %jpegMap = ( 64 %exifMap, # covers all JPEG EXIF mappings 46 65 JFIF => 'APP0', 47 66 CIFF => 'APP0', … … 55 74 Ducky => 'APP12', 56 75 Photoshop => 'APP13', 57 IFD1 => 'IFD0',58 EXIF => 'IFD0', # to write EXIF as a block59 ExifIFD => 'IFD0',60 GPS => 'IFD0',61 SubIFD => 'IFD0',62 GlobParamIFD => 'IFD0',63 PrintIM => 'IFD0',64 76 IPTC => 'Photoshop', 65 InteropIFD => 'ExifIFD',66 77 MakerNotes => ['ExifIFD', 'CIFF'], # (first parent is the default) 78 CanonVRD => 'MakerNotes', # (so VRDOffset will get updated) 79 NikonCapture => 'MakerNotes', # (to allow delete by group) 67 80 Comment => 'COM', 68 81 ); … … 72 85 ORF => \%tiffMap, 73 86 RAW => \%tiffMap, 87 EXIF => \%exifMap, 74 88 ); 75 89 … … 81 95 AFCP CanonVRD CIFF Ducky EXIF ExifIFD File FlashPix FotoStation GlobParamIFD 82 96 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-* 84 99 ); 85 100 # other group names of new tag values to remove when deleting an entire group … … 114 129 my %translateWriteGroup = ( 115 130 EXIF => 'ExifIFD', 131 Meta => 'MetaIFD', 116 132 File => 'Comment', 117 133 MIE => 'MIE', 118 134 ); 119 # names of valid EXIF directories:135 # names of valid EXIF and Meta directories: 120 136 my %exifDirs = ( 121 137 gps => 'GPS', … … 125 141 interopifd => 'InteropIFD', 126 142 makernotes => 'MakerNotes', 143 previewifd => 'PreviewIFD', # (in MakerNotes) 144 metaifd => 'MetaIFD', # Kodak APP3 Meta 127 145 ); 128 146 # min/max values for integer formats … … 131 149 'int8s' => [-0x80, 0x7f], 132 150 'int16u' => [0, 0xffff], 151 'int16uRev' => [0, 0xffff], 133 152 'int16s' => [-0x8000, 0x7fff], 134 153 'int32u' => [0, 0xffffffff], 135 154 'int32s' => [-0x80000000, 0x7fffffff], 136 155 ); 137 my $maxSegmentLen = 0xfffd; # maximum length of data in a JPEG segment 156 # lookup for file types with block-writable EXIF 157 my %blockExifTypes = ( JPEG=>1, PNG=>1, JP2=>1, MIE=>1, EXIF=>1 ); 158 159 my $maxSegmentLen = 0xfffd; # maximum length of data in a JPEG segment 160 my $maxXMPLen = $maxSegmentLen; # maximum length of XMP data in JPEG 138 161 139 162 # value separators when conversion list is used (in SetNewValue) 140 163 my %listSep = ( PrintConv => '; ?', ValueConv => ' ' ); 164 165 # printConv hash keys to ignore when doing reverse lookup 166 my %ignorePrintConv = ( OTHER => 1, BITMASK => 1, Notes => 1 ); 141 167 142 168 #------------------------------------------------------------------------------ … … 153 179 # Replace => 0, 1 or 2 - overwrite previous new values (2=reset) 154 180 # 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) 155 183 # Shift => undef, 0, +1 or -1 - shift value if possible 156 184 # NoShortcut => true to prevent looking up shortcut tags 157 185 # 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 158 188 # Returns: number of tags set (plus error string in list context) 159 189 # Notes: For tag lists (like Keywords), call repeatedly with the same tag name for 160 190 # 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: 162 192 # TagInfo - tag info ref 163 193 # DelValue - list ref for values to delete 164 194 # Value - list ref for values to add 165 # IsCreating - must be set for the tag to be added .otherwise just166 # 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 167 197 # CreateGroups - hash of all family 0 group names where tag may be created 168 198 # WriteGroup - group name where information is being written (correct case) 169 199 # WantGroup - group name as specified in call to function (case insensitive) 170 # Next - pointer to next new ValueHash (if more than one)200 # Next - pointer to next new value hash (if more than one) 171 201 # Self - ExifTool object reference 172 202 # Shift - shift value … … 177 207 my ($self, $tag, $value, %options) = @_; 178 208 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}; 181 211 my $protected = $options{Protected} || 0; 212 my $listOnly = $options{ListOnly}; 213 my $setTags = $options{SetTags}; 182 214 my $numSet = 0; 215 183 216 unless (defined $tag) { 184 217 # remove any existing set values … … 191 224 if (ref $value) { 192 225 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}; 193 229 foreach (@$value) { 194 my ($n, $e) = SetNewValue($self, $tag, $_, %options );230 my ($n, $e) = SetNewValue($self, $tag, $_, %options, ListOnly => 1); 195 231 $err = $e if $e; 196 232 $numSet += $n; 197 233 delete $options{Replace}; # don't replace earlier values in list 198 234 } 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; 202 239 } elsif (ref $value eq 'SCALAR') { 203 240 $value = $$value; 204 241 } 205 242 } 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 213 247 # set group name in options if specified 214 if ($tag =~ /(. +?):(.+)/) {248 if ($tag =~ /(.*):(.+)/) { 215 249 $options{Group} = $1 if $1 ne '*' and lc($1) ne 'all'; 216 250 $tag = $2; 217 251 } 252 # allow trailing '#' for ValueConv value 253 $options{Type} = 'ValueConv' if $tag =~ s/#$//; 218 254 # ignore leading family number if 0 or 1 specified 219 255 if ($options{Group} and $options{Group} =~ /^(\d+)(.*)/ and $1 < 2) { … … 235 271 my $remove = ($options{Replace} and $options{Replace} > 1); 236 272 if ($wantGroup) { 237 @del = grep /^$wantGroup$/i, @delGroups ;273 @del = grep /^$wantGroup$/i, @delGroups unless $wantGroup =~ /^XM[LP]-\*$/i; 238 274 # remove associated groups when excluding from mass delete 239 275 if (@del and $remove) { … … 253 289 } 254 290 } 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; 257 294 } else { 258 295 # 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), '*'; 260 297 } 261 298 if (@del) { 262 299 ++$numSet; 263 300 my @donegrps; 301 my $delGroup = $self->{DEL_GROUP}; 264 302 foreach $grp (@del) { 265 303 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 } 268 330 } 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 } 270 337 # remove all of this group from previous new values 271 338 $self->RemoveNewValuesForGroup($grp); … … 287 354 # allow language suffix of form "-en_CA" or "-<rfc3066>" on tag name 288 355 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 290 357 { 291 358 $tag = $1; 359 # normalize case of language codes 292 360 $langCode = lc($2); 293 361 $langCode .= (length($3) == 3 ? uc($3) : lc($3)) if $3; … … 296 364 # only allow language codes in tables which support them 297 365 next unless $$tagInfo{Table}; 298 my $langInfoProc = $tagInfo->{Table} ->{LANG_INFO} or next;366 my $langInfoProc = $tagInfo->{Table}{LANG_INFO} or next; 299 367 my $langInfo = &$langInfoProc($tagInfo, $langCode); 300 368 push @matchingTags, $langInfo if $langInfo; … … 308 376 if ($match and not $options{NoShortcut}) { 309 377 if (@{$Image::ExifTool::Shortcuts::Main{$match}} == 1) { 310 $tag = $Image::ExifTool::Shortcuts::Main{$match} ->[0];378 $tag = $Image::ExifTool::Shortcuts::Main{$match}[0]; 311 379 @matchingTags = FindTagInfo($tag); 312 380 last if @matchingTags; … … 319 387 } 320 388 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; 322 392 } 323 393 } … … 335 405 $verbose > 2 and print $out "$err\n"; 336 406 } 337 goto ReturnNow; # all done 407 # all done 408 return ($numSet, $err) if wantarray; 409 $err and warn "$err\n"; 410 return $numSet; 338 411 } 339 412 # get group name that we're looking for … … 346 419 } elsif ($wantGroup =~ /^SubIFD(\d+)$/i) { 347 420 $ifdName = "SubIFD$1"; 421 } elsif ($wantGroup =~ /^Version(\d+)$/i) { 422 $ifdName = "Version$1"; # Sony IDC VersionIFD 348 423 } elsif ($wantGroup =~ /^MIE(\d*-?)(\w+)$/i) { 349 424 $mieGroup = "MIE$1" . ucfirst(lc($2)); 350 425 } else { 351 426 $ifdName = $exifDirs{lc($wantGroup)}; 352 if ( $wantGroup =~ /^XMP\b/i) {427 if (not $ifdName and $wantGroup =~ /^XMP\b/i) { 353 428 # must load XMP table to set group1 names 354 429 my $table = GetTagTable('Image::ExifTool::XMP::Main'); … … 362 437 # the highest priority group 363 438 # 364 my (@tagInfoList, %writeGroup, %preferred, %tagPriority, $avoid, $wasProtected);439 my (@tagInfoList, @writeAlsoList, %writeGroup, %preferred, %tagPriority, $avoid, $wasProtected); 365 440 my $highestPriority = -1; 366 441 foreach $tagInfo (@matchingTags) { … … 372 447 $writeGroup = $self->GetGroup($tagInfo, 0); 373 448 unless (lc($writeGroup) eq $lcWant) { 374 if ($writeGroup eq 'EXIF' ) {449 if ($writeGroup eq 'EXIF' or $writeGroup eq 'SonyIDC') { 375 450 next unless $ifdName; 451 # can't yet write PreviewIFD tags 452 $ifdName eq 'PreviewIFD' and ++$foundMatch, next; 376 453 $writeGroup = $ifdName; # write to the specified IFD 377 454 } elsif ($writeGroup eq 'MIE') { … … 379 456 $writeGroup = $mieGroup; # write to specific MIE group 380 457 # 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}; 383 460 $writeGroup =~ s/^MIE/$mieGroup/; 384 461 } 385 } els e{462 } elsif (not $$tagInfo{AllowGroup} or $wantGroup !~ /^$$tagInfo{AllowGroup}$/i) { 386 463 # allow group1 name to be specified 387 464 my $grp1 = $self->GetGroup($tagInfo, 1); 388 465 unless ($grp1 and lc($grp1) eq $lcWant) { 389 466 # must also check group1 name directly in case it is different 390 $grp1 = $tagInfo->{Groups} ->{1};467 $grp1 = $tagInfo->{Groups}{1}; 391 468 next unless $grp1 and lc($grp1) eq $lcWant; 392 469 } … … 400 477 my $table = $tagInfo->{Table}; 401 478 my $writeProc = $table->{WRITE_PROC}; 402 # load parenttable if this was a user-defined table403 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; 406 483 } 407 484 next unless $writeProc and &$writeProc(); … … 410 487 next unless $writable or ($table->{WRITABLE} and 411 488 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 } 412 504 # don't write tag if protected 413 505 if ($tagInfo->{Protected}) { … … 416 508 my %lkup = ( 1=>'unsafe', 2=>'protected', 3=>'unsafe and protected'); 417 509 $wasProtected = $lkup{$prot}; 510 if ($verbose > 1) { 511 my $wgrp1 = $self->GetWriteGroup1($tagInfo, $writeGroup); 512 print $out "Not writing $wgrp1:$tag ($wasProtected)\n"; 513 } 418 514 next; 419 515 } 420 516 } 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 436 518 $tagPriority{$tagInfo} = $priority; 437 519 if ($priority > $highestPriority) { … … 445 527 ++$avoid if $$tagInfo{Avoid}; 446 528 } 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 } 448 535 $writeGroup{$tagInfo} = $writeGroup; 449 536 } 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 450 543 # don't create tags with priority 0 if group priorities are set 451 544 if ($highestPriority == 0 and %{$self->{WRITE_PRIORITY}}) { … … 487 580 # generate new value hash for each tag 488 581 # 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 end492 @tagInfoList = sort { $tagPriority{$a} <=> $tagPriority{$b} } @tagInfoList; 582 my ($prioritySet, $createGroups, %alsoWrote); 583 584 delete $$self{CHECK_WARN}; # reset CHECK_PROC warnings 585 493 586 # 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; 495 592 my $writeGroup = $writeGroup{$tagInfo}; 496 593 my $permanent = $$tagInfo{Permanent}; 497 594 $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); 504 596 $tag = $tagInfo->{Name}; # get proper case for tag name 505 597 my $shift = $options{Shift}; 506 598 if (defined $shift) { 507 if ($tagInfo->{Shift}) { 599 # (can't currently shift List-type tags) 600 if ($tagInfo->{Shift} and not $tagInfo->{List}) { 508 601 unless ($shift) { 509 602 # set shift according to AddValue/DelValue 510 603 $shift = 1 if $options{AddValue}; 511 604 $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; 512 612 } 513 613 } elsif ($shift) { … … 525 625 next; 526 626 } 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); 653 633 if ($err2) { 654 634 $err = "$err2 for $wgrp1:$tag"; 655 635 $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 } 659 688 } 660 689 } … … 680 709 } 681 710 682 # set value in NEW_VALUE hash683 711 if (defined $val) { 684 712 # we are editing this tag, so create a NEW_VALUE hash entry 685 my $n ewValueHash = $self->GetNewValueHash($tagInfo, $writeGroup, 'create');686 $n ewValueHash->{WantGroup} = $wantGroup;713 my $nvHash = $self->GetNewValueHash($tagInfo, $writeGroup, 'create'); 714 $nvHash->{WantGroup} = $wantGroup; 687 715 # save maker note information if writing maker notes 688 716 if ($$tagInfo{MakerNotes}) { 689 $n ewValueHash->{MAKER_NOTE_FIXUP} = $self->{MAKER_NOTE_FIXUP};717 $nvHash->{MAKER_NOTE_FIXUP} = $self->{MAKER_NOTE_FIXUP}; 690 718 } 691 719 if ($options{DelValue} or $options{AddValue} or $shift) { 692 720 # flag any AddValue or DelValue by creating the DelValue list 693 $n ewValueHash->{DelValue} or $newValueHash->{DelValue} = [ ];721 $nvHash->{DelValue} or $nvHash->{DelValue} = [ ]; 694 722 if ($shift) { 695 723 # add shift value to list 696 $n ewValueHash->{Shift} = $val;724 $nvHash->{Shift} = $val; 697 725 } elsif ($options{DelValue}) { 698 726 # don't create if we are replacing a specific value 699 $n ewValueHash->{IsCreating} = 0 unless $val eq '';727 $nvHash->{IsCreating} = 0 unless $val eq '' or $tagInfo->{List}; 700 728 # add delete value to list 701 push @{$n ewValueHash->{DelValue}},$val;729 push @{$nvHash->{DelValue}}, ref $val eq 'ARRAY' ? @$val : $val; 702 730 if ($verbose > 1) { 703 731 my $verb = $permanent ? 'Replacing' : 'Deleting'; 704 732 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 } 706 741 } 707 742 } … … 710 745 # (will only create the priority tag if it doesn't exist, 711 746 # others get changed only if they already exist) 712 if ($preferred{$tagInfo} or $tagInfo->{Table} ->{PREFERRED}) {747 if ($preferred{$tagInfo} or $tagInfo->{Table}{PREFERRED}) { 713 748 if ($permanent or $shift) { 714 749 # don't create permanent or Shift-ed tag but define IsCreating 715 750 # 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 718 754 # also create tag if any DelValue value is empty ('') 719 grep(/^$/,@{$n ewValueHash->{DelValue}}))755 grep(/^$/,@{$nvHash->{DelValue}})) 720 756 { 721 $n ewValueHash->{IsCreating} = 1;757 $nvHash->{IsCreating} = $options{EditOnly} ? 0 : ($options{EditGroup} ? 2 : 1); 722 758 # add to hash of groups where this tag is being created 723 759 $createGroups or $createGroups = $options{CreateGroups} || { }; 724 760 $$createGroups{$self->GetGroup($tagInfo, 0)} = 1; 725 $n ewValueHash->{CreateGroups} = $createGroups;726 } 727 } 728 if (%{$self->{DEL_GROUP}} and $n ewValueHash->{IsCreating}) {761 $nvHash->{CreateGroups} = $createGroups; 762 } 763 } 764 if (%{$self->{DEL_GROUP}} and $nvHash->{IsCreating}) { 729 765 my ($grp, @grps); 730 766 foreach $grp (keys %{$self->{DEL_GROUP}}) { 731 next if $self->{DEL_GROUP} ->{$grp} == 2;767 next if $self->{DEL_GROUP}{$grp} == 2; 732 768 # set flag indicating tags were written after this group was deleted 733 $self->{DEL_GROUP} ->{$grp} = 2;769 $self->{DEL_GROUP}{$grp} = 2; 734 770 push @grps, $grp; 735 771 } … … 740 776 } 741 777 if ($shift or not $options{DelValue}) { 742 $n ewValueHash->{Value} or $newValueHash->{Value} = [ ];743 if ( $tagInfo->{List}) {744 # we can write a list of entries745 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; 746 782 } else { 747 # not a List tag -- overwrite existing value748 $newValueHash->{Value}->[0] =$val;783 # add to existing list 784 push @{$nvHash->{Value}}, ref $val eq 'ARRAY' ? @$val : $val; 749 785 } 750 786 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'); 752 791 my $verb = ($shift ? 'Shifting' : ($options{AddValue} ? 'Adding' : 'Writing')); 753 792 print $out "$verb $wgrp1:$tag$ifExists\n"; … … 755 794 } 756 795 } elsif ($permanent) { 757 $err = "Can't delete $ tag";796 $err = "Can't delete $wgrp1:$tag"; 758 797 $verbose > 1 and print $out "$err\n"; 759 798 next; … … 764 803 # create empty new value hash entry to delete this tag 765 804 $self->GetNewValueHash($tagInfo, $writeGroup, 'delete'); 766 my $n ewValueHash = $self->GetNewValueHash($tagInfo, $writeGroup, 'create');767 $n ewValueHash->{WantGroup} = $wantGroup;805 my $nvHash = $self->GetNewValueHash($tagInfo, $writeGroup, 'create'); 806 $nvHash->{WantGroup} = $wantGroup; 768 807 $verbose > 1 and print $out "Deleting $wgrp1:$tag\n"; 769 808 } 770 809 ++$numSet; 810 $$setTags{$tagInfo} = 1 if $setTags; 771 811 $prioritySet = 1 if $preferred{$tagInfo}; 812 WriteAlso: 772 813 # also write related tags 773 814 my $writeAlso = $$tagInfo{WriteAlso}; 774 815 if ($writeAlso) { 775 my $wtag; 816 my ($wtag, $n); 817 local $SIG{'__WARN__'} = \&SetWarning; 776 818 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; 777 828 #### eval WriteAlso ($val) 778 829 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 } 785 846 } 786 847 } 787 848 } 788 849 # print warning if we couldn't set our priority tag 789 if ( $err and not $prioritySet) {790 warn "$err\n" unlesswantarray;850 if (defined $err and not $prioritySet) { 851 warn "$err\n" if $err and not wantarray; 791 852 } elsif (not $numSet) { 792 my $pre = $wantGroup ? "$wantGroup:": '';853 my $pre = $wantGroup ? ($ifdName || $wantGroup) . ':' : ''; 793 854 if ($wasProtected) { 794 855 $err = "Tag '$pre$tag' is $wasProtected for writing"; … … 800 861 $verbose > 2 and print $out "$err\n"; 801 862 warn "$err\n" unless wantarray; 863 } elsif ($$self{CHECK_WARN}) { 864 $err = $$self{CHECK_WARN}; 865 $verbose > 2 and print $out "$err\n"; 802 866 } elsif ($err and not $verbose) { 803 867 undef $err; … … 810 874 # set new values from information in specified file 811 875 # 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 813 880 # 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). 818 886 sub SetNewValuesFromFile($$;@) 819 887 { 888 local $_; 820 889 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 } 822 900 # expand shortcuts 823 901 @setTags and ExpandShortcuts(\@setTags); … … 825 903 my $options = $self->{OPTIONS}; 826 904 # 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 # +------------------------------------------+ 827 910 $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, 828 928 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}, 832 933 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}, 839 936 ); 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 840 947 # get all tags from source file (including MakerNotes block) 841 948 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 later949 return $info if $$info{Error} and $$info{Error} eq 'Error opening file'; 950 delete $srcExifTool->{VALUE}{Error}; # delete so we can check this later 844 951 845 952 # sort tags in reverse order so we get priority tag last … … 854 961 $self->{MAKER_NOTE_BYTE_ORDER} = $srcExifTool->{MAKER_NOTE_BYTE_ORDER}; 855 962 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 } 858 969 # 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); 860 971 # delete this tag if we could't set it 861 $n or delete $ info->{$tag};972 $n or delete $$info{$tag}; 862 973 } 863 974 return $info; … … 869 980 my (@setList, $set, %setMatches); 870 981 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); 873 994 # handle redirection to another tag 874 995 if ($tag =~ /(.+?)\s*(>|<)\s*(.+)/) { 875 996 $dstGrp = ''; 997 my $opt; 876 998 if ($2 eq '>') { 877 999 ($tag, $dstTag) = ($1, $3); … … 885 1007 $tag = $_; # restore original case 886 1008 # recover leading whitespace (except for initial single space) 887 # and flag expression by starting with '@'888 $ tag =~ s/(.+?)\s*(>|<) ?/\@/;889 $ expr = 1; # flag this expression1009 $tag =~ s/(.+?)\s*(>|<) ?//; 1010 $$opts{EXPR} = 1; # flag this expression 1011 $grp = ''; 890 1012 } else { 891 1013 $opt = $1 if $tag =~ s/^([-+])\s*//; … … 893 1015 } 894 1016 # 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/#$//; 898 1024 # ignore leading family number 899 1025 $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 } 909 1053 } 910 1054 # redirect, exclude or set this tag (Note: $grp is '' if we don't care) … … 912 1056 # redirect this tag 913 1057 $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 } 916 1068 } 917 1069 # 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; 919 1072 # write to specified destination group/tag 920 1073 $dst = [ $dstGrp, $dstTag ]; 921 1074 } elsif ($isExclude) { 922 1075 # implicitly assume '*' if first entry is an exclusion 923 unshift @setList, [ undef, '*', '*', [ '', '*' ] ] unless @setList;1076 unshift @setList, [ undef, '*', '*', [ '', '*' ], $opts ] unless @setList; 924 1077 # exclude this tag by leaving $dst undefined 925 1078 } else { 926 # copy to same group/tag 927 $dst = [ $grp, $tag ]; 1079 $dst = [ $grp, $$opts{WILD} ? '*' : $tag ]; # copy to same group 928 1080 } 929 1081 $grp or $grp = '*'; # use '*' for any group 930 1082 # 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 condition1083 unshift @setList, [ $fam, $grp, $tag, $dst, $opts ]; 1084 } 1085 # 2) initialize lists of matching tags for each setTag 934 1086 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 condition1087 $$set[3] and $setMatches{$set} = [ ]; 1088 } 1089 # 3) loop through all tags in source image and save tags matching each setTag 938 1090 my %rtnInfo; 939 1091 foreach $tag (@tags) { 940 # don't try to set Warning's or Error's941 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}; 943 1095 next; 944 1096 } 945 my @dstList;946 1097 # only set specified tags 947 1098 my $lcTag = lc(GetTagName($tag)); 948 my @grp;1099 my (@grp, %grp); 949 1100 foreach $set (@setList) { 950 1101 # 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 } 952 1106 # then check for matching group 953 1107 unless ($$set[1] eq '*') { 954 1108 # 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 } 956 1113 # handle leading family number 957 1114 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]]; 959 1116 } else { 960 next unless $ $set[1] eq $grp[0] or $$set[1] eq $grp[1];1117 next unless $grp{$$set[1]}; 961 1118 } 962 1119 } 963 1120 last unless $$set[3]; # all done if we hit an exclude 964 # add to the list of tags matching this condition1121 # add to the list of tags matching this setTag 965 1122 push @{$setMatches{$set}}, $tag; 966 1123 } 967 1124 } 968 # 4) loop through each conditionin original order, setting new tag values1125 # 4) loop through each setTag in original order, setting new tag values 969 1126 foreach $set (reverse @setList) { 1127 # get options for SetNewValue 1128 my $opts = $$set[4]; 970 1129 # handle expressions 971 if ($$ set[2] =~ s/^\@//) {1130 if ($$opts{EXPR}) { 972 1131 my $val = $srcExifTool->InsertTagValues(\@tags, $$set[2], 'Error'); 973 1132 unless (defined $val) { … … 975 1134 $tag = NextTagKey(\%rtnInfo, 'Warning'); 976 1135 $rtnInfo{$tag} = $srcExifTool->GetValue('Error'); 977 delete $srcExifTool->{VALUE} ->{Error};1136 delete $srcExifTool->{VALUE}{Error}; 978 1137 next; 979 1138 } 980 1139 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); 986 1143 $rtnInfo{$dstTag} = $val if $rtnVals[0]; # tag was set successfully 987 1144 next; 988 1145 } 989 1146 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}); 996 1150 } else { 997 @values = ( $info->{$tag} );1151 $val = $$info{$tag}; 998 1152 } 999 1153 my ($dstGrp, $dstTag) = @{$$set[3]}; … … 1003 1157 $noWarn = 1; # don't warn on wildcard destinations 1004 1158 } 1005 $opts{Group} = $dstGrp; 1159 $$opts{Group} = $dstGrp; 1160 } else { 1161 delete $$opts{Group}; 1006 1162 } 1007 1163 # transfer maker note information if setting this tag 1008 if ($srcExifTool->{TAG_INFO} ->{$tag}->{MakerNotes}) {1164 if ($srcExifTool->{TAG_INFO}{$tag}{MakerNotes}) { 1009 1165 $self->{MAKER_NOTE_FIXUP} = $srcExifTool->{MAKER_NOTE_FIXUP}; 1010 1166 $self->{MAKER_NOTE_BYTE_ORDER} = $srcExifTool->{MAKER_NOTE_BYTE_ORDER}; … … 1014 1170 $noWarn = 1; 1015 1171 } 1016 # add or delete value if specified1017 $opts{$$set[4]} = 1 if $$set[4];1018 1172 # 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 1033 1182 } 1034 1183 } … … 1038 1187 #------------------------------------------------------------------------------ 1039 1188 # Get new value(s) for tag 1040 # Inputs: 0) ExifTool object reference, 1) tag key, tag name,or tagInfo hash ref1189 # Inputs: 0) ExifTool object reference, 1) tag name or tagInfo hash ref 1041 1190 # 2) optional pointer to return new value hash reference (not part of public API) 1042 1191 # or 0) new value hash reference (not part of public API) … … 1044 1193 # Notes: 1) Preferentially returns new value from Extra table if writable Extra tag exists 1045 1194 # 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 1046 1196 sub GetNewValues($;$$) 1047 1197 { 1048 1198 local $_; 1049 my $n ewValueHash;1199 my $nvHash; 1050 1200 if (ref $_[0] eq 'HASH') { 1051 $n ewValueHash = shift;1201 $nvHash = shift; 1052 1202 } else { 1053 1203 my ($self, $tag, $newValueHashPt) = @_; 1054 1204 if ($self->{NEW_VALUE}) { 1055 my $tagInfo;1205 my ($group, $tagInfo); 1056 1206 if (ref $tag) { 1057 $n ewValueHash = $self->GetNewValueHash($tag);1207 $nvHash = $self->GetNewValueHash($tag); 1058 1208 } elsif (defined($tagInfo = $Image::ExifTool::Extra{$tag}) and 1059 1209 $$tagInfo{Writable}) 1060 1210 { 1061 $n ewValueHash = $self->GetNewValueHash($tagInfo);1211 $nvHash = $self->GetNewValueHash($tagInfo); 1062 1212 } else { 1213 # separate group from tag name 1214 $group = $1 if $tag =~ s/(.*)://; 1063 1215 my @tagInfoList = FindTagInfo($tag); 1064 # choose the one that we are creating1065 1216 # decide which tag we want 1217 GNV_TagInfo: foreach $tagInfo (@tagInfoList) { 1066 1218 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}; 1069 1235 } 1070 1236 } 1071 1237 } 1072 1238 # return new value hash if requested 1073 $newValueHashPt and $$newValueHashPt = $n ewValueHash;1074 } 1075 if ($n ewValueHash and $newValueHash->{Value}) {1076 my $vals = $n ewValueHash->{Value};1239 $newValueHashPt and $$newValueHashPt = $nvHash; 1240 } 1241 if ($nvHash and $nvHash->{Value}) { 1242 my $vals = $nvHash->{Value}; 1077 1243 # 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}; 1080 1248 my $conv = $$tagInfo{RawConvInv}; 1081 my $self = $n ewValueHash->{Self};1249 my $self = $nvHash->{Self}; 1082 1250 my ($val, $checkProc); 1083 1251 my $table = $tagInfo->{Table}; … … 1089 1257 $val = &$conv($val, $self); 1090 1258 } else { 1091 #### eval RawConvInv ($self, $val )1259 #### eval RawConvInv ($self, $val, $taginfo) 1092 1260 $val = eval $conv; 1093 1261 $@ and $evalWarning = $@; 1094 1262 } 1095 1263 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 } 1098 1269 @$vals = (); 1099 1270 last; … … 1111 1282 } 1112 1283 # 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]; 1118 1286 } 1119 1287 return () if wantarray; # return empty list … … 1132 1300 my $newVal = $self->{NEW_VALUE}; 1133 1301 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 } 1135 1310 $num += scalar keys %{$self->{DEL_GROUP}}; 1136 1311 return $num unless wantarray; 1137 1312 my $pseudo = 0; 1138 1313 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) 1141 1315 foreach $tag (qw{FileName Directory FileModifyDate}) { 1142 1316 ++$pseudo if defined $$newVal{$Image::ExifTool::Extra{$tag}}; … … 1155 1329 my $key; 1156 1330 foreach $key (keys %$newValues) { 1157 my $n ewValueHash = $$newValues{$key};1158 while ($n ewValueHash) {1159 $n ewValueHash->{Save} = 1; # set Save flag1160 $n ewValueHash = $newValueHash->{Next};1331 my $nvHash = $$newValues{$key}; 1332 while ($nvHash) { 1333 $nvHash->{Save} = 1; # set Save flag 1334 $nvHash = $nvHash->{Next}; 1161 1335 } 1162 1336 } 1163 1337 # initialize hash for saving overwritten new values 1164 1338 $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 } 1165 1346 } 1166 1347 … … 1169 1350 # Inputs: 0) ExifTool object reference 1170 1351 # Notes: Restores saved new values, but currently doesn't restore them in the 1171 # or ginal order, so there may be some minor side-effects when restoring tags1352 # original order, so there may be some minor side-effects when restoring tags 1172 1353 # with overlapping groups. ie) XMP:Identifier, XMP-dc:Identifier 1173 1354 sub RestoreNewValues($) … … 1182 1363 foreach $key (@keys) { 1183 1364 my $lastHash; 1184 my $n ewValueHash = $$newValues{$key};1185 while ($n ewValueHash) {1186 if ($n ewValueHash->{Save}) {1187 $lastHash = $n ewValueHash;1365 my $nvHash = $$newValues{$key}; 1366 while ($nvHash) { 1367 if ($nvHash->{Save}) { 1368 $lastHash = $nvHash; 1188 1369 } else { 1189 1370 # remove this entry from the list 1190 1371 if ($lastHash) { 1191 $lastHash->{Next} = $n ewValueHash->{Next};1192 } elsif ($n ewValueHash->{Next}) {1193 $$newValues{$key} = $n ewValueHash->{Next};1372 $lastHash->{Next} = $nvHash->{Next}; 1373 } elsif ($nvHash->{Next}) { 1374 $$newValues{$key} = $nvHash->{Next}; 1194 1375 } else { 1195 1376 delete $$newValues{$key}; 1196 1377 } 1197 1378 } 1198 $n ewValueHash = $newValueHash->{Next};1379 $nvHash = $nvHash->{Next}; 1199 1380 } 1200 1381 } … … 1206 1387 if ($$newValues{$key}) { 1207 1388 # add saved values to end of list 1208 my $n ewValueHash = LastInList($$newValues{$key});1209 $n ewValueHash->{Next} = $$savedValues{$key};1389 my $nvHash = LastInList($$newValues{$key}); 1390 $nvHash->{Next} = $$savedValues{$key}; 1210 1391 } else { 1211 1392 $$newValues{$key} = $$savedValues{$key}; … … 1213 1394 } 1214 1395 $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}; 1215 1403 } 1216 1404 } … … 1225 1413 { 1226 1414 my ($self, $file, $originalTime) = @_; 1227 my $n ewValueHash;1228 my $val = $self->GetNewValues('FileModifyDate', \$n ewValueHash);1415 my $nvHash; 1416 my $val = $self->GetNewValues('FileModifyDate', \$nvHash); 1229 1417 return 0 unless defined $val; 1230 my $isOverwriting = IsOverwriting($n ewValueHash);1418 my $isOverwriting = IsOverwriting($nvHash); 1231 1419 return 0 unless $isOverwriting; 1232 1420 if ($isOverwriting < 0) { # are we shifting time? … … 1234 1422 $originalTime = -M $file unless defined $originalTime; 1235 1423 return 0 unless defined $originalTime; 1236 return 0 unless IsOverwriting($n ewValueHash, $^T - $originalTime*(24*3600));1237 $val = $n ewValueHash->{Value}->[0]; # get shifted value1424 return 0 unless IsOverwriting($nvHash, $^T - $originalTime*(24*3600)); 1425 $val = $nvHash->{Value}[0]; # get shifted value 1238 1426 } 1239 1427 unless (utime($val, $val, $file)) { … … 1242 1430 } 1243 1431 ++$self->{CHANGED}; 1244 $self->V Print(1, " + FileModifyDate = '$val'\n");1432 $self->VerboseValue('+ FileModifyDate', $val); 1245 1433 return 1; 1246 1434 } … … 1256 1444 { 1257 1445 my ($self, $file, $newName) = @_; 1258 my ($n ewValueHash, $doName, $doDir);1446 my ($nvHash, $doName, $doDir); 1259 1447 # determine the new file name 1260 1448 unless (defined $newName) { 1261 my $filename = $self->GetNewValues('FileName', \$n ewValueHash);1262 $doName = 1 if defined $filename and IsOverwriting($n ewValueHash, $file);1263 my $dir = $self->GetNewValues('Directory', \$n ewValueHash);1264 $doDir = 1 if defined $dir and IsOverwriting($n ewValueHash, $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); 1265 1453 return 0 unless $doName or $doDir; # nothing to do 1266 1454 if ($doName) { … … 1287 1475 # attempt to rename the file 1288 1476 unless (rename $file, $newName) { 1477 local (*EXIFTOOL_SFN_IN, *EXIFTOOL_SFN_OUT); 1289 1478 # renaming didn't work, so copy the file instead 1290 1479 unless (open EXIFTOOL_SFN_IN, $file) { … … 1318 1507 } 1319 1508 ++$self->{CHANGED}; 1320 $self->V Print(1, " + FileName = '$newName'\n");1509 $self->VerboseValue('+ FileName', $newName); 1321 1510 return 1; 1322 1511 } … … 1326 1515 # Inputs: 0) ExifTool object reference, 1327 1516 # 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) 1329 1518 # 3) optional output file type (required only if input file is not specified 1330 1519 # and output file is a reference) … … 1332 1521 sub WriteInfo($$;$$) 1333 1522 { 1334 local $_;1523 local ($_, *EXIFTOOL_FILE2, *EXIFTOOL_OUTFILE); 1335 1524 my ($self, $infile, $outfile, $outType) = @_; 1336 my (@fileTypeList, $fileType, $tiffType );1525 my (@fileTypeList, $fileType, $tiffType, $hdr, $seekErr, $type, $tmpfile); 1337 1526 my ($inRef, $outRef, $closeIn, $closeOut, $outPos, $outBuff, $eraseIn); 1338 1527 my $oldRaf = $self->{RAF}; 1339 my $rtnVal = 1;1528 my $rtnVal = 0; 1340 1529 1341 1530 # initialize member variables … … 1344 1533 # first, save original file modify date if necessary 1345 1534 # (do this now in case we are modifying file in place and shifting date) 1346 my ($n ewValueHash, $originalTime);1347 my $fileModifyDate = $self->GetNewValues('FileModifyDate', \$n ewValueHash);1348 if (defined $fileModifyDate and IsOverwriting($n ewValueHash) < 0 and1535 my ($nvHash, $originalTime); 1536 my $fileModifyDate = $self->GetNewValues('FileModifyDate', \$nvHash); 1537 if (defined $fileModifyDate and IsOverwriting($nvHash) < 0 and 1349 1538 defined $infile and ref $infile ne 'SCALAR') 1350 1539 { … … 1354 1543 # do quick in-place change of file dir/name or date if that is all we are doing 1355 1544 # 1545 my ($numNew, $numPseudo) = $self->CountNewValues(); 1356 1546 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); 1359 1548 if ($numNew == $numPseudo) { 1360 1549 $rtnVal = 2; … … 1372 1561 $outfile = $newFileName; 1373 1562 # can't delete original 1374 } elsif (IsOverwriting($n ewValueHash, $infile)) {1563 } elsif (IsOverwriting($nvHash, $infile)) { 1375 1564 $outfile = GetNewFileName($infile, $newFileName); 1376 $eraseIn = 1; # delete original 1565 $eraseIn = 1; # delete original 1377 1566 } 1378 1567 } … … 1385 1574 if (UNIVERSAL::isa($inRef,'GLOB')) { 1386 1575 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 $@)) { 1388 1577 # convert image data from UTF-8 to character stream if necessary 1578 my $buff = $@ ? pack('C*',unpack('U0C*',$$inRef)) : Encode::encode('utf8',$$inRef); 1389 1579 if (defined $outfile) { 1390 my $buff = pack('C*', unpack('U0U*', $$inRef));1391 1580 $inRef = \$buff; 1392 1581 } else { 1393 $$inRef = pack('C*', unpack('U0U*', $$inRef));1582 $$inRef = $buff; 1394 1583 } 1395 1584 } 1396 1585 } 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)) { 1398 1589 $fileType = GetFileType($infile); 1399 $tiffType = GetFileExtension($infile); 1590 @fileTypeList = GetFileType($infile); 1591 $tiffType = $$self{FILE_EXT} = GetFileExtension($infile); 1400 1592 $self->VPrint(0, "Rewriting $infile...\n"); 1401 1593 $inRef = \*EXIFTOOL_FILE2; 1402 1594 $closeIn = 1; # we must close the file since we opened it 1403 1595 } else { 1404 my $forUpdate = (defined $outfile ? '' : ' for update'); 1405 $self->Error("Error opening file$forUpdate"); 1596 $self->Error('Error opening file'); 1406 1597 return 0; 1407 1598 } … … 1411 1602 } else { 1412 1603 # create file from scratch 1413 $outType = GetFile Type($outfile) unless $outType or ref $outfile;1604 $outType = GetFileExtension($outfile) unless $outType or ref $outfile; 1414 1605 if (CanCreate($outType)) { 1415 1606 $fileType = $tiffType = $outType; # use output file type if no input file … … 1425 1616 } 1426 1617 } 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 } 1432 1625 } 1433 1626 # … … 1446 1639 } elsif (not defined $outfile) { 1447 1640 # editing in place, so write to memory first 1641 # (only when infile is a file ref or scalar ref) 1448 1642 $outBuff = ''; 1449 1643 $outRef = \$outBuff; … … 1451 1645 } elsif (-e $outfile) { 1452 1646 $self->Error("File already exists: $outfile"); 1453 $rtnVal = 0;1454 1647 } elsif (open(EXIFTOOL_OUTFILE, ">$outfile")) { 1455 1648 $outRef = \*EXIFTOOL_OUTFILE; … … 1458 1651 $outPos = 0; 1459 1652 } else { 1460 $self->Error("Error creating file: $outfile");1461 $ rtnVal = 0;1653 my $tmp = $tmpfile ? ' temporary' : ''; 1654 $self->Error("Error creating$tmp file: $outfile"); 1462 1655 } 1463 1656 # 1464 1657 # write the file 1465 1658 # 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 } 1471 1677 # $raf->Debug() and warn " RAF debugging enabled!\n"; 1472 1678 my $inPos = $raf->Tell(); 1473 $raf->BinMode();1474 1679 $self->{RAF} = $raf; 1475 1680 my %dirInfo = ( … … 1477 1682 OutFile => $outRef, 1478 1683 ); 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 } 1481 1695 # save file type in member variable 1482 $dirInfo{Parent} = $self->{FILE_TYPE} = $ type;1696 $dirInfo{Parent} = $self->{FILE_TYPE} = $self->{PATH}[0] = $type; 1483 1697 # determine which directories we must write for this file type 1484 1698 $self->InitWriteDirs($type); … … 1487 1701 } elsif ($type eq 'TIFF') { 1488 1702 # disallow writing of some TIFF-based RAW images: 1489 if ( $tiffType =~ /^(SRF|SR2|ARW|RAW|DCR|K25)$/) {1703 if (grep /^$tiffType$/, @{$noWriteFile{TIFF}}) { 1490 1704 $fileType = $tiffType; 1491 1705 undef $rtnVal; … … 1503 1717 require Image::ExifTool::MinoltaRaw; 1504 1718 $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') { 1506 1723 $rtnVal = $self->ProcessTIFF(\%dirInfo); 1724 } elsif ($type eq 'X3F') { 1725 require Image::ExifTool::SigmaRaw; 1726 $rtnVal = Image::ExifTool::SigmaRaw::ProcessX3F($self, \%dirInfo); 1507 1727 } elsif ($type eq 'PNG') { 1508 1728 require Image::ExifTool::PNG; … … 1523 1743 require Image::ExifTool::PostScript; 1524 1744 $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); 1525 1748 } elsif ($type eq 'ICC') { 1526 1749 require Image::ExifTool::ICC_Profile; … … 1532 1755 require Image::ExifTool::Jpeg2000; 1533 1756 $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 } 1536 1769 } else { 1537 1770 undef $rtnVal; # flag that we don't write this type of file … … 1541 1774 last unless @fileTypeList; 1542 1775 # 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; 1547 1777 if (UNIVERSAL::isa($outRef,'GLOB')) { 1548 1778 seek($outRef, 0, $outPos); … … 1553 1783 # print file format errors 1554 1784 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 } 1557 1807 } 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"; 1559 1811 } 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) 1565 1819 } 1566 1820 # 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 } 1568 1832 1569 1833 # rewrite original file in place if required … … 1590 1854 # errors on input file are significant if we edited the file in place 1591 1855 $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 } 1593 1885 # 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; 1595 1887 } 1596 1888 } … … 1600 1892 $rtnVal and $rtnVal = -1 unless close($outRef); 1601 1893 # 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 } 1603 1911 } 1604 1912 # set FileModifyDate if requested (and if possible!) 1605 1913 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) 1607 1916 { 1608 $self->SetFileModifyDate($closeOut ? $outfile : $infile, $originalTime);1917 ++$self->{CHANGED}; # we changed something 1609 1918 } 1610 1919 # check for write error and set appropriate error message and return value 1611 1920 if ($rtnVal < 0) { 1612 $self->Error('Error writing output file') ;1921 $self->Error('Error writing output file') unless $$self{VALUE}{Error}; 1613 1922 $rtnVal = 0; # return 0 on failure 1614 1923 } elsif ($rtnVal > 0) { … … 1623 1932 #------------------------------------------------------------------------------ 1624 1933 # 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) 1626 1935 # Returns: tag list (sorted alphabetically) 1627 1936 # Notes: Can't get tags for specific IFD … … 1630 1939 local $_; 1631 1940 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; 1635 1945 LoadAllTables(); # first load all our tables 1636 my @tableNames = ( keys %allTables );1946 my @tableNames = keys %allTables; 1637 1947 1638 1948 # loop through all tables and save tag names to %allTags hash … … 1643 1953 my @infoArray = GetTagInfoList($table,$tagID); 1644 1954 my $tagInfo; 1645 foreach $tagInfo (@infoArray) { 1646 my $tag = $$tagInfo{Name} || die "no name for tag!\n"; 1955 GATInfo: foreach $tagInfo (@infoArray) { 1956 my $tag = $$tagInfo{Name}; 1957 $tag or warn("no name for tag!\n"), next; 1647 1958 # 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 } 1652 1966 } 1653 1967 $allTags{$tag} = 1; … … 1660 1974 #------------------------------------------------------------------------------ 1661 1975 # Get list of all writable tags 1662 # Inputs: 0) optional group name 1976 # Inputs: 0) optional group name (or names separated by colons) 1663 1977 # Returns: tag list (sorted alphbetically) 1664 1978 sub GetWritableTags(;$) … … 1666 1980 local $_; 1667 1981 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; 1671 1986 LoadAllTables(); 1672 1987 my @tableNames = keys %allTables; … … 1687 2002 my @infoArray = GetTagInfoList($table,$tagID); 1688 2003 my $tagInfo; 1689 foreach $tagInfo (@infoArray) { 1690 my $tag = $$tagInfo{Name} || die "no name for tag!\n"; 2004 GWTInfo: foreach $tagInfo (@infoArray) { 2005 my $tag = $$tagInfo{Name}; 2006 $tag or warn("no name for tag!\n"), next; 1691 2007 my $writable = $$tagInfo{Writable}; 1692 2008 next unless $writable or ($table->{WRITABLE} and 1693 2009 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 } 1697 2016 } 1698 2017 $writableTags{$tag} = 1; … … 1712 2031 my $family = shift || 0; 1713 2032 2033 $family == 3 and return('Doc#', 'Main'); 2034 $family == 4 and return('Copy#'); 2035 1714 2036 LoadAllTables(); # first load all our tables 1715 2037 1716 my @tableNames = ( keys %allTables );2038 my @tableNames = keys %allTables; 1717 2039 1718 2040 # loop through all tag tables and get all group names … … 1720 2042 while (@tableNames) { 1721 2043 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); 1731 2048 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; 1735 2051 } 1736 2052 } … … 1761 2077 1762 2078 #------------------------------------------------------------------------------ 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 2082 sub 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 2111 sub ConvInv($$$$$;$$) 2112 { 2113 my ($self, $val, $tagInfo, $tag, $wgrp1, $convType, $wantGroup) = @_; 2114 my ($err, $type); 2115 2116 Conv: 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 #------------------------------------------------------------------------------ 1763 2287 # convert tag names to values in a string (ie. "${EXIF:ISO}x $$" --> "100x $") 1764 2288 # Inputs: 0) ExifTool object ref, 1) reference to list of found tags 1765 2289 # 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) 1769 2293 # Hash ref - hash for return of tag/value pairs 1770 2294 # 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 1772 2298 sub InsertTagValues($$$;$) 1773 2299 { 1774 2300 my ($self, $foundTags, $line, $opt) = @_; 1775 2301 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 '/'; 1781 2308 $rtnStr .= "$pre$var"; 2309 $line =~ s/^\}// if $bra; 1782 2310 next; 1783 2311 } 1784 # check to see if this is a group name1785 if ($line =~ /^:([\w-]+)(.*)/s) {1786 $group = $var;2312 # allow multiple group names 2313 while ($line =~ /^:([-\w]+)(.*)/s) { 2314 my $group = $var; 1787 2315 ($var, $line) = ($1, $2); 1788 $line =~ s/^\}// if $group =~ s/^\{//;1789 2316 $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; 1793 2322 push @tags, $var; 1794 2323 ExpandShortcuts(\@tags); … … 1797 2326 for (;;) { 1798 2327 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); 1803 2331 # find the specified tag 1804 2332 my @matches = grep /^$tag(\s|$)/i, @$foundTags; 2333 @matches = $self->GroupMatches($group, \@matches); 1805 2334 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 }1811 2335 if (defined $val and $tg =~ / \((\d+)\)$/) { 1812 2336 # take the most recently extracted tag … … 1814 2338 next if $tag !~ / \((\d+)\)$/ or $1 > $tagNum; 1815 2339 } 1816 $val = $self->GetValue($tg );2340 $val = $self->GetValue($tg, $type); 1817 2341 $tag = $tg; 1818 2342 last unless $tag =~ / /; # all done if we got our best match 1819 2343 } 1820 2344 } else { 1821 # remove trailing bracket if we had a leading one1822 $val = $self->GetValue($tag );2345 # get the tag value 2346 $val = $self->GetValue($tag, $type); 1823 2347 unless (defined $val) { 1824 2348 # check for tag name with different case 1825 2349 ($tg) = grep /^$tag$/i, @$foundTags; 1826 2350 if (defined $tg) { 1827 $val = $self->GetValue($tg );2351 $val = $self->GetValue($tg, $type); 1828 2352 $tag = $tg; 1829 2353 } … … 1831 2355 } 1832 2356 if (ref $val eq 'ARRAY') { 1833 $val = join( ', ', @$val);2357 $val = join($self->{OPTIONS}{ListSep}, @$val); 1834 2358 } 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 } 1836 2364 } elsif (not defined $val) { 1837 2365 last unless @tags; … … 1847 2375 } 1848 2376 unless (defined $val or ref $opt) { 1849 $val = $self->{OPTIONS} ->{MissingTagValue};2377 $val = $self->{OPTIONS}{MissingTagValue}; 1850 2378 unless (defined $val) { 1851 2379 no strict 'refs'; … … 1855 2383 } 1856 2384 if (ref $opt eq 'HASH') { 2385 $var .= '#' if $type; 1857 2386 $rtnStr .= "$pre\$info{'$var'}"; 1858 2387 $$opt{$var} = $val; … … 1871 2400 { 1872 2401 my $tag = shift; 1873 $tag =~ s/^(. +)://; # ignore group name2402 $tag =~ s/^(.*)://; # ignore group name 1874 2403 my @tagInfo = FindTagInfo($tag); 1875 return undef unless @tagInfo; 2404 unless (@tagInfo) { 2405 return 0 if TagExists($tag); 2406 return undef; 2407 } 1876 2408 my $tagInfo; 1877 2409 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}; 1879 2416 } 1880 2417 return 0; … … 1909 2446 1910 2447 #------------------------------------------------------------------------------ 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? 2451 sub 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 #------------------------------------------------------------------------------ 1911 2460 # Get new file name 1912 2461 # Inputs: 0) existing name, 1) new name … … 1926 2475 1927 2476 #------------------------------------------------------------------------------ 2477 # Get next available tag key 2478 # Inputs: 0) hash reference (keys are tag keys), 1) tag name 2479 # Returns: next available tag key 2480 sub 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 #------------------------------------------------------------------------------ 1928 2492 # Reverse hash lookup 1929 2493 # Inputs: 0) value, 1) hash reference … … 1932 2496 { 1933 2497 my ($val, $conv) = @_; 2498 return undef unless defined $val; 1934 2499 my $multi; 1935 if ($val =~ /^Unknown\s*\((. +)\)$/i) {2500 if ($val =~ /^Unknown\s*\((.*)\)$/i) { 1936 2501 $val = $1; # was unknown 1937 2502 if ($val =~ /^0x([\da-fA-F]+)$/) { … … 1939 2504 } 1940 2505 } else { 2506 my $qval = quotemeta $val; 1941 2507 my @patterns = ( 1942 "^ \Q$val\E\$",# exact match1943 "^(?i) \Q$val\E\$",# case-insensitive1944 "^(?i) \Q$val\E",# beginning of string1945 "(?i) \Q$val\E",# substring2508 "^$qval\$", # exact match 2509 "^(?i)$qval\$", # case-insensitive 2510 "^(?i)$qval", # beginning of string 2511 "(?i)$qval", # substring 1946 2512 ); 2513 # hash entries to ignore in reverse lookup 1947 2514 my ($pattern, $found, $matches); 1948 2515 PAT: foreach $pattern (@patterns) { 1949 2516 $matches = scalar grep /$pattern/, values(%$conv); 1950 2517 next unless $matches; 1951 2518 # 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 } 1953 2526 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 } 1961 2532 } 1962 2533 unless ($found) { 1963 undef $val; 2534 # call OTHER conversion routine if available 2535 $val = $$conv{OTHER} ? &{$$conv{OTHER}}($val,1,$conv) : undef; 1964 2536 $multi = 1 if $matches > 1; 1965 2537 } 1966 2538 } 1967 if (wantarray) { 1968 return ($val, $multi); 1969 } else { 1970 return $val; 1971 } 2539 return ($val, $multi) if wantarray; 2540 return $val; 1972 2541 } 1973 2542 … … 1975 2544 # Return true if we are deleting or overwriting the specified tag 1976 2545 # Inputs: 0) new value hash reference 1977 # 2) optional tag valueif deleting specific values1978 # Returns: >0 - tag should be deleted2546 # 1) optional tag value (before RawConv) if deleting specific values 2547 # Returns: >0 - tag should be overwritten 1979 2548 # =0 - the tag should be preserved 1980 2549 # <0 - not sure, we need the value to know 1981 2550 sub IsOverwriting($;$) 1982 2551 { 1983 my ($n ewValueHash, $value) = @_;1984 return 0 unless $n ewValueHash;2552 my ($nvHash, $val) = @_; 2553 return 0 unless $nvHash; 1985 2554 # 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 } 1987 2578 # 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) { 1992 2580 require 'Image/ExifTool/Shift.pl'; 1993 my $err = ApplyShift($ type, $shift, $value, $newValueHash);2581 my $err = ApplyShift($$tagInfo{Shift}, $shift, $val, $nvHash); 1994 2582 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}"); 1997 2584 return 0; 1998 2585 } 1999 2586 # don't bother overwriting if value is the same 2000 return 0 if $val ue eq $newValueHash->{Value}->[0];2587 return 0 if $val eq $$nvHash{Value}[0]; 2001 2588 return 1; 2002 2589 } 2003 # never overwrite if DelValue list exists but is empty2004 return 0 unless @{$newValueHash->{DelValue}};2005 # return "don't know" if we don't have a value to test2006 return -1 unless defined $value;2007 2590 # return 1 if value matches a DelValue 2008 my $ val;2009 foreach $ val (@{$newValueHash->{DelValue}}) {2010 return 1 if $val ue eq $val;2591 my $delVal; 2592 foreach $delVal (@{$$nvHash{DelValue}}) { 2593 return 1 if $val eq $delVal; 2011 2594 } 2012 2595 return 0; … … 2019 2602 sub IsCreating($) 2020 2603 { 2021 return $_[0] ->{IsCreating};2604 return $_[0]{IsCreating}; 2022 2605 } 2023 2606 … … 2028 2611 sub GetWriteGroup($) 2029 2612 { 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 2620 sub GetWriteGroup1($$) 2621 { 2622 my ($self, $tagInfo, $writeGroup) = @_; 2623 return $writeGroup unless $writeGroup =~ /^(MakerNotes|XMP|Composite)$/; 2624 return $self->GetGroup($tagInfo, 1); 2031 2625 } 2032 2626 … … 2040 2634 { 2041 2635 my ($self, $tagInfo, $writeGroup, $opts) = @_; 2042 my $n ewValueHash = $self->{NEW_VALUE}->{$tagInfo};2636 my $nvHash = $self->{NEW_VALUE}{$tagInfo}; 2043 2637 2044 2638 my %opts; # quick lookup for options … … 2048 2642 if ($writeGroup) { 2049 2643 # find the new value in the list with the specified write group 2050 while ($n ewValueHash and $newValueHash->{WriteGroup} ne $writeGroup) {2051 $n ewValueHash = $newValueHash->{Next};2644 while ($nvHash and $nvHash->{WriteGroup} ne $writeGroup) { 2645 $nvHash = $nvHash->{Next}; 2052 2646 } 2053 2647 } 2054 2648 # remove this entry if deleting, or if creating a new entry and 2055 2649 # this entry is marked with "Save" flag 2056 if (defined $n ewValueHash and ($opts{'delete'} or2057 ($opts{'create'} and $n ewValueHash->{Save})))2650 if (defined $nvHash and ($opts{'delete'} or 2651 ($opts{'create'} and $nvHash->{Save}))) 2058 2652 { 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'}) { 2063 2673 # create a new entry 2064 $n ewValueHash = {2674 $nvHash = { 2065 2675 TagInfo => $tagInfo, 2066 2676 WriteGroup => $writeGroup, … … 2068 2678 }; 2069 2679 # add entry to our NEW_VALUE hash 2070 if ($self->{NEW_VALUE} ->{$tagInfo}) {2680 if ($self->{NEW_VALUE}{$tagInfo}) { 2071 2681 # add to end of linked list 2072 my $lastHash = LastInList($self->{NEW_VALUE} ->{$tagInfo});2073 $lastHash->{Next} = $n ewValueHash;2682 my $lastHash = LastInList($self->{NEW_VALUE}{$tagInfo}); 2683 $lastHash->{Next} = $nvHash; 2074 2684 } else { 2075 $self->{NEW_VALUE} ->{$tagInfo} = $newValueHash;2076 } 2077 } 2078 return $n ewValueHash;2685 $self->{NEW_VALUE}{$tagInfo} = $nvHash; 2686 } 2687 } 2688 return $nvHash; 2079 2689 } 2080 2690 … … 2083 2693 sub LoadAllTables() 2084 2694 { 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 tables2097 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 table2102 my $writeProc = $table->{WRITE_PROC};2103 $writeProc and &$writeProc();2104 # recursively scan through tables in subdirectories2105 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 loading2112 next if $allTables{$tableName} or $pushedTables{$tableName};2113 push @tableNames, $tableName; # must scan this one too2114 $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; 2120 2730 } 2121 2731 … … 2125 2735 sub RemoveNewValueHash($$$) 2126 2736 { 2127 my ($self, $n ewValueHash, $tagInfo) = @_;2128 my $firstHash = $self->{NEW_VALUE} ->{$tagInfo};2129 if ($n ewValueHash eq $firstHash) {2737 my ($self, $nvHash, $tagInfo) = @_; 2738 my $firstHash = $self->{NEW_VALUE}{$tagInfo}; 2739 if ($nvHash eq $firstHash) { 2130 2740 # remove first entry from linked list 2131 if ($n ewValueHash->{Next}) {2132 $self->{NEW_VALUE} ->{$tagInfo} = $newValueHash->{Next};2741 if ($nvHash->{Next}) { 2742 $self->{NEW_VALUE}{$tagInfo} = $nvHash->{Next}; 2133 2743 } else { 2134 delete $self->{NEW_VALUE} ->{$tagInfo};2744 delete $self->{NEW_VALUE}{$tagInfo}; 2135 2745 } 2136 2746 } else { 2137 2747 # find the list element pointing to this hash 2138 $firstHash = $firstHash->{Next} while $firstHash->{Next} ne $n ewValueHash;2748 $firstHash = $firstHash->{Next} while $firstHash->{Next} ne $nvHash; 2139 2749 # remove from linked list 2140 $firstHash->{Next} = $n ewValueHash->{Next};2750 $firstHash->{Next} = $nvHash->{Next}; 2141 2751 } 2142 2752 # save the existing entry if necessary 2143 if ($n ewValueHash->{Save}) {2753 if ($nvHash->{Save}) { 2144 2754 my $saveHash = $self->{SAVE_NEW_VALUE}; 2145 2755 # add to linked list of saved new value hashes 2146 $n ewValueHash->{Next} = $saveHash->{$tagInfo};2147 $saveHash->{$tagInfo} = $n ewValueHash;2756 $nvHash->{Next} = $saveHash->{$tagInfo}; 2757 $saveHash->{$tagInfo} = $nvHash; 2148 2758 } 2149 2759 } … … 2163 2773 2164 2774 my ($out, @keys, $hashKey); 2165 $out = $self->{OPTIONS} ->{TextOut} if $self->{OPTIONS}->{Verbose} > 1;2775 $out = $self->{OPTIONS}{TextOut} if $self->{OPTIONS}{Verbose} > 1; 2166 2776 2167 2777 # loop though all new values, and remove any in this group 2168 2778 @keys = keys %{$self->{NEW_VALUE}}; 2169 2779 foreach $hashKey (@keys) { 2170 my $n ewValueHash = $self->{NEW_VALUE}->{$hashKey};2780 my $nvHash = $self->{NEW_VALUE}{$hashKey}; 2171 2781 # loop through each entry in linked list 2172 2782 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) { 2178 2790 $out and print $out "Removed new value for $wgrp:$$tagInfo{Name}\n"; 2179 2791 # remove from linked list 2180 $self->RemoveNewValueHash($n ewValueHash, $tagInfo);2181 } 2182 $n ewValueHash = $nextHash or last;2792 $self->RemoveNewValueHash($nvHash, $tagInfo); 2793 } 2794 $nvHash = $nextHash or last; 2183 2795 } 2184 2796 } … … 2193 2805 my ($self, $tagTablePtr) = @_; 2194 2806 my @tagInfoList; 2195 if ($self->{NEW_VALUE}) { 2807 my $nv = $self->{NEW_VALUE}; 2808 if ($nv) { 2196 2809 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}; 2199 2812 next if $tagTablePtr and $tagTablePtr ne $tagInfo->{Table}; 2200 2813 push @tagInfoList, $tagInfo; … … 2212 2825 my $self = shift; 2213 2826 my (%tagInfoHash, $hashKey); 2214 while ($self->{NEW_VALUE}) { 2827 my $nv = $self->{NEW_VALUE}; 2828 while ($nv) { 2215 2829 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}; 2219 2832 next if $tagTablePtr and $tagTablePtr ne $tagInfo->{Table}; 2220 2833 $tagInfoHash{$$tagInfo{TagID}} = $tagInfo; … … 2233 2846 { 2234 2847 my ($self, $tagTablePtr, $parent) = @_; 2235 $parent or $parent = $tagTablePtr->{GROUPS} ->{0};2848 $parent or $parent = $tagTablePtr->{GROUPS}{0}; 2236 2849 my $tagID; 2237 2850 my %addDirHash; … … 2247 2860 # (take directory name from SubDirectory DirName if it exists, 2248 2861 # otherwise Group0 name of SubDirectory TagTable or tag Group1 name) 2249 my $dirName = $tagInfo->{SubDirectory} ->{DirName};2862 my $dirName = $tagInfo->{SubDirectory}{DirName}; 2250 2863 unless ($dirName) { 2251 2864 # use tag name for directory name and save for next time 2252 2865 $dirName = $$tagInfo{Name}; 2253 $tagInfo->{SubDirectory} ->{DirName} = $dirName;2866 $tagInfo->{SubDirectory}{DirName} = $dirName; 2254 2867 } 2255 2868 # save this directory information if we are writing it … … 2260 2873 } 2261 2874 } 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) 2271 2881 # Inputs: 0) tagInfo hash ref, 1) locale code (ie. "en_CA" for MIE) 2272 2882 # Returns: new tagInfo hash ref, or undef if invalid … … 2277 2887 # make a new tagInfo hash for this locale 2278 2888 my $table = $$tagInfo{Table}; 2279 Image::ExifTool::GenerateTagIDs($table);2280 2889 my $tagID = $$tagInfo{TagID} . '-' . $langCode; 2281 2890 my $langInfo = $$table{$tagID}; … … 2299 2908 # Inputs: 0) ExifTool object reference, 1) file type string (or map hash ref) 2300 2909 # 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) 2301 2912 sub InitWriteDirs($$;$) 2302 2913 { … … 2310 2921 } 2311 2922 my @tagInfoList = $self->GetNewTagInfoList(); 2312 my $tagInfo; 2923 my ($tagInfo, $nvHash); 2924 2925 # save the preferred group 2926 $$self{PreferredGroup} = $preferredGroup; 2927 2313 2928 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}) { 2316 2931 # 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 } 2318 2945 # tag belongs to directory specified by WriteGroup, or by 2319 2946 # the Group0 name if WriteGroup not defined 2320 my $dirName = $n ewValueHash->{WriteGroup};2947 my $dirName = $nvHash->{WriteGroup}; 2321 2948 # remove MIE copy number(s) if they exist 2322 2949 if ($dirName =~ /^MIE\d*(-[a-z]+)?\d*$/i) { … … 2331 2958 } 2332 2959 $$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; 2342 2961 $dirName = $parent || shift @dirNames 2343 2962 } 2344 last unless $newValueHash->{Next};2345 # cycle through all hashes in linked list2346 $newValueHash = $newValueHash->{Next};2347 2963 } 2348 2964 } … … 2350 2966 # add delete groups to list of edited groups 2351 2967 foreach (keys %{$self->{DEL_GROUP}}) { 2968 next if /^-/; # ignore excluded groups 2352 2969 my $dirName = $_; 2353 2970 # translate necessary group 0 names 2354 2971 $dirName = $translateWriteGroup{$dirName} if $translateWriteGroup{$dirName}; 2972 # convert XMP group 1 names 2973 $dirName = 'XMP' if $dirName =~ /^XMP-/; 2355 2974 my @dirNames; 2356 2975 while ($dirName) { … … 2370 2989 $$editDirs{APP0} = undef; 2371 2990 } 2372 2373 if ($self->{OPTIONS} ->{Verbose}) {2374 my $out = $self->{OPTIONS} ->{TextOut};2991 2992 if ($self->{OPTIONS}{Verbose}) { 2993 my $out = $self->{OPTIONS}{TextOut}; 2375 2994 print $out " Editing tags in: "; 2376 2995 foreach (sort keys %$editDirs) { print $out "$_ "; } 2377 2996 print $out "\n"; 2378 return unless $self->{OPTIONS} ->{Verbose} > 1;2997 return unless $self->{OPTIONS}{Verbose} > 1; 2379 2998 print $out " Creating tags in: "; 2380 2999 foreach (sort keys %$addDirs) { print $out "$_ "; } … … 2391 3010 { 2392 3011 my ($self, $dirInfo, $tagTablePtr, $writeProc) = @_; 3012 my ($out, $nvHash); 2393 3013 2394 3014 $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}; 2397 3016 # set directory name from default group0 name if not done already 2398 3017 my $dirName = $$dirInfo{DirName}; 2399 my $grp0 = $tagTablePtr->{GROUPS}->{0}; 3018 my $dataPt = $$dirInfo{DataPt}; 3019 my $grp0 = $tagTablePtr->{GROUPS}{0}; 2400 3020 $dirName or $dirName = $$dirInfo{DirName} = $grp0; 2401 3021 if (%{$self->{DEL_GROUP}}) { … … 2405 3025 my $delFlag = ($$delGroup{$grp0} or $$delGroup{$grp1}); 2406 3026 if ($delFlag) { 2407 unless ($ self->{FILE_TYPE} =~ /^(JPEG|PNG|JP2)$/) {3027 unless ($blockExifTypes{$$self{FILE_TYPE}}) { 2408 3028 # restrict delete logic to prevent entire tiff image from being killed 2409 3029 # (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') { 2411 3036 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); 2413 3038 undef $grp1; 2414 3039 } elsif ($grp0 eq 'EXIF' and $$delGroup{$grp0}) { … … 2417 3042 } 2418 3043 if ($grp1) { 2419 if ($ $dirInfo{DataPt}or $$dirInfo{RAF}) {3044 if ($dataPt or $$dirInfo{RAF}) { 2420 3045 ++$self->{CHANGED}; 2421 3046 $out and print $out " Deleting $grp1\n"; … … 2423 3048 delete $self->{TIFF_END} if $dirName =~ /IFD/; 2424 3049 } 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 } 2436 3077 } 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 } 2454 3081 } 2455 3082 } 2456 3083 # use default proc from tag table if no proc specified 2457 3084 $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 } 2458 3116 # 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)) { 2463 3122 return undef; 2464 3123 } else { … … 2468 3127 } 2469 3128 } 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 } 2474 3131 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 } 2478 3141 } 2479 3142 my $saveOrder = GetByteOrder(); 2480 3143 my $oldChanged = $self->{CHANGED}; 2481 3144 $self->{DIR_NAME} = $dirName; 3145 push @{$self->{PATH}}, $$dirInfo{DirName}; 3146 $$dirInfo{IsWriting} = 1; 2482 3147 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); 2483 3151 $self->{DIR_NAME} = $oldDir; 2484 $self->{CHANGED} = $oldChanged unless defined $newData; # nothing changed if error occurred2485 3152 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; 2487 3154 return $newData; 2488 3155 } … … 2530 3197 # MaxLen => maximum length to dump 2531 3198 # Out => output file reference 3199 # Len => data length 2532 3200 sub HexDump($;$%) 2533 3201 { … … 2543 3211 my $datLen = length($$dataPt) - $start; 2544 3212 my $more; 3213 $len = $opts{Len} if defined $opts{Len}; 2545 3214 2546 3215 $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; 2554 3217 if ($maxLen and $len > $maxLen) { 2555 3218 # print one line less to allow for $more line below … … 2558 3221 $len = $maxLen; 2559 3222 } 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 } 2560 3228 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) 2561 3230 my $i; 2562 3231 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; 2564 3233 printf $out "$prefix%8.4x: ", $addr+$i; 2565 3234 my $dat = substr($$dataPt, $i+$start, $wid); 2566 my $s = join(' ', (unpack('H*',$dat) =~ /../g));3235 my $s = join(' ', unpack($tmpl, $dat)); 2567 3236 printf $out $format, $s; 2568 3237 $dat =~ tr /\x00-\x1f\x7f-\xff/./; … … 2590 3259 { 2591 3260 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); 2595 3264 2596 3265 # generate hex number if tagID is numerical … … 2605 3274 } else { 2606 3275 my $prefix; 2607 $prefix = $parms{Table} ->{TAG_PREFIX} if $parms{Table};3276 $prefix = $parms{Table}{TAG_PREFIX} if $parms{Table}; 2608 3277 if ($prefix or $hexID) { 2609 3278 $prefix = 'Unknown' unless $prefix; … … 2623 3292 if (defined $index) { 2624 3293 $line .= $index . ') '; 2625 $line .= ' ' if $index < 10;3294 $line .= ' ' if length($index) < 2; 2626 3295 $indent .= ' '; # indent everything else to align with tag name 2627 3296 } … … 2629 3298 if ($tagInfo and $$tagInfo{SubDirectory}) { 2630 3299 $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 } 2636 3308 } 2637 3309 print $out "$line\n"; … … 2641 3313 $parms{DataPt} or defined $size or $tagID =~ /\//)) 2642 3314 { 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 } 2645 3322 $line .= $parms{Extra} if defined $parms{Extra}; 2646 3323 my $format = $parms{Format}; … … 2665 3342 $parms{Out} = $out; 2666 3343 $parms{Prefix} = $indent; 2667 # limit dump length unless verbose > 32668 $parms{MaxLen} = 96 unless $verbose > 3;3344 # limit dump length if Verbose < 5 3345 $parms{MaxLen} = $verbose == 3 ? 96 : 2048 if $verbose < 5; 2669 3346 HexDump($dataPt, $size, %parms); 2670 3347 } … … 2682 3359 my $trailer = $$dirInfo{DirName} || 'Unknown'; 2683 3360 my $pos = $$dirInfo{DataPos}; 2684 my $verbose = $self->{OPTIONS} ->{Verbose};3361 my $verbose = $self->{OPTIONS}{Verbose}; 2685 3362 my $htmlDump = $self->{HTML_DUMP}; 2686 3363 my ($buff, $buf2); … … 2700 3377 my $desc = "$trailer trailer"; 2701 3378 $desc = "[$desc]" if $trailer eq 'Unknown'; 2702 $self->H tmlDump($pos, $num, $desc, undef, 0x08);3379 $self->HDump($pos, $num, $desc, undef, 0x08); 2703 3380 last; 2704 3381 } 2705 my $out = $self->{OPTIONS} ->{TextOut};3382 my $out = $self->{OPTIONS}{TextOut}; 2706 3383 printf $out "$trailer trailer (%d bytes at offset 0x%.4x):\n", $size, $pos; 2707 3384 last unless $verbose > 2; … … 2725 3402 HexDump(\$buff, undef, Addr => $pos, Out => $out); 2726 3403 if (defined $buf2) { 2727 print " [snip ", $size - $num * 2, " bytes]\n";3404 print $out " [snip ", $size - $num * 2, " bytes]\n"; 2728 3405 HexDump(\$buf2, undef, Addr => $pos + $size - $num, Out => $out); 2729 3406 } … … 2742 3419 my $pos = $$dirInfo{DataPos}; 2743 3420 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 2750 3448 $$dirInfo{DirName} = 'Unknown'; 2751 $$dirInfo{DirLen} = $prePos - $pos; 3449 $$dirInfo{DataPos} = $pos; 3450 $$dirInfo{DirLen} = $prePos - $pos; 2752 3451 $self->DumpTrailer($dirInfo); 2753 3452 } 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; 2757 3458 $$dirInfo{DataPos} = $prePos; 2758 3459 $$dirInfo{DirLen} = $preLen; 2759 3460 $self->DumpTrailer($dirInfo); 2760 3461 } 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 } 2769 3464 } 2770 3465 … … 2790 3485 { 2791 3486 my ($self, $name, $entries, $size) = @_; 2792 return unless $self->{OPTIONS} ->{Verbose};3487 return unless $self->{OPTIONS}{Verbose}; 2793 3488 if (ref $name eq 'HASH') { 2794 3489 $size = $$name{DirLen} unless $size; … … 2796 3491 } 2797 3492 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; 2807 3496 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 3503 sub 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"; 2808 3512 } 2809 3513 … … 2887 3591 2888 3592 #------------------------------------------------------------------------------ 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 3601 sub 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'; 2959 3610 } else { 2960 # do it ourself2961 $outVal = PackUTF8(unpack("$fmt*",$val));2962 }2963 $outVal =~ s/\0.*//s; # truncate at null terminator2964 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-82977 local $SIG{'__WARN__'} = \&SetWarning;2978 # repack UTF-8 string in specified format2979 $str = pack("$fmt*", unpack('U0U*',$str));2980 } else {2981 # do it ourself2982 $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 exists3000 $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 3662 sub 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(); 3023 3674 } 3024 3675 … … 3036 3687 3037 3688 #------------------------------------------------------------------------------ 3038 # Convert a floating point number into a rational3689 # Convert a floating point number (or 'inf' or 'undef' or a fraction) into a rational 3039 3690 # Inputs: 0) floating point number, 1) optional maximum value (defaults to 0x7fffffff) 3040 3691 # 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! 3042 3697 sub Rationalize($;$) 3043 3698 { 3044 3699 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 3045 3703 # Note: Just testing "if $val" doesn't work because '0.0' is true! (ugghh!) 3046 3704 return (0, 1) if $val == 0; … … 3102 3760 } 3103 3761 sub SetRational32s(@) { 3104 my ($numer,$denom) = Rationalize($_[0],0x ffff);3762 my ($numer,$denom) = Rationalize($_[0],0x7fff); 3105 3763 my $val = Set16s($numer) . Set16u($denom); 3106 3764 $_[1] and substr(${$_[1]}, $_[2], length($val)) = $val; … … 3141 3799 int16s => \&Set16s, 3142 3800 int16u => \&Set16u, 3801 int16uRev => \&Set16uRev, 3143 3802 int32s => \&Set32s, 3144 3803 int32u => \&Set32u, … … 3199 3858 if ($format =~ /^int/) { 3200 3859 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)); 3203 3863 } 3204 3864 $packed .= &$proc($val); … … 3253 3913 if ($lookup) { 3254 3914 $bit = ReverseLookup($val, $lookup); 3915 # (Note: may get non-numerical $bit values from Unknown() tags) 3255 3916 unless (defined $bit) { 3256 3917 if ($val =~ /\[(\d+)\]/) { # numerical bit specification … … 3265 3926 $bit = $val; 3266 3927 } 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 } 3268 3932 my $word = int($bit / $bits); 3269 3933 $outVal[$word] |= (1 << ($bit - $word * $bits)); … … 3304 3968 3305 3969 #------------------------------------------------------------------------------ 3306 # Read/rewrite trailer information (including multiple trailers)3307 # Inputs: 0) ExifTool object ref, 1) DirInfo ref:3308 # - requires RAF and DirName3309 # - OutFile is a scalar reference for writing3310 # - scans from current file position if ScanForAFCP is set3311 # 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 updated3314 # - preserves current file position and byte order3315 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 trailers3328 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 later3333 $$outfile and $$dirInfo{OutFile} = \$outBuff, $outBuff = '';3334 # must generate new fixup if necessary so we can shift3335 # the old fixup separately after we prepend this trailer3336 delete $$dirInfo{Fixup};3337 }3338 delete $$dirInfo{DirLen}; # reset trailer length3339 $$dirInfo{Offset} = $offset; # set offset from end of file3340 $$dirInfo{Trailer} = 1; # set Trailer flag in case proc cares3341 3342 # read or write this trailer3343 # (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 order3353 $$outfile = $outBuff . $$outfile;3354 # must adjust old fixup start if it exists3355 $$fixup{Start} += length($outBuff) if $fixup;3356 $outBuff = ''; # free memory3357 }3358 if ($fixup) {3359 # add new fixup information if any3360 $fixup->AddFixup($$dirInfo{Fixup}) if $$dirInfo{Fixup};3361 } else {3362 $fixup = $$dirInfo{Fixup}; # save fixup3363 }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 trailer3370 $success = 0;3371 last;3372 }3373 last unless $result > 0 and $$dirInfo{DirLen};3374 # look for next trailer3375 $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 order3381 $raf->Seek($pos, 0); # restore original file position3382 $$dirInfo{OutFile} = $outfile; # restore original outfile3383 $$dirInfo{Offset} = $offset; # return offset to start of first trailer3384 $$dirInfo{Fixup} = $fixup; # return fixup information3385 return $success;3386 }3387 3388 #------------------------------------------------------------------------------3389 3970 # Write trailer buffer to file (applying fixups if necessary) 3390 3971 # Inputs: 0) ExifTool object ref, 1) trailer dirInfo ref, 2) output file ref … … 3393 3974 { 3394 3975 my ($self, $trailInfo, $outfile) = @_; 3395 if ($self->{DEL_GROUP} ->{Trailer}) {3976 if ($self->{DEL_GROUP}{Trailer}) { 3396 3977 $self->VPrint(0, " Deleting trailer ($$trailInfo{Offset} bytes)\n"); 3397 3978 ++$self->{CHANGED}; … … 3404 3985 if ($pos > 0) { 3405 3986 # shift offsets to final AFCP location and write it out 3406 $trailInfo->{Fixup} ->{Shift} += $pos;3987 $trailInfo->{Fixup}{Shift} += $pos; 3407 3988 $trailInfo->{Fixup}->ApplyFixup($trailPt); 3408 3989 } else { … … 3430 4011 my $type; 3431 4012 foreach $type (@types) { 3432 next unless $self->{NEW_VALUE} ->{$Image::ExifTool::Extra{$type}};4013 next unless $self->{NEW_VALUE}{$Image::ExifTool::Extra{$type}}; 3433 4014 my $val = $self->GetNewValues($type) or next; 3434 4015 my $verb = $trailPt ? 'Writing' : 'Adding'; … … 3480 4061 3481 4062 #------------------------------------------------------------------------------ 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 4067 sub 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 #------------------------------------------------------------------------------ 3482 4099 # WriteJPEG : Write JPEG image 3483 4100 # Inputs: 0) ExifTool object reference, 1) dirInfo reference … … 3490 4107 my $raf = $$dirInfo{RAF}; 3491 4108 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}; 3494 4111 my $rtnVal = 0; 3495 4112 my ($err, %doneDir); … … 3509 4126 my $editDirs = $self->{EDIT_DIRS}; 3510 4127 my $delGroup = $self->{DEL_GROUP}; 4128 my $path = $$self{PATH}; 4129 my $pn = scalar @$path; 3511 4130 3512 4131 # set input record separator to 0xff (the JPEG marker) to make reading quicker 3513 my $oldsep = $/; 3514 $/ = "\xff"; 4132 local $/ = "\xff"; 3515 4133 # 3516 4134 # pre-scan image to determine if any create-able segment already exists … … 3549 4167 $raf->Read($s, $n) == $n or last; 3550 4168 $len -= $n; 4169 # (Note: only necessary to recognize APP segments that we can create) 3551 4170 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'; 3554 4173 } 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'; 3557 4177 } elsif ($marker == 0xe2) { 3558 $s =~ /^ICC_PROFILE\0/ and $dirName = 'ICC_Profile';4178 $s =~ /^ICC_PROFILE\0/ and $dirName = 'ICC_Profile'; 3559 4179 } elsif ($marker == 0xec) { 3560 $s =~ /^Ducky/ and $dirName = 'Ducky';4180 $s =~ /^Ducky/ and $dirName = 'Ducky'; 3561 4181 } elsif ($marker == 0xed) { 3562 $s =~ /^$psAPP13hdr/ and $dirName = 'Photoshop';4182 $s =~ /^$psAPP13hdr/ and $dirName = 'Photoshop'; 3563 4183 } 3564 4184 # initialize doneDir as a flag that the directory exists … … 3580 4200 # re-write the image 3581 4201 # 3582 my ($combinedSegData, $segPos );4202 my ($combinedSegData, $segPos, %extendedXMP); 3583 4203 # read through each segment in the JPEG file 3584 4204 Marker: for (;;) { … … 3616 4236 my $markerName = JpegMarkerName($marker); 3617 4237 my $dirName = shift @dirOrder; # get directory name 4238 $$path[$pn] = $markerName; 3618 4239 # 3619 4240 # create all segments that must come before this one … … 3635 4256 DirLen => length $jfif, 3636 4257 ); 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}; 3637 4262 my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr); 4263 $$delGroup{JFIF} = $delJFIF if defined $delJFIF; 3638 4264 if (defined $newData and length $newData) { 3639 4265 my $app0hdr = "\xff\xe0" . pack('n', length($newData) + 7); … … 3650 4276 $self->{TIFF_TYPE} = 'APP1'; 3651 4277 my $tagTablePtr = GetTagTable('Image::ExifTool::Exif::Main'); 3652 # use specified byte ordering or ordering from maker notes if set3653 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 }3660 4278 my %dirInfo = ( 3661 NewDataPos => 8, # new data will come after TIFF header3662 4279 DirName => 'IFD0', 3663 Parent => $markerName,4280 Parent => 'APP1', 3664 4281 ); 3665 my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr );4282 my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr, \&WriteTIFF); 3666 4283 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); 3669 4285 if ($size <= $maxSegmentLen) { 3670 4286 # 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) { 3672 4288 $writeBuffer = ''; 3673 4289 $oldOutfile = $outfile; 3674 4290 $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}; 3677 4294 } 3678 4295 # write the new segment with appropriate header 3679 4296 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; 3681 4298 } else { 3682 4299 delete $self->{PREVIEW_INFO}; … … 3693 4310 my $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main'); 3694 4311 my %dirInfo = ( 3695 Parent => $markerName,4312 Parent => 'APP13', 3696 4313 ); 3697 4314 my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr); … … 3709 4326 my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main'); 3710 4327 my %dirInfo = ( 3711 Parent => $markerName, 4328 Parent => 'APP1', 4329 # specify MaxDataLen so XMP is split if required 4330 MaxDataLen => $maxXMPLen - length($xmpAPP1hdr), 3712 4331 ); 3713 4332 my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr); 3714 4333 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; 3723 4336 } 3724 4337 } … … 3732 4345 my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main'); 3733 4346 my %dirInfo = ( 3734 Parent => $markerName,4347 Parent => 'APP2', 3735 4348 ); 3736 4349 my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr); … … 3748 4361 my $tagTablePtr = GetTagTable('Image::ExifTool::APP12::Ducky'); 3749 4362 my %dirInfo = ( 3750 Parent => $markerName,4363 Parent => 'APP12', 3751 4364 ); 3752 4365 my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr); … … 3758 4371 Write($outfile, $app12hdr, 'Ducky', $buff) or $err = 1; 3759 4372 } else { 3760 $self->Warn(" APP12 Duckysegment too large! ($size bytes)");4373 $self->Warn("Ducky APP12 segment too large! ($size bytes)"); 3761 4374 } 3762 4375 } … … 3769 4382 my $newComment = $self->GetNewValues('Comment'); 3770 4383 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 } 3773 4388 WriteMultiSegment($outfile, 0xfe, '', \$newComment) or $err = 1; 3774 4389 ++$self->{CHANGED}; … … 3788 4403 next; 3789 4404 } elsif ($marker == 0xda) { # SOS 4405 pop @$path; 3790 4406 $verbose and print $out "JPEG SOS\n"; 3791 4407 # write SOS segment … … 3834 4450 $self->ProcessTrailers($trailInfo) or undef $trailInfo; 3835 4451 } 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 { 3837 4488 # 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 3839 4491 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) 3844 4496 my $junkLen; 3845 4497 # adjust position if image isn't at the start (ie. Olympus E-1/E-300) 3846 4498 if ($buff =~ m/(\xff\xd8\xff.|.\xd8\xff\xdb)/sg) { 3847 4499 $junkLen = pos($buff) - 4; 4500 # Sony previewimage trailer has a 32 byte header 4501 $junkLen -= 32 if $$self{Make} =~/SONY/i and $junkLen > 32; 3848 4502 $newPos += $junkLen; 3849 4503 } … … 3851 4505 my $previewInfo = $self->{PREVIEW_INFO}; 3852 4506 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}) { 3856 4512 # adjust for our base by looking at how far the pointer got shifted 3857 4513 $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; 3858 4518 } 3859 4519 $fixup->SetMarkerPointers($outfile, 'PreviewImage', $newPos); … … 3864 4524 undef $writeBuffer; 3865 4525 # write preview image 3866 if ($ previewInfo->{Data} ne 'LOAD') {4526 if ($$previewInfo{Data} ne 'LOAD_PREVIEW') { 3867 4527 # write any junk that existed before the preview image 3868 4528 Write($outfile, substr($buff,0,$junkLen)) or $err = 1 if $junkLen; 3869 4529 # 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}; 3872 4532 # (don't increment CHANGED because we could be rewriting existing preview) 3873 4533 $delPreview = 1; # remove old preview … … 3893 4553 $verbose and print $out " Preserving unknown trailer ($extra bytes)\n"; 3894 4554 $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; 3901 4556 } 3902 4557 } … … 3929 4584 } 3930 4585 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) 3934 4588 while (exists $$editDirs{$markerName} or $$delGroup{'*'}) { 3935 4589 my $oldChanged = $self->{CHANGED}; … … 3938 4592 $segType = 'JFIF'; 3939 4593 $$delGroup{JFIF} and $del = 1, last; 4594 last unless $$editDirs{JFIF}; 3940 4595 SetByteOrder('MM'); 3941 4596 my $tagTablePtr = GetTagTable('Image::ExifTool::JFIF::Main'); … … 3958 4613 $segType = 'CIFF'; 3959 4614 $$delGroup{CIFF} and $del = 1, last; 4615 last unless $$editDirs{CIFF}; 3960 4616 my $newData = ''; 3961 4617 my %dirInfo = ( … … 3980 4636 $doneDir{IFD0} = 1; 3981 4637 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 } 3984 4644 # rewrite EXIF as if this were a TIFF file in memory 3985 4645 my %dirInfo = ( 3986 DataPt => $segDataPt,3987 DataPos => $segPos,4646 DataPt => $segDataPt, 4647 DataPos => $segPos, 3988 4648 DirStart => 6, 3989 Base => $segPos + 6,3990 OutFile => \$buff,3991 Parent => $markerName,4649 Base => $segPos + 6, 4650 Parent => $markerName, 4651 DirName => 'IFD0', 3992 4652 ); 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 { 3996 4660 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 3999 4662 } 4000 4663 # 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) { 4002 4665 $writeBuffer = ''; 4003 4666 $oldOutfile = $outfile; 4004 4667 $outfile = \$writeBuffer; 4005 4668 # 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}; 4007 4671 } 4008 4672 # delete segment if IFD contains no entries 4009 4673 $del = 1 unless length($$segDataPt) > length($exifAPP1hdr); 4010 4674 # check for XMP data 4011 } elsif ($$segDataPt =~ /^ $xmpAPP1hdr/) {4675 } elsif ($$segDataPt =~ /^($xmpAPP1hdr|$xmpExtAPP1hdr)/) { 4012 4676 $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; 4015 4679 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 } 4016 4730 my $start = length $xmpAPP1hdr; 4017 4731 my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main'); 4018 4732 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), 4026 4738 ); 4027 4739 my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr); 4028 4740 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 } 4033 4751 } else { 4034 4752 $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 4035 4778 } 4036 4779 $del = 1 unless length $$segDataPt; 4780 } elsif ($$segDataPt =~ /^http/ or $$segDataPt =~ /<exif:/) { 4781 $self->Warn('Ignored APP1 XMP segment with non-standard header', 1); 4037 4782 } 4038 4783 } elsif ($marker == 0xe2) { # APP2 (ICC Profile, FPXR) … … 4082 4827 if ($$segDataPt =~ /^(Meta|META|Exif)\0\0/) { 4083 4828 $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; 4085 4854 } 4086 4855 } elsif ($marker == 0xe5) { # APP5 (Ricoh RMETA) … … 4131 4900 next Marker; # get the next segment to combine 4132 4901 } 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 } 4134 4908 $doneDir{Photoshop} = 1; 4135 4909 # process APP13 Photoshop record … … 4163 4937 unless ($$delGroup{File} and $$delGroup{File} != 2) { 4164 4938 my $tagInfo = $Image::ExifTool::Extra{Comment}; 4165 my $n ewValueHash = $self->GetNewValueHash($tagInfo);4166 if (IsOverwriting($n ewValueHash, $segData) or $$delGroup{File}) {4167 $newComment = GetNewValues($n ewValueHash);4939 my $nvHash = $self->GetNewValueHash($tagInfo); 4940 if (IsOverwriting($nvHash, $segData) or $$delGroup{File}) { 4941 $newComment = GetNewValues($nvHash); 4168 4942 } else { 4169 4943 delete $$editDirs{COM}; # we aren't editing COM after all … … 4172 4946 } 4173 4947 } 4174 $ verbose > 1 and print $out " - Comment = '$$segDataPt'\n";4948 $self->VerboseValue('- Comment', $$segDataPt); 4175 4949 if (defined $newComment and length $newComment) { 4176 4950 # write out the comments 4177 $ verbose > 1 and print $out " + Comment = '$newComment'\n";4951 $self->VerboseValue('+ Comment', $newComment); 4178 4952 WriteMultiSegment($outfile, 0xfe, '', \$newComment) or $err = 1; 4179 4953 } else { … … 4198 4972 my $size = length($$segDataPt); 4199 4973 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)"); 4201 4976 $err = 1; 4202 4977 } else { … … 4207 4982 } 4208 4983 } 4984 pop @$path if @$path > $pn; 4209 4985 # if oldOutfile is still set, there was an error copying the JPEG 4210 4986 $oldOutfile and return 0; … … 4214 4990 Write($outfile, $$trailPt) or $err = 1 if $trailPt; 4215 4991 } 4216 $/ = $oldsep; # restore separator to original value4217 4992 # set return value to -1 if we only had a write error 4218 4993 $rtnVal = -1 if $rtnVal and $err; … … 4244 5019 { 4245 5020 my ($valPtr, $format, $count) = @_; 4246 my (@vals, $ n);5021 my (@vals, $val, $n); 4247 5022 4248 5023 if ($format eq 'string' or $format eq 'undef') { … … 4266 5041 @vals = ( $$valPtr ); 4267 5042 } 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 } 4271 5047 for ($n=0; $n<$count; ++$n) { 4272 5048 $val = shift @vals; … … 4288 5064 } elsif ($format =~ /^rational/ or $format eq 'float' or $format eq 'double') { 4289 5065 # 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 } 4291 5077 if ($format =~ /^rational\d+u$/ and $val < 0) { 4292 5078 return 'Must be a positive number'; … … 4325 5111 4326 5112 #------------------------------------------------------------------------------ 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 5116 sub 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 #------------------------------------------------------------------------------ 4327 5131 # copy image data from one file to another 4328 5132 # Inputs: 0) ExifTool object reference … … 4334 5138 my ($self, $imageDataBlocks, $outfile) = @_; 4335 5139 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; 4337 5143 foreach $dataBlock (@$imageDataBlocks) { 4338 5144 my ($pos, $size, $pad) = @$dataBlock; 4339 5145 $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'; 4347 5148 # pad if necessary 4348 5149 Write($outfile, "\0" x $pad) or $err = 'writ' if $pad; … … 4366 5167 4367 5168 # get default format ('int8u' unless specified) 5169 my $dataPt = $$dirInfo{DataPt} or return undef; 4368 5170 my $defaultFormat = $$tagTablePtr{FORMAT} || 'int8u'; 4369 5171 my $increment = FormatSize($defaultFormat); … … 4373 5175 } 4374 5176 # extract data members first if necessary 5177 my @varOffsets; 4375 5178 if ($$tagTablePtr{DATAMEMBER}) { 4376 5179 $$dirInfo{DataMember} = $$tagTablePtr{DATAMEMBER}; 5180 $$dirInfo{VarFormatData} = \@varOffsets; 4377 5181 $self->ProcessBinaryData($dirInfo, $tagTablePtr); 4378 5182 delete $$dirInfo{DataMember}; 4379 }4380 my $dataPt = $$dirInfo{DataPt};5183 delete $$dirInfo{VarFormatData}; 5184 } 4381 5185 my $dirStart = $$dirInfo{DirStart} || 0; 4382 5186 my $dirLen = $$dirInfo{DirLen} || length($$dataPt) - $dirStart; 4383 5187 my $newData = substr($$dataPt, $dirStart, $dirLen) or return undef; 4384 5188 my $dirName = $$dirInfo{DirName}; 4385 my $verbose = $self->Options('Verbose'); 5189 my $varSize = 0; 5190 my @varInfo = @varOffsets; 4386 5191 my $tagInfo; 4387 5192 $dataPt = \$newData; 4388 5193 foreach $tagInfo ($self->GetNewTagInfoList($tagTablePtr)) { 4389 5194 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 } 4393 5205 my $count = 1; 4394 5206 my $format = $$tagInfo{Format}; 5207 my $entry = int($tagID) * $increment + $varSize; # relative offset of this entry 4395 5208 if ($format) { 4396 5209 if ($format =~ /(.*)\[(.*)\]/) { … … 4399 5212 my $size = $dirLen; # used in eval 4400 5213 # 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 4402 5215 $count = eval $count; 4403 5216 $@ 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; 4404 5220 } 4405 5221 } else { 4406 5222 $format = $defaultFormat; 4407 5223 } 4408 my $entry = $tagID * $increment; # relative offset of this entry4409 5224 my $val = ReadValue($dataPt, $entry, $format, $count, $dirLen-$entry); 4410 5225 next unless defined $val; 4411 my $n ewValueHash = $self->GetNewValueHash($tagInfo);4412 next unless IsOverwriting($n ewValueHash, $val);4413 my $newVal = GetNewValues($n ewValueHash);5226 my $nvHash = $self->GetNewValueHash($tagInfo); 5227 next unless IsOverwriting($nvHash, $val); 5228 my $newVal = GetNewValues($nvHash); 4414 5229 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; 4415 5233 # set the size 4416 5234 if ($$tagInfo{DataTag} and not $$tagInfo{IsOffset}) { … … 4418 5236 my $data = $self->GetNewValues($$tagInfo{DataTag}); 4419 5237 $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 } 4420 5242 } 4421 5243 my $rtnVal = WriteValue($newVal, $format, $count, $dataPt, $entry); 4422 5244 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); 4428 5247 ++$self->{CHANGED}; 4429 5248 } 4430 5249 } 4431 5250 # 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; 4433 5254 my $fixup = $$dirInfo{Fixup}; 4434 5255 my $tagID; 4435 5256 foreach $tagID (@{$tagTablePtr->{IS_OFFSET}}) { 4436 5257 $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) 4438 5263 next unless $entry <= $dirLen - 4; 4439 5264 # (Ricoh has 16-bit preview image offsets, so can't just assume int32u) 4440 5265 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; 4441 5269 $fixup->AddFixup($entry, $$tagInfo{DataTag}, $format); 4442 5270 # handle the preview image now if this is a JPEG file 4443 5271 next unless $self->{FILE_TYPE} eq 'JPEG' and $$tagInfo{DataTag} and 4444 5272 $$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; 4447 5277 my $size = ReadValue($dataPt, $entry, $format, 1, $dirLen-$entry); 4448 5278 my $previewInfo = $self->{PREVIEW_INFO}; 4449 5279 $previewInfo or $previewInfo = $self->{PREVIEW_INFO} = { }; 4450 5280 # 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}) { 4454 5286 if ($offset >= 0 and $offset + $size <= $$dirInfo{DataLen}) { 4455 $ previewInfo->{Data} = substr(${$$dirInfo{DataPt}},$offset,$size);5287 $$previewInfo{Data} = substr(${$$dirInfo{DataPt}},$offset,$size); 4456 5288 } 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; 4460 5321 } 4461 5322 } … … 4470 5331 { 4471 5332 my ($self, $dirInfo, $tagTablePtr) = @_; 4472 my $buff ;5333 my $buff = ''; 4473 5334 $$dirInfo{OutFile} = \$buff; 4474 5335 return $buff if $self->ProcessTIFF($dirInfo, $tagTablePtr) > 0; … … 4495 5356 =head1 AUTHOR 4496 5357 4497 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)5358 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 4498 5359 4499 5360 This library is free software; you can redistribute it and/or modify it -
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/XMP.pm
r16842 r24107 11 11 # 08/25/2006 - P. Harvey Added ability to handle blank nodes 12 12 # 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) 13 14 # 14 15 # References: 1) http://www.adobe.com/products/xmp/pdfs/xmpspec.pdf … … 17 18 # 4) http://www.iptc.org/IPTC4XMP/ 18 19 # 5) http://creativecommons.org/technology/xmp 20 # --> changed to http://wiki.creativecommons.org/Companion_File_metadata_specification (2007/12/21) 19 21 # 6) http://www.optimasc.com/products/fileid/xmp-extensions.pdf 20 22 # 7) Lou Salkind private communication 21 23 # 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) 22 26 # 23 # Notes: - I am handling property qualifiersas if they were separate27 # Notes: - Property qualifiers are handled as if they were separate 24 28 # properties (with no associated namespace). 25 29 # … … 36 40 37 41 use strict; 38 use vars qw($VERSION $AUTOLOAD @ISA @EXPORT_OK); 42 use vars qw($VERSION $AUTOLOAD @ISA @EXPORT_OK $xlatNamespace %nsURI %dateTimeInfo 43 %xmpTableDefaults %specialStruct %sDimensions %sArea %sColorant); 39 44 use Image::ExifTool qw(:Utils); 40 45 use Image::ExifTool::Exif; 41 46 require Exporter; 42 47 43 $VERSION = ' 1.78';48 $VERSION = '2.37'; 44 49 @ISA = qw(Exporter); 45 50 @EXPORT_OK = qw(EscapeXML UnescapeXML); … … 47 52 sub ProcessXMP($$;$); 48 53 sub WriteXMP($$;$); 54 sub CheckXMP($$$); 49 55 sub ParseXMPElement($$$;$$$); 50 56 sub DecodeBase64($); … … 53 59 sub ValidateXMP($;$); 54 60 sub UnescapeChar($$); 61 sub AddFlattenedTags($$); 62 sub FormatXMPDate($); 63 sub ConvertRational($); 64 65 my %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 69 my %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 79 my %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 155 my %uri2ns; 156 { 157 my $ns; 158 foreach $ns (keys %nsURI) { 159 $uri2ns{$nsURI{$ns}} = $ns; 160 } 161 } 55 162 56 163 # conversions for GPS coordinates … … 80 187 PrintConvInv => \&ToDegrees, 81 188 ); 82 my%dateTimeInfo = (83 Groups => { 2 => 'Time' },189 %dateTimeInfo = ( 190 # NOTE: Do NOT put "Groups" here because Groups hash must not be common! 84 191 Writable => 'date', 85 192 Shift => 'Time', 86 193 PrintConv => '$self->ConvertDateTime($val)', 194 PrintConvInv => '$self->InverseDateTime($val,undef,1)', 87 195 ); 88 196 89 197 # 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) 199 my %ignoreNamespace = ( 'x'=>1, rdf=>1, xmlns=>1, xml=>1, svg=>1, et=>1, office=>1 ); 104 200 105 201 # these are the attributes that we handle for properties that contain … … 107 203 # just copy them over. These are harder since we don't store attributes 108 204 # for properties without simple values. (maybe this will change...) 205 # (special attributes are indicated by a list reference of tag information) 109 206 my %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' ], 113 210 'rdf:parseType' => 1, 114 211 '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. 232 my %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 ); 255 my %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 ); 266 my %sJobRef = ( 267 STRUCT_NAME => 'JobRef', 268 NAMESPACE => 'stJob', 269 id => { }, 270 name => { }, 271 url => { }, 272 ); 273 my %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 ); 282 my %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 ); 293 my %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 ); 345 my %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 ); 357 my %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) 367 my %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 ); 381 my %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 399 my %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) 118 411 %Image::ExifTool::XMP::Main = ( 119 412 GROUPS => { 2 => 'Unknown' }, … … 136 429 SubDirectory => { TagTable => 'Image::ExifTool::XMP::xmpRights' }, 137 430 }, 431 xmpNote => { 432 Name => 'xmpNote', 433 SubDirectory => { TagTable => 'Image::ExifTool::XMP::xmpNote' }, 434 }, 138 435 xmpMM => { 139 436 Name => 'xmpMM', … … 151 448 Name => 'pdf', 152 449 SubDirectory => { TagTable => 'Image::ExifTool::XMP::pdf' }, 450 }, 451 pdfx => { 452 Name => 'pdfx', 453 SubDirectory => { TagTable => 'Image::ExifTool::XMP::pdfx' }, 153 454 }, 154 455 photoshop => { … … 177 478 SubDirectory => { TagTable => 'Image::ExifTool::XMP::iptcCore' }, 178 479 }, 480 iptcExt => { 481 Name => 'iptcExt', 482 SubDirectory => { TagTable => 'Image::ExifTool::XMP::iptcExt' }, 483 }, 179 484 PixelLive => { 180 485 SubDirectory => { TagTable => 'Image::ExifTool::XMP::PixelLive' }, … … 184 489 SubDirectory => { TagTable => 'Image::ExifTool::XMP::xmpPLUS' }, 185 490 }, 491 plus => { 492 Name => 'plus', 493 SubDirectory => { TagTable => 'Image::ExifTool::XMP::plus' }, 494 }, 186 495 cc => { 187 496 Name => 'cc', … … 202 511 microsoft => { 203 512 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' }, 205 522 }, 206 523 lr => { … … 211 528 Name => 'DICOM', 212 529 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' }, 213 582 }, 214 583 ); … … 219 588 # Writable - only need to define this for writable tags if not plain text 220 589 # (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) 222 592 # 223 593 # (Note that family 1 group names are generated from the property namespace, not 224 594 # the group1 names below which exist so the groups will appear in the list.) 225 595 # 226 my%xmpTableDefaults = (596 %xmpTableDefaults = ( 227 597 WRITE_PROC => \&WriteXMP, 598 CHECK_PROC => \&CheckXMP, 228 599 WRITABLE => 'string', 229 600 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 }, 230 627 ); 231 628 … … 234 631 %xmpTableDefaults, 235 632 GROUPS => { 1 => 'XMP-dc', 2 => 'Other' }, 236 NAMESPACE => 'dc', 633 NAMESPACE => 'dc', 634 TABLE_DESC => 'XMP Dublin Core', 237 635 NOTES => 'Dublin Core schema tags.', 238 636 contributor => { Groups => { 2 => 'Author' }, List => 'Bag' }, 239 637 coverage => { }, 240 638 creator => { Groups => { 2 => 'Author' }, List => 'Seq' }, 241 date => { %dateTimeInfo, List => 'Seq'},639 date => { Groups => { 2 => 'Time' }, List => 'Seq', %dateTimeInfo }, 242 640 description => { Groups => { 2 => 'Image' }, Writable => 'lang-alt' }, 243 641 'format' => { Groups => { 2 => 'Image' } }, … … 247 645 relation => { List => 'Bag' }, 248 646 rights => { Groups => { 2 => 'Author' }, Writable => 'lang-alt' }, 249 source => { Groups => { 2 => 'Author' } },647 source => { Groups => { 2 => 'Author' }, Avoid => 1 }, 250 648 subject => { Groups => { 2 => 'Image' }, List => 'Bag' }, 251 649 title => { Groups => { 2 => 'Image' }, Writable => 'lang-alt' }, … … 257 655 %xmpTableDefaults, 258 656 GROUPS => { 1 => 'XMP-xmp', 2 => 'Image' }, 259 NAMESPACE => 'xmp',657 NAMESPACE => 'xmp', 260 658 NOTES => q{ 261 659 XMP Basic schema tags. If the older "xap", "xapBJ", "xapMM" or "xapRights" … … 263 661 "xmpBJ", "xmpMM" and "xmpRights" prefixes for use in family 1 group names. 264 662 }, 265 Advisory => { List => 'Bag' }, 663 Advisory => { List => 'Bag' }, # (deprecated) 266 664 BaseURL => { }, 267 CreateDate => { %dateTimeInfo }, 665 # (date/time tags not as reliable as EXIF) 666 CreateDate => { Groups => { 2 => 'Time' }, %dateTimeInfo, Priority => 0 }, 268 667 CreatorTool => { }, 269 668 Identifier => { Avoid => 1, List => 'Bag' }, 270 669 Label => { }, 271 MetadataDate=> { %dateTimeInfo },272 ModifyDate => { %dateTimeInfo},670 MetadataDate=> { Groups => { 2 => 'Time' }, %dateTimeInfo }, 671 ModifyDate => { Groups => { 2 => 'Time' }, %dateTimeInfo, Priority => 0 }, 273 672 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 }, 291 686 ); 292 687 … … 295 690 %xmpTableDefaults, 296 691 GROUPS => { 1 => 'XMP-xmpRights', 2 => 'Author' }, 297 NAMESPACE => 'xmpRights',692 NAMESPACE => 'xmpRights', 298 693 NOTES => 'XMP Rights Management schema tags.', 299 694 Certificate => { }, … … 304 699 ); 305 700 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) 711 my %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 722 my %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 306 732 # XMP Media Management schema properties (xmpMM, xapMM) 307 733 %Image::ExifTool::XMP::xmpMM = ( 308 734 %xmpTableDefaults, 309 735 GROUPS => { 1 => 'XMP-xmpMM', 2 => 'Other' }, 310 NAMESPACE => 'xmpMM', 736 NAMESPACE => 'xmpMM', 737 TABLE_DESC => 'XMP Media Management', 311 738 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 }, 325 740 DocumentID => { }, 326 History => { 327 SubDirectory => { }, 328 Struct => 'ResourceEvent', 329 List => 'Seq', 330 }, 741 History => { Struct => \%sResourceEvent, List => 'Seq' }, 331 742 # 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' }, 337 744 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 }, 348 746 Manager => { Groups => { 2 => 'Author' } }, 349 747 ManageTo => { Groups => { 2 => 'Author' } }, 350 748 ManageUI => { }, 351 749 ManagerVariant => { }, 750 Manifest => { Struct => \%sManifestItem, List => 'Bag' }, 751 OriginalDocumentID=> { }, 752 Pantry => { Struct => \%sPantryItem, List => 'Bag' }, 352 753 PreservedFileName => { }, # undocumented 353 754 RenditionClass => { }, 354 755 RenditionParams => { }, 355 756 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) 383 761 ); 384 762 … … 387 765 %xmpTableDefaults, 388 766 GROUPS => { 1 => 'XMP-xmpBJ', 2 => 'Other' }, 389 NAMESPACE => 'xmpBJ', 767 NAMESPACE => 'xmpBJ', 768 TABLE_DESC => 'XMP Basic Job Ticket', 390 769 NOTES => 'XMP Basic Job Ticket schema tags.', 391 770 # Note: JobRef is a List of structures. To accomplish this, we set the XMP 392 771 # List=>'Bag', but since SubDirectory is defined, this tag isn't writable 393 772 # 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' }, 403 775 ); 404 776 … … 407 779 %xmpTableDefaults, 408 780 GROUPS => { 1 => 'XMP-xmpTPg', 2 => 'Image' }, 409 NAMESPACE => 'xmpTPg', 781 NAMESPACE => 'xmpTPg', 782 TABLE_DESC => 'XMP Paged-Text', 410 783 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' }, 587 810 ); 588 811 … … 591 814 %xmpTableDefaults, 592 815 GROUPS => { 1 => 'XMP-pdf', 2 => 'Image' }, 593 NAMESPACE => 'pdf', 816 NAMESPACE => 'pdf', 817 TABLE_DESC => 'XMP PDF', 594 818 NOTES => q{ 595 819 Adobe PDF schema tags. The official XMP specification defines only 596 Keywords, PDFVersion and Producer. The other tags are included because they597 have been observed in PDF files, but Creator, Subject and Title are avoided598 w hen 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. 599 823 }, 600 824 Author => { Groups => { 2 => 'Author' } }, #PH 601 ModDate => { %dateTimeInfo }, #PH602 CreationDate=> { %dateTimeInfo }, #PH825 ModDate => { Groups => { 2 => 'Time' }, %dateTimeInfo }, #PH 826 CreationDate=> { Groups => { 2 => 'Time' }, %dateTimeInfo }, #PH 603 827 Creator => { Groups => { 2 => 'Author' }, Avoid => 1 }, 828 Copyright => { Groups => { 2 => 'Author' }, Avoid => 1 }, #PH 829 Marked => { Avoid => 1, Writable => 'boolean' }, #PH 604 830 Subject => { Avoid => 1 }, 605 831 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 }, 606 838 Keywords => { }, 607 839 PDFVersion => { }, 608 840 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 }, 609 853 ); 610 854 … … 613 857 %xmpTableDefaults, 614 858 GROUPS => { 1 => 'XMP-photoshop', 2 => 'Image' }, 615 NAMESPACE => 'photoshop', 859 NAMESPACE => 'photoshop', 860 TABLE_DESC => 'XMP Photoshop', 616 861 NOTES => 'Adobe Photoshop schema tags.', 617 862 AuthorsPosition => { Groups => { 2 => 'Author' } }, … … 619 864 Category => { }, 620 865 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 }, 621 880 Country => { Groups => { 2 => 'Location' } }, 622 ColorMode => { }, #PH623 881 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 => { }, 625 893 History => { }, #PH (CS3) 626 Headline => { },894 ICCProfile => { Name => 'ICCProfileName' }, #PH 627 895 Instructions => { }, 628 ICCProfile => { Name => 'ICCProfileName' }, #PH629 896 LegacyIPTCDigest=> { }, #PH 630 897 SidecarForExtension => { }, #PH (CS3) 631 Source => { Groups => { 2 => 'Author' } , Avoid => 1},898 Source => { Groups => { 2 => 'Author' } }, 632 899 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 635 904 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' }, 636 916 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 }, 638 933 ); 639 934 … … 642 937 %xmpTableDefaults, 643 938 GROUPS => { 1 => 'XMP-crs', 2 => 'Image' }, 644 NAMESPACE => 'crs', 939 NAMESPACE => 'crs', 940 TABLE_DESC => 'Photoshop Camera Raw Schema', 645 941 NOTES => 'Photoshop Camera Raw Schema tags.', 646 942 AlreadyApplied => { Writable => 'boolean' }, #PH (written by LightRoom beta 4.1) … … 657 953 ColorNoiseReduction => { Writable => 'integer' }, 658 954 Contrast => { Writable => 'integer', Avoid => 1 }, 955 Converter => { }, #PH guess (found in EXIF) 659 956 CropTop => { Writable => 'real' }, 660 957 CropLeft => { Writable => 'real' }, … … 678 975 HasSettings => { Writable => 'boolean' }, 679 976 LuminanceSmoothing => { Writable => 'integer' }, 977 MoireFilter => { PrintConv => { Off=>'Off', On=>'On' } }, 680 978 RawFileName => { }, 681 979 RedHue => { Writable => 'integer' }, … … 685 983 ShadowTint => { Writable => 'integer' }, 686 984 Sharpness => { Writable => 'integer', Avoid => 1 }, 687 Temperature => { Writable => 'integer' }, 985 Smoothness => { Writable => 'integer' }, 986 Temperature => { Writable => 'integer', Avoid => 1, Name => 'ColorTemperature' }, 688 987 Tint => { Writable => 'integer' }, 689 988 ToneCurve => { List => 'Seq' }, … … 762 1061 SplitToningShadowSaturation => { Writable => 'integer' }, 763 1062 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' }, 764 1292 ); 765 1293 … … 768 1296 %xmpTableDefaults, 769 1297 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', 771 1301 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 }, 778 1305 Compression => { 779 1306 Writable => 'integer', 1307 SeparateTable => 'EXIF Compression', 780 1308 PrintConv => \%Image::ExifTool::Exif::compression, 781 1309 }, … … 796 1324 }, 797 1325 }, 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 }, 808 1327 YCbCrPositioning => { 809 1328 Writable => 'integer', … … 817 1336 ResolutionUnit => { 818 1337 Writable => 'integer', 1338 Notes => 'the value 1 is not standard EXIF', 819 1339 PrintConv => { 820 1340 1 => 'None', … … 824 1344 }, 825 1345 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) 831 1351 Description => 'Date/Time Modified', 1352 Groups => { 2 => 'Time' }, 832 1353 %dateTimeInfo, 833 1354 }, 834 1355 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' }, 840 1358 Software => { }, 841 1359 Artist => { Groups => { 2 => 'Author' } }, 842 Copyright => { 843 Groups => { 2 => 'Author' }, 844 Writable => 'lang-alt', 845 }, 1360 Copyright => { Groups => { 2 => 'Author' }, Writable => 'lang-alt' }, 846 1361 NativeDigest => { }, #PH 847 1362 ); … … 851 1366 %xmpTableDefaults, 852 1367 GROUPS => { 1 => 'XMP-exif', 2 => 'Image' }, 853 NAMESPACE => 'exif', 1368 NAMESPACE => 'exif', 1369 PRIORITY => 0, # not as reliable as actual EXIF tags 854 1370 NOTES => 'EXIF schema for EXIF tags.', 855 1371 ExifVersion => { }, … … 857 1373 ColorSpace => { 858 1374 Writable => 'integer', 1375 # (some applications incorrectly write -1 as a long integer) 1376 ValueConv => '$val == 0xffffffff ? 0xffff : $val', 1377 ValueConvInv => '$val', 859 1378 PrintConv => { 860 1379 1 => 'sRGB', 861 1380 2 => 'Adobe RGB', 862 1381 0xffff => 'Uncalibrated', 863 0xffffffff => 'Uncalibrated',864 1382 }, 865 1383 }, … … 867 1385 List => 'Seq', 868 1386 Writable => 'integer', 869 PrintConv => { 870 0 => '.', 1387 AutoSplit => 1, 1388 PrintConvColumns => 2, 1389 PrintConv => { 1390 0 => '-', 871 1391 1 => 'Y', 872 1392 2 => 'Cb', … … 877 1397 }, 878 1398 }, 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' }, 894 1404 RelatedSoundFile => { }, 895 1405 DateTimeOriginal => { 896 1406 Description => 'Date/Time Original', 1407 Groups => { 2 => 'Time' }, 897 1408 %dateTimeInfo, 898 1409 }, 899 DateTimeDigitized => { 1410 DateTimeDigitized => { # (EXIF tag named CreateDate, but this exists in XMP-xmp) 900 1411 Description => 'Date/Time Digitized', 1412 Groups => { 2 => 'Time' }, 901 1413 %dateTimeInfo, 902 1414 }, … … 904 1416 Writable => 'rational', 905 1417 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 906 PrintConvInv => ' eval $val',1418 PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', 907 1419 }, 908 1420 FNumber => { … … 915 1427 Writable => 'integer', 916 1428 PrintConv => { 1429 0 => 'Not Defined', 917 1430 1 => 'Manual', 918 1431 2 => 'Program AE', … … 925 1438 }, 926 1439 }, 927 SpectralSensitivity => { 928 Groups => { 2 => 'Camera' }, 929 }, 1440 SpectralSensitivity => { Groups => { 2 => 'Camera' } }, 930 1441 ISOSpeedRatings => { 931 1442 Name => 'ISO', 932 1443 Writable => 'integer', 933 1444 List => 'Seq', 1445 AutoSplit => 1, 934 1446 }, 935 1447 OECF => { 936 1448 Name => 'Opto-ElectricConvFactor', 937 1449 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 }, 958 1456 ShutterSpeedValue => { 959 1457 Writable => 'rational', … … 961 1459 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 962 1460 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)', 965 1462 }, 966 1463 ApertureValue => { … … 971 1468 PrintConvInv => '$val', 972 1469 }, 973 BrightnessValue => { 974 Writable => 'rational', 975 }, 1470 BrightnessValue => { Writable => 'rational' }, 976 1471 ExposureBiasValue => { 977 1472 Name => 'ExposureCompensation', 978 1473 Writable => 'rational', 979 PrintConv => 'Image::ExifTool::Exif:: ConvertFraction($val)',1474 PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)', 980 1475 PrintConvInv => '$val', 981 1476 }, … … 991 1486 Groups => { 2 => 'Camera' }, 992 1487 Writable => 'rational', 993 PrintConv => '$val eq "inf"? $val : "$val m"',1488 PrintConv => '$val =~ /^(inf|undef)$/ ? $val : "$val m"', 994 1489 PrintConvInv => '$val=~s/\s*m$//;$val', 995 1490 }, … … 1009 1504 LightSource => { 1010 1505 Groups => { 2 => 'Camera' }, 1506 SeparateTable => 'EXIF LightSource', 1011 1507 PrintConv => \%Image::ExifTool::Exif::lightSource, 1012 1508 }, 1013 1509 Flash => { 1014 1510 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 }, 1048 1535 }, 1049 1536 FocalLength=> { 1050 1537 Groups => { 2 => 'Camera' }, 1051 1538 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' }, 1063 1544 SpatialFrequencyResponse => { 1064 1545 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' }, 1093 1550 FocalPlaneResolutionUnit => { 1094 1551 Groups => { 2 => 'Camera' }, 1095 1552 Writable => 'integer', 1553 Notes => 'values 1, 4 and 5 are not standard EXIF', 1096 1554 PrintConv => { 1097 1555 1 => 'None', # (not standard EXIF) … … 1102 1560 }, 1103 1561 }, 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' }, 1111 1564 SensingMethod => { 1112 1565 Groups => { 2 => 'Camera' }, 1113 1566 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) 1116 1570 2 => 'One-chip color area', 1117 1571 3 => 'Two-chip color area', 1118 1572 4 => 'Three-chip color area', 1119 1573 5 => 'Color sequential area', 1574 6 => 'Monochrome linear', # (not standard EXIF) 1120 1575 7 => 'Trilinear', 1121 1576 8 => 'Color sequential linear', … … 1132 1587 SceneType => { Writable => 'integer', PrintConv => { 1 => 'Directly photographed' } }, 1133 1588 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 }, 1140 1597 CustomRendered => { 1141 1598 Writable => 'integer', … … 1167 1624 Writable => 'integer', 1168 1625 Groups => { 2 => 'Camera' }, 1626 PrintConv => '"$val mm"', 1627 PrintConvInv => '$val=~s/\s*mm$//;$val', 1169 1628 }, 1170 1629 SceneCaptureType => { … … 1221 1680 DeviceSettingDescription => { 1222 1681 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 }, 1237 1689 }, 1238 1690 SubjectDistanceRange => { … … 1261 1713 Groups => { 2 => 'Location' }, 1262 1714 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"', 1264 1719 PrintConvInv => '$val=~s/\s*m$//;$val', 1265 1720 }, 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 }, 1267 1733 GPSSatellites => { Groups => { 2 => 'Location' } }, 1268 1734 GPSStatus => { 1269 1735 Groups => { 2 => 'Location' }, 1270 1736 PrintConv => { 1271 A => 'Measurement In Progress',1272 V => 'Measurement Interoperability',1737 A => 'Measurement Active', 1738 V => 'Measurement Void', 1273 1739 }, 1274 1740 }, … … 1281 1747 }, 1282 1748 }, 1283 GPSDOP => { 1284 Groups => { 2 => 'Location' }, 1285 Writable => 'rational', 1286 }, 1749 GPSDOP => { Groups => { 2 => 'Location' }, Writable => 'rational' }, 1287 1750 GPSSpeedRef => { 1288 1751 Groups => { 2 => 'Location' }, … … 1293 1756 }, 1294 1757 }, 1295 GPSSpeed => { 1296 Groups => { 2 => 'Location' }, 1297 Writable => 'rational', 1298 }, 1758 GPSSpeed => { Groups => { 2 => 'Location' }, Writable => 'rational' }, 1299 1759 GPSTrackRef => { 1300 1760 Groups => { 2 => 'Location' }, … … 1304 1764 }, 1305 1765 }, 1306 GPSTrack => { 1307 Groups => { 2 => 'Location' }, 1308 Writable => 'rational', 1309 }, 1766 GPSTrack => { Groups => { 2 => 'Location' }, Writable => 'rational' }, 1310 1767 GPSImgDirectionRef => { 1311 1768 PrintConv => { … … 1314 1771 }, 1315 1772 }, 1316 GPSImgDirection => { 1317 Groups => { 2 => 'Location' }, 1318 Writable => 'rational', 1319 }, 1773 GPSImgDirection => { Groups => { 2 => 'Location' }, Writable => 'rational' }, 1320 1774 GPSMapDatum => { Groups => { 2 => 'Location' } }, 1321 1775 GPSDestLatitude => { Groups => { 2 => 'Location' }, %latConv }, … … 1328 1782 }, 1329 1783 }, 1330 GPSDestBearing => { 1331 Groups => { 2 => 'Location' }, 1332 Writable => 'rational', 1333 }, 1784 GPSDestBearing => { Groups => { 2 => 'Location' }, Writable => 'rational' }, 1334 1785 GPSDestDistanceRef => { 1335 1786 Groups => { 2 => 'Location' }, … … 1357 1808 ); 1358 1809 1359 # Auxiliary schema properties (aux) - not fully documented 1810 # Auxiliary schema properties (aux) - not fully documented (ref PH) 1360 1811 %Image::ExifTool::XMP::aux = ( 1361 1812 %xmpTableDefaults, 1362 1813 GROUPS => { 1 => 'XMP-aux', 2 => 'Camera' }, 1363 NAMESPACE => 'aux',1814 NAMESPACE => 'aux', 1364 1815 NOTES => 'Photoshop Auxiliary schema tags.', 1365 1816 Firmware => { }, #7 1366 1817 FlashCompensation => { Writable => 'rational' }, #7 1367 1818 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 }, 1369 1848 Lens => { }, 1370 1849 OwnerName => { }, #7 1371 1850 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) 1375 1863 %Image::ExifTool::XMP::iptcCore = ( 1376 1864 %xmpTableDefaults, 1377 1865 GROUPS => { 1 => 'XMP-iptcCore', 2 => 'Author' }, 1378 NAMESPACE => 'Iptc4xmpCore', 1866 NAMESPACE => 'Iptc4xmpCore', 1867 TABLE_DESC => 'XMP IPTC Core', 1379 1868 NOTES => q{ 1380 IPTC Core schema tags. The actual IPTC Core namespace schemaprefix is1869 IPTC Core schema tags. The actual IPTC Core namespace prefix is 1381 1870 "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/>) 1383 1873 }, 1384 1874 CountryCode => { Groups => { 2 => 'Location' } }, 1385 1875 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' }, 1397 1897 IntellectualGenre => { Groups => { 2 => 'Other' } }, 1398 1898 Location => { Groups => { 2 => 'Location' } }, … … 1401 1901 ); 1402 1902 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', 1408 1909 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, 1484 1941 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' }, 1519 1973 ); 1520 1974 … … 1523 1977 %xmpTableDefaults, 1524 1978 GROUPS => { 1 => 'XMP-lr', 2 => 'Image' }, 1525 NAMESPACE => 'lr', 1979 NAMESPACE => 'lr', 1980 TABLE_DESC => 'XMP Adobe Lightroom', 1526 1981 NOTES => 'Adobe Lightroom "lr" schema tags.', 1527 1982 privateRTKInfo => { }, … … 1529 1984 ); 1530 1985 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 = ( 1533 1988 %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 => { }, 1555 1994 ); 1556 1995 … … 1566 2005 # (used to set EXIF GPS position from XMP tags) 1567 2006 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 }, 1572 2013 PrintConv => { 1573 2014 N => 'North', … … 1576 2017 }, 1577 2018 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 }, 1582 2025 PrintConv => { 1583 2026 E => 'East', … … 1620 2063 my ($str, $conv) = @_; 1621 2064 $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 2073 sub FullEscapeXML($) 2074 { 2075 my $str = shift; 2076 $str =~ s/([&><'"])/&$charName{$1};/sg; # escape necessary XML characters 2077 $str =~ s/\\/\/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 2089 sub 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; 1622 2095 $str =~ s/&(#?\w+);/UnescapeChar($1,$conv)/sge; 1623 2096 return $str; … … 1639 2112 $val = $1; 1640 2113 } 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 2128 sub 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 2162 sub 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; 1651 2181 } 1652 2182 … … 1654 2184 # Utility routine to decode a base64 string 1655 2185 # Inputs: 0) base64 string 1656 # Returns: 2186 # Returns: reference to decoded data 1657 2187 sub DecodeBase64($) 1658 2188 { … … 1662 2192 # truncate at first unrecognized character (base 64 data 1663 2193 # 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; 1665 2195 # translate to uucoded and remove padding and white space 1666 2196 $str =~ tr/A-Za-z0-9+\/= \t\n\r\f/ -_/d; … … 1689 2219 #------------------------------------------------------------------------------ 1690 2220 # 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) 2224 sub GetXMPTagID($;$$) 1694 2225 { 1695 my $props = shift;2226 my ($props, $structProps, $nsList) = @_; 1696 2227 my ($tag, $prop, $namespace); 1697 2228 foreach $prop (@$props) { … … 1699 2230 # (Note: namespace can be '' for property qualifiers) 1700 2231 my ($ns, $nm) = ($prop =~ /(.*?):(.*)/) ? ($1, $2) : ('', $prop); 1701 $nm =~ s/ .*//; # remove nodeID if it exists1702 2232 if ($ignoreNamespace{$ns}) { 1703 2233 # 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; 1706 2242 } else { 2243 $nm =~ s/ .*//; # remove nodeID if it exists 1707 2244 # all uppercase is ugly, so convert it 1708 2245 if ($nm !~ /[a-z]/) { 1709 my $xlatNS = $ xlatNamespace{$ns} || $ns;2246 my $xlatNS = $$xlatNamespace{$ns} || $ns; 1710 2247 my $info = $Image::ExifTool::XMP::Main{$xlatNS}; 1711 2248 my $table; 1712 2249 if (ref $info eq 'HASH' and $info->{SubDirectory}) { 1713 $table = GetTagTable($info->{SubDirectory} ->{TagTable});2250 $table = GetTagTable($info->{SubDirectory}{TagTable}); 1714 2251 } 1715 2252 unless ($table and $table->{$nm}) { … … 1723 2260 $tag = $nm; 1724 2261 } 2262 # save structure information if necessary 2263 if ($structProps) { 2264 push @$structProps, [ $nm ]; 2265 push @$nsList, $ns if $nsList; 2266 } 1725 2267 } 1726 2268 # save namespace of first property to contribute to tag name 1727 $namespace = $ns unless defined$namespace;2269 $namespace = $ns unless $namespace; 1728 2270 } 1729 2271 if (wantarray) { 1730 return ($tag, $namespace );2272 return ($tag, $namespace || ''); 1731 2273 } else { 1732 2274 return $tag; 1733 2275 } 2276 } 2277 2278 #------------------------------------------------------------------------------ 2279 # Register namespace for specified user-defined table 2280 # Inputs: 0) tag or structure table ref 2281 # Returns: namespace prefix 2282 sub 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 2311 sub 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; 1734 2395 } 1735 2396 … … 1744 2405 return undef unless $$tagInfo{Writable} and $$tagInfo{Writable} eq 'lang-alt'; 1745 2406 $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; 1747 2411 } 1748 2412 … … 1784 2448 $buff = substr($lastBuff, pos($lastBuff)); 1785 2449 } 1786 $xmp .= $buff;1787 my $pos = length($xmp) - length($buff) - 18; # 18 is length("<xpacket end...")-11788 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 1789 2453 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 1801 2459 undef $xmp; 1802 2460 } else { … … 1804 2462 } 1805 2463 } 1806 unless ($exifTool->{VALUE} ->{FileType}) {2464 unless ($exifTool->{VALUE}{FileType}) { 1807 2465 $exifTool->{FILE_TYPE} = $exifTool->{FILE_EXT}; 1808 2466 $exifTool->SetFileType('<unknown file containing XMP>'); … … 1818 2476 1819 2477 #------------------------------------------------------------------------------ 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 2481 sub 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 2497 sub 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 #------------------------------------------------------------------------------ 1820 2512 # We found an XMP property name/value 1821 2513 # Inputs: 0) ExifTool object ref, 1) Pointer to tag table 1822 2514 # 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') 1824 2516 # Returns: 1 if valid tag was found 1825 2517 sub FoundXMP($$$$;$) 1826 2518 { 1827 2519 local $_; 1828 my ($exifTool, $tagTablePtr, $props, $val, $ lang) = @_;1829 1830 my ($tag, $n amespace) = GetXMPTagID($props);2520 my ($exifTool, $tagTablePtr, $props, $val, $attrs) = @_; 2521 my ($lang, @structProps); 2522 my ($tag, $ns) = GetXMPTagID($props, $exifTool->{OPTIONS}{Struct} ? \@structProps : undef); 1831 2523 return 0 unless $tag; # ignore things that aren't valid tags 1832 2524 1833 2525 # translate namespace if necessary 1834 $n amespace = $xlatNamespace{$namespace} if $xlatNamespace{$namespace};1835 my $info = $tagTablePtr->{$n amespace};1836 my $table;2526 $ns = $$xlatNamespace{$ns} if $$xlatNamespace{$ns}; 2527 my $info = $tagTablePtr->{$ns}; 2528 my ($table, $added, $xns, $tagID); 1837 2529 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; 1839 2548 } 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) 2561 NoLoop: 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; 1852 2670 } 1853 2671 # 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 } 1859 2696 } 1860 2697 if (defined $lang and lc($lang) ne 'x-default') { … … 1863 2700 $tagInfo = $langInfo if $langInfo; 1864 2701 } 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'); 1869 2720 # convert rational and date values to a more sensible format 1870 2721 my $fmt = $$tagInfo{Writable}; 1871 2722 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 } 1888 2744 my $tagID = join('/',@$props); 1889 2745 $exifTool->VerboseInfo($tagID, $tagInfo, Value=>$val); … … 1904 2760 { 1905 2761 my ($exifTool, $tagTablePtr, $dataPt, $start, $propListPt, $blankInfo) = @_; 1906 my $count = 0;2762 my ($count, $nItems) = (0, 0); 1907 2763 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 } 1908 2774 $start or $start = 0; 1909 2775 $propListPt or $propListPt = [ ]; … … 1920 2786 my $nodeID = $$blankInfo{NodeID} = $oldNodeID; 1921 2787 # get next element 1922 last unless $$dataPt =~ m/<([ \w:-]+)(.*?)>/sg;2788 last unless $$dataPt =~ m/<([-\w:.\x80-\xff]+)(.*?)>/sg; 1923 2789 my ($prop, $attrs) = ($1, $2); 1924 2790 my $val = ''; … … 1933 2799 # my $val2 = $1; 1934 2800 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 } 1936 2805 my $len = pos($$dataPt) - $pos - length($prop) - 3; 1937 2806 my $val2 = substr($$dataPt, $pos, $len); … … 1943 2812 } 1944 2813 } 2814 my $parseResource; 1945 2815 if ($prop eq 'rdf:li') { 1946 2816 # add index to list items so we can keep them in order 1947 2817 # (this also enables us to keep structure elements grouped properly 1948 2818 # 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; 1950 2826 } elsif ($prop eq 'rdf:Description') { 1951 2827 # trim comments and whitespace from rdf:Description properties only 1952 2828 $val =~ s/<!--.*?-->//g; 1953 2829 $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; 1954 2833 } elsif ($prop eq 'xmp:xmpmeta') { 1955 2834 # patch MicrosoftPhoto unconformity … … 1959 2838 # extract property attributes 1960 2839 my (%attrs, @attrs); 1961 while ($attrs =~ m/(\S+?) =(['"])(.*?)\2/sg) {2840 while ($attrs =~ m/(\S+?)\s*=\s*(['"])(.*?)\2/sg) { 1962 2841 push @attrs, $1; # preserve order 1963 2842 $attrs{$1} = $3; 1964 2843 } 1965 2844 2845 # hook for special parsing of attributes 2846 $attrProc and &$attrProc(\@attrs, \%attrs, \$prop, \$val); 2847 1966 2848 # add nodeID to property path (with leading ' #') if it exists 1967 2849 if (defined $attrs{'rdf:nodeID'}) { … … 1969 2851 delete $attrs{'rdf:nodeID'}; 1970 2852 $prop .= ' #' . $nodeID; 2853 undef $parseResource; # can't ignore if this is a node 1971 2854 } 1972 2855 1973 2856 # 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 } 1975 2872 1976 2873 # handle properties inside element attributes (RDF shorthand format): … … 1994 2891 $name = $propName; 1995 2892 } 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 } 1996 2909 if ($isWriting) { 1997 2910 # keep track of our namespaces when writing 1998 2911 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')) { 2000 2914 my $nsUsed = $exifTool->{XMP_NS}; 2001 2915 $$nsUsed{$name} = $attrs{$shortName} unless defined $$nsUsed{$name}; 2002 2916 } 2917 delete $attrs{$shortName}; # (handled by namespace logic) 2003 2918 next; 2004 2919 } elsif ($recognizedAttrs{$propName}) { 2005 2920 # save UUID to use same ID when writing 2006 2921 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); 2011 2926 } 2012 2927 } … … 2014 2929 } 2015 2930 } 2931 my $shortVal = $attrs{$shortName}; 2016 2932 if ($ignoreNamespace{$ns}) { 2017 2933 $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 } 2018 2942 next; 2019 2943 } 2020 my $shortVal = $attrs{$shortName};2021 2944 delete $attrs{$shortName}; # don't re-use this attribute 2022 2945 push @$propListPt, $propName; … … 2027 2950 CaptureXMP($exifTool, $propListPt, $shortVal); 2028 2951 } else { 2029 FoundXMP($exifTool, $tagTablePtr, $propListPt, $shortVal);2952 &$foundProc($exifTool, $tagTablePtr, $propListPt, $shortVal); 2030 2953 } 2031 2954 pop @$propListPt; … … 2049 2972 # if element value is empty, take value from 'resource' attribute 2050 2973 # (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 } 2054 2981 # look for additional elements contained within this one 2055 2982 if (!ParseXMPElement($exifTool, $tagTablePtr, \$val, 0, $propListPt, $blankInfo)) { … … 2057 2984 # (unless we already extracted shorthand values from this element) 2058 2985 if (length $val or not $shorthand) { 2986 my $lastProp = $$propListPt[-1]; 2059 2987 if (defined $nodeID) { 2060 2988 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; 2061 2994 } else { 2062 FoundXMP($exifTool, $tagTablePtr, $propListPt, $val, $attrs{'xml:lang'});2995 &$foundProc($exifTool, $tagTablePtr, $propListPt, $val, \%attrs); 2063 2996 } 2064 2997 } 2065 2998 } 2066 2999 } 2067 pop @$propListPt ;3000 pop @$propListPt unless $parseResource; 2068 3001 ++$count; 2069 3002 } … … 2082 3015 # Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table 2083 3016 # 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 2084 3027 sub ProcessXMP($$;$) 2085 3028 { 2086 3029 my ($exifTool, $dirInfo, $tagTablePtr) = @_; 2087 3030 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); 2091 3033 my $rtnVal = 0; 2092 3034 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 2097 3054 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); 2100 3057 ($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 } 2101 3073 # 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) { 2106 3080 $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) { 2108 3082 $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) { 2110 3084 $fmt = 0; # UTF-8 with BOM or unknown encoding without BOM 2111 3085 } elsif ($buf2 =~ /^(\xfe\xff|\xff\xfe|\xef\xbb\xbf)(<\?xpacket begin=)/g) { 2112 3086 $double = $1; # double-encoded UTF 2113 3087 } else { 2114 return 0; # not XMP or XML3088 return 0; # not recognized XMP or XML 2115 3089 } 2116 3090 $bom = 1 if $1; 2117 3091 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 } 2119 3114 $isXML = 1; 3115 } elsif ($2 eq '<rdf:RDF') { 3116 $isRDF = 1; # recognize XMP without x:xmpmeta element 2120 3117 } 2121 3118 if ($buff =~ /^\0\0/) { … … 2144 3141 # as characters and look for warnings indicating a false assumption 2145 3142 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); 2147 3146 } else { 2148 3147 my $fmt = ($double eq "\xfe\xff") ? 'n' : 'v'; … … 2160 3159 $dirStart = 0; 2161 3160 $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 2165 3171 # take substring if necessary 2166 3172 if ($dataLen != $dirStart + $dirLen) { … … 2169 3175 $dirStart = 0; 2170 3176 } 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) { 2172 3179 $exifTool->FoundTag('XMP', substr($$dataPt, $dirStart, $dirLen)); 2173 3180 } 2174 3181 if ($exifTool->Options('Verbose') and not $exifTool->{XMP_CAPTURE}) { 2175 $exifTool->VerboseDir( 'XMP', 0, $dirLen);3182 $exifTool->VerboseDir($isSVG ? 'SVG' : 'XMP', 0, $dirLen); 2176 3183 } 2177 3184 # … … 2181 3188 pos($$dataPt) = $dirStart; 2182 3189 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; 2185 3194 $$exifTool{XMP_NO_XPACKET} = 1 + $bom; 2186 3195 } elsif ($$dataPt =~ /\G\Q$begin\E/gc) { 2187 3196 delete $$exifTool{XMP_NO_XPACKET}; 2188 } elsif ($$dataPt =~ /<x(mp)?:x mpmeta/gc) {3197 } elsif ($$dataPt =~ /<x(mp)?:x[ma]pmeta/gc) { 2189 3198 $$exifTool{XMP_NO_XPACKET} = 1 + $bom; 2190 3199 } else { … … 2192 3201 # check for UTF-16 encoding (insert one \0 between characters) 2193 3202 $begin = join "\0", split //, $begin; 3203 # must reset pos because it was killed by previous unsuccessful //g match 3204 pos($$dataPt) = $dirStart; 2194 3205 if ($$dataPt =~ /\G(\0)?\Q$begin\E\0./g) { 2195 3206 # validate byte ordering by checking for U+FEFF character … … 2203 3214 # check for UTF-32 encoding (with three \0's between characters) 2204 3215 $begin =~ s/\0/\0\0\0/g; 2205 # must reset pos because it was killed by previous unsuccessful //g match2206 3216 pos($$dataPt) = $dirStart; 2207 3217 if ($$dataPt !~ /\G(\0\0\0)?\Q$begin\E\0\0\0./g) { … … 2217 3227 } 2218 3228 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 2220 3235 if ($] >= 5.006001) { 2221 $buff = pack('C0U*', unpack(" x$dirStart$fmt*",$$dataPt));3236 $buff = pack('C0U*', unpack("$fmt*",$$dataPt)); 2222 3237 } else { 2223 $buff = Image::ExifTool::PackUTF8(unpack(" x$dirStart$fmt*",$$dataPt));3238 $buff = Image::ExifTool::PackUTF8(unpack("$fmt*",$$dataPt)); 2224 3239 } 2225 3240 $dataPt = \$buff; 2226 3241 $dirStart = 0; 2227 } 3242 $dirLen = length $$dataPt; 3243 } 3244 # initialize namespace translation 3245 $xlatNamespace = \%stdXlatNS; 3246 2228 3247 # avoid scanning for XMP later in case ScanForXMP is set 2229 3248 $$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'); 2230 3255 2231 3256 # parse the XMP … … 2236 3261 $$dirInfo{DataPt} = $dataPt if $rtnVal and $$dirInfo{RAF}; 2237 3262 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; 2238 3273 return $rtnVal; 2239 3274 } … … 2261 3296 =head1 AUTHOR 2262 3297 2263 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)3298 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 2264 3299 2265 3300 This library is free software; you can redistribute it and/or modify it … … 2270 3305 =over 4 2271 3306 2272 =item L<http://www.adobe.com/ products/xmp/pdfs/xmpspec.pdf>3307 =item L<http://www.adobe.com/devnet/xmp/> 2273 3308 2274 3309 =item L<http://www.w3.org/TR/rdf-syntax-grammar/> 2275 3310 2276 =item L<http://www.portfoliofaq.com/pfaq/v7mappings.htm>2277 2278 3311 =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>2283 3312 2284 3313 =back
Note:
See TracChangeset
for help on using the changeset viewer.