diff options
Diffstat (limited to 'src/mesh/assimp-master/contrib/Open3DGC/o3dgcArithmeticCodec.cpp')
-rw-r--r-- | src/mesh/assimp-master/contrib/Open3DGC/o3dgcArithmeticCodec.cpp | 862 |
1 files changed, 0 insertions, 862 deletions
diff --git a/src/mesh/assimp-master/contrib/Open3DGC/o3dgcArithmeticCodec.cpp b/src/mesh/assimp-master/contrib/Open3DGC/o3dgcArithmeticCodec.cpp deleted file mode 100644 index 2ae70fa..0000000 --- a/src/mesh/assimp-master/contrib/Open3DGC/o3dgcArithmeticCodec.cpp +++ /dev/null @@ -1,862 +0,0 @@ -/* -Copyright (c) 2004 Amir Said (said@ieee.org) & William A. Pearlman (pearlw@ecse.rpi.edu) -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 (said@ieee.org) & - -// William A. Pearlman (pearlw@ecse.rpi.edu) - -// - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// - -// 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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; - } -} -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |