Esempio n. 1
0
def test_roundtrip():
    #assert False
    with open("lzss3.py", "rb") as f:
        indata = f.read()
    out = BytesIO()
    compress(indata, out)
    compressed_data = out.getvalue()
    assert len(compressed_data) < len(indata)

    decompressed_data = decompress(out.getvalue())
    assert indata == decompressed_data


    #same as above, but with lz11
    out = BytesIO()
    compress_nlz11(indata, out)
    compressed_data = out.getvalue()
    assert len(compressed_data) < len(indata)

    decompressed_data = decompress(out.getvalue())
    assert indata == decompressed_data
Esempio n. 2
0
def explore_2(data_section, out_dir):
    screen_meta_raw, screen_data = parse_section_data(data_section)
    screen_meta = parse_screen_meta(screen_meta_raw)
    data = BytesIO(screen_data)
    with open(out_dir + '/meta.txt', 'w') as meta_fd:
        for n, entry in enumerate(screen_meta):
            data.seek(entry.offset)
            if entry.flag2:
                chunk = decompress(data)
            else:
                chunk = data.read(entry.length)
            with open(out_dir + '/s2_{:04}.bin'.format(n), 'wb') as data_fd:
                data_fd.write(chunk)
            print('{0:04} 0x{1.offset:06x} {1.flag1:d} 0x{2:06x} {1.flag2:d}'.
                  format(n, entry, len(chunk)),
                  file=meta_fd)
Esempio n. 3
0
def main():

    parser = argparse.ArgumentParser()
    parser.add_argument("script_file", help="Target *.xml.lz file")
    # parser.add_argument("-a", "--annotate", action="store_true",
    #                     help="Replace ")
    args = parser.parse_args()

    with open(args.script_file, 'rb') as text_file:
        data = decompress(text_file)

    data = BytesIO(data)

    assert data.read(4) == b'1LMG'

    # Seek to and read message pointers
    data.seek(8)
    pointers_offset, = unpack('<H', data.read(2))
    data.seek(pointers_offset + 0x34)

    assert data.read(4) == b'\x2a\x00\x00\x00'  # Not sure of the significance

    message_count, = unpack('<L', data.read(4))
    messages = []
    Message = namedtuple('Message', ['label_offset', 'message_pointer'])

    for m in range(message_count):
        messages.append(Message(*unpack('<LL', data.read(8))))

    labels_pointer = data.tell()  # XXX Can I actually *find* this anywhere?

    for message in messages:
        # Find the label and print it as a header
        label = get_label(data, labels_pointer + message.label_offset)

        print(label)
        print('=' * len(label))

        # Extract the actual message
        message = message_iterator(data, message.message_pointer)
        message = decode_message(message)

        print(message, end='\n\n')
Esempio n. 4
0
def explore_compressed_sections(data_section, skip, file_size, out_dir):
    BYTE_ALIGNMENT = 4
    last_offset = 0

    offset = 0
    with open(out_dir + '/meta.txt', 'w') as meta_fd:
        while offset < file_size:
            #while offset < 0x0104d8:
            try:
                chunk = decompress(data_section)
                size = len(chunk)
                offset_str = r'0x{0:06x}'.format(offset)
                with open(out_dir + '/' + offset_str + '.bin', 'wb') as output:
                    output.write(chunk)
                print(offset_str + r': 0x{:06x} 0x{:06x}'.format(offset, size),
                      file=meta_fd)
                last_offset = offset
                offset += BYTE_ALIGNMENT
            except:
                offset += BYTE_ALIGNMENT
            data_section.seek(offset)
Esempio n. 5
0
def explore_3(data_section, out_dir):
    screen_meta_raw, screen_data = parse_section_data(data_section)
    screen_meta = parse_screen_meta(screen_meta_raw)
    data = BytesIO(screen_data)
    with open(out_dir + '/meta.txt', 'w') as meta_fd:
        for n, entry in enumerate(screen_meta):
            data.seek(entry.offset)
            if entry.flag2 or entry.length > 0x5000:
                chunk = decompress(data)
            else:
                chunk = data.read(entry.length)
            if chunk[:4] == b'RNAN':
                ext = 'rnan'
            else:
                ext = 'bin'
            with open(out_dir + '/s3_{:04}.{}'.format(n, ext),
                      'wb') as data_fd:
                data_fd.write(chunk)
            print(
                '{0:04} 0x{1.offset:06x} {1.flag1:d} 0x{2:06x} {1.flag2:d} {3:4}'
                .format(n, entry, len(chunk), ext),
                file=meta_fd)
