First public commit.
This commit is contained in:
parent
2a48f52979
commit
4bac9d83ed
288 changed files with 18417 additions and 1076 deletions
140
lenser/gallery.py
Normal file
140
lenser/gallery.py
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
"""Render every Mode x Palette x Dither variation of an image, for the GUI's
|
||||
"Explore variations" contact sheet. Kept import-light enough to run in
|
||||
ProcessPoolExecutor worker processes; platform-aware (C64 or Atari).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from . import imageprep
|
||||
from .convert import render_preview
|
||||
|
||||
DITHERS = ["bayer", "floyd", "atkinson", "none"]
|
||||
|
||||
|
||||
def combos(platform: str):
|
||||
"""(mode, palette, dither) triples for a platform."""
|
||||
if platform == "apple":
|
||||
from .apple.convert import MODES as PMODES
|
||||
return [(m, "mono", d) for m in PMODES for d in DITHERS]
|
||||
if platform == "atari":
|
||||
from .atari.convert import MODES as AMODES
|
||||
# floyd first: gr15/gr15dli use dither-aware palette selection
|
||||
adith = ["floyd", "atkinson", "bayer", "none"]
|
||||
return [(m, "ntsc", d) for m in AMODES for d in adith]
|
||||
if platform == "ti99":
|
||||
from .ti99.convert import MODES as TMODES
|
||||
# atkinson first: gm2 selection is dither-aware, and atkinson's lighter
|
||||
# diffusion bleeds less across the tight 8x8 two-colour cells than floyd
|
||||
tdith = ["atkinson", "floyd", "bayer", "none"]
|
||||
return [(m, "tms9918", d) for m in TMODES for d in tdith]
|
||||
if platform == "coco":
|
||||
from .coco.convert import MODES as COMODES
|
||||
return [(m, "mc6847", d) for m in COMODES for d in DITHERS]
|
||||
if platform == "bbc":
|
||||
from .bbc.convert import MODES as BMODES
|
||||
return [(m, "bbc", d) for m in BMODES for d in DITHERS]
|
||||
if platform == "coleco":
|
||||
from .coleco.convert import MODES as CVMODES
|
||||
# same TMS9918A GM2 as the TI-99 -> dither-aware, atkinson first
|
||||
cvdith = ["atkinson", "floyd", "bayer", "none"]
|
||||
return [(m, "tms9918", d) for m in CVMODES for d in cvdith]
|
||||
if platform == "a2600":
|
||||
from .a2600.convert import MODES as VMODES
|
||||
# atkinson/none first: bayer fares poorly on the 40px playfield
|
||||
adith = ["atkinson", "none", "floyd", "bayer"]
|
||||
return [(m, "tia", d) for m in VMODES for d in adith]
|
||||
if platform == "intv":
|
||||
from .intv.convert import MODES as IMODES
|
||||
# none first: the 64-tile GRAM limit makes error-diffusion counterproductive
|
||||
idith = ["none", "atkinson", "bayer", "floyd"]
|
||||
return [(m, "stic", d) for m in IMODES for d in idith]
|
||||
if platform == "vic20":
|
||||
from .vic20.convert import MODES as VMODES
|
||||
# floyd first: the colour selection is dither-aware (segment metric)
|
||||
vdith = ["floyd", "atkinson", "bayer", "none"]
|
||||
return [(m, "vic", d) for m in VMODES for d in vdith]
|
||||
if platform == "spectrum":
|
||||
from .spectrum.convert import MODES as ZMODES
|
||||
# atkinson first: 2-colour-per-cell (attribute clash), lighter diffusion
|
||||
# bleeds less across cells (as on the TI-99)
|
||||
zdith = ["atkinson", "floyd", "bayer", "none"]
|
||||
return [(m, "spectrum", d) for m in ZMODES for d in zdith]
|
||||
if platform == "a5200":
|
||||
from .a5200.convert import MODES as XMODES
|
||||
# floyd first: reuses the dither-aware Atari GTIA encoders
|
||||
xdith = ["floyd", "atkinson", "bayer", "none"]
|
||||
return [(m, "ntsc", d) for m in XMODES for d in xdith]
|
||||
if platform == "a7800":
|
||||
from .a7800.convert import MODES as SMODES
|
||||
sdith = ["floyd", "atkinson", "bayer", "none"]
|
||||
return [(m, "ntsc", d) for m in SMODES for d in sdith]
|
||||
if platform == "c128":
|
||||
from .c128.convert import MODES as C128_MODES
|
||||
# floyd first: the 640x200 two-tone is pure luminance dither, so error
|
||||
# diffusion yields the smoothest tonal gradients at this high resolution.
|
||||
c128dith = ["floyd", "atkinson", "bayer", "none"]
|
||||
return [(m, "vdc", d) for m in C128_MODES for d in c128dith]
|
||||
if platform in ("c16", "plus4"):
|
||||
from .c16.convert import MODES as C16_MODES
|
||||
# floyd first: TED hires picks 2 of 128 colours per cell, so error
|
||||
# diffusion brackets each cell and blends to the true shade.
|
||||
c16dith = ["floyd", "atkinson", "bayer", "none"]
|
||||
return [(m, "ted", d) for m in C16_MODES for d in c16dith]
|
||||
if platform == "cpc":
|
||||
from .cpc.convert import MODES as CPC_MODES
|
||||
# floyd first: a flat N-colour palette dithered -> error diffusion gives
|
||||
# the smoothest gradients.
|
||||
cpcdith = ["floyd", "atkinson", "bayer", "none"]
|
||||
return [(m, "cpc", d) for m in CPC_MODES for d in cpcdith]
|
||||
if platform == "coco3":
|
||||
from .coco3.convert import MODES as COCO3_MODES
|
||||
# floyd first: flat palette chosen from 64 colours, dithered.
|
||||
c3dith = ["floyd", "atkinson", "bayer", "none"]
|
||||
return [(m, "gime", d) for m in COCO3_MODES for d in c3dith]
|
||||
if platform == "nes":
|
||||
from .nes.convert import MODES as NES_MODES
|
||||
# atkinson first: lighter diffusion bleeds less across the NES's tight
|
||||
# 16x16 attribute-palette regions (like the TI/Spectrum cell platforms).
|
||||
nesdith = ["atkinson", "floyd", "bayer", "none"]
|
||||
return [(m, "nes", d) for m in NES_MODES for d in nesdith]
|
||||
if platform == "iigs":
|
||||
from .iigs.convert import MODES as IIGS_MODES
|
||||
# floyd first: per-line 16-of-4096 palette, dithered -> smoothest result.
|
||||
gsdith = ["floyd", "atkinson", "bayer", "none"]
|
||||
return [(m, "iigs", d) for m in IIGS_MODES for d in gsdith]
|
||||
if platform in ("pet2001", "pet4032", "pet8032", "superpet"):
|
||||
# one-bit quadrant-block mono; floyd carries the most tone at low res.
|
||||
return [("mono", "pet", d) for d in ("floyd", "atkinson", "bayer", "none")]
|
||||
if platform == "sms":
|
||||
from .sms.convert import MODES as SMS_MODES
|
||||
# floyd first: 16 colours/tile from 2 palettes -> error diffusion blends
|
||||
# to the smoothest result.
|
||||
smsdith = ["floyd", "atkinson", "bayer", "none"]
|
||||
return [(m, "sms", d) for m in SMS_MODES for d in smsdith]
|
||||
if platform == "amiga":
|
||||
from .amiga.convert import MODES as AMIGA_MODES
|
||||
# floyd first: flat 32-of-4096 palette dithered -> smoothest gradients.
|
||||
amdith = ["floyd", "atkinson", "bayer", "none"]
|
||||
return [(m, "amiga", d) for m in AMIGA_MODES for d in amdith]
|
||||
if platform == "ansi":
|
||||
from .ansi.convert import MODES as ANSI_MODES
|
||||
# floyd first: a free 16-colour quantise, so error diffusion blends best.
|
||||
ansidith = ["floyd", "atkinson", "bayer", "none"]
|
||||
return [(m, "vga", d) for m in ANSI_MODES for d in ansidith]
|
||||
from .convert import MODES as CMODES
|
||||
# floyd first: C64 colour selection is dither-aware, so error diffusion gives
|
||||
# the smoothest, most accurate result.
|
||||
cdith = ["floyd", "atkinson", "bayer", "none"]
|
||||
return [(m, p, d) for m in CMODES for p in ["colodore", "pepto"] for d in cdith]
|
||||
|
||||
|
||||
def render_variation(args):
|
||||
"""Worker entry. args = (path, platform, mode, palette, dither, prep_kwargs,
|
||||
base_name). Returns (mode, palette, dither, error, rgb)."""
|
||||
path, platform, mode, palette, dither, prep_kwargs, base_name = args
|
||||
from . import platforms
|
||||
prep = imageprep.PrepOptions(**prep_kwargs)
|
||||
conv = platforms.convert(platform, path, mode, palette, dither,
|
||||
False, prep, base_name)
|
||||
rgb = render_preview(conv, palette, scale=1)
|
||||
return (mode, palette, dither, conv.error, rgb)
|
||||
Loading…
Add table
Add a link
Reference in a new issue