File Coverage

blib/lib/Image/ExifTool/SonyIDC.pm
Criterion Covered Total %
statement 12 36 33.3
branch 0 14 0.0
condition n/a
subroutine 4 5 80.0
pod 0 1 0.0
total 16 56 28.5


line stmt bran cond sub pod time code
1             #------------------------------------------------------------------------------
2             # File: SonyIDC.pm
3             #
4             # Description: Read/write Sony IDC information
5             #
6             # Revisions: 2010/01/05 - P. Harvey Created
7             #------------------------------------------------------------------------------
8              
9             package Image::ExifTool::SonyIDC;
10              
11 3     3   27 use strict;
  3         14  
  3         141  
12 3     3   20 use vars qw($VERSION);
  3         10  
  3         153  
13 3     3   25 use Image::ExifTool qw(:DataAccess :Utils);
  3         13  
  3         721  
14 3     3   30 use Image::ExifTool::Exif;
  3         10  
  3         2995  
15              
16             $VERSION = '1.08';
17              
18             # Sony IDC tags (ref PH)
19             %Image::ExifTool::SonyIDC::Main = (
20             WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
21             CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
22             GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
23             NOTES => 'Tags written by the Sony Image Data Converter utility in ARW images.',
24             SET_GROUP1 => 1,
25             0x201 => {
26             Name => 'IDCPreviewStart',
27             IsOffset => 1,
28             OffsetPair => 0x202,
29             DataTag => 'IDCPreview',
30             Writable => 'int32u',
31             Protected => 2,
32             },
33             0x202 => {
34             Name => 'IDCPreviewLength',
35             OffsetPair => 0x201,
36             DataTag => 'IDCPreview',
37             Writable => 'int32u',
38             Protected => 2,
39             },
40             0x8000 => {
41             Name => 'IDCCreativeStyle',
42             Writable => 'int32u',
43             PrintConvColumns => 2,
44             PrintConv => {
45             1 => 'Camera Setting',
46             2 => 'Standard',
47             3 => 'Real',
48             4 => 'Vivid',
49             5 => 'Adobe RGB',
50             6 => 'A100 Standard', # shows up as '-' in IDC menu
51             7 => 'Neutral',
52             8 => 'Portrait',
53             9 => 'Landscape',
54             10 => 'Clear',
55             11 => 'Deep',
56             12 => 'Light',
57             13 => 'Sunset',
58             14 => 'Night View',
59             15 => 'Autumn Leaves',
60             16 => 'B&W',
61             17 => 'Sepia',
62             },
63             },
64             0x8001 => {
65             Name => 'CreativeStyleWasChanged',
66             Writable => 'int32u',
67             Notes => 'set if the creative style was ever changed',
68             # (even if it was changed back again later)
69             PrintConv => { 0 => 'No', 1 => 'Yes' },
70             },
71             0x8002 => {
72             Name => 'PresetWhiteBalance',
73             Writable => 'int32u',
74             PrintConv => {
75             1 => 'Camera Setting',
76             2 => 'Color Temperature',
77             3 => 'Specify Gray Point',
78             4 => 'Daylight',
79             5 => 'Cloudy',
80             6 => 'Shade',
81             7 => 'Cool White Fluorescent',
82             8 => 'Day Light Fluorescent',
83             9 => 'Day White Fluorescent',
84             10 => 'Warm White Fluorescent',
85             11 => 'Tungsten',
86             12 => 'Flash',
87             13 => 'Auto',
88             },
89             },
90             0x8013 => { Name => 'ColorTemperatureAdj', Writable => 'int16u' },
91             0x8014 => { Name => 'PresetWhiteBalanceAdj',Writable => 'int32s' },
92             0x8015 => { Name => 'ColorCorrection', Writable => 'int32s' },
93             0x8016 => { Name => 'SaturationAdj', Writable => 'int32s' },
94             0x8017 => { Name => 'ContrastAdj', Writable => 'int32s' },
95             0x8018 => {
96             Name => 'BrightnessAdj',
97             Writable => 'int32s',
98             PrintConv => 'sprintf("%.2f", $val/300)', #JR
99             PrintConvInv => '$val * 300',
100             },
101             0x8019 => { Name => 'HueAdj', Writable => 'int32s' },
102             0x801a => { Name => 'SharpnessAdj', Writable => 'int32s' },
103             0x801b => { Name => 'SharpnessOvershoot', Writable => 'int32s' },
104             0x801c => { Name => 'SharpnessUndershoot', Writable => 'int32s' },
105             0x801d => { Name => 'SharpnessThreshold', Writable => 'int32s' },
106             0x801e => {
107             Name => 'NoiseReductionMode',
108             Writable => 'int16u',
109             PrintConv => {
110             0 => 'Off',
111             1 => 'On',
112             },
113             },
114             0x8021 => {
115             Name => 'GrayPoint',
116             Writable => 'int16u',
117             Count => 4,
118             },
119             0x8022 => {
120             Name => 'D-RangeOptimizerMode',
121             Writable => 'int16u',
122             PrintConv => {
123             0 => 'Off',
124             1 => 'Auto',
125             2 => 'Manual',
126             },
127             },
128             0x8023 => { Name => 'D-RangeOptimizerValue', Writable => 'int32s' },
129             0x8024 => { Name => 'D-RangeOptimizerHighlight',Writable => 'int32s' },
130             0x8026 => {
131             Name => 'HighlightColorDistortReduct',
132             Writable => 'int16u',
133             PrintConv => {
134             0 => 'Standard',
135             1 => 'Advanced',
136             },
137             },
138             0x8027 => {
139             Name => 'NoiseReductionValue',
140             Writable => 'int32s',
141             ValueConv => '($val + 100) / 2',
142             ValueConvInv => '$val * 2 - 100',
143             },
144             0x8028 => {
145             Name => 'EdgeNoiseReduction',
146             Writable => 'int32s',
147             ValueConv => '($val + 100) / 2',
148             ValueConvInv => '$val * 2 - 100',
149             },
150             0x8029 => {
151             Name => 'ColorNoiseReduction',
152             Writable => 'int32s',
153             ValueConv => '($val + 100) / 2',
154             ValueConvInv => '$val * 2 - 100',
155             },
156             0x802d => { Name => 'D-RangeOptimizerShadow', Writable => 'int32s' },
157             0x8030 => { Name => 'PeripheralIllumCentralRadius', Writable => 'int32s' },
158             0x8031 => { Name => 'PeripheralIllumCentralValue', Writable => 'int32s' },
159             0x8032 => { Name => 'PeripheralIllumPeriphValue', Writable => 'int32s' },
160             0x8040 => { #JR
161             Name => 'DistortionCompensation',
162             Writable => 'int32s',
163             PrintConv => {
164             -1 => 'n/a', # (fixed by lens)
165             1 => 'On',
166             2 => 'Off',
167             },
168             },
169             0x9000 => {
170             Name => 'ToneCurveBrightnessX',
171             Writable => 'int16u',
172             Count => -1,
173             },
174             0x9001 => {
175             Name => 'ToneCurveRedX',
176             Writable => 'int16u',
177             Count => -1,
178             },
179             0x9002 => {
180             Name => 'ToneCurveGreenX',
181             Writable => 'int16u',
182             Count => -1,
183             },
184             0x9003 => {
185             Name => 'ToneCurveBlueX',
186             Writable => 'int16u',
187             Count => -1,
188             },
189             0x9004 => {
190             Name => 'ToneCurveBrightnessY',
191             Writable => 'int16u',
192             Count => -1,
193             },
194             0x9005 => {
195             Name => 'ToneCurveRedY',
196             Writable => 'int16u',
197             Count => -1,
198             },
199             0x9006 => {
200             Name => 'ToneCurveGreenY',
201             Writable => 'int16u',
202             Count => -1,
203             },
204             0x9007 => {
205             Name => 'ToneCurveBlueY',
206             Writable => 'int16u',
207             Count => -1,
208             },
209             0x900d => { #JR
210             Name => 'ChromaticAberrationCorrection', # "Magnification Chromatic Aberration"
211             Writable => 'int32s',
212             PrintConv => { 1 => 'On', 2 => 'Off' },
213             },
214             0x900e => { #JR
215             Name => 'InclinationCorrection',
216             Writable => 'int32u',
217             PrintConv => { 0 => 'Off', 1 => 'On' },
218             },
219             0x900f => { #JR
220             Name => 'InclinationAngle',
221             Writable => 'int32s',
222             PrintConv => 'sprintf("%.1f deg", $val/1000)',
223             PrintConvInv => 'ToFloat($val) * 1000',
224             },
225             0x9010 => { #JR
226             Name => 'Cropping',
227             Writable => 'int32u',
228             PrintConv => { 0 => 'Off', 1 => 'On' },
229             },
230             0x9011 => { #JR
231             Name => 'CropArea',
232             Writable => 'int32u',
233             Count => 4,
234             },
235             0x9012 => { #JR
236             Name => 'PreviewImageSize',
237             Writable => 'int32u',
238             Count => 2,
239             },
240             0x9013 => { #JR (ARQ images)
241             Name => 'PxShiftPeriphEdgeNR',
242             Writable => 'int32s',
243             PrintConv => { 0 => 'Off', 1 => 'On' },
244             },
245             0x9014 => { #JR (ARQ images)
246             Name => 'PxShiftPeriphEdgeNRValue',
247             Writable => 'int32s',
248             PrintConv => 'sprintf("%.1f", $val/10)',
249             PrintConvInv => '$val * 10',
250             },
251             0x9017 => { Name => 'WhitesAdj', Writable => 'int32s' }, #JR
252             0x9018 => { Name => 'BlacksAdj', Writable => 'int32s' }, #JR
253             0x9019 => { Name => 'HighlightsAdj', Writable => 'int32s' }, #JR
254             0x901a => { Name => 'ShadowsAdj', Writable => 'int32s' }, #JR
255             0xd000 => { Name => 'CurrentVersion', Writable => 'int32u' },
256             0xd001 => {
257             Name => 'VersionIFD',
258             Groups => { 1 => 'Version0' },
259             Flags => 'SubIFD',
260             Notes => 'there is one VersionIFD for each entry in the "Version Stack"',
261             SubDirectory => {
262             DirName => 'Version0',
263             TagTable => 'Image::ExifTool::SonyIDC::Main',
264             Start => '$val',
265             Base => '$start',
266             MaxSubdirs => 20, # (IDC v3.0 writes max. 10)
267             RelativeBase => 1, # needed to write SubIFD with relative offsets
268             },
269             },
270             0xd100 => {
271             Name => 'VersionCreateDate',
272             Writable => 'string',
273             Groups => { 2 => 'Time' },
274             Notes => 'date/time when this entry was created in the "Version Stack"',
275             Shift => 'Time',
276             PrintConv => '$self->ConvertDateTime($val)',
277             PrintConvInv => '$self->InverseDateTime($val,0)',
278             },
279             0xd101 => {
280             Name => 'VersionModifyDate',
281             Writable => 'string',
282             Groups => { 2 => 'Time' },
283             Shift => 'Time',
284             PrintConv => '$self->ConvertDateTime($val)',
285             PrintConvInv => '$self->InverseDateTime($val,0)',
286             },
287             );
288              
289             # extract IDC preview images as composite tags
290             %Image::ExifTool::SonyIDC::Composite = (
291             GROUPS => { 2 => 'Image' },
292             IDCPreviewImage => {
293             Groups => { 2 => 'Preview' },
294             Require => {
295             0 => 'IDCPreviewStart',
296             1 => 'IDCPreviewLength',
297             },
298             # extract all preview images (not just one)
299             RawConv => q{
300             @grps = $self->GetGroup($$val{0});
301             require Image::ExifTool::SonyIDC;
302             Image::ExifTool::SonyIDC::ExtractPreviews($self);
303             },
304             },
305             );
306              
307             # add our composite tags
308             Image::ExifTool::AddCompositeTags('Image::ExifTool::SonyIDC');
309              
310             # set "Permanent" flag for all tags
311             {
312             my $key;
313             foreach $key (TagTableKeys(\%Image::ExifTool::SonyIDC::Main)) {
314             $Image::ExifTool::SonyIDC::Main{$key}{Permanent} = 1;
315             }
316             }
317              
318             #------------------------------------------------------------------------------
319             # Extract all IDC preview images
320             # Inputs: 0) ExifTool object ref
321             # Returns: data for "IDCPreviewImage" tag (which I have never seen),
322             # or undef if there was no preview in the SonyIDC IFD
323             sub ExtractPreviews($)
324             {
325 0     0 0   my $et = shift;
326 0           my $i = 1;
327 0           my $xtra = ' (1)';
328 0           my $preview;
329             # loop through all available IDC preview images in the order they were found
330 0           for (;;) {
331 0           my $key = "IDCPreviewStart$xtra";
332 0 0         unless (defined $$et{VALUE}{$key}) {
333 0 0         last unless $xtra;
334 0           $xtra = ''; # do the last tag extracted last
335 0           next;
336             }
337             # run through IDC preview images in the same order they were extracted
338 0 0         my $off = $et->GetValue($key, 'ValueConv') or last;
339 0 0         my $len = $et->GetValue("IDCPreviewLength$xtra", 'ValueConv') or last;
340             # get stack version from number in group 1 name
341 0           my $grp1 = $et->GetGroup($key, 1);
342 0 0         if ($grp1 =~ /(\d+)$/) {
343 0           my $tag = "IDCPreviewImage$1";
344 0 0         unless ($Image::ExifTool::Extra{$tag}) {
345 0           AddTagToTable(\%Image::ExifTool::Extra, $tag, {
346             Name => $tag,
347             Groups => { 0 => 'Composite', 1 => 'Composite', 2 => 'Preview'},
348             });
349             }
350 0           my $val = Image::ExifTool::Exif::ExtractImage($et, $off, $len, $tag);
351 0           $et->FoundTag($tag, $val, $et->GetGroup($key));
352             } else {
353 0           $preview = Image::ExifTool::Exif::ExtractImage($et, $off, $len, 'IDCPreviewImage');
354             }
355             # step to next set of tags unless we are done
356 0 0         last unless $xtra;
357 0           ++$i;
358 0           $xtra = " ($i)";
359             }
360 0           return $preview;
361             }
362              
363             1; # end
364              
365             __END__