00001 #ifndef __J2K__LZH__LZHLEncoderStat_CPP__
00002 #define __J2K__LZH__LZHLEncoderStat_CPP__
00003
00004 LZHLEncoderStat::LZHLEncoderStat()
00005 {
00006 nextStat = HUFFRECALCLEN;
00007 symbolTable = new Symbol[ NHUFFSYMBOLS ];
00008 memcpy( symbolTable, symbolTable0, sizeof(Symbol)*NHUFFSYMBOLS );
00009 }
00010
00011 LZHLEncoderStat::~LZHLEncoderStat()
00012 {
00013 delete [] symbolTable;
00014 }
00015
00016 LZHLEncoderStat::Symbol LZHLEncoderStat::symbolTable0[ NHUFFSYMBOLS ] = {
00017 #include <j2k/LZH/Table/henc.tbl>
00018 };
00019
00020 inline void LZHLEncoderStat::_addGroup( int* groups, int group, int nBits )
00021 {
00022 assert( nBits <= 8 );
00023
00024
00025 for( int j=group; j > 0 && nBits < groups[ j - 1 ] ; --j )
00026 groups[ j ] = groups[ j - 1 ];
00027
00028 groups[ j ] = nBits;
00029 }
00030
00031 void LZHLEncoderStat::calcStat( int* groups )
00032 {
00033 HuffStatTmpStruct s[ NHUFFSYMBOLS ];
00034 int total = makeSortedTmp( s );
00035
00036 nextStat = HUFFRECALCLEN;
00037
00038 int pos = 0;
00039 int nTotal = 0;
00040
00041 for ( int group=0; group < 14 ; ++group )
00042 {
00043 int avgGroup = ( total - nTotal )/( 16 - group );
00044 int i = 0, n = 0, nn = 0;
00045
00046 for ( int nBits=0 ;; ++nBits )
00047 {
00048 int over = 0;
00049 int nItems = 1 << nBits;
00050
00051 if ( pos + i + nItems > NHUFFSYMBOLS )
00052 {
00053 nItems = NHUFFSYMBOLS - pos;
00054 over = 1;
00055 }
00056
00057 for ( ; i < nItems ; ++i )
00058 nn += s[ pos + i ].n;
00059
00060 if ( over || nBits >= 8 || nn > avgGroup )
00061 {
00062 if ( nBits == 0 || abs( n - avgGroup ) > abs( nn - avgGroup ) ) {
00063 n = nn;
00064 } else {
00065 --nBits;
00066 }
00067
00068 _addGroup( groups, group, nBits );
00069 nTotal += n;
00070 pos += 1 << nBits;
00071
00072 break;
00073
00074 } else {
00075 n = nn;
00076 }
00077 }
00078 }
00079
00080 int bestNBits = 0, bestNBits15 = 0;
00081 int best = 0x7FFFFFFF;
00082 int i = 0, nn = 0, left = 0;
00083
00084 for ( int j=pos; j < NHUFFSYMBOLS ; ++j )
00085 left += s[ j ].n;
00086
00087 for ( int nBits = 0 ;; ++nBits ) {
00088 int nItems = 1 << nBits;
00089 if ( pos + i + nItems > NHUFFSYMBOLS )
00090 break;
00091
00092 for ( ; i < nItems ; ++i )
00093 nn += s[ pos + i ].n;
00094
00095 int nItems15 = NHUFFSYMBOLS - ( pos + i );
00096
00097 for ( int nBits15=0 ;; ++nBits15 )
00098 if ( 1 << nBits15 >= nItems15 )
00099 break;
00100
00101 assert( left >= nn );
00102
00103 if ( nBits <= 8 && nBits15 <= 8 ) {
00104 int n = nn * nBits + ( left - nn ) * nBits15;
00105
00106 if ( n < best ) {
00107 best = n;
00108 bestNBits = nBits;
00109 bestNBits15 = nBits15;
00110
00111 } else {
00112 break;
00113 }
00114 }
00115 }
00116
00117 int pos15 = pos + ( 1 << bestNBits );
00118 _addGroup( groups, 14, bestNBits );
00119 _addGroup( groups, 15, bestNBits15 );
00120
00121 pos = 0;
00122
00123 for ( j=0; j < 16 ; ++j ) {
00124 int nBits = groups[ j ];
00125 int nItems = 1 << nBits;
00126 int maxK = min( nItems, NHUFFSYMBOLS - pos );
00127
00128 for ( int k=0; k < maxK ; ++k ) {
00129 int symbol = s[ pos + k ].i;
00130 symbolTable[ symbol ].nBits = nBits + 4;
00131 symbolTable[ symbol ].code = ( j << nBits ) | k;
00132 }
00133
00134 pos += 1 << nBits;
00135 }
00136 }
00137
00138 #endif