| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | ########################################################### | 
| 2 |  |  |  |  |  |  | # A Perl package for showing/modifying JPEG (meta)data.   # | 
| 3 |  |  |  |  |  |  | # Copyright (C) 2004,2005,2006 Stefano Bettelli           # | 
| 4 |  |  |  |  |  |  | # See the COPYING and LICENSE files for license terms.    # | 
| 5 |  |  |  |  |  |  | ########################################################### | 
| 6 | 15 |  |  | 15 |  | 87 | use Image::MetaData::JPEG::data::Tables qw(:TagsAPP3); | 
|  | 15 |  |  |  |  | 32 |  | 
|  | 15 |  |  |  |  | 1959 |  | 
| 7 | 15 |  |  | 15 |  | 86 | no  integer; | 
|  | 15 |  |  |  |  | 38 |  | 
|  | 15 |  |  |  |  | 144 |  | 
| 8 | 15 |  |  | 15 |  | 357 | use strict; | 
|  | 15 |  |  |  |  | 30 |  | 
|  | 15 |  |  |  |  | 428 |  | 
| 9 | 15 |  |  | 15 |  | 80 | use warnings; | 
|  | 15 |  |  |  |  | 32 |  | 
|  | 15 |  |  |  |  | 2709 |  | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | ########################################################### | 
| 12 |  |  |  |  |  |  | # This method parses an APP3 Exif segment, which is very  # | 
| 13 |  |  |  |  |  |  | # similar to an APP1 Exif segment (infact, it is its      # | 
| 14 |  |  |  |  |  |  | # extension with additional tags, see parse_app1_exif for # | 
| 15 |  |  |  |  |  |  | # additional details). The structure is as follows:       # | 
| 16 |  |  |  |  |  |  | #---------------------------------------------------------# | 
| 17 |  |  |  |  |  |  | #  6 bytes  identifier ('Meta\000\000' = 0x4d6574610000)  # | 
| 18 |  |  |  |  |  |  | #  2 bytes  TIFF header endianness ('II' or 'MM')         # | 
| 19 |  |  |  |  |  |  | #  2 bytes  TIFF header signature (a fixed value = 42)    # | 
| 20 |  |  |  |  |  |  | #  4 bytes  TIFF header: offset of 0th IFD                # | 
| 21 |  |  |  |  |  |  | # ...IFD... 0th IFD (mandatory, I think)                  # | 
| 22 |  |  |  |  |  |  | # ...IFD... Special effects IFD (optional) linked by IFD0 # | 
| 23 |  |  |  |  |  |  | # ...IFD... Borders IFD (optional) linked by IFD0         # | 
| 24 |  |  |  |  |  |  | #=========================================================# | 
| 25 |  |  |  |  |  |  | # Ref: ... ???                                            # | 
| 26 |  |  |  |  |  |  | ########################################################### | 
| 27 |  |  |  |  |  |  | sub parse_app3 { | 
| 28 | 2 |  |  | 2 | 0 | 6 | my ($this) = @_; | 
| 29 |  |  |  |  |  |  | # decode and save the identifier (it should be 'Meta\000\000' | 
| 30 |  |  |  |  |  |  | # for an APP3 segment) and die if it is not correct. | 
| 31 | 2 |  |  |  |  | 11 | my $identifier = $this->store_record | 
| 32 |  |  |  |  |  |  | ('Identifier', $ASCII, 0, length $APP3_EXIF_TAG)->get_value(); | 
| 33 | 2 | 50 |  |  |  | 9 | $this->die("Incorrect identifier ($identifier)") | 
| 34 |  |  |  |  |  |  | if $identifier ne $APP3_EXIF_TAG; | 
| 35 |  |  |  |  |  |  | # decode the TIFF header (records added automatically in root); | 
| 36 |  |  |  |  |  |  | # it should be located immediately after the identifier | 
| 37 | 2 |  |  |  |  | 16 | my ($tiff_base, $ifd0_link, $endianness) = | 
| 38 |  |  |  |  |  |  | $this->parse_TIFF_header(length $identifier); | 
| 39 |  |  |  |  |  |  | # Remember to convert the ifd0 offset with the TIFF header base. | 
| 40 | 2 |  |  |  |  | 5 | my $ifd0_offset = $tiff_base + $ifd0_link; | 
| 41 |  |  |  |  |  |  | # locally set the current endianness to what we have found. | 
| 42 | 2 |  |  |  |  | 7 | local $this->{endianness} = $endianness; | 
| 43 |  |  |  |  |  |  | # parse all the records of the 0th IFD, as well as their subdirs | 
| 44 | 2 |  |  |  |  | 10 | $this->parse_ifd('IFD0', $ifd0_offset, $tiff_base, 1); | 
| 45 |  |  |  |  |  |  | } | 
| 46 |  |  |  |  |  |  |  | 
| 47 |  |  |  |  |  |  | # successful load | 
| 48 |  |  |  |  |  |  | 1; |