#! /usr/bin/perl $quick = shift(@ARGV) if $ARGV[0] eq "-q"; $verbose = shift(@ARGV) if $ARGV[0] eq "-v"; unless(-f $ARGV[0] || -f $ARGV[0] . ".vfo") { print STDERR "Usage: $0 file.vfo [...] Dump info from a /usr/gfx/ucode/.../vfo/*.vfo file.\n"; exit(1); } while(@ARGV) { $fname = shift(@ARGV); %entry = (); $maxname = 1; unless(open(F, $fname) || open(F, $fname . ".vfo")) { print STDERR "$fname: Cannot open: $!\n"; next; } seek(F, 128, 0); read(F, $hdr, 3*4); ($nstrings, $zero, $stringbase) = unpack("NNN", $hdr); (print STDERR "$fname doesn't appear to be a .vfo file\n"), next if $nstrings<=0 || $nstrings>10000 || $stringbase<=0 || $stringbase>1e6; $offset = $stringbase + 4; for($i = 0; $i < $nstrings; $i++) { seek(F, $offset, 0); read(F, $slen, 4); ($strlen) = unpack("N", $slen); if($strlen < 0 || $strlen > 100) { print STDERR "$fname: unreasonable string length $strlen at offset $offset\n"; last; } read(F, $name, $strlen); $pad4size = (($strlen + 3) & ~3) - $strlen; read(F, $pad4, $pad4size) if $pad4size > 0; read(F, $strinfo, 3*4); ($dtype, $array, $doffset) = unpack("NNN", $strinfo); seek(F, $doffset, 0); $dlen = $dtype==17 ? 8 : 4; $val = ""; if($array > 0) { $val = "[$array]{ "; read(F, $data, 4); ($array2) = unpack("N", $data); if($array2 != $array) { printf STDERR "%s: claimed array length %d at %d doesn't match %d at %d\n", $fname, $array, $offset+$strlen+$pad4size+4, $array2, $doffset; last; } } $index = 0; do { if(read(F, $data, $dlen) != $dlen) { print STDERR "$fname offset $doffset: couldn't read value for $name\n"; last; } if($dtype == 15) { ($dstrlen) = unpack("N", $data); read(F, $data, $dstrlen); $data = '"' . $data . '"'; } elsif($dtype == 17) { ($data) = unpack("d", $data); $data = sprintf("%.10g", $data); } else { ($data) = unpack("N", $data); } $val .= $data . " "; } while(++$index < $array); if($array > 0) { $val .= "}"; } else { chop($val); } $val .= " <$dtype>[$zero]@$doffset" if $verbose; $entry{$name} = $val; $maxname = length($name) if $maxname < length($name); $offset += 4 + $strlen + $pad4size + 3*4; } if($quick) { $qname = sprintf("%dx%d_%d%s", $entry{"ActivePixelsPerLine"}, $entry{"ActiveLinesPerFrame"} / $entry{"FieldsPerFrame"}, $entry{"FormatInfo_PixelClock"} / ($entry{"TotalPixelsPerLine"} * $entry{"TotalLinesPerFrame"}), $entry{"FormatInfo_Stereo"} ? "s" : "" ); printf "%s\t%s (%s)\n", $fname, $qname, $entry{"FormatName"}; } else { $maxname = ($maxname + 8) & ~7; print "== $fname ==\n"; foreach $name (sort {$a cmp $b} keys(entry)) { print $name, "\t" x int((7+$maxname-length($name))/8), $entry{$name}, "\n"; } print "\n\n" if @ARGV; } }