nx_facefind.nx source
↩ module page · 89 lines · 4729 B
1// nx_facefind.nx -- CLI over nx_facefind_lib (aesthetictwin AT30, 2026-09-16): the face box and both eye boxes of a
2// mirrored photograph, from the sovereign cascade evaluator over the loaded (beta-only, licensed) cascade data.
3// nx_facefind <jpeg> [min_face_permil] -> FACEFIND ... verdict=FOUND | NOFACE | NOEYES
4// exit: 0 found | 2 usage | 3 unreadable | 4 decode failed | 5 cascade refused | 6 no face | 7 no eyes
5// Sides follow the image: R is the eye on the image left (the subject's right in an unmirrored still).
6// license_tier: ORIGINAL No hw writes (Rule 26).
7import "nx_syscalls.nx"
8import "nx_jpeg_ascii.nx"
9import "nx_facefind_lib.nx"
10
11const FC_EXIT_USAGE: i64 = 2
12const FC_EXIT_READ: i64 = 3
13const FC_EXIT_DECODE: i64 = 4
14const FC_EXIT_CASCADE: i64 = 5
15const FC_EXIT_NOFACE: i64 = 6
16const FC_EXIT_NOEYES: i64 = 7
17const FC_ARGC_MIN: i64 = 2
18const FC_ARGC_PERMIL: i64 = 3
19const FC_I64: i64 = 8
20const FC_D0: i64 = 48
21const FC_D9: i64 = 57
22const FC_TEN: i64 = 10
23
24func fc_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
25func fc_putn(v: i64) -> i64 {
26 let b: *u8 = sys_mmap(32)
27 var m: i64 = v
28 var neg: i64 = 0
29 if m < 0 { neg = 1; m = 0 - m }
30 var k: i64 = 0
31 if m == 0 { b[0] = FC_D0 as u8; k = 1 }
32 while m > 0 { b[k] = (FC_D0 + (m % FC_TEN)) as u8; m = m / FC_TEN; k = k + 1 }
33 let o: *u8 = sys_mmap(34)
34 var j: i64 = 0
35 if neg == 1 { o[0] = 45 as u8; j = 1 }
36 var i: i64 = 0
37 while i < k { o[j + i] = b[k - 1 - i]; i = i + 1 }
38 sys_write(1, o, j + k)
39 return 0
40}
41func fc_kv(k: *u8, v: i64) -> i64 { fc_puts(k); fc_putn(v); return 0 }
42func fc_atoi(s: *u8) -> i64 {
43 var v: i64 = 0
44 var i: i64 = 0
45 while s[i] != (0 as u8) {
46 let c: i64 = s[i] as i64
47 if c >= FC_D0 { if c <= FC_D9 { v = v * FC_TEN + (c - FC_D0) } }
48 i = i + 1
49 }
50 return v
51}
52func main(argc: i64, argv: **u8) -> i64 {
53 if argc < FC_ARGC_MIN { fc_puts("usage: nx_facefind <jpeg> [min_face_permil]\n" as *u8); return FC_EXIT_USAGE }
54 let path: *u8 = argv[1]
55 var permil: i64 = FF_MIN_FACE_PERMIL
56 if argc >= FC_ARGC_PERMIL { permil = fc_atoi(argv[2]) }
57 if permil <= 0 { permil = FF_MIN_FACE_PERMIL }
58 let fl: *i64 = sys_mmap(16) as *i64
59 fl[0] = 0
60 let jpeg: *u8 = sys_read_file(path, fl)
61 if (jpeg as i64) == 0 { fc_puts("FACEFIND unreadable\n" as *u8); return FC_EXIT_READ }
62 if fl[0] <= 0 { fc_puts("FACEFIND unreadable\n" as *u8); return FC_EXIT_READ }
63 let pp: *i64 = sys_mmap(FC_I64) as *i64
64 let pw: *i64 = sys_mmap(FC_I64) as *i64
65 let ph: *i64 = sys_mmap(FC_I64) as *i64
66 let ps: *i64 = sys_mmap(FC_I64) as *i64
67 let drc: i64 = nx_jpeg_decode_luma(jpeg, fl[0], pp, pw, ph, ps)
68 if drc != NX_JPEG_ASCII_OK { fc_kv("FACEFIND decode-failed rc=" as *u8, drc); fc_puts("\n" as *u8); return FC_EXIT_DECODE }
69 let rc: *i64 = sys_mmap(FC_I64) as *i64
70 let face_c: *HaarCascade = ff_load_face(rc)
71 if (face_c as i64) == 0 { fc_kv("FACEFIND cascade-refused face rc=" as *u8, rc[0]); fc_puts("\n" as *u8); return FC_EXIT_CASCADE }
72 let eye_c: *HaarCascade = ff_load_eye(rc)
73 if (eye_c as i64) == 0 { fc_kv("FACEFIND cascade-refused eye rc=" as *u8, rc[0]); fc_puts("\n" as *u8); return FC_EXIT_CASCADE }
74 let res: *i64 = sys_mmap(FF_R_N * FC_I64) as *i64
75 let frc: i64 = ff_find(face_c, eye_c, pp[0] as *u8, pw[0], ph[0], ps[0], permil, res)
76 fc_puts("FACEFIND file=" as *u8); fc_puts(path)
77 fc_kv(" w=" as *u8, pw[0]); fc_kv(" h=" as *u8, ph[0]); fc_kv(" min_face_permil=" as *u8, permil)
78 fc_kv(" raw=" as *u8, res[FF_R_RAW]); fc_kv(" groups=" as *u8, res[FF_R_GROUPS]); fc_kv(" capped=" as *u8, res[FF_R_CAPPED])
79 fc_kv(" face=" as *u8, res[FF_R_FACE])
80 fc_kv(" box=" as *u8, res[FF_R_FX]); fc_kv("," as *u8, res[FF_R_FY]); fc_kv("," as *u8, res[FF_R_FW]); fc_kv("," as *u8, res[FF_R_FH]); fc_kv(" votes=" as *u8, res[FF_R_FVOTES])
81 fc_kv(" eye_raw=" as *u8, res[FF_R_EYE_RAW]); fc_kv(" eye_groups=" as *u8, res[FF_R_EYE_GROUPS]); fc_kv(" eyes=" as *u8, res[FF_R_EYES])
82 fc_kv(" R=" as *u8, res[FF_R_RX]); fc_kv("," as *u8, res[FF_R_RY]); fc_kv("," as *u8, res[FF_R_RW]); fc_kv("," as *u8, res[FF_R_RH])
83 fc_kv(" L=" as *u8, res[FF_R_LX]); fc_kv("," as *u8, res[FF_R_LY]); fc_kv("," as *u8, res[FF_R_LW]); fc_kv("," as *u8, res[FF_R_LH])
84 fc_kv(" eye_votes=" as *u8, res[FF_R_RVOTES]); fc_kv("," as *u8, res[FF_R_LVOTES]); fc_kv(" face_rank=" as *u8, res[FF_R_FACE_RANK])
85 if frc == FF_E_NOFACE { fc_puts(" verdict=NOFACE\n" as *u8); return FC_EXIT_NOFACE }
86 if frc == FF_E_NOEYES { fc_puts(" verdict=NOEYES\n" as *u8); return FC_EXIT_NOEYES }
87 fc_puts(" verdict=FOUND\n" as *u8)
88 return 0
89}