Blame src/lzo_swd.ch

Packit Service 5195f2
/* lzo_swd.ch -- sliding window dictionary
Packit Service 5195f2
Packit Service 5195f2
   This file is part of the LZO real-time data compression library.
Packit Service 5195f2
Packit Service 5195f2
   Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer
Packit Service 5195f2
   All Rights Reserved.
Packit Service 5195f2
Packit Service 5195f2
   The LZO library is free software; you can redistribute it and/or
Packit Service 5195f2
   modify it under the terms of the GNU General Public License as
Packit Service 5195f2
   published by the Free Software Foundation; either version 2 of
Packit Service 5195f2
   the License, or (at your option) any later version.
Packit Service 5195f2
Packit Service 5195f2
   The LZO library is distributed in the hope that it will be useful,
Packit Service 5195f2
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 5195f2
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 5195f2
   GNU General Public License for more details.
Packit Service 5195f2
Packit Service 5195f2
   You should have received a copy of the GNU General Public License
Packit Service 5195f2
   along with the LZO library; see the file COPYING.
Packit Service 5195f2
   If not, write to the Free Software Foundation, Inc.,
Packit Service 5195f2
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Packit Service 5195f2
Packit Service 5195f2
   Markus F.X.J. Oberhumer
Packit Service 5195f2
   <markus@oberhumer.com>
Packit Service 5195f2
   http://www.oberhumer.com/opensource/lzo/
Packit Service 5195f2
 */
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
#if (LZO_UINT_MAX < LZO_0xffffffffL)
Packit Service 5195f2
#  error "LZO_UINT_MAX"
Packit Service 5195f2
#endif
Packit Service 5195f2
#if defined(LZO_DEBUG)
Packit Service 5195f2
#  include <stdio.h>
Packit Service 5195f2
#endif
Packit Service 5195f2
#if defined(__LZO_CHECKER)
Packit Service 5195f2
#  include <stdlib.h>
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
/***********************************************************************
Packit Service 5195f2
//
Packit Service 5195f2
************************************************************************/
Packit Service 5195f2
Packit Service 5195f2
/* unsigned type for dictionary access - don't waste memory here */
Packit Service 5195f2
#if (0UL + SWD_N + SWD_F + SWD_F < 65535UL)
Packit Service 5195f2
   typedef lzo_uint16_t     swd_uint;
Packit Service 5195f2
#  define SWD_UINT_MAX      0xffffu
Packit Service 5195f2
#else
Packit Service 5195f2
   typedef lzo_uint32_t     swd_uint;
Packit Service 5195f2
#  define SWD_UINT_MAX      0xffffffffu
Packit Service 5195f2
#endif
Packit Service 5195f2
#define swd_uintp           swd_uint *
Packit Service 5195f2
#define SWD_UINT(x)         ((swd_uint)(x))
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
#ifndef SWD_HSIZE
Packit Service 5195f2
#  define SWD_HSIZE         16384
Packit Service 5195f2
#endif
Packit Service 5195f2
#ifndef SWD_MAX_CHAIN
Packit Service 5195f2
#  define SWD_MAX_CHAIN     2048
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
#if !defined(HEAD3)
Packit Service 5195f2
#if 1
Packit Service 5195f2
#  define HEAD3(b,p) \
Packit Service 5195f2
    ((DMUL(0x9f5f,(((((lzo_xint)b[p]<<5)^b[p+1])<<5)^b[p+2]))>>5) & (SWD_HSIZE-1))
Packit Service 5195f2
#else
Packit Service 5195f2
#  define HEAD3(b,p) \
Packit Service 5195f2
    ((DMUL(0x9f5f,(((((lzo_xint)b[p+2]<<5)^b[p+1])<<5)^b[p]))>>5) & (SWD_HSIZE-1))