Esempio n. 6
0
for n, section in enumerate(data_sections):
    output = open('/tmp/cpac/{0}'.format(n), 'wb')
    output.write(section)


# Rip a palette that goes with the Capcom logo
data = BytesIO(data_sections[0])
data.seek(0x2d80)
capcom_palette = palette.parse(data.read(0x200))

# Rip the Capcom logo
data = BytesIO(data_sections[2])
data.seek(0xa00)  # Pointer found at 0x14

tiles = decompress(data)
tiles = split_into_tiles(tiles)

data.seek(0xa00 + 0xde8)
screen = Screen(decompress(data))

image = screen.image([capcom_palette], tiles)

with open('/tmp/logo.ppm', 'w') as output:
    # PPM header
    output.write(
        'P3\n'
        '256 192\n'
        '31\n'
    )
Esempio n. 7
0
    data_sections = parse_cpac(cpac_2d)

for n, section in enumerate(data_sections):
    output = open('/tmp/cpac/{0}'.format(n), 'wb')
    output.write(section)

# Rip a palette that goes with the Capcom logo
data = BytesIO(data_sections[0])
data.seek(0x2d80)
capcom_palette = palette.parse(data.read(0x200))

# Rip the Capcom logo
data = BytesIO(data_sections[2])
data.seek(0xa00)  # Pointer found at 0x14

tiles = decompress(data)
tiles = split_into_tiles(tiles)

data.seek(0xa00 + 0xde8)
screen = Screen(decompress(data))

image = screen.image([capcom_palette], tiles)

with open('/tmp/logo.ppm', 'w') as output:
    # PPM header
    output.write('P3\n' '256 192\n' '31\n')

    for row in image:
        for pixel in row:
            print(pixel.r, pixel.g, pixel.b, file=output, end='  ')
