code wiki / _hdl_build / nx_caption_burn_gate.nx

nx_caption_burn_gate.nx source

↩ module page · 103 lines · 5149 B

1// nx_caption_burn_gate.nx -- proves the live-translation RENDER vertical end-to-end, NO fake green: 2// EN caption -> nx_mt_phrasetable EN->ES -> nx_caption_burn burns it onto a 320x180 "video" frame. 3// Rows: (1) caption active at t=1000ms, (2) burn sets text pixels, (3) the bottom bar is drawn (bar color), 4// (4) the VIDEO area above the bar is PRESERVED (caption doesn't clobber the frame), (5) neg-control: at 5// t=5000ms NO caption is active (cb_active_at=-1) so nothing burns -> the bar region stays video-colored. 6// Eyeball -> knowledge/nx_caption_burn.png. expect_exit: 0 license_tier: ORIGINAL 7import "nx_syscalls.nx" 8import "nx_css_color_decode.nx" 9import "nx_paint_solid_rect.nx" 10import "nx_font_bitmap_5x7.nx" 11import "nx_paint_text.nx" 12import "nx_caption_burn.nx" 13import "nx_mt_phrasetable.nx" 14import "nx_png_write.nx" 15 16func cg(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 17func cgn(v: i64) -> i64 { 18 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 19 var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 20 let d: *u8 = sys_mmap(24); var k: i64 = 0 21 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 22 var j: i64 = k - 1 23 while j >= 0 { sys_write(1, ((d as i64)+j) as *u8, 1); j = j - 1 } 24 return 0 25} 26func px_is(p: *CssColor, r: i64, g: i64, b: i64) -> i64 { if p.r==r { if p.g==g { if p.b==b { return 1 } } } return 0 } 27 28func main() -> i64 { 29 cg("=== nx_caption_burn_gate: EN caption -> phrase-table ES -> burn onto a video frame ===\n" as *u8) 30 let w: i64 = 320 31 let h: i64 = 180 32 let pixels: *u8 = sys_mmap(w * h * 4) 33 let fb: *Framebuffer = sys_mmap(NX_FRAMEBUFFER_BYTES) as *Framebuffer 34 nx_framebuffer_init(fb, pixels, w, h) 35 nx_framebuffer_clear(fb) 36 37 let vid: *CssColor = sys_mmap(NX_CSS_COLOR_BYTES) as *CssColor 38 vid.r=40; vid.g=60; vid.b=90; vid.a=255 39 nx_paint_solid_rect(fb, 0, 0, w, h, vid) 40 41 let bar: *CssColor = sys_mmap(NX_CSS_COLOR_BYTES) as *CssColor 42 bar.r=0; bar.g=0; bar.b=0; bar.a=255 43 let fg: *CssColor = sys_mmap(NX_CSS_COLOR_BYTES) as *CssColor 44 fg.r=255; fg.g=255; fg.b=0; fg.a=255 45 let probe: *CssColor = sys_mmap(NX_CSS_COLOR_BYTES) as *CssColor 46 47 // translate the EN caption -> ES 48 let src: *u8 = "HELLO FRIEND WELCOME" as *u8 49 var sn: i64 = 0 50 while src[sn] != (0 as u8) { sn = sn + 1 } 51 let es: *u8 = sys_mmap(256) 52 let esn: i64 = nx_mt_translate(src, sn, es, 256) 53 cg(" EN='" as *u8); sys_write(1, src, sn); cg("' -> ES='" as *u8); sys_write(1, es, esn); cg("'\n" as *u8) 54 55 // caption track: one segment [0,2000)ms 56 let t0: *i64 = sys_mmap(8) as *i64 57 let t1: *i64 = sys_mmap(8) as *i64 58 t0[0]=0; t1[0]=2000 59 60 var pass: i64 = 0 61 var fail: i64 = 0 62 63 // ROW1: active at t=1000ms 64 if cb_active_at(t0, t1, 1, 1000) == 0 { pass=pass+1; cg(" ROW active@1000ms: GREEN\n" as *u8) } else { fail=fail+1; cg(" ROW active@1000ms: RED\n" as *u8) } 65 66 // ROW2: burn sets text pixels 67 let set1: i64 = nx_caption_burn(fb, es, esn, 2, bar, fg) 68 if set1 > 0 { pass=pass+1; cg(" ROW burn-paints-text: GREEN (" as *u8); cgn(set1); cg(" px)\n" as *u8) } else { fail=fail+1; cg(" ROW burn-paints-text: RED\n" as *u8) } 69 70 // ROW3: the bottom bar is drawn (bar color at far-left of the bar row) 71 nx_framebuffer_get_pixel(fb, 3, h - 3, probe) 72 if px_is(probe,0,0,0)==1 { pass=pass+1; cg(" ROW bar-drawn: GREEN\n" as *u8) } else { fail=fail+1; cg(" ROW bar-drawn: RED\n" as *u8) } 73 74 // ROW4: the video area above the bar is preserved 75 nx_framebuffer_get_pixel(fb, 3, 3, probe) 76 if px_is(probe,40,60,90)==1 { pass=pass+1; cg(" ROW video-preserved: GREEN\n" as *u8) } else { fail=fail+1; cg(" ROW video-preserved: RED\n" as *u8) } 77 78 // ROW5 neg-control: reset frame; at t=5000ms NO caption active -> we DON'T burn -> bar region stays video 79 nx_paint_solid_rect(fb, 0, 0, w, h, vid) 80 let a2: i64 = cb_active_at(t0, t1, 1, 5000) 81 if a2 == (0 - 1) { 82 nx_framebuffer_get_pixel(fb, w / 2, h - 3, probe) 83 if px_is(probe,40,60,90)==1 { pass=pass+1; cg(" ROW neg-control no-caption-no-burn: GREEN\n" as *u8) } else { fail=fail+1; cg(" ROW neg-control leaked a caption: RED\n" as *u8) } 84 } else { fail=fail+1; cg(" ROW neg-control: RED (claimed a caption active at 5000ms)\n" as *u8) } 85 86 // re-render the active caption for the eyeball image 87 nx_paint_solid_rect(fb, 0, 0, w, h, vid) 88 nx_caption_burn(fb, es, esn, 2, bar, fg) 89 let rgb: *u8 = sys_mmap(w * h * 3) 90 var i: i64 = 0 91 while i < w * h { 92 rgb[i*3+0] = pixels[i*4+0] 93 rgb[i*3+1] = pixels[i*4+1] 94 rgb[i*3+2] = pixels[i*4+2] 95 i = i + 1 96 } 97 nx_png_write_rgb("knowledge/nx_caption_burn.png" as *u8, rgb, w, h) 98 cg(" eyeball -> knowledge/nx_caption_burn.png\n" as *u8) 99 100 cg("CAPTION-BURN-GATE pass=" as *u8); cgn(pass); cg(" fail=" as *u8); cgn(fail) 101 if fail == 0 { cg(" verdict=GREEN -- EN->ES translate -> caption burned onto the frame; video preserved; neg-control clean\n" as *u8); sys_exit(0); return 0 } 102 cg(" verdict=RED\n" as *u8); sys_exit(1); return 1 103}