Packit Service 5195f2
#endif
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
#if !(SWD_NO_HEAD2) && (SWD_THRESHOLD == 1) && !defined(HEAD2)
Packit Service 5195f2
#  if 1 && (LZO_OPT_UNALIGNED16)
Packit Service 5195f2
#    define HEAD2(b,p)      UA_GET_NE16((b)+(p))
Packit Service 5195f2
#  else
Packit Service 5195f2
#    define HEAD2(b,p)      (b[p] ^ ((unsigned)b[(p)+1]<<8))
Packit Service 5195f2
#  endif
Packit Service 5195f2
#  define NIL2              SWD_UINT_MAX
Packit Service 5195f2
#endif
Packit Service 5195f2
#ifndef IF_HEAD2
Packit Service 5195f2
#define IF_HEAD2(s)         /*empty*/
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
typedef struct
Packit Service 5195f2
{
Packit Service 5195f2
/* public - "built-in" */
Packit Service 5195f2
    lzo_uint swd_n;
Packit Service 5195f2
    lzo_uint swd_f;
Packit Service 5195f2
    lzo_uint swd_threshold;
Packit Service 5195f2
Packit Service 5195f2
/* public - configuration */
Packit Service 5195f2
    lzo_uint max_chain;
Packit Service 5195f2
    lzo_uint nice_length;
Packit Service 5195f2
    lzo_bool use_best_off;
Packit Service 5195f2
    lzo_uint lazy_insert;
Packit Service 5195f2
Packit Service 5195f2
/* public - output */
Packit Service 5195f2
    lzo_uint m_len;
Packit Service 5195f2
    lzo_uint m_off;
Packit Service 5195f2
    lzo_uint look;
Packit Service 5195f2
    int b_char;
Packit Service 5195f2
#if defined(SWD_BEST_OFF)
Packit Service 5195f2
    lzo_uint best_off[ SWD_BEST_OFF ];
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
/* semi public */
Packit Service 5195f2
    LZO_COMPRESS_T *c;
Packit Service 5195f2
    lzo_uint m_pos;
Packit Service 5195f2
#if defined(SWD_BEST_OFF)
Packit Service 5195f2
    lzo_uint best_pos[ SWD_BEST_OFF ];
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
/* private */
Packit Service 5195f2
    const lzo_bytep dict;
Packit Service 5195f2
    const lzo_bytep dict_end;
Packit Service 5195f2
    lzo_uint dict_len;
Packit Service 5195f2
Packit Service 5195f2
/* private */
Packit Service 5195f2
    lzo_uint ip;                /* input pointer (lookahead) */
Packit Service 5195f2
    lzo_uint bp;                /* buffer pointer */
Packit Service 5195f2
    lzo_uint rp;                /* remove pointer */
Packit Service 5195f2
    lzo_uint b_size;
Packit Service 5195f2
Packit Service 5195f2
    lzo_bytep b_wrap;
Packit Service 5195f2
Packit Service 5195f2
    lzo_uint node_count;
Packit Service 5195f2
    lzo_uint first_rp;
Packit Service 5195f2
Packit Service 5195f2
#if defined(__LZO_CHECKER)
Packit Service 5195f2
    /* malloc arrays of the exact size to detect any overrun */
Packit Service 5195f2
    unsigned char *b;
Packit Service 5195f2
    swd_uint *head3;
Packit Service 5195f2
    swd_uint *succ3;
Packit Service 5195f2
    swd_uint *best3;
Packit Service 5195f2
    swd_uint *llen3;
Packit Service 5195f2
# ifdef HEAD2
Packit Service 5195f2
    swd_uint *head2;
Packit Service 5195f2
# endif
Packit Service 5195f2
Packit Service 5195f2
#else
Packit Service 5195f2
    unsigned char b [ SWD_N + SWD_F + SWD_F ];
Packit Service 5195f2
    swd_uint head3 [ SWD_HSIZE ];
Packit Service 5195f2
    swd_uint succ3 [ SWD_N + SWD_F ];
Packit Service 5195f2
    swd_uint best3 [ SWD_N + SWD_F ];
Packit Service 5195f2
    swd_uint llen3 [ SWD_HSIZE ];
Packit Service 5195f2
# ifdef HEAD2
Packit Service 5195f2
    swd_uint head2 [ 65536L ];
Packit Service 5195f2
# endif
Packit Service 5195f2
#endif
Packit Service 5195f2
}
Packit Service 5195f2
lzo_swd_t;
Packit Service 5195f2
#define lzo_swd_p   lzo_swd_t *
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
#define s_b(s)      s->b
Packit Service 5195f2
#define s_head3(s)  s->head3
Packit Service 5195f2
#define s_succ3(s)  s->succ3
Packit Service 5195f2
#define s_best3(s)  s->best3
Packit Service 5195f2
#define s_llen3(s)  s->llen3
Packit Service 5195f2
#ifdef HEAD2
Packit Service 5195f2
#define s_head2(s)  s->head2
Packit Service 5195f2
#endif
Packit Service 5195f2
#define SIZEOF_LZO_SWD_T    (sizeof(lzo_swd_t))
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
/* Access macro for head3.
Packit Service 5195f2
 * head3[key] may be uninitialized if the list is emtpy,
Packit Service 5195f2
 * but then its value will never be used.
Packit Service 5195f2
 */
Packit Service 5195f2
#if 1 || defined(__LZO_CHECKER)
Packit Service 5195f2
#  define s_get_head3(s,key) \
Packit Service 5195f2
        ((swd_uint)((s_llen3(s)[key] == 0) ? SWD_UINT_MAX : s_head3(s)[key]))
