#------------------------------------------------------------------------------
# File: Samsung.pm
#
# Description: Samsung EXIF maker notes tags
#
# Revisions: 2010/03/01 - P. Harvey Created
#
# References: 1) Tae-Sun Park private communication
# 2) http://www.cybercom.net/~dcoffin/dcraw/
# 3) Pascal de Bruijn private communication (NX100)
#------------------------------------------------------------------------------
package Image::ExifTool::Samsung;
use strict;
use vars qw($VERSION %samsungLensTypes);
use Image::ExifTool qw(:DataAccess :Utils);
use Image::ExifTool::Exif;
$VERSION = '1.14';
sub WriteSTMN($$$);
sub ProcessINFO($$$);
sub ProcessSamsungIFD($$$);
%samsungLensTypes = (
0 => 'Built-in or Manual Lens', #PH (EX1, WB2000)
1 => 'Samsung 30mm F2 Pancake',
2 => 'Samsung Zoom 18-55mm F3.5-5.6 OIS', # (also version II, ref 1)
3 => 'Samsung Zoom 50-200mm F4-5.6 ED OIS',
# what about the non-OIS version of the 18-55,
# which was supposed to be available before the 20-50?
4 => 'Samsung 20-50mm F3.5-5.6 Compact Zoom', #PH
5 => 'Samsung 20mm F2.8 Pancake', #PH (guess)
# 6 - 'Samsung 85mm F1.4 ED SSA', ? (ref 1 guess)
7 => 'Samsung 60mm F2.8 Macro ED OIS SSA', #1
8 => 'Samsung 16mm F2.4 Ultra Wide Pancake', #1
);
# range of values for Formats used in encrypted information
my %formatMinMax = (
int16u => [ 0, 65535 ],
int32u => [ 0, 4294967295 ],
int16s => [ -32768, 32767 ],
int32s => [ -2147483648, 2147483647 ],
);
# Samsung "STMN" maker notes (ref PH)
%Image::ExifTool::Samsung::Type1 = (
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
WRITE_PROC => \&WriteSTMN,
CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
WRITABLE => 1,
FORMAT => 'int32u',
FIRST_ENTRY => 0,
IS_OFFSET => [ 2 ], # tag 2 is 'IsOffset'
IS_SUBDIR => [ 11 ],
GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
NOTES => q{
Tags found in the binary "STMN" format maker notes written by a number of
Samsung models.
},
0 => {
Name => 'MakerNoteVersion',
Format => 'undef[8]',
},
2 => {
Name => 'PreviewImageStart',
OffsetPair => 3, # associated byte count tagID
DataTag => 'PreviewImage',
IsOffset => 3,
Protected => 2,
},
3 => {
Name => 'PreviewImageLength',
OffsetPair => 2, # point to associated offset
DataTag => 'PreviewImage',
Protected => 2,
},
11 => {
Name => 'SamsungIFD',
# Note: this is not always an IFD. In many models the string
# "Park Byeongchan" is found at this location
Condition => '$$valPt =~ /^[^\0]\0\0\0/',
Format => 'undef[$size - 44]',
SubDirectory => { TagTable => 'Image::ExifTool::Samsung::IFD' },
},
);
%Image::ExifTool::Samsung::IFD = (
PROCESS_PROC => \&ProcessSamsungIFD,
NOTES => q{
This is a standard-format IFD found in the Type1 maker notes of some Samsung
models, except that the entry count is a 4-byte integer and the offsets are
relative to the end of the IFD. Currently, no tags in this IFD are known,
so the Unknown (-u) or Verbose (-v) option must be used to see this
information.
},
GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
# 0x0001 - undef[4000|4100]: starts with "MN_PRV" (or all zeros)
# 0x0002 - undef[7000] : starts with "Kim Miae"
# 0x0003 - undef[5000] : starts with "Lee BK"
# 0x0004 - undef[500|2000] : starts with "IPCD" (or all zeros)
# 0x0006 - undef[100|200] : starts with "MN_ADS" (or all zeros)
);
# Samsung maker notes (ref PH)
%Image::ExifTool::Samsung::Type2 = (
WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
WRITABLE => 1,
GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
NOTES => 'Tags found in the EXIF-format maker notes of newer Samsung models.',
0x0001 => {
Name => 'MakerNoteVersion',
Writable => 'undef',
Count => 4,
},
0x0021 => { #1
Name => 'PictureWizard',
Writable => 'int16u',
SubDirectory => { TagTable => 'Image::ExifTool::Samsung::PictureWizard' },
},
# 0x0023 - string: "0123456789" (PH)
0x0030 => { #1 (NX100 with GPS)
Name => 'LocalLocationName',
Writable => 'string',
Format => 'undef',
# this contains 2 place names (in Korean if in Korea), separated by a null+space
# - terminate at double-null and replace nulls with newlines
ValueConv => '$val=~s/\0\0.*//; $val=~s/\0 */\n/g; $val',
ValueConvInv => '$val=~s/(\x0d\x0a|\x0d|\x0a)/\0 /g; $val . "\0\0"'
},
0x0031 => { #1 (NX100 with GPS)
Name => 'LocationName',
Writable => 'string',
},
0x0035 => {
Name => 'PreviewIFD',
Condition => '$$self{TIFF_TYPE} eq "SRW"', # (not an IFD in JPEG images)
Groups => { 1 => 'PreviewIFD' },
Flags => 'SubIFD',
SubDirectory => {
TagTable => 'Image::ExifTool::Nikon::PreviewIFD',
ByteOrder => 'Unknown',
Start => '$val',
},
},
0x0043 => { #1 (NC)
Name => 'CameraTemperature',
Groups => { 2 => 'Camera' },
Writable => 'rational64s',
# (DPreview samples all 0.2 C --> pre-production model)
PrintConv => '"$val C"',
PrintConvInv => '$val=~s/ ?C//; $val',
},
# 0x00a0 - undef[8192]: white balance information (ref 1):
# At byte 5788, the WBAdjust: "Adjust\0\X\0\Y\0\Z\xee\xea\xce\xab", where
# Y = BA adjust (0=Blue7, 7=0, 14=Amber7), Z = MG (0=Magenta7, 7=0, 14=Green7)
#
# the following tags found only in SRW images
#
# 0xa000 - rational64u: 1 or 1.1 (ref PH)
0xa001 => { #1
Name => 'FirmwareName',
Groups => { 2 => 'Camera' },
Writable => 'string',
},
# 0xa002 - string[30]: '0' or 'DY049P000000' (ref PH)
0xa003 => { #1 (SRW images only)
Name => 'LensType',
Groups => { 2 => 'Camera' },
Writable => 'int16u',
PrintConv => \%samsungLensTypes,
},
0xa004 => { #1
Name => 'LensFirmware',
Groups => { 2 => 'Camera' },
Writable => 'string',
},
# 0xa005 - string[30]: constant for a given lens? Not the printed serial number (ref 1)
0xa010 => { #1
Name => 'SensorAreas',
Groups => { 2 => 'Camera' },
Notes => 'full and valid sensor areas',
Writable => 'int32u',
Count => 8,
},
0xa011 => { #1
Name => 'ColorSpace',
Writable => 'int16u',
PrintConv => {
0 => 'sRGB',
1 => 'Adobe RGB',
},
},
0xa012 => { #1
Name => 'SmartRange',
Writable => 'int16u',
PrintConv => { 0 => 'Off', 1 => 'On' },
},
0xa013 => { #1
Name => 'ExposureCompensation',
Writable => 'rational64s',
},
0xa014 => { #1
Name => 'ISO',
Writable => 'int32u',
},
0xa018 => { #1
Name => 'ExposureTime',
Writable => 'rational64u',
PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
},
0xa019 => { #1
Name => 'FNumber',
Priority => 0,
Writable => 'rational64u',
PrintConv => 'sprintf("%.1f",$val)',
PrintConvInv => '$val',
},
0xa01a => { #1
Name => 'FocalLengthIn35mmFormat',
Groups => { 2 => 'Camera' },
Priority => 0,
Format => 'int32u',
ValueConv => '$val / 10',
ValueConvInv => '$val * 10',
PrintConv => '"$val mm"',
PrintConvInv => '$val=~s/\s*mm$//;$val',
},
0xa020 => { #1
Name => 'EncryptionKey',
Writable => 'int32u',
Count => 11,
Protected => 1,
DataMember => 'EncryptionKey',
RawConv => '$$self{EncryptionKey} = [ split(" ",$val) ]; $val',
Notes => 'key used to decrypt the tags below',
# value is "305 72 737 456 282 307 519 724 13 505 193"
},
0xa021 => { #1
Name => 'WB_RGGBLevelsUncorrected',
Writable => 'int32u',
Count => 4,
Notes => 'these tags not corrected for WB_RGGBLevelsBlack',
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0")',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0)',
},
0xa022 => { #1
Name => 'WB_RGGBLevelsAuto',
Writable => 'int32u',
Count => 4,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-4)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,4)',
},
0xa023 => { #1
Name => 'WB_RGGBLevelsIlluminator1',
Writable => 'int32u',
Count => 4,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-8)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,8)',
},
0xa024 => { #1
Name => 'WB_RGGBLevelsIlluminator2',
Writable => 'int32u',
Count => 4,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-1)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,1)',
},
#this doesn't seem correct
#0xa025 => { #PH/1
# Name => 'ColorTemperatureAuto',
# Writable => 'int32u',
# RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,6)',
# RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-6)',
#},
0xa028 => { #2/PH
Name => 'WB_RGGBLevelsBlack',
Writable => 'int32s',
Count => 4,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0")',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0)',
},
0xa030 => { #1
Name => 'ColorMatrix',
Writable => 'int32s',
Count => 9,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0")',
},
0xa031 => { #1
Name => 'ColorMatrixSRGB',
Writable => 'int32s',
Count => 9,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0")',
},
0xa032 => { #1
Name => 'ColorMatrixAdobeRGB',
Writable => 'int32s',
Count => 9,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0")',
},
0xa033 => { #1
Name => 'Samsung_Type2_0xa033',
Unknown => 1,
Hidden => 1,
Writable => 'int32s',
Count => 4,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0")',
},
0xa034 => { #1
Name => 'Samsung_Type2_0xa034',
Unknown => 1,
Hidden => 1,
Writable => 'int32s',
Count => 4,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,4)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-4)',
},
0xa035 => { #1
Name => 'Samsung_Type2_0xa035',
Unknown => 1,
Hidden => 1,
Writable => 'int32u',
Count => 2,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0")',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0)',
},
0xa036 => { #1
Name => 'Samsung_Type2_0xa036',
Unknown => 1,
Hidden => 1,
Writable => 'int32u',
Count => 2,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-2)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,2)',
},
0xa040 => { #1
Name => 'ToneCurve1',
Writable => 'int32u',
Count => 23,
Notes => q{
first value gives the number of tone curve entries. This is followed by an
array of X coordinates then an array of Y coordinates
},
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0,"-0")',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0",0)',
},
0xa041 => { #1
Name => 'ToneCurve2',
Writable => 'int32u',
Count => 23,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0,"-0")',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0",0)',
},
0xa042 => { #1
Name => 'ToneCurve3',
Writable => 'int32u',
Count => 23,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0,"-0")',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0",0)',
},
0xa043 => { #1
Name => 'ToneCurve4',
Writable => 'int32u',
Count => 23,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0,"-0")',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0",0)',
},
0xa048 => { #1
Name => 'Samsung_Type2_0xa048',
Unknown => 1,
Hidden => 1,
Writable => 'int32s',
Count => 12,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0")',
},
0xa050 => { #1 (vignette curve?)
Name => 'Samsung_Type2_0xa050',
Unknown => 1,
Hidden => 1,
Writable => 'int32s',
Count => 8,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0")',
},
0xa051 => { #1
Name => 'Samsung_Type2_0xa051',
Unknown => 1,
Hidden => 1,
Writable => 'int16u',
Count => 22,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0",-7,-3)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0,7,3)',
},
0xa052 => { #1 (vignette curve?)
Name => 'Samsung_Type2_0xa052',
Unknown => 1,
Hidden => 1,
Writable => 'int16u',
Count => 15,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0,"-0")',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0",0)',
},
0xa053 => { #1
Name => 'Samsung_Type2_0xa053',
Unknown => 1,
Hidden => 1,
Writable => 'int16u',
Count => 15,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0,"-0")',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0",0)',
},
0xa054 => { #1
Name => 'Samsung_Type2_0xa054',
Unknown => 1,
Hidden => 1,
Writable => 'int16u',
Count => 15,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0,"-0")',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0",0)',
},
0xa055 => { #1
Name => 'Samsung_Type2_0xa055',
Unknown => 1,
Hidden => 1,
Writable => 'int32s',
Count => 8,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,8)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-8)',
},
0xa056 => { #1
Name => 'Samsung_Type2_0xa056',
Unknown => 1,
Hidden => 1,
Writable => 'int32s',
Count => 8,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,5)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-5)',
},
0xa057 => { #1
Name => 'Samsung_Type2_0xa057',
Unknown => 1,
Hidden => 1,
Writable => 'int32s',
Count => 8,
RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,2)',
RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-2)',
},
);
# Picture Wizard information (ref 1)
%Image::ExifTool::Samsung::PictureWizard = (
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
WRITABLE => 1,
FORMAT => 'int16u',
FIRST_ENTRY => 0,
GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
0 => {
Name => 'PictureWizardMode',
PrintConvColumns => 3,
PrintConv => { #3
0 => 'Standard',
1 => 'Vivid',
2 => 'Portrait',
3 => 'Landscape',
4 => 'Forest',
5 => 'Retro',
6 => 'Cool',
7 => 'Calm',
8 => 'Classic',
9 => 'Custom1',
10 => 'Custom2',
11 => 'Custom3',
255 => 'n/a', #PH
},
},
1 => 'PictureWizardColor',
2 => {
Name => 'PictureWizardSaturation',
ValueConv => '$val - 4',
ValueConvInv => '$val + 4',
},
3 => {
Name => 'PictureWizardSharpness',
ValueConv => '$val - 4',
ValueConvInv => '$val + 4',
},
4 => {
Name => 'PictureWizardContrast',
ValueConv => '$val - 4',
ValueConvInv => '$val + 4',
},
);
# INFO tags in Samsung MP4 videos (ref PH)
%Image::ExifTool::Samsung::INFO = (
PROCESS_PROC => \&ProcessINFO,
GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
NOTES => q{
This information is found in MP4 videos from Samsung models such as the
SMX-C20N.
},
EFCT => 'Effect', # (guess)
QLTY => 'Quality',
# MDEL - value: 0
# ASPT - value: 1, 2
);
# Samsung MP4 TAGS information (PH - from WP10 sample)
# --> very similar to Sanyo MP4 information
%Image::ExifTool::Samsung::MP4 = (
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
NOTES => q{
This information is found in Samsung MP4 videos from models such as the
WP10.
},
0x00 => {
Name => 'Make',
Format => 'string[24]',
PrintConv => 'ucfirst(lc($val))',
},
0x18 => {
Name => 'Model',
Description => 'Camera Model Name',
Format => 'string[16]',
},
0x2e => { # (NC)
Name => 'ExposureTime',
Format => 'int32u',
ValueConv => '$val ? 10 / $val : 0',
PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
},
0x32 => {
Name => 'FNumber',
Format => 'rational64u',
PrintConv => 'sprintf("%.1f",$val)',
},
0x3a => { # (NC)
Name => 'ExposureCompensation',
Format => 'rational64s',
PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
},
0x6a => {
Name => 'ISO',
Format => 'int32u',
},
0x7d => {
Name => 'Software',
Format => 'string[32]',
# (these tags are not at a constant offset for Olympus/Sanyo videos,
# so just to be safe use this to validate subsequent tags)
RawConv => q{
$val =~ /^SAMSUNG/ or return undef;
$$self{SamsungMP4} = 1;
return $val;
},
},
0xf4 => {
Name => 'Thumbnail',
Condition => '$$self{SamsungMP4}',
SubDirectory => {
TagTable => 'Image::ExifTool::Samsung::Thumbnail',
Base => '$start',
},
},
);
# thumbnail image information found in MP4 videos (similar in Olympus,Samsung,Sanyo)
%Image::ExifTool::Samsung::Thumbnail = (
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
FIRST_ENTRY => 0,
FORMAT => 'int32u',
1 => 'ThumbnailWidth',
2 => 'ThumbnailHeight',
3 => 'ThumbnailLength',
4 => { Name => 'ThumbnailOffset', IsOffset => 1 },
);
# Samsung composite tags
%Image::ExifTool::Samsung::Composite = (
GROUPS => { 2 => 'Image' },
WB_RGGBLevels => {
Require => {
0 => 'WB_RGGBLevelsUncorrected',
1 => 'WB_RGGBLevelsBlack',
},
ValueConv => q{
my @a = split ' ', $val[0];
my @b = split ' ', $val[1];
$a[$_] -= $b[$_] foreach 0..$#a;
return "@a";
},
},
);
# add our composite tags
Image::ExifTool::AddCompositeTags('Image::ExifTool::Samsung');
#------------------------------------------------------------------------------
# Encrypt/Decrypt NX10 information
# Inputs: 0) ExifTool ref, 1) value as a string of integers,
# 2) tagInfo hash ref, 3-N) encryption salt values
# Returns: encrypted/decrypted value
# Notes:
# 1) The encryption salt starts with '-' to reverse the encryption algorithm
# 2) Additional salt values are provided when tag stores multiple arrays
# (in which case the first value of the tag gives the array length)
sub Crypt($$$@)
{
my ($exifTool, $val, $tagInfo, @salt) = @_;
my $key = $$exifTool{EncryptionKey} or return undef;
my $format = $$tagInfo{Writable} || $$tagInfo{Format} or return undef;
return undef unless $formatMinMax{$format};
my ($min, $max) = @{$formatMinMax{$format}};
my @a = split ' ', $val;
my $newSalt = (@salt > 1) ? 1 : 0; # skip length entry if this is an array
my ($i, $sign, $salt, $start);
for ($i=$newSalt; $i<@a; ++$i) {
if ($i == $newSalt) {
$start = $i;
$salt = shift @salt;
$sign = ($salt =~ s/^-//) ? -1 : 1;
$newSalt += $a[0] if @salt;
}
$a[$i] += $sign * $$key[($salt+$i-$start) % scalar(@$key)];
# handle integer wrap-around
if ($sign > 0) {
$a[$i] -= $max - $min + 1 if $a[$i] > $max;
} else {
$a[$i] += $max - $min + 1 if $a[$i] < $min;
}
}
return "@a";
}
#------------------------------------------------------------------------------
# Process Samsung MP4 INFO data
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
# Returns: 1 on success
sub ProcessINFO($$$)
{
my ($exifTool, $dirInfo, $tagTablePtr) = @_;
my $dataPt = $$dirInfo{DataPt};
my $pos = $$dirInfo{DirStart};
my $len = $$dirInfo{DirLen};
my $end = $pos + $len;
$exifTool->VerboseDir('INFO', undef, $len);
while ($pos + 8 <= $end) {
my $tag = substr($$dataPt, $pos, 4);
my $val = Get32u($dataPt, $pos + 4);
unless ($$tagTablePtr{$tag}) {
my $name = "Samsung_INFO_$tag";
$name =~ tr/-_0-9a-zA-Z//dc;
AddTagToTable($tagTablePtr, $tag, { Name => $name }) if $name;
}
$exifTool->HandleTag($tagTablePtr, $tag, $val);
$pos += 8;
}
return 1;
}
#------------------------------------------------------------------------------
# Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref
# Returns: true on success
sub ProcessSamsungIFD($$$)
{
my ($exifTool, $dirInfo, $tagTablePtr) = @_;
my $len = $$dirInfo{DataLen};
my $pos = $$dirInfo{DirStart};
return 0 unless $pos + 4 < $len;
my $dataPt = $$dirInfo{DataPt};
my $buff = substr($$dataPt, $pos, 4);
# this is not an IFD for many models
# (the string "Park Byeongchan" is often found here)
return 0 unless $buff =~ s/^([^\0])\0\0\0/$1\0$1\0/s;
my $numEntries = ord $1;
if ($$exifTool{HTML_DUMP}) {
my $pt = $$dirInfo{DirStart} + $$dirInfo{DataPos} + $$dirInfo{Base};
$exifTool->HDump($pt-44, 44, "MakerNotes header", 'Samsung Type1');
$exifTool->HDump($pt, 4, "MakerNotes entries", "Format: int32u\nEntry count: $numEntries");
$$dirInfo{NoDumpEntryCount} = 1;
}
substr($$dataPt, $pos, 4) = $buff; # insert bogus 2-byte entry count
# offset base is at end of IFD
my $shift = $$dirInfo{DirStart} + 4 + $numEntries * 12 + 4;
$$dirInfo{Base} += $shift;
$$dirInfo{DataPos} -= $shift;
$$dirInfo{DirStart} += 2; # start at bogus entry count
$$dirInfo{ZeroOffsetOK} = 1; # disable check for zero offset
delete $$exifTool{NO_UNKNOWN}; # (set for BinaryData, but not for EXIF IFD's)
my $rtn = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
substr($$dataPt, $pos + 2, 1) = "\0"; # remove bogus count
return $rtn;
}
#------------------------------------------------------------------------------
# Write Samsung STMN maker notes
# Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref
# Returns: Binary data block or undefined on error
sub WriteSTMN($$$)
{
my ($exifTool, $dirInfo, $tagTablePtr) = @_;
# create a Fixup for the PreviewImage
$$dirInfo{Fixup} = new Image::ExifTool::Fixup;
my $val = Image::ExifTool::WriteBinaryData($exifTool, $dirInfo, $tagTablePtr);
# force PreviewImage into the trailer even if it fits in EXIF segment
$$exifTool{PREVIEW_INFO}{IsTrailer} = 1 if $$exifTool{PREVIEW_INFO};
return $val;
}
1; # end
__END__
=head1 NAME
Image::ExifTool::Samsung - Samsung EXIF maker notes tags
=head1 SYNOPSIS
This module is loaded automatically by Image::ExifTool when required.
=head1 DESCRIPTION
This module contains definitions required by Image::ExifTool to interpret
Samsung maker notes in EXIF information.
=head1 AUTHOR
Copyright 2003-2012, Phil Harvey (phil at owl.phy.queensu.ca)
This library is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
=head1 REFERENCES
=over 4
=item L
=back
=head1 ACKNOWLEDGEMENTS
Thanks to Tae-Sun Park for decoding a number of tags, and Pascal de Bruijn
for the PictureWizard values.
=head1 SEE ALSO
L,
L
=cut