123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863 |
- /*
- 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/ -
- // -
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Inclusion - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- #include <stdlib.h>
- #include "o3dgcArithmeticCodec.h"
- namespace o3dgc
- {
- // - - Constants - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- const unsigned AC__MinLength = 0x01000000U; // threshold for renormalization
- const unsigned AC__MaxLength = 0xFFFFFFFFU; // maximum AC interval length
- // Maximum values for binary models
- const unsigned BM__LengthShift = 13; // length bits discarded before mult.
- const unsigned BM__MaxCount = 1 << BM__LengthShift; // for adaptive models
- // Maximum values for general models
- const unsigned DM__LengthShift = 15; // length bits discarded before mult.
- const unsigned DM__MaxCount = 1 << DM__LengthShift; // for adaptive models
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Static functions - - - - - - - - - - - - - - - - - - - - - - - - - - -
- AI_WONT_RETURN static void AC_Error(const char * msg) AI_WONT_RETURN_SUFFIX;
- static void AC_Error(const char * msg)
- {
- fprintf(stderr, "\n\n -> Arithmetic coding error: ");
- fputs(msg, stderr);
- fputs("\n Execution terminated!\n", stderr);
- getchar();
- exit(1);
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Coding implementations - - - - - - - - - - - - - - - - - - - - - - - -
- inline void Arithmetic_Codec::propagate_carry(void)
- {
- unsigned char * p; // carry propagation on compressed data buffer
- for (p = ac_pointer - 1; *p == 0xFFU; p--) *p = 0;
- ++*p;
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- inline void Arithmetic_Codec::renorm_enc_interval(void)
- {
- do { // output and discard top byte
- *ac_pointer++ = (unsigned char)(base >> 24);
- base <<= 8;
- } while ((length <<= 8) < AC__MinLength); // length multiplied by 256
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- inline void Arithmetic_Codec::renorm_dec_interval(void)
- {
- do { // read least-significant byte
- value = (value << 8) | unsigned(*++ac_pointer);
- } while ((length <<= 8) < AC__MinLength); // length multiplied by 256
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Arithmetic_Codec::put_bit(unsigned bit)
- {
- #ifdef _DEBUG
- if (mode != 1) AC_Error("encoder not initialized");
- #endif
- length >>= 1; // halve interval
- if (bit) {
- unsigned init_base = base;
- base += length; // move base
- if (init_base > base) propagate_carry(); // overflow = carry
- }
- if (length < AC__MinLength) renorm_enc_interval(); // renormalization
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- unsigned Arithmetic_Codec::get_bit(void)
- {
- #ifdef _DEBUG
- if (mode != 2) AC_Error("decoder not initialized");
- #endif
- length >>= 1; // halve interval
- unsigned bit = (value >= length); // decode bit
- if (bit) value -= length; // move base
- if (length < AC__MinLength) renorm_dec_interval(); // renormalization
- return bit; // return data bit value
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Arithmetic_Codec::put_bits(unsigned data, unsigned bits)
- {
- #ifdef _DEBUG
- if (mode != 1) AC_Error("encoder not initialized");
- if ((bits < 1) || (bits > 20)) AC_Error("invalid number of bits");
- if (data >= (1U << bits)) AC_Error("invalid data");
- #endif
- unsigned init_base = base;
- base += data * (length >>= bits); // new interval base and length
- if (init_base > base) propagate_carry(); // overflow = carry
- if (length < AC__MinLength) renorm_enc_interval(); // renormalization
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- unsigned Arithmetic_Codec::get_bits(unsigned bits)
- {
- #ifdef _DEBUG
- if (mode != 2) AC_Error("decoder not initialized");
- if ((bits < 1) || (bits > 20)) AC_Error("invalid number of bits");
- #endif
- unsigned s = value / (length >>= bits); // decode symbol, change length
- value -= length * s; // update interval
- if (length < AC__MinLength) renorm_dec_interval(); // renormalization
- return s;
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Arithmetic_Codec::encode(unsigned bit,
- Static_Bit_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 1) AC_Error("encoder not initialized");
- #endif
- unsigned x = M.bit_0_prob * (length >> BM__LengthShift); // product l x p0
- // update interval
- if (bit == 0)
- length = x;
- else {
- unsigned init_base = base;
- base += x;
- length -= x;
- if (init_base > base) propagate_carry(); // overflow = carry
- }
- if (length < AC__MinLength) renorm_enc_interval(); // renormalization
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- unsigned Arithmetic_Codec::decode(Static_Bit_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 2) AC_Error("decoder not initialized");
- #endif
- unsigned x = M.bit_0_prob * (length >> BM__LengthShift); // product l x p0
- unsigned bit = (value >= x); // decision
- // update & shift interval
- if (bit == 0)
- length = x;
- else {
- value -= x; // shifted interval base = 0
- length -= x;
- }
- if (length < AC__MinLength) renorm_dec_interval(); // renormalization
- return bit; // return data bit value
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Arithmetic_Codec::encode(unsigned bit,
- Adaptive_Bit_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 1) AC_Error("encoder not initialized");
- #endif
- unsigned x = M.bit_0_prob * (length >> BM__LengthShift); // product l x p0
- // update interval
- if (bit == 0) {
- length = x;
- ++M.bit_0_count;
- }
- else {
- unsigned init_base = base;
- base += x;
- length -= x;
- if (init_base > base) propagate_carry(); // overflow = carry
- }
- if (length < AC__MinLength) renorm_enc_interval(); // renormalization
- if (--M.bits_until_update == 0) M.update(); // periodic model update
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- unsigned Arithmetic_Codec::decode(Adaptive_Bit_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 2) AC_Error("decoder not initialized");
- #endif
- unsigned x = M.bit_0_prob * (length >> BM__LengthShift); // product l x p0
- unsigned bit = (value >= x); // decision
- // update interval
- if (bit == 0) {
- length = x;
- ++M.bit_0_count;
- }
- else {
- value -= x;
- length -= x;
- }
- if (length < AC__MinLength) renorm_dec_interval(); // renormalization
- if (--M.bits_until_update == 0) M.update(); // periodic model update
- return bit; // return data bit value
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Arithmetic_Codec::encode(unsigned data,
- Static_Data_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 1) AC_Error("encoder not initialized");
- if (data >= M.data_symbols) AC_Error("invalid data symbol");
- #endif
- unsigned x, init_base = base;
- // compute products
- if (data == M.last_symbol) {
- x = M.distribution[data] * (length >> DM__LengthShift);
- base += x; // update interval
- length -= x; // no product needed
- }
- else {
- x = M.distribution[data] * (length >>= DM__LengthShift);
- base += x; // update interval
- length = M.distribution[data+1] * length - x;
- }
-
- if (init_base > base) propagate_carry(); // overflow = carry
- if (length < AC__MinLength) renorm_enc_interval(); // renormalization
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- unsigned Arithmetic_Codec::decode(Static_Data_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 2) AC_Error("decoder not initialized");
- #endif
- unsigned n, s, x, y = length;
- if (M.decoder_table) { // use table look-up for faster decoding
- unsigned dv = value / (length >>= DM__LengthShift);
- unsigned t = dv >> M.table_shift;
- s = M.decoder_table[t]; // initial decision based on table look-up
- n = M.decoder_table[t+1] + 1;
- while (n > s + 1) { // finish with bisection search
- unsigned m = (s + n) >> 1;
- if (M.distribution[m] > dv) n = m; else s = m;
- }
- // compute products
- x = M.distribution[s] * length;
- if (s != M.last_symbol) y = M.distribution[s+1] * length;
- }
- else { // decode using only multiplications
- x = s = 0;
- length >>= DM__LengthShift;
- unsigned m = (n = M.data_symbols) >> 1;
- // decode via bisection search
- do {
- unsigned z = length * M.distribution[m];
- if (z > value) {
- n = m;
- y = z; // value is smaller
- }
- else {
- s = m;
- x = z; // value is larger or equal
- }
- } while ((m = (s + n) >> 1) != s);
- }
- value -= x; // update interval
- length = y - x;
- if (length < AC__MinLength) renorm_dec_interval(); // renormalization
- return s;
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Arithmetic_Codec::encode(unsigned data,
- Adaptive_Data_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 1) AC_Error("encoder not initialized");
- if (data >= M.data_symbols)
- {
- AC_Error("invalid data symbol");
- }
- #endif
- unsigned x, init_base = base;
- // compute products
- if (data == M.last_symbol) {
- x = M.distribution[data] * (length >> DM__LengthShift);
- base += x; // update interval
- length -= x; // no product needed
- }
- else {
- x = M.distribution[data] * (length >>= DM__LengthShift);
- base += x; // update interval
- length = M.distribution[data+1] * length - x;
- }
- if (init_base > base) propagate_carry(); // overflow = carry
- if (length < AC__MinLength) renorm_enc_interval(); // renormalization
- ++M.symbol_count[data];
- if (--M.symbols_until_update == 0) M.update(true); // periodic model update
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- unsigned Arithmetic_Codec::decode(Adaptive_Data_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 2) AC_Error("decoder not initialized");
- #endif
- unsigned n, s, x, y = length;
- if (M.decoder_table) { // use table look-up for faster decoding
- unsigned dv = value / (length >>= DM__LengthShift);
- unsigned t = dv >> M.table_shift;
- s = M.decoder_table[t]; // initial decision based on table look-up
- n = M.decoder_table[t+1] + 1;
- while (n > s + 1) { // finish with bisection search
- unsigned m = (s + n) >> 1;
- if (M.distribution[m] > dv) n = m; else s = m;
- }
- // compute products
- x = M.distribution[s] * length;
- if (s != M.last_symbol) {
- y = M.distribution[s+1] * length;
- }
- }
- else { // decode using only multiplications
- x = s = 0;
- length >>= DM__LengthShift;
- unsigned m = (n = M.data_symbols) >> 1;
- // decode via bisection search
- do {
- unsigned z = length * M.distribution[m];
- if (z > value) {
- n = m;
- y = z; // value is smaller
- }
- else {
- s = m;
- x = z; // value is larger or equal
- }
- } while ((m = (s + n) >> 1) != s);
- }
- value -= x; // update interval
- length = y - x;
- if (length < AC__MinLength) renorm_dec_interval(); // renormalization
- ++M.symbol_count[s];
- if (--M.symbols_until_update == 0) M.update(false); // periodic model update
- return s;
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Other Arithmetic_Codec implementations - - - - - - - - - - - - - - - -
- Arithmetic_Codec::Arithmetic_Codec(void)
- {
- mode = buffer_size = 0;
- new_buffer = code_buffer = 0;
- }
- Arithmetic_Codec::Arithmetic_Codec(unsigned max_code_bytes,
- unsigned char * user_buffer)
- {
- mode = buffer_size = 0;
- new_buffer = code_buffer = 0;
- set_buffer(max_code_bytes, user_buffer);
- }
- Arithmetic_Codec::~Arithmetic_Codec(void)
- {
- delete [] new_buffer;
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Arithmetic_Codec::set_buffer(unsigned max_code_bytes,
- unsigned char * user_buffer)
- {
- // test for reasonable sizes
- if (!max_code_bytes)// || (max_code_bytes > 0x10000000U)) // updated by K. Mammou
- {
- AC_Error("invalid codec buffer size");
- }
- if (mode != 0) AC_Error("cannot set buffer while encoding or decoding");
- if (user_buffer != 0) { // user provides memory buffer
- buffer_size = max_code_bytes;
- code_buffer = user_buffer; // set buffer for compressed data
- delete [] new_buffer; // free anything previously assigned
- new_buffer = 0;
- return;
- }
- if (max_code_bytes <= buffer_size) return; // enough available
- buffer_size = max_code_bytes; // assign new memory
- delete [] new_buffer; // free anything previously assigned
- new_buffer = new unsigned char[buffer_size+16]; // 16 extra bytes
- code_buffer = new_buffer; // set buffer for compressed data
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Arithmetic_Codec::start_encoder(void)
- {
- if (mode != 0) AC_Error("cannot start encoder");
- if (buffer_size == 0) AC_Error("no code buffer set");
- mode = 1;
- base = 0; // initialize encoder variables: interval and pointer
- length = AC__MaxLength;
- ac_pointer = code_buffer; // pointer to next data byte
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Arithmetic_Codec::start_decoder(void)
- {
- if (mode != 0) AC_Error("cannot start decoder");
- if (buffer_size == 0) AC_Error("no code buffer set");
- // initialize decoder: interval, pointer, initial code value
- mode = 2;
- length = AC__MaxLength;
- ac_pointer = code_buffer + 3;
- value = (unsigned(code_buffer[0]) << 24)|(unsigned(code_buffer[1]) << 16) |
- (unsigned(code_buffer[2]) << 8)| unsigned(code_buffer[3]);
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Arithmetic_Codec::read_from_file(FILE * code_file)
- {
- unsigned shift = 0, code_bytes = 0;
- int file_byte;
- // read variable-length header with number of code bytes
- do {
- if ((file_byte = getc(code_file)) == EOF)
- AC_Error("cannot read code from file");
- code_bytes |= unsigned(file_byte & 0x7F) << shift;
- shift += 7;
- } while (file_byte & 0x80);
- // read compressed data
- if (code_bytes > buffer_size) AC_Error("code buffer overflow");
- if (fread(code_buffer, 1, code_bytes, code_file) != code_bytes)
- AC_Error("cannot read code from file");
- start_decoder(); // initialize decoder
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- unsigned Arithmetic_Codec::stop_encoder(void)
- {
- if (mode != 1) AC_Error("invalid to stop encoder");
- mode = 0;
- unsigned init_base = base; // done encoding: set final data bytes
- if (length > 2 * AC__MinLength) {
- base += AC__MinLength; // base offset
- length = AC__MinLength >> 1; // set new length for 1 more byte
- }
- else {
- base += AC__MinLength >> 1; // base offset
- length = AC__MinLength >> 9; // set new length for 2 more bytes
- }
- if (init_base > base) propagate_carry(); // overflow = carry
- renorm_enc_interval(); // renormalization = output last bytes
- unsigned code_bytes = unsigned(ac_pointer - code_buffer);
- if (code_bytes > buffer_size) AC_Error("code buffer overflow");
- return code_bytes; // number of bytes used
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- unsigned Arithmetic_Codec::write_to_file(FILE * code_file)
- {
- unsigned header_bytes = 0, code_bytes = stop_encoder(), nb = code_bytes;
- // write variable-length header with number of code bytes
- do {
- int file_byte = int(nb & 0x7FU);
- if ((nb >>= 7) > 0) file_byte |= 0x80;
- if (putc(file_byte, code_file) == EOF)
- AC_Error("cannot write compressed data to file");
- header_bytes++;
- } while (nb);
- // write compressed data
- if (fwrite(code_buffer, 1, code_bytes, code_file) != code_bytes)
- AC_Error("cannot write compressed data to file");
- return code_bytes + header_bytes; // bytes used
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Arithmetic_Codec::stop_decoder(void)
- {
- if (mode != 2) AC_Error("invalid to stop decoder");
- mode = 0;
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - Static bit model implementation - - - - - - - - - - - - - - - - - - - - -
- Static_Bit_Model::Static_Bit_Model(void)
- {
- bit_0_prob = 1U << (BM__LengthShift - 1); // p0 = 0.5
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Static_Bit_Model::set_probability_0(double p0)
- {
- if ((p0 < 0.0001)||(p0 > 0.9999)) AC_Error("invalid bit probability");
- bit_0_prob = unsigned(p0 * (1 << BM__LengthShift));
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - Adaptive bit model implementation - - - - - - - - - - - - - - - - - - - -
- Adaptive_Bit_Model::Adaptive_Bit_Model(void)
- {
- reset();
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Adaptive_Bit_Model::reset(void)
- {
- // initialization to equiprobable model
- bit_0_count = 1;
- bit_count = 2;
- bit_0_prob = 1U << (BM__LengthShift - 1);
- update_cycle = bits_until_update = 4; // start with frequent updates
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Adaptive_Bit_Model::update(void)
- {
- // halve counts when a threshold is reached
- if ((bit_count += update_cycle) > BM__MaxCount) {
- bit_count = (bit_count + 1) >> 1;
- bit_0_count = (bit_0_count + 1) >> 1;
- if (bit_0_count == bit_count) ++bit_count;
- }
- // compute scaled bit 0 probability
- unsigned scale = 0x80000000U / bit_count;
- bit_0_prob = (bit_0_count * scale) >> (31 - BM__LengthShift);
- // set frequency of model updates
- update_cycle = (5 * update_cycle) >> 2;
- if (update_cycle > 64) update_cycle = 64;
- bits_until_update = update_cycle;
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Static data model implementation - - - - - - - - - - - - - - - - - - -
- Static_Data_Model::Static_Data_Model(void)
- {
- data_symbols = 0;
- distribution = 0;
- }
- Static_Data_Model::~Static_Data_Model(void)
- {
- delete [] distribution;
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Static_Data_Model::set_distribution(unsigned number_of_symbols,
- const double probability[])
- {
- if ((number_of_symbols < 2) || (number_of_symbols > (1 << 11)))
- AC_Error("invalid number of data symbols");
- if (data_symbols != number_of_symbols) { // assign memory for data model
- data_symbols = number_of_symbols;
- last_symbol = data_symbols - 1;
- delete [] distribution;
- // define size of table for fast decoding
- if (data_symbols > 16) {
- unsigned table_bits = 3;
- while (data_symbols > (1U << (table_bits + 2))) ++table_bits;
- table_size = 1 << table_bits;
- table_shift = DM__LengthShift - table_bits;
- distribution = new unsigned[data_symbols+table_size+2];
- decoder_table = distribution + data_symbols;
- }
- else { // small alphabet: no table needed
- decoder_table = 0;
- table_size = table_shift = 0;
- distribution = new unsigned[data_symbols];
- }
- }
- // compute cumulative distribution, decoder table
- unsigned s = 0;
- double sum = 0.0, p = 1.0 / double(data_symbols);
- for (unsigned k = 0; k < data_symbols; k++) {
- if (probability) p = probability[k];
- if ((p < 0.0001) || (p > 0.9999)) AC_Error("invalid symbol probability");
- distribution[k] = unsigned(sum * (1 << DM__LengthShift));
- sum += p;
- if (table_size == 0) continue;
- unsigned w = distribution[k] >> table_shift;
- while (s < w) decoder_table[++s] = k - 1;
- }
- if (table_size != 0) {
- decoder_table[0] = 0;
- while (s <= table_size) decoder_table[++s] = data_symbols - 1;
- }
- if ((sum < 0.9999) || (sum > 1.0001)) AC_Error("invalid probabilities");
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Adaptive data model implementation - - - - - - - - - - - - - - - - - -
- Adaptive_Data_Model::Adaptive_Data_Model(void)
- {
- data_symbols = 0;
- distribution = 0;
- }
- Adaptive_Data_Model::Adaptive_Data_Model(unsigned number_of_symbols)
- {
- data_symbols = 0;
- distribution = 0;
- set_alphabet(number_of_symbols);
- }
- Adaptive_Data_Model::~Adaptive_Data_Model(void)
- {
- delete [] distribution;
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Adaptive_Data_Model::set_alphabet(unsigned number_of_symbols)
- {
- if ((number_of_symbols < 2) || (number_of_symbols > (1 << 11)))
- AC_Error("invalid number of data symbols");
- if (data_symbols != number_of_symbols) { // assign memory for data model
- data_symbols = number_of_symbols;
- last_symbol = data_symbols - 1;
- delete [] distribution;
- // define size of table for fast decoding
- if (data_symbols > 16) {
- unsigned table_bits = 3;
- while (data_symbols > (1U << (table_bits + 2))) ++table_bits;
- table_size = 1 << table_bits;
- table_shift = DM__LengthShift - table_bits;
- distribution = new unsigned[2*data_symbols+table_size+2];
- decoder_table = distribution + 2 * data_symbols;
- }
- else { // small alphabet: no table needed
- decoder_table = 0;
- table_size = table_shift = 0;
- distribution = new unsigned[2*data_symbols];
- }
- symbol_count = distribution + data_symbols;
- }
- reset(); // initialize model
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Adaptive_Data_Model::update(bool from_encoder)
- {
- // halve counts when a threshold is reached
- if ((total_count += update_cycle) > DM__MaxCount) {
- total_count = 0;
- for (unsigned n = 0; n < data_symbols; n++)
- total_count += (symbol_count[n] = (symbol_count[n] + 1) >> 1);
- }
- assert(total_count > 0);
- // compute cumulative distribution, decoder table
- unsigned k, sum = 0, s = 0;
- unsigned scale = 0x80000000U / total_count;
- if (from_encoder || (table_size == 0))
- for (k = 0; k < data_symbols; k++) {
- distribution[k] = (scale * sum) >> (31 - DM__LengthShift);
- sum += symbol_count[k];
- }
- else {
- assert(decoder_table);
- for (k = 0; k < data_symbols; k++) {
- distribution[k] = (scale * sum) >> (31 - DM__LengthShift);
- sum += symbol_count[k];
- unsigned w = distribution[k] >> table_shift;
- while (s < w) decoder_table[++s] = k - 1;
- }
- decoder_table[0] = 0;
- while (s <= table_size) decoder_table[++s] = data_symbols - 1;
- }
- // set frequency of model updates
- update_cycle = (5 * update_cycle) >> 2;
- unsigned max_cycle = (data_symbols + 6) << 3;
- if (update_cycle > max_cycle) update_cycle = max_cycle;
- symbols_until_update = update_cycle;
- }
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- void Adaptive_Data_Model::reset(void)
- {
- if (data_symbols == 0) return;
- // restore probability estimates to uniform distribution
- total_count = 0;
- update_cycle = data_symbols;
- for (unsigned k = 0; k < data_symbols; k++) symbol_count[k] = 1;
- update(false);
- symbols_until_update = update_cycle = (data_symbols + 6) >> 1;
- }
- }
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|