code wiki / _hdl_build / nx_jpeg_huff_enc.nx
nx_jpeg_huff_enc.nx source
↩ module page · 113 lines · 6573 B
1// nx_jpeg_huff_enc.nx -- SOVEREIGN JPEG baseline Huffman ENCODE substrate (J1 of the sovereign JPEG
2// encoder yardstick, for the patent-free codec RD head-to-head). The JPEG arc was decode-only; this is
3// the missing encode side. Provides the STANDARD ITU-T T.81 Annex K.3 luminance Huffman tables (DC +
4// AC) as canonical code/size lookups, the JPEG magnitude-category + sign-magnitude additional-bits
5// encoding, and DC/AC symbol emission over the shared MSB-first bit writer (nx_h264_bitwriter, reused
6// as the generic hardware-rung bit primitive -- DRY). JPEG/Annex K is fully public since 1992 and
7// patent-expired -> patent-clean. Self-proof = encode->decode round-trip (no 3rd party). The byte
8// 0xFF-stuffing belongs to the scan-writer stage (J3), not here. license_tier: ORIGINAL
9import "nx_syscalls.nx"
10import "nx_h264_bitwriter.nx"
11
12// --- standard Annex K.3 luminance DC: BITS[1..16] (counts), HUFFVAL (12 categories 0..11) ---
13func jhe_dc_bits(b: *i64) -> i64 {
14 b[0]=0; b[1]=0; b[2]=1; b[3]=5; b[4]=1; b[5]=1; b[6]=1; b[7]=1; b[8]=1
15 b[9]=1; b[10]=0; b[11]=0; b[12]=0; b[13]=0; b[14]=0; b[15]=0; b[16]=0
16 return 12
17}
18func jhe_dc_val(v: *i64) -> i64 { var i: i64=0; while i<12 { v[i]=i; i=i+1 } return 12 }
19
20// --- standard Annex K.3 luminance AC: BITS[1..16] (sum=162), HUFFVAL (162 run/size symbols) ---
21func jhe_ac_bits(b: *i64) -> i64 {
22 b[0]=0; b[1]=0; b[2]=2; b[3]=1; b[4]=3; b[5]=3; b[6]=2; b[7]=4; b[8]=3
23 b[9]=5; b[10]=5; b[11]=4; b[12]=4; b[13]=0; b[14]=0; b[15]=1; b[16]=125
24 return 162
25}
26func jhe_ac_val(v: *i64) -> i64 {
27 v[0]=0x01; v[1]=0x02; v[2]=0x03; v[3]=0x00; v[4]=0x04; v[5]=0x11; v[6]=0x05; v[7]=0x12
28 v[8]=0x21; v[9]=0x31; v[10]=0x41; v[11]=0x06; v[12]=0x13; v[13]=0x51; v[14]=0x61; v[15]=0x07
29 v[16]=0x22; v[17]=0x71; v[18]=0x14; v[19]=0x32; v[20]=0x81; v[21]=0x91; v[22]=0xa1; v[23]=0x08
30 v[24]=0x23; v[25]=0x42; v[26]=0xb1; v[27]=0xc1; v[28]=0x15; v[29]=0x52; v[30]=0xd1; v[31]=0xf0
31 v[32]=0x24; v[33]=0x33; v[34]=0x62; v[35]=0x72; v[36]=0x82; v[37]=0x09; v[38]=0x0a; v[39]=0x16
32 v[40]=0x17; v[41]=0x18; v[42]=0x19; v[43]=0x1a; v[44]=0x25; v[45]=0x26; v[46]=0x27; v[47]=0x28
33 v[48]=0x29; v[49]=0x2a; v[50]=0x34; v[51]=0x35; v[52]=0x36; v[53]=0x37; v[54]=0x38; v[55]=0x39
34 v[56]=0x3a; v[57]=0x43; v[58]=0x44; v[59]=0x45; v[60]=0x46; v[61]=0x47; v[62]=0x48; v[63]=0x49
35 v[64]=0x4a; v[65]=0x53; v[66]=0x54; v[67]=0x55; v[68]=0x56; v[69]=0x57; v[70]=0x58; v[71]=0x59
36 v[72]=0x5a; v[73]=0x63; v[74]=0x64; v[75]=0x65; v[76]=0x66; v[77]=0x67; v[78]=0x68; v[79]=0x69
37 v[80]=0x6a; v[81]=0x73; v[82]=0x74; v[83]=0x75; v[84]=0x76; v[85]=0x77; v[86]=0x78; v[87]=0x79
38 v[88]=0x7a; v[89]=0x83; v[90]=0x84; v[91]=0x85; v[92]=0x86; v[93]=0x87; v[94]=0x88; v[95]=0x89
39 v[96]=0x8a; v[97]=0x92; v[98]=0x93; v[99]=0x94; v[100]=0x95; v[101]=0x96; v[102]=0x97; v[103]=0x98
40 v[104]=0x99; v[105]=0x9a; v[106]=0xa2; v[107]=0xa3; v[108]=0xa4; v[109]=0xa5; v[110]=0xa6; v[111]=0xa7
41 v[112]=0xa8; v[113]=0xa9; v[114]=0xaa; v[115]=0xb2; v[116]=0xb3; v[117]=0xb4; v[118]=0xb5; v[119]=0xb6
42 v[120]=0xb7; v[121]=0xb8; v[122]=0xb9; v[123]=0xba; v[124]=0xc2; v[125]=0xc3; v[126]=0xc4; v[127]=0xc5
43 v[128]=0xc6; v[129]=0xc7; v[130]=0xc8; v[131]=0xc9; v[132]=0xca; v[133]=0xd2; v[134]=0xd3; v[135]=0xd4
44 v[136]=0xd5; v[137]=0xd6; v[138]=0xd7; v[139]=0xd8; v[140]=0xd9; v[141]=0xda; v[142]=0xe1; v[143]=0xe2
45 v[144]=0xe3; v[145]=0xe4; v[146]=0xe5; v[147]=0xe6; v[148]=0xe7; v[149]=0xe8; v[150]=0xe9; v[151]=0xea
46 v[152]=0xf1; v[153]=0xf2; v[154]=0xf3; v[155]=0xf4; v[156]=0xf5; v[157]=0xf6; v[158]=0xf7; v[159]=0xf8
47 v[160]=0xf9; v[161]=0xfa
48 return 162
49}
50
51// Canonical Huffman code generation (ITU-T T.81 Annex C, Figures C.2/C.3): from BITS[1..16] + HUFFVAL
52// produce ehufco[symbol]=code and ehufsi[symbol]=size (0 if symbol unused). Returns symbol count.
53func jhe_gen(bits: *i64, huffval: *i64, nval: i64, ehufco: *i64, ehufsi: *i64) -> i64 {
54 let huffsize: *i64 = sys_mmap(512*8) as *i64
55 var k: i64=0; var l: i64=1
56 while l<=16 { var i: i64=1; while i<=bits[l] { huffsize[k]=l; k=k+1; i=i+1 } l=l+1 }
57 huffsize[k]=0
58 let huffcode: *i64 = sys_mmap(512*8) as *i64
59 var code: i64=0; var si: i64=huffsize[0]; k=0
60 var done: i64=0
61 while done==0 {
62 while huffsize[k]==si { huffcode[k]=code; code=code+1; k=k+1 }
63 if huffsize[k]==0 { done=1 } else { while huffsize[k]!=si { code=code<<1; si=si+1 } }
64 }
65 var s: i64=0
66 while s<256 { ehufco[s]=0; ehufsi[s]=0; s=s+1 }
67 k=0
68 while k<nval { let vv: i64=huffval[k]; ehufco[vv]=huffcode[k]; ehufsi[vv]=huffsize[k]; k=k+1 }
69 return nval
70}
71
72// JPEG magnitude category of v = number of bits to hold |v| (0->0, 1->1, 2..3->2, ...).
73func jhe_mag_cat(v: i64) -> i64 { var a: i64=v; if a<0 { a=0-a } var c: i64=0; while a>0 { c=c+1; a=a>>1 } return c }
74
75// JPEG sign-magnitude "additional bits" for value v at category cat (cat>0): v if v>=0 else v+(2^cat-1).
76func jhe_mag_bits(v: i64, cat: i64) -> i64 { var m: i64=v; if v<0 { m=v+(1<<cat)-1 } return m & ((1<<cat)-1) }
77
78// emit a DC coefficient difference: Huffman(category) then the category's additional bits.
79func jhe_emit_dc(bw: *BitWriter, ehufco: *i64, ehufsi: *i64, diff: i64) -> i64 {
80 let cat: i64=jhe_mag_cat(diff)
81 bw_write_bits(bw, ehufco[cat], ehufsi[cat])
82 if cat>0 { bw_write_bits(bw, jhe_mag_bits(diff, cat), cat) }
83 return 0
84}
85
86// emit an AC coefficient: Huffman((run<<4)|size) then additional bits. run=15,v=0 -> ZRL (0xF0);
87// run=0,v=0 -> EOB (0x00).
88func jhe_emit_ac(bw: *BitWriter, ehufco: *i64, ehufsi: *i64, run: i64, v: i64) -> i64 {
89 let cat: i64=jhe_mag_cat(v)
90 let sym: i64=(run<<4)|cat
91 bw_write_bits(bw, ehufco[sym], ehufsi[sym])
92 if cat>0 { bw_write_bits(bw, jhe_mag_bits(v, cat), cat) }
93 return 0
94}
95
96// --- matched DECODE side (the sovereign round-trip oracle; no 3rd party) ---
97func jhe_read_bit(buf: *u8, pos: *i64) -> i64 { let p: i64=pos[0]; let bit: i64=((buf[p>>3] as i64) >> (7-(p&7))) & 1; pos[0]=p+1; return bit }
98func jhe_decode_sym(buf: *u8, pos: *i64, ehufco: *i64, ehufsi: *i64) -> i64 {
99 var acc: i64=0; var nb: i64=0
100 while nb<16 {
101 acc=(acc<<1)|jhe_read_bit(buf, pos); nb=nb+1
102 var s: i64=0
103 while s<256 { if ehufsi[s]==nb { if ehufco[s]==acc { return s } } s=s+1 }
104 }
105 return 0-1
106}
107func jhe_decode_mag(buf: *u8, pos: *i64, cat: i64) -> i64 {
108 if cat==0 { return 0 }
109 var t: i64=0; var i: i64=0
110 while i<cat { t=(t<<1)|jhe_read_bit(buf, pos); i=i+1 }
111 if t < (1<<(cat-1)) { return t - (1<<cat) + 1 }
112 return t
113}