"""Atari 7800 monochrome / tinted-mono (MARIA 160A restricted to one hue). Reuses the c160 machinery but restricts the colour pool to the 16 luminances of a single hue (hue 0 = greyscale), so the 8 palettes become up to ~16 grey levels and the per-segment palette choice yields a smooth, detailed luminance image. """ from __future__ import annotations import numpy as np from ... import palette as c64pal from ...convert.base import DIFFUSION_DITHERS, perceptual_error from ...atari import palette as apal from . import c160 WIDTH, HEIGHT, PIXEL_ASPECT = c160.WIDTH, c160.HEIGHT, c160.PIXEL_ASPECT def convert(img_rgb, palette_name="ntsc", dither_mode="floyd", intensive=False, base_color=None): # mono is carried by dithering -> needs error diffusion if dither_mode not in DIFFUSION_DITHERS: dither_mode = "floyd" hue = 0 if base_color is None else (int(base_color) & 0x0F) candidates = list(range(hue * 16, hue * 16 + 16)) # 16 lums of this hue conv = c160.convert(img_rgb, palette_name, dither_mode, intensive, base_color=base_color, candidates=candidates, _mode="mono") # report error in LUMINANCE space (a greyscale image must not be scored # against the colour original, as the colour modes are) plab = apal.palette_lab("ntsc").copy() plab[:, 1:] = 0.0 img_l = c64pal.srgb_to_lab(img_rgb) img_l[..., 1:] = 0.0 conv.error = perceptual_error(np.asarray(conv.index_image), img_l, plab) conv.meta["base_color"] = base_color return conv