14.19: Filter › Scanlines, its own filter, on Swift's cdde327 kernel

This commit is contained in:
ZacharyZhang-NY committed 2026-10-11 10:46:16 -04:00
1 parent d06fb55bc4
commit 1a129b9a23
26 files changed
+905 -479

No files matched your search

+37 -7
View File
@@ -8,7 +8,7 @@ enum {
DITHER_ATKINSON, DITHER_FLOYD_STEINBERG,
DITHER_BAYER_2, DITHER_BAYER_4, DITHER_BAYER_8,
DITHER_DOTS, DITHER_LINES, DITHER_DIAMONDS,
DITHER_PATTERNS, DITHER_GLYPHS, DITHER_SCANLINES
DITHER_PATTERNS, DITHER_GLYPHS
};
typedef struct {
@@ -20,8 +20,7 @@ typedef struct {
// −1…1: darker (more ink) or lighter, and flatter or punchier, before dithering.
float density;
float contrast;
// Halftone and glyph cells, in pixels (scanlines: the distance between lines), and the halftone screen's angle in
// radians.
// Halftone and glyph cells, in pixels, and the halftone screen's angle in radians.
int cell;
float angle;
// Halftone dots, patterns and glyphs mark the light tones on the dark color instead of the dark on the light.
@@ -38,18 +37,49 @@ typedef struct {
const uint8_t *glyphs;
const float *glyphCoverage;
int glyphCount;
// Scanlines: how far each line breaks into round dots (0–1), and how many pixels its wobble pushes it sideways.
float dots;
float wobble;
} DitherParams;
// Filter › Scanlines: the picture as a CRT draws it, in lines of light on a dark screen.
typedef struct {
// Pixels from one line to the next.
int spacing;
// How much of the gap a full-bright line fills, 0–1; dimmer parts draw it thinner.
float thickness;
// 0–1: tones darker than this break the lines into round dots, blending through dashes into the solid line above it.
float dots;
// Pixels a line wavers sideways, in a wave down the screen.
float wobble;
// Pixels a line rises where the picture under it is bright (falls, if negative), so lines swell into its shapes.
float displace;
// 0–1: tones darker than this draw no line at all.
float threshold;
// Pixels the red and blue are moved apart, either way, for colored fringes.
float split;
// −1…1: darker or lighter, and flatter or punchier, before the lines are drawn.
float density;
float contrast;
// 0–1: how bright the lines are where the picture is black.
float blackLevel;
// 0–1: how far the brightness is smoothed, over a few line spacings, before it displaces the lines.
float smoothness;
// 0: lines of `light` on `dark` (straight sRGB), brighter where the picture is. 1: lines in the picture's colors.
int originalColors;
uint8_t dark[3];
uint8_t light[3];
} ScanlinesParams;
// Draws premultiplied RGBA pixels (4 bytes per pixel, `stride` bytes per row) as scanlines, in place. Alpha is kept and
// fully transparent pixels are left alone. Returns 0 if working memory couldn't be had.
int scanlines_apply(uint8_t *rgba, size_t width, size_t height, size_t stride, const ScanlinesParams *params);
// Dithers premultiplied RGBA pixels (4 bytes per pixel, `stride` bytes per row) in place. Alpha is kept and fully
// transparent pixels are left alone. Returns 0 if working memory couldn't be had.
int dither_apply(uint8_t *rgba, size_t width, size_t height, size_t stride, const DitherParams *params);
// Turns each `block` × `block` square of premultiplied RGBA pixels into a round dot in its own color on `gap` (straight
// sRGB), like the lit pixels of a dot-matrix screen. The dot's edge is smoothed and alpha is kept.
void dither_dots(uint8_t *rgba, size_t width, size_t height, size_t stride, int block, const uint8_t *gap);
// Adds `glow` (premultiplied RGBA, same layout) over the pixels at `amount`, never past their own alpha.
// Adds `glow` (premultiplied RGBA, same layout) over the pixels at `amount`, easing off as they near full brightness
// and never past their own alpha.
void dither_glow(uint8_t *rgba, const uint8_t *glow, size_t width, size_t height, size_t stride, float amount);
// Rounds 16-bit premultiplied RGBA (`width` × `height`, tightly packed) to 8 bits into `rgba` (`stride` bytes per
// row), adding noise of about one 8-bit step first so smooth gradients don't come out in steps. The noise is fixed per