nx_photomark.nx source
↩ module page · 155 lines · 11887 B
1// nx_photomark.nx -- CLI over nx_photomark_lib (aesthetictwin AT4 / AT23 / AT30 / AT31, 2026-09-16): landmarks and scale-free
2// face axes MEASURED from a mirrored photograph, written onto a twin card with a side per eye, and the referee that scores
3// the ruler against the outside oracle rows.
4// nx_photomark measure <jpeg|png> -> codec, route, face box, eye bands, both canthi of each eye, roll, tilt per
5// side (raw and roll-corrected), canon ratios, mouth
6// nx_photomark card <slug> <refkey> <jpeg|png> <when> -> measure, then append canthal_tilt L/R, intercanthal_index,
7// intercanthal_eq_fissure and (when the mouth was seen) upper_over_lower_lip
8// nx_photomark referee <oracle-file> [dir] -> every oracle row against the ruler: per-still NME per canthus and a partition;
9// AT44: per mouth landmark too, as the ruler places it and anchored on the
10// oracle's canthi, each with its own partition
11// measure (AT44) also prints the fissure windows and any canthus pinned to one, and the mouth as five landmarks with its named reason
12// exit: 0 ok | 2 usage | 3 unreadable | 4 decode failed | 5 UNMEASURED (no face or no eye pair) | 6 rows exist
13// The cascade route is taken when the two cascade files load (knowledge/fetched/cmp_aesthetictwin_haar_*.xml, beta-only
14// data); otherwise the skin route, and the receipt names the route. Sides follow the image: the eye on the image left is
15// the subject's RIGHT eye; a mirrored still swaps them. A PNG (an estate render, e.g. nx_anat_sov output) reads through
16// the same door as a JPEG still, so one ruler measures the reference and the twin; the receipt names the codec (1 JPEG, 2 PNG).
17// license_tier: ORIGINAL No hw writes (Rule 26).
18import "nx_syscalls.nx"
19import "nx_photomark_lib.nx"
20
21const PMC_EXIT_USAGE: i64 = 2
22const PMC_EXIT_READ: i64 = 3
23const PMC_EXIT_DECODE: i64 = 4
24const PMC_EXIT_UNMEASURED: i64 = 5
25const PMC_EXIT_EXISTS: i64 = 6
26const PMC_ARGC_MEASURE: i64 = 3
27const PMC_ARGC_CARD: i64 = 6
28const PMC_ARGC_REFEREE: i64 = 3
29const PMC_ARGC_REFEREE_DIR: i64 = 4
30const PMC_I64: i64 = 8
31
32func pmc_usage() -> i64 {
33 ri_puts("usage: nx_photomark measure <jpeg|png> | card <slug> <refkey> <jpeg|png> <when> | referee <oracle-file> [dir]\n" as *u8)
34 return PMC_EXIT_USAGE
35}
36func pmc_kv(k: *u8, v: i64) -> i64 { ri_puts(k); ri_putn(v); return 0 }
37func pmc_report(path: *u8, res: *i64) -> i64 {
38 ri_puts("PHOTOMARK file=" as *u8); ri_puts(path)
39 pmc_kv(" w=" as *u8, res[PM_R_W]); pmc_kv(" h=" as *u8, res[PM_R_H]); pmc_kv(" codec=" as *u8, res[PM_R_CODEC]); pmc_kv(" route=" as *u8, res[PM_R_ROUTE]); pmc_kv(" cell=" as *u8, res[PM_R_CELL])
40 pmc_kv(" face=" as *u8, res[PM_R_FACE]); pmc_kv(" face_cells=" as *u8, res[PM_R_FACE_CELLS]); pmc_kv(" face_votes=" as *u8, res[PM_R_FVOTES])
41 pmc_kv(" face_box=" as *u8, res[PM_R_FX0]); pmc_kv("," as *u8, res[PM_R_FY0]); pmc_kv("," as *u8, res[PM_R_FX1]); pmc_kv("," as *u8, res[PM_R_FY1])
42 pmc_kv(" dark_blobs=" as *u8, res[PM_R_BLOBS]); pmc_kv(" blobs_capped=" as *u8, res[PM_R_BLOBS_CAPPED])
43 pmc_kv(" head_box=" as *u8, res[PM_R_HX0]); pmc_kv("," as *u8, res[PM_R_HY0]); pmc_kv("," as *u8, res[PM_R_HX1]); pmc_kv("," as *u8, res[PM_R_HY1])
44 pmc_kv(" eye_band_R=" as *u8, res[PM_R_EX0]); pmc_kv("," as *u8, res[PM_R_EY0]); pmc_kv("," as *u8, res[PM_R_EX1]); pmc_kv("," as *u8, res[PM_R_EY1])
45 pmc_kv(" eye_band_L=" as *u8, res[PM_R_LX0]); pmc_kv("," as *u8, res[PM_R_LY0]); pmc_kv("," as *u8, res[PM_R_LX1]); pmc_kv("," as *u8, res[PM_R_LY1])
46 pmc_kv(" eye_votes=" as *u8, res[PM_R_EYE_VOTES_R]); pmc_kv("," as *u8, res[PM_R_EYE_VOTES_L])
47 pmc_kv(" eyes=" as *u8, res[PM_R_EYES]); pmc_kv(" pair_fail=" as *u8, res[PM_R_PAIR_FAIL])
48 pmc_kv(" fissure_window_R=" as *u8, res[PM_R_EYE_WX0]); pmc_kv("," as *u8, res[PM_R_EYE_WX1]); pmc_kv(" fissure_window_L=" as *u8, res[PM_R_EYE_LWX0]); pmc_kv("," as *u8, res[PM_R_EYE_LWX1])
49 pmc_kv(" pinned_bits=" as *u8, res[PM_R_PINNED])
50 ri_puts("\n" as *u8)
51 if res[PM_R_ROUTE] == PM_ROUTE_SKIN {
52 ri_puts("PHOTOMARK top_blobs(x0,y0,x1,y1:cells)" as *u8)
53 var tb: i64 = 0
54 while tb < PM_TOP_BLOBS { let sl: i64 = PM_R_TB + tb * PM_TB_FIELDS; if res[sl + 4] > 0 { pmc_kv(" b=" as *u8, res[sl]); pmc_kv("," as *u8, res[sl + 1]); pmc_kv("," as *u8, res[sl + 2]); pmc_kv("," as *u8, res[sl + 3]); pmc_kv(":" as *u8, res[sl + 4]) } tb = tb + 1 }
55 ri_puts("\n" as *u8)
56 }
57 if res[PM_R_EYES] == 2 {
58 ri_puts("PHOTOMARK canthi(image x,y; sides by the image, unmirrored assumed)" as *u8)
59 pmc_kv(" R_lateral=" as *u8, res[PM_R_RLAT_X]); pmc_kv("," as *u8, res[PM_R_RLAT_Y])
60 pmc_kv(" R_medial=" as *u8, res[PM_R_RMED_X]); pmc_kv("," as *u8, res[PM_R_RMED_Y])
61 pmc_kv(" L_medial=" as *u8, res[PM_R_LMED_X]); pmc_kv("," as *u8, res[PM_R_LMED_Y])
62 pmc_kv(" L_lateral=" as *u8, res[PM_R_LLAT_X]); pmc_kv("," as *u8, res[PM_R_LLAT_Y])
63 pmc_kv(" eye_pixels_R=" as *u8, res[PM_R_EYE_PIX_R]); pmc_kv(" eye_pixels_L=" as *u8, res[PM_R_EYE_PIX_L])
64 ri_puts("\n" as *u8)
65 ri_puts("PHOTOMARK axes" as *u8)
66 pmc_kv(" roll_deg10=" as *u8, res[PM_R_ROLL])
67 pmc_kv(" canthal_tilt_R_deg10=" as *u8, res[PM_R_TILT_R]); pmc_kv(" canthal_tilt_L_deg10=" as *u8, res[PM_R_TILT_L])
68 pmc_kv(" tilt_R_raw_deg10=" as *u8, res[PM_R_TILT_R_RAW]); pmc_kv(" tilt_L_raw_deg10=" as *u8, res[PM_R_TILT_L_RAW])
69 pmc_kv(" fissure_R_px=" as *u8, res[PM_R_FISSURE_R]); pmc_kv(" fissure_L_px=" as *u8, res[PM_R_FISSURE_L]); pmc_kv(" tilt_err_deg10=" as *u8, res[PM_R_TILT_ERR]); pmc_kv(" tilt_row_ok=" as *u8, res[PM_R_TILT_OK])
70 pmc_kv(" intercanthal_index_permil=" as *u8, res[PM_R_ICI]); pmc_kv(" intercanthal_eq_fissure_permil=" as *u8, res[PM_R_ICF])
71 pmc_kv(" mouth=" as *u8, res[PM_R_MOUTH]); ri_puts(" mouth_why=" as *u8); ri_puts(pm_mouth_why_name(res[PM_R_MOUTH_WHY]))
72 pmc_kv(" seam_px=" as *u8, res[PM_R_MOUTH_PIX]); pmc_kv(" seam_strength=" as *u8, res[PM_R_SEAM_STRENGTH]); pmc_kv(" seam_floor=" as *u8, res[PM_R_SEAM_FLOOR]); pmc_kv(" seam_hyp=" as *u8, res[PM_R_SEAM_HYP]); pmc_kv(" seam_probe_px=" as *u8, res[PM_R_SEAM_PROBE]); pmc_kv(" lip_reach_px=" as *u8, res[PM_R_LIP_REACH]); pmc_kv("," as *u8, res[PM_R_LIP_REACH_LO])
73 pmc_kv(" mouth_box=" as *u8, res[PM_R_MX0]); pmc_kv("," as *u8, res[PM_R_MY0]); pmc_kv("," as *u8, res[PM_R_MX1]); pmc_kv("," as *u8, res[PM_R_MY1])
74 pmc_kv(" stomion_y=" as *u8, res[PM_R_STOMION_Y]); pmc_kv(" upper_over_lower_lip_permil=" as *u8, res[PM_R_LIP])
75 ri_puts("\n" as *u8)
76 // AT44: the mouth as five landmarks, published whether or not the mouth passed (what was found before what was refused)
77 ri_puts("PHOTOMARK mouth(image x,y)" as *u8)
78 pmc_kv(" labrale_superius=" as *u8, res[PM_R_LS_X]); pmc_kv("," as *u8, res[PM_R_LS_Y])
79 pmc_kv(" stomion=" as *u8, res[PM_R_STO_X]); pmc_kv("," as *u8, res[PM_R_STO_Y])
80 pmc_kv(" labrale_inferius=" as *u8, res[PM_R_LI_X]); pmc_kv("," as *u8, res[PM_R_LI_Y])
81 pmc_kv(" cheilion_R=" as *u8, res[PM_R_CHR_X]); pmc_kv("," as *u8, res[PM_R_CHR_Y])
82 pmc_kv(" cheilion_L=" as *u8, res[PM_R_CHL_X]); pmc_kv("," as *u8, res[PM_R_CHL_Y])
83 ri_puts("\n" as *u8)
84 }
85 if res[PM_R_EYES] != 2 { if res[PM_R_PAIR_FAIL] != PM_PF_NONE {
86 // PUBLISH WHAT WAS FOUND BEFORE DECIDING WHAT COULD NOT BE. The four canthi exist before the pair check refuses them, and a
87 // refusal that prints only its code cannot say whether the pair missed by a hair or by a mile -- MEASURED 2026-09-18, a
88 // mirror-symmetric render passed the asymmetry check at 305 of 350 permil and a lower-face edit alone then tipped it over,
89 // which only these numbers could show
90 let frw: i64 = pm_dist(res[PM_R_RLAT_X], res[PM_R_RLAT_Y], res[PM_R_RMED_X], res[PM_R_RMED_Y])
91 let flw: i64 = pm_dist(res[PM_R_LMED_X], res[PM_R_LMED_Y], res[PM_R_LLAT_X], res[PM_R_LLAT_Y])
92 ri_puts("PHOTOMARK pair_refused_candidates(image x,y)" as *u8)
93 pmc_kv(" R_lateral=" as *u8, res[PM_R_RLAT_X]); pmc_kv("," as *u8, res[PM_R_RLAT_Y])
94 pmc_kv(" R_medial=" as *u8, res[PM_R_RMED_X]); pmc_kv("," as *u8, res[PM_R_RMED_Y])
95 pmc_kv(" L_medial=" as *u8, res[PM_R_LMED_X]); pmc_kv("," as *u8, res[PM_R_LMED_Y])
96 pmc_kv(" L_lateral=" as *u8, res[PM_R_LLAT_X]); pmc_kv("," as *u8, res[PM_R_LLAT_Y])
97 pmc_kv(" fissure_R_px=" as *u8, frw); pmc_kv(" fissure_L_px=" as *u8, flw)
98 pmc_kv(" asym_permil=" as *u8, pm_abs(frw - flw) * PM_PERMIL / pm_max(pm_max(frw, flw), 1)); pmc_kv(" asym_limit_permil=" as *u8, PM_FISSURE_ASYM_PERMIL)
99 pmc_kv(" eye_pixels_R=" as *u8, res[PM_R_EYE_PIX_R]); pmc_kv(" eye_pixels_L=" as *u8, res[PM_R_EYE_PIX_L])
100 ri_puts("\n" as *u8)
101 } }
102 return 0
103}
104func pmc_load(rc: *i64, out: *i64) -> i64 {
105 let face_c: *HaarCascade = ff_load_face(rc)
106 let eye_c: *HaarCascade = ff_load_eye(rc)
107 out[0] = face_c as i64
108 out[1] = eye_c as i64
109 if (face_c as i64) == 0 { return 0 }
110 if (eye_c as i64) == 0 { return 0 }
111 return 1
112}
113func main(argc: i64, argv: **u8) -> i64 {
114 if argc < PMC_ARGC_MEASURE { return pmc_usage() }
115 let verb: *u8 = argv[1]
116 let rc: *i64 = sys_mmap(PMC_I64) as *i64
117 let cs: *i64 = sys_mmap(2 * PMC_I64) as *i64
118 let loaded: i64 = pmc_load(rc, cs)
119 let face_c: *HaarCascade = cs[0] as *HaarCascade
120 let eye_c: *HaarCascade = cs[1] as *HaarCascade
121 if ri_streq(verb, "referee" as *u8) == 1 {
122 var dir: *u8 = PM_DEFAULT_DIR
123 if argc >= PMC_ARGC_REFEREE_DIR { dir = argv[3] }
124 pmc_kv("REFEREE cascades_loaded=" as *u8, loaded); ri_puts("\n" as *u8)
125 let judged: i64 = pm_referee(argv[2], dir, face_c, eye_c)
126 if judged == PM_E_READ { ri_puts("REFEREE oracle file unreadable\n" as *u8); return PMC_EXIT_READ }
127 return 0
128 }
129 let res: *i64 = sys_mmap(PM_R_N * PMC_I64) as *i64
130 if ri_streq(verb, "measure" as *u8) == 1 {
131 let r: i64 = pm_landmarks_file_auto(argv[2], res, face_c, eye_c)
132 if r == PM_E_READ { ri_puts("PHOTOMARK unreadable\n" as *u8); return PMC_EXIT_READ }
133 if r == PM_E_DECODE { ri_puts("PHOTOMARK decode failed\n" as *u8); return PMC_EXIT_DECODE }
134 pmc_kv("PHOTOMARK cascades_loaded=" as *u8, loaded); ri_puts("\n" as *u8)
135 pmc_report(argv[2], res)
136 if r == PM_E_NOFACE { ri_puts("PHOTOMARK verdict=UNMEASURED no face\n" as *u8); return PMC_EXIT_UNMEASURED }
137 if r == PM_E_NOEYES { ri_puts("PHOTOMARK verdict=UNMEASURED no eye pair passed the pair check\n" as *u8); return PMC_EXIT_UNMEASURED }
138 ri_puts("PHOTOMARK verdict=MEASURED\n" as *u8)
139 return 0
140 }
141 if ri_streq(verb, "card" as *u8) == 1 {
142 if argc < PMC_ARGC_CARD { return pmc_usage() }
143 let r: i64 = pm_landmarks_file_auto(argv[4], res, face_c, eye_c)
144 if r == PM_E_READ { ri_puts("PHOTOMARK unreadable\n" as *u8); return PMC_EXIT_READ }
145 if r == PM_E_DECODE { ri_puts("PHOTOMARK decode failed\n" as *u8); return PMC_EXIT_DECODE }
146 pmc_report(argv[4], res)
147 if r != PM_OK { ri_puts("PHOTOMARK verdict=UNMEASURED nothing written\n" as *u8); return PMC_EXIT_UNMEASURED }
148 let n: i64 = pm_card_write(argv[2], argv[3], argv[5], res)
149 if n == PM_E_EXISTS { ri_puts("PHOTOMARK card rows exist -- refused\n" as *u8); return PMC_EXIT_EXISTS }
150 if n == PM_E_READ { ri_puts("PHOTOMARK card unreadable\n" as *u8); return PMC_EXIT_READ }
151 pmc_kv("PHOTOMARK card rows_appended=" as *u8, n); ri_puts(" verdict=MEASURED\n" as *u8)
152 return 0
153 }
154 return pmc_usage()
155}