from kandinsky import fill_rect as fr, draw_string as ds from ion import keydown as kd from numpy import array as ar, concatenate as ct, zeros as zs B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ID = 1 class TP: def __init__(self, w1, w2, w3, mb, lo, ll): self.w1, self.w2, self.w3, self.mb = w1, w2, w3, mb self.lo, self.ll = lo, ll self.m1l = self._cmv(w1) self.m1d = self._cmv(6 - w1 if mb > 1 else 7 - w1) if mb == 1: self.md = self.m1d; return self.m2l = self._cmv(w2) self.m2d = self._cmv(13 - w2 if mb > 2 else 14 - w2) if mb == 2: self.md = self.m2d; return self.m3l = self._cmv(w3) self.m3d = self._cmv(20 - w3 if mb > 3 else 21 - w3) self.md = min(self.m3d, 2047) def _cmv(self, w): return (2 << (w - 1)) - 1 if w > 0 else 0 class SW: def __init__(self, ws): self.ws = ws self.buf = zs(ws, dtype=ID) self.idx = 0 self.of = 0 def add_b(self, b): self.buf[self.idx] = b self.of += ((self.idx + 1) // self.ws) * (self.ws) self.idx = (self.idx + 1) % self.ws def get_b(self, d): idx = (self.idx - d - 1) % self.ws return int(self.buf[idx]) def get_l(self): return self.idx + self.of def pw(gen): while True: try: a = next(gen) b = next(gen) yield a, b except StopIteration: break class TI: def __init__(self, data, tps, p=None): self.img = dc(fb64(data), tps) self.tps = tps p = p or self.img self.clrs = [ r565(next(p) * 256 + next(p)) for _ in range(next(p) + 1) ] dims = (next(self.img) << 24) | (next(self.img) << 16) | (next(self.img) << 8) | next(self.img) self.w, self.h = dims >> 18, (dims >> 4) & 0x3FFF def dr_img(self, x, y): x0 = x for b in self.img: l, c = (b >> 4) + 1, b & 0x0F if x + l*4 > x0 + self.w*4: x, y = x0, y + 4 if self.clrs[c] != (255, 255, 255): fr(x, y, l*4, 4, self.clrs[c]) x += l*4 def dld(eb, tps): if eb[0] & 0b11000000 == 0b10000000 or tps.mb == 1: d = (eb[0] >> tps.w1) & ((1 << (6 - tps.w1)) - 1) l = eb[0] & ((1 << tps.w1) - 1) return l + 3, d + 1, 1 elif (eb[0] & 0b11000000 == 0b11000000 and eb[1] & 0b10000000 == 0) or tps.mb == 2: cv = ((eb[0] & 0b00111111) << (8 if tps.mb <= 2 else 7)) | eb[1] d = cv >> tps.w2 l = cv & ((1 << tps.w2) - 1) if d <= tps.m1d: l += tps.m1l return l + 3, d + 1, 2 elif (eb[0] & 0b11000000 == 0b11000000 and eb[1] & 0b10000000 == 0b10000000 and eb[2] & 0b10000000 == 0) or tps.mb == 3: cv = ((eb[0] & 0b00111111) << (15 if tps.mb <= 3 else 14)) | ((eb[1] & 0b01111111) << 8) | eb[2] d = cv >> tps.w3 l = cv & ((1 << tps.w3) - 1) if d <= tps.m1d: l += tps.m1l + tps.m2l elif d <= tps.m2d: l += tps.m2l return l + 3, d + 1, 3 elif (eb[0] & 0b11000000 == 0b11000000 and eb[1] & 0b10000000 == 0b10000000 and eb[2] & 0b10000000 == 0b10000000) or tps.mb == 4: cv = ((eb[0] & 0b00111111) << 22) | ((eb[1] & 0b01111111) << 15) | ((eb[2] & 0b01111111) << 8) | eb[3] d = cv >> 17 l = cv & ((1 << 17) - 1) return l + 3, d + 1, 4 def dc(data, tps): tl, of, tx, p = len(data), 0, SW(tps.md), 0 while of < tl: od = data[of] if od & 0x80 == 0x00: if tps.lo <= od <= tps.lo + 127 - tps.ll: tx.add_b(od) of += 1 else: ll = 127 - od + 1 + tps.lo of += 1 for i in range(ll): tx.add_b(data[of + i]) of += ll else: l, d, nb = dld(data[of:of + 4], tps) of += nb ep = tx.get_l() - (d - l) if ep <= tx.get_l(): for i in range(l): tx.add_b(tx.get_b(d - 1)) else: ch = [tx.get_b(d - i - 1) for i in range(d)] * (l // d + 1) for i in range(l): tx.add_b(ch[i]) while p < tx.get_l(): yield tx.get_b(tx.get_l() - p - 1) p += 1 def r565(c): return ((c >> 11 & 0x1F) * 255 // 31, (c >> 5 & 0x3F) * 255 // 63, (c & 0x1F) * 255 // 31) def gclr(p): p = fb64(p) return [r565(p[1 + i] * 256 + p[2 + i]) for i in range(0, p[0] * 2, 2)] def fb64(eb): dl = (len(eb) * 3) // 4 - eb.count('=') da = zs(dl, dtype=ID) ai = 0 for i in range(0, len(eb), 4): bl = eb[i:i+4].replace("=", "A") bi = sum((B64.index(c) << (6 * (3 - j))) for j, c in enumerate(bl)) for byte in bi.to_bytes(3, "big"): if ai < dl: da[ai] = byte ai += 1 return da tps = TP(1, 3, 9, 2, 0, 32) img = TI('D2Cud6aYKGsgSNQasxqSOe9czRzd3HHUnjdI77Q7vtiMegB58ANw8PDwsMAdfnAxjGVgMiEgASAB8FDwUAMUBQYDcSMSEfAA8DABAySaIQAREjQGAwGjAzQWAxEAEQNErqEgAjQFFgMxA0QmAxF08PAQAQM0JgMhAzRGuXyQB1ABwMEDNAYIGQUGCnXwEIAnICEDFBU2AsFACgknBgNg8CBwRxAhAyYTAgYDEQYkCgk3BgIBMAfAkBcLECEMAwIDFAwTxCgGR7wgJ3SwkBEAQQMkAyQTBRTBUQMBMEdqoMAxA5QVBgg3DQMBQAEXwNAhA6QWOcWoQBFgwMAhAgMGpBYKAhMx8DDAEQMEBgIMBgoGdAUGE0HwMLDEwBZ9tAYDwFJ99BQWkiBxsBEKBAN0E2QGAzGAF4CgwZgTeHQjVBYDIfAwwGZBIAF60ACBAAEOoAQ3JKVRG29hcAuRAAMZBAUHAhMnBBMUCclQMRoWDHjREA4LHhsOEbcnA0ckCQQJFCYTAQoCBicIDAAOCw4rHgseC8HZFCcCBwJHVCYMAwoDBVcKAg57oQ4bXgvDKBZgtzQ2AyYDVwgHAg4LLisuzgMGBZcJVgoDRgNXCQgCngtzrgsOAwYNCVcZFiwjFs1YRwkIA3KezgMJDRpIDQUsGQIFJs2BJwgXCAN4jr4CCUc4dwLIKAwJFwgnA2COzgJHCKcClAYDBwgJFw0HA37OAghXCGcJAgWUBQMYFw0XA3N+vgMEEgmHCCK0BQYMzFCeFAIXCHtnAgWkBdF5RwgJA2huvgMkEggJJwkGAsQFBAUEBgMIJwkIDQKuBSQGDAYtBQJUBRIKFAXIsMM4GAxvfs4DNAI5AlQGA4QmAwgXKAKgBhQJBQInAgkFJAwDepQmAxgpDMNZBgMCBAgCCCccFCN6lDYDKA0FxiADFgwTCkcSAxYCfIRGA0ihJggZdWcJDQYCdFYKOAKewQACBSl1dwYCBlRWAz0Drs6eKRg3KAImBQRzdgMYDQO+3gITAkkIScLgeZYDDQITzt7EsBJ5iQwCFwoSVrRg7p4tAxkICQUSWQgMBwknBDwGAgMvTZ5uXQoDIgwCcxcFBwgHOQ0TT2xtbo5N3wJTEhNvTY6+/f09vv7+/sAd' , tps) img.dr_img(40,0)