Blame src/lzo_swd.ch

Packit 679830
/* lzo_swd.ch -- sliding window dictionary
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
#if (LZO_UINT_MAX < LZO_0xffffffffL)
Packit 679830
#  error "LZO_UINT_MAX"
Packit 679830
#endif
Packit 679830
#if defined(LZO_DEBUG)
Packit 679830
#  include <stdio.h>
Packit 679830
#endif
Packit 679830
#if defined(__LZO_CHECKER)
Packit 679830
#  include <stdlib.h>
Packit 679830
#endif
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
//
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
/* unsigned type for dictionary access - don't waste memory here */
Packit 679830
#if (0UL + SWD_N + SWD_F + SWD_F < 65535UL)
Packit 679830
   typedef lzo_uint16_t     swd_uint;
Packit 679830
#  define SWD_UINT_MAX      0xffffu
Packit 679830
#else
Packit 679830
   typedef lzo_uint32_t     swd_uint;
Packit 679830
#  define SWD_UINT_MAX      0xffffffffu
Packit 679830
#endif
Packit 679830
#define swd_uintp           swd_uint *
Packit 679830
#define SWD_UINT(x)         ((swd_uint)(x))
Packit 679830
Packit 679830
Packit 679830
#ifndef SWD_HSIZE
Packit 679830
#  define SWD_HSIZE         16384
Packit 679830
#endif
Packit 679830
#ifndef SWD_MAX_CHAIN
Packit 679830
#  define SWD_MAX_CHAIN     2048
Packit 679830
#endif
Packit 679830
Packit 679830
#if !defined(HEAD3)
Packit 679830
#if 1
Packit 679830
#  define HEAD3(b,p) \
Packit 679830
    ((DMUL(0x9f5f,(((((lzo_xint)b[p]<<5)^b[p+1])<<5)^b[p+2]))>>5) & (SWD_HSIZE-1))
Packit 679830
#else
Packit 679830
#  define HEAD3(b,p) \
Packit 679830
    ((DMUL(0x9f5f,(((((lzo_xint)b[p+2]<<5)^b[p+1])<<5)^b[p]))>>5) & (SWD_HSIZE-1))
