lzop: new applet. Busyboxed by Alain Knaff. +7700 bytes.

This commit is contained in:
Denis Vlasenko 2009-04-29 12:01:51 +00:00
parent c8653f62f2
commit 052ad9a568
12 changed files with 2990 additions and 0 deletions

View File

@ -165,6 +165,21 @@ config GZIP
gzip is used to compress files.
It's probably the most widely used UNIX compression program.
config LZOP
bool "lzop"
default n
help
Lzop compression/decompresion.
config LZOP_COMPR_HIGH
bool "lzop complession levels 7,8,9 (not very useful)"
default n
depends on LZOP
help
High levels (7,8,9) of lzop compression. These levels
are actually slower than gzip at equivalent compression ratios
and take up 3.2K of code.
config RPM2CPIO
bool "rpm2cpio"
default n

View File

@ -16,6 +16,8 @@ lib-$(CONFIG_DPKG) += dpkg.o
lib-$(CONFIG_DPKG_DEB) += dpkg_deb.o
lib-$(CONFIG_GUNZIP) += bbunzip.o
lib-$(CONFIG_GZIP) += gzip.o bbunzip.o
lib-$(CONFIG_LZOP) += lzop.o lzo1x_1.o lzo1x_1o.o lzo1x_d.o
lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o
lib-$(CONFIG_RPM2CPIO) += rpm2cpio.o
lib-$(CONFIG_RPM) += rpm.o
lib-$(CONFIG_TAR) += tar.o

93
archival/liblzo.h Normal file
View File

