Ignore:
Timestamp:
2011-06-01T12:33:42+12:00 (13 years ago)
Author:
sjm84
Message:

Updating the ExifTool perl modules

File:
1 edited

Legend:

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

    r16842 r24107  
    66# Revisions:    05/16/2006 - P. Harvey Created
    77#               06/07/2007 - PH Added support for FLV (Flash Video) files
     8#               10/23/2008 - PH Added support for XMP in FLV and SWF
    89#
    910# References:   1) http://www.the-labs.com/MacromediaFlash/SWF-Spec/SWFfileformat.html
    1011#               2) http://sswf.sourceforge.net/SWFalexref.html
    1112#               3) http://osflash.org/flv/
     13#               4) http://www.irisa.fr/texmex/people/dufouil/ffmpegdoxy/flv_8h.html
     14#               5) http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart3.pdf (Oct 2008)
     15#               6) http://www.adobe.com/devnet/swf/pdf/swf_file_format_spec_v9.pdf
     16#               7) http://help.adobe.com/en_US/FlashMediaServer/3.5_Deving/WS5b3ccc516d4fbf351e63e3d11a0773d56e-7ff6.html
     17#               8) http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v10.pdf
    1218#
    1319# Notes:        I'll add AMF3 support if someone sends me a FLV with AMF3 data
     
    2127use Image::ExifTool::FLAC;
    2228
    23 $VERSION = '1.02';
     29$VERSION = '1.09';
    2430
    2531sub ProcessMeta($$$;$);
     32
     33# Meta packets that we process
     34my %processMetaPacket = ( onMetaData => 1, onXMPData => 1 );
    2635
    2736# information extracted from SWF header
    2837%Image::ExifTool::Flash::Main = (
    2938    GROUPS => { 2 => 'Video' },
     39    VARS => { ALPHA_FIRST => 1 },
    3040    NOTES => q{
    31         The information below is extracted from the header of SWF (Shockwave Flash)
    32         files.
     41        The information below is extracted from SWF (Shockwave Flash) files.  Tags
     42        with string ID's represent information extracted from the file header.
    3343    },
    3444    FlashVersion => { },
     
    4050    Duration => {
    4151        Notes => 'calculated from FrameRate and FrameCount',
    42         PrintConv => 'sprintf("%.2f sec",$val)',
     52        PrintConv => 'ConvertDuration($val)',
     53    },
     54    69 => {
     55        Name => 'FileAttributes',
     56        PrintConv => { BITMASK => {
     57            0 => 'UseNetwork',
     58            3 => 'ActionScript3',
     59            4 => 'HasMetadata',
     60        } },
     61    },
     62    77 => {
     63        Name => 'XMP',
     64        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
    4365    },
    4466);
     
    7496        Name => 'AudioEncoding',
    7597        PrintConv => {
    76             0 => 'Uncompressed',
     98            0 => 'PCM-BE (uncompressed)', # PCM-BE according to ref 4
    7799            1 => 'ADPCM',
    78100            2 => 'MP3',
    79             5 => 'Nellymoser 8kHz mono',
     101            3 => 'PCM-LE (uncompressed)', #4
     102            4 => 'Nellymoser 16kHz Mono', #8
     103            5 => 'Nellymoser 8kHz Mono',
    80104            6 => 'Nellymoser',
     105            7 => 'G.711 A-law logarithmic PCM', #8
     106            8 => 'G.711 mu-law logarithmic PCM', #8
     107            # (9 is reserved, ref 8)
     108            10 => 'AAC', #8
     109            11 => 'Speex', #8
     110            13 => 'MP3 8-Khz', #8
     111            15 => 'Device-specific sound', #8
    81112        },
    82113    },
     
    91122    },
    92123    'Bit6' => {
    93         Name => 'AudioSampleBits',
     124        Name => 'AudioBitsPerSample',
    94125        ValueConv => '8 * ($val + 1)',
    95126    },
     
    112143        Name => 'VideoEncoding',
    113144        PrintConv => {
     145            1 => 'JPEG', #8
    114146            2 => 'Sorensen H.263',
    115             3 => 'Screen video',
     147            3 => 'Screen Video',
    116148            4 => 'On2 VP6',
     149            5 => 'On2 VP6 Alpha', #3
     150            6 => 'Screen Video 2', #3
     151            7 => 'H.264', #7 (called "AVC" by ref 8)
    117152        },
    118153    },
     
    132167        Groups => { 2 => 'Audio' },
    133168        ValueConv => '$val * 1000',
    134         PrintConv => 'int($val + 0.5)',
     169        PrintConv => 'ConvertBitrate($val)',
    135170    },
    136171    'audiodelay'    => { Name => 'AudioDelay',      Groups => { 2 => 'Audio' } },
     
    138173    'audiosamplesize'=>{ Name => 'AudioSampleSize', Groups => { 2 => 'Audio' } },
    139174    'audiosize'     => { Name => 'AudioSize',       Groups => { 2 => 'Audio' } },
     175    'bytelength'    => 'ByteLength', # (youtube)
     176    'canseekontime' => 'CanSeekOnTime', # (youtube)
    140177    'canSeekToEnd'  => 'CanSeekToEnd',
    141178    'creationdate'  => {
     
    145182        ValueConv => '$val=~s/\s+$//; $val',    # trim trailing whitespace
    146183    },
     184    'createdby'     => 'CreatedBy', #7
    147185    'cuePoints'     => {
    148186        Name => 'CuePoint',
     
    152190    'duration' => {
    153191        Name => 'Duration',
    154         PrintConv => 'sprintf("%.3fs",$val)',
     192        PrintConv => 'ConvertDuration($val)',
    155193    },
    156194    'filesize'      => 'FileSizeBytes',
     
    165203    'hasVideo'      => 'HasVideo',
    166204    'height'        => 'ImageHeight',
     205    'httphostheader'=> 'HTTPHostHeader', # (youtube)
    167206    'keyframesTimes'=> 'KeyFramesTimes',
    168207    'keyframesFilepositions' => 'KeyFramePositions',
     
    175214        PrintConv => '$self->ConvertDateTime($val)',
    176215    },
     216    'purl'          => 'URL', # (youtube) (what does P mean?)
     217    'pmsg'          => 'Message', # (youtube) (what does P mean?)
     218    'sourcedata'    => 'SourceData', # (youtube)
     219    'starttime'     => { # (youtube)
     220        Name => 'StartTime',
     221        PrintConv => 'ConvertDuration($val)',
     222    },
    177223    'stereo'        => { Name => 'Stereo',          Groups => { 2 => 'Audio' } },
     224    'totalduration' => { # (youtube)
     225        Name => 'TotalDuration',
     226        PrintConv => 'ConvertDuration($val)',
     227    },
     228    'totaldatarate' => { # (youtube)
     229        Name => 'TotalDataRate',
     230        ValueConv => '$val * 1000',
     231        PrintConv => 'int($val + 0.5)',
     232    },
     233    'totalduration' => 'TotalDuration',
    178234    'videocodecid'  => 'VideoCodecID',
    179235    'videodatarate' => {
    180236        Name => 'VideoBitrate',
    181237        ValueConv => '$val * 1000',
    182         PrintConv => 'int($val + 0.5)',
     238        PrintConv => 'ConvertBitrate($val)',
    183239    },
    184240    'videosize'     => 'VideoSize',
    185241    'width'         => 'ImageWidth',
     242    # tags in 'onXMPData' packets
     243    'liveXML'       => { #5
     244        Name => 'XMP',
     245        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     246    },
    186247);
    187248
     
    234295    my $dirLen = $$dirInfo{DirLen} || length($$dataPt);
    235296    my $pos = $$dirInfo{Pos} || 0;
    236     my $verbose = $exifTool->Options('Verbose');
    237297    my ($type, $val, $rec);
    238298
     
    312372                # switch to subdirectory table if necessary
    313373                if ($tagInfo and $$tagInfo{SubDirectory}) {
    314                     $tag = $$tagInfo{Name}; # use our name for the tag
    315                     $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
     374                    my $subTable = $tagInfo->{SubDirectory}->{TagTable};
     375                    # descend into Flash SubDirectory
     376                    if ($subTable =~ /^Image::ExifTool::Flash::/) {
     377                        $tag = $$tagInfo{Name}; # use our name for the tag
     378                        $subTablePtr = GetTagTable($subTable);
     379                    }
    316380                }
    317381                # get object value
     
    332396                if (not $$subTablePtr{$tag} and $tag =~ /^\w+$/) {
    333397                    Image::ExifTool::AddTagToTable($subTablePtr, $tag, { Name => ucfirst($tag) });
    334                     $verbose > 1 and $exifTool->VPrint(1, "  | (adding $tag)\n");
     398                    $exifTool->VPrint(1, "  | (adding $tag)\n");
    335399                }
    336400                $exifTool->HandleTag($subTablePtr, $tag, $v,
     
    383447        last if $single;        # all done if extracting single value
    384448        unless ($isStruct{$type}) {
    385             # only process "onMetaData" Meta packets
     449            # only process certain Meta packets
    386450            if ($type == 0x02 and not $rec) {
    387                 my $verb = ($val eq 'onMetaData') ? 'processing' : 'ignoring';
     451                my $verb = $processMetaPacket{$val} ? 'processing' : 'ignoring';
    388452                $exifTool->VPrint(0, "  | ($verb $val information)\n");
    389                 last unless $val eq 'onMetaData';
     453                last unless $processMetaPacket{$val};
    390454            } else {
    391455                # give verbose indication if we ignore a lone value
     
    477541
    478542#------------------------------------------------------------------------------
     543# Read data from possibly compressed file
     544# Inputs: 0) RAF reference, 1) data buffer, 2) bytes to read, 2) compressed flag
     545# Returns: number of bytes read (may be greater than requested bytes if compressed)
     546# - concatenates data to current buffer
     547# - updates compressed flag with reference to inflate object for future calls
     548#   (or sets to error message and returns zero on error)
     549sub ReadCompressed($$$$)
     550{
     551    my ($raf, $len, $inflate) = ($_[0], $_[2], $_[3]);
     552    my $buff;
     553    unless ($raf->Read($buff, $len)) {
     554        $_[3] = 'Error reading file';
     555        return 0;
     556    }
     557    # uncompress if necessary
     558    if ($inflate) {
     559        unless (ref $inflate) {
     560            unless (eval 'require Compress::Zlib') {
     561                $_[3] = 'Install Compress::Zlib to extract compressed information';
     562                return 0;
     563            }
     564            $inflate = Compress::Zlib::inflateInit();
     565            unless ($inflate) {
     566                $_[3] = 'Error initializing inflate for Flash data';
     567                return 0;
     568            }
     569            $_[3] = $inflate;   # pass inflate object back to caller
     570        }
     571        my $tmp = $buff;
     572        $buff = '';
     573        # read 64 more bytes at a time and inflate until we get enough uncompressed data
     574        for (;;) {
     575            my ($dat, $stat) = $inflate->inflate($tmp);
     576            if ($stat == Compress::Zlib::Z_STREAM_END() or
     577                $stat == Compress::Zlib::Z_OK())
     578            {
     579                $buff .= $dat;  # add inflated data to buffer
     580                last if length $buff >= $len or $stat == Compress::Zlib::Z_STREAM_END();
     581                $raf->Read($tmp,64) or last;    # must read a bit more data
     582            } else {
     583                $buff = '';
     584                last;
     585            }
     586        }
     587        $_[3] = 'Error inflating compressed Flash data' unless length $buff;
     588    }
     589    $_[1] = defined $_[1] ? $_[1] . $buff : $buff;
     590    return length $buff;
     591}
     592
     593#------------------------------------------------------------------------------
    479594# Read information frame a Flash file
    480595# Inputs: 0) ExifTool object reference, 1) Directory information reference
     
    483598{
    484599    my ($exifTool, $dirInfo) = @_;
    485     my $verbose = $exifTool->Options('Verbose');
    486600    my $raf = $$dirInfo{RAF};
    487     my $buff;
     601    my ($buff, $hasMeta);
    488602
    489603    $raf->Read($buff, 8) == 8 or return 0;
     
    491605    my ($compressed, $vers) = ($1 eq 'C' ? 1 : 0, ord($2));
    492606
    493     # read the first bit of the file
    494     $raf->Read($buff, 64) or return 0;
    495 
     607    SetByteOrder('II');
    496608    $exifTool->SetFileType();
    497609    GetTagTable('Image::ExifTool::Flash::Main');  # make sure table is initialized
     
    500612    FoundFlashTag($exifTool, Compressed => $compressed);
    501613
    502     # uncompress if necessary
    503     if ($compressed) {
    504         unless (eval 'require Compress::Zlib') {
    505             $exifTool->Warn('Install Compress::Zlib to extract compressed information');
    506             return 1;
    507         }
    508         my $inflate = Compress::Zlib::inflateInit();
    509         my $tmp = $buff;
    510         $buff = '';
    511         # read file 64 bytes at a time and inflate until we get enough uncompressed data
    512         for (;;) {
    513             unless ($inflate) {
    514                 $exifTool->Warn('Error inflating compressed Flash data');
    515                 return 1;
    516             }
    517             my ($dat, $stat) = $inflate->inflate($tmp);
    518             if ($stat == Compress::Zlib::Z_STREAM_END() or
    519                 $stat == Compress::Zlib::Z_OK())
    520             {
    521                 $buff .= $dat;  # add inflated data to buffer
    522                 last if length $buff >= 64 or $stat == Compress::Zlib::Z_STREAM_END();
    523                 $raf->Read($tmp,64) or last;    # read some more data
    524             } else {
    525                 undef $inflate; # issue warning the next time around
    526             }
    527         }
     614    # read the next 64 bytes of the file (and inflate if necessary)
     615    $buff = '';
     616    unless (ReadCompressed($raf, $buff, 64, $compressed)) {
     617        $exifTool->Warn($compressed) if $compressed;
     618        return 1;
    528619    }
     620
    529621    # unpack elements of bit-packed Flash Rect structure
    530     my ($nBits, $totBits, $nBytes);
    531     for (;;) {
    532         if (length($buff)) {
    533             $nBits = unpack('C', $buff) >> 3;    # bits in x1,x2,y1,y2 elements
    534             $totBits = 5 + $nBits * 4;           # total bits in Rect structure
    535             $nBytes = int(($totBits + 7) / 8);   # byte length of Rect structure
    536             last if length $buff >= $nBytes + 4; # make sure header is long enough
    537         }
     622    my $nBits = unpack('C', $buff) >> 3;    # bits in x1,x2,y1,y2 elements
     623    my $totBits = 5 + $nBits * 4;           # total bits in Rect structure
     624    my $nBytes = int(($totBits + 7) / 8);   # byte length of Rect structure
     625    if (length $buff < $nBytes + 4) {
    538626        $exifTool->Warn('Truncated Flash file');
    539627        return 1;
     
    555643    FoundFlashTag($exifTool, Duration => $vals[1] * 256 / $vals[0]) if $vals[0];
    556644
     645    # scan through the tags to find FileAttributes and XMP
     646    $buff = substr($buff, $nBytes + 4);
     647    for (;;) {
     648        my $buffLen = length $buff;
     649        last if $buffLen < 2;
     650        my $code = Get16u(\$buff, 0);
     651        my $pos = 2;
     652        my $tag = $code >> 6;
     653        my $size = $code & 0x3f;
     654        $exifTool->VPrint(1, "SWF tag $tag ($size bytes):\n");
     655        last unless $tag == 69 or $tag == 77 or $hasMeta;
     656        # read enough to get a complete short record
     657        if ($pos + $size > $buffLen) {
     658            # (read 2 extra bytes if available to get next tag word)
     659            unless (ReadCompressed($raf, $buff, $size + 2, $compressed)) {
     660                $exifTool->Warn($compressed) if $compressed;
     661                return 1;
     662            }
     663            $buffLen = length $buff;
     664            last if $pos + $size > $buffLen;
     665        }
     666        # read extended record if necessary
     667        if ($size == 0x3f) {
     668            last if $pos + 4 > $buffLen;
     669            $size = Get32u(\$buff, $pos);
     670            $pos += 4;
     671            last if $size > 1000000; # don't read anything huge
     672            if ($pos + $size > $buffLen) {
     673                unless (ReadCompressed($raf, $buff, $size + 2, $compressed)) {
     674                    $exifTool->Warn($compressed) if $compressed;
     675                    return 1;
     676                }
     677                $buffLen = length $buff;
     678                last if $pos + $size > $buffLen;
     679            }
     680            $exifTool->VPrint(1, "  [extended size $size bytes]\n");
     681        }
     682        if ($tag == 69) {       # FileAttributes
     683            last unless $size;
     684            my $flags = Get8u(\$buff, $pos);
     685            FoundFlashTag($exifTool, $tag => $flags);
     686            last unless $flags & 0x10;  # only continue if we have metadata (XMP)
     687            $hasMeta = 1;
     688        } elsif ($tag == 77) {  # Metadata
     689            my $val = substr($buff, $pos, $size);
     690            FoundFlashTag($exifTool, $tag => $val);
     691            last;
     692        }
     693        last if $pos + 2 > $buffLen;
     694        $buff = substr($buff, $pos);    # remove everything before the next tag
     695    }
    557696    return 1;
    558697}
     
    583722=head1 AUTHOR
    584723
    585 Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
     724Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
    586725
    587726This library is free software; you can redistribute it and/or modify it
     
    598737=item L<http://osflash.org/flv/>
    599738
     739=item L<http://www.irisa.fr/texmex/people/dufouil/ffmpegdoxy/flv_8h.html>
     740
     741=item L<http://help.adobe.com/en_US/FlashMediaServer/3.5_Deving/WS5b3ccc516d4fbf351e63e3d11a0773d56e-7ff6.html>
     742
     743=item L<http://www.adobe.com/devnet/swf/pdf/swf_file_format_spec_v9.pdf>
     744
     745=item L<http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v10.pdf>
     746
    600747=back
    601748
Note: See TracChangeset for help on using the changeset viewer.