code wiki / (root) / nx_facefind.nx

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}