1#------------------------------------------------------------------------------
2# File:         Kodak.pm
3#
4# Description:  Kodak EXIF maker notes and APP3 "Meta" tags
5#
6# Revisions:    03/28/2005  - P. Harvey Created
7#
8# References:   1) http://search.cpan.org/dist/Image-MetaData-JPEG/
9#               2) http://www.ozhiker.com/electronics/pjmt/jpeg_info/meta.html
10#               3) http://www.cybercom.net/~dcoffin/dcraw/
11#               4) Jim McGarvey private communication
12#               IB) Iliah Borg private communication (LibRaw)
13#
14# Notes:        There really isn't much public information about Kodak formats.
15#               The only source I could find was Image::MetaData::JPEG, which
16#               didn't provide information about decoding the tag values.  So
17#               this module represents a lot of work downloading sample images
18#               (about 100MB worth!), and testing with my daughter's CX4200.
19#------------------------------------------------------------------------------
20
21package Image::ExifTool::Kodak;
22
23use strict;
24use vars qw($VERSION);
25use Image::ExifTool qw(:DataAccess :Utils);
26use Image::ExifTool::Exif;
27
28$VERSION = '1.47';
29
30sub ProcessKodakIFD($$$);
31sub ProcessKodakText($$$);
32sub ProcessPose($$$);
33sub WriteKodakIFD($$$);
34
35# Kodak type 1 maker notes (ref 1)
36%Image::ExifTool::Kodak::Main = (
37    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
38    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
39    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
40    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
41    NOTES => q{
42        The table below contains the most common set of Kodak tags.  The following
43        Kodak camera models have been tested and found to use these tags: C360,
44        C663, C875, CX6330, CX6445, CX7330, CX7430, CX7525, CX7530, DC4800, DC4900,
45        DX3500, DX3600, DX3900, DX4330, DX4530, DX4900, DX6340, DX6440, DX6490,
46        DX7440, DX7590, DX7630, EasyShare-One, LS420, LS443, LS633, LS743, LS753,
47        V530, V550, V570, V603, V610, V705, Z650, Z700, Z710, Z730, Z740, Z760 and
48        Z7590.
49    },
50    WRITABLE => 1,
51    FIRST_ENTRY => 8,
52    0x00 => {
53        Name => 'KodakModel',
54        Format => 'string[8]',
55    },
56    0x09 => {
57        Name => 'Quality',
58        PrintConv => { #PH
59            1 => 'Fine',
60            2 => 'Normal',
61        },
62    },
63    0x0a => {
64        Name => 'BurstMode',
65        PrintConv => { 0 => 'Off', 1 => 'On' },
66    },
67    0x0c => {
68        Name => 'KodakImageWidth',
69        Format => 'int16u',
70    },
71    0x0e => {
72        Name => 'KodakImageHeight',
73        Format => 'int16u',
74    },
75    0x10 => {
76        Name => 'YearCreated',
77        Groups => { 2 => 'Time' },
78        Format => 'int16u',
79    },
80    0x12 => {
81        Name => 'MonthDayCreated',
82        Groups => { 2 => 'Time' },
83        Format => 'int8u[2]',
84        ValueConv => 'sprintf("%.2d:%.2d",split(" ", $val))',
85        ValueConvInv => '$val=~tr/:./ /;$val',
86    },
87    0x14 => {
88        Name => 'TimeCreated',
89        Groups => { 2 => 'Time' },
90        Format => 'int8u[4]',
91        Shift => 'Time',
92        ValueConv => 'sprintf("%.2d:%.2d:%.2d.%.2d",split(" ", $val))',
93        ValueConvInv => '$val=~tr/:./ /;$val',
94    },
95    0x18 => {
96        Name => 'BurstMode2',
97        Format => 'int16u',
98        Unknown => 1, # not sure about this tag (or other 'Unknown' tags)
99    },
100    0x1b => {
101        Name => 'ShutterMode',
102        PrintConv => { #PH
103            0 => 'Auto',
104            8 => 'Aperture Priority',
105            32 => 'Manual?',
106        },
107    },
108    0x1c => {
109        Name => 'MeteringMode',
110        PrintConv => { #PH
111            0 => 'Multi-segment',
112            1 => 'Center-weighted average',
113            2 => 'Spot',
114        },
115    },
116    0x1d => 'SequenceNumber',
117    0x1e => {
118        Name => 'FNumber',
119        Format => 'int16u',
120        ValueConv => '$val / 100',
121        ValueConvInv => 'int($val * 100 + 0.5)',
122    },
123    0x20 => {
124        Name => 'ExposureTime',
125        Format => 'int32u',
126        ValueConv => '$val / 1e5',
127        ValueConvInv => '$val * 1e5',
128        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
129        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
130    },
131    0x24 => {
132        Name => 'ExposureCompensation',
133        Format => 'int16s',
134        ValueConv => '$val / 1000',
135        ValueConvInv => '$val * 1000',
136        PrintConv => '$val > 0 ? "+$val" : $val',
137        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
138    },
139    0x26 => {
140        Name => 'VariousModes',
141        Format => 'int16u',
142        Unknown => 1,
143    },
144    0x28 => {
145        Name => 'Distance1',
146        Format => 'int32u',
147        Unknown => 1,
148    },
149    0x2c => {
150        Name => 'Distance2',
151        Format => 'int32u',
152        Unknown => 1,
153    },
154    0x30 => {
155        Name => 'Distance3',
156        Format => 'int32u',
157        Unknown => 1,
158    },
159    0x34 => {
160        Name => 'Distance4',
161        Format => 'int32u',
162        Unknown => 1,
163    },
164    0x38 => {
165        Name => 'FocusMode',
166        PrintConv => {
167            0 => 'Normal',
168            2 => 'Macro',
169        },
170    },
171    0x3a => {
172        Name => 'VariousModes2',
173        Format => 'int16u',
174        Unknown => 1,
175    },
176    0x3c => {
177        Name => 'PanoramaMode',
178        Format => 'int16u',
179        Unknown => 1,
180    },
181    0x3e => {
182        Name => 'SubjectDistance',
183        Format => 'int16u',
184        Unknown => 1,
185    },
186    0x40 => {
187        Name => 'WhiteBalance',
188        Priority => 0,
189        PrintConv => { #PH
190            0 => 'Auto',
191            1 => 'Flash?',
192            2 => 'Tungsten',
193            3 => 'Daylight',
194            # 5 - seen this for "Auto" with a ProBack 645M
195        },
196    },
197    0x5c => {
198        Name => 'FlashMode',
199        Flags => 'PrintHex',
200        # various models express this number differently
201        PrintConv => { #PH
202            0x00 => 'Auto',
203            0x01 => 'Fill Flash',
204            0x02 => 'Off',
205            0x03 => 'Red-Eye',
206            0x10 => 'Fill Flash',
207            0x20 => 'Off',
208            0x40 => 'Red-Eye?',
209        },
210    },
211    0x5d => {
212        Name => 'FlashFired',
213        PrintConv => { 0 => 'No', 1 => 'Yes' },
214    },
215    0x5e => {
216        Name => 'ISOSetting',
217        Format => 'int16u',
218        PrintConv => '$val ? $val : "Auto"',
219        PrintConvInv => '$val=~/^\d+$/ ? $val : 0',
220    },
221    0x60 => {
222        Name => 'ISO',
223        Format => 'int16u',
224    },
225    0x62 => {
226        Name => 'TotalZoom',
227        Format => 'int16u',
228        ValueConv => '$val / 100',
229        ValueConvInv => '$val * 100',
230    },
231    0x64 => {
232        Name => 'DateTimeStamp',
233        Format => 'int16u',
234        PrintConv => '$val ? "Mode $val" : "Off"',
235        PrintConvInv => '$val=~tr/0-9//dc; $val ? $val : 0',
236    },
237    0x66 => {
238        Name => 'ColorMode',
239        Format => 'int16u',
240        Flags => 'PrintHex',
241        # various models express this number differently
242        PrintConv => { #PH
243            0x01 => 'B&W',
244            0x02 => 'Sepia',
245            0x03 => 'B&W Yellow Filter',
246            0x04 => 'B&W Red Filter',
247            0x20 => 'Saturated Color',
248            0x40 => 'Neutral Color',
249            0x100 => 'Saturated Color',
250            0x200 => 'Neutral Color',
251            0x2000 => 'B&W',
252            0x4000 => 'Sepia',
253        },
254    },
255    0x68 => {
256        Name => 'DigitalZoom',
257        Format => 'int16u',
258        ValueConv => '$val / 100',
259        ValueConvInv => '$val * 100',
260    },
261    0x6b => {
262        Name => 'Sharpness',
263        Format => 'int8s',
264        %Image::ExifTool::Exif::printParameter,
265    },
266);
267
268# Kodak type 2 maker notes (ref PH)
269%Image::ExifTool::Kodak::Type2 = (
270    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
271    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
272    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
273    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
274    NOTES => q{
275        These tags are used by the Kodak DC220, DC260, DC265 and DC290,
276        Hewlett-Packard PhotoSmart 618, C500 and C912, Pentax EI-200 and EI-2000,
277        and Minolta EX1500Z.
278    },
279    WRITABLE => 1,
280    FIRST_ENTRY => 0,
281    0x08 => {
282        Name => 'KodakMaker',
283        Format => 'string[32]',
284    },
285    0x28 => {
286        Name => 'KodakModel',
287        Format => 'string[32]',
288    },
289    0x6c => {
290        Name => 'KodakImageWidth',
291        Format => 'int32u',
292    },
293    0x70 => {
294        Name => 'KodakImageHeight',
295        Format => 'int32u',
296    },
297);
298
299# Kodak type 3 maker notes (ref PH)
300%Image::ExifTool::Kodak::Type3 = (
301    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
302    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
303    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
304    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
305    NOTES => 'These tags are used by the DC240, DC280, DC3400 and DC5000.',
306    WRITABLE => 1,
307    FIRST_ENTRY => 0,
308    0x0c => {
309        Name => 'YearCreated',
310        Groups => { 2 => 'Time' },
311        Format => 'int16u',
312    },
313    0x0e => {
314        Name => 'MonthDayCreated',
315        Groups => { 2 => 'Time' },
316        Format => 'int8u[2]',
317        ValueConv => 'sprintf("%.2d:%.2d",split(" ", $val))',
318        ValueConvInv => '$val=~tr/:./ /;$val',
319    },
320    0x10 => {
321        Name => 'TimeCreated',
322        Groups => { 2 => 'Time' },
323        Format => 'int8u[4]',
324        Shift => 'Time',
325        ValueConv => 'sprintf("%2d:%.2d:%.2d.%.2d",split(" ", $val))',
326        ValueConvInv => '$val=~tr/:./ /;$val',
327    },
328    0x1e => {
329        Name => 'OpticalZoom',
330        Format => 'int16u',
331        ValueConv => '$val / 100',
332        ValueConvInv => '$val * 100',
333    },
334    0x37 => {
335        Name => 'Sharpness',
336        Format => 'int8s',
337        %Image::ExifTool::Exif::printParameter,
338    },
339    0x38 => {
340        Name => 'ExposureTime',
341        Format => 'int32u',
342        ValueConv => '$val / 1e5',
343        ValueConvInv => '$val * 1e5',
344        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
345        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
346    },
347    0x3c => {
348        Name => 'FNumber',
349        Format => 'int16u',
350        ValueConv => '$val / 100',
351        ValueConvInv => 'int($val * 100 + 0.5)',
352    },
353    0x4e => {
354        Name => 'ISO',
355        Format => 'int16u',
356    },
357);
358
359# Kodak type 4 maker notes (ref PH)
360%Image::ExifTool::Kodak::Type4 = (
361    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
362    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
363    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
364    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
365    NOTES => 'These tags are used by the DC200 and DC215.',
366    WRITABLE => 1,
367    FIRST_ENTRY => 0,
368    0x20 => {
369        Name => 'OriginalFileName',
370        Format => 'string[12]',
371    },
372);
373
374# Kodak type 5 maker notes (ref PH)
375%Image::ExifTool::Kodak::Type5 = (
376    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
377    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
378    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
379    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
380    NOTES => q{
381        These tags are used by the CX4200, CX4210, CX4230, CX4300, CX4310, CX6200
382        and CX6230.
383    },
384    WRITABLE => 1,
385    FIRST_ENTRY => 0,
386    0x14 => {
387        Name => 'ExposureTime',
388        Format => 'int32u',
389        ValueConv => '$val / 1e5',
390        ValueConvInv => '$val * 1e5',
391        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
392        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
393    },
394    0x1a => {
395        Name => 'WhiteBalance',
396        PrintConv => {
397            1 => 'Daylight',
398            2 => 'Flash',
399            3 => 'Tungsten',
400        },
401    },
402    0x1c => {
403        Name => 'FNumber',
404        Format => 'int16u',
405        ValueConv => '$val / 100',
406        ValueConvInv => 'int($val * 100 + 0.5)',
407    },
408    0x1e => {
409        Name => 'ISO',
410        Format => 'int16u',
411    },
412    0x20 => {
413        Name => 'OpticalZoom',
414        Format => 'int16u',
415        ValueConv => '$val / 100',
416        ValueConvInv => '$val * 100',
417    },
418    0x22 => {
419        Name => 'DigitalZoom',
420        Format => 'int16u',
421        ValueConv => '$val / 100',
422        ValueConvInv => '$val * 100',
423    },
424    0x27 => {
425        Name => 'FlashMode',
426        PrintConv => {
427            0 => 'Auto',
428            1 => 'On',
429            2 => 'Off',
430            3 => 'Red-Eye',
431        },
432    },
433    0x2a => {
434        Name => 'ImageRotated',
435        PrintConv => { 0 => 'No', 1 => 'Yes' },
436    },
437    0x2b => {
438        Name => 'Macro',
439        PrintConv => { 0 => 'On', 1 => 'Off' },
440    },
441);
442
443# Kodak type 6 maker notes (ref PH)
444%Image::ExifTool::Kodak::Type6 = (
445    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
446    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
447    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
448    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
449    NOTES => 'These tags are used by the DX3215 and DX3700.',
450    WRITABLE => 1,
451    FIRST_ENTRY => 0,
452    0x10 => {
453        Name => 'ExposureTime',
454        Format => 'int32u',
455        ValueConv => '$val / 1e5',
456        ValueConvInv => '$val * 1e5',
457        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
458        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
459    },
460    0x14 => {
461        Name => 'ISOSetting',
462        Format => 'int32u',
463        Unknown => 1,
464    },
465    0x18 => {
466        Name => 'FNumber',
467        Format => 'int16u',
468        ValueConv => '$val / 100',
469        ValueConvInv => 'int($val * 100 + 0.5)',
470    },
471    0x1a => {
472        Name => 'ISO',
473        Format => 'int16u',
474    },
475    0x1c => {
476        Name => 'OpticalZoom',
477        Format => 'int16u',
478        ValueConv => '$val / 100',
479        ValueConvInv => '$val * 100',
480    },
481    0x1e => {
482        Name => 'DigitalZoom',
483        Format => 'int16u',
484        ValueConv => '$val / 100',
485        ValueConvInv => '$val * 100',
486    },
487    0x22 => {
488        Name => 'Flash',
489        Format => 'int16u',
490        PrintConv => {
491            0 => 'No Flash',
492            1 => 'Fired',
493        },
494    },
495);
496
497# Kodak type 7 maker notes (ref PH)
498%Image::ExifTool::Kodak::Type7 = (
499    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
500    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
501    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
502    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
503    WRITABLE => 1,
504    FIRST_ENTRY => 0,
505    NOTES => q{
506        The maker notes of models such as the C340, C433, CC533, LS755, V803 and
507        V1003 seem to start with the camera serial number.  The C310, C315, C330,
508        C643, C743, CD33, CD43, CX7220 and CX7300 maker notes are also decoded using
509        this table, although the strings for these cameras don't conform to the
510        usual Kodak serial number format, and instead have the model name followed
511        by 8 digits.
512    },
513    0 => { # (not confirmed)
514        Name => 'SerialNumber',
515        Format => 'string[16]',
516        ValueConv => '$val=~s/\s+$//; $val', # remove trailing whitespace
517        ValueConvInv => '$val',
518    },
519);
520
521# Kodak IFD-format maker notes (ref PH)
522%Image::ExifTool::Kodak::Type8 = (
523    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
524    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
525    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
526    NOTES => q{
527        Kodak models such as the ZD710, P712, P850, P880, V1233, V1253, V1275,
528        V1285, Z612, Z712, Z812, Z885 use standard TIFF IFD format for the maker
529        notes.  In keeping with Kodak's strategy of inconsistent makernotes, models
530        such as the M380, M1033, M1093, V1073, V1273, Z1012, Z1085 and Z8612
531        also use these tags, but these makernotes begin with a TIFF header instead
532        of an IFD entry count and use relative instead of absolute offsets.  There
533        is a large amount of information stored in these maker notes (apparently
534        with much duplication), but relatively few tags have so far been decoded.
535    },
536    0xfc00 => [{
537        Name => 'SubIFD0',
538        Condition => '$format eq "undef"',
539        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
540        NestedHtmlDump => 2, # (so HtmlDump doesn't show these as double-referenced)
541        SubDirectory => {
542            TagTable => 'Image::ExifTool::Kodak::SubIFD0',
543            Base => '$start',
544            ProcessProc => \&ProcessKodakIFD,
545            WriteProc => \&WriteKodakIFD,
546        },
547    },{
548        Name => 'SubIFD0',
549        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
550        Flags => 'SubIFD',
551        SubDirectory => {
552            TagTable => 'Image::ExifTool::Kodak::SubIFD0',
553            Start => '$val',
554            # (odd but true: the Base for this SubIFD is different than 0xfc01-0xfc06)
555        },
556    }],
557    # SubIFD1 and higher data is preceded by a TIFF byte order mark to indicate
558    # the byte ordering used.  Beginning with the M580, these subdirectories are
559    # stored as 'undef' data rather than as a standard EXIF SubIFD.
560    0xfc01 => [{
561        Name => 'SubIFD1',
562        Condition => '$format eq "undef"',
563        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
564        NestedHtmlDump => 2,
565        SubDirectory => {
566            TagTable => 'Image::ExifTool::Kodak::SubIFD1',
567            Base => '$start',
568        },
569    },{
570        Name => 'SubIFD1',
571        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
572        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
573        Flags => 'SubIFD',
574        SubDirectory => {
575            TagTable => 'Image::ExifTool::Kodak::SubIFD1',
576            Start => '$val',
577            Base => '$start',
578        },
579    }],
580    0xfc02 => [{
581        Name => 'SubIFD2',
582        Condition => '$format eq "undef"',
583        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
584        NestedHtmlDump => 2,
585        SubDirectory => {
586            TagTable => 'Image::ExifTool::Kodak::SubIFD2',
587            Base => '$start',
588        },
589    },{
590        Name => 'SubIFD2',
591        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
592        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
593        Flags => 'SubIFD',
594        SubDirectory => {
595            TagTable => 'Image::ExifTool::Kodak::SubIFD2',
596            Start => '$val',
597            Base => '$start',
598        },
599    }],
600    0xfc03 => [{
601        Name => 'SubIFD3',
602        Condition => '$format eq "undef"',
603        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
604        NestedHtmlDump => 2,
605        SubDirectory => {
606            TagTable => 'Image::ExifTool::Kodak::SubIFD3',
607            Base => '$start',
608        },
609    },{
610        Name => 'SubIFD3',
611        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
612        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
613        Flags => 'SubIFD',
614        SubDirectory => {
615            TagTable => 'Image::ExifTool::Kodak::SubIFD3',
616            Start => '$val',
617            Base => '$start',
618        },
619    }],
620    # (SubIFD4 has the pointer zeroed in my samples, but support it
621    # in case it is used by future models -- ignored if pointer is zero)
622    0xfc04 => [{
623        Name => 'SubIFD4',
624        Condition => '$format eq "undef"',
625        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
626        NestedHtmlDump => 2,
627        SubDirectory => {
628            TagTable => 'Image::ExifTool::Kodak::SubIFD4',
629            Base => '$start',
630        },
631    },{
632        Name => 'SubIFD4',
633        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
634        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
635        Flags => 'SubIFD',
636        SubDirectory => {
637            TagTable => 'Image::ExifTool::Kodak::SubIFD4',
638            Start => '$val',
639            Base => '$start',
640        },
641    }],
642    0xfc05 => [{
643        Name => 'SubIFD5',
644        Condition => '$format eq "undef"',
645        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
646        NestedHtmlDump => 2,
647        SubDirectory => {
648            TagTable => 'Image::ExifTool::Kodak::SubIFD5',
649            Base => '$start',
650        },
651    },{
652        Name => 'SubIFD5',
653        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
654        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
655        Flags => 'SubIFD',
656        SubDirectory => {
657            TagTable => 'Image::ExifTool::Kodak::SubIFD5',
658            Start => '$val',
659            Base => '$start',
660        },
661    }],
662    0xfc06 => [{ # new for the M580
663        Name => 'SubIFD6',
664        Condition => '$format eq "undef"',
665        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
666        NestedHtmlDump => 2,
667        SubDirectory => {
668            TagTable => 'Image::ExifTool::Kodak::SubIFD6',
669            Base => '$start',
670        },
671    },{
672        Name => 'SubIFD6',
673        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
674        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
675        Flags => 'SubIFD',
676        SubDirectory => {
677            TagTable => 'Image::ExifTool::Kodak::SubIFD6',
678            Start => '$val',
679            Base => '$start',
680        },
681    }],
682    0xfcff => {
683        Name => 'SubIFD255',
684        Condition => '$format eq "undef"',
685        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
686        NestedHtmlDump => 2,
687        SubDirectory => {
688            TagTable => 'Image::ExifTool::Kodak::SubIFD0',
689            # (uses the same Base as the main MakerNote IFD)
690        },
691    },
692    0xff00 => {
693        Name => 'CameraInfo',
694        Condition => '$$valPt ne "\0\0\0\0"',   # may be zero if dir doesn't exist
695        Groups => { 1 => 'MakerNotes' },        # SubIFD needs group 1 set
696        Flags => 'SubIFD',
697        SubDirectory => {
698            TagTable => 'Image::ExifTool::Kodak::CameraInfo',
699            Start => '$val',
700            # (uses the same Base as the main MakerNote IFD)
701        },
702    },
703);
704
705# Kodak type 9 maker notes (ref PH)
706%Image::ExifTool::Kodak::Type9 = (
707    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
708    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
709    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
710    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
711    WRITABLE => 1,
712    FIRST_ENTRY => 0,
713    NOTES => q{
714        These tags are used by the Kodak C140, C180, C913, C1013, M320, M340 and
715        M550, as well as various cameras marketed by other manufacturers.
716    },
717    0x0c => [
718        {
719            Name => 'FNumber',
720            Condition => '$$self{Make} =~ /Kodak/i',
721            Format => 'int16u',
722            ValueConv => '$val / 100',
723            ValueConvInv => 'int($val * 100 + 0.5)',
724        },{
725            Name => 'FNumber',
726            Format => 'int16u',
727            ValueConv => '$val / 10',
728            ValueConvInv => 'int($val * 10 + 0.5)',
729        },
730    ],
731    0x10 => {
732        Name => 'ExposureTime',
733        Format => 'int32u',
734        ValueConv => '$val / 1e6',
735        ValueConvInv => '$val * 1e6',
736        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
737        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
738    },
739    0x14 => {
740        Name => 'DateTimeOriginal',
741        Description => 'Date/Time Original',
742        Groups => { 2 => 'Time' },
743        Format => 'string[20]',
744        Shift => 'Time',
745        ValueConv => '$val=~s{/}{:}g; $val',
746        ValueConvInv => '$val=~s{^(\d{4}):(\d{2}):}{$1/$2/}; $val',
747        PrintConv => '$self->ConvertDateTime($val)',
748        PrintConvInv => '$self->InverseDateTime($val,0)',
749    },
750    0x34 => {
751        Name => 'ISO',
752        Format => 'int16u',
753    },
754    0x57 => {
755        Name => 'FirmwareVersion',
756        Condition => '$$self{Make} =~ /Kodak/i',
757        Format => 'string[16]',
758        Notes => 'Kodak only',
759    },
760    0xa8 => {
761        Name => 'UnknownNumber', # (was SerialNumber, but not unique for all cameras. eg. C1013)
762        Condition => '$$self{Make} =~ /Kodak/i and $$valPt =~ /^([A-Z0-9]{1,11}\0|[A-Z0-9]{12})/i',
763        Format => 'string[12]',
764        Notes => 'Kodak only',
765        Writable => 0,
766    },
767    0xc4 => {
768        Name => 'UnknownNumber', # (confirmed NOT to be serial number for Easyshare Mini - PH)
769        Condition => '$$self{Make} =~ /Kodak/i and $$valPt =~ /^([A-Z0-9]{1,11}\0|[A-Z0-9]{12})/i',
770        Format => 'string[12]',
771        Notes => 'Kodak only',
772        Writable => 0,
773    },
774);
775
776# more Kodak IFD-format maker notes (ref PH)
777%Image::ExifTool::Kodak::Type10 = (
778    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
779    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
780    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
781    PRIORITY => 0,
782    NOTES => q{
783        Another variation of the IFD-format type, this time with just a byte order
784        indicator instead of a full TIFF header.  These tags are used by the Z980.
785    },
786    # 0x01 int16u - always 0
787    0x02 => {
788        Name => 'PreviewImageSize',
789        Writable => 'int16u',
790        Count => 2,
791        PrintConv => '$val =~ tr/ /x/; $val',
792        PrintConvInv => '$val =~ tr/x/ /; $val',
793    },
794    # 0x03 int32u - ranges from about 33940 to 40680
795    # 0x04 int32u - always 18493
796    # 0x06 undef[4] - 07 d9 04 11
797    # 0x07 undef[3] - varies
798    # 0x08 int16u - 1 (mostly), 2
799    # 0x09 int16u - 255
800    # 0x0b int16u[2] - '0 0' (mostly), '20 0', '21 0', '1 0'
801    # 0x0c int16u - 1 (mostly), 3, 259, 260
802    # 0x0d int16u - 0
803    # 0x0e int16u - 0, 1, 2 (MeteringMode? 0=Partial, 1,2=Multi)
804    # 0x0f int16u - 0, 5 (MeteringMode? 0=Multi, 5=Partial)
805    # 0x10 int16u - ranges from about 902 to 2308
806    0x12 => {
807        Name => 'ExposureTime',
808        Writable => 'int32u',
809        ValueConv => '$val / 1e5',
810        ValueConvInv => '$val * 1e5',
811        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
812        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
813    },
814    0x13 => {
815        Name => 'FNumber',
816        Writable => 'int16u',
817        ValueConv => '$val / 10',
818        ValueConvInv => '$val * 10',
819    },
820    0x14 => {
821        Name => 'ISO',
822        Writable => 'int16u',
823        ValueConv => 'exp($val/3*log(2))*25',
824        ValueConvInv => '3*log($val/25)/log(2)',
825        PrintConv => 'int($val + 0.5)',
826        PrintConvInv => '$val',
827    },
828    # 0x15 int16u - 18-25 (SceneMode? 21=auto, 24=Aperture Priority, 19=high speed)
829    # 0x16 int16u - 50
830    # 0x17 int16u - 0, 65535 (MeteringMode? 0=Multi, 65535=Partial)
831    # 0x19 int16u - 0, 4 (WhiteBalance? 0=Auto, 4=Manual)
832    # 0x1a int16u - 0, 65535
833    # 0x1b int16u - 416-696
834    # 0x1c int16u - 251-439 (low when 0x1b is high)
835    0x1d => {
836        Name => 'FocalLength',
837        Writable => 'int32u',
838        ValueConv => '$val / 100',
839        ValueConvInv => '$val * 100',
840        PrintConv => '"$val mm"',
841        PrintConvInv => '$val=~s/\s*mm//;$val',
842    },
843    # 0x1e int16u - 100
844    # 0x1f int16u - 0, 1
845    # 0x20,0x21 int16u - 1
846    # 0x27 undef[4] - fe ff ff ff
847    # 0x32 undef[4] - 00 00 00 00
848    # 0x61 int32u[2] - '0 0' or '34050 0'
849    # 0x62 int8u - 0, 1
850    # 0x63 int8u - 1
851    # 0x64,0x65 int8u - 0, 1, 2
852    # 0x66 int32u - 0
853    # 0x67 int32u - 3
854    # 0x68 int32u - 0
855    # 0x3fe undef[2540]
856);
857
858# Kodak PixPro S-1 maker notes (ref PH)
859# (similar to Ricoh::Type2 and GE::Main)
860%Image::ExifTool::Kodak::Type11 = (
861    # (can't currently write these)
862    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
863    NOTES =>q{
864        These tags are found in models such as the PixPro S-1.  They are not
865        writable because the inconsistency of Kodak maker notes is beginning to get
866        on my nerves.
867    },
868    # (these are related to the Kodak QuickTime UserData tags)
869    0x0104 => 'FirmwareVersion',
870    0x0203 => {
871        Name => 'PictureEffect',
872        PrintConv => {
873            0 => 'None',
874            3 => 'Monochrome',
875            9 => 'Kodachrome',
876        },
877    },
878    # 0x0204 - ExposureComp or FlashExposureComp maybe?
879    0x0207 => 'KodakModel',
880    0x0300 => 'KodakMake',
881    0x0308 => 'LensSerialNumber',
882    0x0309 => 'LensModel',
883    0x030d => { Name => 'LevelMeter', Unknown => 1 }, # (guess)
884    0x0311 => 'Pitch', # Units??
885    0x0312 => 'Yaw',   # Units??
886    0x0313 => 'Roll',  # Units??
887    0x0314 => { Name => 'CX',   Unknown => 1 },
888    0x0315 => { Name => 'CY',   Unknown => 1 },
889    0x0316 => { Name => 'Rads', Unknown => 1 },
890);
891
892# Kodak SubIFD0 tags (ref PH)
893%Image::ExifTool::Kodak::SubIFD0 = (
894    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
895    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
896    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
897    NOTES => 'SubIFD0 through SubIFD5 tags are written a number of newer Kodak models.',
898    0xfa02 => {
899        Name => 'SceneMode',
900        Writable => 'int16u',
901        Notes => 'may not be valid for some models', # eg. M580?
902        PrintConvColumns => 2,
903        PrintConv => {
904            1 => 'Sport',
905            3 => 'Portrait',
906            4 => 'Landscape',
907            6 => 'Beach',
908            7 => 'Night Portrait',
909            8 => 'Night Landscape',
910            9 => 'Snow',
911            10 => 'Text',
912            11 => 'Fireworks',
913            12 => 'Macro',
914            13 => 'Museum',
915            16 => 'Children',
916            17 => 'Program',
917            18 => 'Aperture Priority',
918            19 => 'Shutter Priority',
919            20 => 'Manual',
920            25 => 'Back Light',
921            28 => 'Candlelight',
922            29 => 'Sunset',
923            31 => 'Panorama Left-right',
924            32 => 'Panorama Right-left',
925            33 => 'Smart Scene',
926            34 => 'High ISO',
927        },
928    },
929    # 0xfa04 - values: 0 (normally), 2 (panorama shots)
930    # 0xfa0f - values: 0 (normally), 1 (macro?)
931    # 0xfa11 - some sort of FNumber (x 100)
932    0xfa19 => {
933        Name => 'SerialNumber', # (verified with Z712 - PH)
934        Writable => 'string',
935    },
936    0xfa1d => {
937        Name => 'KodakImageWidth',
938        Writable => 'int16u',
939    },
940    0xfa1e => {
941        Name => 'KodakImageHeight',
942        Writable => 'int16u',
943    },
944    0xfa20 => {
945        Name => 'SensorWidth',
946        Writable => 'int16u',
947    },
948    0xfa21 => {
949        Name => 'SensorHeight',
950        Writable => 'int16u',
951    },
952    0xfa23 => {
953        Name => 'FNumber',
954        Writable => 'int16u',
955        Priority => 0,
956        ValueConv => '$val / 100',
957        ValueConvInv => '$val * 100',
958    },
959    0xfa24 => {
960        Name => 'ExposureTime',
961        Writable => 'int32u',
962        Priority => 0,
963        ValueConv => '$val / 1e5',
964        ValueConvInv => '$val * 1e5',
965        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
966        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
967    },
968    0xfa2e => {
969        Name => 'ISO',
970        Writable => 'int16u',
971        Priority => 0,
972    },
973    0xfa3d => {
974        Name => 'OpticalZoom',
975        Writable => 'int16u',
976        ValueConv => '$val / 100',
977        ValueConvInv => '$val * 100',
978        PrintConv => 'sprintf("%.2f",$val)',
979        PrintConvInv => '$val=~s/ ?x//; $val',
980    },
981    0xfa46 => {
982        Name => 'ISO',
983        Writable => 'int16u',
984        Priority => 0,
985    },
986    # 0xfa4c - related to focal length (1=wide, 32=full zoom)
987    0xfa51 => {
988        Name => 'KodakImageWidth',
989        Writable => 'int16u',
990    },
991    0xfa52 => {
992        Name => 'KodakImageHeight',
993        Writable => 'int16u',
994    },
995    0xfa54 => {
996        Name => 'ThumbnailWidth',
997        Writable => 'int16u',
998    },
999    0xfa55 => {
1000        Name => 'ThumbnailHeight',
1001        Writable => 'int16u',
1002    },
1003    0xfa57 => {
1004        Name => 'PreviewImageWidth',
1005        Writable => 'int16u',
1006    },
1007    0xfa58 => {
1008        Name => 'PreviewImageHeight',
1009        Writable => 'int16u',
1010    },
1011);
1012
1013# Kodak SubIFD1 tags (ref PH)
1014%Image::ExifTool::Kodak::SubIFD1 = (
1015    PROCESS_PROC => \&ProcessKodakIFD,
1016    WRITE_PROC => \&WriteKodakIFD,
1017    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1018    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
1019    0x0027 => {
1020        Name => 'ISO',
1021        Writable => 'int16u',
1022        Priority => 0,
1023    },
1024    0x0028 => {
1025        Name => 'ISO',
1026        Writable => 'int16u',
1027        Priority => 0,
1028    },
1029);
1030
1031my %sceneModeUsed = (
1032    0 => 'Program',
1033    2 => 'Aperture Priority',
1034    3 => 'Shutter Priority',
1035    4 => 'Manual',
1036    5 => 'Portrait',
1037    6 => 'Sport',
1038    7 => 'Children',
1039    8 => 'Museum',
1040    10 => 'High ISO',
1041    11 => 'Text',
1042    12 => 'Macro',
1043    13 => 'Back Light',
1044    16 => 'Landscape',
1045    17 => 'Night Landscape',
1046    18 => 'Night Portrait',
1047    19 => 'Snow',
1048    20 => 'Beach',
1049    21 => 'Fireworks',
1050    22 => 'Sunset',
1051    23 => 'Candlelight',
1052    28 => 'Panorama',
1053);
1054
1055# Kodak SubIFD2 tags (ref PH)
1056%Image::ExifTool::Kodak::SubIFD2 = (
1057    PROCESS_PROC => \&ProcessKodakIFD,
1058    WRITE_PROC => \&WriteKodakIFD,
1059    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1060    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
1061    0x6002 => {
1062        Name => 'SceneModeUsed',
1063        Writable => 'int32u',
1064        PrintConvColumns => 2,
1065        PrintConv => \%sceneModeUsed,
1066    },
1067    0x6006 => {
1068        Name => 'OpticalZoom',
1069        Writable => 'int32u',
1070        ValueConv => '$val / 100',
1071        ValueConvInv => '$val * 100',
1072        PrintConv => 'sprintf("%.2f",$val)',
1073        PrintConvInv => '$val=~s/ ?x//; $val',
1074    },
1075    # 0x6009 - some sort of FNumber (x 100)
1076    0x6103 => {
1077        Name => 'MaxAperture',
1078        Writable => 'int32u',
1079        ValueConv => '$val / 100',
1080        ValueConvInv => '$val * 100',
1081    },
1082    0xf002 => {
1083        Name => 'SceneModeUsed',
1084        Writable => 'int32u',
1085        PrintConvColumns => 2,
1086        PrintConv => \%sceneModeUsed,
1087    },
1088    0xf006 => {
1089        Name => 'OpticalZoom',
1090        Writable => 'int32u',
1091        ValueConv => '$val / 100',
1092        ValueConvInv => '$val * 100',
1093        PrintConv => 'sprintf("%.2f",$val)',
1094        PrintConvInv => '$val=~s/ ?x//; $val',
1095    },
1096    # 0xf009 - some sort of FNumber (x 100)
1097    0xf103 => {
1098        Name => 'FNumber',
1099        Writable => 'int32u',
1100        Priority => 0,
1101        ValueConv => '$val / 100',
1102        ValueConvInv => '$val * 100',
1103    },
1104    0xf104 => {
1105        Name => 'ExposureTime',
1106        Writable => 'int32u',
1107        Priority => 0,
1108        ValueConv => '$val / 1e6',
1109        ValueConvInv => '$val * 1e6',
1110        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
1111        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
1112    },
1113    0xf105 => {
1114        Name => 'ISO',
1115        Writable => 'int32u',
1116        Priority => 0,
1117        ValueConv => '$val / 10',
1118        ValueConvInv => '$val * 10',
1119    },
1120);
1121
1122# Kodak SubIFD3 tags (ref PH)
1123%Image::ExifTool::Kodak::SubIFD3 = (
1124    PROCESS_PROC => \&ProcessKodakIFD,
1125    WRITE_PROC => \&WriteKodakIFD,
1126    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1127    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
1128    0x1000 => {
1129        Name => 'OpticalZoom',
1130        Writable => 'int16u',
1131        ValueConv => '$val / 100',
1132        ValueConvInv => '$val * 100',
1133        PrintConv => 'sprintf("%.2f",$val)',
1134        PrintConvInv => '$val=~s/ ?x//; $val',
1135    },
1136    # 0x1002 - related to focal length (1=wide, 32=full zoom)
1137    # 0x1006 - pictures remaining? (gradually decreases as pictures are taken)
1138#
1139# the following unknown Kodak tags in subIFD3 may store an IFD count of 0 or 1 instead
1140# of the correct value (which changes from model to model).  This bad count is fixed
1141# with the "FixCount" patch.  Models known to have this problem include:
1142# M380, M1033, M1093IS, V1073, V1233, V1253, V1273, V1275, V1285, Z612, Z712,
1143# Z812, Z885, Z915, Z950, Z1012IS, Z1085IS, ZD710
1144#
1145    0x2007 => {
1146        Name => 'Kodak_SubIFD3_0x2007',
1147        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1148    },
1149    0x2008 => {
1150        Name => 'Kodak_SubIFD3_0x2008',
1151        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1152    },
1153    0x2009 => {
1154        Name => 'Kodak_SubIFD3_0x2009',
1155        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1156    },
1157    0x200a => {
1158        Name => 'Kodak_SubIFD3_0x200a',
1159        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1160    },
1161    0x200b => {
1162        Name => 'Kodak_SubIFD3_0x200b',
1163        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1164    },
1165    0x3020 => {
1166        Name => 'Kodak_SubIFD3_0x3020',
1167        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1168    },
1169    0x3030 => {
1170        Name => 'Kodak_SubIFD3_0x3030',
1171        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1172    },
1173    0x3040 => {
1174        Name => 'Kodak_SubIFD3_0x3040',
1175        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1176    },
1177    0x3050 => {
1178        Name => 'Kodak_SubIFD3_0x3050',
1179        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1180    },
1181    0x3060 => {
1182        Name => 'Kodak_SubIFD3_0x3060',
1183        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1184    },
1185    0x8001 => {
1186        Name => 'Kodak_SubIFD3_0x8001',
1187        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1188    },
1189    0x8002 => {
1190        Name => 'Kodak_SubIFD3_0x8002',
1191        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1192    },
1193    0x8003 => {
1194        Name => 'Kodak_SubIFD3_0x8003',
1195        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1196    },
1197    0x8004 => {
1198        Name => 'Kodak_SubIFD3_0x8004',
1199        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1200    },
1201    0x8005 => {
1202        Name => 'Kodak_SubIFD3_0x8005',
1203        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1204    },
1205    0x8006 => {
1206        Name => 'Kodak_SubIFD3_0x8006',
1207        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1208    },
1209    0x8007 => {
1210        Name => 'Kodak_SubIFD3_0x8007',
1211        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1212    },
1213    0x8008 => {
1214        Name => 'Kodak_SubIFD3_0x8008',
1215        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1216    },
1217    0x8009 => {
1218        Name => 'Kodak_SubIFD3_0x8009',
1219        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1220    },
1221    0x800a => {
1222        Name => 'Kodak_SubIFD3_0x800a',
1223        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1224    },
1225    0x800b => {
1226        Name => 'Kodak_SubIFD3_0x800b',
1227        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1228    },
1229    0x800c => {
1230        Name => 'Kodak_SubIFD3_0x800c',
1231        Flags => [ 'FixCount', 'Unknown', 'Hidden' ],
1232    },
1233);
1234
1235# Kodak SubIFD4 tags (ref PH)
1236%Image::ExifTool::Kodak::SubIFD4 = (
1237    PROCESS_PROC => \&ProcessKodakIFD,
1238    WRITE_PROC => \&WriteKodakIFD,
1239    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1240    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
1241);
1242
1243# Kodak SubIFD5 tags (ref PH)
1244%Image::ExifTool::Kodak::SubIFD5 = (
1245    PROCESS_PROC => \&ProcessKodakIFD,
1246    WRITE_PROC => \&WriteKodakIFD,
1247    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1248    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
1249    0x000f => {
1250        Name => 'OpticalZoom',
1251        Writable => 'int16u',
1252        ValueConv => '$val / 100',
1253        ValueConvInv => '$val * 100',
1254        PrintConv => 'sprintf("%.2f",$val)',
1255        PrintConvInv => '$val=~s/ ?x//; $val',
1256    },
1257);
1258
1259# Kodak SubIFD6 tags (ref PH)
1260%Image::ExifTool::Kodak::SubIFD6 = (
1261    PROCESS_PROC => \&ProcessKodakIFD,
1262    WRITE_PROC => \&WriteKodakIFD,
1263    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1264    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
1265    NOTES => 'SubIFD6 is written by the M580.',
1266);
1267
1268# Decoded from P712, P850 and P880 samples (ref PH)
1269%Image::ExifTool::Kodak::CameraInfo = (
1270    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
1271    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1272    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
1273    NOTES => 'These tags are used by the  P712, P850 and P880.',
1274    0xf900 => {
1275        Name => 'SensorWidth',
1276        Writable => 'int16u',
1277        Notes => 'effective sensor size',
1278    },
1279    0xf901 => {
1280        Name => 'SensorHeight',
1281        Writable => 'int16u',
1282    },
1283    0xf902 => {
1284        Name => 'BayerPattern',
1285        Writable => 'string',
1286    },
1287    0xf903 => {
1288        Name => 'SensorFullWidth',
1289        Writable => 'int16u',
1290        Notes => 'includes black border?',
1291    },
1292    0xf904 => {
1293        Name => 'SensorFullHeight',
1294        Writable => 'int16u',
1295    },
1296    0xf907 => {
1297        Name => 'KodakImageWidth',
1298        Writable => 'int16u',
1299    },
1300    0xf908 => {
1301        Name => 'KodakImageHeight',
1302        Writable => 'int16u',
1303    },
1304    0xfa00 => {
1305        Name => 'KodakInfoType',
1306        Writable => 'string',
1307    },
1308    0xfa04 => {
1309        Name => 'SerialNumber', # (unverified)
1310        Writable => 'string',
1311    },
1312    0xfd04 => {
1313        Name => 'FNumber',
1314        Writable => 'int16u',
1315        Priority => 0,
1316        ValueConv => '$val / 100',
1317        ValueConvInv => '$val * 100',
1318    },
1319    0xfd05 => {
1320        Name => 'ExposureTime',
1321        Writable => 'int32u',
1322        Priority => 0,
1323        ValueConv => '$val / 1e6',
1324        ValueConvInv => '$val * 1e6',
1325        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
1326        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
1327    },
1328    0xfd06 => {
1329        Name => 'ISO',
1330        Writable => 'int16u',
1331        Priority => 0,
1332    },
1333);
1334
1335# treat unknown maker notes as binary data (allows viewing with -U)
1336%Image::ExifTool::Kodak::Unknown = (
1337    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
1338    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
1339    FIRST_ENTRY => 0,
1340);
1341
1342# tags found in the KodakIFD (in IFD0 of KDC, DCR, TIFF and JPEG images) (ref PH)
1343%Image::ExifTool::Kodak::IFD = (
1344    GROUPS => { 0 => 'MakerNotes', 1 => 'KodakIFD', 2 => 'Image'},
1345    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
1346    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
1347    WRITE_GROUP => 'KodakIFD',
1348    SET_GROUP1 => 1,
1349    NOTES => q{
1350        These tags are found in a separate IFD of JPEG, TIFF, DCR and KDC images
1351        from some older Kodak models such as the DC50, DC120, DCS760C, DCS Pro 14N,
1352        14nx, SLR/n, Pro Back and Canon EOS D2000.
1353    },
1354    # 0x0000: int8u[4]    - values: "1 0 0 0" (DC50), "1 1 0 0" (DC120)
1355    0x0000 => { #4
1356        Name => 'KodakVersion',
1357        Writable => 'int8u',
1358        Count => 4,
1359        PrintConv => '$val =~ tr/ /./; $val',
1360        PrintConvInv => '$val =~ tr/./ /; $val',
1361    },
1362    0x0001 => {
1363        # (related to EV but exact meaning unknown)
1364        Name => 'UnknownEV', # ("DeletedTag", ref 4)
1365        Writable => 'rational64u',
1366        Unknown => 1,
1367    },
1368    # 0x0002: int8u       - values: 0
1369    0x0003 => { Name => 'ExposureValue',    Writable => 'rational64u' },
1370    # 0x0004: rational64u - values: 2.875,3.375,3.625,4,4.125,7.25
1371    # 0x0005: int8u       - values: 0
1372    # 0x0006: int32u[12]  - ?
1373    # 0x0007: int32u[3]   - values: "65536 67932 69256"
1374    0x03e9 => { Name => 'OriginalFileName', Writable => 'string' },
1375    0x03ea => { Name => 'KodakTag',         Writable => 'int32u' }, #4
1376    0x03eb => { Name => 'SensorLeftBorder', Writable => 'int16u' }, # ("FinishedImageX", ref 4)
1377    0x03ec => { Name => 'SensorTopBorder',  Writable => 'int16u' }, # ("FinishedImageY", ref 4)
1378    0x03ed => { Name => 'SensorImageWidth', Writable => 'int16u' }, # ("FinishedImageWidth", ref 4)
1379    0x03ee => { Name => 'SensorImageHeight',Writable => 'int16u' }, # ("FinishedImageHeight", ref 4)
1380    0x03ef => { Name => 'BlackLevelTop',    Writable => 'int16u' }, #4
1381    0x03f0 => { Name => 'BlackLevelBottom', Writable => 'int16u' }, #4
1382    0x03f1 => {
1383        Name => 'TextualInfo', # ("CameraSettingString", ref 4)
1384        SubDirectory => {
1385            TagTable => 'Image::ExifTool::Kodak::TextualInfo',
1386        },
1387    },
1388    0x03f2 => { #IB/4
1389        Name => 'FlashMode',
1390        Writable => 'int16u',
1391        Unknown => 1,
1392        Priority => 0,
1393    },
1394    0x03f3 => { #IB/4
1395        Name => 'FlashCompensation',
1396        Writable => 'rational64s',
1397    },
1398    0x03f4 => { #4
1399        Name => 'WindMode',
1400        Writable => 'int16u',
1401        Unknown => 1,
1402    },
1403    0x03f5 => { #4
1404        Name => 'FocusMode',
1405        Writable => 'int16u',
1406        Unknown => 1,
1407        Priority => 0,
1408    },
1409    0x03f8 => { #IB/4
1410        Name => 'MinAperture',
1411        Writable => 'rational64u',
1412    },
1413    0x03f9 => { #IB/4
1414        Name => 'MaxAperture',
1415        Writable => 'rational64u',
1416    },
1417    0x03fa => { #4
1418        Name => 'WhiteBalanceMode',
1419        Writable => 'int16u',
1420        Unknown => 1,
1421    },
1422    0x03fb => { #4
1423        Name => 'WhiteBalanceDetected',
1424        Writable => 'int16u',
1425        Unknown => 1,
1426    },
1427    0x03fc => { #3
1428        Name => 'WhiteBalance',
1429        Writable => 'int16u',
1430        Priority => 0,
1431        PrintConv => { },   # no values yet known
1432    },
1433    0x03fd => [{ #3
1434        Name => 'Processing',
1435        Condition => '$count == 72',
1436        SubDirectory => {
1437            TagTable => 'Image::ExifTool::Kodak::Processing',
1438        },
1439    },{
1440        Name => 'ProcessingParameters', #4
1441        Binary => 1,
1442        # int8u[256]
1443    }],
1444    0x03fe => { Name => 'ImageAbsoluteX',       Writable => 'int16s', }, #4
1445    0x03ff => { Name => 'ImageAbsoluteY',       Writable => 'int16s' }, #4
1446    0x0400 => { Name => 'ApplicationKeyString', Writable => 'string' }, #4
1447    0x0401 => {
1448        Name => 'Time', # ("CaptureTime", ref 4)
1449        Groups => { 2 => 'Time' },
1450        Writable => 'string',
1451    },
1452    0x0402 => { #4
1453        Name => 'GPSString',
1454        Groups => { 2 => 'Location' },
1455        Writable => 'string',
1456    },
1457    0x0403 => { #4
1458        Name => 'EventLogCapture',
1459        Binary => 1,
1460        Unknown => 1,
1461        # int32u[3072]
1462    },
1463    0x0404 => { #4
1464        Name => 'ComponentTable',
1465        Binary => 1,
1466        Unknown => 1,
1467    },
1468    0x0405 => { #4
1469        Name => 'CustomIlluminant',
1470        Writable => 'int16u',
1471        Unknown => 1,
1472    },
1473    0x0406 => [{ #IB/4
1474        Name => 'CameraTemperature',
1475        Condition => '$count == 1',
1476        Groups => { 2 => 'Camera' },
1477        Writable => 'rational64s',
1478        PrintConv => '"$val C"',
1479        PrintConvInv => '$val=~s/ ?C//; $val',
1480    },{
1481        Name => 'CameraTemperature',
1482        # (when count is 2, values seem related to temperature, but are not Celius)
1483    }],
1484    0x0407 => { #IB/4
1485        Name => 'AdapterVoltage',
1486        Groups => { 2 => 'Camera' },
1487        Writable => 'rational64u',
1488    },
1489    0x0408 => { #IB/4
1490        Name => 'BatteryVoltage',
1491        Groups => { 2 => 'Camera' },
1492        Writable => 'rational64u',
1493    },
1494    0x0409 => { #4
1495        Name => 'DacVoltages',
1496        # rational64u[8]
1497    },
1498    0x040a => { #4
1499        Name => 'IlluminantDetectorData',
1500        Binary => 1,
1501        Unknown => 1,
1502    },
1503    0x040b => { #4
1504        Name => 'PixelClockFrequency',
1505        Writable => 'int32u',
1506    },
1507    0x040c => { #4
1508        Name => 'CenterPixel',
1509        Writable => 'int16u',
1510        Count => 3,
1511    },
1512    0x040d => { #4
1513        Name => 'BurstCount',
1514        Writable => 'int16u',
1515    },
1516    0x040e => { #4
1517        Name => 'BlackLevelRough',
1518        Writable => 'int16u',
1519    },
1520    0x040f => { #4
1521        Name => 'OffsetMapHorizontal',
1522        Binary => 1,
1523        Unknown => 1,
1524        # int16s[1736]
1525    },
1526    0x0410 => { #4
1527        Name => 'OffsetMapVertical',
1528        Binary => 1,
1529        Unknown => 1,
1530        # int16s[1160]
1531    },
1532    0x0411 => { #4
1533        Name => 'Histogram',
1534        Binary => 1,
1535        Unknown => 1,
1536        # int16u[256]
1537    },
1538    0x0412 => { #4
1539        Name => 'VerticalClockOverlaps',
1540        Writable => 'int16u',
1541        Count => 2,
1542    },
1543    0x0413 => 'SensorTemperature', #4
1544    0x0414 => { Name => 'XilinxVersion',        Writable => 'string' }, #4
1545    0x0415 => { Name => 'FirmwareVersion',      Writable => 'int32u' }, #4
1546    0x0416 => { Name => 'BlackLevelRoughAfter', Writable => 'int16u' }, #4
1547    0x0417 => 'BrightRowsTop', #4
1548    0x0418 => 'EventLogProcess', #4
1549    0x0419 => 'DacVoltagesFlush', #4
1550    0x041a => 'FlashUsed', #4
1551    0x041b => 'FlashType', #4
1552    0x041c => 'SelfTimer', #4
1553    0x041d => 'AFMode', #4
1554    0x041e => 'LensType', #4
1555    0x041f => { Name => 'ImageCropX',           Writable => 'int16s' }, #4
1556    0x0420 => { Name => 'ImageCropY',           Writable => 'int16s' }, #4
1557    0x0421 => 'AdjustedTbnImageWidth', #4
1558    0x0422 => 'AdjustedTbnImageHeight', #4
1559    0x0423 => { Name => 'IntegrationTime',      Writable => 'int32u' }, #4
1560    0x0424 => 'BracketingMode', #4
1561    0x0425 => 'BracketingStep', #4
1562    0x0426 => 'BracketingCounter', #4
1563    0x042e => 'HuffmanTableLength', #4 (int8u[16])
1564    0x042f => 'HuffmanTableValue', #4 (int8u[13])
1565    0x0438 => { Name => 'MainBoardVersion',     Writable => 'int32u' }, #4
1566    0x0439 => { Name => 'ImagerBoardVersion',   Writable => 'int32u' }, #4
1567    0x044c => 'FocusEdgeMap', #4
1568    0x05e6 => 'IdleTiming', #4
1569    0x05e7 => 'FlushTiming', #4
1570    0x05e8 => 'IntegrateTiming', #4
1571    0x05e9 => 'RegisterReadTiming', #4
1572    0x05ea => 'FirstLineTransferTiming', #4
1573    0x05eb => 'ShiftTiming', #4
1574    0x05ec => 'NormalLineTransferTiming', #4
1575    0x05ed => 'TestTransferTiming', #4
1576    # 0x05f0-0x05f9 "TestTiming", ref 4
1577    0x05fa => 'MinimumFlushRows', #4
1578    0x05fd => { Name => 'ImagerPowerOnDelayMsec', Writable => 'int32u' }, #4
1579    0x05fe => 'ImagerInitialTimingCode', #4
1580    0x05ff => 'ImagerLogicProgram', #4
1581    0x0600 => { Name => 'ImagerBiasSettlingDelayMsec', Writable => 'int32u' }, #4
1582    0x0604 => 'IdleSequence', #4
1583    0x0605 => 'FirstFlushSequence', #4
1584    0x0606 => 'FinalFlushSequence', #4
1585    0x0607 => 'SampleBlackSequence', #4
1586    0x0608 => 'TransferSequence', #4
1587    0x060e => 'DacCountsPerVolt', #4
1588    0x060f => 'BlackDacChannel', #4
1589    0x0610 => 'BlackAdCountsPerDacVolt', #4
1590    0x0611 => 'BlackTarget', #4
1591    0x0612 => 'BlackDacSettlingMsec', #4
1592    # 0x0618-0x062b - reserved for .IF file use, ref 4
1593    0x07d0 => { #4
1594        Name => 'StandardMatrixDaylight',
1595        Writable => 'rational64s',
1596        Count => 9,
1597    },
1598    0x07d1 => { #4
1599        Name => 'StandardMatrixTungsten',
1600        Writable => 'rational64s',
1601        Count => 9,
1602    },
1603    0x07d2 => { #4
1604        Name => 'StandardMatrixFluorescent',
1605        Writable => 'rational64s',
1606        Count => 9,
1607    },
1608    0x07d3 => { #4
1609        Name => 'StandardMatrixFlash',
1610        Writable => 'rational64s',
1611        Count => 9,
1612    },
1613    0x07d4 => { #4 (never used)
1614        Name => 'StandardMatrixCustom',
1615        Writable => 'rational64s',
1616        Count => 9,
1617    },
1618    0x07da => { #4
1619        Name => 'DeviantMatrixDaylight',
1620        Writable => 'rational64s',
1621        Count => 9,
1622    },
1623    0x07db => { #4
1624        Name => 'DeviantMatrixTungsten',
1625        Writable => 'rational64s',
1626        Count => 9,
1627    },
1628    0x07dc => { #4
1629        Name => 'DeviantMatrixFluorescent',
1630        Writable => 'rational64s',
1631        Count => 9,
1632    },
1633    0x07dd => { #4
1634        Name => 'DeviantMatrixFlash',
1635        Writable => 'rational64s',
1636        Count => 9,
1637    },
1638    0x07de => { #4 (never used)
1639        Name => 'DeviantMatrixCustom',
1640        Writable => 'rational64s',
1641        Count => 9,
1642    },
1643    0x07e4 => { #4
1644        Name => 'UniqueMatrixDaylight',
1645        Writable => 'rational64s',
1646        Count => 9,
1647    },
1648    0x07e5 => { #4
1649        Name => 'UniqueMatrixTungsten',
1650        Writable => 'rational64s',
1651        Count => 9,
1652    },
1653    0x07e6 => { #4
1654        Name => 'UniqueMatrixFluorescent',
1655        Writable => 'rational64s',
1656        Count => 9,
1657    },
1658    0x07e7 => { #4
1659        Name => 'UniqueMatrixFlash',
1660        Writable => 'rational64s',
1661        Count => 9,
1662    },
1663    0x07e8 => { #4
1664        Name => 'UniqueMatrixCustom',
1665        Writable => 'rational64s',
1666        Count => 9,
1667    },
1668    0x07e9 => { #4
1669        Name => 'UniqueMatrixAuto',
1670        Writable => 'rational64s',
1671        Count => 9,
1672    },
1673    0x0834 => { #4
1674        Name => 'StandardWhiteDaylight',
1675        Writable => 'rational64s',
1676        Count => 3,
1677    },
1678    0x0835 => { #4
1679        Name => 'StandardWhiteTungsten',
1680        Writable => 'rational64s',
1681        Count => 3,
1682    },
1683    0x0836 => { #4
1684        Name => 'StandardWhiteFluorescent',
1685        Writable => 'rational64s',
1686        Count => 3,
1687    },
1688    0x0837 => { #4
1689        Name => 'StandardWhiteFlash',
1690        Writable => 'rational64s',
1691        Count => 3,
1692    },
1693    0x0838 => { #4 (never used)
1694        Name => 'StandardWhiteCustom',
1695        Writable => 'rational64s',
1696        Count => 3,
1697    },
1698    0x083e => { #4
1699        Name => 'DeviantWhiteDaylight',
1700        Writable => 'rational64s',
1701        Count => 3,
1702    },
1703    0x083f => { #4
1704        Name => 'DeviantWhiteTungsten',
1705        Writable => 'rational64s',
1706        Count => 3,
1707    },
1708    0x0840 => { #4
1709        Name => 'DeviantWhiteFluorescent',
1710        Writable => 'rational64s',
1711        Count => 3,
1712    },
1713    0x0841 => { #4
1714        Name => 'DeviantWhiteFlash',
1715        Writable => 'rational64s',
1716        Count => 3,
1717    },
1718    0x0842 => { #4 (never used)
1719        Name => 'DeviantWhiteCustom',
1720        Writable => 'rational64s',
1721        Count => 3,
1722    },
1723    # 0x0843 - rational64u[3]
1724    # 0x0844 - rational64u[3]
1725    0x0846 => { #3 ("WhiteBalanceKelvin", ref 4)
1726        Name => 'ColorTemperature',
1727        Writable => 'int16u',
1728    },
1729    0x0847 => 'WB_RGBLevelsAsShot', #4
1730    0x0848 => 'WB_RGBLevelsDaylight', #IB (rational64s/u[3]) ("UniqueWhiteDaylight", ref 4)
1731    0x0849 => 'WB_RGBLevelsTungsten', #IB (rational64s/u[3]) ("UniqueWhiteTungsten", ref 4)
1732    0x084a => 'WB_RGBLevelsFluorescent', #IB (rational64s/u[3]) ("UniqueWhiteFluorescent", ref 4)
1733    0x084b => 'WB_RGBLevelsFlash', #IB (rational64s/u[3]) ("UniqueWhiteFlash", ref 4)
1734    0x084c => 'WB_RGBLevelsCustom', #IB (rational64u[3]) ("UniqueWhiteCustom", ref 4)
1735    0x084d => 'WB_RGBLevelsAuto', #IB (rational64u[3]) ("UniqueWhiteAuto", ref 4)
1736    0x0852 => { #3/4
1737        Name => 'WB_RGBMulDaylight', # ("AdjustWhiteFactorsDaylight", ref 4)
1738        Writable => 'rational64u',
1739        Count => 3,
1740    },
1741    0x0853 => { #3/4
1742        Name => 'WB_RGBMulTungsten', # ("AdjustWhiteFactorsTungsten", ref 4)
1743        Writable => 'rational64u',
1744        Count => 3,
1745    },
1746    0x0854 => { #3/4
1747        Name => 'WB_RGBMulFluorescent', # ("AdjustWhiteFactorsFluorescent", ref 4)
1748        Writable => 'rational64u',
1749        Count => 3,
1750    },
1751    0x0855 => { #3/4
1752        Name => 'WB_RGBMulFlash', # ("AdjustWhiteFactorsFlash", ref 4)
1753        Writable => 'rational64u',
1754        Count => 3,
1755    },
1756    0x085c => { Name => 'WB_RGBCoeffsDaylight', Binary => 1 }, #3 ("WhiteBalanceParametersDaylight", ref 4)
1757    0x085d => { Name => 'WB_RGBCoeffsTungsten', Binary => 1 }, #3 ("WhiteBalanceParametersTungsten", ref 4)
1758    0x085e => { Name => 'WB_RGBCoeffsFluorescent',Binary=>1 }, #3 ("WhiteBalanceParametersFluorescent", ref 4)
1759    0x085f => { Name => 'WB_RGBCoeffsFlash',    Binary => 1 }, #3 ("WhiteBalanceParametersFlash", ref 4)
1760    0x0898 => { Name => 'ExposureGainDaylight', Writable => 'rational64s' }, #4
1761    0x0899 => { Name => 'ExposureGainTungsten', Writable => 'rational64s' }, #4
1762    0x089a => { Name => 'ExposureGainFluorescent',Writable=>'rational64s' }, #4
1763    0x089b => { Name => 'ExposureGainFlash',    Writable => 'rational64s' }, #4
1764    0x089c => { Name => 'ExposureGainCustom',   Writable => 'rational64s' }, #4 (never used)
1765    0x089d => { Name => 'AnalogISOTable',       Writable => 'rational64u', Count => 3 }, #4
1766    0x089e => { Name => 'AnalogCaptureISO',     Writable => 'int32u' }, #4
1767    0x089f => { Name => 'ISOCalibrationGain',   Writable => 'rational64u' }, #4
1768    0x08a0 => 'ISOCalibrationGainTable', #4
1769    0x08a1 => 'ExposureHeadroomFactor', #4
1770    0x08ab => 'LinearitySplineTags', #4 (int16u[24])
1771    # 0x08ac-0x08fb - LinearitySpline(n) (rational64s[75])
1772    0x08fc => { #4
1773        Name => 'MonitorMatrix',
1774        Writable => 'rational64s',
1775        Count => 9,
1776    },
1777    0x08fd => 'TonScaleTable', #4
1778    0x08fe => { Name => 'Gamma',                Writable => 'rational64u' }, #4
1779    0x08ff => 'LogLinTable', #4
1780    0x0900 => 'LinLogTable', #4
1781    0x0901 => { Name => 'GammaTable',           Binary => 1 }, #4 (int16u[4096])
1782    0x0902 => { Name => 'LogScale',             Writable => 'rational64u' }, #4
1783    0x0903 => { Name => 'BaseISO',              Writable => 'rational64u' }, #IB (ISO before digital gain)
1784    0x0904 => { Name => 'LinLogCoring',         Writable => 'int16u' }, #4
1785    0x0905 => { Name => 'PatternGainConversionTable', Binary => 1 }, #4 (int8u[256])
1786    0x0906 => 'DefectCount', #4
1787    0x0907 => { Name => 'DefectList',           Binary => 1 }, #4 (undef[48])
1788    0x0908 => { Name => 'DefectListPacked',     Binary => 1 }, #4 (int16u[296])
1789    0x0909 => { Name => 'ImageSpace',           Writable => 'int16u' }, #4
1790    0x090a => { Name => 'ThumbnailCompressionTable',Binary => 1 }, #4 (int8u[4096])
1791    0x090b => { Name => 'ThumbnailExpansionTable',  Binary => 1 }, #4 (int16u[256])
1792    0x090c => { Name => 'ImageCompressionTable',    Binary => 1 }, #4 (int16u[4096])
1793    0x090d => { Name => 'ImageExpansionTable',      Binary => 1 }, #4 (int16u[1024/4096])
1794    0x090e => 'EighteenPercentPoint', #4
1795    0x090f => { Name => 'DefectIsoCode',        Writable => 'int16u' }, #4
1796    0x0910 => { Name => 'BaseISODaylight',      Writable => 'rational64u' }, #4
1797    0x0911 => { Name => 'BaseISOTungsten',      Writable => 'rational64u' }, #4
1798    0x0912 => { Name => 'BaseISOFluorescent',   Writable => 'rational64u' }, #4
1799    0x0913 => { Name => 'BaseISOFlash',         Writable => 'rational64u' }, #4
1800    0x091a => { Name => 'MatrixSelectThreshold',Writable => 'int16s' }, #4
1801    0x091b => { Name => 'MatrixSelectK',        Writable => 'rational64u' }, #4
1802    0x091c => { Name => 'IlluminantDetectTable',Binary => 1 }, #4 (int16u[200])
1803    0x091d => 'RGTable', #4
1804    0x091e => { Name => 'MatrixSelectThreshold1', Writable => 'int16s' }, #4
1805    0x091f => { Name => 'MatrixSelectThreshold2', Writable => 'int16s' }, #4
1806    0x0924 => 'PortraitMatrix', #4
1807    0x0925 => 'PortraitToneScaleTable', #4
1808    0x092e => { Name => 'EnableSharpening',     Writable => 'int16u' }, #4
1809    0x092f => { #4
1810        Name => 'SharpeningKernel',
1811        Writable => 'int16s',
1812        Count => 25,
1813    },
1814    0x0930 => { Name => 'EdgeMapSlope',         Writable => 'int16u' }, #4
1815    0x0931 => { Name => 'EdgeMapX1',            Writable => 'int16u' }, #4
1816    0x0932 => { Name => 'EdgeMapX2',            Writable => 'int16u' }, #4
1817    0x0933 => { #4
1818        Name => 'KernelDenominators',
1819        Writable => 'int16u',
1820        Count => 3,
1821    },
1822    0x0934 => { Name => 'EdgeMapX3',            Writable => 'int16u' }, #4
1823    0x0935 => { Name => 'EdgeMapX4',            Writable => 'int16u' }, #4
1824    0x0936 => 'SharpenForThumbnail', #4
1825    0x0937 => 'EdgeSpline', #4
1826    0x0938 => 'DownSampleBy2Hor', #4 (int16s[4])
1827    0x0939 => 'DownSampleBy2Ver', #4 (int16s[4])
1828    0x093a => 'DownSampleBy4Hor', #4 (int16s[6])
1829    0x093b => 'DownSampleBy4Ver', #4 (int16s[6])
1830    0x093c => 'DownSampleBy3Hor', #4 (int16s[6])
1831    0x093d => 'DownSampleBy3Ver', #4 (int16s[6])
1832    0x093e => 'DownSampleBy6Hor', #4 (int16s[8])
1833    0x093f => 'DownSampleBy6Ver', #4 (int16s[8])
1834    0x0940 => 'DownSampleBy2Hor3MPdcr', #4
1835    0x0941 => 'DownSampleBy2Ver3MPdcr', #4
1836    0x0942 => 'ThumbnailResizeRatio', #4
1837    0x0943 => { Name => 'AtCaptureUserCrop',    Writable => 'int32u', Count => 4 }, #4 (Top, Left, Bottom, Right)
1838    0x0944 => { Name => 'ImageResolution',      Writable => 'int32u' }, #4 (Contains enum for imageDcrRes or imageJpegRes)
1839    0x0945 => { Name => 'ImageResolutionJpg',   Writable => 'int32u' }, #4 (Contains enum for imageJpegRes)
1840    0x094c => 'USMParametersLow', #4 (int16s[8])
1841    0x094d => 'USMParametersMed', #4 (int16s[8])
1842    0x094e => 'USMParametersHigh', #4 (int16s[8])
1843    0x094f => 'USMParametersHost', #4 (int16s[10])
1844    0x0950 => { Name => 'EdgeSplineLow', Binary => 1 }, #4 (rational64s[57])
1845    0x0951 => { Name => 'EdgeSplineMed', Binary => 1 }, #4 (rational64s[69])
1846    0x0952 => { Name => 'EdgeSplineHigh',Binary => 1 }, #4 (rational64s[69])
1847    0x0953 => 'USMParametersHost6MP', #4 (int16s[10])
1848    0x0954 => 'USMParametersHost3MP', #4 (int16s[10])
1849    0x0960 => { Name => 'PatternImagerWidth',   Writable => 'int16u' }, #4
1850    0x0961 => { Name => 'PatternImagerHeight',  Writable => 'int16u' }, #4
1851    0x0962 => { Name => 'PatternAreaWidth',     Writable => 'int16u' }, #4
1852    0x0963 => { Name => 'PatternAreaHeight',    Writable => 'int16u' }, #4
1853    0x0964 => { Name => 'PatternCorrectionGains', Binary => 1 }, #4 (undef[48174])
1854    0x0965 => 'PatternCorrectionOffsets', #4
1855    0x0966 => { Name => 'PatternX',             Writable => 'int16u' }, #4
1856    0x0967 => { Name => 'PatternY',             Writable => 'int16u' }, #4
1857    0x0968 => { Name => 'PatternCorrectionFactors', Binary => 1 }, #4 (undef[48174])
1858    0x0969 => { Name => 'PatternCorrectionFactorScale', Writable => 'int16u' }, #4
1859    0x096a => { Name => 'PatternCropRows1',     Writable => 'int16u' }, #4
1860    0x096b => { Name => 'PatternCropRows2',     Writable => 'int16u' }, #4
1861    0x096c => { Name => 'PatternCropCols1',     Writable => 'int16u' }, #4
1862    0x096d => { Name => 'PatternCropCols2',     Writable => 'int16u' }, #4
1863    0x096e => 'PixelCorrectionGains', #4
1864    0x096f => 'StitchRows', #4 (int16u[6])
1865    0x0970 => 'StitchColumns', #4 (int16u)
1866    0x0971 => { Name => 'PixelCorrectionScale', Writable => 'int16u' }, #4
1867    0x0972 => { Name => 'PixelCorrectionOffset',Writable => 'int16u' }, #4
1868    0x0988 => 'LensTableIndex', #4
1869    0x0992 => 'DiffTileGains602832', #4
1870    0x0993 => 'DiffTileGains24t852822', #4 (reserved tags 2450-2459)
1871    0x099c => 'TileGainDeterminationTable', #4 (int16s[0])
1872    0x099d => 'NemoBlurKernel', #4 (int16s[14])
1873    0x099e => 'NemoTileSize', #4 (int16u)
1874    0x099f => 'NemoGainFactors', #4 (rational64s[4])
1875    0x09a0 => 'NemoDarkLimit', #4 (int16u)
1876    0x09a1 => 'NemoHighlight12Limit', #4
1877    0x09c4 => { Name => 'ImagerFileProductionLevel',Writable => 'int16u' }, #4
1878    0x09c5 => { Name => 'ImagerFileDateCreated',    Writable => 'int32u' }, #4 (unknown encoding - PH)
1879    0x09c6 => { Name => 'CalibrationVersion',       Writable => 'string' }, #4
1880    0x09c7 => { Name => 'ImagerFileTagsVersionStandard', Writable => 'int16u' }, #4
1881    0x09c8 => { Name => 'IFCameraModel',            Writable => 'string' }, #4
1882    0x09c9 => { Name => 'CalibrationHistory',       Writable => 'string' }, #4
1883    0x09ca => { Name => 'CalibrationLog',           Binary => 1 }, #4 (undef[1140])
1884    0x09ce => { Name => 'SensorSerialNumber', Writable => 'string', Groups => { 2 => 'Camera' } }, #IB/4
1885    0x09f6 => 'DefectConcealArtCorrectThres', #4 (no longer used)
1886    0x09f7 => 'SglColDCACThres1', #4
1887    0x09f8 => 'SglColDCACThres2', #4
1888    0x09f9 => 'SglColDCACTHres3', #4
1889    0x0a01 => 'DblColDCACThres1', #4
1890    0x0a02 => 'DblColDCACThres2', #4
1891    0x0a0a => { Name => 'DefectConcealThresTable',  Binary => 1 }, #4 (int16u[121/79])
1892    0x0a28 => 'MonoUniqueMatrix', #4
1893    0x0a29 => 'MonoMonitorMatrix', #4
1894    0x0a2a => 'MonoToneScaleTable', #4
1895    # 0x0a32-0x0a3b "OmenInitialSurfaceRed(n)", ref 4
1896    # 0x0a3c-0x0a45 "OmenInitialSurfaceGoR(n)", ref 4
1897    # 0x0a46-0x0a4f "OmenInitialSurfaceBlue(n)", ref 4
1898    # 0x0a50-0x0a59 "OmenInitialSurfaceGoB(n)", ref 4
1899    0x0a5a => 'OmenInitialScaling', #4
1900    0x0a5b => 'OmenInitialRows', #4
1901    0x0a5c => 'OmenInitialColumns', #4
1902    0x0a5d => { Name => 'OmenInitialIPFStrength',Writable => 'int32s', Count => 4 }, #4
1903    0x0a5e => { Name => 'OmenEarlyStrength',     Writable => 'int32s', Count => 4 }, #4
1904    0x0a5f => { Name => 'OmenAutoStrength',      Writable => 'int32s', Count => 4 }, #4
1905    0x0a60 => { Name => 'OmenAtCaptureStrength', Writable => 'int32s', Count => 4 }, #4
1906    0x0a61 => 'OmenAtCaptureMode', #4
1907    0x0a62 => { Name => 'OmenFocalLengthLimit',  Writable => 'int16s' }, #4
1908    0x0a64 => { Name => 'OmenSurfaceIndex',      Writable => 'int16s' }, #4 (which InitialSurface to use)
1909    0x0a65 => 'OmenPercentToRationalLimitsRed', #4 (signed rationals for 0 and 100)
1910    0x0a66 => 'OmenPercentToRationalLimitsGoR', #4 (signed rationals for 0 and 100)
1911    0x0a67 => 'OmenPercentToRationalLimitsBlue', #4 (signed rationals for 0 and 100)
1912    0x0a68 => 'OmenPercentToRationalLimitsGoB', #4 (signed rationals for 0 and 100)
1913    0x0a6e => 'OmenEarlyGoBSurface', #4
1914    0x0a6f => 'OmenEarlyGoBRows', #4
1915    0x0a70 => 'OmenEarlyGoBColumns', #4
1916    0x0a73 => 'OmenSmoothingKernel', #4
1917    0x0a74 => 'OmenGradientOffset', #4
1918    0x0a75 => 'OmenGradientKernel', #4
1919    0x0a76 => 'OmenGradientKernelTaps', #4
1920    0x0a77 => 'OmenRatioClipFactors', #4
1921    0x0a78 => 'OmenRatioExclusionFactors', #4
1922    0x0a79 => 'OmenGradientExclusionLimits', #4
1923    0x0a7a => 'OmenROICoordinates', #4
1924    0x0a7b => 'OmenROICoefficients', #4
1925    0x0a7c => 'OmenRangeWeighting', #4
1926    0x0a7d => 'OmenMeanToStrength', #4
1927    0x0bb8 => 'FactoryWhiteGainsDaylight', #4
1928    0x0bb9 => 'FactoryWhiteOffsetsDaylight', #4
1929    0x0bba => 'DacGainsCoarse', #4
1930    0x0bbb => 'DacGainsFine', #4
1931    0x0bbc => 'DigitalExposureGains', #4
1932    0x0bbd => 'DigitalExposureBiases', #4
1933    0x0bbe => 'BlackClamp', #4
1934    0x0bbf => 'ChannelCoarseGainAdjust', #4
1935    0x0bc0 => 'BlackClampOffset', #4
1936    0x0bf4 => 'DMPixelThresholdFactor', #4 (TIFF_RATIONAL)
1937    0x0bf5 => 'DMWindowThresholdFactor', #4 (TIFF_RATIONAL)
1938    0x0bf6 => 'DMTrimFraction', #4 (TIFF_RATIONAL)
1939    0x0bf7 => 'DMSmoothRejThresh', #4 (TIFF_RATIONAL)
1940    0x0bf8 => 'DMFillRejThresh', #4 (TIFF_RATIONAL)
1941    0x0bf9 => 'VMWsize', #4 (TIFF_SHORT)
1942    0x0bfa => 'DMErodeRadius', #4 (TIFF_SHORT)
1943    0x0bfb => 'DMNumPatches', #4 (TIFF_SHORT)
1944    0x0bfc => 'DMNoiseScale', #4 (TIFF_RATIONAL)
1945    0x0bfe => 'BrightDefectThreshold', #4
1946    0x0bff => 'BrightDefectIntegrationMS', #4
1947    0x0c00 => 'BrightDefectIsoCode', #4
1948    0x0c03 => 'TopDarkRow1', #4 (support 330 dark map generation algorithm)
1949    0x0c04 => 'TopDarkRow2', #4 (these tags were 3175-3192 prior to 18Jan2001)
1950    0x0c05 => 'BottomDarkRow1', #4
1951    0x0c06 => 'BottomDarkRow2', #4
1952    0x0c07 => 'LeftDarkCol1', #4
1953    0x0c08 => 'LeftDarkCol2', #4
1954    0x0c09 => 'RightDarkCol1', #4
1955    0x0c0a => 'RightDarkCol2', #4
1956    0x0c0b => 'HMPixThresh', #4
1957    0x0c0c => 'HMColThresh', #4
1958    0x0c0d => 'HMWsize', #4
1959    0x0c0e => 'HMColRejThresh', #4
1960    0x0c0f => 'VMPixThresh', #4
1961    0x0c10 => 'VMColThresh', #4
1962    0x0c11 => 'VMNbands', #4
1963    0x0c12 => 'VMColDropThresh', #4
1964    0x0c13 => 'VMPatchResLimit', #4
1965    0x0c14 => 'MapScale', #4
1966    0x0c1c => 'Klut', #4
1967    0x0c1d => 'RimNonlinearity', #4 (Obsolete)
1968    0x0c1e => 'InverseRimNonlinearity', #4 (Obsolete)
1969    0x0c1f => 'RembrandtToneScale', #4 (Obsolete)
1970    0x0c20 => 'RimToNifColorTransform', #4 (Obsolete)
1971    0x0c21 => 'RimToNifScaleFactor', #4 (Obsolete)
1972    0x0c22 => 'NifNonlinearity', #4 (Obsolete)
1973    0x0c23 => 'SBALogTransform', #4 (Obsolete)
1974    0x0c24 => 'InverseSBALogTransform', #4 (Obsolete)
1975    0x0c25 => { Name => 'SBABlack',         Writable => 'int16u' }, #4
1976    0x0c26 => { Name => 'SBAGray',          Writable => 'int16u' }, #4
1977    0x0c27 => { Name => 'SBAWhite',         Writable => 'int16u' }, #4
1978    0x0c28 => { Name => 'GaussianWeights',  Binary => 1 }, #4 (int16u[864])
1979    0x0c29 => { Name => 'SfsBoundary',      Binary => 1 }, #4 (int16u[6561])
1980    0x0c2a => 'CoringTableBest', #4 (Obsolete)
1981    0x0c2b => 'CoringTableBetter', #4 (Obsolete)
1982    0x0c2c => 'CoringTableGood', #4 (Obsolete)
1983    0x0c2d => 'ExposureReferenceGain', #4 (Obsolete)
1984    0x0c2e => 'ExposureReferenceOffset', #4 (Obsolete)
1985    0x0c2f => 'SBARedBalanceLut', #4 (Obsolete)
1986    0x0c30 => 'SBAGreenBalanceLut', #4 (Obsolete)
1987    0x0c31 => 'SBABlueBalanceLut', #4 (Obsolete)
1988    0x0c32 => { Name => 'SBANeutralBAL',        Writable => 'int32s' }, #4
1989    0x0c33 => { Name => 'SBAGreenMagentaBAL',   Writable => 'int32s' }, #4
1990    0x0c34 => { Name => 'SBAIlluminantBAL',     Writable => 'int32s' }, #4
1991    0x0c35 => { Name => 'SBAAnalysisComplete',  Writable => 'int8u' }, #4
1992    0x0c36 => 'JPEGQTableBest', #4
1993    0x0c37 => 'JPEGQTableBetter', #4
1994    0x0c38 => 'JPEGQTableGood', #4
1995    0x0c39 => 'RembrandtPortraitToneScale', #4 (Obsolete)
1996    0x0c3a => 'RembrandtConsumerToneScale', #4 (Obsolete)
1997    0x0c3b => 'CFAGreenThreshold1', #4 (Now CFAGreenThreshold1H)
1998    0x0c3c => 'CFAGreenThreshold2', #4 (Now CFAGreenThreshold2V)
1999    0x0c3d => { Name => 'QTableLarge50Pct',     Binary => 1 }, #4 (undef[130])
2000    0x0c3e => { Name => 'QTableLarge67Pct',     Binary => 1 }, #4 (undef[130])
2001    0x0c3f => { Name => 'QTableLarge100Pct',    Binary => 1 }, #4 (undef[130])
2002    0x0c40 => { Name => 'QTableMedium50Pct',    Binary => 1 }, #4 (undef[130])
2003    0x0c41 => { Name => 'QTableMedium67Pct',    Binary => 1 }, #4 (undef[130])
2004    0x0c42 => { Name => 'QTableMedium100Pct',   Binary => 1 }, #4 (undef[130])
2005    0x0c43 => { Name => 'QTableSmall50Pct',     Binary => 1 }, #4 (undef[130])
2006    0x0c44 => { Name => 'QTableSmall67Pct',     Binary => 1 }, #4 (undef[130])
2007    0x0c45 => { Name => 'QTableSmall100Pct',    Binary => 1 }, #4 (undef[130])
2008    0x0c46 => { Name => 'SBAHighGray',          Writable => 'int16u' }, #4
2009    0x0c47 => { Name => 'SBALowGray',           Writable => 'int16u' }, #4
2010    0x0c48 => { Name => 'CaptureLook',          Writable => 'int16u' }, #4 (was "ToneScaleFlag")
2011    0x0c49 => { Name => 'SBAIllOffset',         Writable => 'int16s' }, #4
2012    0x0c4a => { Name => 'SBAGmOffset',          Writable => 'int16s' }, #4
2013    0x0c4b => 'NifNonlinearity12Bit', #4 (Obsolete)
2014    0x0c4c => 'SharpeningOn', #4 (Obsolete)
2015    0x0c4d => 'NifNonlinearity16Bit', #4 (Obsolete)
2016    0x0c4e => 'RawHistogram', #4
2017    0x0c4f => 'RawCFAComponentAverages', #4
2018    0x0c50 => 'DisableFlagsPresent', #4
2019    0x0c51 => 'DelayCols', #4
2020    0x0c52 => 'DummyColsLeft', #4
2021    0x0c53 => 'TrashColsRight', #4
2022    0x0c54 => 'BlackColsRight', #4
2023    0x0c55 => 'DummyColsRight', #4
2024    0x0c56 => 'OverClockColsRight', #4
2025    0x0c57 => 'UnusedBlackRowsTopOut', #4
2026    0x0c58 => 'TrashRowsBottom', #4
2027    0x0c59 => 'BlackRowsBottom', #4
2028    0x0c5a => 'OverClockRowsBottom', #4
2029    0x0c5b => 'BlackColsLeft', #4
2030    0x0c5c => 'BlackRowsTop', #4
2031    0x0c5d => 'PartialActiveColsLeft', #4
2032    0x0c5e => 'PartialActiveColsRight', #4
2033    0x0c5f => 'PartialActiveRowsTop', #4
2034    0x0c60 => 'PartialActiveRowsBottom', #4
2035    0x0c61 => { Name => 'ProcessBorderColsLeft',    Writable => 'int16u' }, #4
2036    0x0c62 => { Name => 'ProcessBorderColsRight',   Writable => 'int16u' }, #4
2037    0x0c63 => { Name => 'ProcessBorderRowsTop',     Writable => 'int16u' }, #4
2038    0x0c64 => { Name => 'ProcessBorderRowsBottom',  Writable => 'int16u' }, #4
2039    0x0c65 => 'ActiveCols', #4
2040    0x0c66 => 'ActiveRows', #4
2041    0x0c67 => 'FirstLines', #4
2042    0x0c68 => 'UnusedBlackRowsTopIn', #4
2043    0x0c69 => 'UnusedBlackRowsBottomIn', #4
2044    0x0c6a => 'UnusedBlackRowsBottomOut', #4
2045    0x0c6b => 'UnusedBlackColsLeftOut', #4
2046    0x0c6c => 'UnusedBlackColsLeftIn', #4
2047    0x0c6d => 'UnusedBlackColsRightIn', #4
2048    0x0c6e => 'UnusedBlackColsRightOut', #4
2049    0x0c6f => { Name => 'CFAOffsetRows',            Writable => 'int32u' }, #4
2050    0x0c70 => { Name => 'ShiftCols',                Writable => 'int16s' }, #4
2051    0x0c71 => { Name => 'CFAOffsetCols',            Writable => 'int32u' }, #4
2052    0x0c76 => 'DarkMapScale', #4
2053    0x0c77 => 'HMapHandling', #4
2054    0x0c78 => 'VMapHandling', #4
2055    0x0c79 => 'DarkThreshold', #4
2056    0x0c7a => { Name => 'DMDitherMatrix',           Writable => 'int16u' }, #4
2057    0x0c7b => { Name => 'DMDitherMatrixWidth',      Writable => 'int16u' }, #4
2058    0x0c7c => { Name => 'DMDitherMatrixHeight',     Writable => 'int16u' }, #4
2059    0x0c7d => { Name => 'MaxPixelValueThreshold',   Writable => 'int16u' }, #4
2060    0x0c7e => { Name => 'HoleFillDeltaThreshold',   Writable => 'int16u' }, #4
2061    0x0c7f => { Name => 'DarkPedestal',             Writable => 'int16u' }, #4
2062    0x0c80 => { Name => 'ImageProcessingFileTagsVersionNumber', Writable => 'int16u' }, #4
2063    0x0c81 => { Name => 'ImageProcessingFileDateCreated', Writable => 'string', Groups => { 2 => 'Time' } }, #4
2064    0x0c82 => { Name => 'DoublingMicrovolts',       Writable => 'int32s' }, #4
2065    0x0c83 => { #4
2066        Name => 'DarkFrameShortExposure',
2067        Writable => 'int32u',
2068        ValueConv => '$val / 1e6', # (microseconds)
2069        ValueConvInv => '$val * 1e6',
2070        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
2071        PrintConvInv => '$val',
2072    },
2073    0x0c84 => { #4
2074        Name => 'DarkFrameLongExposure',
2075        Writable => 'int32u',
2076        ValueConv => '$val / 1e6', # (microseconds)
2077        ValueConvInv => '$val * 1e6',
2078        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
2079        PrintConvInv => '$val',
2080    },
2081    0x0c85 => { Name => 'DarkFrameCountFactor',     Writable => 'rational64u' }, #4
2082    0x0c88 => { Name => 'HoleFillDarkDeltaThreshold', Writable => 'int16u' }, #4
2083    0x0c89 => 'FarkleWhiteThreshold', #4
2084    0x0c8a => { Name => 'ColumnResetOffsets',       Binary => 1 }, #4 (int16u[3012])
2085    0x0c8b => { Name => 'ColumnGainFactors',        Binary => 1 }, #4 (int16u[3012])
2086    # 0x0c94-0x0c9d ColumnOffsets (int16u[3012]), ref 4
2087    0x0c8c => 'Channel0LagKernel', #4
2088    0x0c8d => 'Channel1LagKernel', #4
2089    0x0c8e => 'Channel2LagKernel', #4
2090    0x0c8f => 'Channel3LagKernel', #4
2091    0x0c90 => 'BluegrassTable', #4
2092    0x0c91 => 'BluegrassScale1', #4
2093    0x0c92 => 'BluegrassScale2', #4
2094    0x0ce4 => 'FinishedFileProcessingRequest', #4
2095    0x0ce5 => { Name => 'FirmwareVersion',  Writable => 'string', Groups => { 2 => 'Camera' } }, # ("ProcessingSoftware", ref 4)
2096    0x0ce6 => 'HostSoftwareExportVersion', #4 (ULONG only exists if made by host SW)
2097    0x0ce7 => { #4
2098        Name => 'HostSoftwareRendering',
2099        Writable => 'int32u',
2100        PrintConv => {
2101            0 => 'Normal (sRGB)',
2102            1 => 'Linear (camera RGB)',
2103            2 => 'Pro Photo RGB',
2104            3 => 'Unknown',
2105            4 => 'Other Profile',
2106        },
2107    },
2108    0x0dac => 'DCS3XXProcessingInfoIFD', #4 (Obsolete)
2109    0x0dad => 'DCS3XXProcessingInfo', #4 (Obsolete)
2110    0x0dae => { Name => 'IPAVersion',       Writable => 'int32u' }, #4
2111    0x0db6 => 'FinishIPAVersion', #4
2112    0x0db7 => 'FinishIPFVersion', #4
2113    0x0db8 => { #4
2114        Name => 'FinishFileType',
2115        Writable => 'int32u',
2116        PrintConv => {
2117            0 => 'JPEG Best',
2118            1 => 'JPEG Better',
2119            2 => 'JPEG Good',
2120            3 => 'TIFF RGB',
2121        },
2122    },
2123    0x0db9 => { #4
2124        Name => 'FinishResolution',
2125        Writable => 'int32u',
2126        PrintConv => {
2127            0 => '100%',
2128            1 => '67%',
2129            2 => '50%',
2130            3 => '25%',
2131        },
2132    },
2133    0x0dba => { #4
2134        Name => 'FinishNoise',
2135        Writable => 'int32u',
2136        PrintConv => {
2137            0 => 'Normal',
2138            1 => 'Strong',
2139            2 => 'Low',
2140        },
2141    },
2142    0x0dbb => { #4
2143        Name => 'FinishSharpening',
2144        Writable => 'int32u',
2145        PrintConv => {
2146            0 => 'None',
2147            1 => 'High',
2148            2 => 'Medium',
2149            3 => 'Low',
2150        },
2151    },
2152    0x0dbc => { #4
2153        Name => 'FinishLook',
2154        Writable => 'int32u',
2155        PrintConv => {
2156            0 => 'Product',
2157            1 => 'Portrait',
2158            2 => 'Product Reduced',
2159            3 => 'Portrait Reduced',
2160            4 => 'Monochrome Product',
2161            5 => 'Monochrome Portrait',
2162            6 => 'Wedding',
2163            7 => 'Event',
2164            8 => 'Product Hi Color',
2165            9 => 'Portrait Hi Color',
2166            # (past this is not yet implemented)
2167            10 => 'Product Hi Color Hold',
2168            11 => 'Portrait Hi Color Hold',
2169            13 => 'DCS BW Normal',
2170            14 => 'DCS BW Wratten 8',
2171            15 => 'DCS BW Wratten 25',
2172            16 => 'DCS Sepia 1',
2173            17 => 'DCS Sepia 2',
2174        },
2175    },
2176    0x0dbd => { #4
2177        Name => 'FinishExposure',
2178        Writable => 'int32u',
2179        PrintConv => { 0 => 'Yes', 1 => 'No' },
2180    },
2181    0x0e0b => { Name => 'SigmaScalingFactorLowRes', Writable => 'rational64u' }, #4 (for scaling sigma tables in-camera)
2182    0x0e0c => { Name => 'SigmaScalingFactorCamera', Writable => 'rational64u' }, #4 (for scaling sigma tables in-camera)
2183    0x0e0d => { Name => 'SigmaImpulseParameters',   Writable => 'int16u', Count => -1 }, #4 (for impulse reduction control)
2184    0x0e0e => { Name => 'SigmaNoiseThreshTableV2',  Binary => 1 }, #4 (replaces V2 caltable)
2185    0x0e0f => { Name => 'SigmaSizeTable',           Writable => 'int16u', Count => -1 }, #4
2186    0x0e10 => 'DacGainsCoarseAdjPreIF41', #4 (Tag not used due to abandoned implementation)
2187    0x0e11 => { Name => 'SigmaNoiseFilterCalTableV1', Binary => 1 }, #4 (undef[418]) (Defines Version 1 of Sigma Noise Filter table within .IF/.IPF)
2188    0x0e12 => { Name => 'SigmaNoiseFilterTableV1',  Binary => 1}, #4 (Defines Version 1 of Sigma Noise Filter table within image)
2189    0x0e13 => 'Lin12ToKlut8', #4
2190    0x0e14 => 'SigmaNoiseFilterTableV1Version', #4 (int16u/int32u) (This tag describes the version level of the SigmaNoiseFilterTableV1 class of tags)
2191    0x0e15 => 'Lin12ToKlut12', #4
2192    0x0e16 => 'Klut12ToLin12', #4
2193    0x0e17 => { Name => 'NifNonlinearity12To16',    Binary => 1 }, #4 (int16u[4096])
2194    0x0e18 => { Name => 'SBALog12Transform',        Binary => 1 }, #4 (int16u[4096])
2195    0x0e19 => { Name => 'InverseSBALog12Transform', Binary=> 1 }, #4 (int16u[3613])
2196    0x0e1a => { Name => 'ToneScale0',   Binary => 1 }, #4 (int16u[4096]) (Was Portrait12ToneScale on DCS3XX 1.3.1)
2197    0x0e1b => { Name => 'ToneScale1',   Binary => 1 }, #4 (int16u[4096]) (Was Consumer12ToneScale on DCS3XX 1.3.1)
2198    0x0e1c => { Name => 'ToneScale2',   Binary => 1 }, #4 (int16u[4096])
2199    0x0e1d => { Name => 'ToneScale3',   Binary => 1 }, #4 (int16u[4096])
2200    0x0e1e => { Name => 'ToneScale4',   Binary => 1 }, #4 (int16u[4096])
2201    0x0e1f => { Name => 'ToneScale5',   Binary => 1 }, #4 (int16u[4096])
2202    0x0e20 => { Name => 'ToneScale6',   Binary => 1 }, #4 (int16u[4096])
2203    0x0e21 => { Name => 'ToneScale7',   Binary => 1 }, #4 (int16u[4096])
2204    0x0e22 => { Name => 'ToneScale8',   Binary => 1 }, #4 (int16u[4096])
2205    0x0e23 => { Name => 'ToneScale9',   Binary => 1 }, #4 (int16u[4096])
2206    0x0e24 => 'DayMat0', #4 (Obsolete)
2207    0x0e25 => 'DayMat1', #4 (Obsolete)
2208    0x0e26 => 'DayMat2', #4 (Obsolete)
2209    0x0e27 => 'DayMat3', #4 (Obsolete)
2210    0x0e28 => 'DayMat4', #4 (Obsolete)
2211    0x0e29 => 'DayMat5', #4 (Obsolete)
2212    0x0e2a => 'DayMat6', #4 (Obsolete)
2213    0x0e2b => 'DayMat7', #4 (Obsolete)
2214    0x0e2c => 'DayMat8', #4 (Obsolete)
2215    0x0e2d => 'DayMat9', #4 (Obsolete)
2216    0x0e2e => 'TungMat0', #4 (Obsolete)
2217    0x0e2f => 'TungMat1', #4 (Obsolete)
2218    0x0e30 => 'TungMat2', #4 (Obsolete)
2219    0x0e31 => 'TungMat3', #4 (Obsolete)
2220    0x0e32 => 'TungMat4', #4 (Obsolete)
2221    0x0e33 => 'TungMat5', #4 (Obsolete)
2222    0x0e34 => 'TungMat6', #4 (Obsolete)
2223    0x0e35 => 'TungMat7', #4 (Obsolete)
2224    0x0e36 => 'TungMat8', #4 (Obsolete)
2225    0x0e37 => 'TungMat9', #4 (Obsolete)
2226    0x0e38 => 'FluorMat0', #4 (Obsolete)
2227    0x0e39 => 'FluorMat1', #4 (Obsolete)
2228    0x0e3a => 'FluorMat2', #4 (Obsolete)
2229    0x0e3b => 'FluorMat3', #4 (Obsolete)
2230    0x0e3c => 'FluorMat4', #4 (Obsolete)
2231    0x0e3d => 'FluorMat5', #4 (Obsolete)
2232    0x0e3e => 'FluorMat6', #4 (Obsolete)
2233    0x0e3f => 'FluorMat7', #4 (Obsolete)
2234    0x0e40 => 'FluorMat8', #4 (Obsolete)
2235    0x0e41 => 'FluorMat9', #4 (Obsolete)
2236    0x0e42 => 'FlashMat0', #4 (Obsolete)
2237    0x0e43 => 'FlashMat1', #4 (Obsolete)
2238    0x0e44 => 'FlashMat2', #4 (Obsolete)
2239    0x0e45 => 'FlashMat3', #4 (Obsolete)
2240    0x0e46 => 'FlashMat4', #4 (Obsolete)
2241    0x0e47 => 'FlashMat5', #4 (Obsolete)
2242    0x0e48 => 'FlashMat6', #4 (Obsolete)
2243    0x0e49 => 'FlashMat7', #4 (Obsolete)
2244    0x0e4a => 'FlashMat8', #4 (Obsolete)
2245    0x0e4b => 'FlashMat9', #4 (Obsolete)
2246    0x0e4c => { #IB
2247        Name => 'KodakLook', # ("LookNameTable", ref 4)
2248        Format => 'undef',
2249        Writable => 'string',
2250        ValueConv => '$val=~tr/\0/\n/; $val',
2251        ValueConvInv => '$val=~tr/\n/\0/; $val',
2252    },
2253    0x0e4d => { Name => 'IPFCameraModel',   Writable => 'string' }, #4
2254    0x0e4e => { Name => 'AH2GreenInterpolationThreshold',   Writable => 'int16u' }, #4
2255    0x0e4f => { Name => 'ResamplingKernelDenominators067',  Writable => 'int16u', Count => 3 }, #4 (table of sharpening denoms; 0=Low, 1=Medium, 2=High)
2256    0x0e50 => { Name => 'ResamplingKernelDenominators050',  Writable => 'int16u', Count => 3 }, #4 (table of sharpening denoms; 0=Low, 1=Medium, 2=High)
2257    0x0e51 => { Name => 'ResamplingKernelDenominators100',  Writable => 'int16u', Count => 3 }, #4 (table of sharpening denoms; 0=Low, 1=Medium, 2=High)
2258    0x0e56 => 'LookMat0', #4 (rational64s[9])
2259    0x0e57 => 'LookMat1', #4 (rational64s[9])
2260    0x0e58 => 'LookMat2', #4 (rational64s[9])
2261    0x0e59 => 'LookMat3', #4 (rational64s[9])
2262    0x0e5a => 'LookMat4', #4 (rational64s[9])
2263    0x0e5b => 'LookMat5', #4 (rational64s[9])
2264    0x0e5c => 'LookMat6', #4 (rational64s[9])
2265    0x0e5d => 'LookMat7', #4 (rational64s[9])
2266    0x0e5e => 'LookMat8', #4 (rational64s[9])
2267    0x0e5f => 'LookMat9', #4 (rational64s[9])
2268    0x0e60 => { #4
2269        Name => 'CFAInterpolationAlgorithm',
2270        Writable => 'int16u',
2271        PrintConv => { 0 => 'AH2', 1 => 'Karnak' },
2272    },
2273    0x0e61 => { #4
2274        Name => 'CFAInterpolationMetric',
2275        Writable => 'int16u',
2276        PrintConv => { 0 => 'Linear12', 1 => 'KLUT12' },
2277    },
2278    0x0e62 => { Name => 'CFAZipperFixThreshold',            Writable => 'int16u' }, #4
2279    0x0e63 => { Name => 'NoiseReductionParametersKhufuRGB', Writable => 'int16u', Count => 9 }, #4
2280    0x0e64 => { Name => 'NoiseReductionParametersKhufu6MP', Writable => 'int16u', Count => 9 }, #4
2281    0x0e65 => { Name => 'NoiseReductionParametersKhufu3MP', Writable => 'int16u', Count => 9 }, #4
2282    0x0e6a => { Name => 'ChromaNoiseHighFThresh',           Writable => 'int32u', Count => 2 }, #4
2283    0x0e6b => { Name => 'ChromaNoiseLowFThresh',            Writable => 'int32u', Count => 2 }, #4
2284    0x0e6c => { Name => 'ChromaNoiseEdgeMapThresh',         Writable => 'int32u' }, #4
2285    0x0e6d => { Name => 'ChromaNoiseColorSpace',            Writable => 'int32u' }, #4
2286    0x0e6e => { Name => 'EnableChromaNoiseReduction',       Writable => 'int16u' }, #4
2287    # 9 values for noise reduction parameters:
2288    #  0 - NRLowType
2289    #  1 - NRLowRadius
2290    #  2 - NRLowStrength
2291    #  3 - NRMediumType
2292    #  4 - NRMediumRadius
2293    #  5 - NRMediumStrength
2294    #  6 - NRHighType
2295    #  7 - NRHighRadius
2296    #  8 - NRHighStrength
2297    # NRType values:
2298    #  0 = None
2299    #  1 = SigmaChroma
2300    #  2 = SigmaOnly
2301    #  3 = SigmaMoire
2302    #  4 = SigmaChromaWithRadius
2303    #  5 = SigmaMoireWithRadius
2304    #  6 = SigmaExpert (aka Khufu)
2305    #  7 = SigmaWithRadius
2306    0x0e6f => { Name => 'NoiseReductionParametersHostRGB',  Writable => 'int16u', Count => 9 }, #4
2307    0x0e70 => { Name => 'NoiseReductionParametersHost6MP',  Writable => 'int16u', Count => 9 }, #4
2308    0x0e71 => { Name => 'NoiseReductionParametersHost3MP',  Writable => 'int16u', Count => 9 }, #4
2309    0x0e72 => { Name => 'NoiseReductionParametersCamera',   Writable => 'int16u', Count => 6 }, #4
2310    0x0e73 => { #4
2311        Name => 'NoiseReductionParametersAtCapture',
2312        Writable => 'int16u',
2313        Count => 6,
2314        # 6 values:
2315        #  0 - Algorithm type
2316        #  1 - Radius
2317        #  2 - Strength
2318        #  3 - Khufu Luma
2319        #  4 - Reserved 1
2320        #  5 - Reserved 2
2321    },
2322    0x0e74 => { Name => 'LCDMatrix',            Writable => 'rational64s', Count => 9 }, #4
2323    0x0e75 => { Name => 'LCDMatrixChickFix',    Writable => 'rational64s', Count => 9 }, #4
2324    0x0e76 => { Name => 'LCDMatrixMarvin',      Writable => 'rational64s', Count => 9 }, #4
2325    0x0e7c => { Name => 'LCDGammaTableChickFix',Binary => 1 }, #4 (int16u[4096])
2326    0x0e7d => { Name => 'LCDGammaTableMarvin',  Binary => 1 }, #4 (int16u[4096])
2327    0x0e7e => { Name => 'LCDGammaTable',        Binary => 1 }, #4 (int16u[4096])
2328    0x0e7f => 'LCDSharpeningF1', #4 (int16s[4])
2329    0x0e80 => 'LCDSharpeningF2', #4
2330    0x0e81 => 'LCDSharpeningF3', #4
2331    0x0e82 => 'LCDSharpeningF4', #4
2332    0x0e83 => 'LCDEdgeMapX1', #4
2333    0x0e84 => 'LCDEdgeMapX2', #4
2334    0x0e85 => 'LCDEdgeMapX3', #4
2335    0x0e86 => 'LCDEdgeMapX4', #4
2336    0x0e87 => 'LCDEdgeMapSlope', #4
2337    0x0e88 => 'YCrCbMatrix', #4
2338    0x0e89 => 'LCDEdgeSpline', #4 (rational64s[9])
2339    0x0e92 => { Name => 'Fac18Per',     Writable => 'int16u' }, #4
2340    0x0e93 => { Name => 'Fac170Per',    Writable => 'int16u' }, #4
2341    0x0e94 => { Name => 'Fac100Per',    Writable => 'int16u' }, #4
2342    0x0e9b => 'ExtraTickLocations', #4 (int16u[7])
2343    0x0e9c => { Name => 'RGBtoeV0',     Binary => 1 }, #4 (int16s[256])
2344    0x0e9d => { Name => 'RGBtoeV1',     Binary => 1 }, #4 (int16s[256])
2345    0x0e9e => { Name => 'RGBtoeV2',     Binary => 1 }, #4 (int16s[256])
2346    0x0e9f => { Name => 'RGBtoeV3',     Binary => 1 }, #4 (int16s[256])
2347    0x0ea0 => { Name => 'RGBtoeV4',     Binary => 1 }, #4 (int16s[256])
2348    0x0ea1 => { Name => 'RGBtoeV5',     Binary => 1 }, #4 (int16s[256])
2349    0x0ea2 => { Name => 'RGBtoeV6',     Binary => 1 }, #4 (int16s[256])
2350    0x0ea3 => { Name => 'RGBtoeV7',     Binary => 1 }, #4 (int16s[256])
2351    0x0ea4 => { Name => 'RGBtoeV8',     Binary => 1 }, #4 (int16s[256])
2352    0x0ea5 => { Name => 'RGBtoeV9',     Binary => 1 }, #4 (int16s[256])
2353    0x0ea6 => { Name => 'LCDHistLUT0',  Binary => 1 }, #4 (rational64s[48])
2354    0x0ea7 => { Name => 'LCDHistLUT1',  Binary => 1 }, #4 (rational64s[57])
2355    0x0ea8 => { Name => 'LCDHistLUT2',  Binary => 1 }, #4 (rational64s[48])
2356    0x0ea9 => { Name => 'LCDHistLUT3',  Binary => 1 }, #4 (rational64s[57])
2357    0x0eaa => { Name => 'LCDHistLUT4',  Binary => 1 }, #4 (rational64s[48])
2358    0x0eab => { Name => 'LCDHistLUT5',  Binary => 1 }, #4 (rational64s[57])
2359    0x0eac => { Name => 'LCDHistLUT6',  Binary => 1 }, #4 (rational64s[48])
2360    0x0ead => { Name => 'LCDHistLUT7',  Binary => 1 }, #4 (rational64s[48])
2361    0x0eae => { Name => 'LCDHistLUT8',  Binary => 1 }, #4
2362    0x0eaf => { Name => 'LCDHistLUT9',  Binary => 1 }, #4
2363    0x0eb0 => 'LCDLinearClipValue', #4
2364    0x0ece => 'LCDStepYvalues', #4 (int8u[10])
2365    0x0ecf => 'LCDStepYvaluesChickFix', #4 (int8u[10])
2366    0x0ed0 => 'LCDStepYvaluesMarvin', #4 (int8u[10])
2367    0x0ed8 => { Name => 'InterpolationCoefficients', Binary => 1 }, #4 (int16s[69])
2368    0x0ed9 => 'InterpolationCoefficients6MP', #4
2369    0x0eda => 'InterpolationCoefficients3MP', #4
2370    0x0f00 => { Name => 'NoiseReductionParametersHostNormal',  Binary => 1 }, #4 (int16u[140])
2371    0x0f01 => { Name => 'NoiseReductionParametersHostStrong',  Binary => 1 }, #4 (int16u[140])
2372    0x0f02 => { Name => 'NoiseReductionParametersHostLow',  Binary => 1 }, #4
2373    0x0f0a => { Name => 'MariahTextureThreshold',   Writable => 'int16u' }, #4
2374    0x0f0b => { Name => 'MariahMapLoThreshold',     Writable => 'int16u' }, #4
2375    0x0f0c => { Name => 'MariahMapHiThreshold',     Writable => 'int16u' }, #4
2376    0x0f0d => { Name => 'MariahChromaBlurSize',     Writable => 'int16u' }, #4
2377    0x0f0e => { Name => 'MariahSigmaThreshold',     Writable => 'int16u' }, #4
2378    0x0f0f => { Name => 'MariahThresholds',         Binary => 1 }, #4
2379    0x0f10 => { Name => 'MariahThresholdsNormal',   Binary => 1 }, #4 (int16u[140])
2380    0x0f11 => { Name => 'MariahThresholdsStrong',   Binary => 1 }, #4 (int16u[140])
2381    0x0f12 => { Name => 'MariahThresholdsLow',      Binary => 1 }, #4
2382    0x0f14 => 'KhufuLinearRedMixingCoefficient', #4
2383    0x0f15 => 'KhufuLinearGreenMixingCoefficient', #4
2384    0x0f16 => 'KhufuLinearBlueMixingCoefficient', #4
2385    0x0f17 => 'KhufuUSpaceC2MixingCoefficient', #4
2386    0x0f18 => 'KhufuSigmaGaussianWeights', #4
2387    0x0f19 => 'KhufuSigmaScalingFactors6MP', #4 (rational64u[6])
2388    0x0f1a => 'KhufuSigmaScalingFactors3MP', #4 (rational64u[6])
2389    0x0f1b => 'KhufuSigmaScalingFactors14MP', #4
2390    # 0x0f1e-0x0f27 - KhufuLinearRGBtoLogRGB(n), (for Khufu) ref 4
2391    # 0x0f28-0x0f31 - KhufuLogRGBtoLinearRGB(n), (for Khufu) ref 4
2392    0x0f32 => { Name => 'KhufuI0Thresholds',    Binary => 1 }, #4 (int32s[348])
2393    0x0f33 => { Name => 'KhufuI1Thresholds',    Binary => 1 }, #4 (int32s[348])
2394    0x0f34 => { Name => 'KhufuI2Thresholds',    Binary => 1 }, #4 (int32s[348])
2395    0x0f35 => { Name => 'KhufuI3Thresholds',    Binary => 1 }, #4 (int32s[348])
2396    0x0f36 => { Name => 'KhufuI4Thresholds',    Binary => 1 }, #4 (int32s[348])
2397    0x0f37 => { Name => 'KhufuI5Thresholds',    Binary => 1 }, #4 (int32s[348])
2398    0x0f3c => { Name => 'CondadoDayBVThresh',   Writable => 'int16u' }, #4
2399    0x0f3d => { Name => 'CondadoNeuRange',      Writable => 'int16u' }, #4
2400    0x0f3e => { Name => 'CondadoBVFactor',      Writable => 'int16s' }, #4
2401    0x0f3f => { Name => 'CondadoIllFactor',     Writable => 'int16s' }, #4
2402    0x0f40 => { Name => 'CondadoTunThresh',     Writable => 'int16s' }, #4
2403    0x0f41 => { Name => 'CondadoFluThresh',     Writable => 'int16s' }, #4
2404    0x0f42 => { Name => 'CondadoDayOffsets',    Writable => 'int16s', Count => 2 }, #4
2405    0x0f43 => { Name => 'CondadoTunOffsets',    Writable => 'int16s', Count => 2 }, #4
2406    0x0f44 => { Name => 'CondadoFluOffsets',    Writable => 'int16s', Count => 2 }, #4
2407    0x0f5a => 'ERIMMToCRGB0Spline', #4 (rational64s[33])
2408    0x0f5b => 'ERIMMToCRGB1Spline', #4 (rational64s[36])
2409    0x0f5c => 'ERIMMToCRGB2Spline', #4 (rational64s[33])
2410    0x0f5d => 'ERIMMToCRGB3Spline', #4 (rational64s[33])
2411    0x0f5e => 'ERIMMToCRGB4Spline', #4 (rational64s[33])
2412    0x0f5f => 'ERIMMToCRGB5Spline', #4 (rational64s[33])
2413    0x0f60 => 'ERIMMToCRGB6Spline', #4 (rational64s[33])
2414    0x0f61 => 'ERIMMToCRGB7Spline', #4 (rational64s[33])
2415    0x0f62 => 'ERIMMToCRGB8Spline', #4
2416    0x0f63 => 'ERIMMToCRGB9Spline', #4
2417    0x0f64 => 'CRGBToERIMM0Spline', #4 (rational64s[27])
2418    0x0f65 => 'CRGBToERIMM1Spline', #4 (rational64s[54])
2419    0x0f66 => 'CRGBToERIMM2Spline', #4 (rational64s[27])
2420    0x0f67 => 'CRGBToERIMM3Spline', #4 (rational64s[54])
2421    0x0f68 => 'CRGBToERIMM4Spline', #4 (rational64s[27])
2422    0x0f69 => 'CRGBToERIMM5Spline', #4 (rational64s[54])
2423    0x0f6a => 'CRGBToERIMM6Spline', #4 (rational64s[27])
2424    0x0f6b => 'CRGBToERIMM7Spline', #4 (rational64s[27])
2425    0x0f6c => 'CRGBToERIMM8Spline', #4
2426    0x0f6d => 'CRGBToERIMM9Spline', #4
2427    0x0f6e => 'ERIMMNonLinearitySpline', #4 (rational64s[42])
2428    0x0f6f => 'Delta12To8Spline', #4 (rational64s[12])
2429    0x0f70 => 'Delta8To12Spline', #4 (rational64s[12])
2430    0x0f71 => 'InverseMonitorMatrix', #4 (rational64s[9])
2431    0x0f72 => { Name => 'NifNonlinearityExt', Binary => 1 }, #4 (int16s[8000])
2432    0x0f73 => { Name => 'InvNifNonLinearity', Binary => 1 }, #4 (int16u[256])
2433    0x0f74 => 'RIMM13ToERIMM12Spline', #4 (rational64s[51])
2434    0x0f78 => 'ToneScale0Spline', #4 (rational64s[57])
2435    0x0f79 => 'ToneScale1Spline', #4 (rational64s[51])
2436    0x0f7a => 'ToneScale2Spline', #4 (rational64s[57])
2437    0x0f7b => 'ToneScale3Spline', #4 (rational64s[51])
2438    0x0f7c => 'ToneScale4Spline', #4 (rational64s[57])
2439    0x0f7d => 'ToneScale5Spline', #4 (rational64s[51])
2440    0x0f7e => 'ToneScale6Spline', #4 (rational64s[57])
2441    0x0f7f => 'ToneScale7Spline', #4 (rational64s[57])
2442    0x0f80 => 'ToneScale8Spline', #4
2443    0x0f81 => 'ToneScale9Spline', #4
2444    0x0f82 => 'ERIMMToneScale0Spline', #4 (rational64s[60])
2445    0x0f83 => 'ERIMMToneScale1Spline', #4 (rational64s[54])
2446    0x0f84 => 'ERIMMToneScale2Spline', #4 (rational64s[60])
2447    0x0f85 => 'ERIMMToneScale3Spline', #4 (rational64s[54])
2448    0x0f86 => 'ERIMMToneScale4Spline', #4 (rational64s[60])
2449    0x0f87 => 'ERIMMToneScale5Spline', #4 (rational64s[54])
2450    0x0f88 => 'ERIMMToneScale6Spline', #4 (rational64s[60])
2451    0x0f89 => 'ERIMMToneScale7Spline', #4 (rational64s[60])
2452    0x0f8a => 'ERIMMToneScale8Spline', #4
2453    0x0f8b => 'ERIMMToneScale9Spline', #4
2454    0x0f8c => 'RIMMToCRGB0Spline', #4 (rational64s[66])
2455    0x0f8d => 'RIMMToCRGB1Spline', #4 (rational64s[84])
2456    0x0f8e => 'RIMMToCRGB2Spline', #4 (rational64s[66])
2457    0x0f8f => 'RIMMToCRGB3Spline', #4 (rational64s[84])
2458    0x0f90 => 'RIMMToCRGB4Spline', #4 (rational64s[66])
2459    0x0f91 => 'RIMMToCRGB5Spline', #4 (rational64s[84])
2460    0x0f92 => 'RIMMToCRGB6Spline', #4 (rational64s[66])
2461    0x0f93 => 'RIMMToCRGB7Spline', #4 (rational64s[66])
2462    0x0f94 => 'RIMMToCRGB8Spline', #4
2463    0x0f95 => 'RIMMToCRGB9Spline', #4
2464    0x0fa0 => 'QTableLarge25Pct', #4
2465    0x0fa1 => 'QTableMedium25Pct', #4
2466    0x0fa2 => 'QTableSmall25Pct', #4
2467    0x1130 => 'NoiseReductionKernel', #4 (Noise filter kernel.  No longer needed)
2468    0x1388 => 'UserMetaData', #4 (undef[0])
2469    0x1389 => { Name => 'InputProfile',     Writable => 'undef', Binary => 1 }, #IB ("SourceProfile", ref 4)
2470    0x138a => { Name => 'KodakLookProfile', Writable => 'undef', Binary => 1 }, #IB ("LookProfile", ref 4)
2471    0x138b => { Name => 'OutputProfile',    Writable => 'undef', Binary => 1 }, #IB ("DestinationProfile", ref 4)
2472    0x1390 => { Name => 'SourceProfilePrefix',  Writable => 'string' }, #4 (eg. 'DCSProSLRn')
2473    0x1391 => { Name => 'ToneCurveProfileName', Writable => 'string' }, #4
2474    0x1392 => { Name => 'InputProfile', SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' } }, #4
2475    0x1393 => { Name => 'ProcessParametersV2',  Binary => 1 }, #4 (Used by the SDK, Firmware should not use!)
2476    0x1394 => 'ReservedBlob2', #4
2477    0x1395 => 'ReservedBlob3', #4
2478    0x1396 => 'ReservedBlob4', #4
2479    0x1397 => 'ReservedBlob5', #4
2480    0x1398 => 'ReservedBlob6', #4
2481    0x1399 => 'ReservedBlob7', #4
2482    0x139a => 'ReservedBlob8', #4
2483    0x139b => 'ReservedBlob9', #4
2484    0x1770 => { Name => 'ScriptVersion',    Writable => 'int32u' }, #4
2485    0x177a => 'ImagerTimingData', #4
2486    0x1784 => { Name => 'ISO',              Writable => 'int32u' }, #3 ("NsecPerIcCode", ref 4)
2487    0x17a2 => 'Scav11Cols', #4
2488    0x17a3 => 'Scav12Cols', #4
2489    0x17a4 => 'Scav21Cols', #4
2490    0x17a5 => 'Scav22Cols', #4
2491    0x17a6 => 'ActiveCTEMonitor1Cols', #4
2492    0x17a7 => 'ActiveCTEMonitor2Cols', #4
2493    0x17a8 => 'ActiveCTEMonitorRows', #4
2494    0x17a9 => 'ActiveBuf1Cols', #4
2495    0x17aa => 'ActiveBuf2Cols', #4
2496    0x17ab => 'ActiveBuf1Rows', #4
2497    0x17ac => 'ActiveBuf2Rows', #4
2498    0x17c0 => 'HRNoiseLines', #4
2499    0x17c1 => 'RNoiseLines', #4
2500    0x17c2 => 'ANoiseLines', #4
2501    0x17d4 => { Name => 'ImagerCols',   Writable => 'int16u' }, #4
2502    0x17de => { Name => 'ImagerRows',   Writable => 'int16u' }, #4
2503    0x17e8 => { Name => 'PartialActiveCols1',   Writable => 'int32u' }, #4
2504    0x17f2 => { Name => 'PartialActiveCols2',   Writable => 'int32u' }, #4
2505    0x17fc => { Name => 'PartialActiveRows1',   Writable => 'int32u' }, #4
2506    0x1806 => { Name => 'PartialActiveRows2',   Writable => 'int32u' }, #4
2507    0x1810 => { Name => 'ElectricalBlackColumns',Writable=> 'int32u' }, #4
2508    0x181a => { Name => 'ResetBlackSegRows',    Writable => 'int32u' }, #4
2509    0x1838 => { Name => 'CaptureWidthNormal',   Writable => 'int32u' }, #4
2510    0x1839 => { Name => 'CaptureHeightNormal',  Writable => 'int32u' }, #4
2511    0x183a => 'CaptureWidthResetBlackSegNormal', #4
2512    0x183b => 'CaptureHeightResetBlackSegNormal', #4
2513    0x183c => 'DarkRefOffsetNormal', #4
2514    0x1842 => { Name => 'CaptureWidthTest',     Writable => 'int32u' }, #4
2515    0x1843 => 'CaptureHeightTest', #4
2516    0x1844 => 'CaptureWidthResetBlackSegTest', #4
2517    0x1845 => 'CaptureHeightResetBlackSegTest', #4
2518    0x1846 => 'DarkRefOffsetTest', #4
2519    0x184c => { Name => 'ImageSegmentStartLine',Writable => 'int32u' }, #4
2520    0x184d => { Name => 'ImageSegmentLines',    Writable => 'int32u' }, #4
2521    0x184e => { Name => 'SkipLineTime',         Writable => 'int32u' }, #4
2522    0x1860 => { Name => 'FastResetLineTime',    Writable => 'int32u' }, #4
2523    0x186a => { Name => 'NormalLineTime',       Writable => 'int32u' }, #4
2524    0x1874 => { Name => 'MinIntegrationRows',   Writable => 'int32u' }, #4
2525    0x187e => { Name => 'PreReadFastResetCount',Writable => 'int32u' }, #4
2526    0x1888 => { Name => 'TransferTimeNormal',   Writable => 'int32u' }, #4
2527    0x1889 => { Name => 'TransferTimeTest',     Writable => 'int32u' }, #4
2528    0x188a => { Name => 'QuietTime',            Writable => 'int32u' }, #4
2529    0x189c => { Name => 'OverClockCols',        Writable => 'int16u' }, #4
2530    0x18a6 => { Name => 'H2ResetBlackPixels',   Writable => 'int32u' }, #4
2531    0x18b0 => { Name => 'H3ResetBlackPixels',   Writable => 'int32u' }, #4
2532    0x18ba => { Name => 'BlackAcquireRows',     Writable => 'int32u' }, #4
2533    0x18c4 => { Name => 'OverClockRows',        Writable => 'int16u' }, #4
2534    0x18ce => { Name => 'H3ResetBlackColumns',  Writable => 'int32u' }, #4
2535    0x18d8 => { Name => 'DarkBlackSegRows',     Writable => 'int32u' }, #4
2536    0x1900 => 'CrossbarEnable', #4
2537    0x1901 => { Name => 'FifoenOnePixelDelay',  Writable => 'int32u' }, #4
2538    0x1902 => { Name => 'ReadoutTypeRequested', Writable => 'int32u' }, #4
2539    0x1903 => { Name => 'ReadoutTypeActual',    Writable => 'int32u' }, #4
2540    0x190a => { Name => 'OffsetDacValue',       Writable => 'int32u' }, #4
2541    0x1914 => { Name => 'TempAmpGainX100',      Writable => 'int32u' }, #4
2542    0x191e => { Name => 'VarrayDacNominalValues',Writable=> 'int32u', Count => 3 }, #4
2543    0x1928 => 'VddimDacNominalValues', #4
2544    0x1964 => { Name => 'C14Configuration',     Writable => 'int32u' }, #4
2545    0x196e => { Name => 'TDA1Offset',           Writable => 'int32u', Count => 3 }, #4
2546    0x196f => { Name => 'TDA1Bandwidth',        Writable => 'int32u' }, #4
2547    0x1970 => { Name => 'TDA1Gain',             Writable => 'int32u', Count => 3 }, #4
2548    0x1971 => { Name => 'TDA1EdgePolarity',     Writable => 'int32u' }, #4
2549    0x1978 => { Name => 'TDA2Offset',           Writable => 'int32u', Count => 3 }, #4
2550    0x1979 => { Name => 'TDA2Bandwidth',        Writable => 'int32u' }, #4
2551    0x197a => { Name => 'TDA2Gain',             Writable => 'int32u', Count => 3 }, #4
2552    0x197b => { Name => 'TDA2EdgePolarity',     Writable => 'int32u' }, #4
2553    0x1982 => { Name => 'TDA3Offset',           Writable => 'int32u', Count => 3 }, #4
2554    0x1983 => { Name => 'TDA3Bandwidth',        Writable => 'int32u' }, #4
2555    0x1984 => { Name => 'TDA3Gain',             Writable => 'int32u', Count => 3 }, #4
2556    0x1985 => { Name => 'TDA3EdgePolarity',     Writable => 'int32u' }, #4
2557    0x198c => { Name => 'TDA4Offset',           Writable => 'int32u', Count => 3 }, #4
2558    0x198d => { Name => 'TDA4Bandwidth',        Writable => 'int32u' }, #4
2559    0x198e => { Name => 'TDA4Gain',             Writable => 'int32u', Count => 3 }, #4
2560    0x198f => { Name => 'TDA4EdgePolarity',     Writable => 'int32u' }, #4
2561    0xfde8 => { Name => 'ComLenBlkSize',        Writable => 'int16u' }, #4
2562);
2563
2564# contains WB adjust set in software (ref 3)
2565%Image::ExifTool::Kodak::Processing = (
2566    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
2567    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
2568    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
2569    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
2570    FORMAT => 'int16u',
2571    FIRST_ENTRY => 0,
2572    20 => {
2573        Name => 'WB_RGBLevels',
2574        Format => 'int16u[3]',
2575        ValueConv => q{
2576            my @a = split ' ',$val;
2577            foreach (@a) {
2578                $_ = 2048 / $_ if $_;
2579            }
2580            return join ' ', @a;
2581        }
2582    },
2583);
2584
2585# tags found in the Kodak KDC_IFD (in IFD0 of KDC images) (ref 3)
2586%Image::ExifTool::Kodak::KDC_IFD = (
2587    GROUPS => { 0 => 'MakerNotes', 1 => 'KDC_IFD', 2 => 'Image'},
2588    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
2589    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
2590    WRITE_GROUP => 'KDC_IFD',
2591    SET_GROUP1 => 1,
2592    NOTES => q{
2593        These tags are found in a separate IFD of KDC images from some newer Kodak
2594        models such as the P880 and Z1015IS.
2595    },
2596    0xfa00 => {
2597        Name => 'SerialNumber', #PH (unverified)
2598        Writable => 'string',
2599    },
2600    0xfa0d => {
2601        Name => 'WhiteBalance',
2602        Writable => 'int8u',
2603        PrintConv => { #PH
2604            0 => 'Auto',
2605            1 => 'Fluorescent', # (NC)
2606            2 => 'Tungsten', # (NC)
2607            3 => 'Daylight', # (NC)
2608            6 => 'Shade', # (NC, called "Open Shade" by Kodak)
2609        },
2610    },
2611    # the following tags are numbered for use in the Composite tag lookup
2612    0xfa25 => 'WB_RGBLevelsAuto',
2613    0xfa27 => 'WB_RGBLevelsTungsten', # (NC)
2614    0xfa28 => 'WB_RGBLevelsFluorescent', # (NC)
2615    0xfa29 => 'WB_RGBLevelsDaylight', # (NC)
2616    0xfa2a => 'WB_RGBLevelsShade', # (NC)
2617);
2618
2619# textual-based Kodak TextualInfo tags (not found in KDC images) (ref PH)
2620%Image::ExifTool::Kodak::TextualInfo = (
2621    GROUPS => { 0 => 'MakerNotes', 1 => 'Kodak', 2 => 'Image'},
2622    PROCESS_PROC => \&ProcessKodakText,
2623    NOTES => q{
2624        Below is a list of tags which have been observed in the Kodak TextualInfo
2625        data, however ExifTool will extract information from any tags found here.
2626    },
2627    'Actual Compensation' => 'ActualCompensation',
2628    'AF Function'   => 'AFMode', # values: "S" (=Single?, then maybe C for Continuous, M for Manual?) - PH
2629    'Aperture'      => {
2630        Name => 'Aperture',
2631        ValueConv => '$val=~s/^f//i; $val',
2632    },
2633    'Auto Bracket'  => 'AutoBracket',
2634    'Brightness Value' => 'BrightnessValue',
2635    'Camera'        => 'CameraModel',
2636    'Camera body'   => 'CameraBody',
2637    'Compensation'  => 'ExposureCompensation',
2638    'Date'          => {
2639        Name => 'Date',
2640        Groups => { 2 => 'Time' },
2641    },
2642    'Exposure Bias' => 'ExposureBias',
2643    'Exposure Mode' => {
2644        Name => 'ExposureMode',
2645        PrintConv => {
2646            OTHER => sub { shift }, # pass other values straight through
2647            'M' => 'Manual',
2648            'A' => 'Aperture Priority', #(NC -- I suppose this could be "Auto" too)
2649            'S' => 'Shutter Priority', #(NC)
2650            'P' => 'Program', #(NC)
2651            'B' => 'Bulb', #(NC)
2652            # have seen "Manual (M)" written by DCS760C - PH
2653            # and "Aperture priority AE (Av)" written by a ProBack 645M
2654        },
2655    },
2656    'Firmware Version' => 'FirmwareVersion',
2657    'Flash Compensation' => 'FlashExposureComp',
2658    'Flash Fired'   => 'FlashFired',
2659    'Flash Sync Mode' => 'FlashSyncMode',
2660    'Focal Length'  => {
2661        Name => 'FocalLength',
2662        PrintConv => '"$val mm"',
2663    },
2664    'Height'        => 'KodakImageHeight',
2665    'Image Number'  => 'ImageNumber',
2666    'ISO'           => 'ISO',
2667    'ISO Speed'     => 'ISO',
2668    'Lens'          => { Name => 'Lens', Priority => 0 },
2669    'Max Aperture'  => {
2670        Name => 'MaxAperture',
2671        ValueConv => '$val=~s/^f//i; $val',
2672    },
2673    'Meter Mode'    => 'MeterMode',
2674    'Min Aperture'  => {
2675        Name => 'MinAperture',
2676        ValueConv => '$val=~s/^f//i; $val',
2677    },
2678    'Popup Flash'   => 'PopupFlash',
2679    'Serial Number' => 'SerialNumber',
2680    'Shooting Mode' => 'ShootingMode',
2681    'Shutter'       => 'ShutterSpeed',
2682    'Temperature'   => 'Temperature', # with a value of 15653, what could this be? - PH
2683    'Time'          => {
2684        Name => 'Time',
2685        Groups => { 2 => 'Time' },
2686    },
2687    'White balance' => 'WhiteBalance',
2688    'Width'         => 'KodakImageWidth',
2689    '_other_info'   => {
2690        Name => 'OtherInfo',
2691        Notes => 'any other information without a tag name',
2692    },
2693);
2694
2695# Kodak APP3 "Meta" tags (ref 2)
2696%Image::ExifTool::Kodak::Meta = (
2697    GROUPS => { 0 => 'Meta', 1 => 'MetaIFD', 2 => 'Image'},
2698    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
2699    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
2700    WRITE_GROUP => 'MetaIFD',   # default write group
2701    NOTES => q{
2702        These tags are found in the APP3 "Meta" segment of JPEG images from Kodak
2703        cameras such as the DC280, DC3400, DC5000, MC3, M580, Z950 and Z981.  The
2704        structure of this segment is similar to the APP1 "Exif" segment, but a
2705        different set of tags is used.
2706    },
2707    0xc350 => 'FilmProductCode',
2708    0xc351 => 'ImageSourceEK',
2709    0xc352 => 'CaptureConditionsPAR',
2710    0xc353 => {
2711        Name => 'CameraOwner',
2712        Writable => 'undef',
2713        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val,$tag)',
2714        RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
2715    },
2716    0xc354 => {
2717        Name => 'SerialNumber',
2718        Writable => 'undef',
2719        Groups => { 2 => 'Camera' },
2720        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val,$tag)', #PH
2721        RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
2722    },
2723    0xc355 => 'UserSelectGroupTitle',
2724    0xc356 => 'DealerIDNumber',
2725    0xc357 => 'CaptureDeviceFID',
2726    0xc358 => 'EnvelopeNumber',
2727    0xc359 => 'FrameNumber',
2728    0xc35a => 'FilmCategory',
2729    0xc35b => 'FilmGencode',
2730    0xc35c => 'ModelAndVersion',
2731    0xc35d => 'FilmSize',
2732    0xc35e => 'SBA_RGBShifts',
2733    0xc35f => 'SBAInputImageColorspace',
2734    0xc360 => 'SBAInputImageBitDepth',
2735    0xc361 => {
2736        Name => 'SBAExposureRecord',
2737        Binary => 1,
2738    },
2739    0xc362 => {
2740        Name => 'UserAdjSBA_RGBShifts',
2741        Binary => 1,
2742    },
2743    0xc363 => 'ImageRotationStatus',
2744    0xc364 => 'RollGuidElements',
2745    0xc365 => 'MetadataNumber',
2746    0xc366 => 'EditTagArray',
2747    0xc367 => 'Magnification',
2748    # 0xc36b - string[8]: "1.0"
2749    0xc36c => 'NativeXResolution',
2750    0xc36d => 'NativeYResolution',
2751    0xc36e => {
2752        Name => 'KodakEffectsIFD',
2753        Flags => 'SubIFD',
2754        Groups => { 1 => 'KodakEffectsIFD' },
2755        SubDirectory => {
2756            TagTable => 'Image::ExifTool::Kodak::SpecialEffects',
2757            Start => '$val',
2758        },
2759    },
2760    0xc36f => {
2761        Name => 'KodakBordersIFD',
2762        Flags => 'SubIFD',
2763        Groups => { 1 => 'KodakBordersIFD' },
2764        SubDirectory => {
2765            TagTable => 'Image::ExifTool::Kodak::Borders',
2766            Start => '$val',
2767        },
2768    },
2769    0xc37a => 'NativeResolutionUnit',
2770    0xc418 => 'SourceImageDirectory',
2771    0xc419 => 'SourceImageFileName',
2772    0xc41a => 'SourceImageVolumeName',
2773    0xc46c => 'PrintQuality',
2774    0xc46e => 'ImagePrintStatus',
2775    # 0cx46f - int16u: 1
2776);
2777
2778# Kodak APP3 "Meta" Special Effects sub-IFD (ref 2)
2779%Image::ExifTool::Kodak::SpecialEffects = (
2780    GROUPS => { 0 => 'Meta', 1 => 'KodakEffectsIFD', 2 => 'Image'},
2781    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
2782    0 => 'DigitalEffectsVersion',
2783    1 => {
2784        Name => 'DigitalEffectsName',
2785        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val,"DigitalEffectsName")',
2786    },
2787    2 => 'DigitalEffectsType',
2788);
2789
2790# Kodak APP3 "Meta" Borders sub-IFD (ref 2)
2791%Image::ExifTool::Kodak::Borders = (
2792    GROUPS => { 0 => 'Meta', 1 => 'KodakBordersIFD', 2 => 'Image'},
2793    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
2794    0 => 'BordersVersion',
2795    1 => {
2796        Name => 'BorderName',
2797        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val,"BorderName")',
2798    },
2799    2 => 'BorderID',
2800    3 => 'BorderLocation',
2801    4 => 'BorderType',
2802    8 => 'WatermarkType',
2803);
2804
2805# tags in Kodak MOV videos (ref PH)
2806# (similar information in Kodak,Minolta,Nikon,Olympus,Pentax and Sanyo videos)
2807%Image::ExifTool::Kodak::MOV = (
2808    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
2809    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
2810    FIRST_ENTRY => 0,
2811    NOTES => q{
2812        This information is found in the TAGS atom of MOV videos from Kodak models
2813        such as the P880.
2814    },
2815    0 => {
2816        Name => 'Make',
2817        Format => 'string[21]',
2818    },
2819    0x16 => {
2820        Name => 'Model',
2821        Format => 'string[42]',
2822    },
2823    0x40 => {
2824        Name => 'ModelType',
2825        Format => 'string[8]',
2826    },
2827    # (01 00 at offset 0x48)
2828    0x4e => {
2829        Name => 'ExposureTime',
2830        Format => 'int32u',
2831        ValueConv => '$val ? 10 / $val : 0',
2832        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
2833    },
2834    0x52 => {
2835        Name => 'FNumber',
2836        Format => 'rational64u',
2837        PrintConv => 'sprintf("%.1f",$val)',
2838    },
2839    0x5a => {
2840        Name => 'ExposureCompensation',
2841        Format => 'rational64s',
2842        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
2843    },
2844    # 0x6c => 'WhiteBalance', ?
2845    0x70 => {
2846        Name => 'FocalLength',
2847        Format => 'rational64u',
2848        PrintConv => 'sprintf("%.1f mm",$val)',
2849    },
2850);
2851
2852# Kodak DcMD atoms (ref PH)
2853%Image::ExifTool::Kodak::DcMD = (
2854    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
2855    NOTES => 'Metadata directory found in MOV and MP4 videos from some Kodak cameras.',
2856    Cmbo => {
2857        Name => 'CameraByteOrder',
2858        PrintConv => {
2859            II => 'Little-endian (Intel, II)',
2860            MM => 'Big-endian (Motorola, MM)',
2861        },
2862    },
2863    CMbo => { # (as written by Kodak Playsport video camera)
2864        Name => 'CameraByteOrder',
2865        PrintConv => {
2866            II => 'Little-endian (Intel, II)',
2867            MM => 'Big-endian (Motorola, MM)',
2868        },
2869    },
2870    DcME => {
2871        Name => 'DcME',
2872        SubDirectory => {
2873            TagTable => 'Image::ExifTool::Kodak::DcME',
2874        },
2875    },
2876    DcEM => {
2877        Name => 'DcEM',
2878        SubDirectory => {
2879            TagTable => 'Image::ExifTool::Kodak::DcEM',
2880        },
2881    },
2882);
2883
2884# Kodak DcME atoms (ref PH)
2885%Image::ExifTool::Kodak::DcME = (
2886    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
2887    # Mtmd - 24 bytes: ("00 00 00 00 00 00 00 01" x 3)
2888    # Keyw - keywords? (six bytes all zero)
2889    # Rate -  2 bytes: 00 00
2890);
2891
2892# Kodak DcEM atoms (ref PH)
2893%Image::ExifTool::Kodak::DcEM = (
2894    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
2895    # Mtmd - 24 bytes: ("00 00 00 00 00 00 00 01" x 3)
2896    # Csat - 16 bytes: 00 06 00 00 62 00 61 00 73 00 69 00 63 00 00 00 [....b.a.s.i.c...]
2897    # Ksre -  8 bytes: 00 01 00 00 00 00
2898);
2899
2900# tags in "free" atom of Kodak M5370 MP4 videos (ref PH)
2901%Image::ExifTool::Kodak::Free = (
2902    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
2903    NOTES => q{
2904        Information stored in the "free" atom of Kodak MP4 videos. (VERY bad form
2905        for Kodak to store useful information in an atom intended for unused space!)
2906    },
2907    # (2012/01/19: Kodak files for bankruptcy -- this is poetic metadata justice)
2908    Seri => {
2909        Name => 'SerialNumber',
2910        # byte 0 is string length;  byte 1 is zero;  string starts at byte 2
2911        ValueConv => 'substr($val, 2, unpack("C",$val))',
2912    },
2913    SVer => {
2914        Name => 'FirmwareVersion',
2915        ValueConv => 'substr($val, 2, unpack("C",$val))',
2916    },
2917    # Clor - 2 bytes: 0 1  (?)
2918    # CapM - 2 bytes: 0 1  (capture mode? = exposure mode?)
2919    # WBMD - 2 bytes: 0 0  (white balance?)
2920    Expc => { # (NC)
2921        Name => 'ExposureCompensation',
2922        Format => 'int16s',
2923        ValueConv => '$val / 3', # (guess)
2924        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
2925    },
2926    # Zone - 2 bytes: 0 2  (time zone? focus zone?)
2927    # FoMD - 2 bytes: 0 0  (focus mode?)
2928    # Shap - 2 bytes: 0 2  (sharpness?)
2929    Expo => {
2930        Name => 'ExposureTime',
2931        Format => 'rational32u',
2932        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
2933    },
2934    FNum => {
2935        Name => 'FNumber',
2936        Format => 'int16u',
2937        ValueConv => '$val / 100',
2938        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
2939    },
2940    ISOS => { Name => 'ISO', Format => 'int16u' },
2941    StSV => {
2942        Name => 'ShutterSpeedValue',
2943        Format => 'int16s',
2944        ValueConv => 'abs($val)<100 ? 2**(-$val/3) : 0',
2945        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
2946    },
2947    AprV => {
2948        Name => 'ApertureValue',
2949        Format => 'int16s',
2950        ValueConv => '2 ** ($val / 2000)',
2951        PrintConv => 'sprintf("%.1f",$val)',
2952    },
2953    BrtV => { # (NC)
2954        Name => 'BrightnessValue',
2955        Format => 'int32s',
2956        ValueConv => '$val / 1000', # (guess)
2957    },
2958    FoLn => {
2959        Name => 'FocalLength',
2960        Groups => { 2 => 'Camera' },
2961        Format => 'int16u',
2962        PrintConv => 'sprintf("%.1f mm",$val)',
2963    },
2964    FL35 => {
2965        Name => 'FocalLengthIn35mmFormat',
2966        Groups => { 2 => 'Camera' },
2967        Format => 'int16u',
2968        PrintConv => '"$val mm"',
2969    },
2970    Scrn => {
2971        Name => 'PreviewInfo',
2972        SubDirectory => { TagTable => 'Image::ExifTool::Kodak::Scrn' },
2973    },
2974);
2975
2976# tags in "frea" atom of Kodak PixPro SP360 MP4 videos (ref PH)
2977%Image::ExifTool::Kodak::frea = (
2978    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
2979    NOTES => 'Information stored in the "frea" atom of Kodak PixPro SP360 MP4 videos.',
2980    tima => {
2981        Name => 'Duration',
2982        Format => 'int32u',
2983        Priority => 0,  # (only integer seconds)
2984        PrintConv => 'ConvertDuration($val)',
2985    },
2986   'ver '=> { Name => 'KodakVersion' },
2987    thma => { Name => 'ThumbnailImage', Groups => { 2 => 'Preview' }, Binary => 1 },
2988    scra => { Name => 'PreviewImage',   Groups => { 2 => 'Preview' }, Binary => 1 },
2989);
2990
2991# preview information in free/Scrn atom of MP4 videos (ref PH)
2992%Image::ExifTool::Kodak::Scrn = (
2993    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
2994    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
2995    FORMAT => 'int16u',
2996    0 => 'PreviewImageWidth',
2997    1 => 'PreviewImageHeight',
2998    2 => { Name => 'PreviewImageLength', Format => 'int32u' },
2999    4 => {
3000        Name => 'PreviewImage',
3001        Groups => { 2 => 'Preview' },
3002        Format => 'undef[$val{2}]',
3003        RawConv => '$self->ValidateImage(\$val, $tag)',
3004    },
3005);
3006
3007# acceleration information extracted from 'pose' atom of MP4 videos (ref PH, PixPro 4KVR360)
3008%Image::ExifTool::Kodak::pose = (
3009    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
3010    PROCESS_PROC => \&ProcessPose,
3011    NOTES => q{
3012        Streamed orientation information from the PixPro 4KVR360, extracted as
3013        sub-documents when the L<Duplicates|../ExifTool.html#Duplicates> option is used.
3014    },
3015    Accelerometer => { }, # up, back, left?  units of g
3016    AngularVelocity => { } # left, up, ccw?  units?
3017);
3018
3019# Kodak composite tags
3020%Image::ExifTool::Kodak::Composite = (
3021    GROUPS => { 2 => 'Camera' },
3022    DateCreated => {
3023        Groups => { 2 => 'Time' },
3024        Require => {
3025            0 => 'Kodak:YearCreated',
3026            1 => 'Kodak:MonthDayCreated',
3027        },
3028        ValueConv => '"$val[0]:$val[1]"',
3029    },
3030    WB_RGBLevels => {
3031        Require => {
3032            0 => 'KDC_IFD:WhiteBalance',
3033        },
3034        # indices of the following entries are KDC_IFD:WhiteBalance + 1
3035        Desire => {
3036            1 => 'WB_RGBLevelsAuto',
3037            2 => 'WB_RGBLevelsFluorescent',
3038            3 => 'WB_RGBLevelsTungsten',
3039            4 => 'WB_RGBLevelsDaylight',
3040            5 => 'WB_RGBLevels4',
3041            6 => 'WB_RGBLevels5',
3042            7 => 'WB_RGBLevelsShade',
3043        },
3044        ValueConv => '$val[$val[0] + 1]',
3045    },
3046    WB_RGBLevels2 => {
3047        Name => 'WB_RGBLevels',
3048        Require => {
3049            0 => 'KodakIFD:WhiteBalance',
3050            1 => 'WB_RGBMul0',
3051            2 => 'WB_RGBMul1',
3052            3 => 'WB_RGBMul2',
3053            4 => 'WB_RGBMul3',
3054            5 => 'WB_RGBCoeffs0',
3055            6 => 'WB_RGBCoeffs1',
3056            7 => 'WB_RGBCoeffs2',
3057            8 => 'WB_RGBCoeffs3',
3058        },
3059        # indices of the following entries are KDC_IFD:WhiteBalance + 1
3060        Desire => {
3061            9 => 'KodakIFD:ColorTemperature',
3062            10 => 'Kodak:WB_RGBLevels',
3063        },
3064        ValueConv => 'Image::ExifTool::Kodak::CalculateRGBLevels(@val)',
3065    },
3066);
3067
3068# add our composite tags
3069Image::ExifTool::AddCompositeTags('Image::ExifTool::Kodak');
3070
3071#------------------------------------------------------------------------------
3072# Process Kodak accelerometer data (ref PH)
3073# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
3074# Returns: 1 on success
3075sub ProcessPose($$$)
3076{
3077    my ($et, $dirInfo, $tagTablePtr) = @_;
3078    my $dataPt = $$dirInfo{DataPt};
3079    my $dirLen = length $$dataPt;
3080    my $ee = $et->Options('ExtractEmbedded');
3081    my ($i, $pos);
3082
3083    return 0 if $dirLen < 0x14;
3084    my $num = Get32u($dataPt, 0x10);
3085    return 0 if $dirLen < 0x14 + $num * 24;
3086
3087    $et->VerboseDir('Kodak pose', undef, $dirLen);
3088
3089    $$et{DOC_NUM} = 0;
3090    for ($i=0, $pos=0x14; $i<$num; ++$i, $pos+=24) {
3091        $et->HandleTag($tagTablePtr, AngularVelocity =>
3092            Image::ExifTool::GetRational64s($dataPt, $pos) . ' ' .
3093            Image::ExifTool::GetRational64s($dataPt, $pos + 8) . ' ' .
3094            Image::ExifTool::GetRational64s($dataPt, $pos + 16));
3095        $ee or $pos += $num * 24, last;
3096        ++$$et{DOC_NUM};
3097    }
3098    $$et{DOC_NUM} = 0;
3099
3100    return 1 if $dirLen < $pos + 0x10;
3101    $num = Get32u($dataPt, $pos + 0x0c);
3102    return 1 if $dirLen < $pos + 0x10 + $num * 24;
3103
3104    for ($i=0, $pos+=0x10; $i<$num; ++$i, $pos+=24) {
3105        $et->HandleTag($tagTablePtr, Accelerometer =>
3106            Image::ExifTool::GetRational64s($dataPt, $pos) . ' ' .
3107            Image::ExifTool::GetRational64s($dataPt, $pos + 8) . ' ' .
3108            Image::ExifTool::GetRational64s($dataPt, $pos + 16));
3109        $ee or $pos += $num * 24, last;
3110        ++$$et{DOC_NUM};
3111    }
3112    $$et{DOC_NUM} = 0;
3113    $ee or $et->Warn('Use the ExtractEmbedded option to extract all accelerometer data',3);
3114    return 1;
3115}
3116
3117#------------------------------------------------------------------------------
3118# Calculate RGB levels from associated tags (ref 3)
3119# Inputs: 0) KodakIFD:WhiteBalance, 1-4) WB_RGBMul0-3, 5-8) WB_RGBCoeffs0-3
3120#         9) (optional) KodakIFD:ColorTemperature, 10) (optional) Kodak:WB_RGBLevels
3121# Returns: WB_RGBLevels or undef
3122sub CalculateRGBLevels(@)
3123{
3124    return undef if $_[10]; # use existing software levels if they exist
3125    my $wbi = $_[0];
3126    return undef if $wbi < 0 or $wbi > 3;
3127    my @mul = split ' ', $_[$wbi + 1], 13; # (only use the first 12 coeffs)
3128    my @coefs = split ' ', ${$_[$wbi + 5]}; # (extra de-reference for Binary data)
3129    my $wbtemp100 = ($_[9] || 6500) / 100;
3130    return undef unless @mul >= 3 and @coefs >= 12;
3131    my ($i, $c, $n, $num, @cam_mul);
3132    for ($c=$n=0; $c<3; ++$c) {
3133        for ($num=$i=0; $i<4; ++$i) {
3134            $num += $coefs[$n++] * ($wbtemp100 ** $i);
3135        }
3136        $cam_mul[$c] = 2048 / ($num * $mul[$c]);
3137    }
3138    return join(' ', @cam_mul);
3139}
3140
3141#------------------------------------------------------------------------------
3142# Process Kodak textual TextualInfo
3143# Inputs: 0) ExifTool object ref, 1) dirInfo hash ref, 2) tag table ref
3144# Returns: 1 on success
3145sub ProcessKodakText($$$)
3146{
3147    my ($et, $dirInfo, $tagTablePtr) = @_;
3148    my $dataPt = $$dirInfo{DataPt};
3149    my $dirStart = $$dirInfo{DirStart} || 0;
3150    my $dirLen = $$dirInfo{DirLen} || length($$dataPt) - $dirStart;
3151    my $data = substr($$dataPt, $dirStart, $dirLen);
3152    $data =~ s/\0.*//s;     # truncate at null if it exists
3153    my @lines = split /[\n\r]+/, $data;
3154    my ($line, $success, @other, $tagInfo);
3155    $et->VerboseDir('Kodak Text');
3156    foreach $line (@lines) {
3157        if ($line =~ /(.*?):\s*(.*)/) {
3158            my ($tag, $val) = ($1, $2);
3159            if ($$tagTablePtr{$tag}) {
3160                $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
3161            } else {
3162                my $tagName = $tag;
3163                $tagName =~ s/([A-Z])\s+([A-Za-z])/${1}_\U$2/g;
3164                $tagName =~ s/([a-z])\s+([A-Za-z0-9])/${1}\U$2/g;
3165                $tagName =~ s/\s+//g;
3166                $tagName =~ s/[^-\w]+//g;   # delete remaining invalid characters
3167                $tagName = 'NoName' unless $tagName;
3168                $tagInfo = { Name => $tagName };
3169                AddTagToTable($tagTablePtr, $tag, $tagInfo);
3170            }
3171            $et->HandleTag($tagTablePtr, $tag, $val, TagInfo => $tagInfo);
3172            $success = 1;
3173        } else {
3174            # strip off leading/trailing white space and ignore blank lines
3175            push @other, $1 if $line =~ /^\s*(\S.*?)\s*$/;
3176        }
3177    }
3178    if ($success) {
3179        if (@other) {
3180            $tagInfo = $et->GetTagInfo($tagTablePtr, '_other_info');
3181            $et->FoundTag($tagInfo, \@other);
3182        }
3183    } else {
3184        $et->Warn("Can't parse Kodak TextualInfo data", 1);
3185    }
3186    return $success;
3187}
3188
3189#------------------------------------------------------------------------------
3190# Process Kodak IFD (with leading byte order mark)
3191# Inputs: 0) ExifTool object ref, 1) dirInfo hash ref, 2) tag table ref
3192# Returns: 1 on success, otherwise returns 0 and sets a Warning
3193sub ProcessKodakIFD($$$)
3194{
3195    my ($et, $dirInfo, $tagTablePtr) = @_;
3196    my $dirStart = $$dirInfo{DirStart} || 0;
3197    return 1 if $dirStart <= 0 or $dirStart + 2 > $$dirInfo{DataLen};
3198    my $byteOrder = substr(${$$dirInfo{DataPt}}, $dirStart, 2);
3199    unless (Image::ExifTool::SetByteOrder($byteOrder)) {
3200        $et->Warn("Invalid Kodak $$dirInfo{Name} directory");
3201        return 1;
3202    }
3203    $$dirInfo{DirStart} += 2;   # skip byte order mark
3204    $$dirInfo{DirLen} -= 2;
3205    if ($$et{HTML_DUMP}) {
3206        my $base = $$dirInfo{Base} + $$dirInfo{DataPos};
3207        $et->HDump($dirStart+$base, 2, "Byte Order Mark");
3208    }
3209    return Image::ExifTool::Exif::ProcessExif($et, $dirInfo, $tagTablePtr);
3210}
3211
3212#------------------------------------------------------------------------------
3213# Write Kodak IFD (with leading byte order mark)
3214# Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref
3215# Returns: Exif data block (may be empty if no Exif data) or undef on error
3216sub WriteKodakIFD($$$)
3217{
3218    my ($et, $dirInfo, $tagTablePtr) = @_;
3219    my $dirStart = $$dirInfo{DirStart} || 0;
3220    return '' if $dirStart <= 0 or $dirStart + 2 > $$dirInfo{DataLen};
3221    my $byteOrder = substr(${$$dirInfo{DataPt}}, $dirStart, 2);
3222    return '' unless Image::ExifTool::SetByteOrder($byteOrder);
3223    $$dirInfo{DirStart} += 2;   # skip byte order mark
3224    $$dirInfo{DirLen} -= 2;
3225    my $buff = Image::ExifTool::Exif::WriteExif($et, $dirInfo, $tagTablePtr);
3226    return $buff unless defined $buff and length $buff;
3227    # apply one-time fixup for length of byte order mark
3228    if ($$dirInfo{Fixup}) {
3229        $dirInfo->{Fixup}->{Shift} += 2;
3230        $$dirInfo{Fixup}->ApplyFixup(\$buff);
3231        delete $$dirInfo{Fixup};
3232    }
3233    return Image::ExifTool::GetByteOrder() . $buff;
3234}
3235
32361;  # end
3237
3238__END__
3239
3240=head1 NAME
3241
3242Image::ExifTool::Kodak - Kodak EXIF maker notes and APP3 "Meta" tags
3243
3244=head1 SYNOPSIS
3245
3246This module is loaded automatically by Image::ExifTool when required.
3247
3248=head1 DESCRIPTION
3249
3250This module contains definitions required by Image::ExifTool to
3251interpret Kodak maker notes EXIF meta information.
3252
3253=head1 AUTHOR
3254
3255Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
3256
3257This library is free software; you can redistribute it and/or modify it
3258under the same terms as Perl itself.
3259
3260=head1 REFERENCES
3261
3262=over 4
3263
3264=item L<Image::MetaData::JPEG|Image::MetaData::JPEG>
3265
3266=item L<http://www.ozhiker.com/electronics/pjmt/jpeg_info/meta.html>
3267
3268=item L<http://www.cybercom.net/~dcoffin/dcraw/>
3269
3270=item (...plus lots of testing with my daughter's CX4200!)
3271
3272=back
3273
3274=head1 SEE ALSO
3275
3276L<Image::ExifTool::TagNames/Kodak Tags>,
3277L<Image::ExifTool(3pm)|Image::ExifTool>
3278
3279=cut
3280