def readSEEK(self, data): if self.verbose: print('Reading SEEK') magic, length = self.unpack_from('4sI', data, self.seekref.offset) if magic != b'SEEK': error.InvalidMagicError('Invalid SEEK magic (got %s)' % byterepr(magic)) self.seek = np.fromstring(data.read(length - 8), dtype=np.int16)
def readFATB(self, data, ptr): hdr, ptr = self.unpack_from(GARC_FATB_HEADER, data, ptr, getptr=True) if hdr[0] != b'BTAF': error.InvalidMagicError('Invalid FATB magic %s, expected BTAF' % byterepr(hdr[0])) #headerlen = hdr[1] entrycount = hdr[2] tblstart = ptr self.fatb = [] #for i in range(0, entrycount): for offset in self.fato: entry = FATBEntry() flags, ptr = self.unpack_from('I', data, tblstart + offset, getptr=True) flags = flags[0] entry.flags = flags for j in range(0, 32): exists = (flags & 1) flags >>= 1 if exists: subentry = FATBSubEntry() subdata, ptr = self.unpack_from('3I', data, ptr, getptr=True) subentry.start, subentry.end, subentry.length = subdata entry.subentries += [None ] * (j - len(entry.subentries) + 1) entry.subentries[j] = subentry entry.isfolder = len(entry.subentries) > 1 self.fatb.append(entry) return ptr
def readheader(self): self.byteorder = ENDIANS[self.unpack_from('>H', self.data, 4)[0]] INFOTable.byteorder = self.byteorder BCSARSection.byteorder = self.byteorder header = self.unpack_from(CSAR_HEADER, self.data, 0) magic = header[0] if magic != b'CSAR': error.InvalidMagicError('Invalid magic %s, expected CSAR' % byterepr(magic)) #bom = header[1] #headerlen = header[2] #version = header[3] #? #filelen = header[4] seccount = header[5] #padding = header[6] #? for sec in header[7]: id, padding, offset, size = sec if id == STRG.id: #STRG self.strg.offset = offset self.strg.size = size elif id == INFO.id: #INFO self.info.offset = offset self.info.size = size elif id == FILE.id: #FILE self.file.offset = offset self.file.size = size else: error.InvalidSectionError('Invalid section ID 0x%04x' % id)
def extract(self, data): header = self.unpack_from(INFO_HEADER, data, self.offset) if header[0] != b'INFO': error.InvalidMagicError('Invalid magic %s, expected INFO' % header[0]) #sectionlen = header[1] for i, el in enumerate(header[2]): id, padding, offset = el if id == AudioTable.id: self.audiotbl = AudioTable(offset + self.offset + 8) elif id == BankTable.id: self.banktbl = BankTable(offset + self.offset + 8) elif id == PlayerTable.id: self.playertbl = PlayerTable(offset + self.offset + 8) elif id == WaveArcTable.id: self.warctbl = WaveArcTable(offset + self.offset + 8) elif id == SetTable.id: self.settbl = SetTable(offset + self.offset + 8) elif id == GroupTable.id: self.grouptbl = GroupTable(offset + self.offset + 8) elif id == FileTable.id: self.filetbl = FileTable(offset + self.offset + 8) elif id == FileTable.endid: self.filetbl.end = offset self.readTable(data, self.filetbl) self.readTable(data, self.warctbl) self.readTable(data, self.banktbl) self.readTable(data, self.audiotbl) self.readTable(data, self.settbl) self.readTable(data, self.grouptbl)
def extract(self, data): header = self.unpack_from(STRG_HEADER, data, self.offset) if header[0] != b'STRG': error.InvalidMagicError('Invalid magic %s, expected STRG' % byterepr(header[0])) #sectionlen = header[1] for i, el in enumerate(header[2]): id, padding, offset = el if id == 0x2400: #STRinGs table offset self.strtbl_offset = offset + 8 + (8 * i) elif id == 0x2401: #Another offset table self.othertbl_offset = offset + 8 + (8 * i) else: error.InvalidSectionError('Invalid section ID in STRG 0x%04x' % id) strtbl_offsettbl = self.unpack_from(STRG_STR_OFFSETTABLE, data, self.strtbl_offset + self.offset) self.strings_count = strtbl_offsettbl[0] for entry in strtbl_offsettbl[1]: id, padding, offset, size = entry if id != 0x1f01: error.InvalidSectionError( 'Invalid entry ID in strings table offsets 0x%04x, expected 0x1f01' % id) else: self.strings.append( self.unpack_from('n', data, offset + self.strtbl_offset + 0x40)[0].decode('utf-8'))
def readheader(self, data): self.byteorder = ENDIANS[rawutil.unpack_from('>H', data, 8)[0]] hdata, ptr = self.unpack_from(GARC_HEADER_STRUCT, data, 0, getptr=True) if hdata[0] != b'CRAG': error.InvalidMagicError('Invalid magic %s, expected CRAG' % byterepr(hdata[0])) #headerlen = hdata[1] #bom = hdata[2] self.version = hdata[3] self.chunkcount = hdata[4] self.dataoffset = hdata[5] #filelen = hdata[6] padinfo, ptr = self.unpack_from(GARC_HEADER_END[self.version], data, ptr, getptr=True) if self.version == 0x0400: print('Version: 4') self.larger_unpadded = padinfo[0] self.pad_to_nearest = 4 elif self.version == 0x0600: print('Version: 6') self.larger_padded = padinfo[0] self.larger_unpadded = padinfo[1] self.pad_to_nearest = padinfo[2] else: error.UnsupportedVersionError('Unsupported version 0x%04x' % self.version) return ptr
def readheader(self): self.byteorder = ENDIANS[rawutil.unpack_from('<H', self.file, 4)[0]] header = self.unpack_from(NARC_HEADER_STRUCT, self.file, 0, NARC_HEADER_NAMES) if header.magic != b'NARC': error.InvalidMagicError('Invalid NARC magic: %s' % byterepr(header.magic))
def readCMAP(self, data, secoffset): magic, size = self.unpack_from('4sI', data, secoffset) if magic != b'CMAP': error.InvalidMagicError('Invalid CMAP magic (got %s)' % byterepr(magic)) if self.version == 'NX': startcode, endcode, method, reserved, nextoffset = self.unpack_from( '2I2HI', data) else: startcode, endcode, method, reserved, nextoffset = self.unpack_from( '4HI', data) if method == CMAP_DIRECT: indexoffset = self.unpack_from('H', data)[0] for code in range(startcode, endcode): self.glyphmap[chr(code)] = code - startcode + indexoffset elif method == CMAP_TABLE: for i, item in enumerate( self.unpack_from('%dH' % (endcode - startcode), data)): self.glyphmap[chr(i + startcode)] = item elif method == CMAP_SCAN: if self.version == 'NX': count, items = self.unpack_from('I/p1[IH2x]', data) else: count, items = self.unpack_from('H/p1[2H]', data) for code, offset in items: self.glyphmap[chr(code)] = offset if nextoffset > 0: self.readCMAP(data, nextoffset - 8)
def readpat1(self, ptr): data = self.unpack_from(pat1_SECTION, self.file, ptr) magic = data[0] if magic != b'pat1': error.InvalidMagicError('Invalid pat1 magic %s' % byterepr(magic)) seclen = data[1] order = data[2] seconds = data[3] firstoffset = data[4] secondsoffset = data[5] start = data[6] end = data[7] childbinding = data[8] #padding = data[9] first = self.unpack_from('n', self.file, ptr + firstoffset)[0].decode('ascii') groups = [] for i in range(seconds): groups.append( self.unpack_from('n', self.file, ptr + secondsoffset + i * 28)[0].decode('ascii')) self.root['pat1'] = OrderedDict() node = self.root['pat1'] node['order'] = order node['seconds-number'] = seconds node['start'] = start node['end'] = end node['child-binding'] = childbinding node['first-group'] = first node['seconds-group-names'] = groups
def read_header(self, data): magic = data.read(8) if magic != b'MsgStdBn': error.InvalidMagicError('Invalid magic %s, expected MsgStdBn' % byterepr(magic)) self.byteorder = ENDIANS[rawutil.unpack_from('>H', data)[0]] magic, bom, unk1, self.encoding, unk2, self.sectionnum, unk3, self.filesize, unk4 = self.unpack_from( '8s2H2B2HI10s', data, 0)
def read_ivfc_tree(self): header = self.unpack_from(IVFC_HEADER_STRUCT, self.data, self.base, IVFC_HEADER_NAMES) if header.magic != b'IVFC': error.InvalidMagicError('Invalid magic, %s, expected IVFC' % byterepr(header.magic)) #self.read_level3(*header.levels[2][:3]) self.read_level3(0x1000, *header.levels[2][1:3])
def readheader(self, data): hdata = self.unpack_from(CBMD_HEADER_STRUCT, data, 0) if hdata[0] != b'CBMD': error.InvalidMagicError('Invalid magic %s, expected CBMD' % byterepr(hdata[0])) self.commonoffset = hdata[2] self.regionoffsets = hdata[3] self.cwavoffset = hdata[5]
def readFATB(self): fatb = self.unpack_from(NARC_FATB_SECTION, self.file, None, NARC_FATB_NAMES) if fatb.magic != b'BTAF': error.InvalidMagicError('Invalid FATB magic: %s' % byterepr(fatb.magic)) self.entrycount = fatb.entrycount self.entries = fatb.entries
def read_header(self, data): self.byteorder = ENDIANS[rawutil.unpack_from(">H", data, 4)[0]] header = self.unpack_from("4s2H 2I2H SSS", data, 0, "magic, bom, headerlen, version, filesize, seccount, reserved, inforef, seekref, dataref") if header.magic != b"CSTM": error.InvalidMagicError("Invalid magic %s, expected CSTM" % byterepr(header.magic)) self.filesize = header.filesize self.inforef = SizedRef(header.inforef) self.seekref = SizedRef(header.seekref) self.dataref = SizedRef(header.dataref)
def readhdr(self, content): magic = ord(content.read(1)) if magic != 0x10: error.InvalidMagicError('Invalid magic 0x%02x, expected 0x10' % magic) self.decsize = self.unpack_from('<U', content, 1)[0] if self.decsize == 0: raise RuntimeError( 'INTERNAL. SHOULD BE CAUGHT (Recognition error)')
def readATR1(self, data, magic): magic, size, unknown = self.unpack_from('4sI8s', data) baseoffset = data.tell() if magic != b'ATR1': error.InvalidMagicError('Invalid ATR1 magic (%s)' % byterepr(magic)) self.strnum = self.unpack_from('I', data)[0] endpos = baseoffset + size endpos += 0x10 - (endpos % 0x10 or 0x10) data.seek(endpos)
def readSFAT(self, data, ptr): sfat, ptr = self.unpack_from(SFAT_STRUCT, data, ptr, getptr=True) magic = sfat[0] if magic != b'SFAT': error.InvalidMagicError('Invalid SFAT magic %s' % byterepr(magic)) #headerlen = sfat[1] self.node_count = sfat[2] self.hash_multiplier = sfat[3] self.nodes = [SFATnode(node) for node in sfat[4]] return ptr
def readINFX(self, data, start, size): data.seek(start) magic, size = self.unpack_from('4sI', data) if magic != b'INFX': error.InvalidMagicError('Invalid INFO magic (got %s)' % byterepr(magic)) baseoffset = data.tell() entrycount, table = self.unpack_from('I/p1[2HI]', data) for id, pad, offset in table: if id == 0x7901: # ??? values = self.unpack_from('2I', data, baseoffset + offset)
def readmeta(self, data): meta, ptr = self.unpack_from(ALYT_META_STRUCT, data, 0, getptr=True) if meta[0] != b'ALYT': error.InvalidMagicError('Invalid magic %s, expected ALYT' % byterepr(meta[0])) self.ltbl = meta[10] self.lmtl = meta[11] self.lfnl = meta[12] self.nametable = [el[0].decode('utf-8') for el in meta[14]] self.symtable = [el[0].decode('utf-8') for el in meta[16]] self.sarc = data.read()
def readDATA(self, data): magic, length = self.unpack_from('4sI', data, self.dataref.offset) if magic != b'DATA': error.InvalidMagicError('Invalid DATA magic (got %s)' % byterepr(magic)) if self.verbose: print('Extracting DATA') #TODO: Other codecs if self.codec == DSPADPCM: self.decodeDSPADPCM(data) self.extract_track(self.channels)
def readNLI1(self, data, magic): magic, size, unknown = self.unpack_from('4sI8s', data) baseoffset = data.tell() if magic != b'NLI1': error.InvalidMagicError('Invalid NLI1 magic (%s)' % byterepr(magic)) endpos = baseoffset + size endpos += 0x10 - (endpos % 0x10 or 0x10) data.seek(endpos) error.NotImplementedWarning( 'Support for section NLI1 is not implemented yet')
def read_header(self, input): self.input.seek(0) magic = ord(input.read(1)) if magic != 0x40: error.InvalidMagicError('Invalid magic 0x%02x, expected 0x40' % magic) self.decsize = self.unpack_from('U', input, 1)[0] if self.decsize == 0: self.decsize = self.unpack_from('I', input, 4)[0] if self.decsize == 0: #still raise RuntimeError( 'INTERNAL. SHOULD BE CAUGHT (Recognition error)')
def read_header(self, data): self.byteorder = ENDIANS[rawutil.unpack_from('>H', data, 4)[0]] header = self.unpack_from( '4s2H 2I2H SS', data, 0, 'magic, bom, headerlen, version, filesize, seccount, reserved, inforef, dataref' ) if header.magic != b'CWAV': error.InvalidMagicError('Invalid magic %s, expected CWAV' % byterepr(header.magic)) self.filesize = header.filesize self.inforef = SizedRef(header.inforef) self.dataref = SizedRef(header.dataref)
def readheader(self, data): magic, hdrlen, bom = rawutil.unpack_from('>4s2H', data, 0) if magic != b'SARC': error.InvalidMagicError('Invalid magic %s, expected SARC' % byterepr(magic)) self.byteorder = ENDIANS[bom] hdr, ptr = self.unpack_from(SARC_HEADER_STRUCT, data, 0, getptr=True) #magic = hdr[0] #headerlen = hdr[1] #bom = hdr[2] #filelen = hdr[3] self.dataoffset = hdr[4] #unknown = hdr[5] return ptr
def readFLIMheader(self, data): data.seek(-0x24, 2) self.byteorder = ENDIANS[rawutil.unpack_from('>H', data)[0]] data.seek(-0x28, 2) hdata = self.unpack_from(BFLIM_FLIM_HDR_STRUCT, data) if hdata[0] != b'FLIM': error.InvalidMagicError('Invalid magic %s, expected FLIM' % byterepr(hdata[0])) #bom = hdata[1] #headerlen = hdata[2] self.version = hdata[3] if self.verbose: print('Version: %08x' % self.version)
def readFATO(self, data, ptr): fato, ptr = self.unpack_from(GARC_FATO_SECTION, data, ptr, getptr=True) if fato[0] != b'OTAF': error.InvalidMagicError('Invalid FATO magic %s, expected OTAF' % byterepr(fato[0])) #sectionlen = fato[1] entrycount = fato[2] self.filenum = entrycount #padding = fato[3] table = fato[4] self.fato = [el[0] for el in table] if self.verbose: print('File count: %d' % entrycount) return ptr
def readheader(self): self.byteorder = ENDIANS[rawutil.unpack_from('>H', self.file, 4)[0]] header = self.unpack_from(FLAN_HEADER, self.file, 0) if header[0] != b'FLAN': error.InvalidMagicError('Invalid magic %s, expected FLAN' % byterepr(header[0])) #bom = header[1] headerlen = header[2] self.version = header[3] #unknown = header[4] self.filelen = header[5] self.seccount = header[6] #padding = header[7] return headerlen
def readheader(self, data): magic, bom = self.unpack_from('>4sH', data) if magic != b'FLAN': error.InvalidMagicError('Invalid magic %s, expected FLAN' % byterepr(magic)) node = self.makenode(self.output, 'FLAN') self.byteorder = ENDIANS[bom] headerlen, self.version, filesize, self.secnum, padding = self.unpack_from("H2I2H", data) node['byte order'] = self.byteorder node['version'] = self.version node['readable version'] = '%d.%d.%d.%d' % (self.version >> 24, (self.version >> 16) & 0xff, (self.version >> 8) & 0xFF, self.version & 0xFF) node['number of sections'] = self.secnum if self.verbose: print('Format version : %s' % node['readable version']) print('Number of sections : %d' % self.secnum)
def readFNTB(self): offset = self.file.tell() fntb = self.unpack_from(NARC_FNTB_SECTION, self.file, None, NARC_FNTB_NAMES) if fntb.magic != b'BTNF': error.InvalidMagicError('Invalid FNTB magic: %s' % byterepr(fntb.magic)) if fntb.sectionlen == 0x10: #No names... self.has_names = False else: self.has_names = True error.NotImplementedWarning( 'NARC with file names are not implemented yet. Continuing without them.' ) self.fimgoffset = offset + fntb.sectionlen
def readHeader(self, data): self.fileheader = rawutil.unpack_from(FILE_HEADER_STRUCT, data, names=FILE_HEADER_NAMES) if self.fileheader.magic_texture != b"texture\x00": error.InvalidMagicError("Invalid magic %s, expected texture\x00" % byterepr(self.fileheader.magic_texture)) self.outname = os.path.join( os.path.dirname(self.filename), self.fileheader.filename.decode("utf-8").rpartition(".")[0] + ".png") if self.verbose: print("Version : %08X" % self.fileheader.version) print("Origin file name : %s" % self.fileheader.filename.decode("utf-8"))