code wiki / _hdl_build / nx_image_symmetry_lib.nx
nx_image_symmetry_lib.nx source
↩ module page · 66 lines · 2945 B
1// nx_image_symmetry_lib.nx -- shared ImageBeauty core (NO main), so both the nx_image_beauty tool AND the nx_gen_rank
2// tool score with ONE source of truth (OO/DRY, per the consolidate-via-atlas directive). go_image_symmetry = the
3// objective_beauty.py _bilateral_symmetry integer port on the proven nx_png_decode. Object model: companion_arch.md.
4// license_tier: ORIGINAL
5import "nx_syscalls.nx"
6import "nx_png_decoder.nx"
7const K_MAGIC_1024: i64 = 1024
8
9func ib_itoa(dst: *u8, off: i64, v: i64) -> i64 { let t: *u8=sys_mmap(28); var m: i64=v; var neg: i64=0; if m<0 {neg=1; m=0-m} var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var o: i64=off; if neg==1 {dst[o]=45 as u8; o=o+1} var q: i64=k-1; while q>=0{dst[o]=t[q];o=o+1;q=q-1} return o }
10func ib_cat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64=off; var i: i64=0; while s[i]!=(0 as u8){dst[o]=s[i]; o=o+1; i=i+1} return o }
11
12// bilateral symmetry Q1000 (1000 = perfect mirror). returns -1 decode-null, -2 decode-error.
13func go_image_symmetry(png: *u8, plen: i64) -> i64 {
14 let r: *NxPngResult = nx_png_decode(png, plen)
15 if (r as i64) == 0 { return 0 - 1 }
16 if r.error_code != NX_PNG_OK { return 0 - 2 }
17 let w: i64 = r.header.width
18 let h: i64 = r.header.height
19 let ch: i64 = r.n_channels
20 let px: *u8 = r.pixels
21 if w < 2 { return 1000 }
22 var totaldiff: i64 = 0; var count: i64 = 0
23 let half: i64 = w / 2
24 var y: i64 = 0
25 while y < h {
26 var x: i64 = 0
27 while x < half {
28 let xr: i64 = w - 1 - x
29 var c: i64 = 0
30 while c < ch {
31 var a: i64 = px[(y*w+x)*ch+c] & 0xff
32 var b: i64 = px[(y*w+xr)*ch+c] & 0xff
33 var d: i64 = a - b; if d < 0 { d = 0 - d }
34 totaldiff = totaldiff + d; count = count + 1
35 c = c + 1
36 }
37 x = x + 1
38 }
39 y = y + 1
40 }
41 if count == 0 { return 1000 }
42 let meandiff: i64 = totaldiff / count
43 var score: i64 = 1000 - meandiff * 1000 / 80
44 if score < 0 { score = 0 }
45 return score
46}
47// score a gallery image BY CID (traversal-safe: fixed prefix + [A-Za-z0-9-] cid + .png). returns Q1000, or <0 on error.
48func go_score_cid(cid: *u8) -> i64 {
49 let path: *u8 = sys_mmap(K_MAGIC_1024); var po: i64 = ib_cat(path, 0, "/volume1/ai/gen/blob-" as *u8)
50 var ci: i64 = 0
51 while cid[ci]!=(0 as u8) {
52 let c: i64 = cid[ci]&0xff
53 var ok: i64 = 0
54 if c>=48 { if c<=57 { ok=1 } }
55 if c>=65 { if c<=90 { ok=1 } }
56 if c>=97 { if c<=122 { ok=1 } }
57 if c==45 { ok=1 }
58 if ok==1 { if po < 1000 { path[po]=cid[ci]; po=po+1 } }
59 ci=ci+1
60 }
61 po = ib_cat(path, po, ".png" as *u8); path[po]=0 as u8
62 let lp: *i64 = sys_mmap(16) as *i64
63 let png: *u8 = sys_read_file(path, lp)
64 if (png as i64) == 0 { return 0 - 3 }
65 return go_image_symmetry(png, lp[0])
66}