Packit Service 5195f2
#else
Packit Service 5195f2
#  define s_get_head3(s,key)    (s_head3(s)[key])
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
/***********************************************************************
Packit Service 5195f2
//
Packit Service 5195f2
************************************************************************/
Packit Service 5195f2
Packit Service 5195f2
static
Packit Service 5195f2
void swd_initdict(lzo_swd_p s, const lzo_bytep dict, lzo_uint dict_len)
Packit Service 5195f2
{
Packit Service 5195f2
    s->dict = s->dict_end = NULL;
Packit Service 5195f2
    s->dict_len = 0;
Packit Service 5195f2
Packit Service 5195f2
    if (!dict || dict_len == 0)
Packit Service 5195f2
        return;
Packit Service 5195f2
    if (dict_len > s->swd_n)
Packit Service 5195f2
    {
Packit Service 5195f2
        dict += dict_len - s->swd_n;
Packit Service 5195f2
        dict_len = s->swd_n;
Packit Service 5195f2
    }
Packit Service 5195f2
Packit Service 5195f2
    s->dict = dict;
Packit Service 5195f2
    s->dict_len = dict_len;
Packit Service 5195f2
    s->dict_end = dict + dict_len;
Packit Service 5195f2
    lzo_memcpy(s_b(s),dict,dict_len);
Packit Service 5195f2
    s->ip = dict_len;
Packit Service 5195f2
}
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
static
Packit Service 5195f2
void swd_insertdict(lzo_swd_p s, lzo_uint node, lzo_uint len)
Packit Service 5195f2
{
Packit Service 5195f2
    lzo_uint key;
Packit Service 5195f2
Packit Service 5195f2
    s->node_count = s->swd_n - len;
Packit Service 5195f2
    s->first_rp = node;
Packit Service 5195f2
Packit Service 5195f2
    if (len) do
Packit Service 5195f2
    {
Packit Service 5195f2
        key = HEAD3(s_b(s),node);
Packit Service 5195f2
        s_succ3(s)[node] = s_get_head3(s,key);
Packit Service 5195f2
        s_head3(s)[key] = SWD_UINT(node);
Packit Service 5195f2
        s_best3(s)[node] = SWD_UINT(s->swd_f + 1);
Packit Service 5195f2
        s_llen3(s)[key]++;
Packit Service 5195f2
        assert(s_llen3(s)[key] <= s->swd_n);
Packit Service 5195f2
Packit Service 5195f2
#ifdef HEAD2
Packit Service 5195f2
        IF_HEAD2(s) {
Packit Service 5195f2
            key = HEAD2(s_b(s),node);
Packit Service 5195f2
            s_head2(s)[key] = SWD_UINT(node);
Packit Service 5195f2
        }
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
        node++;
Packit Service 5195f2
    }
Packit Service 5195f2
    while (--len != 0);
Packit Service 5195f2
}
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
/***********************************************************************
Packit Service 5195f2
//
Packit Service 5195f2
************************************************************************/
Packit Service 5195f2
Packit Service 5195f2
static void swd_exit(lzo_swd_p s);
Packit Service 5195f2
Packit Service 5195f2
static
Packit Service 5195f2
int swd_init(lzo_swd_p s, const lzo_bytep dict, lzo_uint dict_len)
Packit Service 5195f2
{
Packit Service 5195f2
#if defined(__LZO_CHECKER)
Packit Service 5195f2
    unsigned r = 1;
Packit Service 5195f2
    s->b = (lzo_bytep) malloc(SWD_N + SWD_F + SWD_F);
Packit Service 5195f2
    s->head3 = (swd_uintp) malloc(sizeof(swd_uint) * SWD_HSIZE);
Packit Service 5195f2
    s->succ3 = (swd_uintp) malloc(sizeof(swd_uint) * (SWD_N + SWD_F));
Packit Service 5195f2
    s->best3 = (swd_uintp) malloc(sizeof(swd_uint) * (SWD_N + SWD_F));
Packit Service 5195f2
    s->llen3 = (swd_uintp) malloc(sizeof(swd_uint) * SWD_HSIZE);
Packit Service 5195f2
    r &= s->b != NULL;
Packit Service 5195f2
    r &= s->head3 != NULL;
Packit Service 5195f2
    r &= s->succ3 != NULL;
Packit Service 5195f2
    r &= s->best3 != NULL;
Packit Service 5195f2
    r &= s->llen3 != NULL;
Packit Service 5195f2
#ifdef HEAD2
Packit Service 5195f2
    IF_HEAD2(s) {
Packit Service 5195f2
        s->head2 = (swd_uintp) malloc(sizeof(swd_uint) * 65536L);
Packit Service 5195f2
        r &= s->head2 != NULL;
Packit Service 5195f2
    }
Packit Service 5195f2
#endif
Packit Service 5195f2
    if (r != 1) {
Packit Service 5195f2
        swd_exit(s);
Packit Service 5195f2
        return LZO_E_OUT_OF_MEMORY;
Packit Service 5195f2
    }
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
    s->m_len = 0;
Packit Service 5195f2
    s->m_off = 0;
Packit Service 5195f2
#if defined(SWD_BEST_OFF)
Packit Service 5195f2
    {
Packit Service 5195f2
        unsigned i;
Packit Service 5195f2
        for (i = 0; i < SWD_BEST_OFF; i++)
Packit Service 5195f2
            s->best_off[i] = s->best_pos[i] = 0;
Packit Service 5195f2
    }
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
    s->swd_n = SWD_N;
Packit Service 5195f2
    s->swd_f = SWD_F;
Packit Service 5195f2
    s->swd_threshold = SWD_THRESHOLD;
Packit Service 5195f2
Packit Service 5195f2
    /* defaults */
Packit Service 5195f2
    s->max_chain = SWD_MAX_CHAIN;
Packit Service 5195f2
    s->nice_length = s->swd_f;
Packit Service 5195f2
    s->use_best_off = 0;
Packit Service 5195f2
    s->lazy_insert = 0;
Packit Service 5195f2
Packit Service 5195f2
    s->b_size = s->swd_n + s->swd_f;
Packit Service 5195f2
#if 0
Packit Service 5195f2
    if (2 * s->swd_f >= s->swd_n || s->b_size + s->swd_f >= SWD_UINT_MAX)
Packit Service 5195f2
        return LZO_E_ERROR;
Packit Service 5195f2
#else
Packit Service 5195f2
    LZO_COMPILE_TIME_ASSERT(!(0ul + 2 * SWD_F >= SWD_N))
Packit Service 5195f2
    LZO_COMPILE_TIME_ASSERT(!(0ul + SWD_N + SWD_F + SWD_F >= SWD_UINT_MAX))
Packit Service 5195f2
#endif
Packit Service 5195f2
    s->b_wrap = s_b(s) + s->b_size;
Packit Service 5195f2
    s->node_count = s->swd_n;
Packit Service 5195f2
Packit Service 5195f2
    lzo_memset(s_llen3(s), 0, (lzo_uint)sizeof(s_llen3(s)[0]) * (lzo_uint)SWD_HSIZE);
Packit Service 5195f2
#ifdef HEAD2
Packit Service 5195f2
    IF_HEAD2(s) {
Packit Service 5195f2
#if 1
Packit Service 5195f2
        lzo_memset(s_head2(s), 0xff, (lzo_uint)sizeof(s_head2(s)[0]) * 65536L);
Packit Service 5195f2
        assert(s_head2(s)[0] == NIL2);
Packit Service 5195f2
#else
Packit Service 5195f2
        lzo_xint i;
Packit Service 5195f2
        for (i = 0; i < 65536L; i++)
Packit Service 5195f2
            s_head2(s)[i] = NIL2;
Packit Service 5195f2
#endif
Packit Service 5195f2
    }
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
    s->ip = 0;
Packit Service 5195f2
    swd_initdict(s,dict,dict_len);
Packit Service 5195f2
    s->bp = s->ip;
Packit Service 5195f2
    s->first_rp = s->ip;
Packit Service 5195f2
Packit Service 5195f2
    assert(s->ip + s->swd_f <= s->b_size);
Packit Service 5195f2
#if 1
Packit Service 5195f2
    s->look = (lzo_uint) (s->c->in_end - s->c->ip);
Packit Service 5195f2
    if (s->look > 0)
Packit Service 5195f2
    {
Packit Service 5195f2
        if (s->look > s->swd_f)
Packit Service 5195f2
            s->look = s->swd_f;
Packit Service 5195f2
        lzo_memcpy(&s_b(s)[s->ip],s->c->ip,s->look);
Packit Service 5195f2
        s->c->ip += s->look;
Packit Service 5195f2
        s->ip += s->look;
Packit Service 5195f2
    }
Packit Service 5195f2
#else
Packit Service 5195f2
    s->look = 0;
Packit Service 5195f2
    while (s->look < s->swd_f)
Packit Service 5195f2
    {
Packit Service 5195f2
        int c;
Packit Service 5195f2
        if ((c = getbyte(*(s->c))) < 0)
Packit Service 5195f2
            break;
Packit Service 5195f2
        s_b(s)[s->ip] = LZO_BYTE(c);
Packit Service 5195f2
        s->ip++;
Packit Service 5195f2
        s->look++;
Packit Service 5195f2
    }
Packit Service 5195f2
#endif
Packit Service 5195f2
    if (s->ip == s->b_size)
Packit Service 5195f2
        s->ip = 0;
Packit Service 5195f2
Packit Service 5195f2
    if (s->look >= 2 && s->dict_len > 0)
Packit Service 5195f2
        swd_insertdict(s,0,s->dict_len);
Packit Service 5195f2
Packit Service 5195f2
    s->rp = s->first_rp;
Packit Service 5195f2
    if (s->rp >= s->node_count)
Packit Service 5195f2
        s->rp -= s->node_count;
Packit Service 5195f2
    else
Packit Service 5195f2
        s->rp += s->b_size - s->node_count;
Packit Service 5195f2
Packit Service 5195f2
#if 1 || defined(__LZO_CHECKER)
Packit Service 5195f2
    /* initialize memory for the first few HEAD3 (if s->ip is not far
Packit Service 5195f2
     * enough ahead to do this job for us). The value doesn't matter. */
Packit Service 5195f2
    if (s->look < 3) {
Packit Service 5195f2
        lzo_bytep p = &s_b(s)[s->bp+s->look];
Packit Service 5195f2
        p[0] = p[1] = p[2] = 0;
Packit Service 5195f2
    }
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
    return LZO_E_OK;
Packit Service 5195f2
}
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
static
Packit Service 5195f2
void swd_exit(lzo_swd_p s)
Packit Service 5195f2
{
Packit Service 5195f2
#if defined(__LZO_CHECKER)
Packit Service 5195f2
    /* free in reverse order of allocations */
Packit Service 5195f2
#ifdef HEAD2
Packit Service 5195f2
    free(s->head2); s->head2 = NULL;
Packit Service 5195f2
#endif
Packit Service 5195f2
    free(s->llen3); s->llen3 = NULL;
Packit Service 5195f2
    free(s->best3); s->best3 = NULL;
Packit Service 5195f2
    free(s->succ3); s->succ3 = NULL;
Packit Service 5195f2
    free(s->head3); s->head3 = NULL;
Packit Service 5195f2
    free(s->b); s->b = NULL;
Packit Service 5195f2
#else
Packit Service 5195f2
    LZO_UNUSED(s);
Packit Service 5195f2
#endif
Packit Service 5195f2
}
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
#define swd_pos2off(s,pos) \
Packit Service 5195f2
    (s->bp > (pos) ? s->bp - (pos) : s->b_size - ((pos) - s->bp))
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
/***********************************************************************
Packit Service 5195f2
//
Packit Service 5195f2
************************************************************************/
Packit Service 5195f2
Packit Service 5195f2
static __lzo_inline
Packit Service 5195f2
void swd_getbyte(lzo_swd_p s)
Packit Service 5195f2
{
Packit Service 5195f2
    int c;
Packit Service 5195f2
Packit Service 5195f2
    if ((c = getbyte(*(s->c))) < 0)
Packit Service 5195f2
    {
Packit Service 5195f2
        if (s->look > 0)
Packit Service 5195f2
            --s->look;
Packit Service 5195f2
#if 1 || defined(__LZO_CHECKER)
Packit Service 5195f2
        /* initialize memory - value doesn't matter */
Packit Service 5195f2
        s_b(s)[s->ip] = 0;
Packit Service 5195f2
        if (s->ip < s->swd_f)
Packit Service 5195f2
            s->b_wrap[s->ip] = 0;
Packit Service 5195f2
#endif
Packit Service 5195f2
    }
Packit Service 5195f2
    else
Packit Service 5195f2
    {
Packit Service 5195f2
        s_b(s)[s->ip] = LZO_BYTE(c);
Packit Service 5195f2
        if (s->ip < s->swd_f)
Packit Service 5195f2
            s->b_wrap[s->ip] = LZO_BYTE(c);
Packit Service 5195f2
    }
Packit Service 5195f2
    if (++s->ip == s->b_size)
Packit Service 5195f2
        s->ip = 0;
Packit Service 5195f2
    if (++s->bp == s->b_size)
Packit Service 5195f2
        s->bp = 0;
Packit Service 5195f2
    if (++s->rp == s->b_size)
Packit Service 5195f2
        s->rp = 0;
Packit Service 5195f2
}
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
/***********************************************************************
Packit Service 5195f2
// remove node from lists
Packit Service 5195f2
************************************************************************/
Packit Service 5195f2
Packit Service 5195f2
static __lzo_inline
Packit Service 5195f2
void swd_remove_node(lzo_swd_p s, lzo_uint node)
Packit Service 5195f2
{
Packit Service 5195f2
    if (s->node_count == 0)
Packit Service 5195f2
    {
Packit Service 5195f2
        lzo_uint key;
Packit Service 5195f2
Packit Service 5195f2
#ifdef LZO_DEBUG
Packit Service 5195f2
        if (s->first_rp != LZO_UINT_MAX)
Packit Service 5195f2
        {
Packit Service 5195f2
            if (node != s->first_rp)
Packit Service 5195f2
                printf("Remove %5ld: %5ld %5ld %5ld %5ld  %6ld %6ld\n",
Packit Service 5195f2
                        (long)node, (long)s->rp, (long)s->ip, (long)s->bp,
Packit Service 5195f2
                        (long)s->first_rp, (long)(s->ip - node),
Packit Service 5195f2
                        (long)(s->ip - s->bp));
Packit Service 5195f2
            assert(node == s->first_rp);
Packit Service 5195f2
            s->first_rp = LZO_UINT_MAX;
Packit Service 5195f2
        }
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
        key = HEAD3(s_b(s),node);
Packit Service 5195f2
        assert(s_llen3(s)[key] > 0);
Packit Service 5195f2
        --s_llen3(s)[key];
Packit Service 5195f2
Packit Service 5195f2
#ifdef HEAD2
Packit Service 5195f2
        IF_HEAD2(s) {
Packit Service 5195f2
            key = HEAD2(s_b(s),node);
Packit Service 5195f2
            assert(s_head2(s)[key] != NIL2);
Packit Service 5195f2
            if ((lzo_uint) s_head2(s)[key] == node)
Packit Service 5195f2
                s_head2(s)[key] = NIL2;
Packit Service 5195f2
        }
Packit Service 5195f2
#endif
Packit Service 5195f2
    }
Packit Service 5195f2
    else
Packit Service 5195f2
        --s->node_count;
Packit Service 5195f2
}
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
/***********************************************************************
Packit Service 5195f2
//
Packit Service 5195f2
************************************************************************/
Packit Service 5195f2
Packit Service 5195f2
static
Packit Service 5195f2
void swd_accept(lzo_swd_p s, lzo_uint n)
Packit Service 5195f2
{
Packit Service 5195f2
    assert(n <= s->look);
Packit Service 5195f2
Packit Service 5195f2
    if (n) do
Packit Service 5195f2
    {
Packit Service 5195f2
        lzo_uint key;
Packit Service 5195f2
Packit Service 5195f2
        swd_remove_node(s,s->rp);
Packit Service 5195f2
Packit Service 5195f2
        /* add bp into HEAD3 */
Packit Service 5195f2
        key = HEAD3(s_b(s),s->bp);
Packit Service 5195f2
        s_succ3(s)[s->bp] = s_get_head3(s,key);
Packit Service 5195f2
        s_head3(s)[key] = SWD_UINT(s->bp);
Packit Service 5195f2
        s_best3(s)[s->bp] = SWD_UINT(s->swd_f + 1);
Packit Service 5195f2
        s_llen3(s)[key]++;
Packit Service 5195f2
        assert(s_llen3(s)[key] <= s->swd_n);
Packit Service 5195f2
Packit Service 5195f2
#ifdef HEAD2
Packit Service 5195f2
        /* add bp into HEAD2 */
Packit Service 5195f2
        IF_HEAD2(s) {
Packit Service 5195f2
            key = HEAD2(s_b(s),s->bp);
Packit Service 5195f2
            s_head2(s)[key] = SWD_UINT(s->bp);
Packit Service 5195f2
        }
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
        swd_getbyte(s);
Packit Service 5195f2
    } while (--n != 0);
Packit Service 5195f2
}
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
/***********************************************************************
Packit Service 5195f2
//
Packit Service 5195f2
************************************************************************/
Packit Service 5195f2
Packit Service 5195f2
static
Packit Service 5195f2
void swd_search(lzo_swd_p s, lzo_uint node, lzo_uint cnt)
Packit Service 5195f2
{
Packit Service 5195f2
    const lzo_bytep p1;
Packit Service 5195f2
    const lzo_bytep p2;
Packit Service 5195f2
    const lzo_bytep px;
Packit Service 5195f2
    lzo_uint m_len = s->m_len;
Packit Service 5195f2
    const lzo_bytep b  = s_b(s);
Packit Service 5195f2
    const lzo_bytep bp = s_b(s) + s->bp;
Packit Service 5195f2
    const lzo_bytep bx = s_b(s) + s->bp + s->look;
Packit Service 5195f2
    unsigned char scan_end1;
Packit Service 5195f2
Packit Service 5195f2
    assert(s->m_len > 0);
Packit Service 5195f2
Packit Service 5195f2
    scan_end1 = bp[m_len - 1];
Packit Service 5195f2
    for ( ; cnt-- > 0; node = s_succ3(s)[node])
Packit Service 5195f2
    {
Packit Service 5195f2
        p1 = bp;
Packit Service 5195f2
        p2 = b + node;
Packit Service 5195f2
        px = bx;
Packit Service 5195f2
Packit Service 5195f2
        assert(m_len < s->look);
Packit Service 5195f2
Packit Service 5195f2
        if (
Packit Service 5195f2
#if 1
Packit Service 5195f2
            p2[m_len - 1] == scan_end1 &&
Packit Service 5195f2
            p2[m_len] == p1[m_len] &&
Packit Service 5195f2
#endif
Packit Service 5195f2
            p2[0] == p1[0] &&
Packit Service 5195f2
            p2[1] == p1[1])
Packit Service 5195f2
        {
Packit Service 5195f2
            lzo_uint i;
Packit Service 5195f2
            assert(lzo_memcmp(bp,&b[node],3) == 0);
Packit Service 5195f2
Packit Service 5195f2
#if 0 && (LZO_OPT_UNALIGNED32)
Packit Service 5195f2
            p1 += 3; p2 += 3;
Packit Service 5195f2
            while (p1 + 4 <= px && UA_GET_NE32(p1) == UA_GET_NE32(p2))
Packit Service 5195f2
                p1 += 4, p2 += 4;
Packit Service 5195f2
            while (p1 < px && *p1 == *p2)
Packit Service 5195f2
                p1 += 1, p2 += 1;
Packit Service 5195f2
#else
Packit Service 5195f2
            p1 += 2; p2 += 2;
Packit Service 5195f2
            do {} while (++p1 < px && *p1 == *++p2);
Packit Service 5195f2
#endif
Packit Service 5195f2
            i = pd(p1, bp);
Packit Service 5195f2
Packit Service 5195f2
#ifdef LZO_DEBUG
Packit Service 5195f2
            if (lzo_memcmp(bp,&b[node],i) != 0)
Packit Service 5195f2
                printf("%5ld %5ld %5ld %02x/%02x %02x/%02x\n",
Packit Service 5195f2
                        (long)s->bp, (long) node, (long) i,
Packit Service 5195f2
                        bp[0], bp[1], b[node], b[node+1]);
Packit Service 5195f2
#endif
Packit Service 5195f2
            assert(lzo_memcmp(bp,&b[node],i) == 0);
Packit Service 5195f2
Packit Service 5195f2
#if defined(SWD_BEST_OFF)
Packit Service 5195f2
            if (i < SWD_BEST_OFF)
Packit Service 5195f2
            {
Packit Service 5195f2
                if (s->best_pos[i] == 0)
Packit Service 5195f2
                    s->best_pos[i] = node + 1;
Packit Service 5195f2
            }
Packit Service 5195f2
#endif
Packit Service 5195f2
            if (i > m_len)
Packit Service 5195f2
            {
Packit Service 5195f2
                s->m_len = m_len = i;
Packit Service 5195f2
                s->m_pos = node;
Packit Service 5195f2
                if (m_len == s->look)
Packit Service 5195f2
                    return;
Packit Service 5195f2
                if (m_len >= s->nice_length)
Packit Service 5195f2
                    return;
Packit Service 5195f2
                if (m_len > (lzo_uint) s_best3(s)[node])
Packit Service 5195f2
                    return;
Packit Service 5195f2
                scan_end1 = bp[m_len - 1];
Packit Service 5195f2
            }
Packit Service 5195f2
        }
Packit Service 5195f2
    }
Packit Service 5195f2
}
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
/***********************************************************************
Packit Service 5195f2
//
Packit Service 5195f2
************************************************************************/
Packit Service 5195f2
Packit Service 5195f2
#ifdef HEAD2
Packit Service 5195f2
Packit Service 5195f2
static
Packit Service 5195f2
lzo_bool swd_search2(lzo_swd_p s)
Packit Service 5195f2
{
Packit Service 5195f2
    lzo_uint key;
Packit Service 5195f2
Packit Service 5195f2
    assert(s->look >= 2);
Packit Service 5195f2
    assert(s->m_len > 0);
Packit Service 5195f2
Packit Service 5195f2
    key = s_head2(s)[ HEAD2(s_b(s),s->bp) ];
Packit Service 5195f2
    if (key == NIL2)
Packit Service 5195f2
        return 0;
Packit Service 5195f2
#ifdef LZO_DEBUG
Packit Service 5195f2
    if (lzo_memcmp(&s_b(s)[s->bp],&s_b(s)[key],2) != 0)
Packit Service 5195f2
        printf("%5ld %5ld %02x/%02x %02x/%02x\n", (long)s->bp, (long)key,
Packit Service 5195f2
                s_b(s)[s->bp], s_b(s)[s->bp+1], s_b(s)[key], s_b(s)[key+1]);
Packit Service 5195f2
#endif
Packit Service 5195f2
    assert(lzo_memcmp(&s_b(s)[s->bp],&s_b(s)[key],2) == 0);
Packit Service 5195f2
#if defined(SWD_BEST_OFF)
Packit Service 5195f2
    if (s->best_pos[2] == 0)
Packit Service 5195f2
        s->best_pos[2] = key + 1;
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
    if (s->m_len < 2)
Packit Service 5195f2
    {
Packit Service 5195f2
        s->m_len = 2;
Packit Service 5195f2
        s->m_pos = key;
Packit Service 5195f2
    }
Packit Service 5195f2
    return 1;
Packit Service 5195f2
}
Packit Service 5195f2
Packit Service 5195f2
#endif
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
/***********************************************************************
Packit Service 5195f2
//
Packit Service 5195f2
************************************************************************/
Packit Service 5195f2
Packit Service 5195f2
static
Packit Service 5195f2
void swd_findbest(lzo_swd_p s)
Packit Service 5195f2
{
Packit Service 5195f2
    lzo_uint key;
Packit Service 5195f2
    lzo_uint cnt, node;
Packit Service 5195f2
    lzo_uint len;
Packit Service 5195f2
Packit Service 5195f2
    assert(s->m_len > 0);
Packit Service 5195f2
Packit Service 5195f2
    /* get current head, add bp into HEAD3 */
Packit Service 5195f2
    key = HEAD3(s_b(s),s->bp);
Packit Service 5195f2
    node = s_succ3(s)[s->bp] = s_get_head3(s,key);
Packit Service 5195f2
    cnt = s_llen3(s)[key]++;
Packit Service 5195f2
    assert(s_llen3(s)[key] <= s->swd_n + s->swd_f);
Packit Service 5195f2
    if (cnt > s->max_chain && s->max_chain > 0)
Packit Service 5195f2
        cnt = s->max_chain;
Packit Service 5195f2
    s_head3(s)[key] = SWD_UINT(s->bp);
Packit Service 5195f2
Packit Service 5195f2
    s->b_char = s_b(s)[s->bp];
Packit Service 5195f2
    len = s->m_len;
Packit Service 5195f2
    if (s->m_len >= s->look)
Packit Service 5195f2
    {
Packit Service 5195f2
        if (s->look == 0)
Packit Service 5195f2
            s->b_char = -1;
Packit Service 5195f2
        s->m_off = 0;
Packit Service 5195f2
        s_best3(s)[s->bp] = SWD_UINT(s->swd_f + 1);
Packit Service 5195f2
    }
Packit Service 5195f2
    else
Packit Service 5195f2
    {
Packit Service 5195f2
#if defined(HEAD2)
Packit Service 5195f2
        if (swd_search2(s) && s->look >= 3)
Packit Service 5195f2
            swd_search(s,node,cnt);
Packit Service 5195f2
#else
Packit Service 5195f2
        if (s->look >= 3)
Packit Service 5195f2
            swd_search(s,node,cnt);
Packit Service 5195f2
#endif
Packit Service 5195f2
        if (s->m_len > len)
Packit Service 5195f2
            s->m_off = swd_pos2off(s,s->m_pos);
Packit Service 5195f2
        s_best3(s)[s->bp] = SWD_UINT(s->m_len);
Packit Service 5195f2
Packit Service 5195f2
#if defined(SWD_BEST_OFF)
Packit Service 5195f2
        if (s->use_best_off)
Packit Service 5195f2
        {
Packit Service 5195f2
            unsigned i;
Packit Service 5195f2
            for (i = 2; i < SWD_BEST_OFF; i++)
Packit Service 5195f2
                if (s->best_pos[i] > 0)
Packit Service 5195f2
                    s->best_off[i] = swd_pos2off(s,s->best_pos[i]-1);
Packit Service 5195f2
                else
Packit Service 5195f2
                    s->best_off[i] = 0;
Packit Service 5195f2
        }
Packit Service 5195f2
#endif
Packit Service 5195f2
    }
Packit Service 5195f2
Packit Service 5195f2
    swd_remove_node(s,s->rp);
Packit Service 5195f2
Packit Service 5195f2
#ifdef HEAD2
Packit Service 5195f2
    /* add bp into HEAD2 */
Packit Service 5195f2
    IF_HEAD2(s) {
Packit Service 5195f2
        key = HEAD2(s_b(s),s->bp);
Packit Service 5195f2
        s_head2(s)[key] = SWD_UINT(s->bp);
Packit Service 5195f2
    }
Packit Service 5195f2
#endif
Packit Service 5195f2
}
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
#undef HEAD3
Packit Service 5195f2
#undef HEAD2
Packit Service 5195f2
#undef IF_HEAD2
Packit Service 5195f2
#undef s_get_head3
Packit Service 5195f2
Packit Service 5195f2
Packit Service 5195f2
/*
Packit Service 5195f2
vi:ts=4:et
Packit Service 5195f2
*/
Packit Service 5195f2