nx_mediajudge.nx source
↩ module page · 58 lines · 4579 B
1// nx_mediajudge.nx -- aesthetictwin AT36 (2026-09-17): the CLI over nx_mediajudge_lib. Submitted media through the beauty
2// rulers with a report: the still is decoded by the estate's chokepoint (JPEG, PNG, GIF first frame, WebP lossless, BMP,
3// TIFF, TGA, PCX, ICO, PNM; an APNG is judged on its first frame with the frame count announced), measured by the photo
4// ruler, the skin ruler and the symmetry judge, and the outputs land beside each other in <outdir>: the original copy, the
5// overlay PNG of what the rulers saw, the manifest in nx_asset_page's row shape, the slug-keyed plane staging file for
6// nx_store_seed (nx_asset_page emit reads the asset plane) and the judge file in the estate's pipe grammar.
7// nx_mediajudge judge <slug> <file> <outdir> [oracle-file|-] [href-prefix] -> MEDIAJUDGE receipt line
8// href-prefix is the site-absolute path the published page's asset hrefs carry (/compare/<dom>/media/<slug>/): the edge
9// 301-strips trailing slashes, so a relative href resolves against the PARENT and nx_page_verify names it BROKEN-BY-LAW.
10// exit: 0 ok | 2 usage | 3 unreadable | 4 no decoder took the bytes | 5 an output refused
11// license_tier: ORIGINAL No hw writes (Rule 26).
12import "nx_syscalls.nx"
13import "nx_mediajudge_lib.nx"
14
15const MJC_EXIT_USAGE: i64 = 2
16const MJC_EXIT_READ: i64 = 3
17const MJC_EXIT_DECODE: i64 = 4
18const MJC_EXIT_WRITE: i64 = 5
19const MJC_ARGC_JUDGE: i64 = 5
20const MJC_ARGC_JUDGE_ORACLE: i64 = 6
21const MJC_ARGC_JUDGE_HREF: i64 = 7
22const MJC_NO_ORACLE: *u8 = "-"
23
24func mjc_usage() -> i64 { ri_puts("usage: nx_mediajudge judge <slug> <file> <outdir> [oracle-file|-] [href-prefix]\n" as *u8); return MJC_EXIT_USAGE }
25func mjc_kv(k: *u8, v: i64) -> i64 { ri_puts(k); ri_putn(v); return 0 }
26
27func main(argc: i64, argv: **u8) -> i64 {
28 if argc < MJC_ARGC_JUDGE { return mjc_usage() }
29 if ri_streq(argv[1], "judge" as *u8) == 0 { return mjc_usage() }
30 var oracle: *u8 = "" as *u8
31 if argc >= MJC_ARGC_JUDGE_ORACLE { if ri_streq(argv[5], MJC_NO_ORACLE) == 0 { oracle = argv[5] } }
32 var hrefpfx: *u8 = "" as *u8
33 if argc >= MJC_ARGC_JUDGE_HREF { hrefpfx = argv[6] }
34 let cs: *i64 = sys_mmap(2 * MJ_I64) as *i64
35 let loaded: i64 = mj_load_cascades(cs)
36 let res: *i64 = sys_mmap(PM_R_N * MJ_I64) as *i64
37 let sres: *i64 = sys_mmap(SKS_R_N * MJ_I64) as *i64
38 let out: *i64 = sys_mmap(MJ_R_N * MJ_I64) as *i64
39 let r: i64 = mj_judge_file_at(argv[3], argv[2], argv[4], oracle, hrefpfx, cs[0] as *HaarCascade, cs[1] as *HaarCascade, res, sres, out)
40 ri_puts("MEDIAJUDGE slug=" as *u8); ri_puts(argv[2]); ri_puts(" file=" as *u8); ri_puts(argv[3])
41 mjc_kv(" cascades_loaded=" as *u8, loaded)
42 if r == MJ_E_READ { ri_puts(" verdict=UNREADABLE\n" as *u8); return MJC_EXIT_READ }
43 if r == MJ_E_DECODE { mjc_kv(" bytes=" as *u8, out[MJ_R_ORIGINAL_BYTES]); ri_puts(" verdict=NO-DECODER-TOOK-THE-BYTES\n" as *u8); return MJC_EXIT_DECODE }
44 mjc_kv(" w=" as *u8, out[MJ_R_W]); mjc_kv(" h=" as *u8, out[MJ_R_H]); mjc_kv(" codec=" as *u8, out[MJ_R_CODEC])
45 mjc_kv(" frames=" as *u8, out[MJ_R_FRAMES]); mjc_kv(" frames_capped=" as *u8, out[MJ_R_FRAMES_CAPPED])
46 mjc_kv(" ruler_rc=" as *u8, out[MJ_R_RULER_RC]); mjc_kv(" route=" as *u8, res[PM_R_ROUTE])
47 mjc_kv(" face=" as *u8, res[PM_R_FACE]); mjc_kv(" eyes=" as *u8, res[PM_R_EYES]); mjc_kv(" mouth=" as *u8, res[PM_R_MOUTH])
48 mjc_kv(" tilt_R_deg10=" as *u8, res[PM_R_TILT_R]); mjc_kv(" tilt_L_deg10=" as *u8, res[PM_R_TILT_L])
49 mjc_kv(" ici_permil=" as *u8, res[PM_R_ICI]); mjc_kv(" icf_permil=" as *u8, res[PM_R_ICF]); mjc_kv(" lip_permil=" as *u8, res[PM_R_LIP])
50 mjc_kv(" skin_L_e3=" as *u8, sres[SKS_R_L]); mjc_kv(" skin_ita_deg10=" as *u8, sres[SKS_R_ITA]); mjc_kv(" skin_pixels=" as *u8, sres[SKS_R_COUNT])
51 mjc_kv(" symmetry_q1000=" as *u8, out[MJ_R_SYMMETRY])
52 mjc_kv(" referee_judged=" as *u8, out[MJ_R_REFEREE_JUDGED]); mjc_kv(" referee_found=" as *u8, out[MJ_R_REFEREE_FOUND]); mjc_kv(" referee_nme_max=" as *u8, out[MJ_R_REFEREE_NME_MAX])
53 mjc_kv(" overlay_bytes=" as *u8, out[MJ_R_OVERLAY_BYTES]); mjc_kv(" manifest_bytes=" as *u8, out[MJ_R_MANIFEST_BYTES]); mjc_kv(" plane_bytes=" as *u8, out[MJ_R_PLANE_BYTES]); mjc_kv(" judge_rows=" as *u8, out[MJ_R_JUDGE_ROWS]); mjc_kv(" gap_rows=" as *u8, out[MJ_R_GAP_ROWS])
54 ri_puts(" href_prefix=" as *u8); ri_puts(hrefpfx)
55 if r == MJ_E_WRITE { ri_puts(" verdict=OUTPUT-REFUSED\n" as *u8); return MJC_EXIT_WRITE }
56 if res[PM_R_EYES] == 2 { ri_puts(" verdict=MEASURED\n" as *u8) } else { ri_puts(" verdict=JUDGED-NO-EYE-PAIR\n" as *u8) }
57 return 0
58}