code wiki / _hdl_build / nx_cbx_pages.nx
nx_cbx_pages.nx
buildroot/runtime/_hdl_build/nx_cbx_pages.nx
about
nx_cbx_pages.nx -- SOVEREIGN CBX page-image extraction (Reader-arc RUNG 3, FORMAT-FIX rev "cfix":2).
The operator headline ask: "convert pdf into cbx type zoom" so books read easily on mobile; then
"the formats are broken like for the comics" -- this rev EATS that debt. CBX = comic-archive style:
ordered page IMAGES the browser renders + pinch/pan/zooms natively. KEY INSIGHT: the browser is the
last-mile image renderer/zoomer (allowed). Nishi only EXTRACTS page image BYTES sovereignly, serves them.
CONTAINERS (routed by MAGIC BYTES, never extension -- wild comics LIE: zip renamed .cbr, rar renamed .cbz):
(A) ZIP (cbz) -- central-directory walker (proven, from nx_epub_read.nx), store+deflate.
(B) RAR4 (cbr) -- sovereign block walker, STORED (method 0x30) entries extracted. Comics keep
JPEG pages STORED (compressing JPEG gains ~0%), so store-only covers the real corpus; entries that
ARE compressed are COUNTED and reported CBX-RAR-COMPRESSED-UNSUPPORTED -- honest, never fake pages.
(C) RAR5 (cbr) -- vint block walker, method bits 7..9 == 0 (store) extracted; same honesty.
(D) 7z (cb7) -- CBX-7Z-UNSUPPORTED honest skip (LZMA decode not built yet).
(E) Scanned/image PDF -- /DCTDecode image XObjects = raw JPEG between stream/endstream. Anchor on
/DCTDecode (NEVER bare "stream"), confirm SOI ff d8, scan to endstream. Vector/text PDF -> honest skip.
FORMAT-FIX rev (the broken-comics debt this rev eats):
1. NATURAL page sort -- ascii sort put "page10" before "page2" in any non-zero-padded comic = pages
OUT OF ORDER. name_cmp_nat compares digit runs numerically (case-insensitive elsewhere).
2. PER-PAGE magic gate -- __MACOSX/._foo.jpg AppleDouble junk passed the extension filter and was
WRITTEN as a broken page. Now every page's BYTES must pass img_sig_ok or the entry is skipped+logged.
3. CBR support (B)(C) + magic sniffing (misnamed containers) + honest skip codes.
4. "cfix":2 schema tag in cbx.json -- the server treats a cbx.json WITHOUT the current tag as a cache
MISS, so comics extracted by the OLD organ self-heal on next open (no remote rm; additive).
SOVEREIGN: pure Nishi organs + raw syscalls. NO python/unzip/unrar/pdfium/mupdf/ghostscript/poppler/gcc/sh.
Image DISPLAY+zoom is the browser (last-mile); the viewer JS/CSS is hand-written (no 3rd-party libs).
NO-FAKE-GREEN: every written page's first bytes are a REAL image magic (JPEG/PNG/GIF/BMP/WEBP); skips are
COUNTED and printed, never silent. ADDITIVE (rule 13): output dir per slug; reruns overwrite atomically.
license_tier: ORIGINAL
dependencies 3 imports · 0 importers
imports: nx_syscalls.nxnx_itoa_lib.nxnx_deflate.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 35 | const PAGE_MAGIC_1024: i64 = 1024 |
| 36 | const PAGE_MAGIC_1048576: i64 = 1048576 |
| 266 | const PAGE_CAP: i64 = 67108864 // 64 MiB per page buffer (largest cbz page << this) |
| 305 | const ECAP: i64 = 4096 // max archive entries enumerated |
functions
| 39 | func er_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } |
| 40 | func er_w(fd: i64, s: *u8) -> i64 { sys_write(fd, s, er_slen(s)); return 0 } |
| 45 | func er_n(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 } |
| 46 | func er_p(s: *u8) -> i64 { er_w(1, s); return 0 } |
| 47 | func er_pn(v: i64) -> i64 { er_n(1, v); return 0 } |
| 49 | func le16(b: *u8, o: i64) -> i64 { return (b[o] as i64) | ((b[o+1] as i64) << 8) } |
| 50 | func le32(b: *u8, o: i64) -> i64 { return (b[o] as i64) | ((b[o+1] as i64) << 8) | ((b[o+2] as i64) << 16) | ((b[o+3] as i64) << 24) } |
| 52 | func er_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){dst[off+i]=s[i];i=i+1} return off+i } |
| 53 | func er_catn(dst: *u8, off: i64, v: i64) -> i64 { let t: *u8=sys_mmap(28); var m: i64=v; var k: i64=0; if m==0{t[0]=48 as u8;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{dst[off+i]=t[k-1-i];i=i+1} return off+k } |
| 56 | func find_sub(hay: *u8, hl: i64, needle: *u8) -> i64 |
| 71 | func find_sub_from(hay: *u8, hl: i64, needle: *u8, from: i64) -> i64 |
| 79 | func find_eocd(z: *u8, zl: i64) -> i64 called by 1: zip_enum |
| 91 | func zip_enum(z: *u8, zl: i64, arena: *u8, acap: i64, noffs: *i64, meths: *i64, comps: *i64, doffs: *i64, ecap: i64) -> i64 |
| 128 | func name_cmp(a: *u8, b: *u8) -> i64 called by 1: is_image_name |
| 143 | func lc(c: i64) -> i64 { if c >= 65 { if c <= 90 { return c + 32 } } return c } |
| 146 | func nat_digits(s: *u8, o: i64) -> i64 called by 1: name_cmp_nat |
| 160 | func name_cmp_nat(a: *u8, b: *u8) -> i64 |
| 213 | func is_image_name(name: *u8) -> i64 |
| 237 | func is_junk_name(name: *u8) -> i64 |
| 249 | func ext_of(name: *u8, out: *u8) -> i64 |
| 264 | func ensure_dir(path: *u8) -> i64 { __syscall(258, 0-100, path, 0x1ed, 0, 0, 0); return 0 } |
| 269 | func write_page(dir: *u8, idx: i64, ext: *u8, bytes: *u8, n: i64) -> i64 |
| 285 | func page_fname(out: *u8, idx: i64, ext: *u8) -> i64 |
| 296 | func img_sig_ok(b: *u8, n: i64) -> i64 called by 1: emit_pages |
| 313 | func emit_pages(z: *u8, slug: *u8, fmt: *u8, arena: *u8, noffs: *i64, meths: *i64, comps: *i64, doffs: *i64, nent: i64, cover_only: i64) -> i64 |
| 466 | func rar4_enum(z: *u8, zl: i64, arena: *u8, acap: i64, noffs: *i64, meths: *i64, comps: *i64, doffs: *i64, ecap: i64, skipc: *i64) -> i64 |
| 527 | func r5v(z: *u8, pos: *i64, zl: i64) -> i64 called by 1: rar5_enum |
| 550 | func rar5_enum(z: *u8, zl: i64, arena: *u8, acap: i64, noffs: *i64, meths: *i64, comps: *i64, doffs: *i64, ecap: i64, skipc: *i64) -> i64 |
| 609 | func do_pdf(path: *u8, slug: *u8) -> i64 |
| 694 | func do_cbz(path: *u8, slug: *u8, cover_only: i64) -> i64 |
| 758 | func main(argc: i64, argv: *i64) -> i64 |