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}