| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Video::Dumper::QuickTime; | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | require 5.007003;    # for Encode | 
| 4 |  |  |  |  |  |  |  | 
| 5 | 1 |  |  | 1 |  | 61138 | use strict; | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 65 |  | 
| 6 | 1 |  |  | 1 |  | 5 | use warnings; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 35 |  | 
| 7 | 1 |  |  | 1 |  | 5 | use Carp; | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 102 |  | 
| 8 | 1 |  |  | 1 |  | 3125 | use Encode; | 
|  | 1 |  |  |  |  | 29443 |  | 
|  | 1 |  |  |  |  | 111 |  | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | BEGIN { | 
| 11 | 1 |  |  | 1 |  | 10 | use Exporter (); | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 23 |  | 
| 12 | 1 |  |  | 1 |  | 5 | use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 181 |  | 
| 13 | 1 |  |  | 1 |  | 2 | $VERSION     = '1.0005'; | 
| 14 | 1 |  |  |  |  | 20 | @ISA         = qw(Exporter); | 
| 15 | 1 |  |  |  |  | 3 | @EXPORT      = qw(); | 
| 16 | 1 |  |  |  |  | 2 | @EXPORT_OK   = qw(); | 
| 17 | 1 |  |  |  |  | 13506 | %EXPORT_TAGS = (); | 
| 18 |  |  |  |  |  |  | } | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | =head1 NAME | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | Video::Dumper::QuickTime - Dump QuickTime movie file structure | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | =head1 VERSION | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | Version 1.0004 | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | use Video::Dumper::QuickTime; | 
| 31 |  |  |  |  |  |  | my $file = QuickTime->new( -filename => $filename, -progress => \&showProgress ); | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | eval {$file->Dump ()}; | 
| 34 |  |  |  |  |  |  | print "Error during processing: $@\n" if $@; | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | my $dumpStr = $file->Result (); | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | Video::Dumper::QuickTime parses a QuickTime movie file and generates a | 
| 41 |  |  |  |  |  |  | multi-line string describing the structure of the file. | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | The module is intended primarily as a diagnostic tool, although it would be | 
| 44 |  |  |  |  |  |  | possible to subclass Video::Dumper::QuickTime to extract various sections of a | 
| 45 |  |  |  |  |  |  | QuickTime file. | 
| 46 |  |  |  |  |  |  |  | 
| 47 |  |  |  |  |  |  | =head1 Methods | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | The methods fall into two groups - those required to use the method, and those | 
| 50 |  |  |  |  |  |  | useful for subclassing it. | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | The general use methods are presented first, followed by the accessor and | 
| 53 |  |  |  |  |  |  | utility methods of more use in subclassing. | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | =head2 General use methods | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | =cut | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | =head3 new | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | Create a new C instance. | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | my $msi = QuickTime->new (-filename => $filename); | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | =over 4 | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | =item I<-filename>: required | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | the QuickTime movie file to open | 
| 70 |  |  |  |  |  |  |  | 
| 71 |  |  |  |  |  |  | =item I<-noise>: optional | 
| 72 |  |  |  |  |  |  |  | 
| 73 |  |  |  |  |  |  | Set error reporting level. | 
| 74 |  |  |  |  |  |  |  | 
| 75 |  |  |  |  |  |  | Currently recognised levels are: | 
| 76 |  |  |  |  |  |  |  | 
| 77 |  |  |  |  |  |  | =over 4 | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | =item 0: no reporting | 
| 80 |  |  |  |  |  |  |  | 
| 81 |  |  |  |  |  |  | =item 1: report unknown atoms | 
| 82 |  |  |  |  |  |  |  | 
| 83 |  |  |  |  |  |  | =item 2: report non-decoded parameters and nested atoms | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | =back | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | =item I<-progress>: optional | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | reference to a callback sub to display parsing progress. | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | The progress sub is passed two parameters, the current position and the total | 
| 92 |  |  |  |  |  |  | work to be done. A typical callback sub would look like: | 
| 93 |  |  |  |  |  |  |  | 
| 94 |  |  |  |  |  |  | sub showProgress { | 
| 95 |  |  |  |  |  |  | my ( $pos, $total ) = @_; | 
| 96 |  |  |  |  |  |  | ... | 
| 97 |  |  |  |  |  |  | } | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  | =back | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | =cut | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | sub new { | 
| 104 | 1 |  |  | 1 | 1 | 50 | my $proto = shift; | 
| 105 | 1 |  | 33 |  |  | 9 | my $class = ref ($proto) || $proto; | 
| 106 | 1 |  |  |  |  | 4 | my $self  = bless {}, $class; | 
| 107 |  |  |  |  |  |  |  | 
| 108 | 1 |  |  |  |  | 5 | $self = $self->_init (@_); | 
| 109 |  |  |  |  |  |  |  | 
| 110 | 1 |  |  |  |  | 4 | return $self; | 
| 111 |  |  |  |  |  |  | } | 
| 112 |  |  |  |  |  |  |  | 
| 113 |  |  |  |  |  |  | sub _init { | 
| 114 | 1 |  |  | 1 |  | 3 | my $self  = shift; | 
| 115 | 1 |  |  |  |  | 4 | my %param = @_; | 
| 116 | 1 |  |  |  |  | 6 | $self->_init_attributes (@_); | 
| 117 | 1 |  | 50 |  |  | 7 | $self->{indentStr} ||= '.  '; | 
| 118 | 1 |  | 50 |  |  | 8 | $self->{indent}    ||= ''; | 
| 119 | 1 |  |  |  |  | 3 | $self->{result}       = ''; | 
| 120 | 1 |  |  |  |  | 3 | $self->{unknownAtoms} = {}; | 
| 121 | 1 | 50 |  |  |  | 7 | $self->{noise}        = 2 unless exists $self->{noise}; | 
| 122 | 1 |  |  |  |  | 3 | return $self; | 
| 123 |  |  |  |  |  |  | } | 
| 124 |  |  |  |  |  |  |  | 
| 125 |  |  |  |  |  |  | sub _init_attributes { | 
| 126 | 1 |  |  | 1 |  | 3 | my $self = shift; | 
| 127 | 1 |  |  |  |  | 3 | my %raw  = @_; | 
| 128 | 1 |  |  |  |  | 2 | my %param; | 
| 129 |  |  |  |  |  |  |  | 
| 130 | 1 |  |  |  |  | 5 | for (keys %raw) { | 
| 131 | 1 |  |  |  |  | 8 | /^-?(.+)/; | 
| 132 | 1 |  |  |  |  | 7 | $param{$1} = $raw{$_}; | 
| 133 |  |  |  |  |  |  | } | 
| 134 |  |  |  |  |  |  |  | 
| 135 | 1 |  |  |  |  | 11 | $self->{noise}      = $param{noise}; | 
| 136 | 1 |  |  |  |  | 3 | $self->{parsedSize} = 0; | 
| 137 | 1 | 50 |  |  |  | 5 | $self->{progress}   = $param{progress} if exists $param{progress}; | 
| 138 |  |  |  |  |  |  |  | 
| 139 | 1 |  |  |  |  | 4 | my $filename = $param{filename}; | 
| 140 | 1 | 50 |  |  |  | 4 | croak "filename parameter required" unless defined $filename; | 
| 141 | 1 |  |  |  |  | 2 | $self->{filename} = $filename; | 
| 142 | 1 | 50 |  |  |  | 16 | croak "File not found: $filename" unless -f $filename; | 
| 143 |  |  |  |  |  |  |  | 
| 144 | 1 |  |  |  |  | 13 | $self->{filesize}   = -s $filename; | 
| 145 | 1 |  |  |  |  | 10 | $self->{nextUpdate} = $self->{filesize} / 100; | 
| 146 |  |  |  |  |  |  |  | 
| 147 | 1 | 50 |  |  |  | 54 | open $self->{handle}, '<', $self->{filename} | 
| 148 |  |  |  |  |  |  | or die "Can't open $self->{filename}: $!\n"; | 
| 149 | 1 |  |  |  |  | 7 | binmode $self->{handle}; | 
| 150 |  |  |  |  |  |  | } | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  | sub _closeFile { | 
| 153 | 1 |  |  | 1 |  | 2 | my $self = shift; | 
| 154 |  |  |  |  |  |  |  | 
| 155 | 1 | 50 |  |  |  | 37 | close $self->{handle} if $self->{handle}; | 
| 156 |  |  |  |  |  |  | } | 
| 157 |  |  |  |  |  |  |  | 
| 158 |  |  |  |  |  |  | =head3 Dump | 
| 159 |  |  |  |  |  |  |  | 
| 160 |  |  |  |  |  |  | Parse the movie file and return the result string. | 
| 161 |  |  |  |  |  |  |  | 
| 162 |  |  |  |  |  |  | =cut | 
| 163 |  |  |  |  |  |  |  | 
| 164 |  |  |  |  |  |  |  | 
| 165 |  |  |  |  |  |  | sub Dump {    # Find top level atoms | 
| 166 | 1 |  |  | 1 | 1 | 694 | my $self = shift; | 
| 167 | 1 |  |  |  |  | 2 | my $pos  = 0; | 
| 168 |  |  |  |  |  |  |  | 
| 169 | 1 |  |  |  |  | 2 | eval { | 
| 170 | 1 |  |  |  |  | 2 | push @{$self->{atomStack}}, (['global', {}]); | 
|  | 1 |  |  |  |  | 5 |  | 
| 171 | 1 |  |  |  |  | 35 | $pos = $self->describeAtom ($pos) while !eof ($self->{handle}); | 
| 172 |  |  |  |  |  |  | }; | 
| 173 |  |  |  |  |  |  |  | 
| 174 | 1 |  |  |  |  | 7 | $self->_closeFile (); | 
| 175 |  |  |  |  |  |  |  | 
| 176 | 1 | 50 | 33 |  |  | 10 | die $@ if $@ and $@ ne "end\n"; | 
| 177 | 1 |  |  |  |  | 6 | return $self->{result}; | 
| 178 |  |  |  |  |  |  | } | 
| 179 |  |  |  |  |  |  |  | 
| 180 |  |  |  |  |  |  | =head3 IndentStr | 
| 181 |  |  |  |  |  |  |  | 
| 182 |  |  |  |  |  |  | Returns the string used for indenting in the result string. | 
| 183 |  |  |  |  |  |  |  | 
| 184 |  |  |  |  |  |  | =cut | 
| 185 |  |  |  |  |  |  |  | 
| 186 |  |  |  |  |  |  | sub IndentStr { | 
| 187 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 188 |  |  |  |  |  |  |  | 
| 189 | 0 |  |  |  |  | 0 | return $self->{indentStr}; | 
| 190 |  |  |  |  |  |  | } | 
| 191 |  |  |  |  |  |  |  | 
| 192 |  |  |  |  |  |  | =head3 Result | 
| 193 |  |  |  |  |  |  |  | 
| 194 |  |  |  |  |  |  | C returns the result string generated by Dump. This can be usefull if | 
| 195 |  |  |  |  |  |  | you need to wrap the call the C in an C, but still want any output | 
| 196 |  |  |  |  |  |  | that was generated in the case when an exception was thrown. | 
| 197 |  |  |  |  |  |  |  | 
| 198 |  |  |  |  |  |  | =cut | 
| 199 |  |  |  |  |  |  |  | 
| 200 |  |  |  |  |  |  | sub Result { | 
| 201 | 1 |  |  | 1 | 1 | 7 | my $self = shift; | 
| 202 |  |  |  |  |  |  |  | 
| 203 | 1 |  |  |  |  | 54 | return $self->{result}; | 
| 204 |  |  |  |  |  |  | } | 
| 205 |  |  |  |  |  |  |  | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | =head2 Subclassing utility methods | 
| 208 |  |  |  |  |  |  |  | 
| 209 |  |  |  |  |  |  | The following methods are used internally to manipulate and decode the data in | 
| 210 |  |  |  |  |  |  | the movie file. The present documentation if rather scanty, but will be improved | 
| 211 |  |  |  |  |  |  | over time (sooner if you ask for it!). | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  | Generally the method name and parameter list are given. Parameters in C<[]> are | 
| 214 |  |  |  |  |  |  | optional. Parameters followed by C<...> may be repeated as required. | 
| 215 |  |  |  |  |  |  |  | 
| 216 |  |  |  |  |  |  | =head3 read ($length[, $offset]); | 
| 217 |  |  |  |  |  |  |  | 
| 218 |  |  |  |  |  |  | C takes two parameters - a length (required) and a starting offset | 
| 219 |  |  |  |  |  |  | (optional). | 
| 220 |  |  |  |  |  |  |  | 
| 221 |  |  |  |  |  |  | C returns a string containing the number of bytes asked for starting from | 
| 222 |  |  |  |  |  |  | the current position or the given offset. | 
| 223 |  |  |  |  |  |  |  | 
| 224 |  |  |  |  |  |  | C will C if the end of the file is reached without reading | 
| 225 |  |  |  |  |  |  | any further bytes. | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  | C will C if fewer than the requested bytes | 
| 228 |  |  |  |  |  |  | are available. | 
| 229 |  |  |  |  |  |  |  | 
| 230 |  |  |  |  |  |  | =cut | 
| 231 |  |  |  |  |  |  |  | 
| 232 |  |  |  |  |  |  | sub read { | 
| 233 | 538 |  |  | 538 | 1 | 929 | my $self = shift; | 
| 234 | 538 |  |  |  |  | 2006 | my ($len, $offset) = @_; | 
| 235 | 538 |  |  |  |  | 1047 | my $buf; | 
| 236 |  |  |  |  |  |  |  | 
| 237 | 538 | 100 |  |  |  | 5508 | seek $self->{handle}, $offset, 0 if defined $offset; | 
| 238 |  |  |  |  |  |  |  | 
| 239 | 538 |  |  |  |  | 5101 | my $n = read $self->{handle}, $buf, $len; | 
| 240 | 538 | 50 |  |  |  | 3252 | croak 'read failed' unless defined $n; | 
| 241 | 538 | 100 |  |  |  | 2939 | die "end\n" if !$n; | 
| 242 | 537 | 50 |  |  |  | 2204 | croak "short read ($len/$n)" unless $n == $len; | 
| 243 |  |  |  |  |  |  |  | 
| 244 | 537 | 50 |  |  |  | 2116 | if (defined $self->{progress}) { | 
| 245 | 0 |  |  |  |  | 0 | $self->{parsedSize} += $n; | 
| 246 |  |  |  |  |  |  |  | 
| 247 | 0 | 0 |  |  |  | 0 | if ($self->{nextUpdate} >= $self->{parsedSize}) { | 
| 248 | 0 |  |  |  |  | 0 | $self->{nextUpdate} += $self->{filesize} / 100; | 
| 249 | 0 |  |  |  |  | 0 | $self->{progress}->($self->{parsedSize}, $self->{filesize}); | 
| 250 |  |  |  |  |  |  | } | 
| 251 |  |  |  |  |  |  | } | 
| 252 |  |  |  |  |  |  |  | 
| 253 | 537 |  |  |  |  | 5044 | return $buf; | 
| 254 |  |  |  |  |  |  | } | 
| 255 |  |  |  |  |  |  |  | 
| 256 |  |  |  |  |  |  |  | 
| 257 |  |  |  |  |  |  | =head3 append ($str, ...) | 
| 258 |  |  |  |  |  |  |  | 
| 259 |  |  |  |  |  |  | Append a list of strings to the result string. | 
| 260 |  |  |  |  |  |  |  | 
| 261 |  |  |  |  |  |  | If the last character in the result string before the append was a new line | 
| 262 |  |  |  |  |  |  | character prepend the current indent string first. | 
| 263 |  |  |  |  |  |  |  | 
| 264 |  |  |  |  |  |  | =cut | 
| 265 |  |  |  |  |  |  |  | 
| 266 |  |  |  |  |  |  | sub append { | 
| 267 | 817 |  |  | 817 | 1 | 2154 | my $self = shift; | 
| 268 | 817 |  |  |  |  | 3667 | my $lastChar = substr $self->{result}, -1; | 
| 269 |  |  |  |  |  |  |  | 
| 270 | 817 | 100 |  |  |  | 5224 | $self->{result} .= $self->{indent} if $lastChar eq "\n"; | 
| 271 | 817 |  |  |  |  | 5928 | $self->{result} .= join '', @_; | 
| 272 |  |  |  |  |  |  | } | 
| 273 |  |  |  |  |  |  |  | 
| 274 |  |  |  |  |  |  |  | 
| 275 |  |  |  |  |  |  | =head3 findAtom ($attribute[, $regexp]) | 
| 276 |  |  |  |  |  |  |  | 
| 277 |  |  |  |  |  |  | Search down the atom stack for an atom with a matching attribute and return the | 
| 278 |  |  |  |  |  |  | atom if found,or undef if no matching atom is found. | 
| 279 |  |  |  |  |  |  |  | 
| 280 |  |  |  |  |  |  | If the regular expression is provided the value of the attribute mustmatch | 
| 281 |  |  |  |  |  |  | against the regular expression. The regex should be generated using C. | 
| 282 |  |  |  |  |  |  |  | 
| 283 |  |  |  |  |  |  | See also L and L | 
| 284 |  |  |  |  |  |  |  | 
| 285 |  |  |  |  |  |  | =cut | 
| 286 |  |  |  |  |  |  |  | 
| 287 |  |  |  |  |  |  | sub findAtom { | 
| 288 | 9 |  |  | 9 | 1 | 14 | my ($self, $attrib, $regexp) = @_; | 
| 289 | 9 |  |  |  |  | 12 | my $limit = @{$self->{atomStack}}; | 
|  | 9 |  |  |  |  | 23 |  | 
| 290 | 9 |  |  |  |  | 13 | my $dataRef; | 
| 291 | 9 |  |  |  |  | 12 | my $index = -1; | 
| 292 |  |  |  |  |  |  |  | 
| 293 | 9 |  |  |  |  | 30 | while (-$index < $limit) { | 
| 294 | 34 |  |  |  |  | 38 | $dataRef = \%{$self->{atomStack}[$index--][1]}; | 
|  | 34 |  |  |  |  | 95 |  | 
| 295 | 34 | 100 |  |  |  | 144 | next if !exists $dataRef->{$attrib}; | 
| 296 | 11 | 100 |  |  |  | 25 | last if !defined $regexp; | 
| 297 | 4 | 100 |  |  |  | 42 | last if $dataRef->{$attrib} =~ $regexp; | 
| 298 |  |  |  |  |  |  | } | 
| 299 |  |  |  |  |  |  |  | 
| 300 | 9 |  |  |  |  | 120 | return $dataRef; | 
| 301 |  |  |  |  |  |  | } | 
| 302 |  |  |  |  |  |  |  | 
| 303 |  |  |  |  |  |  | =head3 findAtomValue ($attribute[, $regexp]) | 
| 304 |  |  |  |  |  |  |  | 
| 305 |  |  |  |  |  |  | Search down the atom stack for an atom with a matching attribute and return the | 
| 306 |  |  |  |  |  |  | attribute value if found, or '' if no matching atom is found. | 
| 307 |  |  |  |  |  |  |  | 
| 308 |  |  |  |  |  |  | If the regular expression is provided the value of the attribute mustmatch | 
| 309 |  |  |  |  |  |  | against the regular expression. The regex should be generated using C. | 
| 310 |  |  |  |  |  |  |  | 
| 311 |  |  |  |  |  |  | See also L and L | 
| 312 |  |  |  |  |  |  |  | 
| 313 |  |  |  |  |  |  | =cut | 
| 314 |  |  |  |  |  |  |  | 
| 315 |  |  |  |  |  |  | sub findAtomValue { | 
| 316 | 7 |  |  | 7 | 1 | 15 | my ($self, $attrib, $regexp) = @_; | 
| 317 | 7 |  |  |  |  | 29 | my $dataRef = $self->findAtom ($attrib, $regexp); | 
| 318 |  |  |  |  |  |  |  | 
| 319 | 7 | 50 |  |  |  | 60 | return $dataRef ? $dataRef->{$attrib} : ''; | 
| 320 |  |  |  |  |  |  | } | 
| 321 |  |  |  |  |  |  |  | 
| 322 |  |  |  |  |  |  | =head3 setParentAttrib ($attrib, $value) | 
| 323 |  |  |  |  |  |  |  | 
| 324 |  |  |  |  |  |  | Set an attribute on the parent of the current atom. | 
| 325 |  |  |  |  |  |  |  | 
| 326 |  |  |  |  |  |  | =cut | 
| 327 |  |  |  |  |  |  |  | 
| 328 |  |  |  |  |  |  | sub setParentAttrib { | 
| 329 | 11 |  |  | 11 | 1 | 64 | my ($self, $attrib, $value) = @_; | 
| 330 | 11 |  |  |  |  | 121 | $self->{atomStack}[-2][1]{$attrib} = $value; | 
| 331 |  |  |  |  |  |  | } | 
| 332 |  |  |  |  |  |  |  | 
| 333 |  |  |  |  |  |  | =head3 getParentAttribs | 
| 334 |  |  |  |  |  |  |  | 
| 335 |  |  |  |  |  |  | Return a hash ref containing all the attribute => value pairs for the parent | 
| 336 |  |  |  |  |  |  | atom. | 
| 337 |  |  |  |  |  |  |  | 
| 338 |  |  |  |  |  |  | =cut | 
| 339 |  |  |  |  |  |  |  | 
| 340 |  |  |  |  |  |  | sub getParentAttribs { | 
| 341 | 0 |  |  | 0 | 1 | 0 | my ($self) = @_; | 
| 342 |  |  |  |  |  |  |  | 
| 343 | 0 |  |  |  |  | 0 | return $self->{atomStack}[-2][1]; | 
| 344 |  |  |  |  |  |  | } | 
| 345 |  |  |  |  |  |  |  | 
| 346 |  |  |  |  |  |  | =head3 describeAtom ($pos) | 
| 347 |  |  |  |  |  |  |  | 
| 348 |  |  |  |  |  |  | Add a descriptive header to the result string for the atom at the given | 
| 349 |  |  |  |  |  |  | position. | 
| 350 |  |  |  |  |  |  |  | 
| 351 |  |  |  |  |  |  | If L and L are available for the atom they are called to | 
| 352 |  |  |  |  |  |  | dump the atom's contents. If specific decoding is not available the atom is | 
| 353 |  |  |  |  |  |  | flagged as unknown and raw data for it is shown in the Dump result. | 
| 354 |  |  |  |  |  |  |  | 
| 355 |  |  |  |  |  |  | =head3 dump_xxxx ($pos, $length) | 
| 356 |  |  |  |  |  |  |  | 
| 357 |  |  |  |  |  |  | C is the four char code for an atom. C is called with the start | 
| 358 |  |  |  |  |  |  | and length of an atom of type C and is expected to decode the atom's | 
| 359 |  |  |  |  |  |  | contents. | 
| 360 |  |  |  |  |  |  |  | 
| 361 |  |  |  |  |  |  | =head3 name_xxxx | 
| 362 |  |  |  |  |  |  |  | 
| 363 |  |  |  |  |  |  | C is the four char code for an atom. C returns a string to be | 
| 364 |  |  |  |  |  |  | shown as the name for the atom C. | 
| 365 |  |  |  |  |  |  |  | 
| 366 |  |  |  |  |  |  | =cut | 
| 367 |  |  |  |  |  |  |  | 
| 368 |  |  |  |  |  |  | sub describeAtom { | 
| 369 | 60 |  |  | 60 | 1 | 120 | my $self = shift; | 
| 370 | 60 |  |  |  |  | 72 | my $pos  = shift; | 
| 371 | 60 |  |  |  |  | 155 | my ($len, $key) = unpack ("Na4", $self->read (8, $pos)); | 
| 372 |  |  |  |  |  |  |  | 
| 373 | 59 | 100 | 66 |  |  | 756 | if (!defined $len or $len == 0) { | 
| 374 | 3 |  |  |  |  | 9 | $self->append ("End entry\n"); | 
| 375 | 3 |  |  |  |  | 14 | return $pos + 4; | 
| 376 |  |  |  |  |  |  | } | 
| 377 |  |  |  |  |  |  |  | 
| 378 | 56 | 50 |  |  |  | 806 | $key = 'x' . unpack ('H8', $key) if $key =~ /[\x00-\x1f]/; | 
| 379 | 56 |  |  |  |  | 349 | $key =~ tr/ /_/; | 
| 380 | 56 |  |  |  |  | 170 | $key =~ s/([^\w \d_])/sprintf "%02X", ord ($1)/ge; | 
|  | 2 |  |  |  |  | 8 |  | 
| 381 |  |  |  |  |  |  |  | 
| 382 | 56 | 50 |  |  |  | 753 | if (!length $key) { | 
| 383 | 0 |  |  |  |  | 0 | return $pos; | 
| 384 |  |  |  |  |  |  | } | 
| 385 |  |  |  |  |  |  |  | 
| 386 | 56 |  |  |  |  | 496 | my $member = "dump_$key"; | 
| 387 | 56 |  |  |  |  | 163 | my $name   = "name_$key"; | 
| 388 |  |  |  |  |  |  |  | 
| 389 | 56 | 100 |  |  |  | 13668 | $name = $self->can ($name) ? $self->$name () . ' ' : ''; | 
| 390 |  |  |  |  |  |  |  | 
| 391 | 56 |  |  |  |  | 416 | my $header = sprintf "'%s' %s@ %s (0x%08x) for %s (0x%08x):", $key, $name, | 
| 392 |  |  |  |  |  |  | groupDigits ($pos), $pos, groupDigits ($len), $len; | 
| 393 |  |  |  |  |  |  |  | 
| 394 | 56 |  |  |  |  | 364 | $self->append ("$header\n"); | 
| 395 | 56 |  |  |  |  | 180 | $self->{indent} .= $self->{indentStr}; | 
| 396 | 56 | 100 |  |  |  | 477 | if ($self->can ($member)) { | 
| 397 | 50 |  |  |  |  | 54 | push @{$self->{atomStack}}, [$key, {}]; | 
|  | 50 |  |  |  |  | 1330 |  | 
| 398 | 50 |  |  |  |  | 464 | $self->$member ($pos, $len); | 
| 399 | 50 |  |  |  |  | 147 | pop @{$self->{atomStack}}; | 
|  | 50 |  |  |  |  | 112 |  | 
| 400 |  |  |  |  |  |  | } else { | 
| 401 | 6 |  |  |  |  | 17 | $self->append ("   Unhandled: length = " . groupDigits ($len) . "\n"); | 
| 402 | 6 | 100 |  |  |  | 47 | $self->dumpBlock ($pos + 8, $len > 24 ? 16 : $len - 8) if $len > 8; | 
|  |  | 50 |  |  |  |  |  | 
| 403 | 6 | 50 | 33 |  |  | 119 | if (!$self->{unknownAtoms}{$key}++ && $self->{noise}) { | 
| 404 | 0 |  |  |  |  | 0 | printf "Unknown atom '%s' %s (0x%08x) long at %s (0x%08x))\n", $key, | 
| 405 |  |  |  |  |  |  | groupDigits ($pos), $pos, groupDigits ($len), $len; | 
| 406 |  |  |  |  |  |  | } | 
| 407 |  |  |  |  |  |  | } | 
| 408 | 56 |  |  |  |  | 400 | $self->{indent} = substr $self->{indent}, length $self->{indentStr}; | 
| 409 | 56 |  |  |  |  | 502 | return $pos + $len; | 
| 410 |  |  |  |  |  |  | } | 
| 411 |  |  |  |  |  |  |  | 
| 412 |  |  |  |  |  |  | =head3 describeAtoms ($pos, $count) | 
| 413 |  |  |  |  |  |  |  | 
| 414 |  |  |  |  |  |  | Calls L for each of $count atoms starting at $pos. | 
| 415 |  |  |  |  |  |  |  | 
| 416 |  |  |  |  |  |  | =cut | 
| 417 |  |  |  |  |  |  |  | 
| 418 |  |  |  |  |  |  | sub describeAtoms { | 
| 419 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 420 | 0 |  |  |  |  | 0 | my ($pos, $count) = @_; | 
| 421 |  |  |  |  |  |  |  | 
| 422 | 0 |  |  |  |  | 0 | $pos = $self->describeAtom ($pos) while $count--; | 
| 423 | 0 |  |  |  |  | 0 | return $pos; | 
| 424 |  |  |  |  |  |  | } | 
| 425 |  |  |  |  |  |  |  | 
| 426 |  |  |  |  |  |  | =head3 describeAtomsIn ($pos, $end) | 
| 427 |  |  |  |  |  |  |  | 
| 428 |  |  |  |  |  |  | Calls L for each atom starting at $pos and before $end. | 
| 429 |  |  |  |  |  |  |  | 
| 430 |  |  |  |  |  |  | =cut | 
| 431 |  |  |  |  |  |  |  | 
| 432 |  |  |  |  |  |  | sub describeAtomsIn { | 
| 433 | 18 |  |  | 18 | 1 | 30 | my $self = shift; | 
| 434 | 18 |  |  |  |  | 24 | my ($pos, $end) = @_; | 
| 435 |  |  |  |  |  |  |  | 
| 436 | 18 |  |  |  |  | 123 | $pos = $self->describeAtom ($pos) while $pos < $end; | 
| 437 |  |  |  |  |  |  | } | 
| 438 |  |  |  |  |  |  |  | 
| 439 |  |  |  |  |  |  | =head3 unwrapAtoms ($pos, $len) | 
| 440 |  |  |  |  |  |  |  | 
| 441 |  |  |  |  |  |  | Calls L for each atom in the given range. Used to decode an | 
| 442 |  |  |  |  |  |  | atom that is purely a container for other atoms. | 
| 443 |  |  |  |  |  |  |  | 
| 444 |  |  |  |  |  |  | =cut | 
| 445 |  |  |  |  |  |  |  | 
| 446 |  |  |  |  |  |  | sub unwrapAtoms { | 
| 447 | 16 |  |  | 16 | 1 | 27 | my $self = shift; | 
| 448 | 16 |  |  |  |  | 32 | my ($pos, $len) = @_; | 
| 449 |  |  |  |  |  |  |  | 
| 450 | 16 |  |  |  |  | 129 | $self->describeAtomsIn ($pos + 8, $pos + $len); | 
| 451 |  |  |  |  |  |  | } | 
| 452 |  |  |  |  |  |  |  | 
| 453 |  |  |  |  |  |  | =head3 atomList ($pos, $len) | 
| 454 |  |  |  |  |  |  |  | 
| 455 |  |  |  |  |  |  | Dump a version and flags header followed by a list of atoms. | 
| 456 |  |  |  |  |  |  |  | 
| 457 |  |  |  |  |  |  | =cut | 
| 458 |  |  |  |  |  |  |  | 
| 459 |  |  |  |  |  |  | sub atomList { | 
| 460 | 2 |  |  | 2 | 1 | 3 | my $self = shift; | 
| 461 | 2 |  |  |  |  | 4 | my ($pos, $len) = @_; | 
| 462 |  |  |  |  |  |  |  | 
| 463 | 2 |  |  |  |  | 7 | $self->append ('Version:  ', unpack ('C',   $self->read (1)), "\n"); | 
| 464 | 2 |  |  |  |  | 197 | $self->append ('Flags:    ', unpack ('B24', $self->read (3)), "\n"); | 
| 465 | 2 |  |  |  |  | 9 | NToSigned ($self->read (4)); | 
| 466 | 2 |  |  |  |  | 8 | $self->describeAtomsIn ($pos + 16, $pos + $len); | 
| 467 |  |  |  |  |  |  | } | 
| 468 |  |  |  |  |  |  |  | 
| 469 |  |  |  |  |  |  | #sub construct_hash { | 
| 470 |  |  |  |  |  |  | #    my ($input) = @_; | 
| 471 |  |  |  |  |  |  | #    my %hash; | 
| 472 |  |  |  |  |  |  | # | 
| 473 |  |  |  |  |  |  | #    while ( length($input) > 0 ) { | 
| 474 |  |  |  |  |  |  | #        my ($len) = NToSigned( substr( $input, 0, 4, '' ) ); | 
| 475 |  |  |  |  |  |  | #        my ($cntnt) = substr( $input, 0, $len - 4, '' ); | 
| 476 |  |  |  |  |  |  | #        my ($type) = substr( $cntnt, 0, 4, '' ); | 
| 477 |  |  |  |  |  |  | # | 
| 478 |  |  |  |  |  |  | #        if ( exists $hash{$type} ) { | 
| 479 |  |  |  |  |  |  | #            my @a = grep( $type, keys %hash ); | 
| 480 |  |  |  |  |  |  | #            $hash{ $type . length(@a) } = $cntnt; | 
| 481 |  |  |  |  |  |  | #        } | 
| 482 |  |  |  |  |  |  | #        else { | 
| 483 |  |  |  |  |  |  | #            $hash{$type} = $cntnt; | 
| 484 |  |  |  |  |  |  | #        } | 
| 485 |  |  |  |  |  |  | #    } | 
| 486 |  |  |  |  |  |  | #    %hash; | 
| 487 |  |  |  |  |  |  | #} | 
| 488 |  |  |  |  |  |  |  | 
| 489 |  |  |  |  |  |  | sub dump_A9cmt { | 
| 490 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 491 | 0 |  |  |  |  | 0 | $self->showStr (@_); | 
| 492 |  |  |  |  |  |  | } | 
| 493 |  |  |  |  |  |  |  | 
| 494 |  |  |  |  |  |  | sub dump_A9cpy { | 
| 495 | 1 |  |  | 1 | 0 | 1 | my $self = shift; | 
| 496 | 1 |  |  |  |  | 6 | $self->showStr (@_); | 
| 497 |  |  |  |  |  |  | } | 
| 498 |  |  |  |  |  |  |  | 
| 499 |  |  |  |  |  |  | sub dump_A9des { | 
| 500 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 501 | 0 |  |  |  |  | 0 | $self->showStr (@_); | 
| 502 |  |  |  |  |  |  | } | 
| 503 |  |  |  |  |  |  |  | 
| 504 |  |  |  |  |  |  | sub dump_A9inf { | 
| 505 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 506 | 0 |  |  |  |  | 0 | $self->showStr (@_); | 
| 507 |  |  |  |  |  |  | } | 
| 508 |  |  |  |  |  |  |  | 
| 509 |  |  |  |  |  |  | sub dump_A9nam { | 
| 510 | 1 |  |  | 1 | 0 | 2 | my $self = shift; | 
| 511 | 1 |  |  |  |  | 3 | $self->showStr (@_); | 
| 512 |  |  |  |  |  |  | } | 
| 513 |  |  |  |  |  |  |  | 
| 514 |  |  |  |  |  |  | sub dump_actn { | 
| 515 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 516 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 517 | 0 |  |  |  |  | 0 | my %actionTypes = ( | 
| 518 |  |  |  |  |  |  | 1  => 'mcActionIdle', | 
| 519 |  |  |  |  |  |  | 2  => 'mcActionDraw', | 
| 520 |  |  |  |  |  |  | 3  => 'mcActionActivate', | 
| 521 |  |  |  |  |  |  | 4  => 'mcActionDeactivate', | 
| 522 |  |  |  |  |  |  | 5  => 'mcActionMouseDown', | 
| 523 |  |  |  |  |  |  | 6  => 'mcActionKey', | 
| 524 |  |  |  |  |  |  | 8  => 'mcActionPlay', | 
| 525 |  |  |  |  |  |  | 12 => 'mcActionGoToTime', | 
| 526 |  |  |  |  |  |  | 14 => 'mcActionSetVolume', | 
| 527 |  |  |  |  |  |  | 15 => 'mcActionGetVolume', | 
| 528 |  |  |  |  |  |  | 18 => 'mcActionStep', | 
| 529 |  |  |  |  |  |  | 21 => 'mcActionSetLooping', | 
| 530 |  |  |  |  |  |  | 22 => 'mcActionGetLooping', | 
| 531 |  |  |  |  |  |  | 23 => 'mcActionSetLoopIsPalindrome', | 
| 532 |  |  |  |  |  |  | 24 => 'mcActionGetLoopIsPalindrome', | 
| 533 |  |  |  |  |  |  | 25 => 'mcActionSetGrowBoxBounds', | 
| 534 |  |  |  |  |  |  | 26 => 'mcActionControllerSizeChanged', | 
| 535 |  |  |  |  |  |  | 29 => 'mcActionSetSelectionBegin', | 
| 536 |  |  |  |  |  |  | 30 => 'mcActionSetSelectionDuration', | 
| 537 |  |  |  |  |  |  | 32 => 'mcActionSetKeysEnabled', | 
| 538 |  |  |  |  |  |  | 33 => 'mcActionGetKeysEnabled', | 
| 539 |  |  |  |  |  |  | 34 => 'mcActionSetPlaySelection', | 
| 540 |  |  |  |  |  |  | 35 => 'mcActionGetPlaySelection', | 
| 541 |  |  |  |  |  |  | 36 => 'mcActionSetUseBadge', | 
| 542 |  |  |  |  |  |  | 37 => 'mcActionGetUseBadge', | 
| 543 |  |  |  |  |  |  | 38 => 'mcActionSetFlags', | 
| 544 |  |  |  |  |  |  | 39 => 'mcActionGetFlags', | 
| 545 |  |  |  |  |  |  | 40 => 'mcActionSetPlayEveryFrame', | 
| 546 |  |  |  |  |  |  | 41 => 'mcActionGetPlayEveryFrame', | 
| 547 |  |  |  |  |  |  | 42 => 'mcActionGetPlayRate', | 
| 548 |  |  |  |  |  |  | 43 => 'mcActionShowBalloon', | 
| 549 |  |  |  |  |  |  | 44 => 'mcActionBadgeClick', | 
| 550 |  |  |  |  |  |  | 45 => 'mcActionMovieClick', | 
| 551 |  |  |  |  |  |  | 46 => 'mcActionSuspend', | 
| 552 |  |  |  |  |  |  | 47 => 'mcActionResume', | 
| 553 |  |  |  |  |  |  | 48 => 'mcActionSetControllerKeysEnabled', | 
| 554 |  |  |  |  |  |  | 49 => 'mcActionGetTimeSliderRect', | 
| 555 |  |  |  |  |  |  | 50 => 'mcActionMovieEdited', | 
| 556 |  |  |  |  |  |  | 51 => 'mcActionGetDragEnabled', | 
| 557 |  |  |  |  |  |  | 52 => 'mcActionSetDragEnabled', | 
| 558 |  |  |  |  |  |  | 53 => 'mcActionGetSelectionBegin', | 
| 559 |  |  |  |  |  |  | 54 => 'mcActionGetSelectionDuration', | 
| 560 |  |  |  |  |  |  | 55 => 'mcActionPrerollAndPlay', | 
| 561 |  |  |  |  |  |  | 56 => 'mcActionGetCursorSettingEnabled', | 
| 562 |  |  |  |  |  |  | 57 => 'mcActionSetCursorSettingEnabled', | 
| 563 |  |  |  |  |  |  | 58 => 'mcActionSetColorTable', | 
| 564 |  |  |  |  |  |  | 59 => 'mcActionLinkToURL', | 
| 565 |  |  |  |  |  |  | 60 => 'mcActionCustomButtonClick', | 
| 566 |  |  |  |  |  |  | 61 => 'mcActionForceTimeTableUpdate', | 
| 567 |  |  |  |  |  |  | 62 => 'mcActionSetControllerTimeLimits', | 
| 568 |  |  |  |  |  |  | 63 => 'mcActionExecuteAllActionsForQTEvent', | 
| 569 |  |  |  |  |  |  | 64 => 'mcActionExecuteOneActionForQTEvent', | 
| 570 |  |  |  |  |  |  | 65 => 'mcActionAdjustCursor', | 
| 571 |  |  |  |  |  |  | 66 => 'mcActionUseTrackForTimeTable', | 
| 572 |  |  |  |  |  |  | 67 => 'mcActionClickAndHoldPoint', | 
| 573 |  |  |  |  |  |  | 68 => 'mcActionShowMessageString', | 
| 574 |  |  |  |  |  |  | 69 => 'mcActionShowStatusString', | 
| 575 |  |  |  |  |  |  | 70 => 'mcActionGetExternalMovie', | 
| 576 |  |  |  |  |  |  | 71 => 'mcActionGetChapterTime', | 
| 577 |  |  |  |  |  |  | 72 => 'mcActionPerformActionList', | 
| 578 |  |  |  |  |  |  | 73 => 'mcActionEvaluateExpression', | 
| 579 |  |  |  |  |  |  | 74 => 'mcActionFetchParameterAs', | 
| 580 |  |  |  |  |  |  | 75 => 'mcActionGetCursorByID', | 
| 581 |  |  |  |  |  |  | 76 => 'mcActionGetNextURL', | 
| 582 |  |  |  |  |  |  | 77 => 'mcActionMovieChanged', | 
| 583 |  |  |  |  |  |  | 78 => 'mcActionDoScript', | 
| 584 |  |  |  |  |  |  | 79 => 'mcActionRestartAtTime', | 
| 585 |  |  |  |  |  |  | 80 => 'mcActionGetIndChapter', | 
| 586 |  |  |  |  |  |  | 81 => 'mcActionLinkToURLExtended', | 
| 587 |  |  |  |  |  |  | ); | 
| 588 |  |  |  |  |  |  |  | 
| 589 | 0 |  | 0 |  |  | 0 | my $type = $actionTypes{NToSigned ($self->read (4))} || 'unknown'; | 
| 590 | 0 |  |  |  |  | 0 | $self->append      ("Action type: $type\n"); | 
| 591 | 0 |  |  |  |  | 0 | $self->append      ("Reserved\n"); | 
| 592 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 593 |  |  |  |  |  |  | } | 
| 594 |  |  |  |  |  |  |  | 
| 595 |  |  |  |  |  |  | sub name_actn { | 
| 596 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 597 | 0 |  |  |  |  | 0 | return 'Action'; | 
| 598 |  |  |  |  |  |  | } | 
| 599 |  |  |  |  |  |  |  | 
| 600 |  |  |  |  |  |  | sub dump_alis { | 
| 601 | 2 |  |  | 2 | 0 | 4 | my $self = shift; | 
| 602 | 2 |  |  |  |  | 3 | my ($pos, $len) = @_; | 
| 603 |  |  |  |  |  |  |  | 
| 604 | 2 |  |  |  |  | 8 | $self->append ('File #', groupDigits (NToSigned ($self->read (4))), "\n"); | 
| 605 |  |  |  |  |  |  | } | 
| 606 |  |  |  |  |  |  |  | 
| 607 |  |  |  |  |  |  | sub name_alis { | 
| 608 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 609 | 2 |  |  |  |  | 6 | return 'File alias'; | 
| 610 |  |  |  |  |  |  | } | 
| 611 |  |  |  |  |  |  |  | 
| 612 |  |  |  |  |  |  | sub dump_clip { | 
| 613 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 614 | 0 |  |  |  |  | 0 | $self->unwrapAtoms (@_); | 
| 615 |  |  |  |  |  |  | } | 
| 616 |  |  |  |  |  |  |  | 
| 617 |  |  |  |  |  |  | sub name_clip { | 
| 618 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 619 | 0 |  |  |  |  | 0 | return 'Clipping region'; | 
| 620 |  |  |  |  |  |  | } | 
| 621 |  |  |  |  |  |  |  | 
| 622 |  |  |  |  |  |  | sub dump_cmov { | 
| 623 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 624 | 0 |  |  |  |  | 0 | $self->unwrapAtoms (@_); | 
| 625 |  |  |  |  |  |  | } | 
| 626 |  |  |  |  |  |  |  | 
| 627 |  |  |  |  |  |  | sub name_cmov { | 
| 628 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 629 | 0 |  |  |  |  | 0 | return 'Compressed movie'; | 
| 630 |  |  |  |  |  |  | } | 
| 631 |  |  |  |  |  |  |  | 
| 632 |  |  |  |  |  |  | sub dump_code { | 
| 633 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 634 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 635 |  |  |  |  |  |  |  | 
| 636 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 637 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 638 |  |  |  |  |  |  | } | 
| 639 |  |  |  |  |  |  |  | 
| 640 |  |  |  |  |  |  | sub name_code { | 
| 641 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 642 | 0 |  |  |  |  | 0 | return 'Code resource'; | 
| 643 |  |  |  |  |  |  | } | 
| 644 |  |  |  |  |  |  |  | 
| 645 |  |  |  |  |  |  | sub dump_data { | 
| 646 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 647 | 0 |  |  |  |  | 0 | $self->unwrapAtoms (@_); | 
| 648 |  |  |  |  |  |  | } | 
| 649 |  |  |  |  |  |  |  | 
| 650 |  |  |  |  |  |  |  | 
| 651 |  |  |  |  |  |  | sub name_data { | 
| 652 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 653 | 0 |  |  |  |  | 0 | return 'Data resource'; | 
| 654 |  |  |  |  |  |  | } | 
| 655 |  |  |  |  |  |  |  | 
| 656 |  |  |  |  |  |  | sub dump_dcom { | 
| 657 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 658 |  |  |  |  |  |  |  | 
| 659 | 0 |  |  |  |  | 0 | $self->append ('Compression type: ', $self->get4Char (), "\n"); | 
| 660 |  |  |  |  |  |  | } | 
| 661 |  |  |  |  |  |  |  | 
| 662 |  |  |  |  |  |  | sub name_dcom { | 
| 663 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 664 | 0 |  |  |  |  | 0 | return 'Compression type'; | 
| 665 |  |  |  |  |  |  | } | 
| 666 |  |  |  |  |  |  |  | 
| 667 |  |  |  |  |  |  | sub dump_dflt { | 
| 668 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 669 |  |  |  |  |  |  |  | 
| 670 | 0 |  |  |  |  | 0 | $self->atomList (@_); | 
| 671 |  |  |  |  |  |  | } | 
| 672 |  |  |  |  |  |  |  | 
| 673 |  |  |  |  |  |  | sub name_dflt { | 
| 674 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 675 | 0 |  |  |  |  | 0 | return 'Shared frame'; | 
| 676 |  |  |  |  |  |  | } | 
| 677 |  |  |  |  |  |  |  | 
| 678 |  |  |  |  |  |  | sub dump_dinf { | 
| 679 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 680 |  |  |  |  |  |  |  | 
| 681 | 2 |  |  |  |  | 12 | $self->unwrapAtoms (@_); | 
| 682 |  |  |  |  |  |  | } | 
| 683 |  |  |  |  |  |  |  | 
| 684 |  |  |  |  |  |  | sub name_dint { | 
| 685 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 686 | 0 |  |  |  |  | 0 | return 'Media location'; | 
| 687 |  |  |  |  |  |  | } | 
| 688 |  |  |  |  |  |  |  | 
| 689 |  |  |  |  |  |  | sub dump_dref { | 
| 690 | 2 |  |  | 2 | 0 | 3 | my $self = shift; | 
| 691 |  |  |  |  |  |  |  | 
| 692 | 2 |  |  |  |  | 7 | $self->append   ("\n"); | 
| 693 | 2 |  |  |  |  | 9 | $self->atomList (@_); | 
| 694 |  |  |  |  |  |  | } | 
| 695 |  |  |  |  |  |  |  | 
| 696 |  |  |  |  |  |  | sub name_dref { | 
| 697 | 2 |  |  | 2 | 0 | 6 | my $self = shift; | 
| 698 | 2 |  |  |  |  | 5 | return 'Data references'; | 
| 699 |  |  |  |  |  |  | } | 
| 700 |  |  |  |  |  |  |  | 
| 701 |  |  |  |  |  |  | sub dump_edts { | 
| 702 | 2 |  |  | 2 | 0 | 7 | my $self = shift; | 
| 703 | 2 |  |  |  |  | 15 | $self->unwrapAtoms (@_); | 
| 704 |  |  |  |  |  |  | } | 
| 705 |  |  |  |  |  |  |  | 
| 706 |  |  |  |  |  |  | sub name_edts { | 
| 707 | 2 |  |  | 2 | 0 | 127 | my $self = shift; | 
| 708 | 2 |  |  |  |  | 13 | return "Edit list"; | 
| 709 |  |  |  |  |  |  | } | 
| 710 |  |  |  |  |  |  |  | 
| 711 |  |  |  |  |  |  | sub dump_elst { | 
| 712 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 713 |  |  |  |  |  |  |  | 
| 714 | 2 |  |  |  |  | 8 | $self->append ('Version:  ', unpack ('C',   $self->read (1)), "\n"); | 
| 715 | 2 |  |  |  |  | 80 | $self->append ('Flags:    ', unpack ('B24', $self->read (3)), "\n"); | 
| 716 |  |  |  |  |  |  |  | 
| 717 | 2 |  |  |  |  | 7 | my $items = NToSigned ($self->read (4)); | 
| 718 | 2 |  |  |  |  | 115 | for (1 .. $items) { | 
| 719 | 2 |  |  |  |  | 11 | $self->append ("  $_\n"); | 
| 720 | 2 |  |  |  |  | 10 | my $scale = $self->findAtomValue ('timescale'); | 
| 721 | 2 |  |  |  |  | 7 | my $duration = NToSigned ($self->read (4)); | 
| 722 | 2 | 50 |  |  |  | 12 | my $durSecs = $scale ? $duration / $scale : '---'; | 
| 723 | 2 |  |  |  |  | 239 | $self->append ("    Duration: $duration ticks (${durSecs} seconds)\n"); | 
| 724 | 2 |  |  |  |  | 7 | $self->append ('    Start:    ', NToSigned ($self->read (4)), "\n"); | 
| 725 | 2 |  |  |  |  | 9 | $self->append ('    Rate:     ', NToFixed ($self->read (4)), "\n"); | 
| 726 |  |  |  |  |  |  | } | 
| 727 |  |  |  |  |  |  | } | 
| 728 |  |  |  |  |  |  |  | 
| 729 |  |  |  |  |  |  | sub name_elst { | 
| 730 | 2 |  |  | 2 | 0 | 6 | my $self = shift; | 
| 731 | 2 |  |  |  |  | 81 | return 'Media edit segment defs'; | 
| 732 |  |  |  |  |  |  | } | 
| 733 |  |  |  |  |  |  |  | 
| 734 |  |  |  |  |  |  | sub dump_enfs { | 
| 735 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 736 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 737 |  |  |  |  |  |  |  | 
| 738 | 0 |  |  |  |  | 0 | $self->append ('Enabled: ', cToBool ($self->read (1)), "\n"); | 
| 739 |  |  |  |  |  |  | } | 
| 740 |  |  |  |  |  |  |  | 
| 741 |  |  |  |  |  |  | sub name_enfs { | 
| 742 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 743 | 0 |  |  |  |  | 0 | return 'Enable Frame Stepping'; | 
| 744 |  |  |  |  |  |  | } | 
| 745 |  |  |  |  |  |  |  | 
| 746 |  |  |  |  |  |  | sub dump_evnt { | 
| 747 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 748 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 749 |  |  |  |  |  |  |  | 
| 750 | 0 |  |  |  |  | 0 | $self->append ('Event type:     ', $self->get4Char (), "\n"); | 
| 751 |  |  |  |  |  |  |  | 
| 752 | 0 |  |  |  |  | 0 | NToSigned ($self->read (4)); | 
| 753 | 0 |  |  |  |  | 0 | $self->append      ("Reserved\n"); | 
| 754 | 0 |  |  |  |  | 0 | $self->read        (4); | 
| 755 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 756 |  |  |  |  |  |  | } | 
| 757 |  |  |  |  |  |  |  | 
| 758 |  |  |  |  |  |  | sub name_evnt { | 
| 759 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 760 | 0 |  |  |  |  | 0 | return 'Sprite event'; | 
| 761 |  |  |  |  |  |  | } | 
| 762 |  |  |  |  |  |  |  | 
| 763 |  |  |  |  |  |  | sub dump_expr { | 
| 764 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 765 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 766 |  |  |  |  |  |  |  | 
| 767 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 768 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 769 |  |  |  |  |  |  | } | 
| 770 |  |  |  |  |  |  |  | 
| 771 |  |  |  |  |  |  | sub name_expr { | 
| 772 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 773 | 0 |  |  |  |  | 0 | return 'Expression'; | 
| 774 |  |  |  |  |  |  | } | 
| 775 |  |  |  |  |  |  |  | 
| 776 |  |  |  |  |  |  | sub dump_free { | 
| 777 | 1 |  |  | 1 | 0 | 2 | my $self = shift; | 
| 778 | 1 |  |  |  |  | 3 | my ($pos, $len) = @_; | 
| 779 |  |  |  |  |  |  |  | 
| 780 | 1 |  |  |  |  | 20 | $self->append ("Padding = $len bytes\n"); | 
| 781 | 1 |  |  |  |  | 3 | $self->{parsedSize} += $len - 8; | 
| 782 |  |  |  |  |  |  | } | 
| 783 |  |  |  |  |  |  |  | 
| 784 |  |  |  |  |  |  | sub name_free { | 
| 785 | 1 |  |  | 1 | 0 | 3 | my $self = shift; | 
| 786 | 1 |  |  |  |  | 3 | return 'Unused space'; | 
| 787 |  |  |  |  |  |  | } | 
| 788 |  |  |  |  |  |  |  | 
| 789 |  |  |  |  |  |  | sub dump_ftyp { | 
| 790 | 1 |  |  | 1 | 0 | 2 | my $self = shift; | 
| 791 | 1 |  |  |  |  | 3 | $self->append (unpack ("a4", $self->read (4)), "\n"); | 
| 792 |  |  |  |  |  |  | } | 
| 793 |  |  |  |  |  |  |  | 
| 794 |  |  |  |  |  |  | sub name_ftyp { | 
| 795 | 1 |  |  | 1 | 0 | 3 | my $self = shift; | 
| 796 | 1 |  |  |  |  | 4 | return 'File type'; | 
| 797 |  |  |  |  |  |  | } | 
| 798 |  |  |  |  |  |  |  | 
| 799 |  |  |  |  |  |  | sub dump_gmhd { | 
| 800 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 801 | 0 |  |  |  |  | 0 | $self->unwrapAtoms (@_); | 
| 802 |  |  |  |  |  |  | } | 
| 803 |  |  |  |  |  |  |  | 
| 804 |  |  |  |  |  |  | sub name_gmhd { | 
| 805 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 806 | 0 |  |  |  |  | 0 | return 'Generic media header'; | 
| 807 |  |  |  |  |  |  | } | 
| 808 |  |  |  |  |  |  |  | 
| 809 |  |  |  |  |  |  | sub dump_gmin { | 
| 810 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 811 |  |  |  |  |  |  |  | 
| 812 | 0 |  |  |  |  | 0 | $self->append ('Version:  ', unpack ('C',   $self->read (1)), "\n"); | 
| 813 | 0 |  |  |  |  | 0 | $self->append ('Flags:    ', unpack ('B24', $self->read (3)), "\n"); | 
| 814 | 0 |  |  |  |  | 0 | $self->showGMode (); | 
| 815 | 0 |  |  |  |  | 0 | $self->showRGB   (); | 
| 816 | 0 |  |  |  |  | 0 | $self->append    ('Balance:  ', nToSigned ($self->read (2)), "\n"); | 
| 817 | 0 |  |  |  |  | 0 | $self->append    ("Reserved\n"); | 
| 818 | 0 |  |  |  |  | 0 | $self->read      (2); | 
| 819 |  |  |  |  |  |  | } | 
| 820 |  |  |  |  |  |  |  | 
| 821 |  |  |  |  |  |  | sub name_gmin { | 
| 822 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 823 | 0 |  |  |  |  | 0 | return 'Generic media information'; | 
| 824 |  |  |  |  |  |  | } | 
| 825 |  |  |  |  |  |  |  | 
| 826 |  |  |  |  |  |  | sub dump_hdlr { | 
| 827 | 4 |  |  | 4 | 0 | 10 | my $self = shift; | 
| 828 |  |  |  |  |  |  |  | 
| 829 | 4 |  |  |  |  | 14 | $self->append ('Version:  ', unpack ('C',   $self->read (1)), "\n"); | 
| 830 | 4 |  |  |  |  | 17 | $self->append ('Flags:    ', unpack ('B24', $self->read (3)), "\n"); | 
| 831 |  |  |  |  |  |  |  | 
| 832 | 4 |  |  |  |  | 20 | my $cmpt = $self->get4Char (); | 
| 833 | 4 |  |  |  |  | 17 | $self->append ('Component type:     ', $cmpt, "\n"); | 
| 834 |  |  |  |  |  |  |  | 
| 835 | 4 |  |  |  |  | 9 | my $subCmpt = $self->get4Char (); | 
| 836 | 4 |  |  |  |  | 13 | $self->append ('Component sub type: ', $subCmpt, "\n"); | 
| 837 |  |  |  |  |  |  |  | 
| 838 | 4 |  |  |  |  | 58 | $self->setParentAttrib (HdlrCmpt    => $cmpt); | 
| 839 | 4 |  |  |  |  | 80 | $self->setParentAttrib (HdlrSubCmpt => $subCmpt); | 
| 840 |  |  |  |  |  |  |  | 
| 841 | 4 |  |  |  |  | 11 | $self->append ('Manufacturer:       ', $self->get4Char (), "\n"); | 
| 842 | 4 |  |  |  |  | 61 | $self->append ('Flags:              ', unpack ('B32', $self->read (4)), | 
| 843 |  |  |  |  |  |  | "\n"); | 
| 844 | 4 |  |  |  |  | 14 | $self->append ('Mask:               ', unpack ('B32', $self->read (4)), | 
| 845 |  |  |  |  |  |  | "\n"); | 
| 846 |  |  |  |  |  |  |  | 
| 847 | 4 |  |  |  |  | 14 | my $strLen = ord ($self->read (1)); | 
| 848 | 4 |  |  |  |  | 30 | $self->append ('Name:               ', | 
| 849 |  |  |  |  |  |  | unpack ("a$strLen", $self->read ($strLen)), "\n"); | 
| 850 |  |  |  |  |  |  | } | 
| 851 |  |  |  |  |  |  |  | 
| 852 |  |  |  |  |  |  | sub name_hdlr { | 
| 853 | 4 |  |  | 4 | 0 | 7 | my $self = shift; | 
| 854 | 4 |  |  |  |  | 14 | return 'Media data handler'; | 
| 855 |  |  |  |  |  |  | } | 
| 856 |  |  |  |  |  |  |  | 
| 857 |  |  |  |  |  |  | sub dump_imag { | 
| 858 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 859 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 860 |  |  |  |  |  |  |  | 
| 861 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 862 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 863 |  |  |  |  |  |  | } | 
| 864 |  |  |  |  |  |  |  | 
| 865 |  |  |  |  |  |  | sub name_imag { | 
| 866 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 867 | 0 |  |  |  |  | 0 | return 'Image'; | 
| 868 |  |  |  |  |  |  | } | 
| 869 |  |  |  |  |  |  |  | 
| 870 |  |  |  |  |  |  | sub dump_imct { | 
| 871 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 872 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 873 |  |  |  |  |  |  |  | 
| 874 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 875 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 876 |  |  |  |  |  |  | } | 
| 877 |  |  |  |  |  |  |  | 
| 878 |  |  |  |  |  |  | sub name_imct { | 
| 879 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 880 | 0 |  |  |  |  | 0 | return 'Image container'; | 
| 881 |  |  |  |  |  |  | } | 
| 882 |  |  |  |  |  |  |  | 
| 883 |  |  |  |  |  |  | sub dump_imda { | 
| 884 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 885 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 886 |  |  |  |  |  |  |  | 
| 887 | 0 |  |  |  |  | 0 | $len -= 8; | 
| 888 | 0 |  |  |  |  | 0 | $self->append ("Image data " . groupDigits ($len) . " bytes long\n"); | 
| 889 | 0 |  |  |  |  | 0 | $self->{parsedSize} += $len; | 
| 890 |  |  |  |  |  |  | } | 
| 891 |  |  |  |  |  |  |  | 
| 892 |  |  |  |  |  |  | sub name_imda { | 
| 893 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 894 | 0 |  |  |  |  | 0 | return 'Image data'; | 
| 895 |  |  |  |  |  |  | } | 
| 896 |  |  |  |  |  |  |  | 
| 897 |  |  |  |  |  |  | sub dump_imgp { | 
| 898 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 899 |  |  |  |  |  |  |  | 
| 900 | 0 |  |  |  |  | 0 | $self->unwrapAtoms (@_); | 
| 901 |  |  |  |  |  |  | } | 
| 902 |  |  |  |  |  |  |  | 
| 903 |  |  |  |  |  |  | sub name_imgp { | 
| 904 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 905 | 0 |  |  |  |  | 0 | return 'Panorama image container'; | 
| 906 |  |  |  |  |  |  | } | 
| 907 |  |  |  |  |  |  |  | 
| 908 |  |  |  |  |  |  | sub dump_imrg { | 
| 909 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 910 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 911 |  |  |  |  |  |  |  | 
| 912 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 913 | 0 |  |  |  |  | 0 | $self->append      ('X:         ', NToFixed ($self->read (4)), "\n"); | 
| 914 | 0 |  |  |  |  | 0 | $self->append      ('Y:         ', NToFixed ($self->read (4)), "\n"); | 
| 915 |  |  |  |  |  |  | } | 
| 916 |  |  |  |  |  |  |  | 
| 917 |  |  |  |  |  |  | sub name_imrg { | 
| 918 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 919 | 0 |  |  |  |  | 0 | return 'Image group container'; | 
| 920 |  |  |  |  |  |  | } | 
| 921 |  |  |  |  |  |  |  | 
| 922 |  |  |  |  |  |  | sub dump_list { | 
| 923 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 924 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 925 |  |  |  |  |  |  |  | 
| 926 | 0 |  |  |  |  | 0 | $self->append ('Id:    ', NToSigned ($self->read (4)), "\n"); | 
| 927 | 0 |  |  |  |  | 0 | $self->append ('Items: ', NToSigned ($self->read (4)), "\n"); | 
| 928 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 8, $len - 8); | 
| 929 |  |  |  |  |  |  | } | 
| 930 |  |  |  |  |  |  |  | 
| 931 |  |  |  |  |  |  | sub name_list { | 
| 932 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 933 | 0 |  |  |  |  | 0 | return 'List'; | 
| 934 |  |  |  |  |  |  | } | 
| 935 |  |  |  |  |  |  |  | 
| 936 |  |  |  |  |  |  | sub dump_mdat { | 
| 937 | 1 |  |  | 1 | 0 | 88 | my $self = shift; | 
| 938 | 1 |  |  |  |  | 3 | my ($pos, $len) = @_; | 
| 939 |  |  |  |  |  |  |  | 
| 940 | 1 |  |  |  |  | 2 | $len -= 8; | 
| 941 | 1 |  |  |  |  | 140 | $self->append ("Media data " . groupDigits ($len) . " bytes long.\n"); | 
| 942 |  |  |  |  |  |  | } | 
| 943 |  |  |  |  |  |  |  | 
| 944 |  |  |  |  |  |  | sub name_mdat { | 
| 945 | 1 |  |  | 1 | 0 | 3 | my $self = shift; | 
| 946 | 1 |  |  |  |  | 3 | return 'Media data'; | 
| 947 |  |  |  |  |  |  | } | 
| 948 |  |  |  |  |  |  |  | 
| 949 |  |  |  |  |  |  | sub dump_MCPS { | 
| 950 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 951 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 952 | 0 |  |  |  |  | 0 | $self->dumpText ($pos + 8, $len - 8); | 
| 953 |  |  |  |  |  |  | } | 
| 954 |  |  |  |  |  |  |  | 
| 955 |  |  |  |  |  |  | sub dump_mdhd { | 
| 956 | 2 |  |  | 2 | 0 | 4 | my $self = shift; | 
| 957 |  |  |  |  |  |  |  | 
| 958 | 2 |  |  |  |  | 8 | $self->append ('Version:  ', unpack ('C',   $self->read (1)), "\n"); | 
| 959 | 2 |  |  |  |  | 9 | $self->append ('Flags:    ', unpack ('B24', $self->read (3)), "\n"); | 
| 960 | 2 |  |  |  |  | 21 | $self->append ('Creation time:     ', $self->showDate (), "\n"); | 
| 961 | 2 |  |  |  |  | 10 | $self->append ('Modification time: ', $self->showDate (), "\n"); | 
| 962 | 2 |  |  |  |  | 6 | my $timescale = NToSigned ($self->read (4)); | 
| 963 | 2 |  |  |  |  | 10 | $self->setParentAttrib (timescale => $timescale); | 
| 964 | 2 |  |  |  |  | 10 | $self->append ("Time scale:        $timescale ticks per second\n"); | 
| 965 | 2 |  |  |  |  | 51 | my $duration = NToSigned ($self->read (4)); | 
| 966 | 2 |  |  |  |  | 8 | my $durSecs = $duration / $timescale; | 
| 967 | 2 |  |  |  |  | 22 | $self->append ("Duration:          $duration ticks (${durSecs} seconds)\n"); | 
| 968 | 2 |  |  |  |  | 6 | $self->append ('Locale:            ', nToSigned ($self->read (2)), "\n"); | 
| 969 | 2 |  |  |  |  | 207 | $self->append ('Quality:           ', unpack ('B16', $self->read (2)), | 
| 970 |  |  |  |  |  |  | "\n"); | 
| 971 |  |  |  |  |  |  | } | 
| 972 |  |  |  |  |  |  |  | 
| 973 |  |  |  |  |  |  | sub name_mdhd { | 
| 974 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 975 | 2 |  |  |  |  | 5 | return 'Media header'; | 
| 976 |  |  |  |  |  |  | } | 
| 977 |  |  |  |  |  |  |  | 
| 978 |  |  |  |  |  |  | sub dump_mdia { | 
| 979 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 980 | 2 |  |  |  |  | 7 | $self->unwrapAtoms (@_); | 
| 981 |  |  |  |  |  |  | } | 
| 982 |  |  |  |  |  |  |  | 
| 983 |  |  |  |  |  |  | sub name_mdia { | 
| 984 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 985 | 2 |  |  |  |  | 7 | return 'Media container'; | 
| 986 |  |  |  |  |  |  | } | 
| 987 |  |  |  |  |  |  |  | 
| 988 |  |  |  |  |  |  | sub dump_minf { | 
| 989 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 990 |  |  |  |  |  |  |  | 
| 991 | 2 |  |  |  |  | 10 | $self->unwrapAtoms (@_); | 
| 992 |  |  |  |  |  |  | } | 
| 993 |  |  |  |  |  |  |  | 
| 994 |  |  |  |  |  |  | sub name_minf { | 
| 995 | 2 |  |  | 2 | 0 | 6 | my $self = shift; | 
| 996 | 2 |  |  |  |  | 6 | return 'Media data'; | 
| 997 |  |  |  |  |  |  | } | 
| 998 |  |  |  |  |  |  |  | 
| 999 |  |  |  |  |  |  | sub dump_mmdr { | 
| 1000 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1001 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1002 |  |  |  |  |  |  |  | 
| 1003 | 0 |  |  |  |  | 0 | $self->showBogus (); | 
| 1004 | 0 |  |  |  |  | 0 | $self->append    ('Unknown:  ', $self->get4Char (), "\n"); | 
| 1005 | 0 |  |  |  |  | 0 | $self->append    ('Unknown:  ', NToSigned ($self->read (4)), "\n"); | 
| 1006 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 21, $len - 21); | 
| 1007 |  |  |  |  |  |  | } | 
| 1008 |  |  |  |  |  |  |  | 
| 1009 |  |  |  |  |  |  | sub name_mmdr { | 
| 1010 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1011 | 0 |  |  |  |  | 0 | return 'Media data reference'; | 
| 1012 |  |  |  |  |  |  | } | 
| 1013 |  |  |  |  |  |  |  | 
| 1014 |  |  |  |  |  |  | sub dump_moov { | 
| 1015 | 1 |  |  | 1 | 0 | 2 | my $self = shift; | 
| 1016 |  |  |  |  |  |  |  | 
| 1017 | 1 |  |  |  |  | 5 | $self->unwrapAtoms (@_); | 
| 1018 |  |  |  |  |  |  | } | 
| 1019 |  |  |  |  |  |  |  | 
| 1020 |  |  |  |  |  |  | sub name_moov { | 
| 1021 | 1 |  |  | 1 | 0 | 9 | my $self = shift; | 
| 1022 | 1 |  |  |  |  | 4 | return 'Movie container'; | 
| 1023 |  |  |  |  |  |  | } | 
| 1024 |  |  |  |  |  |  |  | 
| 1025 |  |  |  |  |  |  | sub dump_motx { | 
| 1026 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1027 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1028 |  |  |  |  |  |  |  | 
| 1029 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 1030 | 0 |  |  |  |  | 0 | $self->append ('Track index: ', NToSigned ($self->read (4)), "\n"); | 
| 1031 |  |  |  |  |  |  | } | 
| 1032 |  |  |  |  |  |  |  | 
| 1033 |  |  |  |  |  |  | sub name_motx { | 
| 1034 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1035 | 0 |  |  |  |  | 0 | return 'Media track index'; | 
| 1036 |  |  |  |  |  |  | } | 
| 1037 |  |  |  |  |  |  |  | 
| 1038 |  |  |  |  |  |  | sub dump_mvhd { | 
| 1039 | 1 |  |  | 1 | 0 | 3 | my $self = shift; | 
| 1040 | 1 |  |  |  |  | 3 | my ($pos, $len) = @_; | 
| 1041 | 1 |  |  |  |  | 4 | my $buffer = $self->read ($len - 8); | 
| 1042 |  |  |  |  |  |  |  | 
| 1043 | 1 |  |  |  |  | 9 | $self->append ('Version:       ', | 
| 1044 |  |  |  |  |  |  | unpack ('C', substr ($buffer, 0, 1, '')) . "\n"); | 
| 1045 | 1 |  |  |  |  | 8 | $self->append ('Flags:         ', | 
| 1046 |  |  |  |  |  |  | unpack ('B24', substr ($buffer, 0, 3, '')) . "\n"); | 
| 1047 | 1 |  |  |  |  | 7 | $self->append ('Created:       ', | 
| 1048 |  |  |  |  |  |  | $self->showDate (substr ($buffer, 0, 4, '')) . "\n"); | 
| 1049 | 1 |  |  |  |  | 5 | $self->append ('Modified:      ', | 
| 1050 |  |  |  |  |  |  | $self->showDate (substr ($buffer, 0, 4, '')) . "\n"); | 
| 1051 |  |  |  |  |  |  |  | 
| 1052 | 1 |  |  |  |  | 7 | my $timescale = NToSigned (substr ($buffer, 0, 4, '')); | 
| 1053 | 1 |  |  |  |  | 6 | $self->setParentAttrib (timescale => $timescale); | 
| 1054 | 1 |  |  |  |  | 5 | $self->append ("Time scale:    $timescale ticks per second\n"); | 
| 1055 |  |  |  |  |  |  |  | 
| 1056 | 1 |  |  |  |  | 3 | my $duration = unpack ("N", substr ($buffer, 0, 4, '')); | 
| 1057 | 1 |  |  |  |  | 4 | my $durSecs = $duration / $timescale; | 
| 1058 | 1 |  |  |  |  | 17 | $self->append ("Duration:      $duration ticks (${durSecs} seconds)\n"); | 
| 1059 | 1 |  |  |  |  | 7 | $self->append ('Pref rate:     ', | 
| 1060 |  |  |  |  |  |  | NToFixed (substr ($buffer, 0, 4, '')) . "\n"); | 
| 1061 | 1 |  |  |  |  | 7 | $self->append ('Pref vol:      ', | 
| 1062 |  |  |  |  |  |  | unpack ("n", substr ($buffer, 0, 2, '')) . "\n"); | 
| 1063 | 1 |  |  |  |  | 2 | $self->append ("Reserved\n"); | 
| 1064 | 1 |  |  |  |  | 2 | substr $buffer, 0, 10, ''; | 
| 1065 | 1 |  |  |  |  | 6 | $self->append ('Matrix:        ', | 
| 1066 |  |  |  |  |  |  | $self->showMatrix (substr ($buffer, 0, 36, '')) . "\n"); | 
| 1067 | 1 |  |  |  |  | 6 | $self->append ('Preview start: ', | 
| 1068 |  |  |  |  |  |  | unpack ("N", substr ($buffer, 0, 4, '')) . "\n"); | 
| 1069 | 1 |  |  |  |  | 6 | $self->append ('Preview time:  ', | 
| 1070 |  |  |  |  |  |  | unpack ("N", substr ($buffer, 0, 4, '')) . "\n"); | 
| 1071 | 1 |  |  |  |  | 19 | $self->append ('Poster loc:    ', | 
| 1072 |  |  |  |  |  |  | unpack ("N", substr ($buffer, 0, 4, '')) . "\n"); | 
| 1073 | 1 |  |  |  |  | 6 | $self->append ('Sel start:     ', | 
| 1074 |  |  |  |  |  |  | unpack ("N", substr ($buffer, 0, 4, '')) . "\n"); | 
| 1075 | 1 |  |  |  |  | 5 | $self->append ('Sel time:      ', | 
| 1076 |  |  |  |  |  |  | unpack ("N", substr ($buffer, 0, 4, '')) . "\n"); | 
| 1077 | 1 |  |  |  |  | 6 | $self->append ('Time now:      ', | 
| 1078 |  |  |  |  |  |  | unpack ("N", substr ($buffer, 0, 4, '')) . "\n"); | 
| 1079 | 1 |  |  |  |  | 3 | my $nextTrackId = unpack ("N", substr ($buffer, 0, 4, '')); | 
| 1080 | 1 |  |  |  |  | 5 | $self->append ("Next track: $nextTrackId\n"); | 
| 1081 | 1 |  |  |  |  | 3 | $self->{tracks} = $nextTrackId - 1; | 
| 1082 |  |  |  |  |  |  | } | 
| 1083 |  |  |  |  |  |  |  | 
| 1084 |  |  |  |  |  |  | sub name_mvhd { | 
| 1085 | 1 |  |  | 1 | 0 | 3 | my $self = shift; | 
| 1086 | 1 |  |  |  |  | 3 | return 'Movie header'; | 
| 1087 |  |  |  |  |  |  | } | 
| 1088 |  |  |  |  |  |  |  | 
| 1089 |  |  |  |  |  |  | sub dump_name { | 
| 1090 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1091 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1092 | 0 |  |  |  |  | 0 | my $parentType = $self->{atomStack}[-2][0]; | 
| 1093 |  |  |  |  |  |  |  | 
| 1094 | 0 | 0 |  |  |  | 0 | if ($parentType eq 'imag') { | 
| 1095 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 1096 | 0 |  |  |  |  | 0 | $self->dumpUnicodeText ($pos + 12, $len - 12); | 
| 1097 |  |  |  |  |  |  | } else { | 
| 1098 | 0 |  |  |  |  | 0 | $self->dumpText ($pos + 8, $len - 8); | 
| 1099 |  |  |  |  |  |  | } | 
| 1100 |  |  |  |  |  |  | } | 
| 1101 |  |  |  |  |  |  |  | 
| 1102 |  |  |  |  |  |  | sub name_name { | 
| 1103 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1104 | 0 |  |  |  |  | 0 | return 'Name'; | 
| 1105 |  |  |  |  |  |  | } | 
| 1106 |  |  |  |  |  |  |  | 
| 1107 |  |  |  |  |  |  | sub dump_oper { | 
| 1108 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1109 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1110 |  |  |  |  |  |  |  | 
| 1111 | 0 |  |  |  |  | 0 | $self->append ('Operation: ', $self->get4Char (), "\n"); | 
| 1112 | 0 |  |  |  |  | 0 | $self->append ('Operands:  ', NToSigned ($self->read (4)), "\n"); | 
| 1113 | 0 |  |  |  |  | 0 | $self->append ("Reserved\n"); | 
| 1114 | 0 |  |  |  |  | 0 | $self->read   (4); | 
| 1115 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 1116 |  |  |  |  |  |  | } | 
| 1117 |  |  |  |  |  |  |  | 
| 1118 |  |  |  |  |  |  | sub name_oper { | 
| 1119 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1120 | 0 |  |  |  |  | 0 | return 'Operation'; | 
| 1121 |  |  |  |  |  |  | } | 
| 1122 |  |  |  |  |  |  |  | 
| 1123 |  |  |  |  |  |  | sub dump_oprn { | 
| 1124 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1125 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1126 |  |  |  |  |  |  |  | 
| 1127 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 1128 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 1129 |  |  |  |  |  |  | } | 
| 1130 |  |  |  |  |  |  |  | 
| 1131 |  |  |  |  |  |  | sub name_oprn { | 
| 1132 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1133 | 0 |  |  |  |  | 0 | return 'Operand'; | 
| 1134 |  |  |  |  |  |  | } | 
| 1135 |  |  |  |  |  |  |  | 
| 1136 |  |  |  |  |  |  | sub dump_parm { | 
| 1137 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1138 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1139 | 0 |  |  |  |  | 0 | my $paramID = NToSigned ($self->read (4)); | 
| 1140 |  |  |  |  |  |  |  | 
| 1141 | 0 |  |  |  |  | 0 | $self->append ('ID:        ', $paramID, "\n"); | 
| 1142 | 0 |  |  |  |  | 0 | $self->append ('Unknown 2: ', NToSigned ($self->read (4)), "\n"); | 
| 1143 | 0 |  |  |  |  | 0 | $self->append ('Unknown 3: ', NToSigned ($self->read (4)), "\n"); | 
| 1144 |  |  |  |  |  |  |  | 
| 1145 | 0 |  |  |  |  | 0 | my $actionStr = $self->findAtomValue ('ActionType'); | 
| 1146 | 0 |  |  |  |  | 0 | my $atoms = qq/ | 
| 1147 |  |  |  |  |  |  | kActionCase | kActionWhile | 
| 1148 |  |  |  |  |  |  | /; | 
| 1149 | 0 |  |  |  |  | 0 | my $flags = qq/ | 
| 1150 |  |  |  |  |  |  | kActionMovieSetLoopingFlags | 
| 1151 |  |  |  |  |  |  | /; | 
| 1152 | 0 |  |  |  |  | 0 | my $fixed = qq/ | 
| 1153 |  |  |  |  |  |  | kActionMovieSetRate | kActionSpriteRotate | 
| 1154 |  |  |  |  |  |  | /; | 
| 1155 | 0 |  |  |  |  | 0 | my $fixedFixedBool = qq/ | 
| 1156 |  |  |  |  |  |  | kActionSpriteTranslate | 
| 1157 |  |  |  |  |  |  | /; | 
| 1158 | 0 |  |  |  |  | 0 | my $long = qq/ | 
| 1159 |  |  |  |  |  |  | kActionMovieSetLanguage | | 
| 1160 |  |  |  |  |  |  | kActionMovieSetSelection | kActionMovieRestartAtTime | | 
| 1161 |  |  |  |  |  |  | kActionQTVRGoToNodeID | kActionMusicPlayNote | | 
| 1162 |  |  |  |  |  |  | kActionMusicSetController | kOperandSpriteTrackVariable | 
| 1163 |  |  |  |  |  |  | /; | 
| 1164 | 0 |  |  |  |  | 0 | my $name = qq/ | 
| 1165 |  |  |  |  |  |  | kActionMovieGoToTimeByName | kActionMovieSetSelectionByName | 
| 1166 |  |  |  |  |  |  | /; | 
| 1167 | 0 |  |  |  |  | 0 | my $quadFloat = qq/ | 
| 1168 |  |  |  |  |  |  | kActionSpriteTrackSetVariable | 
| 1169 |  |  |  |  |  |  | /; | 
| 1170 | 0 |  |  |  |  | 0 | my $rgnHandle = qq/ | 
| 1171 |  |  |  |  |  |  | kActionTrackSetClip | 
| 1172 |  |  |  |  |  |  | /; | 
| 1173 | 0 |  |  |  |  | 0 | my $short = qq/ | 
| 1174 |  |  |  |  |  |  | kActionMovieSetVolume | kActionTrackSetVolume | | 
| 1175 |  |  |  |  |  |  | kActionTrackSetBalance | kActionTrackSetLayer | | 
| 1176 |  |  |  |  |  |  | kActionSpriteSetImageIndex | kActionSpriteSetVisible | | 
| 1177 |  |  |  |  |  |  | kActionSpriteSetLayer | 
| 1178 |  |  |  |  |  |  | /; | 
| 1179 | 0 |  |  |  |  | 0 | my $time = qq/ | 
| 1180 |  |  |  |  |  |  | kActionMovieGoToTime | 
| 1181 |  |  |  |  |  |  | /; | 
| 1182 |  |  |  |  |  |  |  | 
| 1183 | 0 | 0 |  |  |  | 0 | if ($actionStr =~ m/$atoms/x) { | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 1184 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 1185 |  |  |  |  |  |  | } elsif ($actionStr =~ m/$time/x) { | 
| 1186 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 1187 |  |  |  |  |  |  | } elsif ($actionStr =~ m/$flags/x) { | 
| 1188 | 0 |  |  |  |  | 0 | $self->append ('Flags: ', NToBin ($self->read (4)), "\n"); | 
| 1189 |  |  |  |  |  |  | } elsif ($actionStr =~ m/$fixed/x) { | 
| 1190 | 0 |  |  |  |  | 0 | $self->append ('Value: ', NToFixed ($self->read (4)), "\n"); | 
| 1191 |  |  |  |  |  |  | } elsif ($actionStr =~ m/$fixedFixedBool/x) { | 
| 1192 | 0 |  |  |  |  | 0 | $self->append ('Value 1:    ', NToFixed ($self->read (4)), "\n"); | 
| 1193 | 0 |  |  |  |  | 0 | $self->append ('Value 2:    ', NToFixed ($self->read (4)), "\n"); | 
| 1194 | 0 |  |  |  |  | 0 | $self->append ('Bool value: ', cToBool  ($self->read (1)), "\n"); | 
| 1195 |  |  |  |  |  |  | } elsif ($actionStr =~ m/$long/x) { | 
| 1196 | 0 |  |  |  |  | 0 | $self->append ('Value: ', groupDigits (NToSigned ($self->read (4))), | 
| 1197 |  |  |  |  |  |  | "\n"); | 
| 1198 |  |  |  |  |  |  | } elsif ($actionStr =~ m/$name/x) { | 
| 1199 | 0 |  |  |  |  | 0 | $self->dumpText ($pos + 12, $len - 12); | 
| 1200 |  |  |  |  |  |  | } elsif ($actionStr =~ m/$quadFloat/x) { | 
| 1201 | 0 | 0 |  |  |  | 0 | if ($paramID == 1) { | 
| 1202 | 0 |  |  |  |  | 0 | $self->append ('ID: ', NToSigned ($self->read (4)), "\n"); | 
| 1203 |  |  |  |  |  |  | } else { | 
| 1204 | 0 |  |  |  |  | 0 | $self->append ('value: ', $self->fToFloat ($self->read (4)), "\n"); | 
| 1205 |  |  |  |  |  |  | } | 
| 1206 |  |  |  |  |  |  | } elsif ($actionStr =~ m/$rgnHandle/x) { | 
| 1207 | 0 |  |  |  |  | 0 | $self->append ('Size:   ', nToSigned ($self->read (2)), "\n"); | 
| 1208 | 0 |  |  |  |  | 0 | $self->append ('Top:    ', nToSigned ($self->read (2)), "\n"); | 
| 1209 | 0 |  |  |  |  | 0 | $self->append ('Left:   ', nToSigned ($self->read (2)), "\n"); | 
| 1210 | 0 |  |  |  |  | 0 | $self->append ('Bottom: ', nToSigned ($self->read (2)), "\n"); | 
| 1211 | 0 |  |  |  |  | 0 | $self->append ('Right:  ', nToSigned ($self->read (2)), "\n"); | 
| 1212 |  |  |  |  |  |  | } elsif ($actionStr =~ m/$short/x) { | 
| 1213 | 0 |  |  |  |  | 0 | $self->append ('Value: ', nToSigned ($self->read (2)), "\n"); | 
| 1214 |  |  |  |  |  |  | } else { | 
| 1215 | 0 |  |  |  |  | 0 | $self->append ("Unhandled parameter for action: $actionStr\n"); | 
| 1216 | 0 | 0 |  |  |  | 0 | print "Unhandled parameter for action: $actionStr\n" | 
| 1217 |  |  |  |  |  |  | if $self->{noise} > 1; | 
| 1218 |  |  |  |  |  |  | } | 
| 1219 |  |  |  |  |  |  | } | 
| 1220 |  |  |  |  |  |  |  | 
| 1221 |  |  |  |  |  |  | sub name_parm { | 
| 1222 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1223 | 0 |  |  |  |  | 0 | return 'Parameter'; | 
| 1224 |  |  |  |  |  |  | } | 
| 1225 |  |  |  |  |  |  |  | 
| 1226 |  |  |  |  |  |  | sub dump_play { | 
| 1227 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1228 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1229 |  |  |  |  |  |  |  | 
| 1230 | 0 |  |  |  |  | 0 | $self->append ('Enabled: ', cToBool ($self->read (1)), "\n"); | 
| 1231 |  |  |  |  |  |  | } | 
| 1232 |  |  |  |  |  |  |  | 
| 1233 |  |  |  |  |  |  | sub name_play { | 
| 1234 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1235 | 0 |  |  |  |  | 0 | return 'Auto play'; | 
| 1236 |  |  |  |  |  |  | } | 
| 1237 |  |  |  |  |  |  |  | 
| 1238 |  |  |  |  |  |  | sub dump_rdrf { | 
| 1239 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1240 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1241 |  |  |  |  |  |  |  | 
| 1242 | 0 |  |  |  |  | 0 | $self->append ('Flags:               ', NToBin ($self->read (4)), "\n"); | 
| 1243 | 0 |  |  |  |  | 0 | $self->append ('Data reference type: ', $self->get4Char (4), "\n"); | 
| 1244 | 0 |  |  |  |  | 0 | my $size = NToSigned ($self->read (4)); | 
| 1245 | 0 |  |  |  |  | 0 | $self->append ('Data reference size: ', $size, "\n"); | 
| 1246 | 0 |  |  |  |  | 0 | $self->append ('Data reference:      ', $self->read ($size), "\n"); | 
| 1247 |  |  |  |  |  |  | } | 
| 1248 |  |  |  |  |  |  |  | 
| 1249 |  |  |  |  |  |  | sub name_rdrf { | 
| 1250 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1251 | 0 |  |  |  |  | 0 | return 'Data reference'; | 
| 1252 |  |  |  |  |  |  | } | 
| 1253 |  |  |  |  |  |  |  | 
| 1254 |  |  |  |  |  |  | sub dump_rmcs { | 
| 1255 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1256 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1257 |  |  |  |  |  |  |  | 
| 1258 | 0 |  |  |  |  | 0 | $self->append ('Flags:     ', NToBin    ($self->read (4)), "\n"); | 
| 1259 | 0 |  |  |  |  | 0 | $self->append ('CPU speed: ', NToSigned ($self->read (4)), "\n"); | 
| 1260 |  |  |  |  |  |  | } | 
| 1261 |  |  |  |  |  |  |  | 
| 1262 |  |  |  |  |  |  | sub name_rmcs { | 
| 1263 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1264 | 0 |  |  |  |  | 0 | return 'CPU speed'; | 
| 1265 |  |  |  |  |  |  | } | 
| 1266 |  |  |  |  |  |  |  | 
| 1267 |  |  |  |  |  |  | sub dump_rmda { | 
| 1268 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1269 | 0 |  |  |  |  | 0 | $self->unwrapAtoms (@_); | 
| 1270 |  |  |  |  |  |  | } | 
| 1271 |  |  |  |  |  |  |  | 
| 1272 |  |  |  |  |  |  | sub name_rmda { | 
| 1273 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1274 | 0 |  |  |  |  | 0 | return 'Reference movie descriptor'; | 
| 1275 |  |  |  |  |  |  | } | 
| 1276 |  |  |  |  |  |  |  | 
| 1277 |  |  |  |  |  |  | sub dump_rmdr { | 
| 1278 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1279 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1280 |  |  |  |  |  |  |  | 
| 1281 | 0 |  |  |  |  | 0 | $self->append ('Flags:     ', NToBin    ($self->read (4)), "\n"); | 
| 1282 | 0 |  |  |  |  | 0 | $self->append ('Data rate: ', NToSigned ($self->read (4)), "\n"); | 
| 1283 |  |  |  |  |  |  | } | 
| 1284 |  |  |  |  |  |  |  | 
| 1285 |  |  |  |  |  |  | sub name_rmdr { | 
| 1286 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1287 | 0 |  |  |  |  | 0 | return 'Data rate'; | 
| 1288 |  |  |  |  |  |  | } | 
| 1289 |  |  |  |  |  |  |  | 
| 1290 |  |  |  |  |  |  | sub dump_rmqu { | 
| 1291 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1292 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1293 |  |  |  |  |  |  |  | 
| 1294 | 0 |  |  |  |  | 0 | $self->append ('Quality: ', NToSigned ($self->read (4)), "\n"); | 
| 1295 |  |  |  |  |  |  | } | 
| 1296 |  |  |  |  |  |  |  | 
| 1297 |  |  |  |  |  |  | sub name_rmqu { | 
| 1298 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1299 | 0 |  |  |  |  | 0 | return 'Quality'; | 
| 1300 |  |  |  |  |  |  | } | 
| 1301 |  |  |  |  |  |  |  | 
| 1302 |  |  |  |  |  |  | sub dump_rmra { | 
| 1303 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1304 | 0 |  |  |  |  | 0 | $self->unwrapAtoms (@_); | 
| 1305 |  |  |  |  |  |  | } | 
| 1306 |  |  |  |  |  |  |  | 
| 1307 |  |  |  |  |  |  | sub name_rmra { | 
| 1308 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1309 | 0 |  |  |  |  | 0 | return 'Reference movie'; | 
| 1310 |  |  |  |  |  |  | } | 
| 1311 |  |  |  |  |  |  |  | 
| 1312 |  |  |  |  |  |  | sub dump_rmvc { | 
| 1313 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1314 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1315 |  |  |  |  |  |  |  | 
| 1316 | 0 |  |  |  |  | 0 | $self->append ('Flags:            ', NToBin ($self->read (4)), "\n"); | 
| 1317 | 0 |  |  |  |  | 0 | $self->append ('Software package: ', $self->get4Char (), "\n"); | 
| 1318 | 0 |  |  |  |  | 0 | $self->append ('Version:          ', NToHex    ($self->read (4)), "\n"); | 
| 1319 | 0 |  |  |  |  | 0 | $self->append ('Mask:             ', NToHex    ($self->read (4)), "\n"); | 
| 1320 | 0 |  |  |  |  | 0 | $self->append ('Check type:       ', nToSigned ($self->read (2)), "\n"); | 
| 1321 |  |  |  |  |  |  | } | 
| 1322 |  |  |  |  |  |  |  | 
| 1323 |  |  |  |  |  |  | sub name_rmvc { | 
| 1324 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1325 | 0 |  |  |  |  | 0 | return 'Version check'; | 
| 1326 |  |  |  |  |  |  | } | 
| 1327 |  |  |  |  |  |  |  | 
| 1328 |  |  |  |  |  |  | sub dump_sean { | 
| 1329 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1330 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1331 | 0 |  |  |  |  | 0 | my $end = $pos + $len; | 
| 1332 |  |  |  |  |  |  |  | 
| 1333 | 0 |  |  |  |  | 0 | $pos += 20; | 
| 1334 | 0 |  |  |  |  | 0 | $self->describeAtomsIn ($pos, $end); | 
| 1335 |  |  |  |  |  |  | } | 
| 1336 |  |  |  |  |  |  |  | 
| 1337 |  |  |  |  |  |  | sub name_sean { | 
| 1338 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1339 | 0 |  |  |  |  | 0 | return 'Sprite scene container'; | 
| 1340 |  |  |  |  |  |  | } | 
| 1341 |  |  |  |  |  |  |  | 
| 1342 |  |  |  |  |  |  | sub dump_slau { | 
| 1343 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1344 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1345 |  |  |  |  |  |  |  | 
| 1346 | 0 |  |  |  |  | 0 | $self->append ('Enabled: ', cToBool ($self->read (1)), "\n"); | 
| 1347 |  |  |  |  |  |  | } | 
| 1348 |  |  |  |  |  |  |  | 
| 1349 |  |  |  |  |  |  | sub name_slau { | 
| 1350 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1351 | 0 |  |  |  |  | 0 | return 'Slave audio'; | 
| 1352 |  |  |  |  |  |  | } | 
| 1353 |  |  |  |  |  |  |  | 
| 1354 |  |  |  |  |  |  | sub dump_slgr { | 
| 1355 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1356 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1357 |  |  |  |  |  |  |  | 
| 1358 | 0 |  |  |  |  | 0 | $self->append ('Enabled: ', cToBool ($self->read (1)), "\n"); | 
| 1359 |  |  |  |  |  |  | } | 
| 1360 |  |  |  |  |  |  |  | 
| 1361 |  |  |  |  |  |  | sub name_slgr { | 
| 1362 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1363 | 0 |  |  |  |  | 0 | return 'Slave graphics mode'; | 
| 1364 |  |  |  |  |  |  | } | 
| 1365 |  |  |  |  |  |  |  | 
| 1366 |  |  |  |  |  |  | sub dump_slti { | 
| 1367 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1368 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1369 |  |  |  |  |  |  |  | 
| 1370 | 0 |  |  |  |  | 0 | $self->append ('Enabled: ', cToBool ($self->read (1)), "\n"); | 
| 1371 |  |  |  |  |  |  | } | 
| 1372 |  |  |  |  |  |  |  | 
| 1373 |  |  |  |  |  |  | sub name_slti { | 
| 1374 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1375 | 0 |  |  |  |  | 0 | return 'Slave time'; | 
| 1376 |  |  |  |  |  |  | } | 
| 1377 |  |  |  |  |  |  |  | 
| 1378 |  |  |  |  |  |  | sub dump_sltr { | 
| 1379 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1380 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1381 |  |  |  |  |  |  |  | 
| 1382 | 0 |  |  |  |  | 0 | $self->append ('Enabled: ', cToBool ($self->read (1)), "\n"); | 
| 1383 |  |  |  |  |  |  | } | 
| 1384 |  |  |  |  |  |  |  | 
| 1385 |  |  |  |  |  |  | sub name_sltr { | 
| 1386 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1387 | 0 |  |  |  |  | 0 | return 'Slave track duration'; | 
| 1388 |  |  |  |  |  |  | } | 
| 1389 |  |  |  |  |  |  |  | 
| 1390 |  |  |  |  |  |  | sub dump_spid { | 
| 1391 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1392 |  |  |  |  |  |  |  | 
| 1393 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 1394 | 0 |  |  |  |  | 0 | $self->append ('Sprite id: ', NToSigned ($self->read (4)), "\n"); | 
| 1395 |  |  |  |  |  |  | } | 
| 1396 |  |  |  |  |  |  |  | 
| 1397 |  |  |  |  |  |  | sub name_spid { | 
| 1398 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1399 | 0 |  |  |  |  | 0 | return 'Sprite ID'; | 
| 1400 |  |  |  |  |  |  | } | 
| 1401 |  |  |  |  |  |  |  | 
| 1402 |  |  |  |  |  |  | sub dump_stbl { | 
| 1403 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 1404 |  |  |  |  |  |  |  | 
| 1405 | 2 |  |  |  |  | 5 | $self->unwrapAtoms (@_); | 
| 1406 |  |  |  |  |  |  | } | 
| 1407 |  |  |  |  |  |  |  | 
| 1408 |  |  |  |  |  |  | sub name_stbl { | 
| 1409 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 1410 | 2 |  |  |  |  | 7 | return 'Media time to sample data'; | 
| 1411 |  |  |  |  |  |  | } | 
| 1412 |  |  |  |  |  |  |  | 
| 1413 |  |  |  |  |  |  | sub dump_stco { | 
| 1414 | 2 |  |  | 2 | 0 | 4 | my $self = shift; | 
| 1415 | 2 |  |  |  |  | 5 | my ($pos, $len) = @_; | 
| 1416 | 2 |  |  |  |  | 91 | my $dataRef = $self->findAtom ('HdlrSubCmpt', qr'^(?!alis)'); | 
| 1417 |  |  |  |  |  |  |  | 
| 1418 | 2 |  |  |  |  | 14 | $self->append ('Version:  ', unpack ('C',   $self->read (1)), "\n"); | 
| 1419 | 2 |  |  |  |  | 7 | $self->append ('Flags:    ', unpack ('B24', $self->read (3)), "\n"); | 
| 1420 |  |  |  |  |  |  |  | 
| 1421 | 2 |  |  |  |  | 5 | my $entries = NToSigned ($self->read (4)); | 
| 1422 | 2 |  |  |  |  | 5 | my $digits  = length $entries; | 
| 1423 | 2 |  | 50 |  |  | 22 | my $type    = (defined $dataRef && $dataRef->{'HdlrSubCmpt'}) || ''; | 
| 1424 | 2 |  |  |  |  | 6 | $pos += 16; | 
| 1425 |  |  |  |  |  |  |  | 
| 1426 | 2 |  |  |  |  | 251 | for (1 .. $entries) { | 
| 1427 | 40 |  |  |  |  | 193 | my $off = NToSigned ($self->read (4, $pos)); | 
| 1428 | 40 |  |  |  |  | 68 | $pos += 4; | 
| 1429 | 40 |  |  |  |  | 225 | $self->append (sprintf ("  %*d ", $digits, $_)); | 
| 1430 | 40 |  |  |  |  | 544 | $self->append ("$type @ ", sprintf "%d (0x%04x)\n", $off, $off); | 
| 1431 | 40 | 50 |  |  |  | 252 | if ($type =~ /sprt|moov/) { | 
|  |  | 100 |  |  |  |  |  | 
| 1432 | 0 |  |  |  |  | 0 | $self->describeAtom ($off + 12); | 
| 1433 |  |  |  |  |  |  | } elsif ($type eq 'vide') { | 
| 1434 | 20 |  |  |  |  | 38 | $self->append ("    Not expanded\n"); | 
| 1435 |  |  |  |  |  |  | } else { | 
| 1436 | 20 | 50 | 33 |  |  | 53 | print "stco doesn't handle $type chunks\n" | 
| 1437 |  |  |  |  |  |  | if $self->{noise} && $self->{noise} > 1; | 
| 1438 | 20 |  |  |  |  | 110 | next; | 
| 1439 |  |  |  |  |  |  | } | 
| 1440 |  |  |  |  |  |  | } | 
| 1441 |  |  |  |  |  |  | } | 
| 1442 |  |  |  |  |  |  |  | 
| 1443 |  |  |  |  |  |  | sub name_stco { | 
| 1444 | 2 |  |  | 2 | 0 | 8 | my $self = shift; | 
| 1445 | 2 |  |  |  |  | 10 | return 'Media data chunk locations'; | 
| 1446 |  |  |  |  |  |  | } | 
| 1447 |  |  |  |  |  |  |  | 
| 1448 |  |  |  |  |  |  | sub dump_sprt { | 
| 1449 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1450 |  |  |  |  |  |  |  | 
| 1451 | 0 |  |  |  |  | 0 | $self->atomList (@_); | 
| 1452 |  |  |  |  |  |  | } | 
| 1453 |  |  |  |  |  |  |  | 
| 1454 |  |  |  |  |  |  | sub name_sprt { | 
| 1455 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1456 | 0 |  |  |  |  | 0 | return 'Sprite key frame'; | 
| 1457 |  |  |  |  |  |  | } | 
| 1458 |  |  |  |  |  |  |  | 
| 1459 |  |  |  |  |  |  | sub dump_stsc { | 
| 1460 | 2 |  |  | 2 | 0 | 4 | my $self = shift; | 
| 1461 | 2 |  |  |  |  | 47 | my ($pos, $len) = @_; | 
| 1462 |  |  |  |  |  |  |  | 
| 1463 | 2 |  |  |  |  | 9 | $self->append ('Version:  ', unpack ('C',   $self->read (1)), "\n"); | 
| 1464 | 2 |  |  |  |  | 9 | $self->append ('Flags:    ', unpack ('B24', $self->read (3)), "\n"); | 
| 1465 | 2 |  |  |  |  | 18 | my $entries = NToSigned ($self->read (4)); | 
| 1466 | 2 |  |  |  |  | 5 | my $digits = length $entries; | 
| 1467 |  |  |  |  |  |  |  | 
| 1468 | 2 |  |  |  |  | 18 | for (1 .. $entries) { | 
| 1469 | 27 |  |  |  |  | 573 | $self->append (sprintf ("  %*d\n", $digits, $_)); | 
| 1470 | 27 |  |  |  |  | 140 | $self->append ('    first chunk: ', NToSigned ($self->read (4)), "\n"); | 
| 1471 | 27 |  |  |  |  | 114 | $self->append ('    samp per chunk: ', NToSigned ($self->read (4)), | 
| 1472 |  |  |  |  |  |  | "\n"); | 
| 1473 | 27 |  |  |  |  | 72 | $self->append ('    samp desc id:   ', NToSigned ($self->read (4)), | 
| 1474 |  |  |  |  |  |  | "\n"); | 
| 1475 |  |  |  |  |  |  | } | 
| 1476 |  |  |  |  |  |  | } | 
| 1477 |  |  |  |  |  |  |  | 
| 1478 |  |  |  |  |  |  | sub name_stsc { | 
| 1479 | 2 |  |  | 2 | 0 | 49 | my $self = shift; | 
| 1480 | 2 |  |  |  |  | 6 | return 'Sample number to chunk number mapping'; | 
| 1481 |  |  |  |  |  |  | } | 
| 1482 |  |  |  |  |  |  |  | 
| 1483 |  |  |  |  |  |  | sub dump_stsd { | 
| 1484 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 1485 | 2 |  |  |  |  | 5 | my ($pos, $len) = @_; | 
| 1486 |  |  |  |  |  |  |  | 
| 1487 | 2 |  |  |  |  | 7 | $self->append ('Version:  ', unpack ('C',   $self->read (1)), "\n"); | 
| 1488 | 2 |  |  |  |  | 7 | $self->append ('Flags:    ', unpack ('B24', $self->read (3)), "\n"); | 
| 1489 | 2 |  |  |  |  | 6 | my $entries = NToSigned ($self->read (4)); | 
| 1490 | 2 |  |  |  |  | 119 | my $digits = length $entries; | 
| 1491 |  |  |  |  |  |  |  | 
| 1492 | 2 |  |  |  |  | 9 | for (1 .. $entries) { | 
| 1493 | 2 |  |  |  |  | 14 | $self->append (sprintf ("  %*d\n", $digits, $_)); | 
| 1494 | 2 |  |  |  |  | 7 | NToSigned ($self->read (4)); | 
| 1495 | 2 |  |  |  |  | 11 | $self->append ('    format:  ', $self->get4Char (), "\n"); | 
| 1496 | 2 |  |  |  |  | 6 | $self->append ("    Reserved\n"); | 
| 1497 | 2 |  |  |  |  | 7 | NToSigned ($self->read (6)); | 
| 1498 | 2 |  |  |  |  | 47 | $self->append ('    index:   ', nToSigned ($self->read (2)), "\n"); | 
| 1499 |  |  |  |  |  |  | } | 
| 1500 |  |  |  |  |  |  | } | 
| 1501 |  |  |  |  |  |  |  | 
| 1502 |  |  |  |  |  |  | sub name_stsd { | 
| 1503 | 2 |  |  | 2 | 0 | 4 | my $self = shift; | 
| 1504 | 2 |  |  |  |  | 7 | return 'Sample description container'; | 
| 1505 |  |  |  |  |  |  | } | 
| 1506 |  |  |  |  |  |  |  | 
| 1507 |  |  |  |  |  |  | sub dump_stsh { | 
| 1508 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1509 |  |  |  |  |  |  |  | 
| 1510 | 0 |  |  |  |  | 0 | $self->append ('Version: ', unpack ('C',   $self->read (1)), "\n"); | 
| 1511 | 0 |  |  |  |  | 0 | $self->append ('Flags:   ', unpack ('B24', $self->read (3)), "\n"); | 
| 1512 | 0 |  |  |  |  | 0 | my $entries = NToSigned ($self->read (4)); | 
| 1513 | 0 |  |  |  |  | 0 | my $digits = length $entries; | 
| 1514 |  |  |  |  |  |  |  | 
| 1515 | 0 |  |  |  |  | 0 | for (1 .. $entries) { | 
| 1516 | 0 |  |  |  |  | 0 | $self->append (sprintf ("%*d ", $digits, $_)); | 
| 1517 | 0 |  |  |  |  | 0 | $self->append ('frame diff samp # ', NToSigned ($self->read (4))); | 
| 1518 | 0 |  |  |  |  | 0 | $self->append (' => sync samp # ', NToSigned ($self->read (4)), "\n"); | 
| 1519 |  |  |  |  |  |  | } | 
| 1520 |  |  |  |  |  |  | } | 
| 1521 |  |  |  |  |  |  |  | 
| 1522 |  |  |  |  |  |  | sub name_stsh { | 
| 1523 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1524 | 0 |  |  |  |  | 0 | return 'Shadow sync table'; | 
| 1525 |  |  |  |  |  |  | } | 
| 1526 |  |  |  |  |  |  |  | 
| 1527 |  |  |  |  |  |  | sub dump_stsz { | 
| 1528 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 1529 |  |  |  |  |  |  |  | 
| 1530 | 2 |  |  |  |  | 9 | $self->append ('Version: ', unpack ('C',   $self->read (1)), "\n"); | 
| 1531 | 2 |  |  |  |  | 8 | $self->append ('Flags:   ', unpack ('B24', $self->read (3)), "\n"); | 
| 1532 |  |  |  |  |  |  |  | 
| 1533 | 2 |  |  |  |  | 9 | my $sampleSize = NToSigned ($self->read (4)); | 
| 1534 | 2 |  |  |  |  | 7 | my $entries    = NToSigned ($self->read (4)); | 
| 1535 |  |  |  |  |  |  |  | 
| 1536 | 2 | 50 |  |  |  | 8 | if ($sampleSize) { | 
| 1537 | 0 |  |  |  |  | 0 | $self->append ("Sample size: $sampleSize\n"); | 
| 1538 | 0 |  |  |  |  | 0 | $self->append ("Samples:     $entries\n"); | 
| 1539 |  |  |  |  |  |  | } else { | 
| 1540 | 2 |  |  |  |  | 209 | my $digits = length $entries; | 
| 1541 |  |  |  |  |  |  |  | 
| 1542 | 2 |  |  |  |  | 10 | for (1 .. $entries) { | 
| 1543 | 183 |  |  |  |  | 1505 | $self->append (sprintf ("  %*d: ", $digits, $_)); | 
| 1544 | 183 |  |  |  |  | 752 | $sampleSize = NToSigned ($self->read (4)); | 
| 1545 | 183 |  |  |  |  | 1806 | $self->append ("sample size $sampleSize\n"); | 
| 1546 | 183 |  |  |  |  | 679 | $self->{parsedSize} += $sampleSize; | 
| 1547 |  |  |  |  |  |  | } | 
| 1548 |  |  |  |  |  |  | } | 
| 1549 |  |  |  |  |  |  | } | 
| 1550 |  |  |  |  |  |  |  | 
| 1551 |  |  |  |  |  |  | sub name_stsz { | 
| 1552 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 1553 | 2 |  |  |  |  | 8 | return 'Sample size table'; | 
| 1554 |  |  |  |  |  |  | } | 
| 1555 |  |  |  |  |  |  |  | 
| 1556 |  |  |  |  |  |  | sub dump_stss { | 
| 1557 | 1 |  |  | 1 | 0 | 2 | my $self = shift; | 
| 1558 |  |  |  |  |  |  |  | 
| 1559 | 1 |  |  |  |  | 5 | $self->dump_stts (@_); | 
| 1560 |  |  |  |  |  |  | } | 
| 1561 |  |  |  |  |  |  |  | 
| 1562 |  |  |  |  |  |  | sub name_stss { | 
| 1563 | 1 |  |  | 1 | 0 | 2 | my $self = shift; | 
| 1564 | 1 |  |  |  |  | 37 | return 'Key frame sample numbers table'; | 
| 1565 |  |  |  |  |  |  | } | 
| 1566 |  |  |  |  |  |  |  | 
| 1567 |  |  |  |  |  |  | sub dump_stts { | 
| 1568 | 3 |  |  | 3 | 0 | 8 | my $self = shift; | 
| 1569 | 3 |  |  |  |  | 6 | my ($pos, $len) = @_; | 
| 1570 |  |  |  |  |  |  |  | 
| 1571 | 3 |  |  |  |  | 18 | $self->append ('Version:  ', unpack ('C',   $self->read (1)), "\n"); | 
| 1572 | 3 |  |  |  |  | 11 | $self->append ('Flags:    ', unpack ('B24', $self->read (3)), "\n"); | 
| 1573 | 3 |  |  |  |  | 12 | my $entries = NToSigned ($self->read (4)); | 
| 1574 | 3 |  |  |  |  | 10 | my $digits  = length $entries; | 
| 1575 | 3 |  |  |  |  | 13 | my $scale   = $self->findAtomValue ('timescale'); | 
| 1576 |  |  |  |  |  |  |  | 
| 1577 | 3 |  |  |  |  | 12 | for (1 .. $entries) { | 
| 1578 | 5 |  |  |  |  | 28 | $self->append (sprintf ("  %*d\n", $digits, $_)); | 
| 1579 | 5 |  |  |  |  | 17 | $self->append ('    Sample count: ', NToSigned ($self->read (4)), "\n"); | 
| 1580 |  |  |  |  |  |  |  | 
| 1581 | 5 |  |  |  |  | 15 | my $duration = NToSigned ($self->read (4)); | 
| 1582 | 5 | 50 |  |  |  | 19 | my $durSecs = $scale ? $duration / $scale : '---'; | 
| 1583 | 5 |  |  |  |  | 266 | $self->append ( | 
| 1584 |  |  |  |  |  |  | "    Duration:   $duration ticks (${durSecs} seconds)\n"); | 
| 1585 |  |  |  |  |  |  | } | 
| 1586 |  |  |  |  |  |  | } | 
| 1587 |  |  |  |  |  |  |  | 
| 1588 |  |  |  |  |  |  | sub name_stts { | 
| 1589 | 2 |  |  | 2 | 0 | 4 | my $self = shift; | 
| 1590 | 2 |  |  |  |  | 7 | return 'Sample number to duration maps'; | 
| 1591 |  |  |  |  |  |  | } | 
| 1592 |  |  |  |  |  |  |  | 
| 1593 |  |  |  |  |  |  | sub dump_targ { | 
| 1594 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1595 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1596 |  |  |  |  |  |  |  | 
| 1597 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 1598 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 1599 |  |  |  |  |  |  | } | 
| 1600 |  |  |  |  |  |  |  | 
| 1601 |  |  |  |  |  |  | sub dump_test { | 
| 1602 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1603 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1604 |  |  |  |  |  |  |  | 
| 1605 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 1606 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 1607 |  |  |  |  |  |  | } | 
| 1608 |  |  |  |  |  |  |  | 
| 1609 |  |  |  |  |  |  | sub dump_tkhd { | 
| 1610 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 1611 |  |  |  |  |  |  |  | 
| 1612 | 2 |  |  |  |  | 9 | $self->append ('Version:  ', unpack ('C',   $self->read (1)), "\n"); | 
| 1613 | 2 |  |  |  |  | 12 | $self->append ('Flags:    ', unpack ('B24', $self->read (3)), "\n"); | 
| 1614 | 2 |  |  |  |  | 8 | $self->append ('Creation time:     ', $self->showDate (), "\n"); | 
| 1615 | 2 |  |  |  |  | 8 | $self->append ('Modification time: ', $self->showDate (), "\n"); | 
| 1616 | 2 |  |  |  |  | 7 | $self->append ('Track ID:          ', unpack ("N", $self->read (4)), "\n"); | 
| 1617 | 2 |  |  |  |  | 7 | $self->append ("Reserved\n"); | 
| 1618 | 2 |  |  |  |  | 6 | $self->read   (4); | 
| 1619 | 2 |  |  |  |  | 9 | my $scale = $self->findAtomValue ('timescale'); | 
| 1620 | 2 |  |  |  |  | 8 | my $duration = NToSigned ($self->read (4)); | 
| 1621 | 2 | 50 |  |  |  | 76 | my $durSecs = $scale ? $duration / $scale : '---'; | 
| 1622 | 2 |  |  |  |  | 67 | $self->append ("Duration:          $duration ticks (${durSecs} seconds)\n"); | 
| 1623 | 2 |  |  |  |  | 6 | $self->append ("Reserved\n"); | 
| 1624 | 2 |  |  |  |  | 7 | $self->read   (8); | 
| 1625 | 2 |  |  |  |  | 5 | $self->append ('Layer:             ', nToSigned ($self->read (2)), "\n"); | 
| 1626 | 2 |  |  |  |  | 8 | $self->append ('Alternate group:   ', nToSigned ($self->read (2)), "\n"); | 
| 1627 | 2 |  |  |  |  | 8 | $self->append ('Volume:            ', nToUnsigned ($self->read (2)), "\n"); | 
| 1628 | 2 |  |  |  |  | 9 | $self->append ("Reserved\n"); | 
| 1629 | 2 |  |  |  |  | 6 | $self->read   (2); | 
| 1630 | 2 |  |  |  |  | 9 | $self->append ('Matrix structure:  ', $self->showMatrix (), "\n"); | 
| 1631 | 2 |  |  |  |  | 6 | $self->append ('Track width:       ', NToFixed ($self->read (4)), "\n"); | 
| 1632 | 2 |  |  |  |  | 9 | $self->append ('Track height:      ', NToFixed ($self->read (4)), "\n"); | 
| 1633 |  |  |  |  |  |  | } | 
| 1634 |  |  |  |  |  |  |  | 
| 1635 |  |  |  |  |  |  | sub name_tkhd { | 
| 1636 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 1637 | 2 |  |  |  |  | 5 | return 'Media track header'; | 
| 1638 |  |  |  |  |  |  | } | 
| 1639 |  |  |  |  |  |  |  | 
| 1640 |  |  |  |  |  |  | sub dump_trak { | 
| 1641 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 1642 |  |  |  |  |  |  |  | 
| 1643 | 2 |  |  |  |  | 8 | $self->unwrapAtoms (@_); | 
| 1644 |  |  |  |  |  |  | } | 
| 1645 |  |  |  |  |  |  |  | 
| 1646 |  |  |  |  |  |  | sub name_trak { | 
| 1647 | 2 |  |  | 2 | 0 | 5 | my $self = shift; | 
| 1648 | 2 |  |  |  |  | 6 | return 'Media track container'; | 
| 1649 |  |  |  |  |  |  | } | 
| 1650 |  |  |  |  |  |  |  | 
| 1651 |  |  |  |  |  |  | sub dump_trin { | 
| 1652 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1653 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1654 |  |  |  |  |  |  |  | 
| 1655 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 1656 | 0 |  |  |  |  | 0 | $self->append ('Track index: ', NToSigned ($self->read (4)), "\n"); | 
| 1657 |  |  |  |  |  |  | } | 
| 1658 |  |  |  |  |  |  |  | 
| 1659 |  |  |  |  |  |  | sub name_trin { | 
| 1660 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1661 | 0 |  |  |  |  | 0 | return 'Track index'; | 
| 1662 |  |  |  |  |  |  | } | 
| 1663 |  |  |  |  |  |  |  | 
| 1664 |  |  |  |  |  |  | sub dump_udta { | 
| 1665 | 3 |  |  | 3 | 0 | 5 | my $self = shift; | 
| 1666 |  |  |  |  |  |  |  | 
| 1667 | 3 |  |  |  |  | 10 | $self->unwrapAtoms (@_); | 
| 1668 |  |  |  |  |  |  | } | 
| 1669 |  |  |  |  |  |  |  | 
| 1670 |  |  |  |  |  |  | sub name_udta { | 
| 1671 | 3 |  |  | 3 | 0 | 6 | my $self = shift; | 
| 1672 | 3 |  |  |  |  | 8 | return 'User data'; | 
| 1673 |  |  |  |  |  |  | } | 
| 1674 |  |  |  |  |  |  |  | 
| 1675 |  |  |  |  |  |  | sub dump_vmhd { | 
| 1676 | 1 |  |  | 1 | 0 | 2 | my $self   = shift; | 
| 1677 | 1 |  |  |  |  | 4 | my $parent = $self->{atomStack}[-2][0]; | 
| 1678 |  |  |  |  |  |  |  | 
| 1679 | 1 | 50 |  |  |  | 6 | if ($parent eq 'minf') { | 
| 1680 | 1 |  |  |  |  | 4 | $self->append ('Version:  ', unpack ('C',   $self->read (1)), "\n"); | 
| 1681 | 1 |  |  |  |  | 445 | $self->append ('Flags:    ', unpack ('B24', $self->read (3)), "\n"); | 
| 1682 |  |  |  |  |  |  |  | 
| 1683 | 1 |  |  |  |  | 7 | $self->showGraphicsXferMode (); | 
| 1684 | 1 |  |  |  |  | 6 | $self->showRGB              (); | 
| 1685 |  |  |  |  |  |  | } else { | 
| 1686 | 0 |  |  |  |  | 0 | $self->append ("Unhandled context ($parent) for VideoMediaInfo atom\n"); | 
| 1687 |  |  |  |  |  |  | } | 
| 1688 |  |  |  |  |  |  | } | 
| 1689 |  |  |  |  |  |  |  | 
| 1690 |  |  |  |  |  |  | sub name_vmhd { | 
| 1691 | 1 |  |  | 1 | 0 | 6 | my $self = shift; | 
| 1692 | 1 |  |  |  |  | 5 | return 'Video media header'; | 
| 1693 |  |  |  |  |  |  | } | 
| 1694 |  |  |  |  |  |  |  | 
| 1695 |  |  |  |  |  |  | sub dump_whic { | 
| 1696 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1697 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1698 | 0 |  |  |  |  | 0 | my $dataRef = \%{$self->getParentAttribs ()}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1699 | 0 |  |  |  |  | 0 | my %actions = ( | 
| 1700 |  |  |  |  |  |  | 1024  => 'kActionMovieSetVolume', | 
| 1701 |  |  |  |  |  |  | 1025  => 'kActionMovieSetRate', | 
| 1702 |  |  |  |  |  |  | 1026  => 'kActionMovieSetLoopingFlags', | 
| 1703 |  |  |  |  |  |  | 1027  => 'kActionMovieGoToTime', | 
| 1704 |  |  |  |  |  |  | 1028  => 'kActionMovieGoToTimeByName', | 
| 1705 |  |  |  |  |  |  | 1029  => 'kActionMovieGoToBeginning', | 
| 1706 |  |  |  |  |  |  | 1030  => 'kActionMovieGoToEnd', | 
| 1707 |  |  |  |  |  |  | 1031  => 'kActionMovieStepForward', | 
| 1708 |  |  |  |  |  |  | 1032  => 'kActionMovieStepBackward', | 
| 1709 |  |  |  |  |  |  | 1033  => 'kActionMovieSetSelection', | 
| 1710 |  |  |  |  |  |  | 1034  => 'kActionMovieSetSelectionByName', | 
| 1711 |  |  |  |  |  |  | 1035  => 'kActionMoviePlaySelection', | 
| 1712 |  |  |  |  |  |  | 1036  => 'kActionMovieSetLanguage', | 
| 1713 |  |  |  |  |  |  | 1037  => 'kActionMovieChanged', | 
| 1714 |  |  |  |  |  |  | 1038  => 'kActionMovieRestartAtTime', | 
| 1715 |  |  |  |  |  |  | 2048  => 'kActionTrackSetVolume', | 
| 1716 |  |  |  |  |  |  | 2049  => 'kActionTrackSetBalance', | 
| 1717 |  |  |  |  |  |  | 2050  => 'kActionTrackSetEnabled', | 
| 1718 |  |  |  |  |  |  | 2051  => 'kActionTrackSetMatrix', | 
| 1719 |  |  |  |  |  |  | 2052  => 'kActionTrackSetLayer', | 
| 1720 |  |  |  |  |  |  | 2053  => 'kActionTrackSetClip', | 
| 1721 |  |  |  |  |  |  | 2054  => 'kActionTrackSetCursor', | 
| 1722 |  |  |  |  |  |  | 2055  => 'kActionTrackSetGraphicsMode', | 
| 1723 |  |  |  |  |  |  | 3072  => 'kActionSpriteSetMatrix', | 
| 1724 |  |  |  |  |  |  | 3073  => 'kActionSpriteSetImageIndex', | 
| 1725 |  |  |  |  |  |  | 3074  => 'kActionSpriteSetVisible', | 
| 1726 |  |  |  |  |  |  | 3075  => 'kActionSpriteSetLayer', | 
| 1727 |  |  |  |  |  |  | 3076  => 'kActionSpriteSetGraphicsMode', | 
| 1728 |  |  |  |  |  |  | 3078  => 'kActionSpritePassMouseToCodec', | 
| 1729 |  |  |  |  |  |  | 3079  => 'kActionSpriteClickOnCodec', | 
| 1730 |  |  |  |  |  |  | 3080  => 'kActionSpriteTranslate', | 
| 1731 |  |  |  |  |  |  | 3081  => 'kActionSpriteScale', | 
| 1732 |  |  |  |  |  |  | 3082  => 'kActionSpriteRotate', | 
| 1733 |  |  |  |  |  |  | 3083  => 'kActionSpriteStretch', | 
| 1734 |  |  |  |  |  |  | 4096  => 'kActionQTVRSetPanAngle', | 
| 1735 |  |  |  |  |  |  | 4097  => 'kActionQTVRSetTiltAngle', | 
| 1736 |  |  |  |  |  |  | 4098  => 'kActionQTVRSetFieldOfView', | 
| 1737 |  |  |  |  |  |  | 4099  => 'kActionQTVRShowDefaultView', | 
| 1738 |  |  |  |  |  |  | 4100  => 'kActionQTVRGoToNodeID', | 
| 1739 |  |  |  |  |  |  | 5120  => 'kActionMusicPlayNote', | 
| 1740 |  |  |  |  |  |  | 5121  => 'kActionMusicSetController', | 
| 1741 |  |  |  |  |  |  | 6144  => 'kActionCase', | 
| 1742 |  |  |  |  |  |  | 6145  => 'kActionWhile', | 
| 1743 |  |  |  |  |  |  | 6146  => 'kActionGoToURL', | 
| 1744 |  |  |  |  |  |  | 6147  => 'kActionSendQTEventToSprite', | 
| 1745 |  |  |  |  |  |  | 6148  => 'kActionDebugStr', | 
| 1746 |  |  |  |  |  |  | 6149  => 'kActionPushCurrentTime', | 
| 1747 |  |  |  |  |  |  | 6150  => 'kActionPushCurrentTimeWithLabel', | 
| 1748 |  |  |  |  |  |  | 6151  => 'kActionPopAndGotoTopTime', | 
| 1749 |  |  |  |  |  |  | 6152  => 'kActionPopAndGotoLabeledTime', | 
| 1750 |  |  |  |  |  |  | 6153  => 'kActionStatusString', | 
| 1751 |  |  |  |  |  |  | 6154  => 'kActionSendQTEventToTrackObject', | 
| 1752 |  |  |  |  |  |  | 6155  => 'kActionAddChannelSubscription', | 
| 1753 |  |  |  |  |  |  | 6156  => 'kActionRemoveChannelSubscription', | 
| 1754 |  |  |  |  |  |  | 6157  => 'kActionOpenCustomActionHandler', | 
| 1755 |  |  |  |  |  |  | 6158  => 'kActionDoScript', | 
| 1756 |  |  |  |  |  |  | 7168  => 'kActionSpriteTrackSetVariable', | 
| 1757 |  |  |  |  |  |  | 7169  => 'kActionSpriteTrackNewSprite', | 
| 1758 |  |  |  |  |  |  | 7170  => 'kActionSpriteTrackDisposeSprite', | 
| 1759 |  |  |  |  |  |  | 7171  => 'kActionSpriteTrackSetVariableToString', | 
| 1760 |  |  |  |  |  |  | 7172  => 'kActionSpriteTrackConcatVariables', | 
| 1761 |  |  |  |  |  |  | 7173  => 'kActionSpriteTrackSetVariableToMovieURL', | 
| 1762 |  |  |  |  |  |  | 7174  => 'kActionSpriteTrackSetVariableToMovieBaseURL', | 
| 1763 |  |  |  |  |  |  | 8192  => 'kActionApplicationNumberAndString', | 
| 1764 |  |  |  |  |  |  | 9216  => 'kActionQD3DNamedObjectTranslateTo', | 
| 1765 |  |  |  |  |  |  | 9217  => 'kActionQD3DNamedObjectScaleTo', | 
| 1766 |  |  |  |  |  |  | 9218  => 'kActionQD3DNamedObjectRotateTo', | 
| 1767 |  |  |  |  |  |  | 10240 => 'kActionFlashTrackSetPan', | 
| 1768 |  |  |  |  |  |  | 10241 => 'kActionFlashTrackSetZoom', | 
| 1769 |  |  |  |  |  |  | 10242 => 'kActionFlashTrackSetZoomRect', | 
| 1770 |  |  |  |  |  |  | 10243 => 'kActionFlashTrackGotoFrameNumber', | 
| 1771 |  |  |  |  |  |  | 10244 => 'kActionFlashTrackGotoFrameLabel', | 
| 1772 |  |  |  |  |  |  | 11264 => 'kActionMovieTrackAddChildMovie', | 
| 1773 |  |  |  |  |  |  | 11265 => 'kActionMovieTrackLoadChildMovie', | 
| 1774 |  |  |  |  |  |  | ); | 
| 1775 |  |  |  |  |  |  |  | 
| 1776 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 1777 |  |  |  |  |  |  |  | 
| 1778 | 0 |  |  |  |  | 0 | my $action = NToSigned ($self->read (4)); | 
| 1779 | 0 |  |  |  |  | 0 | my $actionStr = $actions{$action}; | 
| 1780 | 0 | 0 |  |  |  | 0 | $actionStr = "Unknown - $action" if !defined $actionStr; | 
| 1781 | 0 |  |  |  |  | 0 | $self->append ("Type: $actionStr\n"); | 
| 1782 | 0 |  |  |  |  | 0 | $dataRef->{'ActionType'} = $actionStr; | 
| 1783 |  |  |  |  |  |  | } | 
| 1784 |  |  |  |  |  |  |  | 
| 1785 |  |  |  |  |  |  | sub name_whic { | 
| 1786 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1787 | 0 |  |  |  |  | 0 | return 'Which action type'; | 
| 1788 |  |  |  |  |  |  | } | 
| 1789 |  |  |  |  |  |  |  | 
| 1790 | 1 |  |  | 1 | 0 | 2 | sub dump_wide { | 
| 1791 |  |  |  |  |  |  | } | 
| 1792 |  |  |  |  |  |  |  | 
| 1793 |  |  |  |  |  |  | sub name_wide { | 
| 1794 | 1 |  |  | 1 | 0 | 2 | my $self = shift; | 
| 1795 | 1 |  |  |  |  | 2 | return '64 bit expansion place holder'; | 
| 1796 |  |  |  |  |  |  | } | 
| 1797 |  |  |  |  |  |  |  | 
| 1798 |  |  |  |  |  |  | sub dump_WLOC { | 
| 1799 | 1 |  |  | 1 | 0 | 2 | my $self = shift; | 
| 1800 | 1 |  |  |  |  | 64 | my ($pos, $len) = @_; | 
| 1801 |  |  |  |  |  |  |  | 
| 1802 | 1 |  |  |  |  | 9 | $len = 2 * $len - 16; | 
| 1803 | 1 |  |  |  |  | 6 | $self->append (unpack ("H$len\n", $self->read ($len)), "\n"); | 
| 1804 |  |  |  |  |  |  | } | 
| 1805 |  |  |  |  |  |  |  | 
| 1806 |  |  |  |  |  |  | sub name_WLOC { | 
| 1807 | 1 |  |  | 1 | 0 | 3 | my $self = shift; | 
| 1808 | 1 |  |  |  |  | 3 | return 'Default window location'; | 
| 1809 |  |  |  |  |  |  | } | 
| 1810 |  |  |  |  |  |  |  | 
| 1811 |  |  |  |  |  |  | sub dump_x00000001 { | 
| 1812 | 0 |  |  | 0 | 0 | 0 | my $self       = shift; | 
| 1813 | 0 |  |  |  |  | 0 | my $parentType = $self->{atomStack}[-2][0]; | 
| 1814 |  |  |  |  |  |  |  | 
| 1815 | 0 | 0 |  |  |  | 0 | if ($parentType eq 'oprn') { | 
| 1816 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 1817 |  |  |  |  |  |  |  | 
| 1818 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 1819 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 1820 |  |  |  |  |  |  | } else { | 
| 1821 |  |  |  |  |  |  |  | 
| 1822 | 0 |  |  |  |  | 0 | $self->showBogus (); | 
| 1823 | 0 |  |  |  |  | 0 | $self->append ('Matrix structure:  ', $self->showMatrix (), "\n"); | 
| 1824 |  |  |  |  |  |  | } | 
| 1825 |  |  |  |  |  |  | } | 
| 1826 |  |  |  |  |  |  |  | 
| 1827 |  |  |  |  |  |  | sub name_x00000001 { | 
| 1828 | 0 |  |  | 0 | 0 | 0 | my $self       = shift; | 
| 1829 | 0 |  |  |  |  | 0 | my $parentType = $self->{atomStack}[-2][0]; | 
| 1830 |  |  |  |  |  |  |  | 
| 1831 | 0 | 0 |  |  |  | 0 | if ($parentType eq 'oprn') { | 
| 1832 | 0 |  |  |  |  | 0 | return ''; | 
| 1833 |  |  |  |  |  |  | } else { | 
| 1834 | 0 |  |  |  |  | 0 | return 'kSpritePropertyMatrix'; | 
| 1835 |  |  |  |  |  |  | } | 
| 1836 |  |  |  |  |  |  | } | 
| 1837 |  |  |  |  |  |  |  | 
| 1838 |  |  |  |  |  |  | sub dump_x00000002 { | 
| 1839 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1840 |  |  |  |  |  |  |  | 
| 1841 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 1842 | 0 |  |  |  |  | 0 | $self->append ('Value:     ', groupDigits (nToSigned ($self->read (2))), | 
| 1843 |  |  |  |  |  |  | "\n"); | 
| 1844 |  |  |  |  |  |  | } | 
| 1845 |  |  |  |  |  |  |  | 
| 1846 |  |  |  |  |  |  | sub name_x00000002 { | 
| 1847 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1848 | 0 |  |  |  |  | 0 | return 'Constant'; | 
| 1849 |  |  |  |  |  |  | } | 
| 1850 |  |  |  |  |  |  |  | 
| 1851 |  |  |  |  |  |  | sub dump_x00000004 { | 
| 1852 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1853 |  |  |  |  |  |  |  | 
| 1854 | 0 |  |  |  |  | 0 | $self->showBogus (); | 
| 1855 | 0 |  |  |  |  | 0 | $self->append ('Visible:  ', nToSigned ($self->read (2)), "\n"); | 
| 1856 |  |  |  |  |  |  | } | 
| 1857 |  |  |  |  |  |  |  | 
| 1858 |  |  |  |  |  |  | sub name_x00000004 { | 
| 1859 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1860 | 0 |  |  |  |  | 0 | return 'kSpritePropertyVisible'; | 
| 1861 |  |  |  |  |  |  | } | 
| 1862 |  |  |  |  |  |  |  | 
| 1863 |  |  |  |  |  |  | sub dump_x00000005 { | 
| 1864 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1865 |  |  |  |  |  |  |  | 
| 1866 | 0 |  |  |  |  | 0 | $self->showBogus (); | 
| 1867 | 0 |  |  |  |  | 0 | $self->append ('Layer:  ', nToSigned ($self->read (2)), "\n"); | 
| 1868 |  |  |  |  |  |  | } | 
| 1869 |  |  |  |  |  |  |  | 
| 1870 |  |  |  |  |  |  | sub name_x00000005 { | 
| 1871 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1872 | 0 |  |  |  |  | 0 | return 'kSpritePropertyLayer'; | 
| 1873 |  |  |  |  |  |  | } | 
| 1874 |  |  |  |  |  |  |  | 
| 1875 |  |  |  |  |  |  | sub dump_x00000006 { | 
| 1876 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1877 |  |  |  |  |  |  |  | 
| 1878 | 0 |  |  |  |  | 0 | $self->showPlayMode (); | 
| 1879 | 0 |  |  |  |  | 0 | $self->showBogus    (); | 
| 1880 | 0 |  |  |  |  | 0 | $self->showRGB      (); | 
| 1881 |  |  |  |  |  |  | } | 
| 1882 |  |  |  |  |  |  |  | 
| 1883 |  |  |  |  |  |  | sub name_x00000006 { | 
| 1884 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1885 | 0 |  |  |  |  | 0 | return 'kSpritePropertyGraphicsMode'; | 
| 1886 |  |  |  |  |  |  | } | 
| 1887 |  |  |  |  |  |  |  | 
| 1888 | 0 |  |  | 0 | 0 | 0 | sub dump_x00000015 { | 
| 1889 |  |  |  |  |  |  | } | 
| 1890 |  |  |  |  |  |  |  | 
| 1891 |  |  |  |  |  |  | sub name_x00000015 { | 
| 1892 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1893 | 0 |  |  |  |  | 0 | return 'Quicktime version'; | 
| 1894 |  |  |  |  |  |  | } | 
| 1895 |  |  |  |  |  |  |  | 
| 1896 |  |  |  |  |  |  | sub dump_x00000064 { | 
| 1897 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1898 | 0 |  |  |  |  | 0 | $self->showBogus (); | 
| 1899 | 0 |  |  |  |  | 0 | $self->append ('Image index: ', nToSigned ($self->read (2)), "\n"); | 
| 1900 |  |  |  |  |  |  | } | 
| 1901 |  |  |  |  |  |  |  | 
| 1902 |  |  |  |  |  |  | sub name_x00000064 { | 
| 1903 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1904 | 0 |  |  |  |  | 0 | return 'kSpritePropertyImageIndex'; | 
| 1905 |  |  |  |  |  |  | } | 
| 1906 |  |  |  |  |  |  |  | 
| 1907 |  |  |  |  |  |  | sub dump_x00000065 { | 
| 1908 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1909 |  |  |  |  |  |  |  | 
| 1910 | 0 |  |  |  |  | 0 | $self->append    ("Background colour:\n"); | 
| 1911 | 0 |  |  |  |  | 0 | $self->showBogus (); | 
| 1912 | 0 |  |  |  |  | 0 | $self->showRGB   (); | 
| 1913 |  |  |  |  |  |  | } | 
| 1914 |  |  |  |  |  |  |  | 
| 1915 |  |  |  |  |  |  | sub name_x00000065 { | 
| 1916 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1917 | 0 |  |  |  |  | 0 | return 'kSpriteTrackPropertyBackgroundColor'; | 
| 1918 |  |  |  |  |  |  | } | 
| 1919 |  |  |  |  |  |  |  | 
| 1920 |  |  |  |  |  |  | sub dump_x00000066 { | 
| 1921 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1922 | 0 |  |  |  |  | 0 | $self->showBogus (); | 
| 1923 | 0 |  |  |  |  | 0 | $self->append ('Offscreen bit depth: ', nToSigned ($self->read (2)), "\n"); | 
| 1924 |  |  |  |  |  |  | } | 
| 1925 |  |  |  |  |  |  |  | 
| 1926 |  |  |  |  |  |  | sub name_x00000066 { | 
| 1927 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1928 | 0 |  |  |  |  | 0 | return 'kSpriteTrackPropertyOffscreenBitDepth'; | 
| 1929 |  |  |  |  |  |  | } | 
| 1930 |  |  |  |  |  |  |  | 
| 1931 |  |  |  |  |  |  | sub dump_x00000067 { | 
| 1932 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1933 | 0 |  |  |  |  | 0 | $self->showBogus (); | 
| 1934 | 0 |  |  |  |  | 0 | $self->append ('Sample format: ', nToSigned ($self->read (2)), "\n"); | 
| 1935 |  |  |  |  |  |  | } | 
| 1936 |  |  |  |  |  |  |  | 
| 1937 |  |  |  |  |  |  | sub name_x00000067 { | 
| 1938 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1939 | 0 |  |  |  |  | 0 | return 'kSpriteTrackPropertySampleFormat'; | 
| 1940 |  |  |  |  |  |  | } | 
| 1941 |  |  |  |  |  |  |  | 
| 1942 |  |  |  |  |  |  | sub dump_x00000069 { | 
| 1943 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1944 | 0 |  |  |  |  | 0 | $self->showBogus (); | 
| 1945 | 0 |  |  |  |  | 0 | $self->append ('Has Actions: ', cToBool ($self->read (1)), "\n"); | 
| 1946 |  |  |  |  |  |  | } | 
| 1947 |  |  |  |  |  |  |  | 
| 1948 |  |  |  |  |  |  | sub name_x00000069 { | 
| 1949 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1950 | 0 |  |  |  |  | 0 | return 'kSpriteTrackPropertySampleFormat'; | 
| 1951 |  |  |  |  |  |  | } | 
| 1952 |  |  |  |  |  |  |  | 
| 1953 |  |  |  |  |  |  | sub dump_x0000006a { | 
| 1954 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1955 | 0 |  |  |  |  | 0 | $self->showBogus (); | 
| 1956 | 0 |  |  |  |  | 0 | $self->append ('Visible: ', cToBool ($self->read (1)), "\n"); | 
| 1957 |  |  |  |  |  |  | } | 
| 1958 |  |  |  |  |  |  |  | 
| 1959 |  |  |  |  |  |  | sub name_x0000006a { | 
| 1960 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1961 | 0 |  |  |  |  | 0 | return 'kSpriteTrackPropertyScaleSpritesToScaleWorld'; | 
| 1962 |  |  |  |  |  |  | } | 
| 1963 |  |  |  |  |  |  |  | 
| 1964 |  |  |  |  |  |  | sub dump_x0000006b { | 
| 1965 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1966 | 0 |  |  |  |  | 0 | $self->showBogus (); | 
| 1967 |  |  |  |  |  |  |  | 
| 1968 | 0 |  |  |  |  | 0 | my $interval = NToUnsigned ($self->read (4)); | 
| 1969 | 0 | 0 |  |  |  | 0 | my $freq = $interval ? (60.0 / $interval) . ' Hz' : 'fastest'; | 
| 1970 |  |  |  |  |  |  |  | 
| 1971 | 0 | 0 |  |  |  | 0 | $freq = 'off' if $interval == 0xffffffff; | 
| 1972 | 0 |  |  |  |  | 0 | $self->append ("Idle Events: $freq\n"); | 
| 1973 |  |  |  |  |  |  | } | 
| 1974 |  |  |  |  |  |  |  | 
| 1975 |  |  |  |  |  |  | sub name_x0000006b { | 
| 1976 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1977 | 0 |  |  |  |  | 0 | return 'kSpriteTrackPropertyHasActions'; | 
| 1978 |  |  |  |  |  |  | } | 
| 1979 |  |  |  |  |  |  |  | 
| 1980 | 0 |  |  | 0 | 0 | 0 | sub dump_x00000c00 { | 
| 1981 |  |  |  |  |  |  | } | 
| 1982 |  |  |  |  |  |  |  | 
| 1983 |  |  |  |  |  |  | sub name_x00000c00 { | 
| 1984 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1985 | 0 |  |  |  |  | 0 | return 'kOperandSpriteBoundsLeft'; | 
| 1986 |  |  |  |  |  |  | } | 
| 1987 |  |  |  |  |  |  |  | 
| 1988 | 0 |  |  | 0 | 0 | 0 | sub dump_x00000c01 { | 
| 1989 |  |  |  |  |  |  | } | 
| 1990 |  |  |  |  |  |  |  | 
| 1991 |  |  |  |  |  |  | sub name_x00000c01 { | 
| 1992 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 1993 | 0 |  |  |  |  | 0 | return 'kOperandSpriteBoundsTop'; | 
| 1994 |  |  |  |  |  |  | } | 
| 1995 |  |  |  |  |  |  |  | 
| 1996 | 0 |  |  | 0 | 0 | 0 | sub dump_x00000c02 { | 
| 1997 |  |  |  |  |  |  | } | 
| 1998 |  |  |  |  |  |  |  | 
| 1999 |  |  |  |  |  |  | sub name_x00000c02 { | 
| 2000 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 2001 | 0 |  |  |  |  | 0 | return 'kOperandSpriteBoundsRight'; | 
| 2002 |  |  |  |  |  |  | } | 
| 2003 |  |  |  |  |  |  |  | 
| 2004 | 0 |  |  | 0 | 0 | 0 | sub dump_x00000c03 { | 
| 2005 |  |  |  |  |  |  | } | 
| 2006 |  |  |  |  |  |  |  | 
| 2007 |  |  |  |  |  |  | sub name_x00000c03 { | 
| 2008 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 2009 | 0 |  |  |  |  | 0 | return 'kOperandSpriteBoundsBottom'; | 
| 2010 |  |  |  |  |  |  | } | 
| 2011 |  |  |  |  |  |  |  | 
| 2012 | 0 |  |  | 0 | 0 | 0 | sub dump_x00000c04 { | 
| 2013 |  |  |  |  |  |  | } | 
| 2014 |  |  |  |  |  |  |  | 
| 2015 |  |  |  |  |  |  | sub name_x00000c04 { | 
| 2016 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 2017 | 0 |  |  |  |  | 0 | return 'kOperandSpriteImageIndex'; | 
| 2018 |  |  |  |  |  |  | } | 
| 2019 |  |  |  |  |  |  |  | 
| 2020 | 0 |  |  | 0 | 0 | 0 | sub dump_x00000c05 { | 
| 2021 |  |  |  |  |  |  | } | 
| 2022 |  |  |  |  |  |  |  | 
| 2023 |  |  |  |  |  |  | sub name_x00000c05 { | 
| 2024 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 2025 | 0 |  |  |  |  | 0 | return 'kOperandSpriteVisible'; | 
| 2026 |  |  |  |  |  |  | } | 
| 2027 |  |  |  |  |  |  |  | 
| 2028 | 0 |  |  | 0 | 0 | 0 | sub dump_x00000c06 { | 
| 2029 |  |  |  |  |  |  | } | 
| 2030 |  |  |  |  |  |  |  | 
| 2031 |  |  |  |  |  |  | sub name_x00000c06 { | 
| 2032 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 2033 | 0 |  |  |  |  | 0 | return 'kOperandSpriteLayer'; | 
| 2034 |  |  |  |  |  |  | } | 
| 2035 |  |  |  |  |  |  |  | 
| 2036 |  |  |  |  |  |  | sub dump_x00000c07 { | 
| 2037 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 2038 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 2039 |  |  |  |  |  |  |  | 
| 2040 | 0 |  |  |  |  | 0 | $self->setParentAttribs (ActionType => 'kOperandSpriteTrackVariable'); | 
| 2041 | 0 |  |  |  |  | 0 | $self->showUnknown (); | 
| 2042 | 0 |  |  |  |  | 0 | $self->unwrapAtoms ($pos + 12, $len - 12); | 
| 2043 |  |  |  |  |  |  | } | 
| 2044 |  |  |  |  |  |  |  | 
| 2045 |  |  |  |  |  |  | sub name_x00000c07 { | 
| 2046 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 2047 | 0 |  |  |  |  | 0 | return 'kOperandSpriteTrackVariable'; | 
| 2048 |  |  |  |  |  |  | } | 
| 2049 |  |  |  |  |  |  |  | 
| 2050 | 0 |  |  | 0 | 0 | 0 | sub dump_x00001400 { | 
| 2051 |  |  |  |  |  |  | } | 
| 2052 |  |  |  |  |  |  |  | 
| 2053 |  |  |  |  |  |  | sub name_x00001400 { | 
| 2054 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 2055 | 0 |  |  |  |  | 0 | return 'kOperandMouseLocalHLoc'; | 
| 2056 |  |  |  |  |  |  | } | 
| 2057 |  |  |  |  |  |  |  | 
| 2058 | 0 |  |  | 0 | 0 | 0 | sub dump_x00001401 { | 
| 2059 |  |  |  |  |  |  | } | 
| 2060 |  |  |  |  |  |  |  | 
| 2061 |  |  |  |  |  |  | sub name_x00001401 { | 
| 2062 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 2063 | 0 |  |  |  |  | 0 | return 'kOperandMouseLocalVLoc'; | 
| 2064 |  |  |  |  |  |  | } | 
| 2065 |  |  |  |  |  |  |  | 
| 2066 | 0 |  |  | 0 | 0 | 0 | sub dump_x00001402 { | 
| 2067 |  |  |  |  |  |  | } | 
| 2068 |  |  |  |  |  |  |  | 
| 2069 |  |  |  |  |  |  | sub name_x00001402 { | 
| 2070 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 2071 | 0 |  |  |  |  | 0 | return 'kOperandKeyIsDown'; | 
| 2072 |  |  |  |  |  |  | } | 
| 2073 |  |  |  |  |  |  |  | 
| 2074 |  |  |  |  |  |  | =head3 dumpBlock | 
| 2075 |  |  |  |  |  |  |  | 
| 2076 |  |  |  |  |  |  | $self->dumpBlock ($pos + 8, $len - 8); | 
| 2077 |  |  |  |  |  |  |  | 
| 2078 |  |  |  |  |  |  | Dump a raw block of data. Generally used where the block can not be further | 
| 2079 |  |  |  |  |  |  | decoded. | 
| 2080 |  |  |  |  |  |  |  | 
| 2081 |  |  |  |  |  |  | =cut | 
| 2082 |  |  |  |  |  |  |  | 
| 2083 |  |  |  |  |  |  | sub dumpBlock { | 
| 2084 | 6 |  |  | 6 | 1 | 9 | my $self = shift; | 
| 2085 | 6 |  |  |  |  | 19 | my ($pos, $len) = @_; | 
| 2086 |  |  |  |  |  |  |  | 
| 2087 | 6 |  |  |  |  | 16 | while ($len) { | 
| 2088 | 6 | 50 |  |  |  | 17 | my $chunk = $len > 16 ? 16 : $len; | 
| 2089 | 6 |  |  |  |  | 18 | my $str = $self->read ($chunk); | 
| 2090 |  |  |  |  |  |  |  | 
| 2091 | 6 |  |  |  |  | 31 | $str =~ s/([\x00-\x1f\x80-\xff])/sprintf "\\x%02x", ord ($1)/ge; | 
|  | 82 |  |  |  |  | 822 |  | 
| 2092 | 6 |  |  |  |  | 22 | $self->append ("$str\n"); | 
| 2093 | 6 |  |  |  |  | 24 | $len -= $chunk; | 
| 2094 |  |  |  |  |  |  | } | 
| 2095 |  |  |  |  |  |  | } | 
| 2096 |  |  |  |  |  |  |  | 
| 2097 |  |  |  |  |  |  | =head3 dumpText ($pos, $len) | 
| 2098 |  |  |  |  |  |  |  | 
| 2099 |  |  |  |  |  |  | Append an ASCII string starting at $pos for $len characters to the Dump result. | 
| 2100 |  |  |  |  |  |  |  | 
| 2101 |  |  |  |  |  |  | =cut | 
| 2102 |  |  |  |  |  |  |  | 
| 2103 |  |  |  |  |  |  | sub dumpText { | 
| 2104 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 2105 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 2106 |  |  |  |  |  |  |  | 
| 2107 | 0 |  |  |  |  | 0 | $self->append (unpack ("a$len", $self->read ($len, $pos)), "\n"); | 
| 2108 |  |  |  |  |  |  | } | 
| 2109 |  |  |  |  |  |  |  | 
| 2110 |  |  |  |  |  |  | =head3 dumpUnicodeText | 
| 2111 |  |  |  |  |  |  |  | 
| 2112 |  |  |  |  |  |  | Append a utf16 string starting at $pos for $len bytes to the Dump result. | 
| 2113 |  |  |  |  |  |  |  | 
| 2114 |  |  |  |  |  |  | =cut | 
| 2115 |  |  |  |  |  |  |  | 
| 2116 |  |  |  |  |  |  | sub dumpUnicodeText { | 
| 2117 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 2118 | 0 |  |  |  |  | 0 | my ($pos, $len) = @_; | 
| 2119 |  |  |  |  |  |  |  | 
| 2120 | 0 |  |  |  |  | 0 | my $rawStr = "\xff\xfe" . unpack ("a$len", $self->read ($len, $pos)); | 
| 2121 | 0 |  |  |  |  | 0 | my $str = decode ("utf16", $rawStr); | 
| 2122 | 0 |  |  |  |  | 0 | $self->append ($str, "\n"); | 
| 2123 |  |  |  |  |  |  | } | 
| 2124 |  |  |  |  |  |  |  | 
| 2125 |  |  |  |  |  |  | =head3 showBogus | 
| 2126 |  |  |  |  |  |  |  | 
| 2127 |  |  |  |  |  |  | L the next four bytes as a packed version and flags field then skips eight | 
| 2128 |  |  |  |  |  |  | bytes. | 
| 2129 |  |  |  |  |  |  |  | 
| 2130 |  |  |  |  |  |  | =cut | 
| 2131 |  |  |  |  |  |  |  | 
| 2132 |  |  |  |  |  |  | sub showBogus { | 
| 2133 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 2134 |  |  |  |  |  |  |  | 
| 2135 | 0 |  |  |  |  | 0 | $self->append ('Version:  ', unpack ('C',   $self->read (1)), "\n"); | 
| 2136 | 0 |  |  |  |  | 0 | $self->append ('Flags:    ', unpack ('B24', $self->read (3)), "\n"); | 
| 2137 | 0 |  |  |  |  | 0 | $self->append ("Reserved\n"); | 
| 2138 | 0 |  |  |  |  | 0 | $self->read   (8); | 
| 2139 |  |  |  |  |  |  | } | 
| 2140 |  |  |  |  |  |  |  | 
| 2141 |  |  |  |  |  |  | =head3 showPlayMode | 
| 2142 |  |  |  |  |  |  |  | 
| 2143 |  |  |  |  |  |  | L a play mode string decoded from the next four byte flags field. | 
| 2144 |  |  |  |  |  |  |  | 
| 2145 |  |  |  |  |  |  | =cut | 
| 2146 |  |  |  |  |  |  |  | 
| 2147 |  |  |  |  |  |  | sub showPlayMode { | 
| 2148 | 0 |  |  | 0 | 1 | 0 | my $self     = shift; | 
| 2149 | 0 |  |  |  |  | 0 | my $flagBits = shift; | 
| 2150 | 0 |  |  |  |  | 0 | my $flags    = ''; | 
| 2151 |  |  |  |  |  |  |  | 
| 2152 | 0 | 0 |  |  |  | 0 | $flagBits = $self->read (4) if !defined $flagBits; | 
| 2153 | 0 |  |  |  |  | 0 | $flagBits = NToSigned ($flagBits); | 
| 2154 |  |  |  |  |  |  |  | 
| 2155 | 0 | 0 |  |  |  | 0 | $flags .= 'fullScreenHideCursor '        if $flags & 1; | 
| 2156 | 0 | 0 |  |  |  | 0 | $flags .= 'fullScreenAllowEvents '       if $flags & 2; | 
| 2157 | 0 | 0 |  |  |  | 0 | $flags .= 'fullScreenDontChangeMenuBar ' if $flags & 4; | 
| 2158 | 0 | 0 |  |  |  | 0 | $flags .= 'fullScreenPreflightSize '     if $flags & 8; | 
| 2159 | 0 |  |  |  |  | 0 | $self->append ("Play mode flags: $flags\n"); | 
| 2160 |  |  |  |  |  |  | } | 
| 2161 |  |  |  |  |  |  |  | 
| 2162 |  |  |  |  |  |  | =head3 showGMode | 
| 2163 |  |  |  |  |  |  |  | 
| 2164 |  |  |  |  |  |  | L a graphics mode line decoded from the next two byte field. | 
| 2165 |  |  |  |  |  |  |  | 
| 2166 |  |  |  |  |  |  | =cut | 
| 2167 |  |  |  |  |  |  |  | 
| 2168 |  |  |  |  |  |  | sub showGMode { | 
| 2169 | 0 |  |  | 0 | 1 | 0 | my $self  = shift; | 
| 2170 | 0 |  |  |  |  | 0 | my $gMode = shift; | 
| 2171 | 0 | 0 |  |  |  | 0 | $gMode = $self->read (2) if !defined $gMode; | 
| 2172 | 0 |  |  |  |  | 0 | $gMode = NToSigned ($gMode); | 
| 2173 |  |  |  |  |  |  |  | 
| 2174 | 0 |  |  |  |  | 0 | my %modes = ( | 
| 2175 |  |  |  |  |  |  | 0x0000 => 'Copy', | 
| 2176 |  |  |  |  |  |  | 0x0040 => 'Dither copy', | 
| 2177 |  |  |  |  |  |  | 0x0020 => 'Blend', | 
| 2178 |  |  |  |  |  |  | 0x0024 => 'Transparent', | 
| 2179 |  |  |  |  |  |  | 0x0100 => 'Straight alpha', | 
| 2180 |  |  |  |  |  |  | 0x0101 => 'Premul white alpha', | 
| 2181 |  |  |  |  |  |  | 0x0102 => 'Premul black alpha', | 
| 2182 |  |  |  |  |  |  | 0x0104 => 'Straight alpha blend', | 
| 2183 |  |  |  |  |  |  | 0x0103 => 'Composition (dither copy)', | 
| 2184 |  |  |  |  |  |  | ); | 
| 2185 |  |  |  |  |  |  |  | 
| 2186 | 0 |  |  |  |  | 0 | $self->append ("Graphics mode: $modes{$gMode}\n"); | 
| 2187 |  |  |  |  |  |  | } | 
| 2188 |  |  |  |  |  |  |  | 
| 2189 |  |  |  |  |  |  | =head3 showRGB | 
| 2190 |  |  |  |  |  |  |  | 
| 2191 |  |  |  |  |  |  | L three RGB color lines decoded from the next six bytes. | 
| 2192 |  |  |  |  |  |  |  | 
| 2193 |  |  |  |  |  |  | =cut | 
| 2194 |  |  |  |  |  |  |  | 
| 2195 |  |  |  |  |  |  | sub showRGB { | 
| 2196 | 1 |  |  | 1 | 1 | 3 | my $self = shift; | 
| 2197 | 1 |  |  |  |  | 3 | my ($red, $green, $blue) = @_; | 
| 2198 |  |  |  |  |  |  |  | 
| 2199 | 1 | 50 |  |  |  | 6 | $red   = $self->read (2) if !defined $red; | 
| 2200 | 1 | 50 |  |  |  | 6 | $green = $self->read (2) if !defined $green; | 
| 2201 | 1 | 50 |  |  |  | 6 | $blue  = $self->read (2) if !defined $blue; | 
| 2202 | 1 |  |  |  |  | 4 | $red   = nToUnsigned ($red); | 
| 2203 | 1 |  |  |  |  | 3 | $green = nToUnsigned ($green); | 
| 2204 | 1 |  |  |  |  | 12 | $blue  = nToUnsigned ($blue); | 
| 2205 |  |  |  |  |  |  |  | 
| 2206 | 1 |  |  |  |  | 6 | $self->append ("Red:   $red\n"); | 
| 2207 | 1 |  |  |  |  | 4 | $self->append ("Green: $green\n"); | 
| 2208 | 1 |  |  |  |  | 4 | $self->append ("Blue:  $blue\n"); | 
| 2209 |  |  |  |  |  |  | } | 
| 2210 |  |  |  |  |  |  |  | 
| 2211 |  |  |  |  |  |  | =head3 showGraphicsXferMode | 
| 2212 |  |  |  |  |  |  |  | 
| 2213 |  |  |  |  |  |  | L a graphics transfer mode string decoded fromthe next two byte field. | 
| 2214 |  |  |  |  |  |  |  | 
| 2215 |  |  |  |  |  |  | =cut | 
| 2216 |  |  |  |  |  |  |  | 
| 2217 |  |  |  |  |  |  | sub showGraphicsXferMode { | 
| 2218 | 1 |  |  | 1 | 1 | 3 | my $self  = shift; | 
| 2219 | 1 |  |  |  |  | 3 | my $gMode = shift; | 
| 2220 |  |  |  |  |  |  |  | 
| 2221 | 1 | 50 |  |  |  | 6 | $gMode = $self->read (2) if !defined $gMode; | 
| 2222 | 1 |  |  |  |  | 6 | $gMode = nToSigned ($gMode); | 
| 2223 |  |  |  |  |  |  |  | 
| 2224 | 1 |  |  |  |  | 178 | my %modes = ( | 
| 2225 |  |  |  |  |  |  | 0  => 'srcCopy', | 
| 2226 |  |  |  |  |  |  | 1  => 'srcOr', | 
| 2227 |  |  |  |  |  |  | 2  => 'srcXor', | 
| 2228 |  |  |  |  |  |  | 3  => 'srcBic', | 
| 2229 |  |  |  |  |  |  | 4  => 'notSrcCopy', | 
| 2230 |  |  |  |  |  |  | 5  => 'notSrcOr', | 
| 2231 |  |  |  |  |  |  | 6  => 'notSrcXor', | 
| 2232 |  |  |  |  |  |  | 7  => 'notSrcBic', | 
| 2233 |  |  |  |  |  |  | 8  => 'patCopy', | 
| 2234 |  |  |  |  |  |  | 9  => 'patOr', | 
| 2235 |  |  |  |  |  |  | 10 => 'patXor', | 
| 2236 |  |  |  |  |  |  | 11 => 'patBic', | 
| 2237 |  |  |  |  |  |  | 12 => 'notPatCopy', | 
| 2238 |  |  |  |  |  |  | 13 => 'notPatOr', | 
| 2239 |  |  |  |  |  |  | 14 => 'notPatXor', | 
| 2240 |  |  |  |  |  |  | 15 => 'notPatBic', | 
| 2241 |  |  |  |  |  |  | 49 => 'grayishTextOr', | 
| 2242 |  |  |  |  |  |  | 50 => 'hilite', | 
| 2243 |  |  |  |  |  |  | 50 => 'hilitetransfermode', | 
| 2244 |  |  |  |  |  |  | 32 => 'blend', | 
| 2245 |  |  |  |  |  |  | 33 => 'addPin', | 
| 2246 |  |  |  |  |  |  | 34 => 'addOver', | 
| 2247 |  |  |  |  |  |  | 35 => 'subPin', | 
| 2248 |  |  |  |  |  |  | 37 => 'addMax', | 
| 2249 |  |  |  |  |  |  | 37 => 'adMax', | 
| 2250 |  |  |  |  |  |  | 38 => 'subOver', | 
| 2251 |  |  |  |  |  |  | 39 => 'adMin', | 
| 2252 |  |  |  |  |  |  | 64 => 'ditherCopy', | 
| 2253 |  |  |  |  |  |  | 36 => 'transparent', | 
| 2254 |  |  |  |  |  |  | ); | 
| 2255 |  |  |  |  |  |  |  | 
| 2256 | 1 | 50 |  |  |  | 8 | if (exists $modes{$gMode}) { | 
| 2257 | 1 |  |  |  |  | 43 | $self->append ('Mode:  ', $modes{$gMode}, "\n"); | 
| 2258 |  |  |  |  |  |  | } else { | 
| 2259 | 0 |  |  |  |  | 0 | $self->append ('Mode:  unknown - ', $gMode, "\n"); | 
| 2260 |  |  |  |  |  |  | } | 
| 2261 |  |  |  |  |  |  | } | 
| 2262 |  |  |  |  |  |  |  | 
| 2263 |  |  |  |  |  |  | =head3 showDate | 
| 2264 |  |  |  |  |  |  |  | 
| 2265 |  |  |  |  |  |  | L a date string decoded from the next four bytes. | 
| 2266 |  |  |  |  |  |  |  | 
| 2267 |  |  |  |  |  |  | =cut | 
| 2268 |  |  |  |  |  |  |  | 
| 2269 |  |  |  |  |  |  | sub showDate { | 
| 2270 | 10 |  |  | 10 | 1 | 101 | my $self  = shift; | 
| 2271 | 10 |  |  |  |  | 15 | my $stamp = shift; | 
| 2272 |  |  |  |  |  |  |  | 
| 2273 | 10 | 100 |  |  |  | 35 | $stamp = $self->read (4) if !defined $stamp; | 
| 2274 | 10 |  |  |  |  | 100 | $stamp = NToUnsigned ($stamp); | 
| 2275 |  |  |  |  |  |  |  | 
| 2276 |  |  |  |  |  |  | # seconds difference between Mac epoch and Unix/Windows. | 
| 2277 | 10 | 50 |  |  |  | 43 | my $mod = | 
| 2278 |  |  |  |  |  |  | ($^O =~ /MSWin32/) | 
| 2279 |  |  |  |  |  |  | ? (2063824538 - 12530100 + 31536000) | 
| 2280 |  |  |  |  |  |  | : (2063824538 - 12530100); | 
| 2281 | 10 | 50 |  |  |  | 787 | my $date = ($^O =~ /Mac/) ? localtime ($stamp) : localtime ($stamp - $mod); | 
| 2282 | 10 |  |  |  |  | 138 | return $date; | 
| 2283 |  |  |  |  |  |  | } | 
| 2284 |  |  |  |  |  |  |  | 
| 2285 |  |  |  |  |  |  | =head3 showMatrix ([$matrix]) | 
| 2286 |  |  |  |  |  |  |  | 
| 2287 |  |  |  |  |  |  | Returns a matrix string formedby decoding the 36 byte contents of $matrix or the | 
| 2288 |  |  |  |  |  |  | next 36 bytes (if $matrix is not provided). | 
| 2289 |  |  |  |  |  |  |  | 
| 2290 |  |  |  |  |  |  | =cut | 
| 2291 |  |  |  |  |  |  |  | 
| 2292 |  |  |  |  |  |  | sub showMatrix { | 
| 2293 | 3 |  |  | 3 | 1 | 6 | my $self   = shift; | 
| 2294 | 3 |  |  |  |  | 5 | my $matrix = shift; | 
| 2295 |  |  |  |  |  |  |  | 
| 2296 | 3 | 100 |  |  |  | 12 | $matrix = $self->read (36) if !defined $matrix; | 
| 2297 |  |  |  |  |  |  |  | 
| 2298 | 3 |  |  |  |  | 6 | my $str = ''; | 
| 2299 | 3 |  |  |  |  | 9 | for (1 .. 3) { | 
| 2300 | 9 |  |  |  |  | 15 | my $sub = substr $matrix, 0, 12, ''; | 
| 2301 | 9 |  |  |  |  | 24 | $str .= NToFixed (substr $sub, 0, 4, '') . ' '; | 
| 2302 | 9 |  |  |  |  | 25 | $str .= NToFixed (substr $sub, 0, 4, '') . ' '; | 
| 2303 | 9 |  |  |  |  | 29 | $str .= NToFrac (substr $sub, 0, 4, '') . ' '; | 
| 2304 | 9 | 100 |  |  |  | 39 | $str .= ' / ' if $_ != 3; | 
| 2305 |  |  |  |  |  |  | } | 
| 2306 |  |  |  |  |  |  |  | 
| 2307 | 3 |  |  |  |  | 14 | return $str; | 
| 2308 |  |  |  |  |  |  | } | 
| 2309 |  |  |  |  |  |  |  | 
| 2310 |  |  |  |  |  |  | =head3 showStr ($pos) | 
| 2311 |  |  |  |  |  |  |  | 
| 2312 |  |  |  |  |  |  | L the length prefixed string starting at $pos. | 
| 2313 |  |  |  |  |  |  |  | 
| 2314 |  |  |  |  |  |  | =cut | 
| 2315 |  |  |  |  |  |  |  | 
| 2316 |  |  |  |  |  |  | sub showStr { | 
| 2317 | 2 |  |  | 2 | 1 | 4 | my $self = shift; | 
| 2318 | 2 |  |  |  |  | 3 | my $pos  = shift; | 
| 2319 | 2 |  |  |  |  | 6 | my ($len, $key) = unpack ("Na4", $self->read (8, $pos)); | 
| 2320 |  |  |  |  |  |  |  | 
| 2321 | 2 |  |  |  |  | 3 | $len -= 12; | 
| 2322 | 2 |  |  |  |  | 9 | $self->append (unpack ("a$len", $self->read ($len, $pos + 12)), "\n"); | 
| 2323 |  |  |  |  |  |  | } | 
| 2324 |  |  |  |  |  |  |  | 
| 2325 |  |  |  |  |  |  | =head3 showUnknown | 
| 2326 |  |  |  |  |  |  |  | 
| 2327 |  |  |  |  |  |  | L out the next 12 bytes as three unknown signed numbers. | 
| 2328 |  |  |  |  |  |  |  | 
| 2329 |  |  |  |  |  |  | =cut | 
| 2330 |  |  |  |  |  |  |  | 
| 2331 |  |  |  |  |  |  | sub showUnknown { | 
| 2332 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 2333 |  |  |  |  |  |  |  | 
| 2334 | 0 |  |  |  |  | 0 | $self->append ('Unknown 1: ', groupDigits (NToSigned ($self->read (4))), | 
| 2335 |  |  |  |  |  |  | "\n"); | 
| 2336 | 0 |  |  |  |  | 0 | $self->append ('Unknown 2: ', groupDigits (NToSigned ($self->read (4))), | 
| 2337 |  |  |  |  |  |  | "\n"); | 
| 2338 | 0 |  |  |  |  | 0 | $self->append ('Unknown 3: ', groupDigits (NToSigned ($self->read (4))), | 
| 2339 |  |  |  |  |  |  | "\n"); | 
| 2340 |  |  |  |  |  |  | } | 
| 2341 |  |  |  |  |  |  |  | 
| 2342 |  |  |  |  |  |  | =head3 get4Char | 
| 2343 |  |  |  |  |  |  |  | 
| 2344 |  |  |  |  |  |  | Return the next four bytes as a four char code. | 
| 2345 |  |  |  |  |  |  |  | 
| 2346 |  |  |  |  |  |  | =cut | 
| 2347 |  |  |  |  |  |  |  | 
| 2348 |  |  |  |  |  |  | sub get4Char { | 
| 2349 | 14 |  |  | 14 | 1 | 179 | my $self = shift; | 
| 2350 | 14 |  |  |  |  | 30 | return unpack ("a4", $self->read (4)); | 
| 2351 |  |  |  |  |  |  | } | 
| 2352 |  |  |  |  |  |  |  | 
| 2353 |  |  |  |  |  |  | =head2 Helper functions | 
| 2354 |  |  |  |  |  |  |  | 
| 2355 |  |  |  |  |  |  | The following functions are not object members and should be called as: | 
| 2356 |  |  |  |  |  |  |  | 
| 2357 |  |  |  |  |  |  | my $result = Video::Dumper::QuickTime::functionName (...); | 
| 2358 |  |  |  |  |  |  |  | 
| 2359 |  |  |  |  |  |  | =head3 groupDigits ($number) | 
| 2360 |  |  |  |  |  |  |  | 
| 2361 |  |  |  |  |  |  | Inserts commas into a number to group the digits into groups of 3. | 
| 2362 |  |  |  |  |  |  |  | 
| 2363 |  |  |  |  |  |  | =cut | 
| 2364 |  |  |  |  |  |  |  | 
| 2365 |  |  |  |  |  |  | sub groupDigits { | 
| 2366 | 121 |  |  | 121 | 1 | 725 | my $num = reverse shift; | 
| 2367 |  |  |  |  |  |  |  | 
| 2368 | 121 |  |  |  |  | 1306 | $num =~ s/(\d{3}(?=\d))/$1,/g; | 
| 2369 | 121 |  |  |  |  | 1431 | return scalar reverse $num; | 
| 2370 |  |  |  |  |  |  | } | 
| 2371 |  |  |  |  |  |  |  | 
| 2372 |  |  |  |  |  |  | =head3 show ($string) | 
| 2373 |  |  |  |  |  |  |  | 
| 2374 |  |  |  |  |  |  | Attempt to make sense of the series of bytes in $string. Maybe useful for | 
| 2375 |  |  |  |  |  |  | attempting to make sense of unknown atom data. | 
| 2376 |  |  |  |  |  |  |  | 
| 2377 |  |  |  |  |  |  | =cut | 
| 2378 |  |  |  |  |  |  |  | 
| 2379 |  |  |  |  |  |  | sub show { | 
| 2380 | 0 |  |  | 0 | 1 | 0 | local $_; | 
| 2381 | 0 |  |  |  |  | 0 | my $thing = shift; | 
| 2382 | 0 | 0 |  |  |  | 0 | if ($thing =~ /^([^\x00]*)\x00\Z/) { | 
|  |  | 0 |  |  |  |  |  | 
| 2383 | 0 |  |  |  |  | 0 | return $1; | 
| 2384 |  |  |  |  |  |  | } elsif ($thing =~ /[\x00-\x1f]/) { | 
| 2385 | 0 |  |  |  |  | 0 | my $sum = 0; | 
| 2386 | 0 |  |  |  |  | 0 | my @chars = split '', $thing; | 
| 2387 | 0 |  |  |  |  | 0 | $sum = $sum * 256 + ord ($_) for @chars; | 
| 2388 | 0 |  |  |  |  | 0 | return sprintf "0x%0x", $sum; | 
| 2389 |  |  |  |  |  |  | } | 
| 2390 |  |  |  |  |  |  |  | 
| 2391 | 0 |  |  |  |  | 0 | return $thing; | 
| 2392 |  |  |  |  |  |  | } | 
| 2393 |  |  |  |  |  |  |  | 
| 2394 |  |  |  |  |  |  | =head2 Conversion helper functions | 
| 2395 |  |  |  |  |  |  |  | 
| 2396 |  |  |  |  |  |  | The following non-member function unpack strings of bytes into another | 
| 2397 |  |  |  |  |  |  | representation. | 
| 2398 |  |  |  |  |  |  |  | 
| 2399 |  |  |  |  |  |  | =head3 NToFixed ($str) | 
| 2400 |  |  |  |  |  |  |  | 
| 2401 |  |  |  |  |  |  | =cut | 
| 2402 |  |  |  |  |  |  |  | 
| 2403 |  |  |  |  |  |  | sub NToFixed { | 
| 2404 | 25 |  |  | 25 | 1 | 34 | my $str = shift; | 
| 2405 | 25 |  |  |  |  | 116 | return unpack ('l', pack ('l', unpack ("N", $str))) / 0x10000; | 
| 2406 |  |  |  |  |  |  | } | 
| 2407 |  |  |  |  |  |  |  | 
| 2408 |  |  |  |  |  |  | =head3 fToFloat ($str) | 
| 2409 |  |  |  |  |  |  |  | 
| 2410 |  |  |  |  |  |  | =cut | 
| 2411 |  |  |  |  |  |  |  | 
| 2412 |  |  |  |  |  |  | sub fToFloat { | 
| 2413 | 0 |  |  | 0 | 1 | 0 | my $str = shift; | 
| 2414 | 0 |  |  |  |  | 0 | return unpack ('l', pack ('l', unpack ("f", $str))); | 
| 2415 |  |  |  |  |  |  | } | 
| 2416 |  |  |  |  |  |  |  | 
| 2417 |  |  |  |  |  |  | =head3 NToFrac | 
| 2418 |  |  |  |  |  |  |  | 
| 2419 |  |  |  |  |  |  | =cut | 
| 2420 |  |  |  |  |  |  |  | 
| 2421 |  |  |  |  |  |  | sub NToFrac { | 
| 2422 | 9 |  |  | 9 | 1 | 9 | my $str = shift; | 
| 2423 | 9 |  |  |  |  | 20 | my $fract = unpack ('l', pack ('l', unpack ("N", $str))); | 
| 2424 | 9 |  |  |  |  | 26 | return $fract / 0x40000000; | 
| 2425 |  |  |  |  |  |  | } | 
| 2426 |  |  |  |  |  |  |  | 
| 2427 |  |  |  |  |  |  | =head3 NToSigned | 
| 2428 |  |  |  |  |  |  |  | 
| 2429 |  |  |  |  |  |  | =cut | 
| 2430 |  |  |  |  |  |  |  | 
| 2431 |  |  |  |  |  |  | sub NToSigned { | 
| 2432 | 348 |  |  | 348 | 1 | 1233 | my $str = shift; | 
| 2433 | 348 |  |  |  |  | 3344 | return unpack ('l', pack ('l', unpack ("N", $str))); | 
| 2434 |  |  |  |  |  |  | } | 
| 2435 |  |  |  |  |  |  |  | 
| 2436 |  |  |  |  |  |  | =head3 NToUnsigned | 
| 2437 |  |  |  |  |  |  |  | 
| 2438 |  |  |  |  |  |  | =cut | 
| 2439 |  |  |  |  |  |  |  | 
| 2440 |  |  |  |  |  |  | sub NToUnsigned { | 
| 2441 | 10 |  |  | 10 | 1 | 14 | my $str = shift; | 
| 2442 | 10 |  |  |  |  | 149 | return unpack ('L', pack ('L', unpack ("N", $str))); | 
| 2443 |  |  |  |  |  |  | } | 
| 2444 |  |  |  |  |  |  |  | 
| 2445 |  |  |  |  |  |  | =head3 NToHex | 
| 2446 |  |  |  |  |  |  |  | 
| 2447 |  |  |  |  |  |  | =cut | 
| 2448 |  |  |  |  |  |  |  | 
| 2449 |  |  |  |  |  |  | sub NToHex { | 
| 2450 | 0 |  |  | 0 | 1 | 0 | my $str = shift; | 
| 2451 | 0 |  |  |  |  | 0 | return '0x' . unpack ('H8', $str); | 
| 2452 |  |  |  |  |  |  | } | 
| 2453 |  |  |  |  |  |  |  | 
| 2454 |  |  |  |  |  |  | =head3 NToBin | 
| 2455 |  |  |  |  |  |  |  | 
| 2456 |  |  |  |  |  |  | =cut | 
| 2457 |  |  |  |  |  |  |  | 
| 2458 |  |  |  |  |  |  | sub NToBin { | 
| 2459 | 0 |  |  | 0 | 1 | 0 | my $str = shift; | 
| 2460 | 0 |  |  |  |  | 0 | return unpack ('B32', $str); | 
| 2461 |  |  |  |  |  |  | } | 
| 2462 |  |  |  |  |  |  |  | 
| 2463 |  |  |  |  |  |  | =head3 nToSigned | 
| 2464 |  |  |  |  |  |  |  | 
| 2465 |  |  |  |  |  |  | =cut | 
| 2466 |  |  |  |  |  |  |  | 
| 2467 |  |  |  |  |  |  | sub nToSigned { | 
| 2468 | 9 |  |  | 9 | 1 | 17 | my $str = shift; | 
| 2469 | 9 |  |  |  |  | 60 | return unpack ('s', pack ('s', unpack ("n", $str))); | 
| 2470 |  |  |  |  |  |  | } | 
| 2471 |  |  |  |  |  |  |  | 
| 2472 |  |  |  |  |  |  | =head3 nToUnsigned | 
| 2473 |  |  |  |  |  |  |  | 
| 2474 |  |  |  |  |  |  | =cut | 
| 2475 |  |  |  |  |  |  |  | 
| 2476 |  |  |  |  |  |  | sub nToUnsigned { | 
| 2477 | 5 |  |  | 5 | 1 | 11 | my $str = shift; | 
| 2478 | 5 |  |  |  |  | 21 | return unpack ('S', pack ('S', unpack ("n", $str))); | 
| 2479 |  |  |  |  |  |  | } | 
| 2480 |  |  |  |  |  |  |  | 
| 2481 |  |  |  |  |  |  | =head3 cToBool | 
| 2482 |  |  |  |  |  |  |  | 
| 2483 |  |  |  |  |  |  | =cut | 
| 2484 |  |  |  |  |  |  |  | 
| 2485 |  |  |  |  |  |  | sub cToBool { | 
| 2486 | 0 |  |  | 0 | 1 |  | my $str = shift; | 
| 2487 | 0 |  |  |  |  |  | return ord ($str); | 
| 2488 |  |  |  |  |  |  | } | 
| 2489 |  |  |  |  |  |  |  | 
| 2490 |  |  |  |  |  |  | 1; | 
| 2491 |  |  |  |  |  |  |  | 
| 2492 |  |  |  |  |  |  | =head2 Subclassing QuickTime | 
| 2493 |  |  |  |  |  |  |  | 
| 2494 |  |  |  |  |  |  | Because there are a huge number of atom types used by QuickTime (many of them | 
| 2495 |  |  |  |  |  |  | undocumented) and the number of atom types used is increasing over time, | 
| 2496 |  |  |  |  |  |  | Video::Dumper::QuickTime makes no attempt to decode all atom types. Instead it is | 
| 2497 |  |  |  |  |  |  | easy to subclass the QuickTime class to add decoders for atoms of interest, or | 
| 2498 |  |  |  |  |  |  | to change the way atoms that are currently handled by the QuickTime class are | 
| 2499 |  |  |  |  |  |  | decoded for some particular application. | 
| 2500 |  |  |  |  |  |  |  | 
| 2501 |  |  |  |  |  |  | Two methods need to be provided for decoding of an atom. They are of the form: | 
| 2502 |  |  |  |  |  |  |  | 
| 2503 |  |  |  |  |  |  | sub name_xxxx { | 
| 2504 |  |  |  |  |  |  | my $self = shift; | 
| 2505 |  |  |  |  |  |  | return 'The xxxx atom'; | 
| 2506 |  |  |  |  |  |  | } | 
| 2507 |  |  |  |  |  |  |  | 
| 2508 |  |  |  |  |  |  | sub dump_xxxx { | 
| 2509 |  |  |  |  |  |  | my $self = shift; | 
| 2510 |  |  |  |  |  |  | my ( $pos, $len ) = @_; | 
| 2511 |  |  |  |  |  |  |  | 
| 2512 |  |  |  |  |  |  | ... | 
| 2513 |  |  |  |  |  |  | } | 
| 2514 |  |  |  |  |  |  |  | 
| 2515 |  |  |  |  |  |  | where the C is a placeholder for the atom four char code. | 
| 2516 |  |  |  |  |  |  |  | 
| 2517 |  |  |  |  |  |  | A complete subclass package that handles one atom might look like: | 
| 2518 |  |  |  |  |  |  |  | 
| 2519 |  |  |  |  |  |  | package Subclass; | 
| 2520 |  |  |  |  |  |  |  | 
| 2521 |  |  |  |  |  |  | use QuickTime; | 
| 2522 |  |  |  |  |  |  | use base qw(QuickTime); | 
| 2523 |  |  |  |  |  |  |  | 
| 2524 |  |  |  |  |  |  | sub name_smhd { | 
| 2525 |  |  |  |  |  |  | my $self = shift; | 
| 2526 |  |  |  |  |  |  | return 'The smhd atom'; | 
| 2527 |  |  |  |  |  |  | } | 
| 2528 |  |  |  |  |  |  |  | 
| 2529 |  |  |  |  |  |  | sub dump_smhd { | 
| 2530 |  |  |  |  |  |  | my $self = shift; | 
| 2531 |  |  |  |  |  |  | my ( $pos, $len ) = @_; | 
| 2532 |  |  |  |  |  |  | } | 
| 2533 |  |  |  |  |  |  |  | 
| 2534 |  |  |  |  |  |  | There is of course no limit practical to the number of handlers added by a | 
| 2535 |  |  |  |  |  |  | subclass. | 
| 2536 |  |  |  |  |  |  |  | 
| 2537 |  |  |  |  |  |  | =head1 REMARKS | 
| 2538 |  |  |  |  |  |  |  | 
| 2539 |  |  |  |  |  |  | This module recognises a subset of the atoms actually used by QuickTime files. | 
| 2540 |  |  |  |  |  |  | Generally, well formed files should not present a problem because unrecognised | 
| 2541 |  |  |  |  |  |  | atoms will be reported and skipped. | 
| 2542 |  |  |  |  |  |  |  | 
| 2543 |  |  |  |  |  |  | Subclassing Video::Dumper::QuickTime as shown above allows handlers to be added | 
| 2544 |  |  |  |  |  |  | for unrecognised atoms. The author would appreciate any such handler code being | 
| 2545 |  |  |  |  |  |  | forwarded for inclusion in future versions of the module. | 
| 2546 |  |  |  |  |  |  |  | 
| 2547 |  |  |  |  |  |  | =head1 BUGS | 
| 2548 |  |  |  |  |  |  |  | 
| 2549 |  |  |  |  |  |  | Please report any bugs or feature requests to | 
| 2550 |  |  |  |  |  |  | C, or through the web interface at | 
| 2551 |  |  |  |  |  |  | L. | 
| 2552 |  |  |  |  |  |  | I will be notified, and then you'll automatically be notified of progress on | 
| 2553 |  |  |  |  |  |  | your bug as I make changes. | 
| 2554 |  |  |  |  |  |  |  | 
| 2555 |  |  |  |  |  |  | =head1 SUPPORT | 
| 2556 |  |  |  |  |  |  |  | 
| 2557 |  |  |  |  |  |  | This module is supported by the author through CPAN. The following links may be | 
| 2558 |  |  |  |  |  |  | of assistance: | 
| 2559 |  |  |  |  |  |  |  | 
| 2560 |  |  |  |  |  |  | =over 4 | 
| 2561 |  |  |  |  |  |  |  | 
| 2562 |  |  |  |  |  |  | =item * AnnoCPAN: Annotated CPAN documentation | 
| 2563 |  |  |  |  |  |  |  | 
| 2564 |  |  |  |  |  |  | L | 
| 2565 |  |  |  |  |  |  |  | 
| 2566 |  |  |  |  |  |  | =item * CPAN Ratings | 
| 2567 |  |  |  |  |  |  |  | 
| 2568 |  |  |  |  |  |  | L | 
| 2569 |  |  |  |  |  |  |  | 
| 2570 |  |  |  |  |  |  | =item * RT: CPAN's request tracker | 
| 2571 |  |  |  |  |  |  |  | 
| 2572 |  |  |  |  |  |  | L | 
| 2573 |  |  |  |  |  |  |  | 
| 2574 |  |  |  |  |  |  | =item * Search CPAN | 
| 2575 |  |  |  |  |  |  |  | 
| 2576 |  |  |  |  |  |  | L | 
| 2577 |  |  |  |  |  |  |  | 
| 2578 |  |  |  |  |  |  | =back | 
| 2579 |  |  |  |  |  |  |  | 
| 2580 |  |  |  |  |  |  | =head1 ACKNOWLEDGEMENTS | 
| 2581 |  |  |  |  |  |  |  | 
| 2582 |  |  |  |  |  |  | The author appreciates the receipt of a patch containing bug fixes and | 
| 2583 |  |  |  |  |  |  | additional atom decoders from Nick Wellnhofer. | 
| 2584 |  |  |  |  |  |  |  | 
| 2585 |  |  |  |  |  |  | =head1 AUTHOR | 
| 2586 |  |  |  |  |  |  |  | 
| 2587 |  |  |  |  |  |  | Peter Jaquiery | 
| 2588 |  |  |  |  |  |  | CPAN ID: GRANDPA | 
| 2589 |  |  |  |  |  |  | grandpa@cpan.org | 
| 2590 |  |  |  |  |  |  |  | 
| 2591 |  |  |  |  |  |  | =head1 COPYRIGHT & LICENSE | 
| 2592 |  |  |  |  |  |  |  | 
| 2593 |  |  |  |  |  |  | This program is free software; you can redistribute | 
| 2594 |  |  |  |  |  |  | it and/or modify it under the same terms as Perl itself. | 
| 2595 |  |  |  |  |  |  |  | 
| 2596 |  |  |  |  |  |  | The full text of the license can be found in the | 
| 2597 |  |  |  |  |  |  | LICENSE file included with this module. | 
| 2598 |  |  |  |  |  |  |  | 
| 2599 |  |  |  |  |  |  | =cut |