nx_img_print.nx source
↩ module page · 166 lines · 7611 B
1// nx_img_print.nx -- PRINT A DOCUMENT WITH AN IMAGE, end to end sovereign: generate/Decode a PNG ->
2// grayscale (nx_img_place) -> place on a page with a title (nx_doc_layout + nx_font8x8) -> URF -> Print-Job.
3// Proves the full image pipeline: PNG decode (nx_png_decoder) + luminance + aspect-fit + scale-blit.
4// Outward-facing (paper/toner) -- operator approved live printing. never-brick. license_tier: ORIGINAL
5// genealogy_id: project-printer-management-ipp-sclass-2026-06-20
6
7import "nx_syscalls.nx"
8import "nx_png_write.nx"
9import "nx_png_decoder.nx"
10import "nx_img_place.nx"
11import "nx_font8x8.nx"
12import "nx_doc_layout.nx"
13import "nx_pwg_rle.nx"
14import "nx_urf.nx"
15import "nx_ipp_codec.nx"
16import "nx_ipp_transport.nx"
17import "nx_ipp_submit.nx"
18import "nx_toner_meter.nx"
19import "nx_toner_ledger.nx"
20import "nx_toner_store.nx"
21const K_MAGIC_2550: i64 = 2550
22const K_MAGIC_3300: i64 = 3300
23const K_MAGIC_2200: i64 = 2200
24const K_MAGIC_2300: i64 = 2300
25const K_MAGIC_10000: i64 = 10000
26const K_MAGIC_262144: i64 = 262144
27const K_MAGIC_4096: i64 = 4096
28const K_MAGIC_131072: i64 = 131072
29const K_MAGIC_2048: i64 = 2048
30const K_MAGIC_32768: i64 = 32768
31const K_MAGIC_1500: i64 = 1500
32
33func p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
34func pn(v: i64) -> i64 {
35 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
36 var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
37 let t: *u8 = sys_mmap(24); var k: i64 = 0
38 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
39 let b: *u8 = sys_mmap(24); var i: i64 = 0
40 while i < k { b[i] = t[k - 1 - i]; i = i + 1 }
41 sys_write(1, b, k); return 0
42}
43func write_all(fd: i64, buf: *u8, len: i64) -> i64 {
44 var sent: i64 = 0
45 while sent < len { let w: i64 = sys_write(fd, ((buf as i64) + sent) as *u8, len - sent); if w <= 0 { return 0 - 1 } sent = sent + w }
46 return 0
47}
48
49func main() -> i64 {
50 let a: i64 = 192
51 let b: i64 = 168
52 let c: i64 = 8
53 let d: i64 = 127
54 let W: i64 = K_MAGIC_2550
55 let H: i64 = K_MAGIC_3300
56 p("=== PRINT DOCUMENT WITH IMAGE (PNG -> gray -> page -> URF -> Brother) ===\n")
57
58 // 1. generate a deterministic test PNG: a horizontal grayscale ramp (white left -> black right) + border
59 let iw: i64 = 480
60 let ih: i64 = 360
61 let rgb: *u8 = sys_mmap(iw * ih * 3)
62 var yy: i64 = 0
63 while yy < ih {
64 var xx: i64 = 0
65 while xx < iw {
66 var val: i64 = 255 - (xx * 255 / iw)
67 if yy < 4 { val = 0 }
68 if yy >= ih - 4 { val = 0 }
69 if xx < 4 { val = 0 }
70 if xx >= iw - 4 { val = 0 }
71 let bse: i64 = (yy * iw + xx) * 3
72 rgb[bse] = val as u8; rgb[bse + 1] = val as u8; rgb[bse + 2] = val as u8
73 xx = xx + 1
74 }
75 yy = yy + 1
76 }
77 nx_png_write_rgb("knowledge/fetched/nishi_img.png\x00" as *u8, rgb, iw, ih)
78 p("generated nishi_img.png ("); pn(iw); p("x"); pn(ih); p(" RGB)\n")
79
80 // 2. read + DECODE the PNG (sovereign nx_png_decoder)
81 let lenp: *i64 = sys_mmap(8) as *i64
82 let png: *u8 = sys_read_file("knowledge/fetched/nishi_img.png\x00" as *u8, lenp)
83 if png == (0 as *u8) { p("read failed\n"); sys_exit(1); return 1 }
84 let res: *NxPngResult = nx_png_decode(png, lenp[0])
85 if res == (0 as *NxPngResult) { p("decode returned null\n"); sys_exit(1); return 1 }
86 if res.error_code != 0 { p("PNG decode error_code="); pn(res.error_code); p("\n"); sys_exit(1); return 1 }
87 let hdr: *NxPngHeader = res.header
88 let sw: i64 = hdr.width
89 let sh: i64 = hdr.height
90 let bd: i64 = hdr.bit_depth
91 let nch: i64 = res.n_channels
92 p("DECODED PNG: "); pn(sw); p("x"); pn(sh); p(" channels="); pn(nch); p(" depth="); pn(bd); p("\n")
93
94 // 3. grayscale
95 let gray: *u8 = sys_mmap(sw * sh)
96 nx_img_to_gray(res.pixels, sw, sh, nch, bd, gray)
97
98 // 4. page: white + title + centered image
99 let page: *u8 = sys_mmap(W * H)
100 var i: i64 = 0
101 while i < W * H { page[i] = 255 as u8; i = i + 1 }
102 let table: *u8 = font8x8_table()
103 nx_doc_render(page, W, H, table, "NISHI PHOTO PRINT -- sovereign PNG decode to paper", 4, 160, 180, 160, 160, 16)
104 let fw: *i64 = sys_mmap(8) as *i64
105 let fh: *i64 = sys_mmap(8) as *i64
106 nx_img_fit(sw, sh, K_MAGIC_2200, K_MAGIC_2300, fw, fh)
107 let dx: i64 = (W - fw[0]) / 2
108 let dy: i64 = 460
109 nx_img_blit(page, W, H, dx, dy, gray, sw, sh, fw[0], fh[0])
110 p("placed image "); pn(fw[0]); p("x"); pn(fh[0]); p(" at ("); pn(dx); p(","); pn(dy); p(")\n")
111
112 // 5. real toner coverage
113 let cov: i64 = nx_toner_coverage_ppm(page, W * H)
114 let y: *i64 = sys_mmap(8) as *i64
115 let cons: *i64 = sys_mmap(8) as *i64
116 if nx_tstore_load("knowledge/fetched/toner_ledger.bin\x00" as *u8, y, cons) == 0 { y[0] = NX_TONER_YIELD_TN630; cons[0] = 0 }
117 cons[0] = nx_ledger_add(cons[0], cov)
118 nx_tstore_save("knowledge/fetched/toner_ledger.bin\x00" as *u8, y[0], cons[0])
119 let bp: i64 = nx_ledger_remaining_bp(y[0], cons[0])
120 p("page coverage="); pn(cov / K_MAGIC_10000); p("% REAL toner now: "); pn(bp / 100); p("."); let bf: i64 = bp % 100; if bf < 10 { p("0") } pn(bf); p("%\n")
121
122 // 6. URF + Print-Job
123 let doc: *u8 = sys_mmap(W * H + K_MAGIC_262144)
124 let doclen: i64 = nx_urf_encode_gray_page(doc, page, W, H, 300, NX_URF_DUP_LONG, NX_URF_Q_NORMAL)
125 let fd: i64 = sys_openat_wr("knowledge/fetched/nishi_img_page.urf\x00" as *u8, 0x1a4)
126 if fd >= 0 { write_all(fd, doc, doclen); sys_close(fd) }
127 let pay: *u8 = sys_mmap(doclen + K_MAGIC_4096)
128 let hl: i64 = nx_ipp_build_print_job(pay, a, b, c, d, "/ipp/print", "nishi", "nishi-photo", "image/urf")
129 var j: i64 = 0
130 while j < doclen { pay[hl + j] = doc[j]; j = j + 1 }
131 let resp: *u8 = sys_mmap(K_MAGIC_131072)
132 let bod: *u8 = sys_mmap(K_MAGIC_131072)
133 let out2: *i64 = sys_mmap(16) as *i64
134 let v: i64 = nx_ipt_post_ipp(a, b, c, d, 631, "/ipp/print", pay, hl + doclen, resp, K_MAGIC_131072, bod, K_MAGIC_131072, 15, out2)
135 p("submit http="); pn(out2[0]); p(" ipp=0x"); let st: i64 = nx_ipp_status(bod); if st < 16 { p("000") } pn(st); p("\n")
136 if v != NX_IPT_OK { p("submit failed\n"); sys_exit(1); return 1 }
137 let sc: *i64 = sys_mmap(64) as *i64
138 let jid: *i64 = sys_mmap(8) as *i64
139 var job: i64 = 0 - 1
140 if nx_ipp_get_enum(bod, out2[1], "job-id", sc, jid) == NX_IPP_OK { job = jid[0]; p("job-id="); pn(job); p("\n") }
141
142 // 7. poll
143 if job >= 0 {
144 let prq: *u8 = sys_mmap(K_MAGIC_2048)
145 let prs: *u8 = sys_mmap(K_MAGIC_32768)
146 let pbd: *u8 = sys_mmap(K_MAGIC_32768)
147 let pj: *i64 = sys_mmap(8) as *i64
148 var tries: i64 = 0
149 var done: i64 = 0
150 while tries < 12 {
151 if done == 0 {
152 let rl: i64 = nx_ipp_build_get_job_attrs(prq, a, b, c, d, "/ipp/print", "nishi", job)
153 let pv: i64 = nx_ipt_post_ipp(a, b, c, d, 631, "/ipp/print", prq, rl, prs, K_MAGIC_32768, pbd, K_MAGIC_32768, 6, out2)
154 if pv == NX_IPT_OK {
155 let s2: i64 = nx_ipp_status(pbd)
156 if s2 == 0x0406 { p(" job completed (purged)\n"); done = 1 }
157 else { if nx_ipp_get_enum(pbd, out2[1], "job-state", sc, pj) == NX_IPP_OK { p(" job-state="); pn(pj[0]); p("\n"); if pj[0] >= 7 { done = 1 } } }
158 }
159 if done == 0 { sys_sleep_ms(K_MAGIC_1500) }
160 }
161 tries = tries + 1
162 }
163 }
164 p("=== DONE: a document with a decoded image printed from the sovereign stack ===\n")
165 sys_exit(0); return 0
166}