code wiki / (root) / nx_urf.nx

nx_urf.nx source

↩ module page · 79 lines · 3661 B

1// nx_urf.nx -- sovereign URF (Apple Raster / UNIRAST) document encoder. Wraps the shared PWG RLE in the 2// URF container the Brother (and every AirPrint printer) accepts (document-format image/urf). 3// 4// URF layout (reverse-engineered + cross-checked; the Brother advertises urf-supported=W8 = 8-bit gray): 5// FILE HEADER (12 bytes): "UNIRAST\0" (8) + uint32 BE page-count. 6// PER-PAGE HEADER (32 bytes): 7// [0] bitsPerPixel (8 for sgray_8) [1] colorspace (sGray=0,sRGB=1) [2] duplex (0/1/2) 8// [3] quality (0 def,3 draft,4 normal,5 high) [4] mediaType (0 auto) [5] mediaPosition (0 auto) 9// [6..11] reserved(0) [12..15] width BE [16..19] height BE [20..23] dpi BE [24..31] reserved(0) 10// PAGE DATA: PWG/URF PackBits RLE (nx_pwg_rle), pixels top-to-bottom, left-to-right. 11// 12// HONEST NOTE: the RLE is spec-PROVEN (CUPS spec worked example); the URF header is spec-GROUNDED 13// (reverse-engineered) -- the real printer is the final oracle (live submit = the next rung). 14// NEVER-BRICK (#26): pure builder; no syscalls. Sovereign (imports only nx_pwg_rle.nx). 15// genealogy_id: project-printer-management-ipp-sclass-2026-06-20 ; license_tier: ORIGINAL 16 17import "nx_pwg_rle.nx" 18 19const NX_URF_CS_SGRAY: i64 = 0 20const NX_URF_CS_SRGB: i64 = 1 21const NX_URF_DUP_NONE: i64 = 0 22const NX_URF_DUP_SHORT: i64 = 1 23const NX_URF_DUP_LONG: i64 = 2 // long-edge duplex -- the paper-waste fix 24const NX_URF_Q_DEFAULT: i64 = 0 25const NX_URF_Q_DRAFT: i64 = 3 // draft = the toner-saving mode 26const NX_URF_Q_NORMAL: i64 = 4 27const NX_URF_Q_HIGH: i64 = 5 28 29func nx_urf_be32(out: *u8, off: i64, v: i64) -> i64 { 30 out[off] = ((v >> 24) & 0xff) as u8 31 out[off + 1] = ((v >> 16) & 0xff) as u8 32 out[off + 2] = ((v >> 8) & 0xff) as u8 33 out[off + 3] = (v & 0xff) as u8 34 return off + 4 35} 36 37// 12-byte URF file header. Returns 12. 38func nx_urf_file_header(out: *u8, pages: i64) -> i64 { 39 out[0] = 0x55 as u8 // U 40 out[1] = 0x4E as u8 // N 41 out[2] = 0x49 as u8 // I 42 out[3] = 0x52 as u8 // R 43 out[4] = 0x41 as u8 // A 44 out[5] = 0x53 as u8 // S 45 out[6] = 0x54 as u8 // T 46 out[7] = 0x00 as u8 // \0 47 nx_urf_be32(out, 8, pages) 48 return 12 49} 50 51// 32-byte page header at out[off..]. Returns off+32. 52func nx_urf_page_header(out: *u8, off: i64, bpp: i64, colorspace: i64, duplex: i64, 53 quality: i64, width: i64, height: i64, dpi: i64) -> i64 { 54 var o: i64 = off 55 out[o] = bpp as u8; o = o + 1 56 out[o] = colorspace as u8; o = o + 1 57 out[o] = duplex as u8; o = o + 1 58 out[o] = quality as u8; o = o + 1 59 out[o] = 0 as u8; o = o + 1 // media type = auto 60 out[o] = 0 as u8; o = o + 1 // media position = auto 61 var r: i64 = 0 62 while r < 6 { out[o] = 0 as u8; o = o + 1; r = r + 1 } 63 o = nx_urf_be32(out, o, width) 64 o = nx_urf_be32(out, o, height) 65 o = nx_urf_be32(out, o, dpi) 66 var r2: i64 = 0 67 while r2 < 8 { out[o] = 0 as u8; o = o + 1; r2 = r2 + 1 } 68 return o 69} 70 71// Encode a complete single-page 8-bit GRAYSCALE URF document (bitmap = width*height bytes) into out. 72// Returns total byte length. duplex/quality let the caller fix the paper/toner waste at the document level. 73func nx_urf_encode_gray_page(out: *u8, bitmap: *u8, width: i64, height: i64, 74 dpi: i64, duplex: i64, quality: i64) -> i64 { 75 var off: i64 = nx_urf_file_header(out, 1) 76 off = nx_urf_page_header(out, off, 8, NX_URF_CS_SGRAY, duplex, quality, width, height, dpi) 77 let rlen: i64 = nx_rle_encode_page(bitmap, width, height, 1, ((out as i64) + off) as *u8) 78 return off + rlen 79}