home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1997 March / PCO3_97.ISO / filesbbs / os2 / lzo026.arj / LZO026.ZIP / lzo-0.26 / src / lzo1a_cm.ch < prev    next >
Encoding:
Text File  |  1996-07-27  |  5.6 KB  |  225 lines

  1. /* lzo1a_cm.ch -- implementation of the LZO1A compression algorithm
  2.  
  3.    This file is part of the LZO real-time data compression library.
  4.  
  5.    Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
  6.  
  7.    The LZO library is free software; you can redistribute it and/or
  8.    modify it under the terms of the GNU General Public License as
  9.    published by the Free Software Foundation; either version 2 of
  10.    the License, or (at your option) any later version.
  11.  
  12.    The LZO library is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with the LZO library; see the file COPYING.
  19.    If not, write to the Free Software Foundation, Inc.,
  20.    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21.  
  22.    Markus F.X.J. Oberhumer
  23.    markus.oberhumer@jk.uni-linz.ac.at
  24.  */
  25.  
  26.  
  27. /* WARNING: this file should *not* be used by applications. It is
  28.    part of the implementation of the library and is subject
  29.    to change.
  30.  */
  31.  
  32.  
  33.  
  34. /***********************************************************************
  35. // code the match in LZO1 compatible format
  36. ************************************************************************/
  37.  
  38. #define THRESHOLD    (M2_MIN_LEN - 1)
  39. #define MSIZE        LZO_SIZE(M2L_BITS)
  40.  
  41.  
  42. /***********************************************************************
  43. // 
  44. ************************************************************************/
  45.  
  46. #if (DD_BITS == 0)
  47.  
  48.         /* we already matched M2_MIN_LEN bytes,
  49.          * m_pos also already advanced M2_MIN_LEN bytes */
  50.         ip += M2_MIN_LEN;
  51.         assert(m_pos < ip);
  52.  
  53.         /* try to match another M2_MAX_LEN + 1 - M2_MIN_LEN bytes
  54.          * to see if we get more than a M2 match */
  55. #define M2_OR_M3    (MATCH_M2)
  56.  
  57. #else /* (DD_BITS == 0) */
  58.  
  59.         /* we already matched m_len bytes */
  60.         assert(m_len >= M2_MIN_LEN);
  61.         ip += m_len;
  62.         assert(ip <= in_end);
  63.  
  64. #define M2_OR_M3    (m_len <= M2_MAX_LEN)
  65.  
  66. #endif /* (DD_BITS == 0) */
  67.  
  68.  
  69.         if (M2_OR_M3)
  70.         {
  71.         /* we've found a short match */
  72.             assert(ip <= in_end);
  73.  
  74.         /* 2a) compute match parameters */
  75. #if (DD_BITS == 0)
  76.                 assert(ip-m_pos == (lzo_ptrdiff_t)m_off);
  77.             --ip;    /* ran one too far, point back to non-match */
  78.             m_len = ip - ii;
  79. #endif
  80.                 assert(m_len >= M2_MIN_LEN);
  81.                 assert(m_len <= M2_MAX_LEN);
  82.  
  83.                 assert(m_off >= M2_MIN_OFFSET);
  84.                 assert(m_off <= M2_MAX_OFFSET);
  85.                 assert(ii-m_off == m_pos_sav);
  86.                 assert(lzo_memcmp(m_pos_sav,ii,m_len) == 0);
  87.  
  88.         /* 2b) code the match */
  89.             m_off -= M2_MIN_OFFSET;
  90.             /* code short match len + low offset bits */
  91.             *op++ = LZO_BYTE(((m_len - THRESHOLD) << M2O_BITS) |
  92.                              (m_off & M2O_MASK));
  93.             /* code high offset bits */
  94.             *op++ = LZO_BYTE(m_off >> M2O_BITS);
  95.  
  96.  
  97.             if (ip >= ip_end)
  98.             {
  99.                 ii = ip;
  100.                 break;
  101.             }
  102.  
  103.  
  104.         /* 2c) Insert phrases (beginning with ii+1) into the dictionary. */
  105.  
  106. #if (CLEVEL == 9) || (CLEVEL >= 7 && M2L_BITS <= 4) || (CLEVEL >= 5 && M2L_BITS <= 3)
  107.         /* Insert the whole match (ii+1)..(ip-1) into dictionary.  */
  108.             ++ii;
  109.             do {
  110.                 DVAL_NEXT(dv,ii);
  111.                 dict[ DINDEX(dv,ii) ] = ii;
  112.                 MI
  113.             } while (++ii < ip);
  114.             DVAL_NEXT(dv,ii);
  115.             assert(ii == ip);
  116.             DVAL_ASSERT(dv,ip);
  117. #elif (CLEVEL >= 3)
  118.             SI   DI DI   XI
  119. #elif (CLEVEL >= 2)
  120.             SI   DI      XI
  121. #else
  122.                          XI
  123. #endif
  124.         }
  125.  
  126.         else
  127.  
  128.         {
  129.         /* we've found a long match - see how far we can still go */
  130.             const lzo_byte *end;
  131.  
  132.             assert(ip <= in_end);
  133.             assert(ii == ip - (M2_MAX_LEN + 1));
  134.             assert(lzo_memcmp(m_pos_sav,ii,ip-ii) == 0);
  135.  
  136. #if (DD_BITS > 0)
  137.             assert((lzo_ptrdiff_t)m_len == ip-ii);
  138.             m_pos = ip - m_off;
  139.             assert(m_pos == m_pos_sav + m_len);
  140. #endif
  141.  
  142. #if defined(__BOUNDS_CHECKING_ON)
  143.             if (in_end - ip <= (lzo_ptrdiff_t) (M3_MAX_LEN - M3_MIN_LEN))
  144. #else
  145.             if (in_end <= ip + (M3_MAX_LEN - M3_MIN_LEN))
  146. #endif
  147.                 end = in_end;
  148.             else
  149.             {
  150.                 end = ip + (M3_MAX_LEN - M3_MIN_LEN);
  151.                 assert(end < in_end);
  152.             }
  153.  
  154.             while (ip < end  &&  *m_pos == *ip)
  155.                 m_pos++, ip++;
  156.             assert(ip <= in_end);
  157.  
  158.             /* 2a) compute match parameters */
  159.             m_len = (ip - ii);
  160.                 assert(m_len >= M3_MIN_LEN);
  161.                 assert(m_len <= M3_MAX_LEN);
  162.  
  163.                 assert(m_off >= M3_MIN_OFFSET);
  164.                 assert(m_off <= M3_MAX_OFFSET);
  165.                 assert(ii-m_off == m_pos_sav);
  166.                 assert(lzo_memcmp(m_pos_sav,ii,m_len) == 0);
  167.                 assert(ip-m_pos == (lzo_ptrdiff_t)m_off);
  168.  
  169.         /* 2b) code the match */
  170.             m_off -= M3_MIN_OFFSET - M3_EOF_OFFSET;
  171.             /* code long match flag + low offset bits */
  172.             *op++ = LZO_BYTE(((MSIZE - 1) << M3O_BITS) | (m_off & M3O_MASK));
  173.             /* code high offset bits */
  174.             *op++ = LZO_BYTE(m_off >> M3O_BITS);
  175.             /* code match len */
  176.             *op++ = LZO_BYTE(m_len - M3_MIN_LEN);
  177.  
  178.  
  179.             if (ip >= ip_end)
  180.             {
  181.                 ii = ip;
  182.                 break;
  183.             }
  184.  
  185.  
  186.         /* 2c) Insert phrases (beginning with ii+1) into the dictionary. */
  187. #if (CLEVEL == 9)
  188.         /* Insert the whole match (ii+1)..(ip-1) into dictionary.  */
  189.         /* This is not recommended because it can be slow. */
  190.             ++ii;
  191.             do {
  192.                 DVAL_NEXT(dv,ii);
  193.                 dict[ DINDEX(dv,ii) ] = ii;
  194.                 MI
  195.             } while (++ii < ip);
  196.             DVAL_NEXT(dv,ii);
  197.             assert(ii == ip);
  198.             DVAL_ASSERT(dv,ip);
  199. #elif (CLEVEL >= 8)
  200.             SI   DI DI DI DI DI DI DI DI   XI
  201. #elif (CLEVEL >= 7)
  202.             SI   DI DI DI DI DI DI DI      XI
  203. #elif (CLEVEL >= 6)
  204.             SI   DI DI DI DI DI DI         XI
  205. #elif (CLEVEL >= 5)
  206.             SI   DI DI DI DI               XI
  207. #elif (CLEVEL >= 4)
  208.             SI   DI DI DI                  XI
  209. #elif (CLEVEL >= 3)
  210.             SI   DI DI                     XI
  211. #elif (CLEVEL >= 2)
  212.             SI   DI                        XI
  213. #else
  214.                                            XI
  215. #endif
  216.         }
  217.  
  218.         /* ii now points to the start of the next literal run */
  219.         assert(ii == ip);
  220.  
  221.  
  222. /*
  223. vi:ts=4
  224. */
  225.