Example #1
0
def main():
    print(sys.argv)
    start_time = time.time()
    if len(sys.argv) != 5:
        printUsage()
    if sys.argv[1] == "compress":
        compress(filename=sys.argv[2],
                 path_to_dir=sys.argv[3],
                 output_dir=sys.argv[4])
        end_information(sys.argv[3] + sys.argv[2], sys.argv[4] + sys.argv[2])
    elif sys.argv[1] == "decompress":
        decompress(filename=sys.argv[2],
                   path_to_dir=sys.argv[3],
                   output_dir=sys.argv[4])
    else:
        printUsage()
    print(f"{sys.argv[1]} took {time.time() - start_time} seconds.")
Example #2
0
def tests():
    #files = ['pan-tadeusz-czyli-ostatni-zajazd-na-litwie.txt',
    #         'test1.bin',
    #         'test2.bin',
    #         'test3.bin']
    files = ['my_test5.txt']
    for filename in files:
        start_time = time.time()
        print(f"Start compressing {filename}")
        compress(filename, path_to_dir="files/", output_dir="compressed/")
        compress_time = time.time()
        end_information("files/" + filename, "compressed/" + filename)
        print(
            f"Compression of {filename} took {round(compress_time - start_time,2)} seconds"
        )
        decompress(filename,
                   path_to_dir="compressed/",
                   output_dir="decompressed/")
        decompress_time = time.time()
        print(
            f"Decompression of {filename} took {round(decompress_time - compress_time, 2)} seconds"
        )
Example #3
0
    return data


def img_palette_to_gba(img):
    formatted = format_img_palette(img)
    return pal_to_gba(formatted)


def pal_to_gba(palette):
    data = b''
    for color in palette:
        r, g, b = color
        r >>= 3
        g >>= 3
        b >>= 3
        data += (r | (g << 5) | (b << 10)).to_bytes(2, 'little')
    return data


if __name__ == '__main__':
    import lz77
    img = Image.open('../char.png')
    with open('../bpre.gba', 'rb+') as f:
        d = img_to_gba_16colors(img)
        f.seek(0x800000)

        f.write(lz77.compress(d))
        f.seek(0x900000)
        d = format_img_palette(img)
        f.write(lz77.compress(pal_to_gba(d)))
Example #4
0
import lz77

tests = [{
    "message":
    "кибернетики",
    "buffer_size":
    4,
    "dict_size":
    12,
    "result": [(0, 0, 'к'), (0, 0, 'и'), (0, 0, 'б'), (0, 0, 'е'), (0, 0, 'р'),
               (0, 0, 'н'), (3, 1, 'т'), (7, 1, 'к'), (2, 1, '')]
}, {
    "message": "аааааааааааа",
    "buffer_size": 4,
    "dict_size": 12,
    "result": [(0, 0, 'а'), (1, 1, 'а'), (3, 3, 'а'), (4, 4, 'а')]
}]

for test in tests:
    result = lz77.compress(test['message'], test['buffer_size'],
                           test['dict_size'])
    print(result)
    assert result == test['result']

    message = lz77.decompress(test['result'])
    print(message)
    assert message == test['message']
    print('===========================')
Example #5
0
            pattern, color = convert_tile(im, x * 8, y * 8)
            patterns.extend(pattern)
            colors.extend(color)
    return patterns, colors


def print_static_table(data, name):
    print("static const uint8_t {0}[] = {{".format(name), end='')
    print(", ".join([str(row) for row in data]), end='')
    print("};")


if len(sys.argv) < 2:
    sys.exit("Missing arguments")

# convert screen
name = os.path.splitext(os.path.basename(sys.argv[1]))[0]
im = Image.open(sys.argv[1])
assert (im.size == (128, 128) or im.size == (256, 192))
assert (im.mode == "P")
patterns, colors = convert_screen(im)
sys.stderr.write("pat_{0}\n".format(name))
cpatterns = compress(patterns)
sys.stderr.write("col_{0}\n".format(name))
ccolors = compress(colors)

# export table
print_static_table(cpatterns, "pat_" + name)
print("")
print_static_table(ccolors, "col_" + name)
Example #6
0
                    parts_data[parts_offsets.index(offset)] = data
                    updated_parts.append(offset)

        # Write new parts' data
        print parts_offsets
        bac.seek(data_offset + 4)
        bac.truncate()

        new_offsets = []

        for index, data in enumerate(parts_data):
            new_offsets.append(bac.tell() - data_offset)

            # bac.write(pack('<I', len(data) << 8))
            # bac.write(data)
            compress(data, bac)

            # try:
            # if bac.tell() - data_offset < parts_offsets[index + 1]:
            # bac.seek(parts_offsets[index + 1] + data_offset)
            # except IndexError:
            # pass

            # while bac.tell() % 4:
            #    bac.write('\xff')

        print new_offsets

        # Calculate and write block size
        block_size = bac.tell() - data_offset
        bac.seek(data_offset)
