123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- #------------------------------------------------------------------------------
- # File: MIFF.pm
- #
- # Description: Read Magick Image File Format meta information
- #
- # Revisions: 06/10/2005 - P. Harvey Created
- #
- # References: 1) http://www.imagemagick.org/script/miff.php
- # 2) http://www.cs.uni.edu/Help/ImageMagick/www/miff.html
- #------------------------------------------------------------------------------
- package Image::ExifTool::MIFF;
- use strict;
- use vars qw($VERSION);
- use Image::ExifTool qw(:DataAccess :Utils);
- $VERSION = '1.07';
- # MIFF chunks
- %Image::ExifTool::MIFF::Main = (
- GROUPS => { 2 => 'Image' },
- NOTES => q{
- The MIFF (Magick Image File Format) format allows aribrary tag names to be
- used. Only the standard tag names are listed below, however ExifTool will
- decode any tags found in the image.
- },
- 'background-color' => 'BackgroundColor',
- 'blue-primary' => 'BluePrimary',
- 'border-color' => 'BorderColor',
- 'matt-color' => 'MattColor',
- class => 'Class',
- colors => 'Colors',
- colorspace => 'ColorSpace',
- columns => 'ImageWidth',
- compression => 'Compression',
- delay => 'Delay',
- depth => 'Depth',
- dispose => 'Dispose',
- gamma => 'Gamma',
- 'green-primary' => 'GreenPrimary',
- id => 'ID',
- iterations => 'Iterations',
- label => 'Label',
- matte => 'Matte',
- montage => 'Montage',
- packets => 'Packets',
- page => 'Page',
- # profile tags. Note the SubDirectory is not used by ProcessMIFF(),
- # but is inserted for documentation purposes only
- 'profile-APP1' => [
- # [this list is just for the sake of the documentation]
- {
- Name => 'APP1_Profile',
- SubDirectory => {
- TagTable => 'Image::ExifTool::Exif::Main',
- },
- },
- {
- Name => 'APP1_Profile',
- SubDirectory => {
- TagTable => 'Image::ExifTool::XMP::Main',
- },
- },
- ],
- 'profile-exif' => { # haven't seen this, but it would make sense - PH
- Name => 'EXIF_Profile',
- SubDirectory => {
- TagTable => 'Image::ExifTool::Exif::Main',
- },
- },
- 'profile-icc' => {
- Name => 'ICC_Profile',
- SubDirectory => {
- TagTable => 'Image::ExifTool::ICC_Profile::Main',
- },
- },
- 'profile-iptc' => {
- Name => 'IPTC_Profile',
- SubDirectory => {
- TagTable => 'Image::ExifTool::Photoshop::Main',
- },
- },
- 'profile-xmp' => { # haven't seen this, but it would make sense - PH
- Name => 'XMP_Profile',
- SubDirectory => {
- TagTable => 'Image::ExifTool::XMP::Main',
- },
- },
- 'red-primary' => 'RedPrimary',
- 'rendering-intent' => 'RenderingIntent',
- resolution => 'Resolution',
- rows => 'ImageHeight',
- scene => 'Scene',
- signature => 'Signature',
- units => 'Units',
- 'white-point' => 'WhitePoint',
- );
- #------------------------------------------------------------------------------
- # Extract meta information from a MIFF image
- # Inputs: 0) ExifTool object reference, 1) dirInfo reference
- # Returns: 1 on success, 0 if this wasn't a valid MIFF image
- sub ProcessMIFF($$)
- {
- my ($et, $dirInfo) = @_;
- my $raf = $$dirInfo{RAF};
- my $verbose = $$et{OPTIONS}{Verbose};
- my ($hdr, $buff);
- # validate the MIFF file (note: MIFF files _may_ begin with other
- # characters, but this starting sequence is strongly suggested.)
- return 0 unless $raf->Read($hdr, 14) == 14;
- return 0 unless $hdr eq 'id=ImageMagick';
- $et->SetFileType(); # set the FileType tag
- # set end-of-line character sequence to read to end of the TEXT
- # section for new-type MIFF files (text ends with Colon+Ctrl-Z)
- # Old MIFF files end with Colon+Linefeed, so this will likely
- # slurp those entire files, which will be slower, but will work
- # OK except that the profile information won't be decoded
- local $/ = ":\x1a";
- my $mode = '';
- my @profiles;
- if ($raf->ReadLine($buff)) {
- chomp $buff; # remove end-of-line chars
- my $tagTablePtr = GetTagTable('Image::ExifTool::MIFF::Main');
- my @entries = split ' ', $buff;
- unshift @entries, $hdr; # put the ID back in
- my ($tag, $val);
- foreach (@entries) {
- if ($mode eq 'com') {
- $mode = '' if /\}$/;
- next;
- } elsif (/^\{/) {
- $mode = 'com'; # read to the end of the comment
- next;
- }
- if ($mode eq 'val') {
- $val .= " $_"; # join back together with a space
- next unless /\}$/;
- $mode = '';
- $val =~ s/(^\{|\}$)//g; # remove braces
- } elsif (/(.+)=(.+)/) {
- ($tag, $val) = ($1, $2);
- if ($val =~ /^\{/) {
- $mode = 'val'; # read to the end of the value data
- next;
- }
- } elsif (/^:/) {
- # this could be the end of an old-style MIFF file
- last;
- } else {
- # something we don't recognize -- stop parsing here
- $et->Warn('Unrecognized MIFF data');
- last;
- }
- my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
- unless ($tagInfo) {
- $tagInfo = { Name => $tag };
- AddTagToTable($tagTablePtr, $tag, $tagInfo);
- }
- $verbose and $et->VerboseInfo($tag, $tagInfo,
- Table => $tagTablePtr,
- DataPt => \$val,
- );
- # handle profile tags specially
- if ($tag =~ /^profile-(.*)/) {
- push @profiles, [$1, $val];
- } else {
- $et->FoundTag($tagInfo, $val);
- }
- }
- }
- # process profile information
- foreach (@profiles) {
- my ($type, $len) = @{$_};
- unless ($len =~ /^\d+$/) {
- $et->Warn("Invalid length for $type profile");
- last; # don't try to read the rest
- }
- unless ($raf->Read($buff, $len) == $len) {
- $et->Warn("Error reading $type profile ($len bytes)");
- next;
- }
- my $processed = 0;
- my %dirInfo = (
- Parent => 'PNG',
- DataPt => \$buff,
- DataPos => $raf->Tell() - $len,
- DataLen => $len,
- DirStart => 0,
- DirLen => $len,
- );
- if ($type eq 'icc') {
- # ICC Profile information
- my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
- $processed = $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
- } elsif ($type eq 'iptc') {
- if ($buff =~ /^8BIM/) {
- # Photoshop information
- my $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
- $processed = $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
- }
- # I haven't seen 'exif' or 'xmp' profile types yet, but I have seen them
- # in newer PNG files so presumably they are possible here as well - PH
- } elsif ($type eq 'APP1' or $type eq 'exif' or $type eq 'xmp') {
- if ($buff =~ /^$Image::ExifTool::exifAPP1hdr/) {
- # APP1 EXIF
- my $hdrLen = length($Image::ExifTool::exifAPP1hdr);
- $dirInfo{DirStart} += $hdrLen;
- $dirInfo{DirLen} -= $hdrLen;
- # use the usual position for EXIF data: 12 bytes from start of file
- # (this may be wrong, but I can't see where the PNG stores this information)
- $dirInfo{Base} = 12; # this is the usual value
- $processed = $et->ProcessTIFF(\%dirInfo);
- } elsif ($buff =~ /^$Image::ExifTool::xmpAPP1hdr/) {
- # APP1 XMP
- my $hdrLen = length($Image::ExifTool::xmpAPP1hdr);
- my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
- $dirInfo{DirStart} += $hdrLen;
- $dirInfo{DirLen} -= $hdrLen;
- $processed = $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
- }
- }
- unless ($processed) {
- $et->Warn("Unknown MIFF $type profile data");
- if ($verbose) {
- $et->VerboseDir($type, 0, $len);
- $et->VerboseDump(\$buff);
- }
- }
- }
- return 1;
- }
- 1; # end
- __END__
- =head1 NAME
- Image::ExifTool::MIFF - Read Magick Image File Format meta information
- =head1 SYNOPSIS
- This module is used by Image::ExifTool
- =head1 DESCRIPTION
- This module contains routines required by Image::ExifTool to read MIFF
- (Magick Image File Format) images.
- =head1 AUTHOR
- Copyright 2003-2016, Phil Harvey (phil at owl.phy.queensu.ca)
- This library is free software; you can redistribute it and/or modify it
- under the same terms as Perl itself.
- =head1 REFERENCES
- =over 4
- =item L<http://www.imagemagick.org/script/miff.php>
- =item L<http://www.cs.uni.edu/Help/ImageMagick/www/miff.html>
- =back
- =head1 SEE ALSO
- L<Image::ExifTool::TagNames/MIFF Tags>,
- L<Image::ExifTool(3pm)|Image::ExifTool>
- =cut
|