def createFields(self): # First kilobyte: boot sectors yield RawBytes(self, "boot", 1024, "Space for disklabel etc.") # Header yield UInt32(self, "version") yield UInt32(self, "last_page") yield UInt32(self, "nb_badpage") yield UUID(self, "sws_uuid") yield UUID(self, "sws_volume") yield NullBytes(self, "reserved", 117 * 4) # Read bad pages (if any) count = self["nb_badpage"].value if count: if MAX_SWAP_BADPAGES < count: raise ParserError("Invalid number of bad page (%u)" % count) yield GenericVector(self, "badpages", count, UInt32, "badpage") # Read magic padding = self.seekByte(PAGE_SIZE - 10, "padding", null=True) if padding: yield padding yield String(self, "magic", 10, charset="ASCII") # Read all pages yield GenericVector(self, "pages", self["last_page"].value, Page, "page") # Padding at the end padding = self.seekBit(self.size, "end_padding", null=True) if padding: yield padding
def createFields(self): yield String(self, "name", 20, strip='\0') yield GenericVector(self, "samples", 31, SampleInfo, "info") yield UInt8(self, "length") yield UInt8(self, "played_patterns_count") yield GenericVector(self, "patterns", 128, UInt8, "position") yield String(self, "type", 4)
def createFields(self): yield String(self, "signature", 17, "XM signature", charset="ASCII") yield String(self, "title", 20, "XM title", charset="ASCII", strip=' ') yield UInt8(self, "marker", "Marker (0x1A)") yield String(self, "tracker_name", 20, "XM tracker name", charset="ASCII", strip=' ') yield UInt8(self, "format_minor") yield UInt8(self, "format_major") yield filesizeHandler(UInt32(self, "header_size", "Header size (276)")) yield UInt16(self, "song_length", "Length in patten order table") yield UInt16(self, "restart", "Restart position") yield UInt16(self, "channels", "Number of channels (2,4,6,8,10,...,32)") yield UInt16(self, "patterns", "Number of patterns (max 256)") yield UInt16(self, "instruments", "Number of instruments (max 128)") yield Bit(self, "amiga_ftable", "Amiga frequency table") yield Bit(self, "linear_ftable", "Linear frequency table") yield Bits(self, "unused", 14) yield UInt16(self, "tempo", "Default tempo") yield UInt16(self, "bpm", "Default BPM") yield GenericVector(self, "pattern_order", 256, UInt8, "order")
def createFields(self): yield PDFNumber(self, "start_number", "Object number of first entry in subsection") self.info("start_number = %i" % self["start_number"].value) yield PDFNumber(self, "entry_count", "Number of entries in subsection") self.info("entry_count = %i" % self["entry_count"].value) yield LineEnd(self, "line_end") yield GenericVector(self, "entries", int(self["entry_count"].value), Entry)
def getHeaderEndFields(self): instr = self["num_instruments"].value patterns = self["num_patterns"].value # File pointers if instr > 0: yield GenericVector(self, "instr_pptr", instr, UInt16, "offset") if patterns > 0: yield GenericVector(self, "pattern_pptr", patterns, UInt16, "offset") # S3M 3.20 extension if self["creation_version_major"].value >= 3 \ and self["creation_version_minor"].value >= 0x20 \ and self["panning_info"].value == 252: yield GenericVector(self, "channel_panning", 32, ChannelPanning, "channel") # Padding required for 16B alignment size = self._size - self.current_size if size > 0: yield PaddingBytes(self, "padding", size // 8)
def createUnpaddedFields(self): yield String(self, "title", 28, strip='\0') yield textHandler(UInt8(self, "marker[]"), hexadecimal) yield from self.getFileVersionField() yield UInt16(self, "num_orders") yield UInt16(self, "num_instruments") yield UInt16(self, "num_patterns") yield from self.getFirstProperties() yield String(self, "marker[]", 4) yield from self.getLastProperties() yield GenericVector(self, "channel_settings", 32, ChannelSettings, "channel") # Orders yield GenericVector(self, "orders", self.getNumOrders(), UInt8, "order") yield from self.getHeaderEndFields()
def createFields(self): yield UInt32(self, "sample_header_size") yield GenericVector(self, "notes", 96, UInt8, "sample") yield GenericVector(self, "volume_envelope", 24, UInt16, "point") yield GenericVector(self, "panning_envelope", 24, UInt16, "point") yield UInt8(self, "volume_points", r"Number of volume points") yield UInt8(self, "panning_points", r"Number of panning points") yield UInt8(self, "volume_sustain_point") yield UInt8(self, "volume_loop_start_point") yield UInt8(self, "volume_loop_end_point") yield UInt8(self, "panning_sustain_point") yield UInt8(self, "panning_loop_start_point") yield UInt8(self, "panning_loop_end_point") yield StuffType(self, "volume_type") yield StuffType(self, "panning_type") yield UInt8(self, "vibrato_type") yield UInt8(self, "vibrato_sweep") yield UInt8(self, "vibrato_depth") yield UInt8(self, "vibrato_rate") yield UInt16(self, "volume_fadeout") yield GenericVector(self, "reserved", 11, UInt16, "word")
def createFields(self): yield textHandler(UInt32(self, "plugin_id1"), hexadecimal) yield textHandler(UInt32(self, "plugin_id2"), hexadecimal) yield UInt32(self, "input_routing") yield UInt32(self, "output_routing") yield GenericVector(self, "routing_info", 4, UInt32, "reserved") yield String(self, "name", 32, strip='\0') yield String(self, "dll_name", 64, desc="Original DLL name", strip='\0')
def createFields(self): yield UInt32(self, "num_chars") yield UInt32(self, "raw_font_data_size") yield UInt32(self, "max_char_width") yield UInt32(self, "min_char_width") yield UInt32(self, "unknown[]", 4) yield UInt32(self, "unknown[]", 4) yield UInt32(self, "first_char_code") yield UInt32(self, "last_char_code") yield GenericVector(self, "char_codes", self["num_chars"].value, UInt16, "char") yield GenericVector(self, "chars", self["num_chars"].value, CharInfo, "char") # character data. we make an effort to provide # something more meaningful than "RawBytes: # character bitmap data" yield CharData(self["chars"], self, "char_data") # read to the end if self.current_size < self._size: yield self.seekBit(self._size, "unknown[]")
def createFields(self): # Identify tag code = self.stream.readBytes(self.absolute_address, 4) if code in self.ext: cls, count, comment = self.ext[code] else: cls, count, comment = RawBytes, 1, "Unknown tag" # Header yield String(self, "code", 4, comment) yield UInt16(self, "data_size") # Data if not cls: size = self["data_size"].value if size > 0: yield RawBytes(self, "data", size) elif cls in (String, RawBytes): yield cls(self, "value", count) else: if count > 1: yield GenericVector(self, "values", count, cls, "item") else: yield cls(self, "value")
def parseEQBands(parser): size = parser["block_size"].value // 4 if size > 0: yield GenericVector(parser, "gains", size, UInt32, "band")
def createFields(self): width = self.char["width_pixels"].value for line in range(self.char["height_pixels"].value): yield GenericVector(self, "line[]", width, UInt8, "pixel")
def createFields(self): for i in range(self.height): yield GenericVector(self, self.row_name + "[]", self.width, self.item_class, self.item_name)
def createFields(self): yield String(self, "magic", 4, "Signature (BLP2)") yield Enum(UInt32(self, "compression", "Compression type"), { 0: "JPEG Compressed", 1: "Uncompressed or DXT/S3TC compressed" }) yield Enum(UInt8(self, "encoding", "Encoding type"), { 1: "Raw", 2: "DXT/S3TC Texture Compression (a.k.a. DirectX)" }) yield UInt8(self, "alpha_depth", "Alpha channel depth, in bits (0 = no alpha)") yield Enum( UInt8(self, "alpha_encoding", "Encoding used for alpha channel"), { 0: "DXT1 alpha (0 or 1 bit alpha)", 1: "DXT3 alpha (4 bit alpha)", 7: "DXT5 alpha (8 bit interpolated alpha)" }) yield Enum( UInt8(self, "has_mips", "Are mip levels present?"), { 0: "No mip levels", 1: "Mip levels present; number of levels determined by image size" }) yield UInt32(self, "width", "Base image width") yield UInt32(self, "height", "Base image height") for i in range(16): yield UInt32(self, "mipmap_offset[]") for i in range(16): yield UInt32(self, "mipmap_size[]") yield PaletteRGBA(self, "palette", 256) compression = self["compression"].value encoding = self["encoding"].value alpha_depth = self["alpha_depth"].value alpha_encoding = self["alpha_encoding"].value width = self["width"].value height = self["height"].value if compression == 0: # JPEG Compression yield UInt32(self, "jpeg_header_len") yield RawBytes(self, "jpeg_header", self["jpeg_header_len"].value, "Shared JPEG Header") offsets = self.array("mipmap_offset") sizes = self.array("mipmap_size") for i in range(16): if not offsets[i].value or not sizes[i].value: continue padding = self.seekByte(offsets[i].value) if padding: yield padding if compression == 0: yield RawBytes( self, "mipmap[%i]" % i, sizes[i].value, "JPEG data, append to header to recover complete image") elif compression == 1 and encoding == 1: yield Generic2DArray(self, "mipmap_indexes[%i]" % i, height, width, PaletteIndex, "row", "index", "Indexes into the palette") if alpha_depth == 1: yield GenericVector(self, "mipmap_alphas[%i]" % i, height, width, Bit, "row", "is_opaque", "Alpha values") elif alpha_depth == 8: yield GenericVector(self, "mipmap_alphas[%i]" % i, height, width, UInt8, "row", "alpha", "Alpha values") elif compression == 1 and encoding == 2: block_height = alignValue(height, 4) // 4 block_width = alignValue(width, 4) // 4 if alpha_depth in [0, 1] and alpha_encoding == 0: yield Generic2DArray(self, "mipmap[%i]" % i, block_height, block_width, DXT1, "row", "block", "DXT1-compressed image blocks") elif alpha_depth == 8 and alpha_encoding == 1: yield Generic2DArray(self, "mipmap[%i]" % i, block_height, block_width, DXT3, "row", "block", "DXT3-compressed image blocks") elif alpha_depth == 8 and alpha_encoding == 7: yield Generic2DArray(self, "mipmap[%i]" % i, block_height, block_width, DXT5, "row", "block", "DXT5-compressed image blocks") width /= 2 height /= 2
def getHeaderEndFields(self): yield GenericVector(self, "pattern_pptr", 128, UInt16, "offset")
def createFields(self): yield textHandler(Bits(self, "blockheader", 48, "Block header"), hexadecimal) if self["blockheader"].value != 0x314159265359: # pi raise ParserError("Invalid block header!") yield textHandler(UInt32(self, "crc32", "CRC32 for this block"), hexadecimal) yield Bit(self, "randomized", "Is this block randomized?") yield Bits(self, "orig_bwt_pointer", 24, "Starting pointer into BWT after untransform") yield GenericVector( self, "huffman_used_map", 16, Bit, 'block_used', "Bitmap showing which blocks (representing 16 literals each) are in use" ) symbols_used = [] for index, block_used in enumerate( self["huffman_used_map"].array('block_used')): if block_used.value: start_index = index * 16 field = Bzip2Bitmap( self, "huffman_used_bitmap[%i]" % index, 16, start_index, "Bitmap for block %i (literals %i to %i) showing which symbols are in use" % (index, start_index, start_index + 15)) yield field for i, used in enumerate(field): if used.value: symbols_used.append(start_index + i) yield Bits(self, "huffman_groups", 3, "Number of different Huffman tables in use") yield Bits(self, "selectors_used", 15, "Number of times the Huffman tables are switched") yield Bzip2Selectors(self, "selectors_list", self["huffman_groups"].value) trees = [] for group in range(self["huffman_groups"].value): field = Bzip2Lengths(self, "huffman_lengths[]", len(symbols_used) + 2) yield field trees.append(field.tree) counter = 0 rle_run = 0 selector_tree = None while True: if counter % 50 == 0: select_id = self["selectors_list"].array("selector_list")[ counter // 50].realvalue selector_tree = trees[select_id] field = HuffmanCode(self, "huffman_code[]", selector_tree) if field.realvalue in [0, 1]: # RLE codes if rle_run == 0: rle_power = 1 rle_run += (field.realvalue + 1) * rle_power rle_power <<= 1 field._description = "RLE Run Code %i (for %r); Total accumulated run %i (Huffman Code %i)" % ( field.realvalue, chr( symbols_used[0]), rle_run, field.value) elif field.realvalue == len(symbols_used) + 1: field._description = "Block Terminator (%i) (Huffman Code %i)" % ( field.realvalue, field.value) yield field break else: rle_run = 0 move_to_front(symbols_used, field.realvalue - 1) field._description = "Literal %r (value %i) (Huffman Code %i)" % ( chr(symbols_used[0]), field.realvalue, field.value) yield field if field.realvalue == len(symbols_used) + 1: break counter += 1
def parseChannelSettings(parser): size = parser["block_size"].value // 4 if size > 0: yield GenericVector(parser, "settings", size, UInt32, "mix_plugin")