1 /* lzo2a_9x.c -- implementation of the LZO2A-999 compression algorithm
3 This file is part of the LZO real-time data compression library.
5 Copyright (C) 1996-2015 Markus Franz Xaver Johannes Oberhumer
8 The LZO library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of
11 the License, or (at your option) any later version.
13 The LZO library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with the LZO library; see the file COPYING.
20 If not, write to the Free Software Foundation, Inc.,
21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 Markus F.X.J. Oberhumer
24 <markus@oberhumer.com>
25 http://www.oberhumer.com/opensource/lzo/
33 /***********************************************************************
35 ************************************************************************/
37 #define SWD_THRESHOLD 1 /* lower limit for match length */
38 #define SWD_F 2048 /* upper limit for match length */
42 #define LZO_COMPRESS_T lzo2a_999_t
43 #define lzo_swd_t lzo2a_999_swd_t
44 #include "lzo_mchw.ch"
47 #if (LZO_CC_BORLANDC && LZO_MM_FLAT)
48 # if ((__BORLANDC__) >= 0x0450 && (__BORLANDC__) < 0x0460)
49 /* avoid internal compiler error */
55 /***********************************************************************
57 ************************************************************************/
59 #define putbyte(x) *op++ = LZO_BYTE(x)
61 #define putbits(j,x) \
62 if (k == 0) bitp = op++; \
64 if (k >= 8) { *bitp = LZO_BYTE(MASKBITS(8)); DUMPBITS(8); \
65 if (k > 0) bitp = op++; }
67 #define putbit(x) putbits(1,x)
70 /***********************************************************************
71 // this is a public function, but there is no prototype in a header file
72 ************************************************************************/
75 lzo2a_999_compress_callback ( const lzo_bytep in
, lzo_uint in_len
,
76 lzo_bytep out
, lzo_uintp out_len
,
82 lzo2a_999_compress_callback ( const lzo_bytep in
, lzo_uint in_len
,
83 lzo_bytep out
, lzo_uintp out_len
,
90 lzo_uint m_len
, m_off
;
92 LZO_COMPRESS_T
* const c
= &cc
;
93 lzo_swd_p
const swd
= (lzo_swd_p
) wrkmem
;
96 lzo_uint32_t b
= 0; /* bit buffer */
97 unsigned k
= 0; /* bits in bit buffer */
100 LZO_COMPILE_TIME_ASSERT(LZO2A_999_MEM_COMPRESS
>= SIZEOF_LZO_SWD_T
)
104 c
->in_end
= in
+ in_len
;
106 c
->m1
= c
->m2
= c
->m3
= c
->m4
= 0;
110 r
= init_match(c
,swd
,NULL
,0,0);
114 swd
->max_chain
= max_chain
;
116 r
= find_match(c
,swd
,0,0);
121 lzo_uint lazy_match_min_gain
= 0;
134 if (m_len
< M3_MIN_LEN
)
137 lazy_match_min_gain
= 1;
141 if (m_len
>= M1_MIN_LEN
&& m_len
<= M1_MAX_LEN
&& m_off
<= 256)
143 lazy_match_min_gain
= 2;
149 else if (m_len
>= 10)
150 lazy_match_min_gain
= 1;
153 lazy_match_min_gain
= 1;
162 /* try a lazy match */
163 if (lazy_match_min_gain
> 0 && c
->look
> m_len
)
165 unsigned char lit
= LZO_BYTE(swd
->b_char
);
167 r
= find_match(c
,swd
,1,0);
168 assert(r
== 0); LZO_UNUSED(r
);
172 if (m_off
< 8192 && c
->m_off
>= 8192)
173 lazy_match_min_gain
+= extra1
;
176 if (m_len
>= M1_MIN_LEN
&& m_len
<= M1_MAX_LEN
&& m_off
<= 256)
178 if (!(c
->m_len
>= M1_MIN_LEN
&&
179 c
->m_len
<= M1_MAX_LEN
&& c
->m_off
<= 256))
180 lazy_match_min_gain
+= extra2
;
182 if (c
->m_len
>= M1_MIN_LEN
&&
183 c
->m_len
<= M1_MAX_LEN
&& c
->m_off
<= 256)
185 lazy_match_min_gain
-= 1;
188 if ((lzo_int
) lazy_match_min_gain
< 1)
189 lazy_match_min_gain
= 1;
191 if (c
->m_len
>= m_len
+ lazy_match_min_gain
)
197 assert(lzo_memcmp(c
->ip
- c
->look
, c
->ip
- c
->look
- m_off
,
199 assert(m_len
>= 3 || (m_len
>= 2 && m_off
<= 256));
217 putbyte(swd
->b_char
);
219 r
= find_match(c
,swd
,1,0);
220 assert(r
== 0); LZO_UNUSED(r
);
224 assert(m_len
>= M1_MIN_LEN
);
226 assert(m_off
<= SWD_N
);
229 if (m_len
>= M1_MIN_LEN
&& m_len
<= M1_MAX_LEN
&& m_off
<= 256)
233 putbits(2,m_len
- M1_MIN_LEN
);
238 else if (m_off
>= 8192)
240 unsigned len
= m_len
;
241 assert(m_len
>= M3_MIN_LEN
);
247 len
-= M3_MIN_LEN
- 1;
265 putbyte(((m_len
- 2) << 5) | (m_off
& 31));
271 lzo_uint len
= m_len
;
287 r
= find_match(c
,swd
,m_len
,1+ahead
);
288 assert(r
== 0); LZO_UNUSED(r
);
291 c
->codesize
= pd(op
, out
);
294 #if defined(LZO_EOF_CODE)
302 /* flush remaining bits */
303 assert(k
< CHAR_BIT
);
306 assert(b
== MASKBITS(k
));
307 assert(op
- bitp
> 1);
308 *bitp
= LZO_BYTE(MASKBITS(k
));
314 assert(c
->textsize
== in_len
);
315 c
->codesize
= pd(op
, out
);
317 *out_len
= pd(op
, out
);
319 if (c
->cb
&& c
->cb
->nprogress
)
320 (*c
->cb
->nprogress
)(c
->cb
, c
->textsize
, c
->codesize
, 0);
323 printf("%ld -> %ld: %ld %ld %ld %ld %ld %ld\n",
324 (long) c
->textsize
, (long) c
->codesize
,
325 c
->lit_bytes
, c
->m1
, c
->m2
, c
->m3
, c
->m4
, c
->lazy
);
332 /***********************************************************************
334 ************************************************************************/
337 lzo2a_999_compress ( const lzo_bytep in
, lzo_uint in_len
,
338 lzo_bytep out
, lzo_uintp out_len
,
341 return lzo2a_999_compress_callback(in
,in_len
,out
,out_len
,wrkmem
,
342 (lzo_callback_p
) 0, 0);
346 /* vim:set ts=4 sw=4 et: */