@ -0,0 +1,93 @@
/*
This file is part of the LZO real-time data compression library.
Copyright (C) 1996..2008 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
Markus F.X.J. Oberhumer <markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
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.
*/
#include "liblzo_interface.h"
/* lzo-2.03/src/config1x.h */
#define M2_MIN_LEN 3
#define M2_MAX_LEN 8
#define M3_MAX_LEN 33
#define M4_MAX_LEN 9
#define M1_MAX_OFFSET 0x0400
#define M2_MAX_OFFSET 0x0800
#define M3_MAX_OFFSET 0x4000
#define M4_MAX_OFFSET 0xbfff
#define M1_MARKER 0
#define M3_MARKER 32
#define M4_MARKER 16
#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET)
#define MIN_LOOKAHEAD (M2_MAX_LEN + 1)
#define LZO_EOF_CODE
/* lzo-2.03/src/lzo_dict.h */
#define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex]
#define DX2(p,s1,s2) \
(((((unsigned)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0])
//#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0])
//#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0])
#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0])
#define D_SIZE (1U << D_BITS)
#define D_MASK ((1U << D_BITS) - 1)
#define D_HIGH ((D_MASK >> 1) + 1)
#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
( \
m_pos = ip - (unsigned)(ip - m_pos), \
((uintptr_t)m_pos < (uintptr_t)in \
|| (m_off = (unsigned)(ip - m_pos)) <= 0 \
|| m_off > max_offset) \
)
#define DENTRY(p,in) (p)
#define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in)
#define DMS(v,s) ((unsigned) (((v) & (D_MASK >> (s))) << (s)))
#define DM(v) ((unsigned) ((v) & D_MASK))
#define DMUL(a,b) ((unsigned) ((a) * (b)))
/* lzo-2.03/src/lzo_ptr.h */
#define pd(a,b) ((unsigned)((a)-(b)))
# define TEST_IP (ip < ip_end)
# define NEED_IP(x) \
if ((unsigned)(ip_end - ip) < (unsigned)(x)) goto input_overrun
# undef TEST_OP /* don't need both of the tests here */
# define TEST_OP 1
# define NEED_OP(x) \
if ((unsigned)(op_end - op) < (unsigned)(x)) goto output_overrun
#define HAVE_ANY_OP 1
//#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun
//# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun
//#else
//# define TEST_LB(m_pos) ((void) 0)
//# define TEST_LBO(m_pos,o) ((void) 0)
//#endif

View File

@ -0,0 +1,71 @@
/*
This file is part of the LZO real-time data compression library.
Copyright (C) 1996..2008 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
Markus F.X.J. Oberhumer <markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
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.
*/
#define LZO1X
#undef LZO1Y
#undef assert
/*
static void die_at(int line)
{
bb_error_msg_and_die("internal error at %d", line);
}
#define assert(v) if (!(v)) die_at(__LINE__)
*/
#define assert(v) ((void)0)
int lzo1x_1_compress(const uint8_t* src, unsigned src_len,
uint8_t* dst, unsigned* dst_len,
void* wrkmem);
int lzo1x_1_15_compress(const uint8_t* src, unsigned src_len,
uint8_t* dst, unsigned* dst_len,
void* wrkmem);
int lzo1x_999_compress_level(const uint8_t* in, unsigned in_len,
uint8_t* out, unsigned* out_len,
void* wrkmem,
int compression_level);
/* decompression */
//int lzo1x_decompress(const uint8_t* src, unsigned src_len,
// uint8_t* dst, unsigned* dst_len,
// void* wrkmem /* NOT USED */);
/* safe decompression with overrun testing */
int lzo1x_decompress_safe(const uint8_t* src, unsigned src_len,
uint8_t* dst, unsigned* dst_len,
void* wrkmem /* NOT USED */);
#define LZO_E_OK 0
#define LZO_E_ERROR (-1)
#define LZO_E_OUT_OF_MEMORY (-2) /* [not used right now] */
#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */
#define LZO_E_INPUT_OVERRUN (-4)
#define LZO_E_OUTPUT_OVERRUN (-5)
#define LZO_E_LOOKBEHIND_OVERRUN (-6)
#define LZO_E_EOF_NOT_FOUND (-7)
#define LZO_E_INPUT_NOT_CONSUMED (-8)
#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */
/* lzo-2.03/include/lzo/lzoconf.h */
#define LZO_VERSION 0x2030

35
archival/lzo1x_1.c Normal file
View File

@ -0,0 +1,35 @@
/* LZO1X-1 compression
This file is part of the LZO real-time data compression library.
Copyright (C) 1996..2008 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
Markus F.X.J. Oberhumer <markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
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.
*/
#include "libbb.h"
#include "liblzo.h"
#define D_BITS 14
#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5)
#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f)
#define DO_COMPRESS lzo1x_1_compress
#include "lzo1x_c.c"

35
archival/lzo1x_1o.c Normal file
View File

@ -0,0 +1,35 @@
/* LZO1X-1(15) compression
This file is part of the LZO real-time data compression library.
Copyright (C) 1996..2008 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
Markus F.X.J. Oberhumer <markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
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.
*/
#include "libbb.h"
#include "liblzo.h"
#define D_BITS 15
#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5)
#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f)
#define DO_COMPRESS lzo1x_1_15_compress
#include "lzo1x_c.c"

920
archival/lzo1x_9x.c Normal file
View File

@ -0,0 +1,920 @@
/* lzo1x_9x.c -- implementation of the LZO1X-999 compression algorithm
This file is part of the LZO real-time data compression library.
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996 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/
*/
#include "libbb.h"
/* The following is probably only safe on Intel-compatible processors ... */
#define LZO_UNALIGNED_OK_2
#define LZO_UNALIGNED_OK_4
#include "liblzo.h"
#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b))
#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b))
#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c))
/***********************************************************************
//
************************************************************************/
#define SWD_N M4_MAX_OFFSET /* size of ring buffer */
#define SWD_F 2048 /* upper limit for match length */
#define SWD_BEST_OFF (LZO_MAX3(M2_MAX_LEN, M3_MAX_LEN, M4_MAX_LEN) + 1)
typedef struct {
int init;
unsigned look; /* bytes in lookahead buffer */
unsigned m_len;
unsigned m_off;
const uint8_t *bp;
const uint8_t *ip;
const uint8_t *in;
const uint8_t *in_end;
uint8_t *out;
unsigned r1_lit;
} lzo1x_999_t;
#define getbyte(c) ((c).ip < (c).in_end ? *((c).ip)++ : (-1))
/* lzo_swd.c -- sliding window dictionary */
/***********************************************************************
//
************************************************************************/
#define SWD_UINT_MAX USHRT_MAX
#ifndef SWD_HSIZE
# define SWD_HSIZE 16384
#endif
#ifndef SWD_MAX_CHAIN
# define SWD_MAX_CHAIN 2048
#endif
#define HEAD3(b, p) \
( ((0x9f5f * ((((b[p]<<5)^b[p+1])<<5) ^ b[p+2])) >> 5) & (SWD_HSIZE-1) )
#if defined(LZO_UNALIGNED_OK_2)
# define HEAD2(b,p) (* (uint16_t *) &(b[p]))
#else
# define HEAD2(b,p) (b[p] ^ ((unsigned)b[p+1]<<8))
#endif
#define NIL2 SWD_UINT_MAX
typedef struct lzo_swd {
/* public - "built-in" */
/* public - configuration */
unsigned max_chain;
int use_best_off;
/* public - output */
unsigned m_len;
unsigned m_off;
unsigned look;
int b_char;
#if defined(SWD_BEST_OFF)
unsigned best_off[SWD_BEST_OFF];
#endif
/* semi public */
lzo1x_999_t *c;
unsigned m_pos;
#if defined(SWD_BEST_OFF)
unsigned best_pos[SWD_BEST_OFF];
#endif
/* private */
unsigned ip; /* input pointer (lookahead) */
unsigned bp; /* buffer pointer */
unsigned rp; /* remove pointer */
unsigned node_count;
unsigned first_rp;
uint8_t b[SWD_N + SWD_F];
uint8_t b_wrap[SWD_F]; /* must follow b */
uint16_t head3[SWD_HSIZE];
uint16_t succ3[SWD_N + SWD_F];
uint16_t best3[SWD_N + SWD_F];
uint16_t llen3[SWD_HSIZE];
#ifdef HEAD2
uint16_t head2[65536L];
#endif
} lzo_swd_t, *lzo_swd_p;
#define SIZEOF_LZO_SWD_T (sizeof(lzo_swd_t))
/* Access macro for head3.
* head3[key] may be uninitialized, but then its value will never be used.
*/
#define s_get_head3(s,key) s->head3[key]
/***********************************************************************
//
************************************************************************/
#define B_SIZE (SWD_N + SWD_F)
static int swd_init(lzo_swd_p s)
{
/* defaults */
s->node_count = SWD_N;
memset(s->llen3, 0, sizeof(s->llen3[0]) * (unsigned)SWD_HSIZE);
#ifdef HEAD2
memset(s->head2, 0xff, sizeof(s->head2[0]) * 65536L);
assert(s->head2[0] == NIL2);
#endif
s->ip = 0;
s->bp = s->ip;
s->first_rp = s->ip;
assert(s->ip + SWD_F <= B_SIZE);
s->look = (unsigned) (s->c->in_end - s->c->ip);
if (s->look > 0) {
if (s->look > SWD_F)
s->look = SWD_F;
memcpy(&s->b[s->ip],s->c->ip,s->look);
s->c->ip += s->look;
s->ip += s->look;
}
if (s->ip == B_SIZE)
s->ip = 0;
s->rp = s->first_rp;
if (s->rp >= s->node_count)
s->rp -= s->node_count;
else
s->rp += B_SIZE - s->node_count;
return LZO_E_OK;
}
#define swd_pos2off(s,pos) \
(s->bp > (pos) ? s->bp - (pos) : B_SIZE - ((pos) - s->bp))
/***********************************************************************
//
************************************************************************/
static void swd_getbyte(lzo_swd_p s)
{
int c;
if ((c = getbyte(*(s->c))) < 0) {
if (s->look > 0)
--s->look;
} else {
s->b[s->ip] = c;
if (s->ip < SWD_F)
s->b_wrap[s->ip] = c;
}
if (++s->ip == B_SIZE)
s->ip = 0;
if (++s->bp == B_SIZE)
s->bp = 0;
if (++s->rp == B_SIZE)
s->rp = 0;
}
/***********************************************************************
// remove node from lists
************************************************************************/
static void swd_remove_node(lzo_swd_p s, unsigned node)
{
if (s->node_count == 0) {
unsigned key;
key = HEAD3(s->b,node);
assert(s->llen3[key] > 0);
--s->llen3[key];
#ifdef HEAD2
key = HEAD2(s->b,node);
assert(s->head2[key] != NIL2);
if ((unsigned) s->head2[key] == node)
s->head2[key] = NIL2;
#endif
} else
--s->node_count;
}
/***********************************************************************
//
************************************************************************/
static void swd_accept(lzo_swd_p s, unsigned n)
{
assert(n <= s->look);
while (n--) {
unsigned key;
swd_remove_node(s,s->rp);
/* add bp into HEAD3 */
key = HEAD3(s->b,s->bp);
s->succ3[s->bp] = s_get_head3(s,key);
s->head3[key] = s->bp;
s->best3[s->bp] = SWD_F + 1;
s->llen3[key]++;
assert(s->llen3[key] <= SWD_N);
#ifdef HEAD2
/* add bp into HEAD2 */
key = HEAD2(s->b,s->bp);
s->head2[key] = s->bp;
#endif
swd_getbyte(s);
}
}
/***********************************************************************
//
************************************************************************/
static void swd_search(lzo_swd_p s, unsigned node, unsigned cnt)
{
const uint8_t *p1;
const uint8_t *p2;
const uint8_t *px;
unsigned m_len = s->m_len;
const uint8_t *b = s->b;
const uint8_t *bp = s->b + s->bp;
const uint8_t *bx = s->b + s->bp + s->look;
unsigned char scan_end1;
assert(s->m_len > 0);
scan_end1 = bp[m_len - 1];
for ( ; cnt-- > 0; node = s->succ3[node]) {
p1 = bp;
p2 = b + node;
px = bx;
assert(m_len < s->look);
if (p2[m_len - 1] == scan_end1 &&
p2[m_len] == p1[m_len] &&
p2[0] == p1[0] &&
p2[1] == p1[1]) {
unsigned i;
assert(lzo_memcmp(bp,&b[node],3) == 0);
p1 += 2; p2 += 2;
do {} while (++p1 < px && *p1 == *++p2);
i = p1-bp;
assert(lzo_memcmp(bp,&b[node],i) == 0);
#if defined(SWD_BEST_OFF)
if (i < SWD_BEST_OFF) {
if (s->best_pos[i] == 0)
s->best_pos[i] = node + 1;
}
#endif
if (i > m_len) {
s->m_len = m_len = i;
s->m_pos = node;
if (m_len == s->look)
return;
if (m_len >= SWD_F)
return;
if (m_len > (unsigned) s->best3[node])
return;
scan_end1 = bp[m_len - 1];
}
}
}
}
/***********************************************************************
//
************************************************************************/
#ifdef HEAD2
static int swd_search2(lzo_swd_p s)
{
unsigned key;
assert(s->look >= 2);
assert(s->m_len > 0);
key = s->head2[ HEAD2(s->b,s->bp) ];
if (key == NIL2)
return 0;
assert(lzo_memcmp(&s->b[s->bp],&s->b[key],2) == 0);
#if defined(SWD_BEST_OFF)
if (s->best_pos[2] == 0)
s->best_pos[2] = key + 1;
#endif
if (s->m_len < 2) {
s->m_len = 2;
s->m_pos = key;
}
return 1;
}
#endif
/***********************************************************************
//
************************************************************************/
static void swd_findbest(lzo_swd_p s)
{
unsigned key;
unsigned cnt, node;
unsigned len;
assert(s->m_len > 0);
/* get current head, add bp into HEAD3 */
key = HEAD3(s->b,s->bp);
node = s->succ3[s->bp] = s_get_head3(s,key);
cnt = s->llen3[key]++;
assert(s->llen3[key] <= SWD_N + SWD_F);
if (cnt > s->max_chain)
cnt = s->max_chain;
s->head3[key] = s->bp;
s->b_char = s->b[s->bp];
len = s->m_len;
if (s->m_len >= s->look) {
if (s->look == 0)
s->b_char = -1;
s->m_off = 0;
s->best3[s->bp] = SWD_F + 1;
} else {
#ifdef HEAD2
if (swd_search2(s))
#endif
if (s->look >= 3)
swd_search(s,node,cnt);
if (s->m_len > len)
s->m_off = swd_pos2off(s,s->m_pos);
s->best3[s->bp] = s->m_len;
#if defined(SWD_BEST_OFF)
if (s->use_best_off) {
int i;
for (i = 2; i < SWD_BEST_OFF; i++)
if (s->best_pos[i] > 0)
s->best_off[i] = swd_pos2off(s,s->best_pos[i]-1);
else
s->best_off[i] = 0;
}
#endif
}
swd_remove_node(s,s->rp);
#ifdef HEAD2
/* add bp into HEAD2 */
key = HEAD2(s->b,s->bp);
s->head2[key] = s->bp;
#endif
}
#undef HEAD3
#undef HEAD2
#undef s_get_head3
/***********************************************************************
//
************************************************************************/
static int init_match(lzo1x_999_t *c, lzo_swd_p s, uint32_t use_best_off)
{
int r;
assert(!c->init);
c->init = 1;
s->c = c;
r = swd_init(s);
if (r != 0)
return r;
s->use_best_off = use_best_off;
return r;
}
/***********************************************************************
//
************************************************************************/
static int find_match(lzo1x_999_t *c, lzo_swd_p s,
unsigned this_len, unsigned skip)
{
assert(c->init);
if (skip > 0) {
assert(this_len >= skip);
swd_accept(s, this_len - skip);
} else {
assert(this_len <= 1);
}
s->m_len = 1;
s->m_len = 1;
#ifdef SWD_BEST_OFF
if (s->use_best_off)
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;
} else {
c->look = s->look + 1;
}
c->bp = c->ip - c->look;
return LZO_E_OK;
}
/* this is a public functions, but there is no prototype in a header file */
static int lzo1x_999_compress_internal(const uint8_t *in , unsigned in_len,
uint8_t *out, unsigned *out_len,
void *wrkmem,
unsigned good_length,
unsigned max_lazy,
unsigned max_chain,
uint32_t use_best_off);
/***********************************************************************
//
************************************************************************/
static uint8_t *code_match(lzo1x_999_t *c,
uint8_t *op, unsigned m_len, unsigned m_off)
{
assert(op > c->out);
if (m_len == 2) {
assert(m_off <= M1_MAX_OFFSET);
assert(c->r1_lit > 0); assert(c->r1_lit < 4);
m_off -= 1;
*op++ = M1_MARKER | ((m_off & 3) << 2);
*op++ = m_off >> 2;
} else if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) {
assert(m_len >= 3);
m_off -= 1;
*op++ = ((m_len - 1) << 5) | ((m_off & 7) << 2);
*op++ = m_off >> 3;
assert(op[-2] >= M2_MARKER);
} else if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET && c->r1_lit >= 4) {
assert(m_len == 3);
assert(m_off > M2_MAX_OFFSET);
m_off -= 1 + M2_MAX_OFFSET;
*op++ = M1_MARKER | ((m_off & 3) << 2);
*op++ = m_off >> 2;
} else if (m_off <= M3_MAX_OFFSET) {
assert(m_len >= 3);
m_off -= 1;
if (m_len <= M3_MAX_LEN)
*op++ = M3_MARKER | (m_len - 2);
else {
m_len -= M3_MAX_LEN;
*op++ = M3_MARKER | 0;
while (m_len > 255)
{
m_len -= 255;
*op++ = 0;
}
assert(m_len > 0);
*op++ = m_len;
}
*op++ = m_off << 2;
*op++ = m_off >> 6;
} else {
unsigned k;
assert(m_len >= 3);
assert(m_off > 0x4000); assert(m_off <= 0xbfff);
m_off -= 0x4000;
k = (m_off & 0x4000) >> 11;
if (m_len <= M4_MAX_LEN)
*op++ = M4_MARKER | k | (m_len - 2);
else {
m_len -= M4_MAX_LEN;
*op++ = M4_MARKER | k | 0;
while (m_len > 255)
{
m_len -= 255;
*op++ = 0;
}
assert(m_len > 0);
*op++ = m_len;
}
*op++ = m_off << 2;
*op++ = m_off >> 6;
}
return op;
}
static uint8_t *STORE_RUN(lzo1x_999_t *c, uint8_t *op,
const uint8_t *ii, unsigned t)
{
if (op == c->out && t <= 238) {
*op++ = 17 + t;
} else if (t <= 3) {
op[-2] |= t;
} else if (t <= 18) {
*op++ = t - 3;
} else {
unsigned tt = t - 18;
*op++ = 0;
while (tt > 255) {
tt -= 255;
*op++ = 0;
}
assert(tt > 0);
*op++ = tt;
}
do *op++ = *ii++; while (--t > 0);
return op;
}
static uint8_t *code_run(lzo1x_999_t *c, uint8_t *op, const uint8_t *ii,
unsigned lit)
{
if (lit > 0) {
assert(m_len >= 2);
op = STORE_RUN(c,op,ii,lit);
} else {
assert(m_len >= 3);
}
c->r1_lit = lit;
return op;
}
/***********************************************************************
//
************************************************************************/
static int len_of_coded_match(unsigned m_len, unsigned m_off, unsigned lit)
{
int n = 4;
if (m_len < 2)
return -1;
if (m_len == 2)
return (m_off <= M1_MAX_OFFSET && lit > 0 && lit < 4) ? 2 : -1;
if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET)
return 2;
if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET && lit >= 4)
return 2;
if (m_off <= M3_MAX_OFFSET) {
if (m_len <= M3_MAX_LEN)
return 3;
m_len -= M3_MAX_LEN;
} else if (m_off <= M4_MAX_OFFSET) {
if (m_len <= M4_MAX_LEN)
return 3;
m_len -= M4_MAX_LEN;
} else
return -1;
while (m_len > 255) {
m_len -= 255;
n++;
}
return n;
}
static int min_gain(unsigned ahead, unsigned lit1,
unsigned lit2, int l1, int l2, int l3)
{
int lazy_match_min_gain = 0;
assert (ahead >= 1);
lazy_match_min_gain += ahead;
if (lit1 <= 3)
lazy_match_min_gain += (lit2 <= 3) ? 0 : 2;
else if (lit1 <= 18)
lazy_match_min_gain += (lit2 <= 18) ? 0 : 1;
lazy_match_min_gain += (l2 - l1) * 2;
if (l3 > 0)
lazy_match_min_gain -= (ahead - l3) * 2;
if (lazy_match_min_gain < 0)
lazy_match_min_gain = 0;
return lazy_match_min_gain;
}
/***********************************************************************
//
************************************************************************/
#if defined(SWD_BEST_OFF)
static void better_match(const lzo_swd_p swd,
unsigned *m_len, unsigned *m_off)
{
if (*m_len <= M2_MIN_LEN)
return;
if (*m_off <= M2_MAX_OFFSET)
return;
/* M3/M4 -> M2 */
if (*m_off > M2_MAX_OFFSET &&
*m_len >= M2_MIN_LEN + 1 && *m_len <= M2_MAX_LEN + 1 &&
swd->best_off[*m_len-1] && swd->best_off[*m_len-1] <= M2_MAX_OFFSET)
{
*m_len = *m_len - 1;
*m_off = swd->best_off[*m_len];
return;
}
/* M4 -> M2 */
if (*m_off > M3_MAX_OFFSET &&
*m_len >= M4_MAX_LEN + 1 && *m_len <= M2_MAX_LEN + 2 &&
swd->best_off[*m_len-2] && swd->best_off[*m_len-2] <= M2_MAX_OFFSET)
{
*m_len = *m_len - 2;
*m_off = swd->best_off[*m_len];
return;
}
/* M4 -> M3 */
if (*m_off > M3_MAX_OFFSET &&
*m_len >= M4_MAX_LEN + 1 && *m_len <= M3_MAX_LEN + 1 &&
swd->best_off[*m_len-1] && swd->best_off[*m_len-1] <= M3_MAX_OFFSET)
{
*m_len = *m_len - 1;
*m_off = swd->best_off[*m_len];
}
}
#endif
/***********************************************************************
//
************************************************************************/
static int lzo1x_999_compress_internal(const uint8_t *in, unsigned in_len,
uint8_t *out, unsigned *out_len,
void *wrkmem,
unsigned good_length,
unsigned max_lazy,
unsigned max_chain,
uint32_t use_best_off)
{
uint8_t *op;
const uint8_t *ii;
unsigned lit;
unsigned m_len, m_off;
lzo1x_999_t cc;
lzo1x_999_t * const c = &cc;
lzo_swd_p const swd = (lzo_swd_p) wrkmem;
int r;
c->init = 0;
c->ip = c->in = in;
c->in_end = in + in_len;
c->out = out;
op = out;
ii = c->ip; /* point to start of literal run */
lit = 0;
c->r1_lit = 0;
r = init_match(c, swd, use_best_off);
if (r != 0)
return r;
swd->max_chain = max_chain;
r = find_match(c, swd, 0, 0);
if (r != 0)
return r;
while (c->look > 0) {
unsigned ahead;
unsigned max_ahead;
int l1, l2, l3;
m_len = c->m_len;
m_off = c->m_off;
assert(c->bp == c->ip - c->look);
assert(c->bp >= in);
if (lit == 0)
ii = c->bp;
assert(ii + lit == c->bp);
assert(swd->b_char == *(c->bp));
if ( m_len < 2 ||
(m_len == 2 && (m_off > M1_MAX_OFFSET || lit == 0 || lit >= 4)) ||
/* Do not accept this match for compressed-data compatibility
* with LZO v1.01 and before
* [ might be a problem for decompress() and optimize() ]
*/
(m_len == 2 && op == out) ||
(op == out && lit == 0))
{
/* a literal */
m_len = 0;
}
else if (m_len == M2_MIN_LEN) {
/* compression ratio improves if we code a literal in some cases */
if (m_off > MX_MAX_OFFSET && lit >= 4)
m_len = 0;
}
if (m_len == 0) {
/* a literal */
lit++;
swd->max_chain = max_chain;
r = find_match(c,swd,1,0);
assert(r == 0);
continue;
}
/* a match */
#if defined(SWD_BEST_OFF)
if (swd->use_best_off)
better_match(swd,&m_len,&m_off);
#endif
/* shall we try a lazy match ? */
ahead = 0;
if (m_len >= max_lazy) {
/* no */
l1 = 0;
max_ahead = 0;
} else {
/* yes, try a lazy match */
l1 = len_of_coded_match(m_len,m_off,lit);
assert(l1 > 0);
max_ahead = LZO_MIN(2, (unsigned)l1 - 1);
}
while (ahead < max_ahead && c->look > m_len) {
int lazy_match_min_gain;
if (m_len >= good_length)
swd->max_chain = max_chain >> 2;
else
swd->max_chain = max_chain;
r = find_match(c,swd,1,0);
ahead++;
assert(r == 0);
assert(c->look > 0);
assert(ii + lit + ahead == c->bp);
if (c->m_len < m_len)
continue;
if (c->m_len == m_len && c->m_off >= m_off)
continue;
#if defined(SWD_BEST_OFF)
if (swd->use_best_off)
better_match(swd,&c->m_len,&c->m_off);
#endif
l2 = len_of_coded_match(c->m_len,c->m_off,lit+ahead);
if (l2 < 0)
continue;
/* compressed-data compatibility [see above] */
l3 = (op == out) ? -1 : len_of_coded_match(ahead,m_off,lit);
lazy_match_min_gain = min_gain(ahead,lit,lit+ahead,l1,l2,l3);
if (c->m_len >= m_len + lazy_match_min_gain) {
if (l3 > 0) {
/* code previous run */
op = code_run(c,op,ii,lit);
lit = 0;
/* code shortened match */
op = code_match(c,op,ahead,m_off);
} else {
lit += ahead;
assert(ii + lit == c->bp);
}
goto lazy_match_done;
}
}
assert(ii + lit + ahead == c->bp);
/* 1 - code run */
op = code_run(c,op,ii,lit);
lit = 0;
/* 2 - code match */
op = code_match(c,op,m_len,m_off);
swd->max_chain = max_chain;
r = find_match(c,swd,m_len,1+ahead);
assert(r == 0);
lazy_match_done: ;
}
/* store final run */
if (lit > 0)
op = STORE_RUN(c,op,ii,lit);
#if defined(LZO_EOF_CODE)
*op++ = M4_MARKER | 1;
*op++ = 0;
*op++ = 0;
#endif
*out_len = op - out;
return LZO_E_OK;
}
/***********************************************************************
//
************************************************************************/
int lzo1x_999_compress_level(const uint8_t *in, unsigned in_len,
uint8_t *out, unsigned *out_len,
void *wrkmem,
int compression_level)
{
static const struct {
uint16_t good_length;
uint16_t max_lazy;
uint16_t max_chain;
uint16_t use_best_off;
} c[3] = {
{ 8, 32, 256, 0 },
{ 32, 128, 2048, 1 },
{ SWD_F, SWD_F, 4096, 1 } /* max. compression */
};
if (compression_level < 7 || compression_level > 9)
return LZO_E_ERROR;
compression_level -= 7;
return lzo1x_999_compress_internal(in, in_len, out, out_len, wrkmem,
c[compression_level].good_length,
c[compression_level].max_lazy,
c[compression_level].max_chain,
c[compression_level].use_best_off);
}

