From a583b6f55aec298619a2aacf0e15aed6ecf0c320 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Fri, 15 Jan 2016 07:43:17 +0100 Subject: [PATCH 01/21] Copyright message for development version --- precomp.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/precomp.cpp b/precomp.cpp index 8c7a915..ea5f25f 100644 --- a/precomp.cpp +++ b/precomp.cpp @@ -19,11 +19,11 @@ //Version information #define V_MAJOR 0 #define V_MINOR 4 -#define V_MINOR2 4 -#define V_STATE "ALPHA" -//#define V_STATE "UNSTABLE (06 Jan 2016)" -#define V_MSG "USE FOR TESTING ONLY" -//#define V_MSG "USE AT YOUR OWN RISK!" +#define V_MINOR2 5 +//#define V_STATE "ALPHA" +#define V_STATE "DEVELOPMENT" +//#define V_MSG "USE FOR TESTING ONLY" +#define V_MSG "USE AT YOUR OWN RISK!" //#define DEBUG_FILE // batch error levels From 9716502da5f369c6685006d19c978bb2d056121e Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Fri, 15 Jan 2016 08:01:46 +0100 Subject: [PATCH 02/21] PackMP3 library added PackMP3 library version v1.0f added --- contrib/packmp3/huffmp3.cpp | 348 ++ contrib/packmp3/huffmp3.h | 92 + contrib/packmp3/huffmp3tbl.h | 7801 ++++++++++++++++++++++++++++++++ contrib/packmp3/packmp3.cpp | 8142 ++++++++++++++++++++++++++++++++++ contrib/packmp3/packmp3lib.h | 40 + contrib/packmp3/pmp3bitlen.h | 806 ++++ contrib/packmp3/pmp3tbl.h | 842 ++++ 7 files changed, 18071 insertions(+) create mode 100644 contrib/packmp3/huffmp3.cpp create mode 100644 contrib/packmp3/huffmp3.h create mode 100644 contrib/packmp3/huffmp3tbl.h create mode 100644 contrib/packmp3/packmp3.cpp create mode 100644 contrib/packmp3/packmp3lib.h create mode 100644 contrib/packmp3/pmp3bitlen.h create mode 100644 contrib/packmp3/pmp3tbl.h diff --git a/contrib/packmp3/huffmp3.cpp b/contrib/packmp3/huffmp3.cpp new file mode 100644 index 0000000..2e5facf --- /dev/null +++ b/contrib/packmp3/huffmp3.cpp @@ -0,0 +1,348 @@ +#include +#include + +#include "bitops.h" +#include "huffmp3.h" + +// bit buffer size - careful changing this! +// should not be smaller than 8 or HWIDTH_MAX +#define BIT_BUFFER_SIZE 16 + + +/* ----------------------------------------------- + small values quadruple conversion table (abs) + ----------------------------------------------- */ +static const unsigned char sv_qconv_abs[ 16 ][ 4 ] = { + { 0, 0, 0, 0 }, // 0000 -> 0/0/0/0 + { 0, 0, 0, 1 }, // 0001 -> 0/0/0/1 + { 0, 0, 1, 0 }, // 0010 -> 0/0/1/0 + { 0, 0, 1, 1 }, // 0011 -> 0/0/1/1 + { 0, 1, 0, 0 }, // 0100 -> 0/1/0/0 + { 0, 1, 0, 1 }, // 0101 -> 0/1/0/1 + { 0, 1, 1, 0 }, // 0110 -> 0/1/1/0 + { 0, 1, 1, 1 }, // 0111 -> 0/1/1/1 + { 1, 0, 0, 0 }, // 1000 -> 1/0/0/0 + { 1, 0, 0, 1 }, // 1001 -> 1/0/0/1 + { 1, 0, 1, 0 }, // 1010 -> 1/0/1/0 + { 1, 0, 1, 1 }, // 1011 -> 1/0/1/1 + { 1, 1, 0, 0 }, // 1100 -> 1/1/0/0 + { 1, 1, 0, 1 }, // 1101 -> 1/1/0/1 + { 1, 1, 1, 0 }, // 1110 -> 1/1/1/0 + { 1, 1, 1, 1 }, // 1111 -> 1/1/1/1 +}; + + +/* ----------------------------------------------- + constructor for huffman reader class + ----------------------------------------------- */ + +huffman_reader::huffman_reader( unsigned char* data, int size ) +{ + // WARNING: NO error checks in this class! + // init bitreader + bit_reader = new abitreader( data, size ); + // fill the bit buffer for the first time + bit_buffer = bit_reader->read( BIT_BUFFER_SIZE ); + // set count zero + count = 0; +} + + +/* ----------------------------------------------- + destructor for huffman reader class + ----------------------------------------------- */ + +huffman_reader::~huffman_reader( void ) +{ + // close bitreader + delete( bit_reader ); +} + + +/* ----------------------------------------------- + decode one big value pair + ----------------------------------------------- */ + +void huffman_reader::decode_pair( huffman_conv_set* table, unsigned char* vals ) +{ + huffman_conv* conv; + int ext; + + + for ( ext = 0; ext != -1; ext = conv->ext ) { + conv = (table+ext)->h + ( bit_buffer >> ( BIT_BUFFER_SIZE - (table+ext)->hwidth ) ); + advance_bitstream( conv->len ); + } + + vals[ 0 ] = conv->v0; + vals[ 1 ] = conv->v1; +} + + +/* ----------------------------------------------- + decode one small value quadruple + ----------------------------------------------- */ + +void huffman_reader::decode_quadruple( huffman_conv_set* table, unsigned char* vals ) +{ + huffman_conv* conv; + + conv = table->h + ( bit_buffer >> ( BIT_BUFFER_SIZE - table->hwidth ) ); + advance_bitstream( conv->len ); + + memcpy( vals, sv_qconv_abs[ conv->v0 ], sizeof( char ) * 4 ); +} + + +/* ----------------------------------------------- + bit reader function for n bit + ----------------------------------------------- */ + +unsigned int huffman_reader::read_bits( int n ) +{ + unsigned int bits; + + // read bits + bits = ( n <= BIT_BUFFER_SIZE ) ? + bit_buffer >> (BIT_BUFFER_SIZE-n) : + ( bit_buffer << (n-BIT_BUFFER_SIZE) ) | bit_reader->read( (n-BIT_BUFFER_SIZE) ); + // refill the buffer + advance_bitstream( n ); + + return bits; +} + + +/* ----------------------------------------------- + bit reader function for one bit + ----------------------------------------------- */ + +unsigned char huffman_reader::read_bit( void ) +{ + unsigned char bit; + + // read one bit + bit = bit_buffer >> (BIT_BUFFER_SIZE-1); + // refill the buffer + advance_bitstream_1(); + + return bit; +} + + +/* ----------------------------------------------- + reset the internal bit counter + ----------------------------------------------- */ + +void huffman_reader::reset_counter( void ) +{ + count = 0; +} + + +/* ----------------------------------------------- + get the internal bit count + ----------------------------------------------- */ + +int huffman_reader::get_count( void ) +{ + return count; +} + + +/* ----------------------------------------------- + rewind n bits + ----------------------------------------------- */ + +void huffman_reader::rewind_bits( int n ) +{ + // rewind n bits + bit_reader->rewind_bits( n + BIT_BUFFER_SIZE ); + // fill the bit buffer + bit_buffer = bit_reader->read( BIT_BUFFER_SIZE ); + // set back the counter + count = ( count > n ) ? count - n : 0; +} + + +/* ----------------------------------------------- + set position in stream + ----------------------------------------------- */ + +void huffman_reader::setpos( int pbyte, int pbit ) +{ + // reposition the bit reader + bit_reader->setpos( pbyte, pbit ); + // fill the bit buffer + bit_buffer = bit_reader->read( BIT_BUFFER_SIZE ); +} + + +/* ----------------------------------------------- + return current byte position + ----------------------------------------------- */ + +int huffman_reader::getpos( void ) +{ + // ugly, but it works! + return bit_reader->getpos() - ( BIT_BUFFER_SIZE + ( 8 - bit_reader->getbitp() ) ) / 8; +} + + +/* ----------------------------------------------- + refill bit buffer utility function + ----------------------------------------------- */ + +inline void huffman_reader::advance_bitstream( int n ) +{ + // refill the buffer + bit_buffer = ( n >= BIT_BUFFER_SIZE ) ? + bit_reader->read( BIT_BUFFER_SIZE ) : + ( ( bit_buffer << n ) | bit_reader->read( n ) ) & ( ( 1 << BIT_BUFFER_SIZE ) - 1 ); + + // record # of bits read + count += n; +} + + +/* ----------------------------------------------- + refill bit buffer utility function (1 bit) + ----------------------------------------------- */ + +inline void huffman_reader::advance_bitstream_1( void ) +{ + // refill the buffer + bit_buffer = ( ( bit_buffer << 1 ) | bit_reader->read_bit() ) & + ( ( 1 << BIT_BUFFER_SIZE ) - 1 ); + + // increment counter + count++; +} + + +/* ----------------------------------------------- + constructor for huffman writer class + ----------------------------------------------- */ + +huffman_writer::huffman_writer( int adds ) +{ + // WARNING: NO error checks in this class! + // init bitwriter - recommended value: 5MB + if ( adds == 0 ) adds = 5 * 1024 * 1024; + bit_writer = new abitwriter( adds ); + // set count zero + count = 0; +} + + +/* ----------------------------------------------- + destructor for huffman writer class + ----------------------------------------------- */ + +huffman_writer::~huffman_writer( void ) +{ + // close bitwriter + delete( bit_writer ); +} + + +/* ----------------------------------------------- + encode one big value pair + ----------------------------------------------- */ + +void huffman_writer::encode_pair( huffman_code** hcodes, unsigned char* vals ) +{ + huffman_code* hcode; + + // find correct code, encode absvals and signs + hcode = &hcodes[vals[0]][vals[1]]; + write_bits( hcode->code, hcode->len ); +} + + +/* ----------------------------------------------- + encode one small value quadruple + ----------------------------------------------- */ + +void huffman_writer::encode_quadruple( huffman_code* hcode, unsigned char* vals ) +{ + int bits = 0; + int i; + + + // build bits unit + for ( i = 0; i < 4; i++ ) { + bits = bits << 1; + if ( vals[i] ) bits |= 1; + } + + // encode vals + hcode += bits; + write_bits( hcode->code, hcode->len ); +} + + +/* ----------------------------------------------- + bit writer function for n bit + ----------------------------------------------- */ + +void huffman_writer::write_bits( unsigned int bits, int n ) +{ + // write bits + bit_writer->write( bits, n ); + // take count + count += n; +} + + +/* ----------------------------------------------- + bit writer function for 1 bit + ----------------------------------------------- */ + +void huffman_writer::write_bit( unsigned char bit ) +{ + // write bit + bit_writer->write_bit( bit ); + // increment counter + count++; +} + + +/* ----------------------------------------------- + reset the internal bit counter + ----------------------------------------------- */ + +void huffman_writer::reset_counter( void ) +{ + count = 0; +} + + +/* ----------------------------------------------- + get the internal bit count + ----------------------------------------------- */ + +int huffman_writer::get_count( void ) +{ + return count; +} + + +/* ----------------------------------------------- + return data pointer (when finished) + ----------------------------------------------- */ + +unsigned char* huffman_writer::getptr( void ) +{ + return bit_writer->getptr(); +} + + +/* ----------------------------------------------- + return current byte position + ----------------------------------------------- */ + +int huffman_writer::getpos( void ) +{ + return bit_writer->getpos(); +} diff --git a/contrib/packmp3/huffmp3.h b/contrib/packmp3/huffmp3.h new file mode 100644 index 0000000..8ae34cc --- /dev/null +++ b/contrib/packmp3/huffmp3.h @@ -0,0 +1,92 @@ +/* ----------------------------------------------- + struct declarations + ----------------------------------------------- */ + +struct huffman_code { + unsigned char len; + unsigned int code; +}; + +struct huffman_enc_table { + huffman_code** h; + int linbits; + int max; +}; + +struct huffman_conv { + unsigned char len; + int v0; + int v1; + int ext; +}; + +struct huffman_conv_set { + huffman_conv* h; + int hwidth; +}; + +struct huffman_dec_table { + huffman_conv_set* h; + int linbits; + int max; +}; + + +/* ----------------------------------------------- + class for huffman decoding/data reading + ----------------------------------------------- */ + +class huffman_reader +{ + public: + huffman_reader( unsigned char* data, int size ); + ~huffman_reader( void ); + // public functions + void decode_pair( huffman_conv_set* table, unsigned char* vals ); + void decode_quadruple( huffman_conv_set* table, unsigned char* vals ); + unsigned int read_bits( int n ); + // not the fastest method to read single bits/bytes + // luckily, we won't need it that often + unsigned char read_bit( void ); + void reset_counter( void ); + int get_count( void ); + void rewind_bits( int n ); + void setpos( int pbyte, int pbit ); + int getpos(); + + private: + // utility functions + inline void advance_bitstream( int n ); + inline void advance_bitstream_1( void ); + + // storage + abitreader* bit_reader; + unsigned int bit_buffer; + int count; +}; + + +/* ----------------------------------------------- + class for huffman encoding/data writer + ----------------------------------------------- */ + +class huffman_writer +{ + public: + huffman_writer( int adds ); + ~huffman_writer( void ); + // public functions + void encode_pair( huffman_code** hcodes, unsigned char* vals ); + void encode_quadruple( huffman_code* hcode, unsigned char* vals ); + void write_bits( unsigned int bits, int n ); + void write_bit( unsigned char bit ); + void reset_counter( void ); + int get_count( void ); + unsigned char* getptr( void ); + int getpos(); + + private: + // storage + abitwriter* bit_writer; + int count; +}; diff --git a/contrib/packmp3/huffmp3tbl.h b/contrib/packmp3/huffmp3tbl.h new file mode 100644 index 0000000..7024617 --- /dev/null +++ b/contrib/packmp3/huffmp3tbl.h @@ -0,0 +1,7801 @@ +/* ----------------------------------------------- + huffman tables according to mp3 standard + ----------------------------------------------- */ + + +/* ----------------------------------------------- + small values table A + ----------------------------------------------- */ +static huffman_code htabA_enc[ 16 ] = { + { 1, 0x01 }, // 0000 (1/1) + { 4, 0x05 }, // 0001 (4/0101) + { 4, 0x04 }, // 0010 (4/0100) + { 5, 0x05 }, // 0011 (5/00101) + { 4, 0x06 }, // 0100 (4/0110) + { 6, 0x05 }, // 0101 (6/000101) + { 5, 0x04 }, // 0110 (5/00100) + { 6, 0x04 }, // 0111 (6/000100) + { 4, 0x07 }, // 1000 (4/0111) + { 5, 0x03 }, // 1001 (5/00011) + { 5, 0x06 }, // 1010 (5/00110) + { 6, 0x00 }, // 1011 (6/000000) + { 5, 0x07 }, // 1100 (5/00111) + { 6, 0x02 }, // 1101 (6/000010) + { 6, 0x03 }, // 1110 (6/000011) + { 6, 0x01 } // 1111 (6/000001) +}; + +/* ----------------------------------------------- + small values table B + ----------------------------------------------- */ +static huffman_code htabB_enc[ 16 ] = { + { 4, 0x0F }, // 0000 (4/1111) + { 4, 0x0E }, // 0001 (4/1110) + { 4, 0x0D }, // 0010 (4/1101) + { 4, 0x0C }, // 0011 (4/1100) + { 4, 0x0B }, // 0100 (4/1011) + { 4, 0x0A }, // 0101 (4/1010) + { 4, 0x09 }, // 0110 (4/1001) + { 4, 0x08 }, // 0111 (4/1000) + { 4, 0x07 }, // 1000 (4/0111) + { 4, 0x06 }, // 1001 (4/0110) + { 4, 0x05 }, // 1010 (4/0101) + { 4, 0x04 }, // 1011 (4/0100) + { 4, 0x03 }, // 1100 (4/0011) + { 4, 0x02 }, // 1101 (4/0010) + { 4, 0x01 }, // 1110 (4/0001) + { 4, 0x00 } // 1111 (4/0000) +}; + +/* ----------------------------------------------- + big values table 0 (max 0) + ----------------------------------------------- */ +static huffman_code htab0_enc_raw[ 1 ] = { + { 0, 0x0000 } // 0/ 0 ( 0/0) +}; +static huffman_code* htab0_enc[ 1 ] = { + htab0_enc_raw + 0 // htab0 v0=0 pointer +}; + +/* ----------------------------------------------- + big values table 1 (max 1) + ----------------------------------------------- */ +static huffman_code htab1_enc_raw[ 4 ] = { + { 1, 0x0001 }, // 0/ 0 ( 1/1) + { 3, 0x0001 }, // 0/ 1 ( 3/001) + { 2, 0x0001 }, // 1/ 0 ( 2/01) + { 3, 0x0000 } // 1/ 1 ( 3/000) +}; +static huffman_code* htab1_enc[ 2 ] = { + htab1_enc_raw + 0, // htab1 v0=0 pointer + htab1_enc_raw + 2 // htab1 v0=1 pointer +}; + +/* ----------------------------------------------- + big values table 2 (max 2) + ----------------------------------------------- */ +static huffman_code htab2_enc_raw[ 9 ] = { + { 1, 0x0001 }, // 0/ 0 ( 1/1) + { 3, 0x0002 }, // 0/ 1 ( 3/010) + { 6, 0x0001 }, // 0/ 2 ( 6/000001) + { 3, 0x0003 }, // 1/ 0 ( 3/011) + { 3, 0x0001 }, // 1/ 1 ( 3/001) + { 5, 0x0001 }, // 1/ 2 ( 5/00001) + { 5, 0x0003 }, // 2/ 0 ( 5/00011) + { 5, 0x0002 }, // 2/ 1 ( 5/00010) + { 6, 0x0000 } // 2/ 2 ( 6/000000) +}; +static huffman_code* htab2_enc[ 3 ] = { + htab2_enc_raw + 0, // htab2 v0=0 pointer + htab2_enc_raw + 3, // htab2 v0=1 pointer + htab2_enc_raw + 6 // htab2 v0=2 pointer +}; + +/* ----------------------------------------------- + big values table 3 (max 2) + ----------------------------------------------- */ +static huffman_code htab3_enc_raw[ 9 ] = { + { 2, 0x0003 }, // 0/ 0 ( 2/11) + { 2, 0x0002 }, // 0/ 1 ( 2/10) + { 6, 0x0001 }, // 0/ 2 ( 6/000001) + { 3, 0x0001 }, // 1/ 0 ( 3/001) + { 2, 0x0001 }, // 1/ 1 ( 2/01) + { 5, 0x0001 }, // 1/ 2 ( 5/00001) + { 5, 0x0003 }, // 2/ 0 ( 5/00011) + { 5, 0x0002 }, // 2/ 1 ( 5/00010) + { 6, 0x0000 } // 2/ 2 ( 6/000000) +}; +static huffman_code* htab3_enc[ 3 ] = { + htab3_enc_raw + 0, // htab3 v0=0 pointer + htab3_enc_raw + 3, // htab3 v0=1 pointer + htab3_enc_raw + 6 // htab3 v0=2 pointer +}; + +/* ----------------------------------------------- + big values table 5 (max 3) + ----------------------------------------------- */ +static huffman_code htab5_enc_raw[ 16 ] = { + { 1, 0x0001 }, // 0/ 0 ( 1/1) + { 3, 0x0002 }, // 0/ 1 ( 3/010) + { 6, 0x0006 }, // 0/ 2 ( 6/000110) + { 7, 0x0005 }, // 0/ 3 ( 7/0000101) + { 3, 0x0003 }, // 1/ 0 ( 3/011) + { 3, 0x0001 }, // 1/ 1 ( 3/001) + { 6, 0x0004 }, // 1/ 2 ( 6/000100) + { 7, 0x0004 }, // 1/ 3 ( 7/0000100) + { 6, 0x0007 }, // 2/ 0 ( 6/000111) + { 6, 0x0005 }, // 2/ 1 ( 6/000101) + { 7, 0x0007 }, // 2/ 2 ( 7/0000111) + { 8, 0x0001 }, // 2/ 3 ( 8/00000001) + { 7, 0x0006 }, // 3/ 0 ( 7/0000110) + { 6, 0x0001 }, // 3/ 1 ( 6/000001) + { 7, 0x0001 }, // 3/ 2 ( 7/0000001) + { 8, 0x0000 } // 3/ 3 ( 8/00000000) +}; +static huffman_code* htab5_enc[ 4 ] = { + htab5_enc_raw + 0, // htab5 v0=0 pointer + htab5_enc_raw + 4, // htab5 v0=1 pointer + htab5_enc_raw + 8, // htab5 v0=2 pointer + htab5_enc_raw + 12 // htab5 v0=3 pointer +}; + +/* ----------------------------------------------- + big values table 6 (max 3) + ----------------------------------------------- */ +static huffman_code htab6_enc_raw[ 16 ] = { + { 3, 0x0007 }, // 0/ 0 ( 3/111) + { 3, 0x0003 }, // 0/ 1 ( 3/011) + { 5, 0x0005 }, // 0/ 2 ( 5/00101) + { 7, 0x0001 }, // 0/ 3 ( 7/0000001) + { 3, 0x0006 }, // 1/ 0 ( 3/110) + { 2, 0x0002 }, // 1/ 1 ( 2/10) + { 4, 0x0003 }, // 1/ 2 ( 4/0011) + { 5, 0x0002 }, // 1/ 3 ( 5/00010) + { 4, 0x0005 }, // 2/ 0 ( 4/0101) + { 4, 0x0004 }, // 2/ 1 ( 4/0100) + { 5, 0x0004 }, // 2/ 2 ( 5/00100) + { 6, 0x0001 }, // 2/ 3 ( 6/000001) + { 6, 0x0003 }, // 3/ 0 ( 6/000011) + { 5, 0x0003 }, // 3/ 1 ( 5/00011) + { 6, 0x0002 }, // 3/ 2 ( 6/000010) + { 7, 0x0000 } // 3/ 3 ( 7/0000000) +}; +static huffman_code* htab6_enc[ 4 ] = { + htab6_enc_raw + 0, // htab6 v0=0 pointer + htab6_enc_raw + 4, // htab6 v0=1 pointer + htab6_enc_raw + 8, // htab6 v0=2 pointer + htab6_enc_raw + 12 // htab6 v0=3 pointer +}; + +/* ----------------------------------------------- + big values table 7 (max 5) + ----------------------------------------------- */ +static huffman_code htab7_enc_raw[ 36 ] = { + { 1, 0x0001 }, // 0/ 0 ( 1/1) + { 3, 0x0002 }, // 0/ 1 ( 3/010) + { 6, 0x000A }, // 0/ 2 ( 6/001010) + { 8, 0x0013 }, // 0/ 3 ( 8/00010011) + { 8, 0x0010 }, // 0/ 4 ( 8/00010000) + { 9, 0x000A }, // 0/ 5 ( 9/000001010) + { 3, 0x0003 }, // 1/ 0 ( 3/011) + { 4, 0x0003 }, // 1/ 1 ( 4/0011) + { 6, 0x0007 }, // 1/ 2 ( 6/000111) + { 7, 0x000A }, // 1/ 3 ( 7/0001010) + { 7, 0x0005 }, // 1/ 4 ( 7/0000101) + { 8, 0x0003 }, // 1/ 5 ( 8/00000011) + { 6, 0x000B }, // 2/ 0 ( 6/001011) + { 5, 0x0004 }, // 2/ 1 ( 5/00100) + { 7, 0x000D }, // 2/ 2 ( 7/0001101) + { 8, 0x0011 }, // 2/ 3 ( 8/00010001) + { 8, 0x0008 }, // 2/ 4 ( 8/00001000) + { 9, 0x0004 }, // 2/ 5 ( 9/000000100) + { 7, 0x000C }, // 3/ 0 ( 7/0001100) + { 7, 0x000B }, // 3/ 1 ( 7/0001011) + { 8, 0x0012 }, // 3/ 2 ( 8/00010010) + { 9, 0x000F }, // 3/ 3 ( 9/000001111) + { 9, 0x000B }, // 3/ 4 ( 9/000001011) + { 9, 0x0002 }, // 3/ 5 ( 9/000000010) + { 7, 0x0007 }, // 4/ 0 ( 7/0000111) + { 7, 0x0006 }, // 4/ 1 ( 7/0000110) + { 8, 0x0009 }, // 4/ 2 ( 8/00001001) + { 9, 0x000E }, // 4/ 3 ( 9/000001110) + { 9, 0x0003 }, // 4/ 4 ( 9/000000011) + { 10, 0x0001 }, // 4/ 5 (10/0000000001) + { 8, 0x0006 }, // 5/ 0 ( 8/00000110) + { 8, 0x0004 }, // 5/ 1 ( 8/00000100) + { 9, 0x0005 }, // 5/ 2 ( 9/000000101) + { 10, 0x0003 }, // 5/ 3 (10/0000000011) + { 10, 0x0002 }, // 5/ 4 (10/0000000010) + { 10, 0x0000 } // 5/ 5 (10/0000000000) +}; +static huffman_code* htab7_enc[ 6 ] = { + htab7_enc_raw + 0, // htab7 v0=0 pointer + htab7_enc_raw + 6, // htab7 v0=1 pointer + htab7_enc_raw + 12, // htab7 v0=2 pointer + htab7_enc_raw + 18, // htab7 v0=3 pointer + htab7_enc_raw + 24, // htab7 v0=4 pointer + htab7_enc_raw + 30 // htab7 v0=5 pointer +}; + +/* ----------------------------------------------- + big values table 8 (max 5) + ----------------------------------------------- */ +static huffman_code htab8_enc_raw[ 36 ] = { + { 2, 0x0003 }, // 0/ 0 ( 2/11) + { 3, 0x0004 }, // 0/ 1 ( 3/100) + { 6, 0x0006 }, // 0/ 2 ( 6/000110) + { 8, 0x0012 }, // 0/ 3 ( 8/00010010) + { 8, 0x000C }, // 0/ 4 ( 8/00001100) + { 9, 0x0005 }, // 0/ 5 ( 9/000000101) + { 3, 0x0005 }, // 1/ 0 ( 3/101) + { 2, 0x0001 }, // 1/ 1 ( 2/01) + { 4, 0x0002 }, // 1/ 2 ( 4/0010) + { 8, 0x0010 }, // 1/ 3 ( 8/00010000) + { 8, 0x0009 }, // 1/ 4 ( 8/00001001) + { 8, 0x0003 }, // 1/ 5 ( 8/00000011) + { 6, 0x0007 }, // 2/ 0 ( 6/000111) + { 4, 0x0003 }, // 2/ 1 ( 4/0011) + { 6, 0x0005 }, // 2/ 2 ( 6/000101) + { 8, 0x000E }, // 2/ 3 ( 8/00001110) + { 8, 0x0007 }, // 2/ 4 ( 8/00000111) + { 9, 0x0003 }, // 2/ 5 ( 9/000000011) + { 8, 0x0013 }, // 3/ 0 ( 8/00010011) + { 8, 0x0011 }, // 3/ 1 ( 8/00010001) + { 8, 0x000F }, // 3/ 2 ( 8/00001111) + { 9, 0x000D }, // 3/ 3 ( 9/000001101) + { 9, 0x000A }, // 3/ 4 ( 9/000001010) + { 10, 0x0004 }, // 3/ 5 (10/0000000100) + { 8, 0x000D }, // 4/ 0 ( 8/00001101) + { 7, 0x0005 }, // 4/ 1 ( 7/0000101) + { 8, 0x0008 }, // 4/ 2 ( 8/00001000) + { 9, 0x000B }, // 4/ 3 ( 9/000001011) + { 10, 0x0005 }, // 4/ 4 (10/0000000101) + { 10, 0x0001 }, // 4/ 5 (10/0000000001) + { 9, 0x000C }, // 5/ 0 ( 9/000001100) + { 8, 0x0004 }, // 5/ 1 ( 8/00000100) + { 9, 0x0004 }, // 5/ 2 ( 9/000000100) + { 9, 0x0001 }, // 5/ 3 ( 9/000000001) + { 11, 0x0001 }, // 5/ 4 (11/00000000001) + { 11, 0x0000 } // 5/ 5 (11/00000000000) +}; +static huffman_code* htab8_enc[ 6 ] = { + htab8_enc_raw + 0, // htab8 v0=0 pointer + htab8_enc_raw + 6, // htab8 v0=1 pointer + htab8_enc_raw + 12, // htab8 v0=2 pointer + htab8_enc_raw + 18, // htab8 v0=3 pointer + htab8_enc_raw + 24, // htab8 v0=4 pointer + htab8_enc_raw + 30 // htab8 v0=5 pointer +}; + +/* ----------------------------------------------- + big values table 9 (max 5) + ----------------------------------------------- */ +static huffman_code htab9_enc_raw[ 36 ] = { + { 3, 0x0007 }, // 0/ 0 ( 3/111) + { 3, 0x0005 }, // 0/ 1 ( 3/101) + { 5, 0x0009 }, // 0/ 2 ( 5/01001) + { 6, 0x000E }, // 0/ 3 ( 6/001110) + { 8, 0x000F }, // 0/ 4 ( 8/00001111) + { 9, 0x0007 }, // 0/ 5 ( 9/000000111) + { 3, 0x0006 }, // 1/ 0 ( 3/110) + { 3, 0x0004 }, // 1/ 1 ( 3/100) + { 4, 0x0005 }, // 1/ 2 ( 4/0101) + { 5, 0x0005 }, // 1/ 3 ( 5/00101) + { 6, 0x0006 }, // 1/ 4 ( 6/000110) + { 8, 0x0007 }, // 1/ 5 ( 8/00000111) + { 4, 0x0007 }, // 2/ 0 ( 4/0111) + { 4, 0x0006 }, // 2/ 1 ( 4/0110) + { 5, 0x0008 }, // 2/ 2 ( 5/01000) + { 6, 0x0008 }, // 2/ 3 ( 6/001000) + { 7, 0x0008 }, // 2/ 4 ( 7/0001000) + { 8, 0x0005 }, // 2/ 5 ( 8/00000101) + { 6, 0x000F }, // 3/ 0 ( 6/001111) + { 5, 0x0006 }, // 3/ 1 ( 5/00110) + { 6, 0x0009 }, // 3/ 2 ( 6/001001) + { 7, 0x000A }, // 3/ 3 ( 7/0001010) + { 7, 0x0005 }, // 3/ 4 ( 7/0000101) + { 8, 0x0001 }, // 3/ 5 ( 8/00000001) + { 7, 0x000B }, // 4/ 0 ( 7/0001011) + { 6, 0x0007 }, // 4/ 1 ( 6/000111) + { 7, 0x0009 }, // 4/ 2 ( 7/0001001) + { 7, 0x0006 }, // 4/ 3 ( 7/0000110) + { 8, 0x0004 }, // 4/ 4 ( 8/00000100) + { 9, 0x0001 }, // 4/ 5 ( 9/000000001) + { 8, 0x000E }, // 5/ 0 ( 8/00001110) + { 7, 0x0004 }, // 5/ 1 ( 7/0000100) + { 8, 0x0006 }, // 5/ 2 ( 8/00000110) + { 8, 0x0002 }, // 5/ 3 ( 8/00000010) + { 9, 0x0006 }, // 5/ 4 ( 9/000000110) + { 9, 0x0000 } // 5/ 5 ( 9/000000000) +}; +static huffman_code* htab9_enc[ 6 ] = { + htab9_enc_raw + 0, // htab9 v0=0 pointer + htab9_enc_raw + 6, // htab9 v0=1 pointer + htab9_enc_raw + 12, // htab9 v0=2 pointer + htab9_enc_raw + 18, // htab9 v0=3 pointer + htab9_enc_raw + 24, // htab9 v0=4 pointer + htab9_enc_raw + 30 // htab9 v0=5 pointer +}; + +/* ----------------------------------------------- + big values table 10 (max 7) + ----------------------------------------------- */ +static huffman_code htab10_enc_raw[ 64 ] = { + { 1, 0x0001 }, // 0/ 0 ( 1/1) + { 3, 0x0002 }, // 0/ 1 ( 3/010) + { 6, 0x000A }, // 0/ 2 ( 6/001010) + { 8, 0x0017 }, // 0/ 3 ( 8/00010111) + { 9, 0x0023 }, // 0/ 4 ( 9/000100011) + { 9, 0x001E }, // 0/ 5 ( 9/000011110) + { 9, 0x000C }, // 0/ 6 ( 9/000001100) + { 10, 0x0011 }, // 0/ 7 (10/0000010001) + { 3, 0x0003 }, // 1/ 0 ( 3/011) + { 4, 0x0003 }, // 1/ 1 ( 4/0011) + { 6, 0x0008 }, // 1/ 2 ( 6/001000) + { 7, 0x000C }, // 1/ 3 ( 7/0001100) + { 8, 0x0012 }, // 1/ 4 ( 8/00010010) + { 9, 0x0015 }, // 1/ 5 ( 9/000010101) + { 8, 0x000C }, // 1/ 6 ( 8/00001100) + { 8, 0x0007 }, // 1/ 7 ( 8/00000111) + { 6, 0x000B }, // 2/ 0 ( 6/001011) + { 6, 0x0009 }, // 2/ 1 ( 6/001001) + { 7, 0x000F }, // 2/ 2 ( 7/0001111) + { 8, 0x0015 }, // 2/ 3 ( 8/00010101) + { 9, 0x0020 }, // 2/ 4 ( 9/000100000) + { 10, 0x0028 }, // 2/ 5 (10/0000101000) + { 9, 0x0013 }, // 2/ 6 ( 9/000010011) + { 9, 0x0006 }, // 2/ 7 ( 9/000000110) + { 7, 0x000E }, // 3/ 0 ( 7/0001110) + { 7, 0x000D }, // 3/ 1 ( 7/0001101) + { 8, 0x0016 }, // 3/ 2 ( 8/00010110) + { 9, 0x0022 }, // 3/ 3 ( 9/000100010) + { 10, 0x002E }, // 3/ 4 (10/0000101110) + { 10, 0x0017 }, // 3/ 5 (10/0000010111) + { 9, 0x0012 }, // 3/ 6 ( 9/000010010) + { 10, 0x0007 }, // 3/ 7 (10/0000000111) + { 8, 0x0014 }, // 4/ 0 ( 8/00010100) + { 8, 0x0013 }, // 4/ 1 ( 8/00010011) + { 9, 0x0021 }, // 4/ 2 ( 9/000100001) + { 10, 0x002F }, // 4/ 3 (10/0000101111) + { 10, 0x001B }, // 4/ 4 (10/0000011011) + { 10, 0x0016 }, // 4/ 5 (10/0000010110) + { 10, 0x0009 }, // 4/ 6 (10/0000001001) + { 10, 0x0003 }, // 4/ 7 (10/0000000011) + { 9, 0x001F }, // 5/ 0 ( 9/000011111) + { 9, 0x0016 }, // 5/ 1 ( 9/000010110) + { 10, 0x0029 }, // 5/ 2 (10/0000101001) + { 10, 0x001A }, // 5/ 3 (10/0000011010) + { 11, 0x0015 }, // 5/ 4 (11/00000010101) + { 11, 0x0014 }, // 5/ 5 (11/00000010100) + { 10, 0x0005 }, // 5/ 6 (10/0000000101) + { 11, 0x0003 }, // 5/ 7 (11/00000000011) + { 8, 0x000E }, // 6/ 0 ( 8/00001110) + { 8, 0x000D }, // 6/ 1 ( 8/00001101) + { 9, 0x000A }, // 6/ 2 ( 9/000001010) + { 10, 0x000B }, // 6/ 3 (10/0000001011) + { 10, 0x0010 }, // 6/ 4 (10/0000010000) + { 10, 0x0006 }, // 6/ 5 (10/0000000110) + { 11, 0x0005 }, // 6/ 6 (11/00000000101) + { 11, 0x0001 }, // 6/ 7 (11/00000000001) + { 9, 0x0009 }, // 7/ 0 ( 9/000001001) + { 8, 0x0008 }, // 7/ 1 ( 8/00001000) + { 9, 0x0007 }, // 7/ 2 ( 9/000000111) + { 10, 0x0008 }, // 7/ 3 (10/0000001000) + { 10, 0x0004 }, // 7/ 4 (10/0000000100) + { 11, 0x0004 }, // 7/ 5 (11/00000000100) + { 11, 0x0002 }, // 7/ 6 (11/00000000010) + { 11, 0x0000 } // 7/ 7 (11/00000000000) +}; +static huffman_code* htab10_enc[ 8 ] = { + htab10_enc_raw + 0, // htab10 v0=0 pointer + htab10_enc_raw + 8, // htab10 v0=1 pointer + htab10_enc_raw + 16, // htab10 v0=2 pointer + htab10_enc_raw + 24, // htab10 v0=3 pointer + htab10_enc_raw + 32, // htab10 v0=4 pointer + htab10_enc_raw + 40, // htab10 v0=5 pointer + htab10_enc_raw + 48, // htab10 v0=6 pointer + htab10_enc_raw + 56 // htab10 v0=7 pointer +}; + +/* ----------------------------------------------- + big values table 11 (max 7) + ----------------------------------------------- */ +static huffman_code htab11_enc_raw[ 64 ] = { + { 2, 0x0003 }, // 0/ 0 ( 2/11) + { 3, 0x0004 }, // 0/ 1 ( 3/100) + { 5, 0x000A }, // 0/ 2 ( 5/01010) + { 7, 0x0018 }, // 0/ 3 ( 7/0011000) + { 8, 0x0022 }, // 0/ 4 ( 8/00100010) + { 9, 0x0021 }, // 0/ 5 ( 9/000100001) + { 8, 0x0015 }, // 0/ 6 ( 8/00010101) + { 9, 0x000F }, // 0/ 7 ( 9/000001111) + { 3, 0x0005 }, // 1/ 0 ( 3/101) + { 3, 0x0003 }, // 1/ 1 ( 3/011) + { 4, 0x0004 }, // 1/ 2 ( 4/0100) + { 6, 0x000A }, // 1/ 3 ( 6/001010) + { 8, 0x0020 }, // 1/ 4 ( 8/00100000) + { 8, 0x0011 }, // 1/ 5 ( 8/00010001) + { 7, 0x000B }, // 1/ 6 ( 7/0001011) + { 8, 0x000A }, // 1/ 7 ( 8/00001010) + { 5, 0x000B }, // 2/ 0 ( 5/01011) + { 5, 0x0007 }, // 2/ 1 ( 5/00111) + { 6, 0x000D }, // 2/ 2 ( 6/001101) + { 7, 0x0012 }, // 2/ 3 ( 7/0010010) + { 8, 0x001E }, // 2/ 4 ( 8/00011110) + { 9, 0x001F }, // 2/ 5 ( 9/000011111) + { 8, 0x0014 }, // 2/ 6 ( 8/00010100) + { 8, 0x0005 }, // 2/ 7 ( 8/00000101) + { 7, 0x0019 }, // 3/ 0 ( 7/0011001) + { 6, 0x000B }, // 3/ 1 ( 6/001011) + { 7, 0x0013 }, // 3/ 2 ( 7/0010011) + { 9, 0x003B }, // 3/ 3 ( 9/000111011) + { 8, 0x001B }, // 3/ 4 ( 8/00011011) + { 10, 0x0012 }, // 3/ 5 (10/0000010010) + { 8, 0x000C }, // 3/ 6 ( 8/00001100) + { 9, 0x0005 }, // 3/ 7 ( 9/000000101) + { 8, 0x0023 }, // 4/ 0 ( 8/00100011) + { 8, 0x0021 }, // 4/ 1 ( 8/00100001) + { 8, 0x001F }, // 4/ 2 ( 8/00011111) + { 9, 0x003A }, // 4/ 3 ( 9/000111010) + { 9, 0x001E }, // 4/ 4 ( 9/000011110) + { 10, 0x0010 }, // 4/ 5 (10/0000010000) + { 9, 0x0007 }, // 4/ 6 ( 9/000000111) + { 10, 0x0005 }, // 4/ 7 (10/0000000101) + { 8, 0x001C }, // 5/ 0 ( 8/00011100) + { 8, 0x001A }, // 5/ 1 ( 8/00011010) + { 9, 0x0020 }, // 5/ 2 ( 9/000100000) + { 10, 0x0013 }, // 5/ 3 (10/0000010011) + { 10, 0x0011 }, // 5/ 4 (10/0000010001) + { 11, 0x000F }, // 5/ 5 (11/00000001111) + { 10, 0x0008 }, // 5/ 6 (10/0000001000) + { 11, 0x000E }, // 5/ 7 (11/00000001110) + { 8, 0x000E }, // 6/ 0 ( 8/00001110) + { 7, 0x000C }, // 6/ 1 ( 7/0001100) + { 7, 0x0009 }, // 6/ 2 ( 7/0001001) + { 8, 0x000D }, // 6/ 3 ( 8/00001101) + { 9, 0x000E }, // 6/ 4 ( 9/000001110) + { 10, 0x0009 }, // 6/ 5 (10/0000001001) + { 10, 0x0004 }, // 6/ 6 (10/0000000100) + { 10, 0x0001 }, // 6/ 7 (10/0000000001) + { 8, 0x000B }, // 7/ 0 ( 8/00001011) + { 7, 0x0004 }, // 7/ 1 ( 7/0000100) + { 8, 0x0006 }, // 7/ 2 ( 8/00000110) + { 9, 0x0006 }, // 7/ 3 ( 9/000000110) + { 10, 0x0006 }, // 7/ 4 (10/0000000110) + { 10, 0x0003 }, // 7/ 5 (10/0000000011) + { 10, 0x0002 }, // 7/ 6 (10/0000000010) + { 10, 0x0000 } // 7/ 7 (10/0000000000) +}; +static huffman_code* htab11_enc[ 8 ] = { + htab11_enc_raw + 0, // htab11 v0=0 pointer + htab11_enc_raw + 8, // htab11 v0=1 pointer + htab11_enc_raw + 16, // htab11 v0=2 pointer + htab11_enc_raw + 24, // htab11 v0=3 pointer + htab11_enc_raw + 32, // htab11 v0=4 pointer + htab11_enc_raw + 40, // htab11 v0=5 pointer + htab11_enc_raw + 48, // htab11 v0=6 pointer + htab11_enc_raw + 56 // htab11 v0=7 pointer +}; + +/* ----------------------------------------------- + big values table 12 (max 7) + ----------------------------------------------- */ +static huffman_code htab12_enc_raw[ 64 ] = { + { 4, 0x0009 }, // 0/ 0 ( 4/1001) + { 3, 0x0006 }, // 0/ 1 ( 3/110) + { 5, 0x0010 }, // 0/ 2 ( 5/10000) + { 7, 0x0021 }, // 0/ 3 ( 7/0100001) + { 8, 0x0029 }, // 0/ 4 ( 8/00101001) + { 9, 0x0027 }, // 0/ 5 ( 9/000100111) + { 9, 0x0026 }, // 0/ 6 ( 9/000100110) + { 9, 0x001A }, // 0/ 7 ( 9/000011010) + { 3, 0x0007 }, // 1/ 0 ( 3/111) + { 3, 0x0005 }, // 1/ 1 ( 3/101) + { 4, 0x0006 }, // 1/ 2 ( 4/0110) + { 5, 0x0009 }, // 1/ 3 ( 5/01001) + { 7, 0x0017 }, // 1/ 4 ( 7/0010111) + { 7, 0x0010 }, // 1/ 5 ( 7/0010000) + { 8, 0x001A }, // 1/ 6 ( 8/00011010) + { 8, 0x000B }, // 1/ 7 ( 8/00001011) + { 5, 0x0011 }, // 2/ 0 ( 5/10001) + { 4, 0x0007 }, // 2/ 1 ( 4/0111) + { 5, 0x000B }, // 2/ 2 ( 5/01011) + { 6, 0x000E }, // 2/ 3 ( 6/001110) + { 7, 0x0015 }, // 2/ 4 ( 7/0010101) + { 8, 0x001E }, // 2/ 5 ( 8/00011110) + { 7, 0x000A }, // 2/ 6 ( 7/0001010) + { 8, 0x0007 }, // 2/ 7 ( 8/00000111) + { 6, 0x0011 }, // 3/ 0 ( 6/010001) + { 5, 0x000A }, // 3/ 1 ( 5/01010) + { 6, 0x000F }, // 3/ 2 ( 6/001111) + { 6, 0x000C }, // 3/ 3 ( 6/001100) + { 7, 0x0012 }, // 3/ 4 ( 7/0010010) + { 8, 0x001C }, // 3/ 5 ( 8/00011100) + { 8, 0x000E }, // 3/ 6 ( 8/00001110) + { 8, 0x0005 }, // 3/ 7 ( 8/00000101) + { 7, 0x0020 }, // 4/ 0 ( 7/0100000) + { 6, 0x000D }, // 4/ 1 ( 6/001101) + { 7, 0x0016 }, // 4/ 2 ( 7/0010110) + { 7, 0x0013 }, // 4/ 3 ( 7/0010011) + { 8, 0x0012 }, // 4/ 4 ( 8/00010010) + { 8, 0x0010 }, // 4/ 5 ( 8/00010000) + { 8, 0x0009 }, // 4/ 6 ( 8/00001001) + { 9, 0x0005 }, // 4/ 7 ( 9/000000101) + { 8, 0x0028 }, // 5/ 0 ( 8/00101000) + { 7, 0x0011 }, // 5/ 1 ( 7/0010001) + { 8, 0x001F }, // 5/ 2 ( 8/00011111) + { 8, 0x001D }, // 5/ 3 ( 8/00011101) + { 8, 0x0011 }, // 5/ 4 ( 8/00010001) + { 9, 0x000D }, // 5/ 5 ( 9/000001101) + { 8, 0x0004 }, // 5/ 6 ( 8/00000100) + { 9, 0x0002 }, // 5/ 7 ( 9/000000010) + { 8, 0x001B }, // 6/ 0 ( 8/00011011) + { 7, 0x000C }, // 6/ 1 ( 7/0001100) + { 7, 0x000B }, // 6/ 2 ( 7/0001011) + { 8, 0x000F }, // 6/ 3 ( 8/00001111) + { 8, 0x000A }, // 6/ 4 ( 8/00001010) + { 9, 0x0007 }, // 6/ 5 ( 9/000000111) + { 9, 0x0004 }, // 6/ 6 ( 9/000000100) + { 10, 0x0001 }, // 6/ 7 (10/0000000001) + { 9, 0x001B }, // 7/ 0 ( 9/000011011) + { 8, 0x000C }, // 7/ 1 ( 8/00001100) + { 8, 0x0008 }, // 7/ 2 ( 8/00001000) + { 9, 0x000C }, // 7/ 3 ( 9/000001100) + { 9, 0x0006 }, // 7/ 4 ( 9/000000110) + { 9, 0x0003 }, // 7/ 5 ( 9/000000011) + { 9, 0x0001 }, // 7/ 6 ( 9/000000001) + { 10, 0x0000 } // 7/ 7 (10/0000000000) +}; +static huffman_code* htab12_enc[ 8 ] = { + htab12_enc_raw + 0, // htab12 v0=0 pointer + htab12_enc_raw + 8, // htab12 v0=1 pointer + htab12_enc_raw + 16, // htab12 v0=2 pointer + htab12_enc_raw + 24, // htab12 v0=3 pointer + htab12_enc_raw + 32, // htab12 v0=4 pointer + htab12_enc_raw + 40, // htab12 v0=5 pointer + htab12_enc_raw + 48, // htab12 v0=6 pointer + htab12_enc_raw + 56 // htab12 v0=7 pointer +}; + +/* ----------------------------------------------- + big values table 13 (max 15) + ----------------------------------------------- */ +static huffman_code htab13_enc_raw[ 256 ] = { + { 1, 0x0001 }, // 0/ 0 ( 1/1) + { 4, 0x0005 }, // 0/ 1 ( 4/0101) + { 6, 0x000E }, // 0/ 2 ( 6/001110) + { 7, 0x0015 }, // 0/ 3 ( 7/0010101) + { 8, 0x0022 }, // 0/ 4 ( 8/00100010) + { 9, 0x0033 }, // 0/ 5 ( 9/000110011) + { 9, 0x002E }, // 0/ 6 ( 9/000101110) + { 10, 0x0047 }, // 0/ 7 (10/0001000111) + { 9, 0x002A }, // 0/ 8 ( 9/000101010) + { 10, 0x0034 }, // 0/ 9 (10/0000110100) + { 11, 0x0044 }, // 0/10 (11/00001000100) + { 11, 0x0034 }, // 0/11 (11/00000110100) + { 12, 0x0043 }, // 0/12 (12/000001000011) + { 12, 0x002C }, // 0/13 (12/000000101100) + { 13, 0x002B }, // 0/14 (13/0000000101011) + { 13, 0x0013 }, // 0/15 (13/0000000010011) + { 3, 0x0003 }, // 1/ 0 ( 3/011) + { 4, 0x0004 }, // 1/ 1 ( 4/0100) + { 6, 0x000C }, // 1/ 2 ( 6/001100) + { 7, 0x0013 }, // 1/ 3 ( 7/0010011) + { 8, 0x001F }, // 1/ 4 ( 8/00011111) + { 8, 0x001A }, // 1/ 5 ( 8/00011010) + { 9, 0x002C }, // 1/ 6 ( 9/000101100) + { 9, 0x0021 }, // 1/ 7 ( 9/000100001) + { 9, 0x001F }, // 1/ 8 ( 9/000011111) + { 9, 0x0018 }, // 1/ 9 ( 9/000011000) + { 10, 0x0020 }, // 1/10 (10/0000100000) + { 10, 0x0018 }, // 1/11 (10/0000011000) + { 11, 0x001F }, // 1/12 (11/00000011111) + { 12, 0x0023 }, // 1/13 (12/000000100011) + { 12, 0x0016 }, // 1/14 (12/000000010110) + { 12, 0x000E }, // 1/15 (12/000000001110) + { 6, 0x000F }, // 2/ 0 ( 6/001111) + { 6, 0x000D }, // 2/ 1 ( 6/001101) + { 7, 0x0017 }, // 2/ 2 ( 7/0010111) + { 8, 0x0024 }, // 2/ 3 ( 8/00100100) + { 9, 0x003B }, // 2/ 4 ( 9/000111011) + { 9, 0x0031 }, // 2/ 5 ( 9/000110001) + { 10, 0x004D }, // 2/ 6 (10/0001001101) + { 10, 0x0041 }, // 2/ 7 (10/0001000001) + { 9, 0x001D }, // 2/ 8 ( 9/000011101) + { 10, 0x0028 }, // 2/ 9 (10/0000101000) + { 10, 0x001E }, // 2/10 (10/0000011110) + { 11, 0x0028 }, // 2/11 (11/00000101000) + { 11, 0x001B }, // 2/12 (11/00000011011) + { 12, 0x0021 }, // 2/13 (12/000000100001) + { 13, 0x002A }, // 2/14 (13/0000000101010) + { 13, 0x0010 }, // 2/15 (13/0000000010000) + { 7, 0x0016 }, // 3/ 0 ( 7/0010110) + { 7, 0x0014 }, // 3/ 1 ( 7/0010100) + { 8, 0x0025 }, // 3/ 2 ( 8/00100101) + { 9, 0x003D }, // 3/ 3 ( 9/000111101) + { 9, 0x0038 }, // 3/ 4 ( 9/000111000) + { 10, 0x004F }, // 3/ 5 (10/0001001111) + { 10, 0x0049 }, // 3/ 6 (10/0001001001) + { 10, 0x0040 }, // 3/ 7 (10/0001000000) + { 10, 0x002B }, // 3/ 8 (10/0000101011) + { 11, 0x004C }, // 3/ 9 (11/00001001100) + { 11, 0x0038 }, // 3/10 (11/00000111000) + { 11, 0x0025 }, // 3/11 (11/00000100101) + { 11, 0x001A }, // 3/12 (11/00000011010) + { 12, 0x001F }, // 3/13 (12/000000011111) + { 13, 0x0019 }, // 3/14 (13/0000000011001) + { 13, 0x000E }, // 3/15 (13/0000000001110) + { 8, 0x0023 }, // 4/ 0 ( 8/00100011) + { 7, 0x0010 }, // 4/ 1 ( 7/0010000) + { 9, 0x003C }, // 4/ 2 ( 9/000111100) + { 9, 0x0039 }, // 4/ 3 ( 9/000111001) + { 10, 0x0061 }, // 4/ 4 (10/0001100001) + { 10, 0x004B }, // 4/ 5 (10/0001001011) + { 11, 0x0072 }, // 4/ 6 (11/00001110010) + { 11, 0x005B }, // 4/ 7 (11/00001011011) + { 10, 0x0036 }, // 4/ 8 (10/0000110110) + { 11, 0x0049 }, // 4/ 9 (11/00001001001) + { 11, 0x0037 }, // 4/10 (11/00000110111) + { 12, 0x0029 }, // 4/11 (12/000000101001) + { 12, 0x0030 }, // 4/12 (12/000000110000) + { 13, 0x0035 }, // 4/13 (13/0000000110101) + { 13, 0x0017 }, // 4/14 (13/0000000010111) + { 14, 0x0018 }, // 4/15 (14/00000000011000) + { 9, 0x003A }, // 5/ 0 ( 9/000111010) + { 8, 0x001B }, // 5/ 1 ( 8/00011011) + { 9, 0x0032 }, // 5/ 2 ( 9/000110010) + { 10, 0x0060 }, // 5/ 3 (10/0001100000) + { 10, 0x004C }, // 5/ 4 (10/0001001100) + { 10, 0x0046 }, // 5/ 5 (10/0001000110) + { 11, 0x005D }, // 5/ 6 (11/00001011101) + { 11, 0x0054 }, // 5/ 7 (11/00001010100) + { 11, 0x004D }, // 5/ 8 (11/00001001101) + { 11, 0x003A }, // 5/ 9 (11/00000111010) + { 12, 0x004F }, // 5/10 (12/000001001111) + { 11, 0x001D }, // 5/11 (11/00000011101) + { 13, 0x004A }, // 5/12 (13/0000001001010) + { 13, 0x0031 }, // 5/13 (13/0000000110001) + { 14, 0x0029 }, // 5/14 (14/00000000101001) + { 14, 0x0011 }, // 5/15 (14/00000000010001) + { 9, 0x002F }, // 6/ 0 ( 9/000101111) + { 9, 0x002D }, // 6/ 1 ( 9/000101101) + { 10, 0x004E }, // 6/ 2 (10/0001001110) + { 10, 0x004A }, // 6/ 3 (10/0001001010) + { 11, 0x0073 }, // 6/ 4 (11/00001110011) + { 11, 0x005E }, // 6/ 5 (11/00001011110) + { 11, 0x005A }, // 6/ 6 (11/00001011010) + { 11, 0x004F }, // 6/ 7 (11/00001001111) + { 11, 0x0045 }, // 6/ 8 (11/00001000101) + { 12, 0x0053 }, // 6/ 9 (12/000001010011) + { 12, 0x0047 }, // 6/10 (12/000001000111) + { 12, 0x0032 }, // 6/11 (12/000000110010) + { 13, 0x003B }, // 6/12 (13/0000000111011) + { 13, 0x0026 }, // 6/13 (13/0000000100110) + { 14, 0x0024 }, // 6/14 (14/00000000100100) + { 14, 0x000F }, // 6/15 (14/00000000001111) + { 10, 0x0048 }, // 7/ 0 (10/0001001000) + { 9, 0x0022 }, // 7/ 1 ( 9/000100010) + { 10, 0x0038 }, // 7/ 2 (10/0000111000) + { 11, 0x005F }, // 7/ 3 (11/00001011111) + { 11, 0x005C }, // 7/ 4 (11/00001011100) + { 11, 0x0055 }, // 7/ 5 (11/00001010101) + { 12, 0x005B }, // 7/ 6 (12/000001011011) + { 12, 0x005A }, // 7/ 7 (12/000001011010) + { 12, 0x0056 }, // 7/ 8 (12/000001010110) + { 12, 0x0049 }, // 7/ 9 (12/000001001001) + { 13, 0x004D }, // 7/10 (13/0000001001101) + { 13, 0x0041 }, // 7/11 (13/0000001000001) + { 13, 0x0033 }, // 7/12 (13/0000000110011) + { 14, 0x002C }, // 7/13 (14/00000000101100) + { 16, 0x002B }, // 7/14 (16/0000000000101011) + { 16, 0x002A }, // 7/15 (16/0000000000101010) + { 9, 0x002B }, // 8/ 0 ( 9/000101011) + { 8, 0x0014 }, // 8/ 1 ( 8/00010100) + { 9, 0x001E }, // 8/ 2 ( 9/000011110) + { 10, 0x002C }, // 8/ 3 (10/0000101100) + { 10, 0x0037 }, // 8/ 4 (10/0000110111) + { 11, 0x004E }, // 8/ 5 (11/00001001110) + { 11, 0x0048 }, // 8/ 6 (11/00001001000) + { 12, 0x0057 }, // 8/ 7 (12/000001010111) + { 12, 0x004E }, // 8/ 8 (12/000001001110) + { 12, 0x003D }, // 8/ 9 (12/000000111101) + { 12, 0x002E }, // 8/10 (12/000000101110) + { 13, 0x0036 }, // 8/11 (13/0000000110110) + { 13, 0x0025 }, // 8/12 (13/0000000100101) + { 14, 0x001E }, // 8/13 (14/00000000011110) + { 15, 0x0014 }, // 8/14 (15/000000000010100) + { 15, 0x0010 }, // 8/15 (15/000000000010000) + { 10, 0x0035 }, // 9/ 0 (10/0000110101) + { 9, 0x0019 }, // 9/ 1 ( 9/000011001) + { 10, 0x0029 }, // 9/ 2 (10/0000101001) + { 10, 0x0025 }, // 9/ 3 (10/0000100101) + { 11, 0x002C }, // 9/ 4 (11/00000101100) + { 11, 0x003B }, // 9/ 5 (11/00000111011) + { 11, 0x0036 }, // 9/ 6 (11/00000110110) + { 13, 0x0051 }, // 9/ 7 (13/0000001010001) + { 12, 0x0042 }, // 9/ 8 (12/000001000010) + { 13, 0x004C }, // 9/ 9 (13/0000001001100) + { 13, 0x0039 }, // 9/10 (13/0000000111001) + { 14, 0x0036 }, // 9/11 (14/00000000110110) + { 14, 0x0025 }, // 9/12 (14/00000000100101) + { 14, 0x0012 }, // 9/13 (14/00000000010010) + { 16, 0x0027 }, // 9/14 (16/0000000000100111) + { 15, 0x000B }, // 9/15 (15/000000000001011) + { 10, 0x0023 }, // 10/ 0 (10/0000100011) + { 10, 0x0021 }, // 10/ 1 (10/0000100001) + { 10, 0x001F }, // 10/ 2 (10/0000011111) + { 11, 0x0039 }, // 10/ 3 (11/00000111001) + { 11, 0x002A }, // 10/ 4 (11/00000101010) + { 12, 0x0052 }, // 10/ 5 (12/000001010010) + { 12, 0x0048 }, // 10/ 6 (12/000001001000) + { 13, 0x0050 }, // 10/ 7 (13/0000001010000) + { 12, 0x002F }, // 10/ 8 (12/000000101111) + { 13, 0x003A }, // 10/ 9 (13/0000000111010) + { 14, 0x0037 }, // 10/10 (14/00000000110111) + { 13, 0x0015 }, // 10/11 (13/0000000010101) + { 14, 0x0016 }, // 10/12 (14/00000000010110) + { 15, 0x001A }, // 10/13 (15/000000000011010) + { 16, 0x0026 }, // 10/14 (16/0000000000100110) + { 17, 0x0016 }, // 10/15 (17/00000000000010110) + { 11, 0x0035 }, // 11/ 0 (11/00000110101) + { 10, 0x0019 }, // 11/ 1 (10/0000011001) + { 10, 0x0017 }, // 11/ 2 (10/0000010111) + { 11, 0x0026 }, // 11/ 3 (11/00000100110) + { 12, 0x0046 }, // 11/ 4 (12/000001000110) + { 12, 0x003C }, // 11/ 5 (12/000000111100) + { 12, 0x0033 }, // 11/ 6 (12/000000110011) + { 12, 0x0024 }, // 11/ 7 (12/000000100100) + { 13, 0x0037 }, // 11/ 8 (13/0000000110111) + { 13, 0x001A }, // 11/ 9 (13/0000000011010) + { 13, 0x0022 }, // 11/10 (13/0000000100010) + { 14, 0x0017 }, // 11/11 (14/00000000010111) + { 15, 0x001B }, // 11/12 (15/000000000011011) + { 15, 0x000E }, // 11/13 (15/000000000001110) + { 15, 0x0009 }, // 11/14 (15/000000000001001) + { 16, 0x0007 }, // 11/15 (16/0000000000000111) + { 11, 0x0022 }, // 12/ 0 (11/00000100010) + { 11, 0x0020 }, // 12/ 1 (11/00000100000) + { 11, 0x001C }, // 12/ 2 (11/00000011100) + { 12, 0x0027 }, // 12/ 3 (12/000000100111) + { 12, 0x0031 }, // 12/ 4 (12/000000110001) + { 13, 0x004B }, // 12/ 5 (13/0000001001011) + { 12, 0x001E }, // 12/ 6 (12/000000011110) + { 13, 0x0034 }, // 12/ 7 (13/0000000110100) + { 14, 0x0030 }, // 12/ 8 (14/00000000110000) + { 14, 0x0028 }, // 12/ 9 (14/00000000101000) + { 15, 0x0034 }, // 12/10 (15/000000000110100) + { 15, 0x001C }, // 12/11 (15/000000000011100) + { 15, 0x0012 }, // 12/12 (15/000000000010010) + { 16, 0x0011 }, // 12/13 (16/0000000000010001) + { 16, 0x0009 }, // 12/14 (16/0000000000001001) + { 16, 0x0005 }, // 12/15 (16/0000000000000101) + { 12, 0x002D }, // 13/ 0 (12/000000101101) + { 11, 0x0015 }, // 13/ 1 (11/00000010101) + { 12, 0x0022 }, // 13/ 2 (12/000000100010) + { 13, 0x0040 }, // 13/ 3 (13/0000001000000) + { 13, 0x0038 }, // 13/ 4 (13/0000000111000) + { 13, 0x0032 }, // 13/ 5 (13/0000000110010) + { 14, 0x0031 }, // 13/ 6 (14/00000000110001) + { 14, 0x002D }, // 13/ 7 (14/00000000101101) + { 14, 0x001F }, // 13/ 8 (14/00000000011111) + { 14, 0x0013 }, // 13/ 9 (14/00000000010011) + { 14, 0x000C }, // 13/10 (14/00000000001100) + { 15, 0x000F }, // 13/11 (15/000000000001111) + { 16, 0x000A }, // 13/12 (16/0000000000001010) + { 15, 0x0007 }, // 13/13 (15/000000000000111) + { 16, 0x0006 }, // 13/14 (16/0000000000000110) + { 16, 0x0003 }, // 13/15 (16/0000000000000011) + { 13, 0x0030 }, // 14/ 0 (13/0000000110000) + { 12, 0x0017 }, // 14/ 1 (12/000000010111) + { 12, 0x0014 }, // 14/ 2 (12/000000010100) + { 13, 0x0027 }, // 14/ 3 (13/0000000100111) + { 13, 0x0024 }, // 14/ 4 (13/0000000100100) + { 13, 0x0023 }, // 14/ 5 (13/0000000100011) + { 15, 0x0035 }, // 14/ 6 (15/000000000110101) + { 14, 0x0015 }, // 14/ 7 (14/00000000010101) + { 14, 0x0010 }, // 14/ 8 (14/00000000010000) + { 17, 0x0017 }, // 14/ 9 (17/00000000000010111) + { 15, 0x000D }, // 14/10 (15/000000000001101) + { 15, 0x000A }, // 14/11 (15/000000000001010) + { 15, 0x0006 }, // 14/12 (15/000000000000110) + { 17, 0x0001 }, // 14/13 (17/00000000000000001) + { 16, 0x0004 }, // 14/14 (16/0000000000000100) + { 16, 0x0002 }, // 14/15 (16/0000000000000010) + { 12, 0x0010 }, // 15/ 0 (12/000000010000) + { 12, 0x000F }, // 15/ 1 (12/000000001111) + { 13, 0x0011 }, // 15/ 2 (13/0000000010001) + { 14, 0x001B }, // 15/ 3 (14/00000000011011) + { 14, 0x0019 }, // 15/ 4 (14/00000000011001) + { 14, 0x0014 }, // 15/ 5 (14/00000000010100) + { 15, 0x001D }, // 15/ 6 (15/000000000011101) + { 14, 0x000B }, // 15/ 7 (14/00000000001011) + { 15, 0x0011 }, // 15/ 8 (15/000000000010001) + { 15, 0x000C }, // 15/ 9 (15/000000000001100) + { 16, 0x0010 }, // 15/10 (16/0000000000010000) + { 16, 0x0008 }, // 15/11 (16/0000000000001000) + { 19, 0x0001 }, // 15/12 (19/0000000000000000001) + { 18, 0x0001 }, // 15/13 (18/000000000000000001) + { 19, 0x0000 }, // 15/14 (19/0000000000000000000) + { 16, 0x0001 } // 15/15 (16/0000000000000001) +}; +static huffman_code* htab13_enc[ 16 ] = { + htab13_enc_raw + 0, // htab13 v0=0 pointer + htab13_enc_raw + 16, // htab13 v0=1 pointer + htab13_enc_raw + 32, // htab13 v0=2 pointer + htab13_enc_raw + 48, // htab13 v0=3 pointer + htab13_enc_raw + 64, // htab13 v0=4 pointer + htab13_enc_raw + 80, // htab13 v0=5 pointer + htab13_enc_raw + 96, // htab13 v0=6 pointer + htab13_enc_raw + 112, // htab13 v0=7 pointer + htab13_enc_raw + 128, // htab13 v0=8 pointer + htab13_enc_raw + 144, // htab13 v0=9 pointer + htab13_enc_raw + 160, // htab13 v0=10 pointer + htab13_enc_raw + 176, // htab13 v0=11 pointer + htab13_enc_raw + 192, // htab13 v0=12 pointer + htab13_enc_raw + 208, // htab13 v0=13 pointer + htab13_enc_raw + 224, // htab13 v0=14 pointer + htab13_enc_raw + 240 // htab13 v0=15 pointer +}; + +/* ----------------------------------------------- + big values table 15 (max 15) + ----------------------------------------------- */ +static huffman_code htab15_enc_raw[ 256 ] = { + { 3, 0x0007 }, // 0/ 0 ( 3/111) + { 4, 0x000C }, // 0/ 1 ( 4/1100) + { 5, 0x0012 }, // 0/ 2 ( 5/10010) + { 7, 0x0035 }, // 0/ 3 ( 7/0110101) + { 7, 0x002F }, // 0/ 4 ( 7/0101111) + { 8, 0x004C }, // 0/ 5 ( 8/01001100) + { 9, 0x007C }, // 0/ 6 ( 9/001111100) + { 9, 0x006C }, // 0/ 7 ( 9/001101100) + { 9, 0x0059 }, // 0/ 8 ( 9/001011001) + { 10, 0x007B }, // 0/ 9 (10/0001111011) + { 10, 0x006C }, // 0/10 (10/0001101100) + { 11, 0x0077 }, // 0/11 (11/00001110111) + { 11, 0x006B }, // 0/12 (11/00001101011) + { 11, 0x0051 }, // 0/13 (11/00001010001) + { 12, 0x007A }, // 0/14 (12/000001111010) + { 13, 0x003F }, // 0/15 (13/0000000111111) + { 4, 0x000D }, // 1/ 0 ( 4/1101) + { 3, 0x0005 }, // 1/ 1 ( 3/101) + { 5, 0x0010 }, // 1/ 2 ( 5/10000) + { 6, 0x001B }, // 1/ 3 ( 6/011011) + { 7, 0x002E }, // 1/ 4 ( 7/0101110) + { 7, 0x0024 }, // 1/ 5 ( 7/0100100) + { 8, 0x003D }, // 1/ 6 ( 8/00111101) + { 8, 0x0033 }, // 1/ 7 ( 8/00110011) + { 8, 0x002A }, // 1/ 8 ( 8/00101010) + { 9, 0x0046 }, // 1/ 9 ( 9/001000110) + { 9, 0x0034 }, // 1/10 ( 9/000110100) + { 10, 0x0053 }, // 1/11 (10/0001010011) + { 10, 0x0041 }, // 1/12 (10/0001000001) + { 10, 0x0029 }, // 1/13 (10/0000101001) + { 11, 0x003B }, // 1/14 (11/00000111011) + { 11, 0x0024 }, // 1/15 (11/00000100100) + { 5, 0x0013 }, // 2/ 0 ( 5/10011) + { 5, 0x0011 }, // 2/ 1 ( 5/10001) + { 5, 0x000F }, // 2/ 2 ( 5/01111) + { 6, 0x0018 }, // 2/ 3 ( 6/011000) + { 7, 0x0029 }, // 2/ 4 ( 7/0101001) + { 7, 0x0022 }, // 2/ 5 ( 7/0100010) + { 8, 0x003B }, // 2/ 6 ( 8/00111011) + { 8, 0x0030 }, // 2/ 7 ( 8/00110000) + { 8, 0x0028 }, // 2/ 8 ( 8/00101000) + { 9, 0x0040 }, // 2/ 9 ( 9/001000000) + { 9, 0x0032 }, // 2/10 ( 9/000110010) + { 10, 0x004E }, // 2/11 (10/0001001110) + { 10, 0x003E }, // 2/12 (10/0000111110) + { 11, 0x0050 }, // 2/13 (11/00001010000) + { 11, 0x0038 }, // 2/14 (11/00000111000) + { 11, 0x0021 }, // 2/15 (11/00000100001) + { 6, 0x001D }, // 3/ 0 ( 6/011101) + { 6, 0x001C }, // 3/ 1 ( 6/011100) + { 6, 0x0019 }, // 3/ 2 ( 6/011001) + { 7, 0x002B }, // 3/ 3 ( 7/0101011) + { 7, 0x0027 }, // 3/ 4 ( 7/0100111) + { 8, 0x003F }, // 3/ 5 ( 8/00111111) + { 8, 0x0037 }, // 3/ 6 ( 8/00110111) + { 9, 0x005D }, // 3/ 7 ( 9/001011101) + { 9, 0x004C }, // 3/ 8 ( 9/001001100) + { 9, 0x003B }, // 3/ 9 ( 9/000111011) + { 10, 0x005D }, // 3/10 (10/0001011101) + { 10, 0x0048 }, // 3/11 (10/0001001000) + { 10, 0x0036 }, // 3/12 (10/0000110110) + { 11, 0x004B }, // 3/13 (11/00001001011) + { 11, 0x0032 }, // 3/14 (11/00000110010) + { 11, 0x001D }, // 3/15 (11/00000011101) + { 7, 0x0034 }, // 4/ 0 ( 7/0110100) + { 6, 0x0016 }, // 4/ 1 ( 6/010110) + { 7, 0x002A }, // 4/ 2 ( 7/0101010) + { 7, 0x0028 }, // 4/ 3 ( 7/0101000) + { 8, 0x0043 }, // 4/ 4 ( 8/01000011) + { 8, 0x0039 }, // 4/ 5 ( 8/00111001) + { 9, 0x005F }, // 4/ 6 ( 9/001011111) + { 9, 0x004F }, // 4/ 7 ( 9/001001111) + { 9, 0x0048 }, // 4/ 8 ( 9/001001000) + { 9, 0x0039 }, // 4/ 9 ( 9/000111001) + { 10, 0x0059 }, // 4/10 (10/0001011001) + { 10, 0x0045 }, // 4/11 (10/0001000101) + { 10, 0x0031 }, // 4/12 (10/0000110001) + { 11, 0x0042 }, // 4/13 (11/00001000010) + { 11, 0x002E }, // 4/14 (11/00000101110) + { 11, 0x001B }, // 4/15 (11/00000011011) + { 8, 0x004D }, // 5/ 0 ( 8/01001101) + { 7, 0x0025 }, // 5/ 1 ( 7/0100101) + { 7, 0x0023 }, // 5/ 2 ( 7/0100011) + { 8, 0x0042 }, // 5/ 3 ( 8/01000010) + { 8, 0x003A }, // 5/ 4 ( 8/00111010) + { 8, 0x0034 }, // 5/ 5 ( 8/00110100) + { 9, 0x005B }, // 5/ 6 ( 9/001011011) + { 9, 0x004A }, // 5/ 7 ( 9/001001010) + { 9, 0x003E }, // 5/ 8 ( 9/000111110) + { 9, 0x0030 }, // 5/ 9 ( 9/000110000) + { 10, 0x004F }, // 5/10 (10/0001001111) + { 10, 0x003F }, // 5/11 (10/0000111111) + { 11, 0x005A }, // 5/12 (11/00001011010) + { 11, 0x003E }, // 5/13 (11/00000111110) + { 11, 0x0028 }, // 5/14 (11/00000101000) + { 12, 0x0026 }, // 5/15 (12/000000100110) + { 9, 0x007D }, // 6/ 0 ( 9/001111101) + { 7, 0x0020 }, // 6/ 1 ( 7/0100000) + { 8, 0x003C }, // 6/ 2 ( 8/00111100) + { 8, 0x0038 }, // 6/ 3 ( 8/00111000) + { 8, 0x0032 }, // 6/ 4 ( 8/00110010) + { 9, 0x005C }, // 6/ 5 ( 9/001011100) + { 9, 0x004E }, // 6/ 6 ( 9/001001110) + { 9, 0x0041 }, // 6/ 7 ( 9/001000001) + { 9, 0x0037 }, // 6/ 8 ( 9/000110111) + { 10, 0x0057 }, // 6/ 9 (10/0001010111) + { 10, 0x0047 }, // 6/10 (10/0001000111) + { 10, 0x0033 }, // 6/11 (10/0000110011) + { 11, 0x0049 }, // 6/12 (11/00001001001) + { 11, 0x0033 }, // 6/13 (11/00000110011) + { 12, 0x0046 }, // 6/14 (12/000001000110) + { 12, 0x001E }, // 6/15 (12/000000011110) + { 9, 0x006D }, // 7/ 0 ( 9/001101101) + { 8, 0x0035 }, // 7/ 1 ( 8/00110101) + { 8, 0x0031 }, // 7/ 2 ( 8/00110001) + { 9, 0x005E }, // 7/ 3 ( 9/001011110) + { 9, 0x0058 }, // 7/ 4 ( 9/001011000) + { 9, 0x004B }, // 7/ 5 ( 9/001001011) + { 9, 0x0042 }, // 7/ 6 ( 9/001000010) + { 10, 0x007A }, // 7/ 7 (10/0001111010) + { 10, 0x005B }, // 7/ 8 (10/0001011011) + { 10, 0x0049 }, // 7/ 9 (10/0001001001) + { 10, 0x0038 }, // 7/10 (10/0000111000) + { 10, 0x002A }, // 7/11 (10/0000101010) + { 11, 0x0040 }, // 7/12 (11/00001000000) + { 11, 0x002C }, // 7/13 (11/00000101100) + { 11, 0x0015 }, // 7/14 (11/00000010101) + { 12, 0x0019 }, // 7/15 (12/000000011001) + { 9, 0x005A }, // 8/ 0 ( 9/001011010) + { 8, 0x002B }, // 8/ 1 ( 8/00101011) + { 8, 0x0029 }, // 8/ 2 ( 8/00101001) + { 9, 0x004D }, // 8/ 3 ( 9/001001101) + { 9, 0x0049 }, // 8/ 4 ( 9/001001001) + { 9, 0x003F }, // 8/ 5 ( 9/000111111) + { 9, 0x0038 }, // 8/ 6 ( 9/000111000) + { 10, 0x005C }, // 8/ 7 (10/0001011100) + { 10, 0x004D }, // 8/ 8 (10/0001001101) + { 10, 0x0042 }, // 8/ 9 (10/0001000010) + { 10, 0x002F }, // 8/10 (10/0000101111) + { 11, 0x0043 }, // 8/11 (11/00001000011) + { 11, 0x0030 }, // 8/12 (11/00000110000) + { 12, 0x0035 }, // 8/13 (12/000000110101) + { 12, 0x0024 }, // 8/14 (12/000000100100) + { 12, 0x0014 }, // 8/15 (12/000000010100) + { 9, 0x0047 }, // 9/ 0 ( 9/001000111) + { 8, 0x0022 }, // 9/ 1 ( 8/00100010) + { 9, 0x0043 }, // 9/ 2 ( 9/001000011) + { 9, 0x003C }, // 9/ 3 ( 9/000111100) + { 9, 0x003A }, // 9/ 4 ( 9/000111010) + { 9, 0x0031 }, // 9/ 5 ( 9/000110001) + { 10, 0x0058 }, // 9/ 6 (10/0001011000) + { 10, 0x004C }, // 9/ 7 (10/0001001100) + { 10, 0x0043 }, // 9/ 8 (10/0001000011) + { 11, 0x006A }, // 9/ 9 (11/00001101010) + { 11, 0x0047 }, // 9/10 (11/00001000111) + { 11, 0x0036 }, // 9/11 (11/00000110110) + { 11, 0x0026 }, // 9/12 (11/00000100110) + { 12, 0x0027 }, // 9/13 (12/000000100111) + { 12, 0x0017 }, // 9/14 (12/000000010111) + { 12, 0x000F }, // 9/15 (12/000000001111) + { 10, 0x006D }, // 10/ 0 (10/0001101101) + { 9, 0x0035 }, // 10/ 1 ( 9/000110101) + { 9, 0x0033 }, // 10/ 2 ( 9/000110011) + { 9, 0x002F }, // 10/ 3 ( 9/000101111) + { 10, 0x005A }, // 10/ 4 (10/0001011010) + { 10, 0x0052 }, // 10/ 5 (10/0001010010) + { 10, 0x003A }, // 10/ 6 (10/0000111010) + { 10, 0x0039 }, // 10/ 7 (10/0000111001) + { 10, 0x0030 }, // 10/ 8 (10/0000110000) + { 11, 0x0048 }, // 10/ 9 (11/00001001000) + { 11, 0x0039 }, // 10/10 (11/00000111001) + { 11, 0x0029 }, // 10/11 (11/00000101001) + { 11, 0x0017 }, // 10/12 (11/00000010111) + { 12, 0x001B }, // 10/13 (12/000000011011) + { 13, 0x003E }, // 10/14 (13/0000000111110) + { 12, 0x0009 }, // 10/15 (12/000000001001) + { 10, 0x0056 }, // 11/ 0 (10/0001010110) + { 9, 0x002A }, // 11/ 1 ( 9/000101010) + { 9, 0x0028 }, // 11/ 2 ( 9/000101000) + { 9, 0x0025 }, // 11/ 3 ( 9/000100101) + { 10, 0x0046 }, // 11/ 4 (10/0001000110) + { 10, 0x0040 }, // 11/ 5 (10/0001000000) + { 10, 0x0034 }, // 11/ 6 (10/0000110100) + { 10, 0x002B }, // 11/ 7 (10/0000101011) + { 11, 0x0046 }, // 11/ 8 (11/00001000110) + { 11, 0x0037 }, // 11/ 9 (11/00000110111) + { 11, 0x002A }, // 11/10 (11/00000101010) + { 11, 0x0019 }, // 11/11 (11/00000011001) + { 12, 0x001D }, // 11/12 (12/000000011101) + { 12, 0x0012 }, // 11/13 (12/000000010010) + { 12, 0x000B }, // 11/14 (12/000000001011) + { 13, 0x000B }, // 11/15 (13/0000000001011) + { 11, 0x0076 }, // 12/ 0 (11/00001110110) + { 10, 0x0044 }, // 12/ 1 (10/0001000100) + { 9, 0x001E }, // 12/ 2 ( 9/000011110) + { 10, 0x0037 }, // 12/ 3 (10/0000110111) + { 10, 0x0032 }, // 12/ 4 (10/0000110010) + { 10, 0x002E }, // 12/ 5 (10/0000101110) + { 11, 0x004A }, // 12/ 6 (11/00001001010) + { 11, 0x0041 }, // 12/ 7 (11/00001000001) + { 11, 0x0031 }, // 12/ 8 (11/00000110001) + { 11, 0x0027 }, // 12/ 9 (11/00000100111) + { 11, 0x0018 }, // 12/10 (11/00000011000) + { 11, 0x0010 }, // 12/11 (11/00000010000) + { 12, 0x0016 }, // 12/12 (12/000000010110) + { 12, 0x000D }, // 12/13 (12/000000001101) + { 13, 0x000E }, // 12/14 (13/0000000001110) + { 13, 0x0007 }, // 12/15 (13/0000000000111) + { 11, 0x005B }, // 13/ 0 (11/00001011011) + { 10, 0x002C }, // 13/ 1 (10/0000101100) + { 10, 0x0027 }, // 13/ 2 (10/0000100111) + { 10, 0x0026 }, // 13/ 3 (10/0000100110) + { 10, 0x0022 }, // 13/ 4 (10/0000100010) + { 11, 0x003F }, // 13/ 5 (11/00000111111) + { 11, 0x0034 }, // 13/ 6 (11/00000110100) + { 11, 0x002D }, // 13/ 7 (11/00000101101) + { 11, 0x001F }, // 13/ 8 (11/00000011111) + { 12, 0x0034 }, // 13/ 9 (12/000000110100) + { 12, 0x001C }, // 13/10 (12/000000011100) + { 12, 0x0013 }, // 13/11 (12/000000010011) + { 12, 0x000E }, // 13/12 (12/000000001110) + { 12, 0x0008 }, // 13/13 (12/000000001000) + { 13, 0x0009 }, // 13/14 (13/0000000001001) + { 13, 0x0003 }, // 13/15 (13/0000000000011) + { 12, 0x007B }, // 14/ 0 (12/000001111011) + { 11, 0x003C }, // 14/ 1 (11/00000111100) + { 11, 0x003A }, // 14/ 2 (11/00000111010) + { 11, 0x0035 }, // 14/ 3 (11/00000110101) + { 11, 0x002F }, // 14/ 4 (11/00000101111) + { 11, 0x002B }, // 14/ 5 (11/00000101011) + { 11, 0x0020 }, // 14/ 6 (11/00000100000) + { 11, 0x0016 }, // 14/ 7 (11/00000010110) + { 12, 0x0025 }, // 14/ 8 (12/000000100101) + { 12, 0x0018 }, // 14/ 9 (12/000000011000) + { 12, 0x0011 }, // 14/10 (12/000000010001) + { 12, 0x000C }, // 14/11 (12/000000001100) + { 13, 0x000F }, // 14/12 (13/0000000001111) + { 13, 0x000A }, // 14/13 (13/0000000001010) + { 12, 0x0002 }, // 14/14 (12/000000000010) + { 13, 0x0001 }, // 14/15 (13/0000000000001) + { 12, 0x0047 }, // 15/ 0 (12/000001000111) + { 11, 0x0025 }, // 15/ 1 (11/00000100101) + { 11, 0x0022 }, // 15/ 2 (11/00000100010) + { 11, 0x001E }, // 15/ 3 (11/00000011110) + { 11, 0x001C }, // 15/ 4 (11/00000011100) + { 11, 0x0014 }, // 15/ 5 (11/00000010100) + { 11, 0x0011 }, // 15/ 6 (11/00000010001) + { 12, 0x001A }, // 15/ 7 (12/000000011010) + { 12, 0x0015 }, // 15/ 8 (12/000000010101) + { 12, 0x0010 }, // 15/ 9 (12/000000010000) + { 12, 0x000A }, // 15/10 (12/000000001010) + { 12, 0x0006 }, // 15/11 (12/000000000110) + { 13, 0x0008 }, // 15/12 (13/0000000001000) + { 13, 0x0006 }, // 15/13 (13/0000000000110) + { 13, 0x0002 }, // 15/14 (13/0000000000010) + { 13, 0x0000 } // 15/15 (13/0000000000000) +}; +static huffman_code* htab15_enc[ 16 ] = { + htab15_enc_raw + 0, // htab15 v0=0 pointer + htab15_enc_raw + 16, // htab15 v0=1 pointer + htab15_enc_raw + 32, // htab15 v0=2 pointer + htab15_enc_raw + 48, // htab15 v0=3 pointer + htab15_enc_raw + 64, // htab15 v0=4 pointer + htab15_enc_raw + 80, // htab15 v0=5 pointer + htab15_enc_raw + 96, // htab15 v0=6 pointer + htab15_enc_raw + 112, // htab15 v0=7 pointer + htab15_enc_raw + 128, // htab15 v0=8 pointer + htab15_enc_raw + 144, // htab15 v0=9 pointer + htab15_enc_raw + 160, // htab15 v0=10 pointer + htab15_enc_raw + 176, // htab15 v0=11 pointer + htab15_enc_raw + 192, // htab15 v0=12 pointer + htab15_enc_raw + 208, // htab15 v0=13 pointer + htab15_enc_raw + 224, // htab15 v0=14 pointer + htab15_enc_raw + 240 // htab15 v0=15 pointer +}; + +/* ----------------------------------------------- + big values table 16 (max 15) + ----------------------------------------------- */ +static huffman_code htab16_enc_raw[ 256 ] = { + { 1, 0x0001 }, // 0/ 0 ( 1/1) + { 4, 0x0005 }, // 0/ 1 ( 4/0101) + { 6, 0x000E }, // 0/ 2 ( 6/001110) + { 8, 0x002C }, // 0/ 3 ( 8/00101100) + { 9, 0x004A }, // 0/ 4 ( 9/001001010) + { 9, 0x003F }, // 0/ 5 ( 9/000111111) + { 10, 0x006E }, // 0/ 6 (10/0001101110) + { 10, 0x005D }, // 0/ 7 (10/0001011101) + { 11, 0x00AC }, // 0/ 8 (11/00010101100) + { 11, 0x0095 }, // 0/ 9 (11/00010010101) + { 11, 0x008A }, // 0/10 (11/00010001010) + { 12, 0x00F2 }, // 0/11 (12/000011110010) + { 12, 0x00E1 }, // 0/12 (12/000011100001) + { 12, 0x00C3 }, // 0/13 (12/000011000011) + { 13, 0x0178 }, // 0/14 (13/0000101111000) + { 9, 0x0011 }, // 0/15 ( 9/000010001) + { 3, 0x0003 }, // 1/ 0 ( 3/011) + { 4, 0x0004 }, // 1/ 1 ( 4/0100) + { 6, 0x000C }, // 1/ 2 ( 6/001100) + { 7, 0x0014 }, // 1/ 3 ( 7/0010100) + { 8, 0x0023 }, // 1/ 4 ( 8/00100011) + { 9, 0x003E }, // 1/ 5 ( 9/000111110) + { 9, 0x0035 }, // 1/ 6 ( 9/000110101) + { 9, 0x002F }, // 1/ 7 ( 9/000101111) + { 10, 0x0053 }, // 1/ 8 (10/0001010011) + { 10, 0x004B }, // 1/ 9 (10/0001001011) + { 10, 0x0044 }, // 1/10 (10/0001000100) + { 11, 0x0077 }, // 1/11 (11/00001110111) + { 12, 0x00C9 }, // 1/12 (12/000011001001) + { 11, 0x006B }, // 1/13 (11/00001101011) + { 12, 0x00CF }, // 1/14 (12/000011001111) + { 8, 0x0009 }, // 1/15 ( 8/00001001) + { 6, 0x000F }, // 2/ 0 ( 6/001111) + { 6, 0x000D }, // 2/ 1 ( 6/001101) + { 7, 0x0017 }, // 2/ 2 ( 7/0010111) + { 8, 0x0026 }, // 2/ 3 ( 8/00100110) + { 9, 0x0043 }, // 2/ 4 ( 9/001000011) + { 9, 0x003A }, // 2/ 5 ( 9/000111010) + { 10, 0x0067 }, // 2/ 6 (10/0001100111) + { 10, 0x005A }, // 2/ 7 (10/0001011010) + { 11, 0x00A1 }, // 2/ 8 (11/00010100001) + { 10, 0x0048 }, // 2/ 9 (10/0001001000) + { 11, 0x007F }, // 2/10 (11/00001111111) + { 11, 0x0075 }, // 2/11 (11/00001110101) + { 11, 0x006E }, // 2/12 (11/00001101110) + { 12, 0x00D1 }, // 2/13 (12/000011010001) + { 12, 0x00CE }, // 2/14 (12/000011001110) + { 9, 0x0010 }, // 2/15 ( 9/000010000) + { 8, 0x002D }, // 3/ 0 ( 8/00101101) + { 7, 0x0015 }, // 3/ 1 ( 7/0010101) + { 8, 0x0027 }, // 3/ 2 ( 8/00100111) + { 9, 0x0045 }, // 3/ 3 ( 9/001000101) + { 9, 0x0040 }, // 3/ 4 ( 9/001000000) + { 10, 0x0072 }, // 3/ 5 (10/0001110010) + { 10, 0x0063 }, // 3/ 6 (10/0001100011) + { 10, 0x0057 }, // 3/ 7 (10/0001010111) + { 11, 0x009E }, // 3/ 8 (11/00010011110) + { 11, 0x008C }, // 3/ 9 (11/00010001100) + { 12, 0x00FC }, // 3/10 (12/000011111100) + { 12, 0x00D4 }, // 3/11 (12/000011010100) + { 12, 0x00C7 }, // 3/12 (12/000011000111) + { 13, 0x0183 }, // 3/13 (13/0000110000011) + { 13, 0x016D }, // 3/14 (13/0000101101101) + { 10, 0x001A }, // 3/15 (10/0000011010) + { 9, 0x004B }, // 4/ 0 ( 9/001001011) + { 8, 0x0024 }, // 4/ 1 ( 8/00100100) + { 9, 0x0044 }, // 4/ 2 ( 9/001000100) + { 9, 0x0041 }, // 4/ 3 ( 9/001000001) + { 10, 0x0073 }, // 4/ 4 (10/0001110011) + { 10, 0x0065 }, // 4/ 5 (10/0001100101) + { 11, 0x00B3 }, // 4/ 6 (11/00010110011) + { 11, 0x00A4 }, // 4/ 7 (11/00010100100) + { 11, 0x009B }, // 4/ 8 (11/00010011011) + { 12, 0x0108 }, // 4/ 9 (12/000100001000) + { 12, 0x00F6 }, // 4/10 (12/000011110110) + { 12, 0x00E2 }, // 4/11 (12/000011100010) + { 13, 0x018B }, // 4/12 (13/0000110001011) + { 13, 0x017E }, // 4/13 (13/0000101111110) + { 13, 0x016A }, // 4/14 (13/0000101101010) + { 9, 0x0009 }, // 4/15 ( 9/000001001) + { 9, 0x0042 }, // 5/ 0 ( 9/001000010) + { 8, 0x001E }, // 5/ 1 ( 8/00011110) + { 9, 0x003B }, // 5/ 2 ( 9/000111011) + { 9, 0x0038 }, // 5/ 3 ( 9/000111000) + { 10, 0x0066 }, // 5/ 4 (10/0001100110) + { 11, 0x00B9 }, // 5/ 5 (11/00010111001) + { 11, 0x00AD }, // 5/ 6 (11/00010101101) + { 12, 0x0109 }, // 5/ 7 (12/000100001001) + { 11, 0x008E }, // 5/ 8 (11/00010001110) + { 12, 0x00FD }, // 5/ 9 (12/000011111101) + { 12, 0x00E8 }, // 5/10 (12/000011101000) + { 13, 0x0190 }, // 5/11 (13/0000110010000) + { 13, 0x0184 }, // 5/12 (13/0000110000100) + { 13, 0x017A }, // 5/13 (13/0000101111010) + { 14, 0x01BD }, // 5/14 (14/00000110111101) + { 10, 0x0010 }, // 5/15 (10/0000010000) + { 10, 0x006F }, // 6/ 0 (10/0001101111) + { 9, 0x0036 }, // 6/ 1 ( 9/000110110) + { 9, 0x0034 }, // 6/ 2 ( 9/000110100) + { 10, 0x0064 }, // 6/ 3 (10/0001100100) + { 11, 0x00B8 }, // 6/ 4 (11/00010111000) + { 11, 0x00B2 }, // 6/ 5 (11/00010110010) + { 11, 0x00A0 }, // 6/ 6 (11/00010100000) + { 11, 0x0085 }, // 6/ 7 (11/00010000101) + { 12, 0x0101 }, // 6/ 8 (12/000100000001) + { 12, 0x00F4 }, // 6/ 9 (12/000011110100) + { 12, 0x00E4 }, // 6/10 (12/000011100100) + { 12, 0x00D9 }, // 6/11 (12/000011011001) + { 13, 0x0181 }, // 6/12 (13/0000110000001) + { 13, 0x016E }, // 6/13 (13/0000101101110) + { 14, 0x02CB }, // 6/14 (14/00001011001011) + { 10, 0x000A }, // 6/15 (10/0000001010) + { 10, 0x0062 }, // 7/ 0 (10/0001100010) + { 9, 0x0030 }, // 7/ 1 ( 9/000110000) + { 10, 0x005B }, // 7/ 2 (10/0001011011) + { 10, 0x0058 }, // 7/ 3 (10/0001011000) + { 11, 0x00A5 }, // 7/ 4 (11/00010100101) + { 11, 0x009D }, // 7/ 5 (11/00010011101) + { 11, 0x0094 }, // 7/ 6 (11/00010010100) + { 12, 0x0105 }, // 7/ 7 (12/000100000101) + { 12, 0x00F8 }, // 7/ 8 (12/000011111000) + { 13, 0x0197 }, // 7/ 9 (13/0000110010111) + { 13, 0x018D }, // 7/10 (13/0000110001101) + { 13, 0x0174 }, // 7/11 (13/0000101110100) + { 13, 0x017C }, // 7/12 (13/0000101111100) + { 15, 0x0379 }, // 7/13 (15/000001101111001) + { 15, 0x0374 }, // 7/14 (15/000001101110100) + { 10, 0x0008 }, // 7/15 (10/0000001000) + { 10, 0x0055 }, // 8/ 0 (10/0001010101) + { 10, 0x0054 }, // 8/ 1 (10/0001010100) + { 10, 0x0051 }, // 8/ 2 (10/0001010001) + { 11, 0x009F }, // 8/ 3 (11/00010011111) + { 11, 0x009C }, // 8/ 4 (11/00010011100) + { 11, 0x008F }, // 8/ 5 (11/00010001111) + { 12, 0x0104 }, // 8/ 6 (12/000100000100) + { 12, 0x00F9 }, // 8/ 7 (12/000011111001) + { 13, 0x01AB }, // 8/ 8 (13/0000110101011) + { 13, 0x0191 }, // 8/ 9 (13/0000110010001) + { 13, 0x0188 }, // 8/10 (13/0000110001000) + { 13, 0x017F }, // 8/11 (13/0000101111111) + { 14, 0x02D7 }, // 8/12 (14/00001011010111) + { 14, 0x02C9 }, // 8/13 (14/00001011001001) + { 14, 0x02C4 }, // 8/14 (14/00001011000100) + { 10, 0x0007 }, // 8/15 (10/0000000111) + { 11, 0x009A }, // 9/ 0 (11/00010011010) + { 10, 0x004C }, // 9/ 1 (10/0001001100) + { 10, 0x0049 }, // 9/ 2 (10/0001001001) + { 11, 0x008D }, // 9/ 3 (11/00010001101) + { 11, 0x0083 }, // 9/ 4 (11/00010000011) + { 12, 0x0100 }, // 9/ 5 (12/000100000000) + { 12, 0x00F5 }, // 9/ 6 (12/000011110101) + { 13, 0x01AA }, // 9/ 7 (13/0000110101010) + { 13, 0x0196 }, // 9/ 8 (13/0000110010110) + { 13, 0x018A }, // 9/ 9 (13/0000110001010) + { 13, 0x0180 }, // 9/10 (13/0000110000000) + { 14, 0x02DF }, // 9/11 (14/00001011011111) + { 13, 0x0167 }, // 9/12 (13/0000101100111) + { 14, 0x02C6 }, // 9/13 (14/00001011000110) + { 13, 0x0160 }, // 9/14 (13/0000101100000) + { 11, 0x000B }, // 9/15 (11/00000001011) + { 11, 0x008B }, // 10/ 0 (11/00010001011) + { 11, 0x0081 }, // 10/ 1 (11/00010000001) + { 10, 0x0043 }, // 10/ 2 (10/0001000011) + { 11, 0x007D }, // 10/ 3 (11/00001111101) + { 12, 0x00F7 }, // 10/ 4 (12/000011110111) + { 12, 0x00E9 }, // 10/ 5 (12/000011101001) + { 12, 0x00E5 }, // 10/ 6 (12/000011100101) + { 12, 0x00DB }, // 10/ 7 (12/000011011011) + { 13, 0x0189 }, // 10/ 8 (13/0000110001001) + { 14, 0x02E7 }, // 10/ 9 (14/00001011100111) + { 14, 0x02E1 }, // 10/10 (14/00001011100001) + { 14, 0x02D0 }, // 10/11 (14/00001011010000) + { 15, 0x0375 }, // 10/12 (15/000001101110101) + { 15, 0x0372 }, // 10/13 (15/000001101110010) + { 14, 0x01B7 }, // 10/14 (14/00000110110111) + { 10, 0x0004 }, // 10/15 (10/0000000100) + { 12, 0x00F3 }, // 11/ 0 (12/000011110011) + { 11, 0x0078 }, // 11/ 1 (11/00001111000) + { 11, 0x0076 }, // 11/ 2 (11/00001110110) + { 11, 0x0073 }, // 11/ 3 (11/00001110011) + { 12, 0x00E3 }, // 11/ 4 (12/000011100011) + { 12, 0x00DF }, // 11/ 5 (12/000011011111) + { 13, 0x018C }, // 11/ 6 (13/0000110001100) + { 14, 0x02EA }, // 11/ 7 (14/00001011101010) + { 14, 0x02E6 }, // 11/ 8 (14/00001011100110) + { 14, 0x02E0 }, // 11/ 9 (14/00001011100000) + { 14, 0x02D1 }, // 11/10 (14/00001011010001) + { 14, 0x02C8 }, // 11/11 (14/00001011001000) + { 14, 0x02C2 }, // 11/12 (14/00001011000010) + { 13, 0x00DF }, // 11/13 (13/0000011011111) + { 14, 0x01B4 }, // 11/14 (14/00000110110100) + { 11, 0x0006 }, // 11/15 (11/00000000110) + { 12, 0x00CA }, // 12/ 0 (12/000011001010) + { 12, 0x00E0 }, // 12/ 1 (12/000011100000) + { 12, 0x00DE }, // 12/ 2 (12/000011011110) + { 12, 0x00DA }, // 12/ 3 (12/000011011010) + { 12, 0x00D8 }, // 12/ 4 (12/000011011000) + { 13, 0x0185 }, // 12/ 5 (13/0000110000101) + { 13, 0x0182 }, // 12/ 6 (13/0000110000010) + { 13, 0x017D }, // 12/ 7 (13/0000101111101) + { 13, 0x016C }, // 12/ 8 (13/0000101101100) + { 15, 0x0378 }, // 12/ 9 (15/000001101111000) + { 14, 0x01BB }, // 12/10 (14/00000110111011) + { 14, 0x02C3 }, // 12/11 (14/00001011000011) + { 14, 0x01B8 }, // 12/12 (14/00000110111000) + { 14, 0x01B5 }, // 12/13 (14/00000110110101) + { 16, 0x06C0 }, // 12/14 (16/0000011011000000) + { 11, 0x0004 }, // 12/15 (11/00000000100) + { 14, 0x02EB }, // 13/ 0 (14/00001011101011) + { 12, 0x00D3 }, // 13/ 1 (12/000011010011) + { 12, 0x00D2 }, // 13/ 2 (12/000011010010) + { 12, 0x00D0 }, // 13/ 3 (12/000011010000) + { 13, 0x0172 }, // 13/ 4 (13/0000101110010) + { 13, 0x017B }, // 13/ 5 (13/0000101111011) + { 14, 0x02DE }, // 13/ 6 (14/00001011011110) + { 14, 0x02D3 }, // 13/ 7 (14/00001011010011) + { 14, 0x02CA }, // 13/ 8 (14/00001011001010) + { 16, 0x06C7 }, // 13/ 9 (16/0000011011000111) + { 15, 0x0373 }, // 13/10 (15/000001101110011) + { 15, 0x036D }, // 13/11 (15/000001101101101) + { 15, 0x036C }, // 13/12 (15/000001101101100) + { 17, 0x0D83 }, // 13/13 (17/00000110110000011) + { 15, 0x0361 }, // 13/14 (15/000001101100001) + { 11, 0x0002 }, // 13/15 (11/00000000010) + { 13, 0x0179 }, // 14/ 0 (13/0000101111001) + { 13, 0x0171 }, // 14/ 1 (13/0000101110001) + { 11, 0x0066 }, // 14/ 2 (11/00001100110) + { 12, 0x00BB }, // 14/ 3 (12/000010111011) + { 14, 0x02D6 }, // 14/ 4 (14/00001011010110) + { 14, 0x02D2 }, // 14/ 5 (14/00001011010010) + { 13, 0x0166 }, // 14/ 6 (13/0000101100110) + { 14, 0x02C7 }, // 14/ 7 (14/00001011000111) + { 14, 0x02C5 }, // 14/ 8 (14/00001011000101) + { 15, 0x0362 }, // 14/ 9 (15/000001101100010) + { 16, 0x06C6 }, // 14/10 (16/0000011011000110) + { 15, 0x0367 }, // 14/11 (15/000001101100111) + { 17, 0x0D82 }, // 14/12 (17/00000110110000010) + { 15, 0x0366 }, // 14/13 (15/000001101100110) + { 14, 0x01B2 }, // 14/14 (14/00000110110010) + { 11, 0x0000 }, // 14/15 (11/00000000000) + { 9, 0x000C }, // 15/ 0 ( 9/000001100) + { 8, 0x000A }, // 15/ 1 ( 8/00001010) + { 8, 0x0007 }, // 15/ 2 ( 8/00000111) + { 9, 0x000B }, // 15/ 3 ( 9/000001011) + { 9, 0x000A }, // 15/ 4 ( 9/000001010) + { 10, 0x0011 }, // 15/ 5 (10/0000010001) + { 10, 0x000B }, // 15/ 6 (10/0000001011) + { 10, 0x0009 }, // 15/ 7 (10/0000001001) + { 11, 0x000D }, // 15/ 8 (11/00000001101) + { 11, 0x000C }, // 15/ 9 (11/00000001100) + { 11, 0x000A }, // 15/10 (11/00000001010) + { 11, 0x0007 }, // 15/11 (11/00000000111) + { 11, 0x0005 }, // 15/12 (11/00000000101) + { 11, 0x0003 }, // 15/13 (11/00000000011) + { 11, 0x0001 }, // 15/14 (11/00000000001) + { 8, 0x0003 } // 15/15 ( 8/00000011) +}; +static huffman_code* htab16_enc[ 16 ] = { + htab16_enc_raw + 0, // htab16 v0=0 pointer + htab16_enc_raw + 16, // htab16 v0=1 pointer + htab16_enc_raw + 32, // htab16 v0=2 pointer + htab16_enc_raw + 48, // htab16 v0=3 pointer + htab16_enc_raw + 64, // htab16 v0=4 pointer + htab16_enc_raw + 80, // htab16 v0=5 pointer + htab16_enc_raw + 96, // htab16 v0=6 pointer + htab16_enc_raw + 112, // htab16 v0=7 pointer + htab16_enc_raw + 128, // htab16 v0=8 pointer + htab16_enc_raw + 144, // htab16 v0=9 pointer + htab16_enc_raw + 160, // htab16 v0=10 pointer + htab16_enc_raw + 176, // htab16 v0=11 pointer + htab16_enc_raw + 192, // htab16 v0=12 pointer + htab16_enc_raw + 208, // htab16 v0=13 pointer + htab16_enc_raw + 224, // htab16 v0=14 pointer + htab16_enc_raw + 240 // htab16 v0=15 pointer +}; + +/* ----------------------------------------------- + big values table 24 (max 15) + ----------------------------------------------- */ +static huffman_code htab24_enc_raw[ 256 ] = { + { 4, 0x000F }, // 0/ 0 ( 4/1111) + { 4, 0x000D }, // 0/ 1 ( 4/1101) + { 6, 0x002E }, // 0/ 2 ( 6/101110) + { 7, 0x0050 }, // 0/ 3 ( 7/1010000) + { 8, 0x0092 }, // 0/ 4 ( 8/10010010) + { 9, 0x0106 }, // 0/ 5 ( 9/100000110) + { 9, 0x00F8 }, // 0/ 6 ( 9/011111000) + { 10, 0x01B2 }, // 0/ 7 (10/0110110010) + { 10, 0x01AA }, // 0/ 8 (10/0110101010) + { 11, 0x029D }, // 0/ 9 (11/01010011101) + { 11, 0x028D }, // 0/10 (11/01010001101) + { 11, 0x0289 }, // 0/11 (11/01010001001) + { 11, 0x026D }, // 0/12 (11/01001101101) + { 11, 0x0205 }, // 0/13 (11/01000000101) + { 12, 0x0408 }, // 0/14 (12/010000001000) + { 9, 0x0058 }, // 0/15 ( 9/001011000) + { 4, 0x000E }, // 1/ 0 ( 4/1110) + { 4, 0x000C }, // 1/ 1 ( 4/1100) + { 5, 0x0015 }, // 1/ 2 ( 5/10101) + { 6, 0x0026 }, // 1/ 3 ( 6/100110) + { 7, 0x0047 }, // 1/ 4 ( 7/1000111) + { 8, 0x0082 }, // 1/ 5 ( 8/10000010) + { 8, 0x007A }, // 1/ 6 ( 8/01111010) + { 9, 0x00D8 }, // 1/ 7 ( 9/011011000) + { 9, 0x00D1 }, // 1/ 8 ( 9/011010001) + { 9, 0x00C6 }, // 1/ 9 ( 9/011000110) + { 10, 0x0147 }, // 1/10 (10/0101000111) + { 10, 0x0159 }, // 1/11 (10/0101011001) + { 10, 0x013F }, // 1/12 (10/0100111111) + { 10, 0x0129 }, // 1/13 (10/0100101001) + { 10, 0x0117 }, // 1/14 (10/0100010111) + { 8, 0x002A }, // 1/15 ( 8/00101010) + { 6, 0x002F }, // 2/ 0 ( 6/101111) + { 5, 0x0016 }, // 2/ 1 ( 5/10110) + { 6, 0x0029 }, // 2/ 2 ( 6/101001) + { 7, 0x004A }, // 2/ 3 ( 7/1001010) + { 7, 0x0044 }, // 2/ 4 ( 7/1000100) + { 8, 0x0080 }, // 2/ 5 ( 8/10000000) + { 8, 0x0078 }, // 2/ 6 ( 8/01111000) + { 9, 0x00DD }, // 2/ 7 ( 9/011011101) + { 9, 0x00CF }, // 2/ 8 ( 9/011001111) + { 9, 0x00C2 }, // 2/ 9 ( 9/011000010) + { 9, 0x00B6 }, // 2/10 ( 9/010110110) + { 10, 0x0154 }, // 2/11 (10/0101010100) + { 10, 0x013B }, // 2/12 (10/0100111011) + { 10, 0x0127 }, // 2/13 (10/0100100111) + { 11, 0x021D }, // 2/14 (11/01000011101) + { 7, 0x0012 }, // 2/15 ( 7/0010010) + { 7, 0x0051 }, // 3/ 0 ( 7/1010001) + { 6, 0x0027 }, // 3/ 1 ( 6/100111) + { 7, 0x004B }, // 3/ 2 ( 7/1001011) + { 7, 0x0046 }, // 3/ 3 ( 7/1000110) + { 8, 0x0086 }, // 3/ 4 ( 8/10000110) + { 8, 0x007D }, // 3/ 5 ( 8/01111101) + { 8, 0x0074 }, // 3/ 6 ( 8/01110100) + { 9, 0x00DC }, // 3/ 7 ( 9/011011100) + { 9, 0x00CC }, // 3/ 8 ( 9/011001100) + { 9, 0x00BE }, // 3/ 9 ( 9/010111110) + { 9, 0x00B2 }, // 3/10 ( 9/010110010) + { 10, 0x0145 }, // 3/11 (10/0101000101) + { 10, 0x0137 }, // 3/12 (10/0100110111) + { 10, 0x0125 }, // 3/13 (10/0100100101) + { 10, 0x010F }, // 3/14 (10/0100001111) + { 7, 0x0010 }, // 3/15 ( 7/0010000) + { 8, 0x0093 }, // 4/ 0 ( 8/10010011) + { 7, 0x0048 }, // 4/ 1 ( 7/1001000) + { 7, 0x0045 }, // 4/ 2 ( 7/1000101) + { 8, 0x0087 }, // 4/ 3 ( 8/10000111) + { 8, 0x007F }, // 4/ 4 ( 8/01111111) + { 8, 0x0076 }, // 4/ 5 ( 8/01110110) + { 8, 0x0070 }, // 4/ 6 ( 8/01110000) + { 9, 0x00D2 }, // 4/ 7 ( 9/011010010) + { 9, 0x00C8 }, // 4/ 8 ( 9/011001000) + { 9, 0x00BC }, // 4/ 9 ( 9/010111100) + { 10, 0x0160 }, // 4/10 (10/0101100000) + { 10, 0x0143 }, // 4/11 (10/0101000011) + { 10, 0x0132 }, // 4/12 (10/0100110010) + { 10, 0x011D }, // 4/13 (10/0100011101) + { 11, 0x021C }, // 4/14 (11/01000011100) + { 7, 0x000E }, // 4/15 ( 7/0001110) + { 9, 0x0107 }, // 5/ 0 ( 9/100000111) + { 7, 0x0042 }, // 5/ 1 ( 7/1000010) + { 8, 0x0081 }, // 5/ 2 ( 8/10000001) + { 8, 0x007E }, // 5/ 3 ( 8/01111110) + { 8, 0x0077 }, // 5/ 4 ( 8/01110111) + { 8, 0x0072 }, // 5/ 5 ( 8/01110010) + { 9, 0x00D6 }, // 5/ 6 ( 9/011010110) + { 9, 0x00CA }, // 5/ 7 ( 9/011001010) + { 9, 0x00C0 }, // 5/ 8 ( 9/011000000) + { 9, 0x00B4 }, // 5/ 9 ( 9/010110100) + { 10, 0x0155 }, // 5/10 (10/0101010101) + { 10, 0x013D }, // 5/11 (10/0100111101) + { 10, 0x012D }, // 5/12 (10/0100101101) + { 10, 0x0119 }, // 5/13 (10/0100011001) + { 10, 0x0106 }, // 5/14 (10/0100000110) + { 7, 0x000C }, // 5/15 ( 7/0001100) + { 9, 0x00F9 }, // 6/ 0 ( 9/011111001) + { 8, 0x007B }, // 6/ 1 ( 8/01111011) + { 8, 0x0079 }, // 6/ 2 ( 8/01111001) + { 8, 0x0075 }, // 6/ 3 ( 8/01110101) + { 8, 0x0071 }, // 6/ 4 ( 8/01110001) + { 9, 0x00D7 }, // 6/ 5 ( 9/011010111) + { 9, 0x00CE }, // 6/ 6 ( 9/011001110) + { 9, 0x00C3 }, // 6/ 7 ( 9/011000011) + { 9, 0x00B9 }, // 6/ 8 ( 9/010111001) + { 10, 0x015B }, // 6/ 9 (10/0101011011) + { 10, 0x014A }, // 6/10 (10/0101001010) + { 10, 0x0134 }, // 6/11 (10/0100110100) + { 10, 0x0123 }, // 6/12 (10/0100100011) + { 10, 0x0110 }, // 6/13 (10/0100010000) + { 11, 0x0208 }, // 6/14 (11/01000001000) + { 7, 0x000A }, // 6/15 ( 7/0001010) + { 10, 0x01B3 }, // 7/ 0 (10/0110110011) + { 8, 0x0073 }, // 7/ 1 ( 8/01110011) + { 8, 0x006F }, // 7/ 2 ( 8/01101111) + { 8, 0x006D }, // 7/ 3 ( 8/01101101) + { 9, 0x00D3 }, // 7/ 4 ( 9/011010011) + { 9, 0x00CB }, // 7/ 5 ( 9/011001011) + { 9, 0x00C4 }, // 7/ 6 ( 9/011000100) + { 9, 0x00BB }, // 7/ 7 ( 9/010111011) + { 10, 0x0161 }, // 7/ 8 (10/0101100001) + { 10, 0x014C }, // 7/ 9 (10/0101001100) + { 10, 0x0139 }, // 7/10 (10/0100111001) + { 10, 0x012A }, // 7/11 (10/0100101010) + { 10, 0x011B }, // 7/12 (10/0100011011) + { 11, 0x0213 }, // 7/13 (11/01000010011) + { 11, 0x017D }, // 7/14 (11/00101111101) + { 8, 0x0011 }, // 7/15 ( 8/00010001) + { 10, 0x01AB }, // 8/ 0 (10/0110101011) + { 9, 0x00D4 }, // 8/ 1 ( 9/011010100) + { 9, 0x00D0 }, // 8/ 2 ( 9/011010000) + { 9, 0x00CD }, // 8/ 3 ( 9/011001101) + { 9, 0x00C9 }, // 8/ 4 ( 9/011001001) + { 9, 0x00C1 }, // 8/ 5 ( 9/011000001) + { 9, 0x00BA }, // 8/ 6 ( 9/010111010) + { 9, 0x00B1 }, // 8/ 7 ( 9/010110001) + { 9, 0x00A9 }, // 8/ 8 ( 9/010101001) + { 10, 0x0140 }, // 8/ 9 (10/0101000000) + { 10, 0x012F }, // 8/10 (10/0100101111) + { 10, 0x011E }, // 8/11 (10/0100011110) + { 10, 0x010C }, // 8/12 (10/0100001100) + { 11, 0x0202 }, // 8/13 (11/01000000010) + { 11, 0x0179 }, // 8/14 (11/00101111001) + { 8, 0x0010 }, // 8/15 ( 8/00010000) + { 10, 0x014F }, // 9/ 0 (10/0101001111) + { 9, 0x00C7 }, // 9/ 1 ( 9/011000111) + { 9, 0x00C5 }, // 9/ 2 ( 9/011000101) + { 9, 0x00BF }, // 9/ 3 ( 9/010111111) + { 9, 0x00BD }, // 9/ 4 ( 9/010111101) + { 9, 0x00B5 }, // 9/ 5 ( 9/010110101) + { 9, 0x00AE }, // 9/ 6 ( 9/010101110) + { 10, 0x014D }, // 9/ 7 (10/0101001101) + { 10, 0x0141 }, // 9/ 8 (10/0101000001) + { 10, 0x0131 }, // 9/ 9 (10/0100110001) + { 10, 0x0121 }, // 9/10 (10/0100100001) + { 10, 0x0113 }, // 9/11 (10/0100010011) + { 11, 0x0209 }, // 9/12 (11/01000001001) + { 11, 0x017B }, // 9/13 (11/00101111011) + { 11, 0x0173 }, // 9/14 (11/00101110011) + { 8, 0x000B }, // 9/15 ( 8/00001011) + { 11, 0x029C }, // 10/ 0 (11/01010011100) + { 9, 0x00B8 }, // 10/ 1 ( 9/010111000) + { 9, 0x00B7 }, // 10/ 2 ( 9/010110111) + { 9, 0x00B3 }, // 10/ 3 ( 9/010110011) + { 9, 0x00AF }, // 10/ 4 ( 9/010101111) + { 10, 0x0158 }, // 10/ 5 (10/0101011000) + { 10, 0x014B }, // 10/ 6 (10/0101001011) + { 10, 0x013A }, // 10/ 7 (10/0100111010) + { 10, 0x0130 }, // 10/ 8 (10/0100110000) + { 10, 0x0122 }, // 10/ 9 (10/0100100010) + { 10, 0x0115 }, // 10/10 (10/0100010101) + { 11, 0x0212 }, // 10/11 (11/01000010010) + { 11, 0x017F }, // 10/12 (11/00101111111) + { 11, 0x0175 }, // 10/13 (11/00101110101) + { 11, 0x016E }, // 10/14 (11/00101101110) + { 8, 0x000A }, // 10/15 ( 8/00001010) + { 11, 0x028C }, // 11/ 0 (11/01010001100) + { 10, 0x015A }, // 11/ 1 (10/0101011010) + { 9, 0x00AB }, // 11/ 2 ( 9/010101011) + { 9, 0x00A8 }, // 11/ 3 ( 9/010101000) + { 9, 0x00A4 }, // 11/ 4 ( 9/010100100) + { 10, 0x013E }, // 11/ 5 (10/0100111110) + { 10, 0x0135 }, // 11/ 6 (10/0100110101) + { 10, 0x012B }, // 11/ 7 (10/0100101011) + { 10, 0x011F }, // 11/ 8 (10/0100011111) + { 10, 0x0114 }, // 11/ 9 (10/0100010100) + { 10, 0x0107 }, // 11/10 (10/0100000111) + { 11, 0x0201 }, // 11/11 (11/01000000001) + { 11, 0x0177 }, // 11/12 (11/00101110111) + { 11, 0x0170 }, // 11/13 (11/00101110000) + { 11, 0x016A }, // 11/14 (11/00101101010) + { 8, 0x0006 }, // 11/15 ( 8/00000110) + { 11, 0x0288 }, // 12/ 0 (11/01010001000) + { 10, 0x0142 }, // 12/ 1 (10/0101000010) + { 10, 0x013C }, // 12/ 2 (10/0100111100) + { 10, 0x0138 }, // 12/ 3 (10/0100111000) + { 10, 0x0133 }, // 12/ 4 (10/0100110011) + { 10, 0x012E }, // 12/ 5 (10/0100101110) + { 10, 0x0124 }, // 12/ 6 (10/0100100100) + { 10, 0x011C }, // 12/ 7 (10/0100011100) + { 10, 0x010D }, // 12/ 8 (10/0100001101) + { 10, 0x0105 }, // 12/ 9 (10/0100000101) + { 11, 0x0200 }, // 12/10 (11/01000000000) + { 11, 0x0178 }, // 12/11 (11/00101111000) + { 11, 0x0172 }, // 12/12 (11/00101110010) + { 11, 0x016C }, // 12/13 (11/00101101100) + { 11, 0x0167 }, // 12/14 (11/00101100111) + { 8, 0x0004 }, // 12/15 ( 8/00000100) + { 11, 0x026C }, // 13/ 0 (11/01001101100) + { 10, 0x012C }, // 13/ 1 (10/0100101100) + { 10, 0x0128 }, // 13/ 2 (10/0100101000) + { 10, 0x0126 }, // 13/ 3 (10/0100100110) + { 10, 0x0120 }, // 13/ 4 (10/0100100000) + { 10, 0x011A }, // 13/ 5 (10/0100011010) + { 10, 0x0111 }, // 13/ 6 (10/0100010001) + { 10, 0x010A }, // 13/ 7 (10/0100001010) + { 11, 0x0203 }, // 13/ 8 (11/01000000011) + { 11, 0x017C }, // 13/ 9 (11/00101111100) + { 11, 0x0176 }, // 13/10 (11/00101110110) + { 11, 0x0171 }, // 13/11 (11/00101110001) + { 11, 0x016D }, // 13/12 (11/00101101101) + { 11, 0x0169 }, // 13/13 (11/00101101001) + { 11, 0x0165 }, // 13/14 (11/00101100101) + { 8, 0x0002 }, // 13/15 ( 8/00000010) + { 12, 0x0409 }, // 14/ 0 (12/010000001001) + { 10, 0x0118 }, // 14/ 1 (10/0100011000) + { 10, 0x0116 }, // 14/ 2 (10/0100010110) + { 10, 0x0112 }, // 14/ 3 (10/0100010010) + { 10, 0x010B }, // 14/ 4 (10/0100001011) + { 10, 0x0108 }, // 14/ 5 (10/0100001000) + { 10, 0x0103 }, // 14/ 6 (10/0100000011) + { 11, 0x017E }, // 14/ 7 (11/00101111110) + { 11, 0x017A }, // 14/ 8 (11/00101111010) + { 11, 0x0174 }, // 14/ 9 (11/00101110100) + { 11, 0x016F }, // 14/10 (11/00101101111) + { 11, 0x016B }, // 14/11 (11/00101101011) + { 11, 0x0168 }, // 14/12 (11/00101101000) + { 11, 0x0166 }, // 14/13 (11/00101100110) + { 11, 0x0164 }, // 14/14 (11/00101100100) + { 8, 0x0000 }, // 14/15 ( 8/00000000) + { 8, 0x002B }, // 15/ 0 ( 8/00101011) + { 7, 0x0014 }, // 15/ 1 ( 7/0010100) + { 7, 0x0013 }, // 15/ 2 ( 7/0010011) + { 7, 0x0011 }, // 15/ 3 ( 7/0010001) + { 7, 0x000F }, // 15/ 4 ( 7/0001111) + { 7, 0x000D }, // 15/ 5 ( 7/0001101) + { 7, 0x000B }, // 15/ 6 ( 7/0001011) + { 7, 0x0009 }, // 15/ 7 ( 7/0001001) + { 7, 0x0007 }, // 15/ 8 ( 7/0000111) + { 7, 0x0006 }, // 15/ 9 ( 7/0000110) + { 7, 0x0004 }, // 15/10 ( 7/0000100) + { 8, 0x0007 }, // 15/11 ( 8/00000111) + { 8, 0x0005 }, // 15/12 ( 8/00000101) + { 8, 0x0003 }, // 15/13 ( 8/00000011) + { 8, 0x0001 }, // 15/14 ( 8/00000001) + { 4, 0x0003 } // 15/15 ( 4/0011) +}; +static huffman_code* htab24_enc[ 16 ] = { + htab24_enc_raw + 0, // htab24 v0=0 pointer + htab24_enc_raw + 16, // htab24 v0=1 pointer + htab24_enc_raw + 32, // htab24 v0=2 pointer + htab24_enc_raw + 48, // htab24 v0=3 pointer + htab24_enc_raw + 64, // htab24 v0=4 pointer + htab24_enc_raw + 80, // htab24 v0=5 pointer + htab24_enc_raw + 96, // htab24 v0=6 pointer + htab24_enc_raw + 112, // htab24 v0=7 pointer + htab24_enc_raw + 128, // htab24 v0=8 pointer + htab24_enc_raw + 144, // htab24 v0=9 pointer + htab24_enc_raw + 160, // htab24 v0=10 pointer + htab24_enc_raw + 176, // htab24 v0=11 pointer + htab24_enc_raw + 192, // htab24 v0=12 pointer + htab24_enc_raw + 208, // htab24 v0=13 pointer + htab24_enc_raw + 224, // htab24 v0=14 pointer + htab24_enc_raw + 240 // htab24 v0=15 pointer +}; + + +/* ----------------------------------------------- + small values conversion table A + ----------------------------------------------- */ +static huffman_conv htabA_dec_raw[ 64 ] = { + { 6, 0xB, 3, -1 }, // 000000 -> 1011, 6 bit used + { 6, 0xF, 4, -1 }, // 000001 -> 1111, 6 bit used + { 6, 0xD, 3, -1 }, // 000010 -> 1101, 6 bit used + { 6, 0xE, 3, -1 }, // 000011 -> 1110, 6 bit used + { 6, 0x7, 3, -1 }, // 000100 -> 0111, 6 bit used + { 6, 0x5, 2, -1 }, // 000101 -> 0101, 6 bit used + { 5, 0x9, 2, -1 }, // 000110 -> 1001, 5 bit used + { 5, 0x9, 2, -1 }, // 000111 -> 1001, 5 bit used + { 5, 0x6, 2, -1 }, // 001000 -> 0110, 5 bit used + { 5, 0x6, 2, -1 }, // 001001 -> 0110, 5 bit used + { 5, 0x3, 2, -1 }, // 001010 -> 0011, 5 bit used + { 5, 0x3, 2, -1 }, // 001011 -> 0011, 5 bit used + { 5, 0xA, 2, -1 }, // 001100 -> 1010, 5 bit used + { 5, 0xA, 2, -1 }, // 001101 -> 1010, 5 bit used + { 5, 0xC, 2, -1 }, // 001110 -> 1100, 5 bit used + { 5, 0xC, 2, -1 }, // 001111 -> 1100, 5 bit used + { 4, 0x2, 1, -1 }, // 010000 -> 0010, 4 bit used + { 4, 0x2, 1, -1 }, // 010001 -> 0010, 4 bit used + { 4, 0x2, 1, -1 }, // 010010 -> 0010, 4 bit used + { 4, 0x2, 1, -1 }, // 010011 -> 0010, 4 bit used + { 4, 0x1, 1, -1 }, // 010100 -> 0001, 4 bit used + { 4, 0x1, 1, -1 }, // 010101 -> 0001, 4 bit used + { 4, 0x1, 1, -1 }, // 010110 -> 0001, 4 bit used + { 4, 0x1, 1, -1 }, // 010111 -> 0001, 4 bit used + { 4, 0x4, 1, -1 }, // 011000 -> 0100, 4 bit used + { 4, 0x4, 1, -1 }, // 011001 -> 0100, 4 bit used + { 4, 0x4, 1, -1 }, // 011010 -> 0100, 4 bit used + { 4, 0x4, 1, -1 }, // 011011 -> 0100, 4 bit used + { 4, 0x8, 1, -1 }, // 011100 -> 1000, 4 bit used + { 4, 0x8, 1, -1 }, // 011101 -> 1000, 4 bit used + { 4, 0x8, 1, -1 }, // 011110 -> 1000, 4 bit used + { 4, 0x8, 1, -1 }, // 011111 -> 1000, 4 bit used + { 1, 0x0, 0, -1 }, // 100000 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 100001 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 100010 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 100011 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 100100 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 100101 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 100110 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 100111 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 101000 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 101001 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 101010 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 101011 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 101100 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 101101 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 101110 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 101111 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 110000 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 110001 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 110010 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 110011 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 110100 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 110101 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 110110 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 110111 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 111000 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 111001 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 111010 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 111011 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 111100 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 111101 -> 0000, 1 bit used + { 1, 0x0, 0, -1 }, // 111110 -> 0000, 1 bit used + { 1, 0x0, 0, -1 } // 111111 -> 0000, 1 bit used +}; +static huffman_conv_set htabA_dec = { htabA_dec_raw, 6 }; + +/* ----------------------------------------------- + small values conversion table B + ----------------------------------------------- */ +static huffman_conv htabB_dec_raw[ 16 ] = { + { 4, 0xF, 4, -1 }, // 0000 -> 1111, 4 bit used + { 4, 0xE, 3, -1 }, // 0001 -> 1110, 4 bit used + { 4, 0xD, 3, -1 }, // 0010 -> 1101, 4 bit used + { 4, 0xC, 2, -1 }, // 0011 -> 1100, 4 bit used + { 4, 0xB, 3, -1 }, // 0100 -> 1011, 4 bit used + { 4, 0xA, 2, -1 }, // 0101 -> 1010, 4 bit used + { 4, 0x9, 2, -1 }, // 0110 -> 1001, 4 bit used + { 4, 0x8, 1, -1 }, // 0111 -> 1000, 4 bit used + { 4, 0x7, 3, -1 }, // 1000 -> 0111, 4 bit used + { 4, 0x6, 2, -1 }, // 1001 -> 0110, 4 bit used + { 4, 0x5, 2, -1 }, // 1010 -> 0101, 4 bit used + { 4, 0x4, 1, -1 }, // 1011 -> 0100, 4 bit used + { 4, 0x3, 2, -1 }, // 1100 -> 0011, 4 bit used + { 4, 0x2, 1, -1 }, // 1101 -> 0010, 4 bit used + { 4, 0x1, 1, -1 }, // 1110 -> 0001, 4 bit used + { 4, 0x0, 0, -1 } // 1111 -> 0000, 4 bit used +}; +static huffman_conv_set htabB_dec = { htabB_dec_raw, 4 }; + +/* ----------------------------------------------- + small values quadruple conversion table + ----------------------------------------------- */ +static const signed short sv_qconv[ 256 ][ 5 ] = { + { 0, 0, 0, 0, 0 }, // 00000000 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00000001 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00000010 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00000011 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00000100 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00000101 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00000110 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00000111 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00001000 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00001001 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00001010 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00001011 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00001100 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00001101 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00001110 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 0, 0 }, // 00001111 -> 0/0/0/0, 0 signbits + { 0, 0, 0, 1, 1 }, // 00010000 -> 0/0/0/1, 1 signbits + { 0, 0, 0, 1, 1 }, // 00010001 -> 0/0/0/1, 1 signbits + { 0, 0, 0, 1, 1 }, // 00010010 -> 0/0/0/1, 1 signbits + { 0, 0, 0, 1, 1 }, // 00010011 -> 0/0/0/1, 1 signbits + { 0, 0, 0, 1, 1 }, // 00010100 -> 0/0/0/1, 1 signbits + { 0, 0, 0, 1, 1 }, // 00010101 -> 0/0/0/1, 1 signbits + { 0, 0, 0, 1, 1 }, // 00010110 -> 0/0/0/1, 1 signbits + { 0, 0, 0, 1, 1 }, // 00010111 -> 0/0/0/1, 1 signbits + { 0, 0, 0, -1, 1 }, // 00011000 -> 0/0/0/-1, 1 signbits + { 0, 0, 0, -1, 1 }, // 00011001 -> 0/0/0/-1, 1 signbits + { 0, 0, 0, -1, 1 }, // 00011010 -> 0/0/0/-1, 1 signbits + { 0, 0, 0, -1, 1 }, // 00011011 -> 0/0/0/-1, 1 signbits + { 0, 0, 0, -1, 1 }, // 00011100 -> 0/0/0/-1, 1 signbits + { 0, 0, 0, -1, 1 }, // 00011101 -> 0/0/0/-1, 1 signbits + { 0, 0, 0, -1, 1 }, // 00011110 -> 0/0/0/-1, 1 signbits + { 0, 0, 0, -1, 1 }, // 00011111 -> 0/0/0/-1, 1 signbits + { 0, 0, 1, 0, 1 }, // 00100000 -> 0/0/1/0, 1 signbits + { 0, 0, 1, 0, 1 }, // 00100001 -> 0/0/1/0, 1 signbits + { 0, 0, 1, 0, 1 }, // 00100010 -> 0/0/1/0, 1 signbits + { 0, 0, 1, 0, 1 }, // 00100011 -> 0/0/1/0, 1 signbits + { 0, 0, 1, 0, 1 }, // 00100100 -> 0/0/1/0, 1 signbits + { 0, 0, 1, 0, 1 }, // 00100101 -> 0/0/1/0, 1 signbits + { 0, 0, 1, 0, 1 }, // 00100110 -> 0/0/1/0, 1 signbits + { 0, 0, 1, 0, 1 }, // 00100111 -> 0/0/1/0, 1 signbits + { 0, 0, -1, 0, 1 }, // 00101000 -> 0/0/-1/0, 1 signbits + { 0, 0, -1, 0, 1 }, // 00101001 -> 0/0/-1/0, 1 signbits + { 0, 0, -1, 0, 1 }, // 00101010 -> 0/0/-1/0, 1 signbits + { 0, 0, -1, 0, 1 }, // 00101011 -> 0/0/-1/0, 1 signbits + { 0, 0, -1, 0, 1 }, // 00101100 -> 0/0/-1/0, 1 signbits + { 0, 0, -1, 0, 1 }, // 00101101 -> 0/0/-1/0, 1 signbits + { 0, 0, -1, 0, 1 }, // 00101110 -> 0/0/-1/0, 1 signbits + { 0, 0, -1, 0, 1 }, // 00101111 -> 0/0/-1/0, 1 signbits + { 0, 0, 1, 1, 2 }, // 00110000 -> 0/0/1/1, 2 signbits + { 0, 0, 1, 1, 2 }, // 00110001 -> 0/0/1/1, 2 signbits + { 0, 0, 1, 1, 2 }, // 00110010 -> 0/0/1/1, 2 signbits + { 0, 0, 1, 1, 2 }, // 00110011 -> 0/0/1/1, 2 signbits + { 0, 0, 1, -1, 2 }, // 00110100 -> 0/0/1/-1, 2 signbits + { 0, 0, 1, -1, 2 }, // 00110101 -> 0/0/1/-1, 2 signbits + { 0, 0, 1, -1, 2 }, // 00110110 -> 0/0/1/-1, 2 signbits + { 0, 0, 1, -1, 2 }, // 00110111 -> 0/0/1/-1, 2 signbits + { 0, 0, -1, 1, 2 }, // 00111000 -> 0/0/-1/1, 2 signbits + { 0, 0, -1, 1, 2 }, // 00111001 -> 0/0/-1/1, 2 signbits + { 0, 0, -1, 1, 2 }, // 00111010 -> 0/0/-1/1, 2 signbits + { 0, 0, -1, 1, 2 }, // 00111011 -> 0/0/-1/1, 2 signbits + { 0, 0, -1, -1, 2 }, // 00111100 -> 0/0/-1/-1, 2 signbits + { 0, 0, -1, -1, 2 }, // 00111101 -> 0/0/-1/-1, 2 signbits + { 0, 0, -1, -1, 2 }, // 00111110 -> 0/0/-1/-1, 2 signbits + { 0, 0, -1, -1, 2 }, // 00111111 -> 0/0/-1/-1, 2 signbits + { 0, 1, 0, 0, 1 }, // 01000000 -> 0/1/0/0, 1 signbits + { 0, 1, 0, 0, 1 }, // 01000001 -> 0/1/0/0, 1 signbits + { 0, 1, 0, 0, 1 }, // 01000010 -> 0/1/0/0, 1 signbits + { 0, 1, 0, 0, 1 }, // 01000011 -> 0/1/0/0, 1 signbits + { 0, 1, 0, 0, 1 }, // 01000100 -> 0/1/0/0, 1 signbits + { 0, 1, 0, 0, 1 }, // 01000101 -> 0/1/0/0, 1 signbits + { 0, 1, 0, 0, 1 }, // 01000110 -> 0/1/0/0, 1 signbits + { 0, 1, 0, 0, 1 }, // 01000111 -> 0/1/0/0, 1 signbits + { 0, -1, 0, 0, 1 }, // 01001000 -> 0/-1/0/0, 1 signbits + { 0, -1, 0, 0, 1 }, // 01001001 -> 0/-1/0/0, 1 signbits + { 0, -1, 0, 0, 1 }, // 01001010 -> 0/-1/0/0, 1 signbits + { 0, -1, 0, 0, 1 }, // 01001011 -> 0/-1/0/0, 1 signbits + { 0, -1, 0, 0, 1 }, // 01001100 -> 0/-1/0/0, 1 signbits + { 0, -1, 0, 0, 1 }, // 01001101 -> 0/-1/0/0, 1 signbits + { 0, -1, 0, 0, 1 }, // 01001110 -> 0/-1/0/0, 1 signbits + { 0, -1, 0, 0, 1 }, // 01001111 -> 0/-1/0/0, 1 signbits + { 0, 1, 0, 1, 2 }, // 01010000 -> 0/1/0/1, 2 signbits + { 0, 1, 0, 1, 2 }, // 01010001 -> 0/1/0/1, 2 signbits + { 0, 1, 0, 1, 2 }, // 01010010 -> 0/1/0/1, 2 signbits + { 0, 1, 0, 1, 2 }, // 01010011 -> 0/1/0/1, 2 signbits + { 0, 1, 0, -1, 2 }, // 01010100 -> 0/1/0/-1, 2 signbits + { 0, 1, 0, -1, 2 }, // 01010101 -> 0/1/0/-1, 2 signbits + { 0, 1, 0, -1, 2 }, // 01010110 -> 0/1/0/-1, 2 signbits + { 0, 1, 0, -1, 2 }, // 01010111 -> 0/1/0/-1, 2 signbits + { 0, -1, 0, 1, 2 }, // 01011000 -> 0/-1/0/1, 2 signbits + { 0, -1, 0, 1, 2 }, // 01011001 -> 0/-1/0/1, 2 signbits + { 0, -1, 0, 1, 2 }, // 01011010 -> 0/-1/0/1, 2 signbits + { 0, -1, 0, 1, 2 }, // 01011011 -> 0/-1/0/1, 2 signbits + { 0, -1, 0, -1, 2 }, // 01011100 -> 0/-1/0/-1, 2 signbits + { 0, -1, 0, -1, 2 }, // 01011101 -> 0/-1/0/-1, 2 signbits + { 0, -1, 0, -1, 2 }, // 01011110 -> 0/-1/0/-1, 2 signbits + { 0, -1, 0, -1, 2 }, // 01011111 -> 0/-1/0/-1, 2 signbits + { 0, 1, 1, 0, 2 }, // 01100000 -> 0/1/1/0, 2 signbits + { 0, 1, 1, 0, 2 }, // 01100001 -> 0/1/1/0, 2 signbits + { 0, 1, 1, 0, 2 }, // 01100010 -> 0/1/1/0, 2 signbits + { 0, 1, 1, 0, 2 }, // 01100011 -> 0/1/1/0, 2 signbits + { 0, 1, -1, 0, 2 }, // 01100100 -> 0/1/-1/0, 2 signbits + { 0, 1, -1, 0, 2 }, // 01100101 -> 0/1/-1/0, 2 signbits + { 0, 1, -1, 0, 2 }, // 01100110 -> 0/1/-1/0, 2 signbits + { 0, 1, -1, 0, 2 }, // 01100111 -> 0/1/-1/0, 2 signbits + { 0, -1, 1, 0, 2 }, // 01101000 -> 0/-1/1/0, 2 signbits + { 0, -1, 1, 0, 2 }, // 01101001 -> 0/-1/1/0, 2 signbits + { 0, -1, 1, 0, 2 }, // 01101010 -> 0/-1/1/0, 2 signbits + { 0, -1, 1, 0, 2 }, // 01101011 -> 0/-1/1/0, 2 signbits + { 0, -1, -1, 0, 2 }, // 01101100 -> 0/-1/-1/0, 2 signbits + { 0, -1, -1, 0, 2 }, // 01101101 -> 0/-1/-1/0, 2 signbits + { 0, -1, -1, 0, 2 }, // 01101110 -> 0/-1/-1/0, 2 signbits + { 0, -1, -1, 0, 2 }, // 01101111 -> 0/-1/-1/0, 2 signbits + { 0, 1, 1, 1, 3 }, // 01110000 -> 0/1/1/1, 3 signbits + { 0, 1, 1, 1, 3 }, // 01110001 -> 0/1/1/1, 3 signbits + { 0, 1, 1, -1, 3 }, // 01110010 -> 0/1/1/-1, 3 signbits + { 0, 1, 1, -1, 3 }, // 01110011 -> 0/1/1/-1, 3 signbits + { 0, 1, -1, 1, 3 }, // 01110100 -> 0/1/-1/1, 3 signbits + { 0, 1, -1, 1, 3 }, // 01110101 -> 0/1/-1/1, 3 signbits + { 0, 1, -1, -1, 3 }, // 01110110 -> 0/1/-1/-1, 3 signbits + { 0, 1, -1, -1, 3 }, // 01110111 -> 0/1/-1/-1, 3 signbits + { 0, -1, 1, 1, 3 }, // 01111000 -> 0/-1/1/1, 3 signbits + { 0, -1, 1, 1, 3 }, // 01111001 -> 0/-1/1/1, 3 signbits + { 0, -1, 1, -1, 3 }, // 01111010 -> 0/-1/1/-1, 3 signbits + { 0, -1, 1, -1, 3 }, // 01111011 -> 0/-1/1/-1, 3 signbits + { 0, -1, -1, 1, 3 }, // 01111100 -> 0/-1/-1/1, 3 signbits + { 0, -1, -1, 1, 3 }, // 01111101 -> 0/-1/-1/1, 3 signbits + { 0, -1, -1, -1, 3 }, // 01111110 -> 0/-1/-1/-1, 3 signbits + { 0, -1, -1, -1, 3 }, // 01111111 -> 0/-1/-1/-1, 3 signbits + { 1, 0, 0, 0, 1 }, // 10000000 -> 1/0/0/0, 1 signbits + { 1, 0, 0, 0, 1 }, // 10000001 -> 1/0/0/0, 1 signbits + { 1, 0, 0, 0, 1 }, // 10000010 -> 1/0/0/0, 1 signbits + { 1, 0, 0, 0, 1 }, // 10000011 -> 1/0/0/0, 1 signbits + { 1, 0, 0, 0, 1 }, // 10000100 -> 1/0/0/0, 1 signbits + { 1, 0, 0, 0, 1 }, // 10000101 -> 1/0/0/0, 1 signbits + { 1, 0, 0, 0, 1 }, // 10000110 -> 1/0/0/0, 1 signbits + { 1, 0, 0, 0, 1 }, // 10000111 -> 1/0/0/0, 1 signbits + { -1, 0, 0, 0, 1 }, // 10001000 -> -1/0/0/0, 1 signbits + { -1, 0, 0, 0, 1 }, // 10001001 -> -1/0/0/0, 1 signbits + { -1, 0, 0, 0, 1 }, // 10001010 -> -1/0/0/0, 1 signbits + { -1, 0, 0, 0, 1 }, // 10001011 -> -1/0/0/0, 1 signbits + { -1, 0, 0, 0, 1 }, // 10001100 -> -1/0/0/0, 1 signbits + { -1, 0, 0, 0, 1 }, // 10001101 -> -1/0/0/0, 1 signbits + { -1, 0, 0, 0, 1 }, // 10001110 -> -1/0/0/0, 1 signbits + { -1, 0, 0, 0, 1 }, // 10001111 -> -1/0/0/0, 1 signbits + { 1, 0, 0, 1, 2 }, // 10010000 -> 1/0/0/1, 2 signbits + { 1, 0, 0, 1, 2 }, // 10010001 -> 1/0/0/1, 2 signbits + { 1, 0, 0, 1, 2 }, // 10010010 -> 1/0/0/1, 2 signbits + { 1, 0, 0, 1, 2 }, // 10010011 -> 1/0/0/1, 2 signbits + { 1, 0, 0, -1, 2 }, // 10010100 -> 1/0/0/-1, 2 signbits + { 1, 0, 0, -1, 2 }, // 10010101 -> 1/0/0/-1, 2 signbits + { 1, 0, 0, -1, 2 }, // 10010110 -> 1/0/0/-1, 2 signbits + { 1, 0, 0, -1, 2 }, // 10010111 -> 1/0/0/-1, 2 signbits + { -1, 0, 0, 1, 2 }, // 10011000 -> -1/0/0/1, 2 signbits + { -1, 0, 0, 1, 2 }, // 10011001 -> -1/0/0/1, 2 signbits + { -1, 0, 0, 1, 2 }, // 10011010 -> -1/0/0/1, 2 signbits + { -1, 0, 0, 1, 2 }, // 10011011 -> -1/0/0/1, 2 signbits + { -1, 0, 0, -1, 2 }, // 10011100 -> -1/0/0/-1, 2 signbits + { -1, 0, 0, -1, 2 }, // 10011101 -> -1/0/0/-1, 2 signbits + { -1, 0, 0, -1, 2 }, // 10011110 -> -1/0/0/-1, 2 signbits + { -1, 0, 0, -1, 2 }, // 10011111 -> -1/0/0/-1, 2 signbits + { 1, 0, 1, 0, 2 }, // 10100000 -> 1/0/1/0, 2 signbits + { 1, 0, 1, 0, 2 }, // 10100001 -> 1/0/1/0, 2 signbits + { 1, 0, 1, 0, 2 }, // 10100010 -> 1/0/1/0, 2 signbits + { 1, 0, 1, 0, 2 }, // 10100011 -> 1/0/1/0, 2 signbits + { 1, 0, -1, 0, 2 }, // 10100100 -> 1/0/-1/0, 2 signbits + { 1, 0, -1, 0, 2 }, // 10100101 -> 1/0/-1/0, 2 signbits + { 1, 0, -1, 0, 2 }, // 10100110 -> 1/0/-1/0, 2 signbits + { 1, 0, -1, 0, 2 }, // 10100111 -> 1/0/-1/0, 2 signbits + { -1, 0, 1, 0, 2 }, // 10101000 -> -1/0/1/0, 2 signbits + { -1, 0, 1, 0, 2 }, // 10101001 -> -1/0/1/0, 2 signbits + { -1, 0, 1, 0, 2 }, // 10101010 -> -1/0/1/0, 2 signbits + { -1, 0, 1, 0, 2 }, // 10101011 -> -1/0/1/0, 2 signbits + { -1, 0, -1, 0, 2 }, // 10101100 -> -1/0/-1/0, 2 signbits + { -1, 0, -1, 0, 2 }, // 10101101 -> -1/0/-1/0, 2 signbits + { -1, 0, -1, 0, 2 }, // 10101110 -> -1/0/-1/0, 2 signbits + { -1, 0, -1, 0, 2 }, // 10101111 -> -1/0/-1/0, 2 signbits + { 1, 0, 1, 1, 3 }, // 10110000 -> 1/0/1/1, 3 signbits + { 1, 0, 1, 1, 3 }, // 10110001 -> 1/0/1/1, 3 signbits + { 1, 0, 1, -1, 3 }, // 10110010 -> 1/0/1/-1, 3 signbits + { 1, 0, 1, -1, 3 }, // 10110011 -> 1/0/1/-1, 3 signbits + { 1, 0, -1, 1, 3 }, // 10110100 -> 1/0/-1/1, 3 signbits + { 1, 0, -1, 1, 3 }, // 10110101 -> 1/0/-1/1, 3 signbits + { 1, 0, -1, -1, 3 }, // 10110110 -> 1/0/-1/-1, 3 signbits + { 1, 0, -1, -1, 3 }, // 10110111 -> 1/0/-1/-1, 3 signbits + { -1, 0, 1, 1, 3 }, // 10111000 -> -1/0/1/1, 3 signbits + { -1, 0, 1, 1, 3 }, // 10111001 -> -1/0/1/1, 3 signbits + { -1, 0, 1, -1, 3 }, // 10111010 -> -1/0/1/-1, 3 signbits + { -1, 0, 1, -1, 3 }, // 10111011 -> -1/0/1/-1, 3 signbits + { -1, 0, -1, 1, 3 }, // 10111100 -> -1/0/-1/1, 3 signbits + { -1, 0, -1, 1, 3 }, // 10111101 -> -1/0/-1/1, 3 signbits + { -1, 0, -1, -1, 3 }, // 10111110 -> -1/0/-1/-1, 3 signbits + { -1, 0, -1, -1, 3 }, // 10111111 -> -1/0/-1/-1, 3 signbits + { 1, 1, 0, 0, 2 }, // 11000000 -> 1/1/0/0, 2 signbits + { 1, 1, 0, 0, 2 }, // 11000001 -> 1/1/0/0, 2 signbits + { 1, 1, 0, 0, 2 }, // 11000010 -> 1/1/0/0, 2 signbits + { 1, 1, 0, 0, 2 }, // 11000011 -> 1/1/0/0, 2 signbits + { 1, -1, 0, 0, 2 }, // 11000100 -> 1/-1/0/0, 2 signbits + { 1, -1, 0, 0, 2 }, // 11000101 -> 1/-1/0/0, 2 signbits + { 1, -1, 0, 0, 2 }, // 11000110 -> 1/-1/0/0, 2 signbits + { 1, -1, 0, 0, 2 }, // 11000111 -> 1/-1/0/0, 2 signbits + { -1, 1, 0, 0, 2 }, // 11001000 -> -1/1/0/0, 2 signbits + { -1, 1, 0, 0, 2 }, // 11001001 -> -1/1/0/0, 2 signbits + { -1, 1, 0, 0, 2 }, // 11001010 -> -1/1/0/0, 2 signbits + { -1, 1, 0, 0, 2 }, // 11001011 -> -1/1/0/0, 2 signbits + { -1, -1, 0, 0, 2 }, // 11001100 -> -1/-1/0/0, 2 signbits + { -1, -1, 0, 0, 2 }, // 11001101 -> -1/-1/0/0, 2 signbits + { -1, -1, 0, 0, 2 }, // 11001110 -> -1/-1/0/0, 2 signbits + { -1, -1, 0, 0, 2 }, // 11001111 -> -1/-1/0/0, 2 signbits + { 1, 1, 0, 1, 3 }, // 11010000 -> 1/1/0/1, 3 signbits + { 1, 1, 0, 1, 3 }, // 11010001 -> 1/1/0/1, 3 signbits + { 1, 1, 0, -1, 3 }, // 11010010 -> 1/1/0/-1, 3 signbits + { 1, 1, 0, -1, 3 }, // 11010011 -> 1/1/0/-1, 3 signbits + { 1, -1, 0, 1, 3 }, // 11010100 -> 1/-1/0/1, 3 signbits + { 1, -1, 0, 1, 3 }, // 11010101 -> 1/-1/0/1, 3 signbits + { 1, -1, 0, -1, 3 }, // 11010110 -> 1/-1/0/-1, 3 signbits + { 1, -1, 0, -1, 3 }, // 11010111 -> 1/-1/0/-1, 3 signbits + { -1, 1, 0, 1, 3 }, // 11011000 -> -1/1/0/1, 3 signbits + { -1, 1, 0, 1, 3 }, // 11011001 -> -1/1/0/1, 3 signbits + { -1, 1, 0, -1, 3 }, // 11011010 -> -1/1/0/-1, 3 signbits + { -1, 1, 0, -1, 3 }, // 11011011 -> -1/1/0/-1, 3 signbits + { -1, -1, 0, 1, 3 }, // 11011100 -> -1/-1/0/1, 3 signbits + { -1, -1, 0, 1, 3 }, // 11011101 -> -1/-1/0/1, 3 signbits + { -1, -1, 0, -1, 3 }, // 11011110 -> -1/-1/0/-1, 3 signbits + { -1, -1, 0, -1, 3 }, // 11011111 -> -1/-1/0/-1, 3 signbits + { 1, 1, 1, 0, 3 }, // 11100000 -> 1/1/1/0, 3 signbits + { 1, 1, 1, 0, 3 }, // 11100001 -> 1/1/1/0, 3 signbits + { 1, 1, -1, 0, 3 }, // 11100010 -> 1/1/-1/0, 3 signbits + { 1, 1, -1, 0, 3 }, // 11100011 -> 1/1/-1/0, 3 signbits + { 1, -1, 1, 0, 3 }, // 11100100 -> 1/-1/1/0, 3 signbits + { 1, -1, 1, 0, 3 }, // 11100101 -> 1/-1/1/0, 3 signbits + { 1, -1, -1, 0, 3 }, // 11100110 -> 1/-1/-1/0, 3 signbits + { 1, -1, -1, 0, 3 }, // 11100111 -> 1/-1/-1/0, 3 signbits + { -1, 1, 1, 0, 3 }, // 11101000 -> -1/1/1/0, 3 signbits + { -1, 1, 1, 0, 3 }, // 11101001 -> -1/1/1/0, 3 signbits + { -1, 1, -1, 0, 3 }, // 11101010 -> -1/1/-1/0, 3 signbits + { -1, 1, -1, 0, 3 }, // 11101011 -> -1/1/-1/0, 3 signbits + { -1, -1, 1, 0, 3 }, // 11101100 -> -1/-1/1/0, 3 signbits + { -1, -1, 1, 0, 3 }, // 11101101 -> -1/-1/1/0, 3 signbits + { -1, -1, -1, 0, 3 }, // 11101110 -> -1/-1/-1/0, 3 signbits + { -1, -1, -1, 0, 3 }, // 11101111 -> -1/-1/-1/0, 3 signbits + { 1, 1, 1, 1, 4 }, // 11110000 -> 1/1/1/1, 4 signbits + { 1, 1, 1, -1, 4 }, // 11110001 -> 1/1/1/-1, 4 signbits + { 1, 1, -1, 1, 4 }, // 11110010 -> 1/1/-1/1, 4 signbits + { 1, 1, -1, -1, 4 }, // 11110011 -> 1/1/-1/-1, 4 signbits + { 1, -1, 1, 1, 4 }, // 11110100 -> 1/-1/1/1, 4 signbits + { 1, -1, 1, -1, 4 }, // 11110101 -> 1/-1/1/-1, 4 signbits + { 1, -1, -1, 1, 4 }, // 11110110 -> 1/-1/-1/1, 4 signbits + { 1, -1, -1, -1, 4 }, // 11110111 -> 1/-1/-1/-1, 4 signbits + { -1, 1, 1, 1, 4 }, // 11111000 -> -1/1/1/1, 4 signbits + { -1, 1, 1, -1, 4 }, // 11111001 -> -1/1/1/-1, 4 signbits + { -1, 1, -1, 1, 4 }, // 11111010 -> -1/1/-1/1, 4 signbits + { -1, 1, -1, -1, 4 }, // 11111011 -> -1/1/-1/-1, 4 signbits + { -1, -1, 1, 1, 4 }, // 11111100 -> -1/-1/1/1, 4 signbits + { -1, -1, 1, -1, 4 }, // 11111101 -> -1/-1/1/-1, 4 signbits + { -1, -1, -1, 1, 4 }, // 11111110 -> -1/-1/-1/1, 4 signbits + { -1, -1, -1, -1, 4 } // 11111111 -> -1/-1/-1/-1, 4 signbits +}; + +/* ----------------------------------------------- + big values conversion table 0 + ----------------------------------------------- */ +static huffman_conv htab0_dec_start[ 1 ] = { + { 0, 0, 0, -1 } // always -> 0/0, 0 bit used +}; +// big values conversion table #0, total size: 1, ext tables: 0 +static huffman_conv_set htab0_dec[ 1 ] = { + { htab0_dec_start, 0 } // start table +}; + +/* ----------------------------------------------- + big values conversion table 1 + ----------------------------------------------- */ +static huffman_conv htab1_dec_start[ 8 ] = { + { 3, 1, 1, -1 }, // 000 -> 1/1, 3 bit used + { 3, 0, 1, -1 }, // 001 -> 0/1, 3 bit used + { 2, 1, 0, -1 }, // 010 -> 1/0, 2 bit used + { 2, 1, 0, -1 }, // 011 -> 1/0, 2 bit used + { 1, 0, 0, -1 }, // 100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 110 -> 0/0, 1 bit used + { 1, 0, 0, -1 } // 111 -> 0/0, 1 bit used +}; +// big values conversion table #1, total size: 8, ext tables: 0 +static huffman_conv_set htab1_dec[ 1 ] = { + { htab1_dec_start, 3 } // start table +}; + +/* ----------------------------------------------- + big values conversion table 2 + ----------------------------------------------- */ +static huffman_conv htab2_dec_start[ 64 ] = { + { 6, 2, 2, -1 }, // 000000 -> 2/2, 6 bit used + { 6, 0, 2, -1 }, // 000001 -> 0/2, 6 bit used + { 5, 1, 2, -1 }, // 000010 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 000011 -> 1/2, 5 bit used + { 5, 2, 1, -1 }, // 000100 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 000101 -> 2/1, 5 bit used + { 5, 2, 0, -1 }, // 000110 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 000111 -> 2/0, 5 bit used + { 3, 1, 1, -1 }, // 001000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 001001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 001010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 001011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 001100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 001101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 001110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 001111 -> 1/1, 3 bit used + { 3, 0, 1, -1 }, // 010000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 010001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 010010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 010011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 010100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 010101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 010110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 010111 -> 0/1, 3 bit used + { 3, 1, 0, -1 }, // 011000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 011001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 011010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 011011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 011100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 011101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 011110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 011111 -> 1/0, 3 bit used + { 1, 0, 0, -1 }, // 100000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 100001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 100010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 100011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 100100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 100101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 100110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 100111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 101000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 101001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 101010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 101011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 101100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 101101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 101110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 101111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 110000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 110001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 110010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 110011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 110100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 110101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 110110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 110111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 111000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 111001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 111010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 111011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 111100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 111101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 111110 -> 0/0, 1 bit used + { 1, 0, 0, -1 } // 111111 -> 0/0, 1 bit used +}; +// big values conversion table #2, total size: 64, ext tables: 0 +static huffman_conv_set htab2_dec[ 1 ] = { + { htab2_dec_start, 6 } // start table +}; + +/* ----------------------------------------------- + big values conversion table 3 + ----------------------------------------------- */ +static huffman_conv htab3_dec_start[ 64 ] = { + { 6, 2, 2, -1 }, // 000000 -> 2/2, 6 bit used + { 6, 0, 2, -1 }, // 000001 -> 0/2, 6 bit used + { 5, 1, 2, -1 }, // 000010 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 000011 -> 1/2, 5 bit used + { 5, 2, 1, -1 }, // 000100 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 000101 -> 2/1, 5 bit used + { 5, 2, 0, -1 }, // 000110 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 000111 -> 2/0, 5 bit used + { 3, 1, 0, -1 }, // 001000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 001001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 001010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 001011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 001100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 001101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 001110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 001111 -> 1/0, 3 bit used + { 2, 1, 1, -1 }, // 010000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 010001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 010010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 010011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 010100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 010101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 010110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 010111 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 011000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 011001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 011010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 011011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 011100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 011101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 011110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 011111 -> 1/1, 2 bit used + { 2, 0, 1, -1 }, // 100000 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 100001 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 100010 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 100011 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 100100 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 100101 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 100110 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 100111 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 101000 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 101001 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 101010 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 101011 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 101100 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 101101 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 101110 -> 0/1, 2 bit used + { 2, 0, 1, -1 }, // 101111 -> 0/1, 2 bit used + { 2, 0, 0, -1 }, // 110000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 110001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 110010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 110011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 110100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 110101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 110110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 110111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 111000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 111001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 111010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 111011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 111100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 111101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 111110 -> 0/0, 2 bit used + { 2, 0, 0, -1 } // 111111 -> 0/0, 2 bit used +}; +// big values conversion table #3, total size: 64, ext tables: 0 +static huffman_conv_set htab3_dec[ 1 ] = { + { htab3_dec_start, 6 } // start table +}; + +/* ----------------------------------------------- + big values conversion table 5 + ----------------------------------------------- */ +static huffman_conv htab5_dec_start[ 256 ] = { + { 8, 3, 3, -1 }, // 00000000 -> 3/3, 8 bit used + { 8, 2, 3, -1 }, // 00000001 -> 2/3, 8 bit used + { 7, 3, 2, -1 }, // 00000010 -> 3/2, 7 bit used + { 7, 3, 2, -1 }, // 00000011 -> 3/2, 7 bit used + { 6, 3, 1, -1 }, // 00000100 -> 3/1, 6 bit used + { 6, 3, 1, -1 }, // 00000101 -> 3/1, 6 bit used + { 6, 3, 1, -1 }, // 00000110 -> 3/1, 6 bit used + { 6, 3, 1, -1 }, // 00000111 -> 3/1, 6 bit used + { 7, 1, 3, -1 }, // 00001000 -> 1/3, 7 bit used + { 7, 1, 3, -1 }, // 00001001 -> 1/3, 7 bit used + { 7, 0, 3, -1 }, // 00001010 -> 0/3, 7 bit used + { 7, 0, 3, -1 }, // 00001011 -> 0/3, 7 bit used + { 7, 3, 0, -1 }, // 00001100 -> 3/0, 7 bit used + { 7, 3, 0, -1 }, // 00001101 -> 3/0, 7 bit used + { 7, 2, 2, -1 }, // 00001110 -> 2/2, 7 bit used + { 7, 2, 2, -1 }, // 00001111 -> 2/2, 7 bit used + { 6, 1, 2, -1 }, // 00010000 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00010001 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00010010 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00010011 -> 1/2, 6 bit used + { 6, 2, 1, -1 }, // 00010100 -> 2/1, 6 bit used + { 6, 2, 1, -1 }, // 00010101 -> 2/1, 6 bit used + { 6, 2, 1, -1 }, // 00010110 -> 2/1, 6 bit used + { 6, 2, 1, -1 }, // 00010111 -> 2/1, 6 bit used + { 6, 0, 2, -1 }, // 00011000 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00011001 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00011010 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00011011 -> 0/2, 6 bit used + { 6, 2, 0, -1 }, // 00011100 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00011101 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00011110 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00011111 -> 2/0, 6 bit used + { 3, 1, 1, -1 }, // 00100000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00100001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00100010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00100011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00100100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00100101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00100110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00100111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00101000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00101001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00101010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00101011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00101100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00101101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00101110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00101111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00110000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00110001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00110010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00110011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00110100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00110101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00110110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00110111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00111000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00111001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00111010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00111011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00111100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00111101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00111110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 00111111 -> 1/1, 3 bit used + { 3, 0, 1, -1 }, // 01000000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011111 -> 0/1, 3 bit used + { 3, 1, 0, -1 }, // 01100000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111111 -> 1/0, 3 bit used + { 1, 0, 0, -1 }, // 10000000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111110 -> 0/0, 1 bit used + { 1, 0, 0, -1 } // 11111111 -> 0/0, 1 bit used +}; +// big values conversion table #5, total size: 256, ext tables: 0 +static huffman_conv_set htab5_dec[ 1 ] = { + { htab5_dec_start, 8 } // start table +}; + +/* ----------------------------------------------- + big values conversion table 6 + ----------------------------------------------- */ +static huffman_conv htab6_dec_start[ 128 ] = { + { 7, 3, 3, -1 }, // 0000000 -> 3/3, 7 bit used + { 7, 0, 3, -1 }, // 0000001 -> 0/3, 7 bit used + { 6, 2, 3, -1 }, // 0000010 -> 2/3, 6 bit used + { 6, 2, 3, -1 }, // 0000011 -> 2/3, 6 bit used + { 6, 3, 2, -1 }, // 0000100 -> 3/2, 6 bit used + { 6, 3, 2, -1 }, // 0000101 -> 3/2, 6 bit used + { 6, 3, 0, -1 }, // 0000110 -> 3/0, 6 bit used + { 6, 3, 0, -1 }, // 0000111 -> 3/0, 6 bit used + { 5, 1, 3, -1 }, // 0001000 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 0001001 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 0001010 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 0001011 -> 1/3, 5 bit used + { 5, 3, 1, -1 }, // 0001100 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 0001101 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 0001110 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 0001111 -> 3/1, 5 bit used + { 5, 2, 2, -1 }, // 0010000 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 0010001 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 0010010 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 0010011 -> 2/2, 5 bit used + { 5, 0, 2, -1 }, // 0010100 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 0010101 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 0010110 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 0010111 -> 0/2, 5 bit used + { 4, 1, 2, -1 }, // 0011000 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 0011001 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 0011010 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 0011011 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 0011100 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 0011101 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 0011110 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 0011111 -> 1/2, 4 bit used + { 4, 2, 1, -1 }, // 0100000 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 0100001 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 0100010 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 0100011 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 0100100 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 0100101 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 0100110 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 0100111 -> 2/1, 4 bit used + { 4, 2, 0, -1 }, // 0101000 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 0101001 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 0101010 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 0101011 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 0101100 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 0101101 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 0101110 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 0101111 -> 2/0, 4 bit used + { 3, 0, 1, -1 }, // 0110000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0110001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0110010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0110011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0110100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0110101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0110110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0110111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0111000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0111001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0111010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0111011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0111100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0111101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0111110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 0111111 -> 0/1, 3 bit used + { 2, 1, 1, -1 }, // 1000000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1000001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1000010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1000011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1000100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1000101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1000110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1000111 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1001000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1001001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1001010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1001011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1001100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1001101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1001110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1001111 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1010000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1010001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1010010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1010011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1010100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1010101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1010110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1010111 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1011000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1011001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1011010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1011011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1011100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1011101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1011110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 1011111 -> 1/1, 2 bit used + { 3, 1, 0, -1 }, // 1100000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1100001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1100010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1100011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1100100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1100101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1100110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1100111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1101000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1101001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1101010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1101011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1101100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1101101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1101110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 1101111 -> 1/0, 3 bit used + { 3, 0, 0, -1 }, // 1110000 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1110001 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1110010 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1110011 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1110100 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1110101 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1110110 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1110111 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1111000 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1111001 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1111010 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1111011 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1111100 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1111101 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 1111110 -> 0/0, 3 bit used + { 3, 0, 0, -1 } // 1111111 -> 0/0, 3 bit used +}; +// big values conversion table #6, total size: 128, ext tables: 0 +static huffman_conv_set htab6_dec[ 1 ] = { + { htab6_dec_start, 7 } // start table +}; + +/* ----------------------------------------------- + big values conversion table 7 + ----------------------------------------------- */ +static huffman_conv htab7_dec_start[ 256 ] = { + { 8, -1, -1, 1 }, // 00000000 -> extension table #1 + { 8, -1, -1, 2 }, // 00000001 -> extension table #2 + { 8, -1, -1, 3 }, // 00000010 -> extension table #3 + { 8, 1, 5, -1 }, // 00000011 -> 1/5, 8 bit used + { 8, 5, 1, -1 }, // 00000100 -> 5/1, 8 bit used + { 8, -1, -1, 4 }, // 00000101 -> extension table #4 + { 8, 5, 0, -1 }, // 00000110 -> 5/0, 8 bit used + { 8, -1, -1, 5 }, // 00000111 -> extension table #5 + { 8, 2, 4, -1 }, // 00001000 -> 2/4, 8 bit used + { 8, 4, 2, -1 }, // 00001001 -> 4/2, 8 bit used + { 7, 1, 4, -1 }, // 00001010 -> 1/4, 7 bit used + { 7, 1, 4, -1 }, // 00001011 -> 1/4, 7 bit used + { 7, 4, 1, -1 }, // 00001100 -> 4/1, 7 bit used + { 7, 4, 1, -1 }, // 00001101 -> 4/1, 7 bit used + { 7, 4, 0, -1 }, // 00001110 -> 4/0, 7 bit used + { 7, 4, 0, -1 }, // 00001111 -> 4/0, 7 bit used + { 8, 0, 4, -1 }, // 00010000 -> 0/4, 8 bit used + { 8, 2, 3, -1 }, // 00010001 -> 2/3, 8 bit used + { 8, 3, 2, -1 }, // 00010010 -> 3/2, 8 bit used + { 8, 0, 3, -1 }, // 00010011 -> 0/3, 8 bit used + { 7, 1, 3, -1 }, // 00010100 -> 1/3, 7 bit used + { 7, 1, 3, -1 }, // 00010101 -> 1/3, 7 bit used + { 7, 3, 1, -1 }, // 00010110 -> 3/1, 7 bit used + { 7, 3, 1, -1 }, // 00010111 -> 3/1, 7 bit used + { 7, 3, 0, -1 }, // 00011000 -> 3/0, 7 bit used + { 7, 3, 0, -1 }, // 00011001 -> 3/0, 7 bit used + { 7, 2, 2, -1 }, // 00011010 -> 2/2, 7 bit used + { 7, 2, 2, -1 }, // 00011011 -> 2/2, 7 bit used + { 6, 1, 2, -1 }, // 00011100 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00011101 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00011110 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00011111 -> 1/2, 6 bit used + { 5, 2, 1, -1 }, // 00100000 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00100001 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00100010 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00100011 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00100100 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00100101 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00100110 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00100111 -> 2/1, 5 bit used + { 6, 0, 2, -1 }, // 00101000 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00101001 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00101010 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00101011 -> 0/2, 6 bit used + { 6, 2, 0, -1 }, // 00101100 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00101101 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00101110 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00101111 -> 2/0, 6 bit used + { 4, 1, 1, -1 }, // 00110000 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110001 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110010 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110011 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110100 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110101 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110110 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110111 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111000 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111001 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111010 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111011 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111100 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111101 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111110 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111111 -> 1/1, 4 bit used + { 3, 0, 1, -1 }, // 01000000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011111 -> 0/1, 3 bit used + { 3, 1, 0, -1 }, // 01100000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111111 -> 1/0, 3 bit used + { 1, 0, 0, -1 }, // 10000000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111110 -> 0/0, 1 bit used + { 1, 0, 0, -1 } // 11111111 -> 0/0, 1 bit used +}; +// extension table 1, prefix 00000000 +static huffman_conv htab7_dec_ext1[ 4 ] = { + { 2, 5, 5, -1 }, // 00 -> 5/5, 2 bit used + { 2, 4, 5, -1 }, // 01 -> 4/5, 2 bit used + { 2, 5, 4, -1 }, // 10 -> 5/4, 2 bit used + { 2, 5, 3, -1 } // 11 -> 5/3, 2 bit used +}; +// extension table 2, prefix 00000001 +static huffman_conv htab7_dec_ext2[ 2 ] = { + { 1, 3, 5, -1 }, // 0 -> 3/5, 1 bit used + { 1, 4, 4, -1 } // 1 -> 4/4, 1 bit used +}; +// extension table 3, prefix 00000010 +static huffman_conv htab7_dec_ext3[ 2 ] = { + { 1, 2, 5, -1 }, // 0 -> 2/5, 1 bit used + { 1, 5, 2, -1 } // 1 -> 5/2, 1 bit used +}; +// extension table 4, prefix 00000101 +static huffman_conv htab7_dec_ext4[ 2 ] = { + { 1, 0, 5, -1 }, // 0 -> 0/5, 1 bit used + { 1, 3, 4, -1 } // 1 -> 3/4, 1 bit used +}; +// extension table 5, prefix 00000111 +static huffman_conv htab7_dec_ext5[ 2 ] = { + { 1, 4, 3, -1 }, // 0 -> 4/3, 1 bit used + { 1, 3, 3, -1 } // 1 -> 3/3, 1 bit used +}; +// big values conversion table #7, total size: 268, ext tables: 5 +static huffman_conv_set htab7_dec[ 6 ] = { + { htab7_dec_start, 8 }, // start table + { htab7_dec_ext1, 2 }, // ext table #1 + { htab7_dec_ext2, 1 }, // ext table #2 + { htab7_dec_ext3, 1 }, // ext table #3 + { htab7_dec_ext4, 1 }, // ext table #4 + { htab7_dec_ext5, 1 } // ext table #5 +}; + +/* ----------------------------------------------- + big values conversion table 8 + ----------------------------------------------- */ +static huffman_conv htab8_dec_start[ 256 ] = { + { 8, -1, -1, 1 }, // 00000000 -> extension table #1 + { 8, -1, -1, 2 }, // 00000001 -> extension table #2 + { 8, -1, -1, 3 }, // 00000010 -> extension table #3 + { 8, 1, 5, -1 }, // 00000011 -> 1/5, 8 bit used + { 8, 5, 1, -1 }, // 00000100 -> 5/1, 8 bit used + { 8, -1, -1, 4 }, // 00000101 -> extension table #4 + { 8, -1, -1, 5 }, // 00000110 -> extension table #5 + { 8, 2, 4, -1 }, // 00000111 -> 2/4, 8 bit used + { 8, 4, 2, -1 }, // 00001000 -> 4/2, 8 bit used + { 8, 1, 4, -1 }, // 00001001 -> 1/4, 8 bit used + { 7, 4, 1, -1 }, // 00001010 -> 4/1, 7 bit used + { 7, 4, 1, -1 }, // 00001011 -> 4/1, 7 bit used + { 8, 0, 4, -1 }, // 00001100 -> 0/4, 8 bit used + { 8, 4, 0, -1 }, // 00001101 -> 4/0, 8 bit used + { 8, 2, 3, -1 }, // 00001110 -> 2/3, 8 bit used + { 8, 3, 2, -1 }, // 00001111 -> 3/2, 8 bit used + { 8, 1, 3, -1 }, // 00010000 -> 1/3, 8 bit used + { 8, 3, 1, -1 }, // 00010001 -> 3/1, 8 bit used + { 8, 0, 3, -1 }, // 00010010 -> 0/3, 8 bit used + { 8, 3, 0, -1 }, // 00010011 -> 3/0, 8 bit used + { 6, 2, 2, -1 }, // 00010100 -> 2/2, 6 bit used + { 6, 2, 2, -1 }, // 00010101 -> 2/2, 6 bit used + { 6, 2, 2, -1 }, // 00010110 -> 2/2, 6 bit used + { 6, 2, 2, -1 }, // 00010111 -> 2/2, 6 bit used + { 6, 0, 2, -1 }, // 00011000 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00011001 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00011010 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00011011 -> 0/2, 6 bit used + { 6, 2, 0, -1 }, // 00011100 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00011101 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00011110 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00011111 -> 2/0, 6 bit used + { 4, 1, 2, -1 }, // 00100000 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00100001 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00100010 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00100011 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00100100 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00100101 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00100110 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00100111 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00101000 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00101001 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00101010 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00101011 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00101100 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00101101 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00101110 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 00101111 -> 1/2, 4 bit used + { 4, 2, 1, -1 }, // 00110000 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00110001 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00110010 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00110011 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00110100 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00110101 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00110110 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00110111 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00111000 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00111001 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00111010 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00111011 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00111100 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00111101 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00111110 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 00111111 -> 2/1, 4 bit used + { 2, 1, 1, -1 }, // 01000000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01000001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01000010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01000011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01000100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01000101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01000110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01000111 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01001000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01001001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01001010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01001011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01001100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01001101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01001110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01001111 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01010000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01010001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01010010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01010011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01010100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01010101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01010110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01010111 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01011000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01011001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01011010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01011011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01011100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01011101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01011110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01011111 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01100000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01100001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01100010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01100011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01100100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01100101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01100110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01100111 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01101000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01101001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01101010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01101011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01101100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01101101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01101110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01101111 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01110000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01110001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01110010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01110011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01110100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01110101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01110110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01110111 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01111000 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01111001 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01111010 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01111011 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01111100 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01111101 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01111110 -> 1/1, 2 bit used + { 2, 1, 1, -1 }, // 01111111 -> 1/1, 2 bit used + { 3, 0, 1, -1 }, // 10000000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011111 -> 0/1, 3 bit used + { 3, 1, 0, -1 }, // 10100000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111111 -> 1/0, 3 bit used + { 2, 0, 0, -1 }, // 11000000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111110 -> 0/0, 2 bit used + { 2, 0, 0, -1 } // 11111111 -> 0/0, 2 bit used +}; +// extension table 1, prefix 00000000 +static huffman_conv htab8_dec_ext1[ 8 ] = { + { 3, 5, 5, -1 }, // 000 -> 5/5, 3 bit used + { 3, 5, 4, -1 }, // 001 -> 5/4, 3 bit used + { 2, 4, 5, -1 }, // 010 -> 4/5, 2 bit used + { 2, 4, 5, -1 }, // 011 -> 4/5, 2 bit used + { 1, 5, 3, -1 }, // 100 -> 5/3, 1 bit used + { 1, 5, 3, -1 }, // 101 -> 5/3, 1 bit used + { 1, 5, 3, -1 }, // 110 -> 5/3, 1 bit used + { 1, 5, 3, -1 } // 111 -> 5/3, 1 bit used +}; +// extension table 2, prefix 00000001 +static huffman_conv htab8_dec_ext2[ 4 ] = { + { 2, 3, 5, -1 }, // 00 -> 3/5, 2 bit used + { 2, 4, 4, -1 }, // 01 -> 4/4, 2 bit used + { 1, 2, 5, -1 }, // 10 -> 2/5, 1 bit used + { 1, 2, 5, -1 } // 11 -> 2/5, 1 bit used +}; +// extension table 3, prefix 00000010 +static huffman_conv htab8_dec_ext3[ 2 ] = { + { 1, 5, 2, -1 }, // 0 -> 5/2, 1 bit used + { 1, 0, 5, -1 } // 1 -> 0/5, 1 bit used +}; +// extension table 4, prefix 00000101 +static huffman_conv htab8_dec_ext4[ 2 ] = { + { 1, 3, 4, -1 }, // 0 -> 3/4, 1 bit used + { 1, 4, 3, -1 } // 1 -> 4/3, 1 bit used +}; +// extension table 5, prefix 00000110 +static huffman_conv htab8_dec_ext5[ 2 ] = { + { 1, 5, 0, -1 }, // 0 -> 5/0, 1 bit used + { 1, 3, 3, -1 } // 1 -> 3/3, 1 bit used +}; +// big values conversion table #8, total size: 274, ext tables: 5 +static huffman_conv_set htab8_dec[ 6 ] = { + { htab8_dec_start, 8 }, // start table + { htab8_dec_ext1, 3 }, // ext table #1 + { htab8_dec_ext2, 2 }, // ext table #2 + { htab8_dec_ext3, 1 }, // ext table #3 + { htab8_dec_ext4, 1 }, // ext table #4 + { htab8_dec_ext5, 1 } // ext table #5 +}; + +/* ----------------------------------------------- + big values conversion table 9 + ----------------------------------------------- */ +static huffman_conv htab9_dec_start[ 256 ] = { + { 8, -1, -1, 1 }, // 00000000 -> extension table #1 + { 8, 3, 5, -1 }, // 00000001 -> 3/5, 8 bit used + { 8, 5, 3, -1 }, // 00000010 -> 5/3, 8 bit used + { 8, -1, -1, 2 }, // 00000011 -> extension table #2 + { 8, 4, 4, -1 }, // 00000100 -> 4/4, 8 bit used + { 8, 2, 5, -1 }, // 00000101 -> 2/5, 8 bit used + { 8, 5, 2, -1 }, // 00000110 -> 5/2, 8 bit used + { 8, 1, 5, -1 }, // 00000111 -> 1/5, 8 bit used + { 7, 5, 1, -1 }, // 00001000 -> 5/1, 7 bit used + { 7, 5, 1, -1 }, // 00001001 -> 5/1, 7 bit used + { 7, 3, 4, -1 }, // 00001010 -> 3/4, 7 bit used + { 7, 3, 4, -1 }, // 00001011 -> 3/4, 7 bit used + { 7, 4, 3, -1 }, // 00001100 -> 4/3, 7 bit used + { 7, 4, 3, -1 }, // 00001101 -> 4/3, 7 bit used + { 8, 5, 0, -1 }, // 00001110 -> 5/0, 8 bit used + { 8, 0, 4, -1 }, // 00001111 -> 0/4, 8 bit used + { 7, 2, 4, -1 }, // 00010000 -> 2/4, 7 bit used + { 7, 2, 4, -1 }, // 00010001 -> 2/4, 7 bit used + { 7, 4, 2, -1 }, // 00010010 -> 4/2, 7 bit used + { 7, 4, 2, -1 }, // 00010011 -> 4/2, 7 bit used + { 7, 3, 3, -1 }, // 00010100 -> 3/3, 7 bit used + { 7, 3, 3, -1 }, // 00010101 -> 3/3, 7 bit used + { 7, 4, 0, -1 }, // 00010110 -> 4/0, 7 bit used + { 7, 4, 0, -1 }, // 00010111 -> 4/0, 7 bit used + { 6, 1, 4, -1 }, // 00011000 -> 1/4, 6 bit used + { 6, 1, 4, -1 }, // 00011001 -> 1/4, 6 bit used + { 6, 1, 4, -1 }, // 00011010 -> 1/4, 6 bit used + { 6, 1, 4, -1 }, // 00011011 -> 1/4, 6 bit used + { 6, 4, 1, -1 }, // 00011100 -> 4/1, 6 bit used + { 6, 4, 1, -1 }, // 00011101 -> 4/1, 6 bit used + { 6, 4, 1, -1 }, // 00011110 -> 4/1, 6 bit used + { 6, 4, 1, -1 }, // 00011111 -> 4/1, 6 bit used + { 6, 2, 3, -1 }, // 00100000 -> 2/3, 6 bit used + { 6, 2, 3, -1 }, // 00100001 -> 2/3, 6 bit used + { 6, 2, 3, -1 }, // 00100010 -> 2/3, 6 bit used + { 6, 2, 3, -1 }, // 00100011 -> 2/3, 6 bit used + { 6, 3, 2, -1 }, // 00100100 -> 3/2, 6 bit used + { 6, 3, 2, -1 }, // 00100101 -> 3/2, 6 bit used + { 6, 3, 2, -1 }, // 00100110 -> 3/2, 6 bit used + { 6, 3, 2, -1 }, // 00100111 -> 3/2, 6 bit used + { 5, 1, 3, -1 }, // 00101000 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 00101001 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 00101010 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 00101011 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 00101100 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 00101101 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 00101110 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 00101111 -> 1/3, 5 bit used + { 5, 3, 1, -1 }, // 00110000 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 00110001 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 00110010 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 00110011 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 00110100 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 00110101 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 00110110 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 00110111 -> 3/1, 5 bit used + { 6, 0, 3, -1 }, // 00111000 -> 0/3, 6 bit used + { 6, 0, 3, -1 }, // 00111001 -> 0/3, 6 bit used + { 6, 0, 3, -1 }, // 00111010 -> 0/3, 6 bit used + { 6, 0, 3, -1 }, // 00111011 -> 0/3, 6 bit used + { 6, 3, 0, -1 }, // 00111100 -> 3/0, 6 bit used + { 6, 3, 0, -1 }, // 00111101 -> 3/0, 6 bit used + { 6, 3, 0, -1 }, // 00111110 -> 3/0, 6 bit used + { 6, 3, 0, -1 }, // 00111111 -> 3/0, 6 bit used + { 5, 2, 2, -1 }, // 01000000 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01000001 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01000010 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01000011 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01000100 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01000101 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01000110 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01000111 -> 2/2, 5 bit used + { 5, 0, 2, -1 }, // 01001000 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01001001 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01001010 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01001011 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01001100 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01001101 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01001110 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01001111 -> 0/2, 5 bit used + { 4, 1, 2, -1 }, // 01010000 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01010001 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01010010 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01010011 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01010100 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01010101 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01010110 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01010111 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01011000 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01011001 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01011010 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01011011 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01011100 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01011101 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01011110 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01011111 -> 1/2, 4 bit used + { 4, 2, 1, -1 }, // 01100000 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01100001 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01100010 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01100011 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01100100 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01100101 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01100110 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01100111 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01101000 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01101001 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01101010 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01101011 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01101100 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01101101 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01101110 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01101111 -> 2/1, 4 bit used + { 4, 2, 0, -1 }, // 01110000 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01110001 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01110010 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01110011 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01110100 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01110101 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01110110 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01110111 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01111000 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01111001 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01111010 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01111011 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01111100 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01111101 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01111110 -> 2/0, 4 bit used + { 4, 2, 0, -1 }, // 01111111 -> 2/0, 4 bit used + { 3, 1, 1, -1 }, // 10000000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10000001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10000010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10000011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10000100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10000101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10000110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10000111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10001000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10001001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10001010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10001011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10001100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10001101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10001110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10001111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10010000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10010001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10010010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10010011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10010100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10010101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10010110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10010111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10011000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10011001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10011010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10011011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10011100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10011101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10011110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10011111 -> 1/1, 3 bit used + { 3, 0, 1, -1 }, // 10100000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10100001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10100010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10100011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10100100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10100101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10100110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10100111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10101000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10101001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10101010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10101011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10101100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10101101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10101110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10101111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10110000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10110001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10110010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10110011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10110100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10110101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10110110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10110111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10111000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10111001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10111010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10111011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10111100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10111101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10111110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10111111 -> 0/1, 3 bit used + { 3, 1, 0, -1 }, // 11000000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11000001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11000010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11000011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11000100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11000101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11000110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11000111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11001000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11001001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11001010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11001011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11001100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11001101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11001110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11001111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11010000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11010001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11010010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11010011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11010100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11010101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11010110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11010111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11011000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11011001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11011010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11011011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11011100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11011101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11011110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11011111 -> 1/0, 3 bit used + { 3, 0, 0, -1 }, // 11100000 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100001 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100010 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100011 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100100 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100101 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100110 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100111 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101000 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101001 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101010 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101011 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101100 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101101 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101110 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101111 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110000 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110001 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110010 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110011 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110100 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110101 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110110 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110111 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111000 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111001 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111010 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111011 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111100 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111101 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111110 -> 0/0, 3 bit used + { 3, 0, 0, -1 } // 11111111 -> 0/0, 3 bit used +}; +// extension table 1, prefix 00000000 +static huffman_conv htab9_dec_ext1[ 2 ] = { + { 1, 5, 5, -1 }, // 0 -> 5/5, 1 bit used + { 1, 4, 5, -1 } // 1 -> 4/5, 1 bit used +}; +// extension table 2, prefix 00000011 +static huffman_conv htab9_dec_ext2[ 2 ] = { + { 1, 5, 4, -1 }, // 0 -> 5/4, 1 bit used + { 1, 0, 5, -1 } // 1 -> 0/5, 1 bit used +}; +// big values conversion table #9, total size: 260, ext tables: 2 +static huffman_conv_set htab9_dec[ 3 ] = { + { htab9_dec_start, 8 }, // start table + { htab9_dec_ext1, 1 }, // ext table #1 + { htab9_dec_ext2, 1 } // ext table #2 +}; + +/* ----------------------------------------------- + big values conversion table 10 + ----------------------------------------------- */ +static huffman_conv htab10_dec_start[ 256 ] = { + { 8, -1, -1, 1 }, // 00000000 -> extension table #1 + { 8, -1, -1, 2 }, // 00000001 -> extension table #2 + { 8, -1, -1, 3 }, // 00000010 -> extension table #3 + { 8, -1, -1, 4 }, // 00000011 -> extension table #4 + { 8, -1, -1, 5 }, // 00000100 -> extension table #5 + { 8, -1, -1, 6 }, // 00000101 -> extension table #6 + { 8, -1, -1, 7 }, // 00000110 -> extension table #7 + { 8, 1, 7, -1 }, // 00000111 -> 1/7, 8 bit used + { 8, 7, 1, -1 }, // 00001000 -> 7/1, 8 bit used + { 8, -1, -1, 8 }, // 00001001 -> extension table #8 + { 8, -1, -1, 9 }, // 00001010 -> extension table #9 + { 8, -1, -1, 10 }, // 00001011 -> extension table #10 + { 8, 1, 6, -1 }, // 00001100 -> 1/6, 8 bit used + { 8, 6, 1, -1 }, // 00001101 -> 6/1, 8 bit used + { 8, 6, 0, -1 }, // 00001110 -> 6/0, 8 bit used + { 8, -1, -1, 11 }, // 00001111 -> extension table #11 + { 8, -1, -1, 12 }, // 00010000 -> extension table #12 + { 8, -1, -1, 13 }, // 00010001 -> extension table #13 + { 8, 1, 4, -1 }, // 00010010 -> 1/4, 8 bit used + { 8, 4, 1, -1 }, // 00010011 -> 4/1, 8 bit used + { 8, 4, 0, -1 }, // 00010100 -> 4/0, 8 bit used + { 8, 2, 3, -1 }, // 00010101 -> 2/3, 8 bit used + { 8, 3, 2, -1 }, // 00010110 -> 3/2, 8 bit used + { 8, 0, 3, -1 }, // 00010111 -> 0/3, 8 bit used + { 7, 1, 3, -1 }, // 00011000 -> 1/3, 7 bit used + { 7, 1, 3, -1 }, // 00011001 -> 1/3, 7 bit used + { 7, 3, 1, -1 }, // 00011010 -> 3/1, 7 bit used + { 7, 3, 1, -1 }, // 00011011 -> 3/1, 7 bit used + { 7, 3, 0, -1 }, // 00011100 -> 3/0, 7 bit used + { 7, 3, 0, -1 }, // 00011101 -> 3/0, 7 bit used + { 7, 2, 2, -1 }, // 00011110 -> 2/2, 7 bit used + { 7, 2, 2, -1 }, // 00011111 -> 2/2, 7 bit used + { 6, 1, 2, -1 }, // 00100000 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00100001 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00100010 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00100011 -> 1/2, 6 bit used + { 6, 2, 1, -1 }, // 00100100 -> 2/1, 6 bit used + { 6, 2, 1, -1 }, // 00100101 -> 2/1, 6 bit used + { 6, 2, 1, -1 }, // 00100110 -> 2/1, 6 bit used + { 6, 2, 1, -1 }, // 00100111 -> 2/1, 6 bit used + { 6, 0, 2, -1 }, // 00101000 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00101001 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00101010 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00101011 -> 0/2, 6 bit used + { 6, 2, 0, -1 }, // 00101100 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00101101 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00101110 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00101111 -> 2/0, 6 bit used + { 4, 1, 1, -1 }, // 00110000 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110001 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110010 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110011 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110100 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110101 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110110 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00110111 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111000 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111001 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111010 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111011 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111100 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111101 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111110 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 00111111 -> 1/1, 4 bit used + { 3, 0, 1, -1 }, // 01000000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01000111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01001111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01010111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 01011111 -> 0/1, 3 bit used + { 3, 1, 0, -1 }, // 01100000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111111 -> 1/0, 3 bit used + { 1, 0, 0, -1 }, // 10000000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111110 -> 0/0, 1 bit used + { 1, 0, 0, -1 } // 11111111 -> 0/0, 1 bit used +}; +// extension table 1, prefix 00000000 +static huffman_conv htab10_dec_ext1[ 8 ] = { + { 3, 7, 7, -1 }, // 000 -> 7/7, 3 bit used + { 3, 6, 7, -1 }, // 001 -> 6/7, 3 bit used + { 3, 7, 6, -1 }, // 010 -> 7/6, 3 bit used + { 3, 5, 7, -1 }, // 011 -> 5/7, 3 bit used + { 3, 7, 5, -1 }, // 100 -> 7/5, 3 bit used + { 3, 6, 6, -1 }, // 101 -> 6/6, 3 bit used + { 2, 4, 7, -1 }, // 110 -> 4/7, 2 bit used + { 2, 4, 7, -1 } // 111 -> 4/7, 2 bit used +}; +// extension table 2, prefix 00000001 +static huffman_conv htab10_dec_ext2[ 4 ] = { + { 2, 7, 4, -1 }, // 00 -> 7/4, 2 bit used + { 2, 5, 6, -1 }, // 01 -> 5/6, 2 bit used + { 2, 6, 5, -1 }, // 10 -> 6/5, 2 bit used + { 2, 3, 7, -1 } // 11 -> 3/7, 2 bit used +}; +// extension table 3, prefix 00000010 +static huffman_conv htab10_dec_ext3[ 8 ] = { + { 2, 7, 3, -1 }, // 000 -> 7/3, 2 bit used + { 2, 7, 3, -1 }, // 001 -> 7/3, 2 bit used + { 2, 4, 6, -1 }, // 010 -> 4/6, 2 bit used + { 2, 4, 6, -1 }, // 011 -> 4/6, 2 bit used + { 3, 5, 5, -1 }, // 100 -> 5/5, 3 bit used + { 3, 5, 4, -1 }, // 101 -> 5/4, 3 bit used + { 2, 6, 3, -1 }, // 110 -> 6/3, 2 bit used + { 2, 6, 3, -1 } // 111 -> 6/3, 2 bit used +}; +// extension table 4, prefix 00000011 +static huffman_conv htab10_dec_ext4[ 2 ] = { + { 1, 2, 7, -1 }, // 0 -> 2/7, 1 bit used + { 1, 7, 2, -1 } // 1 -> 7/2, 1 bit used +}; +// extension table 5, prefix 00000100 +static huffman_conv htab10_dec_ext5[ 4 ] = { + { 2, 6, 4, -1 }, // 00 -> 6/4, 2 bit used + { 2, 0, 7, -1 }, // 01 -> 0/7, 2 bit used + { 1, 7, 0, -1 }, // 10 -> 7/0, 1 bit used + { 1, 7, 0, -1 } // 11 -> 7/0, 1 bit used +}; +// extension table 6, prefix 00000101 +static huffman_conv htab10_dec_ext6[ 4 ] = { + { 1, 6, 2, -1 }, // 00 -> 6/2, 1 bit used + { 1, 6, 2, -1 }, // 01 -> 6/2, 1 bit used + { 2, 4, 5, -1 }, // 10 -> 4/5, 2 bit used + { 2, 3, 5, -1 } // 11 -> 3/5, 2 bit used +}; +// extension table 7, prefix 00000110 +static huffman_conv htab10_dec_ext7[ 4 ] = { + { 1, 0, 6, -1 }, // 00 -> 0/6, 1 bit used + { 1, 0, 6, -1 }, // 01 -> 0/6, 1 bit used + { 2, 5, 3, -1 }, // 10 -> 5/3, 2 bit used + { 2, 4, 4, -1 } // 11 -> 4/4, 2 bit used +}; +// extension table 8, prefix 00001001 +static huffman_conv htab10_dec_ext8[ 2 ] = { + { 1, 3, 6, -1 }, // 0 -> 3/6, 1 bit used + { 1, 2, 6, -1 } // 1 -> 2/6, 1 bit used +}; +// extension table 9, prefix 00001010 +static huffman_conv htab10_dec_ext9[ 4 ] = { + { 2, 2, 5, -1 }, // 00 -> 2/5, 2 bit used + { 2, 5, 2, -1 }, // 01 -> 5/2, 2 bit used + { 1, 1, 5, -1 }, // 10 -> 1/5, 1 bit used + { 1, 1, 5, -1 } // 11 -> 1/5, 1 bit used +}; +// extension table 10, prefix 00001011 +static huffman_conv htab10_dec_ext10[ 4 ] = { + { 1, 5, 1, -1 }, // 00 -> 5/1, 1 bit used + { 1, 5, 1, -1 }, // 01 -> 5/1, 1 bit used + { 2, 3, 4, -1 }, // 10 -> 3/4, 2 bit used + { 2, 4, 3, -1 } // 11 -> 4/3, 2 bit used +}; +// extension table 11, prefix 00001111 +static huffman_conv htab10_dec_ext11[ 2 ] = { + { 1, 0, 5, -1 }, // 0 -> 0/5, 1 bit used + { 1, 5, 0, -1 } // 1 -> 5/0, 1 bit used +}; +// extension table 12, prefix 00010000 +static huffman_conv htab10_dec_ext12[ 2 ] = { + { 1, 2, 4, -1 }, // 0 -> 2/4, 1 bit used + { 1, 4, 2, -1 } // 1 -> 4/2, 1 bit used +}; +// extension table 13, prefix 00010001 +static huffman_conv htab10_dec_ext13[ 2 ] = { + { 1, 3, 3, -1 }, // 0 -> 3/3, 1 bit used + { 1, 0, 4, -1 } // 1 -> 0/4, 1 bit used +}; +// big values conversion table #10, total size: 306, ext tables: 13 +static huffman_conv_set htab10_dec[ 14 ] = { + { htab10_dec_start, 8 }, // start table + { htab10_dec_ext1, 3 }, // ext table #1 + { htab10_dec_ext2, 2 }, // ext table #2 + { htab10_dec_ext3, 3 }, // ext table #3 + { htab10_dec_ext4, 1 }, // ext table #4 + { htab10_dec_ext5, 2 }, // ext table #5 + { htab10_dec_ext6, 2 }, // ext table #6 + { htab10_dec_ext7, 2 }, // ext table #7 + { htab10_dec_ext8, 1 }, // ext table #8 + { htab10_dec_ext9, 2 }, // ext table #9 + { htab10_dec_ext10, 2 }, // ext table #10 + { htab10_dec_ext11, 1 }, // ext table #11 + { htab10_dec_ext12, 1 }, // ext table #12 + { htab10_dec_ext13, 1 } // ext table #13 +}; + +/* ----------------------------------------------- + big values conversion table 11 + ----------------------------------------------- */ +static huffman_conv htab11_dec_start[ 256 ] = { + { 8, -1, -1, 1 }, // 00000000 -> extension table #1 + { 8, -1, -1, 2 }, // 00000001 -> extension table #2 + { 8, -1, -1, 3 }, // 00000010 -> extension table #3 + { 8, -1, -1, 4 }, // 00000011 -> extension table #4 + { 8, -1, -1, 5 }, // 00000100 -> extension table #5 + { 8, 2, 7, -1 }, // 00000101 -> 2/7, 8 bit used + { 8, 7, 2, -1 }, // 00000110 -> 7/2, 8 bit used + { 8, -1, -1, 6 }, // 00000111 -> extension table #6 + { 7, 7, 1, -1 }, // 00001000 -> 7/1, 7 bit used + { 7, 7, 1, -1 }, // 00001001 -> 7/1, 7 bit used + { 8, 1, 7, -1 }, // 00001010 -> 1/7, 8 bit used + { 8, 7, 0, -1 }, // 00001011 -> 7/0, 8 bit used + { 8, 3, 6, -1 }, // 00001100 -> 3/6, 8 bit used + { 8, 6, 3, -1 }, // 00001101 -> 6/3, 8 bit used + { 8, 6, 0, -1 }, // 00001110 -> 6/0, 8 bit used + { 8, -1, -1, 7 }, // 00001111 -> extension table #7 + { 8, -1, -1, 8 }, // 00010000 -> extension table #8 + { 8, 1, 5, -1 }, // 00010001 -> 1/5, 8 bit used + { 7, 6, 2, -1 }, // 00010010 -> 6/2, 7 bit used + { 7, 6, 2, -1 }, // 00010011 -> 6/2, 7 bit used + { 8, 2, 6, -1 }, // 00010100 -> 2/6, 8 bit used + { 8, 0, 6, -1 }, // 00010101 -> 0/6, 8 bit used + { 7, 1, 6, -1 }, // 00010110 -> 1/6, 7 bit used + { 7, 1, 6, -1 }, // 00010111 -> 1/6, 7 bit used + { 7, 6, 1, -1 }, // 00011000 -> 6/1, 7 bit used + { 7, 6, 1, -1 }, // 00011001 -> 6/1, 7 bit used + { 8, 5, 1, -1 }, // 00011010 -> 5/1, 8 bit used + { 8, 3, 4, -1 }, // 00011011 -> 3/4, 8 bit used + { 8, 5, 0, -1 }, // 00011100 -> 5/0, 8 bit used + { 8, -1, -1, 9 }, // 00011101 -> extension table #9 + { 8, 2, 4, -1 }, // 00011110 -> 2/4, 8 bit used + { 8, 4, 2, -1 }, // 00011111 -> 4/2, 8 bit used + { 8, 1, 4, -1 }, // 00100000 -> 1/4, 8 bit used + { 8, 4, 1, -1 }, // 00100001 -> 4/1, 8 bit used + { 8, 0, 4, -1 }, // 00100010 -> 0/4, 8 bit used + { 8, 4, 0, -1 }, // 00100011 -> 4/0, 8 bit used + { 7, 2, 3, -1 }, // 00100100 -> 2/3, 7 bit used + { 7, 2, 3, -1 }, // 00100101 -> 2/3, 7 bit used + { 7, 3, 2, -1 }, // 00100110 -> 3/2, 7 bit used + { 7, 3, 2, -1 }, // 00100111 -> 3/2, 7 bit used + { 6, 1, 3, -1 }, // 00101000 -> 1/3, 6 bit used + { 6, 1, 3, -1 }, // 00101001 -> 1/3, 6 bit used + { 6, 1, 3, -1 }, // 00101010 -> 1/3, 6 bit used + { 6, 1, 3, -1 }, // 00101011 -> 1/3, 6 bit used + { 6, 3, 1, -1 }, // 00101100 -> 3/1, 6 bit used + { 6, 3, 1, -1 }, // 00101101 -> 3/1, 6 bit used + { 6, 3, 1, -1 }, // 00101110 -> 3/1, 6 bit used + { 6, 3, 1, -1 }, // 00101111 -> 3/1, 6 bit used + { 7, 0, 3, -1 }, // 00110000 -> 0/3, 7 bit used + { 7, 0, 3, -1 }, // 00110001 -> 0/3, 7 bit used + { 7, 3, 0, -1 }, // 00110010 -> 3/0, 7 bit used + { 7, 3, 0, -1 }, // 00110011 -> 3/0, 7 bit used + { 6, 2, 2, -1 }, // 00110100 -> 2/2, 6 bit used + { 6, 2, 2, -1 }, // 00110101 -> 2/2, 6 bit used + { 6, 2, 2, -1 }, // 00110110 -> 2/2, 6 bit used + { 6, 2, 2, -1 }, // 00110111 -> 2/2, 6 bit used + { 5, 2, 1, -1 }, // 00111000 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00111001 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00111010 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00111011 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00111100 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00111101 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00111110 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 00111111 -> 2/1, 5 bit used + { 4, 1, 2, -1 }, // 01000000 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01000001 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01000010 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01000011 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01000100 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01000101 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01000110 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01000111 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01001000 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01001001 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01001010 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01001011 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01001100 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01001101 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01001110 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01001111 -> 1/2, 4 bit used + { 5, 0, 2, -1 }, // 01010000 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01010001 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01010010 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01010011 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01010100 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01010101 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01010110 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 01010111 -> 0/2, 5 bit used + { 5, 2, 0, -1 }, // 01011000 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 01011001 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 01011010 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 01011011 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 01011100 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 01011101 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 01011110 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 01011111 -> 2/0, 5 bit used + { 3, 1, 1, -1 }, // 01100000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01100001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01100010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01100011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01100100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01100101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01100110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01100111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01101000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01101001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01101010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01101011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01101100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01101101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01101110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01101111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01110000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01110001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01110010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01110011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01110100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01110101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01110110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01110111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01111000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01111001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01111010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01111011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01111100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01111101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01111110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 01111111 -> 1/1, 3 bit used + { 3, 0, 1, -1 }, // 10000000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10000111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10001111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10010111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 10011111 -> 0/1, 3 bit used + { 3, 1, 0, -1 }, // 10100000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10100111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10101111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10110111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 10111111 -> 1/0, 3 bit used + { 2, 0, 0, -1 }, // 11000000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11000111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11001111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11010111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11011111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11100111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11101111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110110 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11110111 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111000 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111001 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111010 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111011 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111100 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111101 -> 0/0, 2 bit used + { 2, 0, 0, -1 }, // 11111110 -> 0/0, 2 bit used + { 2, 0, 0, -1 } // 11111111 -> 0/0, 2 bit used +}; +// extension table 1, prefix 00000000 +static huffman_conv htab11_dec_ext1[ 4 ] = { + { 2, 7, 7, -1 }, // 00 -> 7/7, 2 bit used + { 2, 6, 7, -1 }, // 01 -> 6/7, 2 bit used + { 2, 7, 6, -1 }, // 10 -> 7/6, 2 bit used + { 2, 7, 5, -1 } // 11 -> 7/5, 2 bit used +}; +// extension table 2, prefix 00000001 +static huffman_conv htab11_dec_ext2[ 8 ] = { + { 2, 6, 6, -1 }, // 000 -> 6/6, 2 bit used + { 2, 6, 6, -1 }, // 001 -> 6/6, 2 bit used + { 2, 4, 7, -1 }, // 010 -> 4/7, 2 bit used + { 2, 4, 7, -1 }, // 011 -> 4/7, 2 bit used + { 2, 7, 4, -1 }, // 100 -> 7/4, 2 bit used + { 2, 7, 4, -1 }, // 101 -> 7/4, 2 bit used + { 3, 5, 7, -1 }, // 110 -> 5/7, 3 bit used + { 3, 5, 5, -1 } // 111 -> 5/5, 3 bit used +}; +// extension table 3, prefix 00000010 +static huffman_conv htab11_dec_ext3[ 4 ] = { + { 2, 5, 6, -1 }, // 00 -> 5/6, 2 bit used + { 2, 6, 5, -1 }, // 01 -> 6/5, 2 bit used + { 1, 3, 7, -1 }, // 10 -> 3/7, 1 bit used + { 1, 3, 7, -1 } // 11 -> 3/7, 1 bit used +}; +// extension table 4, prefix 00000011 +static huffman_conv htab11_dec_ext4[ 2 ] = { + { 1, 7, 3, -1 }, // 0 -> 7/3, 1 bit used + { 1, 4, 6, -1 } // 1 -> 4/6, 1 bit used +}; +// extension table 5, prefix 00000100 +static huffman_conv htab11_dec_ext5[ 4 ] = { + { 2, 4, 5, -1 }, // 00 -> 4/5, 2 bit used + { 2, 5, 4, -1 }, // 01 -> 5/4, 2 bit used + { 2, 3, 5, -1 }, // 10 -> 3/5, 2 bit used + { 2, 5, 3, -1 } // 11 -> 5/3, 2 bit used +}; +// extension table 6, prefix 00000111 +static huffman_conv htab11_dec_ext6[ 2 ] = { + { 1, 6, 4, -1 }, // 0 -> 6/4, 1 bit used + { 1, 0, 7, -1 } // 1 -> 0/7, 1 bit used +}; +// extension table 7, prefix 00001111 +static huffman_conv htab11_dec_ext7[ 2 ] = { + { 1, 4, 4, -1 }, // 0 -> 4/4, 1 bit used + { 1, 2, 5, -1 } // 1 -> 2/5, 1 bit used +}; +// extension table 8, prefix 00010000 +static huffman_conv htab11_dec_ext8[ 2 ] = { + { 1, 5, 2, -1 }, // 0 -> 5/2, 1 bit used + { 1, 0, 5, -1 } // 1 -> 0/5, 1 bit used +}; +// extension table 9, prefix 00011101 +static huffman_conv htab11_dec_ext9[ 2 ] = { + { 1, 4, 3, -1 }, // 0 -> 4/3, 1 bit used + { 1, 3, 3, -1 } // 1 -> 3/3, 1 bit used +}; +// big values conversion table #11, total size: 286, ext tables: 9 +static huffman_conv_set htab11_dec[ 10 ] = { + { htab11_dec_start, 8 }, // start table + { htab11_dec_ext1, 2 }, // ext table #1 + { htab11_dec_ext2, 3 }, // ext table #2 + { htab11_dec_ext3, 2 }, // ext table #3 + { htab11_dec_ext4, 1 }, // ext table #4 + { htab11_dec_ext5, 2 }, // ext table #5 + { htab11_dec_ext6, 1 }, // ext table #6 + { htab11_dec_ext7, 1 }, // ext table #7 + { htab11_dec_ext8, 1 }, // ext table #8 + { htab11_dec_ext9, 1 } // ext table #9 +}; + +/* ----------------------------------------------- + big values conversion table 12 + ----------------------------------------------- */ +static huffman_conv htab12_dec_start[ 256 ] = { + { 8, -1, -1, 1 }, // 00000000 -> extension table #1 + { 8, -1, -1, 2 }, // 00000001 -> extension table #2 + { 8, -1, -1, 3 }, // 00000010 -> extension table #3 + { 8, -1, -1, 4 }, // 00000011 -> extension table #4 + { 8, 5, 6, -1 }, // 00000100 -> 5/6, 8 bit used + { 8, 3, 7, -1 }, // 00000101 -> 3/7, 8 bit used + { 8, -1, -1, 5 }, // 00000110 -> extension table #5 + { 8, 2, 7, -1 }, // 00000111 -> 2/7, 8 bit used + { 8, 7, 2, -1 }, // 00001000 -> 7/2, 8 bit used + { 8, 4, 6, -1 }, // 00001001 -> 4/6, 8 bit used + { 8, 6, 4, -1 }, // 00001010 -> 6/4, 8 bit used + { 8, 1, 7, -1 }, // 00001011 -> 1/7, 8 bit used + { 8, 7, 1, -1 }, // 00001100 -> 7/1, 8 bit used + { 8, -1, -1, 6 }, // 00001101 -> extension table #6 + { 8, 3, 6, -1 }, // 00001110 -> 3/6, 8 bit used + { 8, 6, 3, -1 }, // 00001111 -> 6/3, 8 bit used + { 8, 4, 5, -1 }, // 00010000 -> 4/5, 8 bit used + { 8, 5, 4, -1 }, // 00010001 -> 5/4, 8 bit used + { 8, 4, 4, -1 }, // 00010010 -> 4/4, 8 bit used + { 8, -1, -1, 7 }, // 00010011 -> extension table #7 + { 7, 2, 6, -1 }, // 00010100 -> 2/6, 7 bit used + { 7, 2, 6, -1 }, // 00010101 -> 2/6, 7 bit used + { 7, 6, 2, -1 }, // 00010110 -> 6/2, 7 bit used + { 7, 6, 2, -1 }, // 00010111 -> 6/2, 7 bit used + { 7, 6, 1, -1 }, // 00011000 -> 6/1, 7 bit used + { 7, 6, 1, -1 }, // 00011001 -> 6/1, 7 bit used + { 8, 1, 6, -1 }, // 00011010 -> 1/6, 8 bit used + { 8, 6, 0, -1 }, // 00011011 -> 6/0, 8 bit used + { 8, 3, 5, -1 }, // 00011100 -> 3/5, 8 bit used + { 8, 5, 3, -1 }, // 00011101 -> 5/3, 8 bit used + { 8, 2, 5, -1 }, // 00011110 -> 2/5, 8 bit used + { 8, 5, 2, -1 }, // 00011111 -> 5/2, 8 bit used + { 7, 1, 5, -1 }, // 00100000 -> 1/5, 7 bit used + { 7, 1, 5, -1 }, // 00100001 -> 1/5, 7 bit used + { 7, 5, 1, -1 }, // 00100010 -> 5/1, 7 bit used + { 7, 5, 1, -1 }, // 00100011 -> 5/1, 7 bit used + { 7, 3, 4, -1 }, // 00100100 -> 3/4, 7 bit used + { 7, 3, 4, -1 }, // 00100101 -> 3/4, 7 bit used + { 7, 4, 3, -1 }, // 00100110 -> 4/3, 7 bit used + { 7, 4, 3, -1 }, // 00100111 -> 4/3, 7 bit used + { 8, 5, 0, -1 }, // 00101000 -> 5/0, 8 bit used + { 8, 0, 4, -1 }, // 00101001 -> 0/4, 8 bit used + { 7, 2, 4, -1 }, // 00101010 -> 2/4, 7 bit used + { 7, 2, 4, -1 }, // 00101011 -> 2/4, 7 bit used + { 7, 4, 2, -1 }, // 00101100 -> 4/2, 7 bit used + { 7, 4, 2, -1 }, // 00101101 -> 4/2, 7 bit used + { 7, 1, 4, -1 }, // 00101110 -> 1/4, 7 bit used + { 7, 1, 4, -1 }, // 00101111 -> 1/4, 7 bit used + { 6, 3, 3, -1 }, // 00110000 -> 3/3, 6 bit used + { 6, 3, 3, -1 }, // 00110001 -> 3/3, 6 bit used + { 6, 3, 3, -1 }, // 00110010 -> 3/3, 6 bit used + { 6, 3, 3, -1 }, // 00110011 -> 3/3, 6 bit used + { 6, 4, 1, -1 }, // 00110100 -> 4/1, 6 bit used + { 6, 4, 1, -1 }, // 00110101 -> 4/1, 6 bit used + { 6, 4, 1, -1 }, // 00110110 -> 4/1, 6 bit used + { 6, 4, 1, -1 }, // 00110111 -> 4/1, 6 bit used + { 6, 2, 3, -1 }, // 00111000 -> 2/3, 6 bit used + { 6, 2, 3, -1 }, // 00111001 -> 2/3, 6 bit used + { 6, 2, 3, -1 }, // 00111010 -> 2/3, 6 bit used + { 6, 2, 3, -1 }, // 00111011 -> 2/3, 6 bit used + { 6, 3, 2, -1 }, // 00111100 -> 3/2, 6 bit used + { 6, 3, 2, -1 }, // 00111101 -> 3/2, 6 bit used + { 6, 3, 2, -1 }, // 00111110 -> 3/2, 6 bit used + { 6, 3, 2, -1 }, // 00111111 -> 3/2, 6 bit used + { 7, 4, 0, -1 }, // 01000000 -> 4/0, 7 bit used + { 7, 4, 0, -1 }, // 01000001 -> 4/0, 7 bit used + { 7, 0, 3, -1 }, // 01000010 -> 0/3, 7 bit used + { 7, 0, 3, -1 }, // 01000011 -> 0/3, 7 bit used + { 6, 3, 0, -1 }, // 01000100 -> 3/0, 6 bit used + { 6, 3, 0, -1 }, // 01000101 -> 3/0, 6 bit used + { 6, 3, 0, -1 }, // 01000110 -> 3/0, 6 bit used + { 6, 3, 0, -1 }, // 01000111 -> 3/0, 6 bit used + { 5, 1, 3, -1 }, // 01001000 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 01001001 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 01001010 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 01001011 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 01001100 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 01001101 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 01001110 -> 1/3, 5 bit used + { 5, 1, 3, -1 }, // 01001111 -> 1/3, 5 bit used + { 5, 3, 1, -1 }, // 01010000 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 01010001 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 01010010 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 01010011 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 01010100 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 01010101 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 01010110 -> 3/1, 5 bit used + { 5, 3, 1, -1 }, // 01010111 -> 3/1, 5 bit used + { 5, 2, 2, -1 }, // 01011000 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01011001 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01011010 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01011011 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01011100 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01011101 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01011110 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01011111 -> 2/2, 5 bit used + { 4, 1, 2, -1 }, // 01100000 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01100001 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01100010 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01100011 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01100100 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01100101 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01100110 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01100111 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01101000 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01101001 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01101010 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01101011 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01101100 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01101101 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01101110 -> 1/2, 4 bit used + { 4, 1, 2, -1 }, // 01101111 -> 1/2, 4 bit used + { 4, 2, 1, -1 }, // 01110000 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01110001 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01110010 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01110011 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01110100 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01110101 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01110110 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01110111 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01111000 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01111001 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01111010 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01111011 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01111100 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01111101 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01111110 -> 2/1, 4 bit used + { 4, 2, 1, -1 }, // 01111111 -> 2/1, 4 bit used + { 5, 0, 2, -1 }, // 10000000 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10000001 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10000010 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10000011 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10000100 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10000101 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10000110 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10000111 -> 0/2, 5 bit used + { 5, 2, 0, -1 }, // 10001000 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10001001 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10001010 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10001011 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10001100 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10001101 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10001110 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10001111 -> 2/0, 5 bit used + { 4, 0, 0, -1 }, // 10010000 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10010001 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10010010 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10010011 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10010100 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10010101 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10010110 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10010111 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10011000 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10011001 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10011010 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10011011 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10011100 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10011101 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10011110 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 10011111 -> 0/0, 4 bit used + { 3, 1, 1, -1 }, // 10100000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111111 -> 1/1, 3 bit used + { 3, 0, 1, -1 }, // 11000000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11000001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11000010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11000011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11000100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11000101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11000110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11000111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11001000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11001001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11001010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11001011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11001100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11001101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11001110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11001111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11010000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11010001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11010010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11010011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11010100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11010101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11010110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11010111 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11011000 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11011001 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11011010 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11011011 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11011100 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11011101 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11011110 -> 0/1, 3 bit used + { 3, 0, 1, -1 }, // 11011111 -> 0/1, 3 bit used + { 3, 1, 0, -1 }, // 11100000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11100001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11100010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11100011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11100100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11100101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11100110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11100111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11101000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11101001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11101010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11101011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11101100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11101101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11101110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11101111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11110000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11110001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11110010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11110011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11110100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11110101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11110110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11110111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11111000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11111001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11111010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11111011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11111100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11111101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 11111110 -> 1/0, 3 bit used + { 3, 1, 0, -1 } // 11111111 -> 1/0, 3 bit used +}; +// extension table 1, prefix 00000000 +static huffman_conv htab12_dec_ext1[ 4 ] = { + { 2, 7, 7, -1 }, // 00 -> 7/7, 2 bit used + { 2, 6, 7, -1 }, // 01 -> 6/7, 2 bit used + { 1, 7, 6, -1 }, // 10 -> 7/6, 1 bit used + { 1, 7, 6, -1 } // 11 -> 7/6, 1 bit used +}; +// extension table 2, prefix 00000001 +static huffman_conv htab12_dec_ext2[ 2 ] = { + { 1, 5, 7, -1 }, // 0 -> 5/7, 1 bit used + { 1, 7, 5, -1 } // 1 -> 7/5, 1 bit used +}; +// extension table 3, prefix 00000010 +static huffman_conv htab12_dec_ext3[ 2 ] = { + { 1, 6, 6, -1 }, // 0 -> 6/6, 1 bit used + { 1, 4, 7, -1 } // 1 -> 4/7, 1 bit used +}; +// extension table 4, prefix 00000011 +static huffman_conv htab12_dec_ext4[ 2 ] = { + { 1, 7, 4, -1 }, // 0 -> 7/4, 1 bit used + { 1, 6, 5, -1 } // 1 -> 6/5, 1 bit used +}; +// extension table 5, prefix 00000110 +static huffman_conv htab12_dec_ext5[ 2 ] = { + { 1, 7, 3, -1 }, // 0 -> 7/3, 1 bit used + { 1, 5, 5, -1 } // 1 -> 5/5, 1 bit used +}; +// extension table 6, prefix 00001101 +static huffman_conv htab12_dec_ext6[ 2 ] = { + { 1, 0, 7, -1 }, // 0 -> 0/7, 1 bit used + { 1, 7, 0, -1 } // 1 -> 7/0, 1 bit used +}; +// extension table 7, prefix 00010011 +static huffman_conv htab12_dec_ext7[ 2 ] = { + { 1, 0, 6, -1 }, // 0 -> 0/6, 1 bit used + { 1, 0, 5, -1 } // 1 -> 0/5, 1 bit used +}; +// big values conversion table #12, total size: 272, ext tables: 7 +static huffman_conv_set htab12_dec[ 8 ] = { + { htab12_dec_start, 8 }, // start table + { htab12_dec_ext1, 2 }, // ext table #1 + { htab12_dec_ext2, 1 }, // ext table #2 + { htab12_dec_ext3, 1 }, // ext table #3 + { htab12_dec_ext4, 1 }, // ext table #4 + { htab12_dec_ext5, 1 }, // ext table #5 + { htab12_dec_ext6, 1 }, // ext table #6 + { htab12_dec_ext7, 1 } // ext table #7 +}; + +/* ----------------------------------------------- + big values conversion table 13 + ----------------------------------------------- */ +static huffman_conv htab13_dec_start[ 256 ] = { + { 8, -1, -1, 1 }, // 00000000 -> extension table #1 + { 8, -1, -1, 2 }, // 00000001 -> extension table #2 + { 8, -1, -1, 3 }, // 00000010 -> extension table #3 + { 8, -1, -1, 4 }, // 00000011 -> extension table #4 + { 8, -1, -1, 5 }, // 00000100 -> extension table #5 + { 8, -1, -1, 6 }, // 00000101 -> extension table #6 + { 8, -1, -1, 7 }, // 00000110 -> extension table #7 + { 8, -1, -1, 8 }, // 00000111 -> extension table #8 + { 8, -1, -1, 9 }, // 00001000 -> extension table #9 + { 8, -1, -1, 10 }, // 00001001 -> extension table #10 + { 8, -1, -1, 11 }, // 00001010 -> extension table #11 + { 8, -1, -1, 12 }, // 00001011 -> extension table #12 + { 8, -1, -1, 13 }, // 00001100 -> extension table #13 + { 8, -1, -1, 14 }, // 00001101 -> extension table #14 + { 8, -1, -1, 15 }, // 00001110 -> extension table #15 + { 8, -1, -1, 16 }, // 00001111 -> extension table #16 + { 8, -1, -1, 17 }, // 00010000 -> extension table #17 + { 8, -1, -1, 18 }, // 00010001 -> extension table #18 + { 8, -1, -1, 19 }, // 00010010 -> extension table #19 + { 8, -1, -1, 20 }, // 00010011 -> extension table #20 + { 8, 8, 1, -1 }, // 00010100 -> 8/1, 8 bit used + { 8, -1, -1, 21 }, // 00010101 -> extension table #21 + { 8, -1, -1, 22 }, // 00010110 -> extension table #22 + { 8, -1, -1, 23 }, // 00010111 -> extension table #23 + { 8, -1, -1, 24 }, // 00011000 -> extension table #24 + { 8, -1, -1, 25 }, // 00011001 -> extension table #25 + { 8, 1, 5, -1 }, // 00011010 -> 1/5, 8 bit used + { 8, 5, 1, -1 }, // 00011011 -> 5/1, 8 bit used + { 8, -1, -1, 26 }, // 00011100 -> extension table #26 + { 8, -1, -1, 27 }, // 00011101 -> extension table #27 + { 8, -1, -1, 28 }, // 00011110 -> extension table #28 + { 8, 1, 4, -1 }, // 00011111 -> 1/4, 8 bit used + { 7, 4, 1, -1 }, // 00100000 -> 4/1, 7 bit used + { 7, 4, 1, -1 }, // 00100001 -> 4/1, 7 bit used + { 8, 0, 4, -1 }, // 00100010 -> 0/4, 8 bit used + { 8, 4, 0, -1 }, // 00100011 -> 4/0, 8 bit used + { 8, 2, 3, -1 }, // 00100100 -> 2/3, 8 bit used + { 8, 3, 2, -1 }, // 00100101 -> 3/2, 8 bit used + { 7, 1, 3, -1 }, // 00100110 -> 1/3, 7 bit used + { 7, 1, 3, -1 }, // 00100111 -> 1/3, 7 bit used + { 7, 3, 1, -1 }, // 00101000 -> 3/1, 7 bit used + { 7, 3, 1, -1 }, // 00101001 -> 3/1, 7 bit used + { 7, 0, 3, -1 }, // 00101010 -> 0/3, 7 bit used + { 7, 0, 3, -1 }, // 00101011 -> 0/3, 7 bit used + { 7, 3, 0, -1 }, // 00101100 -> 3/0, 7 bit used + { 7, 3, 0, -1 }, // 00101101 -> 3/0, 7 bit used + { 7, 2, 2, -1 }, // 00101110 -> 2/2, 7 bit used + { 7, 2, 2, -1 }, // 00101111 -> 2/2, 7 bit used + { 6, 1, 2, -1 }, // 00110000 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00110001 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00110010 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00110011 -> 1/2, 6 bit used + { 6, 2, 1, -1 }, // 00110100 -> 2/1, 6 bit used + { 6, 2, 1, -1 }, // 00110101 -> 2/1, 6 bit used + { 6, 2, 1, -1 }, // 00110110 -> 2/1, 6 bit used + { 6, 2, 1, -1 }, // 00110111 -> 2/1, 6 bit used + { 6, 0, 2, -1 }, // 00111000 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00111001 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00111010 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00111011 -> 0/2, 6 bit used + { 6, 2, 0, -1 }, // 00111100 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00111101 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00111110 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00111111 -> 2/0, 6 bit used + { 4, 1, 1, -1 }, // 01000000 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000001 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000010 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000011 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000100 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000101 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000110 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000111 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001000 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001001 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001010 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001011 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001100 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001101 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001110 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001111 -> 1/1, 4 bit used + { 4, 0, 1, -1 }, // 01010000 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010001 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010010 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010011 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010100 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010101 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010110 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010111 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011000 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011001 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011010 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011011 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011100 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011101 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011110 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011111 -> 0/1, 4 bit used + { 3, 1, 0, -1 }, // 01100000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111111 -> 1/0, 3 bit used + { 1, 0, 0, -1 }, // 10000000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111110 -> 0/0, 1 bit used + { 1, 0, 0, -1 } // 11111111 -> 0/0, 1 bit used +}; +// extension table 1, prefix 00000000 +static huffman_conv htab13_dec_ext1[ 256 ] = { + { 8, -1, -1, 29 }, // 00000000 -> extension table #29 + { 8, 15, 15, -1 }, // 00000001 -> 15/15, 8 bit used + { 8, 14, 15, -1 }, // 00000010 -> 14/15, 8 bit used + { 8, 13, 15, -1 }, // 00000011 -> 13/15, 8 bit used + { 8, 14, 14, -1 }, // 00000100 -> 14/14, 8 bit used + { 8, 12, 15, -1 }, // 00000101 -> 12/15, 8 bit used + { 8, 13, 14, -1 }, // 00000110 -> 13/14, 8 bit used + { 8, 11, 15, -1 }, // 00000111 -> 11/15, 8 bit used + { 8, 15, 11, -1 }, // 00001000 -> 15/11, 8 bit used + { 8, 12, 14, -1 }, // 00001001 -> 12/14, 8 bit used + { 8, 13, 12, -1 }, // 00001010 -> 13/12, 8 bit used + { 8, -1, -1, 30 }, // 00001011 -> extension table #30 + { 7, 14, 12, -1 }, // 00001100 -> 14/12, 7 bit used + { 7, 14, 12, -1 }, // 00001101 -> 14/12, 7 bit used + { 7, 13, 13, -1 }, // 00001110 -> 13/13, 7 bit used + { 7, 13, 13, -1 }, // 00001111 -> 13/13, 7 bit used + { 8, 15, 10, -1 }, // 00010000 -> 15/10, 8 bit used + { 8, 12, 13, -1 }, // 00010001 -> 12/13, 8 bit used + { 7, 11, 14, -1 }, // 00010010 -> 11/14, 7 bit used + { 7, 11, 14, -1 }, // 00010011 -> 11/14, 7 bit used + { 7, 14, 11, -1 }, // 00010100 -> 14/11, 7 bit used + { 7, 14, 11, -1 }, // 00010101 -> 14/11, 7 bit used + { 7, 9, 15, -1 }, // 00010110 -> 9/15, 7 bit used + { 7, 9, 15, -1 }, // 00010111 -> 9/15, 7 bit used + { 7, 15, 9, -1 }, // 00011000 -> 15/9, 7 bit used + { 7, 15, 9, -1 }, // 00011001 -> 15/9, 7 bit used + { 7, 14, 10, -1 }, // 00011010 -> 14/10, 7 bit used + { 7, 14, 10, -1 }, // 00011011 -> 14/10, 7 bit used + { 7, 11, 13, -1 }, // 00011100 -> 11/13, 7 bit used + { 7, 11, 13, -1 }, // 00011101 -> 11/13, 7 bit used + { 7, 13, 11, -1 }, // 00011110 -> 13/11, 7 bit used + { 7, 13, 11, -1 }, // 00011111 -> 13/11, 7 bit used + { 7, 8, 15, -1 }, // 00100000 -> 8/15, 7 bit used + { 7, 8, 15, -1 }, // 00100001 -> 8/15, 7 bit used + { 7, 15, 8, -1 }, // 00100010 -> 15/8, 7 bit used + { 7, 15, 8, -1 }, // 00100011 -> 15/8, 7 bit used + { 7, 12, 12, -1 }, // 00100100 -> 12/12, 7 bit used + { 7, 12, 12, -1 }, // 00100101 -> 12/12, 7 bit used + { 8, 10, 14, -1 }, // 00100110 -> 10/14, 8 bit used + { 8, 9, 14, -1 }, // 00100111 -> 9/14, 8 bit used + { 7, 8, 14, -1 }, // 00101000 -> 8/14, 7 bit used + { 7, 8, 14, -1 }, // 00101001 -> 8/14, 7 bit used + { 8, 7, 15, -1 }, // 00101010 -> 7/15, 8 bit used + { 8, 7, 14, -1 }, // 00101011 -> 7/14, 8 bit used + { 6, 15, 7, -1 }, // 00101100 -> 15/7, 6 bit used + { 6, 15, 7, -1 }, // 00101101 -> 15/7, 6 bit used + { 6, 15, 7, -1 }, // 00101110 -> 15/7, 6 bit used + { 6, 15, 7, -1 }, // 00101111 -> 15/7, 6 bit used + { 6, 13, 10, -1 }, // 00110000 -> 13/10, 6 bit used + { 6, 13, 10, -1 }, // 00110001 -> 13/10, 6 bit used + { 6, 13, 10, -1 }, // 00110010 -> 13/10, 6 bit used + { 6, 13, 10, -1 }, // 00110011 -> 13/10, 6 bit used + { 7, 10, 13, -1 }, // 00110100 -> 10/13, 7 bit used + { 7, 10, 13, -1 }, // 00110101 -> 10/13, 7 bit used + { 7, 11, 12, -1 }, // 00110110 -> 11/12, 7 bit used + { 7, 11, 12, -1 }, // 00110111 -> 11/12, 7 bit used + { 7, 12, 11, -1 }, // 00111000 -> 12/11, 7 bit used + { 7, 12, 11, -1 }, // 00111001 -> 12/11, 7 bit used + { 7, 15, 6, -1 }, // 00111010 -> 15/6, 7 bit used + { 7, 15, 6, -1 }, // 00111011 -> 15/6, 7 bit used + { 6, 6, 15, -1 }, // 00111100 -> 6/15, 6 bit used + { 6, 6, 15, -1 }, // 00111101 -> 6/15, 6 bit used + { 6, 6, 15, -1 }, // 00111110 -> 6/15, 6 bit used + { 6, 6, 15, -1 }, // 00111111 -> 6/15, 6 bit used + { 6, 14, 8, -1 }, // 01000000 -> 14/8, 6 bit used + { 6, 14, 8, -1 }, // 01000001 -> 14/8, 6 bit used + { 6, 14, 8, -1 }, // 01000010 -> 14/8, 6 bit used + { 6, 14, 8, -1 }, // 01000011 -> 14/8, 6 bit used + { 6, 5, 15, -1 }, // 01000100 -> 5/15, 6 bit used + { 6, 5, 15, -1 }, // 01000101 -> 5/15, 6 bit used + { 6, 5, 15, -1 }, // 01000110 -> 5/15, 6 bit used + { 6, 5, 15, -1 }, // 01000111 -> 5/15, 6 bit used + { 6, 9, 13, -1 }, // 01001000 -> 9/13, 6 bit used + { 6, 9, 13, -1 }, // 01001001 -> 9/13, 6 bit used + { 6, 9, 13, -1 }, // 01001010 -> 9/13, 6 bit used + { 6, 9, 13, -1 }, // 01001011 -> 9/13, 6 bit used + { 6, 13, 9, -1 }, // 01001100 -> 13/9, 6 bit used + { 6, 13, 9, -1 }, // 01001101 -> 13/9, 6 bit used + { 6, 13, 9, -1 }, // 01001110 -> 13/9, 6 bit used + { 6, 13, 9, -1 }, // 01001111 -> 13/9, 6 bit used + { 6, 15, 5, -1 }, // 01010000 -> 15/5, 6 bit used + { 6, 15, 5, -1 }, // 01010001 -> 15/5, 6 bit used + { 6, 15, 5, -1 }, // 01010010 -> 15/5, 6 bit used + { 6, 15, 5, -1 }, // 01010011 -> 15/5, 6 bit used + { 6, 14, 7, -1 }, // 01010100 -> 14/7, 6 bit used + { 6, 14, 7, -1 }, // 01010101 -> 14/7, 6 bit used + { 6, 14, 7, -1 }, // 01010110 -> 14/7, 6 bit used + { 6, 14, 7, -1 }, // 01010111 -> 14/7, 6 bit used + { 6, 10, 12, -1 }, // 01011000 -> 10/12, 6 bit used + { 6, 10, 12, -1 }, // 01011001 -> 10/12, 6 bit used + { 6, 10, 12, -1 }, // 01011010 -> 10/12, 6 bit used + { 6, 10, 12, -1 }, // 01011011 -> 10/12, 6 bit used + { 6, 11, 11, -1 }, // 01011100 -> 11/11, 6 bit used + { 6, 11, 11, -1 }, // 01011101 -> 11/11, 6 bit used + { 6, 11, 11, -1 }, // 01011110 -> 11/11, 6 bit used + { 6, 11, 11, -1 }, // 01011111 -> 11/11, 6 bit used + { 6, 4, 15, -1 }, // 01100000 -> 4/15, 6 bit used + { 6, 4, 15, -1 }, // 01100001 -> 4/15, 6 bit used + { 6, 4, 15, -1 }, // 01100010 -> 4/15, 6 bit used + { 6, 4, 15, -1 }, // 01100011 -> 4/15, 6 bit used + { 6, 15, 4, -1 }, // 01100100 -> 15/4, 6 bit used + { 6, 15, 4, -1 }, // 01100101 -> 15/4, 6 bit used + { 6, 15, 4, -1 }, // 01100110 -> 15/4, 6 bit used + { 6, 15, 4, -1 }, // 01100111 -> 15/4, 6 bit used + { 7, 12, 10, -1 }, // 01101000 -> 12/10, 7 bit used + { 7, 12, 10, -1 }, // 01101001 -> 12/10, 7 bit used + { 7, 14, 6, -1 }, // 01101010 -> 14/6, 7 bit used + { 7, 14, 6, -1 }, // 01101011 -> 14/6, 7 bit used + { 6, 15, 3, -1 }, // 01101100 -> 15/3, 6 bit used + { 6, 15, 3, -1 }, // 01101101 -> 15/3, 6 bit used + { 6, 15, 3, -1 }, // 01101110 -> 15/3, 6 bit used + { 6, 15, 3, -1 }, // 01101111 -> 15/3, 6 bit used + { 5, 3, 15, -1 }, // 01110000 -> 3/15, 5 bit used + { 5, 3, 15, -1 }, // 01110001 -> 3/15, 5 bit used + { 5, 3, 15, -1 }, // 01110010 -> 3/15, 5 bit used + { 5, 3, 15, -1 }, // 01110011 -> 3/15, 5 bit used + { 5, 3, 15, -1 }, // 01110100 -> 3/15, 5 bit used + { 5, 3, 15, -1 }, // 01110101 -> 3/15, 5 bit used + { 5, 3, 15, -1 }, // 01110110 -> 3/15, 5 bit used + { 5, 3, 15, -1 }, // 01110111 -> 3/15, 5 bit used + { 6, 8, 13, -1 }, // 01111000 -> 8/13, 6 bit used + { 6, 8, 13, -1 }, // 01111001 -> 8/13, 6 bit used + { 6, 8, 13, -1 }, // 01111010 -> 8/13, 6 bit used + { 6, 8, 13, -1 }, // 01111011 -> 8/13, 6 bit used + { 6, 13, 8, -1 }, // 01111100 -> 13/8, 6 bit used + { 6, 13, 8, -1 }, // 01111101 -> 13/8, 6 bit used + { 6, 13, 8, -1 }, // 01111110 -> 13/8, 6 bit used + { 6, 13, 8, -1 }, // 01111111 -> 13/8, 6 bit used + { 5, 2, 15, -1 }, // 10000000 -> 2/15, 5 bit used + { 5, 2, 15, -1 }, // 10000001 -> 2/15, 5 bit used + { 5, 2, 15, -1 }, // 10000010 -> 2/15, 5 bit used + { 5, 2, 15, -1 }, // 10000011 -> 2/15, 5 bit used + { 5, 2, 15, -1 }, // 10000100 -> 2/15, 5 bit used + { 5, 2, 15, -1 }, // 10000101 -> 2/15, 5 bit used + { 5, 2, 15, -1 }, // 10000110 -> 2/15, 5 bit used + { 5, 2, 15, -1 }, // 10000111 -> 2/15, 5 bit used + { 5, 15, 2, -1 }, // 10001000 -> 15/2, 5 bit used + { 5, 15, 2, -1 }, // 10001001 -> 15/2, 5 bit used + { 5, 15, 2, -1 }, // 10001010 -> 15/2, 5 bit used + { 5, 15, 2, -1 }, // 10001011 -> 15/2, 5 bit used + { 5, 15, 2, -1 }, // 10001100 -> 15/2, 5 bit used + { 5, 15, 2, -1 }, // 10001101 -> 15/2, 5 bit used + { 5, 15, 2, -1 }, // 10001110 -> 15/2, 5 bit used + { 5, 15, 2, -1 }, // 10001111 -> 15/2, 5 bit used + { 6, 6, 14, -1 }, // 10010000 -> 6/14, 6 bit used + { 6, 6, 14, -1 }, // 10010001 -> 6/14, 6 bit used + { 6, 6, 14, -1 }, // 10010010 -> 6/14, 6 bit used + { 6, 6, 14, -1 }, // 10010011 -> 6/14, 6 bit used + { 6, 9, 12, -1 }, // 10010100 -> 9/12, 6 bit used + { 6, 9, 12, -1 }, // 10010101 -> 9/12, 6 bit used + { 6, 9, 12, -1 }, // 10010110 -> 9/12, 6 bit used + { 6, 9, 12, -1 }, // 10010111 -> 9/12, 6 bit used + { 5, 0, 15, -1 }, // 10011000 -> 0/15, 5 bit used + { 5, 0, 15, -1 }, // 10011001 -> 0/15, 5 bit used + { 5, 0, 15, -1 }, // 10011010 -> 0/15, 5 bit used + { 5, 0, 15, -1 }, // 10011011 -> 0/15, 5 bit used + { 5, 0, 15, -1 }, // 10011100 -> 0/15, 5 bit used + { 5, 0, 15, -1 }, // 10011101 -> 0/15, 5 bit used + { 5, 0, 15, -1 }, // 10011110 -> 0/15, 5 bit used + { 5, 0, 15, -1 }, // 10011111 -> 0/15, 5 bit used + { 6, 12, 9, -1 }, // 10100000 -> 12/9, 6 bit used + { 6, 12, 9, -1 }, // 10100001 -> 12/9, 6 bit used + { 6, 12, 9, -1 }, // 10100010 -> 12/9, 6 bit used + { 6, 12, 9, -1 }, // 10100011 -> 12/9, 6 bit used + { 6, 5, 14, -1 }, // 10100100 -> 5/14, 6 bit used + { 6, 5, 14, -1 }, // 10100101 -> 5/14, 6 bit used + { 6, 5, 14, -1 }, // 10100110 -> 5/14, 6 bit used + { 6, 5, 14, -1 }, // 10100111 -> 5/14, 6 bit used + { 5, 10, 11, -1 }, // 10101000 -> 10/11, 5 bit used + { 5, 10, 11, -1 }, // 10101001 -> 10/11, 5 bit used + { 5, 10, 11, -1 }, // 10101010 -> 10/11, 5 bit used + { 5, 10, 11, -1 }, // 10101011 -> 10/11, 5 bit used + { 5, 10, 11, -1 }, // 10101100 -> 10/11, 5 bit used + { 5, 10, 11, -1 }, // 10101101 -> 10/11, 5 bit used + { 5, 10, 11, -1 }, // 10101110 -> 10/11, 5 bit used + { 5, 10, 11, -1 }, // 10101111 -> 10/11, 5 bit used + { 6, 7, 13, -1 }, // 10110000 -> 7/13, 6 bit used + { 6, 7, 13, -1 }, // 10110001 -> 7/13, 6 bit used + { 6, 7, 13, -1 }, // 10110010 -> 7/13, 6 bit used + { 6, 7, 13, -1 }, // 10110011 -> 7/13, 6 bit used + { 6, 13, 7, -1 }, // 10110100 -> 13/7, 6 bit used + { 6, 13, 7, -1 }, // 10110101 -> 13/7, 6 bit used + { 6, 13, 7, -1 }, // 10110110 -> 13/7, 6 bit used + { 6, 13, 7, -1 }, // 10110111 -> 13/7, 6 bit used + { 5, 4, 14, -1 }, // 10111000 -> 4/14, 5 bit used + { 5, 4, 14, -1 }, // 10111001 -> 4/14, 5 bit used + { 5, 4, 14, -1 }, // 10111010 -> 4/14, 5 bit used + { 5, 4, 14, -1 }, // 10111011 -> 4/14, 5 bit used + { 5, 4, 14, -1 }, // 10111100 -> 4/14, 5 bit used + { 5, 4, 14, -1 }, // 10111101 -> 4/14, 5 bit used + { 5, 4, 14, -1 }, // 10111110 -> 4/14, 5 bit used + { 5, 4, 14, -1 }, // 10111111 -> 4/14, 5 bit used + { 6, 12, 8, -1 }, // 11000000 -> 12/8, 6 bit used + { 6, 12, 8, -1 }, // 11000001 -> 12/8, 6 bit used + { 6, 12, 8, -1 }, // 11000010 -> 12/8, 6 bit used + { 6, 12, 8, -1 }, // 11000011 -> 12/8, 6 bit used + { 6, 13, 6, -1 }, // 11000100 -> 13/6, 6 bit used + { 6, 13, 6, -1 }, // 11000101 -> 13/6, 6 bit used + { 6, 13, 6, -1 }, // 11000110 -> 13/6, 6 bit used + { 6, 13, 6, -1 }, // 11000111 -> 13/6, 6 bit used + { 5, 3, 14, -1 }, // 11001000 -> 3/14, 5 bit used + { 5, 3, 14, -1 }, // 11001001 -> 3/14, 5 bit used + { 5, 3, 14, -1 }, // 11001010 -> 3/14, 5 bit used + { 5, 3, 14, -1 }, // 11001011 -> 3/14, 5 bit used + { 5, 3, 14, -1 }, // 11001100 -> 3/14, 5 bit used + { 5, 3, 14, -1 }, // 11001101 -> 3/14, 5 bit used + { 5, 3, 14, -1 }, // 11001110 -> 3/14, 5 bit used + { 5, 3, 14, -1 }, // 11001111 -> 3/14, 5 bit used + { 5, 11, 9, -1 }, // 11010000 -> 11/9, 5 bit used + { 5, 11, 9, -1 }, // 11010001 -> 11/9, 5 bit used + { 5, 11, 9, -1 }, // 11010010 -> 11/9, 5 bit used + { 5, 11, 9, -1 }, // 11010011 -> 11/9, 5 bit used + { 5, 11, 9, -1 }, // 11010100 -> 11/9, 5 bit used + { 5, 11, 9, -1 }, // 11010101 -> 11/9, 5 bit used + { 5, 11, 9, -1 }, // 11010110 -> 11/9, 5 bit used + { 5, 11, 9, -1 }, // 11010111 -> 11/9, 5 bit used + { 6, 9, 11, -1 }, // 11011000 -> 9/11, 6 bit used + { 6, 9, 11, -1 }, // 11011001 -> 9/11, 6 bit used + { 6, 9, 11, -1 }, // 11011010 -> 9/11, 6 bit used + { 6, 9, 11, -1 }, // 11011011 -> 9/11, 6 bit used + { 6, 10, 10, -1 }, // 11011100 -> 10/10, 6 bit used + { 6, 10, 10, -1 }, // 11011101 -> 10/10, 6 bit used + { 6, 10, 10, -1 }, // 11011110 -> 10/10, 6 bit used + { 6, 10, 10, -1 }, // 11011111 -> 10/10, 6 bit used + { 4, 1, 15, -1 }, // 11100000 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11100001 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11100010 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11100011 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11100100 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11100101 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11100110 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11100111 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11101000 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11101001 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11101010 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11101011 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11101100 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11101101 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11101110 -> 1/15, 4 bit used + { 4, 1, 15, -1 }, // 11101111 -> 1/15, 4 bit used + { 4, 15, 1, -1 }, // 11110000 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11110001 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11110010 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11110011 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11110100 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11110101 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11110110 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11110111 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11111000 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11111001 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11111010 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11111011 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11111100 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11111101 -> 15/1, 4 bit used + { 4, 15, 1, -1 }, // 11111110 -> 15/1, 4 bit used + { 4, 15, 1, -1 } // 11111111 -> 15/1, 4 bit used +}; +// extension table 2, prefix 00000001 +static huffman_conv htab13_dec_ext2[ 32 ] = { + { 4, 15, 0, -1 }, // 00000 -> 15/0, 4 bit used + { 4, 15, 0, -1 }, // 00001 -> 15/0, 4 bit used + { 5, 11, 10, -1 }, // 00010 -> 11/10, 5 bit used + { 5, 14, 5, -1 }, // 00011 -> 14/5, 5 bit used + { 5, 14, 4, -1 }, // 00100 -> 14/4, 5 bit used + { 5, 8, 12, -1 }, // 00101 -> 8/12, 5 bit used + { 5, 6, 13, -1 }, // 00110 -> 6/13, 5 bit used + { 5, 14, 3, -1 }, // 00111 -> 14/3, 5 bit used + { 4, 14, 2, -1 }, // 01000 -> 14/2, 4 bit used + { 4, 14, 2, -1 }, // 01001 -> 14/2, 4 bit used + { 5, 2, 14, -1 }, // 01010 -> 2/14, 5 bit used + { 5, 0, 14, -1 }, // 01011 -> 0/14, 5 bit used + { 4, 1, 14, -1 }, // 01100 -> 1/14, 4 bit used + { 4, 1, 14, -1 }, // 01101 -> 1/14, 4 bit used + { 4, 14, 1, -1 }, // 01110 -> 14/1, 4 bit used + { 4, 14, 1, -1 }, // 01111 -> 14/1, 4 bit used + { 5, 14, 0, -1 }, // 10000 -> 14/0, 5 bit used + { 5, 5, 13, -1 }, // 10001 -> 5/13, 5 bit used + { 5, 13, 5, -1 }, // 10010 -> 13/5, 5 bit used + { 5, 7, 12, -1 }, // 10011 -> 7/12, 5 bit used + { 5, 12, 7, -1 }, // 10100 -> 12/7, 5 bit used + { 5, 4, 13, -1 }, // 10101 -> 4/13, 5 bit used + { 5, 8, 11, -1 }, // 10110 -> 8/11, 5 bit used + { 5, 11, 8, -1 }, // 10111 -> 11/8, 5 bit used + { 5, 13, 4, -1 }, // 11000 -> 13/4, 5 bit used + { 5, 9, 10, -1 }, // 11001 -> 9/10, 5 bit used + { 5, 10, 9, -1 }, // 11010 -> 10/9, 5 bit used + { 5, 6, 12, -1 }, // 11011 -> 6/12, 5 bit used + { 4, 12, 6, -1 }, // 11100 -> 12/6, 4 bit used + { 4, 12, 6, -1 }, // 11101 -> 12/6, 4 bit used + { 4, 3, 13, -1 }, // 11110 -> 3/13, 4 bit used + { 4, 3, 13, -1 } // 11111 -> 3/13, 4 bit used +}; +// extension table 3, prefix 00000010 +static huffman_conv htab13_dec_ext3[ 32 ] = { + { 5, 13, 3, -1 }, // 00000 -> 13/3, 5 bit used + { 5, 7, 11, -1 }, // 00001 -> 7/11, 5 bit used + { 4, 2, 13, -1 }, // 00010 -> 2/13, 4 bit used + { 4, 2, 13, -1 }, // 00011 -> 2/13, 4 bit used + { 4, 13, 2, -1 }, // 00100 -> 13/2, 4 bit used + { 4, 13, 2, -1 }, // 00101 -> 13/2, 4 bit used + { 4, 1, 13, -1 }, // 00110 -> 1/13, 4 bit used + { 4, 1, 13, -1 }, // 00111 -> 1/13, 4 bit used + { 4, 11, 7, -1 }, // 01000 -> 11/7, 4 bit used + { 4, 11, 7, -1 }, // 01001 -> 11/7, 4 bit used + { 5, 5, 12, -1 }, // 01010 -> 5/12, 5 bit used + { 5, 12, 5, -1 }, // 01011 -> 12/5, 5 bit used + { 5, 9, 9, -1 }, // 01100 -> 9/9, 5 bit used + { 5, 7, 10, -1 }, // 01101 -> 7/10, 5 bit used + { 4, 12, 3, -1 }, // 01110 -> 12/3, 4 bit used + { 4, 12, 3, -1 }, // 01111 -> 12/3, 4 bit used + { 5, 10, 7, -1 }, // 10000 -> 10/7, 5 bit used + { 5, 9, 7, -1 }, // 10001 -> 9/7, 5 bit used + { 4, 4, 11, -1 }, // 10010 -> 4/11, 4 bit used + { 4, 4, 11, -1 }, // 10011 -> 4/11, 4 bit used + { 3, 13, 1, -1 }, // 10100 -> 13/1, 3 bit used + { 3, 13, 1, -1 }, // 10101 -> 13/1, 3 bit used + { 3, 13, 1, -1 }, // 10110 -> 13/1, 3 bit used + { 3, 13, 1, -1 }, // 10111 -> 13/1, 3 bit used + { 4, 0, 13, -1 }, // 11000 -> 0/13, 4 bit used + { 4, 0, 13, -1 }, // 11001 -> 0/13, 4 bit used + { 4, 13, 0, -1 }, // 11010 -> 13/0, 4 bit used + { 4, 13, 0, -1 }, // 11011 -> 13/0, 4 bit used + { 4, 8, 10, -1 }, // 11100 -> 8/10, 4 bit used + { 4, 8, 10, -1 }, // 11101 -> 8/10, 4 bit used + { 4, 10, 8, -1 }, // 11110 -> 10/8, 4 bit used + { 4, 10, 8, -1 } // 11111 -> 10/8, 4 bit used +}; +// extension table 4, prefix 00000011 +static huffman_conv htab13_dec_ext4[ 16 ] = { + { 4, 4, 12, -1 }, // 0000 -> 4/12, 4 bit used + { 4, 12, 4, -1 }, // 0001 -> 12/4, 4 bit used + { 4, 6, 11, -1 }, // 0010 -> 6/11, 4 bit used + { 4, 11, 6, -1 }, // 0011 -> 11/6, 4 bit used + { 3, 3, 12, -1 }, // 0100 -> 3/12, 3 bit used + { 3, 3, 12, -1 }, // 0101 -> 3/12, 3 bit used + { 3, 2, 12, -1 }, // 0110 -> 2/12, 3 bit used + { 3, 2, 12, -1 }, // 0111 -> 2/12, 3 bit used + { 3, 12, 2, -1 }, // 1000 -> 12/2, 3 bit used + { 3, 12, 2, -1 }, // 1001 -> 12/2, 3 bit used + { 3, 5, 11, -1 }, // 1010 -> 5/11, 3 bit used + { 3, 5, 11, -1 }, // 1011 -> 5/11, 3 bit used + { 4, 11, 5, -1 }, // 1100 -> 11/5, 4 bit used + { 4, 8, 9, -1 }, // 1101 -> 8/9, 4 bit used + { 3, 1, 12, -1 }, // 1110 -> 1/12, 3 bit used + { 3, 1, 12, -1 } // 1111 -> 1/12, 3 bit used +}; +// extension table 5, prefix 00000100 +static huffman_conv htab13_dec_ext5[ 16 ] = { + { 3, 12, 1, -1 }, // 0000 -> 12/1, 3 bit used + { 3, 12, 1, -1 }, // 0001 -> 12/1, 3 bit used + { 4, 9, 8, -1 }, // 0010 -> 9/8, 4 bit used + { 4, 0, 12, -1 }, // 0011 -> 0/12, 4 bit used + { 3, 12, 0, -1 }, // 0100 -> 12/0, 3 bit used + { 3, 12, 0, -1 }, // 0101 -> 12/0, 3 bit used + { 4, 11, 4, -1 }, // 0110 -> 11/4, 4 bit used + { 4, 6, 10, -1 }, // 0111 -> 6/10, 4 bit used + { 4, 10, 6, -1 }, // 1000 -> 10/6, 4 bit used + { 4, 7, 9, -1 }, // 1001 -> 7/9, 4 bit used + { 3, 3, 11, -1 }, // 1010 -> 3/11, 3 bit used + { 3, 3, 11, -1 }, // 1011 -> 3/11, 3 bit used + { 3, 11, 3, -1 }, // 1100 -> 11/3, 3 bit used + { 3, 11, 3, -1 }, // 1101 -> 11/3, 3 bit used + { 4, 8, 8, -1 }, // 1110 -> 8/8, 4 bit used + { 4, 5, 10, -1 } // 1111 -> 5/10, 4 bit used +}; +// extension table 6, prefix 00000101 +static huffman_conv htab13_dec_ext6[ 16 ] = { + { 3, 2, 11, -1 }, // 0000 -> 2/11, 3 bit used + { 3, 2, 11, -1 }, // 0001 -> 2/11, 3 bit used + { 4, 10, 5, -1 }, // 0010 -> 10/5, 4 bit used + { 4, 6, 9, -1 }, // 0011 -> 6/9, 4 bit used + { 3, 10, 4, -1 }, // 0100 -> 10/4, 3 bit used + { 3, 10, 4, -1 }, // 0101 -> 10/4, 3 bit used + { 4, 7, 8, -1 }, // 0110 -> 7/8, 4 bit used + { 4, 8, 7, -1 }, // 0111 -> 8/7, 4 bit used + { 3, 9, 4, -1 }, // 1000 -> 9/4, 3 bit used + { 3, 9, 4, -1 }, // 1001 -> 9/4, 3 bit used + { 4, 7, 7, -1 }, // 1010 -> 7/7, 4 bit used + { 4, 7, 6, -1 }, // 1011 -> 7/6, 4 bit used + { 2, 11, 2, -1 }, // 1100 -> 11/2, 2 bit used + { 2, 11, 2, -1 }, // 1101 -> 11/2, 2 bit used + { 2, 11, 2, -1 }, // 1110 -> 11/2, 2 bit used + { 2, 11, 2, -1 } // 1111 -> 11/2, 2 bit used +}; +// extension table 7, prefix 00000110 +static huffman_conv htab13_dec_ext7[ 8 ] = { + { 2, 1, 11, -1 }, // 000 -> 1/11, 2 bit used + { 2, 1, 11, -1 }, // 001 -> 1/11, 2 bit used + { 2, 11, 1, -1 }, // 010 -> 11/1, 2 bit used + { 2, 11, 1, -1 }, // 011 -> 11/1, 2 bit used + { 3, 0, 11, -1 }, // 100 -> 0/11, 3 bit used + { 3, 11, 0, -1 }, // 101 -> 11/0, 3 bit used + { 3, 9, 6, -1 }, // 110 -> 9/6, 3 bit used + { 3, 4, 10, -1 } // 111 -> 4/10, 3 bit used +}; +// extension table 8, prefix 00000111 +static huffman_conv htab13_dec_ext8[ 8 ] = { + { 3, 3, 10, -1 }, // 000 -> 3/10, 3 bit used + { 3, 10, 3, -1 }, // 001 -> 10/3, 3 bit used + { 3, 5, 9, -1 }, // 010 -> 5/9, 3 bit used + { 3, 9, 5, -1 }, // 011 -> 9/5, 3 bit used + { 2, 2, 10, -1 }, // 100 -> 2/10, 2 bit used + { 2, 2, 10, -1 }, // 101 -> 2/10, 2 bit used + { 2, 10, 2, -1 }, // 110 -> 10/2, 2 bit used + { 2, 10, 2, -1 } // 111 -> 10/2, 2 bit used +}; +// extension table 9, prefix 00001000 +static huffman_conv htab13_dec_ext9[ 8 ] = { + { 2, 1, 10, -1 }, // 000 -> 1/10, 2 bit used + { 2, 1, 10, -1 }, // 001 -> 1/10, 2 bit used + { 2, 10, 1, -1 }, // 010 -> 10/1, 2 bit used + { 2, 10, 1, -1 }, // 011 -> 10/1, 2 bit used + { 3, 0, 10, -1 }, // 100 -> 0/10, 3 bit used + { 3, 6, 8, -1 }, // 101 -> 6/8, 3 bit used + { 2, 10, 0, -1 }, // 110 -> 10/0, 2 bit used + { 2, 10, 0, -1 } // 111 -> 10/0, 2 bit used +}; +// extension table 10, prefix 00001001 +static huffman_conv htab13_dec_ext10[ 8 ] = { + { 3, 8, 6, -1 }, // 000 -> 8/6, 3 bit used + { 3, 4, 9, -1 }, // 001 -> 4/9, 3 bit used + { 2, 9, 3, -1 }, // 010 -> 9/3, 2 bit used + { 2, 9, 3, -1 }, // 011 -> 9/3, 2 bit used + { 3, 3, 9, -1 }, // 100 -> 3/9, 3 bit used + { 3, 5, 8, -1 }, // 101 -> 5/8, 3 bit used + { 3, 8, 5, -1 }, // 110 -> 8/5, 3 bit used + { 3, 6, 7, -1 } // 111 -> 6/7, 3 bit used +}; +// extension table 11, prefix 00001010 +static huffman_conv htab13_dec_ext11[ 8 ] = { + { 2, 2, 9, -1 }, // 000 -> 2/9, 2 bit used + { 2, 2, 9, -1 }, // 001 -> 2/9, 2 bit used + { 2, 9, 2, -1 }, // 010 -> 9/2, 2 bit used + { 2, 9, 2, -1 }, // 011 -> 9/2, 2 bit used + { 3, 5, 7, -1 }, // 100 -> 5/7, 3 bit used + { 3, 7, 5, -1 }, // 101 -> 7/5, 3 bit used + { 2, 3, 8, -1 }, // 110 -> 3/8, 2 bit used + { 2, 3, 8, -1 } // 111 -> 3/8, 2 bit used +}; +// extension table 12, prefix 00001011 +static huffman_conv htab13_dec_ext12[ 8 ] = { + { 2, 8, 3, -1 }, // 000 -> 8/3, 2 bit used + { 2, 8, 3, -1 }, // 001 -> 8/3, 2 bit used + { 3, 6, 6, -1 }, // 010 -> 6/6, 3 bit used + { 3, 4, 7, -1 }, // 011 -> 4/7, 3 bit used + { 3, 7, 4, -1 }, // 100 -> 7/4, 3 bit used + { 3, 5, 6, -1 }, // 101 -> 5/6, 3 bit used + { 3, 6, 5, -1 }, // 110 -> 6/5, 3 bit used + { 3, 7, 3, -1 } // 111 -> 7/3, 3 bit used +}; +// extension table 13, prefix 00001100 +static huffman_conv htab13_dec_ext13[ 2 ] = { + { 1, 1, 9, -1 }, // 0 -> 1/9, 1 bit used + { 1, 9, 1, -1 } // 1 -> 9/1, 1 bit used +}; +// extension table 14, prefix 00001101 +static huffman_conv htab13_dec_ext14[ 4 ] = { + { 2, 0, 9, -1 }, // 00 -> 0/9, 2 bit used + { 2, 9, 0, -1 }, // 01 -> 9/0, 2 bit used + { 2, 4, 8, -1 }, // 10 -> 4/8, 2 bit used + { 2, 8, 4, -1 } // 11 -> 8/4, 2 bit used +}; +// extension table 15, prefix 00001110 +static huffman_conv htab13_dec_ext15[ 8 ] = { + { 2, 7, 2, -1 }, // 000 -> 7/2, 2 bit used + { 2, 7, 2, -1 }, // 001 -> 7/2, 2 bit used + { 3, 4, 6, -1 }, // 010 -> 4/6, 3 bit used + { 3, 6, 4, -1 }, // 011 -> 6/4, 3 bit used + { 1, 2, 8, -1 }, // 100 -> 2/8, 1 bit used + { 1, 2, 8, -1 }, // 101 -> 2/8, 1 bit used + { 1, 2, 8, -1 }, // 110 -> 2/8, 1 bit used + { 1, 2, 8, -1 } // 111 -> 2/8, 1 bit used +}; +// extension table 16, prefix 00001111 +static huffman_conv htab13_dec_ext16[ 2 ] = { + { 1, 8, 2, -1 }, // 0 -> 8/2, 1 bit used + { 1, 1, 8, -1 } // 1 -> 1/8, 1 bit used +}; +// extension table 17, prefix 00010000 +static huffman_conv htab13_dec_ext17[ 4 ] = { + { 2, 3, 7, -1 }, // 00 -> 3/7, 2 bit used + { 2, 2, 7, -1 }, // 01 -> 2/7, 2 bit used + { 1, 1, 7, -1 }, // 10 -> 1/7, 1 bit used + { 1, 1, 7, -1 } // 11 -> 1/7, 1 bit used +}; +// extension table 18, prefix 00010001 +static huffman_conv htab13_dec_ext18[ 4 ] = { + { 1, 7, 1, -1 }, // 00 -> 7/1, 1 bit used + { 1, 7, 1, -1 }, // 01 -> 7/1, 1 bit used + { 2, 5, 5, -1 }, // 10 -> 5/5, 2 bit used + { 2, 0, 7, -1 } // 11 -> 0/7, 2 bit used +}; +// extension table 19, prefix 00010010 +static huffman_conv htab13_dec_ext19[ 4 ] = { + { 2, 7, 0, -1 }, // 00 -> 7/0, 2 bit used + { 2, 3, 6, -1 }, // 01 -> 3/6, 2 bit used + { 2, 6, 3, -1 }, // 10 -> 6/3, 2 bit used + { 2, 4, 5, -1 } // 11 -> 4/5, 2 bit used +}; +// extension table 20, prefix 00010011 +static huffman_conv htab13_dec_ext20[ 4 ] = { + { 2, 5, 4, -1 }, // 00 -> 5/4, 2 bit used + { 2, 2, 6, -1 }, // 01 -> 2/6, 2 bit used + { 2, 6, 2, -1 }, // 10 -> 6/2, 2 bit used + { 2, 3, 5, -1 } // 11 -> 3/5, 2 bit used +}; +// extension table 21, prefix 00010101 +static huffman_conv htab13_dec_ext21[ 2 ] = { + { 1, 0, 8, -1 }, // 0 -> 0/8, 1 bit used + { 1, 8, 0, -1 } // 1 -> 8/0, 1 bit used +}; +// extension table 22, prefix 00010110 +static huffman_conv htab13_dec_ext22[ 2 ] = { + { 1, 1, 6, -1 }, // 0 -> 1/6, 1 bit used + { 1, 6, 1, -1 } // 1 -> 6/1, 1 bit used +}; +// extension table 23, prefix 00010111 +static huffman_conv htab13_dec_ext23[ 2 ] = { + { 1, 0, 6, -1 }, // 0 -> 0/6, 1 bit used + { 1, 6, 0, -1 } // 1 -> 6/0, 1 bit used +}; +// extension table 24, prefix 00011000 +static huffman_conv htab13_dec_ext24[ 4 ] = { + { 2, 5, 3, -1 }, // 00 -> 5/3, 2 bit used + { 2, 4, 4, -1 }, // 01 -> 4/4, 2 bit used + { 1, 2, 5, -1 }, // 10 -> 2/5, 1 bit used + { 1, 2, 5, -1 } // 11 -> 2/5, 1 bit used +}; +// extension table 25, prefix 00011001 +static huffman_conv htab13_dec_ext25[ 2 ] = { + { 1, 5, 2, -1 }, // 0 -> 5/2, 1 bit used + { 1, 0, 5, -1 } // 1 -> 0/5, 1 bit used +}; +// extension table 26, prefix 00011100 +static huffman_conv htab13_dec_ext26[ 2 ] = { + { 1, 3, 4, -1 }, // 0 -> 3/4, 1 bit used + { 1, 4, 3, -1 } // 1 -> 4/3, 1 bit used +}; +// extension table 27, prefix 00011101 +static huffman_conv htab13_dec_ext27[ 2 ] = { + { 1, 5, 0, -1 }, // 0 -> 5/0, 1 bit used + { 1, 2, 4, -1 } // 1 -> 2/4, 1 bit used +}; +// extension table 28, prefix 00011110 +static huffman_conv htab13_dec_ext28[ 2 ] = { + { 1, 4, 2, -1 }, // 0 -> 4/2, 1 bit used + { 1, 3, 3, -1 } // 1 -> 3/3, 1 bit used +}; +// extension table 29, prefix 0000000000000000 +static huffman_conv htab13_dec_ext29[ 8 ] = { + { 3, 15, 14, -1 }, // 000 -> 15/14, 3 bit used + { 3, 15, 12, -1 }, // 001 -> 15/12, 3 bit used + { 2, 15, 13, -1 }, // 010 -> 15/13, 2 bit used + { 2, 15, 13, -1 }, // 011 -> 15/13, 2 bit used + { 1, 14, 13, -1 }, // 100 -> 14/13, 1 bit used + { 1, 14, 13, -1 }, // 101 -> 14/13, 1 bit used + { 1, 14, 13, -1 }, // 110 -> 14/13, 1 bit used + { 1, 14, 13, -1 } // 111 -> 14/13, 1 bit used +}; +// extension table 30, prefix 0000000000001011 +static huffman_conv htab13_dec_ext30[ 2 ] = { + { 1, 10, 15, -1 }, // 0 -> 10/15, 1 bit used + { 1, 14, 9, -1 } // 1 -> 14/9, 1 bit used +}; +// big values conversion table #13, total size: 732, ext tables: 30 +static huffman_conv_set htab13_dec[ 31 ] = { + { htab13_dec_start, 8 }, // start table + { htab13_dec_ext1, 8 }, // ext table #1 + { htab13_dec_ext2, 5 }, // ext table #2 + { htab13_dec_ext3, 5 }, // ext table #3 + { htab13_dec_ext4, 4 }, // ext table #4 + { htab13_dec_ext5, 4 }, // ext table #5 + { htab13_dec_ext6, 4 }, // ext table #6 + { htab13_dec_ext7, 3 }, // ext table #7 + { htab13_dec_ext8, 3 }, // ext table #8 + { htab13_dec_ext9, 3 }, // ext table #9 + { htab13_dec_ext10, 3 }, // ext table #10 + { htab13_dec_ext11, 3 }, // ext table #11 + { htab13_dec_ext12, 3 }, // ext table #12 + { htab13_dec_ext13, 1 }, // ext table #13 + { htab13_dec_ext14, 2 }, // ext table #14 + { htab13_dec_ext15, 3 }, // ext table #15 + { htab13_dec_ext16, 1 }, // ext table #16 + { htab13_dec_ext17, 2 }, // ext table #17 + { htab13_dec_ext18, 2 }, // ext table #18 + { htab13_dec_ext19, 2 }, // ext table #19 + { htab13_dec_ext20, 2 }, // ext table #20 + { htab13_dec_ext21, 1 }, // ext table #21 + { htab13_dec_ext22, 1 }, // ext table #22 + { htab13_dec_ext23, 1 }, // ext table #23 + { htab13_dec_ext24, 2 }, // ext table #24 + { htab13_dec_ext25, 1 }, // ext table #25 + { htab13_dec_ext26, 1 }, // ext table #26 + { htab13_dec_ext27, 1 }, // ext table #27 + { htab13_dec_ext28, 1 }, // ext table #28 + { htab13_dec_ext29, 3 }, // ext table #29 + { htab13_dec_ext30, 1 } // ext table #30 +}; + +/* ----------------------------------------------- + big values conversion table 15 + ----------------------------------------------- */ +static huffman_conv htab15_dec_start[ 256 ] = { + { 8, -1, -1, 1 }, // 00000000 -> extension table #1 + { 8, -1, -1, 2 }, // 00000001 -> extension table #2 + { 8, -1, -1, 3 }, // 00000010 -> extension table #3 + { 8, -1, -1, 4 }, // 00000011 -> extension table #4 + { 8, -1, -1, 5 }, // 00000100 -> extension table #5 + { 8, -1, -1, 6 }, // 00000101 -> extension table #6 + { 8, -1, -1, 7 }, // 00000110 -> extension table #7 + { 8, -1, -1, 8 }, // 00000111 -> extension table #8 + { 8, -1, -1, 9 }, // 00001000 -> extension table #9 + { 8, -1, -1, 10 }, // 00001001 -> extension table #10 + { 8, -1, -1, 11 }, // 00001010 -> extension table #11 + { 8, -1, -1, 12 }, // 00001011 -> extension table #12 + { 8, -1, -1, 13 }, // 00001100 -> extension table #13 + { 8, -1, -1, 14 }, // 00001101 -> extension table #14 + { 8, -1, -1, 15 }, // 00001110 -> extension table #15 + { 8, -1, -1, 16 }, // 00001111 -> extension table #16 + { 8, -1, -1, 17 }, // 00010000 -> extension table #17 + { 8, -1, -1, 18 }, // 00010001 -> extension table #18 + { 8, -1, -1, 19 }, // 00010010 -> extension table #19 + { 8, -1, -1, 20 }, // 00010011 -> extension table #20 + { 8, -1, -1, 21 }, // 00010100 -> extension table #21 + { 8, -1, -1, 22 }, // 00010101 -> extension table #22 + { 8, -1, -1, 23 }, // 00010110 -> extension table #23 + { 8, -1, -1, 24 }, // 00010111 -> extension table #24 + { 8, -1, -1, 25 }, // 00011000 -> extension table #25 + { 8, -1, -1, 26 }, // 00011001 -> extension table #26 + { 8, -1, -1, 27 }, // 00011010 -> extension table #27 + { 8, -1, -1, 28 }, // 00011011 -> extension table #28 + { 8, -1, -1, 29 }, // 00011100 -> extension table #29 + { 8, -1, -1, 30 }, // 00011101 -> extension table #30 + { 8, -1, -1, 31 }, // 00011110 -> extension table #31 + { 8, -1, -1, 32 }, // 00011111 -> extension table #32 + { 8, -1, -1, 33 }, // 00100000 -> extension table #33 + { 8, -1, -1, 34 }, // 00100001 -> extension table #34 + { 8, 9, 1, -1 }, // 00100010 -> 9/1, 8 bit used + { 8, -1, -1, 35 }, // 00100011 -> extension table #35 + { 8, -1, -1, 36 }, // 00100100 -> extension table #36 + { 8, -1, -1, 37 }, // 00100101 -> extension table #37 + { 8, -1, -1, 38 }, // 00100110 -> extension table #38 + { 8, -1, -1, 39 }, // 00100111 -> extension table #39 + { 8, 2, 8, -1 }, // 00101000 -> 2/8, 8 bit used + { 8, 8, 2, -1 }, // 00101001 -> 8/2, 8 bit used + { 8, 1, 8, -1 }, // 00101010 -> 1/8, 8 bit used + { 8, 8, 1, -1 }, // 00101011 -> 8/1, 8 bit used + { 8, -1, -1, 40 }, // 00101100 -> extension table #40 + { 8, -1, -1, 41 }, // 00101101 -> extension table #41 + { 8, -1, -1, 42 }, // 00101110 -> extension table #42 + { 8, -1, -1, 43 }, // 00101111 -> extension table #43 + { 8, 2, 7, -1 }, // 00110000 -> 2/7, 8 bit used + { 8, 7, 2, -1 }, // 00110001 -> 7/2, 8 bit used + { 8, 6, 4, -1 }, // 00110010 -> 6/4, 8 bit used + { 8, 1, 7, -1 }, // 00110011 -> 1/7, 8 bit used + { 8, 5, 5, -1 }, // 00110100 -> 5/5, 8 bit used + { 8, 7, 1, -1 }, // 00110101 -> 7/1, 8 bit used + { 8, -1, -1, 44 }, // 00110110 -> extension table #44 + { 8, 3, 6, -1 }, // 00110111 -> 3/6, 8 bit used + { 8, 6, 3, -1 }, // 00111000 -> 6/3, 8 bit used + { 8, 4, 5, -1 }, // 00111001 -> 4/5, 8 bit used + { 8, 5, 4, -1 }, // 00111010 -> 5/4, 8 bit used + { 8, 2, 6, -1 }, // 00111011 -> 2/6, 8 bit used + { 8, 6, 2, -1 }, // 00111100 -> 6/2, 8 bit used + { 8, 1, 6, -1 }, // 00111101 -> 1/6, 8 bit used + { 8, -1, -1, 45 }, // 00111110 -> extension table #45 + { 8, 3, 5, -1 }, // 00111111 -> 3/5, 8 bit used + { 7, 6, 1, -1 }, // 01000000 -> 6/1, 7 bit used + { 7, 6, 1, -1 }, // 01000001 -> 6/1, 7 bit used + { 8, 5, 3, -1 }, // 01000010 -> 5/3, 8 bit used + { 8, 4, 4, -1 }, // 01000011 -> 4/4, 8 bit used + { 7, 2, 5, -1 }, // 01000100 -> 2/5, 7 bit used + { 7, 2, 5, -1 }, // 01000101 -> 2/5, 7 bit used + { 7, 5, 2, -1 }, // 01000110 -> 5/2, 7 bit used + { 7, 5, 2, -1 }, // 01000111 -> 5/2, 7 bit used + { 7, 1, 5, -1 }, // 01001000 -> 1/5, 7 bit used + { 7, 1, 5, -1 }, // 01001001 -> 1/5, 7 bit used + { 7, 5, 1, -1 }, // 01001010 -> 5/1, 7 bit used + { 7, 5, 1, -1 }, // 01001011 -> 5/1, 7 bit used + { 8, 0, 5, -1 }, // 01001100 -> 0/5, 8 bit used + { 8, 5, 0, -1 }, // 01001101 -> 5/0, 8 bit used + { 7, 3, 4, -1 }, // 01001110 -> 3/4, 7 bit used + { 7, 3, 4, -1 }, // 01001111 -> 3/4, 7 bit used + { 7, 4, 3, -1 }, // 01010000 -> 4/3, 7 bit used + { 7, 4, 3, -1 }, // 01010001 -> 4/3, 7 bit used + { 7, 2, 4, -1 }, // 01010010 -> 2/4, 7 bit used + { 7, 2, 4, -1 }, // 01010011 -> 2/4, 7 bit used + { 7, 4, 2, -1 }, // 01010100 -> 4/2, 7 bit used + { 7, 4, 2, -1 }, // 01010101 -> 4/2, 7 bit used + { 7, 3, 3, -1 }, // 01010110 -> 3/3, 7 bit used + { 7, 3, 3, -1 }, // 01010111 -> 3/3, 7 bit used + { 6, 4, 1, -1 }, // 01011000 -> 4/1, 6 bit used + { 6, 4, 1, -1 }, // 01011001 -> 4/1, 6 bit used + { 6, 4, 1, -1 }, // 01011010 -> 4/1, 6 bit used + { 6, 4, 1, -1 }, // 01011011 -> 4/1, 6 bit used + { 7, 1, 4, -1 }, // 01011100 -> 1/4, 7 bit used + { 7, 1, 4, -1 }, // 01011101 -> 1/4, 7 bit used + { 7, 0, 4, -1 }, // 01011110 -> 0/4, 7 bit used + { 7, 0, 4, -1 }, // 01011111 -> 0/4, 7 bit used + { 6, 2, 3, -1 }, // 01100000 -> 2/3, 6 bit used + { 6, 2, 3, -1 }, // 01100001 -> 2/3, 6 bit used + { 6, 2, 3, -1 }, // 01100010 -> 2/3, 6 bit used + { 6, 2, 3, -1 }, // 01100011 -> 2/3, 6 bit used + { 6, 3, 2, -1 }, // 01100100 -> 3/2, 6 bit used + { 6, 3, 2, -1 }, // 01100101 -> 3/2, 6 bit used + { 6, 3, 2, -1 }, // 01100110 -> 3/2, 6 bit used + { 6, 3, 2, -1 }, // 01100111 -> 3/2, 6 bit used + { 7, 4, 0, -1 }, // 01101000 -> 4/0, 7 bit used + { 7, 4, 0, -1 }, // 01101001 -> 4/0, 7 bit used + { 7, 0, 3, -1 }, // 01101010 -> 0/3, 7 bit used + { 7, 0, 3, -1 }, // 01101011 -> 0/3, 7 bit used + { 6, 1, 3, -1 }, // 01101100 -> 1/3, 6 bit used + { 6, 1, 3, -1 }, // 01101101 -> 1/3, 6 bit used + { 6, 1, 3, -1 }, // 01101110 -> 1/3, 6 bit used + { 6, 1, 3, -1 }, // 01101111 -> 1/3, 6 bit used + { 6, 3, 1, -1 }, // 01110000 -> 3/1, 6 bit used + { 6, 3, 1, -1 }, // 01110001 -> 3/1, 6 bit used + { 6, 3, 1, -1 }, // 01110010 -> 3/1, 6 bit used + { 6, 3, 1, -1 }, // 01110011 -> 3/1, 6 bit used + { 6, 3, 0, -1 }, // 01110100 -> 3/0, 6 bit used + { 6, 3, 0, -1 }, // 01110101 -> 3/0, 6 bit used + { 6, 3, 0, -1 }, // 01110110 -> 3/0, 6 bit used + { 6, 3, 0, -1 }, // 01110111 -> 3/0, 6 bit used + { 5, 2, 2, -1 }, // 01111000 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01111001 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01111010 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01111011 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01111100 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01111101 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01111110 -> 2/2, 5 bit used + { 5, 2, 2, -1 }, // 01111111 -> 2/2, 5 bit used + { 5, 1, 2, -1 }, // 10000000 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10000001 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10000010 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10000011 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10000100 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10000101 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10000110 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10000111 -> 1/2, 5 bit used + { 5, 2, 1, -1 }, // 10001000 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10001001 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10001010 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10001011 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10001100 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10001101 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10001110 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10001111 -> 2/1, 5 bit used + { 5, 0, 2, -1 }, // 10010000 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10010001 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10010010 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10010011 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10010100 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10010101 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10010110 -> 0/2, 5 bit used + { 5, 0, 2, -1 }, // 10010111 -> 0/2, 5 bit used + { 5, 2, 0, -1 }, // 10011000 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10011001 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10011010 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10011011 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10011100 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10011101 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10011110 -> 2/0, 5 bit used + { 5, 2, 0, -1 }, // 10011111 -> 2/0, 5 bit used + { 3, 1, 1, -1 }, // 10100000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10100111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10101111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10110111 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111000 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111001 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111010 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111011 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111100 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111101 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111110 -> 1/1, 3 bit used + { 3, 1, 1, -1 }, // 10111111 -> 1/1, 3 bit used + { 4, 0, 1, -1 }, // 11000000 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11000001 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11000010 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11000011 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11000100 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11000101 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11000110 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11000111 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11001000 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11001001 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11001010 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11001011 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11001100 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11001101 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11001110 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11001111 -> 0/1, 4 bit used + { 4, 1, 0, -1 }, // 11010000 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11010001 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11010010 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11010011 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11010100 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11010101 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11010110 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11010111 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11011000 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11011001 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11011010 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11011011 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11011100 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11011101 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11011110 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11011111 -> 1/0, 4 bit used + { 3, 0, 0, -1 }, // 11100000 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100001 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100010 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100011 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100100 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100101 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100110 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11100111 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101000 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101001 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101010 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101011 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101100 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101101 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101110 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11101111 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110000 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110001 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110010 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110011 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110100 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110101 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110110 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11110111 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111000 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111001 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111010 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111011 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111100 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111101 -> 0/0, 3 bit used + { 3, 0, 0, -1 }, // 11111110 -> 0/0, 3 bit used + { 3, 0, 0, -1 } // 11111111 -> 0/0, 3 bit used +}; +// extension table 1, prefix 00000000 +static huffman_conv htab15_dec_ext1[ 32 ] = { + { 5, 15, 15, -1 }, // 00000 -> 15/15, 5 bit used + { 5, 14, 15, -1 }, // 00001 -> 14/15, 5 bit used + { 5, 15, 14, -1 }, // 00010 -> 15/14, 5 bit used + { 5, 13, 15, -1 }, // 00011 -> 13/15, 5 bit used + { 4, 14, 14, -1 }, // 00100 -> 14/14, 4 bit used + { 4, 14, 14, -1 }, // 00101 -> 14/14, 4 bit used + { 5, 15, 13, -1 }, // 00110 -> 15/13, 5 bit used + { 5, 12, 15, -1 }, // 00111 -> 12/15, 5 bit used + { 5, 15, 12, -1 }, // 01000 -> 15/12, 5 bit used + { 5, 13, 14, -1 }, // 01001 -> 13/14, 5 bit used + { 5, 14, 13, -1 }, // 01010 -> 14/13, 5 bit used + { 5, 11, 15, -1 }, // 01011 -> 11/15, 5 bit used + { 4, 15, 11, -1 }, // 01100 -> 15/11, 4 bit used + { 4, 15, 11, -1 }, // 01101 -> 15/11, 4 bit used + { 5, 12, 14, -1 }, // 01110 -> 12/14, 5 bit used + { 5, 14, 12, -1 }, // 01111 -> 14/12, 5 bit used + { 4, 13, 13, -1 }, // 10000 -> 13/13, 4 bit used + { 4, 13, 13, -1 }, // 10001 -> 13/13, 4 bit used + { 4, 10, 15, -1 }, // 10010 -> 10/15, 4 bit used + { 4, 10, 15, -1 }, // 10011 -> 10/15, 4 bit used + { 4, 15, 10, -1 }, // 10100 -> 15/10, 4 bit used + { 4, 15, 10, -1 }, // 10101 -> 15/10, 4 bit used + { 4, 11, 14, -1 }, // 10110 -> 11/14, 4 bit used + { 4, 11, 14, -1 }, // 10111 -> 11/14, 4 bit used + { 4, 14, 11, -1 }, // 11000 -> 14/11, 4 bit used + { 4, 14, 11, -1 }, // 11001 -> 14/11, 4 bit used + { 4, 12, 13, -1 }, // 11010 -> 12/13, 4 bit used + { 4, 12, 13, -1 }, // 11011 -> 12/13, 4 bit used + { 4, 13, 12, -1 }, // 11100 -> 13/12, 4 bit used + { 4, 13, 12, -1 }, // 11101 -> 13/12, 4 bit used + { 4, 9, 15, -1 }, // 11110 -> 9/15, 4 bit used + { 4, 9, 15, -1 } // 11111 -> 9/15, 4 bit used +}; +// extension table 2, prefix 00000001 +static huffman_conv htab15_dec_ext2[ 32 ] = { + { 4, 15, 9, -1 }, // 00000 -> 15/9, 4 bit used + { 4, 15, 9, -1 }, // 00001 -> 15/9, 4 bit used + { 4, 14, 10, -1 }, // 00010 -> 14/10, 4 bit used + { 4, 14, 10, -1 }, // 00011 -> 14/10, 4 bit used + { 4, 11, 13, -1 }, // 00100 -> 11/13, 4 bit used + { 4, 11, 13, -1 }, // 00101 -> 11/13, 4 bit used + { 4, 13, 11, -1 }, // 00110 -> 13/11, 4 bit used + { 4, 13, 11, -1 }, // 00111 -> 13/11, 4 bit used + { 4, 8, 15, -1 }, // 01000 -> 8/15, 4 bit used + { 4, 8, 15, -1 }, // 01001 -> 8/15, 4 bit used + { 4, 15, 8, -1 }, // 01010 -> 15/8, 4 bit used + { 4, 15, 8, -1 }, // 01011 -> 15/8, 4 bit used + { 4, 12, 12, -1 }, // 01100 -> 12/12, 4 bit used + { 4, 12, 12, -1 }, // 01101 -> 12/12, 4 bit used + { 4, 9, 14, -1 }, // 01110 -> 9/14, 4 bit used + { 4, 9, 14, -1 }, // 01111 -> 9/14, 4 bit used + { 4, 14, 9, -1 }, // 10000 -> 14/9, 4 bit used + { 4, 14, 9, -1 }, // 10001 -> 14/9, 4 bit used + { 4, 7, 15, -1 }, // 10010 -> 7/15, 4 bit used + { 4, 7, 15, -1 }, // 10011 -> 7/15, 4 bit used + { 4, 15, 7, -1 }, // 10100 -> 15/7, 4 bit used + { 4, 15, 7, -1 }, // 10101 -> 15/7, 4 bit used + { 4, 10, 13, -1 }, // 10110 -> 10/13, 4 bit used + { 4, 10, 13, -1 }, // 10111 -> 10/13, 4 bit used + { 4, 13, 10, -1 }, // 11000 -> 13/10, 4 bit used + { 4, 13, 10, -1 }, // 11001 -> 13/10, 4 bit used + { 4, 11, 12, -1 }, // 11010 -> 11/12, 4 bit used + { 4, 11, 12, -1 }, // 11011 -> 11/12, 4 bit used + { 4, 6, 15, -1 }, // 11100 -> 6/15, 4 bit used + { 4, 6, 15, -1 }, // 11101 -> 6/15, 4 bit used + { 5, 10, 14, -1 }, // 11110 -> 10/14, 5 bit used + { 5, 0, 15, -1 } // 11111 -> 0/15, 5 bit used +}; +// extension table 3, prefix 00000010 +static huffman_conv htab15_dec_ext3[ 16 ] = { + { 3, 12, 11, -1 }, // 0000 -> 12/11, 3 bit used + { 3, 12, 11, -1 }, // 0001 -> 12/11, 3 bit used + { 3, 15, 6, -1 }, // 0010 -> 15/6, 3 bit used + { 3, 15, 6, -1 }, // 0011 -> 15/6, 3 bit used + { 4, 8, 14, -1 }, // 0100 -> 8/14, 4 bit used + { 4, 14, 8, -1 }, // 0101 -> 14/8, 4 bit used + { 4, 5, 15, -1 }, // 0110 -> 5/15, 4 bit used + { 4, 9, 13, -1 }, // 0111 -> 9/13, 4 bit used + { 3, 15, 5, -1 }, // 1000 -> 15/5, 3 bit used + { 3, 15, 5, -1 }, // 1001 -> 15/5, 3 bit used + { 3, 7, 14, -1 }, // 1010 -> 7/14, 3 bit used + { 3, 7, 14, -1 }, // 1011 -> 7/14, 3 bit used + { 3, 14, 7, -1 }, // 1100 -> 14/7, 3 bit used + { 3, 14, 7, -1 }, // 1101 -> 14/7, 3 bit used + { 3, 10, 12, -1 }, // 1110 -> 10/12, 3 bit used + { 3, 10, 12, -1 } // 1111 -> 10/12, 3 bit used +}; +// extension table 4, prefix 00000011 +static huffman_conv htab15_dec_ext4[ 16 ] = { + { 3, 12, 10, -1 }, // 0000 -> 12/10, 3 bit used + { 3, 12, 10, -1 }, // 0001 -> 12/10, 3 bit used + { 3, 11, 11, -1 }, // 0010 -> 11/11, 3 bit used + { 3, 11, 11, -1 }, // 0011 -> 11/11, 3 bit used + { 4, 13, 9, -1 }, // 0100 -> 13/9, 4 bit used + { 4, 8, 13, -1 }, // 0101 -> 8/13, 4 bit used + { 3, 4, 15, -1 }, // 0110 -> 4/15, 3 bit used + { 3, 4, 15, -1 }, // 0111 -> 4/15, 3 bit used + { 3, 15, 4, -1 }, // 1000 -> 15/4, 3 bit used + { 3, 15, 4, -1 }, // 1001 -> 15/4, 3 bit used + { 3, 3, 15, -1 }, // 1010 -> 3/15, 3 bit used + { 3, 3, 15, -1 }, // 1011 -> 3/15, 3 bit used + { 3, 15, 3, -1 }, // 1100 -> 15/3, 3 bit used + { 3, 15, 3, -1 }, // 1101 -> 15/3, 3 bit used + { 3, 13, 8, -1 }, // 1110 -> 13/8, 3 bit used + { 3, 13, 8, -1 } // 1111 -> 13/8, 3 bit used +}; +// extension table 5, prefix 00000100 +static huffman_conv htab15_dec_ext5[ 16 ] = { + { 3, 14, 6, -1 }, // 0000 -> 14/6, 3 bit used + { 3, 14, 6, -1 }, // 0001 -> 14/6, 3 bit used + { 3, 2, 15, -1 }, // 0010 -> 2/15, 3 bit used + { 3, 2, 15, -1 }, // 0011 -> 2/15, 3 bit used + { 3, 15, 2, -1 }, // 0100 -> 15/2, 3 bit used + { 3, 15, 2, -1 }, // 0101 -> 15/2, 3 bit used + { 4, 6, 14, -1 }, // 0110 -> 6/14, 4 bit used + { 4, 15, 0, -1 }, // 0111 -> 15/0, 4 bit used + { 3, 1, 15, -1 }, // 1000 -> 1/15, 3 bit used + { 3, 1, 15, -1 }, // 1001 -> 1/15, 3 bit used + { 3, 15, 1, -1 }, // 1010 -> 15/1, 3 bit used + { 3, 15, 1, -1 }, // 1011 -> 15/1, 3 bit used + { 3, 9, 12, -1 }, // 1100 -> 9/12, 3 bit used + { 3, 9, 12, -1 }, // 1101 -> 9/12, 3 bit used + { 3, 12, 9, -1 }, // 1110 -> 12/9, 3 bit used + { 3, 12, 9, -1 } // 1111 -> 12/9, 3 bit used +}; +// extension table 6, prefix 00000101 +static huffman_conv htab15_dec_ext6[ 8 ] = { + { 3, 5, 14, -1 }, // 000 -> 5/14, 3 bit used + { 3, 10, 11, -1 }, // 001 -> 10/11, 3 bit used + { 3, 11, 10, -1 }, // 010 -> 11/10, 3 bit used + { 3, 14, 5, -1 }, // 011 -> 14/5, 3 bit used + { 3, 7, 13, -1 }, // 100 -> 7/13, 3 bit used + { 3, 13, 7, -1 }, // 101 -> 13/7, 3 bit used + { 3, 4, 14, -1 }, // 110 -> 4/14, 3 bit used + { 3, 14, 4, -1 } // 111 -> 14/4, 3 bit used +}; +// extension table 7, prefix 00000110 +static huffman_conv htab15_dec_ext7[ 8 ] = { + { 3, 8, 12, -1 }, // 000 -> 8/12, 3 bit used + { 3, 12, 8, -1 }, // 001 -> 12/8, 3 bit used + { 3, 3, 14, -1 }, // 010 -> 3/14, 3 bit used + { 3, 6, 13, -1 }, // 011 -> 6/13, 3 bit used + { 3, 13, 6, -1 }, // 100 -> 13/6, 3 bit used + { 3, 14, 3, -1 }, // 101 -> 14/3, 3 bit used + { 3, 9, 11, -1 }, // 110 -> 9/11, 3 bit used + { 3, 11, 9, -1 } // 111 -> 11/9, 3 bit used +}; +// extension table 8, prefix 00000111 +static huffman_conv htab15_dec_ext8[ 16 ] = { + { 3, 2, 14, -1 }, // 0000 -> 2/14, 3 bit used + { 3, 2, 14, -1 }, // 0001 -> 2/14, 3 bit used + { 3, 10, 10, -1 }, // 0010 -> 10/10, 3 bit used + { 3, 10, 10, -1 }, // 0011 -> 10/10, 3 bit used + { 3, 14, 2, -1 }, // 0100 -> 14/2, 3 bit used + { 3, 14, 2, -1 }, // 0101 -> 14/2, 3 bit used + { 3, 1, 14, -1 }, // 0110 -> 1/14, 3 bit used + { 3, 1, 14, -1 }, // 0111 -> 1/14, 3 bit used + { 3, 14, 1, -1 }, // 1000 -> 14/1, 3 bit used + { 3, 14, 1, -1 }, // 1001 -> 14/1, 3 bit used + { 4, 0, 14, -1 }, // 1010 -> 0/14, 4 bit used + { 4, 14, 0, -1 }, // 1011 -> 14/0, 4 bit used + { 3, 5, 13, -1 }, // 1100 -> 5/13, 3 bit used + { 3, 5, 13, -1 }, // 1101 -> 5/13, 3 bit used + { 3, 13, 5, -1 }, // 1110 -> 13/5, 3 bit used + { 3, 13, 5, -1 } // 1111 -> 13/5, 3 bit used +}; +// extension table 9, prefix 00001000 +static huffman_conv htab15_dec_ext9[ 8 ] = { + { 3, 7, 12, -1 }, // 000 -> 7/12, 3 bit used + { 3, 12, 7, -1 }, // 001 -> 12/7, 3 bit used + { 3, 4, 13, -1 }, // 010 -> 4/13, 3 bit used + { 3, 8, 11, -1 }, // 011 -> 8/11, 3 bit used + { 2, 13, 4, -1 }, // 100 -> 13/4, 2 bit used + { 2, 13, 4, -1 }, // 101 -> 13/4, 2 bit used + { 3, 11, 8, -1 }, // 110 -> 11/8, 3 bit used + { 3, 9, 10, -1 } // 111 -> 9/10, 3 bit used +}; +// extension table 10, prefix 00001001 +static huffman_conv htab15_dec_ext10[ 8 ] = { + { 3, 10, 9, -1 }, // 000 -> 10/9, 3 bit used + { 3, 6, 12, -1 }, // 001 -> 6/12, 3 bit used + { 3, 12, 6, -1 }, // 010 -> 12/6, 3 bit used + { 3, 3, 13, -1 }, // 011 -> 3/13, 3 bit used + { 2, 13, 3, -1 }, // 100 -> 13/3, 2 bit used + { 2, 13, 3, -1 }, // 101 -> 13/3, 2 bit used + { 2, 13, 2, -1 }, // 110 -> 13/2, 2 bit used + { 2, 13, 2, -1 } // 111 -> 13/2, 2 bit used +}; +// extension table 11, prefix 00001010 +static huffman_conv htab15_dec_ext11[ 8 ] = { + { 3, 2, 13, -1 }, // 000 -> 2/13, 3 bit used + { 3, 0, 13, -1 }, // 001 -> 0/13, 3 bit used + { 2, 1, 13, -1 }, // 010 -> 1/13, 2 bit used + { 2, 1, 13, -1 }, // 011 -> 1/13, 2 bit used + { 2, 7, 11, -1 }, // 100 -> 7/11, 2 bit used + { 2, 7, 11, -1 }, // 101 -> 7/11, 2 bit used + { 2, 11, 7, -1 }, // 110 -> 11/7, 2 bit used + { 2, 11, 7, -1 } // 111 -> 11/7, 2 bit used +}; +// extension table 12, prefix 00001011 +static huffman_conv htab15_dec_ext12[ 8 ] = { + { 2, 13, 1, -1 }, // 000 -> 13/1, 2 bit used + { 2, 13, 1, -1 }, // 001 -> 13/1, 2 bit used + { 3, 5, 12, -1 }, // 010 -> 5/12, 3 bit used + { 3, 13, 0, -1 }, // 011 -> 13/0, 3 bit used + { 2, 12, 5, -1 }, // 100 -> 12/5, 2 bit used + { 2, 12, 5, -1 }, // 101 -> 12/5, 2 bit used + { 2, 8, 10, -1 }, // 110 -> 8/10, 2 bit used + { 2, 8, 10, -1 } // 111 -> 8/10, 2 bit used +}; +// extension table 13, prefix 00001100 +static huffman_conv htab15_dec_ext13[ 4 ] = { + { 2, 10, 8, -1 }, // 00 -> 10/8, 2 bit used + { 2, 4, 12, -1 }, // 01 -> 4/12, 2 bit used + { 2, 12, 4, -1 }, // 10 -> 12/4, 2 bit used + { 2, 6, 11, -1 } // 11 -> 6/11, 2 bit used +}; +// extension table 14, prefix 00001101 +static huffman_conv htab15_dec_ext14[ 8 ] = { + { 2, 11, 6, -1 }, // 000 -> 11/6, 2 bit used + { 2, 11, 6, -1 }, // 001 -> 11/6, 2 bit used + { 3, 9, 9, -1 }, // 010 -> 9/9, 3 bit used + { 3, 0, 12, -1 }, // 011 -> 0/12, 3 bit used + { 2, 3, 12, -1 }, // 100 -> 3/12, 2 bit used + { 2, 3, 12, -1 }, // 101 -> 3/12, 2 bit used + { 2, 12, 3, -1 }, // 110 -> 12/3, 2 bit used + { 2, 12, 3, -1 } // 111 -> 12/3, 2 bit used +}; +// extension table 15, prefix 00001110 +static huffman_conv htab15_dec_ext15[ 8 ] = { + { 2, 7, 10, -1 }, // 000 -> 7/10, 2 bit used + { 2, 7, 10, -1 }, // 001 -> 7/10, 2 bit used + { 2, 10, 7, -1 }, // 010 -> 10/7, 2 bit used + { 2, 10, 7, -1 }, // 011 -> 10/7, 2 bit used + { 2, 10, 6, -1 }, // 100 -> 10/6, 2 bit used + { 2, 10, 6, -1 }, // 101 -> 10/6, 2 bit used + { 3, 12, 0, -1 }, // 110 -> 12/0, 3 bit used + { 3, 0, 11, -1 } // 111 -> 0/11, 3 bit used +}; +// extension table 16, prefix 00001111 +static huffman_conv htab15_dec_ext16[ 4 ] = { + { 1, 12, 2, -1 }, // 00 -> 12/2, 1 bit used + { 1, 12, 2, -1 }, // 01 -> 12/2, 1 bit used + { 2, 2, 12, -1 }, // 10 -> 2/12, 2 bit used + { 2, 5, 11, -1 } // 11 -> 5/11, 2 bit used +}; +// extension table 17, prefix 00010000 +static huffman_conv htab15_dec_ext17[ 4 ] = { + { 2, 11, 5, -1 }, // 00 -> 11/5, 2 bit used + { 2, 1, 12, -1 }, // 01 -> 1/12, 2 bit used + { 2, 8, 9, -1 }, // 10 -> 8/9, 2 bit used + { 2, 9, 8, -1 } // 11 -> 9/8, 2 bit used +}; +// extension table 18, prefix 00010001 +static huffman_conv htab15_dec_ext18[ 4 ] = { + { 2, 12, 1, -1 }, // 00 -> 12/1, 2 bit used + { 2, 4, 11, -1 }, // 01 -> 4/11, 2 bit used + { 2, 11, 4, -1 }, // 10 -> 11/4, 2 bit used + { 2, 6, 10, -1 } // 11 -> 6/10, 2 bit used +}; +// extension table 19, prefix 00010010 +static huffman_conv htab15_dec_ext19[ 4 ] = { + { 2, 3, 11, -1 }, // 00 -> 3/11, 2 bit used + { 2, 7, 9, -1 }, // 01 -> 7/9, 2 bit used + { 1, 11, 3, -1 }, // 10 -> 11/3, 1 bit used + { 1, 11, 3, -1 } // 11 -> 11/3, 1 bit used +}; +// extension table 20, prefix 00010011 +static huffman_conv htab15_dec_ext20[ 4 ] = { + { 2, 9, 7, -1 }, // 00 -> 9/7, 2 bit used + { 2, 8, 8, -1 }, // 01 -> 8/8, 2 bit used + { 2, 2, 11, -1 }, // 10 -> 2/11, 2 bit used + { 2, 5, 10, -1 } // 11 -> 5/10, 2 bit used +}; +// extension table 21, prefix 00010100 +static huffman_conv htab15_dec_ext21[ 4 ] = { + { 1, 11, 2, -1 }, // 00 -> 11/2, 1 bit used + { 1, 11, 2, -1 }, // 01 -> 11/2, 1 bit used + { 2, 10, 5, -1 }, // 10 -> 10/5, 2 bit used + { 2, 1, 11, -1 } // 11 -> 1/11, 2 bit used +}; +// extension table 22, prefix 00010101 +static huffman_conv htab15_dec_ext22[ 4 ] = { + { 1, 11, 1, -1 }, // 00 -> 11/1, 1 bit used + { 1, 11, 1, -1 }, // 01 -> 11/1, 1 bit used + { 2, 11, 0, -1 }, // 10 -> 11/0, 2 bit used + { 2, 6, 9, -1 } // 11 -> 6/9, 2 bit used +}; +// extension table 23, prefix 00010110 +static huffman_conv htab15_dec_ext23[ 4 ] = { + { 2, 9, 6, -1 }, // 00 -> 9/6, 2 bit used + { 2, 4, 10, -1 }, // 01 -> 4/10, 2 bit used + { 2, 10, 4, -1 }, // 10 -> 10/4, 2 bit used + { 2, 7, 8, -1 } // 11 -> 7/8, 2 bit used +}; +// extension table 24, prefix 00010111 +static huffman_conv htab15_dec_ext24[ 4 ] = { + { 2, 8, 7, -1 }, // 00 -> 8/7, 2 bit used + { 2, 3, 10, -1 }, // 01 -> 3/10, 2 bit used + { 1, 10, 3, -1 }, // 10 -> 10/3, 1 bit used + { 1, 10, 3, -1 } // 11 -> 10/3, 1 bit used +}; +// extension table 25, prefix 00011000 +static huffman_conv htab15_dec_ext25[ 2 ] = { + { 1, 5, 9, -1 }, // 0 -> 5/9, 1 bit used + { 1, 9, 5, -1 } // 1 -> 9/5, 1 bit used +}; +// extension table 26, prefix 00011001 +static huffman_conv htab15_dec_ext26[ 2 ] = { + { 1, 2, 10, -1 }, // 0 -> 2/10, 1 bit used + { 1, 10, 2, -1 } // 1 -> 10/2, 1 bit used +}; +// extension table 27, prefix 00011010 +static huffman_conv htab15_dec_ext27[ 2 ] = { + { 1, 1, 10, -1 }, // 0 -> 1/10, 1 bit used + { 1, 10, 1, -1 } // 1 -> 10/1, 1 bit used +}; +// extension table 28, prefix 00011011 +static huffman_conv htab15_dec_ext28[ 4 ] = { + { 2, 0, 10, -1 }, // 00 -> 0/10, 2 bit used + { 2, 10, 0, -1 }, // 01 -> 10/0, 2 bit used + { 1, 6, 8, -1 }, // 10 -> 6/8, 1 bit used + { 1, 6, 8, -1 } // 11 -> 6/8, 1 bit used +}; +// extension table 29, prefix 00011100 +static huffman_conv htab15_dec_ext29[ 2 ] = { + { 1, 8, 6, -1 }, // 0 -> 8/6, 1 bit used + { 1, 4, 9, -1 } // 1 -> 4/9, 1 bit used +}; +// extension table 30, prefix 00011101 +static huffman_conv htab15_dec_ext30[ 2 ] = { + { 1, 9, 4, -1 }, // 0 -> 9/4, 1 bit used + { 1, 3, 9, -1 } // 1 -> 3/9, 1 bit used +}; +// extension table 31, prefix 00011110 +static huffman_conv htab15_dec_ext31[ 4 ] = { + { 1, 9, 3, -1 }, // 00 -> 9/3, 1 bit used + { 1, 9, 3, -1 }, // 01 -> 9/3, 1 bit used + { 2, 7, 7, -1 }, // 10 -> 7/7, 2 bit used + { 2, 0, 9, -1 } // 11 -> 0/9, 2 bit used +}; +// extension table 32, prefix 00011111 +static huffman_conv htab15_dec_ext32[ 2 ] = { + { 1, 5, 8, -1 }, // 0 -> 5/8, 1 bit used + { 1, 8, 5, -1 } // 1 -> 8/5, 1 bit used +}; +// extension table 33, prefix 00100000 +static huffman_conv htab15_dec_ext33[ 2 ] = { + { 1, 2, 9, -1 }, // 0 -> 2/9, 1 bit used + { 1, 6, 7, -1 } // 1 -> 6/7, 1 bit used +}; +// extension table 34, prefix 00100001 +static huffman_conv htab15_dec_ext34[ 2 ] = { + { 1, 7, 6, -1 }, // 0 -> 7/6, 1 bit used + { 1, 9, 2, -1 } // 1 -> 9/2, 1 bit used +}; +// extension table 35, prefix 00100011 +static huffman_conv htab15_dec_ext35[ 2 ] = { + { 1, 1, 9, -1 }, // 0 -> 1/9, 1 bit used + { 1, 9, 0, -1 } // 1 -> 9/0, 1 bit used +}; +// extension table 36, prefix 00100100 +static huffman_conv htab15_dec_ext36[ 2 ] = { + { 1, 4, 8, -1 }, // 0 -> 4/8, 1 bit used + { 1, 8, 4, -1 } // 1 -> 8/4, 1 bit used +}; +// extension table 37, prefix 00100101 +static huffman_conv htab15_dec_ext37[ 2 ] = { + { 1, 5, 7, -1 }, // 0 -> 5/7, 1 bit used + { 1, 7, 5, -1 } // 1 -> 7/5, 1 bit used +}; +// extension table 38, prefix 00100110 +static huffman_conv htab15_dec_ext38[ 2 ] = { + { 1, 3, 8, -1 }, // 0 -> 3/8, 1 bit used + { 1, 8, 3, -1 } // 1 -> 8/3, 1 bit used +}; +// extension table 39, prefix 00100111 +static huffman_conv htab15_dec_ext39[ 2 ] = { + { 1, 6, 6, -1 }, // 0 -> 6/6, 1 bit used + { 1, 4, 7, -1 } // 1 -> 4/7, 1 bit used +}; +// extension table 40, prefix 00101100 +static huffman_conv htab15_dec_ext40[ 2 ] = { + { 1, 7, 4, -1 }, // 0 -> 7/4, 1 bit used + { 1, 0, 8, -1 } // 1 -> 0/8, 1 bit used +}; +// extension table 41, prefix 00101101 +static huffman_conv htab15_dec_ext41[ 2 ] = { + { 1, 8, 0, -1 }, // 0 -> 8/0, 1 bit used + { 1, 5, 6, -1 } // 1 -> 5/6, 1 bit used +}; +// extension table 42, prefix 00101110 +static huffman_conv htab15_dec_ext42[ 2 ] = { + { 1, 6, 5, -1 }, // 0 -> 6/5, 1 bit used + { 1, 3, 7, -1 } // 1 -> 3/7, 1 bit used +}; +// extension table 43, prefix 00101111 +static huffman_conv htab15_dec_ext43[ 2 ] = { + { 1, 7, 3, -1 }, // 0 -> 7/3, 1 bit used + { 1, 4, 6, -1 } // 1 -> 4/6, 1 bit used +}; +// extension table 44, prefix 00110110 +static huffman_conv htab15_dec_ext44[ 2 ] = { + { 1, 0, 7, -1 }, // 0 -> 0/7, 1 bit used + { 1, 7, 0, -1 } // 1 -> 7/0, 1 bit used +}; +// extension table 45, prefix 00111110 +static huffman_conv htab15_dec_ext45[ 2 ] = { + { 1, 0, 6, -1 }, // 0 -> 0/6, 1 bit used + { 1, 6, 0, -1 } // 1 -> 6/0, 1 bit used +}; +// big values conversion table #15, total size: 534, ext tables: 45 +static huffman_conv_set htab15_dec[ 46 ] = { + { htab15_dec_start, 8 }, // start table + { htab15_dec_ext1, 5 }, // ext table #1 + { htab15_dec_ext2, 5 }, // ext table #2 + { htab15_dec_ext3, 4 }, // ext table #3 + { htab15_dec_ext4, 4 }, // ext table #4 + { htab15_dec_ext5, 4 }, // ext table #5 + { htab15_dec_ext6, 3 }, // ext table #6 + { htab15_dec_ext7, 3 }, // ext table #7 + { htab15_dec_ext8, 4 }, // ext table #8 + { htab15_dec_ext9, 3 }, // ext table #9 + { htab15_dec_ext10, 3 }, // ext table #10 + { htab15_dec_ext11, 3 }, // ext table #11 + { htab15_dec_ext12, 3 }, // ext table #12 + { htab15_dec_ext13, 2 }, // ext table #13 + { htab15_dec_ext14, 3 }, // ext table #14 + { htab15_dec_ext15, 3 }, // ext table #15 + { htab15_dec_ext16, 2 }, // ext table #16 + { htab15_dec_ext17, 2 }, // ext table #17 + { htab15_dec_ext18, 2 }, // ext table #18 + { htab15_dec_ext19, 2 }, // ext table #19 + { htab15_dec_ext20, 2 }, // ext table #20 + { htab15_dec_ext21, 2 }, // ext table #21 + { htab15_dec_ext22, 2 }, // ext table #22 + { htab15_dec_ext23, 2 }, // ext table #23 + { htab15_dec_ext24, 2 }, // ext table #24 + { htab15_dec_ext25, 1 }, // ext table #25 + { htab15_dec_ext26, 1 }, // ext table #26 + { htab15_dec_ext27, 1 }, // ext table #27 + { htab15_dec_ext28, 2 }, // ext table #28 + { htab15_dec_ext29, 1 }, // ext table #29 + { htab15_dec_ext30, 1 }, // ext table #30 + { htab15_dec_ext31, 2 }, // ext table #31 + { htab15_dec_ext32, 1 }, // ext table #32 + { htab15_dec_ext33, 1 }, // ext table #33 + { htab15_dec_ext34, 1 }, // ext table #34 + { htab15_dec_ext35, 1 }, // ext table #35 + { htab15_dec_ext36, 1 }, // ext table #36 + { htab15_dec_ext37, 1 }, // ext table #37 + { htab15_dec_ext38, 1 }, // ext table #38 + { htab15_dec_ext39, 1 }, // ext table #39 + { htab15_dec_ext40, 1 }, // ext table #40 + { htab15_dec_ext41, 1 }, // ext table #41 + { htab15_dec_ext42, 1 }, // ext table #42 + { htab15_dec_ext43, 1 }, // ext table #43 + { htab15_dec_ext44, 1 }, // ext table #44 + { htab15_dec_ext45, 1 } // ext table #45 +}; + +/* ----------------------------------------------- + big values conversion table 16 + ----------------------------------------------- */ +static huffman_conv htab16_dec_start[ 256 ] = { + { 8, -1, -1, 1 }, // 00000000 -> extension table #1 + { 8, -1, -1, 2 }, // 00000001 -> extension table #2 + { 8, -1, -1, 3 }, // 00000010 -> extension table #3 + { 8, 15, 15, -1 }, // 00000011 -> 15/15, 8 bit used + { 8, -1, -1, 4 }, // 00000100 -> extension table #4 + { 8, -1, -1, 5 }, // 00000101 -> extension table #5 + { 8, -1, -1, 6 }, // 00000110 -> extension table #6 + { 8, 15, 2, -1 }, // 00000111 -> 15/2, 8 bit used + { 8, -1, -1, 7 }, // 00001000 -> extension table #7 + { 8, 1, 15, -1 }, // 00001001 -> 1/15, 8 bit used + { 8, 15, 1, -1 }, // 00001010 -> 15/1, 8 bit used + { 8, -1, -1, 8 }, // 00001011 -> extension table #8 + { 8, -1, -1, 9 }, // 00001100 -> extension table #9 + { 8, -1, -1, 10 }, // 00001101 -> extension table #10 + { 8, -1, -1, 11 }, // 00001110 -> extension table #11 + { 8, -1, -1, 12 }, // 00001111 -> extension table #12 + { 8, -1, -1, 13 }, // 00010000 -> extension table #13 + { 8, -1, -1, 14 }, // 00010001 -> extension table #14 + { 8, -1, -1, 15 }, // 00010010 -> extension table #15 + { 8, -1, -1, 16 }, // 00010011 -> extension table #16 + { 8, -1, -1, 17 }, // 00010100 -> extension table #17 + { 8, -1, -1, 18 }, // 00010101 -> extension table #18 + { 8, -1, -1, 19 }, // 00010110 -> extension table #19 + { 8, -1, -1, 20 }, // 00010111 -> extension table #20 + { 8, -1, -1, 21 }, // 00011000 -> extension table #21 + { 8, -1, -1, 22 }, // 00011001 -> extension table #22 + { 8, -1, -1, 23 }, // 00011010 -> extension table #23 + { 8, -1, -1, 24 }, // 00011011 -> extension table #24 + { 8, -1, -1, 25 }, // 00011100 -> extension table #25 + { 8, -1, -1, 26 }, // 00011101 -> extension table #26 + { 8, 5, 1, -1 }, // 00011110 -> 5/1, 8 bit used + { 8, -1, -1, 27 }, // 00011111 -> extension table #27 + { 8, -1, -1, 28 }, // 00100000 -> extension table #28 + { 8, -1, -1, 29 }, // 00100001 -> extension table #29 + { 8, -1, -1, 30 }, // 00100010 -> extension table #30 + { 8, 1, 4, -1 }, // 00100011 -> 1/4, 8 bit used + { 8, 4, 1, -1 }, // 00100100 -> 4/1, 8 bit used + { 8, -1, -1, 31 }, // 00100101 -> extension table #31 + { 8, 2, 3, -1 }, // 00100110 -> 2/3, 8 bit used + { 8, 3, 2, -1 }, // 00100111 -> 3/2, 8 bit used + { 7, 1, 3, -1 }, // 00101000 -> 1/3, 7 bit used + { 7, 1, 3, -1 }, // 00101001 -> 1/3, 7 bit used + { 7, 3, 1, -1 }, // 00101010 -> 3/1, 7 bit used + { 7, 3, 1, -1 }, // 00101011 -> 3/1, 7 bit used + { 8, 0, 3, -1 }, // 00101100 -> 0/3, 8 bit used + { 8, 3, 0, -1 }, // 00101101 -> 3/0, 8 bit used + { 7, 2, 2, -1 }, // 00101110 -> 2/2, 7 bit used + { 7, 2, 2, -1 }, // 00101111 -> 2/2, 7 bit used + { 6, 1, 2, -1 }, // 00110000 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00110001 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00110010 -> 1/2, 6 bit used + { 6, 1, 2, -1 }, // 00110011 -> 1/2, 6 bit used + { 6, 2, 1, -1 }, // 00110100 -> 2/1, 6 bit used + { 6, 2, 1, -1 }, // 00110101 -> 2/1, 6 bit used + { 6, 2, 1, -1 }, // 00110110 -> 2/1, 6 bit used + { 6, 2, 1, -1 }, // 00110111 -> 2/1, 6 bit used + { 6, 0, 2, -1 }, // 00111000 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00111001 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00111010 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 00111011 -> 0/2, 6 bit used + { 6, 2, 0, -1 }, // 00111100 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00111101 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00111110 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 00111111 -> 2/0, 6 bit used + { 4, 1, 1, -1 }, // 01000000 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000001 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000010 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000011 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000100 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000101 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000110 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01000111 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001000 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001001 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001010 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001011 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001100 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001101 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001110 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 01001111 -> 1/1, 4 bit used + { 4, 0, 1, -1 }, // 01010000 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010001 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010010 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010011 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010100 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010101 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010110 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01010111 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011000 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011001 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011010 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011011 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011100 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011101 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011110 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 01011111 -> 0/1, 4 bit used + { 3, 1, 0, -1 }, // 01100000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01100111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01101111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01110111 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111000 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111001 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111010 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111011 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111100 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111101 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111110 -> 1/0, 3 bit used + { 3, 1, 0, -1 }, // 01111111 -> 1/0, 3 bit used + { 1, 0, 0, -1 }, // 10000000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10000111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10001111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10010111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10011111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10100111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10101111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10110111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 10111111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11000111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11001111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11010111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11011111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11100111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11101111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110110 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11110111 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111000 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111001 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111010 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111011 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111100 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111101 -> 0/0, 1 bit used + { 1, 0, 0, -1 }, // 11111110 -> 0/0, 1 bit used + { 1, 0, 0, -1 } // 11111111 -> 0/0, 1 bit used +}; +// extension table 1, prefix 00000000 +static huffman_conv htab16_dec_ext1[ 8 ] = { + { 3, 14, 15, -1 }, // 000 -> 14/15, 3 bit used + { 3, 15, 14, -1 }, // 001 -> 15/14, 3 bit used + { 3, 13, 15, -1 }, // 010 -> 13/15, 3 bit used + { 3, 15, 13, -1 }, // 011 -> 15/13, 3 bit used + { 3, 12, 15, -1 }, // 100 -> 12/15, 3 bit used + { 3, 15, 12, -1 }, // 101 -> 15/12, 3 bit used + { 3, 11, 15, -1 }, // 110 -> 11/15, 3 bit used + { 3, 15, 11, -1 } // 111 -> 15/11, 3 bit used +}; +// extension table 2, prefix 00000001 +static huffman_conv htab16_dec_ext2[ 8 ] = { + { 2, 10, 15, -1 }, // 000 -> 10/15, 2 bit used + { 2, 10, 15, -1 }, // 001 -> 10/15, 2 bit used + { 3, 15, 10, -1 }, // 010 -> 15/10, 3 bit used + { 3, 9, 15, -1 }, // 011 -> 9/15, 3 bit used + { 3, 15, 9, -1 }, // 100 -> 15/9, 3 bit used + { 3, 15, 8, -1 }, // 101 -> 15/8, 3 bit used + { 2, 8, 15, -1 }, // 110 -> 8/15, 2 bit used + { 2, 8, 15, -1 } // 111 -> 8/15, 2 bit used +}; +// extension table 3, prefix 00000010 +static huffman_conv htab16_dec_ext3[ 4 ] = { + { 2, 7, 15, -1 }, // 00 -> 7/15, 2 bit used + { 2, 15, 7, -1 }, // 01 -> 15/7, 2 bit used + { 2, 6, 15, -1 }, // 10 -> 6/15, 2 bit used + { 2, 15, 6, -1 } // 11 -> 15/6, 2 bit used +}; +// extension table 4, prefix 00000100 +static huffman_conv htab16_dec_ext4[ 4 ] = { + { 2, 5, 15, -1 }, // 00 -> 5/15, 2 bit used + { 2, 15, 5, -1 }, // 01 -> 15/5, 2 bit used + { 1, 4, 15, -1 }, // 10 -> 4/15, 1 bit used + { 1, 4, 15, -1 } // 11 -> 4/15, 1 bit used +}; +// extension table 5, prefix 00000101 +static huffman_conv htab16_dec_ext5[ 2 ] = { + { 1, 15, 4, -1 }, // 0 -> 15/4, 1 bit used + { 1, 15, 3, -1 } // 1 -> 15/3, 1 bit used +}; +// extension table 6, prefix 00000110 +static huffman_conv htab16_dec_ext6[ 256 ] = { + { 1, 15, 0, -1 }, // 00000000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00000001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00000010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00000011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00000100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00000101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00000110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00000111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00001000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00001001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00001010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00001011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00001100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00001101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00001110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00001111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00010000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00010001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00010010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00010011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00010100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00010101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00010110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00010111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00011000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00011001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00011010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00011011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00011100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00011101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00011110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00011111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00100000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00100001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00100010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00100011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00100100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00100101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00100110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00100111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00101000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00101001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00101010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00101011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00101100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00101101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00101110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00101111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00110000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00110001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00110010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00110011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00110100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00110101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00110110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00110111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00111000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00111001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00111010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00111011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00111100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00111101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00111110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 00111111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01000000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01000001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01000010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01000011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01000100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01000101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01000110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01000111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01001000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01001001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01001010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01001011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01001100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01001101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01001110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01001111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01010000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01010001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01010010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01010011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01010100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01010101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01010110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01010111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01011000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01011001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01011010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01011011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01011100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01011101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01011110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01011111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01100000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01100001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01100010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01100011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01100100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01100101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01100110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01100111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01101000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01101001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01101010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01101011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01101100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01101101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01101110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01101111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01110000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01110001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01110010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01110011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01110100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01110101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01110110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01110111 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01111000 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01111001 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01111010 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01111011 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01111100 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01111101 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01111110 -> 15/0, 1 bit used + { 1, 15, 0, -1 }, // 01111111 -> 15/0, 1 bit used + { 2, 3, 15, -1 }, // 10000000 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10000001 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10000010 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10000011 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10000100 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10000101 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10000110 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10000111 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10001000 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10001001 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10001010 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10001011 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10001100 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10001101 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10001110 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10001111 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10010000 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10010001 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10010010 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10010011 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10010100 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10010101 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10010110 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10010111 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10011000 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10011001 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10011010 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10011011 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10011100 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10011101 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10011110 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10011111 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10100000 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10100001 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10100010 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10100011 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10100100 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10100101 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10100110 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10100111 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10101000 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10101001 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10101010 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10101011 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10101100 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10101101 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10101110 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10101111 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10110000 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10110001 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10110010 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10110011 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10110100 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10110101 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10110110 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10110111 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10111000 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10111001 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10111010 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10111011 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10111100 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10111101 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10111110 -> 3/15, 2 bit used + { 2, 3, 15, -1 }, // 10111111 -> 3/15, 2 bit used + { 8, 12, 14, -1 }, // 11000000 -> 12/14, 8 bit used + { 8, -1, -1, 32 }, // 11000001 -> extension table #32 + { 7, 13, 14, -1 }, // 11000010 -> 13/14, 7 bit used + { 7, 13, 14, -1 }, // 11000011 -> 13/14, 7 bit used + { 7, 14, 9, -1 }, // 11000100 -> 14/9, 7 bit used + { 7, 14, 9, -1 }, // 11000101 -> 14/9, 7 bit used + { 8, 14, 10, -1 }, // 11000110 -> 14/10, 8 bit used + { 8, 13, 9, -1 }, // 11000111 -> 13/9, 8 bit used + { 6, 14, 14, -1 }, // 11001000 -> 14/14, 6 bit used + { 6, 14, 14, -1 }, // 11001001 -> 14/14, 6 bit used + { 6, 14, 14, -1 }, // 11001010 -> 14/14, 6 bit used + { 6, 14, 14, -1 }, // 11001011 -> 14/14, 6 bit used + { 7, 14, 13, -1 }, // 11001100 -> 14/13, 7 bit used + { 7, 14, 13, -1 }, // 11001101 -> 14/13, 7 bit used + { 7, 14, 11, -1 }, // 11001110 -> 14/11, 7 bit used + { 7, 14, 11, -1 }, // 11001111 -> 14/11, 7 bit used + { 6, 11, 14, -1 }, // 11010000 -> 11/14, 6 bit used + { 6, 11, 14, -1 }, // 11010001 -> 11/14, 6 bit used + { 6, 11, 14, -1 }, // 11010010 -> 11/14, 6 bit used + { 6, 11, 14, -1 }, // 11010011 -> 11/14, 6 bit used + { 6, 12, 13, -1 }, // 11010100 -> 12/13, 6 bit used + { 6, 12, 13, -1 }, // 11010101 -> 12/13, 6 bit used + { 6, 12, 13, -1 }, // 11010110 -> 12/13, 6 bit used + { 6, 12, 13, -1 }, // 11010111 -> 12/13, 6 bit used + { 7, 13, 12, -1 }, // 11011000 -> 13/12, 7 bit used + { 7, 13, 12, -1 }, // 11011001 -> 13/12, 7 bit used + { 7, 13, 11, -1 }, // 11011010 -> 13/11, 7 bit used + { 7, 13, 11, -1 }, // 11011011 -> 13/11, 7 bit used + { 6, 10, 14, -1 }, // 11011100 -> 10/14, 6 bit used + { 6, 10, 14, -1 }, // 11011101 -> 10/14, 6 bit used + { 6, 10, 14, -1 }, // 11011110 -> 10/14, 6 bit used + { 6, 10, 14, -1 }, // 11011111 -> 10/14, 6 bit used + { 6, 12, 12, -1 }, // 11100000 -> 12/12, 6 bit used + { 6, 12, 12, -1 }, // 11100001 -> 12/12, 6 bit used + { 6, 12, 12, -1 }, // 11100010 -> 12/12, 6 bit used + { 6, 12, 12, -1 }, // 11100011 -> 12/12, 6 bit used + { 7, 10, 13, -1 }, // 11100100 -> 10/13, 7 bit used + { 7, 10, 13, -1 }, // 11100101 -> 10/13, 7 bit used + { 7, 13, 10, -1 }, // 11100110 -> 13/10, 7 bit used + { 7, 13, 10, -1 }, // 11100111 -> 13/10, 7 bit used + { 7, 7, 14, -1 }, // 11101000 -> 7/14, 7 bit used + { 7, 7, 14, -1 }, // 11101001 -> 7/14, 7 bit used + { 7, 10, 12, -1 }, // 11101010 -> 10/12, 7 bit used + { 7, 10, 12, -1 }, // 11101011 -> 10/12, 7 bit used + { 6, 12, 10, -1 }, // 11101100 -> 12/10, 6 bit used + { 6, 12, 10, -1 }, // 11101101 -> 12/10, 6 bit used + { 6, 12, 10, -1 }, // 11101110 -> 12/10, 6 bit used + { 6, 12, 10, -1 }, // 11101111 -> 12/10, 6 bit used + { 7, 12, 9, -1 }, // 11110000 -> 12/9, 7 bit used + { 7, 12, 9, -1 }, // 11110001 -> 12/9, 7 bit used + { 7, 7, 13, -1 }, // 11110010 -> 7/13, 7 bit used + { 7, 7, 13, -1 }, // 11110011 -> 7/13, 7 bit used + { 6, 5, 14, -1 }, // 11110100 -> 5/14, 6 bit used + { 6, 5, 14, -1 }, // 11110101 -> 5/14, 6 bit used + { 6, 5, 14, -1 }, // 11110110 -> 5/14, 6 bit used + { 6, 5, 14, -1 }, // 11110111 -> 5/14, 6 bit used + { 5, 11, 13, -1 }, // 11111000 -> 11/13, 5 bit used + { 5, 11, 13, -1 }, // 11111001 -> 11/13, 5 bit used + { 5, 11, 13, -1 }, // 11111010 -> 11/13, 5 bit used + { 5, 11, 13, -1 }, // 11111011 -> 11/13, 5 bit used + { 5, 11, 13, -1 }, // 11111100 -> 11/13, 5 bit used + { 5, 11, 13, -1 }, // 11111101 -> 11/13, 5 bit used + { 5, 11, 13, -1 }, // 11111110 -> 11/13, 5 bit used + { 5, 11, 13, -1 } // 11111111 -> 11/13, 5 bit used +}; +// extension table 7, prefix 00001000 +static huffman_conv htab16_dec_ext7[ 2 ] = { + { 1, 2, 15, -1 }, // 0 -> 2/15, 1 bit used + { 1, 0, 15, -1 } // 1 -> 0/15, 1 bit used +}; +// extension table 8, prefix 00001011 +static huffman_conv htab16_dec_ext8[ 64 ] = { + { 5, 9, 14, -1 }, // 000000 -> 9/14, 5 bit used + { 5, 9, 14, -1 }, // 000001 -> 9/14, 5 bit used + { 6, 11, 12, -1 }, // 000010 -> 11/12, 6 bit used + { 6, 12, 11, -1 }, // 000011 -> 12/11, 6 bit used + { 6, 8, 14, -1 }, // 000100 -> 8/14, 6 bit used + { 6, 14, 8, -1 }, // 000101 -> 14/8, 6 bit used + { 6, 9, 13, -1 }, // 000110 -> 9/13, 6 bit used + { 6, 14, 7, -1 }, // 000111 -> 14/7, 6 bit used + { 6, 11, 11, -1 }, // 001000 -> 11/11, 6 bit used + { 6, 8, 13, -1 }, // 001001 -> 8/13, 6 bit used + { 6, 13, 8, -1 }, // 001010 -> 13/8, 6 bit used + { 6, 6, 14, -1 }, // 001011 -> 6/14, 6 bit used + { 5, 14, 6, -1 }, // 001100 -> 14/6, 5 bit used + { 5, 14, 6, -1 }, // 001101 -> 14/6, 5 bit used + { 5, 9, 12, -1 }, // 001110 -> 9/12, 5 bit used + { 5, 9, 12, -1 }, // 001111 -> 9/12, 5 bit used + { 6, 10, 11, -1 }, // 010000 -> 10/11, 6 bit used + { 6, 11, 10, -1 }, // 010001 -> 11/10, 6 bit used + { 6, 14, 5, -1 }, // 010010 -> 14/5, 6 bit used + { 6, 13, 7, -1 }, // 010011 -> 13/7, 6 bit used + { 5, 4, 14, -1 }, // 010100 -> 4/14, 5 bit used + { 5, 4, 14, -1 }, // 010101 -> 4/14, 5 bit used + { 6, 14, 4, -1 }, // 010110 -> 14/4, 6 bit used + { 6, 8, 12, -1 }, // 010111 -> 8/12, 6 bit used + { 5, 12, 8, -1 }, // 011000 -> 12/8, 5 bit used + { 5, 12, 8, -1 }, // 011001 -> 12/8, 5 bit used + { 5, 3, 14, -1 }, // 011010 -> 3/14, 5 bit used + { 5, 3, 14, -1 }, // 011011 -> 3/14, 5 bit used + { 5, 6, 13, -1 }, // 011100 -> 6/13, 5 bit used + { 5, 6, 13, -1 }, // 011101 -> 6/13, 5 bit used + { 6, 13, 6, -1 }, // 011110 -> 13/6, 6 bit used + { 6, 9, 11, -1 }, // 011111 -> 9/11, 6 bit used + { 6, 11, 9, -1 }, // 100000 -> 11/9, 6 bit used + { 6, 10, 10, -1 }, // 100001 -> 10/10, 6 bit used + { 5, 14, 1, -1 }, // 100010 -> 14/1, 5 bit used + { 5, 14, 1, -1 }, // 100011 -> 14/1, 5 bit used + { 5, 13, 4, -1 }, // 100100 -> 13/4, 5 bit used + { 5, 13, 4, -1 }, // 100101 -> 13/4, 5 bit used + { 6, 11, 8, -1 }, // 100110 -> 11/8, 6 bit used + { 6, 10, 9, -1 }, // 100111 -> 10/9, 6 bit used + { 5, 7, 11, -1 }, // 101000 -> 7/11, 5 bit used + { 5, 7, 11, -1 }, // 101001 -> 7/11, 5 bit used + { 6, 11, 7, -1 }, // 101010 -> 11/7, 6 bit used + { 6, 13, 0, -1 }, // 101011 -> 13/0, 6 bit used + { 4, 14, 3, -1 }, // 101100 -> 14/3, 4 bit used + { 4, 14, 3, -1 }, // 101101 -> 14/3, 4 bit used + { 4, 14, 3, -1 }, // 101110 -> 14/3, 4 bit used + { 4, 14, 3, -1 }, // 101111 -> 14/3, 4 bit used + { 5, 0, 14, -1 }, // 110000 -> 0/14, 5 bit used + { 5, 0, 14, -1 }, // 110001 -> 0/14, 5 bit used + { 5, 14, 0, -1 }, // 110010 -> 14/0, 5 bit used + { 5, 14, 0, -1 }, // 110011 -> 14/0, 5 bit used + { 5, 5, 13, -1 }, // 110100 -> 5/13, 5 bit used + { 5, 5, 13, -1 }, // 110101 -> 5/13, 5 bit used + { 5, 13, 5, -1 }, // 110110 -> 13/5, 5 bit used + { 5, 13, 5, -1 }, // 110111 -> 13/5, 5 bit used + { 5, 7, 12, -1 }, // 111000 -> 7/12, 5 bit used + { 5, 7, 12, -1 }, // 111001 -> 7/12, 5 bit used + { 5, 12, 7, -1 }, // 111010 -> 12/7, 5 bit used + { 5, 12, 7, -1 }, // 111011 -> 12/7, 5 bit used + { 5, 4, 13, -1 }, // 111100 -> 4/13, 5 bit used + { 5, 4, 13, -1 }, // 111101 -> 4/13, 5 bit used + { 5, 8, 11, -1 }, // 111110 -> 8/11, 5 bit used + { 5, 8, 11, -1 } // 111111 -> 8/11, 5 bit used +}; +// extension table 9, prefix 00001100 +static huffman_conv htab16_dec_ext9[ 32 ] = { + { 5, 9, 10, -1 }, // 00000 -> 9/10, 5 bit used + { 5, 6, 12, -1 }, // 00001 -> 6/12, 5 bit used + { 5, 12, 6, -1 }, // 00010 -> 12/6, 5 bit used + { 5, 3, 13, -1 }, // 00011 -> 3/13, 5 bit used + { 5, 5, 12, -1 }, // 00100 -> 5/12, 5 bit used + { 5, 12, 5, -1 }, // 00101 -> 12/5, 5 bit used + { 4, 0, 13, -1 }, // 00110 -> 0/13, 4 bit used + { 4, 0, 13, -1 }, // 00111 -> 0/13, 4 bit used + { 5, 8, 10, -1 }, // 01000 -> 8/10, 5 bit used + { 5, 10, 8, -1 }, // 01001 -> 10/8, 5 bit used + { 5, 9, 9, -1 }, // 01010 -> 9/9, 5 bit used + { 5, 4, 12, -1 }, // 01011 -> 4/12, 5 bit used + { 5, 11, 6, -1 }, // 01100 -> 11/6, 5 bit used + { 5, 7, 10, -1 }, // 01101 -> 7/10, 5 bit used + { 4, 3, 12, -1 }, // 01110 -> 3/12, 4 bit used + { 4, 3, 12, -1 }, // 01111 -> 3/12, 4 bit used + { 5, 5, 11, -1 }, // 10000 -> 5/11, 5 bit used + { 5, 8, 9, -1 }, // 10001 -> 8/9, 5 bit used + { 4, 1, 12, -1 }, // 10010 -> 1/12, 4 bit used + { 4, 1, 12, -1 }, // 10011 -> 1/12, 4 bit used + { 4, 12, 0, -1 }, // 10100 -> 12/0, 4 bit used + { 4, 12, 0, -1 }, // 10101 -> 12/0, 4 bit used + { 5, 9, 8, -1 }, // 10110 -> 9/8, 5 bit used + { 5, 7, 9, -1 }, // 10111 -> 7/9, 5 bit used + { 3, 14, 2, -1 }, // 11000 -> 14/2, 3 bit used + { 3, 14, 2, -1 }, // 11001 -> 14/2, 3 bit used + { 3, 14, 2, -1 }, // 11010 -> 14/2, 3 bit used + { 3, 14, 2, -1 }, // 11011 -> 14/2, 3 bit used + { 4, 2, 14, -1 }, // 11100 -> 2/14, 4 bit used + { 4, 2, 14, -1 }, // 11101 -> 2/14, 4 bit used + { 4, 1, 14, -1 }, // 11110 -> 1/14, 4 bit used + { 4, 1, 14, -1 } // 11111 -> 1/14, 4 bit used +}; +// extension table 10, prefix 00001101 +static huffman_conv htab16_dec_ext10[ 32 ] = { + { 4, 13, 3, -1 }, // 00000 -> 13/3, 4 bit used + { 4, 13, 3, -1 }, // 00001 -> 13/3, 4 bit used + { 4, 2, 13, -1 }, // 00010 -> 2/13, 4 bit used + { 4, 2, 13, -1 }, // 00011 -> 2/13, 4 bit used + { 4, 13, 2, -1 }, // 00100 -> 13/2, 4 bit used + { 4, 13, 2, -1 }, // 00101 -> 13/2, 4 bit used + { 4, 13, 1, -1 }, // 00110 -> 13/1, 4 bit used + { 4, 13, 1, -1 }, // 00111 -> 13/1, 4 bit used + { 4, 3, 11, -1 }, // 01000 -> 3/11, 4 bit used + { 4, 3, 11, -1 }, // 01001 -> 3/11, 4 bit used + { 5, 9, 7, -1 }, // 01010 -> 9/7, 5 bit used + { 5, 8, 8, -1 }, // 01011 -> 8/8, 5 bit used + { 3, 1, 13, -1 }, // 01100 -> 1/13, 3 bit used + { 3, 1, 13, -1 }, // 01101 -> 1/13, 3 bit used + { 3, 1, 13, -1 }, // 01110 -> 1/13, 3 bit used + { 3, 1, 13, -1 }, // 01111 -> 1/13, 3 bit used + { 4, 12, 4, -1 }, // 10000 -> 12/4, 4 bit used + { 4, 12, 4, -1 }, // 10001 -> 12/4, 4 bit used + { 4, 6, 11, -1 }, // 10010 -> 6/11, 4 bit used + { 4, 6, 11, -1 }, // 10011 -> 6/11, 4 bit used + { 4, 12, 3, -1 }, // 10100 -> 12/3, 4 bit used + { 4, 12, 3, -1 }, // 10101 -> 12/3, 4 bit used + { 4, 10, 7, -1 }, // 10110 -> 10/7, 4 bit used + { 4, 10, 7, -1 }, // 10111 -> 10/7, 4 bit used + { 3, 2, 12, -1 }, // 11000 -> 2/12, 3 bit used + { 3, 2, 12, -1 }, // 11001 -> 2/12, 3 bit used + { 3, 2, 12, -1 }, // 11010 -> 2/12, 3 bit used + { 3, 2, 12, -1 }, // 11011 -> 2/12, 3 bit used + { 4, 12, 2, -1 }, // 11100 -> 12/2, 4 bit used + { 4, 12, 2, -1 }, // 11101 -> 12/2, 4 bit used + { 4, 11, 5, -1 }, // 11110 -> 11/5, 4 bit used + { 4, 11, 5, -1 } // 11111 -> 11/5, 4 bit used +}; +// extension table 11, prefix 00001110 +static huffman_conv htab16_dec_ext11[ 16 ] = { + { 4, 12, 1, -1 }, // 0000 -> 12/1, 4 bit used + { 4, 0, 12, -1 }, // 0001 -> 0/12, 4 bit used + { 4, 4, 11, -1 }, // 0010 -> 4/11, 4 bit used + { 4, 11, 4, -1 }, // 0011 -> 11/4, 4 bit used + { 4, 6, 10, -1 }, // 0100 -> 6/10, 4 bit used + { 4, 10, 6, -1 }, // 0101 -> 10/6, 4 bit used + { 3, 11, 3, -1 }, // 0110 -> 11/3, 3 bit used + { 3, 11, 3, -1 }, // 0111 -> 11/3, 3 bit used + { 4, 5, 10, -1 }, // 1000 -> 5/10, 4 bit used + { 4, 10, 5, -1 }, // 1001 -> 10/5, 4 bit used + { 3, 2, 11, -1 }, // 1010 -> 2/11, 3 bit used + { 3, 2, 11, -1 }, // 1011 -> 2/11, 3 bit used + { 3, 11, 2, -1 }, // 1100 -> 11/2, 3 bit used + { 3, 11, 2, -1 }, // 1101 -> 11/2, 3 bit used + { 3, 1, 11, -1 }, // 1110 -> 1/11, 3 bit used + { 3, 1, 11, -1 } // 1111 -> 1/11, 3 bit used +}; +// extension table 12, prefix 00001111 +static huffman_conv htab16_dec_ext12[ 16 ] = { + { 3, 11, 1, -1 }, // 0000 -> 11/1, 3 bit used + { 3, 11, 1, -1 }, // 0001 -> 11/1, 3 bit used + { 4, 0, 11, -1 }, // 0010 -> 0/11, 4 bit used + { 4, 11, 0, -1 }, // 0011 -> 11/0, 4 bit used + { 4, 6, 9, -1 }, // 0100 -> 6/9, 4 bit used + { 4, 9, 6, -1 }, // 0101 -> 9/6, 4 bit used + { 4, 4, 10, -1 }, // 0110 -> 4/10, 4 bit used + { 4, 10, 4, -1 }, // 0111 -> 10/4, 4 bit used + { 4, 7, 8, -1 }, // 1000 -> 7/8, 4 bit used + { 4, 8, 7, -1 }, // 1001 -> 8/7, 4 bit used + { 3, 10, 3, -1 }, // 1010 -> 10/3, 3 bit used + { 3, 10, 3, -1 }, // 1011 -> 10/3, 3 bit used + { 4, 3, 10, -1 }, // 1100 -> 3/10, 4 bit used + { 4, 5, 9, -1 }, // 1101 -> 5/9, 4 bit used + { 3, 2, 10, -1 }, // 1110 -> 2/10, 3 bit used + { 3, 2, 10, -1 } // 1111 -> 2/10, 3 bit used +}; +// extension table 13, prefix 00010000 +static huffman_conv htab16_dec_ext13[ 16 ] = { + { 4, 9, 5, -1 }, // 0000 -> 9/5, 4 bit used + { 4, 6, 8, -1 }, // 0001 -> 6/8, 4 bit used + { 3, 10, 1, -1 }, // 0010 -> 10/1, 3 bit used + { 3, 10, 1, -1 }, // 0011 -> 10/1, 3 bit used + { 4, 8, 6, -1 }, // 0100 -> 8/6, 4 bit used + { 4, 7, 7, -1 }, // 0101 -> 7/7, 4 bit used + { 3, 9, 4, -1 }, // 0110 -> 9/4, 3 bit used + { 3, 9, 4, -1 }, // 0111 -> 9/4, 3 bit used + { 4, 4, 9, -1 }, // 1000 -> 4/9, 4 bit used + { 4, 5, 7, -1 }, // 1001 -> 5/7, 4 bit used + { 3, 6, 7, -1 }, // 1010 -> 6/7, 3 bit used + { 3, 6, 7, -1 }, // 1011 -> 6/7, 3 bit used + { 2, 10, 2, -1 }, // 1100 -> 10/2, 2 bit used + { 2, 10, 2, -1 }, // 1101 -> 10/2, 2 bit used + { 2, 10, 2, -1 }, // 1110 -> 10/2, 2 bit used + { 2, 10, 2, -1 } // 1111 -> 10/2, 2 bit used +}; +// extension table 14, prefix 00010001 +static huffman_conv htab16_dec_ext14[ 8 ] = { + { 2, 1, 10, -1 }, // 000 -> 1/10, 2 bit used + { 2, 1, 10, -1 }, // 001 -> 1/10, 2 bit used + { 3, 0, 10, -1 }, // 010 -> 0/10, 3 bit used + { 3, 10, 0, -1 }, // 011 -> 10/0, 3 bit used + { 3, 3, 9, -1 }, // 100 -> 3/9, 3 bit used + { 3, 9, 3, -1 }, // 101 -> 9/3, 3 bit used + { 3, 5, 8, -1 }, // 110 -> 5/8, 3 bit used + { 3, 8, 5, -1 } // 111 -> 8/5, 3 bit used +}; +// extension table 15, prefix 00010010 +static huffman_conv htab16_dec_ext15[ 8 ] = { + { 2, 2, 9, -1 }, // 000 -> 2/9, 2 bit used + { 2, 2, 9, -1 }, // 001 -> 2/9, 2 bit used + { 2, 9, 2, -1 }, // 010 -> 9/2, 2 bit used + { 2, 9, 2, -1 }, // 011 -> 9/2, 2 bit used + { 3, 7, 6, -1 }, // 100 -> 7/6, 3 bit used + { 3, 0, 9, -1 }, // 101 -> 0/9, 3 bit used + { 2, 1, 9, -1 }, // 110 -> 1/9, 2 bit used + { 2, 1, 9, -1 } // 111 -> 1/9, 2 bit used +}; +// extension table 16, prefix 00010011 +static huffman_conv htab16_dec_ext16[ 8 ] = { + { 2, 9, 1, -1 }, // 000 -> 9/1, 2 bit used + { 2, 9, 1, -1 }, // 001 -> 9/1, 2 bit used + { 3, 9, 0, -1 }, // 010 -> 9/0, 3 bit used + { 3, 4, 8, -1 }, // 011 -> 4/8, 3 bit used + { 3, 8, 4, -1 }, // 100 -> 8/4, 3 bit used + { 3, 7, 5, -1 }, // 101 -> 7/5, 3 bit used + { 3, 3, 8, -1 }, // 110 -> 3/8, 3 bit used + { 3, 8, 3, -1 } // 111 -> 8/3, 3 bit used +}; +// extension table 17, prefix 00010100 +static huffman_conv htab16_dec_ext17[ 8 ] = { + { 3, 6, 6, -1 }, // 000 -> 6/6, 3 bit used + { 3, 2, 8, -1 }, // 001 -> 2/8, 3 bit used + { 2, 8, 2, -1 }, // 010 -> 8/2, 2 bit used + { 2, 8, 2, -1 }, // 011 -> 8/2, 2 bit used + { 3, 4, 7, -1 }, // 100 -> 4/7, 3 bit used + { 3, 7, 4, -1 }, // 101 -> 7/4, 3 bit used + { 2, 1, 8, -1 }, // 110 -> 1/8, 2 bit used + { 2, 1, 8, -1 } // 111 -> 1/8, 2 bit used +}; +// extension table 18, prefix 00010101 +static huffman_conv htab16_dec_ext18[ 8 ] = { + { 2, 8, 1, -1 }, // 000 -> 8/1, 2 bit used + { 2, 8, 1, -1 }, // 001 -> 8/1, 2 bit used + { 2, 8, 0, -1 }, // 010 -> 8/0, 2 bit used + { 2, 8, 0, -1 }, // 011 -> 8/0, 2 bit used + { 3, 0, 8, -1 }, // 100 -> 0/8, 3 bit used + { 3, 5, 6, -1 }, // 101 -> 5/6, 3 bit used + { 2, 3, 7, -1 }, // 110 -> 3/7, 2 bit used + { 2, 3, 7, -1 } // 111 -> 3/7, 2 bit used +}; +// extension table 19, prefix 00010110 +static huffman_conv htab16_dec_ext19[ 8 ] = { + { 2, 7, 3, -1 }, // 000 -> 7/3, 2 bit used + { 2, 7, 3, -1 }, // 001 -> 7/3, 2 bit used + { 3, 6, 5, -1 }, // 010 -> 6/5, 3 bit used + { 3, 4, 6, -1 }, // 011 -> 4/6, 3 bit used + { 2, 2, 7, -1 }, // 100 -> 2/7, 2 bit used + { 2, 2, 7, -1 }, // 101 -> 2/7, 2 bit used + { 2, 7, 2, -1 }, // 110 -> 7/2, 2 bit used + { 2, 7, 2, -1 } // 111 -> 7/2, 2 bit used +}; +// extension table 20, prefix 00010111 +static huffman_conv htab16_dec_ext20[ 8 ] = { + { 3, 6, 4, -1 }, // 000 -> 6/4, 3 bit used + { 3, 5, 5, -1 }, // 001 -> 5/5, 3 bit used + { 2, 0, 7, -1 }, // 010 -> 0/7, 2 bit used + { 2, 0, 7, -1 }, // 011 -> 0/7, 2 bit used + { 1, 1, 7, -1 }, // 100 -> 1/7, 1 bit used + { 1, 1, 7, -1 }, // 101 -> 1/7, 1 bit used + { 1, 1, 7, -1 }, // 110 -> 1/7, 1 bit used + { 1, 1, 7, -1 } // 111 -> 1/7, 1 bit used +}; +// extension table 21, prefix 00011000 +static huffman_conv htab16_dec_ext21[ 4 ] = { + { 1, 7, 1, -1 }, // 00 -> 7/1, 1 bit used + { 1, 7, 1, -1 }, // 01 -> 7/1, 1 bit used + { 2, 7, 0, -1 }, // 10 -> 7/0, 2 bit used + { 2, 3, 6, -1 } // 11 -> 3/6, 2 bit used +}; +// extension table 22, prefix 00011001 +static huffman_conv htab16_dec_ext22[ 4 ] = { + { 2, 6, 3, -1 }, // 00 -> 6/3, 2 bit used + { 2, 4, 5, -1 }, // 01 -> 4/5, 2 bit used + { 2, 5, 4, -1 }, // 10 -> 5/4, 2 bit used + { 2, 2, 6, -1 } // 11 -> 2/6, 2 bit used +}; +// extension table 23, prefix 00011010 +static huffman_conv htab16_dec_ext23[ 2 ] = { + { 1, 6, 2, -1 }, // 0 -> 6/2, 1 bit used + { 1, 1, 6, -1 } // 1 -> 1/6, 1 bit used +}; +// extension table 24, prefix 00011011 +static huffman_conv htab16_dec_ext24[ 4 ] = { + { 1, 6, 1, -1 }, // 00 -> 6/1, 1 bit used + { 1, 6, 1, -1 }, // 01 -> 6/1, 1 bit used + { 2, 0, 6, -1 }, // 10 -> 0/6, 2 bit used + { 2, 6, 0, -1 } // 11 -> 6/0, 2 bit used +}; +// extension table 25, prefix 00011100 +static huffman_conv htab16_dec_ext25[ 4 ] = { + { 1, 5, 3, -1 }, // 00 -> 5/3, 1 bit used + { 1, 5, 3, -1 }, // 01 -> 5/3, 1 bit used + { 2, 3, 5, -1 }, // 10 -> 3/5, 2 bit used + { 2, 4, 4, -1 } // 11 -> 4/4, 2 bit used +}; +// extension table 26, prefix 00011101 +static huffman_conv htab16_dec_ext26[ 2 ] = { + { 1, 2, 5, -1 }, // 0 -> 2/5, 1 bit used + { 1, 5, 2, -1 } // 1 -> 5/2, 1 bit used +}; +// extension table 27, prefix 00011111 +static huffman_conv htab16_dec_ext27[ 2 ] = { + { 1, 1, 5, -1 }, // 0 -> 1/5, 1 bit used + { 1, 0, 5, -1 } // 1 -> 0/5, 1 bit used +}; +// extension table 28, prefix 00100000 +static huffman_conv htab16_dec_ext28[ 2 ] = { + { 1, 3, 4, -1 }, // 0 -> 3/4, 1 bit used + { 1, 4, 3, -1 } // 1 -> 4/3, 1 bit used +}; +// extension table 29, prefix 00100001 +static huffman_conv htab16_dec_ext29[ 2 ] = { + { 1, 5, 0, -1 }, // 0 -> 5/0, 1 bit used + { 1, 2, 4, -1 } // 1 -> 2/4, 1 bit used +}; +// extension table 30, prefix 00100010 +static huffman_conv htab16_dec_ext30[ 2 ] = { + { 1, 4, 2, -1 }, // 0 -> 4/2, 1 bit used + { 1, 3, 3, -1 } // 1 -> 3/3, 1 bit used +}; +// extension table 31, prefix 00100101 +static huffman_conv htab16_dec_ext31[ 2 ] = { + { 1, 0, 4, -1 }, // 0 -> 0/4, 1 bit used + { 1, 4, 0, -1 } // 1 -> 4/0, 1 bit used +}; +// extension table 32, prefix 0000011011000001 +static huffman_conv htab16_dec_ext32[ 2 ] = { + { 1, 14, 12, -1 }, // 0 -> 14/12, 1 bit used + { 1, 13, 13, -1 } // 1 -> 13/13, 1 bit used +}; +// big values conversion table #16, total size: 804, ext tables: 32 +static huffman_conv_set htab16_dec[ 33 ] = { + { htab16_dec_start, 8 }, // start table + { htab16_dec_ext1, 3 }, // ext table #1 + { htab16_dec_ext2, 3 }, // ext table #2 + { htab16_dec_ext3, 2 }, // ext table #3 + { htab16_dec_ext4, 2 }, // ext table #4 + { htab16_dec_ext5, 1 }, // ext table #5 + { htab16_dec_ext6, 8 }, // ext table #6 + { htab16_dec_ext7, 1 }, // ext table #7 + { htab16_dec_ext8, 6 }, // ext table #8 + { htab16_dec_ext9, 5 }, // ext table #9 + { htab16_dec_ext10, 5 }, // ext table #10 + { htab16_dec_ext11, 4 }, // ext table #11 + { htab16_dec_ext12, 4 }, // ext table #12 + { htab16_dec_ext13, 4 }, // ext table #13 + { htab16_dec_ext14, 3 }, // ext table #14 + { htab16_dec_ext15, 3 }, // ext table #15 + { htab16_dec_ext16, 3 }, // ext table #16 + { htab16_dec_ext17, 3 }, // ext table #17 + { htab16_dec_ext18, 3 }, // ext table #18 + { htab16_dec_ext19, 3 }, // ext table #19 + { htab16_dec_ext20, 3 }, // ext table #20 + { htab16_dec_ext21, 2 }, // ext table #21 + { htab16_dec_ext22, 2 }, // ext table #22 + { htab16_dec_ext23, 1 }, // ext table #23 + { htab16_dec_ext24, 2 }, // ext table #24 + { htab16_dec_ext25, 2 }, // ext table #25 + { htab16_dec_ext26, 1 }, // ext table #26 + { htab16_dec_ext27, 1 }, // ext table #27 + { htab16_dec_ext28, 1 }, // ext table #28 + { htab16_dec_ext29, 1 }, // ext table #29 + { htab16_dec_ext30, 1 }, // ext table #30 + { htab16_dec_ext31, 1 }, // ext table #31 + { htab16_dec_ext32, 1 } // ext table #32 +}; + +/* ----------------------------------------------- + big values conversion table 24 + ----------------------------------------------- */ +static huffman_conv htab24_dec_start[ 256 ] = { + { 8, 14, 15, -1 }, // 00000000 -> 14/15, 8 bit used + { 8, 15, 14, -1 }, // 00000001 -> 15/14, 8 bit used + { 8, 13, 15, -1 }, // 00000010 -> 13/15, 8 bit used + { 8, 15, 13, -1 }, // 00000011 -> 15/13, 8 bit used + { 8, 12, 15, -1 }, // 00000100 -> 12/15, 8 bit used + { 8, 15, 12, -1 }, // 00000101 -> 15/12, 8 bit used + { 8, 11, 15, -1 }, // 00000110 -> 11/15, 8 bit used + { 8, 15, 11, -1 }, // 00000111 -> 15/11, 8 bit used + { 7, 15, 10, -1 }, // 00001000 -> 15/10, 7 bit used + { 7, 15, 10, -1 }, // 00001001 -> 15/10, 7 bit used + { 8, 10, 15, -1 }, // 00001010 -> 10/15, 8 bit used + { 8, 9, 15, -1 }, // 00001011 -> 9/15, 8 bit used + { 7, 15, 9, -1 }, // 00001100 -> 15/9, 7 bit used + { 7, 15, 9, -1 }, // 00001101 -> 15/9, 7 bit used + { 7, 15, 8, -1 }, // 00001110 -> 15/8, 7 bit used + { 7, 15, 8, -1 }, // 00001111 -> 15/8, 7 bit used + { 8, 8, 15, -1 }, // 00010000 -> 8/15, 8 bit used + { 8, 7, 15, -1 }, // 00010001 -> 7/15, 8 bit used + { 7, 15, 7, -1 }, // 00010010 -> 15/7, 7 bit used + { 7, 15, 7, -1 }, // 00010011 -> 15/7, 7 bit used + { 7, 6, 15, -1 }, // 00010100 -> 6/15, 7 bit used + { 7, 6, 15, -1 }, // 00010101 -> 6/15, 7 bit used + { 7, 15, 6, -1 }, // 00010110 -> 15/6, 7 bit used + { 7, 15, 6, -1 }, // 00010111 -> 15/6, 7 bit used + { 7, 5, 15, -1 }, // 00011000 -> 5/15, 7 bit used + { 7, 5, 15, -1 }, // 00011001 -> 5/15, 7 bit used + { 7, 15, 5, -1 }, // 00011010 -> 15/5, 7 bit used + { 7, 15, 5, -1 }, // 00011011 -> 15/5, 7 bit used + { 7, 4, 15, -1 }, // 00011100 -> 4/15, 7 bit used + { 7, 4, 15, -1 }, // 00011101 -> 4/15, 7 bit used + { 7, 15, 4, -1 }, // 00011110 -> 15/4, 7 bit used + { 7, 15, 4, -1 }, // 00011111 -> 15/4, 7 bit used + { 7, 3, 15, -1 }, // 00100000 -> 3/15, 7 bit used + { 7, 3, 15, -1 }, // 00100001 -> 3/15, 7 bit used + { 7, 15, 3, -1 }, // 00100010 -> 15/3, 7 bit used + { 7, 15, 3, -1 }, // 00100011 -> 15/3, 7 bit used + { 7, 2, 15, -1 }, // 00100100 -> 2/15, 7 bit used + { 7, 2, 15, -1 }, // 00100101 -> 2/15, 7 bit used + { 7, 15, 2, -1 }, // 00100110 -> 15/2, 7 bit used + { 7, 15, 2, -1 }, // 00100111 -> 15/2, 7 bit used + { 7, 15, 1, -1 }, // 00101000 -> 15/1, 7 bit used + { 7, 15, 1, -1 }, // 00101001 -> 15/1, 7 bit used + { 8, 1, 15, -1 }, // 00101010 -> 1/15, 8 bit used + { 8, 15, 0, -1 }, // 00101011 -> 15/0, 8 bit used + { 8, -1, -1, 1 }, // 00101100 -> extension table #1 + { 8, -1, -1, 2 }, // 00101101 -> extension table #2 + { 8, -1, -1, 3 }, // 00101110 -> extension table #3 + { 8, -1, -1, 4 }, // 00101111 -> extension table #4 + { 4, 15, 15, -1 }, // 00110000 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00110001 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00110010 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00110011 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00110100 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00110101 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00110110 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00110111 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00111000 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00111001 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00111010 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00111011 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00111100 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00111101 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00111110 -> 15/15, 4 bit used + { 4, 15, 15, -1 }, // 00111111 -> 15/15, 4 bit used + { 8, -1, -1, 5 }, // 01000000 -> extension table #5 + { 8, -1, -1, 6 }, // 01000001 -> extension table #6 + { 8, -1, -1, 7 }, // 01000010 -> extension table #7 + { 8, -1, -1, 8 }, // 01000011 -> extension table #8 + { 8, -1, -1, 9 }, // 01000100 -> extension table #9 + { 8, -1, -1, 10 }, // 01000101 -> extension table #10 + { 8, -1, -1, 11 }, // 01000110 -> extension table #11 + { 8, -1, -1, 12 }, // 01000111 -> extension table #12 + { 8, -1, -1, 13 }, // 01001000 -> extension table #13 + { 8, -1, -1, 14 }, // 01001001 -> extension table #14 + { 8, -1, -1, 15 }, // 01001010 -> extension table #15 + { 8, -1, -1, 16 }, // 01001011 -> extension table #16 + { 8, -1, -1, 17 }, // 01001100 -> extension table #17 + { 8, -1, -1, 18 }, // 01001101 -> extension table #18 + { 8, -1, -1, 19 }, // 01001110 -> extension table #19 + { 8, -1, -1, 20 }, // 01001111 -> extension table #20 + { 8, -1, -1, 21 }, // 01010000 -> extension table #21 + { 8, -1, -1, 22 }, // 01010001 -> extension table #22 + { 8, -1, -1, 23 }, // 01010010 -> extension table #23 + { 8, -1, -1, 24 }, // 01010011 -> extension table #24 + { 8, -1, -1, 25 }, // 01010100 -> extension table #25 + { 8, -1, -1, 26 }, // 01010101 -> extension table #26 + { 8, -1, -1, 27 }, // 01010110 -> extension table #27 + { 8, -1, -1, 28 }, // 01010111 -> extension table #28 + { 8, -1, -1, 29 }, // 01011000 -> extension table #29 + { 8, -1, -1, 30 }, // 01011001 -> extension table #30 + { 8, -1, -1, 31 }, // 01011010 -> extension table #31 + { 8, -1, -1, 32 }, // 01011011 -> extension table #32 + { 8, -1, -1, 33 }, // 01011100 -> extension table #33 + { 8, -1, -1, 34 }, // 01011101 -> extension table #34 + { 8, -1, -1, 35 }, // 01011110 -> extension table #35 + { 8, -1, -1, 36 }, // 01011111 -> extension table #36 + { 8, -1, -1, 37 }, // 01100000 -> extension table #37 + { 8, -1, -1, 38 }, // 01100001 -> extension table #38 + { 8, -1, -1, 39 }, // 01100010 -> extension table #39 + { 8, -1, -1, 40 }, // 01100011 -> extension table #40 + { 8, -1, -1, 41 }, // 01100100 -> extension table #41 + { 8, -1, -1, 42 }, // 01100101 -> extension table #42 + { 8, -1, -1, 43 }, // 01100110 -> extension table #43 + { 8, -1, -1, 44 }, // 01100111 -> extension table #44 + { 8, -1, -1, 45 }, // 01101000 -> extension table #45 + { 8, -1, -1, 46 }, // 01101001 -> extension table #46 + { 8, -1, -1, 47 }, // 01101010 -> extension table #47 + { 8, -1, -1, 48 }, // 01101011 -> extension table #48 + { 8, -1, -1, 49 }, // 01101100 -> extension table #49 + { 8, 7, 3, -1 }, // 01101101 -> 7/3, 8 bit used + { 8, -1, -1, 50 }, // 01101110 -> extension table #50 + { 8, 7, 2, -1 }, // 01101111 -> 7/2, 8 bit used + { 8, 4, 6, -1 }, // 01110000 -> 4/6, 8 bit used + { 8, 6, 4, -1 }, // 01110001 -> 6/4, 8 bit used + { 8, 5, 5, -1 }, // 01110010 -> 5/5, 8 bit used + { 8, 7, 1, -1 }, // 01110011 -> 7/1, 8 bit used + { 8, 3, 6, -1 }, // 01110100 -> 3/6, 8 bit used + { 8, 6, 3, -1 }, // 01110101 -> 6/3, 8 bit used + { 8, 4, 5, -1 }, // 01110110 -> 4/5, 8 bit used + { 8, 5, 4, -1 }, // 01110111 -> 5/4, 8 bit used + { 8, 2, 6, -1 }, // 01111000 -> 2/6, 8 bit used + { 8, 6, 2, -1 }, // 01111001 -> 6/2, 8 bit used + { 8, 1, 6, -1 }, // 01111010 -> 1/6, 8 bit used + { 8, 6, 1, -1 }, // 01111011 -> 6/1, 8 bit used + { 8, -1, -1, 51 }, // 01111100 -> extension table #51 + { 8, 3, 5, -1 }, // 01111101 -> 3/5, 8 bit used + { 8, 5, 3, -1 }, // 01111110 -> 5/3, 8 bit used + { 8, 4, 4, -1 }, // 01111111 -> 4/4, 8 bit used + { 8, 2, 5, -1 }, // 10000000 -> 2/5, 8 bit used + { 8, 5, 2, -1 }, // 10000001 -> 5/2, 8 bit used + { 8, 1, 5, -1 }, // 10000010 -> 1/5, 8 bit used + { 8, -1, -1, 52 }, // 10000011 -> extension table #52 + { 7, 5, 1, -1 }, // 10000100 -> 5/1, 7 bit used + { 7, 5, 1, -1 }, // 10000101 -> 5/1, 7 bit used + { 8, 3, 4, -1 }, // 10000110 -> 3/4, 8 bit used + { 8, 4, 3, -1 }, // 10000111 -> 4/3, 8 bit used + { 7, 2, 4, -1 }, // 10001000 -> 2/4, 7 bit used + { 7, 2, 4, -1 }, // 10001001 -> 2/4, 7 bit used + { 7, 4, 2, -1 }, // 10001010 -> 4/2, 7 bit used + { 7, 4, 2, -1 }, // 10001011 -> 4/2, 7 bit used + { 7, 3, 3, -1 }, // 10001100 -> 3/3, 7 bit used + { 7, 3, 3, -1 }, // 10001101 -> 3/3, 7 bit used + { 7, 1, 4, -1 }, // 10001110 -> 1/4, 7 bit used + { 7, 1, 4, -1 }, // 10001111 -> 1/4, 7 bit used + { 7, 4, 1, -1 }, // 10010000 -> 4/1, 7 bit used + { 7, 4, 1, -1 }, // 10010001 -> 4/1, 7 bit used + { 8, 0, 4, -1 }, // 10010010 -> 0/4, 8 bit used + { 8, 4, 0, -1 }, // 10010011 -> 4/0, 8 bit used + { 7, 2, 3, -1 }, // 10010100 -> 2/3, 7 bit used + { 7, 2, 3, -1 }, // 10010101 -> 2/3, 7 bit used + { 7, 3, 2, -1 }, // 10010110 -> 3/2, 7 bit used + { 7, 3, 2, -1 }, // 10010111 -> 3/2, 7 bit used + { 6, 1, 3, -1 }, // 10011000 -> 1/3, 6 bit used + { 6, 1, 3, -1 }, // 10011001 -> 1/3, 6 bit used + { 6, 1, 3, -1 }, // 10011010 -> 1/3, 6 bit used + { 6, 1, 3, -1 }, // 10011011 -> 1/3, 6 bit used + { 6, 3, 1, -1 }, // 10011100 -> 3/1, 6 bit used + { 6, 3, 1, -1 }, // 10011101 -> 3/1, 6 bit used + { 6, 3, 1, -1 }, // 10011110 -> 3/1, 6 bit used + { 6, 3, 1, -1 }, // 10011111 -> 3/1, 6 bit used + { 7, 0, 3, -1 }, // 10100000 -> 0/3, 7 bit used + { 7, 0, 3, -1 }, // 10100001 -> 0/3, 7 bit used + { 7, 3, 0, -1 }, // 10100010 -> 3/0, 7 bit used + { 7, 3, 0, -1 }, // 10100011 -> 3/0, 7 bit used + { 6, 2, 2, -1 }, // 10100100 -> 2/2, 6 bit used + { 6, 2, 2, -1 }, // 10100101 -> 2/2, 6 bit used + { 6, 2, 2, -1 }, // 10100110 -> 2/2, 6 bit used + { 6, 2, 2, -1 }, // 10100111 -> 2/2, 6 bit used + { 5, 1, 2, -1 }, // 10101000 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10101001 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10101010 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10101011 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10101100 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10101101 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10101110 -> 1/2, 5 bit used + { 5, 1, 2, -1 }, // 10101111 -> 1/2, 5 bit used + { 5, 2, 1, -1 }, // 10110000 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10110001 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10110010 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10110011 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10110100 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10110101 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10110110 -> 2/1, 5 bit used + { 5, 2, 1, -1 }, // 10110111 -> 2/1, 5 bit used + { 6, 0, 2, -1 }, // 10111000 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 10111001 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 10111010 -> 0/2, 6 bit used + { 6, 0, 2, -1 }, // 10111011 -> 0/2, 6 bit used + { 6, 2, 0, -1 }, // 10111100 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 10111101 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 10111110 -> 2/0, 6 bit used + { 6, 2, 0, -1 }, // 10111111 -> 2/0, 6 bit used + { 4, 1, 1, -1 }, // 11000000 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11000001 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11000010 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11000011 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11000100 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11000101 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11000110 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11000111 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11001000 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11001001 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11001010 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11001011 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11001100 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11001101 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11001110 -> 1/1, 4 bit used + { 4, 1, 1, -1 }, // 11001111 -> 1/1, 4 bit used + { 4, 0, 1, -1 }, // 11010000 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11010001 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11010010 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11010011 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11010100 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11010101 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11010110 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11010111 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11011000 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11011001 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11011010 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11011011 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11011100 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11011101 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11011110 -> 0/1, 4 bit used + { 4, 0, 1, -1 }, // 11011111 -> 0/1, 4 bit used + { 4, 1, 0, -1 }, // 11100000 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11100001 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11100010 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11100011 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11100100 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11100101 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11100110 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11100111 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11101000 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11101001 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11101010 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11101011 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11101100 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11101101 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11101110 -> 1/0, 4 bit used + { 4, 1, 0, -1 }, // 11101111 -> 1/0, 4 bit used + { 4, 0, 0, -1 }, // 11110000 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11110001 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11110010 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11110011 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11110100 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11110101 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11110110 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11110111 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11111000 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11111001 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11111010 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11111011 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11111100 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11111101 -> 0/0, 4 bit used + { 4, 0, 0, -1 }, // 11111110 -> 0/0, 4 bit used + { 4, 0, 0, -1 } // 11111111 -> 0/0, 4 bit used +}; +// extension table 1, prefix 00101100 +static huffman_conv htab24_dec_ext1[ 8 ] = { + { 1, 0, 15, -1 }, // 000 -> 0/15, 1 bit used + { 1, 0, 15, -1 }, // 001 -> 0/15, 1 bit used + { 1, 0, 15, -1 }, // 010 -> 0/15, 1 bit used + { 1, 0, 15, -1 }, // 011 -> 0/15, 1 bit used + { 3, 14, 14, -1 }, // 100 -> 14/14, 3 bit used + { 3, 13, 14, -1 }, // 101 -> 13/14, 3 bit used + { 3, 14, 13, -1 }, // 110 -> 14/13, 3 bit used + { 3, 12, 14, -1 } // 111 -> 12/14, 3 bit used +}; +// extension table 2, prefix 00101101 +static huffman_conv htab24_dec_ext2[ 8 ] = { + { 3, 14, 12, -1 }, // 000 -> 14/12, 3 bit used + { 3, 13, 13, -1 }, // 001 -> 13/13, 3 bit used + { 3, 11, 14, -1 }, // 010 -> 11/14, 3 bit used + { 3, 14, 11, -1 }, // 011 -> 14/11, 3 bit used + { 3, 12, 13, -1 }, // 100 -> 12/13, 3 bit used + { 3, 13, 12, -1 }, // 101 -> 13/12, 3 bit used + { 3, 10, 14, -1 }, // 110 -> 10/14, 3 bit used + { 3, 14, 10, -1 } // 111 -> 14/10, 3 bit used +}; +// extension table 3, prefix 00101110 +static huffman_conv htab24_dec_ext3[ 8 ] = { + { 3, 11, 13, -1 }, // 000 -> 11/13, 3 bit used + { 3, 13, 11, -1 }, // 001 -> 13/11, 3 bit used + { 3, 12, 12, -1 }, // 010 -> 12/12, 3 bit used + { 3, 9, 14, -1 }, // 011 -> 9/14, 3 bit used + { 3, 14, 9, -1 }, // 100 -> 14/9, 3 bit used + { 3, 10, 13, -1 }, // 101 -> 10/13, 3 bit used + { 3, 13, 10, -1 }, // 110 -> 13/10, 3 bit used + { 3, 11, 12, -1 } // 111 -> 11/12, 3 bit used +}; +// extension table 4, prefix 00101111 +static huffman_conv htab24_dec_ext4[ 8 ] = { + { 3, 12, 11, -1 }, // 000 -> 12/11, 3 bit used + { 3, 8, 14, -1 }, // 001 -> 8/14, 3 bit used + { 3, 14, 8, -1 }, // 010 -> 14/8, 3 bit used + { 3, 9, 13, -1 }, // 011 -> 9/13, 3 bit used + { 3, 13, 9, -1 }, // 100 -> 13/9, 3 bit used + { 3, 7, 14, -1 }, // 101 -> 7/14, 3 bit used + { 3, 14, 7, -1 }, // 110 -> 14/7, 3 bit used + { 3, 10, 12, -1 } // 111 -> 10/12, 3 bit used +}; +// extension table 5, prefix 01000000 +static huffman_conv htab24_dec_ext5[ 16 ] = { + { 3, 12, 10, -1 }, // 0000 -> 12/10, 3 bit used + { 3, 12, 10, -1 }, // 0001 -> 12/10, 3 bit used + { 3, 11, 11, -1 }, // 0010 -> 11/11, 3 bit used + { 3, 11, 11, -1 }, // 0011 -> 11/11, 3 bit used + { 3, 8, 13, -1 }, // 0100 -> 8/13, 3 bit used + { 3, 8, 13, -1 }, // 0101 -> 8/13, 3 bit used + { 3, 13, 8, -1 }, // 0110 -> 13/8, 3 bit used + { 3, 13, 8, -1 }, // 0111 -> 13/8, 3 bit used + { 4, 0, 14, -1 }, // 1000 -> 0/14, 4 bit used + { 4, 14, 0, -1 }, // 1001 -> 14/0, 4 bit used + { 3, 0, 13, -1 }, // 1010 -> 0/13, 3 bit used + { 3, 0, 13, -1 }, // 1011 -> 0/13, 3 bit used + { 2, 14, 6, -1 }, // 1100 -> 14/6, 2 bit used + { 2, 14, 6, -1 }, // 1101 -> 14/6, 2 bit used + { 2, 14, 6, -1 }, // 1110 -> 14/6, 2 bit used + { 2, 14, 6, -1 } // 1111 -> 14/6, 2 bit used +}; +// extension table 6, prefix 01000001 +static huffman_conv htab24_dec_ext6[ 8 ] = { + { 3, 6, 14, -1 }, // 000 -> 6/14, 3 bit used + { 3, 9, 12, -1 }, // 001 -> 9/12, 3 bit used + { 2, 12, 9, -1 }, // 010 -> 12/9, 2 bit used + { 2, 12, 9, -1 }, // 011 -> 12/9, 2 bit used + { 2, 5, 14, -1 }, // 100 -> 5/14, 2 bit used + { 2, 5, 14, -1 }, // 101 -> 5/14, 2 bit used + { 2, 11, 10, -1 }, // 110 -> 11/10, 2 bit used + { 2, 11, 10, -1 } // 111 -> 11/10, 2 bit used +}; +// extension table 7, prefix 01000010 +static huffman_conv htab24_dec_ext7[ 8 ] = { + { 2, 14, 5, -1 }, // 000 -> 14/5, 2 bit used + { 2, 14, 5, -1 }, // 001 -> 14/5, 2 bit used + { 3, 10, 11, -1 }, // 010 -> 10/11, 3 bit used + { 3, 7, 13, -1 }, // 011 -> 7/13, 3 bit used + { 2, 13, 7, -1 }, // 100 -> 13/7, 2 bit used + { 2, 13, 7, -1 }, // 101 -> 13/7, 2 bit used + { 2, 14, 4, -1 }, // 110 -> 14/4, 2 bit used + { 2, 14, 4, -1 } // 111 -> 14/4, 2 bit used +}; +// extension table 8, prefix 01000011 +static huffman_conv htab24_dec_ext8[ 8 ] = { + { 2, 8, 12, -1 }, // 000 -> 8/12, 2 bit used + { 2, 8, 12, -1 }, // 001 -> 8/12, 2 bit used + { 2, 12, 8, -1 }, // 010 -> 12/8, 2 bit used + { 2, 12, 8, -1 }, // 011 -> 12/8, 2 bit used + { 3, 4, 14, -1 }, // 100 -> 4/14, 3 bit used + { 3, 2, 14, -1 }, // 101 -> 2/14, 3 bit used + { 2, 3, 14, -1 }, // 110 -> 3/14, 2 bit used + { 2, 3, 14, -1 } // 111 -> 3/14, 2 bit used +}; +// extension table 9, prefix 01000100 +static huffman_conv htab24_dec_ext9[ 4 ] = { + { 2, 6, 13, -1 }, // 00 -> 6/13, 2 bit used + { 2, 13, 6, -1 }, // 01 -> 13/6, 2 bit used + { 2, 14, 3, -1 }, // 10 -> 14/3, 2 bit used + { 2, 9, 11, -1 } // 11 -> 9/11, 2 bit used +}; +// extension table 10, prefix 01000101 +static huffman_conv htab24_dec_ext10[ 4 ] = { + { 2, 11, 9, -1 }, // 00 -> 11/9, 2 bit used + { 2, 10, 10, -1 }, // 01 -> 10/10, 2 bit used + { 2, 14, 2, -1 }, // 10 -> 14/2, 2 bit used + { 2, 1, 14, -1 } // 11 -> 1/14, 2 bit used +}; +// extension table 11, prefix 01000110 +static huffman_conv htab24_dec_ext11[ 4 ] = { + { 2, 14, 1, -1 }, // 00 -> 14/1, 2 bit used + { 2, 5, 13, -1 }, // 01 -> 5/13, 2 bit used + { 2, 13, 5, -1 }, // 10 -> 13/5, 2 bit used + { 2, 7, 12, -1 } // 11 -> 7/12, 2 bit used +}; +// extension table 12, prefix 01000111 +static huffman_conv htab24_dec_ext12[ 4 ] = { + { 2, 12, 7, -1 }, // 00 -> 12/7, 2 bit used + { 2, 4, 13, -1 }, // 01 -> 4/13, 2 bit used + { 2, 8, 11, -1 }, // 10 -> 8/11, 2 bit used + { 2, 11, 8, -1 } // 11 -> 11/8, 2 bit used +}; +// extension table 13, prefix 01001000 +static huffman_conv htab24_dec_ext13[ 4 ] = { + { 2, 13, 4, -1 }, // 00 -> 13/4, 2 bit used + { 2, 9, 10, -1 }, // 01 -> 9/10, 2 bit used + { 2, 10, 9, -1 }, // 10 -> 10/9, 2 bit used + { 2, 6, 12, -1 } // 11 -> 6/12, 2 bit used +}; +// extension table 14, prefix 01001001 +static huffman_conv htab24_dec_ext14[ 4 ] = { + { 2, 12, 6, -1 }, // 00 -> 12/6, 2 bit used + { 2, 3, 13, -1 }, // 01 -> 3/13, 2 bit used + { 2, 13, 3, -1 }, // 10 -> 13/3, 2 bit used + { 2, 2, 13, -1 } // 11 -> 2/13, 2 bit used +}; +// extension table 15, prefix 01001010 +static huffman_conv htab24_dec_ext15[ 4 ] = { + { 2, 13, 2, -1 }, // 00 -> 13/2, 2 bit used + { 2, 1, 13, -1 }, // 01 -> 1/13, 2 bit used + { 2, 7, 11, -1 }, // 10 -> 7/11, 2 bit used + { 2, 11, 7, -1 } // 11 -> 11/7, 2 bit used +}; +// extension table 16, prefix 01001011 +static huffman_conv htab24_dec_ext16[ 4 ] = { + { 2, 13, 1, -1 }, // 00 -> 13/1, 2 bit used + { 2, 5, 12, -1 }, // 01 -> 5/12, 2 bit used + { 2, 12, 5, -1 }, // 10 -> 12/5, 2 bit used + { 2, 8, 10, -1 } // 11 -> 8/10, 2 bit used +}; +// extension table 17, prefix 01001100 +static huffman_conv htab24_dec_ext17[ 4 ] = { + { 2, 10, 8, -1 }, // 00 -> 10/8, 2 bit used + { 2, 9, 9, -1 }, // 01 -> 9/9, 2 bit used + { 2, 4, 12, -1 }, // 10 -> 4/12, 2 bit used + { 2, 12, 4, -1 } // 11 -> 12/4, 2 bit used +}; +// extension table 18, prefix 01001101 +static huffman_conv htab24_dec_ext18[ 8 ] = { + { 2, 6, 11, -1 }, // 000 -> 6/11, 2 bit used + { 2, 6, 11, -1 }, // 001 -> 6/11, 2 bit used + { 2, 11, 6, -1 }, // 010 -> 11/6, 2 bit used + { 2, 11, 6, -1 }, // 011 -> 11/6, 2 bit used + { 3, 13, 0, -1 }, // 100 -> 13/0, 3 bit used + { 3, 0, 12, -1 }, // 101 -> 0/12, 3 bit used + { 2, 3, 12, -1 }, // 110 -> 3/12, 2 bit used + { 2, 3, 12, -1 } // 111 -> 3/12, 2 bit used +}; +// extension table 19, prefix 01001110 +static huffman_conv htab24_dec_ext19[ 4 ] = { + { 2, 12, 3, -1 }, // 00 -> 12/3, 2 bit used + { 2, 7, 10, -1 }, // 01 -> 7/10, 2 bit used + { 2, 10, 7, -1 }, // 10 -> 10/7, 2 bit used + { 2, 2, 12, -1 } // 11 -> 2/12, 2 bit used +}; +// extension table 20, prefix 01001111 +static huffman_conv htab24_dec_ext20[ 4 ] = { + { 2, 12, 2, -1 }, // 00 -> 12/2, 2 bit used + { 2, 5, 11, -1 }, // 01 -> 5/11, 2 bit used + { 2, 11, 5, -1 }, // 10 -> 11/5, 2 bit used + { 2, 1, 12, -1 } // 11 -> 1/12, 2 bit used +}; +// extension table 21, prefix 01010000 +static huffman_conv htab24_dec_ext21[ 4 ] = { + { 2, 8, 9, -1 }, // 00 -> 8/9, 2 bit used + { 2, 9, 8, -1 }, // 01 -> 9/8, 2 bit used + { 2, 12, 1, -1 }, // 10 -> 12/1, 2 bit used + { 2, 4, 11, -1 } // 11 -> 4/11, 2 bit used +}; +// extension table 22, prefix 01010001 +static huffman_conv htab24_dec_ext22[ 8 ] = { + { 3, 12, 0, -1 }, // 000 -> 12/0, 3 bit used + { 3, 0, 11, -1 }, // 001 -> 0/11, 3 bit used + { 2, 3, 11, -1 }, // 010 -> 3/11, 2 bit used + { 2, 3, 11, -1 }, // 011 -> 3/11, 2 bit used + { 3, 11, 0, -1 }, // 100 -> 11/0, 3 bit used + { 3, 0, 10, -1 }, // 101 -> 0/10, 3 bit used + { 2, 1, 10, -1 }, // 110 -> 1/10, 2 bit used + { 2, 1, 10, -1 } // 111 -> 1/10, 2 bit used +}; +// extension table 23, prefix 01010010 +static huffman_conv htab24_dec_ext23[ 4 ] = { + { 1, 11, 4, -1 }, // 00 -> 11/4, 1 bit used + { 1, 11, 4, -1 }, // 01 -> 11/4, 1 bit used + { 2, 6, 10, -1 }, // 10 -> 6/10, 2 bit used + { 2, 10, 6, -1 } // 11 -> 10/6, 2 bit used +}; +// extension table 24, prefix 01010011 +static huffman_conv htab24_dec_ext24[ 8 ] = { + { 2, 7, 9, -1 }, // 000 -> 7/9, 2 bit used + { 2, 7, 9, -1 }, // 001 -> 7/9, 2 bit used + { 2, 9, 7, -1 }, // 010 -> 9/7, 2 bit used + { 2, 9, 7, -1 }, // 011 -> 9/7, 2 bit used + { 3, 10, 0, -1 }, // 100 -> 10/0, 3 bit used + { 3, 0, 9, -1 }, // 101 -> 0/9, 3 bit used + { 2, 9, 0, -1 }, // 110 -> 9/0, 2 bit used + { 2, 9, 0, -1 } // 111 -> 9/0, 2 bit used +}; +// extension table 25, prefix 01010100 +static huffman_conv htab24_dec_ext25[ 2 ] = { + { 1, 11, 3, -1 }, // 0 -> 11/3, 1 bit used + { 1, 8, 8, -1 } // 1 -> 8/8, 1 bit used +}; +// extension table 26, prefix 01010101 +static huffman_conv htab24_dec_ext26[ 4 ] = { + { 2, 2, 11, -1 }, // 00 -> 2/11, 2 bit used + { 2, 5, 10, -1 }, // 01 -> 5/10, 2 bit used + { 1, 11, 2, -1 }, // 10 -> 11/2, 1 bit used + { 1, 11, 2, -1 } // 11 -> 11/2, 1 bit used +}; +// extension table 27, prefix 01010110 +static huffman_conv htab24_dec_ext27[ 4 ] = { + { 2, 10, 5, -1 }, // 00 -> 10/5, 2 bit used + { 2, 1, 11, -1 }, // 01 -> 1/11, 2 bit used + { 2, 11, 1, -1 }, // 10 -> 11/1, 2 bit used + { 2, 6, 9, -1 } // 11 -> 6/9, 2 bit used +}; +// extension table 28, prefix 01010111 +static huffman_conv htab24_dec_ext28[ 2 ] = { + { 1, 9, 6, -1 }, // 0 -> 9/6, 1 bit used + { 1, 10, 4, -1 } // 1 -> 10/4, 1 bit used +}; +// extension table 29, prefix 01011000 +static huffman_conv htab24_dec_ext29[ 4 ] = { + { 2, 4, 10, -1 }, // 00 -> 4/10, 2 bit used + { 2, 7, 8, -1 }, // 01 -> 7/8, 2 bit used + { 1, 8, 7, -1 }, // 10 -> 8/7, 1 bit used + { 1, 8, 7, -1 } // 11 -> 8/7, 1 bit used +}; +// extension table 30, prefix 01011001 +static huffman_conv htab24_dec_ext30[ 2 ] = { + { 1, 3, 10, -1 }, // 0 -> 3/10, 1 bit used + { 1, 10, 3, -1 } // 1 -> 10/3, 1 bit used +}; +// extension table 31, prefix 01011010 +static huffman_conv htab24_dec_ext31[ 2 ] = { + { 1, 5, 9, -1 }, // 0 -> 5/9, 1 bit used + { 1, 9, 5, -1 } // 1 -> 9/5, 1 bit used +}; +// extension table 32, prefix 01011011 +static huffman_conv htab24_dec_ext32[ 2 ] = { + { 1, 2, 10, -1 }, // 0 -> 2/10, 1 bit used + { 1, 10, 2, -1 } // 1 -> 10/2, 1 bit used +}; +// extension table 33, prefix 01011100 +static huffman_conv htab24_dec_ext33[ 2 ] = { + { 1, 10, 1, -1 }, // 0 -> 10/1, 1 bit used + { 1, 6, 8, -1 } // 1 -> 6/8, 1 bit used +}; +// extension table 34, prefix 01011101 +static huffman_conv htab24_dec_ext34[ 2 ] = { + { 1, 8, 6, -1 }, // 0 -> 8/6, 1 bit used + { 1, 7, 7, -1 } // 1 -> 7/7, 1 bit used +}; +// extension table 35, prefix 01011110 +static huffman_conv htab24_dec_ext35[ 2 ] = { + { 1, 4, 9, -1 }, // 0 -> 4/9, 1 bit used + { 1, 9, 4, -1 } // 1 -> 9/4, 1 bit used +}; +// extension table 36, prefix 01011111 +static huffman_conv htab24_dec_ext36[ 2 ] = { + { 1, 3, 9, -1 }, // 0 -> 3/9, 1 bit used + { 1, 9, 3, -1 } // 1 -> 9/3, 1 bit used +}; +// extension table 37, prefix 01100000 +static huffman_conv htab24_dec_ext37[ 2 ] = { + { 1, 5, 8, -1 }, // 0 -> 5/8, 1 bit used + { 1, 8, 5, -1 } // 1 -> 8/5, 1 bit used +}; +// extension table 38, prefix 01100001 +static huffman_conv htab24_dec_ext38[ 2 ] = { + { 1, 2, 9, -1 }, // 0 -> 2/9, 1 bit used + { 1, 6, 7, -1 } // 1 -> 6/7, 1 bit used +}; +// extension table 39, prefix 01100010 +static huffman_conv htab24_dec_ext39[ 2 ] = { + { 1, 7, 6, -1 }, // 0 -> 7/6, 1 bit used + { 1, 9, 2, -1 } // 1 -> 9/2, 1 bit used +}; +// extension table 40, prefix 01100011 +static huffman_conv htab24_dec_ext40[ 2 ] = { + { 1, 1, 9, -1 }, // 0 -> 1/9, 1 bit used + { 1, 9, 1, -1 } // 1 -> 9/1, 1 bit used +}; +// extension table 41, prefix 01100100 +static huffman_conv htab24_dec_ext41[ 2 ] = { + { 1, 4, 8, -1 }, // 0 -> 4/8, 1 bit used + { 1, 8, 4, -1 } // 1 -> 8/4, 1 bit used +}; +// extension table 42, prefix 01100101 +static huffman_conv htab24_dec_ext42[ 2 ] = { + { 1, 5, 7, -1 }, // 0 -> 5/7, 1 bit used + { 1, 7, 5, -1 } // 1 -> 7/5, 1 bit used +}; +// extension table 43, prefix 01100110 +static huffman_conv htab24_dec_ext43[ 2 ] = { + { 1, 3, 8, -1 }, // 0 -> 3/8, 1 bit used + { 1, 8, 3, -1 } // 1 -> 8/3, 1 bit used +}; +// extension table 44, prefix 01100111 +static huffman_conv htab24_dec_ext44[ 2 ] = { + { 1, 6, 6, -1 }, // 0 -> 6/6, 1 bit used + { 1, 2, 8, -1 } // 1 -> 2/8, 1 bit used +}; +// extension table 45, prefix 01101000 +static huffman_conv htab24_dec_ext45[ 2 ] = { + { 1, 8, 2, -1 }, // 0 -> 8/2, 1 bit used + { 1, 1, 8, -1 } // 1 -> 1/8, 1 bit used +}; +// extension table 46, prefix 01101001 +static huffman_conv htab24_dec_ext46[ 2 ] = { + { 1, 4, 7, -1 }, // 0 -> 4/7, 1 bit used + { 1, 7, 4, -1 } // 1 -> 7/4, 1 bit used +}; +// extension table 47, prefix 01101010 +static huffman_conv htab24_dec_ext47[ 4 ] = { + { 1, 8, 1, -1 }, // 00 -> 8/1, 1 bit used + { 1, 8, 1, -1 }, // 01 -> 8/1, 1 bit used + { 2, 0, 8, -1 }, // 10 -> 0/8, 2 bit used + { 2, 8, 0, -1 } // 11 -> 8/0, 2 bit used +}; +// extension table 48, prefix 01101011 +static huffman_conv htab24_dec_ext48[ 2 ] = { + { 1, 5, 6, -1 }, // 0 -> 5/6, 1 bit used + { 1, 6, 5, -1 } // 1 -> 6/5, 1 bit used +}; +// extension table 49, prefix 01101100 +static huffman_conv htab24_dec_ext49[ 4 ] = { + { 1, 1, 7, -1 }, // 00 -> 1/7, 1 bit used + { 1, 1, 7, -1 }, // 01 -> 1/7, 1 bit used + { 2, 0, 7, -1 }, // 10 -> 0/7, 2 bit used + { 2, 7, 0, -1 } // 11 -> 7/0, 2 bit used +}; +// extension table 50, prefix 01101110 +static huffman_conv htab24_dec_ext50[ 2 ] = { + { 1, 3, 7, -1 }, // 0 -> 3/7, 1 bit used + { 1, 2, 7, -1 } // 1 -> 2/7, 1 bit used +}; +// extension table 51, prefix 01111100 +static huffman_conv htab24_dec_ext51[ 2 ] = { + { 1, 0, 6, -1 }, // 0 -> 0/6, 1 bit used + { 1, 6, 0, -1 } // 1 -> 6/0, 1 bit used +}; +// extension table 52, prefix 10000011 +static huffman_conv htab24_dec_ext52[ 2 ] = { + { 1, 0, 5, -1 }, // 0 -> 0/5, 1 bit used + { 1, 5, 0, -1 } // 1 -> 5/0, 1 bit used +}; +// big values conversion table #24, total size: 470, ext tables: 52 +static huffman_conv_set htab24_dec[ 53 ] = { + { htab24_dec_start, 8 }, // start table + { htab24_dec_ext1, 3 }, // ext table #1 + { htab24_dec_ext2, 3 }, // ext table #2 + { htab24_dec_ext3, 3 }, // ext table #3 + { htab24_dec_ext4, 3 }, // ext table #4 + { htab24_dec_ext5, 4 }, // ext table #5 + { htab24_dec_ext6, 3 }, // ext table #6 + { htab24_dec_ext7, 3 }, // ext table #7 + { htab24_dec_ext8, 3 }, // ext table #8 + { htab24_dec_ext9, 2 }, // ext table #9 + { htab24_dec_ext10, 2 }, // ext table #10 + { htab24_dec_ext11, 2 }, // ext table #11 + { htab24_dec_ext12, 2 }, // ext table #12 + { htab24_dec_ext13, 2 }, // ext table #13 + { htab24_dec_ext14, 2 }, // ext table #14 + { htab24_dec_ext15, 2 }, // ext table #15 + { htab24_dec_ext16, 2 }, // ext table #16 + { htab24_dec_ext17, 2 }, // ext table #17 + { htab24_dec_ext18, 3 }, // ext table #18 + { htab24_dec_ext19, 2 }, // ext table #19 + { htab24_dec_ext20, 2 }, // ext table #20 + { htab24_dec_ext21, 2 }, // ext table #21 + { htab24_dec_ext22, 3 }, // ext table #22 + { htab24_dec_ext23, 2 }, // ext table #23 + { htab24_dec_ext24, 3 }, // ext table #24 + { htab24_dec_ext25, 1 }, // ext table #25 + { htab24_dec_ext26, 2 }, // ext table #26 + { htab24_dec_ext27, 2 }, // ext table #27 + { htab24_dec_ext28, 1 }, // ext table #28 + { htab24_dec_ext29, 2 }, // ext table #29 + { htab24_dec_ext30, 1 }, // ext table #30 + { htab24_dec_ext31, 1 }, // ext table #31 + { htab24_dec_ext32, 1 }, // ext table #32 + { htab24_dec_ext33, 1 }, // ext table #33 + { htab24_dec_ext34, 1 }, // ext table #34 + { htab24_dec_ext35, 1 }, // ext table #35 + { htab24_dec_ext36, 1 }, // ext table #36 + { htab24_dec_ext37, 1 }, // ext table #37 + { htab24_dec_ext38, 1 }, // ext table #38 + { htab24_dec_ext39, 1 }, // ext table #39 + { htab24_dec_ext40, 1 }, // ext table #40 + { htab24_dec_ext41, 1 }, // ext table #41 + { htab24_dec_ext42, 1 }, // ext table #42 + { htab24_dec_ext43, 1 }, // ext table #43 + { htab24_dec_ext44, 1 }, // ext table #44 + { htab24_dec_ext45, 1 }, // ext table #45 + { htab24_dec_ext46, 1 }, // ext table #46 + { htab24_dec_ext47, 2 }, // ext table #47 + { htab24_dec_ext48, 1 }, // ext table #48 + { htab24_dec_ext49, 2 }, // ext table #49 + { htab24_dec_ext50, 1 }, // ext table #50 + { htab24_dec_ext51, 1 }, // ext table #51 + { htab24_dec_ext52, 1 } // ext table #52 +}; + + +/* ----------------------------------------------- + huffman tables for encoding of big values + ----------------------------------------------- */ +static huffman_enc_table bv_enc_table[ 32 ] = { + { htab0_enc, 0, 0 + 0 }, // table 0 + { htab1_enc, 0, 1 + 0 }, // table 1 + { htab2_enc, 0, 2 + 0 }, // table 2 + { htab3_enc, 0, 2 + 0 }, // table 3 + { NULL, 0, 0 + 0 }, // not used + { htab5_enc, 0, 3 + 0 }, // table 5 + { htab6_enc, 0, 3 + 0 }, // table 6 + { htab7_enc, 0, 5 + 0 }, // table 7 + { htab8_enc, 0, 5 + 0 }, // table 8 + { htab9_enc, 0, 5 + 0 }, // table 9 + { htab10_enc, 0, 7 + 0 }, // table 10 + { htab11_enc, 0, 7 + 0 }, // table 11 + { htab12_enc, 0, 7 + 0 }, // table 12 + { htab13_enc, 0, 15 + 0 }, // table 13 + { NULL, 0, 0 + 0 }, // not used + { htab15_enc, 0, 15 + 0 }, // table 15 + { htab16_enc, 1, 15 + 1 }, // table 16 + { htab16_enc, 2, 15 + 3 }, // table 17 + { htab16_enc, 3, 15 + 7 }, // table 18 + { htab16_enc, 4, 15 + 15 }, // table 19 + { htab16_enc, 6, 15 + 63 }, // table 20 + { htab16_enc, 8, 15 + 255 }, // table 21 + { htab16_enc, 10, 15 + 1023 }, // table 22 + { htab16_enc, 13, 15 + 8191 }, // table 23 + { htab24_enc, 4, 15 + 15 }, // table 24 + { htab24_enc, 5, 15 + 31 }, // table 25 + { htab24_enc, 6, 15 + 63 }, // table 26 + { htab24_enc, 7, 15 + 127 }, // table 27 + { htab24_enc, 8, 15 + 255 }, // table 28 + { htab24_enc, 9, 15 + 511 }, // table 29 + { htab24_enc, 11, 15 + 2047 }, // table 30 + { htab24_enc, 13, 15 + 8191 } // table 31 +}; + + +/* ----------------------------------------------- + huffman tables for decoding of big values + ----------------------------------------------- */ +static huffman_dec_table bv_dec_table[ 32 ] = { + { htab0_dec, 0, 0 + 0 }, // table 0 + { htab1_dec, 0, 1 + 0 }, // table 1 + { htab2_dec, 0, 2 + 0 }, // table 2 + { htab3_dec, 0, 2 + 0 }, // table 3 + { NULL, 0, 0 + 0 }, // not used + { htab5_dec, 0, 3 + 0 }, // table 5 + { htab6_dec, 0, 3 + 0 }, // table 6 + { htab7_dec, 0, 5 + 0 }, // table 7 + { htab8_dec, 0, 5 + 0 }, // table 8 + { htab9_dec, 0, 5 + 0 }, // table 9 + { htab10_dec, 0, 7 + 0 }, // table 10 + { htab11_dec, 0, 7 + 0 }, // table 11 + { htab12_dec, 0, 7 + 0 }, // table 12 + { htab13_dec, 0, 15 + 0 }, // table 13 + { NULL, 0, 0 + 0 }, // not used + { htab15_dec, 0, 15 + 0 }, // table 15 + { htab16_dec, 1, 15 + 1 }, // table 16 + { htab16_dec, 2, 15 + 3 }, // table 17 + { htab16_dec, 3, 15 + 7 }, // table 18 + { htab16_dec, 4, 15 + 15 }, // table 19 + { htab16_dec, 6, 15 + 63 }, // table 20 + { htab16_dec, 8, 15 + 255 }, // table 21 + { htab16_dec, 10, 15 + 1023 }, // table 22 + { htab16_dec, 13, 15 + 8191 }, // table 23 + { htab24_dec, 4, 15 + 15 }, // table 24 + { htab24_dec, 5, 15 + 31 }, // table 25 + { htab24_dec, 6, 15 + 63 }, // table 26 + { htab24_dec, 7, 15 + 127 }, // table 27 + { htab24_dec, 8, 15 + 255 }, // table 28 + { htab24_dec, 9, 15 + 511 }, // table 29 + { htab24_dec, 11, 15 + 2047 }, // table 30 + { htab24_dec, 13, 15 + 8191 } // table 31 +}; + diff --git a/contrib/packmp3/packmp3.cpp b/contrib/packmp3/packmp3.cpp new file mode 100644 index 0000000..2934f80 --- /dev/null +++ b/contrib/packmp3/packmp3.cpp @@ -0,0 +1,8142 @@ +#include +#include +#include + +#include "pmp3tbl.h" +#include "pmp3bitlen.h" +#include "bitops.h" +#include "aricoder.h" +#include "huffmp3.h" +#include "huffmp3tbl.h" + +#if defined BUILD_DLL // define BUILD_LIB from the compiler options if you want to compile a DLL! + #define BUILD_LIB +#endif + +#if defined BUILD_LIB // define BUILD_LIB from the compiler options if you want to compile a library! + #include "packmp3lib.h" +#endif + +#define INTERN static + +#define INIT_MODEL_S(a,b,c) new model_s( a, b, c, 511 ) +#define INIT_MODEL_B(a,b) new model_b( a, b, 511 ) + +#define ABS(v1) ( (v1 < 0) ? -v1 : v1 ) +#define ABSDIFF(v1,v2) ( (v1 > v2) ? (v1 - v2) : (v2 - v1) ) +#define ROUND_F(v1) ( (v1 < 0) ? (int) (v1 - 0.5) : (int) (v1 + 0.5) ) +#define CLAMPED(l,h,v) ( ( v < l ) ? l : ( v > h ) ? h : v ) + +#define MEM_ERRMSG "out of memory error" +#define FRD_ERRMSG "could not read file / file not found" +#define FWR_ERRMSG "could not write file / file write-protected" +#define MSG_SIZE 128 +#define BARLEN 36 + +// special realloc with guaranteed free() of previous memory +static inline void* frealloc( void* ptr, size_t size ) { + void* n_ptr = realloc( ptr, size ); + if ( n_ptr == NULL ) free( ptr ); + return n_ptr; +} + + + +/* ----------------------------------------------- + function declarations: main interface + ----------------------------------------------- */ +#if !defined( BUILD_LIB ) +INTERN void initialize_options( int argc, char** argv ); +INTERN void process_ui( void ); +INTERN inline const char* get_status( bool (*function)() ); +INTERN void show_help( void ); +#endif +INTERN void process_file( void ); +INTERN void execute( bool (*function)() ); + + +/* ----------------------------------------------- + function declarations: main functions + ----------------------------------------------- */ +#if !defined( BUILD_LIB ) +INTERN bool check_file( void ); +INTERN bool swap_streams( void ); +INTERN bool compare_output( void ); +#endif +INTERN bool reset_buffers( void ); +INTERN bool read_mp3( void ); +INTERN bool write_mp3( void ); +INTERN bool analyze_frames( void ); +INTERN bool compress_mp3( void ); +INTERN bool uncompress_pmp( void ); + + +/* ----------------------------------------------- + function declarations: MP3-specific + ----------------------------------------------- */ + +INTERN inline mp3Frame* mp3_read_frame( unsigned char* data, int max_size ); +INTERN inline mp3Frame* mp3_build_frame( void ); +INTERN inline bool mp3_append_frame( mp3Frame* frame ); +INTERN inline bool mp3_discard_frame( mp3Frame* frame ); +INTERN inline bool mp3_mute_frame( mp3Frame* frame ); +INTERN inline bool mp3_unmute_frame( mp3Frame* frame ); +INTERN inline unsigned char* mp3_build_fixed( mp3Frame* frame ); +INTERN inline int mp3_seek_firstframe( unsigned char* data, int size ); +INTERN inline int mp3_get_id3_size( unsigned char* id3tag, int max_size ); +INTERN inline unsigned short mp3_calc_layer3_crc( unsigned char* header, unsigned char* sideinfo, int sidesize ); +INTERN inline granuleData*** mp3_decode_frame( huffman_reader* dec, mp3Frame* frame ); + + +/* ----------------------------------------------- + function declarations: PMP-specific + ----------------------------------------------- */ + +INTERN inline bool pmp_write_header( iostream* str ); +INTERN inline bool pmp_read_header( iostream* str ); +#if !defined( STORE_ID3 ) +INTERN inline bool pmp_encode_id3( aricoder* enc ); +INTERN inline bool pmp_decode_id3( aricoder* dec ); +#else +INTERN inline int pmp_store_data( iostream* str, unsigned char* data, int size ); +INTERN inline int pmp_unstore_data( iostream* str, unsigned char** data ); +#endif +INTERN inline bool pmp_encode_padding( aricoder* enc ); +INTERN inline bool pmp_decode_padding( aricoder* dec ); +INTERN inline bool pmp_encode_block_types( aricoder* enc ); +INTERN inline bool pmp_decode_block_types( aricoder* dec ); +INTERN inline bool pmp_decode_stereo_ms( aricoder* dec ); +INTERN inline bool pmp_encode_global_gain( aricoder* enc ); +INTERN inline bool pmp_decode_global_gain( aricoder* dec ); +INTERN inline bool pmp_encode_slength( aricoder* enc ); +INTERN inline bool pmp_decode_slength( aricoder* dec ); +INTERN inline bool pmp_encode_stereo_ms( aricoder* enc ); +INTERN inline bool pmp_decode_stereo_ms( aricoder* dec ); +INTERN inline bool pmp_encode_region_data( aricoder* enc ); +INTERN inline bool pmp_decode_region_data( aricoder* dec ); +INTERN inline bool pmp_encode_sharing( aricoder* enc ); +INTERN inline bool pmp_decode_sharing( aricoder* dec ); +INTERN inline bool pmp_encode_preemphasis( aricoder* enc ); +INTERN inline bool pmp_decode_preemphasis( aricoder* dec ); +INTERN inline bool pmp_encode_coarse_sf( aricoder* enc ); +INTERN inline bool pmp_decode_coarse_sf( aricoder* dec ); +INTERN inline bool pmp_encode_subblock_gain( aricoder* enc ); +INTERN inline bool pmp_decode_subblock_gain( aricoder* dec ); +INTERN inline bool pmp_encode_main_data( aricoder* enc ); +INTERN inline bool pmp_decode_main_data( aricoder* dec ); +INTERN inline bool pmp_store_unmute_data( iostream* str ); +INTERN inline bool pmp_unstore_unmute_data( iostream* str ); +INTERN inline bool pmp_build_context( void ); +INTERN inline unsigned char* pmp_predict_lame_anc( int nbits, unsigned char* ref ); + + +/* ----------------------------------------------- + function declarations: miscelaneous helpers + ----------------------------------------------- */ +#if !defined( BUILD_LIB ) +INTERN inline void progress_bar( int current, int last ); +INTERN inline char* create_filename( const char* base, const char* extension ); +INTERN inline char* unique_filename( const char* base, const char* extension ); +INTERN inline void set_extension( const char* filename, const char* extension ); +INTERN inline void add_underscore( char* filename ); +#endif +INTERN inline bool file_exists( const char* filename ); + + +/* ----------------------------------------------- + function declarations: developers functions + ----------------------------------------------- */ + +// these are developers functions, they are not needed +// in any way to compress MP3 or decompress PMP +#if !defined(BUILD_LIB) && defined(DEV_BUILD) +INTERN bool write_file( const char* base, const char* ext, void* data, int bpv, int size ); +INTERN bool write_errfile( void ); +INTERN bool write_file_analysis( void ); +INTERN bool write_block_analysis( void ); +INTERN bool write_stat_analysis( void ); +INTERN bool visualize_headers( void ); +INTERN bool visualize_decoded_data( void ); +INTERN bool dump_main_sizes( void ); +INTERN bool dump_aux_sizes( void ); +INTERN bool dump_bitrates( void ); +INTERN bool dump_stereo_ms( void ); +INTERN bool dump_padding( void ); +INTERN bool dump_main_data_bits( void ); +INTERN bool dump_big_value_ns( void ); +INTERN bool dump_global_gain( void ); +INTERN bool dump_slength( void ); +INTERN bool dump_block_types( void ); +INTERN bool dump_sharing( void ); +INTERN bool dump_preemphasis( void ); +INTERN bool dump_coarse( void ); +INTERN bool dump_htable_sel( void ); +INTERN bool dump_region_sizes( void ); +INTERN bool dump_subblock_gains( void ); +INTERN bool dump_data_files( void ); +INTERN bool dump_gg_ctx( void ); +INTERN bool dump_decoded_data( void ); +#endif + + +/* ----------------------------------------------- + global variables: library only variables + ----------------------------------------------- */ +#if defined(BUILD_LIB) +INTERN int lib_in_type = -1; +INTERN int lib_out_type = -1; +#endif + + +/* ----------------------------------------------- + global variables: data storage + ----------------------------------------------- */ + +INTERN mp3Frame* firstframe = NULL; // first physical frame +INTERN mp3Frame* lastframe = NULL; // last physical frame +INTERN unsigned char* main_data = NULL; // (mainly) huffman coded data +INTERN unsigned char* data_before = NULL; // data before (should be ID3v2 tag) +INTERN unsigned char* data_after = NULL; // data after (should be ID3v1 or ID3v2 tag) +INTERN unsigned char* unmute_data = NULL; // fix data (to reverse muted frames) +INTERN int main_data_size = 0 ; // size of main data +INTERN int data_before_size = 0 ; // size of data before +INTERN int data_after_size = 0 ; // size of data after +INTERN int unmute_data_size = 0 ; // size of fix data +INTERN int n_bad_first = 0 ; // # of bad first frames (should be zero!) +INTERN unsigned char* gg_context[2] = {NULL}; // universal context based on global gain + +/* ----------------------------------------------- + global variables: info about audio file + ----------------------------------------------- */ + +INTERN int g_nframes = 0; // number of frames +INTERN int g_nchannels = 0; // number of channels +INTERN int g_samplerate = 0; // sample rate +INTERN int g_bitrate = 0; // bit rate - global or zero for vbr + + +/* ----------------------------------------------- + global variables: frame analysis info + ----------------------------------------------- */ + +INTERN char i_mpeg = -1; // mpeg - non changing +INTERN char i_layer = -1; // layer - non changing +INTERN char i_samplerate = -1; // sample rate - non changing +INTERN char i_bitrate = -1; // bit rate - value or -1 (variable) +INTERN char i_protection = -1; // checksum - for all (1), none (0) or some (-1) frames +INTERN char i_padding = -1; // padding - for all (1), none (0) or some (-1) frames +INTERN char i_privbit = -1; // private bit - value or -1 (variable) +INTERN char i_channels = -1; // channel mode - non changing +INTERN char i_stereo_ms = -1; // ms stereo - for all (1), none (0) or some (-1) frames +INTERN char i_stereo_int = -1; // int stereo - for all (1), none (0) or some (-1) frames +INTERN char i_copyright = -1; // copyright bit - value or -1 (variable) +INTERN char i_original = -1; // original bit - value or -1 (variable) +INTERN char i_emphasis = -1; // emphasis - value or -1 (variable) +INTERN char i_padbits = -1; // side info padding bits - value or -1 (variable) +INTERN char i_bit_res = -1; // bit reservoir - is used (1) or not used (0) +INTERN char i_share = -1; // scalefactor sharing - is used (1) or not used (0) +INTERN char i_sblocks = -1; // special blocks - are used (1) or not used (0) +INTERN char i_mixed = -1; // mixed blocks - are used (1) or not used (0) +INTERN char i_preemphasis = -1; // preemphasis - value or -1 (variable) +INTERN char i_coarse = -1; // coarse scalefactors - value or -1 (variable) +INTERN char i_sbgain = -1; // subblock gain - used properly (1), not used (0) or used for non-short (-1) +INTERN char i_aux_h = -1; // auxiliary data handling - none (0), at begin and end (1), between frames (-1) +INTERN char i_sb_diff = -1; // special blocks diffs between ch0 and ch1 - none (0) or some (-1) + + +/* ----------------------------------------------- + global variables: info about files + ----------------------------------------------- */ + +INTERN char* mp3filename = NULL; // name of MP3 file +INTERN char* pmpfilename = NULL; // name of PMP file +INTERN int mp3filesize; // size of MP3 file +INTERN int pmpfilesize; // size of PMP file +INTERN int filetype; // type of current file +INTERN iostream* str_in = NULL; // input stream +INTERN iostream* str_out = NULL; // output stream + +#if !defined(BUILD_LIB) +INTERN iostream* str_str = NULL; // storage stream + +INTERN char** filelist = NULL; // list of files to process +INTERN int file_cnt = 0; // count of files in list +INTERN int file_no = 0; // number of current file + +INTERN char** err_list = NULL; // list of error messages +INTERN int* err_tp = NULL; // list of error types +#endif + + +/* ----------------------------------------------- + global variables: messages + ----------------------------------------------- */ + +INTERN char errormessage [ 128 ]; +INTERN bool (*errorfunction)(); +INTERN int errorlevel; +// meaning of errorlevel: +// -1 -> wrong input +// 0 -> no error +// 1 -> warning +// 2 -> fatal error + + +/* ----------------------------------------------- + global variables: settings + ----------------------------------------------- */ + +#if !defined( BUILD_LIB ) +INTERN int verbosity = -1; // level of verbosity +INTERN bool overwrite = false; // overwrite files yes / no +INTERN bool wait_exit = true; // pause after finished yes / no +INTERN int verify_lv = 0; // verification level ( none (0), simple (1), detailed output (2) ) +INTERN int err_tol = 1; // error threshold ( proceed on warnings yes (2) / no (1) ) + +INTERN bool developer = false; // allow developers functions yes/no +INTERN int action = A_COMPRESS;// what to do with MP3/PMP files + +INTERN FILE* msgout = stdout; // stream for output of messages +INTERN bool pipe_on = false; // use stdin/stdout instead of filelist +#else +INTERN int err_tol = 1; // error threshold ( proceed on warnings yes (2) / no (1) ) +INTERN int action = A_COMPRESS;// what to do with MP3/PMP files +#endif + + + +/* ----------------------------------------------- + global variables: info about program + ----------------------------------------------- */ + +INTERN const unsigned char appversion = 10; +INTERN const char* subversion = "f"; +INTERN const char* apptitle = "packMP3"; +INTERN const char* appname = "packMP3"; +INTERN const char* versiondate = "11/21/2014"; +INTERN const char* author = "Matthias Stirner"; +#if !defined( BUILD_LIB ) +INTERN const char* website = "http://packjpg.encode.ru/"; +INTERN const char* email = "packjpg@htw-aalen.de"; +INTERN const char* copyright = "2010-2014 Ratisbon University & Matthias Stirner"; +INTERN const char* pmp_ext = "pmp"; +INTERN const char* mp3_ext = "mp3"; +#endif +INTERN const char pmp_magic[] = { 'M', 'S' }; + + +/* ----------------------------------------------- + main-function + ----------------------------------------------- */ + +#if !defined(BUILD_LIB) +int main( int argc, char** argv ) +{ + sprintf( errormessage, "no errormessage specified" ); + + clock_t begin, end; + + int error_cnt = 0; + int warn_cnt = 0; + + double acc_mp3size = 0; + double acc_pmpsize = 0; + + int kbps; + double cr; + double total; + + errorlevel = 0; + + + // read options from command line + initialize_options( argc, argv ); + + // write program info to screen + fprintf( msgout, "\n--> %s v%i.%i%s (%s) by %s <--\n", + apptitle, appversion / 10, appversion % 10, subversion, versiondate, author ); + fprintf( msgout, "Copyright %s\nAll rights reserved\n\n", copyright ); + + // check if user input is wrong, show help screen if it is + if ( ( file_cnt == 0 ) || + ( ( !developer ) && ( (action != A_COMPRESS) || (verify_lv > 1) ) ) ) { + show_help(); + return -1; + } + + // (re)set program has to be done first + reset_buffers(); + + // process file(s) - this is the main function routine + begin = clock(); + for ( file_no = 0; file_no < file_cnt; file_no++ ) { + // process current file + process_ui(); + // store error message and type if any + if ( errorlevel > 0 ) { + err_list[ file_no ] = (char*) calloc( MSG_SIZE, sizeof( char ) ); + err_tp[ file_no ] = errorlevel; + if ( err_list[ file_no ] != NULL ) + strcpy( err_list[ file_no ], errormessage ); + } + // count errors / warnings / file sizes + if ( errorlevel >= err_tol ) error_cnt++; + else { + if ( errorlevel == 1 ) warn_cnt++; + acc_mp3size += mp3filesize; + acc_pmpsize += pmpfilesize; + } + } + end = clock(); + + // errors summary: only needed for -v2 or progress bar + if ( ( verbosity == -1 ) || ( verbosity == 2 ) ) { + // print summary of errors to screen + if ( error_cnt > 0 ) { + fprintf( stderr, "\n\nfiles with errors:\n" ); + fprintf( stderr, "------------------\n" ); + for ( file_no = 0; file_no < file_cnt; file_no++ ) { + if ( err_tp[ file_no ] >= err_tol ) { + fprintf( stderr, "%s (%s)\n", filelist[ file_no ], err_list[ file_no ] ); + } + } + } + // print summary of warnings to screen + if ( warn_cnt > 0 ) { + fprintf( stderr, "\n\nfiles with warnings:\n" ); + fprintf( stderr, "------------------\n" ); + for ( file_no = 0; file_no < file_cnt; file_no++ ) { + if ( err_tp[ file_no ] == 1 ) { + fprintf( stderr, "%s (%s)\n", filelist[ file_no ], err_list[ file_no ] ); + } + } + } + } + + // show statistics + fprintf( msgout, "\n\n-> %i file(s) processed, %i error(s), %i warning(s)\n", + file_cnt, error_cnt, warn_cnt ); + if ( ( file_cnt > error_cnt ) && ( verbosity != 0 ) && ( action == A_COMPRESS ) ) { + acc_mp3size /= 1024.0; acc_pmpsize /= 1024.0; + total = (double) ( end - begin ) / CLOCKS_PER_SEC; + kbps = ( total > 0 ) ? ( acc_mp3size / total ) : acc_mp3size; + cr = ( acc_mp3size > 0 ) ? ( 100.0 * acc_pmpsize / acc_mp3size ) : 0; + + fprintf( msgout, " -------------------------------- \n" ); + if ( total >= 0 ) { + fprintf( msgout, " total time : %8.2f sec\n", total ); + fprintf( msgout, " avrg. kbyte per s : %8i kbps\n", kbps ); + } + else { + fprintf( msgout, " total time : %8s sec\n", "N/A" ); + fprintf( msgout, " avrg. kbyte per s : %8s kbps\n", "N/A" ); + } + fprintf( msgout, " avrg. comp. ratio : %8.2f %%\n", cr ); + fprintf( msgout, " -------------------------------- \n" ); + } + + // pause before exit + if ( wait_exit && ( msgout != stderr ) ) { + fprintf( msgout, "\n\n< press ENTER >\n" ); + fgetc( stdin ); + } + + + return 0; +} +#endif + +/* ----------------------- Begin of library only functions -------------------------- */ + +/* ----------------------------------------------- + DLL export converter function + ----------------------------------------------- */ + +#if defined(BUILD_LIB) +EXPORT bool pmplib_convert_stream2stream( char* msg ) +{ + // process in main function + return pmplib_convert_stream2mem( NULL, NULL, msg ); +} +#endif + + +/* ----------------------------------------------- + DLL export converter function + ----------------------------------------------- */ + +#if defined(BUILD_LIB) +EXPORT bool pmplib_convert_file2file( char* in, char* out, char* msg ) +{ + // init streams + pmplib_init_streams( (void*) in, 0, 0, (void*) out, 0 ); + + // process in main function + return pmplib_convert_stream2mem( NULL, NULL, msg ); +} +#endif + + +/* ----------------------------------------------- + DLL export converter function + ----------------------------------------------- */ + +#if defined(BUILD_LIB) +EXPORT bool pmplib_convert_stream2mem( unsigned char** out_file, unsigned int* out_size, char* msg ) +{ + clock_t begin, end; + int total; + float cr; + + + // (re)set buffers + reset_buffers(); + action = A_COMPRESS; + + // main compression / decompression routines + begin = clock(); + + // process one file + process_file(); + + // fetch pointer and size of output (only for memory output) + if ( ( errorlevel < err_tol ) && ( lib_out_type == 1 ) && + ( out_file != NULL ) && ( out_size != NULL ) ) { + *out_size = str_out->getsize(); + *out_file = str_out->getptr(); + } + + // close iostreams + if ( str_in != NULL ) delete( str_in ); str_in = NULL; + if ( str_out != NULL ) delete( str_out ); str_out = NULL; + + end = clock(); + + // copy errormessage / remove files if error (and output is file) + if ( errorlevel >= err_tol ) { + if ( lib_out_type == 0 ) { + if ( filetype == F_MP3 ) { + if ( file_exists( pmpfilename ) ) remove( pmpfilename ); + } else if ( filetype == F_PMP ) { + if ( file_exists( mp3filename ) ) remove( mp3filename ); + } + } + if ( msg != NULL ) strcpy( msg, errormessage ); + return false; + } + + // get compression info + total = (int) ( (double) (( end - begin ) * 1000) / CLOCKS_PER_SEC ); + cr = ( mp3filesize > 0 ) ? ( 100.0 * pmpfilesize / mp3filesize ) : 0; + + // write success message else + if ( msg != NULL ) { + switch( filetype ) + { + case F_MP3: + sprintf( msg, "Compressed to %s (%.2f%%) in %ims", + pmpfilename, cr, ( total >= 0 ) ? total : -1 ); + break; + case F_PMP: + sprintf( msg, "Decompressed to %s (%.2f%%) in %ims", + mp3filename, cr, ( total >= 0 ) ? total : -1 ); + break; + case F_UNK: + sprintf( msg, "Unknown filetype" ); + break; + } + } + + + return true; +} +#endif + + +/* ----------------------------------------------- + DLL export init input (file/mem) + ----------------------------------------------- */ + +#if defined(BUILD_LIB) +EXPORT void pmplib_init_streams( void* in_src, int in_type, int in_size, void* out_dest, int out_type ) +{ + /* a short reminder about input/output stream types: + + if input is file + ---------------- + in_scr -> name of input file + in_type -> 0 + in_size -> ignore + + if input is memory + ------------------ + in_scr -> array containg data + in_type -> 1 + in_size -> size of data array + + if input is *FILE (f.e. stdin) + ------------------------------ + in_src -> stream pointer + in_type -> 2 + in_size -> ignore + + vice versa for output streams! */ + + unsigned char buffer[ 2 ]; + + + // (re)set errorlevel + errorfunction = NULL; + errorlevel = 0; + mp3filesize = 0; + pmpfilesize = 0; + + // open input stream, check for errors + str_in = new iostream( in_src, in_type, in_size, 0 ); + if ( str_in->chkerr() ) { + sprintf( errormessage, "error opening input stream" ); + errorlevel = 2; + return; + } + + // open output stream, check for errors + str_out = new iostream( out_dest, out_type, 0, 1 ); + if ( str_out->chkerr() ) { + sprintf( errormessage, "error opening output stream" ); + errorlevel = 2; + return; + } + + // free memory from filenames if needed + if ( mp3filename != NULL ) free( mp3filename ); mp3filename = NULL; + if ( pmpfilename != NULL ) free( pmpfilename ); pmpfilename = NULL; + + // check input stream + str_in->read( buffer, 1, 2 ); + str_in->rewind(); + if ( (buffer[0] == pmp_magic[0]) && (buffer[1] == pmp_magic[1]) ) { + // file is PMP + filetype = F_PMP; + // copy filenames + pmpfilename = (char*) calloc( ( in_type == 0 ) ? strlen( (char*) in_src ) + 1 : 32, sizeof( char ) ); + mp3filename = (char*) calloc( ( out_type == 0 ) ? strlen( (char*) out_dest ) + 1 : 32, sizeof( char ) ); + strcpy( pmpfilename, ( in_type == 0 ) ? (char*) in_src : "PMP in memory" ); + strcpy( mp3filename, ( out_type == 0 ) ? (char*) out_dest : "MP3 in memory" ); + } else { + // file is MP3 + filetype = F_MP3; + // copy filenames + mp3filename = (char*) calloc( ( in_type == 0 ) ? strlen( (char*) in_src ) + 1 : 32, sizeof( char ) ); + pmpfilename = (char*) calloc( ( out_type == 0 ) ? strlen( (char*) out_dest ) + 1 : 32, sizeof( char ) ); + strcpy( mp3filename, ( in_type == 0 ) ? (char*) in_src : "MP3 in memory" ); + strcpy( pmpfilename, ( out_type == 0 ) ? (char*) out_dest : "PMP in memory" ); + } + + // store types of in-/output + lib_in_type = in_type; + lib_out_type = out_type; +} +#endif + + +/* ----------------------------------------------- + DLL export version information + ----------------------------------------------- */ + +#if defined(BUILD_LIB) +EXPORT const char* pmplib_version_info( void ) +{ + static char v_info[ 256 ]; + + // copy version info to string + sprintf( v_info, "--> %s library v%i.%i%s (%s) by %s <--", + apptitle, appversion / 10, appversion % 10, subversion, versiondate, author ); + + return (const char*) v_info; +} +#endif + + +/* ----------------------------------------------- + DLL export version information + ----------------------------------------------- */ + +#if defined(BUILD_LIB) +EXPORT const char* pmplib_short_name( void ) +{ + static char v_name[ 256 ]; + + // copy version info to string + sprintf( v_name, "%s v%i.%i%s", + apptitle, appversion / 10, appversion % 10, subversion ); + + return (const char*) v_name; +} +#endif + +/* ----------------------- End of libary only functions -------------------------- */ + +/* ----------------------- Begin of main interface functions -------------------------- */ + + +/* ----------------------------------------------- + reads in commandline arguments + ----------------------------------------------- */ + +#if !defined(BUILD_LIB) +INTERN void initialize_options( int argc, char** argv ) +{ + int tmp_val; + char** tmp_flp; + int i; + + + // get memory for filelist & preset with NULL + filelist = (char**) calloc( argc, sizeof( char* ) ); + for ( i = 0; i < argc; i++ ) + filelist[ i ] = NULL; + + // preset temporary filelist pointer + tmp_flp = filelist; + + + // read in arguments + while ( --argc > 0 ) { + argv++; + // switches begin with '-' + if ( strcmp((*argv), "-p" ) == 0 ) { + err_tol = 2; + } + else if ( strcmp((*argv), "-ver" ) == 0 ) { + verify_lv = ( verify_lv < 1 ) ? 1 : verify_lv; + } + else if ( sscanf( (*argv), "-v%i", &tmp_val ) == 1 ){ + verbosity = tmp_val; + verbosity = ( verbosity < 0 ) ? 0 : verbosity; + verbosity = ( verbosity > 2 ) ? 2 : verbosity; + } + else if ( strcmp((*argv), "-vp" ) == 0 ) { + verbosity = -1; + } + else if ( strcmp((*argv), "-np" ) == 0 ) { + wait_exit = false; + } + else if ( strcmp((*argv), "-o" ) == 0 ) { + overwrite = true; + } + #if defined(DEV_BUILD) + else if ( strcmp((*argv), "-dev") == 0 ) { + developer = true; + } + else if ( strcmp((*argv), "-test") == 0 ) { + verify_lv = 2; + } + else if ( strcmp((*argv), "-san") == 0 ) { + if ( file_exists( STAT_ANALYSIS_CSV ) ) + remove( STAT_ANALYSIS_CSV ); + action = A_STATS_ANALYSIS; + } + else if ( strcmp((*argv), "-fan") == 0 ) { + if ( file_exists( FILE_ANALYSIS_CSV ) ) + remove( FILE_ANALYSIS_CSV ); + action = A_FILE_ANALYSIS; + } + else if ( strcmp((*argv), "-ban") == 0 ) { + action = A_BLOCK_ANALYSIS; + } + else if ( strcmp((*argv), "-dmp") == 0 ) { + action = A_DUMP_SEPERATE; + } + else if ( strcmp((*argv), "-pgm") == 0 ) { + action = A_PGM_INFO; + } + else if ( ( strcmp((*argv), "-comp") == 0) ) { + action = A_COMPRESS; + } + #endif + else if ( strcmp((*argv), "-") == 0 ) { + // switch standard message out stream + msgout = stderr; + // use "-" as placeholder for stdin + *(tmp_flp++) = (char*) "-"; + } + else { + // if argument is not switch, it's a filename + *(tmp_flp++) = *argv; + } + } + + // count number of files (or filenames) in filelist + for ( file_cnt = 0; filelist[ file_cnt ] != NULL; file_cnt++ ); + + // alloc arrays for error messages and types storage + err_list = (char**) calloc( file_cnt, sizeof( char* ) ); + err_tp = (int*) calloc( file_cnt, sizeof( int ) ); +} +#endif + + +/* ----------------------------------------------- + UI for processing one file + ----------------------------------------------- */ + +#if !defined(BUILD_LIB) +INTERN void process_ui( void ) +{ + clock_t begin, end; + const char* actionmsg = NULL; + const char* errtypemsg = NULL; + int total, bpms; + float cr; + + + errorfunction = NULL; + errorlevel = 0; + mp3filesize = 0; + pmpfilesize = 0; + #if !defined(DEV_BUILD) + action = A_COMPRESS; + #endif + + // compare file name, set pipe if needed + if ( ( strcmp( filelist[ file_no ], "-" ) == 0 ) && ( action == A_COMPRESS ) ) { + pipe_on = true; + filelist[ file_no ] = (char*) "STDIN"; + } + else { + pipe_on = false; + } + + if ( verbosity >= 0 ) { // standard UI + fprintf( msgout, "\nProcessing file %i of %i \"%s\" -> ", + file_no + 1, file_cnt, filelist[ file_no ] ); + + if ( verbosity > 1 ) + fprintf( msgout, "\n----------------------------------------" ); + + // check input file and determine filetype + execute( check_file ); + + // get specific action message + if ( filetype == F_UNK ) actionmsg = "unknown filetype"; + else switch ( action ) { + case A_COMPRESS: ( filetype == F_MP3 ) ? actionmsg = "Compressing" : actionmsg = "Decompressing"; + break; + case A_DUMP_SEPERATE: actionmsg = "Dumping binary data"; break; + case A_PGM_INFO: actionmsg = "Writing PGM"; break; + case A_FILE_ANALYSIS: actionmsg = "Analysing files"; break; + case A_BLOCK_ANALYSIS: actionmsg = "Analysing frames"; break; + case A_STATS_ANALYSIS: actionmsg = "Analysing statistics"; break; + } + + if ( verbosity < 2 ) fprintf( msgout, "%s -> ", actionmsg ); + } + else { // progress bar UI + // update progress message + fprintf( msgout, "Processing file %2i of %2i ", file_no + 1, file_cnt ); + progress_bar( file_no, file_cnt ); + fprintf( msgout, "\r" ); + execute( check_file ); + } + fflush( msgout ); + + + // main function routine + begin = clock(); + + // streams are initiated, start processing file + process_file(); + + // close iostreams + if ( str_in != NULL ) delete( str_in ); str_in = NULL; + if ( str_out != NULL ) delete( str_out ); str_out = NULL; + if ( str_str != NULL ) delete( str_str ); str_str = NULL; + // delete if broken or if output not needed + if ( ( !pipe_on ) && ( ( errorlevel >= err_tol ) || ( action != A_COMPRESS ) ) ) { + if ( filetype == F_MP3 ) { + if ( file_exists( pmpfilename ) ) remove( pmpfilename ); + } else if ( filetype == F_PMP ) { + if ( file_exists( mp3filename ) ) remove( mp3filename ); + } + } + + end = clock(); + + // speed and compression ratio calculation + total = (int) ( (double) (( end - begin ) * 1000) / CLOCKS_PER_SEC ); + bpms = ( total > 0 ) ? ( mp3filesize / total ) : mp3filesize; + cr = ( mp3filesize > 0 ) ? ( 100.0 * pmpfilesize / mp3filesize ) : 0; + + + if ( verbosity >= 0 ) { // standard UI + if ( verbosity > 1 ) + fprintf( msgout, "\n----------------------------------------" ); + + // display success/failure message + switch ( verbosity ) { + case 0: + if ( errorlevel < err_tol ) { + if ( action == A_COMPRESS ) fprintf( msgout, "%.2f%%", cr ); + else fprintf( msgout, "DONE" ); + } + else fprintf( msgout, "ERROR" ); + if ( errorlevel > 0 ) fprintf( msgout, "\n" ); + break; + + case 1: + fprintf( msgout, "%s\n", ( errorlevel < err_tol ) ? "DONE" : "ERROR" ); + break; + + case 2: + if ( errorlevel < err_tol ) fprintf( msgout, "\n-> %s OK\n", actionmsg ); + else fprintf( msgout, "\n-> %s ERROR\n", actionmsg ); + break; + } + + // set type of error message + switch ( errorlevel ) { + case 0: errtypemsg = "none"; break; + case 1: ( err_tol > 1 ) ? errtypemsg = "warning (ignored)" : errtypemsg = "warning (skipped file)"; break; + case 2: errtypemsg = "fatal error"; break; + } + + // error/ warning message + if ( errorlevel > 0 ) { + fprintf( msgout, " %s -> %s:\n", get_status( errorfunction ), errtypemsg ); + fprintf( msgout, " %s\n", errormessage ); + } + if ( (verbosity > 0) && (errorlevel < err_tol) && (action == A_COMPRESS) ) { + if ( total >= 0 ) { + fprintf( msgout, " time taken : %7i msec\n", total ); + fprintf( msgout, " byte per ms : %7i byte\n", bpms ); + } + else { + fprintf( msgout, " time taken : %7s msec\n", "N/A" ); + fprintf( msgout, " byte per ms : %7s byte\n", "N/A" ); + } + fprintf( msgout, " comp. ratio : %7.2f %%\n", cr ); + } + if ( ( verbosity > 1 ) && ( action == A_COMPRESS ) ) + fprintf( msgout, "\n" ); + } + else { // progress bar UI + // if this is the last file, update progress bar one last time + if ( file_no + 1 == file_cnt ) { + // update progress message + fprintf( msgout, "Processed %2i of %2i files ", file_no + 1, file_cnt ); + progress_bar( 1, 1 ); + fprintf( msgout, "\r" ); + } + } +} +#endif + + +/* ----------------------------------------------- + gets statusmessage for function + ----------------------------------------------- */ + +#if !defined(BUILD_LIB) +INTERN inline const char* get_status( bool (*function)() ) +{ + if ( function == NULL ) { + return "unknown action"; + } else if ( function == *check_file ) { + return "Determining filetype"; + } else if ( function == *read_mp3 ) { + return "Reading MP3"; + } else if ( function == *write_mp3 ) { + return "Writing MP3"; + } else if ( function == *analyze_frames ) { + return "Analysing frames"; + } else if ( function == *compress_mp3 ) { + return "Compressing to PMP"; + } else if ( function == *uncompress_pmp ) { + return "Uncompressing PMP"; + } else if ( function == *swap_streams ) { + return "Swapping input/output streams"; + } else if ( function == *compare_output ) { + return "Verifying output stream"; + } else if ( function == *reset_buffers ) { + return "Resetting program"; + } + #if defined(DEV_BUILD) + else if ( function == *write_file_analysis ) { + return "Writing file analysis to csv"; + } else if ( function == *write_block_analysis ) { + return "Writing block analysis to csv"; + } else if ( function == *write_stat_analysis ) { + return "Writing statistic analysis to csv"; + } else if ( function == *visualize_headers ) { + return "Writing binary info PGM"; + } else if ( function == *visualize_decoded_data ) { + return "Writing decoded data PGMs"; + } else if ( function == *dump_main_sizes ) { + return "Dumping main data sizes"; + } else if ( function == *dump_aux_sizes ) { + return "Dumping aux data sizes"; + } else if ( function == *dump_bitrates ) { + return "Dumping bitrates"; + } else if ( function == *dump_stereo_ms ) { + return "Dumping MS stereo bits"; + } else if ( function == *dump_padding ) { + return "Dumping padding bits"; + } else if ( function == *dump_main_data_bits ) { + return "Dumping main data bits"; + } else if ( function == *dump_big_value_ns ) { + return "Dumping big value pair #s"; + } else if ( function == *dump_global_gain ) { + return "Dumping global gain"; + } else if ( function == *dump_slength ) { + return "Dumping slength values"; + } else if ( function == *dump_block_types ) { + return "Dumping block types"; + } else if ( function == *dump_sharing ) { + return "Dumping sharing bits"; + } else if ( function == *dump_preemphasis ) { + return "Dumping preemphasis setting"; + } else if ( function == *dump_coarse ) { + return "Dumping coarse scf settings"; + } else if ( function == *dump_htable_sel ) { + return "Dumping hufftable selections"; + } else if ( function == *dump_region_sizes ) { + return "Dumping region sizes"; + } else if ( function == *dump_subblock_gains ) { + return "Dumping subblock gain"; + } else if ( function == *dump_data_files ) { + return "Dumping data files"; + } else if ( function == *dump_gg_ctx ) { + return "Dumping global gain context"; + } else if ( function == *dump_decoded_data ) { + return "Dumping decoded data"; + } + #endif + else { + return "Function description missing!"; + } +} +#endif + + +/* ----------------------------------------------- + shows help in case of wrong input + ----------------------------------------------- */ + +#if !defined(BUILD_LIB) +INTERN void show_help( void ) +{ + fprintf( msgout, "\n" ); + fprintf( msgout, "Website: %s\n", website ); + fprintf( msgout, "Email : %s\n", email ); + fprintf( msgout, "\n" ); + fprintf( msgout, "Usage: %s [switches] [filename(s)]", appname ); + fprintf( msgout, "\n" ); + fprintf( msgout, "\n" ); + fprintf( msgout, " [-ver] verify files after processing\n" ); + fprintf( msgout, " [-v?] set level of verbosity (max: 2) (def: 0)\n" ); + fprintf( msgout, " [-np] no pause after processing files\n" ); + fprintf( msgout, " [-o] overwrite existing files\n" ); + fprintf( msgout, " [-p] proceed on warnings\n" ); + #if defined(DEV_BUILD) + if ( developer ) { + fprintf( msgout, "\n" ); + fprintf( msgout, " [-fan] write files analysis to CSV file\n" ); + fprintf( msgout, " [-ban] write block analysis to CSV file\n" ); + fprintf( msgout, " [-san] write stats analysis to CSV file\n" ); + fprintf( msgout, " [-pgm] visualize data as PGM image\n" ); + fprintf( msgout, " [-dmp] dump data to several binary files\n" ); + } + #endif + fprintf( msgout, "\n" ); + fprintf( msgout, "Examples: \"%s -v1 -o luka.%s\"\n", appname, pmp_ext ); + fprintf( msgout, " \"%s -p *.%s\"\n", appname, mp3_ext ); +} +#endif + + +/* ----------------------------------------------- + processes one file + ----------------------------------------------- */ + +INTERN void process_file( void ) +{ + if ( filetype == F_MP3 ) { + switch ( action ) { + case A_COMPRESS: + execute( read_mp3 ); + execute( analyze_frames ); + execute( compress_mp3 ); + #if !defined(BUILD_LIB) + if ( verify_lv > 0 ) { // verifcation + execute( reset_buffers ); + execute( swap_streams ); + execute( uncompress_pmp ); + execute( write_mp3 ); + execute( compare_output ); + } + #endif + break; + + #if !defined(BUILD_LIB) && defined(DEV_BUILD) + case A_DUMP_SEPERATE: + execute( read_mp3 ); + execute( analyze_frames ); + execute( dump_main_sizes ); + execute( dump_aux_sizes ); + execute( dump_main_data_bits ); + execute( dump_big_value_ns ); + execute( dump_global_gain ); + execute( dump_bitrates ); + execute( dump_htable_sel ); + execute( dump_region_sizes ); + execute( dump_slength ); + execute( dump_stereo_ms ); + execute( dump_padding ); + execute( dump_block_types ); + execute( dump_sharing ); + execute( dump_preemphasis ); + execute( dump_coarse ); + execute( dump_subblock_gains ); + execute( dump_data_files ); + execute( dump_gg_ctx ); + execute( dump_decoded_data ); + break; + + case A_PGM_INFO: + execute( read_mp3 ); + execute( analyze_frames ); + execute( visualize_headers ); + execute( visualize_decoded_data ); + break; + + case A_FILE_ANALYSIS: + execute( read_mp3 ); + execute( analyze_frames ); + execute( write_file_analysis ); + break; + + case A_BLOCK_ANALYSIS: + execute( read_mp3 ); + execute( analyze_frames ); + execute( write_block_analysis ); + break; + + case A_STATS_ANALYSIS: + execute( read_mp3 ); + execute( analyze_frames ); + execute( write_stat_analysis ); + break; + #else + default: + break; + #endif + } + } + else if ( filetype == F_PMP ) { + switch ( action ) + { + case A_COMPRESS: + execute( uncompress_pmp ); + execute( write_mp3 ); + #if !defined(BUILD_LIB) + if ( verify_lv > 0 ) { // verify + execute( reset_buffers ); + execute( swap_streams ); + execute( read_mp3 ); + execute( analyze_frames ); + execute( compress_mp3 ); + execute( compare_output ); + } + #endif + break; + + #if !defined(BUILD_LIB) && defined(DEV_BUILD) + case A_DUMP_SEPERATE: + execute( uncompress_pmp ); + execute( dump_main_sizes ); + execute( dump_aux_sizes ); + execute( dump_main_data_bits ); + execute( dump_big_value_ns ); + execute( dump_global_gain ); + execute( dump_bitrates ); + execute( dump_htable_sel ); + execute( dump_region_sizes ); + execute( dump_slength ); + execute( dump_stereo_ms ); + execute( dump_padding ); + execute( dump_block_types ); + execute( dump_sharing ); + execute( dump_preemphasis ); + execute( dump_coarse ); + execute( dump_subblock_gains ); + execute( dump_data_files ); + execute( dump_gg_ctx ); + execute( dump_decoded_data ); + break; + + case A_PGM_INFO: + execute( uncompress_pmp ); + execute( visualize_headers ); + execute( visualize_decoded_data ); + break; + + case A_FILE_ANALYSIS: + execute( uncompress_pmp ); + execute( write_file_analysis ); + break; + + case A_BLOCK_ANALYSIS: + execute( uncompress_pmp ); + execute( write_block_analysis ); + break; + + case A_STATS_ANALYSIS: + execute( uncompress_pmp ); + execute( write_stat_analysis ); + break; + #else + default: + break; + #endif + } + } + #if !defined(BUILD_LIB) && defined(DEV_BUILD) + // write error file if verify lv > 1 + if ( ( verify_lv > 1 ) && ( errorlevel >= err_tol ) ) + write_errfile(); + #endif + // reset buffers + reset_buffers(); +} + + +/* ----------------------------------------------- + main-function execution routine + ----------------------------------------------- */ + +INTERN void execute( bool (*function)() ) +{ + if ( errorlevel < err_tol ) { + #if !defined BUILD_LIB + clock_t begin, end; + bool success; + int total; + + // write statusmessage + if ( verbosity == 2 ) { + fprintf( msgout, "\n%s ", get_status( function ) ); + for ( int i = strlen( get_status( function ) ); i <= 30; i++ ) + fprintf( msgout, " " ); + } + + // set starttime + begin = clock(); + // call function + success = ( *function )(); + // set endtime + end = clock(); + + if ( ( errorlevel > 0 ) && ( errorfunction == NULL ) ) + errorfunction = function; + + // write time or failure notice + if ( success ) { + total = (int) ( (double) (( end - begin ) * 1000) / CLOCKS_PER_SEC ); + if ( verbosity == 2 ) fprintf( msgout, "%6ims", ( total >= 0 ) ? total : -1 ); + } + else { + errorfunction = function; + if ( verbosity == 2 ) fprintf( msgout, "%8s", "ERROR" ); + } + #else + // call function + ( *function )(); + + // store errorfunction if needed + if ( ( errorlevel > 0 ) && ( errorfunction == NULL ) ) + errorfunction = function; + #endif + } +} + +/* ----------------------- End of main interface functions -------------------------- */ + +/* ----------------------- Begin of main functions -------------------------- */ + + +/* ----------------------------------------------- + check file and determine filetype + ----------------------------------------------- */ + +#if !defined(BUILD_LIB) +INTERN bool check_file( void ) +{ + unsigned char fileid[ 2 ] = { 0, 0 }; + const char* filename = filelist[ file_no ]; + + + // open input stream, check for errors + str_in = new iostream( (void*) filename, ( !pipe_on ) ? 0 : 2, 0, 0 ); + if ( str_in->chkerr() ) { + sprintf( errormessage, FRD_ERRMSG ); + errorlevel = 2; + return false; + } + + // free memory from filenames if needed + if ( mp3filename != NULL ) free( mp3filename ); mp3filename = NULL; + if ( pmpfilename != NULL ) free( pmpfilename ); pmpfilename = NULL; + + // immediately return error if 2 bytes can't be read + if ( str_in->read( fileid, 1, 2 ) != 2 ) { + filetype = F_UNK; + sprintf( errormessage, "file doesn't contain enough data" ); + errorlevel = 2; + return false; + } + + // rewind (need to start from the beginning) + if ( str_in->rewind() != 0 ) { + sprintf( errormessage, FRD_ERRMSG ); + errorlevel = 2; + return false; + } + + // check file id, determine filetype + if ( ( fileid[0] == pmp_magic[0] ) && ( fileid[1] == pmp_magic[1] ) ) { + // PMP marker -> file is PMP + filetype = F_PMP; + // create filenames + if ( !pipe_on ) { + pmpfilename = (char*) calloc( strlen( filename ) + 1, sizeof( char ) ); + strcpy( pmpfilename, filename ); + mp3filename = ( overwrite ) ? + create_filename( filename, (char*) mp3_ext ) : + unique_filename( filename, (char*) mp3_ext ); + } + else { + mp3filename = create_filename( "STDOUT", NULL ); + pmpfilename = create_filename( "STDIN", NULL ); + } + // open output stream, check for errors + str_out = new iostream( (void*) mp3filename, ( !pipe_on ) ? 0 : 2, 0, 1 ); + if ( str_out->chkerr() ) { + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + } + else { + // for all other cases we assume that file might be MPEG X LAYER Y + filetype = F_MP3; + // create filenames + if ( !pipe_on ) { + mp3filename = (char*) calloc( strlen( filename ) + 1, sizeof( char ) ); + strcpy( mp3filename, filename ); + pmpfilename = ( overwrite ) ? + create_filename( filename, (char*) pmp_ext ) : + unique_filename( filename, (char*) pmp_ext ); + } + else { + mp3filename = create_filename( "STDIN", NULL ); + pmpfilename = create_filename( "STDOUT", NULL ); + } + // open output stream, check for errors + str_out = new iostream( (void*) pmpfilename, ( !pipe_on ) ? 0 : 2, 0, 1 ); + if ( str_out->chkerr() ) { + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + } + + + return true; +} +#endif + + +/* ----------------------------------------------- + swap streams / init verification + ----------------------------------------------- */ + +#if !defined(BUILD_LIB) +INTERN bool swap_streams( void ) +{ + // store input stream + str_str = str_in; + str_str->rewind(); + + // replace input stream by output stream / switch mode for reading + str_in = str_out; + str_in->switch_mode(); + + // open new stream for output / check for errors + str_out = new iostream( NULL, 1, 0, 1 ); + if ( str_out->chkerr() ) { + sprintf( errormessage, "error opening comparison stream" ); + errorlevel = 2; + return false; + } + + + return true; +} +#endif + + +/* ----------------------------------------------- + comparison between input & output + ----------------------------------------------- */ + +#if !defined(BUILD_LIB) +INTERN bool compare_output( void ) +{ + unsigned char* buff_ori; + unsigned char* buff_cmp; + int bsize = 1024; + int dsize; + int i, b; + + + // init buffer arrays + buff_ori = ( unsigned char* ) calloc( bsize, sizeof( char ) ); + buff_cmp = ( unsigned char* ) calloc( bsize, sizeof( char ) ); + if ( ( buff_ori == NULL ) || ( buff_cmp == NULL ) ) { + if ( buff_ori != NULL ) free( buff_ori ); + if ( buff_cmp != NULL ) free( buff_cmp ); + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return false; + } + + // switch output stream mode / check for stream errors + str_out->switch_mode(); + while ( true ) { + if ( str_out->chkerr() ) + sprintf( errormessage, "error in comparison stream" ); + else if ( str_in->chkerr() ) + sprintf( errormessage, "error in output stream" ); + else if ( str_str->chkerr() ) + sprintf( errormessage, "error in input stream" ); + else break; + errorlevel = 2; + return false; + } + + // compare sizes + dsize = str_str->getsize(); + if ( str_out->getsize() != dsize ) { + sprintf( errormessage, "file sizes do not match" ); + errorlevel = 2; + return false; + } + + // compare files byte by byte + for ( i = 0; i < dsize; i++ ) { + b = i % bsize; + if ( b == 0 ) { + str_str->read( buff_ori, sizeof( char ), bsize ); + str_out->read( buff_cmp, sizeof( char ), bsize ); + } + if ( buff_ori[ b ] != buff_cmp[ b ] ) { + sprintf( errormessage, "difference found at 0x%X", i ); + errorlevel = 2; + return false; + } + } + + + return true; +} +#endif + + +/* ----------------------------------------------- + set each variable to its initial value + ----------------------------------------------- */ + +INTERN bool reset_buffers( void ) +{ + mp3Frame* frame; + + + + // --- free frame data --- + // start from first frame, throw away all frame data + if ( firstframe != NULL ) { + frame = firstframe; + while ( true ) { + if ( frame->next != NULL ) { + frame = frame->next; + mp3_discard_frame( frame->prev ); + frame->prev = NULL; + } else { + mp3_discard_frame( frame ); + break; + } + } + } + firstframe = NULL; + lastframe = NULL; + + // throw away huffman coded data block + if ( main_data != NULL ) free ( main_data ); + main_data = NULL; + main_data_size = 0; + + // --- free other data --- + if ( data_before != NULL ) free ( data_before ); + if ( data_after != NULL ) free( data_after ); + if ( unmute_data != NULL ) free( unmute_data ); + data_before = NULL; + data_after = NULL; + unmute_data = NULL; + data_before_size = 0; + data_after_size = 0; + unmute_data_size = 0; + if ( gg_context[0] != NULL ) free ( gg_context[0] ); + if ( gg_context[1] != NULL ) free ( gg_context[1] ); + gg_context[0] = NULL; + gg_context[1] = NULL; + + // --- reset global variables --- + g_nframes = 0; // number of frames + g_nchannels = 0; // number of channels + g_samplerate = 0; // sample rate + g_bitrate = 0; // average bit rate + n_bad_first = 0; // # of bad first frames + + // --- reset frame analysis variables --- + i_mpeg = -1; // mpeg - non changing + i_layer = -1; // layer - non changing + i_samplerate = -1; // sample rate - non changing + i_bitrate = -1; // bit rate - value or -1 (variable) + i_protection = -1; // checksum - for all (1), none (0) or some (-1) frames + i_padding = -1; // padding - for all (1), none (0) or some (-1) frames + i_privbit = -1; // private bit - value or -1 (variable) + i_channels = -1; // channel mode - non changing + i_stereo_ms = -1; // ms stereo - for all (1), none (0) or some (-1) frames + i_stereo_int = -1; // int stereo - for all (1), none (0) or some (-1) frames + i_copyright = -1; // copyright bit - value or -1 (variable) + i_original = -1; // original bit - value or -1 (variable) + i_emphasis = -1; // emphasis - value or -1 (variable) + i_padbits = -1; // side info padding bits - value or -1 (variable) + i_bit_res = -1; // bit reservoir - is used (1) or not used (0) + i_share = -1; // scalefactor sharing - is used (1) or not used (0) + i_sblocks = -1; // special blocks - are used (1) or not used (0) + i_mixed = -1; // mixed blocks - are used (1) or not used (0) + i_preemphasis = -1; // preemphasis - value or -1 (variable) + i_coarse = -1; // coarse scalefactors - value or -1 (variable) + i_sbgain = -1; // subblock gain - is used (1) or not used (0) + i_aux_h = -1; // auxiliary data handling - none (0), at begin and end (1), between frames (-1) + i_sb_diff = -1; // special blocks diffs between ch0 and ch1 - none (0) or some (-1) + + + return true; +} + + +/* ----------------------------------------------- + parse MP3 frame structure + ----------------------------------------------- */ + +INTERN bool read_mp3( void ) +{ + unsigned char* mp3data; + int main_data_begin; + int main_data_end; + + char mpeg = -1; + char layer = -1; + char samples = -1; + char channels = -1; + + abytewriter* data_writer; + mp3Frame* frame = NULL; + bool incomplete_last_frame = false; + int type; + int pos; + + + // read the first few bytes from the file into memory + // (these will be used to check for proper frames) + mp3filesize = str_in->getsize(); + if ( mp3filesize > FIRST_FRAME_AREA ) mp3filesize = FIRST_FRAME_AREA; + mp3data = (unsigned char*) calloc( mp3filesize + 1, sizeof( char ) ); + if ( ( mp3data == NULL ) || ( mp3filesize <= 0 ) ) { + if ( mp3data != NULL ) free( mp3data ); + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return false; + } + str_in->read( mp3data, 1, mp3filesize ); + + // find first proper mpeg audio frame + pos = mp3_seek_firstframe( mp3data, mp3filesize ); + if ( pos == -1 ) { + sprintf( errormessage, "no mpeg audio data recognized" ); + errorlevel = 2; + free( mp3data ); + return false; + } + main_data_begin = pos; + + // check first frame header for MPEG and LAYER version + if ( mp3filesize - pos >= 2 ) { + type = MBITS( mp3data[pos+1], 5, 1 ); + if ( type != MPEG1_LAYER_III ) { + sprintf( errormessage, "file is %s, not supported", filetype_description[type] ); + errorlevel = 2; + free( mp3data ); + return false; + } + } + + // if theres still more data, read the whole file into memory now + // (bad for mem consumption, but for now -> so what?) + if ( mp3filesize == FIRST_FRAME_AREA ) { + mp3filesize = str_in->getsize(); // check size of file again + mp3data = (unsigned char*) frealloc( mp3data, mp3filesize * sizeof( char ) ); + if ( mp3data == NULL ) { + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return false; + } + str_in->read( mp3data + FIRST_FRAME_AREA, 1, mp3filesize - FIRST_FRAME_AREA ); + } + + + // now, read frames until the end of the stream or a bad frame is encountered + data_writer = new abytewriter(0); + while ( pos < mp3filesize ) { + // read frame, check result + frame = mp3_read_frame( mp3data + pos, mp3filesize - pos ); + if ( frame == NULL ) { + if ( errorlevel == 2 ) { + // append some useful info to the existing error message + sprintf( errormessage + strlen( errormessage ), " (frame #%i at 0x%X)", + ( lastframe != NULL ) ? lastframe->n + 1 : 0, pos ); + free( mp3data ); + delete( data_writer ); + return false; + } + else break; + } else if ( frame->frame_size > mp3filesize - pos ) { + // check for incomplete last frame + incomplete_last_frame = true; + mp3_discard_frame( frame ); + break; + } else if ( ( frame->mpeg != mpeg ) || ( frame->layer != layer ) || + ( frame->samples != samples ) || ( frame->channels != channels ) ) { + // check for inconsistencies + if ( mpeg == -1 ) { + mpeg = frame->mpeg; + layer = frame->layer; + samples = frame->samples; + channels = frame->channels; + } else { + mp3_discard_frame( frame ); + break; + } + } + if ( lastframe != NULL ) { // fix previous frames aux size, check for problems + if ( frame->aux_size < 0 ) { // main data out of bounds + if ( lastframe->n > MAX_BAD_FIRST - 2 ) { mp3_discard_frame( frame ); break; } + else n_bad_first = lastframe->n + 2; + } else if ( lastframe->aux_size < frame->bit_reservoir ) { // overlapping main data + if ( lastframe->n > MAX_BAD_FIRST - 1 ) { mp3_discard_frame( frame ); break; } + else n_bad_first = lastframe->n + 1; + } else if ( frame->n == -1 ) { // obvious contradiction (see mp3_read_frame()) + if ( lastframe->n > MAX_BAD_FIRST - 2 ) { mp3_discard_frame( frame ); break; } + else n_bad_first = lastframe->n + 2; + } + // fix previous frame aux size + lastframe->aux_size -= frame->bit_reservoir; + } else if ( ( frame->aux_size < 0 ) || ( frame->n == -1 ) ) n_bad_first = 1; + // update main index, store main data + frame->main_index = data_writer->getpos() - frame->bit_reservoir; + data_writer->write_n( mp3data + pos + frame->fixed_size, frame->frame_size - frame->fixed_size ); + // insert frame into the frame chain + mp3_append_frame( frame ); + // check for pointing to empty space + if ( frame->main_index < 0 ) n_bad_first = frame->n + 1; + // advance to next physical frame + pos += frame->frame_size; + } + + // store main data + main_data_size = data_writer->getpos(); + if ( main_data_size > 0 ) main_data = data_writer->getptr(); + delete( data_writer ); + + // check number of proper frames (must be at least 5) + if ( lastframe->n + 1 - n_bad_first < 5 ) { + sprintf( errormessage, "corrupted file, compression not possible" ); + errorlevel = 2; + return false; + } + + + // end of main mp3 data processing + main_data_end = pos; + // check for ID3 tags at end of file + if ( !incomplete_last_frame && ( main_data_end < mp3filesize ) ) { + if ( main_data_end + mp3_get_id3_size( mp3data+main_data_end, mp3filesize-main_data_end ) != mp3filesize ) { + // allow for a tolerance of 64K unidentified garbage data at EOF + if ( mp3filesize - main_data_end > GARBAGE_TOLERANCE ) { + sprintf( errormessage, "synching failure (frame #%i at 0x%X)", lastframe->n + 1, pos ); + errorlevel = 2; + free( mp3data ); + return false; + }/* else { // (!!!) strict mode? + sprintf( errormessage, "%i byte of unidentified garbage after EOF", mp3filesize - main_data_end ); + errorlevel = 1; + }*/ + } + } + + // clean up and store id3 tags and garbage data + data_after_size = mp3filesize - main_data_end; + data_before_size = main_data_begin; + if ( data_after_size > 0 ) { + data_after = (unsigned char*) calloc( data_after_size, sizeof( char ) ); + if ( ( mp3data == NULL ) || ( mp3filesize <= 0 ) ) { + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return false; + } + memcpy( data_after, mp3data + main_data_end, data_after_size ); + } + if ( data_before_size > 0 ) + data_before = (unsigned char*) frealloc( mp3data, data_before_size * sizeof(char) ); + else free( mp3data ); + + + return true; +} + + +/* ----------------------------------------------- + write MP3 from frame structure + ----------------------------------------------- */ + +INTERN bool write_mp3( void ) +{ + unsigned char* data = main_data; + unsigned char* fixed; + mp3Frame* frame; + + + // write data before (usually ID3v2 tag) + str_out->write( data_before, 1, data_before_size ); + + // write physical frames + // main data has to be in order! + for ( frame = firstframe; frame != NULL; frame = frame->next ) { + fixed = mp3_build_fixed( frame ); + str_out->write( fixed, 1, frame->fixed_size ); + str_out->write( data, 1, frame->frame_size - frame->fixed_size ); + data += frame->frame_size - frame->fixed_size; + } + + // write data after + str_out->write( data_after, 1, data_after_size ); + + // errormessage if write error + if ( str_out->chkerr() ) { + sprintf( errormessage, "write error, possibly drive is full" ); + errorlevel = 2; + return false; + } + + // get filesize + mp3filesize = str_out->getsize(); + + + return true; +} + + +/* ----------------------------------------------- + analyse frames for redundancies and errors + ----------------------------------------------- */ + +INTERN bool analyze_frames( void ) +{ + mp3Frame* frame; + granuleInfo* granule; + bool aux0 = false; + bool aux1 = false; + bool sbx_gain = false; + int nch; + int ch, gr; + + + // (re)set analysis data + i_mpeg = firstframe->mpeg; + i_layer = firstframe->layer; + i_samplerate = firstframe->samples; + i_bitrate = firstframe->bits; + i_protection = firstframe->protection; + i_padding = firstframe->padding; + i_privbit = firstframe->privbit; + i_channels = firstframe->channels; + i_stereo_ms = firstframe->stereo_ms; + i_stereo_int = firstframe->stereo_int; + i_copyright = firstframe->copyright; + i_original = firstframe->original; + i_emphasis = firstframe->emphasis; + i_padbits = firstframe->padbits; + i_bit_res = ( firstframe->bit_reservoir > 0 ) ? 1 : 0; + if ( firstframe->aux_size > 0 ) { + i_aux_h = 1; + aux0 = true; + } else i_aux_h = 0; + // for granules + granule = firstframe->granules[0][0]; + i_share = ( granule->share != 0 ) ? 1 : 0; + i_sblocks = ( granule->window_switching != 0 ) ? 1 : 0; + i_mixed = ( granule->mixed_flag != 0 ) ? 1 : 0; + i_preemphasis = granule->preemphasis; + i_coarse = granule->coarse_scalefactors; + // easy way out for these - will be tested later + i_sb_diff = 0; + i_sbgain = 0; + + + // analyse frames, check for redundancies and errors + for ( frame = firstframe; frame != NULL; frame = frame->next ) { + // no need to check mpeg, layer, samples, channels + // already did this in read_mp3()! + + // analyse (mainly) frame header data + // special tolerance for the following, as they often get mixed up in frame #0 + if ( ( i_privbit != -1 ) && ( i_privbit != frame->privbit ) ) { + if ( frame->n == 1 ) { // tolerance for first frame + if ( n_bad_first == 0 ) n_bad_first = 1; + i_privbit = frame->privbit; + } else i_privbit = -1; + } + if ( ( i_copyright != -1 ) && ( i_copyright != frame->copyright ) ) { + if ( frame->n == 1 ) { // tolerance for first frame + if ( n_bad_first == 0 ) n_bad_first = 1; + i_copyright = frame->copyright; + } else i_copyright = -1; + } + if ( ( i_original != -1 ) && ( i_original != frame->original ) ) { + if ( frame->n == 1 ) { // tolerance for first frame + if ( n_bad_first == 0 ) n_bad_first = 1; + i_original = frame->original; + } else i_original = -1; + } + if ( ( i_protection != -1 ) && ( i_protection != frame->protection ) ) i_protection = -1; + if ( ( i_bitrate != -1 ) && ( i_bitrate != frame->bits ) ) i_bitrate = -1; + if ( ( i_padding != -1 ) && ( i_padding != frame->padding ) ) i_padding = -1; + if ( ( i_stereo_ms != -1 ) && ( i_stereo_ms != frame->stereo_ms ) ) i_stereo_ms = -1; + if ( ( i_stereo_int != -1 ) && ( i_stereo_int != frame->stereo_int ) ) i_stereo_int = -1; + if ( ( i_emphasis != -1 ) && ( i_emphasis != frame->emphasis ) ) i_emphasis = -1; + if ( ( i_padbits != -1 ) && ( i_padbits != frame->padbits ) ) i_padbits = -1; + if ( ( i_bit_res != 1 ) && ( frame->bit_reservoir > 0 ) ) i_bit_res = 1; + if ( i_aux_h != -1 ) { + // no auxiliary before aux0 or after aux1 + if ( frame->aux_size > 0 ) { + if ( !aux0 ) aux1 = true; + } else { + if ( aux1 ) i_aux_h = -1; + if ( aux0 ) aux0 = false; + } + } + nch = frame->nchannels; + for ( ch = 0; ch < nch; ch++ ) { + for ( gr = 0; gr < 2; gr++ ) { + granule = frame->granules[ch][gr]; + sbx_gain = + ( granule->sb_gain[0] != 0 ) || + ( granule->sb_gain[1] != 0 ) || + ( granule->sb_gain[2] != 0 ); + if ( ( i_share != 1 ) && ( granule->share != 0 ) ) i_share = 1; + if ( ( i_sblocks != 1 ) && ( granule->window_switching ) ) i_sblocks = 1; + if ( ( i_mixed != 1 ) && ( granule->mixed_flag ) ) i_mixed = 1; + if ( ( i_preemphasis != -1 ) && ( i_preemphasis != granule->preemphasis ) ) i_preemphasis = -1; + if ( ( i_coarse != -1 ) && ( i_coarse != granule->coarse_scalefactors ) ) i_coarse = -1; + if ( ( i_sbgain != -1 ) && ( sbx_gain ) ) i_sbgain = ( granule->block_type == SHORT_BLOCK ) ? 1 : -1; + if ( ( i_sb_diff != 1 ) && ( ch == 1 ) ) + if ( granule->block_type != frame->granules[0][gr]->block_type ) i_sb_diff = 1; + } + } + } + + // last check for aux data handling + if ( ( i_aux_h != -1 ) && ( aux1 ) ) i_aux_h = 1; + + // fill in some global info + g_nframes = lastframe->n + 1; + g_nchannels = ( i_channels == MP3_MONO ) ? 1 : 2; // number of channels + g_samplerate = mp3_samplerate_table[(int)i_samplerate]; // sample rate + g_bitrate = ( i_bitrate == -1 ) ? 0 : mp3_bitrate_table[(int)i_bitrate]; // bit rate + + + return true; +} + + +INTERN bool compress_mp3( void ) +{ + aricoder* encoder; + + + // --- check for incompatibilities and problems --- + + // unsupported stuff -> not recoverable + if ( i_protection == -1 ) { // inconsistent use of checksums + sprintf( errormessage, "inconsistent use of checksums, not supported" ); + errorlevel = 2; + return false; + } + if ( i_stereo_int == -1 ) { // inconsistent use of intensity stereo + sprintf( errormessage, "inconsistent use of int stereo, not supported" ); + errorlevel = 2; + return false; + } + if ( i_emphasis == -1 ) { // inconsistent use of emphasis + sprintf( errormessage, "inconsistent use of emphasis, not supported" ); + errorlevel = 2; + return false; + } + if ( i_mixed != 0x0 ) { // mixed blocks + sprintf( errormessage, "mixed blocks used, not supported" ); + errorlevel = 2; + return false; + } + + // inconsistencies -> recoverable + if ( i_privbit == -1 ) { // inconsistent private bit -> steganograhy? + sprintf( errormessage, "inconsistent private bit" ); + errorlevel = 1; + i_privbit = 0; + } + if ( i_copyright == -1 ) { // inconsistent copyright bit -> steganograhy? + sprintf( errormessage, "inconsistent copyright bit" ); + errorlevel = 1; + i_copyright = 0; + } + if ( i_original == -1 ) { // inconsistent original bit -> steganograhy? + sprintf( errormessage, "inconsistent original bit" ); + errorlevel = 1; + i_original = 1; + } + if ( i_padbits != 0 ) { // non-zero padbits -> steganograhy? + sprintf( errormessage, "non-zero padbits found" ); + errorlevel = 1; + i_padbits = 0; + } + + + // --- write PMP header with some basic info --- + + // PMP magic number & version byte + str_out->write( (void*) pmp_magic, 1, 2 ); + str_out->write( (void*) &appversion, 1, 1 ); + + // PMP header data + if ( !pmp_write_header( str_out ) ) return false; + + + #if defined( STORE_ID3 ) + // --- store ID3 data instead of compressing --- + + if ( data_before_size > 0 ) + if ( pmp_store_data( str_out, data_before, data_before_size ) != data_before_size ) return false; + if ( data_after_size > 0 ) + if ( pmp_store_data( str_out, data_after, data_after_size ) != data_after_size ) return false; + #endif + + + // --- mute frames, store fix data (only if broken) --- + + if ( n_bad_first > 0 ) { + // mute all frames up to last bad + for ( mp3Frame* frame = firstframe; n_bad_first > 0; frame = frame->next, n_bad_first-- ) + mp3_mute_frame( frame ); + // store fix data + if ( !pmp_store_unmute_data( str_out ) ) return false; + } + + + // --- actual compressed data writing starts here --- + + // init arithmetic compression + encoder = new aricoder( str_out, 1 ); + + #if !defined( STORE_ID3 ) + // id3 tags / other tags / garbage + if ( ( data_before_size > 0 ) || ( data_after_size > 0 ) ) + if ( !pmp_encode_id3( encoder ) ) return false; + #endif + + // frame header data + if ( i_padding != 0 ) // padding bits + if ( !pmp_encode_padding( encoder ) ) return false; + if ( i_sblocks != 0 ) // special block types + if ( !pmp_encode_block_types( encoder ) ) return false; + // global gain + if ( !pmp_encode_global_gain( encoder ) ) return false; + // build context from global gain + if ( !pmp_build_context() ) return false; + // slength + if ( !pmp_encode_slength( encoder ) ) return false; + /* + // region sizes + if ( !pmp_encode_region_bounds( encoder ) ) return false; + // huffman table selections + if ( !pmp_encode_htable_selection( encoder ) ) return false; + */ + if ( !pmp_encode_region_data( encoder ) ) return false; + if ( i_share != 0 ) // scalefactor sharing + if ( !pmp_encode_sharing( encoder ) ) return false; + if ( i_preemphasis != 0 ) // preemphasis + if ( !pmp_encode_preemphasis( encoder ) ) return false; + if ( i_coarse != 0 ) // coarse setting + if ( !pmp_encode_coarse_sf( encoder ) ) return false; + if ( i_sbgain != 0 ) // subblock gain + if ( !pmp_encode_subblock_gain( encoder ) ) return false; + if ( i_stereo_ms != 0 ) // ms stereo settings + if ( !pmp_encode_stereo_ms( encoder ) ) return false; + // main data + if ( !pmp_encode_main_data( encoder ) ) return false; + + // finalize arithmetic compression + delete( encoder ); + + + // --- final checks --- + + // errormessage if write error + if ( str_out->chkerr() ) { + sprintf( errormessage, "write error, possibly drive is full" ); + errorlevel = 2; + return false; + } + + // get filesize + pmpfilesize = str_out->getsize(); + + + return true; +} + + +INTERN bool uncompress_pmp( void ) +{ + aricoder* decoder; + unsigned char hcode; + + + // --- no error checks needed! --- + // (we already did this when compressing) + + + // --- read PMP header and analyse basic info --- + + // PMP magic number + // skip 2 bytes (no need to check again) + str_in->read( &hcode, 1, 1 ); + str_in->read( &hcode, 1, 1 ); + + // version number + str_in->read( &hcode, 1, 1 ); + // compare version number + if ( hcode != appversion ) { + sprintf( errormessage, "incompatible file, use %s v%i.%i", + appname, hcode / 10, hcode % 10 ); + errorlevel = 2; + return false; + } + + // read and analyse header + if ( !pmp_read_header( str_in ) ) return false; + + + #if defined( STORE_ID3 ) + // --- unstore ID3 data --- + + if ( data_before_size > 0 ) { + data_before_size = pmp_unstore_data( str_in, &data_before ); + if ( data_before_size <= 0 ) return false; + } + if ( data_after_size > 0 ) { + data_after_size = pmp_unstore_data( str_in, &data_after ); + if ( data_after_size <= 0 ) return false; + } + #endif + + + // --- unstore unmute fix data for later use (only if needed) --- + + // unstore fix data + if ( n_bad_first > 0 ) { + if ( !pmp_unstore_unmute_data( str_in ) ) return false; + n_bad_first = 0; // not a beautiful solution + } + + + // --- actual decompression starts here --- + + // init arithmetic decompression + decoder = new aricoder( str_in, 0 ); + + #if !defined( STORE_ID3 ) + // id3 tags / other tags / garbage + if ( ( data_before_size > 0 ) || ( data_after_size > 0 ) ) + if ( !pmp_decode_id3( decoder ) ) return false; + #endif + + // frame header data + if ( i_padding != 0 ) // padding bits + if ( !pmp_decode_padding( decoder ) ) return false; + if ( i_sblocks != 0 ) // special block types + if ( !pmp_decode_block_types( decoder ) ) return false; + // global gain + if ( !pmp_decode_global_gain( decoder ) ) return false; + // build context from global gain + if ( !pmp_build_context() ) return false; + // slength + if ( !pmp_decode_slength( decoder ) ) return false; + /* + // region sizes + if ( !pmp_decode_region_bounds( decoder ) ) return false; + // huffman table selections + if ( !pmp_decode_htable_selection( decoder ) ) return false; + */ + if ( !pmp_decode_region_data( decoder ) ) return false; + if ( i_share != 0 ) // scalefactor sharing + if ( !pmp_decode_sharing( decoder ) ) return false; + if ( i_preemphasis != 0 ) // preemphasis + if ( !pmp_decode_preemphasis( decoder ) ) return false; + if ( i_coarse != 0 ) // coarse setting + if ( !pmp_decode_coarse_sf( decoder ) ) return false; + if ( i_sbgain != 0 ) // subblock gain + if ( !pmp_decode_subblock_gain( decoder ) ) return false; + if ( i_stereo_ms != 0 ) // ms stereo settings + if ( !pmp_decode_stereo_ms( decoder ) ) return false; + // main data + if ( !pmp_decode_main_data( decoder ) ) return false; + + // finalize arithmetic compression + delete( decoder ); + + + // --- unmute frames and reverse to bad (but bitwise identical) state --- + + if ( unmute_data_size > 0 ) // unmute all frames up to # found in unmute data first byte + for ( mp3Frame* frame = firstframe; n_bad_first < *unmute_data; frame = frame->next, n_bad_first++ ) + mp3_unmute_frame( frame ); + + + // --- final checks --- + + // get filesize + pmpfilesize = str_in->getsize(); + + + return true; +} + +/* ----------------------- End of main functions -------------------------- */ + +/* ----------------------- Begin of MP3 specific functions -------------------------- */ + + +/* ----------------------------------------------- + read one physical frame + ----------------------------------------------- */ +INTERN inline mp3Frame* mp3_read_frame( unsigned char* data, int max_size ) +{ + mp3Frame* frame; + granuleInfo* granule; + abitreader* side_reader; + unsigned char* header; + unsigned char* sideinfo; + unsigned short crc; + int nsb = 0; + int nch = 0; + int ch, gr; + + + // immediately return if not enough data (min size for header and side info = 21) + if ( max_size < 21 ) return NULL; + + // --- frame header --- + header = data + 0; + + // check syncword + if ( ( header[0] != 0xFF ) || ( (header[1]&0xFA) != 0xFA ) ) { + // no syncword or not MPEG-1 LAYER III + // might be end of audio data -> process in other function + return NULL; + } + + // alloc memory for frame + frame = (mp3Frame*) calloc( 1, sizeof( mp3Frame ) ); + if ( frame == NULL ) { + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return NULL; + } + + // preset pointers + frame->granules = NULL; + frame->prev = NULL; + frame->next = NULL; + frame->n = 0; + + // extract data + frame->mpeg = (header[1]>>3)&0x3; + frame->layer = (header[1]>>1)&0x3; + frame->protection = ((header[1]>>0)&0x1)^1; + frame->bits = (header[2]>>4)&0xF; + frame->samples = (header[2]>>2)&0x3; + frame->padding = (header[2]>>1)&0x1; + frame->privbit = (header[2]>>0)&0x1; + frame->channels = (header[3]>>6)&0x3; + frame->stereo_ms = (header[3]>>5)&0x1; + frame->stereo_int = (header[3]>>4)&0x1; + frame->copyright = (header[3]>>3)&0x1; + frame->original = (header[3]>>2)&0x1; + frame->emphasis = (header[3]>>0)&0x3; + + // check data for problems + // this also contains the never used free form stream flag -> so what? + if ( ( frame->bits == 0x0 ) || ( frame->bits == 0xF ) || ( frame->samples == 0x3 ) ) { + free( frame ); + return NULL; + } + + // number of channels + frame->nchannels = ( frame->channels == MP3_MONO ) ? 1 : 2; + nch = frame->nchannels; + + // alloc memory for granules + frame->granules = (granuleInfo***) calloc( nch, sizeof( granuleInfo** ) ); + for ( ch = 0; ch < nch; ch++ ) { + frame->granules[ch] = (granuleInfo**) calloc( 2, sizeof( granuleInfo* ) ); + for ( gr = 0; gr < 2; gr++ ) + frame->granules[ch][gr] = (granuleInfo*) calloc( 1, sizeof( granuleInfo ) ); + } + + // calculate size of frame - use the lookup table + frame->frame_size = mp3_frame_size_table[(int)frame->samples][(int)frame->bits]; + if ( frame->padding ) frame->frame_size++; + + // this is the actual calculation routine, which is now no more used + /* if ( frame->layer != LAYER_I ) frame->frame_size = (int) ( frame->padding + + ( ( 144000 * bitrate_table[frame->mpeg][frame->layer][frame->bits] ) / + samplerate_table[frame->mpeg][frame->samples] ) ); + else frame->frame_size = (int) ( ( ( frame->padding ) ? 4 : 0 ) + + ( ( 48000 * bitrate_table[frame->mpeg][frame->layer][frame->bits] ) / + samplerate_table[frame->mpeg][frame->samples] ) );*/ + + // --- side information... --- + nsb = ( nch == 1 ) ? 17 : 32; + frame->fixed_size = 4 + nsb + (frame->protection ? 2 : 0); + // check if enough data is available + if ( frame->fixed_size > max_size ) { + free( frame ); + return NULL; + } + // --- ...and optional crc checksum --- + if ( frame->protection == 0x1 ) { + sideinfo = data + 6; + // if there is a crc: check and discard + crc = (data[4]<<8) + (data[5]<<0); + if ( crc != mp3_calc_layer3_crc( header, sideinfo, nsb ) ) { + sprintf( errormessage, "crc checksum mismatch" ); + errorlevel = 1; // (!!!) careful - file might be broken + } + } + else sideinfo = data + 4; + side_reader = new abitreader( sideinfo, nsb ); + // frame global side info + frame->bit_reservoir = (short) side_reader->read( 9 ); + frame->padbits = (char) side_reader->read( (nch==1) ? 5 : 3 ); + for ( ch = 0; ch < nch; ch++ ) { + frame->granules[ch][0]->share = (char) side_reader->read( 4 ); + frame->granules[ch][1]->share = 0x0; + } + // granule specific side info + for ( gr = 0; gr < 2; gr++ ) { + for ( ch = 0; ch < nch; ch++ ) { + granule = frame->granules[ch][gr]; + granule->main_data_bit = (short) side_reader->read( 12 ); + granule->big_val_pairs = (short) side_reader->read( 9 ); + granule->global_gain = (short) side_reader->read( 8 ); + granule->slength = (char) side_reader->read( 4 ); + granule->window_switching = (char) side_reader->read( 1 ); + if ( granule->window_switching == 0 ) { // for normal blocks + granule->region_table[0] = (char) side_reader->read( 5 ); + granule->region_table[1] = (char) side_reader->read( 5 ); + granule->region_table[2] = (char) side_reader->read( 5 ); + granule->region0_size = (char) side_reader->read( 4 ); + granule->region1_size = (char) side_reader->read( 3 ); + if ( granule->region0_size+granule->region1_size > 20 ) { + sprintf( errormessage, "region size out of bounds" ); + errorlevel = 2; + return NULL; + } + granule->region_bound[0] = + mp3_bandwidth_bounds[(int)frame->samples][(int)granule->region0_size+1]; + granule->region_bound[1] = + mp3_bandwidth_bounds[(int)frame->samples][(int)granule->region0_size+granule->region1_size+2]; + granule->region_bound[2] = granule->big_val_pairs << 1; + if ( granule->region_bound[0] > granule->region_bound[2] ) { + granule->region_bound[0] = granule->region_bound[2]; + granule->region_bound[1] = granule->region_bound[2]; + } else if ( granule->region_bound[1] > granule->region_bound[2] ) + granule->region_bound[1] = granule->region_bound[2]; + granule->block_type = LONG_BLOCK; + granule->mixed_flag = 0; + granule->sb_gain[0] = 0; + granule->sb_gain[1] = 0; + granule->sb_gain[2] = 0; + } else { // for special blocks + granule->block_type = (char) side_reader->read( 2 ); + granule->mixed_flag = (char) side_reader->read( 1 ); + granule->region_table[0] = (char) side_reader->read( 5 ); + granule->region_table[1] = (char) side_reader->read( 5 ); + granule->sb_gain[0] = (char) side_reader->read( 3 ); + granule->sb_gain[1] = (char) side_reader->read( 3 ); + granule->sb_gain[2] = (char) side_reader->read( 3 ); + if ( granule->block_type != SHORT_BLOCK ) { + // region sizes for different block types + granule->region0_size = 8; + granule->region1_size = 0; + granule->region_bound[0] = + mp3_bandwidth_bounds[(int)frame->samples][8]; + } else { // special treatment for mixed blocks needed (!) + granule->region0_size = 9; + granule->region1_size = 0; + granule->region_bound[0] = + mp3_bandwidth_bounds_short[(int)frame->samples][9/3] * 3; + } + granule->region_bound[1] = granule->big_val_pairs << 1; + if ( granule->region_bound[0] > granule->region_bound[1] ) + granule->region_bound[0] = granule->region_bound[1]; + granule->region_bound[2] = granule->region_bound[1]; + granule->region_table[2] = 0; + } + granule->preemphasis = (char) side_reader->read( 1 ); + granule->coarse_scalefactors = (char) side_reader->read( 1 ); + granule->select_htabB = (char) side_reader->read( 1 ); + granule->sv_bound = 0; + // check for obvious problems/contradictions + if ( granule->main_data_bit == 0 ) { + if ( ( granule->big_val_pairs != 0 ) || ( granule->slength != 0 ) ) + frame->n = -1; // mistreat frame number as trouble indicator :-) + } + } + } + delete( side_reader ); + + // calculate total size of main (not aux) data (in byte) + frame->main_bits = 0; + for ( gr = 0; gr < 2; gr++ ) + for ( ch = 0; ch < nch; ch++ ) + frame->main_bits += frame->granules[ch][gr]->main_data_bit; + frame->main_size = (frame->main_bits+7)>>3; + + // calculate temporary size of aux data (in byte), subject to change + frame->aux_size = + frame->frame_size - + frame->fixed_size + + frame->bit_reservoir - + frame->main_size; + + + return frame; +} + + +/* ----------------------------------------------- + build frame from i_variables + ----------------------------------------------- */ +INTERN inline mp3Frame* mp3_build_frame( void ) +{ + mp3Frame* frame; + granuleInfo* granule; + int ch, gr; + int nch; + + + // alloc memory for frame + frame = (mp3Frame*) calloc( 1, sizeof( mp3Frame ) ); + if ( frame == NULL ) { + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return NULL; + } + + // preset pointers + frame->granules = NULL; + frame->prev = NULL; + frame->next = NULL; + + // fill in some info + frame->mpeg = i_mpeg; + frame->layer = i_layer; + frame->protection = i_protection; + frame->bits = i_bitrate; + frame->samples = i_samplerate; + frame->padding = i_padding; + frame->privbit = i_privbit; + frame->channels = i_channels; + frame->stereo_ms = i_stereo_ms; + frame->stereo_int = i_stereo_int; + frame->copyright = i_copyright; + frame->original = i_original; + frame->emphasis = i_emphasis; + frame->bit_reservoir = 0; + frame->padbits = i_padbits; + + // stuff that is known right now (# channels and fixed size) + if ( frame->channels == MP3_MONO ) { + frame->fixed_size = ( frame->protection ) ? 4 + 2 + 17 : 4 + 17; + frame->nchannels = 1; nch = frame->nchannels; + } else { + frame->fixed_size = ( frame->protection ) ? 4 + 2 + 32 : 4 + 32; + frame->nchannels = 2; nch = frame->nchannels; + } + + // alloc memory for granules + frame->granules = (granuleInfo***) calloc( nch, sizeof( granuleInfo** ) ); + for ( ch = 0; ch < nch; ch++ ) { + frame->granules[ch] = (granuleInfo**) calloc( 2, sizeof( granuleInfo* ) ); + for ( gr = 0; gr < 2; gr++ ) + frame->granules[ch][gr] = (granuleInfo*) calloc( 1, sizeof( granuleInfo ) ); + } + + // granule specific stuff + for ( ch = 0; ch < nch; ch++ ) { + for ( gr = 0; gr < 2; gr++ ) { + granule = frame->granules[ch][gr]; + granule->share = ( gr == 0 ) ? i_share : 0; + granule->window_switching = i_sblocks; + granule->mixed_flag = i_mixed; + granule->block_type = LONG_BLOCK; + granule->sb_gain[0] = i_sbgain; + granule->sb_gain[1] = i_sbgain; + granule->sb_gain[2] = i_sbgain; + granule->preemphasis = i_preemphasis; + granule->coarse_scalefactors = i_coarse; + } + } + + + return frame; +} + + +/* ----------------------------------------------- + append frame to the frame chain + ----------------------------------------------- */ +INTERN inline bool mp3_append_frame( mp3Frame* frame ) +{ + static granuleInfo* lastgranule[2] = { NULL, NULL }; + static int n = 0; + int ch; + + + // insert frame into the frame chain, set up links between frames + // aux size correction has to take place elsewhere + if ( lastframe == NULL ) { + firstframe = frame; + frame->prev = NULL; + lastgranule[0] = NULL; + lastgranule[1] = NULL; + n = 0; + } else { + lastframe->next = frame; + frame->prev = lastframe; + } + lastframe = frame; + + // set up links for granules between each other + for ( ch = 0; ch < frame->nchannels; ch++ ) { + frame->granules[ch][0]->n = n<<1; + frame->granules[ch][1]->n = frame->granules[ch][0]->n|1; + frame->granules[ch][0]->next = frame->granules[ch][1]; + frame->granules[ch][1]->prev = frame->granules[ch][0]; + frame->granules[ch][0]->prev = lastgranule[ch]; + frame->granules[ch][1]->next = NULL; + if ( lastgranule[ch] != NULL ) + lastgranule[ch]->next = frame->granules[ch][0]; + lastgranule[ch] = frame->granules[ch][1]; + } + + // some generic stuff + frame->n = n++; + frame->next = NULL; + + + return true; +} + + +/* ----------------------------------------------- + discard frame data + ----------------------------------------------- */ +INTERN inline bool mp3_discard_frame( mp3Frame* frame ) +{ + int nch; + int ch, gr; + + + // discard all data in one frame + nch = frame->nchannels; + if ( frame->granules != NULL ) { + for ( ch = 0; ch < nch; ch++ ) { + for ( gr = 0; gr < 2; gr++ ) + free ( frame->granules[ch][gr] ); + free ( frame->granules[ch] ); + } + free ( frame->granules ); + } + free ( frame ); + + + return true; +} + + +/* ----------------------------------------------- + mute a single frame + ----------------------------------------------- */ +INTERN inline bool mp3_mute_frame( mp3Frame* frame ) +{ + granuleInfo* granule; + unsigned char* ptr; + int nch, ums; + int ch, gr; + + + // mute a single frame -> dangerous, be careful! + nch = frame->nchannels; + ums = 2 + ( nch * 2 * 4 ); + + // store reconstruction data + if ( unmute_data_size == 0 ) { // first alloc - no mem check needed + unmute_data = (unsigned char*) calloc( ++unmute_data_size, sizeof( char ) ); + unmute_data_size = 1; + *unmute_data = 0; + } + unmute_data = (unsigned char*) // realloc for new size + frealloc( unmute_data, ( unmute_data_size + ums ) * sizeof( char ) ); + if ( unmute_data == NULL ) { + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return false; + } + ptr = unmute_data + unmute_data_size; + unmute_data_size += ums; + // some bits are wasted here + // normally muting frames shouldn't be necessary at all anyways + (*ptr) = (frame->privbit&0x1) << 7; + (*ptr) |= (frame->original&0x1) << 6; + (*ptr) |= (frame->copyright&0x1) << 5; + (*ptr++) |= (frame->bit_reservoir >> 8) & 0x1; + (*ptr++) = (frame->bit_reservoir >> 0) & 0xFF; + for ( ch = 0; ch < nch; ch++ ) { + for ( gr = 0; gr < 2; gr++ ) { + granule = frame->granules[ch][gr]; + (*ptr++) = (granule->main_data_bit >> 4) & 0xFF; + (*ptr++) = ( (granule->main_data_bit << 4) & 0xF0 ) | ( granule->slength & 0x0F ); + (*ptr++) = (granule->big_val_pairs >> 1) & 0xFF; + (*ptr++) = (granule->big_val_pairs << 7) & 0x80; + } + } + // take count - careful this doesn't excede 255 + (*unmute_data)++; + + // mute frame - this has to be done in order + // we assume that all previous frames are muted, too! + if ( frame->prev != NULL ) { + // make some room, use prev frame aux too! + frame->bit_reservoir += frame->prev->aux_size; + if ( frame->bit_reservoir >= 512 ) { + frame->prev->aux_size = frame->bit_reservoir - 511; + frame->bit_reservoir = 511; + } else frame->prev->aux_size = 0; + } else frame->bit_reservoir = 0; + frame->aux_size = frame->frame_size - frame->fixed_size + frame->bit_reservoir; + if ( frame->next != NULL ) frame->aux_size -= frame->next->bit_reservoir; + frame->main_size = 0; + frame->main_bits = 0; + if ( frame->granules != NULL ) { + for ( ch = 0; ch < nch; ch++ ) { + for ( gr = 0; gr < 2; gr++ ) { + granule = frame->granules[ch][gr]; + granule->main_data_bit = 0; + granule->big_val_pairs = 0; + granule->slength = 0; + // fix region bounds + granule->region_bound[0] = 0; + granule->region_bound[1] = 0; + granule->region_bound[2] = 0; + } + } + } + + + return true; +} + + +/* ----------------------------------------------- + unmute a single frame + ----------------------------------------------- */ +INTERN inline bool mp3_unmute_frame( mp3Frame* frame ) +{ + granuleInfo* granule; + unsigned char* ptr; + int nch, ums; + int ch, gr; + + + // restore a single frame to it's original, broken state + // enough fix data has to be present, channel mode has to be consistent + nch = g_nchannels; + ums = 2 + ( nch * 2 * 4 ); + ptr = unmute_data + 1 + ( n_bad_first * ums ); + + // unmute frame - has to be done in order, too! + frame->privbit = ((*ptr)>>7) & 0x1; + frame->original = ((*ptr)>>6) & 0x1; + frame->copyright = ((*ptr)>>5) & 0x1; + frame->bit_reservoir = (*ptr++) << 8; + frame->bit_reservoir |= (*ptr++) << 0; + for ( ch = 0; ch < nch; ch++ ) { + for ( gr = 0; gr < 2; gr++ ) { + granule = frame->granules[ch][gr]; + granule->main_data_bit = (*ptr++) << 4; + granule->main_data_bit |= (*ptr) >> 4; + granule->slength = (*ptr++) & 0x0F; + granule->big_val_pairs = (*ptr++) << 1; + granule->big_val_pairs |= (*ptr++) >> 7; + } + } // no need to accomodate for the changed frame params - for now (!!!) + + + return true; +} + + +/* ----------------------------------------------- + build fixed part of physical frame + ----------------------------------------------- */ +INTERN inline unsigned char* mp3_build_fixed( mp3Frame* frame ) +{ + static unsigned char* fixed = ( unsigned char* ) calloc( 64, 1 ); + unsigned char* tmp_ptr; + + granuleInfo* granule; + abitwriter* side_writer; + + unsigned char* header; + unsigned char* sideinfo; + unsigned short crc; + + int nsb = 0; + int nch = 0; + int ch, gr; + + + // preparations + memset( fixed, 0, 64 ); + nch = frame->nchannels; + nsb = ( nch == 1 ) ? 17 : 32; + header = fixed + 0; + sideinfo = fixed + ( ( frame->protection ) ? 4 + 2 : 4 ); + + + // --- frame header --- + + // insert data + header[0] = 0xFF; + header[1] = 0xFA; + header[1] |= frame->mpeg << 3; + header[1] |= frame->layer << 1; + header[1] |= frame->protection ^ 1; + header[2] |= frame->bits << 4; + header[2] |= frame->samples << 2; + header[2] |= frame->padding << 1; + header[2] |= frame->privbit << 0; + header[3] |= frame->channels << 6; + header[3] |= frame->stereo_ms << 5; + header[3] |= frame->stereo_int << 4; + header[3] |= frame->copyright << 3; + header[3] |= frame->original << 2; + header[3] |= frame->emphasis << 0; + + + // --- side information... --- + + // init abitwriter + side_writer = new abitwriter( 64 ); + + // frame global side info + side_writer->write( frame->bit_reservoir, 9 ); + side_writer->write( frame->padbits, (nch==1) ? 5 : 3 ); + for ( ch = 0; ch < nch; ch++ ) + side_writer->write( frame->granules[ch][0]->share, 4 ); + + // granule specific side info + for ( gr = 0; gr < 2; gr++ ) { + for ( ch = 0; ch < nch; ch++ ) { + granule = frame->granules[ch][gr]; + side_writer->write( granule->main_data_bit, 12 ); + side_writer->write( granule->big_val_pairs, 9 ); + side_writer->write( granule->global_gain, 8 ); + side_writer->write( granule->slength, 4 ); + side_writer->write( granule->window_switching, 1 ); + if ( granule->window_switching == 0 ) { // for normal blocks + side_writer->write( granule->region_table[0], 5 ); + side_writer->write( granule->region_table[1], 5 ); + side_writer->write( granule->region_table[2], 5 ); + side_writer->write( granule->region0_size, 4 ); + side_writer->write( granule->region1_size, 3 ); + } else { // for special blocks + side_writer->write( granule->block_type, 2 ); + side_writer->write( granule->mixed_flag, 1 ); + side_writer->write( granule->region_table[0], 5 ); + side_writer->write( granule->region_table[1], 5 ); + side_writer->write( granule->sb_gain[0], 3 ); + side_writer->write( granule->sb_gain[1], 3 ); + side_writer->write( granule->sb_gain[2], 3 ); + } + side_writer->write( granule->preemphasis, 1 ); + side_writer->write( granule->coarse_scalefactors, 1 ); + side_writer->write( granule->select_htabB, 1 ); + } + } + + // get pointer, store and free up memory + tmp_ptr = side_writer->getptr(); + memcpy( sideinfo, tmp_ptr, nsb ); + delete( side_writer ); + free( tmp_ptr ); + + + // --- ...and optional crc checksum --- + + if ( frame->protection == 0x1 ) { + crc = mp3_calc_layer3_crc( header, sideinfo, nsb ); + header[ 4 ] = (crc>>8)&0xFF; + header[ 5 ] = (crc>>0)&0xFF; + } + + + return fixed; +} + + +/* ----------------------------------------------- + seeks for the first proper MPEG audio frame + ----------------------------------------------- */ +INTERN inline int mp3_seek_firstframe( unsigned char* data, int size ) +{ + int mpeg = -1; + int layer = -1; + int samples = -1; + int channels = -1; + int protection = -1; + + int bits; + int padding; + int frame_size; + + int pos0 = 0; + int pos1 = 0; + int pos, n; + + + // check for ID3 or other tag at beginning of data + pos0 = mp3_get_id3_size( data, size ); + + // calculate last tolerable seek position + pos1 = pos0 + GARBAGE_TOLERANCE; + if ( pos1 > size - 4 ) pos1 = size - 4; + + // mp3 frame seeker loop + // conditions for proper first frame: 5 consecutive frames, + // same channel, mpeg, layer, samples setting + while( true ) { + // seek for first frame candidate + for ( ; pos0 < pos1; pos0++ ) + if ( data[pos0] == 0xFF ) if ( (data[pos0+1]&0xE0) == 0xE0 ) break; + // nothing found -> give up + if ( pos0 == pos1 ) return -1; + // check for consecutive frames + for ( pos = pos0, n = 0; ( n < 5 ) && ( pos < size - 4 ); n++, pos += frame_size ) { + // check syncword + if ( ( data[pos] != 0xFF ) || ( (data[pos+1]&0xE0) != 0xE0 ) ) break; + // extract and store or compare data from header + if ( n == 0 ) { + mpeg = (data[pos+1]>>3)&0x3; + layer = (data[pos+1]>>1)&0x3; + protection = (data[pos+1]>>0)&0x1; + samples = (data[pos+2]>>2)&0x3; + channels = (data[pos+3]>>6)&0x3; + } else if ( + ( mpeg != ((data[pos+1]>>3)&0x3) ) || + ( layer != ((data[pos+1]>>1)&0x3) ) || + ( protection != ((data[pos+1]>>0)&0x1) ) || + ( samples != ((data[pos+2]>>2)&0x3) ) || + ( channels != ((data[pos+3]>>6)&0x3) ) ) break; + bits = (data[pos+2]>>4)&0xF; + padding = (data[pos+2]>>1)&0x1; + // check for problems + if ( ( mpeg == 0x1 ) || ( layer == 0x0 ) || + ( bits == 0x0 ) || ( bits == 0xF ) || ( samples == 0x3 ) ) break; + // find out frame size + frame_size = frame_size_table[mpeg][layer][samples][bits]; + if ( padding ) frame_size += (layer == LAYER_I) ? 4 : 1; + } + // consider first frame proper if 5 consecutive frames are found + if ( n >= 5 ) break; + pos0++; + } + + + return pos0; +} + + +/* ----------------------------------------------- + extract ID3v2 tag from beginning of file + ----------------------------------------------- */ +INTERN inline int mp3_get_id3_size( unsigned char* id3tag, int max_size ) +{ + static const char* id3v1_begin = "TAG"; + static const char* id3v2_begin = "ID3"; + static const char* lyrics3_begin = "LYRICSBEGIN"; + static const char* apetag_begin = "APETAGEX"; + bool unsynchronized = false; + int size; + + + // check if at least 10 bytes are available + if ( max_size < 10 ) return 0; + + if ( memcmp( id3v2_begin, id3tag, 3 ) == 0 ) { + // ID3v2 tag -> find out size, start with 10 + size = 10; + // check for unsynchronization + unsynchronized = ( BITN( id3tag[5], 7 ) == 1 ); + // check for footer + size += ( BITN( id3tag[5], 4 ) == 1 ) ? 10 : 0; + // calculate size + size += id3tag[9] << 0; + size += id3tag[8] << 7; + size += id3tag[7] << 14; + size += id3tag[6] << 21; + // check if size is ok + if ( size > max_size ) return 0; + // pay attention to unsynchronization where needed + if ( unsynchronized ) for ( int pos = 0; pos < size-1; pos++ ) { + if ( id3tag[pos] == 0xFF ) if ( id3tag[pos+1] == 0x00 ) { + pos++; size++; + if ( size > max_size ) return 0; + } + } + } + else if ( memcmp( id3v1_begin, id3tag, 3 ) == 0 ) { + // ID3v1 tag -> size is exactle 128 byte + size = 128; + // check if size is ok + if ( size > max_size ) return 0; + } + else if ( ( memcmp( lyrics3_begin, id3tag, 6 ) == 0 ) && ( max_size >= 148 ) ) { + // LYRICS3 tag, must be followed by ID3v1 -> doublecheck and find out size + if ( ( memcmp( lyrics3_begin, id3tag, 11 ) == 0 ) && ( memcmp( id3v1_begin, id3tag + max_size - 128, 3 ) == 0 ) && ( memcmp( lyrics3_begin, (char*) id3tag + max_size - 128 - 9, 6 ) == 0 ) ) + size = max_size; + else return 0; + } + else if ( memcmp( apetag_begin, id3tag, 8 ) == 0 ) { + // APE tag -> keep all the data after (ok solution for now) + size = max_size; + } + else { + // no tag header found -> not a proper tag + return 0; + } + + + return size; +} + + +/* ----------------------------------------------- + calculate frame crc + ----------------------------------------------- */ +INTERN inline unsigned short mp3_calc_layer3_crc( unsigned char* header, unsigned char* sideinfo, int sidesize ) +{ + // crc has a start value of 0xFFFF + unsigned short crc = 0xFFFF; + + // process two last bytes from header... + crc = (crc << 8) ^ crc_table[(crc>>8) ^ header[2]]; + crc = (crc << 8) ^ crc_table[(crc>>8) ^ header[3]]; + // ... and all the bytes from the side information + for ( int i = 0; i < sidesize; i++ ) + crc = (crc << 8) ^ crc_table[(crc>>8) ^ sideinfo[i]]; + + return crc; +} + + +/* ----------------------------------------------- + decode one MP3 frame + ----------------------------------------------- */ +INTERN inline granuleData*** mp3_decode_frame( huffman_reader* dec, mp3Frame* frame ) +{ + // storage + static granuleData*** frame_data = NULL; + granuleInfo* granule; + signed short* coefs; + unsigned char* scfs; + // scalefactors settings + const int* slen; + int sl; + // coefficients settings + short* region_bounds; + char* region_tables; + huffman_dec_table* bv_table; + huffman_conv_set* conv_set; + signed short* cf_start; + int linbits; + // general settings + unsigned char vals[4]; + int bitp = 0; + int lmaxp = 0; + char share; + // counters + int ch, gr; + int p, g, r; + int i; + + + + // alloc mem for frame data if not done before + // no need to free this memory again! + if ( frame_data == NULL ) { + frame_data = ( granuleData*** ) calloc( 2, sizeof( granuleData** ) ); + for ( ch = 0; ch < 2; ch++ ) { + frame_data[ ch ] = ( granuleData** ) calloc( 2, sizeof( granuleData* ) ); + for ( gr = 0; gr < 2; gr++ ) { + frame_data[ ch ][ gr ] = ( granuleData* ) calloc( 1, sizeof( granuleData ) ); + frame_data[ ch ][ gr ]->scalefactors = ( unsigned char* ) calloc( 36, sizeof( char ) ); + frame_data[ ch ][ gr ]->coefficients = ( signed short* ) calloc( 578, sizeof( short ) ); + } + } + } + + + // decode frame + for ( gr = 0; gr < 2; gr++ ) { + for ( ch = 0; ch < frame->nchannels; ch++ ) { + // --- preparations --- + granule = frame->granules[ch][gr]; + coefs = frame_data[ch][gr]->coefficients; + scfs = frame_data[ch][gr]->scalefactors; + cf_start = coefs; + // clear memory (= set coefficents/scalefactors zero) + memset( coefs, 0, sizeof( short ) * 576 ); + memset( scfs, 0, sizeof( char ) * 36 ); + // set position in stream + dec->setpos( frame->main_index + ( bitp / 8 ), 8 - ( bitp % 8 ) ); + dec->reset_counter(); + // take count of inner frame main data bits + lmaxp = granule->main_data_bit; + bitp += lmaxp; + // set decoding parameters + slen = slength_table[ (int) granule->slength ]; + region_bounds = granule->region_bound; + region_tables = granule->region_table; + + // --- scale factors --- + // read long block scalefactors (with sharing) + if ( granule->block_type != SHORT_BLOCK ) { + // get sharing params if any + share = ( gr ) ? frame->granules[ch][0]->share : 0; + // read 21 (max) scalefactors + for ( g = 0, p = 0; g < 4; g++ ) { + if ( (share>>(3-g)) & 0x1 ) { // shared + memcpy( scfs, frame_data[ch][0]->scalefactors + p, sizeof( char) * scf_width[ g ] ); + scfs += scf_width[ g ]; + p = scf_bounds[ g ]; + } else for ( sl = slen[ (g<2)?0:1 ]; p < scf_bounds[ g ]; p++ ) { // non shared + *(scfs++) = dec->read_bits( sl ); + } + } + } else { // read short block scfs + // read 36 (3*12) scalefactors + for ( i = 0; i < 3; i++ ) // 3 subblocks + for ( g = 0, p = 0; g < 3; g++ ) // 3 groups + for ( sl = slen[ (g==0)?0:1 ]; p < scf_bounds_short[ g ]; p++ ) // no sharing! + *(scfs++) = dec->read_bits( sl ); + } + + // --- coefficients / big values --- + for ( p = 0, r = 0; r < 3; r++ ) { + if ( region_tables[ r ] == 0 ) { // tbl0 skipping + coefs = cf_start + region_bounds[ r ]; + p = region_bounds[ r ]; + continue; + } + // decoding with other tables + bv_table = bv_dec_table + region_tables[ r ]; + if ( bv_table == NULL ) return NULL; + conv_set = bv_table->h; + linbits = bv_table->linbits; + if ( linbits == 0 ) { // without linbits + for ( ; p < region_bounds[ r ]; p += 2, coefs += 2 ) { + dec->decode_pair( conv_set, vals ); + for ( i = 0; i < 2; i++ ) if ( vals[i] > 0 ) + coefs[i] = ( dec->read_bit() ) ? -vals[i] : vals[i]; + if ( dec->get_count() > lmaxp ) { + // high error tolerance! + memset( coefs, 0, sizeof( short ) * 2 ); + break; + } + } + } else { // with linbits + for ( ; p < region_bounds[ r ]; p += 2, coefs += 2 ) { + dec->decode_pair( conv_set, vals ); + for ( i = 0; i < 2; i++ ) if ( vals[i] > 0 ) { + coefs[i] = ( vals[i] == 15 ) ? 15 + dec->read_bits( linbits ) : vals[i]; + if ( dec->read_bit() ) coefs[i] = - coefs[i]; + } + if ( dec->get_count() > lmaxp ) { + // high error tolerance! + memset( coefs, 0, sizeof( short ) * 2 ); + break; + } + } + } + } + + // --- coefficients / small values --- + conv_set = ( granule->select_htabB ) ? &htabB_dec : &htabA_dec; + for ( ; ( dec->get_count() < lmaxp ) && ( p < 576 ); p += 4, coefs += 4 ) { + dec->decode_quadruple( conv_set, vals ); + for ( i = 0; i < 4; i++ ) if ( vals[i] ) + coefs[i] = ( dec->read_bit() ) ? -1 : 1; + if ( dec->get_count() > lmaxp ) { + memset( coefs, 0, sizeof( short ) * 4 ); + break; + } + } + + // set sv_bound + granule->sv_bound = p; + } + } + + + + return frame_data; +} + +/* ----------------------- End of MP3 specific functions -------------------------- */ + +/* ----------------------- Begin of PMP specific functions -------------------------- */ + + +/* ----------------------------------------------- + writes the PMP file header + ----------------------------------------------- */ +INTERN inline bool pmp_write_header( iostream* str ) +{ + unsigned char header[4] = { 0 }; + unsigned char nframes[4] = { 0 }; + + + // build the header[] + // store necessary information, ignore unsupported + // 1st byte: global samples and channels, and... + // ...bitrate (zero if vbr/not global) + header[0] |= i_samplerate << 6; // sample rate + header[0] |= i_channels << 4; // channel mode + header[0] |= ( (i_bitrate!=-1) ? i_bitrate : 0 ) << 0; // bitrate + // 2nd byte: usage of padding, ms/int stereo, special blocks, subblock gain, ... + // ... sharing, preemphasis and coarse scalefactors + header[1] |= ( (i_padding==0) ? 0 : 1 ) << 7; // padding + header[1] |= ( (i_stereo_ms==0 ) ? 0 : 1 ) << 6; // ms stereo + header[1] |= ( (i_stereo_int==0 ) ? 0 : 1 ) << 5; // int stereo + header[1] |= ( (i_sblocks==0 ) ? 0 : 1 ) << 4; // special blocks + header[1] |= ( (i_sbgain==0) ? 0 : 1 ) << 3; // subblock gain + header[1] |= ( (i_share==0) ? 0 : 1 ) << 2; // sharing + header[1] |= ( (i_preemphasis==0) ? 0 : 1 ) << 1; // preemphasis + header[1] |= ( (i_coarse==0) ? 0 : 1 ) << 0; // coarse scfs + // 3rd byte: setting of protection, original, copyright and private bits, ... + // ... emphasis setting and indicators for data before/after, special block diffs, bad first frames + header[2] |= i_protection << 7; // protection + header[2] |= i_original << 6; // original bit + header[2] |= i_copyright << 5; // copyright bit + header[2] |= i_privbit << 4; // private bit + header[2] |= i_emphasis << 2; // emphasis + header[2] |= ( (data_before_size>0) ? 1 : 0 ) << 1; // data before + header[2] |= ( (data_after_size>0) ? 1 : 0 ) << 0; // data after + // 4th byte: usage of bit reservoir, special block diffs, bad first frames + // ... still 5 free (use for max comp) + header[3] |= ( (i_bit_res==0) ? 0 : 1 ) << 7; // bit reservoir + header[3] |= ( (i_sb_diff==0) ? 0 : 1 ) << 6; // special block diffs + header[3] |= ( (n_bad_first>0) ? 1 : 0 ) << 5; // bad first frames + + // store # of frames in nframes[] in little endian + // yup, that's a waste, but - so what? + nframes[0] = ( g_nframes >> 24 ) & 0xFF; + nframes[1] = ( g_nframes >> 16 ) & 0xFF; + nframes[2] = ( g_nframes >> 8 ) & 0xFF; + nframes[3] = ( g_nframes >> 0 ) & 0xFF; + + // 8 bytes to write, together with magic # and version: 11 bytes + str->write( (void*) header, 1, 4 ); + str->write( (void*) nframes, 1, 4 ); + + + return true; +} + + +/* ----------------------------------------------- + reads the PMP file header + ----------------------------------------------- */ +INTERN inline bool pmp_read_header( iostream* str ) +{ + unsigned char header[4] = { 0 }; + unsigned char nframes[4] = { 0 }; + + mp3Frame* frame = NULL; + int n; + + + // read header and size from file + str->read( (void*) header, 1, 4 ); + str->read( (void*) nframes, 1, 4 ); + if ( str->chkeof() ) { + sprintf( errormessage, "unexpected end of data" ); + errorlevel = 2; + return false; + } + + // extract information from header[] + // 1st byte: global samples and channels, and... + // ...bitrate (zero if vbr/not global) + i_samplerate = (header[0]>>6)&0x3; + i_channels = (header[0]>>4)&0x3; + i_bitrate = (header[0]>>0)&0xF; + if ( i_bitrate == 0 ) i_bitrate =-1; + // 2nd byte: usage of padding, ms/int stereo, special blocks, subblock gain, ... + // ... sharing, preemphasis and coarse scalefactors + i_padding = -((header[1]>>7)&0x1); + i_stereo_ms = -((header[1]>>6)&0x1); + i_stereo_int = ((header[1]>>5)&0x1); + i_sblocks = ((header[1]>>4)&0x1); + i_sbgain = -((header[1]>>3)&0x1); + i_share = -((header[1]>>2)&0x1); + i_preemphasis = -((header[1]>>1)&0x1); + i_coarse = -((header[1]>>0)&0x1); + // 3rd byte: setting of protection, original, copyright and private bits, ... + // ... emphasis setting and indicators for data before/after, special block diffs, bad first frames + i_protection = (header[2]>>7)&0x1; + i_original = (header[2]>>6)&0x1; + i_copyright = (header[2]>>5)&0x1; + i_privbit = (header[2]>>4)&0x1; + i_emphasis = (header[2]>>2)&0x3; + data_before_size = (header[2]>>1)&0x1; + data_after_size = (header[2]>>0)&0x1; + // 4th byte: usage of bit reservoir, special block diffs, bad first frames + // ... still 5 free (use for max comp) + i_bit_res = -((header[3]>>7)&0x1); + i_sb_diff = ((header[3]>>6)&0x1); + n_bad_first = (header[3]>>5)&0x1; + + // set nframes known i_variables + i_mpeg = MP3_V1_0; + i_layer = LAYER_III; + i_padbits = 0; + i_mixed = 0; + i_aux_h = -2; + + // check for possible mistakes made by myself + if ( ( i_bitrate == 0xF ) || ( i_samplerate == 0x3 ) ) { + sprintf( errormessage, "not a proper PMP file" ); + errorlevel = 2; + return false; + } + + // extract # of frames from nframes[] in little endian + g_nframes = 0; + g_nframes |= nframes[0] << 24; + g_nframes |= nframes[1] << 16; + g_nframes |= nframes[2] << 8; + g_nframes |= nframes[3] << 0; + + // build frames structure + for ( n = 0; n < g_nframes; n++ ) { + // read frame, check result + frame = mp3_build_frame(); + // bad result -> use existing error message and exit + if ( frame == NULL ) return false; + // insert frame into the frame chain + mp3_append_frame( frame ); + } + + // make some safe assumptions + g_nchannels = ( i_channels == MP3_MONO ) ? 1 : 2; // number of channels + g_samplerate = mp3_samplerate_table[(int)i_samplerate]; // sample rate + g_bitrate = ( i_bitrate == -1 ) ? 0 : mp3_bitrate_table[(int)i_bitrate]; // bit rate + + + return true; +} + + +#if !defined( STORE_ID3 ) +/* ----------------------------------------------- + encodes a stream of generic data (8bit) + ----------------------------------------------- */ +INTERN bool pmp_encode_id3( aricoder* enc ) +{ + // this will be used for id3 tags, other tags and garbage + // little is known, so we'll just use a generic markov model + model_s* model; + int i; + + + // arithmetic encode data + model = INIT_MODEL_S( 256 + 1, 256, 0 ); + // data before main data + if ( data_before_size > 0 ) { + for ( i = 0; i < data_before_size; i++ ) + encode_ari( enc, model, data_before[ i ] ); + // encode end-of-data symbol (256) + encode_ari( enc, model, 256 ); + } + // data after main data + if ( data_after_size > 0 ) { + for ( i = 0; i < data_after_size; i++ ) + encode_ari( enc, model, data_after[ i ] ); + // encode end-of-data symbol (256) + encode_ari( enc, model, 256 ); + } + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + decodes a stream of generic data (8 bit) + ----------------------------------------------- */ +INTERN bool pmp_decode_id3( aricoder* dec ) +{ + abytewriter* bwrt; + model_s* model; + int c; + + + // decode max. 2 chunks of data, ending with 256 symbol + model = INIT_MODEL_S( 256 + 1, 256, 0 ); + + // data before main data + if ( data_before_size > 0 ) { + bwrt = new abytewriter( 1024 ); // start byte writer + while ( true ) { + c = decode_ari( dec, model ); + if ( c == 256 ) break; + bwrt->write( (unsigned char) c ); + } + // check for out of memory + if ( bwrt->error ) { + delete bwrt; delete model; + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return false; + } + // get data/true length and close byte writer + data_before = bwrt->getptr(); + data_before_size = bwrt->getpos(); + delete bwrt; + } + + // data after main data + if ( data_after_size > 0 ) { + bwrt = new abytewriter( 1024 ); // start byte writer + while ( true ) { + c = decode_ari( dec, model ); + if ( c == 256 ) break; + bwrt->write( (unsigned char) c ); + } + // check for out of memory + if ( bwrt->error ) { + delete bwrt; delete model; + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return false; + } + // get data/true length and close byte writer + data_after = bwrt->getptr(); + data_after_size = bwrt->getpos(); + delete bwrt; + } + + // done, delete model + delete( model ); + + + return true; +} +#else +/* ----------------------------------------------- + stores a stream of generic data (8bit) + ----------------------------------------------- */ +INTERN inline int pmp_store_data( iostream* str, unsigned char* data, int size ) +{ + unsigned char ezis[4]; // little endian size + + + // store size in little endian + ezis[0] = ( size >> 24 ) & 0xFF; + ezis[1] = ( size >> 16 ) & 0xFF; + ezis[2] = ( size >> 8 ) & 0xFF; + ezis[3] = ( size >> 0 ) & 0xFF; + + // the rest is as simple as it gets... + str->write( ezis, sizeof( char ), 4 ); + str->write( data, sizeof( char ), size ); + + + return size; +} + + +/* ----------------------------------------------- + unstores a stream of generic data (8bit) + ----------------------------------------------- */ +INTERN inline int pmp_unstore_data( iostream* str, unsigned char** data ) +{ + unsigned char ezis[4]; // little endian size + int size = 0; // integer size + + + // unstore little endian size + str->read( ezis, sizeof( char ), 4 ); + size |= ezis[0] << 24; + size |= ezis[1] << 16; + size |= ezis[2] << 8; + size |= ezis[3] << 0; + + // alloc memory for data + *data = (unsigned char*) calloc( size, sizeof( char ) ); + if ( *data == NULL ) { + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return -1; + } + + // read data to memory + str->read( *data, sizeof( char ), size ); + + // check for eof trouble + if ( str->chkeof() ) { + sprintf( errormessage, "unexpected end of data" ); + errorlevel = 2; + return -1; + } + + + return size; +} +#endif + + +/* ----------------------------------------------- + encode the padding bit (1 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_encode_padding( aricoder* enc ) +{ + // padding bit: + // - no correlation with others at all + // - always comes in perfectly predictable run/length pairs + // -> use run length encoding and arithmetic compression + // (can still be improved upon) + + model_s* model; + int run = 0; + char bit = 0; + + + // encoding start + model = INIT_MODEL_S( PADDING_MAX_RUN+1, PADDING_MAX_RUN+1, 1 ); + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) { + if ( frame->padding != bit ) { + bit ^= 0x1; + while ( run >= PADDING_MAX_RUN+1 ) { + encode_ari( enc, model, PADDING_MAX_RUN ); + model->shift_context( PADDING_MAX_RUN ); + encode_ari( enc, model, 0 ); + model->shift_context( 0 ); + run -= PADDING_MAX_RUN; + } + encode_ari( enc, model, run ); + model->shift_context( run ); + run = 0; + } + run++; + } + // encode last run + if ( run > 0 ) { + while ( run >= PADDING_MAX_RUN+1 ) { + encode_ari( enc, model, PADDING_MAX_RUN ); + model->shift_context( PADDING_MAX_RUN ); + encode_ari( enc, model, 0 ); + model->shift_context( 0 ); + run -= PADDING_MAX_RUN; + } + encode_ari( enc, model, run ); + } + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + decode the padding bit (1 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_decode_padding( aricoder* dec ) +{ + model_s* model; + int run = 0; + char bit = 0; + + + // decoding start + model = INIT_MODEL_S( PADDING_MAX_RUN+1, PADDING_MAX_RUN+1, 1 ); + // decode the first run + run = decode_ari( dec, model ); + model->shift_context( run ); + // ... and all others + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) { + while ( run == 0 ) { + bit ^= 0x1; + run = decode_ari( dec, model ); + model->shift_context( run ); + } + run--; + frame->padding = bit; + } + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + encode block types (1-3 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_encode_block_types( aricoder* enc ) +{ + // block types: + // - consist of two things: switching bit and block type spec + // - safe for the first few frames, block type spec is predictable + // - switching occurs periodically + // - ch1 block types are often identical to ch0 block types + // -> use run length encoding for switching and predict specs + + granuleInfo* granule; + model_s* mod_sw; + model_s* mod_bt; + int run = 0; + char bit = 0; + int ctx; + int c; + + + // init models + mod_sw = INIT_MODEL_S( SWITCHING_MAX_RUN+1, SWITCHING_MAX_RUN+1, 1 ); + mod_bt = INIT_MODEL_S( 4, 4, 1 ); + + // encoding start + for ( int ch = 0; ch < g_nchannels; ch++ ) { + if ( ( i_sb_diff == 0 ) && ( ch == 1 ) ) break; + mod_sw->shift_context( 0 ); run = 0; + // first step - encode the switching runs + for ( bit = 0, granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next ) { + // encode the switching run + if ( granule->window_switching != bit ) { + bit ^= 0x1; + while ( run >= SWITCHING_MAX_RUN+1 ) { + encode_ari( enc, mod_sw, SWITCHING_MAX_RUN ); + mod_sw->shift_context( SWITCHING_MAX_RUN ); + encode_ari( enc, mod_sw, 0 ); + mod_sw->shift_context( 0 ); + run -= SWITCHING_MAX_RUN; + } + encode_ari( enc, mod_sw, run ); + mod_sw->shift_context( run ); + run = 0; + } + run++; + } + if ( run > 0 ) { // encode last run + while ( run >= SWITCHING_MAX_RUN+1 ) { + encode_ari( enc, mod_sw, SWITCHING_MAX_RUN ); + mod_sw->shift_context( SWITCHING_MAX_RUN ); + encode_ari( enc, mod_sw, 0 ); + mod_sw->shift_context( 0 ); + run -= SWITCHING_MAX_RUN; + } + encode_ari( enc, mod_sw, run ); + mod_sw->shift_context( run ); + } + // second step - encode the block types + c = STOP_BLOCK; + for ( granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next ) { + if ( granule->window_switching ) { + if ( c == STOP_BLOCK ) ctx = START_BLOCK; + else if ( granule->next != NULL ) + ctx = ( granule->next->window_switching ) ? SHORT_BLOCK : STOP_BLOCK; + else ctx = STOP_BLOCK; + mod_bt->shift_context( ctx ); + c = granule->block_type; + encode_ari( enc, mod_bt, c ); + } + } + } + + // done, delete models + delete( mod_sw ); + delete( mod_bt ); + + + return true; +} + + +/* ----------------------------------------------- + decode block types (1-3 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_decode_block_types( aricoder* dec ) +{ + granuleInfo* granule0; + granuleInfo* granule1; + model_s* mod_sw; + model_s* mod_bt; + char bit = 0; + int run; + int ctx; + int c; + + + // init models + mod_sw = INIT_MODEL_S( SWITCHING_MAX_RUN+1, SWITCHING_MAX_RUN+1, 1 ); + mod_bt = INIT_MODEL_S( 4, 4, 1 ); + + // decoding start + for ( int ch = 0; ch < g_nchannels; ch++ ) { + if ( ( i_sb_diff == 0 ) && ( ch == 1 ) ) break; + mod_sw->shift_context( 0 ); + // first step - decode the switching runs + // decode the first run + run = decode_ari( dec, mod_sw ); + mod_sw->shift_context( run ); + // ... and all others + for ( bit = 0, granule0 = firstframe->granules[ch][0]; granule0 != NULL; granule0 = granule0->next ) { + while ( run == 0 ) { + bit ^= 0x1; + run = decode_ari( dec, mod_sw ); + mod_sw->shift_context( run ); + } + run--; + granule0->window_switching = bit; + } + // second step - decode the block types + c = STOP_BLOCK; + for ( granule0 = firstframe->granules[ch][0]; granule0 != NULL; granule0 = granule0->next ) { + if ( granule0->window_switching ) { + if ( c == STOP_BLOCK ) ctx = START_BLOCK; + else if ( granule0->next != NULL ) + ctx = ( granule0->next->window_switching ) ? SHORT_BLOCK : STOP_BLOCK; + else ctx = STOP_BLOCK; + mod_bt->shift_context( ctx ); + c = decode_ari( dec, mod_bt ); + granule0->block_type = c; + } else granule0->block_type = LONG_BLOCK; + } + } + + // done, delete model + delete( mod_sw ); + delete( mod_bt ); + + // copy ch1 block types to ch0 if identical + if ( ( i_sb_diff == 0 ) && ( g_nchannels == 2 ) ) { + granule1 = firstframe->granules[1][0]; + for ( granule0 = firstframe->granules[0][0]; granule0 != NULL; granule0 = granule0->next ) { + granule1->window_switching = granule0->window_switching; + granule1->block_type = granule0->block_type; + granule1 = granule1->next; + } + } + + + return true; +} + + +/* ----------------------------------------------- + encode the global gain (8 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_encode_global_gain( aricoder* enc ) +{ + // global gain: + // - high correlation with everything else + // - high noise + // - difficult to predict from each other + // -> encode using differential coding and 0th order model + // this will serve as context for everything else + + granuleInfo* granule0; + granuleInfo* granule1; + model_s* model; + int last = 0; + int c = 0; + + + // set up model (will use one model for both channels) + model = INIT_MODEL_S( 256, 0, 0 ); + + // --- first channel --- + // model->shift_context( 0 ); + for ( granule0 = firstframe->granules[0][0]; granule0 != NULL; granule0 = granule0->next ) { + c = ( granule0->global_gain - last ) & 0xFF; + last = granule0->global_gain; + encode_ari( enc, model, c ); + } + + // --- second channel --- + if ( g_nchannels == 2 ) { + // model->shift_context( 0 ); + granule0 = firstframe->granules[0][0]; + for ( granule1 = firstframe->granules[1][0]; granule1 != NULL; granule1 = granule1->next ) { + c = ( granule1->global_gain - granule0->global_gain ) & 0xFF; + granule0 = granule0->next; + encode_ari( enc, model, c ); + } + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + decode the global gain (8 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_decode_global_gain( aricoder* dec ) +{ + granuleInfo* granule0; + granuleInfo* granule1; + model_s* model; + int last = 0; + int c = 0; + + + // set up model (will use one model for both channels) + model = INIT_MODEL_S( 256, 0, 0 ); + + // --- first channel --- + // model->shift_context( 0 ); + for ( granule0 = firstframe->granules[0][0]; granule0 != NULL; granule0 = granule0->next ) { + c = decode_ari( dec, model ); + // model->shift_context( c ); + last = ( c + last ) & 0xFF; + granule0->global_gain = last; + } + + // --- second channel --- + if ( g_nchannels == 2 ) { + // model->shift_context( 0 ); + granule0 = firstframe->granules[0][0]; + for ( granule1 = firstframe->granules[1][0]; granule1 != NULL; granule1 = granule1->next ) { + c = decode_ari( dec, model ); + // model->shift_context( c ); + granule1->global_gain = ( c + granule0->global_gain ) & 0xFF; + granule0 = granule0->next; + } + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + encode the slength (4 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_encode_slength( aricoder* enc ) +{ + // slength: + // - high correlation with global gain + // - different correlation for ch0 and ch1 + // - predictable from each other to some degree + // -> encode using gg_context and markov model + + unsigned char* gg_ctx; + granuleInfo* granule; + model_s* model; + int ch; + int c; + + + // set up model (one model for both channels, flush in between) + model = INIT_MODEL_S( 16, (GG_CONTEXT_SIZE > 16 ) ? GG_CONTEXT_SIZE : 16, 2 ); + + // encoding start + for ( ch = 0; ch < g_nchannels; ch++ ) { + // reset and flush model + model->flush_model( 1 ); + gg_ctx = gg_context[ ch ]; c = 0; + // encode one channel + for ( granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next ) { + shift_model( model, *(gg_ctx++), c ); + c = granule->slength; + encode_ari( enc, model, c ); + } + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + decode the slength (4 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_decode_slength( aricoder* dec ) +{ + unsigned char* gg_ctx; + granuleInfo* granule; + model_s* model; + int ch; + int c; + + + // set up model (one model for both channels, flush in between) + model = INIT_MODEL_S( 16, (GG_CONTEXT_SIZE > 16 ) ? GG_CONTEXT_SIZE : 16, 2 ); + + // decoding start + for ( ch = 0; ch < g_nchannels; ch++ ) { + // reset and flush model + model->flush_model( 1 ); + gg_ctx = gg_context[ ch ]; c = 0; + // decode one channel + for ( granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next ) { + shift_model( model, *(gg_ctx++), c ); + c = decode_ari( dec, model ); + granule->slength = c; + } + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + encode ms stereo setting (1 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_encode_stereo_ms( aricoder* enc ) +{ + // stereo ms bit: + // - only occurs in joint stereo mode + // - predictable from each other to some degree + // -> encode using markov model + + model_b* model; + unsigned char ctx = 0; + + + // encoding start + model = INIT_MODEL_B( 16, 1 ); + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) { + model->shift_context( ctx ); + encode_ari( enc, model, frame->stereo_ms ); + ctx = ( ( ctx << 1 ) | frame->stereo_ms ) & 0xF; + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + decode ms stereo setting (1 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_decode_stereo_ms( aricoder* dec ) +{ + model_b* model; + unsigned char ctx = 0; + + + // decoding start + model = INIT_MODEL_B( 16, 1 ); + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) { + model->shift_context( ctx ); + frame->stereo_ms = decode_ari( dec, model ); + ctx = ( ( ctx << 1 ) | frame->stereo_ms ) & 0xF; + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + encode region bounds and tables (32 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_encode_region_data( aricoder* enc ) +{ + // region bounds: + // - little correlation with global gain + // - high correlation among each others + // - no good context for bv bounds at all + // - sv bounds have to be processed elsewhere + // -> different treatment for r0, r1 and bv: + // -> r0: markov model and bv context + // -> r1: r0 and bv context + // -> bv: block type context + // + // huffman table selection: + // - high correlation with global gain + // - high correlation between neighbors and tables + // -> encode using gg_context and markov model + // -> each region gets its own model + + + const int* bw_conv = mp3_bandwidth_conv[ (int) i_samplerate ]; + unsigned char* gg_ctx; + granuleInfo* granule; + model_s* mod_t0; + model_s* mod_t1; + model_s* mod_t2; + model_b* mod_ts; + model_s* mod_s0; + model_s* mod_s1; + model_s* mod_bv; + int t_r0, t_r1, t_r2, t_sv; + int s_r0, s_r2; + // int s_r0, s_r1, s_r2; + int ctx_sv; + int ch; + + + // set up models (one for each region table and size) + mod_t0 = INIT_MODEL_S( 32, (GG_CONTEXT_SIZE > 32 ) ? GG_CONTEXT_SIZE : 32, 2 ); + mod_t1 = INIT_MODEL_S( 32, 32, 2 ); + mod_t2 = INIT_MODEL_S( 32, 32, 2 ); + mod_ts = INIT_MODEL_B( 16, 1 ); + mod_s0 = INIT_MODEL_S( 16, 22, 2 ); + mod_s1 = INIT_MODEL_S( 8, 22, 2 ); + mod_bv = INIT_MODEL_S( (576/2)+1, 1+1, 1 ); + + // encoding start + for ( ch = 0; ch < g_nchannels; ch++ ) { + // reset and flush models + mod_s0->flush_model( 1 ); + mod_s1->flush_model( 1 ); + mod_bv->flush_model( 1 ); + // reset context + gg_ctx = gg_context[ ch ]; ctx_sv = 0; + t_r0 = 0; t_r1 = 0; t_r2 = 0; t_sv = 0; + // s_r0 = 0; s_r1 = 0; s_r2 = 0; + s_r0 = 0; s_r2 = 0; + // encode all region bounds and tables for one channel + for ( granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next ) { + // --- region bounds (big_val_pairs, region0_size, region2_size) --- + if ( granule->big_val_pairs > 576 / 2 ) { + sprintf( errormessage, "big value pairs out of bounds (%ch>%ch)", granule->big_val_pairs, 576 / 2 ); + errorlevel = 2; + return false; + } + if ( granule->window_switching ) { + // region 2 size (# big value pairs) + mod_bv->shift_context( ( granule->block_type == SHORT_BLOCK ) ? 1 : 0 ); + encode_ari( enc, mod_bv, granule->big_val_pairs ); + s_r0 = 0; // s_r1 = 0; + } else { + s_r2 = bw_conv[ granule->big_val_pairs << 1 ]; + // region 2 size (# big value pairs) + mod_bv->shift_context( 0 ); + encode_ari( enc, mod_bv, granule->big_val_pairs ); + // region 0 size + shift_model( mod_s0, s_r0, s_r2 ); + s_r0 = granule->region0_size; + encode_ari( enc, mod_s0, s_r0 ); + // region 1 size + shift_model( mod_s1, s_r0, s_r2 ); + encode_ari( enc, mod_s1, granule->region1_size ); + // context customizations + s_r0++; // s_r1 = s_r0 + granule->region1_size + 1; + } + // --- region tables (region0/1/2_table, select_htabB) --- + // region 0 table + shift_model( mod_t0, *gg_ctx, t_r0 ); + // shift_model( mod_t0, s_r0, t_r0 ); + t_r0 = granule->region_table[0]; + encode_ari( enc, mod_t0, t_r0 ); + // region 1 table + shift_model( mod_t1, t_r0, s_r0 ); + t_r1 = granule->region_table[1]; + encode_ari( enc, mod_t1, t_r1 ); + // region 2 table + if ( !granule->window_switching ) { + shift_model( mod_t2, t_r0, t_r1 ); + t_r2 = granule->region_table[2]; + encode_ari( enc, mod_t2, t_r2 ); + } + // small values table + mod_ts->shift_context( ctx_sv ); + t_sv = granule->select_htabB; + encode_ari( enc, mod_ts, t_sv ); + ctx_sv = ( ( ctx_sv << 1 ) | t_sv ) & 0xF; + // advance context + gg_ctx++; + } + } + + // done, delete models + delete( mod_t0 ); + delete( mod_t1 ); + delete( mod_t2 ); + delete( mod_ts ); + delete( mod_s0 ); + delete( mod_s1 ); + delete( mod_bv ); + + + return true; +} + + +/* ----------------------------------------------- + decode region sizes and table selection (32 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_decode_region_data( aricoder* dec ) +{ + const int* bw_conv = mp3_bandwidth_conv[ (int) i_samplerate ]; + unsigned char* gg_ctx; + granuleInfo* granule; + model_s* mod_t0; + model_s* mod_t1; + model_s* mod_t2; + model_b* mod_ts; + model_s* mod_s0; + model_s* mod_s1; + model_s* mod_bv; + int t_r0, t_r1, t_r2, t_sv; + int s_r0, s_r2; + // int s_r0, s_r1, s_r2; + int ctx_sv; + int ch; + + + // set up models (one for each region table and size) + mod_t0 = INIT_MODEL_S( 32, (GG_CONTEXT_SIZE > 32 ) ? GG_CONTEXT_SIZE : 32, 2 ); + mod_t1 = INIT_MODEL_S( 32, 32, 2 ); + mod_t2 = INIT_MODEL_S( 32, 32, 2 ); + mod_ts = INIT_MODEL_B( 16, 1 ); + mod_s0 = INIT_MODEL_S( 16, 22, 2 ); + mod_s1 = INIT_MODEL_S( 8, 22, 2 ); + mod_bv = INIT_MODEL_S( (576/2)+1, 1+1, 1 ); + + // decoding start + for ( ch = 0; ch < g_nchannels; ch++ ) { + // reset and flush model + mod_s0->flush_model( 1 ); + mod_s1->flush_model( 1 ); + mod_bv->flush_model( 1 ); + // reset context + gg_ctx = gg_context[ ch ]; ctx_sv = 0; + t_r0 = 0; t_r1 = 0; t_r2 = 0; t_sv = 0; + // s_r0 = 0; s_r1 = 0; s_r2 = 0; + s_r0 = 0; s_r2 = 0; + // decode all region tables for one channel + for ( granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next ) { + // --- region bounds (big_val_pairs, region0_size, region2_size) --- + if ( !granule->window_switching ) { + // region 2 + mod_bv->shift_context( 0 ); + granule->big_val_pairs = decode_ari( dec, mod_bv ); + s_r2 = bw_conv[ granule->big_val_pairs << 1 ]; + // region 0 + shift_model( mod_s0, s_r0, s_r2 ); + s_r0 = decode_ari( dec, mod_s0 ); + granule->region0_size = s_r0; + // region 1 + shift_model( mod_s1, s_r0, s_r2 ); + granule->region1_size = decode_ari( dec, mod_s1 ); + // set region 1/2 bounds + granule->region_bound[0] = + mp3_bandwidth_bounds[(int)i_samplerate][s_r0+1]; + granule->region_bound[1] = + mp3_bandwidth_bounds[(int)i_samplerate][s_r0+granule->region1_size+2]; + // set bv bound and check other bounds + granule->region_bound[2] = granule->big_val_pairs << 1; + if ( granule->region_bound[0] > granule->region_bound[2] ) { + granule->region_bound[0] = granule->region_bound[2]; + granule->region_bound[1] = granule->region_bound[2]; + } else if ( granule->region_bound[1] > granule->region_bound[2] ) + granule->region_bound[1] = granule->region_bound[2]; + // context customizations + s_r0++; // s_r1 = s_r0 + granule->region1_size + 1; + } else if ( granule->block_type != SHORT_BLOCK ) { + // region sizes for different block types + granule->region0_size = 8; + granule->region1_size = 0; + // set region bound + granule->region_bound[0] = + mp3_bandwidth_bounds[(int)i_samplerate][8]; + // decode bv pairs, set bound and check r0 bound + mod_bv->shift_context( 0 ); + granule->big_val_pairs = decode_ari( dec, mod_bv ); + granule->region_bound[1] = granule->big_val_pairs << 1; + if ( granule->region_bound[0] > granule->region_bound[1] ) + granule->region_bound[0] = granule->region_bound[1]; + granule->region_bound[2] = granule->region_bound[1]; + // context setting + s_r0 = 0; // s_r1 = 0; + } else { // special treatment for mixed blocks needed (!) + granule->region0_size = 9; + granule->region1_size = 0; + // set region bound + granule->region_bound[0] = + mp3_bandwidth_bounds_short[(int)i_samplerate][9/3] * 3; + // decode bv pairs, set bound and check r0 bound + mod_bv->shift_context( 1 ); + granule->big_val_pairs = decode_ari( dec, mod_bv ); + granule->region_bound[1] = granule->big_val_pairs << 1; + if ( granule->region_bound[0] > granule->region_bound[1] ) + granule->region_bound[0] = granule->region_bound[1]; + granule->region_bound[2] = granule->region_bound[1]; + // context setting + s_r0 = 0; // s_r1 = 0; + } + // --- region tables (region0/1/2_table, select_htabB) --- + // region 0 table + shift_model( mod_t0, *gg_ctx, t_r0 ); + t_r0 = decode_ari( dec, mod_t0 ); + granule->region_table[0] = t_r0; + // region 1 table + shift_model( mod_t1, t_r0, s_r0 ); + t_r1 = decode_ari( dec, mod_t1 ); + granule->region_table[1] = t_r1; + // region 2 table + if ( !granule->window_switching ) { + shift_model( mod_t2, t_r0, t_r1 ); + t_r2 = decode_ari( dec, mod_t2 ); + granule->region_table[2] = t_r2; + } else granule->region_table[2] = 0; + // small values table + mod_ts->shift_context( ctx_sv ); + t_sv = decode_ari( dec, mod_ts ); + granule->select_htabB = t_sv; + ctx_sv = ( ( ctx_sv << 1 ) | t_sv ) & 0xF; + // advance context + gg_ctx++; + } + } + + // done, delete models + delete( mod_t0 ); + delete( mod_t1 ); + delete( mod_t2 ); + delete( mod_ts ); + delete( mod_s0 ); + delete( mod_s1 ); + delete( mod_bv ); + + + return true; +} + +/* ----------------------------------------------- + encode scalefactor sharing (2/4 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_encode_sharing( aricoder* enc ) +{ + // scalefactor sharing: + // - comes in packs of four + // - only every second granule matters + // - high correlation with slength + // - high correlation among fourpacks + // -> encode using markov model + slength context + + granuleInfo* granule; + model_s* model; + int ch; + int c; + + + // set up model (one model for both channels, flush in between) + model = INIT_MODEL_S( 16, 16, 3 ); + + // encoding start + for ( ch = 0; ch < g_nchannels; ch++ ) { + // reset and flush model + model->flush_model( 1 ); + c = 0; + // encode one channel + for ( granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next->next ) { + shift_model( model, c, granule->slength, granule->next->slength ); + c = granule->share; + encode_ari( enc, model, c ); + } + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + decode scalefactor sharing (2/4 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_decode_sharing( aricoder* dec ) +{ + granuleInfo* granule; + model_s* model; + int ch; + int c; + + + // set up model (one model for both channels, flush in between) + model = INIT_MODEL_S( 16, 16, 3 ); + + // decoding start + for ( ch = 0; ch < g_nchannels; ch++ ) { + // reset and flush model + model->flush_model( 1 ); + c = 0; + // decode one channel + for ( granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next->next ) { + shift_model( model, c, granule->slength, granule->next->slength ); + c = decode_ari( dec, model ); + granule->share = c; + } + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + encode the preemphasis setting (1 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_encode_preemphasis( aricoder* enc ) +{ + // preemphasis: + // - little correlation with global gain + // - near impossible to predict from each other + // - high differences between ch0 and ch1 (joint) + // -> encode using simple markov model + // -> improve later + + granuleInfo* granule; + model_b* model; + int ctx; + int ch; + int c; + + + // set up model (one model for both channels, flush in between) + model = INIT_MODEL_B( 16, 1 ); + + // encoding start + for ( ch = 0; ch < g_nchannels; ch++ ) { + // reset and flush model + model->flush_model( 1 ); + ctx = 0; + // encode one channel + for ( granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next ) { + model->shift_context( ctx ); + c = granule->preemphasis; + encode_ari( enc, model, c ); + ctx = ( ( ctx << 1 ) | c ) & 0xF; + } + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + decode the preemphasis setting (1 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_decode_preemphasis( aricoder* dec ) +{ + granuleInfo* granule; + model_b* model; + int ctx; + int ch; + int c; + + + // set up model (one model for both channels, flush in between) + model = INIT_MODEL_B( 16, 1 ); + + // decoding start + for ( ch = 0; ch < g_nchannels; ch++ ) { + // reset and flush model + model->flush_model( 1 ); + ctx = 0; + // decode one channel + for ( granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next ) { + model->shift_context( ctx ); + c = decode_ari( dec, model ); + granule->preemphasis = c; + ctx = ( ( ctx << 1 ) | c ) & 0xF; + } + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + encode the coarse sf setting (1 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_encode_coarse_sf( aricoder* enc ) +{ + // coarse scalefactors + // - little correlation with global gain + // - near impossible to predict from each other + // - differences between ch0 and ch1 (joint) + // -> encode using simple markov model + // -> improve later + + granuleInfo* granule; + model_b* model; + int ctx; + int ch; + int c; + + + // set up model (one model for both channels, flush in between) + model = INIT_MODEL_B( 16, 1 ); + + // encoding start + for ( ch = 0; ch < g_nchannels; ch++ ) { + // reset and flush model + model->flush_model( 1 ); + ctx = 0; + // encode one channel + for ( granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next ) { + model->shift_context( ctx ); + c = granule->coarse_scalefactors; + encode_ari( enc, model, c ); + ctx = ( ( ctx << 1 ) | c ) & 0xF; + } + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + decode the coarse sf setting (1 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_decode_coarse_sf( aricoder* dec ) +{ + granuleInfo* granule; + model_b* model; + int ctx; + int ch; + int c; + + + // set up model (one model for both channels, flush in between) + model = INIT_MODEL_B( 16, 1 ); + + // decoding start + for ( ch = 0; ch < g_nchannels; ch++ ) { + // reset and flush model + model->flush_model( 1 ); + ctx = 0; + // decode one channel + for ( granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next ) { + model->shift_context( ctx ); + c = decode_ari( dec, model ); + granule->coarse_scalefactors = c; + ctx = ( ( ctx << 1 ) | c ) & 0xF; + } + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + encode the subblock gain (9 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_encode_subblock_gain( aricoder* enc ) +{ + // subblock gain: + // - only occurs for short blocks + // - little correlation with each other + // - no visible correlation with anything else + // -> use simple markov model + + granuleInfo* granule; + model_s* model; + int ch, sb; + + + // set up model (one model for both channels, flush in between) + model = INIT_MODEL_S( 8, 8, 1 ); + + // decoding start + model->shift_context( 0 ); + for ( ch = 0; ch < g_nchannels; ch++ ) { + // encode one channel + for ( granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next ) { + if ( granule->window_switching ) { + for ( sb = 0; sb < 3; sb++ ) { + encode_ari( enc, model, granule->sb_gain[sb] ); + model->shift_context( granule->sb_gain[sb] ); + } + } + } + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + decode the subblock gain (9 bit) + ----------------------------------------------- */ +INTERN inline bool pmp_decode_subblock_gain( aricoder* dec ) +{ + granuleInfo* granule; + model_s* model; + int ch, sb; + + + // set up model (one model for both channels, flush in between) + model = INIT_MODEL_S( 8, 8, 1 ); + + // decoding start + model->shift_context( 0 ); + for ( ch = 0; ch < g_nchannels; ch++ ) { + // decode one channel + for ( granule = firstframe->granules[ch][0]; granule != NULL; granule = granule->next ) { + if ( granule->window_switching ) { + for ( sb = 0; sb < 3; sb++ ) { + granule->sb_gain[sb] = decode_ari( dec, model ); + model->shift_context( granule->sb_gain[sb] ); + } + } else memset( granule->sb_gain, 0, sizeof( char ) * 3 ); + } + } + + // done, delete model + delete( model ); + + + return true; +} + + +/* ----------------------------------------------- + encode the main data + ----------------------------------------------- */ +INTERN inline bool pmp_encode_main_data( aricoder* enc ) +{ + // main data: + // consists of scalefactors & coefficients + // several other data is also encoded here: + // - sv bound (for performance reasons) + // - aux data, aux data size & padding bits + // - reconstruction information (stuffing bits) + // - bitrate (for performance reasons) + // + // scalefactors: + // correlation with temporal and local neighbours + // -> encode with neighborhood context + // + // coefficients: + // good routines are already included in mp3 standard, + // but no temporal context is used there + // -> remodel mp3 coding with arithmetic coding + // -> use neighborhood context + // + // stuffing bits (between granules): + // this data either follows a pattern or is garbage + // -> use 4 bit prev bits context + // + // padding bits/aux data (at end of frame): + // usually follows a specific pattern + // -> try prediction + // -> use 8 bit prev bits context + // + // sv bound: + // should be predictable from neighborhood + // and bv bound + // -> encode diff with bv bound + // -> use prev and bv bound context + // + // bitrate: + // high correlation with main size + // -> encode using main size prediction as context + + // context / storage + static unsigned char* pad_and_aux= ( unsigned char* ) calloc( 2048, 1 ); // !!! (length) + mp3Frame* frame; + granuleInfo* granule; + unsigned char* scf_c[2]; + unsigned char* scf_l_long[2]; + unsigned char* scf_l_short[2]; + unsigned char* abs_c[2]; + unsigned char* sgn_c[2]; + unsigned char* len_c[2]; + unsigned short* lbt_c[2]; + unsigned char* absl_ctx_h[2]; + unsigned char* abss_ctx_h[2]; + unsigned char* sgnl_ctx_h[2]; + unsigned char* sgns_ctx_h[2]; + unsigned char* lenl_ctx_h[2]; + unsigned char* lens_ctx_h[2]; + unsigned char* scf_prev; + unsigned char* ctx_h_abs; + unsigned char* ctx_h_sgn; + unsigned char* ctx_h_len; + unsigned char* scf; + unsigned char* abs; + unsigned char* sgn; + unsigned char* len; + unsigned short* lbt; + unsigned char* swap; + unsigned char* pna_c; + unsigned char ctx_scf; + unsigned char ctx_abs; + unsigned char ctx_pat; + unsigned char ctx_svb[2] = { 0, 0 }; + unsigned char ctx_nst = 0; + unsigned char ctx_bst = 0; + unsigned char ctx_aux = 0; + unsigned char ctx_pad = 0; + // statistical models + model_s* mod_scf[2][4][10]; // scalefactors + model_s* mod_abv[2][8][32]; // absolutes big values <= 15 + model_b* mod_asv[2][8][2]; // absolulte small values + model_b* mod_sgn[2][8]; // signs + model_s* mod_len[2][14]; // residual bitlengths + model_b* mod_res; // residual bits + model_s* mod_svb; // small values bound + model_s* mod_bvf; // fix for sv bound (usually none) + model_s* mod_nst; // number of stuffing bits (usually zero) + model_b* mod_bst; // stuffing bits + model_b* mod_pad; // padding and ancillary bits + model_b* mod_pap; // predcition for p&a bits + model_s* mod_aux; // byte size of ancillary data + model_s* mod_btr; // frame bitrate + model_s* mod_abc; // current absolute big values (shortcut) + model_b* mod_asc; // current absolute small values (shortcut) + model_b* mod_sgc; // current signs (shortcut) + model_s* mod_lnc; // current bitlengths (shortcut) + model_s* mod_sfc; // current scalefactors (shortcut) + // lookup tables + const int* bitrate_pred = mp3_bitrate_pred[(int)i_samplerate]; + // huffman decoder + huffman_reader* huffman; + // mp3 decoding settings + short* region_bounds; + char* region_tables; + huffman_dec_table* bv_table; + huffman_conv_set* conv_set; + int linbits; + const int* slen; + int rlb, sl; + // general settings + int bitp = 0; + int bitc = 0; + int lmaxp = 0; + int sbl = 0; + int flags = 0; + bool j_coding; + bool bad_coding = false; + char shared[2][4]; + // counters + int ch, gr; + int p, g, r; + int i, c, n; + + + // --- PRE-PROCESSING PREPARATIONS: INIT STATISTICAL MODELS/HUFFMAN DECODER/CONTEXT --- + // decide if joint context will be used (will be used for joint & standard stereo) + j_coding = ( i_channels == MP3_STEREO ) || ( i_channels == MP3_JOINT_STEREO ); + // init huffman decoder/reader + huffman = new huffman_reader( main_data, main_data_size ); + // reset ancillary predictor + pmp_predict_lame_anc( -1, NULL ); + // init statistical models + mod_svb = INIT_MODEL_S( ( 576 / 4 ) + 1 + 1, ( 576 / 4 ) + 1 + 1, 1 ); + mod_bvf = INIT_MODEL_S( ( 576 / 2 ) + 1, 0, 0 ); + mod_nst = INIT_MODEL_S( STUFFING_STEP + 1, STUFFING_STEP + 1, 1 ); + mod_bst = INIT_MODEL_B( 16, 1 ); + mod_pad = INIT_MODEL_B( 256, 1 ); + mod_pap = INIT_MODEL_B( 0, 0 ); + mod_aux = INIT_MODEL_S( AUX_DATA_STEP + 1, AUX_DATA_STEP + 1, 1 ); + mod_btr = INIT_MODEL_S( 16, 16, 1 ); + mod_res = INIT_MODEL_B( 13 + 1, 2 ); + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( g = 0; g < 10; g++ ) { + mod_scf[ch][0][g] = INIT_MODEL_S( 2, 16, 2 ); + mod_scf[ch][1][g] = INIT_MODEL_S( 4, 16, 2 ); + mod_scf[ch][2][g] = INIT_MODEL_S( 8, 16, 2 ); + mod_scf[ch][3][g] = INIT_MODEL_S( 16, 16, 2 ); + } + for ( flags = 0x0; flags < ( (j_coding&&ch) ? 0x8 : 0x2 ); flags++ ) { + mod_abv[ch][flags][ 0] = NULL; + mod_abv[ch][flags][ 1] = INIT_MODEL_S( 1 + 1, 16, 2 ); + mod_abv[ch][flags][ 2] = INIT_MODEL_S( 2 + 1, 16, 2 ); + mod_abv[ch][flags][ 3] = INIT_MODEL_S( 2 + 1, 16, 2 ); + mod_abv[ch][flags][ 4] = NULL; + mod_abv[ch][flags][ 5] = INIT_MODEL_S( 3 + 1, 16, 2 ); + mod_abv[ch][flags][ 6] = INIT_MODEL_S( 3 + 1, 16, 2 ); + mod_abv[ch][flags][ 7] = INIT_MODEL_S( 5 + 1, 16, 2 ); + mod_abv[ch][flags][ 8] = INIT_MODEL_S( 5 + 1, 16, 2 ); + mod_abv[ch][flags][ 9] = INIT_MODEL_S( 5 + 1, 16, 2 ); + mod_abv[ch][flags][10] = INIT_MODEL_S( 7 + 1, 16, 2 ); + mod_abv[ch][flags][11] = INIT_MODEL_S( 7 + 1, 16, 2 ); + mod_abv[ch][flags][12] = INIT_MODEL_S( 7 + 1, 16, 2 ); + mod_abv[ch][flags][13] = INIT_MODEL_S( 15 + 1, 16, 2 ); + mod_abv[ch][flags][14] = NULL; + mod_abv[ch][flags][15] = INIT_MODEL_S( 15 + 1, 16, 2 ); + mod_abv[ch][flags][16] = INIT_MODEL_S( 15 + 1, 16, 2 ); + mod_abv[ch][flags][17] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][18] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][19] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][20] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][21] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][22] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][23] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][24] = INIT_MODEL_S( 15 + 1, 16, 2 ); + mod_abv[ch][flags][25] = mod_abv[ch][flags][24]; + mod_abv[ch][flags][26] = mod_abv[ch][flags][24]; + mod_abv[ch][flags][27] = mod_abv[ch][flags][24]; + mod_abv[ch][flags][28] = mod_abv[ch][flags][24]; + mod_abv[ch][flags][29] = mod_abv[ch][flags][24]; + mod_abv[ch][flags][30] = mod_abv[ch][flags][24]; + mod_abv[ch][flags][31] = mod_abv[ch][flags][24]; + mod_asv[ch][flags][0] = INIT_MODEL_B( 16, 2 ); + mod_asv[ch][flags][1] = INIT_MODEL_B( 16, 2 ); + mod_sgn[ch][flags] = INIT_MODEL_B( 16, 2 ); + } + mod_len[ch][0] = NULL; + for ( i = 1; i <= 13; i++ ) + mod_len[ch][i] = INIT_MODEL_S( i + 1, 13 + 1, 1 ); + } + + + // --- PRE-PROCESSING PREPARATIONS: ALLOCATION OF MEMORY --- + for ( ch = 0; ch < g_nchannels; ch++ ) { + // alloc memory + scf_c[ch] = ( unsigned char* ) calloc( 21, sizeof( char ) ); + scf_l_long[ch] = ( unsigned char* ) calloc( 21, sizeof( char ) ); + scf_l_short[ch] = ( unsigned char* ) calloc( 21, sizeof( char ) ); + abs_c[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + sgn_c[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + len_c[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + lbt_c[ch] = ( unsigned short* ) calloc( 576, sizeof( short ) ); + absl_ctx_h[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + abss_ctx_h[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + sgnl_ctx_h[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + sgns_ctx_h[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + lenl_ctx_h[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + lens_ctx_h[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + // check for problems + if ( ( scf_c[ch] == NULL ) || ( scf_l_long[ch] == NULL ) || ( scf_l_short[ch] == NULL ) || + ( abs_c[ch] == NULL ) || ( absl_ctx_h[ch] == NULL ) || ( abss_ctx_h[ch] == NULL ) || + ( sgn_c[ch] == NULL ) || ( sgnl_ctx_h[ch] == NULL ) || ( sgns_ctx_h[ch] == NULL ) || + ( len_c[ch] == NULL ) || ( lenl_ctx_h[ch] == NULL ) || ( lens_ctx_h[ch] == NULL ) || + ( lbt_c[ch] == NULL ) ) { + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return false; + } + } + + + // --- MAIN PROCESSING LOOP: ENCODING AND DECODING --- + for ( frame = firstframe; frame != NULL; frame = frame->next, bitp = 0 ) { + for ( gr = 0; gr < 2; gr++ ) { + for ( ch = 0; ch < g_nchannels; ch++ ) { + + // --- MAIN DATA DECODING: PREPARATIONS --- + // initialize shortcuts + granule = frame->granules[ch][gr]; + sbl = ( granule->block_type == SHORT_BLOCK ) ? 1 : 0; + lmaxp = granule->main_data_bit; + slen = slength_table[ (int) granule->slength ]; + region_bounds = granule->region_bound; + region_tables = granule->region_table; + abs = abs_c[ch] + 1; + sgn = sgn_c[ch] + 1; + len = len_c[ch] + 1; + lbt = lbt_c[ch]; + // set compression flags + flags = ( !j_coding || ( ch == 0 ) ) ? sbl : + ( sbl << 0 ) | // long (0) or short (1) block + ( frame->stereo_ms << 1 ) | // stereo ms on/off + ( ( flags ^ sbl ) << 2 ); // ch0/ch1 block type diffs y/n + // store sharing info + if ( gr == 0 ) { + shared[ch][0] = ( granule->share >> 3 ) & 0x1; + shared[ch][1] = ( granule->share >> 2 ) & 0x1; + shared[ch][2] = ( granule->share >> 1 ) & 0x1; + shared[ch][3] = ( granule->share >> 0 ) & 0x1; + } + // reset counter + huffman->reset_counter(); + bitc = 0; + bad_coding = false; + + + // ---> SCALEFACTOR PROCESSING <--- + if ( !sbl ) { + + // --- SCALEFACTOR READING/ENCODING: LONG BLOCKS --- + scf = scf_c[ch]; + scf_prev = scf_l_long[ch]; + ctx_scf = 0; + + // read/encode 21 scalefactors with/without sharing + for ( g = 0, p = 0; g < 4; g++ ) { + sl = slen[ ( g < 2 ) ? 0 : 1 ]; + if ( ( gr ) & ( shared[ch][g] ) ) { // shared + // loop invariant conditions (-funswitch-loops) + memcpy( scf + p, scf_prev + p, scf_width[ g ] ); + p = scf_bounds[ g ]; + ctx_scf = scf[p-1]; + } else if ( sl == 0 ) { // zero slength + memset( scf + p, 0, scf_width[ g ] ); + p = scf_bounds[ g ]; + ctx_scf = 0; + } else { + mod_sfc = mod_scf[ch][sl-1][(shared[ch][g])?g|4:g]; + for ( ; p < scf_bounds[ g ]; p++ ) { // non shared + scf[p] = huffman->read_bits( sl ); + shift_model( mod_sfc, ctx_scf, scf_prev[p] ); + encode_ari( enc, mod_sfc, scf[p] ); + ctx_scf = scf[p]; + } + } + } + + // --- SCALEFACTORS FINISHED: SWAP DATA --- + swap = scf_c[ch]; scf_c[ch] = scf_l_long[ch]; scf_l_long[ch] = swap; + + } else { + + // --- SCALEFACTOR READING/ENCODING: SHORT BLOCKS --- + // encode (only non shared) + for ( i = 0; i < 3; i++ ) { // 3 subblocks + scf = scf_c[ch]; + scf_prev = scf_l_short[ch]; + ctx_scf = 0; + for ( g = 0, p = 0; g < 2; g++ ) { // lo/hi groups + sl = slen[ g ]; + if ( sl == 0 ) { // zero slength + memset( scf + p, 0, scf_lh_width_short[ g ] ); + p = scf_lh_bounds_short[ g ]; + } else { + mod_sfc = mod_scf[ch][sl-1][g|0x8]; + for ( ; p < scf_lh_bounds_short[ g ]; p++ ) { + scf[p] = huffman->read_bits( sl ); + shift_model( mod_sfc, ctx_scf, scf_prev[p] ); + encode_ari( enc, mod_sfc, scf[p] ); + ctx_scf = scf[p]; + } + } + } + // --- SWAP DATA --- + swap = scf_c[ch]; scf_c[ch] = scf_l_short[ch]; scf_l_short[ch] = swap; + } + } + + // sanity check + if ( huffman->get_count() > lmaxp ) { // main data not big enough - no rollback for scfs + sprintf( errormessage, "huffman decoding error (in frame #%i)", frame->n ); + errorlevel = 2; + return false; + } + + + // ---> COEFFICIENTS PROCESSING <--- + + // --- COEFFICIENT DECODING: BIG VALUES --- + for ( p = 0, r = 0; ( r < 3 ) && ( !bad_coding ); r++ ) { + if ( region_tables[ r ] == 0 ) { // tbl0 skipping + p = region_bounds[ r ]; + continue; + } + // set table and linbits + bv_table = bv_dec_table + region_tables[ r ]; + if ( bv_table == NULL ) { // illegal table? + sprintf( errormessage, "bad huffman table (%i) used (in frame #%i)", + region_tables[ r ], frame->n ); + errorlevel = 2; + return false; + } + conv_set = bv_table->h; + linbits = bv_table->linbits; + + // decoding with/without linbits + for ( ; p < region_bounds[ r ]; bitc = huffman->get_count() ) { + huffman->decode_pair( conv_set, abs + p ); + for ( i = 0; i < 2; i++, p++ ) if ( abs[p] > 0 ) { + if ( linbits > 0 ) if ( abs[p] == 15 ) { + // loop invariant condition (-unswitch-loops) + lbt[p] = huffman->read_bits( linbits ); + len[p] = BITLEN8192P(lbt[p]); + } + sgn[p] = huffman->read_bit(); + } + if ( huffman->get_count() > lmaxp ) { // bad coding rollback + bad_coding = true; + abs[--p] = 0; sgn[p] = 0; len[p] = 0; + abs[--p] = 0; sgn[p] = 0; len[p] = 0; + huffman->rewind_bits( huffman->get_count() - bitc ); + break; // rollback complete + } + } + } + + // --- COEFFICIENT DECODING: SMALL VALUES --- + if ( !bad_coding ) { + conv_set = ( granule->select_htabB ) ? &htabB_dec : &htabA_dec; + for ( bitc = huffman->get_count(); p < 576; bitc = huffman->get_count() ) { + if ( bitc == lmaxp ) break; + huffman->decode_quadruple( conv_set, abs + p ); + for ( i = 0; i < 4; i++, p++ ) if ( abs[p] > 0 ) + sgn[p] = huffman->read_bit(); + if ( huffman->get_count() > lmaxp ) { // bad coding rollback + bad_coding = true; + abs[--p] = 0; sgn[p] = 0; + abs[--p] = 0; sgn[p] = 0; + abs[--p] = 0; sgn[p] = 0; + abs[--p] = 0; sgn[p] = 0; + huffman->rewind_bits( huffman->get_count() - bitc ); + break; // rollback complete + } + } + } + + + // --- SETTING AND ENCODING OF SV BOUND --- + granule->sv_bound = p; // set sv_bound + if ( !sbl ) + mod_svb->shift_context( ctx_svb[ch] ); + else mod_svb->shift_context( 144 + 1 ); + if ( p >= granule->region_bound[ 2 ] ) { // for proper files: encode actual sv bound + c = granule->sv_bound >> 2; + encode_ari( enc, mod_svb, c ); + if ( !sbl ) ctx_svb[ch] = c; + } else { // for broken files: encode negative diff with r2 bound + encode_ari( enc, mod_svb, 144 + 1 ); + c = ( granule->region_bound[ 2 ] - granule->sv_bound ) >> 1; + encode_ari( enc, mod_bvf, c ); + // fix bounds + granule->region_bound[ 2 ] = p; + for ( i = 1; i >= 0; i-- ) if ( p < granule->region_bound[i] ) + granule->region_bound[i] = p; + else break; + } + + // --- COEFFICIENT ENCODING: PREPARATIONS --- + if ( !sbl ) { + ctx_h_abs = absl_ctx_h[ch]+1; + ctx_h_sgn = sgnl_ctx_h[ch]+1; + ctx_h_len = lenl_ctx_h[ch]+1; + } else { + ctx_h_abs = abss_ctx_h[ch]+1; + ctx_h_sgn = sgns_ctx_h[ch]+1; + ctx_h_len = lens_ctx_h[ch]+1; + } + ctx_abs = 0; ctx_pat = 0; + rlb = region_bounds[2]; + mod_sgc = mod_sgn[ch][flags]; + + // --- COEFFICIENT ENCODING: SMALL VALUES --- + mod_asc = mod_asv[ch][flags][(int) granule->select_htabB]; + for ( p = granule->sv_bound-1; p >= rlb; p-- ) { + shift_model( mod_asc, ctx_pat, ctx_h_abs[p] ); + encode_ari( enc, mod_asc, abs[p] ); // absolutes + ctx_pat = ( (ctx_pat<<1) | abs[p] ) & 0xF; + ctx_abs = ( 2 * abs[p] + ctx_abs + 2 ) / 3; + if ( abs[p] == 1 ) { + shift_model( mod_sgc, ctx_h_abs[p], ctx_h_sgn[p] ); + encode_ari( enc, mod_sgc, sgn[p] ); // signs + } + } + + // --- COEFFICIENT ENCODING: BIG VALUES --- + for ( r = 2; r >= 0; r-- ) { + rlb = (r==0) ? 0 : region_bounds[ r-1 ]; + if ( p < rlb ) continue; + if ( region_tables[ r ] == 0 ) { // tbl0 skipping + memset( abs + rlb, 0, p - rlb ); + p = rlb; ctx_abs = 0; + continue; + } + // set table and linbits + bv_table = bv_dec_table + region_tables[ r ]; + linbits = bv_table->linbits; + mod_abc = mod_abv[ch][flags][(int) region_tables[ r ]]; + mod_lnc = mod_len[ch][linbits]; + + // encoding with/without linbits + for ( ; p >= rlb; p-- ) { + shift_model( mod_abc, ctx_abs, ctx_h_abs[p] ); + encode_ari( enc, mod_abc, abs[p] ); // absolutes + ctx_abs = ( 2 * abs[p] + ctx_abs + 2 ) / 3; + if ( abs[p] > 0 ) { + shift_model( mod_sgc, ctx_h_abs[p], ctx_h_sgn[p] ); + encode_ari( enc, mod_sgc, sgn[p] ); // signs + if ( linbits > 0 ) if ( abs[p] == 15 ) { + // loop invariant condition (-funswitch-loops) + mod_lnc->shift_context( ctx_h_len[p] ); + encode_ari( enc, mod_lnc, len[p] ); // bitlengths + for ( i = len[p] - 2; i >= 0; i-- ) { + shift_model( mod_res, len[p], i ); // bit residuals + encode_ari( enc, mod_res, BITN( lbt[p], i ) ); + } + } + } + } + } + + // --- COEFFICIENTS FINISHED: UPDATE CONTEXT --- + p = granule->sv_bound; + if ( p < 578 ) memset( abs + p, 0, 578 - p ); + // loop invariant condition + if ( !j_coding || ( ch == 0 ) ) { // !!! + // channel 0 context + for ( i = 578-1; i >= 0; i-- ) { + ctx_h_abs[i] = ( 3 * abs[i] + abs[i-1] + abs[i+1] + 2 * ctx_h_abs[i] + 4 ) / 7; + if ( abs[i] > 0 ) { + ctx_h_sgn[i] = ( ( ctx_h_sgn[i] << 1 ) | ( sgn[i] & 0x1 ) ) & 0xF; + if ( abs[i] == 15 ) ctx_h_len[i] = ( 2 * len[i] + ctx_h_len[i] + 2 ) / 3; + else ctx_h_len[i] >>= 1; + } else { + ctx_h_sgn[i] = ( ctx_h_sgn[i] << 1 ) & 0xF; + ctx_h_len[i] >>= 1; + } + } + // loop invariant condition + if ( j_coding ) { + // channel 1 context + if ( !sbl ) { + ctx_h_abs = absl_ctx_h[1]+1; + ctx_h_sgn = sgnl_ctx_h[1]+1; + ctx_h_len = lenl_ctx_h[1]+1; + } else { + ctx_h_abs = abss_ctx_h[1]+1; + ctx_h_sgn = sgns_ctx_h[1]+1; + ctx_h_len = lens_ctx_h[1]+1; + } + if ( p < 578 ) { + memset( ctx_h_abs + p, 0, 578 - p ); + memset( ctx_h_sgn + p, 2, 578 - p ); // !!! + memset( ctx_h_len + p, 0, 578 - p ); + } + for ( i = p-1; i >= 0; i-- ) { + ctx_h_abs[i] = abs[i]; + if ( abs[i] > 0 ) { + ctx_h_sgn[i] = sgn[i]; + if ( abs[i] == 15 ) ctx_h_len[i] = len[i]; + else ctx_h_len[i] = 0; + } else { + ctx_h_sgn[i] = 2; + ctx_h_len[i] = 0; + } + } + } + } + + + // ---> RECONSTRUCTION INFORMATION: STUFFING BITS <--- + n = lmaxp - bitc; // # of stuffing bits + if ( n == 0 ) { // the prefered case + mod_nst->shift_context( ctx_nst ); + encode_ari( enc, mod_nst, 0 ); + ctx_nst = 0; + } else { // encode # of stuff bits ( should be zero! ) + for ( ; n >= STUFFING_STEP; n -= STUFFING_STEP ) { + mod_nst->shift_context( ctx_nst ); + encode_ari( enc, mod_nst, STUFFING_STEP ); + ctx_nst = STUFFING_STEP; + } + mod_nst->shift_context( ctx_nst ); + encode_ari( enc, mod_nst, n ); + ctx_nst = n; + // encode stuffing bits + for ( ; bitc < lmaxp; bitc++ ) { + mod_bst->shift_context( ctx_bst ); + c = huffman->read_bit(); + encode_ari( enc, mod_bst, c ); + ctx_bst = ( (ctx_bst<<1) | c ) & 0xF; + } + } + + + // ---> GRANULE FINISHED! <--- + bitp += lmaxp; + /*if ( ( granule->n >= 0 ) && ( granule->n <= 0 ) ) { + fprintf( stderr, "\ngranule %i channel %i block_type: %i flags: %i\n", granule->n, ch, granule->block_type, flags ); + fprintf( stderr, "\ngranule %i channel %i nst: %i bst: %i aus: %i aux: %i pad: %i abs: %i\n", granule->n, ch, ctx_nst, ctx_bst, ctx_aux, ctx_aux, ctx_pad, ctx_abs ); + fprintf( stderr, "\ngranule %i channel %i bounds: %i/%i/%i/%i/%i\n", granule->n, ch, granule->region_bound[0], granule->region_bound[1], granule->region_bound[2], granule->sv_bound, granule->main_data_bit ); + fprintf( stderr, "\ngranule %i channel %i tables: %i/%i/%i/%i\n", granule->n, ch, granule->region_table[0], granule->region_table[1], granule->region_table[2], granule->select_htabB ); + fprintf( stderr, "\ngranule %i channel %i pos: %i\n", granule->n, ch, huffman->getpos() ); + fprintf( stderr, "\ngranule %i channel %i bad_coding: %s\n", granule->n, ch, bad_coding ? "yes" : "no" ); + fprintf( stderr, "\ngranule %i channel %i scfs: (%i/%i)\n", granule->n, ch, granule->share, granule->slength ); + for ( i = 0; i < 21; i++ ) fprintf( stderr, "%i, ", scf[i] ); + fprintf( stderr, "\n" ); + fprintf( stderr, "\ngranule %i channel %i coefs:\n", granule->n, ch ); + for ( i = 0; i < 578; i++ ) fprintf( stderr, "%i, ", abs[i] ); + fprintf( stderr, "\n" ); + for ( i = 0; i < 576; i++ ) if ( abs[i] == 15 ) fprintf( stderr, "%i, ", lbt[i] ); + fprintf( stderr, "\n" ); + for ( i = 0; i < 578; i++ ) if ( abs[i] > 0 ) fprintf( stderr, "%s", (sgn[i]) ? "+" : "-" ); + fprintf( stderr, "\n" ); + // fprintf( stderr, "\ngranule %i channel %i abs_ctx:\n", granule->n, ch ); + // for ( i = 0; i < 578; i++ ) fprintf( stderr, "%i, ", ctx_h_abs[i] ); + // fprintf( stderr, "\n" ); + // fprintf( stderr, "\ngranule %i channel %i sgn_ctx:\n", granule->n, ch ); + // for ( i = 0; i < 578; i++ ) fprintf( stderr, "%i, ", ctx_h_sgn[i] ); + // fprintf( stderr, "\n" ); + // fprintf( stderr, "\ngranule %i channel %i len_ctx:\n", granule->n, ch ); + // for ( i = 0; i < 578; i++ ) fprintf( stderr, "%i, ", ctx_h_len[i] ); + // fprintf( stderr, "\n" ); + }*/ + } + } + + + // ---> ENCODE BITRATE <--- + if ( i_bitrate == -1 ) { + mod_btr->shift_context( bitrate_pred[ frame->main_size ] ); // !!! (bit-reservoir?) + encode_ari( enc, mod_btr, frame->bits ); + } + + + // ---> RECONSTRUCTION INFORMATION: AUX DATA AND PADDING <--- + if ( ( frame != lastframe ) && ( i_bit_res != 0 ) ) { + if ( frame->aux_size + frame->next->bit_reservoir < 511 ) + n = frame->aux_size; // byte size of aux data + else n = 511 - frame->next->bit_reservoir; // space taken from bit reservoir + for ( ; n >= AUX_DATA_STEP; n -= AUX_DATA_STEP ) { + mod_aux->shift_context( ctx_aux ); + encode_ari( enc, mod_aux, AUX_DATA_STEP ); + ctx_aux = AUX_DATA_STEP; + } + mod_aux->shift_context( ctx_aux ); + encode_ari( enc, mod_aux, n ); + ctx_aux = n; + } + // # of padding and aux data bits + n = ( ( frame->main_size + frame->aux_size ) * 8 ) - bitp; + // locally store padding and aux data + for ( pna_c = pad_and_aux, i = n; i >= 8; i -= 8 ) + *(pna_c++) = huffman->read_bits( 8 ); + *pna_c = huffman->read_bits( i ); + // make and check prediction + if ( pmp_predict_lame_anc( n, pad_and_aux ) == NULL ) + // prediction matches + encode_ari( enc, mod_pap, 1 ); + else { // prediction doesn't match + encode_ari( enc, mod_pap, 0 ); + huffman->rewind_bits( n ); + for ( ctx_pad = 0xFF; n > 0; n-- ) { + mod_pad->shift_context( ctx_pad ); + c = huffman->read_bit(); + encode_ari( enc, mod_pad, c ); + ctx_pad = ( (ctx_pad<<1) | c ) & 0xFF; + } + } + // encode padding bits(convert to full bytes) + /*for ( c = 0xFF; n >= 8; n -= 8 ) { + mod_pad->shift_context( c ); + c = huffman->read_bits( 8 ); + encode_ari( enc, mod_pad, c ); + } + if ( n > 0 ) { + mod_pad->shift_context( 0xFF + n ); + c = huffman->read_bits( n ); + encode_ari( enc, mod_pad, c ); + }*/ + + // ---> FRAME FINISHED! <---- + } + + + // ---> AFTER ENCODING: CLEAN UP <--- + + // --- CLEAN UP: MODELS AND HUFFMAN CODER --- + delete( huffman ); + delete( mod_svb ); + delete( mod_bvf ); + delete( mod_nst ); + delete( mod_bst ); + delete( mod_pad ); + delete( mod_pap ); + delete( mod_aux ); + delete( mod_btr ); + delete( mod_res ); + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( sl = 0; sl < 4; sl++ ) + for ( g = 0; g < 6; g++ ) + delete( mod_scf[ch][sl][g] ); + for ( flags = 0x0; flags < ( (j_coding&&ch) ? 0x8 : 0x2 ); flags++ ) { + delete( mod_abv[ch][flags][ 1] ); + delete( mod_abv[ch][flags][ 2] ); + delete( mod_abv[ch][flags][ 3] ); + delete( mod_abv[ch][flags][ 5] ); + delete( mod_abv[ch][flags][ 6] ); + delete( mod_abv[ch][flags][ 7] ); + delete( mod_abv[ch][flags][ 8] ); + delete( mod_abv[ch][flags][ 9] ); + delete( mod_abv[ch][flags][10] ); + delete( mod_abv[ch][flags][11] ); + delete( mod_abv[ch][flags][12] ); + delete( mod_abv[ch][flags][13] ); + delete( mod_abv[ch][flags][15] ); + delete( mod_abv[ch][flags][16] ); + delete( mod_abv[ch][flags][24] ); + delete( mod_asv[ch][flags][0] ); + delete( mod_asv[ch][flags][1] ); + delete( mod_sgn[ch][flags] ); + } + for ( i = 0; i <= 13; i++ ) + delete( mod_len[ch][i] ); + } + + // --- CLEAN UP: MEMORY DEALLOCATION --- + for ( ch = 0; ch < g_nchannels; ch++ ) { + free( scf_c[ch] ); free( scf_l_long[ch] ); free( scf_l_short[ch] ); + free( abs_c[ch] ); free( absl_ctx_h[ch] ); free( abss_ctx_h[ch] ); + free( sgn_c[ch] ); free( sgnl_ctx_h[ch] ); free( sgns_ctx_h[ch] ); + free( len_c[ch] ); free( lenl_ctx_h[ch] ); free( lens_ctx_h[ch] ); + free( lbt_c[ch] ); + } + + + return true; +} + + +/* ----------------------------------------------- + decode the main data + ----------------------------------------------- */ +INTERN inline bool pmp_decode_main_data( aricoder* dec ) +{ + // context / storage + static unsigned char* pad_and_aux= ( unsigned char* ) calloc( 2048, 1 ); + mp3Frame* frame; + granuleInfo* granule; + unsigned char* scf_c[2]; + unsigned char* scf_l_long[2]; + unsigned char* scf_l_short[2]; + unsigned char* abs_c[2]; + unsigned char* sgn_c[2]; + unsigned char* len_c[2]; + unsigned short* lbt_c[2]; + unsigned char* absl_ctx_h[2]; + unsigned char* abss_ctx_h[2]; + unsigned char* sgnl_ctx_h[2]; + unsigned char* sgns_ctx_h[2]; + unsigned char* lenl_ctx_h[2]; + unsigned char* lens_ctx_h[2]; + unsigned char* scf_prev; + unsigned char* ctx_h_abs; + unsigned char* ctx_h_sgn; + unsigned char* ctx_h_len; + unsigned char* scf; + unsigned char* abs; + unsigned char* sgn; + unsigned char* len; + unsigned short* lbt; + unsigned char* swap; + unsigned char* pna_c; + unsigned char ctx_scf; + unsigned char ctx_abs; + unsigned char ctx_pat; + unsigned char ctx_svb[2] = { 0, 0 }; + unsigned char ctx_nst = 0; + unsigned char ctx_bst = 0; + unsigned char ctx_aux = 0; + unsigned char ctx_pad = 0; + // statistical models + model_s* mod_scf[2][4][10]; + model_s* mod_abv[2][8][32]; + model_b* mod_asv[2][8][2]; + model_b* mod_sgn[2][8]; + model_s* mod_len[2][14]; + model_b* mod_res; + model_s* mod_svb; + model_s* mod_bvf; + model_s* mod_nst; + model_b* mod_bst; + model_b* mod_pad; + model_b* mod_pap; + model_s* mod_aux; + model_s* mod_btr; + model_s* mod_abc; + model_b* mod_asc; + model_b* mod_sgc; + model_s* mod_lnc; + model_s* mod_sfc; + // lookup tables + const int* bitrate_pred = mp3_bitrate_pred[(int)i_samplerate]; + const int* frame_size = mp3_frame_size_table[(int)i_samplerate]; + // huffman encoder + huffman_writer* huffman; + // mp3 encoding settings + short* region_bounds; + char* region_tables; + huffman_enc_table* bv_table; + huffman_code** hcodes; + huffman_code* hcode; + int bitres = 0; + int linbits; + const int* slen; + int rlb, sl; + // general settings + int bitp = 0; + int sbl = 0; + int flags = 0; + bool j_coding; + char shared[2][4]; + // counters + int ch, gr; + int p, g, r; + int i, c, n; + + + + // --- PRE-PROCESSING PREPARATIONS: INIT STATISTICAL MODELS/HUFFMAN DECODER/CONTEXT --- + // decide if joint context will be used (will be used for joint & standard stereo) + j_coding = ( i_channels == MP3_STEREO ) || ( i_channels == MP3_JOINT_STEREO ); + // init huffman encoder/writer + huffman = new huffman_writer( 0 ); + // reset ancillary predictor + pmp_predict_lame_anc( -1, NULL ); + // init statistical models + mod_svb = INIT_MODEL_S( ( 576 / 4 ) + 1 + 1, ( 576 / 4 ) + 1 + 1, 1 ); + mod_bvf = INIT_MODEL_S( ( 576 / 2 ) + 1, 0, 0 ); + mod_nst = INIT_MODEL_S( STUFFING_STEP + 1, STUFFING_STEP + 1, 1 ); + mod_bst = INIT_MODEL_B( 16, 1 ); + mod_pad = INIT_MODEL_B( 256, 1 ); + mod_pap = INIT_MODEL_B( 0, 0 ); + mod_aux = INIT_MODEL_S( AUX_DATA_STEP + 1, AUX_DATA_STEP + 1, 1 ); + mod_btr = INIT_MODEL_S( 16, 16, 1 ); + mod_res = INIT_MODEL_B( 13 + 1, 2 ); + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( g = 0; g < 10; g++ ) { + mod_scf[ch][0][g] = INIT_MODEL_S( 2, 16, 2 ); + mod_scf[ch][1][g] = INIT_MODEL_S( 4, 16, 2 ); + mod_scf[ch][2][g] = INIT_MODEL_S( 8, 16, 2 ); + mod_scf[ch][3][g] = INIT_MODEL_S( 16, 16, 2 ); + } + for ( flags = 0x0; flags < ( (j_coding&&ch) ? 0x8 : 0x2 ); flags++ ) { + mod_abv[ch][flags][ 0] = NULL; + mod_abv[ch][flags][ 1] = INIT_MODEL_S( 1 + 1, 16, 2 ); + mod_abv[ch][flags][ 2] = INIT_MODEL_S( 2 + 1, 16, 2 ); + mod_abv[ch][flags][ 3] = INIT_MODEL_S( 2 + 1, 16, 2 ); + mod_abv[ch][flags][ 4] = NULL; + mod_abv[ch][flags][ 5] = INIT_MODEL_S( 3 + 1, 16, 2 ); + mod_abv[ch][flags][ 6] = INIT_MODEL_S( 3 + 1, 16, 2 ); + mod_abv[ch][flags][ 7] = INIT_MODEL_S( 5 + 1, 16, 2 ); + mod_abv[ch][flags][ 8] = INIT_MODEL_S( 5 + 1, 16, 2 ); + mod_abv[ch][flags][ 9] = INIT_MODEL_S( 5 + 1, 16, 2 ); + mod_abv[ch][flags][10] = INIT_MODEL_S( 7 + 1, 16, 2 ); + mod_abv[ch][flags][11] = INIT_MODEL_S( 7 + 1, 16, 2 ); + mod_abv[ch][flags][12] = INIT_MODEL_S( 7 + 1, 16, 2 ); + mod_abv[ch][flags][13] = INIT_MODEL_S( 15 + 1, 16, 2 ); + mod_abv[ch][flags][14] = NULL; + mod_abv[ch][flags][15] = INIT_MODEL_S( 15 + 1, 16, 2 ); + mod_abv[ch][flags][16] = INIT_MODEL_S( 15 + 1, 16, 2 ); + mod_abv[ch][flags][17] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][18] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][19] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][20] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][21] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][22] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][23] = mod_abv[ch][flags][16]; + mod_abv[ch][flags][24] = INIT_MODEL_S( 15 + 1, 16, 2 ); + mod_abv[ch][flags][25] = mod_abv[ch][flags][24]; + mod_abv[ch][flags][26] = mod_abv[ch][flags][24]; + mod_abv[ch][flags][27] = mod_abv[ch][flags][24]; + mod_abv[ch][flags][28] = mod_abv[ch][flags][24]; + mod_abv[ch][flags][29] = mod_abv[ch][flags][24]; + mod_abv[ch][flags][30] = mod_abv[ch][flags][24]; + mod_abv[ch][flags][31] = mod_abv[ch][flags][24]; + mod_asv[ch][flags][0] = INIT_MODEL_B( 16, 2 ); + mod_asv[ch][flags][1] = INIT_MODEL_B( 16, 2 ); + mod_sgn[ch][flags] = INIT_MODEL_B( 16, 2 ); + } + mod_len[ch][0] = NULL; + for ( i = 1; i <= 13; i++ ) + mod_len[ch][i] = INIT_MODEL_S( i + 1, 13 + 1, 1 ); + } + + + // --- PRE-PROCESSING PREPARATIONS: ALLOCATION OF MEMORY --- + for ( ch = 0; ch < g_nchannels; ch++ ) { + // alloc memory + scf_c[ch] = ( unsigned char* ) calloc( 21, sizeof( char ) ); + scf_l_long[ch] = ( unsigned char* ) calloc( 21, sizeof( char ) ); + scf_l_short[ch] = ( unsigned char* ) calloc( 21, sizeof( char ) ); + abs_c[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + sgn_c[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + len_c[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + lbt_c[ch] = ( unsigned short* ) calloc( 576, sizeof( short ) ); + absl_ctx_h[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + abss_ctx_h[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + sgnl_ctx_h[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + sgns_ctx_h[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + lenl_ctx_h[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + lens_ctx_h[ch] = ( unsigned char* ) calloc( 578+1+1, sizeof( char ) ); + // check for problems + if ( ( scf_c[ch] == NULL ) || ( scf_l_long[ch] == NULL ) || ( scf_l_short[ch] == NULL ) || + ( abs_c[ch] == NULL ) || ( absl_ctx_h[ch] == NULL ) || ( abss_ctx_h[ch] == NULL ) || + ( sgn_c[ch] == NULL ) || ( sgnl_ctx_h[ch] == NULL ) || ( sgns_ctx_h[ch] == NULL ) || + ( len_c[ch] == NULL ) || ( lenl_ctx_h[ch] == NULL ) || ( lens_ctx_h[ch] == NULL ) || + ( lbt_c[ch] == NULL ) ) { + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return false; + } + } + + + // --- MAIN PROCESSING LOOP: DECODING AND ENCODING --- + for ( frame = firstframe; frame != NULL; frame = frame->next, bitp = 0 ) { + // record main index + frame->main_index = huffman->getpos(); + for ( gr = 0; gr < 2; gr++ ) { + for ( ch = 0; ch < g_nchannels; ch++ ) { + + // --- MAIN DATA DECODING: PREPARATIONS --- + // initialize shortcuts + granule = frame->granules[ch][gr]; + sbl = ( granule->block_type == SHORT_BLOCK ) ? 1 : 0; + slen = slength_table[ (int) granule->slength ]; + region_bounds = granule->region_bound; + region_tables = granule->region_table; + abs = abs_c[ch] + 1; + sgn = sgn_c[ch] + 1; + len = len_c[ch] + 1; + lbt = lbt_c[ch]; + // set compression flags + flags = ( !j_coding || ( ch == 0 ) ) ? sbl : + ( sbl << 0 ) | // long (0) or short (1) block + ( frame->stereo_ms << 1 ) | // stereo ms on/off + ( ( flags ^ sbl ) << 2 ); // ch0/ch1 block type diffs y/n + // store sharing info + if ( gr == 0 ) { + shared[ch][0] = ( granule->share >> 3 ) & 0x1; + shared[ch][1] = ( granule->share >> 2 ) & 0x1; + shared[ch][2] = ( granule->share >> 1 ) & 0x1; + shared[ch][3] = ( granule->share >> 0 ) & 0x1; + } + // reset counter + huffman->reset_counter(); + // store bit reservoir state + frame->bit_reservoir = bitres; + + + // ---> SCALEFACTOR PROCESSING <--- + if ( !sbl ) { + + // --- SCALEFACTOR DECODING/WRITING: LONG BLOCKS --- + scf = scf_c[ch]; + scf_prev = scf_l_long[ch]; + ctx_scf = 0; + + // decode/write 21 scalefactors with/without sharing + for ( g = 0, p = 0; g < 4; g++ ) { + sl = slen[ ( g < 2 ) ? 0 : 1 ]; + if ( ( gr ) & ( shared[ch][g] ) ) { // shared + // loop invariant condition (-funswitch-loops) + memcpy( scf + p, scf_prev + p, scf_width[ g ] ); + p = scf_bounds[ g ]; + ctx_scf = scf[p-1]; + } else if ( sl == 0 ) { // zero slength + memset( scf + p, 0, scf_width[ g ] ); + p = scf_bounds[ g ]; + ctx_scf = 0; + } else { + mod_sfc = mod_scf[ch][sl-1][(shared[ch][g])?g|0x4:g]; + for ( ; p < scf_bounds[ g ]; p++ ) { // non shared + shift_model( mod_sfc, ctx_scf, scf_prev[p] ); + scf[p] = decode_ari( dec, mod_sfc ); + huffman->write_bits( scf[p], sl ); + ctx_scf = scf[p]; + } + } + } + + // --- SCALEFACTORS FINISHED: SWAP DATA --- + swap = scf_c[ch]; scf_c[ch] = scf_l_long[ch]; scf_l_long[ch] = swap; + + } else { + + // --- SCALEFACTOR DECODING/WRITING: SHORT BLOCKS --- + // encode (only non shared) + for ( i = 0; i < 3; i++ ) { // 3 subblocks + scf = scf_c[ch]; + scf_prev = scf_l_short[ch]; + ctx_scf = 0; + for ( g = 0, p = 0; g < 2; g++ ) { // lo&hi groups + sl = slen[ g ]; + if ( sl == 0 ) { // zero slength + memset( scf + p, 0, scf_lh_width_short[ g ] ); + p = scf_lh_bounds_short[ g ]; + } else { + mod_sfc = mod_scf[ch][sl-1][g|0x8]; + for ( ; p < scf_lh_bounds_short[ g ]; p++ ) { // scfs + shift_model( mod_sfc, ctx_scf, scf_prev[p] ); + scf[p] = decode_ari( dec, mod_sfc ); + huffman->write_bits( scf[p], sl ); + ctx_scf = scf[p]; + } + } + } + // --- SWAP DATA --- + swap = scf_c[ch]; scf_c[ch] = scf_l_short[ch]; scf_l_short[ch] = swap; + } + } + + + // ---> COEFFICIENTS PROCESSING <--- + + // --- DECODING AND FIXING OF SV BOUND --- + if ( !sbl ) { + mod_svb->shift_context( ctx_svb[ch] ); + } else mod_svb->shift_context( 144 + 1 ); + c = decode_ari( dec, mod_svb ); + if ( c <= 144 ) { // for proper files + granule->sv_bound = c << 2; + if ( granule->region_bound[ 2 ] % 4 == 2 ) + granule->sv_bound += 2; + if ( !sbl ) ctx_svb[ch] = c; + } else { // for broken files + c = decode_ari( dec, mod_bvf ); + granule->sv_bound = granule->region_bound[ 2 ] - ( c << 1 ); + // fix bounds + granule->region_bound[ 2 ] = granule->sv_bound; + for ( i = 1; i >= 0; i-- ) if ( granule->sv_bound < granule->region_bound[i] ) + granule->region_bound[i] = granule->sv_bound; + else break; + } + + + // --- COEFFICIENT DECODING: PREPARATIONS --- + if ( granule->block_type != SHORT_BLOCK ) { + ctx_h_abs = absl_ctx_h[ch]+1; + ctx_h_sgn = sgnl_ctx_h[ch]+1; + ctx_h_len = lenl_ctx_h[ch]+1; + } else { + ctx_h_abs = abss_ctx_h[ch]+1; + ctx_h_sgn = sgns_ctx_h[ch]+1; + ctx_h_len = lens_ctx_h[ch]+1; + } + ctx_abs = 0; ctx_pat = 0; + rlb = region_bounds[2]; + mod_sgc = mod_sgn[ch][flags]; + + // --- COEFFICIENT DECODING: SMALL VALUES --- + mod_asc = mod_asv[ch][flags][(int) granule->select_htabB]; + for ( p = granule->sv_bound-1; p >= rlb; p-- ) { + shift_model( mod_asc, ctx_pat, ctx_h_abs[p] ); + abs[p] = decode_ari( dec, mod_asc ); // absolutes + ctx_pat = ( (ctx_pat<<1) | abs[p] ) & 0xF; + ctx_abs = ( 2 * abs[p] + ctx_abs + 2 ) / 3; + if ( abs[p] == 1 ) { + shift_model( mod_sgc, ctx_h_abs[p], ctx_h_sgn[p] ); + sgn[p] = decode_ari( dec, mod_sgc ); // signs + } + } + + // --- COEFFICIENT DECODING: BIG VALUES --- + for ( r = 2; r >= 0; r-- ) { + rlb = (r==0) ? 0 : region_bounds[ r-1 ]; + if ( p < rlb ) continue; + if ( region_tables[ r ] == 0 ) { // tbl0 skipping + memset( abs + rlb, 0, p - rlb ); + p = rlb; ctx_abs = 0; + continue; + } + // set table and linbits + bv_table = bv_enc_table + region_tables[ r ]; + linbits = bv_table->linbits; + mod_abc = mod_abv[ch][flags][(int) region_tables[ r ]]; + mod_lnc = mod_len[ch][linbits]; + + // decoding with/without linbits + for ( ; p >= rlb; p-- ) { + shift_model( mod_abc, ctx_abs, ctx_h_abs[p] ); + abs[p] = decode_ari( dec, mod_abc ); // absolutes + ctx_abs = ( 2 * abs[p] + ctx_abs + 2 ) / 3; + if ( abs[p] > 0 ) { + shift_model( mod_sgc, ctx_h_abs[p], ctx_h_sgn[p] ); + sgn[p] = decode_ari( dec, mod_sgc ); // signs + if ( linbits > 0 ) if ( abs[p] == 15 ) { + // loop invariant condition (-funswitch-loops) + mod_lnc->shift_context( ctx_h_len[p] ); + len[p] = decode_ari( dec, mod_lnc ); // bitlengths + if ( len[p] > 0 ) { + for ( lbt[p] = 1, i = len[p] - 2; i >= 0; i-- ) { + shift_model( mod_res, len[p], i ); // bit residuals + lbt[p] = ( lbt[p] << 1 ) | decode_ari( dec, mod_res ); + } + } else lbt[p] = 0; + } + } + } + } + + + // --- COEFFICIENT ENCODING: BIG VALUES --- + for ( p = 0, r = 0; r < 3; r++ ) { + if ( region_tables[ r ] == 0 ) { // tbl0 skipping + p = region_bounds[ r ]; + continue; + } + // set table and linbits + bv_table = bv_enc_table + region_tables[ r ]; + hcodes = bv_table->h; + linbits = bv_table->linbits; + + // encoding with/without linbits + while ( p < region_bounds[ r ] ) { + huffman->encode_pair( hcodes, abs + p ); + for ( i = 0; i < 2; i++, p++ ) if ( abs[p] > 0 ) { + if ( linbits > 0 ) // loop invariant condition (-unswitch-loops) + if ( abs[p] == 15 ) huffman->write_bits( lbt[p], linbits ); + huffman->write_bit( sgn[p] ); + } + } + } + + // --- COEFFICIENT ENCODING: SMALL VALUES --- + hcode = ( granule->select_htabB ) ? htabB_enc : htabA_enc; + while ( p < granule->sv_bound ) { + huffman->encode_quadruple( hcode, abs + p ); + for ( i = 0; i < 4; i++, p++ ) if ( abs[p] ) + huffman->write_bit( sgn[p] ); + } + + // --- COEFFICIENTS FINISHED: UPDATE CONTEXT --- + if ( p < 578 ) memset( abs + p, 0, 578 - p ); + // loop invariant condition + if ( !j_coding || ( ch == 0 ) ) { + // channel 0 context + for ( i = 578-1; i >= 0; i-- ) { + ctx_h_abs[i] = ( 3 * abs[i] + abs[i-1] + abs[i+1] + 2 * ctx_h_abs[i] + 4 ) / 7; + if ( abs[i] > 0 ) { + ctx_h_sgn[i] = ( ( ctx_h_sgn[i] << 1 ) | ( sgn[i] & 0x1 ) ) & 0xF; + if ( abs[i] == 15 ) ctx_h_len[i] = ( 2 * len[i] + ctx_h_len[i] + 2 ) / 3; + else ctx_h_len[i] >>= 1; + } else { + ctx_h_sgn[i] = ( ctx_h_sgn[i] << 1 ) & 0xF; + ctx_h_len[i] >>= 1; + } + } + // loop invariant condition + if ( j_coding ) { + // channel 1 context + if ( !sbl ) { + ctx_h_abs = absl_ctx_h[1]+1; + ctx_h_sgn = sgnl_ctx_h[1]+1; + ctx_h_len = lenl_ctx_h[1]+1; + } else { + ctx_h_abs = abss_ctx_h[1]+1; + ctx_h_sgn = sgns_ctx_h[1]+1; + ctx_h_len = lens_ctx_h[1]+1; + } + if ( p < 578 ) { + memset( ctx_h_abs + p, 0, 578 - p ); + memset( ctx_h_sgn + p, 2, 578 - p ); + memset( ctx_h_len + p, 0, 578 - p ); + } + for ( i = p-1; i >= 0; i-- ) { + ctx_h_abs[i] = abs[i]; + if ( abs[i] > 0 ) { + ctx_h_sgn[i] = sgn[i]; + if ( abs[i] == 15 ) ctx_h_len[i] = len[i]; + else ctx_h_len[i] = 0; + } else { + ctx_h_sgn[i] = 2; + ctx_h_len[i] = 0; + } + } + } + } + + + // ---> RECONSTRUCTION INFORMATION: STUFFING BITS <--- + for ( n = 0, c = STUFFING_STEP; c == STUFFING_STEP; n += c ) { + // find out # of stuffing bits + mod_nst->shift_context( ctx_nst ); + c = decode_ari( dec, mod_nst ); + ctx_nst = c; + } + for ( ; n > 0; n-- ) { + mod_bst->shift_context( ctx_bst ); + c = decode_ari( dec, mod_bst ); + huffman->write_bit( c ); + ctx_bst = ( (ctx_bst<<1) | c ) & 0xF; + } + + + // ---> GRANULE FINISHED! <--- + granule->main_data_bit = huffman->get_count(); + bitp += granule->main_data_bit; + /*if ( ( granule->n >= 0 ) && ( granule->n <= 0 ) ) { + fprintf( stderr, "\ngranule %i channel %i block_type: %i flags: %i\n", granule->n, ch, granule->block_type, flags ); + fprintf( stderr, "\ngranule %i channel %i nst: %i bst: %i aus: %i aux: %i pad: %i abs: %i\n", granule->n, ch, ctx_nst, ctx_bst, ctx_aux, ctx_aux, ctx_pad, ctx_abs ); + fprintf( stderr, "\ngranule %i channel %i bounds: %i/%i/%i/%i/%i\n", granule->n, ch, granule->region_bound[0], granule->region_bound[1], granule->region_bound[2], granule->sv_bound, granule->main_data_bit ); + fprintf( stderr, "\ngranule %i channel %i tables: %i/%i/%i/%i\n", granule->n, ch, granule->region_table[0], granule->region_table[1], granule->region_table[2], granule->select_htabB ); + fprintf( stderr, "\ngranule %i channel %i pos: %i\n", granule->n, ch, huffman->getpos() ); + fprintf( stderr, "\ngranule %i channel %i scfs: (%i/%i)\n", granule->n, ch, granule->share, granule->slength ); + for ( i = 0; i < 21; i++ ) fprintf( stderr, "%i, ", scf[i] ); + fprintf( stderr, "\n" ); + fprintf( stderr, "\ngranule %i channel %i coefs:\n", granule->n, ch ); + for ( i = 0; i < 578; i++ ) fprintf( stderr, "%i, ", abs[i] ); + fprintf( stderr, "\n" ); + for ( i = 0; i < 576; i++ ) if ( abs[i] == 15 ) fprintf( stderr, "%i, ", lbt[i] ); + fprintf( stderr, "\n" ); + for ( i = 0; i < 578; i++ ) if ( abs[i] > 0 ) fprintf( stderr, "%s", (sgn[i]) ? "+" : "-" ); + fprintf( stderr, "\n" ); + // fprintf( stderr, "\ngranule %i channel %i abs_ctx:\n", granule->n, ch ); + // for ( i = 0; i < 578; i++ ) fprintf( stderr, "%i, ", ctx_h_abs[i] ); + // fprintf( stderr, "\n" ); + // fprintf( stderr, "\ngranule %i channel %i sgn_ctx:\n", granule->n, ch ); + // for ( i = 0; i < 578; i++ ) fprintf( stderr, "%i, ", ctx_h_sgn[i] ); + // fprintf( stderr, "\n" ); + // fprintf( stderr, "\ngranule %i channel %i len_ctx:\n", granule->n, ch ); + // for ( i = 0; i < 578; i++ ) fprintf( stderr, "%i, ", ctx_h_len[i] ); + // fprintf( stderr, "\n" ); + }*/ + } + } + // --- STORE FRAME MAIN DATA SIZES --- + frame->main_bits = bitp; + frame->main_size = ( bitp + 7 ) / 8; + + + // ---> DECODE BITRATE <--- + if ( i_bitrate == -1 ) { + mod_btr->shift_context( bitrate_pred[ frame->main_size ] ); + frame->bits = decode_ari( dec, mod_btr ); + } + // calculate size of frame - use the lookup table + frame->frame_size = frame_size[(int)frame->bits]; + if ( frame->padding ) frame->frame_size++; + + + // ---> RECONSTRUCTION INFORMATION: AUX DATA AND PADDING <--- + if ( i_bit_res != 0 ) { + // preliminary next frame bit reservoir size + bitres = + frame->frame_size - + frame->fixed_size + + frame->bit_reservoir - + frame->main_size; + if ( frame != lastframe ) { + n = ( bitres < 511 ) ? 0 : bitres - 511; + for ( c = AUX_DATA_STEP; c == AUX_DATA_STEP; n += c ) { + // byte size of aux data + mod_aux->shift_context( ctx_aux ); + c = decode_ari( dec, mod_aux ); + ctx_aux = c; + } + frame->aux_size = n; + } else frame->aux_size = bitres; + // finalize size of bit reservoir + bitres -= frame->aux_size; + } else { + bitres = 0; + frame->aux_size = + frame->frame_size - + frame->fixed_size + + frame->bit_reservoir - + frame->main_size; + } + // # of padding and aux data bits + n = ( ( frame->main_size + frame->aux_size ) * 8 ) - bitp; + // check if data can be predicted 100% + if ( decode_ari( dec, mod_pap ) == 1 ) { + // prediction matches ! + pna_c = pmp_predict_lame_anc( n, NULL ); + for ( ; n >= 8; n -= 8 ) huffman->write_bits( *(pna_c++), 8 ); + if ( n > 0 ) huffman->write_bits( *(pna_c) >> (8-n), n ); + } else { + // prediction doesn't match (d'oh!) + pna_c = pad_and_aux; *pna_c = 0; + for ( ctx_pad = 0xFF, i = 1; i <= n; i++ ) { + mod_pad->shift_context( ctx_pad ); + c = decode_ari( dec, mod_pad ); + huffman->write_bit( c ); + ctx_pad = ( (ctx_pad<<1) | c ) & 0xFF; + *pna_c = (*pna_c<<1)|c; + if ( i % 8 == 0 ) *(++pna_c) = 0; + } + if ( pmp_predict_lame_anc( n, pad_and_aux ) == NULL ) { + sprintf( errormessage, "ancilary prediction error, please report" ); + errorlevel = 2; + return false; + } + } + // decode padding bits + /*for ( c = 0xFF; n >= 8; n -= 8 ) { + mod_pad->shift_context( c ); + c = decode_ari( dec, mod_pad ); + huffman->write_bits( c, 8 ); + } + if ( n > 0 ) { + mod_pad->shift_context( 0xFF + n ); + c = decode_ari( dec, mod_pad ); + huffman->write_bits( c, n ); + }*/ + + // ---> FRAME FINISHED! <---- + } + + + // ---> AFTER ENCODING: GRAB POINTER AND CLEAN UP <--- + + // --- GRAB POINTER AND SIZE --- + main_data = huffman->getptr(); + main_data_size = huffman->getpos(); + + // --- CALCULATE MP3 FILE SIZE --- + mp3filesize = + data_before_size + + data_after_size + + main_data_size + + ( g_nframes * lastframe->fixed_size ); + + // --- CLEAN UP: MODELS AND HUFFMAN CODER --- + delete( huffman ); + delete( mod_svb ); + delete( mod_bvf ); + delete( mod_nst ); + delete( mod_bst ); + delete( mod_pad ); + delete( mod_pap ); + delete( mod_aux ); + delete( mod_btr ); + delete( mod_res ); + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( sl = 0; sl < 4; sl++ ) + for ( g = 0; g < 6; g++ ) + delete( mod_scf[ch][sl][g] ); + for ( flags = 0x0; flags < ( (j_coding&&ch) ? 0x8 : 0x2 ); flags++ ) { + delete( mod_abv[ch][flags][ 1] ); + delete( mod_abv[ch][flags][ 2] ); + delete( mod_abv[ch][flags][ 3] ); + delete( mod_abv[ch][flags][ 5] ); + delete( mod_abv[ch][flags][ 6] ); + delete( mod_abv[ch][flags][ 7] ); + delete( mod_abv[ch][flags][ 8] ); + delete( mod_abv[ch][flags][ 9] ); + delete( mod_abv[ch][flags][10] ); + delete( mod_abv[ch][flags][11] ); + delete( mod_abv[ch][flags][12] ); + delete( mod_abv[ch][flags][13] ); + delete( mod_abv[ch][flags][15] ); + delete( mod_abv[ch][flags][16] ); + delete( mod_abv[ch][flags][24] ); + delete( mod_asv[ch][flags][0] ); + delete( mod_asv[ch][flags][1] ); + delete( mod_sgn[ch][flags] ); + } + for ( i = 0; i <= 13; i++ ) + delete( mod_len[ch][i] ); + } + + // --- CLEAN UP: MEMORY DEALLOCATION --- + for ( ch = 0; ch < g_nchannels; ch++ ) { + free( scf_c[ch] ); free( scf_l_long[ch] ); free( scf_l_short[ch] ); + free( abs_c[ch] ); free( absl_ctx_h[ch] ); free( abss_ctx_h[ch] ); + free( sgn_c[ch] ); free( sgnl_ctx_h[ch] ); free( sgns_ctx_h[ch] ); + free( len_c[ch] ); free( lenl_ctx_h[ch] ); free( lens_ctx_h[ch] ); + free( lbt_c[ch] ); + } + + + return true; +} + + +/* ----------------------------------------------- + store unmute data + ----------------------------------------------- */ +INTERN inline bool pmp_store_unmute_data( iostream* str ) +{ + // as simple as it gets... + str->write( unmute_data, sizeof( char ), unmute_data_size ); + + return true; +} + + +/* ----------------------------------------------- + unstore unmute data + ----------------------------------------------- */ +INTERN inline bool pmp_unstore_unmute_data( iostream* str ) +{ + unsigned char n; + + // read # of of muted frames, set data size + str->read( &n, sizeof( char ), 1 ); + if ( str->chkeof() ) n = 0; + unmute_data_size = 1 + n * ( 2 + ( g_nchannels * 2 * 4 ) ); + + // alloc memory for unmute data + unmute_data = (unsigned char*) calloc( unmute_data_size, sizeof( char ) ); + if ( unmute_data == NULL ) { + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return false; + } + + // read unmute data + *unmute_data = n; + str->read( unmute_data + 1, sizeof( char ), unmute_data_size - 1 ); + + // check for eof + if ( str->chkeof() ) { + sprintf( errormessage, "unexpected end of data" ); + errorlevel = 2; + return false; + } + + + return true; +} + + +/* ----------------------------------------------- + build universal context from global gain + ----------------------------------------------- */ +INTERN inline bool pmp_build_context( void ) +{ + granuleInfo* granule; + int count_gg[ 2 ][ 256 ]; + unsigned char* gg0; + unsigned char* gg1; + int ngr; + + int lbound; + int inc0, inc1; + int i, ch; + + + // check and free gg context arrays where needed + if ( gg_context[0] != NULL ) free ( gg_context[0] ); + if ( gg_context[1] != NULL ) free ( gg_context[1] ); + gg_context[0] = NULL; + gg_context[1] = NULL; + + // number of granules (per channel) + ngr = g_nframes * 2; + + // alloc memory for three global gain contexts + // yup, this might be a waste for mono files + gg_context[0] = (unsigned char*) calloc ( ngr, sizeof( char ) ); + gg_context[1] = (unsigned char*) calloc ( ngr, sizeof( char ) ); + if ( ( gg_context[0] == NULL ) || ( gg_context[1] == NULL ) ) { + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return false; + } + + // set everything zero + memset( count_gg[0], 0, 256 * 4 ); + memset( count_gg[1], 0, 256 * 4 ); + + // count channel 0 symbol occurences + gg0 = gg_context[0]; + for ( granule = firstframe->granules[0][0]; granule != NULL; granule = granule->next ) { + *gg0 = granule->global_gain; + count_gg[0][*(gg0++)]++; + } + for ( i = 1; i < 256; i++ ) // accumulate counts + count_gg[0][i] += count_gg[0][i-1]; + + // count channel 1 and diff symbol occurences + if ( g_nchannels == 2 ) { + gg0 = gg_context[0]; + gg1 = gg_context[1]; + for ( granule = firstframe->granules[1][0]; granule != NULL; granule = granule->next ) { + *gg1 = granule->global_gain; + count_gg[1][*(gg1++)]++; + gg0++; + } + for ( i = 1; i < 256; i++ ) // accumulate counts + count_gg[1][i] += count_gg[1][i-1]; + } + + // analyse and process gg_context + for ( ch = 0; ch < g_nchannels; ch++ ) { + // find the interval with the highest increase + for ( lbound = 0, inc0 = 0, inc1 = 0, i = 0; i < 256 - GG_CONTEXT_SIZE; i++ ) { + inc1 = count_gg[ch][i + GG_CONTEXT_SIZE] - count_gg[ch][i]; + if ( inc1 >= inc0 ) { + inc0 = inc1; + lbound = i; + } + } + // process gg_context + for ( i = 0, gg0 = gg_context[ch]; i < ngr; i++, gg0++ ) { + if ( *gg0 >= lbound ) { + *gg0 -= lbound; + if ( *gg0 >= GG_CONTEXT_SIZE ) *gg0 = GG_CONTEXT_SIZE - 1; + } else *gg0 = 0; + } + } + + + return true; +} + + + + + +/* ----------------------------------------------- + predict LAME ancillary data + ----------------------------------------------- */ +INTERN inline unsigned char* pmp_predict_lame_anc( int nbits, unsigned char* ref ) +{ + static unsigned char* pred = (unsigned char*) calloc( 2048, sizeof( char ) ); + static unsigned char* lame_str = (unsigned char*) calloc( 4 + 16, sizeof( char ) ); // !!! + const unsigned char b01 = 0x55; + const unsigned char b10 = 0xAA; + const unsigned char b00 = 0x00; + const unsigned char b11 = 0xFF; + static int lame_str_len = 4; + static int lame_bit = 0; + static bool alt_pred = 0; + int offset; + int nbytes; + int i; + + // fprintf( stderr, "state:%i/%i/%02X/%02X ", (alt_pred)?0:1, nbits, pred[0], (ref!=NULL)?ref[0]:0xFF ); + if ( nbits < 0 ) { + // (re-)init prediction + lame_bit = 0; + lame_str_len = 4; + memcpy( lame_str, "LAME", 4 ); + alt_pred = false; + } else { + offset = nbits % 8; + nbytes = nbits / 8; + // build prediction + if ( !alt_pred ) { // option 0 - lame predictor + for ( i = 0; ( nbits >=8 ) && ( i < 4 ); nbits -= 8, i++ ) + pred[i] = lame_str[i]; // 'LAME' + if ( nbits >= 32 ) { + for ( ; ( nbits >= 8 ) && ( i < lame_str_len ); nbits -= 8, i++ ) + pred[i] = lame_str[i]; // version number + } + for ( ; nbits > 0; nbits -= 8, i++ ) + pred[i] = ( lame_bit == 0 ) ? b01 : b10; // switching bits + lame_bit ^= ( offset % 2 ); + } // else: keep the prediction as is + if ( ref != NULL ) { // compare prediction with reference (if any) + if ( ( memcmp( pred, ref, nbytes ) == 0 ) && // match + ( ref[nbytes] == pred[nbytes] >> (8-offset) ) ) return NULL; + else { // no match - check alternatives / relearn version number + if ( (nbytes >= 8 ) && ( memcmp( ref, lame_str, 4 ) == 0 ) ) { // 'LAME' match + // careful !!! (ref has to be >=8 in size) + // relearn version number (if any) + for ( i = 4; ( i < 4 + 16 ) && ( i < nbytes ); i++ ) { + if ( ref[i] == b01 ) { + lame_bit = 0; + break; + } else if ( ref[i] == b10 ) { + lame_bit = 1; + break; + } + lame_str[i] = ref[i]; + } + lame_str_len = i; + } else if ( ( nbytes == 0 ) && ( offset > 1 ) ) { + if ( (b00^ref[0]) >> (8-offset) == 0 ) { + memset( pred, b00, 2048 ); + alt_pred = true; + } else if ( (b11^ref[0]) >> (8-offset) == 0 ) { + memset( pred, b11, 2048 ); + alt_pred = true; + } else alt_pred = false; + } else if ( nbytes >= 1 ) { + if ( b00 == ref[0] ) { + memset( pred, b00, 2048 ); + alt_pred = true; + } else if ( b11 == ref[0] ) { + memset( pred, b11, 2048 ); + alt_pred = true; + } else alt_pred = false; + } + } + } + // else: no reference, so prediction is assumed correct + } + + + return pred; +} + +/* ----------------------- End of PMP specific functions -------------------------- */ + +/* ----------------------- Begin of miscellaneous helper functions -------------------------- */ + + +/* ----------------------------------------------- + displays progress bar on screen + ----------------------------------------------- */ +#if !defined(BUILD_LIB) +INTERN inline void progress_bar( int current, int last ) +{ + int barpos = ( ( current * BARLEN ) + ( last / 2 ) ) / last; + int i; + + + // generate progress bar + fprintf( msgout, "[" ); + #if defined(_WIN32) + for ( i = 0; i < barpos; i++ ) + fprintf( msgout, "\xFE" ); + #else + for ( i = 0; i < barpos; i++ ) + fprintf( msgout, "X" ); + #endif + for ( ; i < BARLEN; i++ ) + fprintf( msgout, " " ); + fprintf( msgout, "]" ); +} +#endif + +/* ----------------------------------------------- + creates filename, callocs memory for it + ----------------------------------------------- */ +#if !defined(BUILD_LIB) +INTERN inline char* create_filename( const char* base, const char* extension ) +{ + int len = strlen( base ) + ( ( extension == NULL ) ? 0 : strlen( extension ) + 1 ) + 1; + char* filename = (char*) calloc( len, sizeof( char ) ); + + // create a filename from base & extension + strcpy( filename, base ); + set_extension( filename, extension ); + + return filename; +} +#endif + +/* ----------------------------------------------- + creates filename, callocs memory for it + ----------------------------------------------- */ +#if !defined(BUILD_LIB) +INTERN inline char* unique_filename( const char* base, const char* extension ) +{ + int len = strlen( base ) + ( ( extension == NULL ) ? 0 : strlen( extension ) + 1 ) + 1; + char* filename = (char*) calloc( len, sizeof( char ) ); + + // create a unique filename using underscores + strcpy( filename, base ); + set_extension( filename, extension ); + while ( file_exists( filename ) ) { + len += sizeof( char ); + filename = (char*) realloc( filename, len ); + add_underscore( filename ); + } + + return filename; +} +#endif + +/* ----------------------------------------------- + changes extension of filename + ----------------------------------------------- */ +#if !defined(BUILD_LIB) +INTERN inline void set_extension( const char* filename, const char* extension ) +{ + char* extstr; + + // find position of extension in filename + extstr = ( strrchr( filename, '.' ) == NULL ) ? + strrchr( filename, '\0' ) : strrchr( filename, '.' ); + + // set new extension + if ( extension != NULL ) { + (*extstr++) = '.'; + strcpy( extstr, extension ); + } + else + (*extstr) = '\0'; +} +#endif + +/* ----------------------------------------------- + adds underscore after filename + ----------------------------------------------- */ +#if !defined(BUILD_LIB) +INTERN inline void add_underscore( char* filename ) +{ + char* tmpname = (char*) calloc( strlen( filename ) + 1, sizeof( char ) ); + char* extstr; + + // copy filename to tmpname + strcpy( tmpname, filename ); + // search extension in filename + extstr = strrchr( filename, '.' ); + + // add underscore before extension + if ( extstr != NULL ) { + (*extstr++) = '_'; + strcpy( extstr, strrchr( tmpname, '.' ) ); + } + else + sprintf( filename, "%s_", tmpname ); + + // free memory + free( tmpname ); +} +#endif + +/* ----------------------------------------------- + checks if a file exists + ----------------------------------------------- */ +INTERN inline bool file_exists( const char* filename ) +{ + // needed for both, executable and library + FILE* fp = fopen( filename, "rb" ); + + if ( fp == NULL ) return false; + else { + fclose( fp ); + return true; + } +} + +/* ----------------------- End of miscellaneous helper functions -------------------------- */ + +/* ----------------------- Begin of developers functions -------------------------- */ + + +#if !defined(BUILD_LIB) && defined(DEV_BUILD) +/* ----------------------------------------------- + Writes to file + ----------------------------------------------- */ +INTERN bool write_file( const char* base, const char* ext, void* data, int bpv, int size ) +{ + FILE* fp; + char* fn; + + // create filename + fn = create_filename( base, ext ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ) { + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // write & close + fwrite( data, bpv, size, fp ); + fclose( fp ); + + return true; +} + + +/* ----------------------------------------------- + Writes error info file + ----------------------------------------------- */ +INTERN bool write_errfile( void ) +{ + FILE* fp; + char* fn; + + + // return immediately if theres no error + if ( errorlevel == 0 ) return true; + + // create filename based on errorlevel + if ( errorlevel == 1 ) { + fn = create_filename( filelist[ file_no ], "wrn.nfo" ); + } + else { + fn = create_filename( filelist[ file_no ], "err.nfo" ); + } + + // open file for output + fp = fopen( fn, "w" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // write status and errormessage to file + fprintf( fp, "--> error (level %i) in file \"%s\" <--\n", errorlevel, filelist[ file_no ] ); + fprintf( fp, "\n" ); + // write error specification to file + fprintf( fp, " %s -> %s:\n", get_status( errorfunction ), + ( errorlevel == 1 ) ? "warning" : "error" ); + fprintf( fp, " %s\n", errormessage ); + + // done, close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + Writes info to a specific csv file + ----------------------------------------------- */ +INTERN bool write_file_analysis( void ) +{ + static const char* fn = FILE_ANALYSIS_CSV; + FILE* fp; + bool labels; + + mp3Frame* frame; + granuleInfo* granule; + int total_fixed = 0; + int total_scf = 0; + int total_coef = 0; + int total_aux = 0; + int main_bits; + int cur_scf; + int share = 0; + const int* slen; + int ch, gr; + + + // check if file exists + labels = !file_exists( fn ); + + // open file for output + fp = fopen( fn, "a" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + + + // calculate sizes of scf/coef/aux/fixed + for ( frame = firstframe; frame != NULL; frame = frame->next ) { + main_bits = 0; cur_scf = 0; + for ( ch = 0; ch < g_nchannels; ch++ ) for ( gr = 0; gr < 2; gr++ ) { + granule = frame->granules[ch][gr]; + slen = slength_table[ (int) granule->slength ]; + main_bits += granule->main_data_bit; + if ( granule->block_type != SHORT_BLOCK ) { + if ( ( ( share >> 3 ) & 1 ) == 0 ) cur_scf += slen[ 0 ] * 6; + if ( ( ( share >> 2 ) & 1 ) == 0 ) cur_scf += slen[ 0 ] * 5; + if ( ( ( share >> 1 ) & 1 ) == 0 ) cur_scf += slen[ 1 ] * 5; + if ( ( ( share >> 0 ) & 1 ) == 0 ) cur_scf += slen[ 1 ] * 5; + } else { + cur_scf += slen[ 0 ] * 6 * 3; + cur_scf += slen[ 1 ] * 6 * 3; + } + share = granule->share; + } + total_fixed += frame->fixed_size * 8; + total_scf += cur_scf; + total_coef += main_bits - cur_scf; + total_aux += frame->aux_size * 8; + if ( main_bits % 8 > 0 ) + total_aux += 8 - ( main_bits % 8 ); + } + + // write labels + if ( labels ) { + fprintf( fp, "name;" ); + fprintf( fp, "total_bits;" ); + fprintf( fp, "tag_bits;" ); + fprintf( fp, "fixed_bits;" ); + fprintf( fp, "scf_bits;" ); + fprintf( fp, "coef_bits;" ); + fprintf( fp, "aux_bits;" ); + fprintf( fp, "frames;" ); + fprintf( fp, "mpeg;" ); + fprintf( fp, "layer;" ); + fprintf( fp, "samples;" ); + fprintf( fp, "bitrate;" ); + fprintf( fp, "channels;" ); + fprintf( fp, "protection;" ); + fprintf( fp, "padding;" ); + fprintf( fp, "ms_stereo;" ); + fprintf( fp, "int_stereo;" ); + fprintf( fp, "private;" ); + fprintf( fp, "copyright;" ); + fprintf( fp, "original;" ); + fprintf( fp, "emphasis;" ); + fprintf( fp, "padbits;" ); + fprintf( fp, "bitres;" ); + fprintf( fp, "sharing;" ); + fprintf( fp, "switching;" ); + fprintf( fp, "mixed;" ); + fprintf( fp, "preemphasis;" ); + fprintf( fp, "coarse;" ); + fprintf( fp, "sbgain;" ); + fprintf( fp, "auxiliary_h;" ); + fprintf( fp, "sblock_diff;" ); + fprintf( fp, "bad_first" ); + fprintf( fp, "\n" ); + } + + // write data + fprintf( fp, "%s;", mp3filename ); + fprintf( fp, "%i;", mp3filesize * 8 ); + fprintf( fp, "%i;", ( data_before_size + data_after_size ) * 8 ); + fprintf( fp, "%i;", total_fixed ); + fprintf( fp, "%i;", total_scf ); + fprintf( fp, "%i;", total_coef ); + fprintf( fp, "%i;", total_aux ); + fprintf( fp, "%i;", g_nframes ); + fprintf( fp, "%s;", mpeg_description[(int)i_mpeg] ); + fprintf( fp, "%s;", layer_description[(int)i_layer] ); + fprintf( fp, "%i;", g_samplerate ); + fprintf( fp, "%i;", g_bitrate * 1000 ); + fprintf( fp, "%s;", channels_description[(int)i_channels ] ); + fprintf( fp, "%i;", i_protection ); + fprintf( fp, "%i;", i_padding ); + fprintf( fp, "%i;", i_stereo_ms ); + fprintf( fp, "%i;", i_stereo_int ); + fprintf( fp, "%i;", i_privbit ); + fprintf( fp, "%i;", i_copyright ); + fprintf( fp, "%i;", i_original ); + fprintf( fp, "%i;", i_emphasis ); + fprintf( fp, "%i;", i_padbits ); + fprintf( fp, "%i;", i_bit_res); + fprintf( fp, "%i;", i_share ); + fprintf( fp, "%i;", i_sblocks ); + fprintf( fp, "%i;", i_mixed ); + fprintf( fp, "%i;", i_preemphasis ); + fprintf( fp, "%i;", i_coarse ); + fprintf( fp, "%i;", i_sbgain ); + fprintf( fp, "%i;", i_aux_h ); + fprintf( fp, "%i;", i_sb_diff ); + fprintf( fp, "%i", n_bad_first ); + fprintf( fp, "\n" ); + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + Writes block analysis to csv + ----------------------------------------------- */ +INTERN bool write_block_analysis( void ) +{ + const char* frm_ext = "frm.csv"; + const char* ch_ext[2] = { "ch0.csv", "ch1.csv" }; + FILE* fp; + char* fn; + + mp3Frame* frame; + int ch, gr; + + + /* --- frames analysis --- */ + + // create filename + fn = create_filename( filelist[ file_no ], frm_ext ); + + // open file for output + fp = fopen( fn, "w" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // write labels (header) + fprintf( fp, "frame;" ); + fprintf( fp, "main_index;" ); + fprintf( fp, "frame_size;" ); + fprintf( fp, "fixed_size;" ); + fprintf( fp, "bit_reservoir;"); + fprintf( fp, "main_bits;" ); + fprintf( fp, "main_size;" ); + fprintf( fp, "aux_size;" ); + fprintf( fp, "mpeg;"); + fprintf( fp, "layer;"); + fprintf( fp, "samples;"); + fprintf( fp, "bitrate;"); + fprintf( fp, "channels;"); + fprintf( fp, "protection;"); + fprintf( fp, "padding;"); + fprintf( fp, "ms_stereo;"); + fprintf( fp, "int_stereo;"); + fprintf( fp, "private;"); + fprintf( fp, "copyright;"); + fprintf( fp, "original;"); + fprintf( fp, "emphasis;"); + fprintf( fp, "padbits"); + fprintf( fp, "\n" ); + + // write frame data + for ( frame = firstframe; frame != NULL; frame = frame->next ) { + // header/frame-global info + fprintf( fp, "%i;", frame->n ); + fprintf( fp, "%i;", frame->main_index ); + fprintf( fp, "%i;", frame->frame_size ); + fprintf( fp, "%i;", frame->fixed_size ); + fprintf( fp, "%i;", frame->bit_reservoir ); + fprintf( fp, "%i;", frame->main_bits ); + fprintf( fp, "%i;", frame->main_size ); + fprintf( fp, "%i;", frame->aux_size ); + fprintf( fp, "%s;", mpeg_description[(int)frame->mpeg ] ); + fprintf( fp, "%s;", layer_description[(int)frame->layer ] ); + fprintf( fp, "%i;", mp3_samplerate_table[(int)frame->samples] ); + fprintf( fp, "%i;", mp3_bitrate_table[(int)frame->bits] * 1000 ); + fprintf( fp, "%s;", channels_description[(int)frame->channels ] ); + fprintf( fp, "%i;", frame->protection ); + fprintf( fp, "%i;", frame->padding ); + fprintf( fp, "%i;", frame->stereo_ms ); + fprintf( fp, "%i;", frame->stereo_int ); + fprintf( fp, "%i;", frame->privbit ); + fprintf( fp, "%i;", frame->copyright ); + fprintf( fp, "%i;", frame->original ); + fprintf( fp, "%i;", frame->emphasis ); + fprintf( fp, "%i;", frame->padbits ); + fprintf( fp, "\n" ); + } + + // close file + fclose( fp ); + + + /* --- granules analysis --- */ + for ( ch = 0; ch < g_nchannels; ch++ ) { + // create filename + fn = create_filename( filelist[ file_no ], ch_ext[ch] ); + + // open file for output + fp = fopen( fn, "w" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // labels (granules) + fprintf( fp, "block;" ); + fprintf( fp, "ms_stereo;" ); + fprintf( fp, "int_stereo;" ); + fprintf( fp, "share;" ); + fprintf( fp, "main_bit;" ); + fprintf( fp, "big_vals;" ); + fprintf( fp, "gl_gain;" ); + fprintf( fp, "slength;" ); + fprintf( fp, "switching;" ); + fprintf( fp, "block_type;" ); + fprintf( fp, "mixed;" ); + fprintf( fp, "preemphasis;" ); + fprintf( fp, "coarse;" ); + fprintf( fp, "r0_tbl;" ); + fprintf( fp, "r1_tbl;" ); + fprintf( fp, "r2_tbl;" ); + fprintf( fp, "sm_tbl;" ); + fprintf( fp, "r0_size;" ); + fprintf( fp, "r1_size;" ); + fprintf( fp, "r0_bound;" ); + fprintf( fp, "r1_bound;" ); + fprintf( fp, "r2_bound;" ); + fprintf( fp, "sv_bound;" ); + fprintf( fp, "sb0_gain;" ); + fprintf( fp, "sb1_gain;" ); + fprintf( fp, "sb2_gain" ); + fprintf( fp, "\n" ); + + // write granules data + for ( frame = firstframe; frame != NULL; frame = frame->next ) if ( ch < frame->nchannels ) { + for ( gr = 0; gr < 2; gr++ ) { + fprintf( fp, "%i;", frame->granules[ch][gr]->n ); + fprintf( fp, "%i;", frame->stereo_ms ); + fprintf( fp, "%i;", frame->stereo_int ); + fprintf( fp, "0b%i%i%i%i;", + BITN( frame->granules[ch][gr]->share, 3 ), + BITN( frame->granules[ch][gr]->share, 2 ), + BITN( frame->granules[ch][gr]->share, 1 ), + BITN( frame->granules[ch][gr]->share, 0 ) ); + fprintf( fp, "%i;", frame->granules[ch][gr]->main_data_bit ); + fprintf( fp, "%i;", frame->granules[ch][gr]->big_val_pairs ); + fprintf( fp, "%i;", frame->granules[ch][gr]->global_gain ); + fprintf( fp, "%i/%i;", slength_table[ (int) frame->granules[ch][gr]->slength ][ 0 ], slength_table[ (int) frame->granules[ch][gr]->slength ][ 1 ] ); + fprintf( fp, "%i;", frame->granules[ch][gr]->window_switching ); + fprintf( fp, "%s;", blocktype_description[(int)frame->granules[ch][gr]->block_type] ); + fprintf( fp, "%i;", frame->granules[ch][gr]->mixed_flag ); + fprintf( fp, "%i;", frame->granules[ch][gr]->preemphasis ); + fprintf( fp, "%i;", frame->granules[ch][gr]->coarse_scalefactors ); + fprintf( fp, "%i;", frame->granules[ch][gr]->region_table[0] ); + fprintf( fp, "%i;", frame->granules[ch][gr]->region_table[1] ); + fprintf( fp, "%i;", frame->granules[ch][gr]->region_table[2] ); + fprintf( fp, "%i;", frame->granules[ch][gr]->select_htabB ); + fprintf( fp, "%i;", frame->granules[ch][gr]->region0_size ); + fprintf( fp, "%i;", frame->granules[ch][gr]->region1_size ); + fprintf( fp, "%i;", frame->granules[ch][gr]->region_bound[0] ); + fprintf( fp, "%i;", frame->granules[ch][gr]->region_bound[1] ); + fprintf( fp, "%i;", frame->granules[ch][gr]->region_bound[2] ); + fprintf( fp, "%i;", frame->granules[ch][gr]->sv_bound ); + fprintf( fp, "%i;", frame->granules[ch][gr]->sb_gain[0] ); + fprintf( fp, "%i;", frame->granules[ch][gr]->sb_gain[1] ); + fprintf( fp, "%i", frame->granules[ch][gr]->sb_gain[2] ); + fprintf( fp, "\n" ); + } + } + + // close file + fclose( fp ); + } + + + return true; +} + + +/* ----------------------------------------------- + Writes statistic info to a specific csv file + ----------------------------------------------- */ +INTERN bool write_stat_analysis( void ) +{ + static const char* fn = STAT_ANALYSIS_CSV; + FILE* fp; + bool labels; + + huffman_reader* decoder; + mp3Frame* frame; + granuleInfo* granule; + granuleData*** frame_data; + int ch, gr; + int i; + + unsigned int coef_stats[ 16 ] = { 0 }; + unsigned int coefb_stats[ 15 ] = { 0 }; + unsigned int scf_stats[ 16 ] = { 0 }; + unsigned int bv_tbl_stats[ 32 ] = { 0 }; + unsigned int sv_tbl_stats[ 2 ] = { 0 }; + unsigned int blt_stats[ 4 ] = { 0 }; + unsigned int n_bad_bv_bound = 0; + unsigned int n_bad_sv_bound = 0; + int bv_bound_max_dist = 0; + int sv_bound_max_dist = 0; + int bv_bound_avrg = 0; + int sv_bound_avrg = 0; + int bad_code = 0; + int r2bvs_avrg = 0; + + + + // check if file exists + labels = !file_exists( fn ); + + // open file for output + fp = fopen( fn, "a" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + + // write labels + if ( labels ) { + fprintf( fp, "name;" ); + fprintf( fp, "n_frames;" ); + fprintf( fp, "muted;" ); + fprintf( fp, "bad_code;" ); + for ( i = 0; i < 15; i++ ) + fprintf( fp, "cf=%i;", i ); + fprintf( fp, "cf>=15;" ); + for ( i = 0; i < 15; i++ ) + fprintf( fp, "cb=%i;", i ); + for ( i = 0; i < 16; i++ ) + fprintf( fp, "sc=%i;", i ); + for ( i = 0; i < 32; i++ ) + fprintf( fp, "bv_tbl%i;", i ); + fprintf( fp, "sv_tblA;" ); + fprintf( fp, "sv_tblB;" ); + fprintf( fp, "long;" ); + fprintf( fp, "start;" ); + fprintf( fp, "short;" ); + fprintf( fp, "stop;" ); + fprintf( fp, "n_bad_bv;" ); + fprintf( fp, "bad_bv_lim;" ); + fprintf( fp, "bad_bv_avr;" ); + fprintf( fp, "n_bad_sv;" ); + fprintf( fp, "bad_sv_lim;" ); + fprintf( fp, "bad_sv_avr;" ); + fprintf( fp, "reg2_bv_avr" ); + fprintf( fp, "\n" ); + } + + // init decoder + decoder = new huffman_reader( main_data, main_data_size ); + + // run statistical analysis + for ( frame = firstframe; frame != NULL; frame = frame->next ) { + // skip bad first frames + if ( frame->n < n_bad_first ) continue; + frame_data = mp3_decode_frame( decoder, frame ); + if ( frame_data == NULL ) bad_code++; + for ( ch = 0; ch < frame->nchannels; ch++ ) { + for ( gr = 0; gr < 2; gr++ ) { + granule = frame->granules[ch][gr]; + // simple stuff first + bv_tbl_stats[ (int) granule->region_table[0] ]++; + bv_tbl_stats[ (int) granule->region_table[1] ]++; + sv_tbl_stats[ (int) granule->select_htabB ]++; + blt_stats[ (int) granule->block_type ]++; + if ( !granule->window_switching ) + bv_tbl_stats[ (int) granule->region_table[2] ]++; + if ( frame_data == NULL ) continue; + // count coefficients and scalefactors + if ( granule->block_type != SHORT_BLOCK ) { + for ( i = 0; i < 21; i++ ) + scf_stats[ (int) frame_data[ch][gr]->scalefactors[i] ]++; + } else { + for ( i = 0; i < 36; i++ ) + scf_stats[ (int) frame_data[ch][gr]->scalefactors[i] ]++; + } + for ( i = 0; i < 576; i++ ) { + if ( ABS(frame_data[ch][gr]->coefficients[i]) < 16 ) + coef_stats[ ABS(frame_data[ch][gr]->coefficients[i]) ]++; + else coef_stats[ 15 ]++; + coefb_stats[ BITLEN8224N(frame_data[ch][gr]->coefficients[i]) ]++; + } + // check for bad sv bounds + for ( i = 0; i < granule->sv_bound; i++ ) + if ( frame_data[ch][gr]->coefficients[granule->sv_bound-i-1] != 0 ) break; + i /= 4; + if ( i > 0 ) { + n_bad_sv_bound++; + sv_bound_avrg += i; + if ( sv_bound_max_dist < i ) sv_bound_max_dist = i; + } + // done if zero table + // if ( granule->window_switching ) if ( granule->region_table[2] == 0 ) continue; + // else if ( granule->region_table[1] == 0 ) continue; + // check for bad bv bounds + for ( i = 0; i < granule->region_bound[2]; i++ ) + if ( ABS(frame_data[ch][gr]->coefficients[granule->region_bound[2]-i-1]) > 1 ) break; + i /= 2; + if ( i > 1 ) { + n_bad_bv_bound++; + bv_bound_avrg += i; + if ( bv_bound_max_dist < i ) bv_bound_max_dist = i; + } + // count region 2 coefficients ABS > 2 + for ( i = granule->region_bound[(granule->window_switching)?0:1]; i < granule->region_bound[2]; i++ ) + if ( ABS(frame_data[ch][gr]->coefficients[i]) > 1 ) r2bvs_avrg++; + } + } + } + sv_bound_avrg = ( n_bad_sv_bound > 0 ) ? sv_bound_avrg / n_bad_sv_bound : 0; + bv_bound_avrg = ( n_bad_bv_bound > 0 ) ? bv_bound_avrg / n_bad_bv_bound : 0; + r2bvs_avrg = r2bvs_avrg / ( g_nframes * 2 * g_nchannels ); + + // done analyzing, delete decoder + delete( decoder ); + + // write data + fprintf( fp, "%s;", mp3filename ); + fprintf( fp, "%i;", g_nframes ); + fprintf( fp, "%i;", n_bad_first ); + fprintf( fp, "%i;", bad_code ); + for ( i = 0; i < 16; i++ ) + fprintf( fp, "%i;", (int) coef_stats[i] ); + for ( i = 0; i < 15; i++ ) + fprintf( fp, "%i;", (int) coefb_stats[i] ); + for ( i = 0; i < 16; i++ ) + fprintf( fp, "%i;", (int) scf_stats[i] ); + for ( i = 0; i < 32; i++ ) + fprintf( fp, "%i;", (int) bv_tbl_stats[i] ); + for ( i = 0; i < 2; i++ ) + fprintf( fp, "%i;", (int) sv_tbl_stats[i] ); + for ( i = 0; i < 4; i++ ) + fprintf( fp, "%i;", (int) blt_stats[i] ); + fprintf( fp, "%i;", (int) n_bad_bv_bound ); + fprintf( fp, "%i;", bv_bound_max_dist ); + fprintf( fp, "%i;", bv_bound_avrg ); + fprintf( fp, "%i;", (int) n_bad_sv_bound ); + fprintf( fp, "%i;", sv_bound_max_dist ); + fprintf( fp, "%i;", sv_bound_avrg ); + fprintf( fp, "%i", r2bvs_avrg ); + fprintf( fp, "\n" ); + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + Make a PGM of header/sideinfo data + ----------------------------------------------- */ +INTERN bool visualize_headers( void ) +{ + static const int img_width = 1280; // must be divisible by 2 + static const bool inc_all = false; + static unsigned char* line = (unsigned char*) calloc ( img_width, sizeof( char ) ); + mp3Frame* frame; + mp3Frame* frame0 = firstframe; + mp3Frame* frame1 = firstframe; + int i; + + FILE* fp; + char* fn; + + + // create filename + fn = create_filename( filelist[ file_no ], "headers.pgm" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // write PGM header + fprintf( fp, "P5\n" ); + fprintf( fp, "# created by %s v%i.%i%s (%s) by %s\n", + appname, appversion / 10, appversion % 10, subversion, versiondate, author ); + fprintf( fp, "%i %i\n", img_width, ( ((g_nframes*2) + img_width - 1) / img_width ) * ( inc_all ? 60 : 40 ) ); + fprintf( fp, "255\n" ); + + do { // write data, line per line, 2x2 pixels for header stuff + memset ( line, 0x0, img_width ); + frame0 = frame1; + for ( i = 0; i < (img_width/2); i++ ) { + frame1 = frame1->next; + if ( frame1 == NULL ) break; + } + i = frame0->n; + + if ( inc_all ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 ] = frame->mpeg << 6; + line[ (frame->n-i) * 2 + 1 ] = line[ (frame->n-i) * 2 ]; + } // 2 (MPEG) + fwrite( line, 1, img_width, fp ); + fwrite( line, 1, img_width, fp ); + } // -2 + + if ( inc_all ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 ] = frame->layer << 6; + line[ (frame->n-i) * 2 + 1 ] = line[ (frame->n-i) * 2 ]; + } // 4 (LAYER) + fwrite( line, 1, img_width, fp ); + fwrite( line, 1, img_width, fp ); + } // -4 + + if ( inc_all ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 ] = frame->channels << 6; + line[ (frame->n-i) * 2 + 1 ] = line[ (frame->n-i) * 2 ]; + } // 6 (CHANNELS) + fwrite( line, 1, img_width, fp ); + fwrite( line, 1, img_width, fp ); + } // -6 + + if ( inc_all ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 ] = frame->samples << 6; + line[ (frame->n-i) * 2 + 1 ] = line[ (frame->n-i) * 2 ]; + } // 8 (SAMPLES) + fwrite( line, 1, img_width, fp ); + fwrite( line, 1, img_width, fp ); + } // -8 + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 ] = frame->bits << 4; + line[ (frame->n-i) * 2 + 1 ] = line[ (frame->n-i) * 2 ]; + } // 10 (BITRATE) + fwrite( line, 1, img_width, fp ); + fwrite( line, 1, img_width, fp ); + + if ( inc_all ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 ] = ( frame->protection == 0 ) ? 0 : 255; + line[ (frame->n-i) * 2 + 1 ] = line[ (frame->n-i) * 2 ]; + } // 12 (PROTECTION) + fwrite( line, 1, img_width, fp ); + fwrite( line, 1, img_width, fp ); + } // -10 + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 ] = ( frame->padding == 0 ) ? 0 : 255; + line[ (frame->n-i) * 2 + 1 ] = line[ (frame->n-i) * 2 ]; + } // 14 (PADDING) + fwrite( line, 1, img_width, fp ); + fwrite( line, 1, img_width, fp ); + + if ( inc_all ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 ] = ( frame->privbit == 0 ) ? 0 : 255; + line[ (frame->n-i) * 2 + 1 ] = line[ (frame->n-i) * 2 ]; + } // 16 (PRIVATE) + fwrite( line, 1, img_width, fp ); + fwrite( line, 1, img_width, fp ); + } // -12 + + if ( inc_all ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 ] = ( frame->copyright == 0 ) ? 0 : 255; + line[ (frame->n-i) * 2 + 1 ] = line[ (frame->n-i) * 2 ]; + } // 18 (COPYRIGHT) + fwrite( line, 1, img_width, fp ); + fwrite( line, 1, img_width, fp ); + } // -14 + + if ( inc_all ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 ] = ( frame->original == 0 ) ? 0 : 255; + line[ (frame->n-i) * 2 + 1 ] = line[ (frame->n-i) * 2 ]; + } // 20 (ORIGINAL) + fwrite( line, 1, img_width, fp ); + fwrite( line, 1, img_width, fp ); + } // -16 + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 ] = ( frame->stereo_ms == 0 ) ? 0 : 255; + line[ (frame->n-i) * 2 + 1 ] = line[ (frame->n-i) * 2 ]; + } // 22 (MS STEREO) + fwrite( line, 1, img_width, fp ); + fwrite( line, 1, img_width, fp ); + + if ( inc_all ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 ] = ( frame->stereo_int == 0 ) ? 0 : 255; + line[ (frame->n-i) * 2 + 1 ] = line[ (frame->n-i) * 2 ]; + } // 24 (INT STEREO) + fwrite( line, 1, img_width, fp ); + fwrite( line, 1, img_width, fp ); + } // -18 + + if ( inc_all ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 ] = frame->emphasis << 6; + line[ (frame->n-i) * 2 + 1 ] = line[ (frame->n-i) * 2 ]; + } // 26 (EMPHASIS) + fwrite( line, 1, img_width, fp ); + fwrite( line, 1, img_width, fp ); + } // -20 + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->main_data_bit >> 4; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->main_data_bit >> 4; + } + fwrite( line, 1, img_width, fp ); // 27 (MAIN DATA BIT) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->main_data_bit >> 4; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->main_data_bit >> 4; + } + } + fwrite( line, 1, img_width, fp ); // 28 (MAIN DATA BIT) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->big_val_pairs >> 1; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->big_val_pairs >> 1; + } + fwrite( line, 1, img_width, fp ); // 29 (BIG VALUES) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->big_val_pairs >> 1; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->big_val_pairs >> 1; + } + } + fwrite( line, 1, img_width, fp ); // 30 (BIG VALUES) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->share << 4; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->share << 4; + } + fwrite( line, 1, img_width, fp ); // 31 (SHARING) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->share << 4; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->share << 4; + } + } + fwrite( line, 1, img_width, fp ); // 32 (SHARING) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->global_gain; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->global_gain; + } + fwrite( line, 1, img_width, fp ); // 33 (GLOBAL GAIN) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->global_gain; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->global_gain; + } + } + fwrite( line, 1, img_width, fp ); // 34 (GLOBAL GAIN) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->slength << 4; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->slength << 4; + } + fwrite( line, 1, img_width, fp ); // 35 (SLENGTH) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->slength << 4; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->slength << 4; + } + } + fwrite( line, 1, img_width, fp ); // 36 (SLENGTH) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->block_type << 6; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->block_type << 6; + } + fwrite( line, 1, img_width, fp ); // 37 (BLOCK TYPE) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->block_type << 6; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->block_type << 6; + } + } + fwrite( line, 1, img_width, fp ); // 38 (BLOCK TYPE) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->preemphasis * 255; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->preemphasis * 255; + } + fwrite( line, 1, img_width, fp ); // 39 (PREEMPHASIS) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->preemphasis * 255; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->preemphasis * 255; + } + } + fwrite( line, 1, img_width, fp ); // 40 (PREEMPHASIS) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->coarse_scalefactors * 255; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->coarse_scalefactors * 255; + } + fwrite( line, 1, img_width, fp ); // 41 (COARSE) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->coarse_scalefactors * 255; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->coarse_scalefactors * 255; + } + } + fwrite( line, 1, img_width, fp ); // 42 (COARSE) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->region_table[0] << 3; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->region_table[0] << 3; + } + fwrite( line, 1, img_width, fp ); // 43 (R0 TABLE) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->region_table[0] << 3; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->region_table[0] << 3; + } + } + fwrite( line, 1, img_width, fp ); // 44 (R0 TABLE) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->region_table[1] << 3; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->region_table[1] << 3; + } + fwrite( line, 1, img_width, fp ); // 45 (R1 TABLE) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->region_table[1] << 3; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->region_table[1] << 3; + } + } + fwrite( line, 1, img_width, fp ); // 46 (R1 TABLE) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->region_table[2] << 3; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->region_table[2] << 3; + } + fwrite( line, 1, img_width, fp ); // 47 (R2 TABLE) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->region_table[2] << 3; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->region_table[2] << 3; + } + } + fwrite( line, 1, img_width, fp ); // 48 (R2 TABLE) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->select_htabB * 255; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->select_htabB * 255; + } + fwrite( line, 1, img_width, fp ); // 49 (R4 TABLE) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->select_htabB * 255; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->select_htabB * 255; + } + } + fwrite( line, 1, img_width, fp ); // 50 (R4 TABLE) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->region0_size << 4; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->region0_size << 4; + } + fwrite( line, 1, img_width, fp ); // 51 (R0 SIZE) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->region0_size << 4; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->region0_size << 4; + } + } + fwrite( line, 1, img_width, fp ); // 52 (R0 SIZE) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->region1_size << 4; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->region1_size << 4; + } + fwrite( line, 1, img_width, fp ); // 53 (R1 SIZE) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->region1_size << 4; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->region1_size << 4; + } + } + fwrite( line, 1, img_width, fp ); // 54 (R1 SIZE) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->sb_gain[0] << 5; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->sb_gain[0] << 5; + } + fwrite( line, 1, img_width, fp ); // 55 (SB0 GAIN) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->sb_gain[0] << 5; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->sb_gain[0] << 5; + } + } + fwrite( line, 1, img_width, fp ); // 56 (SB0 GAIN) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->sb_gain[1] << 5; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->sb_gain[1] << 5; + } + fwrite( line, 1, img_width, fp ); // 57 (SB1 GAIN) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->sb_gain[1] << 5; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->sb_gain[1] << 5; + } + } + fwrite( line, 1, img_width, fp ); // 58 (SB1 GAIN) + + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[0][0]->sb_gain[2] << 5; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[0][1]->sb_gain[2] << 5; + } + fwrite( line, 1, img_width, fp ); // 59 (SB2 GAIN) + if ( g_nchannels == 2 ) { + for ( frame = frame0; frame != frame1; frame = frame->next ) { + line[ (frame->n-i) * 2 + 0 ] = frame->granules[1][0]->sb_gain[2] << 5; + line[ (frame->n-i) * 2 + 1 ] = frame->granules[1][1]->sb_gain[2] << 5; + } + } + fwrite( line, 1, img_width, fp ); // 60 (SB2 GAIN) + } while ( frame1 != NULL ); + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + Make a PGM of coefs/scalefactors + ----------------------------------------------- */ +INTERN bool visualize_decoded_data( void ) +{ + static const int nfs = 2; + static const int nfc = 9; + static const unsigned char v_types[4][2] = { + { 0xFF, 0xFF }, { 0xFF, 0x00 }, + { 0x00, 0x00 }, { 0x00, 0xFF } + }; + static const unsigned char v_unk = 0x7F; + static const unsigned char v_zero = 0x00; + + FILE* fp[nfs+nfc]; + const char* ext[nfs+nfc] = { + "scale.unt.pgm", + "scale.nrm.pgm", + "coefs.f15.pgm", + "coefs.sgn.pgm", + "coefs.l15.pgm", + "coefs.len.pgm", + "coefs.nzz.pgm", + "coefs.reg.pgm", + "coefs.tbl.pgm", + "coefs.bsb.pgm", + "coefs.nnz.pgm" + }; + char* fn; + + int total_cf, total_sc; + int width_cf, width_sc; + int height_cf, height_sc; + mp3Frame* frame; + granuleInfo* granule; + granuleData*** frame_data; + huffman_reader* decoder; + unsigned char* data_cf[nfc]; + unsigned char* data_sc[nfs]; + unsigned char* temp_cf; + unsigned char* temp_sc; + int temp_reg[15]; + int tmp; + int gr, ch; + int blt; + int n_sc, n_cf; + int i, r; + + + // open files + for ( i = 0; i < (nfs+nfc); i++ ) { + fn = create_filename( filelist[ file_no ], ext[i] ); + // open file for output + fp[i] = fopen( fn, "wb" ); + free( fn ); + if ( fp[i] == NULL ) { + for ( i--; i >= 0; i-- ) fclose( fp[i] ); + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + } + + // decide widths for both (try reaching 4:3 ratio) + total_cf = g_nframes * g_nchannels * 2 * ( 576 + 2 + 2 + 2 ); + total_sc = g_nframes * g_nchannels * 2 * ( 32 + 2 + 2 + 2 ); + height_cf = ( 576 + 2 + 2 + 2 ) * 2; + for ( i = 2; ( 582 * 582 * i * i ) <= total_cf; i += 2 ) + height_cf = ( 576 + 2 + 2 + 2 ) * i; + height_sc = ( 32 + 2 + 2 + 2 ) * 2; + for ( i = 2; ( 38 * 38 * i * i ) <= total_sc; i += 2 ) + height_sc = ( 32 + 2 + 2 + 2 ) * i; + width_cf = ( total_cf + height_cf - 1 ) / height_cf; + width_sc = ( total_sc + height_sc - 1 ) / height_sc; + if ( width_cf % 2 == 1 ) width_cf++; + if ( width_sc % 2 == 1 ) width_sc++; + + // write pgm headers + for ( i = 0; i < (nfs+nfc); i++ ) { + fprintf( fp[i], "P5\n" ); + fprintf( fp[i], "# created by %s v%i.%i%s (%s) by %s\n", + appname, appversion / 10, appversion % 10, subversion, versiondate, author ); + fprintf( fp[i], "%i %i\n", (i>=nfs)?width_cf:width_sc, (i>=nfs)?height_cf:height_sc ); + fprintf( fp[i], "255\n" ); + } + + // alloc memory + temp_sc = ( unsigned char* ) calloc( 32, sizeof( char ) ); + temp_cf = ( unsigned char* ) calloc( 576, sizeof( char ) ); + for ( i = 0; i < nfs; i++ ) { + data_sc[i] = ( unsigned char* ) calloc( width_sc * g_nchannels * 38, sizeof( char ) ); + if ( data_sc[i] == NULL ) { + free( temp_sc ); free( temp_cf ); + for ( i = (nfs+nfc) - 1; i >= 0; i-- ) fclose( fp[i] ); + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return false; + } + } + for ( i = 0; i < nfc; i++ ) { + data_cf[i] = ( unsigned char* ) calloc( width_cf * g_nchannels * 582, sizeof( char ) ); + if ( data_cf[i] == NULL ) { + free( temp_sc ); free( temp_cf ); + for ( i = (nfs+nfc) - 1; i >= 0; i-- ) fclose( fp[i] ); + sprintf( errormessage, MEM_ERRMSG ); + errorlevel = 2; + return false; + } + } + + + // init decoder + decoder = new huffman_reader( main_data, main_data_size ); + + // main processing loop + for ( n_sc = 0, n_cf = 0, frame = firstframe; frame != NULL; frame = frame->next ) { + frame_data = ( frame->n >= n_bad_first ) ? mp3_decode_frame( decoder, frame ) : NULL; + for ( gr = 0; gr < 2; gr++, n_sc++, n_cf++ ) { + if ( frame_data != NULL ) for ( ch = 0; ch < g_nchannels; ch++ ) { + granule = frame->granules[ch][gr]; + // block type + blt = frame->granules[ch][gr]->block_type; + + // scalefactors visualization + for ( i = 0; i < nfs; i++ ) { + switch ( i ) { + case 0: // untouched scalefactors + for ( r = ( blt == SHORT_BLOCK ) ? 31 : 20; r >= 0; r-- ) + temp_sc[r] = frame_data[ch][gr]->scalefactors[ r ] * 16; + break; + case 1: // normalized scalefactors + for ( r = ( blt == SHORT_BLOCK ) ? 31 : 20; r >= 0; r-- ) { + temp_sc[r] = frame_data[ch][gr]->scalefactors[ r ]; + if ( granule->preemphasis && ( granule->block_type != SHORT_BLOCK ) ) + temp_sc[r] += preemphasis_table[ i ]; + if ( granule->coarse_scalefactors ) + temp_sc[r] <<= 1; + temp_sc[r] *= 6; + } + break; + } + data_sc[i][ ( ( 0 + (ch*40) ) * width_sc ) + n_sc ] = v_types[blt][0]; + data_sc[i][ ( ( 1 + (ch*40) ) * width_sc ) + n_sc ] = v_types[blt][1]; + data_sc[i][ ( ( 34 + (ch*40) ) * width_sc ) + n_sc ] = v_types[blt][0]; + data_sc[i][ ( ( 35 + (ch*40) ) * width_sc ) + n_sc ] = v_types[blt][1]; + if ( ch == 0 ) for ( r = ( blt == SHORT_BLOCK ) ? 31 : 20; r >= 0; r-- ) + data_sc[i][ ( ( 2 + 31 - r ) * width_sc ) + n_sc ] = temp_sc[r]; + else for ( r = ( blt == SHORT_BLOCK ) ? 31 : 20; r >= 0; r-- ) + data_sc[i][ ( ( 40 + 2 + r ) * width_sc ) + n_sc ] = temp_sc[r]; + if ( g_nchannels == 1 ) { + data_sc[i][ ( 36 * width_sc ) + n_sc ] = granule->global_gain; + data_sc[i][ ( 37 * width_sc ) + n_sc ] = granule->global_gain; + } else if ( ch == 0 ) { + data_sc[i][ ( 36 * width_sc ) + n_sc ] = granule->global_gain; + data_sc[i][ ( 37 * width_sc ) + n_sc ] = frame->stereo_ms * 255; + } else { + data_sc[i][ ( 38 * width_sc ) + n_sc ] = frame->stereo_ms * 255; + data_sc[i][ ( 39 * width_sc ) + n_sc ] = granule->global_gain; + } + } + + + // coefficients visualization + for ( i = 0; i < nfc; i++ ) { + switch ( i ) { + case 0: // fixed 4 bit part + for ( r = 0; r < 576; r++ ) temp_cf[r] = + ( frame_data[ch][gr]->coefficients[ r ] > 15 ) ? 15 * 16: + ( frame_data[ch][gr]->coefficients[ r ] < -15 ) ? 15 * 16: + ( frame_data[ch][gr]->coefficients[ r ] >= 0 ) ? + frame_data[ch][gr]->coefficients[ r ] * 16: + -frame_data[ch][gr]->coefficients[ r ] * 16; + break; + case 1: // sign + for ( r = 0; r < 576; r++ ) temp_cf[r] = + ( frame_data[ch][gr]->coefficients[ r ] == 0 ) ? 128 : + ( frame_data[ch][gr]->coefficients[ r ] > 0 ) ? 255 : 0; + break; + case 2: // 4 bit truncated bitlength + for ( r = 0; r < 576; r++ ) temp_cf[r] = + ( frame_data[ch][gr]->coefficients[ r ] > 15 ) ? + BITLEN8192P( ( frame_data[ch][gr]->coefficients[ r ] - 15 ) ) * 18 : + ( frame_data[ch][gr]->coefficients[ r ] < -15 ) ? + BITLEN8192P( ( -frame_data[ch][gr]->coefficients[ r ] - 15 ) ) * 18 : 0; + break; + case 3: // full bitlength + for ( r = 0; r < 576; r++ ) temp_cf[r] = + BITLEN8224N( frame_data[ch][gr]->coefficients[ r ] ) * 19; + break; + case 4: // zeroes - non-zeroes + for ( r = 0; r < 576; r++ ) temp_cf[r] = + ( frame_data[ch][gr]->coefficients[ r ] == 0 ) ? 0 : 128; + break; + case 5: // regions + for ( r = 0; r < 576; r++ ) temp_cf[r] = + ( r < granule->region_bound[0] ) ? 255 : + ( r < granule->region_bound[1] ) ? 191 : + ( r < granule->region_bound[2] ) ? 131 : + ( r < granule->sv_bound ) ? 63 : 0; + break; + case 6: // tables + for ( r = 0; r < 576; r++ ) temp_cf[r] = + ( r < granule->region_bound[0] ) ? granule->region_table[0] * 7 + 21 : + ( r < granule->region_bound[1] ) ? granule->region_table[1] * 7 + 21 : + ( r < granule->region_bound[2] ) ? granule->region_table[2] * 7 + 21 : + ( r < granule->sv_bound ) ? granule->select_htabB * 7 + 7 : 0; + break; + case 7: // only bv/sv region diffs + for ( r = 0; r < 576; r++ ) temp_cf[r] = + ( r < granule->sv_bound - granule->region_bound[2] ) ? 255 : 0; + break; + case 8: // numbers of non-zeroes + memset( temp_reg, 0x00, 16 * sizeof(int) ); + for ( tmp = 0; tmp < 16; tmp++ ) for ( r = 0; r < 576; r++ ) + if ( ABS( frame_data[ch][gr]->coefficients[ r ] ) >= tmp ) temp_reg[tmp]++; + for ( tmp = 0, r = 0; tmp < 16; tmp++ ) for ( ; r < temp_reg[15-tmp]; r++ ) + temp_cf[r] = (15-tmp) * 16; + break; + } + data_cf[i][ ( ( 0 + (ch*584) ) * width_cf ) + n_cf ] = v_types[blt][0]; + data_cf[i][ ( ( 1 + (ch*584) ) * width_cf ) + n_cf ] = v_types[blt][1]; + data_cf[i][ ( ( 578 + (ch*584) ) * width_cf ) + n_cf ] = v_types[blt][0]; + data_cf[i][ ( ( 579 + (ch*584) ) * width_cf ) + n_cf ] = v_types[blt][1]; + if ( ch == 0 ) for ( r = 576 - 1; r >= 0; r-- ) + data_cf[i][ ( ( 2 + 575 - r ) * width_cf ) + n_cf ] = temp_cf[ r ]; + else for ( r = 0; r < 576; r++ ) + data_cf[i][ ( ( 584 + 2 + r ) * width_cf ) + n_cf ] = temp_cf[ r ]; + if ( g_nchannels == 1 ) { + data_cf[i][ ( 580 * width_cf ) + n_cf ] = granule->global_gain; + data_cf[i][ ( 581 * width_cf ) + n_cf ] = granule->global_gain; + } else if ( ch == 0 ) { + data_cf[i][ ( 580 * width_cf ) + n_cf ] = granule->global_gain; + data_cf[i][ ( 581 * width_cf ) + n_cf ] = frame->stereo_ms * 255; + } else { + data_cf[i][ ( 582 * width_cf ) + n_cf ] = frame->stereo_ms * 255; + data_cf[i][ ( 583 * width_cf ) + n_cf ] = granule->global_gain; + } + } + } else { + // no scalefactors + for ( i = 0; i < nfs; i++ ) { + data_sc[i][ ( 0 * width_sc ) + n_sc ] = v_unk; + data_sc[i][ ( 1 * width_sc ) + n_sc ] = v_unk; + data_sc[i][ ( 34 * width_sc ) + n_sc ] = v_unk; + data_sc[i][ ( 35 * width_sc ) + n_sc ] = v_unk; + if ( g_nchannels == 2 ) { + data_sc[i][ ( 36 * width_sc ) + n_sc ] = v_unk; + data_sc[i][ ( 37 * width_sc ) + n_sc ] = v_unk; + data_sc[i][ ( 70 * width_sc ) + n_sc ] = v_unk; + data_sc[i][ ( 71 * width_sc ) + n_sc ] = v_unk; + } + } + // no coefficients + for ( i = 0; i < nfc; i++ ) { + data_cf[i][ ( 0 * width_cf ) + n_cf ] = v_unk; + data_cf[i][ ( 1 * width_cf ) + n_cf ] = v_unk; + data_cf[i][ ( 578 * width_cf ) + n_cf ] = v_unk; + data_cf[i][ ( 579 * width_cf ) + n_cf ] = v_unk; + if ( g_nchannels == 2 ) { + data_cf[i][ ( 580 * width_cf ) + n_cf ] = v_unk; + data_cf[i][ ( 581 * width_cf ) + n_cf ] = v_unk; + data_cf[i][ ( 1158 * width_cf ) + n_cf ] = v_unk; + data_cf[i][ ( 1159 * width_cf ) + n_cf ] = v_unk; + } + } + } + } + + if ( n_sc >= width_sc ) { // flush scfs + for ( i = 0; i < nfs; i++ ) { + fwrite( data_sc[i], 1, width_sc * g_nchannels * 38, fp[i] ); + memset( data_sc[i], v_zero, width_sc * g_nchannels * 38 ); + } + n_sc = 0; + } + + if ( n_cf >= width_cf ) { // flush coefs + for ( i = 0; i < nfc; i++ ) { + fwrite( data_cf[i], 1, width_cf * g_nchannels * 582, fp[nfs+i] ); + memset( data_cf[i], v_zero, width_cf * g_nchannels * 582 ); + } + n_cf = 0; + } + } + if ( n_sc > 0 ) { // flush scfs + for ( i = 0; i < nfs; i++ ) + fwrite( data_sc[i], 1, width_sc * g_nchannels * 38, fp[i] ); + n_sc = 0; + } + if ( n_cf > 0 ) { // flush coefs + for ( i = 0; i < nfc; i++ ) + fwrite( data_cf[i], 1, width_cf * g_nchannels * 582, fp[nfs+i] ); + n_cf = 0; + } + + + // close file pointers / dealloc memory + free( temp_cf ); + free( temp_sc ); + for ( i = 0; i < (nfs+nfc); i++ ) fclose( fp[i] ); + for ( i = 0; i < nfs; i++ ) free( data_sc[i] ); + for ( i = 0; i < nfc; i++ ) free( data_cf[i] ); + + + // delete decoder + delete( decoder ); + + + return true; +} + + +/* ----------------------------------------------- + dump main data size + ----------------------------------------------- */ +INTERN bool dump_main_sizes( void ) +{ + FILE* fp; + char* fn; + + + // create filename + fn = create_filename( filelist[ file_no ], "main_size.u2b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data & close file + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + fwrite( &(frame->main_size), 2, 1, fp ); + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump aux data size + ----------------------------------------------- */ +INTERN bool dump_aux_sizes( void ) +{ + FILE* fp; + char* fn; + + + // create filename + fn = create_filename( filelist[ file_no ], "aux_size.u2b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data & close file + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + fwrite( &(frame->aux_size), 2, 1, fp ); + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump bitrates + ----------------------------------------------- */ +INTERN bool dump_bitrates( void ) +{ + FILE* fp; + char* fn; + + + // only output for vbr files + if ( i_bitrate != -1 ) return true; + + // create filename + fn = create_filename( filelist[ file_no ], "bitrate.u1b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data & close file + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + fwrite( &(frame->bits), 1, 1, fp ); + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump stereo ms bit + ----------------------------------------------- */ +INTERN bool dump_stereo_ms( void ) +{ + FILE* fp; + char* fn; + + + // check if there is any ms stereo + if ( i_stereo_ms == 0 ) return true; + + // create filename + fn = create_filename( filelist[ file_no ], "stereo_ms.u1b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data & close file + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + fwrite( &(frame->stereo_ms), 1, 1, fp ); + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump padding bit + ----------------------------------------------- */ +INTERN bool dump_padding( void ) +{ + FILE* fp; + char* fn; + + + // check if there is any padding + if ( i_padding == 0 ) return true; + + // create filename + fn = create_filename( filelist[ file_no ], "padding.u1b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data & close file + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + fwrite( &(frame->padding), 1, 1, fp ); + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump main data bit counts + ----------------------------------------------- */ +INTERN bool dump_main_data_bits( void ) +{ + FILE* fp; + char* fn; + int ch, gr; + + + // create filename + fn = create_filename( filelist[ file_no ], "main_bits.u2b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + for ( gr = 0; gr < 2; gr++ ) + fwrite( &(frame->granules[ch][gr]->main_data_bit), 2, 1, fp ); + + } + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump big values + ----------------------------------------------- */ +INTERN bool dump_big_value_ns( void ) +{ + FILE* fp; + char* fn; + int ch, gr; + + + // create filename + fn = create_filename( filelist[ file_no ], "big_value_pairs.u2b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + for ( gr = 0; gr < 2; gr++ ) + fwrite( &(frame->granules[ch][gr]->big_val_pairs), 2, 1, fp ); + + } + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump global gains + ----------------------------------------------- */ +INTERN bool dump_global_gain( void ) +{ + FILE* fp; + char* fn; + int ch, gr; + + + // create filename + fn = create_filename( filelist[ file_no ], "global_gain.u1b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + for ( gr = 0; gr < 2; gr++ ) + fwrite( &(frame->granules[ch][gr]->global_gain), 1, 1, fp ); + + } + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump slength + ----------------------------------------------- */ +INTERN bool dump_slength( void ) +{ + FILE* fp; + char* fn; + int ch, gr; + + + // create filename + fn = create_filename( filelist[ file_no ], "slength.u1b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + for ( gr = 0; gr < 2; gr++ ) + fwrite( &(frame->granules[ch][gr]->slength), 1, 1, fp ); + + } + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump block types + ----------------------------------------------- */ +INTERN bool dump_block_types( void ) +{ + FILE* fp; + char* fn; + int ch, gr; + + + // create filename + fn = create_filename( filelist[ file_no ], "block_types.u1b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + for ( gr = 0; gr < 2; gr++ ) + fwrite( &(frame->granules[ch][gr]->block_type), 1, 1, fp ); + + } + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump sharing bits + ----------------------------------------------- */ +INTERN bool dump_sharing( void ) +{ + FILE* fp; + char* fn; + int ch; + int c; + + + // create filename + fn = create_filename( filelist[ file_no ], "sharing.u1b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) { + c = BITN( frame->granules[ch][0]->share, 3 ); fwrite( &c, 1, 1, fp ); + c = BITN( frame->granules[ch][0]->share, 2 ); fwrite( &c, 1, 1, fp ); + c = BITN( frame->granules[ch][0]->share, 1 ); fwrite( &c, 1, 1, fp ); + c = BITN( frame->granules[ch][0]->share, 0 ); fwrite( &c, 1, 1, fp ); + } + } + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump preemphasis setting + ----------------------------------------------- */ +INTERN bool dump_preemphasis( void ) +{ + FILE* fp; + char* fn; + int ch, gr; + + + // create filename + fn = create_filename( filelist[ file_no ], "preemphasis.u1b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + for ( gr = 0; gr < 2; gr++ ) + fwrite( &(frame->granules[ch][gr]->preemphasis), 1, 1, fp ); + + } + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump coarse setting + ----------------------------------------------- */ +INTERN bool dump_coarse( void ) +{ + FILE* fp; + char* fn; + int ch, gr; + + + // create filename + fn = create_filename( filelist[ file_no ], "coarse_scalefactors.u1b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + for ( gr = 0; gr < 2; gr++ ) + fwrite( &(frame->granules[ch][gr]->coarse_scalefactors), 1, 1, fp ); + + } + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump huffman table selections + ----------------------------------------------- */ +INTERN bool dump_htable_sel( void ) +{ + FILE* fp; + char* fn; + int ch, gr; + + + // create filename + fn = create_filename( filelist[ file_no ], "htable_selection.u1b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( int i = 0; i < 3; i++ ) { + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + for ( gr = 0; gr < 2; gr++ ) + fwrite( &(frame->granules[ch][gr]->region_table[i]), 1, 1, fp ); + } + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + for ( gr = 0; gr < 2; gr++ ) + fwrite( &(frame->granules[ch][gr]->select_htabB), 1, 1, fp ); + } + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump region sizes + ----------------------------------------------- */ +INTERN bool dump_region_sizes( void ) +{ + FILE* fp; + char* fn; + int ch, gr; + + + // create filename + fn = create_filename( filelist[ file_no ], "region_sizes.u1b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + for ( gr = 0; gr < 2; gr++ ) + fwrite( &(frame->granules[ch][gr]->region0_size), 1, 1, fp ); + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) + for ( gr = 0; gr < 2; gr++ ) + fwrite( &(frame->granules[ch][gr]->region1_size), 1, 1, fp ); + } + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump subblock gains + ----------------------------------------------- */ +INTERN bool dump_subblock_gains( void ) +{ + FILE* fp; + char* fn; + int ch, gr; + + + // check if there is any subblock gain + if ( i_sbgain == 0 ) return true; + + // create filename + fn = create_filename( filelist[ file_no ], "subblock_gain.u1b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data + for ( ch = 0; ch < g_nchannels; ch++ ) { + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) { + for ( gr = 0; gr < 2; gr++ ) if ( frame->granules[ch][gr]->block_type == SHORT_BLOCK ) { + fwrite( &(frame->granules[ch][gr]->sb_gain[0]), 1, 1, fp ); + fwrite( &(frame->granules[ch][gr]->sb_gain[1]), 1, 1, fp ); + fwrite( &(frame->granules[ch][gr]->sb_gain[2]), 1, 1, fp ); + } + } + } + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump data files + ----------------------------------------------- */ +INTERN bool dump_data_files( void ) +{ + FILE* fp_aux; + FILE* fp_huf; + char* fn; + + + // --- simple stuff --- + if ( main_data_size > 0 ) + if ( !write_file( filelist[ file_no ], "main_data.s1b", main_data, 1, main_data_size ) ) + return false; + if ( data_before_size > 0 ) + if ( !write_file( filelist[ file_no ], "data_before.s1b", data_before, 1, data_before_size ) ) + return false; + if ( data_after_size > 0 ) + if ( !write_file( filelist[ file_no ], "data_after.s1b", data_after, 1, data_after_size ) ) + return false; + + // --- huffman and aux data files --- + + // open huffman file + fn = create_filename( filelist[ file_no ], "huff_data.s1b" ); + fp_huf = fopen( fn, "wb" ); + free( fn ); + // open aux file + fn = create_filename( filelist[ file_no ], "aux_data.s1b" ); + fp_aux = fopen( fn, "wb" ); + free( fn ); + // check for problems + if ( ( fp_huf == NULL ) || ( fp_aux == NULL ) ) { + if ( fp_huf != NULL ) fclose( fp_huf ); + if ( fp_aux != NULL ) fclose( fp_aux ); + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + + // dump data + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) { + if ( frame->n < n_bad_first ) continue; + fwrite( main_data + frame->main_index, 1, frame->main_size, fp_huf ); + fwrite( main_data + frame->main_index + frame->main_size, 1, frame->aux_size, fp_aux ); + } + + // close files + fclose( fp_huf ); + fclose( fp_aux ); + + + return true; +} + + +/* ----------------------------------------------- + dump global gain context + ----------------------------------------------- */ +INTERN bool dump_gg_ctx( void ) +{ + FILE* fp; + char* fn; + + + // build the context (even if it is already built) + pmp_build_context(); + + + // create filename + fn = create_filename( filelist[ file_no ], "gg_ctx.u1b" ); + + // open file for output + fp = fopen( fn, "wb" ); + if ( fp == NULL ){ + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + free( fn ); + + // dump data + fwrite( gg_context[0], 1, 2 * g_nframes, fp ); + if ( g_nchannels == 2 ) + fwrite( gg_context[1], 1, 2 * g_nframes, fp ); + + // close file + fclose( fp ); + + + return true; +} + + +/* ----------------------------------------------- + dump coefficients + ----------------------------------------------- */ +INTERN bool dump_decoded_data( void ) +{ + static const unsigned char zeroes[32] = { 0 }; + FILE* fp_cf[2]; + FILE* fp_sc[2]; + const char* ext_cf[2] = { "coefs.ch0.s2b", "coefs.ch1.s2b" }; + const char* ext_sc[2] = { "scale.ch0.u1b", "scale.ch1.u1b" }; + char* fn; + int ch, gr; + + granuleData*** frame_data; + huffman_reader* decoder; + + + // open 4 files (max) + for ( ch = 0; ch < g_nchannels; ch++ ) { + // coeficients file + // create filename + fn = create_filename( filelist[ file_no ], ext_cf[ch] ); + // open file for output + fp_cf[ch] = fopen( fn, "wb" ); + free( fn ); + // scalefactors file + // create filename + fn = create_filename( filelist[ file_no ], ext_sc[ch] ); + // open file for output + fp_sc[ch] = fopen( fn, "wb" ); + free( fn ); + // error checking and file pointer rollback + if ( ( fp_cf[ch] == NULL ) || ( fp_sc[ch] == NULL ) ) { + for ( ; ch >= 0; ch-- ) { + if ( fp_cf[ch] != NULL ) fclose( fp_cf[ch] ); + if ( fp_sc[ch] != NULL ) fclose( fp_sc[ch] ); + } + sprintf( errormessage, FWR_ERRMSG ); + errorlevel = 2; + return false; + } + } + + // init decoder + decoder = new huffman_reader( main_data, main_data_size ); + + // dump data + for ( mp3Frame* frame = firstframe; frame != NULL; frame = frame->next ) { + // skip bad first frames + if ( frame->n < n_bad_first ) continue; + frame_data = mp3_decode_frame( decoder, frame ); + if ( frame_data == NULL ) continue; + for ( gr = 0; gr < 2; gr++ ) { + for ( ch = 0; ch < g_nchannels; ch++ ) { + fwrite( frame_data[ch][gr]->coefficients, sizeof( short ), 576, fp_cf[ch] ); + if ( frame->granules[ch][gr]->block_type != SHORT_BLOCK ) { + fwrite( frame_data[ch][gr]->scalefactors, sizeof( char ), 21, fp_sc[ch] ); + fwrite( zeroes, sizeof( char ), 11, fp_sc[ch] ); + } else fwrite( frame_data[ch][gr]->scalefactors, sizeof( char ), 32, fp_sc[ch] ); + } + } + } + + // close files + for ( ch = 0; ch < g_nchannels; ch++ ) { + fclose( fp_cf[ch] ); + fclose( fp_sc[ch] ); + } + + // delete decoder + delete( decoder ); + + + return true; +} +#endif + +/* ----------------------- End of developers functions -------------------------- */ + +/* ----------------------- End of file -------------------------- */ diff --git a/contrib/packmp3/packmp3lib.h b/contrib/packmp3/packmp3lib.h new file mode 100644 index 0000000..b4898f7 --- /dev/null +++ b/contrib/packmp3/packmp3lib.h @@ -0,0 +1,40 @@ +// packMP3lib.h - function declarations for the packMP3 library +#if defined BUILD_DLL + #define EXPORT __declspec( dllexport ) +#else + #define EXPORT extern +#endif + +/* ----------------------------------------------- + function declarations: library only functions + ----------------------------------------------- */ + +EXPORT bool pmplib_convert_stream2stream( char* msg ); +EXPORT bool pmplib_convert_file2file( char* in, char* out, char* msg ); +EXPORT bool pmplib_convert_stream2mem( unsigned char** out_file, unsigned int* out_size, char* msg ); +EXPORT void pmplib_init_streams( void* in_src, int in_type, int in_size, void* out_dest, int out_type ); +EXPORT const char* pmplib_version_info( void ); +EXPORT const char* pmplib_short_name( void ); + +/* a short reminder about input/output stream types + for the pmplib_init_streams() function + + if input is file + ---------------- + in_scr -> name of input file + in_type -> 0 + in_size -> ignore + + if input is memory + ------------------ + in_scr -> array containg data + in_type -> 1 + in_size -> size of data array + + if input is *FILE (f.e. stdin) + ------------------------------ + in_src -> stream pointer + in_type -> 2 + in_size -> ignore + + vice versa for output streams! */ diff --git a/contrib/packmp3/pmp3bitlen.h b/contrib/packmp3/pmp3bitlen.h new file mode 100644 index 0000000..6a0b6d7 --- /dev/null +++ b/contrib/packmp3/pmp3bitlen.h @@ -0,0 +1,806 @@ +/* ----------------------------------------------- + bitlength makro header file + ----------------------------------------------- */ + +#define BITLEN8192P(v) ( (pbitlen_p8192)[ ( v ) ] ) +#define BITMAX16(bl) ( (pbitmax_16)[ ( bl ) ] ) +#define BITLEN8224N(v) ( (pbitlen_n8224_8223+8224)[ ( v ) ] ) + + +/* ----------------------------------------------- + precalc max values for bit lengths 0...16 + ----------------------------------------------- */ +static const int pbitmax_16[] = +{ + 0, 1, 3, 7, + 15, 31, 63, 127, + 255, 511, 1023, 2047, + 4095, 8191, 16383, 32767 +}; + + +/* ----------------------------------------------- + precalc bit lengths for values 0...8192 + ----------------------------------------------- */ +static const unsigned char pbitlen_p8192[] = +{ + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 32 + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 64 + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 96 + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 128 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 160 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 192 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 224 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 256 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 288 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 320 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 352 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 384 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 416 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 448 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 480 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 512 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 544 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 576 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 608 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 640 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 672 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 704 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 736 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 768 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 800 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 832 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 864 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 896 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 928 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 960 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 992 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 1024 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1056 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1088 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1120 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1152 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1184 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1216 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1248 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1280 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1312 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1344 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1376 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1408 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1440 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1472 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1504 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1536 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1568 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1600 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1632 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1664 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1696 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1728 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1760 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1792 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1824 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1856 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1888 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1920 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1952 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1984 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 2016 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 2048 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2080 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2112 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2144 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2176 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2208 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2240 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2272 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2304 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2336 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2368 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2400 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2432 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2464 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2496 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2528 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2560 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2592 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2624 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2656 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2688 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2720 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2752 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2784 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2816 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2848 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2880 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2912 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2944 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2976 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3008 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3040 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3072 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3104 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3136 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3168 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3200 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3232 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3264 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3296 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3328 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3360 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3392 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3424 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3456 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3488 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3520 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3552 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3584 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3616 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3648 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3680 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3712 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3744 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3776 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3808 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3840 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3872 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3904 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3936 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3968 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 4000 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 4032 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 4064 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 4096 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4128 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4160 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4192 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4224 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4256 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4288 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4320 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4352 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4384 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4416 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4448 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4480 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4512 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4544 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4576 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4608 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4640 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4672 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4704 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4736 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4768 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4800 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4832 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4864 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4896 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4928 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4960 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4992 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5024 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5056 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5088 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5120 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5152 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5184 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5216 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5248 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5280 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5312 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5344 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5376 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5408 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5440 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5472 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5504 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5536 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5568 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5600 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5632 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5664 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5696 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5728 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5760 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5792 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5824 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5856 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5888 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5920 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5952 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5984 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6016 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6048 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6080 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6112 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6144 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6176 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6208 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6240 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6272 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6304 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6336 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6368 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6400 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6432 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6464 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6496 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6528 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6560 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6592 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6624 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6656 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6688 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6720 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6752 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6784 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6816 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6848 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6880 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6912 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6944 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6976 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7008 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7040 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7072 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7104 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7136 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7168 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7200 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7232 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7264 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7296 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7328 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7360 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7392 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7424 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7456 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7488 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7520 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7552 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7584 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7616 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7648 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7680 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7712 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7744 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7776 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7808 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7840 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7872 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7904 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7936 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7968 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8000 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8032 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8064 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8096 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8128 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8160 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8192 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14 // 8224 +}; + + +/* ----------------------------------------------- + precalc bit lengths for values -8206...8206 + ----------------------------------------------- */ +static const unsigned char pbitlen_n8224_8223[] = +{ + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // -8192 + 14,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -8160 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -8128 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -8096 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -8064 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -8032 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -8000 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7968 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7936 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7904 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7872 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7840 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7808 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7776 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7744 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7712 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7680 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7648 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7616 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7584 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7552 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7520 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7488 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7456 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7424 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7392 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7360 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7328 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7296 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7264 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7232 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7200 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7168 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7136 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7104 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7072 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7040 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -7008 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6976 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6944 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6912 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6880 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6848 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6816 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6784 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6752 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6720 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6688 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6656 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6624 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6592 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6560 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6528 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6496 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6464 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6432 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6400 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6368 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6336 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6304 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6272 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6240 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6208 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6176 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6144 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6112 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6080 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6048 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -6016 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5984 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5952 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5920 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5888 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5856 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5824 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5792 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5760 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5728 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5696 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5664 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5632 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5600 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5568 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5536 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5504 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5472 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5440 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5408 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5376 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5344 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5312 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5280 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5248 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5216 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5184 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5152 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5120 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5088 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5056 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -5024 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4992 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4960 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4928 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4896 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4864 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4832 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4800 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4768 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4736 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4704 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4672 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4640 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4608 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4576 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4544 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4512 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4480 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4448 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4416 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4384 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4352 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4320 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4288 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4256 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4224 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4192 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4160 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4128 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // -4096 + 13,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -4064 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -4032 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -4000 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3968 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3936 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3904 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3872 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3840 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3808 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3776 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3744 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3712 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3680 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3648 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3616 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3584 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3552 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3520 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3488 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3456 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3424 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3392 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3360 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3328 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3296 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3264 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3232 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3200 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3168 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3136 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3104 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3072 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3040 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -3008 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2976 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2944 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2912 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2880 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2848 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2816 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2784 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2752 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2720 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2688 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2656 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2624 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2592 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2560 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2528 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2496 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2464 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2432 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2400 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2368 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2336 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2304 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2272 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2240 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2208 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2176 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2144 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2112 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2080 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // -2048 + 12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -2016 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1984 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1952 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1920 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1888 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1856 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1824 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1792 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1760 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1728 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1696 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1664 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1632 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1600 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1568 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1536 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1504 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1472 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1440 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1408 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1376 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1344 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1312 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1280 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1248 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1216 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1184 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1152 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1120 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1088 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1056 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // -1024 + 11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -992 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -960 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -928 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -896 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -864 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -832 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -800 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -768 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -736 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -704 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -672 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -640 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -608 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -576 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -544 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // -512 + 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // -480 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // -448 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // -416 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // -384 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // -352 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // -320 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // -288 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // -256 + 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // -224 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // -192 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // -160 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // -128 + 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // -96 + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // -64 + 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // -32 + 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1, // 0 + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 32 + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 64 + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 96 + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 128 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 160 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 192 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 224 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 256 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 288 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 320 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 352 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 384 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 416 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 448 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 480 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 512 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 544 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 576 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 608 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 640 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 672 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 704 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 736 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 768 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 800 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 832 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 864 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 896 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 928 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 960 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 992 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 1024 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1056 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1088 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1120 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1152 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1184 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1216 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1248 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1280 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1312 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1344 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1376 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1408 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1440 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1472 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1504 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1536 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1568 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1600 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1632 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1664 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1696 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1728 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1760 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1792 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1824 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1856 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1888 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1920 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1952 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 1984 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 2016 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 2048 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2080 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2112 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2144 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2176 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2208 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2240 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2272 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2304 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2336 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2368 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2400 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2432 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2464 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2496 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2528 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2560 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2592 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2624 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2656 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2688 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2720 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2752 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2784 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2816 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2848 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2880 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2912 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2944 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 2976 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3008 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3040 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3072 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3104 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3136 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3168 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3200 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3232 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3264 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3296 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3328 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3360 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3392 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3424 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3456 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3488 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3520 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3552 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3584 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3616 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3648 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3680 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3712 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3744 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3776 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3808 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3840 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3872 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3904 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3936 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 3968 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 4000 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 4032 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 4064 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 4096 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4128 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4160 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4192 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4224 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4256 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4288 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4320 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4352 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4384 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4416 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4448 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4480 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4512 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4544 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4576 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4608 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4640 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4672 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4704 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4736 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4768 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4800 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4832 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4864 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4896 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4928 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4960 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 4992 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5024 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5056 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5088 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5120 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5152 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5184 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5216 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5248 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5280 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5312 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5344 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5376 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5408 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5440 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5472 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5504 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5536 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5568 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5600 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5632 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5664 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5696 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5728 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5760 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5792 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5824 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5856 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5888 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5920 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5952 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 5984 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6016 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6048 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6080 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6112 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6144 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6176 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6208 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6240 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6272 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6304 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6336 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6368 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6400 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6432 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6464 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6496 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6528 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6560 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6592 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6624 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6656 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6688 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6720 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6752 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6784 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6816 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6848 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6880 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6912 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6944 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 6976 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7008 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7040 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7072 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7104 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7136 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7168 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7200 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7232 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7264 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7296 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7328 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7360 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7392 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7424 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7456 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7488 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7520 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7552 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7584 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7616 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7648 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7680 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7712 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7744 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7776 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7808 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7840 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7872 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7904 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7936 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 7968 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8000 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8032 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8064 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8096 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8128 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8160 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 8192 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14 // 8224 +}; diff --git a/contrib/packmp3/pmp3tbl.h b/contrib/packmp3/pmp3tbl.h new file mode 100644 index 0000000..5033014 --- /dev/null +++ b/contrib/packmp3/pmp3tbl.h @@ -0,0 +1,842 @@ +/* ----------------------------------------------- + defines for use in packMP3 processing + ----------------------------------------------- */ + +// action defines +#define A_COMPRESS 1 +#define A_DUMP_SEPERATE 2 +#define A_FILE_ANALYSIS 3 +#define A_BLOCK_ANALYSIS 4 +#define A_STATS_ANALYSIS 5 +#define A_PGM_INFO 6 + +// mpeg audio type defines +#define MPEG2_5_LAYER_III 0x1 +#define MPEG2_5_LAYER_II 0x2 +#define MPEG2_5_LAYER_I 0x3 +#define MPEG2_LAYER_III 0x9 +#define MPEG2_LAYER_II 0xA +#define MPEG2_LAYER_I 0xB +#define MPEG1_LAYER_III 0xD +#define MPEG1_LAYER_II 0xE +#define MPEG1_LAYER_I 0xF + +// file type defines +#define F_MP3 1 +#define F_PMP 2 +#define F_UNK 3 + +// mpeg version defines +#define MP3_V2_5 0 +#define MP3_V2_0 2 +#define MP3_V1_0 3 + +// layer defines +#define LAYER_III 1 +#define LAYER_II 2 +#define LAYER_I 3 + +// channel mode defines +#define MP3_STEREO 0 +#define MP3_JOINT_STEREO 1 +#define MP3_DUAL_CHANNEL 2 +#define MP3_MONO 3 + +// block type definitions +#define LONG_BLOCK 0 +#define START_BLOCK 1 +#define SHORT_BLOCK 2 +#define STOP_BLOCK 3 + + +/* ----------------------------------------------- + structs for exchange of data + ----------------------------------------------- */ + +struct granuleInfo { + // # of current granule (can be calculated from frame->n) + int n; + // universal data + char share; + short main_data_bit; + short big_val_pairs; + short global_gain; + char slength; + char window_switching; + char preemphasis; + char coarse_scalefactors; + char select_htabB; + // info specific to normal blocks + char region_table[3]; + char region0_size; + char region1_size; + short region_bound[3]; + short sv_bound; + // info specific to special blocks + char block_type; + char mixed_flag; + char sb_gain[3]; + // links to next & previous granule + granuleInfo* next; + granuleInfo* prev; +}; + +struct mp3Frame { + // # of current frame + int n; + // information contained in header + char mpeg; + char layer; + char protection; + char bits; + char samples; + char padding; + char privbit; + char channels; + char stereo_ms; + char stereo_int; + char copyright; + char original; + char emphasis; + // information contained in side info + short bit_reservoir; + char padbits; + granuleInfo*** granules; + // additional info + int frame_size; + int fixed_size; + int main_size; + int aux_size; + int main_index; + int main_bits; + char nchannels; + // links to next & previous frame + mp3Frame* next; + mp3Frame* prev; +}; + +struct granuleData { + unsigned char* scalefactors; + signed short* coefficients; +}; + + +/* ----------------------------------------------- + some possible compression tweaks + ----------------------------------------------- */ + +// maximum runlength in padding encoding +#define PADDING_MAX_RUN 255 +// maximum runlength in block type encoding +#define SWITCHING_MAX_RUN 31 +// size of global gain context ( max 256 ) +#define GG_CONTEXT_SIZE 16 +// step size for aux data size +#define AUX_DATA_STEP 255 +// step size for stuffing bits +#define STUFFING_STEP 15 +// max allowed bad frames at file begin (max 255) +#define MAX_BAD_FIRST 255 +// store ID3 data instead of trying to compress (not recommended) +// #define STORE_ID3 + + +/* ----------------------------------------------- + generic tweaks + ----------------------------------------------- */ + +// maximum tolerance for garbage at begin and end +#define GARBAGE_TOLERANCE 64 * 1024 +// area (starting from file begin) to seek for first proper frame +#define FIRST_FRAME_AREA 1 * 1024 * 1024 +// name of the file analysis CSV file +#define FILE_ANALYSIS_CSV "zzz_file_analysis.csv" +// name of the stats analysis CSV file +#define STAT_ANALYSIS_CSV "zzz_stat_analysis.csv" + + +/* ----------------------------------------------- + samplerate table, indexed by MPEG and SAMPLE + ----------------------------------------------- */ +static const int samplerate_table[4][4] = +{ + {11025, 12000, 8000, -1}, // MPEG 2.5 + {0, 0, 0, -1}, // DUMMY + {22050, 24000, 16000, -1}, // MPEG 2.0 + {44100, 48000, 32000, -1} // MPEG 1.0 +}; +// shortcut for MPEG 1 LAYER III +static const int* mp3_samplerate_table = samplerate_table[MP3_V1_0]; + + +/* ----------------------------------------------- + bitrate table, indexed by MPEG, LAYER, BIT + ----------------------------------------------- */ +static const int bitrate_table[4][4][16] = +{ + { // MPEG 2.5 + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, // DUMMY + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, // LAYER III + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, // LAYER II + {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1} // LAYER I + }, + { // DUMMY + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, // DUMMY + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, // DUMMY + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, // DUMMY + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1} // DUMMY + }, + { // MPEG 2.0 + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, // DUMMY + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, // LAYER III + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, // LAYER II + {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1} // LAYER I + }, + { // MPEG 1.0 + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, // DUMMY + {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1}, // LAYER III + {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1}, // LAYER II + {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1} // LAYER I + } +}; +// shortcut for MPEG 1 LAYER III +static const int* mp3_bitrate_table = bitrate_table[MP3_V1_0][LAYER_III]; + + +/* ----------------------------------------------- + frame size table, indexed by MPEG, LAYER, SAMPLE, BITS + ----------------------------------------------- */ +static const int frame_size_table[4][4][4][16] = +{ + { // MPEG-2.5 + { // DUMMY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 11.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 12.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 8.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + }, + { // LAYER III + { 0, 104, 208, 313, 417, 522, 626, 731, 835, 1044, 1253, 1462, 1671, 1880, 2089, -1 }, // 11.0kHz + { 0, 96, 192, 288, 384, 480, 576, 672, 768, 960, 1152, 1344, 1536, 1728, 1920, -1 }, // 12.0kHz + { 0, 144, 288, 432, 576, 720, 864, 1008, 1152, 1440, 1728, 2016, 2304, 2592, 2880, -1 }, // 8.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + }, + { // LAYER II + { 0, 104, 208, 313, 417, 522, 626, 731, 835, 1044, 1253, 1462, 1671, 1880, 2089, -1 }, // 11.0kHz + { 0, 96, 192, 288, 384, 480, 576, 672, 768, 960, 1152, 1344, 1536, 1728, 1920, -1 }, // 12.0kHz + { 0, 144, 288, 432, 576, 720, 864, 1008, 1152, 1440, 1728, 2016, 2304, 2592, 2880, -1 }, // 8.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + }, + { // LAYER I + { 0, 139, 208, 243, 278, 348, 417, 487, 557, 626, 696, 766, 835, 975, 1114, -1 }, // 11.0kHz + { 0, 128, 192, 224, 256, 320, 384, 448, 512, 576, 640, 704, 768, 896, 1024, -1 }, // 12.0kHz + { 0, 192, 288, 336, 384, 480, 576, 672, 768, 864, 960, 1056, 1152, 1344, 1536, -1 }, // 8.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + } + }, + { // DUMMY + { // DUMMY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 0.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 0.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 0.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + }, + { // LAYER III + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 0.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 0.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 0.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + }, + { // LAYER II + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 0.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 0.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 0.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + }, + { // LAYER I + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 0.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 0.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 0.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + } + }, + { // MPEG-2 + { // DUMMY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 22.1kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 24.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 16.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + }, + { // LAYER III + { 0, 52, 104, 156, 208, 261, 313, 365, 417, 522, 626, 731, 835, 940, 1044, -1 }, // 22.1kHz + { 0, 48, 96, 144, 192, 240, 288, 336, 384, 480, 576, 672, 768, 864, 960, -1 }, // 24.0kHz + { 0, 72, 144, 216, 288, 360, 432, 504, 576, 720, 864, 1008, 1152, 1296, 1440, -1 }, // 16.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + }, + { // LAYER II + { 0, 52, 104, 156, 208, 261, 313, 365, 417, 522, 626, 731, 835, 940, 1044, -1 }, // 22.1kHz + { 0, 48, 96, 144, 192, 240, 288, 336, 384, 480, 576, 672, 768, 864, 960, -1 }, // 24.0kHz + { 0, 72, 144, 216, 288, 360, 432, 504, 576, 720, 864, 1008, 1152, 1296, 1440, -1 }, // 16.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + }, + { // LAYER I + { 0, 69, 104, 121, 139, 174, 208, 243, 278, 313, 348, 383, 417, 487, 557, -1 }, // 22.1kHz + { 0, 64, 96, 112, 128, 160, 192, 224, 256, 288, 320, 352, 384, 448, 512, -1 }, // 24.0kHz + { 0, 96, 144, 168, 192, 240, 288, 336, 384, 432, 480, 528, 576, 672, 768, -1 }, // 16.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + } + }, + { // MPEG-1 + { // DUMMY + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 44.1kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 48.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 }, // 32.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + }, + { // LAYER III + { 0, 104, 130, 156, 182, 208, 261, 313, 365, 417, 522, 626, 731, 835, 1044, -1 }, // 44.1kHz + { 0, 96, 120, 144, 168, 192, 240, 288, 336, 384, 480, 576, 672, 768, 960, -1 }, // 48.0kHz + { 0, 144, 180, 216, 252, 288, 360, 432, 504, 576, 720, 864, 1008, 1152, 1440, -1 }, // 32.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + }, + { // LAYER II + { 0, 104, 156, 182, 208, 261, 313, 365, 417, 522, 626, 731, 835, 1044, 1253, -1 }, // 44.1kHz + { 0, 96, 144, 168, 192, 240, 288, 336, 384, 480, 576, 672, 768, 960, 1152, -1 }, // 48.0kHz + { 0, 144, 216, 252, 288, 360, 432, 504, 576, 720, 864, 1008, 1152, 1440, 1728, -1 }, // 32.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + }, + { // LAYER I + { 0, 34, 69, 104, 139, 174, 208, 243, 278, 313, 348, 383, 417, 452, 487, -1 }, // 44.1kHz + { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1 }, // 48.0kHz + { 0, 48, 96, 144, 192, 240, 288, 336, 384, 432, 480, 528, 576, 624, 672, -1 }, // 32.0kHz + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1 } // 0.0kHz + } + } +}; +// shortcut for MPEG 1 LAYER III +static const int* mp3_frame_size_table[ 4 ] = +{ + frame_size_table[MP3_V1_0][LAYER_III][0], + frame_size_table[MP3_V1_0][LAYER_III][1], + frame_size_table[MP3_V1_0][LAYER_III][2], + frame_size_table[MP3_V1_0][LAYER_III][3] +}; + + +/* ----------------------------------------------- + slength lo/hi table, indexed by slength + ----------------------------------------------- */ +static const int slength_table[ 16 ][ 2 ] = +{ + { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 3, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }, + { 2, 1 }, { 2, 2 }, { 2, 3 }, { 3, 1 }, + { 3, 2 }, { 3, 3 }, { 4, 2 }, { 4, 3 } +}; +/*static const int slength_max_table[ 16 ][ 2 ] = +{ + { 0, 0 }, { 0, 1 }, { 0, 3 }, { 0, 7 }, + { 7, 0 }, { 1, 1 }, { 1, 3 }, { 1, 7 }, + { 3, 1 }, { 3, 3 }, { 3, 7 }, { 7, 1 }, + { 7, 3 }, { 7, 7 }, { 15, 3 }, { 15, 7 } +};*/ + + +/* ----------------------------------------------- + scalefactor group bounds + ----------------------------------------------- */ +static const int scf_bounds[ 4 ] = { 6, 11, 16, 21 }; +static const int scf_width[ 4 ] = { 6, 5, 5, 5 }; +static const int scf_bounds_short[ 4 ] = { 6, 11, 12 }; +static const int scf_width_short[ 4 ] = { 6, 5, 1 }; +static const int scf_lh_bounds[ 2 ] = { 11, 21 }; +static const int scf_lh_width[ 2 ] = { 11, 10 }; +static const int scf_lh_bounds_short[ 2 ] = { 6, 12 }; +static const int scf_lh_width_short[ 2 ] = { 6, 6 }; + + +/* ----------------------------------------------- + preemphasis table + ----------------------------------------------- */ +static const int preemphasis_table[ 21 ] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 }; + + +/* ----------------------------------------------- + layer 3 bandwith tables, indexed by MPEG and SAMPLE + ----------------------------------------------- */ +static const int bandwidth_table[4][4][22] = +{ + { // MPEG-2.5 + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 }, // 11.0kHz + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 }, // 12.0kHz + { 12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2 }, // 8.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + }, + { // DUMMY + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, // 0.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, // 0.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, // 0.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + }, + { // MPEG-2 + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 }, // 22.1kHz + { 6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36 }, // 24.0kHz + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 }, // 16.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + }, + { // MPEG-1 + { 4,4,4,4,4,4,6,6,8,8,10,12,16,20,24,28,34,42,50,54,76,158 }, // 44.1kHz + { 4,4,4,4,4,4,6,6,6,8,10,12,16,18,22,28,34,40,46,54,54,192 }, // 48.0kHz + { 4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102,26 }, // 32.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + } +}; +static const int bandwidth_table_short[4][4][13] = +{ + { // MPEG-2.5 + { 4,4,4,6,8,10,12,14,18,24,30,40,18 }, // 11.0kHz + { 4,4,4,6,8,10,12,14,18,24,30,40,18 }, // 12.0kHz + { 8,8,8,12,16,20,24,28,36,2,2,2,26 }, // 8.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + }, + { // DUMMY + { 0,0,0,0,0,0,0,0,0,0,0,0,0 }, // 0.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0 }, // 0.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0 }, // 0.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + }, + { // MPEG-2 + { 4,4,4,6,6,8,10,14,18,26,32,42,18 }, // 22.1kHz + { 4,4,4,6,8,10,12,14,18,24,32,44,12 }, // 24.0kHz + { 4,4,4,6,8,10,12,14,18,24,30,40,18 }, // 16.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + }, + { // MPEG-1 + { 4,4,4,4,6,8,10,12,14,18,22,30,56 }, // 44.1kHz + { 4,4,4,4,6,6,10,12,14,16,20,26,66 }, // 48.0kHz + { 4,4,4,4,6,8,12,16,20,26,34,42,12 }, // 32.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + } +}; +static const int bandwidth_bounds[4][4][22+1] = +{ + { // MPEG-2.5 + { 0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576 }, // 11.0kHz + { 0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576 }, // 12.0kHz + { 0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576 }, // 8.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + }, + { // DUMMY + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, // 0.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, // 0.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, // 0.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + }, + { // MPEG-2 + { 0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576 }, // 22.1kHz + { 0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,332,394,464,540,576 }, // 24.0kHz + { 0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576 }, // 16.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + }, + { // MPEG-1 + { 0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576 }, // 44.1kHz + { 0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576 }, // 48.0kHz + { 0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576 }, // 32.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + } +}; +static const int bandwidth_bounds_short[4][4][13+1] = +{ + { // MPEG-2.5 + { 0,4,8,12,18,26,36,48,62,80,104,134,174,192 }, // 11.0kHz + { 0,4,8,12,18,26,36,48,62,80,104,134,174,192 }, // 12.0kHz + { 0,8,16,24,36,52,72,96,124,160,162,164,166,192 }, // 8.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + }, + { // DUMMY + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, // 0.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, // 0.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, // 0.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + }, + { // MPEG-2 + { 0,4,8,12,18,24,32,42,56,74,100,132,174,192 }, // 22.1kHz + { 0,4,8,12,18,26,36,48,62,80,104,136,180,192 }, // 24.0kHz + { 0,4,8,12,18,26,36,48,62,80,104,134,174,192 }, // 16.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + }, + { // MPEG-1 + { 0,4,8,12,16,22,30,40,52,66,84,106,136,192 }, // 44.1kHz + { 0,4,8,12,16,22,28,38,50,64,80,100,126,192 }, // 48.0kHz + { 0,4,8,12,16,22,30,42,58,78,104,138,180,192 }, // 32.0kHz + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 } // 0.0kHz + } +}; + +// shortcuts for MPEG 1 LAYER III +/*static const int* mp3_bandwidth_table[4] = +{ + bandwidth_table[MP3_V1_0][0], + bandwidth_table[MP3_V1_0][1], + bandwidth_table[MP3_V1_0][2], + bandwidth_table[MP3_V1_0][3] +}; +static const int* mp3_bandwidth_table_short[4] = +{ + bandwidth_table_short[MP3_V1_0][0], + bandwidth_table_short[MP3_V1_0][1], + bandwidth_table_short[MP3_V1_0][2], + bandwidth_table_short[MP3_V1_0][3] +};*/ +static const int* mp3_bandwidth_bounds[4] = +{ + bandwidth_bounds[MP3_V1_0][0], + bandwidth_bounds[MP3_V1_0][1], + bandwidth_bounds[MP3_V1_0][2], + bandwidth_bounds[MP3_V1_0][3] +}; +static const int* mp3_bandwidth_bounds_short[4] = +{ + bandwidth_bounds_short[MP3_V1_0][0], + bandwidth_bounds_short[MP3_V1_0][1], + bandwidth_bounds_short[MP3_V1_0][2], + bandwidth_bounds_short[MP3_V1_0][3] +}; + + +/* ----------------------------------------------- + crc calculation table + ----------------------------------------------- */ +static const unsigned short crc_table[ 256 ] = +{ + 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011, + 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022, + 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072, + 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041, + 0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2, + 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1, + 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1, + 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082, + 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192, + 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1, + 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1, + 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2, + 0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151, + 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162, + 0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132, + 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101, + 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312, + 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321, + 0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371, + 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342, + 0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1, + 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2, + 0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2, + 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381, + 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291, + 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2, + 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2, + 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1, + 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252, + 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261, + 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231, + 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202 +}; + + +/* ----------------------------------------------- + position to band conversion + ----------------------------------------------- */ +static const int mp3_bandwidth_conv[3][576+1] = +{ // conversions for MPEG-1 AUDIO LAYER 3, valid samplerate only + { // 44.1kHz + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, // 32 + 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,11,11, // 64 + 11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13, // 96 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 128 + 14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 160 + 15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, // 192 + 16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, // 224 + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, // 256 + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, // 288 + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, // 320 + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20, // 352 + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, // 384 + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, // 416 + 20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, // 448 + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, // 480 + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, // 512 + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, // 544 + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, // 576 + 21 + }, + { // 48.0kHz + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, // 32 + 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,11,11,11,11, // 64 + 11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13, // 96 + 13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 128 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16, // 160 + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17, // 192 + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, // 224 + 17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, // 256 + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19, // 288 + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, // 320 + 19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, // 352 + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, // 384 + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, // 416 + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, // 448 + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, // 480 + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, // 512 + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, // 544 + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, // 576 + 21 + }, + { // 32.0kHz + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, // 32 + 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10, // 64 + 10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 96 + 12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14, // 128 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15, // 160 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 192 + 15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, // 224 + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, // 256 + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, // 288 + 17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, // 320 + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, // 352 + 18,18,18,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, // 384 + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, // 416 + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, // 448 + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, // 480 + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, // 512 + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, // 544 + 20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, // 576 + 21 + }, +}; + + +/* ----------------------------------------------- + bitrate prediction from main size + ----------------------------------------------- */ +static const int mp3_bitrate_pred[3][2049] = +{ // predictions for MPEG-1 AUDIO LAYER 3, valid samplerate only + { // 44.1kHz + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 31 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 63 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 95 + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 127 + 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, // 159 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 191 + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 223 + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 255 + 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 287 + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, // 319 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 351 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 383 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 415 + 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 447 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 479 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 511 + 10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 543 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 575 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 607 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 639 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 671 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 703 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13, // 735 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 767 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 799 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 831 + 13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 863 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 895 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 927 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 959 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 991 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 1023 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15, // 1055 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1087 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1119 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1151 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1183 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1215 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1247 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1279 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1311 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1343 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1375 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1407 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1439 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1471 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1503 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1535 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1567 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1599 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1631 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1663 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1695 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1727 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1759 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1791 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1823 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1855 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1887 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1919 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1951 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1983 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 2015 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 2047 + 15, + }, + { // 48.0kHz + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 31 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 63 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 95 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, // 127 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 159 + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 191 + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 223 + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 255 + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 287 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 319 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 351 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 383 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 415 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 447 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 479 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 511 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 543 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 575 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 607 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 639 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 671 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 703 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 735 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 767 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 799 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 831 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 863 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 895 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 927 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 959 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 991 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1023 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1055 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1087 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1119 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1151 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1183 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1215 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1247 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1279 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1311 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1343 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1375 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1407 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1439 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1471 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1503 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1535 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1567 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1599 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1631 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1663 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1695 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1727 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1759 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1791 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1823 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1855 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1887 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1919 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1951 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1983 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 2015 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 2047 + 15, + }, + { // 32.0kHz + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 31 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 63 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 95 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 127 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 159 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 191 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, // 223 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // 255 + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 287 + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 319 + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 351 + 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 383 + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 415 + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 447 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 479 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, // 511 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 543 + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 575 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 607 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 639 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 671 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 703 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 735 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 767 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 799 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 831 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, // 863 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 895 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 927 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 959 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // 991 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 1023 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 1055 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 1087 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 1119 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, // 1151 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 1183 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 1215 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 1247 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 1279 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 1311 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 1343 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 1375 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 1407 + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, // 1439 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1471 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1503 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1535 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1567 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1599 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1631 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1663 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1695 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1727 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1759 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1791 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1823 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1855 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1887 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1919 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1951 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 1983 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 2015 + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, // 2047 + 15, + } +}; + + +/* ----------------------------------------------- + description tables for packMP3 analysis + ----------------------------------------------- */ +#if defined(DEV_BUILD) +static const char* mpeg_description[4] = { "MPEG-2.5", NULL, "MPEG-2", "MPEG-1" }; +static const char* layer_description[4] = { NULL, "LAYER III", "LAYER II", "LAYER I" }; +static const char* channels_description[4] = { "STEREO", "JOINT STEREO", "DUAL CHANNEL", "MONO" }; +static const char* blocktype_description[4] = { "LONG", "START", "SHORT", "STOP" }; +#endif +static const char* filetype_description[16] = { + "not an MPEG audio file", "MPEG-2.5 LAYER III", "MPEG-2.5 LAYER II", "MPEG-2.5 LAYER I", + "not an MPEG audio file", "not an MPEG audio file", "not an MPEG audio file", "not an MPEG audio file", + "not an MPEG audio file", "MPEG-2 LAYER III", "MPEG-2 LAYER II", "MPEG-2 LAYER I", + "not an MPEG audio file", "MPEG-1 LAYER III", "MPEG-1 LAYER II", "MPEG-1 LAYER I" +}; From 53001ec909dd3676f3bd7450f8ed4f850802037e Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Fri, 15 Jan 2016 08:02:10 +0100 Subject: [PATCH 03/21] Windows make scripts adjusted for PackMP3 --- make.bat | 12 +++++++++++- makecomf.bat | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/make.bat b/make.bat index 785824b..43c0db9 100644 --- a/make.bat +++ b/make.bat @@ -5,6 +5,7 @@ set BZIP=contrib\bzip2\bzlib.c contrib\bzip2\blocksort.c contrib\bzip2\crctable. set ZLIB=contrib\zlib\adler32.c contrib\zlib\crc32.c contrib\zlib\zutil.c contrib\zlib\trees.c contrib\zlib\inftrees.c contrib\zlib\inffast.c contrib\zlib\inflate.c contrib\zlib\deflate.c set ZLIB_O=adler32.o crc32.o zutil.o trees.o inftrees.o inffast.o inflate.o deflate.o set JPG=aricoder.o bitops.o packjpg.o +SET MP3=packmp3.o huffmp3.o gcc -c -O2 -s -fomit-frame-pointer -march=pentiumpro -Wno-attributes %ZLIB% pushd contrib\packjpg g++ -c -O3 -DBUILD_LIB -Wall -pedantic -funroll-loops -ffast-math -fsched-spec-load -fomit-frame-pointer aricoder.cpp bitops.cpp packjpg.cpp @@ -15,7 +16,16 @@ move aricoder.o ..\..\ move bitops.o ..\..\ move packjpg.o ..\..\ popd -g++ -static -static-libgcc -static-libstdc++ -lpthread -Wall precomp.cpp %JPG% %GIF% %BZIP% %ZLIB_O% -O2 -march=pentiumpro -fomit-frame-pointer -s -oprecomp.exe +pushd contrib\packmp3 +copy ..\packjpg\aricoder.* +copy ..\packjpg\bitops.* +g++ -c -O3 -DBUILD_LIB -Wall -pedantic -funroll-loops -ffast-math -fsched-spec-load -fomit-frame-pointer aricoder.cpp bitops.cpp huffmp3.cpp packmp3.cpp +move huffmp3.o ..\..\ +move packmp3.o ..\..\ +if exist aricoder.* del aricoder.* +if exist bitops.* del bitops.* +popd +g++ -static -static-libgcc -static-libstdc++ -lpthread -Wall precomp.cpp %JPG% %MP3% %GIF% %BZIP% %ZLIB_O% -O2 -march=pentiumpro -fomit-frame-pointer -s -oprecomp.exe if not %ERRORLEVEL% == 0 echo ERROR!!! if %ERRORLEVEL% == 0 echo. if %ERRORLEVEL% == 0 echo Build successful. diff --git a/makecomf.bat b/makecomf.bat index 1082554..9d5dfcd 100644 --- a/makecomf.bat +++ b/makecomf.bat @@ -5,6 +5,7 @@ set BZIP=contrib\bzip2\bzlib.c contrib\bzip2\blocksort.c contrib\bzip2\crctable. set ZLIB=contrib\zlib\adler32.c contrib\zlib\crc32.c contrib\zlib\zutil.c contrib\zlib\trees.c contrib\zlib\inftrees.c contrib\zlib\inffast.c contrib\zlib\inflate.c contrib\zlib\deflate.c set ZLIB_O=adler32.o crc32.o zutil.o trees.o inftrees.o inffast.o inflate.o deflate.o set JPG=aricoder.o bitops.o packjpg.o +SET MP3=packmp3.o huffmp3.o gcc -c -O2 -s -fomit-frame-pointer -march=pentiumpro -Wno-attributes %ZLIB% pushd contrib\packjpg g++ -c -O3 -DBUILD_LIB -Wall -pedantic -funroll-loops -ffast-math -fsched-spec-load -fomit-frame-pointer aricoder.cpp bitops.cpp packjpg.cpp @@ -15,7 +16,16 @@ move aricoder.o ..\..\ move bitops.o ..\..\ move packjpg.o ..\..\ popd -g++ -static-libgcc -static-libstdc++ -DCOMFORT -Wall precomp.cpp %JPG% %GIF% %BZIP% %ZLIB_O% -O2 -march=pentiumpro -fomit-frame-pointer -s -oprecomf.exe +pushd contrib\packmp3 +copy ..\packjpg\aricoder.* +copy ..\packjpg\bitops.* +g++ -c -O3 -DBUILD_LIB -Wall -pedantic -funroll-loops -ffast-math -fsched-spec-load -fomit-frame-pointer aricoder.cpp bitops.cpp huffmp3.cpp packmp3.cpp +move huffmp3.o ..\..\ +move packmp3.o ..\..\ +if exist aricoder.* del aricoder.* +if exist bitops.* del bitops.* +popd +g++ -static-libgcc -static-libstdc++ -DCOMFORT -Wall precomp.cpp %JPG% %MP3% %GIF% %BZIP% %ZLIB_O% -O2 -march=pentiumpro -fomit-frame-pointer -s -oprecomf.exe if not %ERRORLEVEL% == 0 echo ERROR!!! if %ERRORLEVEL% == 0 echo. if %ERRORLEVEL% == 0 echo Build successful. From 15279ea72d2d48b12a7acf9dec86013af97abad9 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Fri, 15 Jan 2016 08:09:06 +0100 Subject: [PATCH 04/21] Adjusted readme files to packMP3 --- README.md | 3 ++- readme.txt | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6101995..07e26f0 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Thanks for support, help and comments: - Stephan Busch (Squeeze Chart Author, http://www.squeezechart.com) - Werner Bergmans (Maximum Compression Benchmark Author, http://www.maximumcompression.com) -- Matthias Stirner (PackJPG, http://www.elektronik.htw-aalen.de/packjpg/index.htm, http://www.matthiasstirner.com) +- Matthias Stirner (PackJPG, PackMP3, http://www.elektronik.htw-aalen.de/packjpg/index.htm, http://packjpg.encode.ru/?page_id=19, http://www.matthiasstirner.com) - Mark Adler (http://www.zlib.net) - Matt Mahoney (http://www.mattmahoney.net) - Malcolm Taylor (http://www.msoftware.co.nz) @@ -51,6 +51,7 @@ Thanks for support, help and comments: Legal stuff ----------- - PackJPG v2.5j (http://www.elektronik.htw-aalen.de/packjpg/index.htm) by Matthias Stirner is used for compression/decompression of JPG files. +- PackMP3 v1.0f by Matthias Stirner (http://packjpg.encode.ru/?page_id=19) by Matthias Stirner is used for compression/decompression of MP3 files. - bZip2 1.0.6 (http://www.bzip.org) by Julian Seward is used for compression/decompression of bZip2 streams. - zLib 1.2.8 (http://www.zlib.net) by Jean-loup Gailly and Mark Adler is used for compression/decompression of zLib streams. - GifLib 4.1.4 (http://sourceforge.net/projects/giflib) is used for compression/decompression of GIF files. The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond diff --git a/readme.txt b/readme.txt index a107d58..6e571c0 100644 --- a/readme.txt +++ b/readme.txt @@ -34,6 +34,9 @@ Check: "FlateDecode" appears in the file, but not paired with "ASCII85Decode". JPG Precomp uses packJPG by Matthias Stirner (http://www.elektronik.htw-aalen.de/packjpg/index.htm) to losslessy compress JPG images. +MP3 +Precomp uses packMP3 by Matthias Stirner (http://packjpg.encode.ru/?page_id=19) to losslessy compress MP3 audio files. + MJPEG MJPEG is a video format that consists of JPG images without huffman tables. Precomp inserts them so that packJPG is able to compress the images. @@ -215,7 +218,7 @@ http://schnaader.info Thanks for support, help and comments: Stephan Busch (Squeeze Chart Author, http://www.squeezechart.com)) Werner Bergmans (Maximum Compression Benchmark Author, http://www.maximumcompression.com) - Matthias Stirner (PackJPG, http://www.elektronik.htw-aalen.de/packjpg/index.htm, http://www.matthiasstirner.com) + Matthias Stirner (PackJPG, PackMP3, http://www.elektronik.htw-aalen.de/packjpg/index.htm, http://packjpg.encode.ru/?page_id=19, http://www.matthiasstirner.com) Mark Adler (http://www.zlib.net) Matt Mahoney (http://www.mattmahoney.net) Malcolm Taylor (http://www.msoftware.co.nz) @@ -225,6 +228,7 @@ Thanks for support, help and comments: 8. Legal stuff -------------- PackJPG v2.5j (http://www.elektronik.htw-aalen.de/packjpg/index.htm) by Matthias Stirner is used for compression/decompression of JPG files. +PackMP3 v1.0f by Matthias Stirner (http://packjpg.encode.ru/?page_id=19) by Matthias Stirner is used for compression/decompression of MP3 files. bZip2 1.0.6 (http://www.bzip.org) by Julian Seward is used for compression/decompression of bZip2 streams. zLib 1.2.8 (http://www.zlib.net) by Jean-loup Gailly and Mark Adler is used for compression/decompression of zLib streams. GifLib 4.1.4 (http://sourceforge.net/projects/giflib) is used for compression/decompression of GIF files. From cc0ca60b136ed2b3a663652c048a36eaa908d202 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Sat, 16 Jan 2016 14:12:17 +0100 Subject: [PATCH 05/21] Adjusted Visual Studio solution to PackMP3 Also modified bitops.cpp from PackJPG to compile using MSVC again --- contrib/packjpg/bitops.cpp | 5 ++++- vs2012/Precomp/Precomp.vcxproj | 8 +++++++- vs2012/Precomp/Precomp.vcxproj.filters | 24 +++++++++++++++++++++--- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/contrib/packjpg/bitops.cpp b/contrib/packjpg/bitops.cpp index 82c9c10..12e60ba 100644 --- a/contrib/packjpg/bitops.cpp +++ b/contrib/packjpg/bitops.cpp @@ -7,7 +7,10 @@ reading and writing of arrays #include #include #include "bitops.h" - +#ifdef _MSC_VER // Changed by schnaader to enable compilation by MSVC +#include +#define setmode _setmode +#endif #define BUFFER_SIZE 1024 * 1024 diff --git a/vs2012/Precomp/Precomp.vcxproj b/vs2012/Precomp/Precomp.vcxproj index cb7bc0d..6d4b6dd 100644 --- a/vs2012/Precomp/Precomp.vcxproj +++ b/vs2012/Precomp/Precomp.vcxproj @@ -90,6 +90,8 @@ + + @@ -109,8 +111,12 @@ - + + + + + diff --git a/vs2012/Precomp/Precomp.vcxproj.filters b/vs2012/Precomp/Precomp.vcxproj.filters index 5ff3a6e..bb98b8e 100644 --- a/vs2012/Precomp/Precomp.vcxproj.filters +++ b/vs2012/Precomp/Precomp.vcxproj.filters @@ -84,6 +84,12 @@ Quelldateien + + Quelldateien + + + Quelldateien + @@ -110,9 +116,6 @@ Headerdateien - - Headerdateien - Headerdateien @@ -146,5 +149,20 @@ Headerdateien + + Headerdateien + + + Headerdateien + + + Headerdateien + + + Headerdateien + + + Headerdateien + \ No newline at end of file From 5bd5b9429f0b7c9aee2f4a3b2160bedadb652aeb Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Sat, 16 Jan 2016 14:13:13 +0100 Subject: [PATCH 06/21] Modified PackMP3 files to use header files shared with PackJPG --- contrib/packmp3/huffmp3.cpp | 2 +- contrib/packmp3/packmp3.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/packmp3/huffmp3.cpp b/contrib/packmp3/huffmp3.cpp index 2e5facf..4f31bff 100644 --- a/contrib/packmp3/huffmp3.cpp +++ b/contrib/packmp3/huffmp3.cpp @@ -1,7 +1,7 @@ #include #include -#include "bitops.h" +#include "../packjpg/bitops.h" #include "huffmp3.h" // bit buffer size - careful changing this! diff --git a/contrib/packmp3/packmp3.cpp b/contrib/packmp3/packmp3.cpp index 2934f80..906a289 100644 --- a/contrib/packmp3/packmp3.cpp +++ b/contrib/packmp3/packmp3.cpp @@ -4,8 +4,8 @@ #include "pmp3tbl.h" #include "pmp3bitlen.h" -#include "bitops.h" -#include "aricoder.h" +#include "../packjpg/bitops.h" +#include "../packjpg/aricoder.h" #include "huffmp3.h" #include "huffmp3tbl.h" From 03f85c6a191fbd232747681c97b94c43b22800a1 Mon Sep 17 00:00:00 2001 From: schnaader Date: Sat, 16 Jan 2016 15:04:32 +0100 Subject: [PATCH 07/21] Adjusted Linux makefile to packMP3 --- Makefile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 8f16d3b..bf5f83f 100644 --- a/Makefile +++ b/Makefile @@ -1,25 +1,29 @@ PROGNAME = precomp CFLAGS = -DLINUX -D_FILE_OFFSET_BITS=64 -O2 -Wall SRC_PACKJPG = contrib/packjpg/aricoder.cpp contrib/packjpg/bitops.cpp contrib/packjpg/packjpg.cpp +SRC_PACKMP3 = contrib/packmp3/huffmp3.cpp contrib/packmp3/packmp3.cpp FLAGS_PACKJPG = -O3 -DUNIX -DBUILD_LIB -Wall -pedantic -funroll-loops -ffast-math -fsched-spec-load -fomit-frame-pointer OBJ_ZLIB = contrib/zlib/adler32.o contrib/zlib/crc32.o contrib/zlib/zutil.o contrib/zlib/trees.o contrib/zlib/inftrees.o contrib/zlib/inffast.o contrib/zlib/inflate.o contrib/zlib/deflate.o OBJ_BZIP2 = contrib/bzip2/bzlib.o contrib/bzip2/blocksort.o contrib/bzip2/crctable.o contrib/bzip2/compress.o contrib/bzip2/decompress.o contrib/bzip2/huffman.o contrib/bzip2/randtable.o OBJ_GIFLIB = contrib/giflib/gifalloc.o contrib/giflib/gif_err.o contrib/giflib/dgif_lib_gcc.o contrib/giflib/egif_lib_gcc.o -OBJECTS = aricoder.o bitops.o packjpg.o adler32.o crc32.o zutil.o trees.o inftrees.o inffast.o inflate.o deflate.o bzlib.o blocksort.o crctable.o compress.o decompress.o huffman.o randtable.o gifalloc.o gif_err.o dgif_lib_gcc.o egif_lib_gcc.o +OBJECTS = aricoder.o bitops.o packjpg.o huffmp3.o packmp3.o adler32.o crc32.o zutil.o trees.o inftrees.o inffast.o inflate.o deflate.o bzlib.o blocksort.o crctable.o compress.o decompress.o huffman.o randtable.o gifalloc.o gif_err.o dgif_lib_gcc.o egif_lib_gcc.o .PHONY: all -all: packjpg $(PROGNAME) +all: packjpg packmp3 $(PROGNAME) .PHONY: clean clean: rm -f *.o rm -f $(PROGNAME) -$(PROGNAME): $(OBJ_ZLIB) $(OBJ_BZIP2) $(OBJ_GIFLIB) $(OBJ_PACKJPG) +$(PROGNAME): $(OBJ_ZLIB) $(OBJ_BZIP2) $(OBJ_GIFLIB) g++ $(CFLAGS) $(OBJECTS) precomp.cpp -s -oprecomp packjpg: $(SRC_PACKJPG) g++ -c $(FLAGS_PACKJPG) $(SRC_PACKJPG) +packmp3: $(SRC_PACKMP3) + g++ -c $(FLAGS_PACKJPG) $(SRC_PACKMP3) + %.o: %.c gcc -g -c $(CFLAGS) $< From 6f5dbd26945a66db3de68bf3665ee9e03c2a3997 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Sun, 17 Jan 2016 16:34:42 +0100 Subject: [PATCH 08/21] PackMP3 version info - Display PackMP3 version info together with PackJPG version info - Changed URL to Matthias Stirner's homepage --- precomp.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/precomp.cpp b/precomp.cpp index ea5f25f..a9eb6f0 100644 --- a/precomp.cpp +++ b/precomp.cpp @@ -123,6 +123,12 @@ bool pjglib_convert_file2file( char* in, char* out, char* msg ); // DLL to a string const char* pjglib_version_info( void ); +//PackMP3 things + +// this function writes versioninfo for the packJPG +// DLL to a string +const char* pmplib_version_info( void ); + using namespace std; #include "contrib/zlib/zlib.h" @@ -196,7 +202,7 @@ unsigned char base64_char_decode(unsigned char c); void base64_reencode(FILE* file_in, FILE* file_out, int line_count, int max_in_count = 0x7FFFFFFF, int max_byte_count = 0x7FFFFFFF); void try_decompression_base64(int gzip_header_length); -void packjpg_dll_msg(); +void packjpg_mp3_dll_msg(); bool recompress_gif(FILE* srcfile, FILE* dstfile, unsigned char block_size, GifCodeStruct* g, GifDiffStruct* gd); bool decompress_gif(FILE* srcfile, FILE* dstfile, long long src_pos, int& gif_length, int& decomp_length, unsigned char& block_size, GifCodeStruct* g); void sort_comp_mem_levels(); @@ -1216,7 +1222,7 @@ int init(int argc, char* argv[]) { sort_comp_mem_levels(); - packjpg_dll_msg(); + packjpg_mp3_dll_msg(); return operation; } @@ -1914,7 +1920,7 @@ int init_comfort(int argc, char* argv[]) { sort_comp_mem_levels(); - packjpg_dll_msg(); + packjpg_mp3_dll_msg(); return operation; } @@ -7449,11 +7455,12 @@ void try_decompression_gif(unsigned char version[5]) { //JPEG routines -void packjpg_dll_msg() { +void packjpg_mp3_dll_msg() { - printf("Using PackJPG for JPG recompression.\n"); + printf("Using PackJPG for JPG recompression, PackMP3 for MP3 recompression.\n"); printf("%s\n", pjglib_version_info()); - printf("More about PackJPG here: http://www.elektronik.htw-aalen.de/packjpg\n\n"); + printf("%s\n", pmplib_version_info()); + printf("More about PackJPG and PackMP3 here: http://www.matthiasstirner.com\n\n"); } From 2026f1f49f82a6057f02f94e381c77414b907bb4 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Sun, 17 Jan 2016 16:49:34 +0100 Subject: [PATCH 09/21] MP3 parameter and internal preparation - Decompression/recompression count - Use flag - Show in help --- precomp.cpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/precomp.cpp b/precomp.cpp index a9eb6f0..41ee675 100644 --- a/precomp.cpp +++ b/precomp.cpp @@ -335,6 +335,7 @@ unsigned int recompressed_png_multi_count = 0; unsigned int recompressed_gif_count = 0; unsigned int recompressed_jpg_count = 0; unsigned int recompressed_jpg_prog_count = 0; +unsigned int recompressed_mp3_count = 0; unsigned int recompressed_swf_count = 0; unsigned int recompressed_base64_count = 0; unsigned int recompressed_bzip2_count = 0; @@ -352,6 +353,7 @@ unsigned int decompressed_png_multi_count = 0; unsigned int decompressed_gif_count = 0; unsigned int decompressed_jpg_count = 0; unsigned int decompressed_jpg_prog_count = 0; +unsigned int decompressed_mp3_count = 0; unsigned int decompressed_swf_count = 0; unsigned int decompressed_base64_count = 0; unsigned int decompressed_bzip2_count = 0; @@ -410,6 +412,7 @@ bool use_gzip = true; bool use_png = true; bool use_gif = true; bool use_jpg = true; +bool use_mp3 = true; bool use_swf = true; bool use_base64 = true; bool use_bzip2 = true; @@ -450,6 +453,7 @@ void setSwitches(Switches switches) { use_png = switches.use_png; use_gif = switches.use_gif; use_jpg = switches.use_jpg; + use_mp3 = switches.use_mp3; use_swf = switches.use_swf; use_base64 = switches.use_base64; use_bzip2 = switches.use_bzip2; @@ -856,6 +860,7 @@ int init(int argc, char* argv[]) { use_png = false; use_gif = false; use_jpg = false; + use_mp3 = false; use_swf = false; use_base64 = false; use_bzip2 = false; @@ -868,6 +873,7 @@ int init(int argc, char* argv[]) { use_png = true; use_gif = true; use_jpg = true; + use_mp3 = true; use_swf = true; use_base64 = true; use_bzip2 = true; @@ -898,6 +904,9 @@ int init(int argc, char* argv[]) { case 'J': //JPG use_jpg = set_to; break; + case '3': //MP3 + use_mp3 = set_to; + break; case 'S': //SWF use_swf = set_to; break; @@ -1124,10 +1133,10 @@ int init(int argc, char* argv[]) { if (long_help) { printf(" brute Brute force zLib detection. VERY Slow and most sensitive \n"); } - printf(" t[+-][pzgnfjsmb] Compression type switch \n"); + printf(" t[+-][pzgnfjsmb3] Compression type switch \n"); printf(" t+ = enable these types only, t- = enable all types except these\n"); printf(" P = PDF, Z = ZIP, G = GZip, N = PNG, F = GIF, J = JPG\n"); - printf(" S = SWF, M = MIME Base64, B = bZip2\n"); + printf(" S = SWF, M = MIME Base64, B = bZip2, 3 = MP3\n"); if (!long_help) { printf(" longhelp Show long help\n"); } else { @@ -1344,7 +1353,7 @@ int init_comfort(int argc, char* argv[]) { fprintf(fnewini,"Verbose=off\n\n"); fprintf(fnewini,";; Compression types to use\n"); fprintf(fnewini,";; P = PDF, Z = ZIP, G = GZip, N = PNG, F = GIF, J = JPG, S = SWF\n"); - fprintf(fnewini,";; M = MIME Base64, B = bZip2\n"); + fprintf(fnewini,";; M = MIME Base64, B = bZip2, 3 = MP3\n"); fprintf(fnewini,"; Compression_Types=PZGNFJSMB\n\n"); fprintf(fnewini,";; zLib levels to use\n"); fprintf(fnewini,"; zLib_Levels=\n"); @@ -1635,6 +1644,7 @@ int init_comfort(int argc, char* argv[]) { use_png = false; use_gif = false; use_jpg = false; + use_mp3 = false; use_swf = false; use_base64 = false; use_bzip2 = false; @@ -1659,6 +1669,9 @@ int init_comfort(int argc, char* argv[]) { case 'J': //JPG use_jpg = true; break; + case '3': //MP3 + use_mp3 = true; + break; case 'S': //SWF use_swf = true; break; @@ -1711,6 +1724,12 @@ int init_comfort(int argc, char* argv[]) { printf("INI: JPG compression disabled\n"); } + if (use_mp3) { + printf("INI: MP3 compression enabled\n"); + } else { + printf("INI: MP3 compression disabled\n"); + } + if (use_swf) { printf("INI: SWF compression enabled\n"); } else { @@ -1985,6 +2004,7 @@ void denit_compress() { if ((use_gif) && ((recompressed_gif_count > 0) || (decompressed_gif_count > 0))) printf("GIF streams: %i/%i\n", recompressed_gif_count, decompressed_gif_count); if ((use_jpg) && ((recompressed_jpg_count > 0) || (decompressed_jpg_count > 0))) printf("JPG streams: %i/%i\n", recompressed_jpg_count, decompressed_jpg_count); if ((use_jpg) && ((recompressed_jpg_prog_count > 0) || (decompressed_jpg_prog_count > 0))) printf("JPG streams (progressive): %i/%i\n", recompressed_jpg_prog_count, decompressed_jpg_prog_count); + if ((use_mp3) && ((recompressed_mp3_count > 0) || (decompressed_mp3_count > 0))) printf("MP3 streams: %i/%i\n", recompressed_mp3_count, decompressed_mp3_count); if ((use_swf) && ((recompressed_swf_count > 0) || (decompressed_swf_count > 0))) printf("SWF streams: %i/%i\n", recompressed_swf_count, decompressed_swf_count); if ((use_base64) && ((recompressed_base64_count > 0) || (decompressed_base64_count > 0))) printf("Base64 streams: %i/%i\n", recompressed_base64_count, decompressed_base64_count); if ((use_bzip2) && ((recompressed_bzip2_count > 0) || (decompressed_bzip2_count > 0))) printf("bZip2 streams: %i/%i\n", recompressed_bzip2_count, decompressed_bzip2_count); From c82be9375355f6d773d7583549afe86a39cc971d Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Wed, 20 Jan 2016 10:34:20 +0100 Subject: [PATCH 10/21] Ignore Visual Studio output directories --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 65a62c9..59c952b 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,8 @@ *.log *.tlog *.pdb -*.lastbuildstate \ No newline at end of file +*.lastbuildstate + +# Visual Studio output directories +vs2012/Precomp/Debug +vs2012/Precomp/Release \ No newline at end of file From 120b3a0585235959b2fb05665a2c0ec392062cb0 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Wed, 20 Jan 2016 10:58:23 +0100 Subject: [PATCH 11/21] Bugfix for PackJPG memory corruption - Double free in PackJPG's frealloc for the rare case of size == 0 - Fixes issue #17 --- contrib/packjpg/bitops.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/packjpg/bitops.cpp b/contrib/packjpg/bitops.cpp index 12e60ba..2696b6e 100644 --- a/contrib/packjpg/bitops.cpp +++ b/contrib/packjpg/bitops.cpp @@ -17,7 +17,8 @@ reading and writing of arrays // special realloc with guaranteed free() of previous memory static inline void* frealloc( void* ptr, size_t size ) { void* n_ptr = realloc( ptr, size ); - if ( n_ptr == NULL ) free( ptr ); + // changed by schnaader to fix a bug: if size == 0, realloc will free the memory and n_ptr == NULL, in this case don't call free + if (( n_ptr == NULL ) && (size != 0)) free( ptr ); return n_ptr; } From 0bc525232ab0daa2f8d44e5d26b8aefdc2a1f9c3 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Thu, 21 Jan 2016 15:39:31 +0100 Subject: [PATCH 12/21] Support for MP3 format - adds MP3 support using PackMP3 - closes issue #18 --- precomp.cpp | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 226 insertions(+), 1 deletion(-) diff --git a/precomp.cpp b/precomp.cpp index 41ee675..d7b404b 100644 --- a/precomp.cpp +++ b/precomp.cpp @@ -125,6 +125,11 @@ const char* pjglib_version_info( void ); //PackMP3 things +#include "contrib/packmp3/pmp3tbl.h" + +// function to convert MP3 to PMP and vice versa +bool pmplib_convert_file2file( char* in, char* out, char* msg ); + // this function writes versioninfo for the packJPG // DLL to a string const char* pmplib_version_info( void ); @@ -193,6 +198,7 @@ void try_decompression_png(int windowbits); void try_decompression_png_multi(int windowbits); void try_decompression_gif(unsigned char version[5]); void try_decompression_jpg(long long jpg_length, bool progressive_jpg); +void try_decompression_mp3(long long mp3_length); void try_decompression_zlib(int windowbits); void try_decompression_brute(); void try_decompression_swf(int windowbits, char swf_version); @@ -298,6 +304,7 @@ FILE* fdecomp = NULL; FILE* fpack = NULL; FILE* fpng = NULL; FILE* fjpg = NULL; +FILE* fmp3 = NULL; int retval; long long input_file_pos; @@ -4013,7 +4020,73 @@ bool compress_file(float min_percent, float max_percent) { } } - if ((!compressed_data_found) && (use_swf)) { // No JPG header -> SWF header? + if ((!compressed_data_found) && (use_mp3)) { // No JPG header -> MP3 header? + if ((in_buf[cb] == 0xFF) && ((in_buf[cb + 1] & 0xE0) == 0xE0)) { // frame start + int mpeg = -1; + int layer = -1; + int samples = -1; + int channels = -1; + int protection = -1; + + int bits; + int padding; + int frame_size; + int n = 0; + + long long mp3_length = 0; + + saved_input_file_pos = input_file_pos; + saved_cb = cb; + + long long act_pos = input_file_pos; + + // parse frames until first invalid frame is found or end-of-file + seek_64(fin, act_pos); + while (fread(in, 1, 3, fin) == 3) { + // check syncword + if ((in[0] != 0xFF) || ((in[1] & 0xE0) != 0xE0)) break; + // compare data from header + if (n == 0) { + mpeg = (in[1] >> 3) & 0x3; + layer = (in[1] >> 1) & 0x3; + protection = (in[1] >> 0) & 0x1; + samples = (in[2] >> 2) & 0x3; + channels = (in[3] >> 6) & 0x3; + } else if ( + (mpeg != ((in[1] >> 3) & 0x3)) || + (layer != ((in[1] >> 1) & 0x3)) || + (protection != ((in[1] >> 0) & 0x1)) || + (samples != ((in[2] >> 2) & 0x3)) || + (channels != ((in[3] >> 6) & 0x3))) break; + + bits = (in[2] >> 4) & 0xF; + padding = (in[2] >> 1) & 0x1; + // check for problems + if ((mpeg == 0x1) || (layer == 0x0) || + (bits == 0x0) || (bits == 0xF) || (samples == 0x3)) break; + // find out frame size + frame_size = frame_size_table[mpeg][layer][samples][bits]; + if (padding) frame_size += (layer == LAYER_I) ? 4 : 1; + + n++; + mp3_length += frame_size; + act_pos += frame_size; + seek_64(fin, act_pos); + } + + // conditions for proper first frame: 5 consecutive frames, + if (n >= 5) { + try_decompression_mp3(mp3_length); + } + + if (!compressed_data_found) { + input_file_pos = saved_input_file_pos; + cb = saved_cb; + } + } + } + + if ((!compressed_data_found) && (use_swf)) { // No MP3 header -> SWF header? // CWS = Compressed SWF file if ((in_buf[cb] == 'C') && (in_buf[cb + 1] == 'W') && (in_buf[cb + 2] == 'S')) { char swf_version = in_buf[cb + 3]; @@ -5341,8 +5414,60 @@ while (fin_pos < fin_length) { seek_64(fout, fsave_fout_pos); } + } else if (headertype == 10) { // Mp3 recompression + if (DEBUG_MODE) { + printf("Decompressed data - MP3\n"); + } + int recompressed_data_length; + recompressed_data_length = (fin_fgetc() << 24); + recompressed_data_length += (fin_fgetc() << 16); + recompressed_data_length += (fin_fgetc() << 8); + recompressed_data_length += fin_fgetc(); + + int decompressed_data_length; + decompressed_data_length = (fin_fgetc() << 24); + decompressed_data_length += (fin_fgetc() << 16); + decompressed_data_length += (fin_fgetc() << 8); + decompressed_data_length += fin_fgetc(); + + if (DEBUG_MODE) { + printf("Recompressed Length: %i - Decompressed length: %i\n", recompressed_data_length, decompressed_data_length); + } + + remove(tempfile1); + ftempout = tryOpen(tempfile1,"wb"); + + fast_copy(fin, ftempout, decompressed_data_length); + + safe_fclose(&ftempout); + + remove(tempfile2); + + bool recompress_success = false; + + { + char msg[256]; + recompress_success = pmplib_convert_file2file(tempfile1, tempfile2, msg); + if ((!recompress_success) && (DEBUG_MODE)) { + printf ("packMP3 error: %s\n", msg); + } + } + + if (!recompress_success) { + printf("Error recompressing data!"); + exit(1); + } + + frecomp = tryOpen(tempfile2,"rb"); + + fast_copy(frecomp, fout, recompressed_data_length); + + safe_fclose(&frecomp); + + remove(tempfile2); + remove(tempfile1); } else if (headertype == 254) { // brute mode recompression if (DEBUG_MODE) { @@ -7641,6 +7766,104 @@ void try_decompression_jpg (long long jpg_length, bool progressive_jpg) { } +void try_decompression_mp3 (long long mp3_length) { + + if (DEBUG_MODE) { + print_debug_percent(); + printf ("Possible MP3 found at position "); + print64(saved_input_file_pos); + printf (", length "); + print64(mp3_length); + printf ("\n"); + } + + bool mp3_success = false; + + // Try to decompress at current position + fmp3 = tryOpen(tempfile0,"wb"); + seek_64(fin, input_file_pos); + fast_copy(fin, fmp3, mp3_length); + safe_fclose(&fmp3); + remove(tempfile1); + + // Workaround for bugs, similar to packJPG. + FILE* fworkaround = tryOpen(tempfile1,"wb"); + safe_fclose(&fworkaround); + + bool recompress_success = false; + { + char msg[256]; + recompress_success = pmplib_convert_file2file(tempfile0, tempfile1, msg); + + decompressed_streams_count++; + decompressed_mp3_count++; + + if (!recompress_success) { + if (DEBUG_MODE) printf ("packMP3 error: %s\n", msg); + } + + remove(tempfile0); + } + + if (recompress_success) { + ftempout = tryOpen(tempfile1,"rb"); + fseek(ftempout, 0, SEEK_END); + int mp3_new_length = ftell(ftempout); + safe_fclose(&ftempout); + if (mp3_new_length > 0) { + recompressed_streams_count++; + recompressed_mp3_count++; + non_zlib_was_used = true; + + best_identical_bytes = mp3_length; + best_identical_bytes_decomp = mp3_new_length; + mp3_success = true; + } + } + + if (mp3_success) { + + if (DEBUG_MODE) { + printf("Best match: %i bytes, recompressed to %i bytes\n", best_identical_bytes, best_identical_bytes_decomp); + } + + //End uncompressed data + + compressed_data_found = true; + end_uncompressed_data(); + + //Write compressed data header (MP3) + + fout_fputc(1); //No penalty bytes + fout_fputc(10); //MP3 + + fout_fputc((best_identical_bytes >> 24) % 256); + fout_fputc((best_identical_bytes >> 16) % 256); + fout_fputc((best_identical_bytes >> 8) % 256); + fout_fputc(best_identical_bytes % 256); + + fout_fputc((best_identical_bytes_decomp >> 24) % 256); + fout_fputc((best_identical_bytes_decomp >> 16) % 256); + fout_fputc((best_identical_bytes_decomp >> 8) % 256); + fout_fputc(best_identical_bytes_decomp % 256); + + //Write compressed MP3 + write_decompressed_data(best_identical_bytes_decomp); + + //Start new uncompressed data + + //Set input file pointer after recompressed data + input_file_pos += best_identical_bytes - 1; + cb += best_identical_bytes - 1; + + } else { + if (DEBUG_MODE) { + printf("No matches\n"); + } + } + +} + void try_decompression_zlib(int windowbits) { identical_bytes = -1; best_identical_bytes = -1; @@ -8893,6 +9116,7 @@ void recursion_push() { recursion_stack_push(&fpack, sizeof(fpack)); recursion_stack_push(&fpng, sizeof(fpng)); recursion_stack_push(&fjpg, sizeof(fjpg)); + recursion_stack_push(&fmp3, sizeof(fmp3)); recursion_stack_push(&in_buf[0], sizeof(in_buf[0]) * IN_BUF_SIZE); recursion_stack_push(&metatempfile[0], sizeof(metatempfile[0]) * 18); recursion_stack_push(&tempfile0[0], sizeof(tempfile0[0]) * 19); @@ -8960,6 +9184,7 @@ void recursion_pop() { recursion_stack_pop(&tempfile0[0], sizeof(tempfile0[0]) * 19); recursion_stack_pop(&metatempfile[0], sizeof(metatempfile[0]) * 18); recursion_stack_pop(&in_buf[0], sizeof(in_buf[0]) * IN_BUF_SIZE); + recursion_stack_pop(&fmp3, sizeof(fmp3)); recursion_stack_pop(&fjpg, sizeof(fjpg)); recursion_stack_pop(&fpng, sizeof(fpng)); recursion_stack_pop(&fpack, sizeof(fpack)); From ff680417db4a3ff3cc9aefca9d9db8ae450254ed Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Fri, 22 Jan 2016 07:43:26 +0100 Subject: [PATCH 13/21] Only allow MPEG-1, Layer III as first frame This prevents passing the frames to packMP3 for each frame which slows down the process for non-MPEG-1, Layer III MP3s --- precomp.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/precomp.cpp b/precomp.cpp index d7b404b..ae448ab 100644 --- a/precomp.cpp +++ b/precomp.cpp @@ -125,6 +125,7 @@ const char* pjglib_version_info( void ); //PackMP3 things +#include "contrib/packjpg/bitops.h" // for MBITS #include "contrib/packmp3/pmp3tbl.h" // function to convert MP3 to PMP and vice versa @@ -4052,7 +4053,10 @@ bool compress_file(float min_percent, float max_percent) { protection = (in[1] >> 0) & 0x1; samples = (in[2] >> 2) & 0x3; channels = (in[3] >> 6) & 0x3; - } else if ( + // type must be MPEG-1, Layer III, packMP3 won't process any other files + int type = MBITS( in[1], 5, 1 ); + if ( type != MPEG1_LAYER_III ) break; + } else if ( (mpeg != ((in[1] >> 3) & 0x3)) || (layer != ((in[1] >> 1) & 0x3)) || (protection != ((in[1] >> 0) & 0x1)) || From d48f1a86ef06804f817f8d6314b3167cbfc0abc1 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Mon, 25 Jan 2016 15:03:31 +0100 Subject: [PATCH 14/21] Removed DEBUG_FILE flag Possibility of a debug output in a file was used in early versions of Precomp, not needed anymore. --- precomp.cpp | 138 +--------------------------------------------------- 1 file changed, 1 insertion(+), 137 deletions(-) diff --git a/precomp.cpp b/precomp.cpp index ae448ab..7cbfc60 100644 --- a/precomp.cpp +++ b/precomp.cpp @@ -24,7 +24,6 @@ #define V_STATE "DEVELOPMENT" //#define V_MSG "USE FOR TESTING ONLY" #define V_MSG "USE AT YOUR OWN RISK!" -//#define DEBUG_FILE // batch error levels #define RETURN_NOTHING_DECOMPRESSED 2 @@ -292,9 +291,6 @@ void denit_compress_otf(); void init_decompress_otf(); void denit_decompress_otf(); -#ifdef DEBUG_FILE -FILE* fdebug = NULL; -#endif FILE* fin = NULL; FILE* fout = NULL; FILE* ftempout = NULL; @@ -644,11 +640,6 @@ int init(int argc, char* argv[]) { int i, j; bool appended_pcf = false; - #ifdef DEBUG_FILE - remove("debug.txt"); - fdebug = fopen("debug.txt","wb"); - #endif - printf("\n"); if (V_MINOR2 == 0) { printf("Precomp v%i.%i - %s version",V_MAJOR,V_MINOR,V_STATE); @@ -1198,11 +1189,6 @@ int init(int argc, char* argv[]) { printf("Input file: %s\n",input_file_name); printf("Output file: %s\n\n",output_file_name); - #ifdef DEBUG_FILE - fprintf(fdebug,"Input file: %s\n",input_file_name); - fprintf(fdebug,"Output file: %s\n\n",output_file_name); - fflush(fdebug); - #endif if (DEBUG_MODE) { if (min_ident_size_set) { printf("\n"); @@ -1252,11 +1238,6 @@ int init_comfort(int argc, char* argv[]) { bool recursion_depth_set = false; bool level_switch = false; - #ifdef DEBUG_FILE - remove("debug.txt"); - fdebug = fopen("debug.txt","wb"); - #endif - printf("\n"); if (V_MINOR2 == 0) { printf("Precomp Comfort v%i.%i - %s version",V_MAJOR,V_MINOR,V_STATE); @@ -1909,11 +1890,6 @@ int init_comfort(int argc, char* argv[]) { printf("Input file: %s\n",input_file_name); printf("Output file: %s\n\n",output_file_name); - #ifdef DEBUG_FILE - fprintf(fdebug,"Input file: %s\n",input_file_name); - fprintf(fdebug,"Output file: %s\n\n",output_file_name); - fflush(fdebug); - #endif if (DEBUG_MODE) { if (min_ident_size_set) { printf("\n"); @@ -2119,10 +2095,6 @@ void denit_convert() { } void denit() { - #ifdef DEBUG_FILE - safe_fclose(&fdebug); - #endif - safe_fclose(&fin); safe_fclose(&fout); @@ -2862,16 +2834,10 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, safe_fclose(&ftempout); } - #ifdef DEBUG_FILE - fprintf(fdebug,"----\n"); - #endif for (int index = 0; index < 81; index++) { if (levels_sorted[index] == -1) break; int comp_level = (levels_sorted[index] % 9) + 1; int mem_level = (levels_sorted[index] / 9) + 1; - #ifdef DEBUG_FILE - fprintf(fdebug,"Trying comp_level %i, mem_level %i\n", comp_level, mem_level); - #endif try_recompress(fin, comp_level, mem_level, windowbits); @@ -2923,17 +2889,11 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, } anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } else { comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]++; zlib_level_was_used[(best_compression - 1) + (best_mem_level - 1) * 9] = true; anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } } @@ -3153,17 +3113,11 @@ void try_decompression_zip(int zip_header_length) { safe_fclose(&ftempout); } - #ifdef DEBUG_FILE - fprintf(fdebug,"----\n"); - #endif for (windowbits = -15; windowbits < -7; windowbits++) { for (int index = 0; index < 81; index++) { if (levels_sorted[index] == -1) break; int comp_level = (levels_sorted[index] % 9) + 1; int mem_level = (levels_sorted[index] / 9) + 1; - #ifdef DEBUG_FILE - fprintf(fdebug,"Trying comp_level %i, mem_level %i, windowbits %i\n", comp_level, mem_level, -windowbits); - #endif try_recompress(fin, comp_level, mem_level, windowbits); @@ -3192,17 +3146,11 @@ void try_decompression_zip(int zip_header_length) { } anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } else { comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]++; zlib_level_was_used[(best_compression - 1) + (best_mem_level - 1) * 9] = true; anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } } @@ -5822,10 +5770,6 @@ void try_recompress(FILE* origfile, int comp_level, int mem_level, int windowbit if (identical_bytes > best_identical_bytes) { - #ifdef DEBUG_FILE - fprintf(fdebug, "Identical recompressed bytes: %i\n", identical_bytes); - #endif - //if (identical_bytes > 4) { if (identical_bytes > min_ident_size) { @@ -5933,10 +5877,6 @@ void try_recompress_bzip2(FILE* origfile, int level) { if (identical_bytes > best_identical_bytes) { - #ifdef DEBUG_FILE - fprintf(fdebug, "Identical recompressed bytes: %i\n", identical_bytes); - #endif - //if (identical_bytes > 4) { if (identical_bytes > min_ident_size) { @@ -6478,17 +6418,11 @@ void try_decompression_gzip(int gzip_header_length) { safe_fclose(&ftempout); } - #ifdef DEBUG_FILE - fprintf(fdebug,"----\n"); - #endif for (windowbits = -15; windowbits < -7; windowbits++) { for (int index = 0; index < 81; index++) { if (levels_sorted[index] == -1) break; int comp_level = (levels_sorted[index] % 9) + 1; int mem_level = (levels_sorted[index] / 9) + 1; - #ifdef DEBUG_FILE - fprintf(fdebug,"Trying comp_level %i, mem_level %i, windowbits %i\n", comp_level, mem_level, -windowbits); - #endif try_recompress(fin, comp_level, mem_level, windowbits); @@ -6517,17 +6451,11 @@ void try_decompression_gzip(int gzip_header_length) { } anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } else { comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]++; zlib_level_was_used[(best_compression - 1) + (best_mem_level - 1) * 9] = true; anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } } @@ -6652,16 +6580,10 @@ void try_decompression_png (int windowbits) { safe_fclose(&ftempout); } - #ifdef DEBUG_FILE - fprintf(fdebug,"----\n"); - #endif for (int index = 0; index < 81; index++) { if (levels_sorted[index] == -1) break; int comp_level = (levels_sorted[index] % 9) + 1; int mem_level = (levels_sorted[index] / 9) + 1; - #ifdef DEBUG_FILE - fprintf(fdebug,"Trying comp_level %i, mem_level %i\n", comp_level, mem_level); - #endif try_recompress(fin, comp_level, mem_level, windowbits); @@ -6688,17 +6610,11 @@ void try_decompression_png (int windowbits) { } anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } else { comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]++; zlib_level_was_used[(best_compression - 1) + (best_mem_level - 1) * 9] = true; anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } } @@ -6799,16 +6715,10 @@ void try_decompression_png_multi(int windowbits) { safe_fclose(&ftempout); } - #ifdef DEBUG_FILE - fprintf(fdebug,"----\n"); - #endif for (int index = 0; index < 81; index++) { if (levels_sorted[index] == -1) break; int comp_level = (levels_sorted[index] % 9) + 1; int mem_level = (levels_sorted[index] / 9) + 1; - #ifdef DEBUG_FILE - fprintf(fdebug,"Trying comp_level %i, mem_level %i\n", comp_level, mem_level); - #endif try_recompress(fpng, comp_level, mem_level, windowbits); @@ -6835,17 +6745,11 @@ void try_decompression_png_multi(int windowbits) { } anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } else { comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]++; zlib_level_was_used[(best_compression - 1) + (best_mem_level - 1) * 9] = true; anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } } @@ -7911,16 +7815,10 @@ void try_decompression_zlib(int windowbits) { return; } - #ifdef DEBUG_FILE - fprintf(fdebug,"----\n"); - #endif for (int index = 0; index < 81; index++) { if (levels_sorted[index] == -1) break; int comp_level = (levels_sorted[index] % 9) + 1; int mem_level = (levels_sorted[index] / 9) + 1; - #ifdef DEBUG_FILE - fprintf(fdebug,"Trying comp_level %i, mem_level %i\n", comp_level, mem_level); - #endif try_recompress(fin, comp_level, mem_level, windowbits); @@ -7947,17 +7845,11 @@ void try_decompression_zlib(int windowbits) { } anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } else { comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]++; zlib_level_was_used[(best_compression - 1) + (best_mem_level - 1) * 9] = true; anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } } @@ -8094,17 +7986,11 @@ void try_decompression_brute() { return; } - #ifdef DEBUG_FILE - fprintf(fdebug,"----\n"); - #endif - for (windowbits = -15; windowbits < -7; windowbits++) { + for (windowbits = -15; windowbits < -7; windowbits++) { for (int index = 0; index < 81; index++) { if (levels_sorted[index] == -1) break; int comp_level = (levels_sorted[index] % 9) + 1; int mem_level = (levels_sorted[index] / 9) + 1; - #ifdef DEBUG_FILE - fprintf(fdebug,"Trying comp_level %i, mem_level %i, windowbits %i\n", comp_level, mem_level, -windowbits); - #endif try_recompress(fin, comp_level, mem_level, windowbits); @@ -8133,17 +8019,11 @@ void try_decompression_brute() { } anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } else { comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]++; zlib_level_was_used[(best_compression - 1) + (best_mem_level - 1) * 9] = true; anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } } @@ -8260,16 +8140,10 @@ void try_decompression_swf(int windowbits, char swf_version) { safe_fclose(&ftempout); } - #ifdef DEBUG_FILE - fprintf(fdebug,"----\n"); - #endif for (int index = 0; index < 81; index++) { if (levels_sorted[index] == -1) break; int comp_level = (levels_sorted[index] % 9) + 1; int mem_level = (levels_sorted[index] / 9) + 1; - #ifdef DEBUG_FILE - fprintf(fdebug,"Trying comp_level %i, mem_level %i\n", comp_level, mem_level); - #endif try_recompress(fin, comp_level, mem_level, windowbits); @@ -8296,17 +8170,11 @@ void try_decompression_swf(int windowbits, char swf_version) { } anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } else { comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]++; zlib_level_was_used[(best_compression - 1) + (best_mem_level - 1) * 9] = true; anything_was_used = true; sort_comp_mem_levels(); - #ifdef DEBUG_FILE - fprintf(fdebug,"Compression level %i, mem level %i has new count: %i\n", best_compression, best_mem_level, comp_mem_level_count[(best_compression - 1) + (best_mem_level - 1) * 9]); - #endif } } @@ -8435,10 +8303,6 @@ void try_decompression_bzip2(int compression_level) { safe_fclose(&ftempout); } - #ifdef DEBUG_FILE - fprintf(fdebug,"----\n"); - #endif - try_recompress_bzip2(fin, compression_level); if ((best_identical_bytes > min_ident_size) && (best_identical_bytes < identical_bytes_decomp)) { From ce52abaddff48f1d3fa89e1ca61769dffaa9875a Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Mon, 25 Jan 2016 15:15:50 +0100 Subject: [PATCH 15/21] Case of packJPG/packMP3 Always lower case --- README.md | 6 +++--- precomp.cpp | 8 ++++---- readme.txt | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 99dfe01..4f4e0b2 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Thanks for support, help and comments: - Stephan Busch (Squeeze Chart Author, http://www.squeezechart.com) - Werner Bergmans (Maximum Compression Benchmark Author, http://www.maximumcompression.com) -- Matthias Stirner (PackJPG, PackMP3, http://www.elektronik.htw-aalen.de/packjpg/index.htm, http://packjpg.encode.ru/?page_id=19, http://www.matthiasstirner.com) +- Matthias Stirner (packJPG, packMP3, http://www.elektronik.htw-aalen.de/packjpg/index.htm, http://packjpg.encode.ru/?page_id=19, http://www.matthiasstirner.com) - Mark Adler (http://www.zlib.net) - Matt Mahoney (http://www.mattmahoney.net) - Malcolm Taylor (http://www.msoftware.co.nz) @@ -50,8 +50,8 @@ Thanks for support, help and comments: Legal stuff ----------- -- PackJPG v2.5j (http://www.elektronik.htw-aalen.de/packjpg/index.htm) by Matthias Stirner is used for compression/decompression of JPG files. -- PackMP3 v1.0f by Matthias Stirner (http://packjpg.encode.ru/?page_id=19) by Matthias Stirner is used for compression/decompression of MP3 files. +- packJPG v2.5j (http://www.elektronik.htw-aalen.de/packjpg/index.htm) by Matthias Stirner is used for compression/decompression of JPG files. +- packMP3 v1.0f by Matthias Stirner (http://packjpg.encode.ru/?page_id=19) by Matthias Stirner is used for compression/decompression of MP3 files. - bZip2 1.0.6 (http://www.bzip.org) by Julian Seward is used for compression/decompression of bZip2 streams. - zLib 1.2.8 (http://www.zlib.net) by Jean-loup Gailly and Mark Adler is used for compression/decompression of zLib streams. - GifLib 4.1.4 (http://sourceforge.net/projects/giflib) is used for compression/decompression of GIF files. The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond diff --git a/precomp.cpp b/precomp.cpp index 7cbfc60..dbd0c01 100644 --- a/precomp.cpp +++ b/precomp.cpp @@ -79,7 +79,7 @@ extern "C" #include "contrib/giflib/gif_lib.h" } -//PackJPG things +// packJPG things // Motion JPEG DHT header // JPEG DHT Segment for YCrCb omitted from MJPEG data @@ -122,7 +122,7 @@ bool pjglib_convert_file2file( char* in, char* out, char* msg ); // DLL to a string const char* pjglib_version_info( void ); -//PackMP3 things +// packMP3 things #include "contrib/packjpg/bitops.h" // for MBITS #include "contrib/packmp3/pmp3tbl.h" @@ -7510,10 +7510,10 @@ void try_decompression_gif(unsigned char version[5]) { void packjpg_mp3_dll_msg() { - printf("Using PackJPG for JPG recompression, PackMP3 for MP3 recompression.\n"); + printf("Using packJPG for JPG recompression, packMP3 for MP3 recompression.\n"); printf("%s\n", pjglib_version_info()); printf("%s\n", pmplib_version_info()); - printf("More about PackJPG and PackMP3 here: http://www.matthiasstirner.com\n\n"); + printf("More about packJPG and packMP3 here: http://www.matthiasstirner.com\n\n"); } diff --git a/readme.txt b/readme.txt index 6e571c0..75f03e5 100644 --- a/readme.txt +++ b/readme.txt @@ -218,7 +218,7 @@ http://schnaader.info Thanks for support, help and comments: Stephan Busch (Squeeze Chart Author, http://www.squeezechart.com)) Werner Bergmans (Maximum Compression Benchmark Author, http://www.maximumcompression.com) - Matthias Stirner (PackJPG, PackMP3, http://www.elektronik.htw-aalen.de/packjpg/index.htm, http://packjpg.encode.ru/?page_id=19, http://www.matthiasstirner.com) + Matthias Stirner (packJPG, packMP3, http://www.elektronik.htw-aalen.de/packjpg/index.htm, http://packjpg.encode.ru/?page_id=19, http://www.matthiasstirner.com) Mark Adler (http://www.zlib.net) Matt Mahoney (http://www.mattmahoney.net) Malcolm Taylor (http://www.msoftware.co.nz) @@ -227,8 +227,8 @@ Thanks for support, help and comments: 8. Legal stuff -------------- -PackJPG v2.5j (http://www.elektronik.htw-aalen.de/packjpg/index.htm) by Matthias Stirner is used for compression/decompression of JPG files. -PackMP3 v1.0f by Matthias Stirner (http://packjpg.encode.ru/?page_id=19) by Matthias Stirner is used for compression/decompression of MP3 files. +packJPG v2.5j (http://www.elektronik.htw-aalen.de/packjpg/index.htm) by Matthias Stirner is used for compression/decompression of JPG files. +packMP3 v1.0f by Matthias Stirner (http://packjpg.encode.ru/?page_id=19) by Matthias Stirner is used for compression/decompression of MP3 files. bZip2 1.0.6 (http://www.bzip.org) by Julian Seward is used for compression/decompression of bZip2 streams. zLib 1.2.8 (http://www.zlib.net) by Jean-loup Gailly and Mark Adler is used for compression/decompression of zLib streams. GifLib 4.1.4 (http://sourceforge.net/projects/giflib) is used for compression/decompression of GIF files. From a21bf5dfdcd440ccbcb986bbdbd6fbd558b7b9e9 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Tue, 26 Jan 2016 12:35:25 +0100 Subject: [PATCH 16/21] Comments - Consistent comment case (lower case at the beginning) - Some comments removed - Some old commented code removed --- precomp.cpp | 908 ++++++++++++++++++++++------------------------------ 1 file changed, 379 insertions(+), 529 deletions(-) diff --git a/precomp.cpp b/precomp.cpp index dbd0c01..27e3d8f 100644 --- a/precomp.cpp +++ b/precomp.cpp @@ -16,7 +16,7 @@ #define DLL __declspec(dllexport) #endif -//Version information +// version information #define V_MAJOR 0 #define V_MINOR 4 #define V_MINOR2 5 @@ -69,7 +69,7 @@ #include "contrib/bzip2/bzlib.h" -//GIF things +// GIF things const short InterlacedOffset[] = { 0, 4, 2, 1 }; /* The way Interlaced image should. */ const short InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ @@ -138,8 +138,8 @@ using namespace std; #include "contrib/zlib/zlib.h" -#define CHUNK 262144 //256 KB buffersize -#define DIV3CHUNK 262143 //DIV3CHUNK is a bit smaller/larger than CHUNK, so that DIV3CHUNK mod 3 = 0 +#define CHUNK 262144 // 256 KB buffersize +#define DIV3CHUNK 262143 // DIV3CHUNK is a bit smaller/larger than CHUNK, so that DIV3CHUNK mod 3 = 0 #define CHECKBUF_SIZE 4096 #define COPY_BUF_SIZE 512 #define FAST_COPY_WORK_SIGN_DIST 64 // update work sign after (FAST_COPY_WORK_SIGN_DIST * COPY_BUF_SIZE) bytes @@ -150,12 +150,12 @@ unsigned char copybuf[COPY_BUF_SIZE]; unsigned char in_buf[IN_BUF_SIZE]; long long in_buf_pos; -int cb; //"checkbuf" +int cb; // "checkbuf" unsigned char in[CHUNK]; unsigned char out[CHUNK]; -// Name of temporary files +// name of temporary files char metatempfile[18] = "~temp00000000.dat"; char tempfile0[19] = "~temp000000000.dat"; char tempfile1[19] = "~temp000000001.dat"; @@ -250,7 +250,7 @@ static char work_signs[5] = "|/-\\"; int work_sign_var = 0; long long work_sign_start_time = get_time_ms(); -// Recursion +// recursion int recursion_stack_size = 0; int recursion_depth = 0; int max_recursion_depth = 10; @@ -275,12 +275,12 @@ struct recursion_result { recursion_result recursion_compress(int compressed_bytes, int decompressed_bytes); recursion_result recursion_decompress(long long recursion_data_length); -// Compression-on-the-fly +// compression-on-the-fly unsigned char bz2_in[CHUNK]; unsigned char bz2_out[CHUNK]; -int compression_otf_method = 1; //0 = uncompressed, 1 = bZip2 -int conversion_from_method; //0 = uncompressed, 1 = bZip2 -int conversion_to_method; //0 = uncompressed, 1 = bZip2 +int compression_otf_method = 1; // 0 = uncompressed, 1 = bZip2 +int conversion_from_method; // 0 = uncompressed, 1 = bZip2 +int conversion_to_method; // 0 = uncompressed, 1 = bZip2 bool decompress_otf_end = false; bz_stream otf_bz2_stream_c, otf_bz2_stream_d; void own_fputc(char c, FILE* f); @@ -327,7 +327,7 @@ bool anything_was_used; bool level_switch_used = false; bool non_zlib_was_used; -//Statistics +// statistics unsigned int recompressed_streams_count = 0; unsigned int recompressed_pdf_count = 0; unsigned int recompressed_pdf_count_8_bit = 0; @@ -343,8 +343,8 @@ unsigned int recompressed_mp3_count = 0; unsigned int recompressed_swf_count = 0; unsigned int recompressed_base64_count = 0; unsigned int recompressed_bzip2_count = 0; -unsigned int recompressed_zlib_count = 0; //Intense mode -unsigned int recompressed_brute_count = 0; //Brute mode +unsigned int recompressed_zlib_count = 0; // intense mode +unsigned int recompressed_brute_count = 0; // brute mode unsigned int decompressed_streams_count = 0; unsigned int decompressed_pdf_count = 0; @@ -361,8 +361,8 @@ unsigned int decompressed_mp3_count = 0; unsigned int decompressed_swf_count = 0; unsigned int decompressed_base64_count = 0; unsigned int decompressed_bzip2_count = 0; -unsigned int decompressed_zlib_count = 0; //Intense mode -unsigned int decompressed_brute_count = 0; //Brute mode +unsigned int decompressed_zlib_count = 0; // intense mode +unsigned int decompressed_brute_count = 0; // brute mode #define P_NONE 0 #define P_COMPRESS 1 @@ -370,7 +370,7 @@ unsigned int decompressed_brute_count = 0; //Brute mode #define P_CONVERT 3 int comp_decomp_state = P_NONE; -//Penalty bytes +// penalty bytes #define MAX_PENALTY_BYTES 16384 long long compare_files_penalty(FILE* file1, FILE* file2, long long pos1, long long pos2); #ifndef PRECOMPDLL @@ -384,7 +384,7 @@ char* best_penalty_bytes; #endif int penalty_bytes_len = 0; -long long* ignore_list = NULL; //Positions to ignore +long long* ignore_list = NULL; // positions to ignore int ignore_list_len = 0; // Base64 line length list @@ -409,7 +409,7 @@ bool use_mjpeg = true; int slow_mode_depth_limit = -1; int brute_mode_depth_limit = -1; -//Compression type bools +// compression type bools bool use_pdf = true; bool use_zip = true; bool use_gzip = true; @@ -421,7 +421,7 @@ bool use_swf = true; bool use_base64 = true; bool use_bzip2 = true; -//Precomp DLL things +// Precomp DLL things #ifdef PRECOMPDLL #include "precomp.h" @@ -430,7 +430,7 @@ DLL void get_copyright_msg(char* msg); DLL bool precompress_file(char* in_file, char* out_file, char* msg, Switches switches); DLL bool recompress_file(char* in_file, char* out_file, char* msg, Switches switches); -//Get copyright message +// get copyright message // msg = Buffer for error messages (256 bytes buffer size are enough) DLL void get_copyright_msg(char* msg) { if (V_MINOR2 == 0) { @@ -477,13 +477,13 @@ void setSwitches(Switches switches) { } } -//Precompress a file +// precompress a file // in_file = input filename // out_file = output filename // msg = Buffer for error messages (256 bytes buffer size are enough) DLL bool precompress_file(char* in_file, char* out_file, char* msg, Switches switches) { - //Init compression and memory level count + // init compression and memory level count for (int i = 0; i < 81; i++) { comp_mem_level_count[i] = 0; zlib_level_was_used[i] = false; @@ -497,9 +497,6 @@ DLL bool precompress_file(char* in_file, char* out_file, char* msg, Switches swi return false; } - //fseek(fin, 0, SEEK_END); - //fin_length = ftell(fin); - //fseek(fin, 0, SEEK_SET); fout = fopen(out_file, "wb"); @@ -529,13 +526,13 @@ DLL bool precompress_file(char* in_file, char* out_file, char* msg, Switches swi return true; } -//Recompress a file +// recompress a file // in_file = input filename // out_file = output filename // msg = Buffer for error messages (256 bytes buffer size are enough) DLL bool recompress_file(char* in_file, char* out_file, char* msg, Switches switches) { - //Init compression and memory level count + // init compression and memory level count for (int i = 0; i < 81; i++) { comp_mem_level_count[i] = 0; zlib_level_was_used[i] = false; @@ -549,9 +546,6 @@ DLL bool recompress_file(char* in_file, char* out_file, char* msg, Switches swit return false; } - //fseek(fin, 0, SEEK_END); - //fin_length = ftell(fin); - //fseek(fin, 0, SEEK_SET); fout = fopen(out_file, "wb"); if (fout == NULL) { @@ -580,7 +574,7 @@ DLL bool recompress_file(char* in_file, char* out_file, char* msg, Switches swit return true; } -//Test if a file contains streams that can be precompressed +// test if a file contains streams that can be precompressed DLL bool file_precompressable(char* in, char* msg) { return false; } @@ -591,7 +585,7 @@ int main(int argc, char* argv[]) { int return_errorlevel = 0; - // Register CTRL-C handler + // register CTRL-C handler (void) signal(SIGINT, ctrl_c_handler); #ifndef COMFORT @@ -603,7 +597,7 @@ int main(int argc, char* argv[]) case P_COMPRESS: { start_time = get_time_ms(); - if (!compress_file()) { // None of the streams could be decompressed + if (!compress_file()) { // none of the streams could be decompressed return_errorlevel = RETURN_NOTHING_DECOMPRESSED; } break; @@ -625,7 +619,6 @@ int main(int argc, char* argv[]) } #ifdef COMFORT - //Wait for key wait_for_key(); #endif @@ -649,7 +642,7 @@ int init(int argc, char* argv[]) { printf(" - %s\n",V_MSG); printf("Free for non-commercial use - Copyright 2006-2016 by Christian Schneider\n\n"); - //Init compression and memory level count + // init compression and memory level count bool use_zlib_level[81]; for (i = 0; i < 81; i++) { comp_mem_level_count[i] = 0; @@ -668,7 +661,7 @@ int init(int argc, char* argv[]) { bool long_help = false; for (i = 1; (i < argc) && (parse_on); i++) { - if (argv[i][0] == '-') { //switch + if (argv[i][0] == '-') { // switch if (input_file_given) { valid_syntax = false; parse_on = false; @@ -683,7 +676,7 @@ int init(int argc, char* argv[]) { } case 'I': { - if (toupper(argv[i][2]) == 'N') { //intense mode + if (toupper(argv[i][2]) == 'N') { // intense mode if ((toupper(argv[i][3]) == 'T') && (toupper(argv[i][4]) == 'E') && (toupper(argv[i][5]) == 'N') && (toupper(argv[i][6]) == 'S') && (toupper(argv[i][7]) == 'E')) { slow_mode = true; @@ -885,34 +878,34 @@ int init(int argc, char* argv[]) { } for (j = 3; j < (int)strlen(argv[i]); j++) { switch (toupper(argv[i][j])) { - case 'P': //PDF + case 'P': // PDF use_pdf = set_to; break; - case 'Z': //ZIP + case 'Z': // ZIP use_zip = set_to; break; - case 'G': //GZip + case 'G': // GZip use_gzip = set_to; break; - case 'N': //PNG + case 'N': // PNG use_png = set_to; break; - case 'F': //GIF + case 'F': // GIF use_gif = set_to; break; - case 'J': //JPG + case 'J': // JPG use_jpg = set_to; break; - case '3': //MP3 + case '3': // MP3 use_mp3 = set_to; break; - case 'S': //SWF + case 'S': // SWF use_swf = set_to; break; - case 'M': //MIME Base64 + case 'M': // MIME Base64 use_base64 = set_to; break; - case 'B': //bZip2 + case 'B': // bZip2 use_bzip2 = set_to; break; default: @@ -926,7 +919,7 @@ int init(int argc, char* argv[]) { case 'C': { switch (toupper(argv[i][2])) { - case 'N': // No compression + case 'N': // no compression compression_otf_method = 0; break; case 'B': // bZip2 @@ -942,7 +935,7 @@ int init(int argc, char* argv[]) { case 'N': { switch (toupper(argv[i][2])) { - case 'N': // No compression + case 'N': // no compression conversion_to_method = 0; break; case 'B': // bZip2 @@ -1016,10 +1009,10 @@ int init(int argc, char* argv[]) { output_file_name = new char[strlen(argv[i]) + 5]; strcpy(output_file_name, argv[i] + 2); - //Check for backslash in file name + // check for backslash in file name char* backslash_at_pos = strrchr(output_file_name, PATH_DELIM); - //Dot in output file name? If not, use .pcf extension + // dot in output file name? If not, use .pcf extension char* dot_at_pos = strrchr(output_file_name, '.'); if ((dot_at_pos == NULL) || ((backslash_at_pos != NULL) && (backslash_at_pos > dot_at_pos))) { strcpy(output_file_name + strlen(argv[i]) - 2, ".pcf"); @@ -1068,7 +1061,7 @@ int init(int argc, char* argv[]) { exit(1); } } - } else { //no switch + } else { // no switch if (input_file_given) { error(ERR_MORE_THAN_ONE_INPUT_FILE); } @@ -1084,11 +1077,8 @@ int init(int argc, char* argv[]) { exit(1); } - //fseek(fin, 0, SEEK_END); - //fin_length = ftell(fin); - //fseek(fin, 0, SEEK_SET); - //Output file given? If not, use input filename with .pcf extension + // output file given? If not, use input filename with .pcf extension if ((!output_file_given) && (operation == P_COMPRESS)) { output_file_name = new char[strlen(input_file_name) + 9]; strcpy(output_file_name, input_file_name); @@ -1098,7 +1088,7 @@ int init(int argc, char* argv[]) { strcpy(output_file_name + strlen(input_file_name), ".pcf"); } else { strcpy(dot_at_pos, ".pcf"); - //Same as output file because input file had .pcf extension? + // same as output file because input file had .pcf extension? if (strcmp(input_file_name, output_file_name) == 0) { strcpy(dot_at_pos, "_pcf.pcf"); } @@ -1160,7 +1150,7 @@ int init(int argc, char* argv[]) { } if (operation == P_DECOMPRESS) { - //If .pcf was appended, remove it + // if .pcf was appended, remove it if (appended_pcf) { output_file_name[strlen(output_file_name)-4] = 0; } @@ -1198,7 +1188,6 @@ int init(int argc, char* argv[]) { printf("\n"); printf("Ignore position list:\n"); for (j = 0; j < ignore_list_len; j++) { - //printf("%u\n",ignore_list[j]); print64(ignore_list[j]); printf("\n"); } @@ -1247,7 +1236,7 @@ int init_comfort(int argc, char* argv[]) { printf(" - %s\n",V_MSG); printf("Free for non-commercial use - Copyright 2006-2016 by Christian Schneider\n\n"); - //Init compression and memory level count + // init compression and memory level count bool use_zlib_level[81]; for (i = 0; i < 81; i++) { comp_mem_level_count[i] = 0; @@ -1255,7 +1244,7 @@ int init_comfort(int argc, char* argv[]) { use_zlib_level[i] = true; } - //Parse parameters (should be input file only) + // parse parameters (should be input file only) if (argc == 1) { printf("Usage:\n"); printf("Drag and drop a file on the executable to precompress/restore it.\n"); @@ -1276,10 +1265,8 @@ int init_comfort(int argc, char* argv[]) { wait_for_key(); exit(1); } - //fseek(fin, 0, SEEK_END); - //fin_length = ftell(fin); - //fseek(fin, 0, SEEK_SET); - if (fin_length > 6) { + + if (fin_length > 6) { if (check_for_pcf_file()) { operation = P_DECOMPRESS; } @@ -1293,7 +1280,7 @@ int init_comfort(int argc, char* argv[]) { strcpy(output_file_name + strlen(input_file_name), ".pcf"); } else { strcpy(dot_at_pos, ".pcf"); - //Same as output file because input file had .pcf extension? + // same as output file because input file had .pcf extension? if (strcmp(input_file_name, output_file_name) == 0) { strcpy(dot_at_pos, "_pcf.pcf"); } @@ -1302,10 +1289,10 @@ int init_comfort(int argc, char* argv[]) { } - //Precomf.ini in EXE directory? + // precomf.ini in EXE directory? char precomf_ini[1024]; GetModuleFileName(NULL, precomf_ini, 1024); - //Truncate to get directory of executable only + // truncate to get directory of executable only char* lastslash = strrchr(precomf_ini, PATH_DELIM) + 1; strcpy(lastslash, "precomf.ini"); printf("INI file: %s\n", precomf_ini); @@ -1359,7 +1346,7 @@ int init_comfort(int argc, char* argv[]) { } if (parse_ini_file) { - //Parse INI file + // parse INI file bool print_ignore_positions_message = true; ifstream ini_file(precomf_ini); @@ -1375,7 +1362,7 @@ int init_comfort(int argc, char* argv[]) { line.erase(semicolon_at_pos, line.length() - semicolon_at_pos); } - //Valid line must contain an equal sign (=) + // valid line must contain an equal sign (=) string::size_type equal_at_pos = line.find("=", 0); if (line.empty()) { equal_at_pos = string::npos; @@ -1384,9 +1371,9 @@ int init_comfort(int argc, char* argv[]) { stringstream ss; ss << line; - //Get parameter name + // get parameter name getline(ss, parName, '='); - //Remove spaces + // remove spaces for (it = parName.begin(); it != parName.end(); it++) { if (*it == ' ') { parName.erase(it); @@ -1406,11 +1393,10 @@ int init_comfort(int argc, char* argv[]) { } memset(param, '\0', 256); parName.copy(param, 256); - //printf("parName: <%s>\n", param); - //Get value + // get value getline(ss, valuestr); - //Remove spaces + // remove spaces for (it = valuestr.begin(); it != valuestr.end(); it++) { if (*it == ' ') { valuestr.erase(it); @@ -1430,12 +1416,10 @@ int init_comfort(int argc, char* argv[]) { } memset(value, '\0', 256); valuestr.copy(value, 256); - //printf("value: <%s>\n", value); if (strcmp(param, "") != 0) { bool valid_param = false; - //Minimal identical byte size if (strcmp(param, "minimal_size") == 0) { if (min_ident_size_set) { error(ERR_ONLY_SET_MIN_SIZE_ONCE); @@ -1457,7 +1441,6 @@ int init_comfort(int argc, char* argv[]) { valid_param = true; } - //Verbose mode if (strcmp(param, "verbose") == 0) { if (strcmp(value, "off") == 0) { printf("INI: Disabled verbose mode\n"); @@ -1477,7 +1460,6 @@ int init_comfort(int argc, char* argv[]) { } } - //Compression method if (strcmp(param, "compression_method") == 0) { if (strcmp(value, "0") == 0) { printf("INI: Using no compression method\n"); @@ -1498,7 +1480,6 @@ int init_comfort(int argc, char* argv[]) { } } - //Fast mode if (strcmp(param, "fast_mode") == 0) { if (strcmp(value, "off") == 0) { printf("INI: Disabled fast mode\n"); @@ -1518,7 +1499,6 @@ int init_comfort(int argc, char* argv[]) { } } - //Intense mode if (strcmp(param, "intense_mode") == 0) { if (strcmp(value, "off") == 0) { printf("INI: Disabled intense mode\n"); @@ -1538,7 +1518,6 @@ int init_comfort(int argc, char* argv[]) { } } - //Brute mode if (strcmp(param, "brute_mode") == 0) { if (strcmp(value, "off") == 0) { printf("INI: Disabled brute mode\n"); @@ -1562,7 +1541,6 @@ int init_comfort(int argc, char* argv[]) { } } - //PDF BMP mode if (strcmp(param, "pdf_bmp_mode") == 0) { if (strcmp(value, "off") == 0) { printf("INI: Disabled PDF BMP mode\n"); @@ -1583,7 +1561,6 @@ int init_comfort(int argc, char* argv[]) { } } - //Progressive JPGs only if (strcmp(param, "jpg_progressive_only") == 0) { if (strcmp(value, "off") == 0) { printf("INI: Disabled progressive only JPG mode\n"); @@ -1604,7 +1581,6 @@ int init_comfort(int argc, char* argv[]) { } } - //MJPEG recompression if (strcmp(param, "mjpeg_recompression") == 0) { if (strcmp(value, "off") == 0) { printf("INI: Disabled MJPEG recompression\n"); @@ -1625,7 +1601,6 @@ int init_comfort(int argc, char* argv[]) { } } - //Compression types if (strcmp(param, "compression_types") == 0) { use_pdf = false; use_zip = false; @@ -1640,34 +1615,34 @@ int init_comfort(int argc, char* argv[]) { for (j = 0; j < (int)strlen(value); j++) { switch (toupper(value[j])) { - case 'P': //PDF + case 'P': // PDF use_pdf = true; break; - case 'Z': //ZIP + case 'Z': // ZIP use_zip = true; break; - case 'G': //GZip + case 'G': // GZip use_gzip = true; break; - case 'N': //PNG + case 'N': // PNG use_png = true; break; - case 'F': //GIF + case 'F': // GIF use_gif = true; break; - case 'J': //JPG + case 'J': // JPG use_jpg = true; break; - case '3': //MP3 + case '3': // MP3 use_mp3 = true; break; - case 'S': //SWF + case 'S': // SWF use_swf = true; break; - case 'M': //MIME Base64 + case 'M': // MIME Base64 use_base64 = true; break; - case 'B': //bZip2 + case 'B': // bZip2 use_bzip2 = true; break; default: @@ -1740,7 +1715,7 @@ int init_comfort(int argc, char* argv[]) { valid_param = true; } - //zLib levels + // zLib levels if (strcmp(param, "zlib_levels") == 0) { for (j = 0; j < 81; j++) { use_zlib_level[j] = false; @@ -1776,7 +1751,6 @@ int init_comfort(int argc, char* argv[]) { valid_param = true; } - //Maximal recursion depth if (strcmp(param, "maximal_recursion_depth") == 0) { if (recursion_depth_set) { error(ERR_ONLY_SET_RECURSION_DEPTH_ONCE); @@ -1799,7 +1773,6 @@ int init_comfort(int argc, char* argv[]) { valid_param = true; } - //Ignore position if (strcmp(param, "ignore_positions") == 0) { long long act_ignore_pos = -1; @@ -1830,7 +1803,6 @@ int init_comfort(int argc, char* argv[]) { ignore_list = (long long*)realloc(ignore_list, (ignore_list_len + 1) * sizeof(long long)); ignore_list[ignore_list_len] = act_ignore_pos; ignore_list_len++; - //printf ("INI: Added ignore position %i\n", act_ignore_pos); act_ignore_pos = -1; } break; @@ -1846,7 +1818,6 @@ int init_comfort(int argc, char* argv[]) { ignore_list = (long long*)realloc(ignore_list, (ignore_list_len + 1) * sizeof(long long)); ignore_list[ignore_list_len] = act_ignore_pos; ignore_list_len++; - //printf ("INI: Added ignore position %i\n", act_ignore_pos); } if (print_ignore_positions_message) { @@ -1899,7 +1870,6 @@ int init_comfort(int argc, char* argv[]) { printf("\n"); printf("Ignore position list:\n"); for (i = 0; i < ignore_list_len; i++) { - //printf("%u\n",ignore_list[i]); print64(ignore_list[i]); printf("\n"); } @@ -1972,7 +1942,7 @@ void denit_compress() { printf("\nDone.\n"); printf_time(get_time_ms() - start_time); - //Statistics + // statistics printf("\nRecompressed streams: %i/%i\n", recompressed_streams_count, decompressed_streams_count); if ((recompressed_streams_count > 0) || (decompressed_streams_count > 0)) { @@ -2352,7 +2322,7 @@ size_t fread_skip(unsigned char *ptr, size_t size, size_t count, FILE* stream) { if (read_tmp == 0) return bytes_read; bytes_read += read_tmp; } - // Skip padding bytes + // skip padding bytes read_tmp = own_fread(frs_skipbuf, size, frs_skip_len, stream); if (read_tmp == 0) return bytes_read; frs_offset = 0; @@ -2622,7 +2592,7 @@ int def_bzip2(FILE *source, FILE *dest, int level) { return BZ_OK; } -int file_recompress(FILE* origfile, int compression_level, int windowbits, int memlevel) { // Recompress file +int file_recompress(FILE* origfile, int compression_level, int windowbits, int memlevel) { int retval; ftempout = fopen(tempfile1,"rb"); @@ -2654,7 +2624,7 @@ int file_recompress(FILE* origfile, int compression_level, int windowbits, int m return retval; } -int file_recompress_bzip2(FILE* origfile, int level) { // Recompress file +int file_recompress_bzip2(FILE* origfile, int level) { int retval; ftempout = fopen(tempfile1,"rb"); @@ -2666,7 +2636,6 @@ int file_recompress_bzip2(FILE* origfile, int level) { // Recompress file frecomp = tryOpen(tempfile2,"w+b"); fseek(ftempout, 0, SEEK_SET); - //retval = def_compare(ftempout, frecomp, origfile, compression_level, windowbits, memlevel); retval = def_bzip2(ftempout, frecomp, level); if (retval > -1) { @@ -2758,7 +2727,7 @@ void start_uncompressed_data() { uncompressed_length = 0; uncompressed_pos = input_file_pos; - //Uncompressed data + // uncompressed data fout_fputc(0); uncompressed_data_in_work = true; @@ -2777,7 +2746,7 @@ void end_uncompressed_data() { fout_fputc((uncompressed_length >> 8) % 256); fout_fputc(uncompressed_length % 256); - //Fast copy of uncompressed data + // fast copy of uncompressed data seek_64(fin, uncompressed_pos); fast_copy(fin, fout, uncompressed_length); @@ -2807,12 +2776,12 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, identical_bytes_decomp = -1; real_identical_bytes = -1; final_compression_found = false; - int bmp_header_type = 0; //0 = none, 1 = 8-bit, 2 = 24-bit + int bmp_header_type = 0; // 0 = none, 1 = 8-bit, 2 = 24-bit - // Try to decompress at current position + // try to decompress at current position retval = try_to_decompress(fin, windowbits); - if (retval > 0) { //Seems to be a zLib-Stream + if (retval > 0) { // seems to be a zLib-Stream decompressed_streams_count++; if (img_bpc == 8) { @@ -2844,7 +2813,6 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, if (final_compression_found) break; } - //if ((best_identical_bytes > 4) && (best_identical_bytes < identical_bytes_decomp)) { if ((best_identical_bytes > min_ident_size) && (best_identical_bytes < identical_bytes_decomp)) { recompressed_streams_count++; recompressed_pdf_count++; @@ -2897,13 +2865,13 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, } } - //End uncompressed data + // end uncompressed data compressed_data_found = true; end_uncompressed_data(); - //Write compressed data header (PDF) without 12 first bytes - // (/FlateDecode) + // write compressed data header (PDF) without 12 first bytes + // (/FlateDecode) unsigned char bmp_c = 0; @@ -2920,7 +2888,7 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, } else { fout_fputc(1 + 2 + (best_compression << 2) + bmp_c); } - fout_fputc(0); //PDF + fout_fputc(0); // PDF fout_fputc((((-windowbits) - 8) << 4) + best_mem_level); pdf_header_length -= 12; @@ -2931,7 +2899,7 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, own_fwrite(in_buf + cb + 12, 1, pdf_header_length, fout); - //Store penalty bytes, if any + // store penalty bytes, if any if (best_penalty_bytes_len != 0) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); @@ -2955,7 +2923,7 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, fout_fputc((best_identical_bytes_decomp >> 8) % 256); fout_fputc(best_identical_bytes_decomp % 256); - // Eventually write BMP header + // eventually write BMP header if (bmp_header_type > 0) { @@ -3030,14 +2998,14 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, } if (bmp_header_type == 1) { - // Write BMP palette + // write BMP palette for (i = 0; i < 1024; i++) { fout_fputc(0); } } } - // Write decompressed data + // write decompressed data if ((bmp_header_type == 0) || ((img_width % 4) == 0)) { write_decompressed_data(best_identical_bytes_decomp); @@ -3063,9 +3031,9 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, safe_fclose(&ftempout); } - //Start new uncompressed data + // start new uncompressed data - //Set input file pointer after recompressed data + // set input file pointer after recompressed data input_file_pos += best_identical_bytes - 1; cb += best_identical_bytes - 1; @@ -3093,10 +3061,10 @@ void try_decompression_zip(int zip_header_length) { int windowbits; - // Try to decompress at current position + // try to decompress at current position retval = try_to_decompress(fin, -15); - if (retval > 0) { //Seems to be a zLib-Stream + if (retval > 0) { // seems to be a zLib-Stream decompressed_streams_count++; decompressed_zip_count++; @@ -3125,7 +3093,6 @@ void try_decompression_zip(int zip_header_length) { } } - //if ((best_identical_bytes > 4) && (best_identical_bytes < identical_bytes_decomp)) { if ((best_identical_bytes > min_ident_size) && (best_identical_bytes < best_identical_bytes_decomp)) { recompressed_streams_count++; recompressed_zip_count++; @@ -3154,15 +3121,15 @@ void try_decompression_zip(int zip_header_length) { } } - //End uncompressed data + // end uncompressed data compressed_data_found = true; end_uncompressed_data(); - //Check recursion + // check recursion recursion_result r = recursion_compress(best_identical_bytes, best_identical_bytes_decomp); - //Write compressed data header (ZIP) without 4 first bytes (PK..) + // write compressed data header (ZIP) without 4 first bytes (PK..) int header_byte = 1 + (best_compression << 2); if (best_penalty_bytes_len != 0) { @@ -3172,7 +3139,7 @@ void try_decompression_zip(int zip_header_length) { header_byte += 128; } fout_fputc(header_byte); - fout_fputc(1); //ZIP + fout_fputc(1); // ZIP fout_fputc((((-windowbits) - 8) << 4) + best_mem_level); zip_header_length -= 4; @@ -3183,7 +3150,7 @@ void try_decompression_zip(int zip_header_length) { own_fwrite(in_buf + cb + 4, 1, zip_header_length, fout); - //Store penalty bytes, if any + // store penalty bytes, if any if (best_penalty_bytes_len != 0) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); @@ -3218,7 +3185,7 @@ void try_decompression_zip(int zip_header_length) { fout_fputc(r.file_length % 256); } - // Write decompressed data + // write decompressed data if (r.success) { write_decompressed_data(r.file_length, r.file_name); remove(r.file_name); @@ -3227,7 +3194,7 @@ void try_decompression_zip(int zip_header_length) { write_decompressed_data(best_identical_bytes_decomp); } - //Set input file pointer after recompressed data + // set input file pointer after recompressed data input_file_pos += best_identical_bytes - 1; cb += best_identical_bytes - 1; @@ -3346,9 +3313,6 @@ bool compress_file(float min_percent, float max_percent) { global_min_percent = min_percent; global_max_percent = max_percent; - //fseek(fin, 0, SEEK_END); - //unsigned int size_in = ftell(fin); - if (recursion_depth == 0) write_header(); uncompressed_length = -1; @@ -3423,7 +3387,7 @@ bool compress_file(float min_percent, float max_percent) { // ZIP header? if (((in_buf[cb] == 'P') && (in_buf[cb + 1] == 'K')) && (use_zip)) { - //Local file header? + // local file header? if ((in_buf[cb + 2] == 3) && (in_buf[cb + 3] == 4)) { if (DEBUG_MODE) { printf("ZIP header detected\n"); @@ -3443,16 +3407,6 @@ bool compress_file(float min_percent, float max_percent) { printf("extra field length: %i\n", extra_field_length); } - // Stored ZIP detection - removed because it skips valid ZIP streams. - // Perhaps try to skip only if compressed_size and uncompressed_size - // are greater than 0: - // if ((compressed_size == uncompressed_size) && (compressed_size > 0)) { - /*if (compressed_size == uncompressed_size) { - if (DEBUG_MODE) { - printf("seems to be stored, skipping\n"); - } - } else*/ - if ((filename_length + extra_field_length) <= CHECKBUF_SIZE) { int header_length = 30 + filename_length + extra_field_length; @@ -3475,12 +3429,12 @@ bool compress_file(float min_percent, float max_percent) { } } - if ((!compressed_data_found) && (use_gzip)) { // No ZIP header -> GZip header? + if ((!compressed_data_found) && (use_gzip)) { // no ZIP header -> GZip header? if ((in_buf[cb] == 31) && (in_buf[cb + 1] == 139)) { - //Check zLib header in GZip header + // check zLib header in GZip header int compression_method = (in_buf[cb + 2] & 15); if ((compression_method == 8) && - ((in_buf[cb + 3] & 224) == 0) //Reserved FLG bits must be zero. + ((in_buf[cb + 3] & 224) == 0) // reserved FLG bits must be zero ) { //((in_buf[cb + 8] == 2) || (in_buf[cb + 8] == 4)) { //XFL = 2 or 4 @@ -3506,7 +3460,6 @@ bool compress_file(float min_percent, float max_percent) { int act_checkbuf_pos = 10; if (fextra) { - //int xlen = fgetc(fin) + (fgetc(fin) << 8); int xlen = in_buf[cb + act_checkbuf_pos] + (in_buf[cb + act_checkbuf_pos + 1] << 8); if ((act_checkbuf_pos + xlen) > CHECKBUF_SIZE) { dont_compress = true; @@ -3540,7 +3493,7 @@ bool compress_file(float min_percent, float max_percent) { if (!dont_compress) { - input_file_pos += header_length; //Skip GZip header + input_file_pos += header_length; // skip GZip header try_decompression_gzip(header_length); @@ -3556,7 +3509,7 @@ bool compress_file(float min_percent, float max_percent) { } } - if ((!compressed_data_found) && (use_pdf)) { // No Gzip header -> PDF FlateDecode? + if ((!compressed_data_found) && (use_pdf)) { // no Gzip header -> PDF FlateDecode? if (memcmp(in_buf + cb, "/FlateDecode", 12) == 0) { saved_input_file_pos = input_file_pos; saved_cb = cb; @@ -3575,9 +3528,9 @@ bool compress_file(float min_percent, float max_percent) { if (found_stream) { - // Check if the stream is an image and width and height are given + // check if the stream is an image and width and height are given - // Read 4096 bytes before stream + // read 4096 bytes before stream unsigned char type_buf[4097]; int type_buf_length; @@ -3594,7 +3547,7 @@ bool compress_file(float min_percent, float max_percent) { type_buf_length = input_file_pos + act_search_pos; } - // Find "<<" + // find "<<" int start_pos = -1; @@ -3611,7 +3564,7 @@ bool compress_file(float min_percent, float max_percent) { int width_pos, height_pos, bpc_pos; - // Find "/Width" + // find "/Width" width_pos = (unsigned char*)strstr((const char*)(type_buf + start_pos), "/Width") - type_buf; if (width_pos > 0) @@ -3625,7 +3578,7 @@ bool compress_file(float min_percent, float max_percent) { } } - // Find "/Height" + // find "/Height" height_pos = (unsigned char*)strstr((const char*)(type_buf + start_pos), "/Height") - type_buf; if (height_pos > 0) @@ -3639,7 +3592,7 @@ bool compress_file(float min_percent, float max_percent) { } } - // Find "/BitsPerComponent" + // find "/BitsPerComponent" bpc_pos = (unsigned char*)strstr((const char*)(type_buf + start_pos), "/BitsPerComponent") - type_buf; if (bpc_pos > 0) @@ -3662,15 +3615,15 @@ bool compress_file(float min_percent, float max_percent) { if ((in_buf[cb + act_search_pos + 6] == 13) || (in_buf[cb + act_search_pos + 6] == 10)) { if ((in_buf[cb + act_search_pos + 7] == 13) || (in_buf[cb + act_search_pos + 7] == 10)) { - //Seems to be two byte EOL - zLib Header present? + // seems to be two byte EOL - zLib Header present? if (((((in_buf[cb + act_search_pos + 8] << 8) + in_buf[cb + act_search_pos + 9]) % 31) == 0) && - ((in_buf[cb + act_search_pos + 9] & 32) == 0)) { //FDICT must not be set + ((in_buf[cb + act_search_pos + 9] & 32) == 0)) { // FDICT must not be set int compression_method = (in_buf[cb + act_search_pos + 8] & 15); if (compression_method == 8) { int windowbits = (in_buf[cb + act_search_pos + 8] >> 4) + 8; - input_file_pos += act_search_pos + 10; //Skip PDF part + input_file_pos += act_search_pos + 10; // skip PDF part try_decompression_pdf(-windowbits, act_search_pos + 10, width_val, height_val, bpc_val); @@ -3678,13 +3631,13 @@ bool compress_file(float min_percent, float max_percent) { } } } else { - //Seems to be one byte EOL - zLib Header present? + // seems to be one byte EOL - zLib Header present? if ((((in_buf[cb + act_search_pos + 7] << 8) + in_buf[cb + act_search_pos + 8]) % 31) == 0) { int compression_method = (in_buf[cb + act_search_pos + 7] & 15); if (compression_method == 8) { int windowbits = (in_buf[cb + act_search_pos + 7] >> 4) + 8; - input_file_pos += act_search_pos + 9; //Skip PDF part + input_file_pos += act_search_pos + 9; // skip PDF part try_decompression_pdf(-windowbits, act_search_pos + 9, width_val, height_val, bpc_val); @@ -3702,10 +3655,10 @@ bool compress_file(float min_percent, float max_percent) { } } - if ((!compressed_data_found) && (use_png)) { // No PDF header -> PNG IDAT? + if ((!compressed_data_found) && (use_png)) { // no PDF header -> PNG IDAT? if (memcmp(in_buf + cb, "IDAT", 4) == 0) { - //space for length and crc parts of IDAT chunks + // space for length and crc parts of IDAT chunks idat_lengths = (unsigned int*)(realloc(idat_lengths, 100 * sizeof(unsigned int))); idat_crcs = (unsigned int*)(realloc(idat_crcs, 100 * sizeof(unsigned int))); @@ -3716,7 +3669,7 @@ bool compress_file(float min_percent, float max_percent) { bool zlib_header_correct = false; int windowbits = 0; - //Get preceding length bytes + // get preceding length bytes if (input_file_pos >= 4) { seek_64(fin, input_file_pos - 4); @@ -3726,12 +3679,12 @@ bool compress_file(float min_percent, float max_percent) { idat_lengths[0] = (in[0] << 24) + (in[1] << 16) + (in[2] << 8) + in[3]; if (idat_lengths[0] > 2) { - //Check zLib header and get windowbits + // check zLib header and get windowbits zlib_header[0] = in[8]; zlib_header[1] = in[9]; if ((((in[8] << 8) + in[9]) % 31) == 0) { if ((in[8] & 15) == 8) { - if ((in[9] & 32) == 0) { //FDICT must not be set + if ((in[9] & 32) == 0) { // FDICT must not be set windowbits = (in[8] >> 4) + 8; zlib_header_correct = true; } @@ -3742,10 +3695,10 @@ bool compress_file(float min_percent, float max_percent) { idat_count++; - //Go through additional IDATs + // go through additional IDATs for (;;) { seek_64(fin, tell_64(fin) + idat_lengths[idat_count - 1]); - if (fread(in, 1, 12, fin) != 12) { //CRC, Length, "IDAT" + if (fread(in, 1, 12, fin) != 12) { // CRC, length, "IDAT" idat_count = 0; break; } @@ -3775,18 +3728,18 @@ bool compress_file(float min_percent, float max_percent) { if (idat_count == 1) { - //Try to recompress directly + // try to recompress directly input_file_pos += 6; try_decompression_png(-windowbits); cb += 6; } else if (idat_count > 1) { - //Copy to temp0.dat before trying to recompress + // copy to temp0.dat before trying to recompress remove(tempfile0); fpng = tryOpen(tempfile0,"w+b"); - seek_64(fin, input_file_pos + 6); // Start after zLib header + seek_64(fin, input_file_pos + 6); // start after zLib header - idat_lengths[0] -= 2; //zLib header length + idat_lengths[0] -= 2; // zLib header length for (int i = 0; i < idat_count; i++) { fast_copy(fin, fpng, idat_lengths[i]); seek_64(fin, tell_64(fin) + 12); @@ -3813,7 +3766,7 @@ bool compress_file(float min_percent, float max_percent) { } - if ((!compressed_data_found) && (use_gif)) { // No PNG header -> GIF header? + if ((!compressed_data_found) && (use_gif)) { // no PNG header -> GIF header? if ((in_buf[cb] == 'G') && (in_buf[cb + 1] == 'I') && (in_buf[cb + 2] == 'F')) { if ((in_buf[cb + 3] == '8') && (in_buf[cb + 5] == 'a')) { if ((in_buf[cb + 4] == '7') || (in_buf[cb + 4] == '9')) { @@ -3838,8 +3791,8 @@ bool compress_file(float min_percent, float max_percent) { } } - if ((!compressed_data_found) && (use_jpg)) { // No GIF header -> JPG header? - if ((in_buf[cb] == 0xFF) && (in_buf[cb + 1] == 0xD8)) { //SOI (FF D8) + if ((!compressed_data_found) && (use_jpg)) { // no GIF header -> JPG header? + if ((in_buf[cb] == 0xFF) && (in_buf[cb + 1] == 0xD8)) { // SOI (FF D8) if ((in_buf[cb + 2] == 0xFF)) { saved_input_file_pos = input_file_pos; saved_cb = cb; @@ -3847,7 +3800,7 @@ bool compress_file(float min_percent, float max_percent) { int eoi_count = 1; bool progressive_flag = false; - //Find SOF + // find SOF bool ff_sof_found = false; bool sof_found = false; long long sof_pos = input_file_pos + 1; @@ -3856,11 +3809,11 @@ bool compress_file(float min_percent, float max_percent) { while (fread(in, 1, 1, fin) == 1) { sof_pos++; if (ff_sof_found) { - if (in[0] == 0xD8) { //Another SOI (FF D8) - increase EOI count + if (in[0] == 0xD8) { // another SOI (FF D8) - increase EOI count eoi_count++; } - sof_found = ((in[0] == 0xC0) //baseline - || (in[0] == 0xC2)); //progressive + sof_found = ((in[0] == 0xC0) // baseline + || (in[0] == 0xC2)); // progressive if (sof_found) { progressive_flag = (in[0] == 0xC2); if (fread(in, 1, 3, fin) == 3) { @@ -3880,7 +3833,7 @@ bool compress_file(float min_percent, float max_percent) { } } - //Find EOI + // find EOI bool ff_eoi_found = false; long long eoi_pos = 0; @@ -3891,7 +3844,7 @@ bool compress_file(float min_percent, float max_percent) { while (fread(in, 1, 1, fin) == 1) { eoi_pos++; if (ff_eoi_found) { - if (in[0] == 0xD8) { //Another SOI (FF D8) - increase EOI count + if (in[0] == 0xD8) { // another SOI (FF D8) - increase EOI count eoi_count++; } if (in[0] == 0xD9) { @@ -3911,65 +3864,18 @@ bool compress_file(float min_percent, float max_percent) { long long jpg_length = (eoi_pos + 1) - input_file_pos; - //Check for DHT (0xFFC4) and DQT (0xFFDB) before 1st SOS (0xFFDA) - //Additionaly, check if there is _exactly one_ SOF (0xFFC0, 0xFFC1 - // or 0xFFC2) before 1st SOS (0xFFDA) - - /*fseek(fin, input_file_pos + 2, SEEK_SET); - - bool dht_found = false; - bool dqt_found = false; - bool ff_found = false; - bool sos_found = false; - int sof_count = 0; - int act_pos = input_file_pos + 2; - - while ((fread(in, 1, 1, fin) == 1) && (act_pos != eoi_pos)) { - act_pos++; - if (ff_found) { - if (in[0] == 0xC4) { - dht_found = true; - } - if (in[0] == 0xDB) { - dqt_found = true; - } - if ((in[0] == 0xC0) || (in[0] == 0xC1) || (in[0] == 0xC2)) { - sof_count++; - if (sos_found) { //SOF after SOS -> invalid - sof_count = 0; - break; - } - } - if (in[0] == 0xD9) { //EOI - sos_found = false; //reset SOS status - if (sof_count != 1) break; - sof_count = 0; - } - if (in[0] == 0xDA) { //SOS - sos_found = true; - } - ff_found = (in[0] == 0xFF); - } else { - ff_found = (in[0] == 0xFF); - } - } - - if (dht_found && dqt_found && (sof_count == 1)) {*/ - try_decompression_jpg(jpg_length, progressive_flag); - //} else { - //} + try_decompression_jpg(jpg_length, progressive_flag); if (!compressed_data_found) { input_file_pos = saved_input_file_pos; cb = saved_cb; } - } } } } - if ((!compressed_data_found) && (use_mp3)) { // No JPG header -> MP3 header? + if ((!compressed_data_found) && (use_mp3)) { // no JPG header -> MP3 header? if ((in_buf[cb] == 0xFF) && ((in_buf[cb + 1] & 0xE0) == 0xE0)) { // frame start int mpeg = -1; int layer = -1; @@ -4038,15 +3944,15 @@ bool compress_file(float min_percent, float max_percent) { } } - if ((!compressed_data_found) && (use_swf)) { // No MP3 header -> SWF header? + if ((!compressed_data_found) && (use_swf)) { // no MP3 header -> SWF header? // CWS = Compressed SWF file if ((in_buf[cb] == 'C') && (in_buf[cb + 1] == 'W') && (in_buf[cb + 2] == 'S')) { char swf_version = in_buf[cb + 3]; - // Check version number is 1 - 10 + // check version number is 1 - 10 if ((swf_version > 0) && (swf_version < 10)) { - // Check zLib header + // check zLib header if (((((in_buf[cb + 8] << 8) + in_buf[cb + 9]) % 31) == 0) && - ((in_buf[cb + 9] & 32) == 0)) { //FDICT must not be set + ((in_buf[cb + 9] & 32) == 0)) { // FDICT must not be set int compression_method = (in_buf[cb + 8] & 15); if (compression_method == 8) { int windowbits = (in_buf[cb + 8] >> 4) + 8; @@ -4054,7 +3960,7 @@ bool compress_file(float min_percent, float max_percent) { saved_input_file_pos = input_file_pos; saved_cb = cb; - input_file_pos += 10; //Skip CWS and zLib header + input_file_pos += 10; // skip CWS and zLib header try_decompression_swf(-windowbits, swf_version); @@ -4070,14 +3976,14 @@ bool compress_file(float min_percent, float max_percent) { } } - if ((!compressed_data_found) && (use_base64)) { // No SWF header -> Base64? + if ((!compressed_data_found) && (use_base64)) { // no SWF header -> Base64? if ((in_buf[cb + 1] == 'o') && (in_buf[cb + 2] == 'n') && (in_buf[cb + 3] == 't') && (in_buf[cb + 4] == 'e')) { unsigned char cte_detect[33]; for (int i = 0; i < 33; i++) { cte_detect[i] = tolower(in_buf[cb + i]); } if (memcmp(cte_detect, "content-transfer-encoding: base64", 33) == 0) { - // Search for double CRLF, all between is "header" + // search for double CRLF, all between is "header" int base64_header_length = 33; bool found_double_crlf = false; do { @@ -4085,7 +3991,7 @@ bool compress_file(float min_percent, float max_percent) { if ((in_buf[cb + base64_header_length + 2] == 13) && (in_buf[cb + base64_header_length + 3] == 10)) { found_double_crlf = true; base64_header_length += 4; - // Skip additional CRLFs + // skip additional CRLFs while ((in_buf[cb + base64_header_length] == 13) && (in_buf[cb + base64_header_length + 1] == 10)) { base64_header_length += 2; } @@ -4100,7 +4006,7 @@ bool compress_file(float min_percent, float max_percent) { saved_input_file_pos = input_file_pos; saved_cb = cb; - input_file_pos += base64_header_length; //Skip "header" + input_file_pos += base64_header_length; // skip "header" try_decompression_base64(base64_header_length); @@ -4115,7 +4021,7 @@ bool compress_file(float min_percent, float max_percent) { } } - if ((!compressed_data_found) && (use_bzip2)) { // No Base64 header -> bZip2? + if ((!compressed_data_found) && (use_bzip2)) { // no Base64 header -> bZip2? // BZhx = header, x = compression level/blocksize (1-9) if ((in_buf[cb] == 'B') && (in_buf[cb + 1] == 'Z') && (in_buf[cb + 2] == 'h')) { int compression_level = in_buf[cb + 3] - '0'; @@ -4134,11 +4040,11 @@ bool compress_file(float min_percent, float max_percent) { } - // Nothing so far -> if slow mode is enabled, look for raw zLib header + // nothing so far -> if slow mode is enabled, look for raw zLib header if ((slow_mode) && ((slow_mode_depth_limit == -1) || (recursion_depth <= slow_mode_depth_limit))) { if (!compressed_data_found) { if (((((in_buf[cb] << 8) + in_buf[cb + 1]) % 31) == 0) && - ((in_buf[cb + 1] & 32) == 0)) { //FDICT must not be set + ((in_buf[cb + 1] & 32) == 0)) { // FDICT must not be set int compression_method = (in_buf[cb] & 15); if (compression_method == 8) { int windowbits = (in_buf[cb] >> 4) + 8; @@ -4146,7 +4052,7 @@ bool compress_file(float min_percent, float max_percent) { saved_input_file_pos = input_file_pos; saved_cb = cb; - input_file_pos += 2; //Skip zLib header + input_file_pos += 2; // skip zLib header try_decompression_zlib(-windowbits); @@ -4163,7 +4069,7 @@ bool compress_file(float min_percent, float max_percent) { } } else { - // Nothing so far -> if brute mode is enabled, brute force for zLib streams + // nothing so far -> if brute mode is enabled, brute force for zLib streams if ((brute_mode) && ((brute_mode_depth_limit == -1) || (recursion_depth <= brute_mode_depth_limit))) { if (!compressed_data_found) { saved_input_file_pos = input_file_pos; @@ -4208,10 +4114,6 @@ void decompress_file() { init_decompress_otf(); } - //fseek(fin, 0, SEEK_END); - //int fin_length = ftell(fin); - //fseek(fin, 0, SEEK_SET); - #ifndef PRECOMPDLL if (recursion_depth == 0) { if (!DEBUG_MODE) { @@ -4234,7 +4136,6 @@ void decompress_file() { fin_pos = tell_64(fin); -//while (ftell(fin) < fin_length) { while (fin_pos < fin_length) { #ifndef PRECOMPDLL @@ -4262,7 +4163,7 @@ while (fin_pos < fin_length) { #endif unsigned char header1 = fin_fgetc(); - if (header1 == 0) { //Uncompressed data + if (header1 == 0) { // uncompressed data long long uncompressed_data_length; uncompressed_data_length = ((long long)fin_fgetc() << 56); uncompressed_data_length += ((long long)fin_fgetc() << 48); @@ -4273,10 +4174,9 @@ while (fin_pos < fin_length) { uncompressed_data_length += ((long long)fin_fgetc() << 8); uncompressed_data_length += (long long)fin_fgetc(); - if (uncompressed_data_length == 0) break; // End of PCF file, used by bZip2 compress-on-the-fly + if (uncompressed_data_length == 0) break; // end of PCF file, used by bZip2 compress-on-the-fly if (DEBUG_MODE) { - //printf("Uncompressed data, length=%i\n", uncompressed_data_length); printf("Uncompressed data, length="); print64(uncompressed_data_length); printf("\n"); @@ -4284,7 +4184,7 @@ while (fin_pos < fin_length) { fast_copy(fin, fout, uncompressed_data_length); - } else { //Decompressed data, recompress + } else { // decompressed data, recompress unsigned char headertype = fin_fgetc(); @@ -4314,13 +4214,13 @@ while (fin_pos < fin_length) { pdf_header_length += (fin_fgetc() << 8); pdf_header_length += fin_fgetc(); - //Restore PDF header + // restore PDF header fprintf(fout, "/FlateDecode"); own_fread(in, 1, pdf_header_length, fin); own_fwrite(in, 1, pdf_header_length, fout); - //Read penalty bytes + // read penalty bytes if (penalty_bytes_stored) { penalty_bytes_len = (fin_fgetc() << 24); penalty_bytes_len += (fin_fgetc() << 16); @@ -4345,10 +4245,10 @@ while (fin_pos < fin_length) { printf("Recompressed Length: %i - Decompressed length: %i\n", recompressed_data_length, decompressed_data_length); } - //Keep file position for penalty bytes + // keep file position for penalty bytes long long old_fout_pos = tell_64(fout); - // Read BMP header + // read BMP header int bmp_width = 0; @@ -4366,15 +4266,15 @@ while (fin_pos < fin_length) { } if ((bmp_c == 0) || ((bmp_width % 4) == 0)) { - // Recompress directly to fout + // recompress directly to fout retval = def_part(fin, fout, compression_level, windowbits, memlevel, decompressed_data_length, recompressed_data_length); if (retval != Z_OK) { printf("Error recompressing data!"); printf("retval = %i\n", retval); exit(0); } - } else { // Lines aligned to 4 byte, skip those bytes - // Recompress directly to fout, but skipping bytes + } else { // lines aligned to 4 byte, skip those bytes + // recompress directly to fout, but skipping bytes retval = def_part_skip(fin, fout, compression_level, windowbits, memlevel, decompressed_data_length, recompressed_data_length, bmp_width); @@ -4442,7 +4342,7 @@ while (fin_pos < fin_length) { own_fread(in, 1, zip_header_length, fin); own_fwrite(in, 1, zip_header_length, fout); - //Read penalty bytes + // read penalty bytes if (penalty_bytes_stored) { penalty_bytes_len = (fin_fgetc() << 24); penalty_bytes_len += (fin_fgetc() << 16); @@ -4557,7 +4457,7 @@ while (fin_pos < fin_length) { own_fread(in, 1, gzip_header_length, fin); own_fwrite(in, 1, gzip_header_length, fout); - //Read penalty bytes + // read penalty bytes if (penalty_bytes_stored) { penalty_bytes_len = (fin_fgetc() << 24); penalty_bytes_len += (fin_fgetc() << 16); @@ -4655,16 +4555,16 @@ while (fin_pos < fin_length) { printf("Memory level: %i\n", memlevel); } - //Restore IDAT + // restore IDAT fprintf(fout, "IDAT"); - //Restore zLib header (decrease by 1) + // restore zLib header (decrease by 1) own_fread(in, 1, 2, fin); unsigned char decchar = *(in + 1) - 1; own_fwrite(in, 1, 1, fout); fputc(decchar, fout); - //Read penalty bytes + // read penalty bytes if (penalty_bytes_stored) { penalty_bytes_len = (fin_fgetc() << 24); penalty_bytes_len += (fin_fgetc() << 16); @@ -4737,16 +4637,16 @@ while (fin_pos < fin_length) { printf("Memory level: %i\n", memlevel); } - //Restore first IDAT + // restore first IDAT fprintf(fout, "IDAT"); - //Restore zLib header (decrease by 1) + // restore zLib header (decrease by 1) own_fread(in, 1, 2, fin); unsigned char decchar = *(in + 1) - 1; own_fwrite(in, 1, 1, fout); fputc(decchar, fout); - //Get IDAT count + // get IDAT count own_fread(in, 1, 2, fin); idat_count = (in[0] << 8) + in[1]; idat_count++; @@ -4754,12 +4654,12 @@ while (fin_pos < fin_length) { idat_crcs = (unsigned int*)(realloc(idat_crcs, idat_count * sizeof(unsigned int))); idat_lengths = (unsigned int*)(realloc(idat_lengths, idat_count * sizeof(unsigned int))); - //Get first IDAT length + // get first IDAT length own_fread(in, 1, 4, fin); idat_lengths[0] = (in[0] << 24) + (in[1] << 16) + (in[2] << 8) + in[3]; - idat_lengths[0] -= 2; //zLib header length + idat_lengths[0] -= 2; // zLib header length - //Get IDAT chunk lengths and CRCs + // get IDAT chunk lengths and CRCs for (int i = 1; i < idat_count; i++) { own_fread(in, 1, 4, fin); idat_crcs[i] = (in[0] << 24) + (in[1] << 16) + (in[2] << 8) + in[3]; @@ -4767,7 +4667,7 @@ while (fin_pos < fin_length) { idat_lengths[i] = (in[0] << 24) + (in[1] << 16) + (in[2] << 8) + in[3]; } - //Read penalty bytes + // read penalty bytes if (penalty_bytes_stored) { penalty_bytes_len = (fin_fgetc() << 24); penalty_bytes_len += (fin_fgetc() << 16); @@ -4806,7 +4706,7 @@ while (fin_pos < fin_length) { long long old_frecomp_pos = tell_64(frecomp); - //Recompress data + // recompress data retval = def(ftempout, frecomp, compression_level, windowbits, memlevel); if ((!penalty_bytes_stored) || (retval != Z_OK)) safe_fclose(&frecomp); safe_fclose(&ftempout); @@ -4818,7 +4718,6 @@ while (fin_pos < fin_length) { } if (penalty_bytes_stored) { - //frecomp = tryOpen(tempfile2,"wb"); fflush(frecomp); int pb_pos = 0; @@ -4840,7 +4739,6 @@ while (fin_pos < fin_length) { unsigned int remaining_bytes = recompressed_data_length; unsigned int act_idat_chunk = 0; for (;;) { - //printf("DEBUG: Remaining bytes: %i - IDAT_length: %i\n", remaining_bytes, idat_lengths[act_idat_chunk]); if ((remaining_bytes + 2) > idat_lengths[act_idat_chunk]) { fast_copy(frecomp, fout, idat_lengths[act_idat_chunk]); remaining_bytes -= idat_lengths[act_idat_chunk]; @@ -4885,7 +4783,7 @@ while (fin_pos < fin_length) { GifDiffStruct gDiff; - //Read diff bytes + // read diff bytes gDiff.GIFDiffIndex = (fin_fgetc() << 24); gDiff.GIFDiffIndex += (fin_fgetc() << 16); gDiff.GIFDiffIndex += (fin_fgetc() << 8); @@ -4899,7 +4797,7 @@ while (fin_pos < fin_length) { gDiff.GIFDiffIndex = 0; gDiff.GIFCodeCount = 0; - //Read penalty bytes + // read penalty bytes if (penalty_bytes_stored) { penalty_bytes_len = (fin_fgetc() << 24); penalty_bytes_len += (fin_fgetc() << 16); @@ -4938,7 +4836,7 @@ while (fin_pos < fin_length) { ftempout = tryOpen(tempfile1,"rb"); frecomp = tryOpen(tempfile2,"wb"); - //Recompress data + // recompress data recompress_success = recompress_gif(ftempout, frecomp, block_size, NULL, &gDiff); safe_fclose(&frecomp); @@ -5095,22 +4993,22 @@ while (fin_pos < fin_length) { fputc('C', fout); fputc('W', fout); fputc('S', fout); - // Get Flash version + // get Flash version char c = fin_fgetc(); fputc(c, fout); - // Get length from SWF header + // get length from SWF header for (int i = 0; i < 4; i++) { c = fin_fgetc(); fputc(c, fout); } - //Restore zLib header (decrease by 1) + // restore zLib header (decrease by 1) own_fread(in, 1, 2, fin); unsigned char decchar = *(in + 1) - 1; own_fwrite(in, 1, 1, fout); fputc(decchar, fout); - //Read penalty bytes + // read penalty bytes if (penalty_bytes_stored) { penalty_bytes_len = (fin_fgetc() << 24); penalty_bytes_len += (fin_fgetc() << 16); @@ -5198,7 +5096,7 @@ while (fin_pos < fin_length) { int line_case = (header1 >> 2) & 3; bool recursion_used = ((header1 & 128) == 128); - // Restore Base64 "header" + // restore Base64 "header" int base64_header_length; base64_header_length = (fin_fgetc() << 8); base64_header_length += fin_fgetc(); @@ -5207,10 +5105,10 @@ while (fin_pos < fin_length) { printf("Base64 header length: %i\n", base64_header_length); } own_fread(in, 1, base64_header_length, fin); - fputc(*(in) + 1, fout); // First char was decreased + fputc(*(in) + 1, fout); // first char was decreased own_fwrite(in + 1, 1, base64_header_length - 1, fout); - // Read line length list + // read line length list int line_count = fin_fgetc() << 8; line_count += fin_fgetc(); if (line_case == 2) { @@ -5259,7 +5157,7 @@ while (fin_pos < fin_length) { } } - // Re-encode Base64 + // re-encode Base64 if (recursion_used) { recursion_result r = recursion_decompress(recursion_data_length); @@ -5288,7 +5186,7 @@ while (fin_pos < fin_length) { printf("Compression level: %i\n", level); } - //Read penalty bytes + // read penalty bytes if (penalty_bytes_stored) { penalty_bytes_len = (fin_fgetc() << 24); penalty_bytes_len += (fin_fgetc() << 16); @@ -5440,7 +5338,7 @@ while (fin_pos < fin_length) { printf("Memory level: %i\n", memlevel); } - //Read penalty bytes + // read penalty bytes if (penalty_bytes_stored) { penalty_bytes_len = (fin_fgetc() << 24); penalty_bytes_len += (fin_fgetc() << 16); @@ -5539,13 +5437,13 @@ while (fin_pos < fin_length) { printf("Memory level: %i\n", memlevel); } - //Restore zLib header (decrease by 1) + // restore zLib header (decrease by 1) own_fread(in, 1, 2, fin); unsigned char decchar = *(in + 1) - 1; own_fwrite(in, 1, 1, fout); fputc(decchar, fout); - //Read penalty bytes + // read penalty bytes if (penalty_bytes_stored) { penalty_bytes_len = (fin_fgetc() << 24); penalty_bytes_len += (fin_fgetc() << 16); @@ -5666,7 +5564,7 @@ void convert_file() { for (;;) { bytes_read = own_fread(copybuf, 1, COPY_BUF_SIZE, fin); - // Truncate by 9 bytes (Precomp bZip2 delimiter) if converting from bZip2 + // truncate by 9 bytes (Precomp bZip2 delimiter) if converting from bZip2 if ((conversion_from_method == 1) && (bytes_read < COPY_BUF_SIZE)) { bytes_read -= 9; if (bytes_read < 0) { @@ -5764,25 +5662,18 @@ void try_recompress(FILE* origfile, int comp_level, int mem_level, int windowbit print_work_sign(true); - //if (file_recompress(comp_level, windowbits, mem_level) == Z_OK) { //Successfully recompressed? identical_bytes = file_recompress(origfile, comp_level, windowbits, mem_level); - if (identical_bytes > -1) { //Successfully recompressed? + if (identical_bytes > -1) { // successfully recompressed? if (identical_bytes > best_identical_bytes) { - //if (identical_bytes > 4) { if (identical_bytes > min_ident_size) { if (DEBUG_MODE) { printf("Identical recompressed bytes: %i\n", identical_bytes); } - //DEBUG - //system("copy temp1.dat recomp1.dat"); - //system("copy temp2.dat recomp2.dat"); - - - //Shorten temp2.dat to the identical bytes + // shorten temp2.dat to the identical bytes frecomp = tryOpen(tempfile2,"rb"); fident = tryOpen(tempfile2a, "wb"); fast_copy(frecomp, fident, identical_bytes); @@ -5790,7 +5681,7 @@ void try_recompress(FILE* origfile, int comp_level, int mem_level, int windowbit safe_fclose(&frecomp); - //Decompress temp2.dat to temp3.dat for comparison with temp1.dat + // decompress temp2.dat to temp3.dat for comparison with temp1.dat fident = tryOpen(tempfile2a,"rb"); fseek(fident, 0, SEEK_SET); @@ -5817,7 +5708,7 @@ void try_recompress(FILE* origfile, int comp_level, int mem_level, int windowbit final_compression_found = (identical_bytes_decomp == ftempout_size); if (!final_compression_found) { - //Recompress temp3.dat for comparison with input file + // recompress temp3.dat for comparison with input file remove(tempfile4); fdecomp = tryOpen(tempfile3,"rb"); frecomp2 = tryOpen(tempfile4,"wb"); @@ -5825,10 +5716,6 @@ void try_recompress(FILE* origfile, int comp_level, int mem_level, int windowbit safe_fclose(&frecomp2); safe_fclose(&fdecomp); - //DEBUG - //system("copy temp3.dat recomp3.dat"); - //system("copy temp4.dat recomp4.dat"); - frecomp2 = tryOpen(tempfile4,"rb"); } else { // tempfile4 would be the same as tempfile2a, no need to recompress again frecomp2 = tryOpen(tempfile2a,"rb"); @@ -5871,25 +5758,18 @@ void try_recompress_bzip2(FILE* origfile, int level) { print_work_sign(true); - //if (file_recompress(comp_level, windowbits, mem_level) == Z_OK) { //Successfully recompressed? identical_bytes = file_recompress_bzip2(origfile, level); if (identical_bytes > -1) { //Successfully recompressed? if (identical_bytes > best_identical_bytes) { - //if (identical_bytes > 4) { if (identical_bytes > min_ident_size) { if (DEBUG_MODE) { printf("Identical recompressed bytes: %i\n", identical_bytes); } - //DEBUG - //system("copy temp1.dat recomp1.dat"); - //system("copy temp2.dat recomp2.dat"); - - - //Shorten temp2.dat to the identical bytes + // shorten temp2.dat to the identical bytes frecomp = tryOpen(tempfile2,"rb"); fident = tryOpen(tempfile2a, "wb"); fast_copy(frecomp, fident, identical_bytes); @@ -5897,7 +5777,7 @@ void try_recompress_bzip2(FILE* origfile, int level) { safe_fclose(&frecomp); - //Decompress temp2.dat to temp3.dat for comparison with temp1.dat + // decompress temp2.dat to temp3.dat for comparison with temp1.dat fident = tryOpen(tempfile2a,"rb"); fseek(fident, 0, SEEK_SET); @@ -5924,7 +5804,7 @@ void try_recompress_bzip2(FILE* origfile, int level) { final_compression_found = (identical_bytes_decomp == ftempout_size); if (!final_compression_found) { - //Recompress temp3.dat for comparison with input file + // recompress temp3.dat for comparison with input file remove(tempfile4); fdecomp = tryOpen(tempfile3,"rb"); frecomp2 = tryOpen(tempfile4,"wb"); @@ -5932,10 +5812,6 @@ void try_recompress_bzip2(FILE* origfile, int level) { safe_fclose(&frecomp2); safe_fclose(&fdecomp); - //DEBUG - //system("copy temp3.dat recomp3.dat"); - //system("copy temp4.dat recomp4.dat"); - frecomp2 = tryOpen(tempfile4,"rb"); } else { // tempfile4 would be the same as tempfile2a, no need to recompress again frecomp2 = tryOpen(tempfile2a,"rb"); @@ -5978,15 +5854,15 @@ void write_header() { fprintf(fout, "PCF"); - //Version number + // version number fputc(V_MAJOR, fout); fputc(V_MINOR, fout); fputc(V_MINOR2, fout); - // Compression-on-the-fly method used + // compression-on-the-fly method used fputc(compression_otf_method, fout); - //Write input file name without path + // write input file name without path char* last_backslash = strrchr(input_file_name, PATH_DELIM); if (last_backslash != NULL) { strcpy(input_file_name_without_path, last_backslash + 1); @@ -5999,7 +5875,7 @@ void write_header() { delete[] input_file_name_without_path; - // Initialize compression-on-the-fly now + // initialize compression-on-the-fly now if (compression_otf_method != 0) { init_compress_otf(); } @@ -6023,7 +5899,7 @@ bool check_for_pcf_file() { exit(1); } - // Skip compression method + // skip compression method fread(in, 1, 1, fin); string header_filename = ""; @@ -6033,10 +5909,10 @@ bool check_for_pcf_file() { if (c != 0) header_filename += c; } while (c != 0); - //Append output filename to the executable directory + // append output filename to the executable directory char exec_dir[1024]; GetModuleFileName(NULL, exec_dir, 1024); - //Truncate to get directory of executable only + // truncate to get directory of executable only char* lastslash = strrchr(exec_dir, PATH_DELIM) + 1; strcpy(lastslash, ""); header_filename = exec_dir + header_filename; @@ -6166,7 +6042,7 @@ size_t own_fwrite(const void *ptr, size_t size, size_t count, FILE* stream, int } } else { switch (compression_otf_method) { - case 1: { //bZip2 + case 1: { // bZip2 int flush, ret; unsigned have; @@ -6217,7 +6093,7 @@ size_t own_fread(void *ptr, size_t size, size_t count, FILE* stream) { return fread(ptr, size, count, stream); } else { switch (compression_otf_method) { - case 1: { //bZip2 + case 1: { // bZip2 int ret; int bytes_read = 0; @@ -6292,7 +6168,6 @@ long long compare_files_penalty(FILE* file1, FILE* file2, long long pos1, long l long long same_byte_count_penalty = 0; long long rek_same_byte_count = 0; long long rek_same_byte_count_penalty = -1; - //int old_same_byte_count = 0; long long size1, size2, minsize; long long i; bool endNow = false; @@ -6325,35 +6200,34 @@ long long compare_files_penalty(FILE* file1, FILE* file2, long long pos1, long l for (i = 0; i < minsize; i++) { if (input_bytes1[i] != input_bytes2[i]) { - same_byte_count_penalty -= 5; //4 bytes = position, 1 byte = new byte + same_byte_count_penalty -= 5; // 4 bytes = position, 1 byte = new byte - //if same_byte_count_penalty is too low, stop + // if same_byte_count_penalty is too low, stop if ((long long)(same_byte_count_penalty + (compare_end - same_byte_count)) < 0) { endNow = true; break; } - //stop, if local_penalty_bytes_len gets too big + // stop, if local_penalty_bytes_len gets too big if ((local_penalty_bytes_len + 5) >= MAX_PENALTY_BYTES) { endNow = true; break; } local_penalty_bytes_len += 5; - //Position + // position local_penalty_bytes[local_penalty_bytes_len-5] = (same_byte_count >> 24) % 256; local_penalty_bytes[local_penalty_bytes_len-4] = (same_byte_count >> 16) % 256; local_penalty_bytes[local_penalty_bytes_len-3] = (same_byte_count >> 8) % 256; local_penalty_bytes[local_penalty_bytes_len-2] = same_byte_count % 256; - //New byte + // new byte local_penalty_bytes[local_penalty_bytes_len-1] = input_bytes1[i]; } else { same_byte_count_penalty++; } same_byte_count++; - //if (!endNow) old_same_byte_count = same_byte_count; - if (same_byte_count_penalty > rek_same_byte_count_penalty) { + if (same_byte_count_penalty > rek_same_byte_count_penalty) { use_penalty_bytes = true; rek_penalty_bytes_len = local_penalty_bytes_len; @@ -6363,7 +6237,6 @@ long long compare_files_penalty(FILE* file1, FILE* file2, long long pos1, long l } } - //} while (minsize == COMP_CHUNK); } while ((minsize == COMP_CHUNK) && (!endNow)); if ((rek_penalty_bytes_len > 0) && (use_penalty_bytes)) { @@ -6373,15 +6246,6 @@ long long compare_files_penalty(FILE* file1, FILE* file2, long long pos1, long l penalty_bytes_len = 0; } - - /*if (old_same_byte_count != rek_same_byte_count) { - printf("old_same_byte_count: %i, rek_same_byte_count: %i\n", old_same_byte_count, rek_same_byte_count); - printf("penalty_bytes_len: %i\n\n", penalty_bytes_len); - if (old_same_byte_count > rek_same_byte_count) exit(0); - }*/ - - //return old_same_byte_count; - return rek_same_byte_count; } @@ -6398,10 +6262,10 @@ void try_decompression_gzip(int gzip_header_length) { int windowbits; - // Try to decompress at current position + // try to decompress at current position retval = try_to_decompress(fin, -15); - if (retval > 0) { //Seems to be a zLib-Stream + if (retval > 0) { // seems to be a zLib-Stream decompressed_streams_count++; decompressed_gzip_count++; @@ -6430,7 +6294,6 @@ void try_decompression_gzip(int gzip_header_length) { } } - //if ((best_identical_bytes > 4) && (best_identical_bytes < identical_bytes_decomp)) { if ((best_identical_bytes > min_ident_size) && (best_identical_bytes < identical_bytes_decomp)) { recompressed_streams_count++; recompressed_gzip_count++; @@ -6459,15 +6322,15 @@ void try_decompression_gzip(int gzip_header_length) { } } - //End uncompressed data + // end uncompressed data compressed_data_found = true; end_uncompressed_data(); - //Check recursion + // check recursion recursion_result r = recursion_compress(best_identical_bytes, best_identical_bytes_decomp); - //Write compressed data header (GZip) without 2 first bytes + // write compressed data header (GZip) without 2 first bytes int header_byte = 1 + (best_compression << 2); if (best_penalty_bytes_len != 0) { @@ -6477,7 +6340,7 @@ void try_decompression_gzip(int gzip_header_length) { header_byte += 128; } fout_fputc(header_byte); - fout_fputc(2); //GZip + fout_fputc(2); // GZip fout_fputc((((-windowbits) - 8) << 4) + best_mem_level); gzip_header_length -= 2; @@ -6488,7 +6351,7 @@ void try_decompression_gzip(int gzip_header_length) { own_fwrite(in_buf + cb + 2, 1, gzip_header_length, fout); - //Store penalty bytes, if any + // store penalty bytes, if any if (best_penalty_bytes_len != 0) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); @@ -6523,7 +6386,7 @@ void try_decompression_gzip(int gzip_header_length) { fout_fputc(r.file_length % 256); } - //Write decompressed data + // write decompressed data if (r.success) { write_decompressed_data(r.file_length, r.file_name); remove(r.file_name); @@ -6532,9 +6395,9 @@ void try_decompression_gzip(int gzip_header_length) { write_decompressed_data(best_identical_bytes_decomp); } - //Start new uncompressed data + // start new uncompressed data - //Set input file pointer after recompressed data + // set input file pointer after recompressed data input_file_pos += best_identical_bytes - 1; cb += best_identical_bytes - 1; @@ -6560,10 +6423,10 @@ void try_decompression_png (int windowbits) { real_identical_bytes = -1; final_compression_found = false; - // Try to decompress at current position + // try to decompress at current position retval = try_to_decompress(fin, windowbits); - if (retval > 0) { //Seems to be a zLib-Stream + if (retval > 0) { // seems to be a zLib-Stream decompressed_streams_count++; decompressed_png_count++; @@ -6590,7 +6453,6 @@ void try_decompression_png (int windowbits) { if (final_compression_found) break; } - //if ((best_identical_bytes > 4) && (best_identical_bytes < identical_bytes_decomp)) { if ((best_identical_bytes > min_ident_size) && (best_identical_bytes < identical_bytes_decomp)) { recompressed_streams_count++; recompressed_png_count++; @@ -6618,28 +6480,28 @@ void try_decompression_png (int windowbits) { } } - //End uncompressed data + // end uncompressed data compressed_data_found = true; end_uncompressed_data(); - //Write compressed data header (PNG) + // write compressed data header (PNG) if (best_penalty_bytes_len == 0) { fout_fputc(1 + (best_compression << 2)); } else { fout_fputc(1 + 2 + (best_compression << 2)); } - fout_fputc(3); //PNG + fout_fputc(3); // PNG fout_fputc((((-windowbits) - 8) << 4) + best_mem_level); - //Store zLib header, but increased by 1 to prevent finding it - // again in the next pass + // store zLib header, but increased by 1 to prevent finding it + // again in the next pass own_fwrite(zlib_header, 1, 1, fout); unsigned char incchar = *(zlib_header + 1) + 1; fout_fputc(incchar); - //Store penalty bytes, if any + // store penalty bytes, if any if (best_penalty_bytes_len != 0) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); @@ -6663,13 +6525,13 @@ void try_decompression_png (int windowbits) { fout_fputc((best_identical_bytes_decomp >> 8) % 256); fout_fputc(best_identical_bytes_decomp % 256); - //Write decompressed data + // write decompressed data write_decompressed_data(best_identical_bytes_decomp); - //Start new uncompressed data + // start new uncompressed data - //Set input file pointer after recompressed data + // set input file pointer after recompressed data input_file_pos += best_identical_bytes - 1; cb += best_identical_bytes - 1; @@ -6695,10 +6557,10 @@ void try_decompression_png_multi(int windowbits) { real_identical_bytes = -1; final_compression_found = false; - // Try to decompress at current position + // try to decompress at current position retval = try_to_decompress(fpng, windowbits); - if (retval > 0) { //Seems to be a zLib-Stream + if (retval > 0) { // seems to be a zLib-Stream decompressed_streams_count++; decompressed_png_multi_count++; @@ -6725,7 +6587,6 @@ void try_decompression_png_multi(int windowbits) { if (final_compression_found) break; } - //if ((best_identical_bytes > 4) && (best_identical_bytes < identical_bytes_decomp)) { if ((best_identical_bytes > min_ident_size) && (best_identical_bytes < identical_bytes_decomp)) { recompressed_streams_count++; recompressed_png_multi_count++; @@ -6753,28 +6614,28 @@ void try_decompression_png_multi(int windowbits) { } } - //End uncompressed data + // end uncompressed data compressed_data_found = true; end_uncompressed_data(); - //Write compressed data header (PNG) + // write compressed data header (PNG) if (best_penalty_bytes_len == 0) { fout_fputc(1 + (best_compression << 2)); } else { fout_fputc(1 + 2 + (best_compression << 2)); } - fout_fputc(4); //PNG multi + fout_fputc(4); // PNG multi fout_fputc((((-windowbits) - 8) << 4) + best_mem_level); - //Store zLib header, but increased by 1 to prevent finding it - // again in the next pass + // store zLib header, but increased by 1 to prevent finding it + // again in the next pass own_fwrite(zlib_header, 1, 1, fout); unsigned char incchar = *(zlib_header + 1) + 1; fout_fputc(incchar); - //Simulate IDAT write to get IDAT pairs count + // simulate IDAT write to get IDAT pairs count int i = 1; int idat_pos = idat_lengths[0] - 2; unsigned int idat_pairs_written_count = 0; @@ -6788,17 +6649,17 @@ void try_decompression_png_multi(int windowbits) { i++; } while (i < idat_count); } - //Store IDAT pairs count + // store IDAT pairs count fout_fputc((idat_pairs_written_count >> 8) % 256); fout_fputc(idat_pairs_written_count % 256); - //Store IDAT CRCs and lengths + // store IDAT CRCs and lengths fout_fputc((idat_lengths[0] >> 24) % 256); fout_fputc((idat_lengths[0] >> 16) % 256); fout_fputc((idat_lengths[0] >> 8) % 256); fout_fputc(idat_lengths[0] % 256); - //Store IDAT CRCs and lengths + // store IDAT CRCs and lengths i = 1; idat_pos = idat_lengths[0] - 2; idat_pairs_written_count = 0; @@ -6823,7 +6684,7 @@ void try_decompression_png_multi(int windowbits) { } while (i < idat_count); } - //Store penalty bytes, if any + // store penalty bytes, if any if (best_penalty_bytes_len != 0) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); @@ -6847,16 +6708,16 @@ void try_decompression_png_multi(int windowbits) { fout_fputc((best_identical_bytes_decomp >> 8) % 256); fout_fputc(best_identical_bytes_decomp % 256); - //Write decompressed data + // write decompressed data write_decompressed_data(best_identical_bytes_decomp); - //Start new uncompressed data + // start new uncompressed data - //Set input file pointer after recompressed data + // set input file pointer after recompressed data input_file_pos += best_identical_bytes - 1; cb += best_identical_bytes - 1; - //Now add IDAT chunk overhead + // now add IDAT chunk overhead input_file_pos += (idat_pairs_written_count * 12); cb += (idat_pairs_written_count * 12); @@ -6871,7 +6732,7 @@ void try_decompression_png_multi(int windowbits) { } -//GIF functions +// GIF functions bool newgif_may_write; FILE* frecompress_gif = NULL; @@ -6991,7 +6852,7 @@ bool recompress_gif(FILE* srcfile, FILE* dstfile, unsigned char block_size, GifC long long dstfile_pos = tell_64(dstfile); seek_64(dstfile, 0); - //Change PGF8xa to GIF8xa + // change PGF8xa to GIF8xa fputc('G', dstfile); fputc('I', dstfile); seek_64(dstfile, dstfile_pos); @@ -7011,7 +6872,7 @@ bool recompress_gif(FILE* srcfile, FILE* dstfile, unsigned char block_size, GifC own_fread(&ScreenBuff[i][Col], 1, Width, srcfile); } - // This does send a clear code, so we pass g and gd + // this does send a clear code, so we pass g and gd EGifPutImageDesc(newGifFile, g, gd, Row, Col, Width, Height, myGifFile->Image.Interlace, myGifFile->Image.ColorMap); newgif_may_write = true; @@ -7142,7 +7003,7 @@ bool decompress_gif(FILE* srcfile, FILE* dstfile, long long src_pos, int& gif_le long long dstfile_pos = tell_64(dstfile); seek_64(dstfile, 0); - //Change GIF8xa to PGF8xa + // change GIF8xa to PGF8xa fputc('P', dstfile); fputc('G', dstfile); seek_64(dstfile, dstfile_pos); @@ -7189,13 +7050,13 @@ bool decompress_gif(FILE* srcfile, FILE* dstfile, long long src_pos, int& gif_le delete[] ScreenBuff; } DGifCloseFile(myGifFile); - //TODO: If this fails, write as much rows to dstfile - // as possible to support second decompression. + // TODO: If this fails, write as much rows to dstfile + // as possible to support second decompression. return false; } } } - //Write to dstfile + // write to dstfile for (i = Row; i < (Row + Height); i++) { own_fwrite(&ScreenBuff[i][Col], 1, Width, dstfile); } @@ -7211,7 +7072,7 @@ bool decompress_gif(FILE* srcfile, FILE* dstfile, long long src_pos, int& gif_le DGifCloseFile(myGifFile); return false; } - //Write to dstfile + // write to dstfile own_fwrite(&ScreenBuff[i][Col], 1, Width, dstfile); } } @@ -7296,7 +7157,7 @@ void try_decompression_gif(unsigned char version[5]) { seek_64(fin, input_file_pos); - //Read GIF file + // read GIF file ftempout = tryOpen(tempfile1, "wb"); if (!decompress_gif(fin, ftempout, input_file_pos, gif_length, decomp_length, block_size, &gCode)) { @@ -7324,7 +7185,6 @@ void try_decompression_gif(unsigned char version[5]) { safe_fclose(&ftempout); frecomp = tryOpen(tempfile2,"rb"); - //best_identical_bytes = compare_files(fin, frecomp, input_file_pos, 0); best_identical_bytes = compare_files_penalty(fin, frecomp, input_file_pos, 0); safe_fclose(&frecomp); @@ -7338,14 +7198,14 @@ void try_decompression_gif(unsigned char version[5]) { int decomp_length2 = -1; unsigned char block_size2 = 255; - //Shorten temp2.dat to the identical bytes + // shorten temp2.dat to the identical bytes frecomp = tryOpen(tempfile2,"rb"); fident = tryOpen(tempfile2a, "wb"); fast_copy(frecomp, fident, best_identical_bytes); safe_fclose(&fident); safe_fclose(&frecomp); - //Decompress temp2.dat to temp3.dat for comparison with temp1.dat + // decompress temp2.dat to temp3.dat for comparison with temp1.dat fident = tryOpen(tempfile2a,"rb"); fseek(fident, 0, SEEK_SET); @@ -7355,7 +7215,7 @@ void try_decompression_gif(unsigned char version[5]) { GifCodeFree(&gCode); GifCodeInit(&gCode); decompress_gif(fident, fdecomp, 0, gif_length2, decomp_length2, block_size2, &gCode); - // Do not exit on failure as the GIF file was shortened, so + // do not exit on failure as the GIF file was shortened, so // we surely can't succeed in decompression safe_fclose(&fdecomp); @@ -7374,7 +7234,7 @@ void try_decompression_gif(unsigned char version[5]) { printf ("Identical decompressed bytes: %i of %i\n", identical_bytes_decomp, ftempout_size); } - //Recompress temp3.dat for comparison with input file + // recompress temp3.dat for comparison with input file GifDiffFree(&gDiff); GifDiffInit(&gDiff); @@ -7385,10 +7245,6 @@ void try_decompression_gif(unsigned char version[5]) { safe_fclose(&frecomp2); safe_fclose(&fdecomp); - //DEBUG - //system("copy temp3.dat recomp3.dat"); - //system("copy temp4.dat recomp4.dat"); - frecomp2 = tryOpen(tempfile4,"rb"); real_identical_bytes = compare_files_penalty(fin, frecomp2, input_file_pos, 0); if (DEBUG_MODE) { @@ -7419,12 +7275,12 @@ void try_decompression_gif(unsigned char version[5]) { best_penalty_bytes_len = 0; } - //End uncompressed data + // end uncompressed data compressed_data_found = true; end_uncompressed_data(); - //Write compressed data header (GIF) + // write compressed data header (GIF) unsigned char add_bits = 0; if (best_penalty_bytes_len != 0) add_bits += 2; @@ -7432,9 +7288,9 @@ void try_decompression_gif(unsigned char version[5]) { if (recompress_success_needed) add_bits += 128; fout_fputc(1 + add_bits); - fout_fputc(5); //GIF + fout_fputc(5); // GIF - //Store diff bytes + // store diff bytes fout_fputc((gDiff.GIFDiffIndex >> 24) % 256); fout_fputc((gDiff.GIFDiffIndex >> 16) % 256); fout_fputc((gDiff.GIFDiffIndex >> 8) % 256); @@ -7447,7 +7303,7 @@ void try_decompression_gif(unsigned char version[5]) { fout_fputc(gDiff.GIFDiff[dbc]); } - //Store penalty bytes, if any + // store penalty bytes, if any if (best_penalty_bytes_len != 0) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); @@ -7473,13 +7329,13 @@ void try_decompression_gif(unsigned char version[5]) { fout_fputc((decomp_length >> 8) % 256); fout_fputc(decomp_length % 256); - //Write decompressed data + // write decompressed data write_decompressed_data(decomp_length); - //Start new uncompressed data + // start new uncompressed data - //Set input file pointer after recompressed data + // set input file pointer after recompressed data input_file_pos += gif_length - 1; cb += gif_length - 1; @@ -7499,14 +7355,12 @@ void try_decompression_gif(unsigned char version[5]) { GifDiffFree(&gDiff); GifCodeFree(&gCode); - //exit(0); //Use this to have a look at ~temp1.dat and ~temp2.dat - remove(tempfile2); remove(tempfile1); } -//JPEG routines +// JPG routines void packjpg_mp3_dll_msg() { @@ -7530,18 +7384,18 @@ void try_decompression_jpg (long long jpg_length, bool progressive_jpg) { printf (", length "); print64(jpg_length); printf ("\n"); - // Do not recompress non-progressive JPGs when prog_only is set + // do not recompress non-progressive JPGs when prog_only is set if ((!progressive_jpg) && (prog_only)) { printf("Skipping (only progressive JPGs mode set)\n"); } } - // Do not recompress non-progressive JPGs when prog_only is set + // do not recompress non-progressive JPGs when prog_only is set if ((!progressive_jpg) && (prog_only)) return; bool jpg_success = false; - // Try to decompress at current position + // try to decompress at current position fjpg = tryOpen(tempfile0,"wb"); seek_64(fin, input_file_pos); fast_copy(fin, fjpg, jpg_length); @@ -7562,7 +7416,7 @@ void try_decompression_jpg (long long jpg_length, bool progressive_jpg) { if ((!recompress_success) && (strncmp(msg, "huffman table missing", 21) == 0) && (use_mjpeg)) { if (DEBUG_MODE) printf ("huffman table missing, trying to use Motion JPEG DHT\n"); - // Search 0xFF 0xDA, insert MJPGDHT (MJPGDHT_LEN bytes) + // search 0xFF 0xDA, insert MJPGDHT (MJPGDHT_LEN bytes) fjpg = tryOpen(tempfile0,"rb"); bool found_ffda = false; bool found_ff = false; @@ -7582,7 +7436,7 @@ void try_decompression_jpg (long long jpg_length, bool progressive_jpg) { fdecomp = tryOpen(tempfile3,"wb"); seek_64(fjpg, 0); fast_copy(fjpg, fdecomp, ffda_pos - 1); - // Insert MJPGDHT + // insert MJPGDHT own_fwrite(MJPGDHT, 1, MJPGDHT_LEN, fdecomp); seek_64(fjpg, ffda_pos - 1); fast_copy(fjpg, fdecomp, jpg_length - (ffda_pos - 1)); @@ -7633,19 +7487,19 @@ void try_decompression_jpg (long long jpg_length, bool progressive_jpg) { printf("Best match: %i bytes, recompressed to %i bytes\n", best_identical_bytes, best_identical_bytes_decomp); } - //End uncompressed data + // end uncompressed data compressed_data_found = true; end_uncompressed_data(); - //Write compressed data header (JPG) + // write compressed data header (JPG) if (mjpg_dht_used) { - fout_fputc(1 + 4); //No penalty bytes, Motion JPG DHT used + fout_fputc(1 + 4); // no penalty bytes, Motion JPG DHT used } else { - fout_fputc(1); //No penalty bytes + fout_fputc(1); // no penalty bytes } - fout_fputc(6); //JPG + fout_fputc(6); // JPG fout_fputc((best_identical_bytes >> 24) % 256); fout_fputc((best_identical_bytes >> 16) % 256); @@ -7657,12 +7511,12 @@ void try_decompression_jpg (long long jpg_length, bool progressive_jpg) { fout_fputc((best_identical_bytes_decomp >> 8) % 256); fout_fputc(best_identical_bytes_decomp % 256); - //Write compressed JPG + // write compressed JPG write_decompressed_data(best_identical_bytes_decomp); - //Start new uncompressed data + // start new uncompressed data - //Set input file pointer after recompressed data + // set input file pointer after recompressed data input_file_pos += best_identical_bytes - 1; cb += best_identical_bytes - 1; @@ -7687,14 +7541,14 @@ void try_decompression_mp3 (long long mp3_length) { bool mp3_success = false; - // Try to decompress at current position + // try to decompress at current position fmp3 = tryOpen(tempfile0,"wb"); seek_64(fin, input_file_pos); fast_copy(fin, fmp3, mp3_length); safe_fclose(&fmp3); remove(tempfile1); - // Workaround for bugs, similar to packJPG. + // workaround for bugs, similar to packJPG FILE* fworkaround = tryOpen(tempfile1,"wb"); safe_fclose(&fworkaround); @@ -7735,15 +7589,15 @@ void try_decompression_mp3 (long long mp3_length) { printf("Best match: %i bytes, recompressed to %i bytes\n", best_identical_bytes, best_identical_bytes_decomp); } - //End uncompressed data + // end uncompressed data compressed_data_found = true; end_uncompressed_data(); - //Write compressed data header (MP3) + // write compressed data header (MP3) - fout_fputc(1); //No penalty bytes - fout_fputc(10); //MP3 + fout_fputc(1); // no penalty bytes + fout_fputc(10); // MP3 fout_fputc((best_identical_bytes >> 24) % 256); fout_fputc((best_identical_bytes >> 16) % 256); @@ -7755,12 +7609,12 @@ void try_decompression_mp3 (long long mp3_length) { fout_fputc((best_identical_bytes_decomp >> 8) % 256); fout_fputc(best_identical_bytes_decomp % 256); - //Write compressed MP3 + // write compressed MP3 write_decompressed_data(best_identical_bytes_decomp); - //Start new uncompressed data + // start new uncompressed data - //Set input file pointer after recompressed data + // set input file pointer after recompressed data input_file_pos += best_identical_bytes - 1; cb += best_identical_bytes - 1; @@ -7783,10 +7637,10 @@ void try_decompression_zlib(int windowbits) { real_identical_bytes = -1; final_compression_found = false; - // Try to decompress at current position + // try to decompress at current position retval = try_to_decompress(fin, windowbits); - if (retval > 0) { //Seems to be a zLib-Stream + if (retval > 0) { // seems to be a zLib-Stream decompressed_streams_count++; decompressed_zlib_count++; @@ -7825,7 +7679,6 @@ void try_decompression_zlib(int windowbits) { if (final_compression_found) break; } - //if ((best_identical_bytes > 4) && (best_identical_bytes < identical_bytes_decomp)) { if ((best_identical_bytes > min_ident_size_slow_brute_mode) && (best_identical_bytes < identical_bytes_decomp)) { recompressed_streams_count++; recompressed_zlib_count++; @@ -7853,15 +7706,15 @@ void try_decompression_zlib(int windowbits) { } } - //End uncompressed data + // end uncompressed data compressed_data_found = true; end_uncompressed_data(); - //Check recursion + // check recursion recursion_result r = recursion_compress(best_identical_bytes, best_identical_bytes_decomp); - //Write compressed data header (zLib) + // write compressed data header (zLib) int header_byte = 1 + (best_compression << 2); if (best_penalty_bytes_len != 0) { @@ -7871,16 +7724,16 @@ void try_decompression_zlib(int windowbits) { header_byte += 128; } fout_fputc(header_byte); - fout_fputc(255); //raw zLib + fout_fputc(255); // raw zLib fout_fputc((((-windowbits) - 8) << 4) + best_mem_level); - //Store zLib header, but increased by 1 to prevent finding it - // again in the next pass + // store zLib header, but increased by 1 to prevent finding it + // again in the next pass own_fwrite(in_buf + cb, 1, 1, fout); unsigned char incchar = *(in_buf + cb + 1) + 1; fout_fputc(incchar); - //Store penalty bytes, if any + // store penalty bytes, if any if (best_penalty_bytes_len != 0) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); @@ -7915,7 +7768,7 @@ void try_decompression_zlib(int windowbits) { fout_fputc(r.file_length % 256); } - // Write decompressed data + // write decompressed data if (r.success) { write_decompressed_data(r.file_length, r.file_name); remove(r.file_name); @@ -7924,9 +7777,9 @@ void try_decompression_zlib(int windowbits) { write_decompressed_data(best_identical_bytes_decomp); } - //Start new uncompressed data + // start new uncompressed data - //Set input file pointer after recompressed data + // set input file pointer after recompressed data input_file_pos += best_identical_bytes - 1; cb += best_identical_bytes - 1; @@ -7954,10 +7807,10 @@ void try_decompression_brute() { int windowbits; - // Try to decompress at current position + // try to decompress at current position retval = try_to_decompress(fin, -15); - if (retval > 0) { //Seems to be a zLib-Stream + if (retval > 0) { // seems to be a zLib-Stream decompressed_streams_count++; decompressed_brute_count++; @@ -7998,7 +7851,6 @@ void try_decompression_brute() { } } - //if ((best_identical_bytes > 4) && (best_identical_bytes < identical_bytes_decomp)) { if ((best_identical_bytes > min_ident_size_slow_brute_mode) && (best_identical_bytes < best_identical_bytes_decomp)) { recompressed_streams_count++; recompressed_brute_count++; @@ -8027,15 +7879,15 @@ void try_decompression_brute() { } } - //End uncompressed data + // end uncompressed data compressed_data_found = true; end_uncompressed_data(); - //Check recursion + // check recursion recursion_result r = recursion_compress(best_identical_bytes, best_identical_bytes_decomp); - //Write compressed data header (brute) + // write compressed data header (brute) int header_byte = 1 + (best_compression << 2); if (best_penalty_bytes_len != 0) { @@ -8045,10 +7897,10 @@ void try_decompression_brute() { header_byte += 128; } fout_fputc(header_byte); - fout_fputc(254); //brute + fout_fputc(254); // brute fout_fputc((((-windowbits) - 8) << 4) + best_mem_level); - //Store penalty bytes, if any + // store penalty bytes, if any if (best_penalty_bytes_len != 0) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); @@ -8083,7 +7935,7 @@ void try_decompression_brute() { fout_fputc(r.file_length % 256); } - // Write decompressed data + // write decompressed data if (r.success) { write_decompressed_data(r.file_length, r.file_name); remove(r.file_name); @@ -8092,7 +7944,7 @@ void try_decompression_brute() { write_decompressed_data(best_identical_bytes_decomp); } - //Set input file pointer after recompressed data + // set input file pointer after recompressed data input_file_pos += best_identical_bytes - 1; cb += best_identical_bytes - 1; @@ -8118,10 +7970,10 @@ void try_decompression_swf(int windowbits, char swf_version) { real_identical_bytes = -1; final_compression_found = false; - // Try to decompress at current position + // try to decompress at current position retval = try_to_decompress(fin, windowbits); - if (retval > 0) { //Seems to be a zLib-Stream + if (retval > 0) { // seems to be a zLib-Stream decompressed_streams_count++; decompressed_swf_count++; @@ -8150,7 +8002,6 @@ void try_decompression_swf(int windowbits, char swf_version) { if (final_compression_found) break; } - //if ((best_identical_bytes > 4) && (best_identical_bytes < identical_bytes_decomp)) { if ((best_identical_bytes > min_ident_size) && (best_identical_bytes < identical_bytes_decomp)) { recompressed_streams_count++; recompressed_swf_count++; @@ -8178,15 +8029,15 @@ void try_decompression_swf(int windowbits, char swf_version) { } } - //End uncompressed data + // end uncompressed data compressed_data_found = true; end_uncompressed_data(); - //Check recursion + // check recursion recursion_result r = recursion_compress(best_identical_bytes, best_identical_bytes_decomp); - //Write compressed data header (SWF) + // write compressed data header (SWF) int header_byte = 1 + (best_compression << 2); if (best_penalty_bytes_len != 0) { @@ -8201,16 +8052,16 @@ void try_decompression_swf(int windowbits, char swf_version) { fout_fputc(swf_version); - // Store length from SWF header + // store length from SWF header own_fwrite(in_buf + cb + 4, 1, 4, fout); - //Store zLib header, but increased by 1 to prevent finding it - // again in the next pass + // store zLib header, but increased by 1 to prevent finding it + // again in the next pass own_fwrite(in_buf + cb + 8, 1, 1, fout); unsigned char incchar = *(in_buf + cb + 9) + 1; fout_fputc(incchar); - //Store penalty bytes, if any + // store penalty bytes, if any if (best_penalty_bytes_len != 0) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); @@ -8245,7 +8096,7 @@ void try_decompression_swf(int windowbits, char swf_version) { fout_fputc(r.file_length % 256); } - // Write decompressed data + // write decompressed data if (r.success) { write_decompressed_data(r.file_length, r.file_name); remove(r.file_name); @@ -8254,9 +8105,9 @@ void try_decompression_swf(int windowbits, char swf_version) { write_decompressed_data(best_identical_bytes_decomp); } - //Start new uncompressed data + // start new uncompressed data - //Set input file pointer after recompressed data + // set input file pointer after recompressed data input_file_pos += best_identical_bytes - 1; cb += best_identical_bytes - 1; @@ -8281,10 +8132,10 @@ void try_decompression_bzip2(int compression_level) { real_identical_bytes = -1; final_compression_found = false; - // Try to decompress at current position + // try to decompress at current position retval = try_to_decompress_bzip2(fin, compression_level); - if (retval > 0) { //Seems to be a zLib-Stream + if (retval > 0) { // seems to be a zLib-Stream decompressed_streams_count++; decompressed_bzip2_count++; @@ -8315,15 +8166,15 @@ void try_decompression_bzip2(int compression_level) { non_zlib_was_used = true; - //End uncompressed data + // end uncompressed data compressed_data_found = true; end_uncompressed_data(); - //Check recursion + // check recursion recursion_result r = recursion_compress(best_identical_bytes, best_identical_bytes_decomp); - //Write compressed data header (bZip2) + // write compressed data header (bZip2) int header_byte = 1; if (best_penalty_bytes_len != 0) { @@ -8336,7 +8187,7 @@ void try_decompression_bzip2(int compression_level) { fout_fputc(9); // Base64 fout_fputc(compression_level); - //Store penalty bytes, if any + // store penalty bytes, if any if (best_penalty_bytes_len != 0) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); @@ -8371,7 +8222,7 @@ void try_decompression_bzip2(int compression_level) { fout_fputc(r.file_length % 256); } - // Write decompressed data + // write decompressed data if (r.success) { write_decompressed_data(r.file_length, r.file_name); remove(r.file_name); @@ -8380,9 +8231,9 @@ void try_decompression_bzip2(int compression_level) { write_decompressed_data(best_identical_bytes_decomp); } - //Start new uncompressed data + // start new uncompressed data - //Set input file pointer after recompressed data + // set input file pointer after recompressed data input_file_pos += best_identical_bytes - 1; cb += best_identical_bytes - 1; @@ -8413,7 +8264,7 @@ unsigned char base64_char_decode(unsigned char c) { if (c == '/') return 63; if (c == '=') return 64; // padding - return 65; //invalid + return 65; // invalid } void base64_reencode(FILE* file_in, FILE* file_out, int line_count, int max_in_count, int max_byte_count) { @@ -8434,7 +8285,7 @@ void base64_reencode(FILE* file_in, FILE* file_out, int line_count, int max_in_c } remaining_bytes -= avail_in; - // Make sure avail_in mod 3 = 0, pad with 0 bytes + // make sure avail_in mod 3 = 0, pad with 0 bytes while ((avail_in % 3) != 0) { in[avail_in] = 0; avail_in++; @@ -8447,7 +8298,7 @@ void base64_reencode(FILE* file_in, FILE* file_out, int line_count, int max_in_c if (act_byte_count < max_byte_count) own_fputc(b64[a >> 2], file_out); act_byte_count++; act_line_len++; - if (act_line_len == base64_line_len[line_nr]) { // End of line, write CRLF + if (act_line_len == base64_line_len[line_nr]) { // end of line, write CRLF if (act_byte_count < max_byte_count) own_fputc(13, file_out); act_byte_count++; if (act_byte_count < max_byte_count) own_fputc(10, file_out); @@ -8459,7 +8310,7 @@ void base64_reencode(FILE* file_in, FILE* file_out, int line_count, int max_in_c if (act_byte_count < max_byte_count) own_fputc(b64[((a & 0x03) << 4) | (b >> 4)], file_out); act_byte_count++; act_line_len++; - if (act_line_len == base64_line_len[line_nr]) { // End of line, write CRLF + if (act_line_len == base64_line_len[line_nr]) { // end of line, write CRLF if (act_byte_count < max_byte_count) own_fputc(13, file_out); act_byte_count++; if (act_byte_count < max_byte_count) own_fputc(10, file_out); @@ -8471,7 +8322,7 @@ void base64_reencode(FILE* file_in, FILE* file_out, int line_count, int max_in_c if (act_byte_count < max_byte_count) own_fputc(b64[((b & 0x0F) << 2) | (c >> 6)], file_out); act_byte_count++; act_line_len++; - if (act_line_len == base64_line_len[line_nr]) { // End of line, write CRLF + if (act_line_len == base64_line_len[line_nr]) { // end of line, write CRLF if (act_byte_count < max_byte_count) own_fputc(13, file_out); act_byte_count++; if (act_byte_count < max_byte_count) own_fputc(10, file_out); @@ -8483,7 +8334,7 @@ void base64_reencode(FILE* file_in, FILE* file_out, int line_count, int max_in_c if (act_byte_count < max_byte_count) own_fputc(b64[c & 63], file_out); act_byte_count++; act_line_len++; - if (act_line_len == base64_line_len[line_nr]) { // End of line, write CRLF + if (act_line_len == base64_line_len[line_nr]) { // end of line, write CRLF if (act_byte_count < max_byte_count) own_fputc(13, file_out); act_byte_count++; if (act_byte_count < max_byte_count) own_fputc(10, file_out); @@ -8509,7 +8360,7 @@ void try_decompression_base64(int base64_header_length) { real_identical_bytes = -1; final_compression_found = false; - // Try to decode at current position + // try to decode at current position remove(tempfile1); ftempout = tryOpen(tempfile1,"wb"); seek_64(fin, input_file_pos); @@ -8531,7 +8382,7 @@ void try_decompression_base64(int base64_header_length) { do { avail_in = fread(in, 1, CHUNK, fin); for (i = 0; i < (avail_in >> 2); i++) { - // Are these valid base64 chars? + // are these valid base64 chars? for (j = (i << 2); j < ((i << 2) + 4); j++) { c = base64_char_decode(in[j]); if (c < 64) { @@ -8544,7 +8395,7 @@ void try_decompression_base64(int base64_header_length) { if ((in[j] == 13) || (in[j] == 10)) { if (in[j] == 13) { cr_count++; - if (cr_count == 2) { // Double CRLF -> base64 end + if (cr_count == 2) { // double CRLF -> base64 end stream_finished = true; break; } @@ -8607,7 +8458,7 @@ void try_decompression_base64(int base64_header_length) { if (!decoding_failed) { int line_case = -1; - // Check line case + // check line case if (line_count == 1) { line_case = 0; // one length for all lines } else { @@ -8644,7 +8495,7 @@ void try_decompression_base64(int base64_header_length) { printf ("Can be decoded to %i bytes\n", identical_bytes); } - // Try to re-encode Base64 data + // try to re-encode Base64 data ftempout = fopen(tempfile1,"rb"); if (ftempout == NULL) { @@ -8669,26 +8520,26 @@ void try_decompression_base64(int base64_header_length) { printf("Match: encoded to %i bytes\n", identical_bytes_decomp); } - //End uncompressed data + // end uncompressed data compressed_data_found = true; end_uncompressed_data(); - //Check recursion + // check recursion recursion_result r = recursion_compress(identical_bytes_decomp, identical_bytes); - //Write compressed data header (Base64) + // write compressed data header (Base64) int header_byte = 1 + (line_case << 2); if (r.success) { header_byte += 128; } fout_fputc(header_byte); - fout_fputc(8); //Base64 + fout_fputc(8); // Base64 fout_fputc((base64_header_length >> 8) % 256); fout_fputc(base64_header_length % 256); - //Write "header", but change first char to prevent re-detection + // write "header", but change first char to prevent re-detection fout_fputc(in_buf[cb] - 1); own_fwrite(in_buf + cb + 1, 1, base64_header_length - 1, fout); @@ -8724,7 +8575,7 @@ void try_decompression_base64(int base64_header_length) { fout_fputc(r.file_length % 256); } - //Write decompressed data + // write decompressed data if (r.success) { write_decompressed_data(r.file_length, r.file_name); remove(r.file_name); @@ -8733,9 +8584,9 @@ void try_decompression_base64(int base64_header_length) { write_decompressed_data(identical_bytes); } - //Start new uncompressed data + // start new uncompressed data - //Set input file pointer after recompressed data + // set input file pointer after recompressed data input_file_pos += identical_bytes_decomp - 1; cb += identical_bytes_decomp - 1; } else { @@ -8751,7 +8602,7 @@ void try_decompression_base64(int base64_header_length) { #ifdef COMFORT void wait_for_key() { printf("\nPress any key to continue\n"); - //Wait for key + // wait for key do { } while (!kbhit()); } @@ -8783,7 +8634,7 @@ void error(int error_nr) { break; case ERR_DISK_FULL: printf("There is not enough space on disk"); - // Delete output file + // delete output file safe_fclose(&fout); remove(output_file_name); break; @@ -8850,7 +8701,6 @@ long long fileSize64(char* filename) { #ifndef LINUX unsigned long s1 = 0, s2 = 0; - //HANDLE h = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); #ifdef _MSC_VER HANDLE h = CreateFile(convertCharArrayToLPCWSTR(filename), 0, (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE), NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); #else @@ -8921,18 +8771,18 @@ void init_temp_files() { k /= 10; } - // Create meta file + // create meta file FILE* f = fopen(metatempfile, "wb"); safe_fclose(&f); - // Update temporary file list + // update temporary file list tempfilelist_count += 8; tempfilelist = (char*)realloc(tempfilelist, 20 * tempfilelist_count * sizeof(char)); strcpy(tempfilelist + (tempfilelist_count - 8) * 20, metatempfile); strcpy(tempfilelist + (tempfilelist_count - 7) * 20, tempfile0); strcpy(tempfilelist + (tempfilelist_count - 6) * 20, tempfile1); - // Recursion input file + // recursion input file strcpy(tempfilelist + (tempfilelist_count - 5) * 20, tempfile1); tempfilelist[(tempfilelist_count - 5) * 20 + 18] = '_'; tempfilelist[(tempfilelist_count - 5) * 20 + 19] = 0; @@ -9097,7 +8947,7 @@ recursion_result recursion_compress(int compressed_bytes, int decompressed_bytes recursion_push(); - // Shorten tempfile1 to decompressed_bytes + // shorten tempfile1 to decompressed_bytes FILE* ftempfile1 = fopen(tempfile1, "r+b"); ftruncate(fileno(ftempfile1), decompressed_bytes); fclose(ftempfile1); @@ -9124,7 +8974,7 @@ recursion_result recursion_compress(int compressed_bytes, int decompressed_bytes local_penalty_bytes = new char[MAX_PENALTY_BYTES]; best_penalty_bytes = new char[MAX_PENALTY_BYTES]; - // Disable compression-on-the-fly in recursion - we don't want compressed compressed streams + // disable compression-on-the-fly in recursion - we don't want compressed compressed streams compression_otf_method = 0; recursion_depth++; @@ -9162,7 +9012,7 @@ recursion_result recursion_compress(int compressed_bytes, int decompressed_bytes } else { if ((recursion_depth + 1) > max_recursion_depth_used) max_recursion_depth_used = (recursion_depth + 1); - // Get recursion file size + // get recursion file size tmp_r.file_length = fileSize64(tmp_r.file_name); } @@ -9205,7 +9055,7 @@ recursion_result recursion_decompress(long long recursion_data_length) { local_penalty_bytes = new char[MAX_PENALTY_BYTES]; best_penalty_bytes = new char[MAX_PENALTY_BYTES]; - // Disable compression-on-the-fly in recursion - we don't want compressed compressed streams + // disable compression-on-the-fly in recursion - we don't want compressed compressed streams compression_otf_method = 0; recursion_depth++; @@ -9221,7 +9071,7 @@ recursion_result recursion_decompress(long long recursion_data_length) { printf("Recursion end - back to recursion depth %i\n", recursion_depth); } - // Get recursion file size + // get recursion file size tmp_r.file_length = fileSize64(tmp_r.file_name); tmp_r.frecurse = fopen(tmp_r.file_name, "rb"); @@ -9252,11 +9102,11 @@ void own_fputc(char c, FILE* f) { void fout_fputc(char c) { switch (compression_otf_method) { - case 0: { //uncompressed + case 0: { // uncompressed fputc(c, fout); break; } - case 1: { //bZip2 + case 1: { // bZip2 unsigned char temp_buf[1]; temp_buf[0] = c; own_fwrite(temp_buf, 1, 1, fout); @@ -9269,11 +9119,11 @@ unsigned char fin_fgetc() { if (comp_decomp_state == P_CONVERT) compression_otf_method = conversion_from_method; switch (compression_otf_method) { - case 0: { //uncompressed + case 0: { // uncompressed return fgetc(fin); break; } - case 1: { //bZip2 + case 1: { // bZip2 unsigned char temp_buf[1]; own_fread(temp_buf, 1, 1, fin); return temp_buf[0]; @@ -9288,7 +9138,7 @@ void init_compress_otf() { if (comp_decomp_state == P_CONVERT) compression_otf_method = conversion_to_method; switch (compression_otf_method) { - case 1: { //bZip2 + case 1: { // bZip2 otf_bz2_stream_c.bzalloc = NULL; otf_bz2_stream_c.bzfree = NULL; otf_bz2_stream_c.opaque = NULL; @@ -9305,9 +9155,9 @@ void denit_compress_otf() { if (comp_decomp_state == P_CONVERT) compression_otf_method = conversion_to_method; switch (compression_otf_method) { - case 1: { //bZip2 + case 1: { // bZip2 - // Uncompressed data of length 0 ends bZip2 compress-on-the-fly data + // uncompressed data of length 0 ends bZip2 compress-on-the-fly data char final_buf[9]; for (int i = 0; i < 9; i++) { final_buf[i] = 0; @@ -9324,7 +9174,7 @@ void init_decompress_otf() { if (comp_decomp_state == P_CONVERT) compression_otf_method = conversion_from_method; switch (compression_otf_method) { - case 1: { //bZip2 + case 1: { // bZip2 otf_bz2_stream_d.bzalloc = NULL; otf_bz2_stream_d.bzfree = NULL; otf_bz2_stream_d.opaque = NULL; @@ -9344,7 +9194,7 @@ void denit_decompress_otf() { if (comp_decomp_state == P_CONVERT) compression_otf_method = conversion_from_method; switch (compression_otf_method) { - case 1: { //bZip2 + case 1: { // bZip2 (void)BZ2_bzDecompressEnd(&otf_bz2_stream_d); break; @@ -9352,7 +9202,7 @@ void denit_decompress_otf() { } } -// Get current time in ms +// get current time in ms long long get_time_ms() { #ifndef LINUX return GetTickCount(); @@ -9363,7 +9213,7 @@ long long get_time_ms() { #endif } -// Nice time output, input t in ms +// nice time output, input t in ms // 2^32 ms maximum, so will display incorrect negative values after about 49 days void printf_time(long long t) { printf("Time: "); @@ -9425,4 +9275,4 @@ void ctrl_c_handler(int sig) { (void) signal(SIGINT, SIG_DFL); error(ERR_CTRL_C); -} +} \ No newline at end of file From f5f2bbd8d490ce5095d409b2bd40dc34cf678581 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Tue, 26 Jan 2016 12:54:24 +0100 Subject: [PATCH 17/21] Helper function for try_decompression functions init_decompression_variables() --- precomp.cpp | 101 ++++++++++------------------------------------------ 1 file changed, 19 insertions(+), 82 deletions(-) diff --git a/precomp.cpp b/precomp.cpp index 27e3d8f..55e9c7b 100644 --- a/precomp.cpp +++ b/precomp.cpp @@ -203,10 +203,13 @@ void try_decompression_zlib(int windowbits); void try_decompression_brute(); void try_decompression_swf(int windowbits, char swf_version); void try_decompression_bzip2(int compression_level); +void try_decompression_base64(int gzip_header_length); +// helpers for try_decompression functions + +void init_decompression_variables(); unsigned char base64_char_decode(unsigned char c); void base64_reencode(FILE* file_in, FILE* file_out, int line_count, int max_in_count = 0x7FFFFFFF, int max_byte_count = 0x7FFFFFFF); -void try_decompression_base64(int gzip_header_length); void packjpg_mp3_dll_msg(); bool recompress_gif(FILE* srcfile, FILE* dstfile, unsigned char block_size, GifCodeStruct* g, GifDiffStruct* gd); @@ -2766,7 +2769,7 @@ int identical_bytes_decomp = -1; int real_identical_bytes = -1; bool final_compression_found = false; -void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, int img_height, int img_bpc) { +void init_decompression_variables() { identical_bytes = -1; best_identical_bytes = -1; best_compression = -1; @@ -2776,6 +2779,11 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, identical_bytes_decomp = -1; real_identical_bytes = -1; final_compression_found = false; +} + +void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, int img_height, int img_bpc) { + init_decompression_variables(); + int bmp_header_type = 0; // 0 = none, 1 = 8-bit, 2 = 24-bit // try to decompress at current position @@ -3049,14 +3057,7 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, } void try_decompression_zip(int zip_header_length) { - identical_bytes = -1; - best_identical_bytes = -1; - best_compression = -1; - best_mem_level = -1; - best_penalty_bytes_len = 0; - best_identical_bytes_decomp = -1; - identical_bytes_decomp = -1; - real_identical_bytes = -1; + init_decompression_variables(); final_compression_found = false; int windowbits; @@ -6250,15 +6251,7 @@ long long compare_files_penalty(FILE* file1, FILE* file2, long long pos1, long l } void try_decompression_gzip(int gzip_header_length) { - identical_bytes = -1; - best_identical_bytes = -1; - best_compression = -1; - best_mem_level = -1; - best_penalty_bytes_len = 0; - best_identical_bytes_decomp = -1; - identical_bytes_decomp = -1; - real_identical_bytes = -1; - final_compression_found = false; + init_decompression_variables(); int windowbits; @@ -6413,15 +6406,7 @@ void try_decompression_gzip(int gzip_header_length) { } void try_decompression_png (int windowbits) { - identical_bytes = -1; - best_identical_bytes = -1; - best_compression = -1; - best_mem_level = -1; - best_penalty_bytes_len = 0; - best_identical_bytes_decomp = -1; - identical_bytes_decomp = -1; - real_identical_bytes = -1; - final_compression_found = false; + init_decompression_variables(); // try to decompress at current position retval = try_to_decompress(fin, windowbits); @@ -6547,15 +6532,7 @@ void try_decompression_png (int windowbits) { } void try_decompression_png_multi(int windowbits) { - identical_bytes = -1; - best_identical_bytes = -1; - best_compression = -1; - best_mem_level = -1; - best_penalty_bytes_len = 0; - best_identical_bytes_decomp = -1; - identical_bytes_decomp = -1; - real_identical_bytes = -1; - final_compression_found = false; + init_decompression_variables(); // try to decompress at current position retval = try_to_decompress(fpng, windowbits); @@ -7627,15 +7604,7 @@ void try_decompression_mp3 (long long mp3_length) { } void try_decompression_zlib(int windowbits) { - identical_bytes = -1; - best_identical_bytes = -1; - best_compression = -1; - best_mem_level = -1; - best_penalty_bytes_len = 0; - best_identical_bytes_decomp = -1; - identical_bytes_decomp = -1; - real_identical_bytes = -1; - final_compression_found = false; + init_decompression_variables(); // try to decompress at current position retval = try_to_decompress(fin, windowbits); @@ -7795,15 +7764,7 @@ void try_decompression_zlib(int windowbits) { } void try_decompression_brute() { - identical_bytes = -1; - best_identical_bytes = -1; - best_compression = -1; - best_mem_level = -1; - best_penalty_bytes_len = 0; - best_identical_bytes_decomp = -1; - identical_bytes_decomp = -1; - real_identical_bytes = -1; - final_compression_found = false; + init_decompression_variables(); int windowbits; @@ -7960,15 +7921,7 @@ void try_decompression_brute() { } void try_decompression_swf(int windowbits, char swf_version) { - identical_bytes = -1; - best_identical_bytes = -1; - best_compression = -1; - best_mem_level = -1; - best_penalty_bytes_len = 0; - best_identical_bytes_decomp = -1; - identical_bytes_decomp = -1; - real_identical_bytes = -1; - final_compression_found = false; + init_decompression_variables(); // try to decompress at current position retval = try_to_decompress(fin, windowbits); @@ -8122,15 +8075,7 @@ void try_decompression_swf(int windowbits, char swf_version) { } void try_decompression_bzip2(int compression_level) { - identical_bytes = -1; - best_identical_bytes = -1; - best_compression = -1; - best_mem_level = -1; - best_penalty_bytes_len = 0; - best_identical_bytes_decomp = -1; - identical_bytes_decomp = -1; - real_identical_bytes = -1; - final_compression_found = false; + init_decompression_variables(); // try to decompress at current position retval = try_to_decompress_bzip2(fin, compression_level); @@ -8350,15 +8295,7 @@ void base64_reencode(FILE* file_in, FILE* file_out, int line_count, int max_in_c } void try_decompression_base64(int base64_header_length) { - identical_bytes = -1; - best_identical_bytes = -1; - best_compression = -1; - best_mem_level = -1; - best_penalty_bytes_len = 0; - best_identical_bytes_decomp = -1; - identical_bytes_decomp = -1; - real_identical_bytes = -1; - final_compression_found = false; + init_decompression_variables(); // try to decode at current position remove(tempfile1); From 4edb88f0b292faa8e178a35ce47fe7835538d4d3 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Tue, 9 Feb 2016 10:38:08 +0100 Subject: [PATCH 18/21] Trying to merge with new master Makefile structure --- Makefile | 44 ++++++++++++++++++++++++---------------- contrib/bzip2/Makefile | 12 +++++++++++ contrib/giflib/Makefile | 12 +++++++++++ contrib/packjpg/Makefile | 12 +++++++++++ contrib/packmp3/Makefile | 12 +++++++++++ contrib/zlib/Makefile | 12 +++++++++++ 6 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 contrib/bzip2/Makefile create mode 100644 contrib/giflib/Makefile create mode 100644 contrib/packjpg/Makefile create mode 100644 contrib/packmp3/Makefile create mode 100644 contrib/zlib/Makefile diff --git a/Makefile b/Makefile index bf5f83f..1bebab8 100644 --- a/Makefile +++ b/Makefile @@ -1,29 +1,39 @@ PROGNAME = precomp +BZIP2_OBJ = contrib/bzip2/blocksort.o contrib/bzip2/compress.o contrib/bzip2/decompress.o contrib/bzip2/randtable.o contrib/bzip2/bzlib.o contrib/bzip2/crctable.o contrib/bzip2/huffman.o +GIFLIB_OBJ = contrib/giflib/dgif_lib_gcc.o contrib/giflib/egif_lib_gcc.o contrib/giflib/gifalloc.o contrib/giflib/gif_err.o +PACKJPG_OBJ = contrib/packjpg/aricoder.o contrib/packjpg/bitops.o contrib/packjpg/packjpg.o +PACKMP3_OBJ = contrib/packmp3/huffmp3.o contrib/packmp3/packmp3.o +ZLIB_OBJ = contrib/zlib/adler32.o contrib/zlib/crc32.o contrib/zlib/zutil.o contrib/zlib/trees.o contrib/zlib/inftrees.o contrib/zlib/inffast.o contrib/zlib/inflate.o contrib/zlib/deflate.o CFLAGS = -DLINUX -D_FILE_OFFSET_BITS=64 -O2 -Wall -SRC_PACKJPG = contrib/packjpg/aricoder.cpp contrib/packjpg/bitops.cpp contrib/packjpg/packjpg.cpp -SRC_PACKMP3 = contrib/packmp3/huffmp3.cpp contrib/packmp3/packmp3.cpp -FLAGS_PACKJPG = -O3 -DUNIX -DBUILD_LIB -Wall -pedantic -funroll-loops -ffast-math -fsched-spec-load -fomit-frame-pointer -OBJ_ZLIB = contrib/zlib/adler32.o contrib/zlib/crc32.o contrib/zlib/zutil.o contrib/zlib/trees.o contrib/zlib/inftrees.o contrib/zlib/inffast.o contrib/zlib/inflate.o contrib/zlib/deflate.o -OBJ_BZIP2 = contrib/bzip2/bzlib.o contrib/bzip2/blocksort.o contrib/bzip2/crctable.o contrib/bzip2/compress.o contrib/bzip2/decompress.o contrib/bzip2/huffman.o contrib/bzip2/randtable.o -OBJ_GIFLIB = contrib/giflib/gifalloc.o contrib/giflib/gif_err.o contrib/giflib/dgif_lib_gcc.o contrib/giflib/egif_lib_gcc.o -OBJECTS = aricoder.o bitops.o packjpg.o huffmp3.o packmp3.o adler32.o crc32.o zutil.o trees.o inftrees.o inffast.o inflate.o deflate.o bzlib.o blocksort.o crctable.o compress.o decompress.o huffman.o randtable.o gifalloc.o gif_err.o dgif_lib_gcc.o egif_lib_gcc.o .PHONY: all -all: packjpg packmp3 $(PROGNAME) +all: contrib $(PROGNAME) .PHONY: clean clean: + make -C contrib/bzip2 clean + make -C contrib/giflib clean + make -C contrib/packjpg clean + make -C contrib/packmp3 clean + make -C contrib/zlib clean rm -f *.o - rm -f $(PROGNAME) -$(PROGNAME): $(OBJ_ZLIB) $(OBJ_BZIP2) $(OBJ_GIFLIB) - g++ $(CFLAGS) $(OBJECTS) precomp.cpp -s -oprecomp +bzip2: + make -C contrib/bzip2 -packjpg: $(SRC_PACKJPG) - g++ -c $(FLAGS_PACKJPG) $(SRC_PACKJPG) +giflib: + make -C contrib/giflib -packmp3: $(SRC_PACKMP3) - g++ -c $(FLAGS_PACKJPG) $(SRC_PACKMP3) +packjpg: + make -C contrib/packjpg + +packmp3: + make -C contrib/packmp3 -%.o: %.c - gcc -g -c $(CFLAGS) $< +zlib: + make -C contrib/zlib + +contrib: bzip2 giflib packjpg zlib + +$(PROGNAME): contrib + g++ $(CFLAGS) $(GIFLIB_OBJ) $(PACKJPG_OBJ) $(PACKMP3_OBJ) $(BZIP2_OBJ) $(ZLIB_OBJ) precomp.cpp -s -oprecomp diff --git a/contrib/bzip2/Makefile b/contrib/bzip2/Makefile new file mode 100644 index 0000000..2784279 --- /dev/null +++ b/contrib/bzip2/Makefile @@ -0,0 +1,12 @@ +OBJECTS = bzlib.o blocksort.o crctable.o compress.o decompress.o huffman.o randtable.o +CFLAGS = -DLINUX -D_FILE_OFFSET_BITS=64 -O2 -Wall + +.PHONY: all +all: $(OBJECTS) + +.PHONY: clean +clean: + rm -f *.o + +%.o: %.c + gcc -g -c $(CFLAGS) $< diff --git a/contrib/giflib/Makefile b/contrib/giflib/Makefile new file mode 100644 index 0000000..6b2c98e --- /dev/null +++ b/contrib/giflib/Makefile @@ -0,0 +1,12 @@ +OBJECTS = gifalloc.o gif_err.o dgif_lib_gcc.o egif_lib_gcc.o +CFLAGS = -DLINUX -D_FILE_OFFSET_BITS=64 -O2 -Wall + +.PHONY: all +all: $(OBJECTS) + +.PHONY: clean +clean: + rm -f *.o + +%.o: %.c + gcc -g -c $(CFLAGS) $< diff --git a/contrib/packjpg/Makefile b/contrib/packjpg/Makefile new file mode 100644 index 0000000..bc886fb --- /dev/null +++ b/contrib/packjpg/Makefile @@ -0,0 +1,12 @@ +OBJECTS = bitops.o aricoder.o packjpg.o +CFLAGS = -O3 -DUNIX -DBUILD_LIB -Wall -pedantic -funroll-loops -ffast-math -fsched-spec-load -fomit-frame-pointer + +.PHONY: all +all: $(OBJECTS) + +.PHONY: clean +clean: + rm -f *.o + +%.o: %.cpp + g++ -c $(CFLAGS) $< diff --git a/contrib/packmp3/Makefile b/contrib/packmp3/Makefile new file mode 100644 index 0000000..b14e163 --- /dev/null +++ b/contrib/packmp3/Makefile @@ -0,0 +1,12 @@ +OBJECTS = bitops.o aricoder.o huffmp3.o packmp3.o +CFLAGS = -O3 -DUNIX -DBUILD_LIB -Wall -pedantic -funroll-loops -ffast-math -fsched-spec-load -fomit-frame-pointer + +.PHONY: all +all: $(OBJECTS) + +.PHONY: clean +clean: + rm -f *.o + +%.o: %.cpp + g++ -c $(CFLAGS) $< diff --git a/contrib/zlib/Makefile b/contrib/zlib/Makefile new file mode 100644 index 0000000..471af0f --- /dev/null +++ b/contrib/zlib/Makefile @@ -0,0 +1,12 @@ +OBJECTS = adler32.o crc32.o zutil.o trees.o inftrees.o inffast.o inflate.o deflate.o +CFLAGS = -DLINUX -D_FILE_OFFSET_BITS=64 -O2 -Wall + +.PHONY: all +all: $(OBJECTS) + +.PHONY: clean +clean: + rm -f *.o + +%.o: %.c + gcc -g -c $(CFLAGS) $< From 0193e5da1c6f0922cc3c137d4b83688c68b107b4 Mon Sep 17 00:00:00 2001 From: schnaader Date: Tue, 9 Feb 2016 10:48:17 +0100 Subject: [PATCH 19/21] Corrected Makefiles --- Makefile | 2 +- contrib/packmp3/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1bebab8..30a58ee 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ packmp3: zlib: make -C contrib/zlib -contrib: bzip2 giflib packjpg zlib +contrib: bzip2 giflib packjpg packmp3 zlib $(PROGNAME): contrib g++ $(CFLAGS) $(GIFLIB_OBJ) $(PACKJPG_OBJ) $(PACKMP3_OBJ) $(BZIP2_OBJ) $(ZLIB_OBJ) precomp.cpp -s -oprecomp diff --git a/contrib/packmp3/Makefile b/contrib/packmp3/Makefile index b14e163..c701110 100644 --- a/contrib/packmp3/Makefile +++ b/contrib/packmp3/Makefile @@ -1,4 +1,4 @@ -OBJECTS = bitops.o aricoder.o huffmp3.o packmp3.o +OBJECTS = huffmp3.o packmp3.o CFLAGS = -O3 -DUNIX -DBUILD_LIB -Wall -pedantic -funroll-loops -ffast-math -fsched-spec-load -fomit-frame-pointer .PHONY: all From 491ebece6913560c07a559621a2f9281c4488a4b Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Sun, 14 Feb 2016 11:46:09 +0100 Subject: [PATCH 20/21] Helper functions for writing 16/24/32/64-bit values to fout --- precomp.cpp | 389 ++++++++++++++++------------------------------------ 1 file changed, 119 insertions(+), 270 deletions(-) diff --git a/precomp.cpp b/precomp.cpp index 45362a3..040c71e 100644 --- a/precomp.cpp +++ b/precomp.cpp @@ -289,6 +289,13 @@ bz_stream otf_bz2_stream_c, otf_bz2_stream_d; void own_fputc(char c, FILE* f); unsigned char fin_fgetc(); void fout_fputc(char c); +void fout_fput16(int v); +void fout_fput24(int v); +void fout_fput32_little_endian(int v); +void fout_fput32(int v); +void fout_fput32(unsigned int v); +void fout_fput64(long long v); +void fout_fput64(unsigned long long v); void init_compress_otf(); void denit_compress_otf(); void init_decompress_otf(); @@ -2740,14 +2747,7 @@ void end_uncompressed_data() { if (!uncompressed_data_in_work) return; - fout_fputc((uncompressed_length >> 56) % 256); - fout_fputc((uncompressed_length >> 48) % 256); - fout_fputc((uncompressed_length >> 40) % 256); - fout_fputc((uncompressed_length >> 32) % 256); - fout_fputc((uncompressed_length >> 24) % 256); - fout_fputc((uncompressed_length >> 16) % 256); - fout_fputc((uncompressed_length >> 8) % 256); - fout_fputc(uncompressed_length % 256); + fout_fput64(uncompressed_length); // fast copy of uncompressed data seek_64(fin, uncompressed_pos); @@ -2901,9 +2901,7 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, pdf_header_length -= 12; - fout_fputc((pdf_header_length >> 16) % 256); - fout_fputc((pdf_header_length >> 8) % 256); - fout_fputc(pdf_header_length % 256); + fout_fput24(pdf_header_length); own_fwrite(in_buf + cb + 12, 1, pdf_header_length, fout); @@ -2912,24 +2910,14 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); } - fout_fputc((best_penalty_bytes_len >> 24) % 256); - fout_fputc((best_penalty_bytes_len >> 16) % 256); - fout_fputc((best_penalty_bytes_len >> 8) % 256); - fout_fputc(best_penalty_bytes_len % 256); + fout_fput32(best_penalty_bytes_len); for (int pbc = 0; pbc < best_penalty_bytes_len; pbc++) { fout_fputc(best_penalty_bytes[pbc]); } } - fout_fputc((best_identical_bytes >> 24) % 256); - fout_fputc((best_identical_bytes >> 16) % 256); - fout_fputc((best_identical_bytes >> 8) % 256); - fout_fputc(best_identical_bytes % 256); - - fout_fputc((best_identical_bytes_decomp >> 24) % 256); - fout_fputc((best_identical_bytes_decomp >> 16) % 256); - fout_fputc((best_identical_bytes_decomp >> 8) % 256); - fout_fputc(best_identical_bytes_decomp % 256); + fout_fput32(best_identical_bytes); + fout_fput32(best_identical_bytes_decomp); // eventually write BMP header @@ -2947,10 +2935,7 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, } else { bmp_size += 54; } - fout_fputc(bmp_size % 256); - fout_fputc((bmp_size >> 8) % 256); - fout_fputc((bmp_size >> 16) % 256); - fout_fputc((bmp_size >> 24) % 256); + fout_fput32_little_endian(bmp_size); for (i = 0; i < 4; i++) { fout_fputc(0); @@ -2968,15 +2953,8 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, fout_fputc(0); fout_fputc(0); - fout_fputc(img_width % 256); - fout_fputc((img_width >> 8) % 256); - fout_fputc((img_width >> 16) % 256); - fout_fputc((img_width >> 24) % 256); - - fout_fputc(img_height % 256); - fout_fputc((img_height >> 8) % 256); - fout_fputc((img_height >> 16) % 256); - fout_fputc((img_height >> 24) % 256); + fout_fput32_little_endian(img_width); + fout_fput32_little_endian(img_height); fout_fputc(1); fout_fputc(0); @@ -2996,10 +2974,7 @@ void try_decompression_pdf(int windowbits, int pdf_header_length, int img_width, int datasize = ((img_width+3) & -4) * img_height; if (bmp_header_type == 2) datasize *= 3; - fout_fputc(datasize % 256); - fout_fputc((datasize >> 8) % 256); - fout_fputc((datasize >> 16) % 256); - fout_fputc((datasize >> 24) % 256); + fout_fput32_little_endian(datasize); for (i = 0; i < 16; i++) { fout_fputc(0); @@ -3145,9 +3120,7 @@ void try_decompression_zip(int zip_header_length) { zip_header_length -= 4; - fout_fputc((zip_header_length >> 16) % 256); - fout_fputc((zip_header_length >> 8) % 256); - fout_fputc(zip_header_length % 256); + fout_fput24(zip_header_length); own_fwrite(in_buf + cb + 4, 1, zip_header_length, fout); @@ -3156,34 +3129,17 @@ void try_decompression_zip(int zip_header_length) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); } - fout_fputc((best_penalty_bytes_len >> 24) % 256); - fout_fputc((best_penalty_bytes_len >> 16) % 256); - fout_fputc((best_penalty_bytes_len >> 8) % 256); - fout_fputc(best_penalty_bytes_len % 256); + fout_fput32(best_penalty_bytes_len); for (int pbc = 0; pbc < best_penalty_bytes_len; pbc++) { fout_fputc(best_penalty_bytes[pbc]); } } - fout_fputc((best_identical_bytes >> 24) % 256); - fout_fputc((best_identical_bytes >> 16) % 256); - fout_fputc((best_identical_bytes >> 8) % 256); - fout_fputc(best_identical_bytes % 256); - - fout_fputc((best_identical_bytes_decomp >> 24) % 256); - fout_fputc((best_identical_bytes_decomp >> 16) % 256); - fout_fputc((best_identical_bytes_decomp >> 8) % 256); - fout_fputc(best_identical_bytes_decomp % 256); + fout_fput32(best_identical_bytes); + fout_fput32(best_identical_bytes_decomp); if (r.success) { - fout_fputc((r.file_length >> 56) % 256); - fout_fputc((r.file_length >> 48) % 256); - fout_fputc((r.file_length >> 40) % 256); - fout_fputc((r.file_length >> 32) % 256); - fout_fputc((r.file_length >> 24) % 256); - fout_fputc((r.file_length >> 16) % 256); - fout_fputc((r.file_length >> 8) % 256); - fout_fputc(r.file_length % 256); + fout_fput64(r.file_length); } // write decompressed data @@ -6338,9 +6294,7 @@ void try_decompression_gzip(int gzip_header_length) { gzip_header_length -= 2; - fout_fputc((gzip_header_length >> 16) % 256); - fout_fputc((gzip_header_length >> 8) % 256); - fout_fputc(gzip_header_length % 256); + fout_fput24(gzip_header_length); own_fwrite(in_buf + cb + 2, 1, gzip_header_length, fout); @@ -6349,34 +6303,17 @@ void try_decompression_gzip(int gzip_header_length) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); } - fout_fputc((best_penalty_bytes_len >> 24) % 256); - fout_fputc((best_penalty_bytes_len >> 16) % 256); - fout_fputc((best_penalty_bytes_len >> 8) % 256); - fout_fputc(best_penalty_bytes_len % 256); + fout_fput32(best_penalty_bytes_len); for (int pbc = 0; pbc < best_penalty_bytes_len; pbc++) { fout_fputc(best_penalty_bytes[pbc]); } } - fout_fputc((best_identical_bytes >> 24) % 256); - fout_fputc((best_identical_bytes >> 16) % 256); - fout_fputc((best_identical_bytes >> 8) % 256); - fout_fputc(best_identical_bytes % 256); - - fout_fputc((best_identical_bytes_decomp >> 24) % 256); - fout_fputc((best_identical_bytes_decomp >> 16) % 256); - fout_fputc((best_identical_bytes_decomp >> 8) % 256); - fout_fputc(best_identical_bytes_decomp % 256); + fout_fput32(best_identical_bytes); + fout_fput32(best_identical_bytes_decomp); if (r.success) { - fout_fputc((r.file_length >> 56) % 256); - fout_fputc((r.file_length >> 48) % 256); - fout_fputc((r.file_length >> 40) % 256); - fout_fputc((r.file_length >> 32) % 256); - fout_fputc((r.file_length >> 24) % 256); - fout_fputc((r.file_length >> 16) % 256); - fout_fputc((r.file_length >> 8) % 256); - fout_fputc(r.file_length % 256); + fout_fput64(r.file_length); } // write decompressed data @@ -6491,24 +6428,14 @@ void try_decompression_png (int windowbits) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); } - fout_fputc((best_penalty_bytes_len >> 24) % 256); - fout_fputc((best_penalty_bytes_len >> 16) % 256); - fout_fputc((best_penalty_bytes_len >> 8) % 256); - fout_fputc(best_penalty_bytes_len % 256); + fout_fput32(best_penalty_bytes_len); for (int pbc = 0; pbc < best_penalty_bytes_len; pbc++) { fout_fputc(best_penalty_bytes[pbc]); } } - fout_fputc((best_identical_bytes >> 24) % 256); - fout_fputc((best_identical_bytes >> 16) % 256); - fout_fputc((best_identical_bytes >> 8) % 256); - fout_fputc(best_identical_bytes % 256); - - fout_fputc((best_identical_bytes_decomp >> 24) % 256); - fout_fputc((best_identical_bytes_decomp >> 16) % 256); - fout_fputc((best_identical_bytes_decomp >> 8) % 256); - fout_fputc(best_identical_bytes_decomp % 256); + fout_fput32(best_identical_bytes); + fout_fput32(best_identical_bytes_decomp); // write decompressed data @@ -6627,14 +6554,10 @@ void try_decompression_png_multi(int windowbits) { } while (i < idat_count); } // store IDAT pairs count - fout_fputc((idat_pairs_written_count >> 8) % 256); - fout_fputc(idat_pairs_written_count % 256); + fout_fput16(idat_pairs_written_count); // store IDAT CRCs and lengths - fout_fputc((idat_lengths[0] >> 24) % 256); - fout_fputc((idat_lengths[0] >> 16) % 256); - fout_fputc((idat_lengths[0] >> 8) % 256); - fout_fputc(idat_lengths[0] % 256); + fout_fput32(idat_lengths[0]); // store IDAT CRCs and lengths i = 1; @@ -6642,15 +6565,8 @@ void try_decompression_png_multi(int windowbits) { idat_pairs_written_count = 0; if (idat_pos <= best_identical_bytes) { do { - fout_fputc((idat_crcs[i] >> 24) % 256); - fout_fputc((idat_crcs[i] >> 16) % 256); - fout_fputc((idat_crcs[i] >> 8) % 256); - fout_fputc(idat_crcs[i] % 256); - - fout_fputc((idat_lengths[i] >> 24) % 256); - fout_fputc((idat_lengths[i] >> 16) % 256); - fout_fputc((idat_lengths[i] >> 8) % 256); - fout_fputc(idat_lengths[i] % 256); + fout_fput32(idat_crcs[i]); + fout_fput32(idat_lengths[i]); idat_pairs_written_count++; @@ -6666,24 +6582,14 @@ void try_decompression_png_multi(int windowbits) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); } - fout_fputc((best_penalty_bytes_len >> 24) % 256); - fout_fputc((best_penalty_bytes_len >> 16) % 256); - fout_fputc((best_penalty_bytes_len >> 8) % 256); - fout_fputc(best_penalty_bytes_len % 256); + fout_fput32(best_penalty_bytes_len); for (int pbc = 0; pbc < best_penalty_bytes_len; pbc++) { fout_fputc(best_penalty_bytes[pbc]); } } - fout_fputc((best_identical_bytes >> 24) % 256); - fout_fputc((best_identical_bytes >> 16) % 256); - fout_fputc((best_identical_bytes >> 8) % 256); - fout_fputc(best_identical_bytes % 256); - - fout_fputc((best_identical_bytes_decomp >> 24) % 256); - fout_fputc((best_identical_bytes_decomp >> 16) % 256); - fout_fputc((best_identical_bytes_decomp >> 8) % 256); - fout_fputc(best_identical_bytes_decomp % 256); + fout_fput32(best_identical_bytes); + fout_fput32(best_identical_bytes_decomp); // write decompressed data @@ -7268,10 +7174,7 @@ void try_decompression_gif(unsigned char version[5]) { fout_fputc(5); // GIF // store diff bytes - fout_fputc((gDiff.GIFDiffIndex >> 24) % 256); - fout_fputc((gDiff.GIFDiffIndex >> 16) % 256); - fout_fputc((gDiff.GIFDiffIndex >> 8) % 256); - fout_fputc(gDiff.GIFDiffIndex % 256); + fout_fput32(gDiff.GIFDiffIndex); if(DEBUG_MODE) { if (gDiff.GIFDiffIndex > 0) printf("Diff bytes were used: %i bytes\n", gDiff.GIFDiffIndex); @@ -7286,25 +7189,15 @@ void try_decompression_gif(unsigned char version[5]) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); } - fout_fputc((best_penalty_bytes_len >> 24) % 256); - fout_fputc((best_penalty_bytes_len >> 16) % 256); - fout_fputc((best_penalty_bytes_len >> 8) % 256); - fout_fputc(best_penalty_bytes_len % 256); + fout_fput32(best_penalty_bytes_len); for (int pbc = 0; pbc < best_penalty_bytes_len; pbc++) { fout_fputc(best_penalty_bytes[pbc]); } } - fout_fputc((best_identical_bytes >> 24) % 256); - fout_fputc((best_identical_bytes >> 16) % 256); - fout_fputc((best_identical_bytes >> 8) % 256); - fout_fputc(best_identical_bytes % 256); - - fout_fputc((decomp_length >> 24) % 256); - fout_fputc((decomp_length >> 16) % 256); - fout_fputc((decomp_length >> 8) % 256); - fout_fputc(decomp_length % 256); + fout_fput32(best_identical_bytes); + fout_fput32(decomp_length); // write decompressed data @@ -7478,15 +7371,8 @@ void try_decompression_jpg (long long jpg_length, bool progressive_jpg) { } fout_fputc(6); // JPG - fout_fputc((best_identical_bytes >> 24) % 256); - fout_fputc((best_identical_bytes >> 16) % 256); - fout_fputc((best_identical_bytes >> 8) % 256); - fout_fputc(best_identical_bytes % 256); - - fout_fputc((best_identical_bytes_decomp >> 24) % 256); - fout_fputc((best_identical_bytes_decomp >> 16) % 256); - fout_fputc((best_identical_bytes_decomp >> 8) % 256); - fout_fputc(best_identical_bytes_decomp % 256); + fout_fput32(best_identical_bytes); + fout_fput32(best_identical_bytes_decomp); // write compressed JPG write_decompressed_data(best_identical_bytes_decomp); @@ -7576,15 +7462,8 @@ void try_decompression_mp3 (long long mp3_length) { fout_fputc(1); // no penalty bytes fout_fputc(10); // MP3 - fout_fputc((best_identical_bytes >> 24) % 256); - fout_fputc((best_identical_bytes >> 16) % 256); - fout_fputc((best_identical_bytes >> 8) % 256); - fout_fputc(best_identical_bytes % 256); - - fout_fputc((best_identical_bytes_decomp >> 24) % 256); - fout_fputc((best_identical_bytes_decomp >> 16) % 256); - fout_fputc((best_identical_bytes_decomp >> 8) % 256); - fout_fputc(best_identical_bytes_decomp % 256); + fout_fputc(best_identical_bytes); + fout_fputc(best_identical_bytes_decomp); // write compressed MP3 write_decompressed_data(best_identical_bytes_decomp); @@ -7707,34 +7586,17 @@ void try_decompression_zlib(int windowbits) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); } - fout_fputc((best_penalty_bytes_len >> 24) % 256); - fout_fputc((best_penalty_bytes_len >> 16) % 256); - fout_fputc((best_penalty_bytes_len >> 8) % 256); - fout_fputc(best_penalty_bytes_len % 256); + fout_fput32(best_penalty_bytes_len); for (int pbc = 0; pbc < best_penalty_bytes_len; pbc++) { fout_fputc(best_penalty_bytes[pbc]); } } - fout_fputc((best_identical_bytes >> 24) % 256); - fout_fputc((best_identical_bytes >> 16) % 256); - fout_fputc((best_identical_bytes >> 8) % 256); - fout_fputc(best_identical_bytes % 256); - - fout_fputc((best_identical_bytes_decomp >> 24) % 256); - fout_fputc((best_identical_bytes_decomp >> 16) % 256); - fout_fputc((best_identical_bytes_decomp >> 8) % 256); - fout_fputc(best_identical_bytes_decomp % 256); + fout_fputc(best_identical_bytes); + fout_fputc(best_identical_bytes_decomp); if (r.success) { - fout_fputc((r.file_length >> 56) % 256); - fout_fputc((r.file_length >> 48) % 256); - fout_fputc((r.file_length >> 40) % 256); - fout_fputc((r.file_length >> 32) % 256); - fout_fputc((r.file_length >> 24) % 256); - fout_fputc((r.file_length >> 16) % 256); - fout_fputc((r.file_length >> 8) % 256); - fout_fputc(r.file_length % 256); + fout_fput64(r.file_length); } // write decompressed data @@ -7866,34 +7728,17 @@ void try_decompression_brute() { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); } - fout_fputc((best_penalty_bytes_len >> 24) % 256); - fout_fputc((best_penalty_bytes_len >> 16) % 256); - fout_fputc((best_penalty_bytes_len >> 8) % 256); - fout_fputc(best_penalty_bytes_len % 256); + fout_fput32(best_penalty_bytes_len); for (int pbc = 0; pbc < best_penalty_bytes_len; pbc++) { fout_fputc(best_penalty_bytes[pbc]); } } - fout_fputc((best_identical_bytes >> 24) % 256); - fout_fputc((best_identical_bytes >> 16) % 256); - fout_fputc((best_identical_bytes >> 8) % 256); - fout_fputc(best_identical_bytes % 256); - - fout_fputc((best_identical_bytes_decomp >> 24) % 256); - fout_fputc((best_identical_bytes_decomp >> 16) % 256); - fout_fputc((best_identical_bytes_decomp >> 8) % 256); - fout_fputc(best_identical_bytes_decomp % 256); + fout_fput32(best_identical_bytes); + fout_fput32(best_identical_bytes_decomp); if (r.success) { - fout_fputc((r.file_length >> 56) % 256); - fout_fputc((r.file_length >> 48) % 256); - fout_fputc((r.file_length >> 40) % 256); - fout_fputc((r.file_length >> 32) % 256); - fout_fputc((r.file_length >> 24) % 256); - fout_fputc((r.file_length >> 16) % 256); - fout_fputc((r.file_length >> 8) % 256); - fout_fputc(r.file_length % 256); + fout_fput64(r.file_length); } // write decompressed data @@ -8019,34 +7864,17 @@ void try_decompression_swf(int windowbits, char swf_version) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); } - fout_fputc((best_penalty_bytes_len >> 24) % 256); - fout_fputc((best_penalty_bytes_len >> 16) % 256); - fout_fputc((best_penalty_bytes_len >> 8) % 256); - fout_fputc(best_penalty_bytes_len % 256); + fout_fput32(best_penalty_bytes_len); for (int pbc = 0; pbc < best_penalty_bytes_len; pbc++) { fout_fputc(best_penalty_bytes[pbc]); } } - fout_fputc((best_identical_bytes >> 24) % 256); - fout_fputc((best_identical_bytes >> 16) % 256); - fout_fputc((best_identical_bytes >> 8) % 256); - fout_fputc(best_identical_bytes % 256); - - fout_fputc((best_identical_bytes_decomp >> 24) % 256); - fout_fputc((best_identical_bytes_decomp >> 16) % 256); - fout_fputc((best_identical_bytes_decomp >> 8) % 256); - fout_fputc(best_identical_bytes_decomp % 256); + fout_fput32(best_identical_bytes); + fout_fput32(best_identical_bytes_decomp); if (r.success) { - fout_fputc((r.file_length >> 56) % 256); - fout_fputc((r.file_length >> 48) % 256); - fout_fputc((r.file_length >> 40) % 256); - fout_fputc((r.file_length >> 32) % 256); - fout_fputc((r.file_length >> 24) % 256); - fout_fputc((r.file_length >> 16) % 256); - fout_fputc((r.file_length >> 8) % 256); - fout_fputc(r.file_length % 256); + fout_fput64(r.file_length); } // write decompressed data @@ -8137,34 +7965,17 @@ void try_decompression_bzip2(int compression_level) { if (DEBUG_MODE) { printf("Penalty bytes were used: %i bytes\n", best_penalty_bytes_len); } - fout_fputc((best_penalty_bytes_len >> 24) % 256); - fout_fputc((best_penalty_bytes_len >> 16) % 256); - fout_fputc((best_penalty_bytes_len >> 8) % 256); - fout_fputc(best_penalty_bytes_len % 256); + fout_fput32(best_penalty_bytes_len); for (int pbc = 0; pbc < best_penalty_bytes_len; pbc++) { fout_fputc(best_penalty_bytes[pbc]); } } - fout_fputc((best_identical_bytes >> 24) % 256); - fout_fputc((best_identical_bytes >> 16) % 256); - fout_fputc((best_identical_bytes >> 8) % 256); - fout_fputc(best_identical_bytes % 256); - - fout_fputc((best_identical_bytes_decomp >> 24) % 256); - fout_fputc((best_identical_bytes_decomp >> 16) % 256); - fout_fputc((best_identical_bytes_decomp >> 8) % 256); - fout_fputc(best_identical_bytes_decomp % 256); + fout_fput32(best_identical_bytes); + fout_fput32(best_identical_bytes_decomp); if (r.success) { - fout_fputc((r.file_length >> 56) % 256); - fout_fputc((r.file_length >> 48) % 256); - fout_fputc((r.file_length >> 40) % 256); - fout_fputc((r.file_length >> 32) % 256); - fout_fputc((r.file_length >> 24) % 256); - fout_fputc((r.file_length >> 16) % 256); - fout_fputc((r.file_length >> 8) % 256); - fout_fputc(r.file_length % 256); + fout_fput64(r.file_length); } // write decompressed data @@ -8473,15 +8284,13 @@ void try_decompression_base64(int base64_header_length) { fout_fputc(header_byte); fout_fputc(8); // Base64 - fout_fputc((base64_header_length >> 8) % 256); - fout_fputc(base64_header_length % 256); + fout_fput16(base64_header_length); // write "header", but change first char to prevent re-detection fout_fputc(in_buf[cb] - 1); own_fwrite(in_buf + cb + 1, 1, base64_header_length - 1, fout); - fout_fputc((line_count >> 8) % 256); - fout_fputc(line_count % 256); + fout_fput16(line_count); if (line_case == 2) { for (i = 0; i < line_count; i++) { fout_fputc(base64_line_len[i]); @@ -8491,25 +8300,11 @@ void try_decompression_base64(int base64_header_length) { if (line_case == 1) fout_fputc(base64_line_len[line_count - 1]); } - fout_fputc((identical_bytes >> 24) % 256); - fout_fputc((identical_bytes >> 16) % 256); - fout_fputc((identical_bytes >> 8) % 256); - fout_fputc(identical_bytes % 256); - - fout_fputc((identical_bytes_decomp >> 24) % 256); - fout_fputc((identical_bytes_decomp >> 16) % 256); - fout_fputc((identical_bytes_decomp >> 8) % 256); - fout_fputc(identical_bytes_decomp % 256); + fout_fput32(identical_bytes); + fout_fput32(identical_bytes_decomp); if (r.success) { - fout_fputc((r.file_length >> 56) % 256); - fout_fputc((r.file_length >> 48) % 256); - fout_fputc((r.file_length >> 40) % 256); - fout_fputc((r.file_length >> 32) % 256); - fout_fputc((r.file_length >> 24) % 256); - fout_fputc((r.file_length >> 16) % 256); - fout_fputc((r.file_length >> 8) % 256); - fout_fputc(r.file_length % 256); + fout_fput64(r.file_length); } // write decompressed data @@ -9052,6 +8847,60 @@ void fout_fputc(char c) { } } +void fout_fput16(int v) { + fout_fputc((v >> 8) % 256); + fout_fputc(v % 256); +} + +void fout_fput24(int v) { + fout_fputc((v >> 16) % 256); + fout_fputc((v >> 8) % 256); + fout_fputc(v % 256); +} + +void fout_fput32_little_endian(int v) { + fout_fputc(v % 256); + fout_fputc((v >> 8) % 256); + fout_fputc((v >> 16) % 256); + fout_fputc((v >> 24) % 256); +} + +void fout_fput32(int v) { + fout_fputc((v >> 24) % 256); + fout_fputc((v >> 16) % 256); + fout_fputc((v >> 8) % 256); + fout_fputc(v % 256); +} + +void fout_fput32(unsigned int v) { + fout_fputc((v >> 24) % 256); + fout_fputc((v >> 16) % 256); + fout_fputc((v >> 8) % 256); + fout_fputc(v % 256); +} + +void fout_fput64(long long v) { + fout_fputc((v >> 56) % 256); + fout_fputc((v >> 48) % 256); + fout_fputc((v >> 40) % 256); + fout_fputc((v >> 32) % 256); + fout_fputc((v >> 24) % 256); + fout_fputc((v >> 16) % 256); + fout_fputc((v >> 8) % 256); + fout_fputc(v % 256); +} + +void fout_fput64(unsigned long long v) { + fout_fputc((v >> 56) % 256); + fout_fputc((v >> 48) % 256); + fout_fputc((v >> 40) % 256); + fout_fputc((v >> 32) % 256); + fout_fputc((v >> 24) % 256); + fout_fputc((v >> 16) % 256); + fout_fputc((v >> 8) % 256); + fout_fputc(v % 256); +} + unsigned char fin_fgetc() { if (comp_decomp_state == P_CONVERT) compression_otf_method = conversion_from_method; From 97081a423a1b719f4c0e01b88d139a4038853807 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Wed, 17 Feb 2016 10:31:08 +0100 Subject: [PATCH 21/21] Using official fix for packJPG memory corruption - See issue #17 - See packJPG git: https://github.com/packjpg/packJPG/commit/2d62eda2d75afac6a6b28458c3d966660922fa1b --- contrib/packjpg/bitops.cpp | 5 ++--- contrib/packjpg/packjpg.cpp | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/contrib/packjpg/bitops.cpp b/contrib/packjpg/bitops.cpp index c8f1b62..ba80de9 100644 --- a/contrib/packjpg/bitops.cpp +++ b/contrib/packjpg/bitops.cpp @@ -18,9 +18,8 @@ reading and writing of arrays // special realloc with guaranteed free() of previous memory static inline void* frealloc( void* ptr, size_t size ) { - void* n_ptr = realloc( ptr, size ); - // changed by schnaader to fix a bug: if size == 0, realloc will free the memory and n_ptr == NULL, in this case don't call free - if (( n_ptr == NULL ) && (size != 0)) free( ptr ); + void* n_ptr = realloc( ptr, (size) ? size : 1 ); + if ( n_ptr == NULL ) free( ptr ); return n_ptr; } diff --git a/contrib/packjpg/packjpg.cpp b/contrib/packjpg/packjpg.cpp index b328569..dcc7724 100644 --- a/contrib/packjpg/packjpg.cpp +++ b/contrib/packjpg/packjpg.cpp @@ -322,7 +322,7 @@ packJPG by Matthias Stirner, 01/2014 // special realloc with guaranteed free() of previous memory static inline void* frealloc( void* ptr, size_t size ) { - void* n_ptr = realloc( ptr, size ); + void* n_ptr = realloc( ptr, (size) ? size : 1 ); if ( n_ptr == NULL ) free( ptr ); return n_ptr; }