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}