296
archival/lzo1x_c.c Normal file
View File

@ -0,0 +1,296 @@
/* implementation of the LZO1[XY]-1 compression algorithm
This file is part of the LZO real-time data compression library.
Copyright (C) 1996..2008 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
Markus F.X.J. Oberhumer <markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
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.
*/
/***********************************************************************
// compress a block of data.
************************************************************************/
static NOINLINE unsigned
do_compress(const uint8_t* in, unsigned in_len,
uint8_t* out, unsigned* out_len,
void* wrkmem)
{
register const uint8_t* ip;
uint8_t* op;
const uint8_t* const in_end = in + in_len;
const uint8_t* const ip_end = in + in_len - M2_MAX_LEN - 5;
const uint8_t* ii;
const void* *const dict = (const void**) wrkmem;
op = out;
ip = in;
ii = ip;
ip += 4;
for (;;) {
register const uint8_t* m_pos;
unsigned m_off;
unsigned m_len;
unsigned dindex;
D_INDEX1(dindex,ip);
GINDEX(m_pos,m_off,dict,dindex,in);
if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
goto literal;
#if 1
if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
goto try_match;
D_INDEX2(dindex,ip);
#endif
GINDEX(m_pos,m_off,dict,dindex,in);
if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
goto literal;
if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
goto try_match;
goto literal;
try_match:
#if 1 && defined(LZO_UNALIGNED_OK_2)
if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip)
#else
if (m_pos[0] != ip[0] || m_pos[1] != ip[1])
#endif
{
} else {
if (m_pos[2] == ip[2]) {
#if 0
if (m_off <= M2_MAX_OFFSET)
goto match;
if (lit <= 3)
goto match;
if (lit == 3) { /* better compression, but slower */
assert(op - 2 > out); op[-2] |= (uint8_t)(3);
*op++ = *ii++; *op++ = *ii++; *op++ = *ii++;
goto code_match;
}
if (m_pos[3] == ip[3])
#endif
goto match;
}
else {
/* still need a better way for finding M1 matches */
#if 0
/* a M1 match */
#if 0
if (m_off <= M1_MAX_OFFSET && lit > 0 && lit <= 3)
#else
if (m_off <= M1_MAX_OFFSET && lit == 3)
#endif
{
register unsigned t;
t = lit;
assert(op - 2 > out); op[-2] |= (uint8_t)(t);
do *op++ = *ii++; while (--t > 0);
assert(ii == ip);
m_off -= 1;
*op++ = (uint8_t)(M1_MARKER | ((m_off & 3) << 2));
*op++ = (uint8_t)(m_off >> 2);
ip += 2;
goto match_done;
}
#endif
}
}
/* a literal */
literal:
UPDATE_I(dict, 0, dindex, ip, in);
++ip;
if (ip >= ip_end)
break;
continue;
/* a match */
match:
UPDATE_I(dict, 0, dindex, ip, in);
/* store current literal run */
if (pd(ip, ii) > 0) {
register unsigned t = pd(ip, ii);
if (t <= 3) {
assert(op - 2 > out);
op[-2] |= (uint8_t)(t);
}
else if (t <= 18)
*op++ = (uint8_t)(t - 3);
else {
register unsigned tt = t - 18;
*op++ = 0;
while (tt > 255) {
tt -= 255;
*op++ = 0;
}
assert(tt > 0);
*op++ = (uint8_t)(tt);
}
do *op++ = *ii++; while (--t > 0);
}
/* code the match */
assert(ii == ip);
ip += 3;
if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++
|| m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++
#ifdef LZO1Y
|| m_pos[ 9] != *ip++ || m_pos[10] != *ip++ || m_pos[11] != *ip++
|| m_pos[12] != *ip++ || m_pos[13] != *ip++ || m_pos[14] != *ip++
#endif
) {
--ip;
m_len = pd(ip, ii);
assert(m_len >= 3);
assert(m_len <= M2_MAX_LEN);
if (m_off <= M2_MAX_OFFSET) {
m_off -= 1;
#if defined(LZO1X)
*op++ = (uint8_t)(((m_len - 1) << 5) | ((m_off & 7) << 2));
*op++ = (uint8_t)(m_off >> 3);
#elif defined(LZO1Y)
*op++ = (uint8_t)(((m_len + 1) << 4) | ((m_off & 3) << 2));
*op++ = (uint8_t)(m_off >> 2);
#endif
}
else if (m_off <= M3_MAX_OFFSET) {
m_off -= 1;
*op++ = (uint8_t)(M3_MARKER | (m_len - 2));
goto m3_m4_offset;
} else {
#if defined(LZO1X)
m_off -= 0x4000;
assert(m_off > 0);
assert(m_off <= 0x7fff);
*op++ = (uint8_t)(M4_MARKER | ((m_off & 0x4000) >> 11) | (m_len - 2));
goto m3_m4_offset;
#elif defined(LZO1Y)
goto m4_match;
#endif
}
}
else {
{
const uint8_t* end = in_end;
const uint8_t* m = m_pos + M2_MAX_LEN + 1;
while (ip < end && *m == *ip)
m++, ip++;
m_len = pd(ip, ii);
}
assert(m_len > M2_MAX_LEN);
if (m_off <= M3_MAX_OFFSET) {
m_off -= 1;
if (m_len <= 33)
*op++ = (uint8_t)(M3_MARKER | (m_len - 2));
else {
m_len -= 33;
*op++ = M3_MARKER | 0;
goto m3_m4_len;
}
} else {
#if defined(LZO1Y)
m4_match:
#endif
m_off -= 0x4000;
assert(m_off > 0);
assert(m_off <= 0x7fff);
if (m_len <= M4_MAX_LEN)
*op++ = (uint8_t)(M4_MARKER | ((m_off & 0x4000) >> 11) | (m_len - 2));
else {
m_len -= M4_MAX_LEN;
*op++ = (uint8_t)(M4_MARKER | ((m_off & 0x4000) >> 11));
m3_m4_len:
while (m_len > 255) {
m_len -= 255;
*op++ = 0;
}
assert(m_len > 0);
*op++ = (uint8_t)(m_len);
}
}
m3_m4_offset:
*op++ = (uint8_t)((m_off & 63) << 2);
*op++ = (uint8_t)(m_off >> 6);
}
#if 0
match_done:
#endif
ii = ip;
if (ip >= ip_end)
break;
}
*out_len = pd(op, out);
return pd(in_end, ii);
}
/***********************************************************************
// public entry point
************************************************************************/
int DO_COMPRESS(const uint8_t* in, unsigned in_len,
uint8_t* out, unsigned* out_len,
void* wrkmem)
{
uint8_t* op = out;
unsigned t;
if (in_len <= M2_MAX_LEN + 5)
t = in_len;
else {
t = do_compress(in,in_len,op,out_len,wrkmem);
op += *out_len;
}
if (t > 0) {
const uint8_t* ii = in + in_len - t;
if (op == out && t <= 238)
*op++ = (uint8_t)(17 + t);
else if (t <= 3)
op[-2] |= (uint8_t)(t);
else if (t <= 18)
*op++ = (uint8_t)(t - 3);
else {
unsigned tt = t - 18;
*op++ = 0;
while (tt > 255) {
tt -= 255;
*op++ = 0;
}
assert(tt > 0);
*op++ = (uint8_t)(tt);
}
do *op++ = *ii++; while (--t > 0);
}
*op++ = M4_MARKER | 1;
*op++ = 0;
*op++ = 0;
*out_len = pd(op, out);
return 0; /*LZO_E_OK*/
}