Esempio n. 8
0
def main():

    parser = argparse.ArgumentParser()
    parser.add_argument("cpac_file", help="Target cpac_2d.bin file")
    parser.add_argument("-o",
                        "--out_dir",
                        help="directory for output files",
                        default="out")
    # parser.add_argument("-a", "--annotate", action="store_true",
    #                     help="Replace ")
    args = parser.parse_args()

    if not os.path.exists(args.out_dir):
        os.makedirs(args.out_dir)

    # Dump cpac_2d.bin's sections to separate files for easier individual
    # staring-down
    with open(args.cpac_file, 'rb') as cpac_2d:
        data_sections = parse_cpac(cpac_2d)

    data = BytesIO(data_sections[0])
    pallete_meta_raw, pallete_data = parse_section_data(data)
    pallete_meta = parse_pallete_meta(pallete_meta_raw)

    data = BytesIO(data_sections[2])
    screen_meta_raw, screen_data = parse_section_data(data)
    screen_meta = parse_screen_meta(screen_meta_raw)

    gray_palette = dummy_gray_palette()

    IMAGE_LIST = [
        ImageEntry('capcom', pallete_meta[0], screen_meta[0],
                   PaletteBits.EIGHT, screen_meta[1]),
        ImageEntry('mobiclip', pallete_meta[1], screen_meta[2],
                   PaletteBits.EIGHT, screen_meta[3]),
        ImageEntry('nintendo', pallete_meta[2], screen_meta[4],
                   PaletteBits.FOUR, screen_meta[5]),
        ImageEntry('title-jp', pallete_meta[11], screen_meta[6],
                   PaletteBits.EIGHT, screen_meta[7]),
        ImageEntry('title-en', pallete_meta[12], screen_meta[8],
                   PaletteBits.EIGHT, screen_meta[9]),
        # ??? 10 -20 metal Shutter affect?
        # CREDITS
        # palette ?
        ImageEntry('folder1', pallete_meta[20], screen_meta[301],
                   PaletteBits.FOUR, screen_meta[302]),
        # palette ?
        ImageEntry('folder2', pallete_meta[20], screen_meta[303],
                   PaletteBits.FOUR, screen_meta[304]),
        # palette ?
        ImageEntry('box', pallete_meta[20], screen_meta[305], PaletteBits.FOUR,
                   screen_meta[306]),
    ]

    for i in range(28):
        for z in range(5):
            offset = 21 + i * 10 + z
            IMAGE_LIST.append(
                ImageEntry('credits{:02}-{}'.format(i, z), pallete_meta[22],
                           screen_meta[offset], PaletteBits.FOUR,
                           screen_meta[offset + 5]))

    # for i in range(30):
    #     #if pallete_meta[i].length == 0x200:
    #     #if pallete_meta[i].length == 0x20:
    #     IMAGE_LIST.append(
    #     ImageEntry('unknown'+str(i), pallete_meta[i], screen_meta[301], PaletteBits.FOUR, screen_meta[302]),
    #     )

    for image_meta in IMAGE_LIST:

        print("Loading " + image_meta.image_name)

        # Rip a palette
        if image_meta.palette_entry:
            pallete_size = image_meta.palette_entry.length
            pallete_offset = image_meta.palette_entry.offset
            data = BytesIO(pallete_data)
            data.seek(pallete_offset)
            image_palette = palette.parse(data.read(pallete_size))

            print("\tPalette 0x{0:06x} {1} bytes {2} colors".format(
                pallete_offset, pallete_size, len(image_palette)))
        else:
            image_palette = gray_palette

        tile_offset = image_meta.tile_entry.offset
        screen_offset = image_meta.screen_entry.offset

        data = BytesIO(screen_data)

        data.seek(tile_offset)
        if image_meta.tile_entry.flag2:
            tiles = decompress(data)
        else:
            tiles = data.read(image_meta.tile_entry.length)
        # Is there another way to figure this out?
        #if screen.get_max_tile() > len(tiles) / 64:
        if image_meta.tile_palette_bits == PaletteBits.FOUR:
            tiles = split_into_8x8_tiles_4bit(tiles)
        else:
            tiles = split_into_8x8_tiles_8bit(tiles)
        max_palette = max([entry for tile in tiles for entry in tile])
        print("\tTiles 0x{0:06x} {1} 8x8 tiles max palette {2}".format(
            tile_offset, len(tiles), max_palette))

        data.seek(screen_offset)
        if image_meta.screen_entry.flag2:
            data = decompress(data)
        else:
            data = data.read(image_meta.screen_entry.length)
        screen = Screen(data)

        max_tile = max([ntfs.tile for ntfs in screen.ntfs])
        # if len(screen.ntfs) != 256*192/64:
        #     raise ValueError('invalid ntfs size {0}'.format(len(screen.ntfs)))
        print("\tScreen 0x{0:06x} 256x128 max tile {1}".format(
            screen_offset, max_tile))

        image = screen.image([image_palette], tiles)

        with open(args.out_dir + '/' + image_meta.image_name + '.ppm',
                  'w') as output:
            image_to_ppm(image, output)
Esempio n. 9
0
    """Yield the message at the given pointer, character by character.

    Each character is two bytes long and little endian.
    """
    data.seek(pointer)
    while True:
        char, = unpack('<H', data.read(2))

        if char == 0xfffe:
            raise StopIteration
        else:
            yield char


with open(argv[1], 'rb') as text_file:
    data = decompress(text_file)

data = BytesIO(data)

assert data.read(4) == b'1LMG'

# Seek to and read message pointers
data.seek(8)
pointers_offset, = unpack('<H', data.read(2))
data.seek(pointers_offset + 0x34)

assert data.read(4) == b'\x2a\x00\x00\x00'  # Not sure of the significance

message_count, = unpack('<L', data.read(4))
messages = []
Message = namedtuple('Message', ['label_offset', 'message_pointer'])