Blame src/lzo1b_c.ch

Packit 679830
/* lzo1b_c.ch -- implementation of the LZO1B compression algorithm
Packit 679830
Packit 679830
   This file is part of the LZO real-time data compression library.
Packit 679830
Packit 679830
   Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer
Packit 679830
   All Rights Reserved.
Packit 679830
Packit 679830
   The LZO library is free software; you can redistribute it and/or
Packit 679830
   modify it under the terms of the GNU General Public License as
Packit 679830
   published by the Free Software Foundation; either version 2 of
Packit 679830
   the License, or (at your option) any later version.
Packit 679830
Packit 679830
   The LZO library is distributed in the hope that it will be useful,
Packit 679830
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 679830
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 679830
   GNU General Public License for more details.
Packit 679830
Packit 679830
   You should have received a copy of the GNU General Public License
Packit 679830
   along with the LZO library; see the file COPYING.
Packit 679830
   If not, write to the Free Software Foundation, Inc.,
Packit 679830
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Packit 679830
Packit 679830
   Markus F.X.J. Oberhumer
Packit 679830
   <markus@oberhumer.com>
Packit 679830
   http://www.oberhumer.com/opensource/lzo/
Packit 679830
 */
Packit 679830
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
//
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
#if !defined(LZO_HAVE_R1) && !defined(LZO_NO_R1)
Packit 679830
#  define LZO_HAVE_R1 1
Packit 679830
#endif
Packit 679830
Packit 679830
#if !defined(LZO_HAVE_M3) && !defined(LZO_NO_M3)
Packit 679830
#  if (M3O_BITS < 8)
Packit 679830
#    define LZO_HAVE_M3 1
Packit 679830
#  endif
Packit 679830
#endif
Packit 679830
Packit 679830
Packit 679830
#define MI      /*empty*/
Packit 679830
#define SI      MI
Packit 679830
#if (DD_BITS > 0)
Packit 679830
#define DI      ++ii; DVAL_NEXT(dv,ii); UPDATE_D(dict,drun,dv,ii,in); MI
Packit 679830
#define XI      assert(ii < ip); ii = ip; DVAL_FIRST(dv,(ip));
Packit 679830
#else
Packit 679830
#define DI      ++ii; DINDEX1(dindex,ii); UPDATE_I(dict,0,dindex,ii,in); MI
Packit 679830
#define XI      assert(ii < ip); ii = ip;
Packit 679830
#endif
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
// compress a block of data.
Packit 679830
//
Packit 679830
// I really apologize for this spaghetti code.
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
#ifdef __cplusplus
Packit 679830
extern "C" {
Packit 679830
#endif
Packit 679830
LZO_PRIVATE(int)
Packit 679830
do_compress    ( const lzo_bytep in , lzo_uint  in_len,
Packit 679830
                       lzo_bytep out, lzo_uintp out_len,
Packit 679830
                       lzo_voidp wrkmem )
Packit 679830
{
Packit 679830
    const lzo_bytep ip;
Packit 679830
#if (DD_BITS > 0)
Packit 679830
#if defined(__LZO_HASH_INCREMENTAL)
Packit 679830
    lzo_xint dv;
Packit 679830
#endif
Packit 679830
    unsigned drun = 0;
Packit 679830
#endif
Packit 679830
    lzo_bytep op;
Packit 679830
    const lzo_bytep const in_end = in + in_len;
Packit 679830
    const lzo_bytep const ip_end = in + in_len - MIN_LOOKAHEAD;
Packit 679830
    const lzo_bytep ii;
Packit 679830
#if defined(LZO_HAVE_R1)
Packit 679830
    const lzo_bytep r1 = ip_end;    /* pointer for R1 match (none yet) */
Packit 679830
#endif
Packit 679830
#if defined(LZO_HAVE_M3)
Packit 679830
    lzo_bytep m3 = out + 1;         /* pointer after last m3/m4 match */
Packit 679830
#endif
Packit 679830
Packit 679830
    lzo_dict_p const dict = (lzo_dict_p) wrkmem;
Packit 679830
Packit 679830
Packit 679830
#if (LZO_COLLECT_STATS)
Packit 679830
    lzo_stats->r_bits   = R_BITS;
Packit 679830
    lzo_stats->m3o_bits = M3O_BITS;
Packit 679830
    lzo_stats->dd_bits  = DD_BITS;
Packit 679830
    lzo_stats->clevel   = CLEVEL;
Packit 679830
    lzo_stats->d_bits   = D_BITS;
Packit 679830
    lzo_stats->min_lookahead  = MIN_LOOKAHEAD;
Packit 679830
    lzo_stats->max_lookbehind = MAX_LOOKBEHIND;
Packit 679830
    lzo_stats->compress_id    = LZO_PP_MACRO_EXPAND(COMPRESS_ID);
Packit 679830
#endif
Packit 679830
Packit 679830
    /* init dictionary */
Packit 679830
#if (LZO_DETERMINISTIC)
Packit 679830
    BZERO8_PTR(wrkmem,sizeof(lzo_dict_t),D_SIZE);
Packit 679830
#endif
Packit 679830
Packit 679830
Packit 679830
    op = out;
Packit 679830
    ip = in;
Packit 679830
    ii = ip;            /* point to start of current literal run */
Packit 679830
Packit 679830
Packit 679830
#if (DD_BITS > 0)
Packit 679830
    DVAL_FIRST(dv,ip);
Packit 679830
    UPDATE_D(dict,drun,dv,ip,in);
Packit 679830
    ip++;
Packit 679830
    DVAL_NEXT(dv,ip);
Packit 679830
#else
Packit 679830
    ip++;
Packit 679830
#endif
Packit 679830
Packit 679830
    assert(ip < ip_end);
Packit 679830
    for (;;)
Packit 679830
    {
Packit 679830
        const lzo_bytep m_pos;
Packit 679830
#if !defined(NDEBUG)
Packit 679830
        const lzo_bytep m_pos_sav = NULL;
Packit 679830
#endif
Packit 679830
        LZO_DEFINE_UNINITIALIZED_VAR(lzo_uint, m_off, 0);
Packit 679830
#if (DD_BITS == 0)
Packit 679830
        lzo_uint dindex;
Packit 679830
#endif
Packit 679830
        lzo_uint m_len;
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
// search for a match
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
#if !defined(LZO_SEARCH_MATCH_INCLUDE_FILE)
Packit 679830
#  define LZO_SEARCH_MATCH_INCLUDE_FILE     "lzo1b_sm.ch"
Packit 679830
#endif
Packit 679830
Packit 679830
#include LZO_SEARCH_MATCH_INCLUDE_FILE
Packit 679830
Packit 679830
Packit 679830
#if !defined(LZO_TEST_MATCH_INCLUDE_FILE)
Packit 679830
#  define LZO_TEST_MATCH_INCLUDE_FILE       "lzo1b_tm.ch"
Packit 679830
#endif
Packit 679830
Packit 679830
#include LZO_TEST_MATCH_INCLUDE_FILE
Packit 679830
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
// found a literal
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
Packit 679830
    /* a literal */
Packit 679830
literal:
Packit 679830
#if (DD_BITS == 0)
Packit 679830
        UPDATE_I(dict,0,dindex,ip,in);
Packit 679830
#endif
Packit 679830
        if (++ip >= ip_end)
Packit 679830
            break;
Packit 679830
#if (DD_BITS > 0)
Packit 679830
        DVAL_NEXT(dv,ip);
Packit 679830
#endif
Packit 679830
        continue;
Packit 679830
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
// found a match
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
match:
Packit 679830
#if (DD_BITS == 0)
Packit 679830
        UPDATE_I(dict,0,dindex,ip,in);
Packit 679830
#endif
Packit 679830
        /* we have found a match of at least M2_MIN_LEN */
Packit 679830
Packit 679830
Packit 679830
#if !defined(LZO_CODE_RUN_INCLUDE_FILE)
Packit 679830
#  define LZO_CODE_RUN_INCLUDE_FILE     "lzo1b_cr.ch"
Packit 679830
#endif
Packit 679830
Packit 679830
#include LZO_CODE_RUN_INCLUDE_FILE
Packit 679830
Packit 679830
Packit 679830
        /* ii now points to the start of the current match */
Packit 679830
        assert(ii == ip);
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
// code the match
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
#if !defined(LZO_CODE_MATCH_INCLUDE_FILE)
Packit 679830
#  define LZO_CODE_MATCH_INCLUDE_FILE   "lzo1b_cm.ch"
Packit 679830
#endif
Packit 679830
Packit 679830
#include LZO_CODE_MATCH_INCLUDE_FILE
Packit 679830
Packit 679830
Packit 679830
        /* ii now points to the start of the next literal run */
Packit 679830
        assert(ii == ip);
Packit 679830
Packit 679830
    }
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
// end of block
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
    assert(ip <= in_end);
Packit 679830
Packit 679830
#if (LZO_COLLECT_STATS)
Packit 679830
    {
Packit 679830
        lzo_uint i;
Packit 679830
        const lzo_bytep p;
Packit 679830
Packit 679830
        for (i = 0; i < D_SIZE; i++)
Packit 679830
        {
Packit 679830
            p = dict[i];
Packit 679830
            if (BOUNDS_CHECKING_OFF_IN_EXPR(p == NULL || p < in || p > in_end))
Packit 679830
                lzo_stats->unused_dict_entries++;
Packit 679830
        }
Packit 679830
        lzo_stats->unused_dict_entries_percent =
Packit 679830
            100.0 * lzo_stats->unused_dict_entries / D_SIZE;
Packit 679830
    }
Packit 679830
#endif
Packit 679830
Packit 679830
Packit 679830
#if defined(LZO_RETURN_IF_NOT_COMPRESSIBLE)
Packit 679830
    /* return if op == out to indicate that we
Packit 679830
     * couldn't compress and didn't copy anything.
Packit 679830
     */
Packit 679830
    if (op == out)
Packit 679830
    {
Packit 679830
        *out_len = 0;
Packit 679830
        return LZO_E_NOT_COMPRESSIBLE;
Packit 679830
    }
Packit 679830
#endif
Packit 679830
Packit 679830
    /* store the final literal run */
Packit 679830
    if (pd(in_end,ii) > 0)
Packit 679830
    {
Packit 679830
        lzo_uint t = pd(in_end,ii);
Packit 679830
        op = STORE_RUN(op,ii,t);
Packit 679830
    }
Packit 679830
Packit 679830
    *out_len = pd(op, out);
Packit 679830
    return LZO_E_OK;                /* compression went ok */
Packit 679830
}
Packit 679830
#ifdef __cplusplus
Packit 679830
} /* extern "C" */
Packit 679830
#endif
Packit 679830
Packit 679830
Packit 679830
/*
Packit 679830
vi:ts=4:et
Packit 679830
*/