--- amv.pl 2007/07/19 20:17:37 3 +++ amv.pl 2007/07/19 20:49:06 4 @@ -13,6 +13,12 @@ open(my $fh, '<', $path) || die "can't open $path: $!"; +# offset in file +my $o = 0; + +# shared data hash +my $d; + sub hex_dump { my $bytes = shift || return; @@ -20,17 +26,18 @@ $ascii =~ s/\W/./gs; my $hex = unpack('h*', $bytes); $hex =~ s/(..)/$1 /g; - my $o = 0; # calculate number of characters for offset - my $d = length( sprintf("%x",length($bytes)) ); + #my $d = length( sprintf("%x",length($bytes)) ); + my $d = 4; while ( $hex =~ s/^((?:\w\w\s){1,16})// ) { printf "## %0${d}x | %-48s| %s\n", $o, $1, substr( $ascii, 0, 16 ); if ( length($ascii) >= 16 ) { $ascii = substr( $ascii, 16 ); + $o += 16; } else { + $o += length($ascii); last; } - $o += 16; } } @@ -45,9 +52,15 @@ hex_dump( $bytes ); + if ( $bytes eq 'AMV_END_' ) { + warn "## end of file marker AMV_END_\n"; + $d->{eof}++; + return; + } + if ( $format ) { my @data = unpack($format, $bytes); - dump(@data); + warn "## unpacked = ",dump(@data),"\n"; return @data; } else { return $bytes; @@ -57,11 +70,12 @@ sub next_part { my ( $expected_part, $expected_len, $skip ) = @_; my ( $part, $len ) = x(8,'A4V'); + return unless $len; confess "not $expected_part but $part" if $expected_part ne $part; if ( $expected_len ) { confess "expected $expected_len bytes for $part got $len" if $len != $expected_len; } - printf ">> %s | %d 0x%x bytes\n", $part, $len, $len; + printf ">>> %s | %d 0x%x bytes\n", $part, $len, $len; x($len) if $skip; return $len; } @@ -70,9 +84,7 @@ die "not RIFF but $riff" if $riff ne 'RIFF'; die "not AMV but $amv" if $amv ne 'AMV '; -my $d; - -while ( 1 ) { +while ( ! defined($d->{eof}) ) { my ( $list, $name ) = x(12,'A4x4A4'); die "not LIST but $list" if $list ne 'LIST'; print "> $list .. $name\n"; @@ -80,18 +92,7 @@ if ( $name eq 'hdrl' ) { my $len = next_part( 'amvh', hex(38) ); - - print ">> $name $len\n"; - my ( - $ms_per_frame, - $width, - $height, - $fps, - $ss, - $mm, - $hh, - ) = my @names = ( qw/ms_per_frame width height fps ss mm hh/ ); my $h; map { @@ -112,6 +113,19 @@ next_part( 'strh', 0, 1 ); next_part( 'strf', 0, 1 ); + } elsif ( $name eq 'movi' ) { + + while (1) { + my $frame = $d->{movi}++; + + my $len = next_part( '00dc', 0, 1 ); + last unless $len; + printf ">> %s 00dc - frame %d jpeg %d 0x%x bytes\n", $name, $frame, $len, $len; + + my $len = next_part( '01wb', 0, 1 ); + printf ">> %s 01wb - frame %d audio %d 0x%x bytes\n", $name, $frame, $len, $len; + }; + } else { die "unknown $list $name"; }