code wiki / (root) / nx_media_index.nx

nx_media_index.nx source

↩ module page · 105 lines · 3871 B

1// nx_media_index.nx -- EXPOSURE rung X1 (library): tag a real media file by 2// running the detectors over it, producing a record the portal can filter and 3// search. REUSES the shipped sovereign decoder (nx_png_decode) + R2 presence 4// -- no new decode/detect code. This is how the capabilities reach the real 5// library instead of synthetic in-memory pixels. 6// 7// PNG today (the gallery is PNG, verified end-to-end on a real 1024x768 file). 8// JPEG is a drop-in extension via the existing nx_jpeg_decode; NAS .jpg paths 9// also need an SMB-reachable mount -- both deliberately deferred, not faked. 10// 11// genealogy_id: media_studio_exposure_index (record-hint) 12// lineage_id: decode + presence + tag_record 13// license_tier: ORIGINAL 14import "nx_syscalls.nx" 15import "nx_tier.nx" 16import "nx_image.nx" 17import "nx_png_decoder.nx" 18import "nx_jpeg_ascii.nx" 19import "nx_presence.nx" 20 21const NX_MIDX_OK: i64 = 0 22const NX_MIDX_NOFILE: i64 = 1 23const NX_MIDX_NOTPNG: i64 = 2 24const NX_MIDX_DECERR: i64 = 3 25 26const NX_MIDX_MIN_SKIN: i64 = 50 27const NX_MIDX_MIN_CONC: i64 = 500 28 29// Wrap a decoded PNG result as an nx_image pointing at its pixel buffer. 30func nx_mindex_png_to_image(r: *NxPngResult) -> *Image { 31 let raw: *u8 = sys_mmap(40) 32 let img: *Image = raw as *Image 33 img.pixels = r.pixels 34 img.width = r.header.width 35 img.height = r.header.height 36 img.channels = r.n_channels 37 img.stride = r.header.width * r.n_channels 38 return img 39} 40 41// Wrap a packed RGB buffer (from nx_jpeg_decode_rgb) as an nx_image. 42func nx_mindex_rgb_to_image(rgb: *u8, w: i64, h: i64) -> *Image { 43 let raw: *u8 = sys_mmap(40) 44 let img: *Image = raw as *Image 45 img.pixels = rgb 46 img.width = w 47 img.height = h 48 img.channels = 3 49 img.stride = w * 3 50 return img 51} 52 53// Tag one media file by path. Writes a 7-field record into out[]: 54// [0]=status [1]=width (or PNG err code when status=DECERR) [2]=height 55// [3]=skin permille [4]=conc permille [5]=present(1/0) [6]=skin count 56// Returns the status. 57func nx_mindex_tag_path(path: *u8, out: *i64) -> i64 { 58 out[0] = NX_MIDX_NOFILE 59 out[1] = 0 60 out[2] = 0 61 out[3] = 0 62 out[4] = 0 63 out[5] = 0 64 out[6] = 0 65 out[7] = 0 - 1 // bbox minx,miny,maxx,maxy 66 out[8] = 0 - 1 67 out[9] = 0 - 1 68 out[10] = 0 - 1 69 let szp: *i64 = sys_mmap(16) as *i64 70 let buf: *u8 = sys_read_file(path, szp) 71 if (buf as i64) == 0 { return out[0] } 72 if szp[0] < 8 { out[0] = NX_MIDX_NOTPNG; return out[0] } 73 var img: *Image = 0 as *Image 74 let b0: i64 = buf[0] as i64 75 let b1: i64 = buf[1] as i64 76 if b0 == 137 && b1 == 80 { // PNG (\x89 'P') 77 let r: *NxPngResult = nx_png_decode(buf, szp[0]) 78 if (r as i64) == 0 { out[0] = NX_MIDX_DECERR; return out[0] } 79 if r.error_code != NX_PNG_OK { out[0] = NX_MIDX_DECERR; out[1] = r.error_code; return out[0] } 80 img = nx_mindex_png_to_image(r) 81 } 82 if b0 == 255 && b1 == 216 { // JPEG (0xFF 0xD8) 83 let pr: *i64 = sys_mmap(8) as *i64 84 let pw: *i64 = sys_mmap(8) as *i64 85 let ph: *i64 = sys_mmap(8) as *i64 86 let dr: i64 = nx_jpeg_decode_rgb(buf, szp[0], pr, pw, ph) 87 if dr != NX_JPEG_ASCII_OK { out[0] = NX_MIDX_DECERR; out[1] = dr; return out[0] } 88 img = nx_mindex_rgb_to_image(pr[0] as *u8, pw[0], ph[0]) 89 } 90 if (img as i64) == 0 { out[0] = NX_MIDX_NOTPNG; return out[0] } // unsupported format 91 let pout: *i64 = sys_mmap(128) as *i64 92 nx_presence_scan(img, pout) 93 out[0] = NX_MIDX_OK 94 out[1] = img.width 95 out[2] = img.height 96 out[3] = pout[0] 97 out[4] = pout[1] 98 out[5] = nx_presence_classify(pout[0], pout[1], NX_MIDX_MIN_SKIN, NX_MIDX_MIN_CONC) 99 out[6] = pout[2] 100 out[7] = pout[3] 101 out[8] = pout[4] 102 out[9] = pout[5] 103 out[10] = pout[6] 104 return out[0] 105}