code wiki / _hdl_build / nx_extract.nx
nx_extract.nx source
↩ module page · 149 lines · 7014 B
1// nx_extract.nx -- MLIB-006 (CALLOUT-012). Per-type EXTRACTORS: raw media bytes -> typed facts
2// -> a validated meta record (PROFILE of nx_meta_schema, X-CAP-001). v1 ships THREE REAL parsers
3// (no fakes), each KAT'd bit-stable:
4// - STL (ASCII): triangle count ("facet normal") + bounding-box dims from vertices.
5// - GIF (header): GIF89a magic + logical-screen width/height (LE u16).
6// - TEXT : word + char count (searchable-text basis).
7// Each extraction builds a meta record (modality + attr.* facts) validated via ms_valid (consent
8// hard line). Binary EPUB/PDF + JPEG/PNG/video thumbnails + audio (NV-LPC) ride the existing
9// image/audio organs = the next slice. Self-validating gate (EXTRACTGATE). license_tier: ORIGINAL
10import "nx_syscalls.nx"
11import "nx_meta_schema.nx"
12const K_MAGIC_1000000: i64 = 1000000
13
14func ex_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
15func ex_putn(v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64=v; if m<0 {m=0-m}; let t: *u8 = sys_mmap(28); var k: i64=0; if m==0 {t[0]=48;k=1}; while m>0 {t[k]=48+(m%10); m=m/10; k=k+1}; var i: i64=0; while i<k {bb[i]=t[k-1-i]; i=i+1}; sys_write(1, bb, k); return 0 }
16func ex_itoa(v: i64, out: *u8) -> i64 { var m: i64=v; if m<0 {m=0-m}; let t: *u8 = sys_mmap(28); var k: i64=0; if m==0 {t[0]=48;k=1}; while m>0 {t[k]=48+(m%10); m=m/10; k=k+1}; var i: i64=0; while i<k {out[i]=t[k-1-i]; i=i+1}; out[k]=0 as u8; return k }
17
18// find needle in buf starting at `start`; return index or -1.
19func ex_findfrom(buf: *u8, n: i64, start: i64, needle: *u8) -> i64 {
20 var m: i64 = 0; while needle[m] != (0 as u8) { m = m + 1 }
21 if m == 0 { return 0 - 1 }
22 var i: i64 = start
23 while i + m <= n {
24 var j: i64 = 0; var ok: i64 = 1
25 while j < m { if buf[i + j] != needle[j] { ok = 0; j = m } else { j = j + 1 } }
26 if ok == 1 { return i }
27 i = i + 1
28 }
29 return 0 - 1
30}
31
32// parse a (possibly signed) integer at/after p (skipping spaces); res[0]=value; return new pos.
33func ex_pint(buf: *u8, n: i64, p: i64, res: *i64) -> i64 {
34 var i: i64 = p
35 var sk: i64 = 1
36 while sk == 1 { if i >= n { sk = 0 } else { if buf[i] == (32 as u8) { i = i + 1 } else { sk = 0 } } }
37 var sign: i64 = 1
38 if i < n { if buf[i] == (45 as u8) { sign = 0 - 1; i = i + 1 } }
39 var v: i64 = 0
40 var go: i64 = 1
41 while go == 1 { if i >= n { go = 0 } else { if buf[i] >= 48 { if buf[i] <= 57 { v = v * 10 + (buf[i] - 48); i = i + 1 } else { go = 0 } } else { go = 0 } } }
42 res[0] = v * sign
43 return i
44}
45
46// STL ASCII: returns triangle count; dims3[0..2] = bbox (max-min) per axis.
47func ex_stl(buf: *u8, n: i64, dims3: *i64) -> i64 {
48 var tri: i64 = 0
49 var p: i64 = 0
50 var go: i64 = 1
51 while go == 1 { let idx: i64 = ex_findfrom(buf, n, p, "facet normal" as *u8); if idx < 0 { go = 0 } else { tri = tri + 1; p = idx + 12 } }
52 var minx: i64 = K_MAGIC_1000000; var maxx: i64 = 0 - K_MAGIC_1000000
53 var miny: i64 = K_MAGIC_1000000; var maxy: i64 = 0 - K_MAGIC_1000000
54 var minz: i64 = K_MAGIC_1000000; var maxz: i64 = 0 - K_MAGIC_1000000
55 let r: *i64 = sys_mmap(8)
56 p = 0; go = 1
57 while go == 1 {
58 let idx: i64 = ex_findfrom(buf, n, p, "vertex " as *u8)
59 if idx < 0 { go = 0 } else {
60 var q: i64 = idx + 7
61 q = ex_pint(buf, n, q, r); let x: i64 = r[0]
62 q = ex_pint(buf, n, q, r); let y: i64 = r[0]
63 q = ex_pint(buf, n, q, r); let z: i64 = r[0]
64 if x < minx { minx = x }
65 if x > maxx { maxx = x }
66 if y < miny { miny = y }
67 if y > maxy { maxy = y }
68 if z < minz { minz = z }
69 if z > maxz { maxz = z }
70 p = q
71 }
72 }
73 dims3[0] = maxx - minx; dims3[1] = maxy - miny; dims3[2] = maxz - minz
74 return tri
75}
76
77// GIF header: wh2[0]=width wh2[1]=height; returns 1 if GIF89a magic ok.
78func ex_gif(buf: *u8, n: i64, wh2: *i64) -> i64 {
79 if n < 10 { return 0 }
80 var ok: i64 = 1
81 if buf[0] != (71 as u8) { ok = 0 }
82 if buf[1] != (73 as u8) { ok = 0 }
83 if buf[2] != (70 as u8) { ok = 0 }
84 if buf[3] != (56 as u8) { ok = 0 }
85 if buf[4] != (57 as u8) { ok = 0 }
86 if buf[5] != (97 as u8) { ok = 0 }
87 wh2[0] = (buf[6] as i64) + (buf[7] as i64) * 256
88 wh2[1] = (buf[8] as i64) + (buf[9] as i64) * 256
89 return ok
90}
91
92// plain text: wc2[0]=words wc2[1]=chars.
93func ex_text(buf: *u8, n: i64, wc2: *i64) -> i64 {
94 var chars: i64 = 0
95 while buf[chars] != (0 as u8) { chars = chars + 1 }
96 var words: i64 = 0
97 if chars > 0 { words = 1 }
98 var i: i64 = 0
99 while i < chars { if buf[i] == (32 as u8) { words = words + 1 } i = i + 1 }
100 wc2[0] = words; wc2[1] = chars
101 return 0
102}
103
104func main() -> i64 {
105 let dims3: *i64 = sys_mmap(8 * 3)
106 let stl: *u8 = "solid t\nfacet normal\nfacet normal\nfacet normal\nfacet normal\nfacet normal\nfacet normal\nfacet normal\nfacet normal\nfacet normal\nfacet normal\nfacet normal\nfacet normal\nvertex 0 0 0\nvertex 2 2 2\nvertex 1 1 1\nendsolid t\n"
107 var sn: i64 = 0; while stl[sn] != (0 as u8) { sn = sn + 1 }
108 let tri: i64 = ex_stl(stl, sn, dims3)
109
110 let gif: *u8 = sys_mmap(16)
111 gif[0]=71 as u8; gif[1]=73 as u8; gif[2]=70 as u8; gif[3]=56 as u8; gif[4]=57 as u8; gif[5]=97 as u8
112 gif[6]=64 as u8; gif[7]=0 as u8; gif[8]=48 as u8; gif[9]=0 as u8
113 let wh2: *i64 = sys_mmap(8 * 2)
114 let gmagic: i64 = ex_gif(gif, 10, wh2)
115
116 let wc2: *i64 = sys_mmap(8 * 2)
117 ex_text("the quick brown fox" as *u8, 19, wc2)
118
119 // build + validate a meta record from the STL extraction (composition with X-CAP-001)
120 let keys: *i64 = sys_mmap(8 * 16) as *i64
121 let vals: *i64 = sys_mmap(8 * 16) as *i64
122 let tribuf: *u8 = sys_mmap(28); ex_itoa(tri, tribuf)
123 ms_set(keys, vals, 0, "modality" as *u8, "stl" as *u8)
124 ms_set(keys, vals, 1, "cid" as *u8, "stl-cube-001" as *u8)
125 ms_set(keys, vals, 2, "consent" as *u8, "self" as *u8)
126 ms_set(keys, vals, 3, "attr.triangles" as *u8, tribuf)
127 let recvalid: i64 = ms_valid(keys, vals, 4)
128
129 ex_puts("EXTRACTGATE stl_tri=" as *u8); ex_putn(tri)
130 ex_puts(" stl_dims=" as *u8); ex_putn(dims3[0]); ex_puts("x" as *u8); ex_putn(dims3[1]); ex_puts("x" as *u8); ex_putn(dims3[2])
131 ex_puts(" gif_magic=" as *u8); ex_putn(gmagic); ex_puts(" gif_w=" as *u8); ex_putn(wh2[0]); ex_puts(" gif_h=" as *u8); ex_putn(wh2[1])
132 ex_puts(" text_words=" as *u8); ex_putn(wc2[0]); ex_puts(" text_chars=" as *u8); ex_putn(wc2[1])
133 ex_puts(" record_valid=" as *u8); ex_putn(recvalid)
134
135 var ok: i64 = 1
136 if tri != 12 { ok = 0 }
137 if dims3[0] != 2 { ok = 0 }
138 if dims3[1] != 2 { ok = 0 }
139 if dims3[2] != 2 { ok = 0 }
140 if gmagic != 1 { ok = 0 }
141 if wh2[0] != 64 { ok = 0 }
142 if wh2[1] != 48 { ok = 0 }
143 if wc2[0] != 4 { ok = 0 }
144 if wc2[1] != 19 { ok = 0 }
145 if recvalid != 1 { ok = 0 }
146 if ok == 1 { ex_puts(" verdict=GREEN\n" as *u8); return 0 }
147 ex_puts(" verdict=RED\n" as *u8)
148 return 1
149}