// 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 } }
public LASwriteItemCompressed_BYTE_v2(ArithmeticEncoder enc, uint number) { // set encoder Debug.Assert(enc!=null); this.enc=enc; Debug.Assert(number>0); this.number=number; // create models and integer compressors m_byte=new ArithmeticModel[number]; for(uint i=0; i<number; i++) { m_byte[i]=enc.createSymbolModel(256); } // create last item last_item=new byte[number]; }
public LASwriteItemCompressed_BYTE_v2(ArithmeticEncoder enc, uint number) { // set encoder Debug.Assert(enc != null); this.enc = enc; Debug.Assert(number > 0); this.number = number; // create models and integer compressors m_byte = new ArithmeticModel[number]; for (uint i = 0; i < number; i++) { m_byte[i] = enc.createSymbolModel(256); } // create last item last_item = new byte[number]; }
public LASreadItemCompressed_BYTE_v2(ArithmeticDecoder dec, uint number) { // set decoder Debug.Assert(dec!=null); this.dec=dec; Debug.Assert(number>0); this.number=number; // create models and integer compressors m_byte=new ArithmeticModel[number]; for(uint i=0; i<number; i++) { m_byte[i]=dec.createSymbolModel(256); } // create last item last_item=new byte[number]; }
public LASreadItemCompressed_BYTE_v2(ArithmeticDecoder dec, uint number) { // set decoder Debug.Assert(dec != null); this.dec = dec; Debug.Assert(number > 0); this.number = number; // create models and integer compressors m_byte = new ArithmeticModel[number]; for (uint i = 0; i < number; i++) { m_byte[i] = dec.createSymbolModel(256); } // create last item last_item = new byte[number]; }
// Manage Decompressor public void initDecompressor() { Debug.Assert(dec != null); // maybe create the models if (mBits == null) { mBits = new ArithmeticModel[contexts]; for (uint i = 0; i < contexts; i++) { mBits[i] = dec.createSymbolModel(corr_bits + 1); } #if !COMPRESS_ONLY_K mCorrector = new ArithmeticModel[corr_bits + 1]; mCorrectorBit = dec.createBitModel(); for (uint i = 1; i <= corr_bits; i++) { if (i <= bits_high) { mCorrector[i] = dec.createSymbolModel(1u << (int)i); } else { mCorrector[i] = dec.createSymbolModel(1u << (int)bits_high); } } #endif } // certainly init the models for (uint i = 0; i < contexts; i++) { dec.initSymbolModel(mBits[i]); } #if !COMPRESS_ONLY_K dec.initBitModel(mCorrectorBit); for (uint i = 1; i <= corr_bits; i++) { dec.initSymbolModel(mCorrector[i]); } #endif }
int readCorrector(ArithmeticModel model) { int c; // decode within which interval the corrector is falling k=dec.decodeSymbol(model); // decode the exact location of the corrector within the interval #if COMPRESS_ONLY_K if(k!=0) // then c is either smaller than 0 or bigger than 1 { if(k<32) { c=(int)dec.readBits(k); if(c>=(1<<((int)k-1))) // if c is in the interval [ 2^(k-1) ... + 2^k - 1 ] { // so we translate c back into the interval [ 2^(k-1) + 1 ... 2^k ] by adding 1 c+=1; } else // otherwise c is in the interval [ 0 ... + 2^(k-1) - 1 ] { // so we translate c back into the interval [ - (2^k - 1) ... - (2^(k-1)) ] by subtracting (2^k - 1) c-=((1<<(int)k)-1); } } else { c=corr_min; } } else // then c is either 0 or 1 { c=(int)dec.readBit(); } #else // COMPRESS_ONLY_K if(k!=0) // then c is either smaller than 0 or bigger than 1 { if(k<32) { if(k<=bits_high) // for small k we can do this in one step { // decompress c with the range coder c=(int)dec.decodeSymbol(mCorrector[k]); } else { // for larger k we need to do this in two steps uint k1=k-bits_high; // decompress higher bits with table c=(int)dec.decodeSymbol(mCorrector[k]); // read lower bits raw int c1=(int)dec.readBits(k1); // put the corrector back together c=(c<<(int)k1)|c1; } // translate c back into its correct interval if(c>=(1<<((int)k-1))) // if c is in the interval [ 2^(k-1) ... + 2^k - 1 ] { // so we translate c back into the interval [ 2^(k-1) + 1 ... 2^k ] by adding 1 c+=1; } else // otherwise c is in the interval [ 0 ... + 2^(k-1) - 1 ] { // so we translate c back into the interval [ - (2^k - 1) ... - (2^(k-1)) ] by subtracting (2^k - 1) c-=((1<<(int)k)-1); } } else { c=corr_min; } } else // then c is either 0 or 1 { c=(int)dec.decodeBit(mCorrectorBit); } #endif // COMPRESS_ONLY_K return c; }
void writeCorrector(int c, ArithmeticModel model) { // find the tighest interval [ - (2^k - 1) ... + (2^k) ] that contains c k=0; // do this by checking the absolute value of c (adjusted for the case that c is 2^k) uint c1=(uint)(c<=0?-c:c-1); // this loop could be replaced with more efficient code while(c1!=0) { c1=c1>>1; k=k+1; } // the number k is between 0 and corr_bits and describes the interval the corrector falls into // we can compress the exact location of c within this interval using k bits enc.encodeSymbol(model, k); #if COMPRESS_ONLY_K if(k!=0) // then c is either smaller than 0 or bigger than 1 { Debug.Assert((c!=0)&&(c!=1)); if(k<32) { // translate the corrector c into the k-bit interval [ 0 ... 2^k - 1 ] if(c<0) // then c is in the interval [ - (2^k - 1) ... - (2^(k-1)) ] { // so we translate c into the interval [ 0 ... + 2^(k-1) - 1 ] by adding (2^k - 1) enc.writeBits((int)k, (uint)(c+((1<<(int)k)-1))); } else // then c is in the interval [ 2^(k-1) + 1 ... 2^k ] { // so we translate c into the interval [ 2^(k-1) ... + 2^k - 1 ] by subtracting 1 enc.writeBits((int)k, (uint)(c-1)); } } } else // then c is 0 or 1 { Debug.Assert((c==0)||(c==1)); enc.writeBit((uint)c); } #else // COMPRESS_ONLY_K if(k!=0) // then c is either smaller than 0 or bigger than 1 { Debug.Assert((c!=0)&&(c!=1)); if(k<32) { // translate the corrector c into the k-bit interval [ 0 ... 2^k - 1 ] if(c<0) // then c is in the interval [ - (2^k - 1) ... - (2^(k-1)) ] { // so we translate c into the interval [ 0 ... + 2^(k-1) - 1 ] by adding (2^k - 1) c+=((1<<(int)k)-1); } else // then c is in the interval [ 2^(k-1) + 1 ... 2^k ] { // so we translate c into the interval [ 2^(k-1) ... + 2^k - 1 ] by subtracting 1 c-=1; } if(k<=bits_high) // for small k we code the interval in one step { // compress c with the range coder enc.encodeSymbol(mCorrector[k], (uint)c); } else // for larger k we need to code the interval in two steps { // figure out how many lower bits there are int k1=(int)k-(int)bits_high; // c1 represents the lowest k-bits_high+1 bits c1=(uint)(c&((1<<k1)-1)); // c represents the highest bits_high bits c=c>>k1; // compress the higher bits using a context table enc.encodeSymbol(mCorrector[k], (uint)c); // store the lower k1 bits raw enc.writeBits(k1, c1); } } } else // then c is 0 or 1 { Debug.Assert((c==0)||(c==1)); enc.encodeBit(mCorrectorBit, (uint)c); } #endif // COMPRESS_ONLY_K }
// Manage Decompressor public void initDecompressor() { Debug.Assert(dec!=null); // maybe create the models if(mBits==null) { mBits=new ArithmeticModel[contexts]; for(uint i=0; i<contexts; i++) { mBits[i]=dec.createSymbolModel(corr_bits+1); } #if !COMPRESS_ONLY_K mCorrector=new ArithmeticModel[corr_bits+1]; mCorrectorBit=dec.createBitModel(); for(uint i=1; i<=corr_bits; i++) { if(i<=bits_high) { mCorrector[i]=dec.createSymbolModel(1u<<(int)i); } else { mCorrector[i]=dec.createSymbolModel(1u<<(int)bits_high); } } #endif } // certainly init the models for(uint i=0; i<contexts; i++) { dec.initSymbolModel(mBits[i]); } #if !COMPRESS_ONLY_K dec.initBitModel(mCorrectorBit); for(uint i=1; i<=corr_bits; i++) { dec.initSymbolModel(mCorrector[i]); } #endif }
int readCorrector(ArithmeticModel model) { int c; // decode within which interval the corrector is falling k = dec.decodeSymbol(model); // decode the exact location of the corrector within the interval #if COMPRESS_ONLY_K if (k != 0) // then c is either smaller than 0 or bigger than 1 { if (k < 32) { c = (int)dec.readBits(k); if (c >= (1 << ((int)k - 1))) // if c is in the interval [ 2^(k-1) ... + 2^k - 1 ] { // so we translate c back into the interval [ 2^(k-1) + 1 ... 2^k ] by adding 1 c += 1; } else // otherwise c is in the interval [ 0 ... + 2^(k-1) - 1 ] { // so we translate c back into the interval [ - (2^k - 1) ... - (2^(k-1)) ] by subtracting (2^k - 1) c -= ((1 << (int)k) - 1); } } else { c = corr_min; } } else // then c is either 0 or 1 { c = (int)dec.readBit(); } #else // COMPRESS_ONLY_K if (k != 0) // then c is either smaller than 0 or bigger than 1 { if (k < 32) { if (k <= bits_high) // for small k we can do this in one step { // decompress c with the range coder c = (int)dec.decodeSymbol(mCorrector[k]); } else { // for larger k we need to do this in two steps uint k1 = k - bits_high; // decompress higher bits with table c = (int)dec.decodeSymbol(mCorrector[k]); // read lower bits raw int c1 = (int)dec.readBits(k1); // put the corrector back together c = (c << (int)k1) | c1; } // translate c back into its correct interval if (c >= (1 << ((int)k - 1))) // if c is in the interval [ 2^(k-1) ... + 2^k - 1 ] { // so we translate c back into the interval [ 2^(k-1) + 1 ... 2^k ] by adding 1 c += 1; } else // otherwise c is in the interval [ 0 ... + 2^(k-1) - 1 ] { // so we translate c back into the interval [ - (2^k - 1) ... - (2^(k-1)) ] by subtracting (2^k - 1) c -= ((1 << (int)k) - 1); } } else { c = corr_min; } } else // then c is either 0 or 1 { c = (int)dec.decodeBit(mCorrectorBit); } #endif // COMPRESS_ONLY_K return(c); }
void writeCorrector(int c, ArithmeticModel model) { // find the tighest interval [ - (2^k - 1) ... + (2^k) ] that contains c k = 0; // do this by checking the absolute value of c (adjusted for the case that c is 2^k) uint c1 = (uint)(c <= 0?-c:c - 1); // this loop could be replaced with more efficient code while (c1 != 0) { c1 = c1 >> 1; k = k + 1; } // the number k is between 0 and corr_bits and describes the interval the corrector falls into // we can compress the exact location of c within this interval using k bits enc.encodeSymbol(model, k); #if COMPRESS_ONLY_K if (k != 0) // then c is either smaller than 0 or bigger than 1 { Debug.Assert((c != 0) && (c != 1)); if (k < 32) { // translate the corrector c into the k-bit interval [ 0 ... 2^k - 1 ] if (c < 0) // then c is in the interval [ - (2^k - 1) ... - (2^(k-1)) ] { // so we translate c into the interval [ 0 ... + 2^(k-1) - 1 ] by adding (2^k - 1) enc.writeBits((int)k, (uint)(c + ((1 << (int)k) - 1))); } else // then c is in the interval [ 2^(k-1) + 1 ... 2^k ] { // so we translate c into the interval [ 2^(k-1) ... + 2^k - 1 ] by subtracting 1 enc.writeBits((int)k, (uint)(c - 1)); } } } else // then c is 0 or 1 { Debug.Assert((c == 0) || (c == 1)); enc.writeBit((uint)c); } #else // COMPRESS_ONLY_K if (k != 0) // then c is either smaller than 0 or bigger than 1 { Debug.Assert((c != 0) && (c != 1)); if (k < 32) { // translate the corrector c into the k-bit interval [ 0 ... 2^k - 1 ] if (c < 0) // then c is in the interval [ - (2^k - 1) ... - (2^(k-1)) ] { // so we translate c into the interval [ 0 ... + 2^(k-1) - 1 ] by adding (2^k - 1) c += ((1 << (int)k) - 1); } else // then c is in the interval [ 2^(k-1) + 1 ... 2^k ] { // so we translate c into the interval [ 2^(k-1) ... + 2^k - 1 ] by subtracting 1 c -= 1; } if (k <= bits_high) // for small k we code the interval in one step { // compress c with the range coder enc.encodeSymbol(mCorrector[k], (uint)c); } else // for larger k we need to code the interval in two steps { // figure out how many lower bits there are int k1 = (int)k - (int)bits_high; // c1 represents the lowest k-bits_high+1 bits c1 = (uint)(c & ((1 << k1) - 1)); // c represents the highest bits_high bits c = c >> k1; // compress the higher bits using a context table enc.encodeSymbol(mCorrector[k], (uint)c); // store the lower k1 bits raw enc.writeBits(k1, c1); } } } else // then c is 0 or 1 { Debug.Assert((c == 0) || (c == 1)); enc.encodeBit(mCorrectorBit, (uint)c); } #endif // COMPRESS_ONLY_K }
// 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 }
public void initSymbolModel(ArithmeticModel m, uint[] table=null) { m.init(table); }
// 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); }
public void initSymbolModel(ArithmeticModel m, uint[] table = null) { m.init(table); }