"""TI-99/4A (TMS9918A) monochrome / tinted-mono mode. Same 256x192, 2-colours-per-cell format as gm2, but matched by *luminance* to a grey ramp (black -> grey -> white) so every cell is neutral -- no colour clash, maximum perceived detail, a clean greyscale photo. Pick a base colour for a tinted monochrome instead. Reuses the gm2 byte packing and viewer. """ from __future__ import annotations import numpy as np from ... import palette as c64pal from ...convert import base from .. import palette as tpal from . import gm2 WIDTH, HEIGHT = gm2.WIDTH, gm2.HEIGHT CELL_W, CELL_H = gm2.CELL_W, gm2.CELL_H PIXEL_ASPECT = gm2.PIXEL_ASPECT # Neutral ramp: black(1), grey(14), white(15). Lighter siblings for tinting. NEUTRAL = [1, 14, 15] SIBLINGS = {2: 3, 3: 2, 4: 5, 5: 4, 6: 9, 8: 9, 9: 8, 12: 14, 13: 9} def convert(img_rgb, palette_name="tms9918", dither_mode="atkinson", intensive=False, base_color=None): plab = tpal.palette_lab() prgb = tpal.get_palette().astype(np.uint8) ramp = base.luminance_ramp(plab, NEUTRAL, base_color, SIBLINGS) idx, sets, rows, cols, err = base.mono_render( img_rgb, plab, ramp, WIDTH, HEIGHT, CELL_W, CELL_H, dither_mode, n_free=2) pattern, colors = gm2._encode(idx, sets, rows, cols) data = bytes(pattern) + bytes(colors) return base.Conversion( mode="mono", width=WIDTH, height=HEIGHT, pixel_aspect=PIXEL_ASPECT, index_image=idx.astype(np.uint16), data=data, data_addr=0, viewer="gm2", preview_rgb=prgb[idx], error=err, meta={"palette": "tms9918", "dither": dither_mode, "base_color": base_color}, )