// Encode a symbol with modelling public void encodeSymbol(ArithmeticModel m, uint sym) { Debug.Assert(m != null); Debug.Assert(sym <= m.last_symbol); uint x, init_interval_base = interval_base; // compute products if (sym == m.last_symbol) { x = m.distribution[sym] * (length >> DM.LengthShift); interval_base += x; // update interval length -= x; // no product needed } else { x = m.distribution[sym] * (length >>= DM.LengthShift); interval_base += x; // update interval length = m.distribution[sym + 1] * length - x; } if (init_interval_base > interval_base) { propagate_carry(); // overflow = carry } if (length < AC.MinLength) { renorm_enc_interval(); // renormalization } ++m.symbol_count[sym]; if (--m.symbols_until_update == 0) { m.update(); // periodic model update } }
// Encode a symbol with modelling public void encodeSymbol(ArithmeticModel m, uint sym) { Debug.Assert(m!=null); Debug.Assert(sym<=m.last_symbol); uint x, init_interval_base=interval_base; // compute products if(sym==m.last_symbol) { x=m.distribution[sym]*(length>>DM.LengthShift); interval_base+=x; // update interval length-=x; // no product needed } else { x=m.distribution[sym]*(length>>=DM.LengthShift); interval_base+=x; // update interval length=m.distribution[sym+1]*length-x; } if(init_interval_base>interval_base) propagate_carry(); // overflow = carry if(length<AC.MinLength) renorm_enc_interval(); // renormalization ++m.symbol_count[sym]; if(--m.symbols_until_update==0) m.update(); // periodic model update }
// Decode a symbol with modelling public uint decodeSymbol(ArithmeticModel m) { uint n, sym, x, y=length; if(m.decoder_table!=null) { // use table look-up for faster decoding uint dv=value/(length>>=DM.LengthShift); uint t=dv>>m.table_shift; sym=m.decoder_table[t]; // initial decision based on table look-up n=m.decoder_table[t+1]+1; while(n>sym+1) { // finish with bisection search uint k=(sym+n)>>1; if(m.distribution[k]>dv) n=k; else sym=k; } // compute products x=m.distribution[sym]*length; if(sym!=m.last_symbol) y=m.distribution[sym+1]*length; } else { // decode using only multiplications x=sym=0; length>>=DM.LengthShift; uint k=(n=m.symbols)>>1; // decode via bisection search do { uint z=length*m.distribution[k]; if(z>value) { n=k; y=z; // value is smaller } else { sym=k; x=z; // value is larger or equal } } while((k=(sym+n)>>1)!=sym); } value-=x; // update interval length=y-x; if(length<AC.MinLength) renorm_dec_interval(); // renormalization ++m.symbol_count[sym]; if(--m.symbols_until_update==0) m.update(); // periodic model update Debug.Assert(sym<m.symbols); return sym; }
// Decode a symbol with modelling public uint decodeSymbol(ArithmeticModel m) { uint n, sym, x, y = length; if (m.decoder_table != null) { // use table look-up for faster decoding uint dv = value / (length >>= DM.LengthShift); uint t = dv >> m.table_shift; sym = m.decoder_table[t]; // initial decision based on table look-up n = m.decoder_table[t + 1] + 1; while (n > sym + 1) { // finish with bisection search uint k = (sym + n) >> 1; if (m.distribution[k] > dv) { n = k; } else { sym = k; } } // compute products x = m.distribution[sym] * length; if (sym != m.last_symbol) { y = m.distribution[sym + 1] * length; } } else { // decode using only multiplications x = sym = 0; length >>= DM.LengthShift; uint k = (n = m.symbols) >> 1; // decode via bisection search do { uint z = length * m.distribution[k]; if (z > value) { n = k; y = z; // value is smaller } else { sym = k; x = z; // value is larger or equal } } while((k = (sym + n) >> 1) != sym); } value -= x; // update interval length = y - x; if (length < AC.MinLength) { renorm_dec_interval(); // renormalization } ++m.symbol_count[sym]; if (--m.symbols_until_update == 0) { m.update(); // periodic model update } Debug.Assert(sym < m.symbols); return(sym); }