sub
ProcessUnknown($$$);
sub
ProcessUnknownOrPreview($$$);
sub
ProcessCanon($$$);
sub
ProcessGE2($$$);
sub
WriteUnknownOrPreview($$$);
sub
FixLeicaBase($$;$);
$VERSION
=
'1.71'
;
my
$debug
;
@Image::ExifTool::MakerNotes::Main
= (
{
Name
=>
'MakerNoteCanon'
,
Condition
=>
'$$self{Make} =~ /^Canon/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Canon::Main'
,
ProcessProc
=> \
&ProcessCanon
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteCasio'
,
Condition
=>
'$$self{Make}=~/^CASIO/ and $$valPt!~/^(QVC|DCI)\0/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Casio::Main'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteCasio2'
,
Condition
=>
'$$valPt =~ /^(QVC|DCI)\0/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Casio::Type2'
,
Start
=>
'$valuePtr + 6'
,
ByteOrder
=>
'Unknown'
,
FixBase
=> 1,
},
},
{
Name
=>
'MakerNoteFujiFilm'
,
Condition
=>
'$$valPt =~ /^(FUJIFILM|GENERALE)/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::FujiFilm::Main'
,
OffsetPt
=>
'$valuePtr+8'
,
Base
=>
'$start'
,
ByteOrder
=>
'LittleEndian'
,
},
},
{
Name
=>
'MakerNoteGE'
,
Condition
=>
'$$valPt =~ /^GE(\0\0|NIC\0)/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::GE::Main'
,
Start
=>
'$valuePtr + 18'
,
FixBase
=> 1,
AutoFix
=> 1,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteGE2'
,
Condition
=>
'$$valPt =~ /^GE\x0c\0\0\0\x16\0\0\0/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::FujiFilm::Main'
,
ProcessProc
=> \
&ProcessGE2
,
Start
=>
'$valuePtr + 12'
,
Base
=>
'$start - 6'
,
ByteOrder
=>
'LittleEndian'
,
FixOffsets
=>
'$valuePtr -= 210 if $tagID >= 0x1303'
,
},
},
{
Name
=>
'MakerNoteHasselblad'
,
Condition
=>
'$$self{Make} eq "Hasselblad"'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Unknown::Main'
,
ByteOrder
=>
'Unknown'
,
Start
=>
'$valuePtr'
,
Base
=> 0,
},
},
{
Name
=>
'MakerNoteHP'
,
Condition
=>
'$$valPt =~ /^(Hewlett-Packard|Vivitar)/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::HP::Main'
,
ProcessProc
=> \
&ProcessUnknown
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteHP2'
,
Condition
=>
'$$valPt =~ /^610[\0-\4]/'
,
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::HP::Type2'
,
Start
=>
'$valuePtr'
,
ByteOrder
=>
'LittleEndian'
,
},
},
{
Name
=>
'MakerNoteHP4'
,
Condition
=>
'$$valPt =~ /^IIII\x04\0/'
,
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::HP::Type4'
,
Start
=>
'$valuePtr'
,
ByteOrder
=>
'LittleEndian'
,
},
},
{
Name
=>
'MakerNoteHP6'
,
Condition
=>
'$$valPt =~ /^IIII\x06\0/'
,
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::HP::Type6'
,
Start
=>
'$valuePtr'
,
ByteOrder
=>
'LittleEndian'
,
},
},
{
Name
=>
'MakerNoteISL'
,
Condition
=>
'$$valPt =~ /^ISLMAKERNOTE000\0/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Unknown::Main'
,
Start
=>
'$valuePtr + 24'
,
Base
=>
'$start - 8'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteJVC'
,
Condition
=>
'$$valPt=~/^JVC /'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::JVC::Main'
,
Start
=>
'$valuePtr + 4'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteJVCText'
,
Condition
=>
'$$self{Make}=~/^(JVC|Victor)/ and $$valPt=~/^VER:/'
,
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::JVC::Text'
,
},
},
{
Name
=>
'MakerNoteKodak1a'
,
Condition
=>
'$$self{Make}=~/^EASTMAN KODAK/ and $$valPt=~/^KDK INFO/'
,
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Main'
,
Start
=>
'$valuePtr + 8'
,
ByteOrder
=>
'BigEndian'
,
},
},
{
Name
=>
'MakerNoteKodak1b'
,
Condition
=>
'$$self{Make}=~/^EASTMAN KODAK/ and $$valPt=~/^KDK/'
,
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Main'
,
Start
=>
'$valuePtr + 8'
,
ByteOrder
=>
'LittleEndian'
,
},
},
{
Name
=>
'MakerNoteKodak2'
,
Condition
=>
q{
$$valPt =~ /^.{8}
Eastman Kodak/s or
$$valPt
=~ /^\x01\0[\0\x01]\0\0\0\x04\0[a-zA-Z]{4}/
},
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Type2'
,
ByteOrder
=>
'BigEndian'
,
},
},
{
Name
=>
'MakerNoteKodak3'
,
Condition
=>
q{
$$self{Make}
=~ /^EASTMAN KODAK/ and
$$valPt
=~ /^(?!MM|II).{12}\x07/s and
$$valPt
!~ /^(MM|II|AOC)/
},
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Type3'
,
ByteOrder
=>
'BigEndian'
,
},
},
{
Name
=>
'MakerNoteKodak4'
,
Condition
=>
q{
$$self{Make}
=~ /^Eastman Kodak/ and
$$valPt
=~ /^.{41}JPG/s and
$$valPt
!~ /^(MM|II|AOC)/
},
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Type4'
,
ByteOrder
=>
'BigEndian'
,
},
},
{
Name
=>
'MakerNoteKodak5'
,
Condition
=>
q{
$$self{Make}
=~/^EASTMAN KODAK/ and
(
$$self
{Model}=~/CX(4200|4230|4300|4310|6200|6230)/ or
$$valPt
=~/^\0(\x1a\x18|\x3a\x08|\x59\xf8|\x14\x80)\0/)
},
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Type5'
,
ByteOrder
=>
'BigEndian'
,
},
},
{
Name
=>
'MakerNoteKodak6a'
,
Condition
=>
q{
$$self{Make}
=~/^EASTMAN KODAK/ and
$$self
{Model}=~/DX3215/
},
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Type6'
,
ByteOrder
=>
'BigEndian'
,
},
},
{
Name
=>
'MakerNoteKodak6b'
,
Condition
=>
q{
$$self{Make}
=~/^EASTMAN KODAK/ and
$$self
{Model}=~/DX3700/
},
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Type6'
,
ByteOrder
=>
'LittleEndian'
,
},
},
{
Name
=>
'MakerNoteKodak7'
,
Condition
=>
q{
$$self{Make}
=~/Kodak/i and
$$valPt
=~ /^[CK][A-Z\d]{3} ?[A-Z\d]{1,2}\d{2}[A-Z\d]\d{4}[ \0]/
},
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Type7'
,
ByteOrder
=>
'LittleEndian'
,
},
},
{
Name
=>
'MakerNoteKodak8a'
,
Condition
=>
q{
$$self{Make}
=~/Kodak/i and
(
$$valPt
=~ /^\0[\x02-\x7f]..\0[\x01-\x0c]\0\0/s or
$$valPt
=~ /^[\x02-\x7f]\0..[\x01-\x0c]\0..\0\0/s)
},
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Type8'
,
ProcessProc
=> \
&ProcessUnknown
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteKodak8b'
,
Condition
=>
q{
$$self{Make}
=~/Kodak/i and
$$valPt
=~ /^(MM\0\x2a\0\0\0\x08|II\x2a\0\x08\0\0\0)/
},
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Type8'
,
ProcessProc
=> \
&ProcessUnknown
,
ByteOrder
=>
'Unknown'
,
Start
=>
'$valuePtr + 8'
,
Base
=>
'$start - 8'
,
},
},
{
Name
=>
'MakerNoteKodak9'
,
Condition
=>
'$$valPt =~ m{^IIII[\x02\x03]\0.{14}\d{4}/\d{2}/\d{2} }s'
,
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Type9'
,
ByteOrder
=>
'LittleEndian'
,
},
},
{
Name
=>
'MakerNoteKodak10'
,
Condition
=>
q{
$$self{Make}
=~/Kodak/i and
$$valPt
=~ /^(MM\0[\x02-\x7f]|II[\x02-\x7f]\0)/
},
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Type10'
,
ProcessProc
=> \
&ProcessUnknown
,
ByteOrder
=>
'Unknown'
,
Start
=>
'$valuePtr + 2'
,
},
},
{
Name
=>
'MakerNoteKodakUnknown'
,
Condition
=>
'$$self{Make}=~/Kodak/i and $$valPt!~/^AOC\0/'
,
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Kodak::Unknown'
,
ByteOrder
=>
'BigEndian'
,
},
},
{
Name
=>
'MakerNoteKyocera'
,
Condition
=>
'$$valPt =~ /^KYOCERA/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Unknown::Main'
,
Start
=>
'$valuePtr + 22'
,
Base
=>
'$start + 2'
,
EntryBased
=> 1,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteMinolta'
,
Condition
=>
q{
$$self{Make}
=~/^(Konica Minolta|Minolta)/i and
$$valPt
!~ /^(MINOL|CAMER|MLY0|KC|\+M\+M|\xd7)/
},
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Minolta::Main'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteMinolta2'
,
Condition
=>
'$$valPt =~ /^(MINOL|CAMER)\0/ and $$self{OlympusCAMER} = 1'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Olympus::Main'
,
Start
=>
'$valuePtr + 8'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteMinolta3'
,
Condition
=>
'$$self{Make} =~ /^(Konica Minolta|Minolta)/i'
,
Binary
=> 1,
Notes
=>
'not EXIF-based'
,
},
{
Name
=>
'MakerNoteNikon'
,
Condition
=>
'$$self{Make}=~/^NIKON/i and $$valPt=~/^Nikon\x00\x02/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Nikon::Main'
,
Start
=>
'$valuePtr + 18'
,
Base
=>
'$start - 8'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteNikon2'
,
Condition
=>
'$$self{Make}=~/^NIKON/ and $$valPt=~/^Nikon\x00\x01/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Nikon::Type2'
,
Start
=>
'$valuePtr + 8'
,
ByteOrder
=>
'LittleEndian'
,
},
},
{
Name
=>
'MakerNoteNikon3'
,
Condition
=>
'$$self{Make}=~/^NIKON/i'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Nikon::Main'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteOlympus'
,
Condition
=>
'$$valPt =~ /^(OLYMP|EPSON)\0/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Olympus::Main'
,
Start
=>
'$valuePtr + 8'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteOlympus2'
,
Condition
=>
'$$valPt =~ /^OLYMPUS\0/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Olympus::Main'
,
Start
=>
'$valuePtr + 12'
,
Base
=>
'$start - 12'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteLeica'
,
Condition
=>
'$$self{Make} eq "LEICA"'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Panasonic::Main'
,
Start
=>
'$valuePtr + 8'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteLeica2'
,
Condition
=>
'$$self{Make} =~ /^Leica Camera AG/ and $$valPt =~ /^LEICA\0\0\0/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Panasonic::Leica2'
,
ProcessProc
=> \
&FixLeicaBase
,
Start
=>
'$valuePtr + 8'
,
Base
=>
'$start'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteLeica3'
,
Condition
=>
'$$self{Make} =~ /^Leica Camera AG/ and $$valPt !~ /^LEICA/ and $$self{Model} ne "S2"'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Panasonic::Leica3'
,
Start
=>
'$valuePtr'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteLeica4'
,
Condition
=>
'$$self{Make} =~ /^Leica Camera AG/ and $$valPt =~ /^LEICA0/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Panasonic::Leica4'
,
Start
=>
'$valuePtr + 8'
,
Base
=>
'$start - 8'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteLeica5'
,
Condition
=>
'$$valPt =~ /^LEICA\0\x01\0/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Panasonic::Leica5'
,
Start
=>
'$valuePtr + 8'
,
Base
=>
'$start - 8'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteLeica6'
,
Condition
=>
'$$self{Model} eq "S2"'
,
DataTag
=>
'LeicaTrailer'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Panasonic::Leica6'
,
Start
=>
'$valuePtr + 8'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNotePanasonic'
,
Condition
=>
'$$valPt=~/^Panasonic/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Panasonic::Main'
,
Start
=>
'$valuePtr + 12'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNotePanasonic2'
,
Condition
=>
'$$self{Make}=~/^Panasonic/ and $$valPt=~/^MKE/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Panasonic::Type2'
,
ByteOrder
=>
'LittleEndian'
,
},
},
{
Name
=>
'MakerNotePentax'
,
Condition
=>
q{
$$valPt=~/^AOC\0/ and
$$self{Model}
!~ /^PENTAX Optio ?[34]30RS\s*$/
},
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Pentax::Main'
,
ProcessProc
=> \
&ProcessUnknown
,
FixBase
=> 1,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNotePentax2'
,
Condition
=>
'$$self{Make}=~/^Asahi/ and $$valPt!~/^AOC\0/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Pentax::Type2'
,
ProcessProc
=> \
&ProcessUnknown
,
FixBase
=> 1,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNotePentax3'
,
Condition
=>
'$$self{Make}=~/^Asahi/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Casio::Type2'
,
ProcessProc
=> \
&ProcessUnknown
,
FixBase
=> 1,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNotePentax4'
,
Condition
=>
'$$self{Make}=~/^PENTAX/ and $$valPt=~/^\d{3}/'
,
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Pentax::Type4'
,
Start
=>
'$valuePtr'
,
ByteOrder
=>
'LittleEndian'
,
},
},
{
Name
=>
'MakerNotePentax5'
,
Condition
=>
'$$valPt=~/^PENTAX \0/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Pentax::Main'
,
Start
=>
'$valuePtr + 10'
,
Base
=>
'$start - 10'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNotePentax6'
,
Condition
=>
'$$valPt=~/^S1\0{6}\x0c\0{3}/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Pentax::S1'
,
Start
=>
'$valuePtr + 12'
,
Base
=>
'$start - 12'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNotePhaseOne'
,
Condition
=>
q{
return undef unless $$valPt =~ /^(IIII.waR|MMMMRaw.)/s;
$self->OverrideFileType($$self{TIFF_TYPE}
=
'IIQ'
)
if
$count
> 1000000;
return
1;
},
NotIFD
=> 1,
Binary
=> 1,
PutFirst
=> 1,
Notes
=>
'the raw image data in PhaseOne IIQ images'
,
},
{
Name
=>
'MakerNoteReconyx'
,
Condition
=>
'$$valPt =~ /^\x01\xf1[\x02\x03]\x00/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Reconyx::Main'
,
ByteOrder
=>
'Little-endian'
,
},
},
{
Name
=>
'MakerNoteRicoh'
,
Condition
=>
'$$self{Make}=~/^RICOH/ and $$valPt=~/^(Ricoh| )/i'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Ricoh::Main'
,
Start
=>
'$valuePtr + 8'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteRicohText'
,
Condition
=>
'$$self{Make}=~/^RICOH/'
,
NotIFD
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Ricoh::Text'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteSamsung1a'
,
Condition
=>
'$$valPt =~ /^STMN\d{3}.\0{4}/s'
,
Binary
=> 1,
Notes
=>
'Samsung "STMN" maker notes without PreviewImage'
,
},
{
Name
=>
'MakerNoteSamsung1b'
,
Condition
=>
'$$valPt =~ /^STMN\d{3}/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Samsung::Type1'
,
},
},
{
Name
=>
'MakerNoteSamsung2'
,
Condition
=>
q{
$$self{Make}
eq
'SAMSUNG'
and (
$$self
{TIFF_TYPE} eq
'SRW'
or
$$valPt
=~/^(\0.\0\x01\0\x07\0{3}\x04|.\0\x01\0\x07\0\x04\0{3})0100/s)
},
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Samsung::Type2'
,
ProcessProc
=> \
&ProcessUnknown
,
FixBase
=> 1,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteSanyo'
,
Condition
=>
'$$self{Make}=~/^SANYO/ and $$self{Model}!~/^(C4|J\d|S\d)\b/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Sanyo::Main'
,
Validate
=>
'$val =~ /^SANYO/'
,
Start
=>
'$valuePtr + 8'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteSanyoC4'
,
Condition
=>
'$$self{Make}=~/^SANYO/ and $$self{Model}=~/^C4\b/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Sanyo::Main'
,
Validate
=>
'$val =~ /^SANYO/'
,
Start
=>
'$valuePtr + 8'
,
FixBase
=> 1,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteSanyoPatch'
,
Condition
=>
'$$self{Make}=~/^SANYO/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Sanyo::Main'
,
Validate
=>
'$val =~ /^SANYO/'
,
Start
=>
'$valuePtr + 8'
,
ByteOrder
=>
'Unknown'
,
FixOffsets
=>
'Image::ExifTool::Sanyo::FixOffsets($valuePtr, $valEnd, $size, $tagID, $wFlag)'
,
},
},
{
Name
=>
'MakerNoteSigma'
,
Condition
=>
'$$self{Make}=~/^(SIGMA|FOVEON)/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Sigma::Main'
,
Validate
=>
'$val =~ /^(SIGMA|FOVEON)/'
,
Start
=>
'$valuePtr + 10'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteSony'
,
Condition
=>
'$$self{Make}=~/^SONY/ and $$valPt=~/^SONY (DSC|CAM)/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Sony::Main'
,
Start
=>
'$valuePtr + 12'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteSony2'
,
Condition
=>
'$$self{Make}=~/^SONY/ and $$valPt=~/^SONY PI\0/ and $$self{OlympusCAMER}=1'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Olympus::Main'
,
Start
=>
'$valuePtr + 12'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteSony3'
,
Condition
=>
'$$self{Make}=~/^SONY/ and $$valPt=~/^(PREMI)\0/ and $$self{OlympusCAMER}=1'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Olympus::Main'
,
Start
=>
'$valuePtr + 8'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteSony4'
,
Condition
=>
'$$self{Make}=~/^SONY/ and $$valPt!~/^\x01\x00/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Sony::Main'
,
Start
=>
'$valuePtr'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteSonyEricsson'
,
Condition
=>
'$$valPt =~ /^SEMC MS\0/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Sony::Ericsson'
,
Start
=>
'$valuePtr + 20'
,
Base
=>
'$start - 8'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteSonySRF'
,
Condition
=>
'$$self{Make}=~/^SONY/'
,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Sony::SRF'
,
Start
=>
'$valuePtr'
,
ByteOrder
=>
'Unknown'
,
},
},
{
Name
=>
'MakerNoteUnknownText'
,
Condition
=>
'$$valPt =~ /^[\x09\x0d\x0a\x20-\x7e]+\0*$/'
,
Notes
=>
'unknown text-based maker notes'
,
ValueConv
=>
'length($val) > 64 ? \$val : $val'
,
ValueConvInv
=>
'$val'
,
},
{
Name
=>
'MakerNoteUnknown'
,
PossiblePreview
=> 1,
SubDirectory
=> {
TagTable
=>
'Image::ExifTool::Unknown::Main'
,
ProcessProc
=> \
&ProcessUnknownOrPreview
,
WriteProc
=> \
&WriteUnknownOrPreview
,
ByteOrder
=>
'Unknown'
,
FixBase
=> 2,
},
},
);
my
$tagInfo
;
foreach
$tagInfo
(
@Image::ExifTool::MakerNotes::Main
) {
$$tagInfo
{Writable} =
'undef'
;
$$tagInfo
{Format} =
'undef'
,
$$tagInfo
{WriteGroup} =
'ExifIFD'
;
$$tagInfo
{Groups} = {
1
=>
'MakerNotes'
};
next
unless
$$tagInfo
{SubDirectory};
$$tagInfo
{Binary} = 1,
$$tagInfo
{MakerNotes} = 1;
}
sub
GetMakerNoteOffset($)
{
my
$exifTool
=
shift
;
my
$make
=
$exifTool
->{Make};
my
$model
=
$exifTool
->{Model};
my
(
$relative
,
@offsets
);
if
(
$make
=~ /^Canon/) {
push
@offsets
, (
$model
=~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/) ? 6 : 4;
push
@offsets
, 28
if
$model
=~ /\b(FV\b|OPTURA)/;
push
@offsets
, 16
if
$model
=~ /(PowerShot|IXUS|IXY)/;
}
elsif
(
$make
=~ /^CASIO/) {
push
@offsets
,
$$exifTool
{FILE_TYPE} =~ /^(RIFF|MOV)$/ ? 0 : (4, 16, 2);
}
elsif
(
$make
=~ /^(General Imaging Co.|GEDSC IMAGING CORP.)/i) {
push
@offsets
, 0;
}
elsif
(
$make
=~ /^KYOCERA/) {
push
@offsets
, 12;
}
elsif
(
$make
=~ /^Leica Camera AG/) {
if
(
$model
eq
'S2'
) {
push
@offsets
, 4, (
$$exifTool
{FILE_TYPE} eq
'JPEG'
? 286 : 274);
}
elsif
(
$model
=~ /^(R8|R9|M8)\b/) {
push
@offsets
, 6;
}
else
{
push
@offsets
, 4;
}
}
elsif
(
$make
=~ /^OLYMPUS/ and
$model
=~ /^E-(1|300|330)\b/) {
push
@offsets
, 16;
}
elsif
(
$make
=~ /^OLYMPUS/ and
$model
=~ /^(C2500L|C-1Z?|C-5000Z|X-2|C720UZ|C725UZ|C150|C2Z|E-10|E-20|FerrariMODEL2003|u20D|u10D)\b/)
{
}
elsif
(
$make
=~ /^(Panasonic|JVC)\b/) {
push
@offsets
, 0;
}
elsif
(
$make
=~ /^SONY/) {
if
(
$model
=~ /DSLR/ or
$$exifTool
{OlympusCAMER}) {
push
@offsets
, 4;
}
else
{
push
@offsets
, 0;
}
}
elsif
(
$make
eq
'FUJIFILM'
) {
push
@offsets
, 4, 6;
}
elsif
(
$make
=~ /^TOSHIBA/) {
push
@offsets
, 0, 24;
}
elsif
(
$make
=~ /^PENTAX/) {
push
@offsets
, 4;
$relative
= 0;
}
elsif
(
$make
=~ /^Konica Minolta/i) {
push
@offsets
, 4, -16;
}
elsif
(
$make
=~ /^Minolta/) {
push
@offsets
, 4, -8, -12;
}
else
{
push
@offsets
, 4;
}
return
(
$relative
,
@offsets
);
}
sub
GetValueBlocks($$;$)
{
my
(
$dataPt
,
$dirStart
,
$tagPtr
) =
@_
;
my
$numEntries
= Get16u(
$dataPt
,
$dirStart
);
my
(
$index
,
$valPtr
,
%valBlock
,
%valBlkAdj
,
$end
);
for
(
$index
=0;
$index
<
$numEntries
; ++
$index
) {
my
$entry
=
$dirStart
+ 2 + 12 *
$index
;
my
$format
= Get16u(
$dataPt
,
$entry
+2);
last
if
$format
< 1 or
$format
> 13;
my
$count
= Get32u(
$dataPt
,
$entry
+4);
my
$size
=
$count
*
$Image::ExifTool::Exif::formatSize
[
$format
];
next
if
$size
<= 4;
$valPtr
= Get32u(
$dataPt
,
$entry
+8);
$tagPtr
and
$$tagPtr
{Get16u(
$dataPt
,
$entry
)} =
$valPtr
;
unless
(
defined
$valBlock
{
$valPtr
} and
$valBlock
{
$valPtr
} >
$size
) {
$valBlock
{
$valPtr
} =
$size
;
}
$valPtr
+= 12 *
$index
;
unless
(
defined
$valBlkAdj
{
$valPtr
} and
$valBlkAdj
{
$valPtr
} >
$size
) {
$valBlkAdj
{
$valPtr
} =
$size
;
my
$end
=
$valPtr
+
$size
;
if
(
defined
$valBlkAdj
{MIN}) {
$valBlkAdj
{MIN} =
$valPtr
if
$valBlkAdj
{MIN} < 12 or
$valBlkAdj
{MIN} >
$valPtr
;
$valBlkAdj
{MAX} =
$end
if
$valBlkAdj
{MAX} >
$end
;
}
else
{
$valBlkAdj
{MIN} =
$valPtr
;
$valBlkAdj
{MAX} =
$end
;
}
}
}
return
(\
%valBlock
, \
%valBlkAdj
);
}
sub
FixBase($$)
{
local
$_
;
my
(
$exifTool
,
$dirInfo
) =
@_
;
return
0
if
$$dirInfo
{FixOffsets} or
$$dirInfo
{NoFixBase};
my
$dataPt
=
$$dirInfo
{DataPt};
my
$dataPos
=
$$dirInfo
{DataPos};
my
$dirStart
=
$$dirInfo
{DirStart} || 0;
my
$entryBased
=
$$dirInfo
{EntryBased};
my
$dirName
=
$$dirInfo
{DirName};
my
$fixBase
=
$exifTool
->Options(
'FixBase'
);
my
$setBase
= (
defined
$fixBase
and
$fixBase
ne
''
) ? 1 : 0;
my
(
$fix
,
$fixedBy
,
%tagPtr
);
my
(
$valBlock
,
$valBlkAdj
) = GetValueBlocks(
$dataPt
,
$dirStart
, \
%tagPtr
);
return
0
unless
%$valBlock
;
my
@valPtrs
=
sort
{
$a
<=>
$b
}
keys
%$valBlock
;
if
(
$$exifTool
{Make} =~ /^Canon/ and
$$dirInfo
{DirLen} > 8) {
my
$footerPos
=
$dirStart
+
$$dirInfo
{DirLen} - 8;
my
$footer
=
substr
(
$$dataPt
,
$footerPos
, 8);
if
(
$footer
=~ /^(II\x2a\0|MM\0\x2a)/ and
substr
(
$footer
,0,2) eq GetByteOrder())
{
my
$oldOffset
= Get32u(\
$footer
, 4);
my
$newOffset
=
$dirStart
+
$dataPos
;
if
(
$setBase
) {
$fix
=
$fixBase
;
}
else
{
$fix
=
$newOffset
-
$oldOffset
;
return
0
unless
$fix
;
my
$maxPt
=
$valPtrs
[-1] +
$$valBlock
{
$valPtrs
[-1]};
my
$endDiff
=
$dirStart
+
$$dirInfo
{DirLen} - (
$maxPt
-
$dataPos
) - 8;
if
(not
$endDiff
or
$endDiff
== 1) {
$exifTool
->Warn(
'Canon maker note footer may be invalid (ignored)'
,1);
return
0;
}
}
$exifTool
->Warn(
"Adjusted $dirName base by $fix"
,1);
$$dirInfo
{FixedBy} =
$fix
;
$$dirInfo
{Base} +=
$fix
;
$$dirInfo
{DataPos} -=
$fix
;
return
$fix
;
}
}
my
$minPt
=
$$dirInfo
{MinOffset} =
$valPtrs
[0];
my
$ifdLen
= 2 + 12 * Get16u(
$$dirInfo
{DataPt},
$dirStart
);
my
$ifdEnd
=
$dirStart
+
$ifdLen
;
my
(
$relative
,
@offsets
) = GetMakerNoteOffset(
$exifTool
);
my
$makeDiff
=
$offsets
[0];
my
$verbose
=
$exifTool
->Options(
'Verbose'
);
my
(
$diff
,
$shift
);
my
$expected
=
$dataPos
+
$ifdEnd
+ (
defined
$makeDiff
?
$makeDiff
: 4);
$debug
and
print
"$expected expected\n"
;
my
(
$countNeg12
,
$countZero
,
$countOverlap
) = (0, 0, 0);
my
(
$valPtr
,
$last
);
foreach
$valPtr
(
@valPtrs
) {
printf
(
"%d - %d (%d)\n"
,
$valPtr
,
$valPtr
+
$$valBlock
{
$valPtr
},
$valPtr
- (
$last
|| 0))
if
$debug
;
if
(
defined
$last
) {
my
$gap
=
$valPtr
-
$last
;
if
(
$gap
== 0 or
$gap
== 1) {
++
$countZero
;
}
elsif
(
$gap
== -12 and not
$entryBased
) {
++
$countNeg12
;
}
elsif
(
$gap
< 0) {
++
$countOverlap
if
$valPtr
;
}
elsif
(
$gap
>=
$ifdLen
) {
$minPt
=
$valPtr
if
abs
(
$valPtr
-
$expected
) <= 4;
}
$minPt
=
$valPtr
if
$minPt
< 12;
}
$last
=
$valPtr
+
$$valBlock
{
$valPtr
};
}
if
(((
$countNeg12
>
$countZero
and
$$valBlkAdj
{MIN} >=
$ifdLen
- 2) or
(
$$valBlkAdj
{MIN} ==
$ifdLen
- 2 or
$$valBlkAdj
{MIN} ==
$ifdLen
+ 2)
) and
$$valBlkAdj
{MAX} <=
$$dirInfo
{DirLen}-2)
{
$entryBased
= 1;
$verbose
and
$exifTool
->Warn(
"$dirName offsets are entry-based"
,1);
}
else
{
$diff
= (
$minPt
-
$dataPos
) -
$ifdEnd
;
$shift
= 0;
$countOverlap
and
$exifTool
->Warn(
"Overlapping $dirName values"
,1);
if
(
$entryBased
) {
$exifTool
->Warn(
"$dirName offsets do NOT look entry-based"
,1);
undef
$entryBased
;
undef
$relative
;
}
if
(
$tagPtr
{0xe00}) {
my
$ptr
=
$tagPtr
{0xe00} -
$dataPos
;
return
0
if
$ptr
> 0 and
$ptr
<=
length
(
$$dataPt
) - 8 and
substr
(
$$dataPt
,
$ptr
, 8) eq
"PrintIM\0"
;
}
if
(
$$dirInfo
{FixBase} and
$$dirInfo
{FixBase} == 2) {
return
0
if
$diff
>=0 and
$diff
<= 24;
}
}
if
(
$entryBased
) {
$debug
and
print
"--> entry-based!\n"
;
$makeDiff
= 0;
push
@offsets
, 4;
my
$expected
= 12 * Get16u(
$$dirInfo
{DataPt},
$dirStart
);
$diff
=
$$valBlkAdj
{MIN} -
$expected
;
$shift
=
$dataPos
+
$dirStart
+ 2;
$$dirInfo
{Base} +=
$shift
;
$$dirInfo
{DataPos} -=
$shift
;
$$dirInfo
{EntryBased} = 1;
$$dirInfo
{Relative} = 1;
delete
$$dirInfo
{FixBase};
undef
$fixBase
unless
$setBase
;
}
unless
(
$setBase
) {
return
$shift
unless
defined
$makeDiff
;
return
$shift
if
$diff
== 0 or
$diff
== 4;
foreach
(
@offsets
) {
return
$shift
if
$diff
==
$_
;
}
}
$makeDiff
= 4
unless
defined
$makeDiff
;
$fix
=
$makeDiff
-
$diff
;
if
(
$$dirInfo
{FixBase}) {
if
(
$dataPos
-
$fix
+
$dirStart
<= 0) {
$$dirInfo
{Relative} = (
defined
$relative
) ?
$relative
: 1;
}
if
(
$setBase
) {
$fixedBy
=
$fixBase
;
$fix
+=
$fixBase
;
}
}
elsif
(
defined
$fixBase
) {
$fix
=
$fixBase
if
$fixBase
ne
''
;
$fixedBy
=
$fix
;
}
else
{
if
(
$diff
< 0 or
$diff
> 16 or (
$diff
& 0x01)) {
$exifTool
->Warn(
"Possibly incorrect maker notes offsets (fix by $fix?)"
,1);
}
return
$shift
;
}
if
(
defined
$fixedBy
) {
$exifTool
->Warn(
"Adjusted $dirName base by $fixedBy"
,1);
$$dirInfo
{FixedBy} =
$fixedBy
;
}
$$dirInfo
{Base} +=
$fix
;
$$dirInfo
{DataPos} -=
$fix
;
return
$fix
+
$shift
;
}
sub
LocateIFD($$)
{
my
(
$exifTool
,
$dirInfo
) =
@_
;
my
$dataPt
=
$$dirInfo
{DataPt};
my
$dirStart
=
$$dirInfo
{DirStart} || 0;
my
$size
=
$$dirInfo
{DataLen} -
$dirStart
;
my
$dirLen
=
$$dirInfo
{DirLen} ||
$size
;
my
$tagInfo
=
$$dirInfo
{TagInfo};
my
$ifdOffsetPos
;
my
(
$firstTry
,
$lastTry
) = (0, 32);
$$dirInfo
{Base} or
$$dirInfo
{Base} = 0;
$$dirInfo
{DataPos} or
$$dirInfo
{DataPos} = 0;
if
(
$tagInfo
and
$$tagInfo
{SubDirectory}) {
my
$subdir
=
$$tagInfo
{SubDirectory};
unless
(
$$subdir
{ProcessProc} and
(
$$subdir
{ProcessProc} eq \
&ProcessUnknown
or
$$subdir
{ProcessProc} eq \
&ProcessUnknownOrPreview
))
{
my
$valuePtr
=
$dirStart
;
my
$newStart
=
$dirStart
;
if
(
defined
$$subdir
{Start}) {
$newStart
=
eval
(
$$subdir
{Start});
}
if
(
$$subdir
{Base}) {
my
$start
=
$newStart
+
$$dirInfo
{DataPos};
my
$base
=
$$dirInfo
{Base} || 0;
my
$baseShift
=
eval
(
$$subdir
{Base});
$$dirInfo
{Base} +=
$baseShift
;
$$dirInfo
{DataPos} -=
$baseShift
;
if
(
$$subdir
{Base} =~ /\
$start
\b/) {
$$dirInfo
{Relative} = 1;
if
(
$$subdir
{ProcessProc} and
$$subdir
{ProcessProc} eq \
&FixLeicaBase
) {
my
$oldStart
=
$$dirInfo
{DirStart};
$$dirInfo
{DirStart} =
$newStart
;
FixLeicaBase(
$exifTool
,
$dirInfo
);
$$dirInfo
{DirStart} =
$oldStart
;
}
}
}
if
(
$$subdir
{OffsetPt}) {
if
(
$$subdir
{ByteOrder} =~ /^Little/i) {
SetByteOrder(
'II'
);
}
elsif
(
$$subdir
{ByteOrder} =~ /^Big/i) {
SetByteOrder(
'MM'
);
}
else
{
warn
"Can't have variable byte ordering for SubDirectories using OffsetPt\n"
;
return
undef
;
}
$ifdOffsetPos
=
eval
(
$$subdir
{OffsetPt}) -
$dirStart
;
}
$firstTry
=
$lastTry
=
$newStart
-
$dirStart
;
}
}
if
(
$dirLen
>= 14 +
$firstTry
) {
my
$offset
;
IFD_TRY:
for
(
$offset
=
$firstTry
;
$offset
<=
$lastTry
;
$offset
+=2) {
last
if
$offset
+ 14 >
$dirLen
;
my
$pos
=
$dirStart
+
$offset
;
if
(SetByteOrder(
substr
(
$$dataPt
,
$pos
, 2)) and
Get16u(
$dataPt
,
$pos
+ 2) == 0x2a)
{
$ifdOffsetPos
= 4;
}
if
(
defined
$ifdOffsetPos
) {
my
$ptr
= Get32u(
$dataPt
,
$pos
+
$ifdOffsetPos
);
if
(
$ptr
>=
$ifdOffsetPos
+ 4 and
$ptr
+
$offset
+ 14 <=
$dirLen
) {
$$dirInfo
{DirStart} +=
$ptr
+
$offset
;
$$dirInfo
{DirLen} -=
$ptr
+
$offset
;
my
$shift
=
$$dirInfo
{DataPos} +
$dirStart
+
$offset
;
$$dirInfo
{Base} +=
$shift
;
$$dirInfo
{DataPos} -=
$shift
;
$$dirInfo
{Relative} = 1;
return
$ptr
+
$offset
;
}
undef
$ifdOffsetPos
;
}
my
$num
= Get16u(
$dataPt
,
$pos
);
next
unless
$num
;
if
(!(
$num
& 0xff)) {
ToggleByteOrder();
$num
>>= 8;
}
elsif
(
$num
& 0xff00) {
next
;
}
my
$bytesFromEnd
=
$size
- (
$offset
+ 2 + 12 *
$num
);
if
(
$bytesFromEnd
< 4) {
next
unless
$bytesFromEnd
== 2 or
$bytesFromEnd
== 0;
}
my
$index
;
for
(
$index
=0;
$index
<
$num
; ++
$index
) {
my
$entry
=
$pos
+ 2 + 12 *
$index
;
my
$format
= Get16u(
$dataPt
,
$entry
+2);
my
$count
= Get32u(
$dataPt
,
$entry
+4);
next
unless
$format
or
$count
or
$index
== 0;
next
if
$format
==0 and
$index
==
$num
-1 and
$$exifTool
{Model}=~/EOS 40D/;
next
if
$num
== 12 and
$$exifTool
{Make} eq
'SONY'
and
$index
>= 8;
next
IFD_TRY
if
$format
< 1 or
$format
> 13;
next
IFD_TRY
if
$count
& 0xff000000;
next
unless
$num
== 1;
my
$valueSize
=
$count
*
$Image::ExifTool::Exif::formatSize
[
$format
];
if
(
$valueSize
> 4) {
next
IFD_TRY
if
$valueSize
>
$size
;
my
$valuePtr
= Get32u(
$dataPt
,
$entry
+8);
next
IFD_TRY
if
$valuePtr
> 0x10000;
}
}
$$dirInfo
{DirStart} +=
$offset
;
$$dirInfo
{DirLen} -=
$offset
;
return
$offset
;
}
}
return
undef
;
}
sub
FixLeicaBase($$;$)
{
my
(
$exifTool
,
$dirInfo
,
$tagTablePtr
) =
@_
;
my
$dataPt
=
$$dirInfo
{DataPt};
my
$dirStart
=
$$dirInfo
{DirStart} || 0;
my
(
$valBlock
,
$valBlkAdj
) = GetValueBlocks(
$dataPt
,
$dirStart
);
if
(
%$valBlock
) {
my
@valPtrs
=
sort
{
$a
<=>
$b
}
keys
%$valBlock
;
my
$numEntries
= Get16u(
$dataPt
,
$dirStart
);
my
$diff
=
$valPtrs
[0] - (
$numEntries
* 12 + 4);
if
(
$diff
> 8) {
$$dirInfo
{Base} -= 8;
$$dirInfo
{DataPos} += 8;
}
}
my
$success
= 1;
if
(
$tagTablePtr
) {
$success
= Image::ExifTool::Exif::ProcessExif(
$exifTool
,
$dirInfo
,
$tagTablePtr
);
}
return
$success
;
}
sub
ProcessCanon($$$)
{
my
(
$exifTool
,
$dirInfo
,
$tagTablePtr
) =
@_
;
if
(
$$exifTool
{HTML_DUMP} and
$$dirInfo
{DirLen} > 8) {
my
$dataPos
=
$$dirInfo
{DataPos};
my
$dirStart
=
$$dirInfo
{DirStart} || 0;
my
$footerPos
=
$dirStart
+
$$dirInfo
{DirLen} - 8;
my
$footer
=
substr
(${
$$dirInfo
{DataPt}},
$footerPos
, 8);
if
(
$footer
=~ /^(II\x2a\0|MM\0\x2a)/ and
substr
(
$footer
,0,2) eq GetByteOrder()) {
my
$oldOffset
= Get32u(\
$footer
, 4);
my
$newOffset
=
$dirStart
+
$dataPos
;
my
$str
=
sprintf
(
'Original maker note offset: 0x%.4x'
,
$oldOffset
);
if
(
$oldOffset
!=
$newOffset
) {
$str
.=
sprintf
(
"\nCurrent maker note offset: 0x%.4x"
,
$newOffset
);
}
my
$filePos
= (
$$dirInfo
{Base} || 0) +
$dataPos
+
$footerPos
;
$exifTool
->HDump(
$filePos
, 8,
'[Canon MakerNotes footer]'
,
$str
);
}
}
return
Image::ExifTool::Exif::ProcessExif(
$exifTool
,
$dirInfo
,
$tagTablePtr
);
}
sub
ProcessGE2($$$)
{
my
(
$exifTool
,
$dirInfo
,
$tagTablePtr
) =
@_
;
my
$dataPt
=
$$dirInfo
{DataPt} or
return
0;
my
$dirStart
=
$$dirInfo
{DirStart} || 0;
Set16u(25,
$dataPt
,
$dirStart
);
return
Image::ExifTool::Exif::ProcessExif(
$exifTool
,
$dirInfo
,
$tagTablePtr
);
}
sub
ProcessUnknownOrPreview($$$)
{
my
(
$exifTool
,
$dirInfo
,
$tagTablePtr
) =
@_
;
my
$dataPt
=
$$dirInfo
{DataPt};
my
$dirStart
=
$$dirInfo
{DirStart};
my
$dirLen
=
$$dirInfo
{DirLen};
if
(
$dirLen
> 6 and
substr
(
$$dataPt
,
$dirStart
, 3) eq
"\xff\xd8\xff"
) {
$exifTool
->VerboseDir(
'PreviewImage'
);
if
(
$$exifTool
{HTML_DUMP}) {
my
$pos
=
$$dirInfo
{DataPos} +
$$dirInfo
{Base} +
$dirStart
;
$exifTool
->HDump(
$pos
,
$dirLen
,
'(MakerNotes:PreviewImage data)'
,
"Size: $dirLen bytes"
)
}
$exifTool
->FoundTag(
'PreviewImage'
,
substr
(
$$dataPt
,
$dirStart
,
$dirLen
));
return
1;
}
return
ProcessUnknown(
$exifTool
,
$dirInfo
,
$tagTablePtr
);
}
sub
WriteUnknownOrPreview($$$)
{
my
(
$exifTool
,
$dirInfo
,
$tagTablePtr
) =
@_
;
my
$dataPt
=
$$dirInfo
{DataPt};
my
$dirStart
=
$$dirInfo
{DirStart};
my
$dirLen
=
$$dirInfo
{DirLen};
my
$newVal
;
if
(
$dirLen
> 6 and
substr
(
$$dataPt
,
$dirStart
, 3) eq
"\xff\xd8\xff"
) {
if
(
$$exifTool
{NEW_VALUE}{
$Image::ExifTool::Extra
{PreviewImage}}) {
$newVal
=
$exifTool
->GetNewValues(
'PreviewImage'
) ||
''
;
if
(
$exifTool
->Options(
'Verbose'
) > 1) {
$exifTool
->VerboseValue(
"- MakerNotes:PreviewImage"
,
substr
(
$$dataPt
,
$dirStart
,
$dirLen
));
$exifTool
->VerboseValue(
"+ MakerNotes:PreviewImage"
,
$newVal
)
if
$newVal
;
}
++
$$exifTool
{CHANGED};
}
else
{
$newVal
=
substr
(
$$dataPt
,
$dirStart
,
$dirLen
);
}
}
else
{
$newVal
= Image::ExifTool::Exif::WriteExif(
$exifTool
,
$dirInfo
,
$tagTablePtr
);
}
return
$newVal
;
}
sub
ProcessUnknown($$$)
{
my
(
$exifTool
,
$dirInfo
,
$tagTablePtr
) =
@_
;
my
$success
= 0;
my
$loc
= LocateIFD(
$exifTool
,
$dirInfo
);
if
(
defined
$loc
) {
$exifTool
->{UnknownByteOrder} = GetByteOrder();
if
(
$exifTool
->Options(
'Verbose'
) > 1) {
my
$out
=
$exifTool
->Options(
'TextOut'
);
my
$indent
=
$exifTool
->{INDENT};
$indent
=~ s/\| $/ /;
printf
$out
"${indent}Found IFD at offset 0x%.4x in maker notes:\n"
,
$$dirInfo
{DirStart} +
$$dirInfo
{DataPos} +
$$dirInfo
{Base};
}
$success
= Image::ExifTool::Exif::ProcessExif(
$exifTool
,
$dirInfo
,
$tagTablePtr
);
}
else
{
$exifTool
->{UnknownByteOrder} =
''
;
$exifTool
->Warn(
"Unrecognized $$dirInfo{DirName}"
, 1);
}
return
$success
;
}
1;