コード例 #1
0
ファイル: txa.py プロジェクト: 07th-mod/enter_extractor
def convert_txa(filename, out_dir):
    data = ConstBitStream(filename=filename)

    out_template = os.path.join(
        out_dir,
        os.path.splitext(os.path.basename(filename))[0])
    try:
        os.makedirs(out_template)
    except:
        pass

    magic = data.read("bytes:4")
    size = data.read("uintle:32")
    indexed = data.read("uintle:32")
    chunks = data.read("uintle:32")
    dec_size = data.read("uintle:32")
    unk2 = data.read("uintle:32")
    unk3 = data.read("uintle:32")
    unk4 = data.read("uintle:32")

    print(size, chunks, indexed)

    for i in range(chunks):
        hdr_len = data.read("uintle:16")
        index = data.read("uintle:16")
        w = data.read("uintle:16")
        h = data.read("uintle:16")
        entry_off = data.read("uintle:32")
        entry_len = data.read("uintle:32")
        name = data.read("bytes:%d" % (hdr_len - 16)).strip("\0")

        print(name, index, w, h, entry_off, entry_len)

        temp_pos = data.bytepos
        data.bytepos = entry_off

        # If we are zero size, we're not compressed.
        if entry_len == 0:
            if indexed:
                size = 1024 + (w * h)
                chunk = bytearray(data.read(size * 8).bytes)
            else:
                print("???")

        else:
            chunk = data.read(entry_len * 8)
            chunk = decompress(chunk)

        data.bytepos = temp_pos

        w = adjust_w(w)
        if indexed:
            chunk, masked = get_indexed(chunk, w, h, crop=False)
        else:
            chunk = get_rgba(chunk, w, h, crop=False)
        chunk.save("%s/%s.png" % (out_template, name))
        # dump_to_file(chunk, "temp%d.dat" % index)


################################################################################
コード例 #2
0
def convert_pic_umi(filename, out_file):
    data = ConstBitStream(filename=filename)

    magic = data.read("bytes:4")
    size = data.read("uintle:32")
    ew = data.read("uintle:16")
    eh = data.read("uintle:16")
    width = data.read("uintle:16")
    height = data.read("uintle:16")

    unk1 = data.read("uintle:32")
    chunks = data.read("uintle:32")

    image = QImage(width, height, QImage.Format_ARGB32)
    image.fill(0)
    painter = QPainter(image)

    for i in range(chunks):
        version = data.read("uintle:32")
        x = data.read("uintle:16")
        y = data.read("uintle:16")
        w = data.read("uintle:16")
        h = data.read("uintle:16")

        offset = data.read("uintle:32")
        size = data.read("uintle:32")

        # if not i == 1:
        # continue

        print w, h, size, offset

        temp_pos = data.bytepos
        data.bytepos = offset
        chunk = data.read(size * 8)
        data.bytepos = temp_pos

        chunk = decompress_umi(chunk)
        chunk = adjust_scanline(chunk, w, h)
        dump_to_file(chunk)
        chunk = QImage(chunk, w, h, QImage.Format_ARGB32)
        chunk.fill(0)
        # chunk.save("test.bmp")
        painter.drawImage(QRectF(x, y, w, h), chunk, QRectF((chunk.rect())))
        # break

    painter.end()
    image.save(out_file)


################################################################################
コード例 #3
0
    def png_to_gim(self,
                   png_file,
                   gim_file=None,
                   quant_type=QuantizeType.auto):
        # So there's no confusion.
        png_file = os.path.abspath(png_file)

        if gim_file == None:
            gim_file = os.path.splitext(png_file)[0] + ".gim"

        png_file = self.quantize_png(png_file, quant_type)

        data = ConstBitStream(filename=png_file)
        data.bytepos = 0x18

        options = ["-jar", "tools/gimexport.jar", png_file, gim_file, "3"]

        depth = data.read("int:8")
        color_type = data.read("int:8")

        if color_type == 3:  # Indexed
            options.append("true")
        else:
            options.append("false")

        self.process.start("java", options)
        self.process.waitForFinished(-1)