420
archival/lzo1x_d.c Normal file
View File

@ -0,0 +1,420 @@
/* implementation of the LZO1X decompression algorithm
This file is part of the LZO real-time data compression library.
Copyright (C) 1996..2008 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
Markus F.X.J. Oberhumer <markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
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.
*/
#include "libbb.h"
#include "liblzo.h"
/***********************************************************************
// decompress a block of data.
************************************************************************/
/* safe decompression with overrun testing */
int lzo1x_decompress_safe(const uint8_t* in, unsigned in_len,
uint8_t* out, unsigned* out_len,
void* wrkmem UNUSED_PARAM)
{
register uint8_t* op;
register const uint8_t* ip;
register unsigned t;
#if defined(COPY_DICT)
unsigned m_off;
const uint8_t* dict_end;
#else
register const uint8_t* m_pos = NULL; /* possibly not needed */
#endif
const uint8_t* const ip_end = in + in_len;
#if defined(HAVE_ANY_OP)
uint8_t* const op_end = out + *out_len;
#endif
#if defined(LZO1Z)
unsigned last_m_off = 0;
#endif
// LZO_UNUSED(wrkmem);
#if defined(COPY_DICT)
if (dict) {
if (dict_len > M4_MAX_OFFSET) {
dict += dict_len - M4_MAX_OFFSET;
dict_len = M4_MAX_OFFSET;
}
dict_end = dict + dict_len;
} else {
dict_len = 0;
dict_end = NULL;
}
#endif /* COPY_DICT */
*out_len = 0;
op = out;
ip = in;
if (*ip > 17) {
t = *ip++ - 17;
if (t < 4)
goto match_next;
assert(t > 0); NEED_OP(t); NEED_IP(t+1);
do *op++ = *ip++; while (--t > 0);
goto first_literal_run;
}
while (TEST_IP && TEST_OP) {
t = *ip++;
if (t >= 16)
goto match;
/* a literal run */
if (t == 0) {
NEED_IP(1);
while (*ip == 0) {
t += 255;
ip++;
NEED_IP(1);
}
t += 15 + *ip++;
}
/* copy literals */
assert(t > 0);
NEED_OP(t+3);
NEED_IP(t+4);
#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
# if !defined(LZO_UNALIGNED_OK_4)
if (PTR_ALIGNED2_4(op, ip))
# endif
{
COPY4(op, ip);
op += 4;
ip += 4;
if (--t > 0) {
if (t >= 4) {
do {
COPY4(op, ip);
op += 4;
ip += 4;
t -= 4;
} while (t >= 4);
if (t > 0)
do *op++ = *ip++; while (--t > 0);
} else {
do *op++ = *ip++; while (--t > 0);
}
}
}
# if !defined(LZO_UNALIGNED_OK_4)
else
# endif
#endif
#if !defined(LZO_UNALIGNED_OK_4)
{
*op++ = *ip++;
*op++ = *ip++;
*op++ = *ip++;
do *op++ = *ip++; while (--t > 0);
}
#endif
first_literal_run:
t = *ip++;
if (t >= 16)
goto match;
#if defined(COPY_DICT)
#if defined(LZO1Z)
m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
last_m_off = m_off;
#else
m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
#endif
NEED_OP(3);
t = 3; COPY_DICT(t,m_off)
#else /* !COPY_DICT */
#if defined(LZO1Z)
t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
m_pos = op - t;
last_m_off = t;
#else
m_pos = op - (1 + M2_MAX_OFFSET);
m_pos -= t >> 2;
m_pos -= *ip++ << 2;
#endif
TEST_LB(m_pos); NEED_OP(3);
*op++ = *m_pos++;
*op++ = *m_pos++;
*op++ = *m_pos;
#endif /* COPY_DICT */
goto match_done;
/* handle matches */
do {
match:
if (t >= 64) { /* a M2 match */
#if defined(COPY_DICT)
#if defined(LZO1X)
m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
t = (t >> 5) - 1;
#elif defined(LZO1Y)
m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
t = (t >> 4) - 3;
#elif defined(LZO1Z)
m_off = t & 0x1f;
if (m_off >= 0x1c)
m_off = last_m_off;
else {
m_off = 1 + (m_off << 6) + (*ip++ >> 2);
last_m_off = m_off;
}
t = (t >> 5) - 1;
#endif
#else /* !COPY_DICT */
#if defined(LZO1X)
m_pos = op - 1;
m_pos -= (t >> 2) & 7;
m_pos -= *ip++ << 3;
t = (t >> 5) - 1;
#elif defined(LZO1Y)
m_pos = op - 1;
m_pos -= (t >> 2) & 3;
m_pos -= *ip++ << 2;
t = (t >> 4) - 3;
#elif defined(LZO1Z)
{
unsigned off = t & 0x1f;
m_pos = op;
if (off >= 0x1c) {
assert(last_m_off > 0);
m_pos -= last_m_off;
} else {
off = 1 + (off << 6) + (*ip++ >> 2);
m_pos -= off;
last_m_off = off;
}
}
t = (t >> 5) - 1;
#endif
TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
goto copy_match;
#endif /* COPY_DICT */
}
else if (t >= 32) { /* a M3 match */
t &= 31;
if (t == 0) {
NEED_IP(1);
while (*ip == 0) {
t += 255;
ip++;
NEED_IP(1);
}
t += 31 + *ip++;
}
#if defined(COPY_DICT)
#if defined(LZO1Z)
m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
last_m_off = m_off;
#else
m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
#endif
#else /* !COPY_DICT */
#if defined(LZO1Z)
{
unsigned off = 1 + (ip[0] << 6) + (ip[1] >> 2);
m_pos = op - off;
last_m_off = off;
}
#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
m_pos = op - 1;
m_pos -= (* (const lzo_ushortp) ip) >> 2;
#else
m_pos = op - 1;
m_pos -= (ip[0] >> 2) + (ip[1] << 6);
#endif
#endif /* COPY_DICT */
ip += 2;
}
else if (t >= 16) { /* a M4 match */
#if defined(COPY_DICT)
m_off = (t & 8) << 11;
#else /* !COPY_DICT */
m_pos = op;
m_pos -= (t & 8) << 11;
#endif /* COPY_DICT */
t &= 7;
if (t == 0) {
NEED_IP(1);
while (*ip == 0) {
t += 255;
ip++;
NEED_IP(1);
}
t += 7 + *ip++;
}
#if defined(COPY_DICT)
#if defined(LZO1Z)
m_off += (ip[0] << 6) + (ip[1] >> 2);
#else
m_off += (ip[0] >> 2) + (ip[1] << 6);
#endif
ip += 2;
if (m_off == 0)
goto eof_found;
m_off += 0x4000;
#if defined(LZO1Z)
last_m_off = m_off;
#endif
#else /* !COPY_DICT */
#if defined(LZO1Z)
m_pos -= (ip[0] << 6) + (ip[1] >> 2);
#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
m_pos -= (* (const lzo_ushortp) ip) >> 2;
#else
m_pos -= (ip[0] >> 2) + (ip[1] << 6);
#endif
ip += 2;
if (m_pos == op)
goto eof_found;
m_pos -= 0x4000;
#if defined(LZO1Z)
last_m_off = pd((const uint8_t*)op, m_pos);
#endif
#endif /* COPY_DICT */
}
else { /* a M1 match */
#if defined(COPY_DICT)
#if defined(LZO1Z)
m_off = 1 + (t << 6) + (*ip++ >> 2);
last_m_off = m_off;
#else
m_off = 1 + (t >> 2) + (*ip++ << 2);
#endif
NEED_OP(2);
t = 2; COPY_DICT(t,m_off)
#else /* !COPY_DICT */
#if defined(LZO1Z)
t = 1 + (t << 6) + (*ip++ >> 2);
m_pos = op - t;
last_m_off = t;
#else
m_pos = op - 1;
m_pos -= t >> 2;
m_pos -= *ip++ << 2;
#endif
TEST_LB(m_pos); NEED_OP(2);
*op++ = *m_pos++;
*op++ = *m_pos;
#endif /* COPY_DICT */
goto match_done;
}
/* copy match */
#if defined(COPY_DICT)
NEED_OP(t+3-1);
t += 3-1; COPY_DICT(t,m_off)
#else /* !COPY_DICT */
TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
# if !defined(LZO_UNALIGNED_OK_4)
if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) {
assert((op - m_pos) >= 4); /* both pointers are aligned */
# else
if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) {
# endif
COPY4(op,m_pos);
op += 4; m_pos += 4; t -= 4 - (3 - 1);
do {
COPY4(op,m_pos);
op += 4; m_pos += 4; t -= 4;
} while (t >= 4);
if (t > 0)
do *op++ = *m_pos++; while (--t > 0);
}
else
#endif
{
copy_match:
*op++ = *m_pos++; *op++ = *m_pos++;
do *op++ = *m_pos++; while (--t > 0);
}
#endif /* COPY_DICT */
match_done:
#if defined(LZO1Z)
t = ip[-1] & 3;
#else
t = ip[-2] & 3;
#endif
if (t == 0)
break;
/* copy literals */
match_next:
assert(t > 0);
assert(t < 4);
NEED_OP(t);
NEED_IP(t+1);
#if 0
do *op++ = *ip++; while (--t > 0);
#else
*op++ = *ip++;
if (t > 1) {
*op++ = *ip++;
if (t > 2)
*op++ = *ip++;
}
#endif
t = *ip++;
} while (TEST_IP && TEST_OP);
}
//#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
/* no EOF code was found */
*out_len = pd(op, out);
return LZO_E_EOF_NOT_FOUND;
//#endif
eof_found:
assert(t == 1);
*out_len = pd(op, out);
return (ip == ip_end ? LZO_E_OK :
(ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
//#if defined(HAVE_NEED_IP)
input_overrun:
*out_len = pd(op, out);
return LZO_E_INPUT_OVERRUN;
//#endif
//#if defined(HAVE_NEED_OP)
output_overrun:
*out_len = pd(op, out);
return LZO_E_OUTPUT_OVERRUN;
//#endif
//#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
lookbehind_overrun:
*out_len = pd(op, out);
return LZO_E_LOOKBEHIND_OVERRUN;
//#endif
}

1075
archival/lzop.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -242,6 +242,8 @@ IF_LSATTR(APPLET(lsattr, _BB_DIR_BIN, _BB_SUID_NEVER))
IF_LSMOD(APPLET(lsmod, _BB_DIR_SBIN, _BB_SUID_NEVER))
IF_MODPROBE_SMALL(APPLET_ODDNAME(lsmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe))
IF_UNLZMA(APPLET_ODDNAME(lzmacat, unlzma, _BB_DIR_USR_BIN, _BB_SUID_NEVER, lzmacat))
IF_LZOP(APPLET(lzop, _BB_DIR_BIN, _BB_SUID_NEVER))
IF_LZOP(APPLET_ODDNAME(lzopcat, lzop, _BB_DIR_USR_BIN, _BB_SUID_NEVER, lzopcat))
IF_MAKEDEVS(APPLET(makedevs, _BB_DIR_SBIN, _BB_SUID_NEVER))
IF_MAKEMIME(APPLET(makemime, _BB_DIR_BIN, _BB_SUID_NEVER))
IF_MAN(APPLET(man, _BB_DIR_SBIN, _BB_SUID_NEVER))
@ -401,6 +403,7 @@ IF_UNEXPAND(APPLET_ODDNAME(unexpand, expand, _BB_DIR_USR_BIN, _BB_SUID_NEVER, un
IF_UNIQ(APPLET(uniq, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
IF_UNIX2DOS(APPLET_ODDNAME(unix2dos, dos2unix, _BB_DIR_USR_BIN, _BB_SUID_NEVER, unix2dos))
IF_UNLZMA(APPLET(unlzma, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
IF_LZOP(APPLET_ODDNAME(unlzop, lzop, _BB_DIR_USR_BIN, _BB_SUID_NEVER, unlzop))
IF_UNZIP(APPLET(unzip, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
IF_UPTIME(APPLET(uptime, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
IF_USLEEP(APPLET_NOFORK(usleep, usleep, _BB_DIR_BIN, _BB_SUID_NEVER, usleep))

View File

@ -202,6 +202,31 @@
#define busybox_notes_usage \
"Hello world!\n"
#define lzop_trivial_usage \
"[-cfvd123456789CF] [file..]"
#define lzop_full_usage "\n\n" \
" -c Write to standard output" \
"\n -f Force" \
"\n -v Verbose" \
"\n -d Decompress" \
"\n -F Don't store or verify checksum" \
"\n -C Also write checksum of compressed block" \
"\n -1..9 Compression level" \
#define lzopcat_trivial_usage \
"[-vCF] [file..]"
#define lzopcat_full_usage "\n\n" \
" -v Verbose" \
"\n -F Don't store or verify checksum" \
#define unlzop_trivial_usage \
"[-cfvCF] [file..]"
#define unlzop_full_usage "\n\n" \
" -c Write to standard output" \
"\n -f Force" \
"\n -v Verbose" \
"\n -F Don't store or verify checksum" \
#define bzcat_trivial_usage \
"FILE"
#define bzcat_full_usage "\n\n" \