#!/usr/bin/env python # Extract the ".srf" archives used by "You Don't Know Jack". # Based on the format spec here: # http://wiki.xentax.com/index.php/You_Dont_Know_Jack # Adam Sampson import sys, re, os def die(*s): print >>sys.stderr, "srfextract: " + "".join(map(str, s)) sys.exit(1) def uint32(s): return ord(s[0]) << 24 | ord(s[1]) << 16 | ord(s[2]) << 8 | ord(s[3]) def clean_name(s): def encode(m): return "_%02x" % ord(m.group(0)) return re.sub(r'[^A-Za-z0-9_-]', encode, s) def extract(fn): f = open(fn) s = f.read(12) if s[0:4] != "srf1" or len(s) != 12: die(fn, ": bad header") file_length = uint32(s[4:8]) header_length = uint32(s[8:12]) print >>sys.stderr, "header %d %d" % (file_length, header_length) files = [] while f.tell() < header_length: s = f.read(8) if s == "": break elif len(s) != 8: die(fn, ": unexpected EOF in file header") file_name = clean_name(s[0:4]) sub_count = uint32(s[4:8]) print >>sys.stderr, "file %s %d" % (file_name, sub_count) for i in range(sub_count): s = f.read(12) if len(s) != 12: die(fn, ": unexpected EOF in sub header") sub_id = uint32(s[0:4]) file_offset = uint32(s[4:8]) file_size = uint32(s[8:12]) out_fn = "%s.%s.%04d" % (fn[:-4], file_name, sub_id) print >>sys.stderr, "sub %d %d %d -> %s" % (sub_id, file_offset, file_size, out_fn) files.append((file_offset, file_size, out_fn)) for (offset, size, out_fn) in files: print >>sys.stderr, "x %s %d" % (out_fn, size) f.seek(offset) data = f.read(size) if len(data) != size: die(fn, ": unexpected EOF in file data") of = open(out_fn, "w") of.write(data) of.close() f.close() if __name__ == "__main__": for fn in sys.argv[1:]: extract(fn)