Exemple #1
0
        // 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];
		}
Exemple #3
0
        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
		}
Exemple #10
0
        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);
        }
Exemple #11
0
        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;
		}
Exemple #15
0
        // 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);
        }
Exemple #16
0
 public void initSymbolModel(ArithmeticModel m, uint[] table = null)
 {
     m.init(table);
 }