Packit 679830
#endif
Packit 679830
#endif
Packit 679830
Packit 679830
#if !(SWD_NO_HEAD2) && (SWD_THRESHOLD == 1) && !defined(HEAD2)
Packit 679830
#  if 1 && (LZO_OPT_UNALIGNED16)
Packit 679830
#    define HEAD2(b,p)      UA_GET_NE16((b)+(p))
Packit 679830
#  else
Packit 679830
#    define HEAD2(b,p)      (b[p] ^ ((unsigned)b[(p)+1]<<8))
Packit 679830
#  endif
Packit 679830
#  define NIL2              SWD_UINT_MAX
Packit 679830
#endif
Packit 679830
#ifndef IF_HEAD2
Packit 679830
#define IF_HEAD2(s)         /*empty*/
Packit 679830
#endif
Packit 679830
Packit 679830
Packit 679830
typedef struct
Packit 679830
{
Packit 679830
/* public - "built-in" */
Packit 679830
    lzo_uint swd_n;
Packit 679830
    lzo_uint swd_f;
Packit 679830
    lzo_uint swd_threshold;
Packit 679830
Packit 679830
/* public - configuration */
Packit 679830
    lzo_uint max_chain;
Packit 679830
    lzo_uint nice_length;
Packit 679830
    lzo_bool use_best_off;
Packit 679830
    lzo_uint lazy_insert;
Packit 679830
Packit 679830
/* public - output */
Packit 679830
    lzo_uint m_len;
Packit 679830
    lzo_uint m_off;
Packit 679830
    lzo_uint look;
Packit 679830
    int b_char;
Packit 679830
#if defined(SWD_BEST_OFF)
Packit 679830
    lzo_uint best_off[ SWD_BEST_OFF ];
Packit 679830
#endif
Packit 679830
Packit 679830
/* semi public */
Packit 679830
    LZO_COMPRESS_T *c;
Packit 679830
    lzo_uint m_pos;
Packit 679830
#if defined(SWD_BEST_OFF)
Packit 679830
    lzo_uint best_pos[ SWD_BEST_OFF ];
Packit 679830
#endif
Packit 679830
Packit 679830
/* private */
Packit 679830
    const lzo_bytep dict;
Packit 679830
    const lzo_bytep dict_end;
Packit 679830
    lzo_uint dict_len;
Packit 679830
Packit 679830
/* private */
Packit 679830
    lzo_uint ip;                /* input pointer (lookahead) */
Packit 679830
    lzo_uint bp;                /* buffer pointer */
Packit 679830
    lzo_uint rp;                /* remove pointer */
Packit 679830
    lzo_uint b_size;
Packit 679830
Packit 679830
    lzo_bytep b_wrap;
Packit 679830
Packit 679830
    lzo_uint node_count;
Packit 679830
    lzo_uint first_rp;
Packit 679830
Packit 679830
#if defined(__LZO_CHECKER)
Packit 679830
    /* malloc arrays of the exact size to detect any overrun */
Packit 679830
    unsigned char *b;
Packit 679830
    swd_uint *head3;
Packit 679830
    swd_uint *succ3;
Packit 679830
    swd_uint *best3;
Packit 679830
    swd_uint *llen3;
Packit 679830
# ifdef HEAD2
Packit 679830
    swd_uint *head2;
Packit 679830
# endif
Packit 679830
Packit 679830
#else
Packit 679830
    unsigned char b [ SWD_N + SWD_F + SWD_F ];
Packit 679830
    swd_uint head3 [ SWD_HSIZE ];
Packit 679830
    swd_uint succ3 [ SWD_N + SWD_F ];
Packit 679830
    swd_uint best3 [ SWD_N + SWD_F ];
Packit 679830
    swd_uint llen3 [ SWD_HSIZE ];
Packit 679830
# ifdef HEAD2
Packit 679830
    swd_uint head2 [ 65536L ];
Packit 679830
# endif
Packit 679830
#endif
Packit 679830
}
Packit 679830
lzo_swd_t;
Packit 679830
#define lzo_swd_p   lzo_swd_t *
Packit 679830
Packit 679830
Packit 679830
#define s_b(s)      s->b
Packit 679830
#define s_head3(s)  s->head3
Packit 679830
#define s_succ3(s)  s->succ3
Packit 679830
#define s_best3(s)  s->best3
Packit 679830
#define s_llen3(s)  s->llen3
Packit 679830
#ifdef HEAD2
Packit 679830
#define s_head2(s)  s->head2
Packit 679830
#endif
Packit 679830
#define SIZEOF_LZO_SWD_T    (sizeof(lzo_swd_t))
Packit 679830
Packit 679830
Packit 679830
/* Access macro for head3.
Packit 679830
 * head3[key] may be uninitialized if the list is emtpy,
Packit 679830
 * but then its value will never be used.
Packit 679830
 */
Packit 679830
#if 1 || defined(__LZO_CHECKER)
Packit 679830
#  define s_get_head3(s,key) \
Packit 679830
        ((swd_uint)((s_llen3(s)[key] == 0) ? SWD_UINT_MAX : s_head3(s)[key]))
