code wiki / (root) / nx_phash_test.nx

nx_phash_test.nx source

↩ module page · 75 lines · 3354 B

1// nx_phash_test.nx -- KAT + benchmark for perceptual image hashing. 2// Native sovereign lane; exit 0 = pass, N = assertion N failed. 3// Prints the measured Hamming distances (the benchmark), then asserts the 4// research-documented properties: deterministic; INVARIANT to uniform 5// brightness (dHash's defining property); near-dup strictly closer than a 6// different image; reverse-image lookup returns the right image. 7 8import "fx.nx" 9import "nx_phash.nx" 10 11func nx_putc(c: i64) -> i64 { let b: *u8 = sys_mmap(1); b[0] = c; sys_write(1, b, 1); return 0 } 12func nx_puts(s: *u8) -> i64 { var i: i64 = 0; while (s[i] as i64) != 0 { nx_putc(s[i] as i64); i = i + 1 } return 0 } 13func nx_put_i64(n: i64) -> i64 { 14 if n == 0 { nx_putc(0x30); return 0 } 15 var v: i64 = n; let t: *u8 = sys_mmap(32); var k: i64 = 0 16 while v > 0 { t[k] = 0x30 + (v - (v/10)*10); v = v/10; k = k+1 } 17 while k > 0 { k = k-1; sys_write(1, (((t as i64)+k) as *u8), 1) } 18 return 0 19} 20 21func main() -> i64 { 22 let W: i64 = 16 23 let H: i64 = 16 24 let a: *u8 = sys_mmap(W * H) 25 let ab: *u8 = sys_mmap(W * H) 26 let b: *u8 = sys_mmap(W * H) 27 let an: *u8 = sys_mmap(W * H) 28 var y: i64 = 0 29 while y < H { 30 var x: i64 = 0 31 while x < W { 32 let va: i64 = (x * 37 + y * 17) & 0x3F // pattern A, 0..63 33 a[y * W + x] = va 34 ab[y * W + x] = va + 40 // +40 brightness (no saturation) 35 b[y * W + x] = (y * 37 + x * 17) & 0x3F // different structure (x/y swapped) 36 an[y * W + x] = va // near-dup base (block tweaked below) 37 x = x + 1 38 } 39 y = y + 1 40 } 41 var by: i64 = 2 42 while by < 5 { var bx: i64 = 2; while bx < 5 { an[by * W + bx] = 63; bx = bx + 1 } by = by + 1 } 43 44 let fa: i64 = nx_phash_dhash(a, W, H) 45 let fa2: i64 = nx_phash_dhash(a, W, H) 46 let fab: i64 = nx_phash_dhash(ab, W, H) 47 let fb: i64 = nx_phash_dhash(b, W, H) 48 let fan: i64 = nx_phash_dhash(an, W, H) 49 50 let h_self: i64 = nx_simhash_hamming(fa, fa2) 51 let h_bright: i64 = nx_simhash_hamming(fa, fab) 52 let h_near: i64 = nx_simhash_hamming(fa, fan) 53 let h_diff: i64 = nx_simhash_hamming(fa, fb) 54 55 nx_puts("== dHash benchmark (Hamming /64) ==\n") 56 nx_puts(" identical : "); nx_put_i64(h_self); nx_putc(0x0A) 57 nx_puts(" +brightness : "); nx_put_i64(h_bright); nx_putc(0x0A) 58 nx_puts(" near-dup (block) : "); nx_put_i64(h_near); nx_putc(0x0A) 59 nx_puts(" different image : "); nx_put_i64(h_diff); nx_putc(0x0A) 60 61 if h_self != 0 { return 1 } // deterministic 62 if h_bright != 0 { return 2 } // INVARIANT to uniform brightness (dHash property) 63 if h_near >= h_diff { return 3 } // near-dup strictly closer than a different image 64 65 // reverse-image: a brightness-shifted A, searched among {A, B}, finds A 66 let set: *i64 = sys_mmap(2 * 8) as *i64 67 set[0] = fa; set[1] = fb 68 let hb: *i64 = sys_mmap(8) as *i64 69 if nx_phash_nearest(fab, set, 2, 10, hb) != 0 { return 4 } 70 nx_puts(" reverse-image : +brightness A -> matched index 0 (A) at Hamming "); nx_put_i64(hb[0]); nx_putc(0x0A) 71 // B searched among {A,B} matches itself 72 if nx_phash_nearest(fb, set, 2, 10, hb) != 1 { return 5 } 73 74 return 0 75}