/[amv]/amv.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /amv.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 14 by dpavlin, Sat Jul 21 10:28:39 2007 UTC revision 24 by dpavlin, Sun Jul 22 11:05:47 2007 UTC
# Line 9  Line 9 
9  # http://en.wikipedia.org/wiki/RIFF_(File_format)  # http://en.wikipedia.org/wiki/RIFF_(File_format)
10  # http://www.obrador.com/essentialjpeg/HeaderInfo.htm  # http://www.obrador.com/essentialjpeg/HeaderInfo.htm
11  # http://lists.helixcommunity.org/pipermail/datatype-dev/2005-January/001886.html  # http://lists.helixcommunity.org/pipermail/datatype-dev/2005-January/001886.html
12    # http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm
13    
14  use strict;  use strict;
15    
16  use Data::Dump qw/dump/;  use Data::Dump qw/dump/;
17  use Carp qw/confess/;  use Carp qw/confess/;
18  use File::Path;  use File::Path;
19    use Getopt::Long;
20    
21  my $dump = 0;  my $dump = 0;
22  my $debug = 0;  my $debug = 0;
23    my $verbose = 0;
24    my $dump_dir = '/tmp/dump/';
25    my $dump_avi = "dump.avi";
26    my $no_jpeg_header = 0;
27    my $jpeg_q = 100;
28    my $jpegtran;
29    
30    GetOptions(
31            "dump!"                 => \$dump,
32            "debug!"                => \$debug,
33            "dump-dir=s"    => \$dump_dir,
34            "no-jpeg-headers!" => \$no_jpeg_header,
35            "jpegtran=s"    => \$jpegtran,
36            "verbose!"              => \$verbose,
37    );
38    
39  my $path = shift @ARGV || die "usage: $0 movie.amv\n";  my $path = shift @ARGV || die "usage: $0 movie.amv\n";
40    
41  my $dump_dir = '/tmp/dump/';  # by default, flip frames
42    #$jpegtran = '-flip vertical' unless defined($jpegtran);
43    
44  rmtree $dump_dir if -e $dump_dir;  rmtree $dump_dir if -e $dump_dir;
45  mkpath $dump_dir || die "can't create $dump_dir: $!";  mkpath $dump_dir || die "can't create $dump_dir: $!";
46    
# Line 80  sub x { Line 99  sub x {
99          hex_dump( $bytes );          hex_dump( $bytes );
100    
101          if ( $bytes eq 'AMV_END_' ) {          if ( $bytes eq 'AMV_END_' ) {
102                  warn "> end of file marker AMV_END_\n";                  print "> end of file marker AMV_END_\n" if $dump;
103                  $d->{eof}++;                  $d->{eof}++;
104                  return;                  return;
105          }          }
106    
107          if ( $format ) {          if ( $format ) {
108                  my @data = unpack($format, $bytes);                  my @data = unpack($format, $bytes);
109                  warn "## unpacked = ",dump(@data),"\n" if $debug;                  print "## unpacked = ",dump(@data),"\n" if $debug;
110                  return @data;                  return @data;
111          } else {          } else {
112                  return $bytes;                  return $bytes;
# Line 102  sub next_part { Line 121  sub next_part {
121          if ( $expected_len ) {          if ( $expected_len ) {
122                  confess "expected $expected_len bytes for $part got $len" if $len != $expected_len;                  confess "expected $expected_len bytes for $part got $len" if $len != $expected_len;
123          }          }
124          printf "<< %s - %d 0x%x bytes\n", $part, $len, $len;          printf "## next_part %s - %d 0x%x bytes\n", $part, $len, $len if $debug;
125          x($len) if $skip;          x($len) if $skip;
126          return $len;          return $len;
127  }  }
128    
129  sub huffman {  sub quality {
130            my @table = @_;
131            die "quantization matrice needs to have 64 bytes!" if $#table != 63;
132    
133            my $in = join('', map { chr($_) } @table );
134            my $out;
135    
136            foreach my $t ( @table ) {
137                    $t = int( ( $t * $jpeg_q ) / 100 );
138                    $t = 255 if $t > 255;
139                    $out .= chr($t);
140            }
141    
142  # JPEG DHT Segment for YCrCb omitted from MJPG data          if ( $dump ) {
143  return                  print "## quantization table original\n";
144  "\xFF\xC4\x01\xA2" .                  hex_dump( $in );
145  "\x00\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00" .                  print "## quantization table for $jpeg_q %\n";
146  "\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x01" .                  hex_dump( $out );
147  "\x00\x03\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00" .          }
 "\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x10\x00" .  
 "\x02\x01\x03\x03\x02\x04\x03\x05\x05\x04\x04\x00\x00\x01\x7D" .  
 "\x01\x02\x03\x00\x04\x11\x05\x12\x21\x31\x41\x06\x13\x51\x61" .  
 "\x07\x22\x71\x14\x32\x81\x91\xA1\x08\x23\x42\xB1\xC1\x15\x52" .  
 "\xD1\xF0\x24\x33\x62\x72\x82\x09\x0A\x16\x17\x18\x19\x1A\x25" .  
 "\x26\x27\x28\x29\x2A\x34\x35\x36\x37\x38\x39\x3A\x43\x44\x45" .  
 "\x46\x47\x48\x49\x4A\x53\x54\x55\x56\x57\x58\x59\x5A\x63\x64" .  
 "\x65\x66\x67\x68\x69\x6A\x73\x74\x75\x76\x77\x78\x79\x7A\x83" .  
 "\x84\x85\x86\x87\x88\x89\x8A\x92\x93\x94\x95\x96\x97\x98\x99" .  
 "\x9A\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xB2\xB3\xB4\xB5\xB6" .  
 "\xB7\xB8\xB9\xBA\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xD2\xD3" .  
 "\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8" .  
 "\xE9\xEA\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\x11\x00\x02" .  
 "\x01\x02\x04\x04\x03\x04\x07\x05\x04\x04\x00\x01\x02\x77\x00" .  
 "\x01\x02\x03\x11\x04\x05\x21\x31\x06\x12\x41\x51\x07\x61\x71" .  
 "\x13\x22\x32\x81\x08\x14\x42\x91\xA1\xB1\xC1\x09\x23\x33\x52" .  
 "\xF0\x15\x62\x72\xD1\x0A\x16\x24\x34\xE1\x25\xF1\x17\x18\x19" .  
 "\x1A\x26\x27\x28\x29\x2A\x35\x36\x37\x38\x39\x3A\x43\x44\x45" .  
 "\x46\x47\x48\x49\x4A\x53\x54\x55\x56\x57\x58\x59\x5A\x63\x64" .  
 "\x65\x66\x67\x68\x69\x6A\x73\x74\x75\x76\x77\x78\x79\x7A\x82" .  
 "\x83\x84\x85\x86\x87\x88\x89\x8A\x92\x93\x94\x95\x96\x97\x98" .  
 "\x99\x9A\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xB2\xB3\xB4\xB5" .  
 "\xB6\xB7\xB8\xB9\xBA\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xD2" .  
 "\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xE2\xE3\xE4\xE5\xE6\xE7\xE8" .  
 "\xE9\xEA\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA";  
148    
149            return $out;
150  }  }
151    
152    sub mp3_frame {
153            my $frame = join('',
154                    # Frame sync (all bits set)
155                    1 x 11 .
156                    # MPEG Audio version ID
157                    # 00 - MPEG Version 2.5 (unofficial)
158                    # 01 - reserved
159                    # 10 - MPEG Version 2 (ISO/IEC 13818-3)
160                    # 11 - MPEG Version 1 (ISO/IEC 11172-3)
161                    1,0,
162                    # Layer description
163                    # 00 - reserved
164                    # 01 - Layer III
165                    # 10 - Layer II
166                    # 11 - Layer I
167                    0,1,
168                    # Protection bit
169                    # 0 - Protected by CRC (16bit crc follows header)
170                    # 1 - Not protected
171                    0,
172                    # Bitrate index
173                    0,0,0,0,
174                    # Sampling rate frequency index (22050)
175                    0,0,
176                    # Padding bit
177                    # 0 - frame is not padded
178                    # 1 - frame is padded with one extra slot
179                    0,
180                    # Private bit
181                    0,
182                    # Channel Mode
183                    # 00 - Stereo
184                    # 01 - Joint stereo (Stereo)
185                    # 10 - Dual channel (2 mono channels)
186                    # 11 - Single channel (Mono)
187                    1,1,
188                    # Mode extension (Only if Joint stereo)
189                    0,0,
190                    # Copyright
191                    0,
192                    # Original
193                    0,
194                    # Emphasis
195                    # 00 - none
196                    # 01 - 50/15 ms
197                    # 10 - reserved
198                    # 11 - CCIT J.17
199                    0,0,
200            );
201    
202            die "frame must have 32 bits, not ", length($frame), " for $frame" if length($frame) != 32;
203    
204            my $bits = pack("b32", $frame);
205    
206            die "packed bits must be 4 bytes, not $bits" if length($bits) != 4;
207    
208            my $t = $frame;
209            $t =~ s/(.{8})/$1 /g;
210            warn "## mp3 frame frame = $t\n";
211    
212            return $bits;
213    }
214    
215    my @subframes;
216    my $frame_nr = 1;
217    
218    # how many subframes to join into single frame?
219    my $join_subframes = 0;
220    
221  sub mkjpg {  sub mkjpg {
222          my ($path,$data) = @_;          my ($data) = @_;
         open(my $fh, '>', $path) || die "can't create $path: $!";  
223    
224          confess "no SOI marker in data" if substr($data,0,2) ne "\xFF\xD8";          confess "no SOI marker in data" if substr($data,0,2) ne "\xFF\xD8";
225          $data = substr($data,2);          confess "no EOI marker in data" if substr($data,-2,2) ne "\xFF\xD9";
226            $data = substr($data,2,-2);
227    
228            if ( $#subframes < ( $join_subframes - 1 ) ) {
229                    push @subframes, $data;
230                    print "## saved $frame_nr/", $#subframes + 1, " subframe of ", length($data), " bytes\n" if $debug;
231                    return;
232            }
233    
234            my $w = $d->{amvh}->{width} || die "no width?";
235            my $h = $d->{amvh}->{height} || confess "no height?";
236    
237          my $header =          my $header =
238                  "\xFF\xD8".     # Start of Image (SOI) marker          # Start of Image (SOI) marker
239  #------------------------------------------------------------------          "\xFF\xD8".
240                  "\xFF\xE0".     # JFIF marker          # JFIF marker
241            "\xFF\xE0".
242          pack("nZ5CCCnnCC",          pack("nZ5CCCnnCC",
243                  16,                     # length                  16,                     # length
244                  'JFIF',         # identifier                  'JFIF',         # identifier (JFIF)
245                  1,1,            # version                  1,1,            # version
246                  0,                      # units (none)                  0,                      # units (none)
247                  1,1,            # X,Y density                  1,1,            # X,Y density
248                  0,0,            # X,Y thumbnail                  0,0,            # X,Y thumbnail
249          ).          ).
250  #------------------------------------------------------------------          "\xFF\xFE".
251          "\xFF\xC0".     # Start of frame          "\x00\x3CCREATOR: amv dumper (compat. IJG JPEG v62), quality = 100\n".
252            # quantization table (quaility=100%)
253            "\xFF\xDB".
254            "\x00\x43".
255            # 8 bit values, table 1
256            "\x00".
257            quality(
258        0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E,
259        0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
260        0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
261        0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33,
262        0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44,
263        0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57,
264        0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71,
265        0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63,
266            ).
267            "\xFF\xDB".
268            "\x00\x43".
269            # 8 bit values, table 1
270            "\x01".
271            quality(
272        0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2F, 0x1A,
273        0x1A, 0x2F, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
274        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
275        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
276        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
277        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
278        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
279        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
280            ).
281            # start of frame
282            "\xFF\xC0".
283          pack("ncnncc9",          pack("ncnncc9",
284                  17,                     # len                  17,                     # len
285                  8,                      # sample precision in bits                  8,                      # sample precision in bits
286                  120,160,        # X,Y size                  $h,$w,          # X,Y size
287                  3,                      # number of components                  3,                      # number of components
288                  1,0x21,0,       # Component ID, H+V sampling factors, Quantization table number                  1,0x22,0,       # Component ID, H+V sampling factors, Quantization table number
289                  2,0x11,1,                  2,0x11,1,
290                  3,0x11,1,                  3,0x11,1,
291          ).          ).
 #------------------------------------------------------------------  
         "\xFF\xDB".             # Define Quantization table marker  
         "\x00\x84".             # len  
         "\x00".                 # 8 bit values, (byte) table 0  
         "\x10\x0B\x0C\x0E\x0C".  
         "\x0A\x10\x0E\x0D\x0E".  
         "\x12\x11\x10\x13\x18".  
         "\x28\x1A\x18\x16\x16".  
         "\x18\x31\x23\x25\x1D".  
         "\x28\x3A\x33\x3D\x3C".  
         "\x39\x33\x38\x37\x40".  
         "\x48\x5C\x4E\x40\x44".  
         "\x57\x45\x37\x38\x50".  
         "\x6D\x51\x57\x5F\x62".  
         "\x67\x68\x67\x3E\x4D".  
         "\x71\x79\x70\x64\x78".  
         "\x5C\x65\x67\x63".  
         "\x01".         # 8 bit values, (byte) table 1  
         "\x11\x12\x12\x18\x15".  
         "\x18\x2F\x1A\x1A\x2F".  
         "\x63\x42\x38\x42\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63".  
 #------------------------------------------------------------------  
 #       huffman("\x00").        # 0 DC  
 #       huffman("\x01").        # 1 DC  
 #       huffman("\x10").        # 0 AC  
 #       huffman("\x11").        # 1 AC  
 #------------------------------------------------------------------  
         # Define huffman table (section B.2.4.1)  
         "\xFF\xC4".             # Marker  
         "\x00\x1F".             # Length (31 bytes)  
         "\x00".                 # DC, (byte) table 0  
         "\x00\x01\x05\x01\x01".  
         "\x01\x01\x01\x01\x00".  
         "\x00\x00\x00\x00\x00".  
         "\x00\x00\x01\x02\x03".  
         "\x04\x05\x06\x07\x08".  
         "\x09\x0A\x0B".  
         # Define huffman table (section B.2.4.1)  
         "\xFF\xC4".             # Marker  
         "\x00\xB5".             # Length (181 bytes)  
         "\x10".                 # AC, (byte) table 0  
         "\x00\x02\x01\x03\x03".  
         "\x02\x04\x03\x05\x05".  
         "\x04\x04\x00\x00\x01".  
         "\x7D\x01\x02\x03\x00".  
         "\x04\x11\x05\x12\x21".  
         "\x31\x41\x06\x13\x51".  
         "\x61\x07\x22\x71\x14".  
         "\x32\x81\x91\xA1\x08".  
         "\x23\x42\xB1\xC1\x15".  
         "\x52\xD1\xF0\x24\x33".  
         "\x62\x72\x82\x09\x0A".  
         "\x16\x17\x18\x19\x1A".  
         "\x25\x26\x27\x28\x29".  
         "\x2A\x34\x35\x36\x37".  
         "\x38\x39\x3A\x43\x44".  
         "\x45\x46\x47\x48\x49".  
         "\x4A\x53\x54\x55\x56".  
         "\x57\x58\x59\x5A\x63".  
         "\x64\x65\x66\x67\x68".  
         "\x69\x6A\x73\x74\x75".  
         "\x76\x77\x78\x79\x7A".  
         "\x83\x84\x85\x86\x87".  
         "\x88\x89\x8A\x92\x93".  
         "\x94\x95\x96\x97\x98".  
         "\x99\x9A\xA2\xA3\xA4".  
         "\xA5\xA6\xA7\xA8\xA9".  
         "\xAA\xB2\xB3\xB4\xB5".  
         "\xB6\xB7\xB8\xB9\xBA".  
         "\xC2\xC3\xC4\xC5\xC6".  
         "\xC7\xC8\xC9\xCA\xD2".  
         "\xD3\xD4\xD5\xD6\xD7".  
         "\xD8\xD9\xDA\xE1\xE2".  
         "\xE3\xE4\xE5\xE6\xE7".  
         "\xE8\xE9\xEA\xF1\xF2".  
         "\xF3\xF4\xF5\xF6\xF7".  
         "\xF8\xF9\xFA".  
         # Define huffman table (section B.2.4.1)  
         "\xFF\xC4".             # Marker  
         "\x00\x1F".             # Length (31 bytes)  
         "\x01".                 # DC, (byte) table 1  
         "\x00\x03\x01\x01\x01".  
         "\x01\x01\x01\x01\x01".  
         "\x01\x00\x00\x00\x00".  
         "\x00\x00\x01\x02\x03".  
         "\x04\x05\x06\x07\x08".  
         "\x09\x0A\x0B".  
         # Define huffman table (section B.2.4.1)  
         "\xFF\xC4".             # Marker  
         "\x00\xB5".             # Length (181 bytes)  
         "\x11".                 # AC, (byte) table 1  
         "\x00\x02\x01\x02\x04".  
         "\x04\x03\x04\x07\x05".  
         "\x04\x04\x00\x01\x02".  
         "\x77\x00\x01\x02\x03".  
         "\x11\x04\x05\x21\x31".  
         "\x06\x12\x41\x51\x07".  
         "\x61\x71\x13\x22\x32".  
         "\x81\x08\x14\x42\x91".  
         "\xA1\xB1\xC1\x09\x23".  
         "\x33\x52\xF0\x15\x62".  
         "\x72\xD1\x0A\x16\x24".  
         "\x34\xE1\x25\xF1\x17".  
         "\x18\x19\x1A\x26\x27".  
         "\x28\x29\x2A\x35\x36".  
         "\x37\x38\x39\x3A\x43".  
         "\x44\x45\x46\x47\x48".  
         "\x49\x4A\x53\x54\x55".  
         "\x56\x57\x58\x59\x5A".  
         "\x63\x64\x65\x66\x67".  
         "\x68\x69\x6A\x73\x74".  
         "\x75\x76\x77\x78\x79".  
         "\x7A\x82\x83\x84\x85".  
         "\x86\x87\x88\x89\x8A".  
         "\x92\x93\x94\x95\x96".  
         "\x97\x98\x99\x9A\xA2".  
         "\xA3\xA4\xA5\xA6\xA7".  
         "\xA8\xA9\xAA\xB2\xB3".  
         "\xB4\xB5\xB6\xB7\xB8".  
         "\xB9\xBA\xC2\xC3\xC4".  
         "\xC5\xC6\xC7\xC8\xC9".  
         "\xCA\xD2\xD3\xD4\xD5".  
         "\xD6\xD7\xD8\xD9\xDA".  
         "\xE2\xE3\xE4\xE5\xE6".  
         "\xE7\xE8\xE9\xEA\xF2".  
         "\xF3\xF4\xF5\xF6\xF7".  
         "\xF8\xF9\xFA".  
 #------------------------------------------------------------------  
                 "\xFF\xDA".     # Start of Scan marker  
         pack("nC11",  
                 12,                     # length  
                 3,                      # number of components  
                 1,0x00,         # Scan 1: use DC/AC huff tables 0/0  
                 2,0x11,         # Scan 2: use DC/AC huff tables 1/1  
                 3,0x11,         # Scan 3: use DC/AC huff tables 1/1  
                 0,0x3f,         # Ss, Se  
                 0,                      # Ah, Ai (not used)  
         );  
 #------------------------------------------------------------------  
   
         my $header =  
         # SOI  
         "\xFF\xD8".  
         # JFIF  
         "\xFF\xE0".  
         "\x00\x0e\x41\x56\x49\x31\x00\x00\x00\x00\x00\x00\x00\x00".  
         "\xff\xDD\x00\x04\x00\x00".  
         # quantization table  
         "\xFF\xDB".  
         "\x00\x43\x00\x21\x16\x18".  
         "\x1D\x18\x14\x21\x1D\x1B\x1D\x25".  
         "\x23\x21\x27\x31\x53\x36\x31\x2D".  
         "\x2D\x31\x65\x48\x4c\x3c\x53\x78".  
         "\x6a\x7e\x7c\x76\x6a\x74\x72\x85".  
         "\x95\xbf\xa2\x85\x8d\xb4\x8f\x72".  
         "\x74\xa6\xe2\xa8\xb4\xc5\xcb\xd6".  
         "\xd8\xd6\x80\xa0\xeb\xfb\xe8\xd0".  
         "\xf9\xbf\xd2\xd6\xcd".  
         # quantization table  
         "\xff\xdb".  
         "\x00\x43\x01\x23\x25\x25\x31\x2b\x31".  
         "\x61\x36\x36\x61\xcd\x89\x74\x89".  
         "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd".  
         "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd".  
         "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd".  
         "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd".  
         "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd".  
         "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd".  
         "\xcd\xcd".  
292          # Define huffman table (section B.2.4.1)          # Define huffman table (section B.2.4.1)
293          "\xFF\xC4".     # Marker          "\xFF\xC4".     # Marker
294          "\x00\x1F".     # Length (31 bytes)          "\x00\x1F".     # Length (31 bytes)
# Line 360  sub mkjpg { Line 297  sub mkjpg {
297          "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B".          "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B".
298          # Define huffman table (section B.2.4.1)          # Define huffman table (section B.2.4.1)
299          "\xFF\xC4".     # Marker          "\xFF\xC4".     # Marker
         "\x00\x1F".     # Length (31 bytes)  
         "\x01".         # DC chrominance, table 1  
         "\x00\x03\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00".  
         "\x00\x00\x00\x00".  
         "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B".  
         # Define huffman table (section B.2.4.1)  
         "\xFF\xC4".     # Marker  
300          "\x00\xB5".     # Length (181 bytes)          "\x00\xB5".     # Length (181 bytes)
301          "\x10".         # AC luminance, table 0          "\x10".         # AC luminance, table 0
302          "\x00\x02\x01\x03\x03\x02\x04\x03\x05\x05\x04\x04\x00\x00\x01\x7D".          "\x00\x02\x01\x03\x03\x02\x04\x03\x05\x05\x04\x04\x00\x00\x01\x7D".
# Line 384  sub mkjpg { Line 314  sub mkjpg {
314          "\xC6\xC7\xC8\xC9\xCA\xD2\xD3\xD4\xD5\xD6\xD7\xD8".          "\xC6\xC7\xC8\xC9\xCA\xD2\xD3\xD4\xD5\xD6\xD7\xD8".
315          "\xD9\xDA\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA".          "\xD9\xDA\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA".
316          "\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA".          "\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA".
317            # Define huffman table (section B.2.4.1)
318            "\xFF\xC4".     # Marker
319            "\x00\x1F".     # Length (31 bytes)
320            "\x01".         # DC chrominance, table 1
321            "\x00\x03\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00".
322            "\x00\x00\x00\x00".
323            "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B".
324          #/* Define huffman table (section B.2.4.1) */          #/* Define huffman table (section B.2.4.1) */
325          "\xFF\xC4".     # Marker          "\xFF\xC4".     # Marker
326          "\x00\xB5".     # Length (181 bytes)          "\x00\xB5".     # Length (181 bytes)
# Line 404  sub mkjpg { Line 341  sub mkjpg {
341          "\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xD2\xD3\xD4\xD5\xD6".          "\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xD2\xD3\xD4\xD5\xD6".
342          "\xD7\xD8\xD9\xDA\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9".          "\xD7\xD8\xD9\xDA\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9".
343          "\xEA\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA".          "\xEA\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA".
344          # start of frame          # Start of Scan marker
345          "\xff\xc0".          "\xFF\xDA".
346          "\x00\x11\x08".          pack("nC10",
347          pack("nn", 120, 160).                  12,                     # length
348          "\x03\x01\x21\x00\x02\x11\x01\x03\x11\x01".                  3,                      # number of components
349          #                  1,0x00,         # Scan 1: use DC/AC huff tables 0/0
350          "\xff\xda".                  2,0x11,         # Scan 2: use DC/AC huff tables 1/1
351          "\x00\x0c\x03\x01\x00\x02\x11\x03\x11".                  3,0x11,         # Scan 3: use DC/AC huff tables 1/1
352          "\x00\x3f\x00";                  0,0x3f,         # Ss, Se
353                    0,                      # Ah, Ai (not used)
354            );
355    
356          if ( $dump ) {          if ( $dump ) {
357                  warn "## created JPEG header...\n";                  print "## created JPEG header...\n";
358                  hex_dump( $header, 0 );                  hex_dump( $header, 0 );
359          }          }
360    
361          print $fh $header || die "can't write header into $path: $!";          my $frame = join('', @subframes ) . $data;
362          print $fh $data || die "can't write frame into $path: $!";          @subframes = ();
363    
364            my $path = sprintf("$dump_dir/%04d.jpg", $frame_nr );
365    
366            my $fh;
367            if ( $jpegtran ) {
368                    open($fh, '|-', "jpegtran $jpegtran > $path") || die "can't create $path: $!";
369            } else {
370                    open($fh, '>', $path) || die "can't create $path: $!";
371            }
372    
373            if ( ! $no_jpeg_header ) {
374                    print $fh $header . $frame . "\xFF\xD9" || die "can't write jpeg $path: $!";
375            } else {
376                    print $fh $frame || die "can't write raw jpeg $path: $!";
377            }
378          close $fh || die "can't close $path: $!";          close $fh || die "can't close $path: $!";
379          print ">> created $path ", -s $path, " bytes\n";          print ">> created $frame_nr ", $no_jpeg_header ? 'raw' : '', " jpeg $path ", -s $path, " bytes\n" if $verbose;
380  }  }
381    
382  my ( $riff, $amv ) = x(12, 'Z4x4Z4');  my ( $riff, $amv ) = x(12, 'Z4x4Z4');
383  die "$path not RIFF but $riff" if $riff ne 'RIFF';  die "$path not RIFF but $riff" if $riff ne 'RIFF';
384  die "$path not AMV but $amv" if $amv ne 'AMV ';  die "$path not AMV but $amv" if $amv ne 'AMV ';
385    
386    my $apath = "$dump_dir/audio.wav";
387    open(my $audio_fh, '>', $apath) || die "can't open audio file $apath: $!";
388    
389    print $audio_fh pack 'a4Va4a4VvvVVv4', (
390            # header 'RIFF', size
391            'RIFF',-1,
392            # type: 'WAVE'
393            'WAVE',
394            'fmt ',0x14,
395            # format: DVI (IMA) ADPCM Wave Type
396            0x11,
397            # channels
398            1,
399            # samples/sec
400            22050,
401            # avg. bytes/sec (for esimation)
402            11567,
403            # block align (size of block)
404            0x800,
405            # bits per sample (mono data)
406            4,
407            # cbSize (ADPCM with 7 soefficient pairs)
408            2,
409            # nSamplesPerBlock
410            # (((nBlockAlign - (7 * nChannels)) * 8) / (wBitsPerSample * nChannels)) + 2
411            0x0ff9,
412    );
413    
414    print $audio_fh pack 'a4VVa4V', (
415            # time length of the data in samples
416            'fact',4,
417            220500,
418            #
419            'data',-1,
420    );
421    
422    my $riff_header_len = tell($audio_fh);
423    
424  while ( ! defined($d->{eof}) ) {  while ( ! defined($d->{eof}) ) {
425          my ( $list, $name ) = x(12,'A4x4A4');          my ( $list, $name ) = x(12,'A4x4A4');
426          die "not LIST but $list" if $list ne 'LIST';          die "not LIST but $list" if $list ne 'LIST';
427          print "< $list * $name\n";          print "< $list * $name\n" if $verbose;
428    
429          if ( $name eq 'hdrl' ) {          if ( $name eq 'hdrl' ) {
430    
# Line 465  while ( ! defined($d->{eof}) ) { Line 457  while ( ! defined($d->{eof}) ) {
457                                    
458                          my $len = next_part( '00dc' );                          my $len = next_part( '00dc' );
459                          last unless $len;                          last unless $len;
460                          printf "<< %s 00dc - frame %d jpeg %d 0x%x bytes\n", $name, $frame, $len, $len;                          printf "<< %s 00dc - part %d jpeg %d 0x%x bytes\n", $name, $frame, $len, $len if $verbose;
461                          mkjpg( sprintf("$dump_dir/%03d.jpg", $frame ), x($len) );                          mkjpg( x($len) );
462    
463                          $len = next_part( '01wb', 0, 1 );                          $len = next_part( '01wb' );
464                          printf "<< %s 01wb - frame %d audio %d 0x%x bytes\n", $name, $frame, $len, $len;                          printf "<< %s 01wb - part %d audio %d 0x%x bytes\n", $name, $frame, $len, $len if $verbose;
465    
466                            my $audio_frame = x( $len );
467    
468                            # remove 8 bytes of something
469                            $audio_frame = substr( $audio_frame, 8 );
470    
471                            if ( length($audio_frame) % 2 == 0 ) {
472                                    print "#### even sized frame!";
473    #                               $audio_frame = substr( $audio_frame, 0, -1 );
474                            }
475    
476                            if ( $dump ) {
477                                    print "#### dumping audio frame ", length($audio_frame), " bytes\n";
478                                    hex_dump( $audio_frame );
479                            }
480    
481    #                       print $audio_fh mp3_frame;
482                            print $audio_fh $audio_frame || die "can't write audio frame in $apath: $!";
483    
484                            $frame_nr++;
485                  };                  };
486    
487          } else {          } else {
488                  die "unknown $list $name";                  die "unknown $list $name";
489          }          }
490  }  }
491    
492    my $cmd = "ffmpeg -i $dump_dir/%04d.jpg -r 16 -y $dump_avi";
493    system($cmd) == 0 || die "can't convert frames to avi using $cmd: $!";
494    
495    my $size = tell($audio_fh);
496    warn "## wav file size: $size\n";
497    
498    seek( $audio_fh, 4, 0 );
499    print $audio_fh pack("V", $size - 8);
500    seek( $audio_fh, $riff_header_len - 4, 0 );
501    print $audio_fh pack("V", $size - $riff_header_len);
502    
503    close($audio_fh) || die "can't close audio file $apath: $!";
504    
505    print ">>>> created $frame_nr frames $dump_avi ", -s $dump_avi, " and $apath ", -s $apath, "\n";

Legend:
Removed from v.14  
changed lines
  Added in v.24

  ViewVC Help
Powered by ViewVC 1.1.26