code wiki / _hdl_build / nx_jpeg_sym.nx

nx_jpeg_sym.nx source

↩ module page · 61 lines · 2668 B

1// nx_jpeg_sym.nx -- SOVEREIGN JPEG "modeling" layer: separates a block's entropy into (a) a SYMBOL stream 2// (DC categories + AC (run<<4|size) bytes + EOB/ZRL) and (b) the raw sign-magnitude additional bits. This 3// is exactly the modeling JPEG does before Huffman -- but here the symbols are emitted as plain bytes so a 4// DIFFERENT final coder (our rANS) can entropy-code them. Comparing rANS(symbols) vs Huffman(symbols) with 5// identical magnitude bits isolates the pure entropy-coder question at identical quality. Reuses the J1 6// substrate (jhe_mag_cat / jhe_mag_bits / jhe_decode_mag) over nx_h264_bitwriter. license_tier: ORIGINAL 7import "nx_syscalls.nx" 8import "nx_h264_bitwriter.nx" 9import "nx_jpeg_huff_enc.nx" 10 11// Encode zz[64] (zigzag, zz[0]=DC) -> append symbol bytes to sym[] (sp[0] = running count), and the 12// sign-magnitude additional bits to bwmag. prevdc = previous block's DC. Returns this block's DC. 13func jsym_encode_block(sym: *u8, sp: *i64, bwmag: *BitWriter, zz: *i64, prevdc: i64) -> i64 { 14 var p: i64 = sp[0] 15 let diff: i64 = zz[0] - prevdc 16 let dccat: i64 = jhe_mag_cat(diff) 17 sym[p] = dccat as u8; p = p + 1 18 if dccat > 0 { bw_write_bits(bwmag, jhe_mag_bits(diff, dccat), dccat) } 19 var run: i64 = 0 20 var k: i64 = 1 21 while k < 64 { 22 let v: i64 = zz[k] 23 if v == 0 { run = run + 1 } else { 24 while run >= 16 { sym[p] = 0xF0 as u8; p = p + 1; run = run - 16 } 25 let cat: i64 = jhe_mag_cat(v) 26 let s: i64 = (run << 4) | cat 27 sym[p] = s as u8; p = p + 1 28 if cat > 0 { bw_write_bits(bwmag, jhe_mag_bits(v, cat), cat) } 29 run = 0 30 } 31 k = k + 1 32 } 33 if run > 0 { sym[p] = 0x00 as u8; p = p + 1 } 34 sp[0] = p 35 return zz[0] 36} 37 38// Decode one block: read symbol bytes from sym[] (sp[0] running index) + magnitude bits from magbuf at 39// magpos -> zz[64]. prevdc = previous DC. Returns this block's DC. 40func jsym_decode_block(sym: *u8, sp: *i64, magbuf: *u8, magpos: *i64, prevdc: i64, zz: *i64) -> i64 { 41 var i: i64 = 0 42 while i < 64 { zz[i] = 0; i = i + 1 } 43 var p: i64 = sp[0] 44 let dccat: i64 = sym[p] as i64; p = p + 1 45 let dc: i64 = prevdc + jhe_decode_mag(magbuf, magpos, dccat) 46 zz[0] = dc 47 var k: i64 = 1 48 while k < 64 { 49 let s: i64 = sym[p] as i64; p = p + 1 50 if s == 0 { k = 64 } else { 51 let run: i64 = s >> 4 52 let size: i64 = s & 0xf 53 if size == 0 { k = k + 16 } else { 54 k = k + run 55 if k < 64 { zz[k] = jhe_decode_mag(magbuf, magpos, size); k = k + 1 } 56 } 57 } 58 } 59 sp[0] = p 60 return dc 61}