コード例 #4
0
 def extractXMP(self, filename):
     xmpStr = ""        
     # Can initialise from files, bytes, etc.
     try:
         s = ConstBitStream(filename = filename)
         # Search for ":xmpmeta" string in file
         keepSearching = True
         while keepSearching:
             keepSearching = False
             colonXmpmetaInHexStr = '0x3a786d706d657461'
             foundSt = s.find(colonXmpmetaInHexStr, bytealigned=True)
             if foundSt:
                 byteStart = (int(foundSt[0])//8)
                 # The start of data can be "<xmp:xmpmeta" or "<x:xmpmeta"
                 s.bytepos = byteStart - 4
                 prevals = s.peeklist("4*uint:8")
                 prestr = ''.join(chr(i) for i in prevals)
     #            print (prestr, prestr[2:])
                 if prestr == "<xmp":
                     byteStart = byteStart - 4
                     prefix = "0x3c2f786d70"  # "<\xmp" in hex
                 elif prestr[2:] == "<x":
                     byteStart = byteStart - 2
                     prefix = "0x3c2f78"  # "<\x" in hex
                 else:
     #                print ("Cont")
                     keepSearching = True
                     continue
     #            print("Found start code at byte offset %d." % byteStart)
                 foundEnd = s.find(prefix + colonXmpmetaInHexStr, bytealigned=True)
                 if foundEnd:
                     byteEnd = (int(foundEnd[0])//8)
                     s.bytepos = byteStart
     #                print("Found end code at byte offset %d." % byteEnd)
                     xmpBytes = s.readlist(str(byteEnd-byteStart+len(prefix)//2+9) +"*uint:8")
                     xmpStr = ''.join(chr(i) for i in xmpBytes)
                     #if "Rating" in xmpStr:
     #                print (xmpStr)
     except:
         xmpStr = ""
     return xmpStr
コード例 #5
0
def parseRootPage(fpt, pageSize):
    """
    parse necessary information about the database file and
    return a dictionary of table/index names and its corresponding root page

        @param fpt: the file pointer of the database file
        @param pageSize: the page size of the database
    """
    # read in the whole root page into memory
    bitstream = ConstBitStream(readPage(1, fpt, pageSize))
    readCounts(-1)

    numPages = bitstreamReadAtOffset(bitstream, int, 'bytes:4', 28)
    # skip th db header and thus locate btree page header from the beginning
    bitstream.bytepos = DATABASE_FILE_HEADER_SIZE

    # get the type of page from offset relative to DATABASE_FILE_HEADER_SIZE and read one byte only; reset back to offset DATABASE_FILE_HEADER_SIZE
    pageFlag = bitstreamReadAtOffset(bitstream, int, 'bytes:1',
                                     DATABASE_FILE_HEADER_SIZE)
    # read number of cells inside the rootpage at offset 3 relative to the begining of page header and read two bytes; reset back to offset DATABASE_FILE_HEADER_SIZE
    numTables = bitstreamReadAtOffset(bitstream, int, 'bytes:2',
                                      DATABASE_FILE_HEADER_SIZE + 3)
    tables = {}

    # jump to the cell pointer array relative to offset DATABASE_FILE_HEADER_SIZE
    for i in range(0, numTables):
        # read two bytes at a time as a pointer from the cell pointer array relative to the beginning of the array; reset back to the beginning of cell pointer array each iteration
        cellPosition = bitstreamReadAtOffset(
            bitstream, int, 'bytes:2',
            LEAF_BTREE_PAGE_HEADER_SIZE + DATABASE_FILE_HEADER_SIZE + i * 2)

        # goes to the sqlite master table and find out the root page number; sqlite_master table is a table btree page
        _, record = parse_cell_content(cellPosition,
                                       bitstream,
                                       pageFlag,
                                       fpt,
                                       pageSize,
                                       isSqliteMaster=True)

        # store the table/index name and its root page
        tables.setdefault(record[1], record[-2])

    # return the root page num
    return tables
コード例 #6
0
    def png_to_gim(self, png_file, gim_file=None, quant_type=QuantizeType.auto):
        # So there's no confusion.
        png_file = os.path.abspath(png_file)

        if gim_file == None:
            gim_file = os.path.splitext(png_file)[0] + ".gim"

        png_file = self.quantize_png(png_file, quant_type)

        data = ConstBitStream(filename=png_file)
        data.bytepos = 0x18

        options = ["-jar", "tools/gimexport.jar", png_file, gim_file, "3"]

        depth = data.read("int:8")
        color_type = data.read("int:8")

        if color_type == 3:  # Indexed
            options.append("true")
        else:
            options.append("false")

        self.process.start("java", options)
        self.process.waitForFinished(-1)
コード例 #7
0
ファイル: bup.py プロジェクト: 07th-mod/enter_extractor
def convert_bup(filename, out_dir):
    #For some reason saving the path to a non-existant directory doesn't give an error!
    #for this reason, force creation of the output directory before converting.
    pathlib.Path(out_dir).mkdir(parents=True, exist_ok=True)

    filesize = None
    with open(filename, 'rb') as f:
        test = f.read()
        filesize = len(test)
        print("File is of size: ", filesize)

    rc = RegionChecker(filesize)

    data = ConstBitStream(filename=filename)

    out_template = os.path.join(
        out_dir,
        os.path.splitext(os.path.basename(filename))[0])

    bytePosStart = data.bytepos

    magic = data.read("bytes:4")

    if conf.SWITCH:
        unk_header_1 = data.read("uintle:32")

    size = data.read("uintle:32")
    ew = data.read("uintle:16")
    eh = data.read("uintle:16")
    width = data.read("uintle:16")
    height = data.read("uintle:16")

    tbl1 = data.read("uintle:32")

    base_chunks = data.read("uintle:32")  #num expressions in switch version
    exp_chunks = data.read("uintle:32")  #unnknown on switch version

    if conf.SWITCH:
        unk_header_2 = data.read("uintle:32")  #unknown in switch version

    rc.add(bytePosStart, data.bytepos)

    if conf.debug:
        print('---------- BUP HEADER -----------')
        print("magic:     ", magic)
        if conf.SWITCH:
            print("unk1:      ", unk_header_1)
        print("size:      ", size)
        print("EW, EH:    ", ew, eh)
        print("Width:     ", width)
        print("Height:    ", height)
        print("tbl1:      ", tbl1)
        print("basechunks:", base_chunks)
        print("exp_chunks:", exp_chunks)
        print("Section ends at {}{}".format(hex(base_chunks), hex(exp_chunks)))
        if conf.SWITCH:
            print("Unk2:      ", unk_header_2)
        print()

    if conf.SWITCH:
        skip_amount = 32 * 3
    else:
        skip_amount = 32

    # Dunno what this is for.
    print("Skipping {} bits in the tbl1 header".format(tbl1 * skip_amount))
    bytePosStart = data.bytepos
    for i in range(tbl1):
        print(data.read(skip_amount))
    rc.add(bytePosStart, data.bytepos)

    base = QImage(width, height, QImage.Format_ARGB32)

    # See Documentation - this is used to differentiate between a pixel which has
    # never been written to and a fully transparent pixel
    base.fill(TRANSPARENT_COLOR)

    for i in range(base_chunks):
        try:
            print('--------- Decoding Base Chunk [{}]----------'.format(i))
            offset = data.read("uintle:32")
            print("Testing offset", offset)

            if conf.SWITCH:
                bothChunkSize = data.read("uintle:32")
                print("bothChunkSize", bothChunkSize)

            rc.add(offset, offset + bothChunkSize - 1)

            temp_pos = data.bytepos
            chunk, x, y, masked = process_chunk(data, offset, bothChunkSize)
            if conf.debug_extra:
                chunk.save("%s_%d_Base_Chunk_%s.png" %
                           (out_template, i, str(masked)))

            if conf.SWITCH:
                base = blit_switch(chunk, base, x, y, masked, False)
            else:
                base = blit(chunk, base, x, y, masked)

        except Exception as e:
            print("FAILED:")
            data.bytepos = temp_pos
            print(e)

    # Save the base sprite (the full sprite minus the eyes/mouth usually)
    if conf.debug:
        base.save("%s_BASE.png" % (out_template))

    #seems to be a padding of 3 * 4 = 12 bytes before the start of the expression section
    bytePosStart = data.bytepos
    if conf.SWITCH:
        skip_amount = 32 * 3
        # Dunno what this is for.
        print("Skipping {} bytes before the expression header".format(
            skip_amount / 8))
        print(data.read(skip_amount))

    rc.add(bytePosStart, data.bytepos)

    for i in range(exp_chunks):
        print('--------- Decoding Expression Chunk [{}]----------'.format(i))
        bytePosStart = data.bytepos

        # Name of the expression, like "Def1", "Ikari2"
        if conf.SWITCH:
            name_bytes = data.read("bytes:20")
        else:
            name_bytes = data.read("bytes:16")

        # Name is encoded using CP932 encoding
        name = name_bytes.strip(b'\0').decode("CP932")

        face_off = data.read("uintle:32")

        if conf.SWITCH:
            face_size = data.read("uintle:32")

        if conf.SWITCH:
            #there appear to be 24 zero bytes here always...not sure if i'm correct on this
            zero_bytes = data.read("bytes:24")
            for b in zero_bytes:
                if b != 0:
                    print(
                        "WARNING: Non-zero byte found in probably 24 zero padding bytes in character expression header"
                    )
            print("Zero padding bytes: ", zero_bytes)
        else:
            unk1 = data.read("uintle:32")
            unk2 = data.read("uintle:32")
            unk3 = data.read("uintle:32")

        mouth1_off = data.read("uintle:32")
        if conf.SWITCH:
            mouth1_size = data.read("uintle:32")

        mouth2_off = data.read("uintle:32")
        if conf.SWITCH:
            mouth2_size = data.read("uintle:32")

        mouth3_off = data.read("uintle:32")
        if conf.SWITCH:
            mouth3_size = data.read("uintle:32")

        rc.add(bytePosStart, data.bytepos)

        print('---------- Expression HEADER -----------')
        print("name:     [{}]".format(name))
        print("face_off:      ", face_off)
        print("face_size: ", face_size)

        if conf.SWITCH:
            print("mouth1_size: ", mouth1_size)
            print("mouth2_size: ", mouth2_size)
            print("mouth3_size: ", mouth3_size)
        else:
            print("unk1: ", unk1)
            print("unk2: ", unk2)
            print("unk3: ", unk3)

        print("mouth1_off:", mouth1_off)
        print("mouth2_off:", mouth2_off)
        print("mouth3_off:", mouth3_off)
        print()

        if not face_off:
            png_save_path = "%s_%s.png" % (out_template, name)
            print("saved to {}".format(png_save_path))
            base.save(png_save_path)
            # base.save("%s.png" % (out_template))
            # return
            continue

        rc.add(face_off, face_off + face_size - 1)
        rc.add(mouth1_off, mouth1_off + mouth1_size - 1)
        rc.add(mouth2_off, mouth2_off + mouth2_size - 1)
        rc.add(mouth3_off, mouth3_off + mouth3_size - 1)
        face, x, y, masked = process_chunk(
            data, face_off, forceColorTable0ToBlackTransparent=True)
        if conf.debug:
            png_save_path = "%s_%s_FACE_%s.png" % (out_template, name,
                                                   str(masked))
            print("saved to {}".format(png_save_path))
            face.save(png_save_path)

        if conf.SWITCH:
            exp_base = blit_switch(face, base, x, y, masked, True)
        else:
            exp_base = blit(face, base, x, y, masked)

        for j, mouth_off in enumerate([mouth1_off, mouth2_off, mouth3_off]):
            if not mouth_off:
                continue

            mouth, x, y, masked = process_chunk(
                data, mouth_off, forceColorTable0ToBlackTransparent=True)

            print("masked {}".format(masked))

            if not mouth:
                continue
            if conf.SWITCH:
                exp = blit_switch(mouth, exp_base, x, y, masked, True)
            else:
                exp = blit(mouth, exp_base, x, y, masked)

            if conf.apply_post_filtering:
                fill_all(exp)

            png_save_path = "%s_%s_%d.png" % (out_template, name, j)
            print("saved exp to {}".format(png_save_path))
            exp.save(png_save_path)

            if conf.debug:
                png_save_path = "%s_%s_%d_MOUTH_%s.png" % (out_template, name,
                                                           j, str(masked))
                print("saved to {}".format(png_save_path))
                mouth.save(png_save_path)

    rc.get_regions()
コード例 #8
0
    def load(self, filename):
        filename = filename.lower()

        if not filename in MTB_DIR:
            _LOGGER.error("Invalid MTB file: %s" % filename)
            return

        self.filename = filename

        script_dir = MTB_DIR[filename]
        self.script_pack = ScriptPack(script_dir,
                                      common.editor_config.umdimage_dir)

        # --- MTB FORMAT ---
        # 12 bytes     -- ???
        # XX XX XX XX  -- Table offset
        # 24 bytes     -- ???
        #
        # XX XX        -- MTB Index
        # XX XX        -- Char ID for sprites
        # XX XX        -- Char ID for voices (chapter for voices is 0x63)
        # XX XX        -- Initial sprite ID (?)

        mtb = ConstBitStream(filename=os.path.join(
            common.editor_config.umdimage_dir, self.filename))

        mtb.read(12 * 8)
        table_offset = mtb.read("uintle:32")
        mtb.read(24 * 8)

        mtb_index = mtb.read("uintle:16")
        sprite_char = mtb.read("uintle:16")
        voice_char = mtb.read("uintle:16")
        sprite_id = mtb.read("uintle:16")

        sprite = SpriteId(SPRITE_TYPE.stand, sprite_char, sprite_id)

        # --- TABLE FORMAT ---
        # XX XX XX XX -- Number of files
        #
        # [for each line]
        # XX XX XX XX -- Offset (from table start) of voice info.
        #
        # -- Voice Info --
        # XX XX -- File ID
        # XX XX -- Voice ID (with char ID above and the chapter ID 0x63, we know which voice file to use)

        mtb.bytepos = table_offset
        num_files = mtb.read("uintle:32")

        for i in range(num_files):
            voice_offset = mtb.read("uintle:32")

            # Store our position in the table so we can jump back to it.
            table_pos = mtb.bytepos
            mtb.bytepos = table_offset + voice_offset

            file_id = mtb.read("uintle:16")
            voice_id = mtb.read("uintle:16")

            # Chapter is 0x63, which is where the non-Trial voice samples are stored,
            # but I don't see the information actually recorded in the MTB files,
            # so I'm magic-numbering it here.
            voice = VoiceId(voice_char, 0x63, voice_id)

            self.script_pack[file_id].scene_info.sprite = sprite
            self.script_pack[file_id].scene_info.voice = voice

            # Restore it to our old position.
            mtb.bytepos = table_pos
コード例 #9
0
    print("Found movi signature at byte offset %X" % moviOffset)
else:
    print "Signature movi not found"
print ("Current bytepos %X" % s.bytepos)
foundIdx1Offset = s.find('0x69647831', bytealigned=True)
if foundIdx1Offset:
    idx1Offset = foundIdx1Offset[0] / 8
    print("Found idx1 signature at byte offset %X" % idx1Offset)
else:
    print "Signature idx1 not found"
print ("Current bytepos %X" % s.bytepos)
found01dcOffset = s.findall('0x30316463', bytealigned=True)
for i in found01dcOffset:
    i = (i /8) + 8
    print("%X" % i)
    s.bytepos = i
    print s.bytepos
    timeStamp = s.read(64).bin
    print timeStamp

    print ("Time is %d" % timeStamp)
    # print filetime_to_dt(timeStamp)
    # s.bytepos = i + 4
    # print s.bytepos
    # timelow = s.read(32).Q
    # t = float(timehigh)*2**32 + timelow
    # print (t*1e-7 - 11644473600)
# try:
#     while True:
#         found01dbOffset2 = s.readto('0x30316462')
#         _01dbOffsetList.append((s.bytepos))
コード例 #10
0
    trak.parse_boxes(bstr, recursive=False)

    mdia = None

    for trak_subbox in trak.boxes:
        if trak_subbox.header.type == b"mdia":
            mdia = trak_subbox
        else:
            if isinstance(trak_subbox, bx_def.ContainerBox):
                trak_subbox.parse_boxes(bstr)
            trak_subbox.load(bstr)

    # MOOV.TRAK.MDIA
    mdia_boxes_end = mdia.header.start_pos + mdia.header.box_size
    bstr.bytepos = mdia.boxes_start_pos

    for box_header in Parser.parse(bstr, headers_only=True):
        if bstr.bytepos >= mdia_boxes_end:
            break

        if box_header.type != b"hdlr":
            box = Parser.parse_box(bstr, box_header)
            box.load(bstr)

        else:
            # hdlr.name should finish with a b'\0'. If it doesn't, add one
            # Add a b'\0' for safety
            hdlr_bstr = BitStream(bytes(box_header))
            hdlr_header = Parser.parse_header(hdlr_bstr)
            hdlr_header.box_size += 1