def encode_bpp_char(bmap: Sequence[Sequence[int]], bpp = 1) -> bytes: # height = len(bmap) # width = len(bmap[0]) bits = flatten(''.join(f'{x:0{bpp}b}' for x in flatten(bmap))) bits = list(bits) gbits = grouper(bits, 8, fillvalue='0') # gbits = list(gbits) # print([''.join(x) for x in gbits]) data = bytes(int(''.join(byte), 2) for byte in gbits) # assert len(data) == width * height * 8 // bpp print(len(bits) % 8) extra = b'\0' if len(bits) % 8 == 0 else b'' return data + extra
def resize_frame(im, base_xoff=BASE_XOFF, base_yoff=BASE_YOFF): frame = list(np.asarray(im)) BG = frame[-1][-1] char_is_bg = lambda c: c == BG line_is_bg = lambda line: all(c == BG for c in line) if set(funcutils.flatten(frame)) == {BG}: return None x1 = min(count_in_row(char_is_bg, line) for line in frame) x2 = len(frame[0]) - min(count_in_row(char_is_bg, reversed(line)) for line in frame) y1 = count_in_row(line_is_bg, frame) y2 = len(frame) - count_in_row(line_is_bg, reversed(frame)) crop_area = (x1, y1, x2, y2) if crop_area == (0, 0, len(frame[0]), len(frame)): return None off_area = (x1 - base_xoff, y1 - base_yoff, x2 - base_xoff, y2 - base_yoff) fields = ('x1', 'y1', 'x2', 'y2') loc = dict(zip(fields, off_area)) return loc, np.asarray(im.crop(crop_area))
if __name__ == '__main__': import argparse from nutcracker.graphics import image, grid parser = argparse.ArgumentParser(description='read smush file') parser.add_argument('files', nargs='+', help='files to read from') parser.add_argument('--target', '-t', help='target directory', default='out') parser.add_argument('--nut', action='store_true') parser.add_argument('--map', action='store_true') args = parser.parse_args() files = set(flatten(glob.iglob(r) for r in args.files)) print(files) for filename in files: basename = os.path.basename(filename) output_dir = os.path.join(args.target, basename) os.makedirs(output_dir, exist_ok=True) print(f'Decoding file: {basename}') with open(filename, 'rb') as res: header, frames = anim.parse(res) if args.map: list(print_chunks(chain.from_iterable(frames))) elif not args.nut: for idx, (palette, screen) in enumerate(generate_frames(header, frames)): im = save_single_frame_image(screen)
from nutcracker.utils import funcutils def read_le_uint16(f): return struct.unpack('<H', f[:2])[0] if __name__ == '__main__': import argparse parser = argparse.ArgumentParser(description='read smush file') parser.add_argument('files', nargs='+', help='files to read from') args = parser.parse_args() files = set(funcutils.flatten(glob.iglob(r) for r in args.files)) print(files) for filename in files: with open(filename, 'rb') as res: basename, _ = os.path.splitext(os.path.basename(filename)) print(basename) saud = smush.assert_tag('SAUD', smush.untag(res)) assert res.read() == b'' sound = b'' sample_rate = 22050 print([tag for _, (tag, _) in smush.read_chunks(saud, align=1)]) for _, (tag, data) in smush.read_chunks(saud, align=1): if tag == 'STRK': print([
def get_frame_bpp(frame): return calc_bpp(len(set(flatten(frame[1]))))
def filter_empty_frames(frames): for im in frames: frame = list(np.asarray(im)) if set(flatten(frame)) == {0}: break yield im