Main Page   Packages   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Search  

C:/temp/src/j2k/LZH/LZHLCompressor.cpp

Go to the documentation of this file.
00001 #ifndef __J2K__LZH__LZHLCompressor_CPP__
00002 #define __J2K__LZH__LZHLCompressor_CPP__
00003 
00004 LZHLCompressor::LZHLCompressor() {
00005   table = new LZTableItem[ LZTABLESIZE ];
00006   for ( int i=0; i < LZTABLESIZE ; ++i ) {
00007     table[ i ] = (LZTABLEINT)(-1);
00008   }
00009 }
00010 
00011 LZHLCompressor::~LZHLCompressor() {
00012   delete [] table;
00013 }
00014 
00015 inline LZHASH LZHLCompressor::_updateTable( LZHASH hash, const BYTE* src, LZPOS pos, int len )
00016 {
00017   if ( len <= 0 )
00018     return 0;
00019 
00020   if ( len > LZSKIPHASH ) {
00021     ++src;
00022     hash = 0;
00023     const BYTE* pEnd = src + len + LZMATCH;
00024 
00025     for ( const BYTE* p=src+len; p < pEnd ; ) {
00026       UPDATE_HASH( hash, *p++ );
00027     }
00028 
00029     return hash;
00030   }
00031 
00032   UPDATE_HASH_EX( hash, src );
00033   ++src;
00034 
00035   for ( int i=0; i < len ; ++i ) {
00036      table[ HASH_POS( hash ) ] = (LZTableItem)_wrap( pos + i );
00037      UPDATE_HASH_EX( hash, src + i );
00038   }
00039 
00040   return hash;
00041 }
00042 
00043 size_t LZHLCompressor::compress( BYTE* dst, const BYTE* src, size_t sz ) {
00044   LZHLEncoder coder( &stat, dst );
00045   const BYTE* srcBegin = src;
00046   const BYTE* srcEnd = src + sz;
00047 
00048   LZHASH hash = 0;
00049 
00050   if ( sz >= LZMATCH ) {
00051     const BYTE* pEnd = src + LZMATCH;
00052 
00053     for ( const BYTE* p=src; p < pEnd ; ) {
00054        UPDATE_HASH( hash, *p++ );
00055     }
00056   }
00057 
00058   for (;;) {
00059     int srcLeft = srcEnd - src;
00060     if ( srcLeft < LZMATCH ) {
00061       if ( srcLeft ) {
00062         _toBuf( src, srcLeft );
00063         coder.putRaw( src, srcLeft );
00064         src += srcLeft;
00065       }
00066 
00067       break;  //forever
00068     }
00069 
00070     int nRaw = 0;
00071     int maxRaw = min( srcLeft - LZMATCH, LZHLEncoder::maxRaw );
00072 
00073     #ifdef LZLAZYMATCH
00074      int    lazyMatchLen = 0;
00075      int    lazyMatchHashPos;
00076      LZPOS  lazyMatchBufPos;
00077      int    lazyMatchNRaw;
00078      LZHASH lazyMatchHash;
00079      BOOL   lazyForceMatch = FALSE;
00080     #endif
00081      for (;;) {
00082        LZHASH hash2 = HASH_POS( hash );
00083 
00084        int hashPos = table[ hash2 ];
00085        int wrapBufPos = _wrap( bufPos );
00086        table[ hash2 ] = (LZTableItem)wrapBufPos;
00087 
00088        int matchLen = 0;
00089        if ( hashPos != (LZTABLEINT)(-1) && hashPos != wrapBufPos )
00090        {
00091          int matchLimit = min( min( _distance( wrapBufPos - hashPos ), srcLeft - nRaw ), LZMIN + LZHLEncoder::maxMatchOver );
00092          matchLen = _nMatch( hashPos, src + nRaw, matchLimit );
00093 
00094          #ifdef LZOVERLAP
00095            if ( _wrap( hashPos + matchLen ) == wrapBufPos )
00096            {
00097              assert( matchLen != 0 );
00098              int xtraMatchLimit = min( LZMIN + LZHLEncoder::maxMatchOver - matchLen, srcLeft - nRaw - matchLen );
00099              for ( int xtraMatch = 0; xtraMatch < xtraMatchLimit ; ++xtraMatch )
00100                 {
00101                 if ( src[ nRaw + xtraMatch ] != src[ nRaw + xtraMatch + matchLen ] )
00102                 break;//for ( xtraMatch )
00103                 }
00104 
00105              matchLen += xtraMatch;
00106            }
00107          #endif
00108 
00109          #ifdef LZBACKWARDMATCH
00110            if ( matchLen >= LZMIN - 1 )//to ensure that buf will be overwritten
00111              {
00112              int xtraMatchLimit = min( LZMIN + LZHLEncoder::maxMatchOver - matchLen, nRaw );
00113              int d = (int)_distance( bufPos - hashPos );
00114              xtraMatchLimit = min( min( xtraMatchLimit, d - matchLen ), LZBUFSIZE - d );
00115              for ( int xtraMatch = 0; xtraMatch < xtraMatchLimit ; ++xtraMatch )
00116                 {
00117                 if ( buf[ _wrap( hashPos - xtraMatch - 1 ) ] != src[ nRaw - xtraMatch - 1 ] )
00118                   break;//for ( xtraMatch )
00119                 }
00120 
00121              if ( xtraMatch > 0 ) {
00122                    assert( matchLen + xtraMatch >= LZMIN );
00123                    assert( matchLen + xtraMatch <= _distance( bufPos - hashPos ) );
00124 
00125                    nRaw -= xtraMatch;
00126                    bufPos -= xtraMatch;
00127                    hashPos -= xtraMatch;
00128                    matchLen += xtraMatch;
00129                    wrapBufPos = _wrap( bufPos );
00130                    hash = _calcHash( src + nRaw );
00131 
00132                    #ifdef LZLAZYMATCH
00133                      lazyForceMatch = TRUE;
00134                    #endif
00135              }
00136            }
00137          #endif
00138       }
00139 
00140       #ifdef LZLAZYMATCH
00141         if ( lazyMatchLen >= LZMIN ) {
00142           if ( matchLen > lazyMatchLen ) {
00143             coder.putMatch( src, nRaw, matchLen - LZMIN, _distance( wrapBufPos - hashPos ) );
00144             hash = _updateTable( hash, src + nRaw, bufPos + 1, min( matchLen - 1, srcEnd - (src + nRaw + 1) ) );
00145             _toBuf( src + nRaw, matchLen );
00146             src += nRaw + matchLen;
00147             break;//for ( nRaw )
00148 
00149           } else {
00150             nRaw = lazyMatchNRaw;
00151             bufPos = lazyMatchBufPos;
00152 
00153             hash = lazyMatchHash;
00154             UPDATE_HASH_EX( hash, src + nRaw );
00155             coder.putMatch( src, nRaw, lazyMatchLen - LZMIN, _distance( bufPos - lazyMatchHashPos ) );
00156             hash = _updateTable( hash, src + nRaw + 1, bufPos + 2, min( lazyMatchLen - 2, srcEnd - (src + nRaw + 2) ) );
00157             _toBuf( src + nRaw, lazyMatchLen );
00158             src += nRaw + lazyMatchLen;
00159 
00160             break;//for ( nRaw )
00161           }
00162         }
00163       #endif
00164 
00165       if ( matchLen >= LZMIN ) {
00166 
00167         #ifdef LZLAZYMATCH
00168           if ( !lazyForceMatch ) {
00169              lazyMatchLen = matchLen;
00170              lazyMatchHashPos = hashPos;
00171              lazyMatchNRaw = nRaw;
00172              lazyMatchBufPos = bufPos;
00173              lazyMatchHash = hash;
00174            } else
00175          #endif
00176            {
00177              coder.putMatch( src, nRaw, matchLen - LZMIN, _distance( wrapBufPos - hashPos ) );
00178              hash = _updateTable( hash, src + nRaw, bufPos + 1, min( matchLen - 1, srcEnd - (src + nRaw + 1) ) );
00179              _toBuf( src + nRaw, matchLen );
00180              src += nRaw + matchLen;
00181     
00182              break;//for ( nRaw )
00183            }
00184          }
00185 
00186             #ifdef LZLAZYMATCH
00187             assert( !lazyForceMatch );
00188             #endif
00189 
00190             if ( nRaw + 1 > maxRaw )
00191                 {
00192                 #ifdef LZLAZYMATCH
00193                 if ( lazyMatchLen >= LZMIN )
00194                     {
00195                     coder.putMatch( src, nRaw, lazyMatchLen - LZMIN, _distance( bufPos - lazyMatchHashPos ) );
00196                     hash = _updateTable( hash, src + nRaw, bufPos + 1, min( lazyMatchLen - 1, srcEnd - (src + nRaw + 1) ) );
00197                     _toBuf( src + nRaw, lazyMatchLen );
00198                     src += nRaw + lazyMatchLen;
00199                     break;//for ( nRaw )
00200                     }
00201                 #endif
00202 
00203                if ( nRaw + LZMATCH >= srcLeft && srcLeft <= LZHLEncoder::maxRaw )
00204                  {
00205                    _toBuf( src + nRaw, srcLeft - nRaw );
00206                    nRaw = srcLeft;
00207                  }
00208 
00209                coder.putRaw( src, nRaw );
00210                src += nRaw;
00211                break;//for ( nRaw )
00212               }
00213 
00214             UPDATE_HASH_EX( hash, src + nRaw );
00215             _toBuf( src[ nRaw++ ] );
00216             }//for ( nRaw )
00217         }//forever
00218 
00219     return coder.flush();
00220     }
00221 
00222 #endif

Generated on Sun Oct 14 18:46:32 2001 for Standard J2K Library by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001