Ignore:
Timestamp:
2021-02-26T19:39:51+13:00 (3 years ago)
Author:
anupama
Message:

Committing the improvements to EmbeddedMetaPlugin's processing of Keywords vs other metadata fields. Keywords were literally stored as arrays of words rather than phrases in PDFs (at least in Diego's sample PDF), whereas other meta fields like Subjects and Creators stored them as arrays of phrases. To get both to work, Kathy updated EXIF to a newer version, to retrieve the actual EXIF values stored in the PDF. And Kathy and Dr Bainbridge came up with a new option that I added called apply_join_before_split_to_metafields that's a regex which can list the metadata fields to apply the join_before_split to and whcih previously always got applied to all metadata fields. Now it's applied to any *Keywords metafields by default, as that's the metafield we have experience of that behaves differently to the others, as it stores by word instead of phrases. Tested on Diego's sample PDF. Diego has double-checked it to works on his sample PDF too, setting the split char to ; and turning on the join_before_split and leaving apply_join_before_split_to_metafields at its default of .*Keywords. File changes are strings.properties for the tooltip, the plugin introducing the option and working with it and Kathy's EXIF updates affecting cpan/File and cpan/Image.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Panasonic.pm

    r24107 r34921  
    1515#              10) http://bretteville.com/pdfs/M8Metadata_v2.pdf
    1616#              11) http://www.digital-leica.com/lens_codes/index.html
     17#                  (now https://www.l-camera-forum.com/leica-news/leica-lens-codes/)
    1718#              12) Joerg - http://www.cpanforum.com/threads/11602 (LX3 firmware 2.0)
    1819#              13) Michael Byczkowski private communication (Leica M9)
    1920#              14) Carl Bretteville private communication (M9)
    2021#              15) Zdenek Mihula private communication (TZ8)
     22#              16) Olaf Ulrich private communication
     23#              17) https://exiftool.org/forum/index.php/topic,4922.0.html
     24#              18) Thomas Modes private communication (G6)
     25#              19) https://exiftool.org/forum/index.php/topic,5533.0.html
     26#              20) Bernd-Michael Kemper private communication (DMC-GX80/85)
     27#              21) Klaus Homeister forum post
     28#              22) Daniel Beichl private communication (G9)
     29#              23) Tim Gray private communication (M10 Monochrom)
    2130#              JD) Jens Duttke private communication (TZ3,FZ30,FZ50)
    2231#------------------------------------------------------------------------------
     
    2534
    2635use strict;
    27 use vars qw($VERSION);
     36use vars qw($VERSION %leicaLensTypes);
    2837use Image::ExifTool qw(:DataAccess :Utils);
    2938use Image::ExifTool::Exif;
    3039
    31 $VERSION = '1.59';
    32 
    33 sub ProcessPanasonicType2($$$);
     40$VERSION = '2.14';
     41
     42sub ProcessLeicaLEIC($$$);
    3443sub WhiteBalanceConv($;$$);
    3544
    3645# Leica lens types (ref 10)
    37 my %leicaLensType = (
     46%leicaLensTypes = (
    3847    OTHER => sub {
    3948        my ($val, $inv, $conv) = @_;
     
    4251    },
    4352    Notes => q{
    44         Entries with 2 numbers give the lower 2 bits of the LensType value which are
    45         used to identify certain manually coded lenses on the M9, or the focal
    46         length of some multi-focal lenses.
     53        the LensType value is obtained by splitting the stored value into 2
     54        integers:  The stored value divided by 4, and its lower 2 bits.  The second
     55        number is used only if necessary to identify certain manually coded lenses
     56        on the M9, or the focal length of some multi-focal lenses.
    4757    },
    4858    # All M9 codes (two numbers: first the LensID then the lower 2 bits)
     
    5565    # frame selector.  The bits are zero for uncoded lenses when manually coding
    5666    # from the menu on the M9. - PH
     67    # Frame selector bits (from ref 10, M8):
     68    #   1 => '28/90mm frame lines engaged',
     69    #   2 => '24/35mm frame lines engaged',
     70    #   3 => '50/75mm frame lines engaged',
    5771    '0 0' => 'Uncoded lens',
    5872#
     
    6983    9 => 'Elmarit-M 135mm f/2.8 (I/II)',    # 11829
    7084    '9 0' => 'Apo-Telyt-M 135mm f/3.4',     # 11889
     85    11 => 'Summaron-M 28mm f/5.6',          # ? (ref IB)
     86    12 => 'Thambar-M 90mm f/2.2',           # ? (ref IB)
    7187    16 => 'Tri-Elmar-M 16-18-21mm f/4 ASPH.',# 11626
    7288    '16 1' => 'Tri-Elmar-M 16-18-21mm f/4 ASPH. (at 16mm)',
     
    94110    '39 0' => 'Tele-Elmar-M 135mm f/4 (II)',# 11861
    95111    40 => 'Macro-Adapter M',                # 14409
     112    41 => 'Apo-Summicron-M 50mm f/2 ASPH.', #IB
     113    '41 3' => 'Apo-Summicron-M 50mm f/2 ASPH.', #16
    96114    42 => 'Tri-Elmar-M 28-35-50mm f/4 ASPH.',# 11625
    97115    '42 1' => 'Tri-Elmar-M 28-35-50mm f/4 ASPH. (at 28mm)',
     
    106124    49 => 'Noctilux-M 50mm f/0.95 ASPH.',   # ? (ref 11)
    107125    50 => 'Elmar-M 24mm f/3.8 ASPH.',       # ? (ref 11)
    108     52 => 'Super-Elmar-M 18mm f/3.8 ASPH.', # ? (ref PH/11)
     126    51 => 'Super-Elmar-M 21mm f/3.4 Asph',  # ? (ref 16, frameSelectorBits=1)
     127    '51 2' => 'Super-Elmar-M 14mm f/3.8 Asph', # ? (ref 16)
     128    52 => 'Apo-Telyt-M 18mm f/3.8 ASPH.', # ? (ref PH/11)
     129    53 => 'Apo-Telyt-M 135mm f/3.4',        #IB
     130    '53 2' => 'Apo-Telyt-M 135mm f/3.4',    #16
     131    '53 3' => 'Apo-Summicron-M 50mm f/2 (VI)', #LR
     132    58 => 'Noctilux-M 75mm f/1.25 ASPH.',   # ? (ref IB)
    109133);
    110134
     
    149173    49 => 3, # (NC)
    150174    50 => 2, # (NC)
     175    51 => 1, # or 2 (ref 16)
    151176    52 => 3,
     177    53 => 2, #16
    152178);
    153179
     
    198224    45 => 'My Color', #PH (GF1)
    199225    46 => 'Photo Frame', #PH (FS7)
     226    48 => 'Movie', #PH (GM1)
     227    # 49 - seen for FS4 (snow?)
    200228    51 => 'HDR', #12
     229    52 => 'Peripheral Defocus', #Horst Wandres
     230    55 => 'Handheld Night Shot', #PH (FZ47)
     231    57 => '3D', #PH (3D1)
     232    59 => 'Creative Control', #PH (FZ47)
     233    60 => 'Intelligent Auto Plus', #20
     234    62 => 'Panorama', #17
     235    63 => 'Glass Through', #17
     236    64 => 'HDR', #17
     237    66 => 'Digital Filter', #PH (GF5 "Impressive Art", "Cross Process", "Color Select", "Star")
     238    67 => 'Clear Portrait', #18
     239    68 => 'Silky Skin', #18
     240    69 => 'Backlit Softness', #18
     241    70 => 'Clear in Backlight', #18
     242    71 => 'Relaxing Tone', #18
     243    72 => "Sweet Child's Face", #18
     244    73 => 'Distinct Scenery', #18
     245    74 => 'Bright Blue Sky', #18
     246    75 => 'Romantic Sunset Glow', #18
     247    76 => 'Vivid Sunset Glow', #18
     248    77 => 'Glistening Water', #18
     249    78 => 'Clear Nightscape', #18
     250    79 => 'Cool Night Sky', #18
     251    80 => 'Warm Glowing Nightscape', #18
     252    81 => 'Artistic Nightscape', #18
     253    82 => 'Glittering Illuminations', #18
     254    83 => 'Clear Night Portrait', #18
     255    84 => 'Soft Image of a Flower', #18
     256    85 => 'Appetizing Food', #18
     257    86 => 'Cute Dessert', #18
     258    87 => 'Freeze Animal Motion', #18
     259    88 => 'Clear Sports Shot', #18
     260    89 => 'Monochrome', #18
     261    90 => 'Creative Control', #18
     262    92 => 'Handheld Night Shot', #forum11523
    201263);
    202264
     
    209271        Name => 'ImageQuality',
    210272        Writable => 'int16u',
    211         PrintConv => {
     273        Notes => 'quality of the main image, which may be in a different file',
     274        PrintConv => {
     275            1 => 'TIFF', #PH (FZ20)
    212276            2 => 'High',
    213277            3 => 'Normal',
     278            # 5 - seen this for 1920x1080, 30fps SZ7 video - PH
    214279            6 => 'Very High', #3 (Leica)
    215             7 => 'Raw', #3 (Leica)
     280            7 => 'RAW', #3 (Leica)
    216281            9 => 'Motion Picture', #PH (LZ6)
     282            11 => 'Full HD Movie', #PH (V-LUX)
     283            12 => '4k Movie', #PH (V-LUX)
    217284        },
    218285    },
     
    245312            8 => 'Flash',
    246313            10 => 'Black & White', #3 (Leica)
    247             11 => 'Manual', #PH (FZ8)
     314            11 => 'Manual 2', #PH (FZ8)
    248315            12 => 'Shade', #PH (FS7)
     316            13 => 'Kelvin', #PeterK (NC)
     317            14 => 'Manual 3', #forum9296
     318            15 => 'Manual 4', #forum9296
     319            # also seen 18,26 (forum9296)
     320            19 => 'Auto (cool)', #PH (Leica C-Lux)
    249321        },
    250322    },
     
    257329            4 => 'Auto, Focus button', #4
    258330            5 => 'Auto, Continuous', #4
    259             # have seens 6 for GF1 - PH
     331            6 => 'AF-S', #18 (also seen for GF1 - PH)
     332            7 => 'AF-C', #18
     333            8 => 'AF-F', #18 (auto-focus flexible)
    260334        },
    261335    },
     
    279353                '0 1'   => '9-area', # (FS7)
    280354                '0 16'  => '3-area (high speed)', # (FZ8)
     355                '0 23'  => '23-area', #PH (FZ47,NC)
     356                '0 49'  => '49-area', #20
     357                '0 225' => '225-area', #22
    281358                '1 0'   => 'Spot Focusing', # (FZ8)
    282359                '1 1'   => '5-area', # (FZ8)
     
    284361                '16 0'  => '1-area', # (FZ8)
    285362                '16 16' => '1-area (high speed)', # (FZ8)
    286                 '32 0'  => 'Auto or Face Detect', # (Face Detect for FS7, Auto is DMC-L1 guess)
     363                # '32 0' is Face Detect for FS7, and Face Detect or Focus Tracking
     364                # for the DMC-FZ200 (ref 17), and Auto is DMC-L1 guess,
     365                '32 0'  => 'Tracking',
    287366                '32 1'  => '3-area (left)?', # (DMC-L1 guess)
    288367                '32 2'  => '3-area (center)?', # (DMC-L1 guess)
    289368                '32 3'  => '3-area (right)?', # (DMC-L1 guess)
    290369                '64 0'  => 'Face Detect',
     370                '64 1' => 'Face Detect (animal detect on)', #forum11194
     371                '64 2' => 'Face Detect (animal detect off)', #forum11194
     372                '128 0' => 'Pinpoint focus', #18/forum11194
     373                '240 0' => 'Tracking', #22
    291374            },
    292375        },
     
    296379        Writable => 'int16u',
    297380        PrintConv => {
    298             2 => 'On, Mode 1',
     381            2 => 'On, Optical',
    299382            3 => 'Off',
    300383            4 => 'On, Mode 2',
    301             # GF1 also has a mode 3
     384            5 => 'On, Optical Panning', #18
     385            # GF1 also has a "Mode 3" - PH
     386            6 => 'On, Body-only', #PH (GX7, sensor shift?)
     387            7 => 'On, Body-only Panning', #forum11194
     388            9 => 'Dual IS', #20
     389            10 => 'Dual IS Panning', #forum11194
     390            11 => 'Dual2 IS', #forum9298
     391            12 => 'Dual2 IS Panning', #forum11194
    302392        },
    303393    },
     
    321411        Name => 'Audio',
    322412        Writable => 'int16u',
    323         PrintConv => { 1 => 'Yes', 2 => 'No' },
     413        PrintConv => {
     414            1 => 'Yes',
     415            2 => 'No',
     416            3 => 'Stereo', #PH (NC)
     417        },
    324418    },
    325419    0x21 => { #2
     
    342436        Format => 'int16s',
    343437        Writable => 'int16s',
     438        ValueConv => '$val / 3', #17 (older models may not have factor of 3? - PH)
     439        ValueConvInv => '$val * 3',
     440        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     441        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
    344442    },
    345443    0x25 => { #PH
     
    362460        Writable => 'undef',
    363461    },
    364     # 0x27 - values: 0 (LZ6,FX10K)
     462    0x27 => {
     463        Name => 'VideoFrameRate',
     464        Writable => 'int16u',
     465        Notes => 'only valid for older models',
     466        PrintConv => {
     467            OTHER => sub { shift },
     468            0 => 'n/a',
     469        },
     470    },
    365471    0x28 => {
    366472        Name => 'ColorEffect',
     
    374480            5 => 'Sepia',
    375481            6 => 'Happy', #PH (FX70) (yes, really. you wouldn't want sad colors now would you?)
     482            8 => 'Vivid', #PH (SZ3)
    376483        },
    377484    },
     
    397504            my $m = int($val / 60);
    398505            $val -= $m * 60;
    399             my $s = int($val);
    400             my $f = 100 * ($val - int($val));
    401             return sprintf("%s%.2d:%.2d:%.2d.%.2d",$str,$h,$m,$s,$f);
     506            my $ss = sprintf('%05.2f', $val);
     507            if ($ss >= 60) {
     508                $ss = '00.00';
     509                ++$m >= 60 and $m -= 60, ++$h;
     510            }
     511            return sprintf("%s%.2d:%.2d:%s",$str,$h,$m,$ss);
    402512        },
    403513        PrintConvInv => sub {
     
    419529            0 => 'Off',
    420530            1 => 'On', #PH (TZ5) [was "Low/High Quality" from ref 4]
    421             2 => 'Infinite',
     531            2 => 'Auto Exposure Bracketing (AEB)', #17
     532            3 => 'Focus Bracketing', #forum11194
    422533            4 => 'Unlimited', #PH (TZ5)
     534            8 => 'White Balance Bracketing', #18
     535            17 => 'On (with flash)', #forum5597
     536            18 => 'Aperture Bracketing', #forum11194
    423537        },
    424538    },
     
    430544        {
    431545            Name => 'ContrastMode',
    432             Condition => '$$self{Model} !~ /^DMC-(FX10|G1|L1|L10|LC80|GF1|TZ10|ZS7)$/',
     546            Condition => '$$self{Model} !~ /^DMC-(FX10|G1|L1|L10|LC80|GF\d+|G2|TZ10|ZS7)$/',
    433547            Flags => 'PrintHex',
    434548            Writable => 'int16u',
     
    439553            },
    440554            PrintConv => {
    441                 0 => 'Normal',
    442                 1 => 'Low',
    443                 2 => 'High',
    444                 # 3 - observed with LZ6 and TZ5 in Fireworks mode - PH
    445                 # 5 - observed with FX01, FX40 and FP8 (EXIF contrast "Normal") - PH
    446                 6 => 'Medium Low', #PH (FZ18)
    447                 7 => 'Medium High', #PH (FZ18)
     555                0x00 => 'Normal',
     556                0x01 => 'Low',
     557                0x02 => 'High',
     558                # 0x03 - observed with LZ6 and TZ5 in Fireworks mode
     559                #        and GX7 in Fantasy/Retro/OldDays/HighKey - PH
     560                # 0x04 - observed in MP4 movie with GM1 (EXIF and 0x39 Contrast "Normal") - PH
     561                0x05 => 'Normal 2', #forum1194
     562                0x06 => 'Medium Low', #PH (FZ18)
     563                0x07 => 'Medium High', #PH (FZ18)
     564                # 0x08 - GX7 in DynamicMonochrome mode
     565                0x0d => 'High Dynamic', #PH (FZ47 in ?)
     566                # 0x13 - seen for LX100 (PH)
     567                0x18 => 'Dynamic Range (film-like)', #forum11194
     568                0x2e => 'Match Filter Effects Toy', #forum11194
     569                0x37 => 'Match Photo Style L. Monochrome', #forum11194
    448570                # DMC-LC1 values:
    449571                0x100 => 'Low',
     
    453575        },{
    454576            Name => 'ContrastMode',
    455             Condition => '$$self{Model} eq "DMC-GF1"',
    456             Notes => 'these values are used by the GF1',
     577            Condition => '$$self{Model} =~ /^DMC-(GF\d+|G2)$/',
     578            Notes => 'these values are used by the G2, GF1, GF2, GF3, GF5 and GF6',
    457579            Writable => 'int16u',
    458             PrintConv => {
     580            PrintConv => { # (decoded for GF1 unless otherwise noted)
    459581                0 => '-2',
    460582                1 => '-1',
     
    463585                4 => '+2',
    464586                # Note: Other Contrast tags will be "Normal" in any of these modes:
    465                 7 => 'Nature (Color Film)',
    466                 12 => 'Smooth (Color Film) or Pure (My Color)',
    467                 17 => 'Dynamic (B&W Film)',
    468                 22 => 'Smooth (B&W Film)',
    469                 27 => 'Dynamic (Color Film)',
    470                 32 => 'Vibrant (Color Film) or Expressive (My Color)',
     587                5 => 'Normal 2', # 5 - seen for Portrait (FX80) and Normal (GF6)
     588                7 => 'Nature (Color Film)', # (GF1,G2; GF3 "Miniature")
     589                9 => 'Expressive', #(GF3)
     590                12 => 'Smooth (Color Film) or Pure (My Color)', #(GF1,G2 "Smooth Color")
     591                17 => 'Dynamic (B&W Film)', #(GF1,G2)
     592                22 => 'Smooth (B&W Film)', #(GF1,G2)
     593                25 => 'High Dynamic', #(GF5)
     594                26 => 'Retro', #(GF5)
     595                27 => 'Dynamic (Color Film)', #(GF1,G2) (GF3 "High Key")
     596                28 => 'Low Key', #(GF5)
     597                29 => 'Toy Effect', #(GF5)
     598                32 => 'Vibrant (Color Film) or Expressive (My Color)', # (GF1; G2 "Vibrant"; GF2,GF5 "Expressive")
    471599                33 => 'Elegant (My Color)',
    472                 37 => 'Nostalgic (Color Film)',
    473                 41 => 'Dynamic Art (My Color)',
     600                37 => 'Nostalgic (Color Film)', # (GF1,G2; GF5 "Sepia")
     601                41 => 'Dynamic Art (My Color)', # (GF5 "High Key")
    474602                42 => 'Retro (My Color)',
     603                45 => 'Cinema', #(GF2)
     604                47 => 'Dynamic Mono', #(GF5)
     605                50 => 'Impressive Art', #(GF5)
     606                51 => 'Cross Process', #(GF5)
     607                100 => 'High Dynamic 2', #Exiv2 (G6)
     608                101 => 'Retro 2', #Exiv2 (G6)
     609                102 => 'High Key 2', #Exiv2 (G6)
     610                103 => 'Low Key 2', #Exiv2 (G6)
     611                104 => 'Toy Effect 2', #Exiv2 (G6)
     612                107 => 'Expressive 2', #(GF6)
     613                112 => 'Sepia', #Exiv2 (G6)
     614                117 => 'Miniature', #Exiv2 (G6)
     615                122 => 'Dynamic Monochrome', #(GF6)
     616                127 => 'Old Days', #Exiv2 (G6)
     617                132 => 'Dynamic Monochrome 2', #Exiv2 (G6)
     618                135 => 'Impressive Art 2', #Exiv2 (G6)
     619                136 => 'Cross Process 2', #Exiv2 (G6)
     620                137 => 'Toy Pop', #Exiv2 (G6)
     621                138 => 'Fantasy', #Exiv2 (G6)
     622                256 => 'Normal 3', #Exiv2 (G6)
     623                272 => 'Standard', #Exiv2 (G6)
     624                288 => 'High', #Exiv2 (G6)
     625                # more new modes for GF6:
     626                # ? => 'Old Days',
     627                # ? => 'Toy Pop',
     628                # ? => 'Bleach Bypass',
     629                # ? => 'Fantasy',
     630                # ? => 'Star Filter',
     631                # ? => 'One Point Color',
     632                # ? => 'Sunshine',
    475633            },
    476634        },{
     
    494652        Name => 'NoiseReduction',
    495653        Writable => 'int16u',
     654        Notes => 'the encoding for this value is not consistent between models',
    496655        PrintConv => {
    497656            0 => 'Standard',
     
    500659            3 => 'Lowest (-2)', #JD
    501660            4 => 'Highest (+2)', #JD
     661            5 => '+5', #PH (NC)
     662            6 => '+6', # (NC) seen for DC-S1/S1R (IB)
     663            65531 => '-5', # LX100/FZ2500 "NR1" test shots at imaging-resource (PH)
     664            65532 => '-4',
     665            65533 => '-3',
     666            65534 => '-2',
     667            65535 => '-1',
    502668        },
    503669    },
     
    506672        Writable => 'int16u',
    507673        PrintConv => {
     674            0 => 'Off (0)', #forum11529
    508675            1 => 'Off',
    509676            2 => '10 s',
    510677            3 => '2 s',
     678            4 => '10 s / 3 pictures', #17
     679            258 => '2 s after shutter pressed', #forum11194
     680            266 => '10 s after shutter pressed', #forum11194
     681            778 => '3 photos after 10 s', #forum11194
    511682        },
    512683    },
     
    576747    },
    577748    # 0x37 - values: 0,1,2 (LZ6, 0 for movie preview); 257 (FX10K); 0,256 (TZ5, 0 for movie preview)
    578     # 0x38 - values: 0,1,2 (LZ6, same as 0x37); 1,2 (FX10K); 0,256 (TZ5, 0 for movie preview)
     749    #        --> may indicate battery power (forum11388)
     750    0x38 => { #forum11388
     751        Name => 'BatteryLevel',
     752        Writable => 'int16u',
     753        PrintConv => {
     754            1 => 'Full',
     755            2 => 'Medium',
     756            3 => 'Low',
     757            4 => 'Near Empty',
     758            7 => 'Near Full',
     759            8 => 'Medium Low',
     760            256 => 'n/a',
     761        },
     762    },
    579763    0x39 => { #7 (L1/L10)
    580764        Name => 'Contrast',
     
    599783    0x3c => { #PH
    600784        Name => 'ProgramISO', # (maybe should rename this ISOSetting?)
    601         Writable => 'int16u',
    602         PrintConv => {
    603             OTHER => sub { return shift },
     785        Writable => 'int16u', # (new models store a long here)
     786        PrintConv => {
     787            OTHER => sub { shift },
    604788            65534 => 'Intelligent ISO', #PH (FS7)
    605789            65535 => 'n/a',
     790            -1 => 'n/a',
    606791        },
    607792    },
    608793    0x3d => { #PH
    609         Name => 'AdvancedSceneMode',
    610         Writable => 'int16u',
    611         # values for the FZ28 (SceneMode/AdvancedSceneMode, "*"=add mode name) - PH:
    612         # Portrait: 2/1=Normal*, 24/1=Soft Skin, 2/2=Outdoor*, 2/3=Indoor*, 2/4=Creative*
    613         # Scenery: 3/1=Normal*, 3/2=Nature, 3/3=Architecture, 3/4=Creative*
    614         # Sports: 4/1=Normal*, 4/2=Outdoor*, 4/3=Indoor*, 4/4=Creative*
    615         # Night Scenery: 5/1=Night Portrait, 21/1=*, 21/2=Illuminations, 21/4=Creative*
    616         # Macro (Close-up): 9/2=Flower, 22/1=Food, 9/3=Objects, 9/4=Creative*
    617         # - have seen value of 5 for TZ5 (Macro) and FS20 (Scenery and Intelligent Auto)
    618         #   --> I'm guessing this is "Auto" - PH
    619         # - values for HDR mode (ref 12): 1=Standard, 2=Art, 3=B&W
    620         PrintConv => {
    621             1 => 'Normal',
    622             2 => 'Outdoor/Illuminations/Flower/HDR Art',
    623             3 => 'Indoor/Architecture/Objects/HDR B&W',
    624             4 => 'Creative',
    625             5 => 'Auto',
    626             7 => 'Expressive', #(GF1)
    627             8 => 'Retro', #(GF1)
    628             9 => 'Pure', #(GF1)
    629             10 => 'Elegant', #(GF1)
    630             12 => 'Monochrome', #(GF1)
    631             13 => 'Dynamic Art', #(GF1)
    632             14 => 'Silhouette', #(GF1)
    633         },
     794        Name => 'AdvancedSceneType',
     795        Writable => 'int16u',
     796        Notes => 'used together with SceneMode to derive Composite AdvancedSceneMode',
     797        # see forum11194 for more info
    634798    },
    635799    0x3e => { #PH (TZ5/FS7)
     
    659823        Writable => 'int16u',
    660824        PrintConv => {
    661             0 => 'n/a', #PH (ie. FZ100 "Photo Frame" ShootingMode)
     825            0 => 'n/a', #PH (eg. FZ100 "Photo Frame" ShootingMode)
    662826            1 => 'Standard (color)',
    663827            2 => 'Dynamic (color)',
     
    669833            # 8 => 'My Film 1'? (from owner manual)
    670834            # 9 => 'My Film 2'?
    671             10 => 'Nostalgic', # GH1
    672             11 => 'Vibrant', # GH1
     835            10 => 'Nostalgic', #(GH1)
     836            11 => 'Vibrant', #(GH1)
    673837            # 12 => 'Multi Film'? (in the GH1 specs)
    674838        },
    675839    },
    676     # 0x43 - int16u: 2,3
    677     # 0x44 - int16u: 0,2500
    678     # 0x45 - int16u: 0
     840    0x43 => { #forum9369
     841        Name => 'JPEGQuality',
     842        Writable => 'int16u',
     843        PrintConv => {
     844            0 => 'n/a (Movie)',
     845            2 => 'High',
     846            3 => 'Standard',
     847            6 => 'Very High',
     848            255 => 'n/a (RAW only)',
     849        },
     850    },
     851    0x44 => {
     852        Name => 'ColorTempKelvin',
     853        Format => 'int16u',
     854    },
     855    0x45 => { #19
     856        Name => 'BracketSettings',
     857        Writable => 'int16u',
     858        PrintConv => {
     859            0 => 'No Bracket',
     860            1 => '3 Images, Sequence 0/-/+',
     861            2 => '3 Images, Sequence -/0/+',
     862            3 => '5 Images, Sequence 0/-/+',
     863            4 => '5 Images, Sequence -/0/+',
     864            5 => '7 Images, Sequence 0/-/+',
     865            6 => '7 Images, Sequence -/0/+',
     866        },
     867    },
    679868    0x46 => { #PH/JD
    680         Name => 'WBAdjustAB',
     869        Name => 'WBShiftAB',
    681870        Format => 'int16s',
    682871        Writable => 'int16u',
     
    684873    },
    685874    0x47 => { #PH/JD
    686         Name => 'WBAdjustGM',
     875        Name => 'WBShiftGM',
    687876        Format => 'int16s',
    688877        Writable => 'int16u',
    689878        Notes => 'positive is a shift toward green',
    690879    },
    691     # 0x48 - int16u: 0
    692     # 0x49 - int16u: 2
     880    0x48 => { #17
     881        Name => 'FlashCurtain',
     882        Writable => 'int16u',
     883        PrintConv => {
     884            0 => 'n/a',
     885            1 => '1st',
     886            2 => '2nd',
     887        },
     888    },
     889    0x49 => { #19
     890        Name => 'LongExposureNoiseReduction', # (indicates availability, forum11194)
     891        Writable => 'int16u',
     892        PrintConv => {
     893            1 => 'Off',
     894            2 => 'On'
     895        }
     896    },
    693897    # 0x4a - int16u: 0
    694898    0x4b => { #PH
     
    723927        Name => 'LensType',
    724928        Writable => 'string',
     929        ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
     930        ValueConvInv => '$val',
    725931    },
    726932    0x52 => { #7 (DMC-L1)
    727933        Name => 'LensSerialNumber',
    728934        Writable => 'string',
     935        ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
     936        ValueConvInv => '$val',
    729937    },
    730938    0x53 => { #7 (DMC-L1)
    731939        Name => 'AccessoryType',
    732940        Writable => 'string',
    733     },
    734     # 0x54 - string[14]: "0000000"
    735     # 0x55 - int16u: 1
     941        ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
     942        ValueConvInv => '$val',
     943    },
     944    0x54 => { #19
     945        Name => 'AccessorySerialNumber',
     946        Writable => 'string',
     947        ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
     948        ValueConvInv => '$val',
     949    },
     950    # 0x55 - int16u: 1 (see forum9372)
    736951    # 0x57 - int16u: 0
    737952    0x59 => { #PH (FS7)
     
    763978        },
    764979    },
    765     # 0x5e,0x5f,0x60 - undef[4]
     980    # 0x5e,0x5f - undef[4]
     981    0x60 => { #18
     982        Name => 'LensFirmwareVersion',
     983        Writable => 'undef',
     984        Format => 'int8u',
     985        Count => 4,
     986        PrintConv => '$val=~tr/ /./; $val',
     987        PrintConvInv => '$val=~tr/./ /; $val',
     988    },
    766989    0x61 => { #PH
    767990        Name => 'FaceRecInfo',
     
    8161039    },
    8171040    # 0x6c - int8u: 1
    818     0x6d => { #PH (ZS7)
     1041    0x6d => { #PH (ZS7) (also see forum5997)
    8191042        Name => 'City', # (City/Town)
    8201043        Groups => { 2 => 'Location' },
    8211044        Format => 'string',
    8221045        Writable => 'undef', # (Count 72)
     1046        Notes => 'City/Town as stored by some models, or County/Township for others',
    8231047    },
    8241048    # 0x6e - int8u: 1
     
    8431067    },
    8441068    # 0x71 - undef[128] (maybe text stamp text?)
    845     # 0x72,0x73,0x74,0x75,0x76,0x77,0x78: 0
     1069    0x77 => { #18
     1070        Name => 'BurstSpeed',
     1071        Writable => 'int16u',
     1072        Notes => 'images per second',
     1073    },
     1074    # 0x72,0x73,0x74,0x75,0x77,0x78: 0
     1075    # 0x76: 0, (3 for G6 with HDR on, ref 18)
     1076    0x76 => { #18/21
     1077        Name => 'HDRShot',
     1078        Writable => 'int16u',
     1079        PrintConv => { 0 => 'Off', 3 => 'On' },
     1080    },
    8461081    0x79 => { #PH (GH2)
    8471082        Name => 'IntelligentD-Range',
     
    8551090    },
    8561091    # 0x7a,0x7b: 0
     1092    0x7c => { #18
     1093        Name => 'ClearRetouch',
     1094        Writable => 'int16u',
     1095        PrintConv => { 0 => 'Off', 1 => 'On' },
     1096    },
     1097    0x80 => { #forum5997 (seen garbage here for SZ5 - PH)
     1098        Name => 'City2', # (City/Town/Village)
     1099        Groups => { 2 => 'Location' },
     1100        Format => 'string',
     1101        Writable => 'undef', # (Count 72)
     1102        Notes => 'City/Town/Village as stored by some models',
     1103    },
     1104    # 0x81 - undef[72]: "---"
     1105    # 0x82 - undef[72]: "---"
     1106    # 0x83 - undef[72]: "---"
     1107    # 0x84 - undef[72]: "---"
     1108    # 0x85 - undef[128]: "---"
     1109    0x86 => { #http://dev.exiv2.org/issues/825
     1110        Name => 'ManometerPressure',
     1111        Writable => 'int16u',
     1112        RawConv => '$val==65535 ? undef : $val',
     1113        ValueConv => '$val / 10',
     1114        ValueConvInv => '$val * 10',
     1115        PrintConv => 'sprintf("%.1f kPa",$val)',
     1116        PrintConvInv => '$val=~s/ ?kPa//i; $val',
     1117    },
     1118    0x89 => {
     1119        Name => 'PhotoStyle',
     1120        Writable => 'int16u',
     1121        PrintConv => {
     1122            0 => 'Auto',
     1123            1 => 'Standard or Custom',
     1124            2 => 'Vivid',
     1125            3 => 'Natural',
     1126            4 => 'Monochrome',
     1127            5 => 'Scenery',
     1128            6 => 'Portrait',
     1129            8 => 'Cinelike D', #forum11194
     1130            9 => 'Cinelike V', #forum11194
     1131            11 => 'L. Monochrome', #forum11194
     1132            15 => 'L. Monochrome D', #forum11194
     1133        },
     1134    },
     1135    0x8a => { #18
     1136        Name => 'ShadingCompensation',
     1137        Writable => 'int16u',
     1138        PrintConv => {
     1139            0 => 'Off',
     1140            1 => 'On'
     1141        }
     1142    },
     1143    0x8b => { #21
     1144        Name => 'WBShiftIntelligentAuto',
     1145        Writable => 'int16u',
     1146        Format => 'int16s',
     1147        Notes => 'value is -9 for blue to +9 for amber.  Valid for Intelligent-Auto modes',
     1148    },
     1149    0x8c => {
     1150        Name => 'AccelerometerZ',
     1151        Writable => 'int16u',
     1152        Format => 'int16s',
     1153        Notes => 'positive is acceleration upwards',
     1154    },
     1155    0x8d => {
     1156        Name => 'AccelerometerX',
     1157        Writable => 'int16u',
     1158        Format => 'int16s',
     1159        Notes => 'positive is acceleration to the left',
     1160    },
     1161    0x8e => {
     1162        Name => 'AccelerometerY',
     1163        Writable => 'int16u',
     1164        Format => 'int16s',
     1165        Notes => 'positive is acceleration backwards',
     1166    },
     1167    0x8f => { #18
     1168        Name => 'CameraOrientation',
     1169        Writable => 'int8u',
     1170        PrintConv => {
     1171            0 => 'Normal',
     1172            1 => 'Rotate CW',
     1173            2 => 'Rotate 180',
     1174            3 => 'Rotate CCW',
     1175            4 => 'Tilt Upwards',
     1176            5 => 'Tilt Downwards'
     1177        }
     1178    },
     1179    0x90 => {
     1180        Name => 'RollAngle',
     1181        Writable => 'int16u',
     1182        Format => 'int16s',
     1183        Notes => 'converted to degrees of clockwise camera rotation',
     1184        ValueConv => '$val / 10',
     1185        ValueConvInv => '$val * 10',
     1186    },
     1187    0x91 => {
     1188        Name => 'PitchAngle',
     1189        Writable => 'int16u',
     1190        Format => 'int16s',
     1191        Notes => 'converted to degrees of upward camera tilt',
     1192        ValueConv => '-$val / 10',
     1193        ValueConvInv => '-$val * 10',
     1194    },
     1195    0x92 => { #21 (forum9453) (more to decode in forum11194)
     1196        Name => 'WBShiftCreativeControl',
     1197        Writable => 'int8u',
     1198        Format => 'int8s',
     1199        Notes => 'WB shift or style strength.  Valid for Creative-Control modes',
     1200    },
     1201    0x93 => { #18
     1202        Name => 'SweepPanoramaDirection',
     1203        Writable => 'int8u',
     1204        PrintConv => {
     1205            0 => 'Off',
     1206            1 => 'Left to Right',
     1207            2 => 'Right to Left',
     1208            3 => 'Top to Bottom',
     1209            4 => 'Bottom to Top'
     1210        }
     1211    },
     1212    0x94 => { #18
     1213        Name => 'SweepPanoramaFieldOfView',
     1214        Writable => 'int16u'
     1215    },
     1216    0x96 => { #18
     1217        Name => 'TimerRecording',
     1218        Writable => 'int8u',
     1219        PrintConv => {
     1220            0 => 'Off',
     1221            1 => 'Time Lapse',
     1222            2 => 'Stop-motion Animation',
     1223            3 => 'Focus Bracketing', #forum11194
     1224        },
     1225    },
     1226    0x9d => { #18
     1227        Name => 'InternalNDFilter',
     1228        Writable => 'rational64u'
     1229    },
     1230    0x9e => { #18
     1231        Name => 'HDR',
     1232        Writable => 'int16u',
     1233        PrintConv => {
     1234            0 => 'Off',
     1235            100 => '1 EV',
     1236            200 => '2 EV',
     1237            300 => '3 EV',
     1238            32868 => '1 EV (Auto)',
     1239            32968 => '2 EV (Auto)',
     1240            33068 => '3 EV (Auto)',
     1241        },
     1242    },
     1243    0x9f => { #18
     1244        Name => 'ShutterType',
     1245        Writable => 'int16u',
     1246        PrintConv => {
     1247            0 => 'Mechanical',
     1248            1 => 'Electronic',
     1249            2 => 'Hybrid', #PH (GM1, 1st curtain electronic, 2nd curtain mechanical)
     1250        },
     1251    },
     1252    # 0xa0 - undef[32]: AWB gains and black levels (ref forum9303)
     1253    0xa1 => { #forum11194
     1254        Name => 'FilterEffect',
     1255        Writable => 'rational64u',
     1256        Format => 'int32u',
     1257        PrintConv => {
     1258            '0 0' => 'Expressive',
     1259            # '0 1' => have seen this for XS1 (PH)
     1260            '0 2' => 'Retro',
     1261            '0 4' => 'High Key',
     1262            '0 8' => 'Sepia',
     1263            '0 16' => 'High Dynamic',
     1264            '0 32' => 'Miniature Effect',
     1265            '0 256' => 'Low Key',
     1266            '0 512' => 'Toy Effect',
     1267            '0 1024' => 'Dynamic Monochrome',
     1268            '0 2048' => 'Soft Focus',
     1269            '0 4096' => 'Impressive Art',
     1270            '0 8192' => 'Cross Process',
     1271            '0 16384' => 'One Point Color',
     1272            '0 32768' => 'Star Filter',
     1273            '0 524288' => 'Old Days',
     1274            '0 1048576' => 'Sunshine',
     1275            '0 2097152' => 'Bleach Bypass',
     1276            '0 4194304' => 'Toy Pop',
     1277            '0 8388608' => 'Fantasy',
     1278            '0 33554432' => 'Monochrome',
     1279            '0 67108864' => 'Rough Monochrome',
     1280            '0 134217728' => 'Silky Monochrome',
     1281        },
     1282    },
     1283    0xa3 => { #18
     1284        Name => 'ClearRetouchValue',
     1285        Writable => 'rational64u',
     1286        # undef if ClearRetouch is off, 0 if it is on
     1287    },
     1288    0xa7 => { #forum9374 (conversion table for 14- to 16-bit mapping)
     1289        Name => 'OutputLUT',
     1290        Binary => 1,
     1291        Notes => q{
     1292            2-column by 432-row binary lookup table of unsigned short values for
     1293            converting to 16-bit output (1st column) from 14 bits (2nd column) with
     1294            camera contrast
     1295        },
     1296    },
     1297    0xab => { #18
     1298        Name => 'TouchAE',
     1299        Writable => 'int16u',
     1300        PrintConv => { 0 => 'Off', 1 => 'On' },
     1301    },
     1302    0xac => { #forum11194
     1303        Name => 'MonochromeFilterEffect',
     1304        Writable => 'int16u',
     1305        PrintConv => { 0 => 'Off', 1 => 'Yellow', 2 => 'Orange', 3 => 'Red', 4 => 'Green' },
     1306    },
     1307    0xad => { #forum9360
     1308        Name => 'HighlightShadow',
     1309        Writable => 'int16u',
     1310        Format => 'int16s', #forum11194
     1311        Count => 2,
     1312    },
     1313    0xaf => { #PH (is this in UTC maybe? -- sometimes different time zone other times)
     1314        Name => 'TimeStamp',
     1315        Writable => 'string',
     1316        Groups => { 2 => 'Time' },
     1317        Shift => 'Time',
     1318        PrintConv => '$self->ConvertDateTime($val)',
     1319        PrintConvInv => '$self->InverseDateTime($val)',
     1320    },
     1321    0xb3 => { #forum11194
     1322        Name => 'VideoBurstResolution',
     1323        Writable => 'int16u',
     1324        PrintConv => { 1 => 'Off or 4K', 4 => '6K' },
     1325    },
     1326    0xb4 => { #forum9429
     1327        Name => 'MultiExposure',
     1328        Writable => 'int16u',
     1329        PrintConv => { 0 => 'n/a', 1 => 'Off', 2 => 'On' },
     1330    },
     1331    0xb9 => { #forum9425
     1332        Name => 'RedEyeRemoval',
     1333        Writable => 'int16u',
     1334        PrintConv => { 0 => 'Off', 1 => 'On' },
     1335    },
     1336    0xbb => { #forum9282
     1337        Name => 'VideoBurstMode',
     1338        Writable => 'int32u',
     1339        PrintHex => 1,
     1340        PrintConv => {
     1341            0x01 => 'Off',
     1342            0x04 => 'Post Focus',
     1343            0x18 => '4K Burst',
     1344            0x28 => '4K Burst (Start/Stop)',
     1345            0x48 => '4K Pre-burst',
     1346            0x108 => 'Loop Recording',
     1347            0x810 => '6K Burst',
     1348            0x820 => '6K Burst (Start/Stop)',
     1349            0x408 => 'Focus Stacking', #forum11563
     1350            0x1001 => 'High Resolution Mode',
     1351        },
     1352    },
     1353    0xbc => { #forum9282
     1354        Name => 'DiffractionCorrection',
     1355        Writable => 'int16u',
     1356        PrintConv => { 0 => 'Off', 1 => 'Auto' },
     1357    },
     1358    0xbd => { #forum11194
     1359        Name => 'FocusBracket',
     1360        Notes => 'positive is further, negative is closer',
     1361        Writable => 'int16u',
     1362        Format => 'int16s',
     1363    },
     1364    0xbe => { #forum11194
     1365        Name => 'LongExposureNRUsed',
     1366        Writable => 'int16u',
     1367        PrintConv => { 0 => 'No', 1 => 'Yes' },
     1368    },
     1369    0xbf => { #forum11194
     1370        Name => 'PostFocusMerging',
     1371        Format => 'int32u',
     1372        Count => 2,
     1373        PrintConv => { '0 0' => 'Post Focus Auto Merging or None' },
     1374    },
     1375    0xc1 => { #forum11194
     1376        Name => 'VideoPreburst',
     1377        Writable => 'int16u',
     1378        PrintConv => { 0 => 'No', 1 => '4K or 6K' },
     1379    },
     1380    0xca => { #forum11459
     1381        Name => 'SensorType',
     1382        Writable => 'int16u',
     1383        PrintConv => {
     1384            0 => 'Multi-aspect',
     1385            1 => 'Standard',
     1386        },
     1387    },
     1388    # Note: LensTypeMake and LensTypeModel are combined into a Composite LensType tag
     1389    # defined in Olympus.pm which has the same values as Olympus:LensType
     1390    0xc4 => { #PH
     1391        Name => 'LensTypeMake',
     1392        Condition => '$format eq "int16u" and $$valPt ne "\xff\xff"',   # (ignore make 65535 for now)
     1393        Writable => 'int16u',
     1394    },
     1395    0xc5 => { #PH
     1396        Name => 'LensTypeModel',
     1397        Condition => '$format eq "int16u"',
     1398        Writable => 'int16u',
     1399        RawConv => q{
     1400            return undef unless $val;
     1401            require Image::ExifTool::Olympus; # (to load Composite LensID)
     1402            return $val;
     1403        },
     1404        ValueConv => '$_=sprintf("%.4x",$val); s/(..)(..)/$2 $1/; $_',
     1405        ValueConvInv => '$val =~ s/(..) (..)/$2$1/; hex($val)',
     1406    },
     1407    0xd1 => { #PH
     1408        Name => 'ISO',
     1409        RawConv => '$val > 0xfffffff0 ? undef : $val',
     1410        Writable => 'int32u',
     1411    },
     1412    0xd2 => { #forum11194
     1413        Name => 'MonochromeGrainEffect',
     1414        Writable => 'int16u',
     1415        PrintConv => {
     1416            0 => 'Off',
     1417            1 => 'Low',
     1418            2 => 'Standard',
     1419            3 => 'High',
     1420        },
     1421    },
     1422    0xd6 => { #PH (DC-S1)
     1423        Name => 'NoiseReductionStrength',
     1424        Writable => 'rational64s',
     1425    },
    8571426    0x0e00 => {
    8581427        Name => 'PrintIM',
    8591428        Description => 'Print Image Matching',
    8601429        Writable => 0,
    861         SubDirectory => {
    862             TagTable => 'Image::ExifTool::PrintIM::Main',
    863         },
     1430        SubDirectory => { TagTable => 'Image::ExifTool::PrintIM::Main' },
     1431    },
     1432    0x2003 => { #21
     1433        Name => 'TimeInfo',
     1434        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::TimeInfo' },
    8641435    },
    8651436    0x8000 => { #PH
     
    8761447        },
    8771448    },
    878     # 0x8002 - values: 1,2 related to focus? (PH/JD)
    879     #          1 for HDR modes, 2 for Portrait (ref 12)
    880     # 0x8003 - values: 1,2 related to focus? (PH/JD)
     1449    0x8002 => { #21
     1450        Name => 'HighlightWarning',
     1451        Writable => 'int16u',
     1452        PrintConv => { 0 => 'Disabled', 1 => 'No', 2 => 'Yes' },
     1453    },
     1454    0x8003 => { #21
     1455        Name => 'DarkFocusEnvironment',
     1456        Writable => 'int16u',
     1457        PrintConv => { 1 => 'No', 2 => 'Yes' },
     1458    },
    8811459    0x8004 => { #PH/JD
    8821460        Name => 'WBRedLevel',
     
    8911469        Writable => 'int16u',
    8921470    },
    893     0x8007 => { #PH
    894         Name => 'FlashFired',
    895         Writable => 'int16u',
    896         PrintConv => { 1 => 'No', 2 => 'Yes' },
    897     },
     1471    #0x8007 => { #PH - questionable [disabled because it conflicts with EXIF in too many samples]
     1472    #    Name => 'FlashFired',
     1473    #    Writable => 'int16u',
     1474    #    PrintConv => { 0 => 'Yes', 1 => 'No' },
     1475    #},
    8981476    0x8008 => { #PH (TZ5/FS7)
    8991477        # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
     
    9781556    },
    9791557    0x310 => {
    980         Name => 'LensInfo',
    981         SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::LensInfo' },
     1558        Name => 'LensType',
     1559        Writable => 'int32u',
     1560        SeparateTable => 1,
     1561        ValueConv => '($val >> 2) . " " . ($val & 0x3)',
     1562        ValueConvInv => \&LensTypeConvInv,
     1563        PrintConv => \%leicaLensTypes,
    9821564    },
    9831565    0x311 => {
     
    10361618    WRITABLE => 1,
    10371619    NOTES => 'These tags are used by the Leica R8 and R9 digital backs.',
     1620    0x0b => { #IB
     1621        Name => 'SerialInfo',
     1622        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::SerialInfo' },
     1623    },
    10381624    0x0d => {
    10391625        Name => 'WB_RGBLevels',
     
    10411627        Count => 3,
    10421628    },
     1629);
     1630
     1631# Leica serial number info (ref IB)
     1632%Image::ExifTool::Panasonic::SerialInfo = (
     1633    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1634    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     1635    TAG_PREFIX => 'Leica_SerialInfo',
     1636    FIRST_ENTRY => 0,
     1637    4 => {
     1638        Name => 'SerialNumber',
     1639        Format => 'string[8]',
     1640    }
    10431641);
    10441642
     
    12091807        ValueConv => '($val >> 2) . " " . ($val & 0x3)',
    12101808        ValueConvInv => \&LensTypeConvInv,
    1211         PrintConv => \%leicaLensType,
     1809        PrintConv => \%leicaLensTypes,
    12121810    },
    12131811    0x3406 => { #PH/13
     
    12441842    },
    12451843    # 0x3903 - larger binary data block
     1844);
     1845
     1846# time stamp information (ref 21)
     1847%Image::ExifTool::Panasonic::TimeInfo = (
     1848    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1849    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     1850    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     1851    GROUPS => { 0 => 'MakerNotes', 1 => 'Panasonic', 2 => 'Image' },
     1852    FIRST_ENTRY => 0,
     1853    WRITABLE => 1,
     1854    0 => {
     1855        Name => 'PanasonicDateTime',
     1856        Groups => { 2 => 'Time' },
     1857        Shift => 'Time',
     1858        Format => 'undef[8]',
     1859        RawConv => '$val =~ /^\0/ ? undef : $val',
     1860        ValueConv => 'sprintf("%s:%s:%s %s:%s:%s.%s", unpack "H4H2H2H2H2H2H2", $val)',
     1861        ValueConvInv => q{
     1862            $val =~ s/[-+].*//;     # remove time zone
     1863            $val =~ tr/0-9//dc;     # remove non-digits
     1864            $val = pack("H*",$val);
     1865            $val .= "\0" while length $val < 8;
     1866            return $val;
     1867        },
     1868        PrintConv => '$self->ConvertDateTime($val)',
     1869        PrintConvInv => '$self->InverseDateTime($val)',
     1870    },
     1871    # 8 - 8 bytes usually 8 x 0xff (spot for another date/time?)
     1872    16 => {
     1873        Name => 'TimeLapseShotNumber',
     1874        Format => 'int32u',
     1875    },
    12461876);
    12471877
     
    12561886    0x0016 => {
    12571887        Name => 'LensType',
    1258         Writable => 'int32u',
     1888        Format => 'int32u',
    12591889        Priority => 0,
    12601890        SeparateTable => 1,
    1261         ValueConv => '($val >> 2) . " " . ($val & 0x3)',
     1891        ValueConv => '(($val >> 2) & 0xffff) . " " . ($val & 0x3)',
    12621892        ValueConvInv => \&LensTypeConvInv,
    1263         PrintConv => \%leicaLensType,
     1893        PrintConv => \%leicaLensTypes,
    12641894    },
    12651895);
     
    12781908    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
    12791909    WRITABLE => 1,
    1280     NOTES => 'This information is written by the X1.',
     1910    PRIORITY => 0,
     1911    NOTES => 'This information is written by the X1, X2, X VARIO and T.',
     1912    0x0303 => {
     1913        Name => 'LensType',
     1914        Condition => '$format eq "string"',
     1915        Notes => 'Leica T only',
     1916        Writable => 'string',
     1917    },
     1918    # 0x0304 - int8u[1]: may be M-lens ID for Leica SL, mounted through "M-adapter L" (ref IB)
     1919    #          --> int8u[4] for some models (maybe not lens ID for these?) - PH
     1920    #          (see http://us.leica-camera.com/Photography/Leica-APS-C/Lenses-for-Leica-TL/L-Adapters/M-Adapter-L)
     1921    #          58 = 'Leica Noctilux-M 75mm F1.25 ASPH (Typ 601) on Leica SL
     1922    0x0305 => { #IB
     1923        Name => 'SerialNumber',
     1924        Writable => 'int32u',
     1925    },
    12811926    # 0x0406 - saturation or sharpness
    12821927    0x0407 => { Name => 'OriginalFileName', Writable => 'string' },
    12831928    0x0408 => { Name => 'OriginalDirectory',Writable => 'string' },
     1929    0x040a => { #IB
     1930        Name => 'FocusInfo',
     1931        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::FocusInfo' },
     1932    },
    12841933    # 0x040b - related to white balance
    12851934    0x040d => {
     
    12891938        PrintConv => {
    12901939            '0 0 0 0' => 'Program AE',
     1940          # '0 1 0 0' - seen for X (Typ 113) - PH
    12911941            '1 0 0 0' => 'Aperture-priority AE',
     1942            '1 1 0 0' => 'Aperture-priority AE (1)', # (see for Leica T)
    12921943            '2 0 0 0' => 'Shutter speed priority AE', #(guess)
    12931944            '3 0 0 0' => 'Manual',
    12941945        },
    12951946    },
    1296     # 0x0411 - saturation or sharpness
     1947    0x0410 => {
     1948        Name => 'ShotInfo',
     1949        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::ShotInfo' },
     1950    },
     1951    # 0x0410 - int8u[16]: first byte is FileNumber
     1952    # 0x0411 - int8u[4]: first number is FilmMode (1=Standard,2=Vivid,3=Natural,4=BW Natural,5=BW High Contrast)
    12971953    0x0412 => { Name => 'FilmMode',         Writable => 'string' },
    12981954    0x0413 => { Name => 'WB_RGBLevels',     Writable => 'rational64u', Count => 3 },
     1955    0x0500 => {
     1956        Name => 'InternalSerialNumber',
     1957        Writable => 'undef',
     1958        PrintConv => q{
     1959            return $val unless $val=~/^(.{3})(\d{2})(\d{2})(\d{2})(\d{4})/;
     1960            my $yr = $2 + ($2 < 70 ? 2000 : 1900);
     1961            return "($1) $yr:$3:$4 no. $5";
     1962        },
     1963        PrintConvInv => '$_=$val; tr/A-Z0-9//dc; s/(.{3})(19|20)/$1/; $_',
     1964    },
     1965);
     1966
     1967# Leica type5 ShotInfo (ref PH) (X2)
     1968%Image::ExifTool::Panasonic::ShotInfo = (
     1969    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1970    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     1971    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     1972    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     1973    TAG_PREFIX => 'Leica_ShotInfo',
     1974    FIRST_ENTRY => 0,
     1975    WRITABLE => 1,
     1976    0 => {
     1977        Name => 'FileIndex',
     1978        Format => 'int16u',
     1979    },
     1980);
     1981
     1982# Leica type5 FocusInfo (ref IB)
     1983%Image::ExifTool::Panasonic::FocusInfo = (
     1984    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     1985    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
     1986    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     1987    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     1988    TAG_PREFIX => 'Leica_FocusInfo',
     1989    FIRST_ENTRY => 0,
     1990    WRITABLE => 1,
     1991    FORMAT => 'int16u',
     1992    0 => {
     1993        Name => 'FocusDistance',
     1994        ValueConv => '$val / 1000',
     1995        ValueConvInv => '$val * 1000',
     1996        PrintConv => '$val < 65535 ? "$val m" : "inf"',
     1997        PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 65535',
     1998    },
     1999    1 => {
     2000        Name => 'FocalLength',
     2001        Priority => 0,
     2002        RawConv => '$val ? $val : undef',
     2003        ValueConv => '$val / 1000',
     2004        ValueConvInv => '$val * 1000',
     2005        PrintConv => 'sprintf("%.1f mm",$val)',
     2006        PrintConvInv => '$val=~s/\s*mm$//;$val',
     2007    },
    12992008);
    13002009
     
    13042013    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
    13052014    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
    1306     NOTES => 'This information is written by the S2 (as a trailer in JPEG images).',
     2015    NOTES => q{
     2016        This information is written by the S2 and M (Typ 240), as a trailer in JPEG
     2017        images.
     2018    },
    13072019    0x300 => {
    13082020        Name => 'PreviewImage',
     2021        Groups => { 2 => 'Preview' },
    13092022        Writable => 'undef',
    1310         Notes => 'S2',
     2023        Notes => 'S2 and M (Typ 240)',
    13112024        DataTag => 'PreviewImage',
    13122025        RawConv => q{
     
    13252038        Flags => [ 'Unknown', 'Binary', 'Drop' ],
    13262039    },
    1327     # 0x302 - same value as 4 unknown bytes at the end of JPEG or after the DNG TIFF header
     2040    # 0x302 - same value as 4 unknown bytes at the end of JPEG or after the DNG TIFF header (ImageID, ref IB)
    13282041    0x303 => {
    13292042        Name => 'LensType',
    13302043        Writable => 'string',
    1331     },
    1332     # 0x340 - same as 0x302
     2044        ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
     2045        ValueConvInv => '$val',
     2046    },
     2047    0x304 => { #IB
     2048        Name => 'FocusDistance',
     2049        Notes => 'focus distance in mm for most models, but cm for others',
     2050        Writable => 'int32u',
     2051    },
     2052    0x311 => {
     2053        Name => 'ExternalSensorBrightnessValue',
     2054        Condition => '$$self{Model} =~ /Typ 006/',
     2055        Notes => 'Leica S only',
     2056        Format => 'rational64s', # (may be incorrectly unsigned in JPEG images)
     2057        Writable => 'rational64s',
     2058        PrintConv => 'sprintf("%.2f", $val)',
     2059        PrintConvInv => '$val',
     2060    },
     2061    0x312 => {
     2062        Name => 'MeasuredLV',
     2063        Condition => '$$self{Model} =~ /Typ 006/',
     2064        Notes => 'Leica S only',
     2065        Format => 'rational64s', # (may be incorrectly unsigned in JPEG images)
     2066        Writable => 'rational64s',
     2067        PrintConv => 'sprintf("%.2f", $val)',
     2068        PrintConvInv => '$val',
     2069    },
     2070    0x320 => {
     2071        Name => 'FirmwareVersion',
     2072        Condition => '$$self{Model} =~ /Typ 006/',
     2073        Notes => 'Leica S only',
     2074        Writable => 'int8u',
     2075        Count => 4,
     2076        PrintConv => '$val=~tr/ /./; $val',
     2077        PrintConvInv => '$val=~tr/./ /; $val',
     2078    },
     2079    0x321 => { #IB
     2080        Name => 'LensSerialNumber',
     2081        Condition => '$$self{Model} =~ /Typ 006/',
     2082        Notes => 'Leica S only',
     2083        Writable => 'int32u',
     2084        PrintConv => 'sprintf("%.10d",$val)',
     2085        PrintConvInv => '$val',
     2086    },
     2087    # 0x321 - SerialNumber for Leica S? (ref IB)
     2088    # 0x340 - same as 0x302 (ImageID, ref IB)
     2089);
     2090
     2091# Leica type9 maker notes (ref IB) (S)
     2092%Image::ExifTool::Panasonic::Leica9 = (
     2093    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     2094    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     2095    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     2096    NOTES => 'This information is written by the Leica S (Typ 007) and M10 models.',
     2097    0x304 => {
     2098        Name => 'FocusDistance',
     2099        Notes => 'focus distance in mm for most models, but cm for others',
     2100        Writable => 'int32u',
     2101    },
     2102    0x311 => {
     2103        Name => 'ExternalSensorBrightnessValue',
     2104        Format => 'rational64s', # (may be incorrectly unsigned in JPEG images)
     2105        Writable => 'rational64s',
     2106        PrintConv => 'sprintf("%.2f", $val)',
     2107        PrintConvInv => '$val',
     2108    },
     2109    0x312 => {
     2110        Name => 'MeasuredLV',
     2111        Format => 'rational64s', # (may be incorrectly unsigned in JPEG images)
     2112        Writable => 'rational64s',
     2113        PrintConv => 'sprintf("%.2f", $val)',
     2114        PrintConvInv => '$val',
     2115    },
     2116    # 0x340 - ImageUniqueID
     2117    0x34c => { #23
     2118        Name => 'UserProfile',
     2119        Writable => 'string',
     2120    },
     2121    0x359 => { #23
     2122        Name => 'ISOSelected',
     2123        Writable => 'int32s',
     2124        PrintConv => {
     2125            0 => 'Auto',
     2126            OTHER => sub { return shift; },
     2127        },
     2128    },
     2129    0x35a => { #23
     2130        Name => 'FNumber',
     2131        Writable => 'int32s',
     2132        ValueConv => '$val / 1000',
     2133        ValueConvInv => '$val * 1000',
     2134        PrintConv => 'sprintf("%.1f", $val)',
     2135        PrintConvInv => '$val',
     2136    },
     2137    # 0x357 int32u - 0=DNG, 3162=JPG (ref 23)
    13332138);
    13342139
     
    13512156    # (minimum is 16, maximum is 136.  Value is 0 for pictures captured from video)
    13522157    3 => 'Gain',
    1353 );
    1354 
    1355 # lens information (ref 10)
    1356 %Image::ExifTool::Panasonic::LensInfo = (
    1357     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    1358     WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
    1359     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
    1360     GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
    1361     WRITABLE => 1,
    1362     FORMAT => 'int32u',
    1363     FIRST_ENTRY => 0,
    1364     0 => {
    1365         Name => 'LensType',
    1366         Mask => 0xfffffffc,
    1367         PrintHex => 0,
    1368         SeparateTable => 1,
    1369         ValueConv => '$val >> 2',
    1370         ValueConvInv => '$val << 2',
    1371         PrintConv => \%leicaLensType,
    1372     },
    1373     0.1 => { # lower 2 bits give frame selector position
    1374         Name => 'FrameSelector',
    1375         Mask => 0x03,
    1376         PrintConv => {
    1377             1 => '28/90mm frame lines engaged',
    1378             2 => '24/35mm frame lines engaged',
    1379             3 => '50/75mm frame lines engaged',
    1380         },
    1381     },
    13822158);
    13832159
     
    15032279);
    15042280
     2281# PANA atom found in user data of MP4 videos (ref PH)
     2282%Image::ExifTool::Panasonic::PANA = (
     2283    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     2284    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     2285    NOTES => q{
     2286        Tags extracted from the PANA and LEIC user data found in MP4 videos from
     2287        various Panasonic and Leica models.
     2288    },
     2289    0x00 => {
     2290        Name => 'Make',
     2291        Condition => '$$valPt =~ /^(LEICA|Panasonic)/', # (only seen "LEICA")
     2292        Groups => { 2 => 'Camera' },
     2293        Format => 'string[22]',
     2294        RawConv => '$$self{LeicaLEIC} = 1;$$self{Make} = $val',
     2295    },
     2296    0x04 => {
     2297        Name => 'Model',
     2298        Condition => '$$valPt =~ /^[^\0]{6}/ and not $$self{LeicaLEIC}',
     2299        Description => 'Camera Model Name',
     2300        Groups => { 2 => 'Camera' },
     2301        Format => 'string[16]',
     2302        RawConv => '$$self{Model} = $val',
     2303    },
     2304    0x0c => { # (FZ1000)
     2305        Name => 'Model',
     2306        Condition => '$$valPt =~ /^[^\0]{6}/ and not $$self{LeicaLEIC} and not $$self{Model}',
     2307        Description => 'Camera Model Name',
     2308        Groups => { 2 => 'Camera' },
     2309        Format => 'string[16]',
     2310        RawConv => '$$self{Model} = $val',
     2311    },
     2312    0x10 => { # (DC-FT7)
     2313        Name => 'JPEG-likeData',
     2314        # looks like a JPEG preview, but not a well-formed JPEG file
     2315        Condition => '$$valPt =~ /^\xff\xd8\xff\xe1..Exif\0\0/s',
     2316        Format => 'undef[$size-0x10]',
     2317        SubDirectory => {
     2318            TagTable => 'Image::ExifTool::Exif::Main',
     2319            ProcessProc => \&Image::ExifTool::ProcessTIFF,
     2320            Start => 12,
     2321        },
     2322    },
     2323    0x16 => {
     2324        Name => 'Model',
     2325        Condition => '$$self{LeicaLEIC}',
     2326        Description => 'Camera Model Name',
     2327        Groups => { 2 => 'Camera' },
     2328        Format => 'string[30]',
     2329        RawConv => '$$self{Model} = $val',
     2330    },
     2331    0x40 => {
     2332        Name => 'ThumbnailTest',
     2333        Format => 'undef[0x600]',
     2334        Hidden => 1,
     2335        RawConv => q{
     2336            if (substr($val,0x1c,3) eq "\xff\xd8\xff") { # offset 0x5c
     2337                $$self{ThumbType} = 1;
     2338            } elsif (substr($val,0x506,3) eq "\xff\xd8\xff") { # offset 0x546
     2339                $$self{ThumbType} = 2;
     2340            } elsif (substr($val,0x51e,3) eq "\xff\xd8\xff") { # offset 0x55e (Leica T)
     2341                $$self{ThumbType} = 3;
     2342            } else {
     2343                $$self{ThumbType} = 0;
     2344            }
     2345            return undef;
     2346        },
     2347    },
     2348    0x34 => {
     2349        Name => 'Version1',
     2350        Condition => '$$self{LeicaLEIC}',
     2351        Format => 'string[14]',
     2352    },
     2353    0x3e => {
     2354        Name => 'Version2',
     2355        Condition => '$$self{LeicaLEIC}',
     2356        Format => 'string[14]',
     2357    },
     2358    0x50 => {
     2359        Name => 'MakerNoteLeica5',
     2360        Condition => '$$self{LeicaLEIC}',
     2361        SubDirectory => {
     2362            TagTable => 'Image::ExifTool::Panasonic::Leica5',
     2363            ProcessProc => \&ProcessLeicaLEIC,
     2364        },
     2365    },
     2366    0x58 => {
     2367        Name => 'ThumbnailWidth',
     2368        Condition => '$$self{ThumbType} == 1',
     2369        Notes => 'Panasonic models',
     2370        Format => 'int16u',
     2371    },
     2372    0x5a => {
     2373        Name => 'ThumbnailHeight',
     2374        Condition => '$$self{ThumbType} == 1',
     2375        Format => 'int16u',
     2376    },
     2377    0x5c => {
     2378        Name => 'ThumbnailImage',
     2379        Condition => '$$self{ThumbType} == 1',
     2380        Groups => { 2 => 'Preview' },
     2381        Format => 'undef[16384]',
     2382        ValueConv => '$val=~s/\0*$//; \$val',   # remove trailing zeros
     2383    },
     2384    # 0x5c - there is some messed-up EXIF-IFD-looking data starting here in
     2385    #        Leica X VARIO MP4 videos, but it doesn't quite make sense
     2386    0x536 => { # (Leica X VARIO)
     2387        Name => 'ThumbnailWidth',
     2388        Condition => '$$self{ThumbType} == 2',
     2389        Notes => 'Leica X Vario',
     2390        Format => 'int32uRev', # (little-endian)
     2391    },
     2392    0x53a => { # (Leica X VARIO)
     2393        Name => 'ThumbnailHeight',
     2394        Condition => '$$self{ThumbType} == 2',
     2395        Format => 'int32uRev', # (little-endian)
     2396    },
     2397    0x53e => { # (Leica X VARIO)
     2398        Name => 'ThumbnailLength',
     2399        Condition => '$$self{ThumbType} == 2',
     2400        Format => 'int32uRev', # (little-endian)
     2401    },
     2402    0x546 => { # (Leica X VARIO)
     2403        Name => 'ThumbnailImage',
     2404        Condition => '$$self{ThumbType} == 2',
     2405        Groups => { 2 => 'Preview' },
     2406        Format => 'undef[$val{0x53e}]',
     2407        Binary => 1,
     2408    },
     2409    0x54e => { # (Leica T)
     2410        Name => 'ThumbnailWidth',
     2411        Condition => '$$self{ThumbType} == 3',
     2412        Notes => 'Leica X Vario',
     2413        Format => 'int32uRev', # (little-endian)
     2414    },
     2415    0x552 => { # (Leica T)
     2416        Name => 'ThumbnailHeight',
     2417        Condition => '$$self{ThumbType} == 3',
     2418        Format => 'int32uRev', # (little-endian)
     2419    },
     2420    0x556 => { # (Leica T)
     2421        Name => 'ThumbnailLength',
     2422        Condition => '$$self{ThumbType} == 3',
     2423        Format => 'int32uRev', # (little-endian)
     2424    },
     2425    0x55e => { # (Leica T)
     2426        Name => 'ThumbnailImage',
     2427        Condition => '$$self{ThumbType} == 3',
     2428        Groups => { 2 => 'Preview' },
     2429        Format => 'undef[$val{0x556}]',
     2430        Binary => 1,
     2431    },
     2432    0x4068 => {
     2433        Name => 'ExifData',
     2434        Condition => '$$valPt =~ /^\xff\xd8\xff\xe1..Exif\0\0/s',
     2435        SubDirectory => {
     2436            TagTable => 'Image::ExifTool::Exif::Main',
     2437            ProcessProc => \&Image::ExifTool::ProcessTIFF,
     2438            Start => 12,
     2439        },
     2440    },
     2441    0x4080 => { # (FZ1000)
     2442        Name => 'ExifData',
     2443        Condition => '$$valPt =~ /^\xff\xd8\xff\xe1..Exif\0\0/s',
     2444        SubDirectory => {
     2445            TagTable => 'Image::ExifTool::Exif::Main',
     2446            ProcessProc => \&Image::ExifTool::ProcessTIFF,
     2447            Start => 12,
     2448        },
     2449    },
     2450);
     2451
     2452# Panasonic Composite tags
     2453%Image::ExifTool::Panasonic::Composite = (
     2454    GROUPS => { 2 => 'Camera' },
     2455    AdvancedSceneMode => {
     2456        SeparateTable => 'Panasonic AdvancedSceneMode',    # print values in a separate table
     2457        Require => {
     2458            0 => 'Model',
     2459            1 => 'SceneMode',
     2460            2 => 'AdvancedSceneType',
     2461        },
     2462        ValueConv => '"$val[0] $val[1] $val[2]"',
     2463        PrintConv => { #PH
     2464            OTHER => sub {
     2465                my ($val,$flag,$conv) = @_;
     2466                $val =~ s/.* (\d+ \d+)/$1/; # drop model name
     2467                return $$conv{$val} if $$conv{$val};
     2468                my @v = split ' ', $val;
     2469                my $prt = $shootingMode{$v[0]};
     2470                # AdvancedSceneType=1 for non-automatic modes P,A,S,SCN (ref 19)
     2471                # AdvancedSceneType=5 for automatic mode iA (ref 19)
     2472                if ($prt) {
     2473                    return $prt if $v[1] == 1;
     2474                    return "$prt (intelligent auto)" if $v[1] == 5; #forum11523
     2475                    return "$prt (intelligent auto plus)" if $v[1] == 7; #forum11523
     2476                    return "$prt ($v[1])";
     2477                }
     2478                return "Unknown ($val)";
     2479            },
     2480            Notes => 'A Composite tag derived from Model, SceneMode and AdvancedSceneType.',
     2481            '0 1' => 'Off',
     2482            # '0 7' - seen this for V-LUX movies (PH)
     2483            # '0 8' - seen for D-LUX(Typ104) movies (PH)
     2484            '2 2' => 'Outdoor Portrait', #(FZ28)
     2485            '2 3' => 'Indoor Portrait', #(FZ28)
     2486            '2 4' => 'Creative Portrait', #(FZ28)
     2487            '3 2' => 'Nature', #(FZ28)
     2488            '3 3' => 'Architecture', #(FZ28)
     2489            '3 4' => 'Creative Scenery', #(FZ28)
     2490            #'3 5' - ? (FT1)
     2491            '4 2' => 'Outdoor Sports', #(FZ28)
     2492            '4 3' => 'Indoor Sports', #(FZ28)
     2493            '4 4' => 'Creative Sports', #(FZ28)
     2494            '9 2' => 'Flower', #(FZ28)
     2495            '9 3' => 'Objects', #(FZ28)
     2496            '9 4' => 'Creative Macro', #(FZ28)
     2497            #'9 5' - ? (GF3)
     2498            '18 1' => 'High Sensitivity', #forum11523 (TZ5)
     2499            '20 1' => 'Fireworks', #forum11523 (TZ5)
     2500            '21 2' => 'Illuminations', #(FZ28)
     2501            '21 4' => 'Creative Night Scenery', #(FZ28)
     2502            #'21 5' - ? (LX3)
     2503            '26 1' => 'High-speed Burst (shot 1)', #forum11523 (TZ5)
     2504            '27 1' => 'High-speed Burst (shot 2)', #forum11523 (TZ5)
     2505            '29 1' => 'Snow', #forum11523 (TZ5)
     2506            '30 1' => 'Starry Sky', #forum11523 (TZ5)
     2507            '31 1' => 'Beach', #forum11523 (TZ5)
     2508            '36 1' => 'High-speed Burst (shot 3)', #forum11523 (TZ5)
     2509            #'37 5' - ? (various)
     2510            '39 1' => 'Aerial Photo / Underwater / Multi-aspect', #forum11523 (TZ5)
     2511            '45 2' => 'Cinema', #(GF2)
     2512            '45 7' => 'Expressive', #(GF1,GF2)
     2513            '45 8' => 'Retro', #(GF1,GF2)
     2514            '45 9' => 'Pure', #(GF1,GF2)
     2515            '45 10' => 'Elegant', #(GF1,GF2)
     2516            '45 12' => 'Monochrome', #(GF1,GF2)
     2517            '45 13' => 'Dynamic Art', #(GF1,GF2)
     2518            '45 14' => 'Silhouette', #(GF1,GF2)
     2519            '51 2' => 'HDR Art', #12
     2520            '51 3' => 'HDR B&W', #12
     2521            '59 1' => 'Expressive', #(GF5)
     2522            '59 2' => 'Retro', #(GF5)
     2523            '59 3' => 'High Key', #(GF5)
     2524            '59 4' => 'Sepia', #(GF3,GF5)
     2525            '59 5' => 'High Dynamic', #(GF3,GF5)
     2526            '59 6' => 'Miniature', #(GF3)
     2527            '59 9' => 'Low Key', #(GF5)
     2528            '59 10' => 'Toy Effect', #(GF5)
     2529            '59 11' => 'Dynamic Monochrome', #(GF5)
     2530            '59 12' => 'Soft', #(GF5)
     2531            '66 1' => 'Impressive Art', #19
     2532            '66 2' => 'Cross Process', #(GF5)
     2533            '66 3' => 'Color Select', #(GF5) (called "One Point Color" by some other models - PH)
     2534            '66 4' => 'Star', #(GF5)
     2535            '90 3' => 'Old Days', #18
     2536            '90 4' => 'Sunshine', #18
     2537            '90 5' => 'Bleach Bypass', #18
     2538            '90 6' => 'Toy Pop', #18
     2539            '90 7' => 'Fantasy', #18
     2540            '90 8' => 'Monochrome', #PH (GX7)
     2541            '90 9' => 'Rough Monochrome', #PH (GX7)
     2542            '90 10' => 'Silky Monochrome', #PH (GX7)
     2543            '92 1' => 'Handheld Night Shot', #Horst Wandres (FZ1000)
     2544            # TZ40 Creative Control modes (ref 19)
     2545            'DMC-TZ40 90 1' => 'Expressive',
     2546            'DMC-TZ40 90 2' => 'Retro',
     2547            'DMC-TZ40 90 3' => 'High Key',
     2548            'DMC-TZ40 90 4' => 'Sepia',
     2549            'DMC-TZ40 90 5' => 'High Dynamic',
     2550            'DMC-TZ40 90 6' => 'Miniature',
     2551            'DMC-TZ40 90 9' => 'Low Key',
     2552            'DMC-TZ40 90 10' => 'Toy Effect',
     2553            'DMC-TZ40 90 11' => 'Dynamic Monochrome',
     2554            'DMC-TZ40 90 12' => 'Soft',
     2555        },
     2556    },
     2557);
     2558
     2559# add our composite tags
     2560Image::ExifTool::AddCompositeTags('Image::ExifTool::Panasonic');
     2561
    15052562#------------------------------------------------------------------------------
    15062563# Inverse conversion for Leica M9 lens codes
     
    15372594
    15382595#------------------------------------------------------------------------------
     2596# Process Leica makernotes in LEIC atom of MP4 videos (Leica T and X Vario)
     2597# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
     2598# Returns: 1 on success
     2599sub ProcessLeicaLEIC($$$)
     2600{
     2601    my ($et, $dirInfo, $tagTablePtr) = @_;
     2602    my $dataPt = $$dirInfo{DataPt};
     2603    my $dirStart = $$dirInfo{DirStart} || 0;
     2604    my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
     2605    return 0 if $dirLen < 6;
     2606    SetByteOrder('II');
     2607    my $numEntries = Get16u($dataPt, $dirStart);
     2608    return 0 if $numEntries < 1 or $numEntries > 255;
     2609    my $size = Get32u($dataPt, $dirStart + 2);
     2610    return 0 if $size < $numEntries * 12 or $size + 6 > $dirLen;
     2611    # the Leica programmers want to make things difficult, so they store
     2612    # the entry count before the directory size, making it impossible to
     2613    # process as a standard TIFF IFD without a bit of reorganization...
     2614    Set16u($numEntries, $dataPt, $dirStart + 4);
     2615    my %dirInfo = %$dirInfo;
     2616    $dirInfo{DirStart} = $dirStart + 4;
     2617    $dirInfo{DirLen} = $size - 4;
     2618    $dirInfo{DataPos} -= $dirStart;
     2619    $dirInfo{Base} += $dirStart;
     2620    return Image::ExifTool::Exif::ProcessExif($et, \%dirInfo, $tagTablePtr);
     2621    return 1;
     2622}
     2623
     2624#------------------------------------------------------------------------------
    15392625# Process MakerNote trailer written by Leica S2
    15402626# Inputs: 0) ExifTool object ref, 1) new absolute position of Leica trailer when writing
    1541 # Returns: On success: 1 when reading, directory data when writing; othewise undef
     2627# Returns: On success: 1 when reading, directory data when writing; otherwise undef
    15422628# Notes:
    15432629# - may be called twice for a file if the first call doesn't succeed
     
    15502636sub ProcessLeicaTrailer($;$)
    15512637{
    1552     my ($exifTool, $newPos) = @_;
    1553     my $trail = $$exifTool{LeicaTrailer};
    1554     my $raf = $$exifTool{RAF};
     2638    my ($et, $newPos) = @_;
     2639    my $trail = $$et{LeicaTrailer};
     2640    my $raf = $$et{RAF};
    15552641    my $trailPos = $$trail{TrailPos};
    15562642    my $pos = $trailPos || $$trail{Offset};
     
    15582644    my ($buff, $result, %tagPtr);
    15592645
    1560     delete $$exifTool{LeicaTrailer} if $trailPos;   # done after this
     2646    delete $$et{LeicaTrailer} if $trailPos;   # done after this
    15612647    unless ($len > 0) {
    1562         $exifTool->Warn('Missing Leica MakerNote trailer', 1) if $trailPos;
    1563         undef $$exifTool{LeicaTrailer};
     2648        $et->Warn('Missing Leica MakerNote trailer', 1) if $trailPos;
     2649        delete $$et{LeicaTrailer};
    15642650        return undef;
    15652651    }
     
    15682654    $raf->Seek($oldPos, 0);
    15692655    unless ($ok) {
    1570         $exifTool->Warn('Error reading Leica MakerNote trailer', 1) if $trailPos;
     2656        $et->Warn('Error reading Leica MakerNote trailer', 1) if $trailPos;
    15712657        return undef;
    15722658    }
     
    15752661    if ($buff !~ /^(.{0,256})LEICA\0..../sg) {
    15762662        my $what = $trailPos ? 'trailer' : 'offset';
    1577         $exifTool->Warn("Invalid Leica MakerNote $what", 1);
     2663        $et->Warn("Invalid Leica MakerNote $what", 1);
    15782664        return undef;
    15792665    }
     
    15812667    my $start = pos($buff) - 10;
    15822668    if ($start and not $trailPos) {
    1583         $exifTool->Warn('Invalid Leica MakerNote offset', 1);
     2669        $et->Warn('Invalid Leica MakerNote offset', 1);
    15842670        return undef;
    15852671    }
     
    15902676    my $dirStart = $start + $hdrLen;
    15912677    my $tagInfo = $$trail{TagInfo};
    1592     if ($$exifTool{HTML_DUMP}) {
     2678    if ($$et{HTML_DUMP}) {
    15932679        my $name = $$tagInfo{Name};
    1594         $exifTool->HDump($pos+$start, $len-$start, "$name value", 'Leica MakerNote trailer', 4);
    1595         $exifTool->HDump($pos+$start, $hdrLen, "MakerNotes header", $name);
    1596     } elsif ($exifTool->Options('Verbose')) {
     2680        $et->HDump($pos+$start, $len-$start, "$name value", 'Leica MakerNote trailer', 4);
     2681        $et->HDump($pos+$start, $hdrLen, "MakerNotes header", $name);
     2682    } elsif ($et->Options('Verbose')) {
    15972683        my $where = sprintf('at offset 0x%x', $pos);
    1598         $exifTool->VPrint(0, "Leica MakerNote trailer ($len bytes $where):\n");
     2684        $et->VPrint(0, "Leica MakerNote trailer ($len bytes $where):\n");
    15992685    }
    16002686    # delete LeicaTrailer member so we don't try to process it again
    1601     delete $$exifTool{LeicaTrailer};
    1602     $$exifTool{LeicaTrailerPos} = $pos + $start;    # return actual start position of Leica trailer
     2687    delete $$et{LeicaTrailer};
     2688    $$et{LeicaTrailerPos} = $pos + $start;    # return actual start position of Leica trailer
    16032689
    16042690    my $oldOrder = GetByteOrder();
     
    16112697    if ($valStart < $len) {
    16122698        my $valBlock = Image::ExifTool::MakerNotes::GetValueBlocks(\$buff, $dirStart, \%tagPtr);
    1613         # find the minimum offset (excluding the PreviewImage tag 0x300)
     2699        # find the minimum offset (excluding the PreviewImage tag 0x300 and 0x301)
    16142700        my $minPtr;
    16152701        foreach (keys %tagPtr) {
    16162702            my $ptr = $tagPtr{$_};
    1617             next if $_ == 0x300 or not $ptr;
     2703            next if $_ == 0x300 or $_ == 0x301 or not $ptr or $ptr == 0xffffffff;
    16182704            $minPtr = $ptr if not defined $minPtr or $minPtr > $ptr;
    16192705        }
    16202706        if ($minPtr) {
    16212707            my $diff = $minPtr - ($valStart + $pos);
    1622             # scan value data for the first non-zero byte
    16232708            pos($buff) = $valStart;
    1624             if ($buff =~ /[^\0]/g) {
    1625                 my $n = pos($buff) - 1 - $valStart; # number of zero bytes
    1626                 # S2 writes 282 bytes of zeros, exiftool writes none
    1627                 my $expect = $n >= 282 ? 282 : 0;
    1628                 my $fixBase = $exifTool->Options('FixBase');
    1629                 if ($diff != $expect or defined $fixBase) {
    1630                     $fix = $expect - $diff;
    1631                     if (defined $fixBase) {
    1632                         $fix = $fixBase if $fixBase ne '';
    1633                         $exifTool->Warn("Adjusted MakerNotes base by $fix",1);
    1634                     } else {
    1635                         $exifTool->Warn("Possibly incorrect maker notes offsets (fixed by $fix)",1);
    1636                     }
     2709            my $expect;
     2710            if ($$et{Model} eq 'S2') {
     2711                # scan value data for the first non-zero byte
     2712                if ($buff =~ /[^\0]/g) {
     2713                    my $n = pos($buff) - 1 - $valStart; # number of zero bytes
     2714                    # S2 writes 282 bytes of zeros, exiftool writes none
     2715                    $expect = $n >= 282 ? 282 : 0;
     2716                }
     2717            } else { # M (Type 240)
     2718                # scan for the lens type (M writes 114 bytes of garbage first)
     2719                if ($buff =~ /\G.{114}([\x20-\x7f]*\0*)/sg and length($1) >= 50) {
     2720                    $expect = 114;
     2721                }
     2722            }
     2723            my $fixBase = $et->Options('FixBase');
     2724            if (not defined $expect) {
     2725                $et->Warn('Unrecognized Leica trailer structure');
     2726            } elsif ($diff != $expect or defined $fixBase) {
     2727                $fix = $expect - $diff;
     2728                if (defined $fixBase) {
     2729                    $fix = $fixBase if $fixBase ne '';
     2730                    $et->Warn("Adjusted MakerNotes base by $fix",1);
     2731                } else {
     2732                    $et->Warn("Possibly incorrect maker notes offsets (fixed by $fix)",1);
    16372733                }
    16382734            }
     
    16542750    my $tagTablePtr = GetTagTable($$tagInfo{SubDirectory}{TagTable});
    16552751    if ($newPos) { # are we writing?
     2752        if ($$et{Model} ne 'S2') {
     2753            $et->Warn('Leica MakerNote trailer too messed up to edit.  Copying as a block', 1);
     2754            return $buff;
     2755        }
    16562756        # set position of new MakerNote IFD (+ 8 for Leica MakerNote header)
    16572757        $dirInfo{NewDataPos} = $newPos + $start + 8;
    1658         $result = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
     2758        $result = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
    16592759        # write preview image last if necessary and fix up the preview offsets
    1660         my $previewInfo = $$exifTool{PREVIEW_INFO};
    1661         delete $$exifTool{PREVIEW_INFO};
     2760        my $previewInfo = $$et{PREVIEW_INFO};
     2761        delete $$et{PREVIEW_INFO};
    16622762        if ($result) {
    16632763            if ($previewInfo) {
     
    16712771    } else {
    16722772        # extract information
    1673         $result = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
     2773        $result = $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
    16742774        # also extract as a block if necessary
    1675         if ($exifTool->Options('MakerNotes') or
    1676             $exifTool->{REQ_TAG_LOOKUP}{lc($$tagInfo{Name})})
     2775        if ($et->Options('MakerNotes') or
     2776            $$et{REQ_TAG_LOOKUP}{lc($$tagInfo{Name})})
    16772777        {
    16782778            # makernote header must be included in RebuildMakerNotes call
    16792779            $dirInfo{DirStart} -= 8;
    16802780            $dirInfo{DirLen} += 8;
    1681             $exifTool->{MAKER_NOTE_BYTE_ORDER} = GetByteOrder();
    1682             # rebuild maker notes (creates $exifTool->{MAKER_NOTE_FIXUP})
    1683             my $val = Image::ExifTool::Exif::RebuildMakerNotes($exifTool, $tagTablePtr, \%dirInfo);
     2781            $$et{MAKER_NOTE_BYTE_ORDER} = GetByteOrder();
     2782            # rebuild maker notes (creates $$et{MAKER_NOTE_FIXUP})
     2783            my $val = Image::ExifTool::Exif::RebuildMakerNotes($et, \%dirInfo, $tagTablePtr);
    16842784            unless (defined $val) {
    1685                 $exifTool->Warn('Error rebuilding maker notes (may be corrupt)');
     2785                $et->Warn('Error rebuilding maker notes (may be corrupt)') if $len > 4;
    16862786                $val = $buff,
    16872787            }
    1688             my $key = $exifTool->FoundTag($tagInfo, $val);
    1689             $exifTool->SetGroup($key, 'ExifIFD');
     2788            my $key = $et->FoundTag($tagInfo, $val);
     2789            $et->SetGroup($key, 'ExifIFD');
    16902790        }
    16912791    }
     
    17132813=head1 AUTHOR
    17142814
    1715 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
     2815Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
    17162816
    17172817This library is free software; you can redistribute it and/or modify it
     
    17382838=head1 ACKNOWLEDGEMENTS
    17392839
    1740 Thanks to Tels for the information he provided on decoding some tags, and to
    1741 Marcel Coenen, Jens Duttke and Michael Byczkowski for their contributions.
     2840Thanks to Tels, Marcel Coenen, Jens Duttke, Joerg, Michael Byczkowski, Carl
     2841Bretteville, Zdenek Mihula and Olaf Ulrich for their contributions.
    17422842
    17432843=head1 SEE ALSO
Note: See TracChangeset for help on using the changeset viewer.