Packit 679830
#else
Packit 679830
#  define s_get_head3(s,key)    (s_head3(s)[key])
Packit 679830
#endif
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
//
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
static
Packit 679830
void swd_initdict(lzo_swd_p s, const lzo_bytep dict, lzo_uint dict_len)
Packit 679830
{
Packit 679830
    s->dict = s->dict_end = NULL;
Packit 679830
    s->dict_len = 0;
Packit 679830
Packit 679830
    if (!dict || dict_len == 0)
Packit 679830
        return;
Packit 679830
    if (dict_len > s->swd_n)
Packit 679830
    {
Packit 679830
        dict += dict_len - s->swd_n;
Packit 679830
        dict_len = s->swd_n;
Packit 679830
    }
Packit 679830
Packit 679830
    s->dict = dict;
Packit 679830
    s->dict_len = dict_len;
Packit 679830
    s->dict_end = dict + dict_len;
Packit 679830
    lzo_memcpy(s_b(s),dict,dict_len);
Packit 679830
    s->ip = dict_len;
Packit 679830
}
Packit 679830
Packit 679830
Packit 679830
static
Packit 679830
void swd_insertdict(lzo_swd_p s, lzo_uint node, lzo_uint len)
Packit 679830
{
Packit 679830
    lzo_uint key;
Packit 679830
Packit 679830
    s->node_count = s->swd_n - len;
Packit 679830
    s->first_rp = node;
Packit 679830
Packit 679830
    if (len) do
Packit 679830
    {
Packit 679830
        key = HEAD3(s_b(s),node);
Packit 679830
        s_succ3(s)[node] = s_get_head3(s,key);
Packit 679830
        s_head3(s)[key] = SWD_UINT(node);
Packit 679830
        s_best3(s)[node] = SWD_UINT(s->swd_f + 1);
Packit 679830
        s_llen3(s)[key]++;
Packit 679830
        assert(s_llen3(s)[key] <= s->swd_n);
Packit 679830
Packit 679830
#ifdef HEAD2
Packit 679830
        IF_HEAD2(s) {
Packit 679830
            key = HEAD2(s_b(s),node);
Packit 679830
            s_head2(s)[key] = SWD_UINT(node);
Packit 679830
        }
Packit 679830
#endif
Packit 679830
Packit 679830
        node++;
Packit 679830
    }
Packit 679830
    while (--len != 0);
Packit 679830
}
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
//
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
static void swd_exit(lzo_swd_p s);
Packit 679830
Packit 679830
static
Packit 679830
int swd_init(lzo_swd_p s, const lzo_bytep dict, lzo_uint dict_len)
Packit 679830
{
Packit 679830
#if defined(__LZO_CHECKER)
Packit 679830
    unsigned r = 1;
Packit 679830
    s->b = (lzo_bytep) malloc(SWD_N + SWD_F + SWD_F);
Packit 679830
    s->head3 = (swd_uintp) malloc(sizeof(swd_uint) * SWD_HSIZE);
Packit 679830
    s->succ3 = (swd_uintp) malloc(sizeof(swd_uint) * (SWD_N + SWD_F));
Packit 679830
    s->best3 = (swd_uintp) malloc(sizeof(swd_uint) * (SWD_N + SWD_F));
Packit 679830
    s->llen3 = (swd_uintp) malloc(sizeof(swd_uint) * SWD_HSIZE);
Packit 679830
    r &= s->b != NULL;
Packit 679830
    r &= s->head3 != NULL;
Packit 679830
    r &= s->succ3 != NULL;
Packit 679830
    r &= s->best3 != NULL;
Packit 679830
    r &= s->llen3 != NULL;
Packit 679830
#ifdef HEAD2
Packit 679830
    IF_HEAD2(s) {
Packit 679830
        s->head2 = (swd_uintp) malloc(sizeof(swd_uint) * 65536L);
Packit 679830
        r &= s->head2 != NULL;
Packit 679830
    }
Packit 679830
#endif
Packit 679830
    if (r != 1) {
Packit 679830
        swd_exit(s);
Packit 679830
        return LZO_E_OUT_OF_MEMORY;
Packit 679830
    }
Packit 679830
#endif
Packit 679830
Packit 679830
    s->m_len = 0;
Packit 679830
    s->m_off = 0;
Packit 679830
#if defined(SWD_BEST_OFF)
Packit 679830
    {
Packit 679830
        unsigned i;
Packit 679830
        for (i = 0; i < SWD_BEST_OFF; i++)
Packit 679830
            s->best_off[i] = s->best_pos[i] = 0;
Packit 679830
    }
Packit 679830
#endif
Packit 679830
Packit 679830
    s->swd_n = SWD_N;
Packit 679830
    s->swd_f = SWD_F;
Packit 679830
    s->swd_threshold = SWD_THRESHOLD;
Packit 679830
Packit 679830
    /* defaults */
Packit 679830
    s->max_chain = SWD_MAX_CHAIN;
Packit 679830
    s->nice_length = s->swd_f;
Packit 679830
    s->use_best_off = 0;
Packit 679830
    s->lazy_insert = 0;
Packit 679830
Packit 679830
    s->b_size = s->swd_n + s->swd_f;
Packit 679830
#if 0
Packit 679830
    if (2 * s->swd_f >= s->swd_n || s->b_size + s->swd_f >= SWD_UINT_MAX)
Packit 679830
        return LZO_E_ERROR;
Packit 679830
#else
Packit 679830
    LZO_COMPILE_TIME_ASSERT(!(0ul + 2 * SWD_F >= SWD_N))
Packit 679830
    LZO_COMPILE_TIME_ASSERT(!(0ul + SWD_N + SWD_F + SWD_F >= SWD_UINT_MAX))
Packit 679830
#endif
Packit 679830
    s->b_wrap = s_b(s) + s->b_size;
Packit 679830
    s->node_count = s->swd_n;
Packit 679830
Packit 679830
    lzo_memset(s_llen3(s), 0, (lzo_uint)sizeof(s_llen3(s)[0]) * (lzo_uint)SWD_HSIZE);
Packit 679830
#ifdef HEAD2
Packit 679830
    IF_HEAD2(s) {
Packit 679830
#if 1
Packit 679830
        lzo_memset(s_head2(s), 0xff, (lzo_uint)sizeof(s_head2(s)[0]) * 65536L);
Packit 679830
        assert(s_head2(s)[0] == NIL2);
Packit 679830
#else
Packit 679830
        lzo_xint i;
Packit 679830
        for (i = 0; i < 65536L; i++)
Packit 679830
            s_head2(s)[i] = NIL2;
Packit 679830
#endif
Packit 679830
    }
Packit 679830
#endif
Packit 679830
Packit 679830
    s->ip = 0;
Packit 679830
    swd_initdict(s,dict,dict_len);
Packit 679830
    s->bp = s->ip;
Packit 679830
    s->first_rp = s->ip;
Packit 679830
Packit 679830
    assert(s->ip + s->swd_f <= s->b_size);
Packit 679830
#if 1
Packit 679830
    s->look = (lzo_uint) (s->c->in_end - s->c->ip);
Packit 679830
    if (s->look > 0)
Packit 679830
    {
Packit 679830
        if (s->look > s->swd_f)
Packit 679830
            s->look = s->swd_f;
Packit 679830
        lzo_memcpy(&s_b(s)[s->ip],s->c->ip,s->look);
Packit 679830
        s->c->ip += s->look;
Packit 679830
        s->ip += s->look;
Packit 679830
    }
Packit 679830
#else
Packit 679830
    s->look = 0;
Packit 679830
    while (s->look < s->swd_f)
Packit 679830
    {
Packit 679830
        int c;
Packit 679830
        if ((c = getbyte(*(s->c))) < 0)
Packit 679830
            break;
Packit 679830
        s_b(s)[s->ip] = LZO_BYTE(c);
Packit 679830
        s->ip++;
Packit 679830
        s->look++;
Packit 679830
    }
Packit 679830
#endif
Packit 679830
    if (s->ip == s->b_size)
Packit 679830
        s->ip = 0;
Packit 679830
Packit 679830
    if (s->look >= 2 && s->dict_len > 0)
Packit 679830
        swd_insertdict(s,0,s->dict_len);
Packit 679830
Packit 679830
    s->rp = s->first_rp;
Packit 679830
    if (s->rp >= s->node_count)
Packit 679830
        s->rp -= s->node_count;
Packit 679830
    else
Packit 679830
        s->rp += s->b_size - s->node_count;
Packit 679830
Packit 679830
#if 1 || defined(__LZO_CHECKER)
Packit 679830
    /* initialize memory for the first few HEAD3 (if s->ip is not far
Packit 679830
     * enough ahead to do this job for us). The value doesn't matter. */
Packit 679830
    if (s->look < 3) {
Packit 679830
        lzo_bytep p = &s_b(s)[s->bp+s->look];
Packit 679830
        p[0] = p[1] = p[2] = 0;
Packit 679830
    }
Packit 679830
#endif
Packit 679830
Packit 679830
    return LZO_E_OK;
Packit 679830
}
Packit 679830
Packit 679830
Packit 679830
static
Packit 679830
void swd_exit(lzo_swd_p s)
Packit 679830
{
Packit 679830
#if defined(__LZO_CHECKER)
Packit 679830
    /* free in reverse order of allocations */
Packit 679830
#ifdef HEAD2
Packit 679830
    free(s->head2); s->head2 = NULL;
Packit 679830
#endif
Packit 679830
    free(s->llen3); s->llen3 = NULL;
Packit 679830
    free(s->best3); s->best3 = NULL;
Packit 679830
    free(s->succ3); s->succ3 = NULL;
Packit 679830
    free(s->head3); s->head3 = NULL;
Packit 679830
    free(s->b); s->b = NULL;
Packit 679830
#else
Packit 679830
    LZO_UNUSED(s);
Packit 679830
#endif
Packit 679830
}
Packit 679830
Packit 679830
Packit 679830
#define swd_pos2off(s,pos) \
Packit 679830
    (s->bp > (pos) ? s->bp - (pos) : s->b_size - ((pos) - s->bp))
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
//
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
static __lzo_inline
Packit 679830
void swd_getbyte(lzo_swd_p s)
Packit 679830
{
Packit 679830
    int c;
Packit 679830
Packit 679830
    if ((c = getbyte(*(s->c))) < 0)
Packit 679830
    {
Packit 679830
        if (s->look > 0)
Packit 679830
            --s->look;
Packit 679830
#if 1 || defined(__LZO_CHECKER)
Packit 679830
        /* initialize memory - value doesn't matter */
Packit 679830
        s_b(s)[s->ip] = 0;
Packit 679830
        if (s->ip < s->swd_f)
Packit 679830
            s->b_wrap[s->ip] = 0;
Packit 679830
#endif
Packit 679830
    }
Packit 679830
    else
Packit 679830
    {
Packit 679830
        s_b(s)[s->ip] = LZO_BYTE(c);
Packit 679830
        if (s->ip < s->swd_f)
Packit 679830
            s->b_wrap[s->ip] = LZO_BYTE(c);
Packit 679830
    }
Packit 679830
    if (++s->ip == s->b_size)
Packit 679830
        s->ip = 0;
Packit 679830
    if (++s->bp == s->b_size)
Packit 679830
        s->bp = 0;
Packit 679830
    if (++s->rp == s->b_size)
Packit 679830
        s->rp = 0;
Packit 679830
}
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
// remove node from lists
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
static __lzo_inline
Packit 679830
void swd_remove_node(lzo_swd_p s, lzo_uint node)
Packit 679830
{
Packit 679830
    if (s->node_count == 0)
Packit 679830
    {
Packit 679830
        lzo_uint key;
Packit 679830
Packit 679830
#ifdef LZO_DEBUG
Packit 679830
        if (s->first_rp != LZO_UINT_MAX)
Packit 679830
        {
Packit 679830
            if (node != s->first_rp)
Packit 679830
                printf("Remove %5ld: %5ld %5ld %5ld %5ld  %6ld %6ld\n",
Packit 679830
                        (long)node, (long)s->rp, (long)s->ip, (long)s->bp,
Packit 679830
                        (long)s->first_rp, (long)(s->ip - node),
Packit 679830
                        (long)(s->ip - s->bp));
Packit 679830
            assert(node == s->first_rp);
Packit 679830
            s->first_rp = LZO_UINT_MAX;
Packit 679830
        }
Packit 679830
#endif
Packit 679830
Packit 679830
        key = HEAD3(s_b(s),node);
Packit 679830
        assert(s_llen3(s)[key] > 0);
Packit 679830
        --s_llen3(s)[key];
Packit 679830
Packit 679830
#ifdef HEAD2
Packit 679830
        IF_HEAD2(s) {
Packit 679830
            key = HEAD2(s_b(s),node);
Packit 679830
            assert(s_head2(s)[key] != NIL2);
Packit 679830
            if ((lzo_uint) s_head2(s)[key] == node)
Packit 679830
                s_head2(s)[key] = NIL2;
Packit 679830
        }
Packit 679830
#endif
Packit 679830
    }
Packit 679830
    else
Packit 679830
        --s->node_count;
Packit 679830
}
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
//
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
static
Packit 679830
void swd_accept(lzo_swd_p s, lzo_uint n)
Packit 679830
{
Packit 679830
    assert(n <= s->look);
Packit 679830
Packit 679830
    if (n) do
Packit 679830
    {
Packit 679830
        lzo_uint key;
Packit 679830
Packit 679830
        swd_remove_node(s,s->rp);
Packit 679830
Packit 679830
        /* add bp into HEAD3 */
Packit 679830
        key = HEAD3(s_b(s),s->bp);
Packit 679830
        s_succ3(s)[s->bp] = s_get_head3(s,key);
Packit 679830
        s_head3(s)[key] = SWD_UINT(s->bp);
Packit 679830
        s_best3(s)[s->bp] = SWD_UINT(s->swd_f + 1);
Packit 679830
        s_llen3(s)[key]++;
Packit 679830
        assert(s_llen3(s)[key] <= s->swd_n);
Packit 679830
Packit 679830
#ifdef HEAD2
Packit 679830
        /* add bp into HEAD2 */
Packit 679830
        IF_HEAD2(s) {
Packit 679830
            key = HEAD2(s_b(s),s->bp);
Packit 679830
            s_head2(s)[key] = SWD_UINT(s->bp);
Packit 679830
        }
Packit 679830
#endif
Packit 679830
Packit 679830
        swd_getbyte(s);
Packit 679830
    } while (--n != 0);
Packit 679830
}
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
//
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
static
Packit 679830
void swd_search(lzo_swd_p s, lzo_uint node, lzo_uint cnt)
Packit 679830
{
Packit 679830
    const lzo_bytep p1;
Packit 679830
    const lzo_bytep p2;
Packit 679830
    const lzo_bytep px;
Packit 679830
    lzo_uint m_len = s->m_len;
Packit 679830
    const lzo_bytep b  = s_b(s);
Packit 679830
    const lzo_bytep bp = s_b(s) + s->bp;
Packit 679830
    const lzo_bytep bx = s_b(s) + s->bp + s->look;
Packit 679830
    unsigned char scan_end1;
Packit 679830
Packit 679830
    assert(s->m_len > 0);
Packit 679830
Packit 679830
    scan_end1 = bp[m_len - 1];
Packit 679830
    for ( ; cnt-- > 0; node = s_succ3(s)[node])
Packit 679830
    {
Packit 679830
        p1 = bp;
Packit 679830
        p2 = b + node;
Packit 679830
        px = bx;
Packit 679830
Packit 679830
        assert(m_len < s->look);
Packit 679830
Packit 679830
        if (
Packit 679830
#if 1
Packit 679830
            p2[m_len - 1] == scan_end1 &&
Packit 679830
            p2[m_len] == p1[m_len] &&
Packit 679830
#endif
Packit 679830
            p2[0] == p1[0] &&
Packit 679830
            p2[1] == p1[1])
Packit 679830
        {
Packit 679830
            lzo_uint i;
Packit 679830
            assert(lzo_memcmp(bp,&b[node],3) == 0);
Packit 679830
Packit 679830
#if 0 && (LZO_OPT_UNALIGNED32)
Packit 679830
            p1 += 3; p2 += 3;
Packit 679830
            while (p1 + 4 <= px && UA_GET_NE32(p1) == UA_GET_NE32(p2))
Packit 679830
                p1 += 4, p2 += 4;
Packit 679830
            while (p1 < px && *p1 == *p2)
Packit 679830
                p1 += 1, p2 += 1;
Packit 679830
#else
Packit 679830
            p1 += 2; p2 += 2;
Packit 679830
            do {} while (++p1 < px && *p1 == *++p2);
Packit 679830
#endif
Packit 679830
            i = pd(p1, bp);
Packit 679830
Packit 679830
#ifdef LZO_DEBUG
Packit 679830
            if (lzo_memcmp(bp,&b[node],i) != 0)
Packit 679830
                printf("%5ld %5ld %5ld %02x/%02x %02x/%02x\n",
Packit 679830
                        (long)s->bp, (long) node, (long) i,
Packit 679830
                        bp[0], bp[1], b[node], b[node+1]);
Packit 679830
#endif
Packit 679830
            assert(lzo_memcmp(bp,&b[node],i) == 0);
Packit 679830
Packit 679830
#if defined(SWD_BEST_OFF)
Packit 679830
            if (i < SWD_BEST_OFF)
Packit 679830
            {
Packit 679830
                if (s->best_pos[i] == 0)
Packit 679830
                    s->best_pos[i] = node + 1;
Packit 679830
            }
Packit 679830
#endif
Packit 679830
            if (i > m_len)
Packit 679830
            {
Packit 679830
                s->m_len = m_len = i;
Packit 679830
                s->m_pos = node;
Packit 679830
                if (m_len == s->look)
Packit 679830
                    return;
Packit 679830
                if (m_len >= s->nice_length)
Packit 679830
                    return;
Packit 679830
                if (m_len > (lzo_uint) s_best3(s)[node])
Packit 679830
                    return;
Packit 679830
                scan_end1 = bp[m_len - 1];
Packit 679830
            }
Packit 679830
        }
Packit 679830
    }
Packit 679830
}
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
//
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
#ifdef HEAD2
Packit 679830
Packit 679830
static
Packit 679830
lzo_bool swd_search2(lzo_swd_p s)
Packit 679830
{
Packit 679830
    lzo_uint key;
Packit 679830
Packit 679830
    assert(s->look >= 2);
Packit 679830
    assert(s->m_len > 0);
Packit 679830
Packit 679830
    key = s_head2(s)[ HEAD2(s_b(s),s->bp) ];
Packit 679830
    if (key == NIL2)
Packit 679830
        return 0;
Packit 679830
#ifdef LZO_DEBUG
Packit 679830
    if (lzo_memcmp(&s_b(s)[s->bp],&s_b(s)[key],2) != 0)
Packit 679830
        printf("%5ld %5ld %02x/%02x %02x/%02x\n", (long)s->bp, (long)key,
Packit 679830
                s_b(s)[s->bp], s_b(s)[s->bp+1], s_b(s)[key], s_b(s)[key+1]);
Packit 679830
#endif
Packit 679830
    assert(lzo_memcmp(&s_b(s)[s->bp],&s_b(s)[key],2) == 0);
Packit 679830
#if defined(SWD_BEST_OFF)
Packit 679830
    if (s->best_pos[2] == 0)
Packit 679830
        s->best_pos[2] = key + 1;
Packit 679830
#endif
Packit 679830
Packit 679830
    if (s->m_len < 2)
Packit 679830
    {
Packit 679830
        s->m_len = 2;
Packit 679830
        s->m_pos = key;
Packit 679830
    }
Packit 679830
    return 1;
Packit 679830
}
Packit 679830
Packit 679830
#endif
Packit 679830
Packit 679830
Packit 679830
/***********************************************************************
Packit 679830
//
Packit 679830
************************************************************************/
Packit 679830
Packit 679830
static
Packit 679830
void swd_findbest(lzo_swd_p s)
Packit 679830
{
Packit 679830
    lzo_uint key;
Packit 679830
    lzo_uint cnt, node;
Packit 679830
    lzo_uint len;
Packit 679830
Packit 679830
    assert(s->m_len > 0);
Packit 679830
Packit 679830
    /* get current head, add bp into HEAD3 */
Packit 679830
    key = HEAD3(s_b(s),s->bp);
Packit 679830
    node = s_succ3(s)[s->bp] = s_get_head3(s,key);
Packit 679830
    cnt = s_llen3(s)[key]++;
Packit 679830
    assert(s_llen3(s)[key] <= s->swd_n + s->swd_f);
Packit 679830
    if (cnt > s->max_chain && s->max_chain > 0)
Packit 679830
        cnt = s->max_chain;
Packit 679830
    s_head3(s)[key] = SWD_UINT(s->bp);
Packit 679830
Packit 679830
    s->b_char = s_b(s)[s->bp];
Packit 679830
    len = s->m_len;
Packit 679830
    if (s->m_len >= s->look)
Packit 679830
    {
Packit 679830
        if (s->look == 0)
Packit 679830
            s->b_char = -1;
Packit 679830
        s->m_off = 0;
Packit 679830
        s_best3(s)[s->bp] = SWD_UINT(s->swd_f + 1);
Packit 679830
    }
Packit 679830
    else
Packit 679830
    {
Packit 679830
#if defined(HEAD2)
Packit 679830
        if (swd_search2(s) && s->look >= 3)
Packit 679830
            swd_search(s,node,cnt);
Packit 679830
#else
Packit 679830
        if (s->look >= 3)
Packit 679830
            swd_search(s,node,cnt);
Packit 679830
#endif
Packit 679830
        if (s->m_len > len)
Packit 679830
            s->m_off = swd_pos2off(s,s->m_pos);
Packit 679830
        s_best3(s)[s->bp] = SWD_UINT(s->m_len);
Packit 679830
Packit 679830
#if defined(SWD_BEST_OFF)
Packit 679830
        if (s->use_best_off)
Packit 679830
        {
Packit 679830
            unsigned i;
Packit 679830
            for (i = 2; i < SWD_BEST_OFF; i++)
Packit 679830
                if (s->best_pos[i] > 0)
Packit 679830
                    s->best_off[i] = swd_pos2off(s,s->best_pos[i]-1);
Packit 679830
                else
Packit 679830
                    s->best_off[i] = 0;
Packit 679830
        }
Packit 679830
#endif
Packit 679830
    }
Packit 679830
Packit 679830
    swd_remove_node(s,s->rp);
Packit 679830
Packit 679830
#ifdef HEAD2
Packit 679830
    /* add bp into HEAD2 */
Packit 679830
    IF_HEAD2(s) {
Packit 679830
        key = HEAD2(s_b(s),s->bp);
Packit 679830
        s_head2(s)[key] = SWD_UINT(s->bp);
Packit 679830
    }
Packit 679830
#endif
Packit 679830
}
Packit 679830
Packit 679830
Packit 679830
#undef HEAD3
Packit 679830
#undef HEAD2
Packit 679830
#undef IF_HEAD2
Packit 679830
#undef s_get_head3
Packit 679830
Packit 679830
Packit 679830
/*
Packit 679830
vi:ts=4:et
Packit 679830
*/
Packit 679830