code wiki / (root) / nx_img_place.nx

nx_img_place.nx source

↩ module page · 76 lines · 3079 B

1// nx_img_place.nx -- place a decoded image onto a grayscale print page: luminance conversion + aspect-fit 2// + nearest-neighbor scale-blit. The back half of "print documents WITH images". Works on the raw pixels 3// from nx_png_decoder (any color type, 8/16-bit) and writes into the same 0=black..255=white page bitmap the 4// document renderer + URF encoder use. PURE (operates on caller buffers) -> never-brick. Sovereign. 5// genealogy_id: project-printer-management-ipp-sclass-2026-06-20 ; license_tier: ORIGINAL 6 7// Convert decoded image pixels -> grayscale (0=black..255=white), sw*sh bytes into out. 8// n_channels: 1=gray 2=gray+alpha 3=rgb 4=rgba. bit_depth 8 or 16 (16-bit: take the big-endian MSB). 9// Luminance = (R*77 + G*150 + B*29) >> 8 (Rec.601-ish integer weights summing to 256). 10func nx_img_to_gray(src: *u8, sw: i64, sh: i64, n_channels: i64, bit_depth: i64, out: *u8) -> i64 { 11 var sample_bytes: i64 = 1 12 if bit_depth == 16 { sample_bytes = 2 } 13 let stride: i64 = n_channels * sample_bytes 14 var y: i64 = 0 15 while y < sh { 16 var x: i64 = 0 17 while x < sw { 18 let base: i64 = (y * sw + x) * stride 19 var gray: i64 = 0 20 if n_channels <= 2 { 21 gray = src[base] as i64 // gray (alpha ignored) 22 } else { 23 let r: i64 = src[base] as i64 24 let g: i64 = src[base + sample_bytes] as i64 25 let b: i64 = src[base + 2 * sample_bytes] as i64 26 gray = (r * 77 + g * 150 + b * 29) >> 8 27 } 28 if gray > 255 { gray = 255 } 29 out[y * sw + x] = gray as u8 30 x = x + 1 31 } 32 y = y + 1 33 } 34 return 0 35} 36 37// Compute the largest WxH that fits within (maxW,maxH) preserving the source aspect ratio. 38func nx_img_fit(sw: i64, sh: i64, maxW: i64, maxH: i64, out_w: *i64, out_h: *i64) -> i64 { 39 if sw <= 0 { out_w[0] = maxW; out_h[0] = maxH; return 0 } 40 if sh <= 0 { out_w[0] = maxW; out_h[0] = maxH; return 0 } 41 var fw: i64 = maxW 42 var fh: i64 = maxW * sh / sw 43 if fh > maxH { 44 fh = maxH 45 fw = maxH * sw / sh 46 } 47 if fw < 1 { fw = 1 } 48 if fh < 1 { fh = 1 } 49 out_w[0] = fw 50 out_h[0] = fh 51 return 0 52} 53 54// Blit gray image (src, sw x sh) into page (W x H, 0=black..255=white) at top-left (dx,dy), scaled to 55// boxW x boxH via nearest-neighbor. Bounds-checked. 56func nx_img_blit(page: *u8, W: i64, H: i64, dx: i64, dy: i64, 57 src: *u8, sw: i64, sh: i64, boxW: i64, boxH: i64) -> i64 { 58 if boxW <= 0 { return 0 } 59 if boxH <= 0 { return 0 } 60 var ty: i64 = 0 61 while ty < boxH { 62 let sy: i64 = ty * sh / boxH 63 let py: i64 = dy + ty 64 if py >= 0 { if py < H { 65 var tx: i64 = 0 66 while tx < boxW { 67 let sx: i64 = tx * sw / boxW 68 let px: i64 = dx + tx 69 if px >= 0 { if px < W { page[py * W + px] = src[sy * sw + sx] } } 70 tx = tx + 1 71 } 72 } } 73 ty = ty + 1 74 } 75 return 0 76}