36 lines
1.5 KiB
Python
36 lines
1.5 KiB
Python
"""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
|