1 /* lzo1f_1.c -- implementation of the LZO1F-1 compression algorithm
3 This file is part of the LZO real-time data compression library.
5 Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
6 Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
7 Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
8 Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
9 Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
10 Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
11 Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
12 Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
13 Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
14 Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
15 Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
16 Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
17 Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
18 Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
19 Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
20 Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
23 The LZO library is free software; you can redistribute it and/or
24 modify it under the terms of the GNU General Public License as
25 published by the Free Software Foundation; either version 2 of
26 the License, or (at your option) any later version.
28 The LZO library is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU General Public License for more details.
33 You should have received a copy of the GNU General Public License
34 along with the LZO library; see the file COPYING.
35 If not, write to the Free Software Foundation, Inc.,
36 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
38 Markus F.X.J. Oberhumer
39 <markus@oberhumer.com>
40 http://www.oberhumer.com/opensource/lzo/
45 #include "lzo/lzo1f.h"
48 /***********************************************************************
50 ************************************************************************/
52 #define M2_MAX_OFFSET 0x0800
53 #define M3_MAX_OFFSET 0x3fff
58 #define LZO_HASH LZO_HASH_LZO_INCREMENTAL_A
61 #define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5)
62 #define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f)
66 /***********************************************************************
67 // compress a block of data.
68 ************************************************************************/
71 int do_compress ( const lzo_bytep in
, lzo_uint in_len
,
72 lzo_bytep out
, lzo_uintp out_len
,
75 register const lzo_bytep ip
;
77 const lzo_bytep
const in_end
= in
+ in_len
;
78 const lzo_bytep
const ip_end
= in
+ in_len
- 9;
80 lzo_dict_p
const dict
= (lzo_dict_p
) wrkmem
;
89 register const lzo_bytep m_pos
;
90 LZO_DEFINE_UNINITIALIZED_VAR(lzo_uint
, m_off
, 0);
96 GINDEX(m_pos
,m_off
,dict
,dindex
,in
);
97 if (LZO_CHECK_MPOS_NON_DET(m_pos
,m_off
,in
,ip
,M3_MAX_OFFSET
))
100 if (m_off
<= M2_MAX_OFFSET
|| m_pos
[3] == ip
[3])
104 GINDEX(m_pos
,m_off
,dict
,dindex
,in
);
105 if (LZO_CHECK_MPOS_NON_DET(m_pos
,m_off
,in
,ip
,M3_MAX_OFFSET
))
107 if (m_off
<= M2_MAX_OFFSET
|| m_pos
[3] == ip
[3])
113 #if 0 && defined(LZO_UNALIGNED_OK_2)
114 if (UA_GET16(m_pos
) != UA_GET16(ip
))
116 if (m_pos
[0] != ip
[0] || m_pos
[1] != ip
[1])
122 if (m_pos
[2] == ip
[2])
126 if (m_off
<= M2_MAX_OFFSET
)
130 if (lit
== 3) /* better compression, but slower */
132 assert(op
- 2 > out
); op
[-2] |= LZO_BYTE(3);
133 *op
++ = *ii
++; *op
++ = *ii
++; *op
++ = *ii
++;
145 UPDATE_I(dict
,0,dindex
,ip
,in
);
153 UPDATE_I(dict
,0,dindex
,ip
,in
);
154 /* store current literal run */
158 register lzo_uint t
= lit
;
160 if (t
< 4 && op
> out
)
161 op
[-2] |= LZO_BYTE(t
);
166 register lzo_uint tt
= t
- 31;
175 *op
++ = LZO_BYTE(tt
);
177 do *op
++ = *ii
++; while (--t
> 0);
184 if (*m_pos
++ != *ip
++ || *m_pos
++ != *ip
++ || *m_pos
++ != *ip
++ ||
185 *m_pos
++ != *ip
++ || *m_pos
++ != *ip
++ || *m_pos
++ != *ip
++)
189 assert(m_len
>= 3); assert(m_len
<= 8);
191 if (m_off
<= M2_MAX_OFFSET
)
194 *op
++ = LZO_BYTE(((m_len
- 2) << 5) | ((m_off
& 7) << 2));
195 *op
++ = LZO_BYTE(m_off
>> 3);
197 else if (m_len
== 3 && m_off
<= 2*M2_MAX_OFFSET
&& lit
> 0)
200 /* m_off -= M2_MAX_OFFSET; */
201 *op
++ = LZO_BYTE(((m_off
& 7) << 2));
202 *op
++ = LZO_BYTE(m_off
>> 3);
206 *op
++ = LZO_BYTE(M3_MARKER
| (m_len
- 2));
207 *op
++ = LZO_BYTE((m_off
& 63) << 2);
208 *op
++ = LZO_BYTE(m_off
>> 6);
216 while (ip
< end
&& *m_pos
== *ip
)
223 *op
++ = LZO_BYTE(M3_MARKER
| (m_len
- 2));
227 *op
++ = M3_MARKER
| 0;
234 *op
++ = LZO_BYTE(m_len
);
236 *op
++ = LZO_BYTE((m_off
& 63) << 2);
237 *op
++ = LZO_BYTE(m_off
>> 6);
246 /* store final literal run */
247 if (pd(in_end
,ii
) > 0)
249 register lzo_uint t
= pd(in_end
,ii
);
251 if (t
< 4 && op
> out
)
252 op
[-2] |= LZO_BYTE(t
);
257 register lzo_uint tt
= t
- 31;
266 *op
++ = LZO_BYTE(tt
);
268 do *op
++ = *ii
++; while (--t
> 0);
271 *out_len
= pd(op
, out
);
276 /***********************************************************************
277 // public entry point
278 ************************************************************************/
281 lzo1f_1_compress ( const lzo_bytep in
, lzo_uint in_len
,
282 lzo_bytep out
, lzo_uintp out_len
,
290 else if (in_len
<= 10)
292 *op
++ = LZO_BYTE(in_len
);
293 do *op
++ = *in
++; while (--in_len
> 0);
294 *out_len
= pd(op
, out
);
297 r
= do_compress(in
,in_len
,out
,out_len
,wrkmem
);
302 op
[0] = M3_MARKER
| 1;