Example #7
0
    def update(self, image, vram_offset=0, empty=False, compress=True):
        if not vram_offset:
            vram_offset = getattr(self, 'vram_offset', 0)

        # First tile - empty tile?
        if empty:
            empty = [0] * (8 * 8)
            tiles = [empty]    
        else:
            tiles = []
        
        mappings = []    
        reused = 0    
        
        transforms = (
            (None, False, False),
            (Image.FLIP_LEFT_RIGHT, True, False),
            (Image.FLIP_TOP_BOTTOM, False, True),
            (Image.ROTATE_180, True, True),
        )
        
        # Iterate over top-left coordinates of each tile and split image to 8x8 tiles
        for y in range(0, image.size[1], 8):
            for x in range(0, image.size[0], 8):
                # Crop image to 8x8 tile
                tile = image.crop((x, y, x + 8, y + 8))
                
                # Try to find tile duplicates, fliping horizontally/vertically/both if necessary
                for method, flip_h, flip_v in transforms:
                    if method:
                        transposed = tile.transpose(method)
                    else:
                        transposed = tile
                        
                    data = list(transposed.getdata())
                    
                    # Try to tile duplicate
                    try:
                        n = tiles.index(data)
                    except ValueError:
                        pass
                    else:
                        mappings.append((n, flip_h, flip_v))
                        reused += 1
                        break
                    
                else:
                    data = list(tile.getdata())
                    n = len(tiles)
                    
                    tiles.append(data)
                    mappings.append((n, False, False))
                    
        #assert reused + len(tiles) == len(mappings) + 1   
        print '{} tiles reused, {} in result'.format(reused, len(tiles), len(mappings))    
        
        # Now try to update bbg file itself
        bbg = self.bbg        
        (size, data_offset, mappings_offset, palette_offset,
            color_format, row_len, rows_n, bbg_palette_index, unknown) = self.header
            
        # Write tile data
        data_offset = 0x20
        bbg.seek(data_offset)
        
        # FIXME: Need to implement LZ77 compression
        if color_format == 1:
            data_length = len(tiles) * (8 * 8 / 2)
        else:
            data_length = len(tiles) * (8 * 8)
            
        
        data = []
        palette_indexes = []
        
        for tile in tiles:
            if color_format == 1:
                # Hack for 4 bpp images with multiple palettes
                palette_index = tile[0] // 16
                palette_indexes.append(palette_index)                
                # Store two pixels of tile as one
                for first, second in izip_longest(*[iter(tile)] * 2):
                    first %= 16
                    second %= 16
                    value = (second << 4) | first
                    data.append(chr(value))
            else:
                data += map(chr, tile)
        
        assert len(data) == data_length        

        if compress:
            lz77.compress(data, bbg)
        else:
            bbg.write(pack('<i', data_length << 8))
            bbg.write(''.join(data))
        
        # Write mappings    
        mappings_offset = bbg.tell()    
        
        mappings_length = len(mappings) * 2
        bbg.write(pack('<i', mappings_length << 8))
        
        palette_index = bbg_palette_index >> 4
        mappings_data = []
        
        for n, flip_h, flip_v in mappings:
            # Calculate vram tile offset
            value = n + vram_offset
            # Add palette index
            #value |= bbg_palette_index << 8# 12
            value |= (palette_index + palette_indexes[n]) << 12
            # Set flip_h and flip_v flags
            value |= flip_h << 10
            value |= flip_v << 11
            
            # Pack value
            value = pack('<H', value)
            mappings_data.append(value)
            
        assert len(mappings_data) * 2 == mappings_length
        bbg.write(''.join(mappings_data))

        # Write palette
        palette_offset = bbg.tell()
        if self.palette_data:
            bbg.write(pack('<i', len(self.palette_data) << 8))
            bbg.write(self.palette_data)
        else:
            bbg.write('\x00' * 4)
        
        # Write header
        size = bbg.tell()
        bbg.seek(0)
        bbg.write('BBG\00')
        
        row_len = image.size[0] / 8
        rows_n = image.size[1] / 8
        
        self.header = BBGHeader(size, data_offset, mappings_offset, palette_offset,
            color_format, row_len, rows_n, bbg_palette_index, unknown)
        
        #unknown = 1
        
        #bbg.write(pack('<5i2h', size, data_offset, mappings_offset, palette_offset, unknown, row_len, rows_n))  
        bbg.write(pack('<5i4h', *self.header))