"""Apple //e Double Hi-Res: 140x192, 16 colours (no per-cell limit). Each line is 560 bits = 140 four-bit colour groups, stored 7 bits per byte with the bytes interleaved between auxiliary and main memory (aux holds the even display bytes, main the odd). Needs a //e (auxiliary memory). """ from __future__ import annotations import numpy as np from ... import dither, palette as c64pal from ...convert.base import Conversion, perceptual_error from .. import palette as apal WIDTH, HEIGHT = 140, 192 PIXEL_ASPECT = 2.0 DATA_ADDR = 0x2000 def convert(img_rgb, palette_name="dhgr", dither_mode="floyd", intensive=False, base_color=None): plab = apal.dhgr_lab() prgb = apal.DHGR16.astype(np.uint8) img_lab = c64pal.srgb_to_lab(img_rgb) # (192,140,3) allowed = np.tile(np.arange(16), (HEIGHT, WIDTH, 1)) idx = dither.quantize(img_lab, allowed, plab, dither_mode).astype(np.int64) aux = bytearray(0x2000) main = bytearray(0x2000) for y in range(HEIGHT): stream = np.zeros(560, dtype=np.uint8) row = idx[y] for n in range(WIDTH): c = int(row[n]) stream[4 * n + 0] = c & 1 stream[4 * n + 1] = (c >> 1) & 1 stream[4 * n + 2] = (c >> 2) & 1 stream[4 * n + 3] = (c >> 3) & 1 base = apal.hgr_row_addr(y) for col in range(40): ab = 0 mb = 0 for i in range(7): ab |= int(stream[7 * (2 * col) + i]) << i mb |= int(stream[7 * (2 * col + 1) + i]) << i aux[base + col] = ab main[base + col] = mb data = bytes(main) + bytes(aux) # main half at $2000, aux at $4000 preview = np.repeat(prgb[idx], int(PIXEL_ASPECT), axis=1) return Conversion( mode="dhgr", width=WIDTH, height=HEIGHT, pixel_aspect=PIXEL_ASPECT, index_image=idx.astype(np.uint16), data=data, data_addr=DATA_ADDR, viewer="dhgr", preview_rgb=preview, error=perceptual_error(idx, img_lab, plab), meta={"palette": "dhgr", "dither": dither_mode}, )