blob: 8273612a2e46f8bb3d917b7c85343bf90c55412d [file] [log] [blame]
/* lzo_mchw.ch -- matching functions using a window
This file is part of the LZO real-time data compression library.
Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
The LZO library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
The LZO library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the LZO library; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
*/
/***********************************************************************
//
************************************************************************/
typedef struct
{
unsigned init;
lzo_uint look; /* bytes in lookahead buffer */
lzo_uint m_len;
lzo_uint m_off;
lzo_uint last_m_len;
lzo_uint last_m_off;
const lzo_bytep bp;
const lzo_bytep ip;
const lzo_bytep in;
const lzo_bytep in_end;
lzo_bytep out;
lzo_callback_p cb;
lzo_uint textsize; /* text size counter */
lzo_uint codesize; /* code size counter */
lzo_uint printcount; /* counter for reporting progress every 1K bytes */
/* some stats */
unsigned long lit_bytes;
unsigned long match_bytes;
unsigned long rep_bytes;
unsigned long lazy;
#if defined(LZO1B)
lzo_uint r1_m_len;
/* some stats */
unsigned long r1_r, m3_r, m2_m, m3_m;
#endif
#if defined(LZO1C)
lzo_uint r1_m_len;
lzo_bytep m3;
/* some stats */
unsigned long r1_r, m3_r, m2_m, m3_m;
#endif
#if defined(LZO1F)
lzo_uint r1_lit;
lzo_uint r1_m_len;
/* some stats */
unsigned long r1_r, m2_m, m3_m;
#endif
#if defined(LZO1X) || defined(LZO1Y) || defined(LZO1Z)
lzo_uint r1_lit;
lzo_uint r1_m_len;
/* some stats */
unsigned long m1a_m, m1b_m, m2_m, m3_m, m4_m;
unsigned long lit1_r, lit2_r, lit3_r;
#endif
#if defined(LZO2A)
/* some stats */
unsigned long m1, m2, m3, m4;
#endif
}
LZO_COMPRESS_T;
#define getbyte(c) ((c).ip < (c).in_end ? *((c).ip)++ : (-1))
#include "lzo_swd.ch"
/***********************************************************************
//
************************************************************************/
static int
init_match ( LZO_COMPRESS_T *c, lzo_swd_p s,
const lzo_bytep dict, lzo_uint dict_len,
lzo_uint32_t flags )
{
int r;
assert(!c->init);
c->init = 1;
s->c = c;
c->last_m_len = c->last_m_off = 0;
c->textsize = c->codesize = c->printcount = 0;
c->lit_bytes = c->match_bytes = c->rep_bytes = 0;
c->lazy = 0;
r = swd_init(s,dict,dict_len);
if (r != LZO_E_OK)
{
swd_exit(s);
return r;
}
s->use_best_off = (flags & 1) ? 1 : 0;
return LZO_E_OK;
}
/***********************************************************************
//
************************************************************************/
static int
find_match ( LZO_COMPRESS_T *c, lzo_swd_p s,
lzo_uint this_len, lzo_uint skip )
{
assert(c->init);
if (skip > 0)
{
assert(this_len >= skip);
swd_accept(s, this_len - skip);
c->textsize += this_len - skip + 1;
}
else
{
assert(this_len <= 1);
c->textsize += this_len - skip;
}
s->m_len = SWD_THRESHOLD;
s->m_off = 0;
#ifdef SWD_BEST_OFF
if (s->use_best_off)
lzo_memset(s->best_pos,0,sizeof(s->best_pos));
#endif
swd_findbest(s);
c->m_len = s->m_len;
c->m_off = s->m_off;
swd_getbyte(s);
if (s->b_char < 0)
{
c->look = 0;
c->m_len = 0;
swd_exit(s);
}
else
{
c->look = s->look + 1;
}
c->bp = c->ip - c->look;
#if 0
/* brute force match search */
if (c->m_len > SWD_THRESHOLD && c->m_len + 1 <= c->look)
{
const lzo_bytep ip = c->bp;
const lzo_bytep m = c->bp - c->m_off;
const lzo_bytep in = c->in;
if (ip - in > s->swd_n)
in = ip - s->swd_n;
for (;;)
{
while (*in != *ip)
in++;
if (in == ip)
break;
if (in != m)
if (lzo_memcmp(in,ip,c->m_len+1) == 0)
printf("%p %p %p %5d\n",in,ip,m,c->m_len);
in++;
}
}
#endif
if (c->cb && c->cb->nprogress && c->textsize > c->printcount)
{
(*c->cb->nprogress)(c->cb, c->textsize, c->codesize, 0);
c->printcount += 1024;
}
return LZO_E_OK;
}
/*
vi:ts=4:et
*/