code wiki / _hdl_build / _codec_bench2.nx
_codec_bench2.nx source
↩ module page · 90 lines · 4294 B
1// _codec_bench2.nx -- Nishi-PNG vs real PNG filter set, SAME entropy stage (our deflate), SAME
2// corpus (no-wave, no external tool, no fabrication). For each frame, prefilter then deflate; PNG's
3// set = {Sub,Up,Avg,Paeth} whole-image-best; Nishi = MED (JPEG-LS median predictor, NOT in PNG's
4// set). Exceed iff MED+deflate < PNG-best+deflate. (Honest scope: whole-image filter not per-row;
5// real PNG does per-row best so this is a slightly-weak PNG -- noted. Synthetic frames are
6// LZ-friendly/unrepresentative; the real differentiator is photographic images.)
7import "nx_frame_codec.nx"
8import "nx_deflate_fixed.nx"
9import "nx_syscalls.nx"
10func bp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
11func bn(v: i64) -> i64 { let b: *u8=sys_mmap(28); var m: i64=v; var k: i64=0; let t: *u8=sys_mmap(28); if m==0{t[0]=48;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1}; sys_write(1,b,k); return 0 }
12func paeth(a: i64, b: i64, c: i64) -> i64 {
13 let p: i64 = a + b - c
14 var pa: i64 = p - a; if pa < 0 { pa = 0 - pa }
15 var pb: i64 = p - b; if pb < 0 { pb = 0 - pb }
16 var pc: i64 = p - c; if pc < 0 { pc = 0 - pc }
17 if pa <= pb { if pa <= pc { return a } }
18 if pb <= pc { return b }
19 return c
20}
21func medpred(a: i64, b: i64, c: i64) -> i64 {
22 var mx: i64 = a; if b > mx { mx = b }
23 var mn: i64 = a; if b < mn { mn = b }
24 if c >= mx { return mn }
25 if c <= mn { return mx }
26 return a + b - c
27}
28// mode: 0 none 1 sub(left) 2 up 3 avg 4 paeth 5 med
29func apply_filter(buf: *u8, w: i64, h: i64, res: *u8, mode: i64) -> i64 {
30 var y: i64 = 0
31 while y < h {
32 var x: i64 = 0
33 while x < w {
34 let idx: i64 = y * w + x
35 let cur: i64 = buf[idx] & 255
36 var a: i64 = 0
37 if x > 0 { a = buf[idx - 1] & 255 }
38 var b: i64 = 0
39 if y > 0 { b = buf[idx - w] & 255 }
40 var c: i64 = 0
41 if x > 0 { if y > 0 { c = buf[idx - w - 1] & 255 } }
42 var pred: i64 = 0
43 if mode == 1 { pred = a }
44 if mode == 2 { pred = b }
45 if mode == 3 { pred = (a + b) / 2 }
46 if mode == 4 { pred = paeth(a, b, c) }
47 if mode == 5 { pred = medpred(a, b, c) }
48 res[idx] = ((cur - pred) & 255) as u8
49 x = x + 1
50 }
51 y = y + 1
52 }
53 return 0
54}
55func bench_frame(label: *u8, buf: *u8, w: i64, h: i64, res: *u8, dfo: *u8) -> i64 {
56 let n: i64 = w * h
57 let cap: i64 = n * 4 + 64
58 apply_filter(buf, w, h, res, 1); let s_sub: i64 = dfl_encode(res, n, dfo, cap)
59 apply_filter(buf, w, h, res, 2); let s_up: i64 = dfl_encode(res, n, dfo, cap)
60 apply_filter(buf, w, h, res, 3); let s_avg: i64 = dfl_encode(res, n, dfo, cap)
61 apply_filter(buf, w, h, res, 4); let s_pae: i64 = dfl_encode(res, n, dfo, cap)
62 apply_filter(buf, w, h, res, 5); let s_med: i64 = dfl_encode(res, n, dfo, cap)
63 var png: i64 = s_sub
64 if s_up < png { png = s_up }
65 if s_avg < png { png = s_avg }
66 if s_pae < png { png = s_pae }
67 bp(label); bp(" sub="); bn(s_sub); bp(" up="); bn(s_up); bp(" avg="); bn(s_avg); bp(" paeth="); bn(s_pae)
68 bp(" | PNGbest="); bn(png); bp(" Nishi-MED="); bn(s_med); bp(" -> ")
69 var win: i64 = 0
70 if s_med < png { win = 1 }
71 if win == 1 { bp("MED WINS\n") } else { bp("png<=med\n") }
72 return win
73}
74func main() -> i64 {
75 let w: i64 = 32
76 let h: i64 = 32
77 let n: i64 = w * h
78 let buf: *u8 = sys_mmap(n + 64)
79 let res: *u8 = sys_mmap(n + 64)
80 let dfo: *u8 = sys_mmap(n * 4 + 64)
81 var wins: i64 = 0
82 fc_gen_gradient(buf, w, h); wins = wins + bench_frame("gradient" as *u8, buf, w, h, res, dfo)
83 fc_gen_checker(buf, w, h); wins = wins + bench_frame("checker " as *u8, buf, w, h, res, dfo)
84 fc_gen_edge(buf, w, h); wins = wins + bench_frame("edge " as *u8, buf, w, h, res, dfo)
85 fc_gen_extremes(buf, w, h); wins = wins + bench_frame("extremes" as *u8, buf, w, h, res, dfo)
86 fc_gen_noise(buf, w, h); wins = wins + bench_frame("noise " as *u8, buf, w, h, res, dfo)
87 bp("=== Nishi-MED+deflate beats PNG-best-filter+deflate on "); bn(wins); bp("/5 (same corpus, same entropy stage, no-wave) ===\n")
88 sys_exit(0)
89 return 0
90}