code wiki / (root) / nx_dedither.nx

nx_dedither.nx

buildroot/runtime/nx_dedither.nx

41866 B831 linesdepth 11pulls 50 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_dedither.nx -- RECOVER A 1990s DITHERED IMAGE WITHOUT TOUCHING THE ORIGINAL BYTES. WHY THIS EXISTS (measured 2026-08-07, page3.com/13Nov96.gif): a 280x403 GIF weighing 81,953 B is a PHOTOGRAPH crushed into a 256-entry palette. The encoder of 1996 traded colour depth for file size by scattering alternating palette entries across smooth regions -- so a plain studio backdrop is stored as high-frequency speckle. The archive serves those bytes FAITHFULLY, and faithful is exactly why the backdrop reads as white fuzz. The fuzz is not our defect and not decode damage: header valid, trailer 0x3B present, extension preserved 1:1 from the 1996 HTML, no re-encode anywhere in the pipeline. *THE ARCHIVE WAS RIGHT AND THE PICTURE STILL LOOKED WRONG. Those are different problems and only the second one is fixable. Rule 25 says build intelligence, never strip features -- so this NEVER rewrites the stored asset. It emits a SEPARATE enhanced render beside it. The original remains the record. HOW: a sigma filter (Lee 1983) -- average only over neighbours whose colour is already CLOSE to the centre. Dither speckle is by construction a set of near-neighbours straddling the true value, so it averages away; a real edge has far neighbours, which are EXCLUDED from the mean and therefore survive. A plain box blur would also lower the noise metric -- and would destroy the picture. That is precisely why the selftest below refuses to pass on noise reduction alone. RULER: mean absolute local deviation (MALD) vs a 3x3 mean, x1000, integer. Reported BEFORE and AFTER so the claim is a measurement and not an adjective. usage: nx_dedither <in-image> <out.png> [radius=2] [threshold=40] nx_dedither --kat (selftest: 4 teeth, 2 of them anti-vacuity) argv[1]=input (any format nx_img_bytes_to_rgb decodes), argv[2]=output PNG. exit 0 ok | 2 decode/write failure | 3 usage | 1 selftest RED license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0

dependencies 4 imports · 0 importers

nx_syscalls.nx nx_img_to_rgb.nx nx_png_write.nx nx_img_resample.nx nx_dedither.nx

imports: nx_syscalls.nxnx_img_to_rgb.nxnx_png_write.nxnx_img_resample.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main de sys_write sys_exit dd_kat sys_mmap nxa_die sys_write ↻ sys_exit ↻ nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ dd_mald dd_sigma dp sys_write ↻ dnum dp ↻ sys_mmap ↻ sys_write ↻ dd_coldiff dd_altrate dd_localmean dd_atoi dd_census de ↻ sys_openat_rd sys_mmap ↻ dp ↻ sys_getdents64 dd_cat nx_img_to_rgb

structs

none

consts

41const DD_MAXR: i64 = 8
42const DD_MAXSCALE: i64 = 4
55const DD_DITHER_MIN: i64 = 450
56const DD_MAXTHR: i64 = 255
484const DD_DIRBUF: i64 = 262144
485const DD_RECLEN_OFF: i64 = 16
486const DD_NAME_OFF: i64 = 19

functions

58func dp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
59func de(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(2,s,n); return 0 }
60func dnum(v: i64) -> i64
73func dd_atoi(s: *u8) -> i64
called by 1: main
90func dd_mald(rgb: *u8, w: i64, h: i64) -> i64
126func dd_localmean(rgb: *u8, w: i64, x: i64, y: i64, c: i64) -> i64
149func dd_meangrad(rgb: *u8, w: i64, h: i64) -> i64
189func dd_altrate(rgb: *u8, w: i64, h: i64) -> i64
228func dd_sigma(src: *u8, dst: *u8, w: i64, h: i64, r: i64, thr: i64) -> i64
called by 3: dd_katdd_sweepmain
286func dd_coldiff(rgb: *u8, w: i64, h: i64, xa: i64, xb: i64) -> i64
called by 1: dd_kat
305func dd_kat() -> i64
444func dd_classify(path: *u8) -> i64
488func dd_cat(dst: *u8, off: i64, src: *u8) -> i64 { var o: i64=off; var j: i64=0; while src[j]!=(0 as u8) { dst[o]=src[j]; o=o+1; j=j+1 } return o }
called by 2: dd_censusdd_sweep
490func dd_census(dir: *u8, maxn: i64) -> i64
565func dd_is_palette(path: *u8) -> i64
589func dd_endswith(nm: *u8, sfx: *u8) -> i64
called by 1: dd_sweep
610func dd_sweep(dir: *u8, maxn: i64, r: i64, thr: i64, scale: i64) -> i64
724func main(argc: i64, argv: *i64) -> i64