123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- /*
- Copyright (c) 2004 Amir Said ([email protected]) & William A. Pearlman ([email protected])
- All rights reserved.
- Redistribution and use in source and binary forms, with or without modification,
- are permitted provided that the following conditions are met:
- - Redistributions of source code must retain the above copyright notice, this list
- of conditions and the following disclaimer.
- - Redistributions in binary form must reproduce the above copyright notice, this list of
- conditions and the following disclaimer in the documentation and/or other materials
- provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- OF SUCH DAMAGE.
- */
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // -
- // **************************** -
- // ARITHMETIC CODING EXAMPLES -
- // **************************** -
- // -
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // -
- // Fast arithmetic coding implementation -
- // -> 32-bit variables, 32-bit product, periodic updates, table decoding -
- // -
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // -
- // Version 1.00 - April 25, 2004 -
- // -
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // -
- // WARNING -
- // ========= -
- // -
- // The only purpose of this program is to demonstrate the basic principles -
- // of arithmetic coding. It is provided as is, without any express or -
- // implied warranty, without even the warranty of fitness for any particular -
- // purpose, or that the implementations are correct. -
- // -
- // Permission to copy and redistribute this code is hereby granted, provided -
- // that this warning and copyright notices are not removed or altered. -
- // -
- // Copyright (c) 2004 by Amir Said ([email protected]) & -
- // William A. Pearlman ([email protected]) -
- // -
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // -
- // A description of the arithmetic coding method used here is available in -
- // -
- // Lossless Compression Handbook, ed. K. Sayood -
- // Chapter 5: Arithmetic Coding (A. Said), pp. 101-152, Academic Press, 2003 -
- // -
- // A. Said, Introduction to Arithetic Coding Theory and Practice -
- // HP Labs report HPL-2004-76 - http://www.hpl.hp.com/techreports/ -
- // -
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Definitions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- #ifndef O3DGC_ARITHMETIC_CODEC
- #define O3DGC_ARITHMETIC_CODEC
- #include <stdio.h>
- #include "o3dgcCommon.h"
- #include <assimp/defs.h>
- namespace o3dgc
- {
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Class definitions - - - - - - - - - - - - - - - - - - - - - - - - - - -
- class Static_Bit_Model // static model for binary data
- {
- public:
- Static_Bit_Model(void);
- void set_probability_0(double); // set probability of symbol '0'
- private: // . . . . . . . . . . . . . . . . . . . . . .
- unsigned bit_0_prob;
- friend class Arithmetic_Codec;
- };
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- class Static_Data_Model // static model for general data
- {
- public:
- Static_Data_Model(void);
- ~Static_Data_Model(void);
- unsigned model_symbols(void) { return data_symbols; }
- void set_distribution(unsigned number_of_symbols,
- const double probability[] = 0); // 0 means uniform
- private: // . . . . . . . . . . . . . . . . . . . . . .
- unsigned * distribution, * decoder_table;
- unsigned data_symbols, last_symbol, table_size, table_shift;
- friend class Arithmetic_Codec;
- };
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- class Adaptive_Bit_Model // adaptive model for binary data
- {
- public:
- Adaptive_Bit_Model(void);
- void reset(void); // reset to equiprobable model
- private: // . . . . . . . . . . . . . . . . . . . . . .
- void update(void);
- unsigned update_cycle, bits_until_update;
- unsigned bit_0_prob, bit_0_count, bit_count;
- friend class Arithmetic_Codec;
- };
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- class Adaptive_Data_Model // adaptive model for binary data
- {
- public:
- Adaptive_Data_Model(void);
- Adaptive_Data_Model(unsigned number_of_symbols);
- ~Adaptive_Data_Model(void);
- unsigned model_symbols(void) { return data_symbols; }
- void reset(void); // reset to equiprobable model
- void set_alphabet(unsigned number_of_symbols);
- private: // . . . . . . . . . . . . . . . . . . . . . .
- void update(bool);
- unsigned * distribution, * symbol_count, * decoder_table;
- unsigned total_count, update_cycle, symbols_until_update;
- unsigned data_symbols, last_symbol, table_size, table_shift;
- friend class Arithmetic_Codec;
- };
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Encoder and decoder class - - - - - - - - - - - - - - - - - - - - - - -
- // Class with both the arithmetic encoder and decoder. All compressed data is
- // saved to a memory buffer
- class Arithmetic_Codec
- {
- public:
- Arithmetic_Codec(void);
- ~Arithmetic_Codec(void);
- Arithmetic_Codec(unsigned max_code_bytes,
- unsigned char * user_buffer = 0); // 0 = assign new
- unsigned char * buffer(void) { return code_buffer; }
- void set_buffer(unsigned max_code_bytes,
- unsigned char * user_buffer = 0); // 0 = assign new
- void start_encoder(void);
- void start_decoder(void);
- void read_from_file(FILE * code_file); // read code data, start decoder
- unsigned stop_encoder(void); // returns number of bytes used
- unsigned write_to_file(FILE * code_file); // stop encoder, write code data
- void stop_decoder(void);
- void put_bit(unsigned bit);
- unsigned get_bit(void);
- void put_bits(unsigned data, unsigned number_of_bits);
- unsigned get_bits(unsigned number_of_bits);
- void encode(unsigned bit,
- Static_Bit_Model &);
- unsigned decode(Static_Bit_Model &);
- void encode(unsigned data,
- Static_Data_Model &);
- unsigned decode(Static_Data_Model &);
- void encode(unsigned bit,
- Adaptive_Bit_Model &);
- unsigned decode(Adaptive_Bit_Model &);
- void encode(unsigned data,
- Adaptive_Data_Model &);
- unsigned decode(Adaptive_Data_Model &);
- // This section was added by K. Mammou
- void ExpGolombEncode(unsigned int symbol,
- int k,
- Static_Bit_Model & bModel0,
- Adaptive_Bit_Model & bModel1)
- {
- while(1)
- {
- if (symbol >= (unsigned int)(1<<k))
- {
- encode(1, bModel1);
- symbol = symbol - (1<<k);
- k++;
- }
- else
- {
- encode(0, bModel1); // now terminated zero of unary part
- while (k--) // next binary part
- {
- encode((signed short)((symbol>>k)&1), bModel0);
- }
- break;
- }
- }
- }
- unsigned ExpGolombDecode(int k,
- Static_Bit_Model & bModel0,
- Adaptive_Bit_Model & bModel1)
- {
- unsigned int l;
- int symbol = 0;
- int binary_symbol = 0;
- do
- {
- l=decode(bModel1);
- if (l==1)
- {
- symbol += (1<<k);
- k++;
- }
- }
- while (l!=0);
- while (k--) //next binary part
- if (decode(bModel0)==1)
- {
- binary_symbol |= (1<<k);
- }
- return (unsigned int) (symbol+binary_symbol);
- }
- //----------------------------------------------------------
- private: // . . . . . . . . . . . . . . . . . . . . . .
- void propagate_carry(void);
- void renorm_enc_interval(void);
- void renorm_dec_interval(void);
- unsigned char * code_buffer, * new_buffer, * ac_pointer;
- unsigned base, value, length; // arithmetic coding state
- unsigned buffer_size, mode; // mode: 0 = undef, 1 = encoder, 2 = decoder
- };
- inline long DecodeIntACEGC(Arithmetic_Codec & acd,
- Adaptive_Data_Model & mModelValues,
- Static_Bit_Model & bModel0,
- Adaptive_Bit_Model & bModel1,
- const unsigned long exp_k,
- const unsigned long M)
- {
- unsigned long uiValue = acd.decode(mModelValues);
- if (uiValue == M)
- {
- uiValue += acd.ExpGolombDecode(exp_k, bModel0, bModel1);
- }
- return UIntToInt(uiValue);
- }
- inline unsigned long DecodeUIntACEGC(Arithmetic_Codec & acd,
- Adaptive_Data_Model & mModelValues,
- Static_Bit_Model & bModel0,
- Adaptive_Bit_Model & bModel1,
- const unsigned long exp_k,
- const unsigned long M)
- {
- unsigned long uiValue = acd.decode(mModelValues);
- if (uiValue == M)
- {
- uiValue += acd.ExpGolombDecode(exp_k, bModel0, bModel1);
- }
- return uiValue;
- }
- inline void EncodeIntACEGC(long predResidual,
- Arithmetic_Codec & ace,
- Adaptive_Data_Model & mModelValues,
- Static_Bit_Model & bModel0,
- Adaptive_Bit_Model & bModel1,
- const unsigned long M)
- {
- unsigned long uiValue = IntToUInt(predResidual);
- if (uiValue < M)
- {
- ace.encode(uiValue, mModelValues);
- }
- else
- {
- ace.encode(M, mModelValues);
- ace.ExpGolombEncode(uiValue-M, 0, bModel0, bModel1);
- }
- }
- inline void EncodeUIntACEGC(long predResidual,
- Arithmetic_Codec & ace,
- Adaptive_Data_Model & mModelValues,
- Static_Bit_Model & bModel0,
- Adaptive_Bit_Model & bModel1,
- const unsigned long M)
- {
- unsigned long uiValue = (unsigned long) predResidual;
- if (uiValue < M)
- {
- ace.encode(uiValue, mModelValues);
- }
- else
- {
- ace.encode(M, mModelValues);
- ace.ExpGolombEncode(uiValue-M, 0, bModel0, bModel1);
- }
- }
- }
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- #endif
|