2 * LZO1X Compressor from MiniLZO
4 * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
6 * The full LZO package can be found at:
7 * http://www.oberhumer.com/opensource/lzo/
9 * Changed for kernel use by:
10 * Nitin Gupta <nitingupta910@gmail.com>
11 * Richard Purdie <rpurdie@openedhand.com>
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/lzo.h>
17 #include <asm/unaligned.h>
20 static noinline
size_t
21 _lzo1x_1_do_compress(const unsigned char *in
, size_t in_len
,
22 unsigned char *out
, size_t *out_len
, void *wrkmem
)
24 const unsigned char * const in_end
= in
+ in_len
;
25 const unsigned char * const ip_end
= in
+ in_len
- M2_MAX_LEN
- 5;
26 const unsigned char ** const dict
= wrkmem
;
27 const unsigned char *ip
= in
, *ii
= ip
;
28 const unsigned char *end
, *m
, *m_pos
;
29 size_t m_off
, m_len
, dindex
;
30 unsigned char *op
= out
;
35 dindex
= ((size_t)(0x21 * DX3(ip
, 5, 5, 6)) >> 5) & D_MASK
;
41 if (ip
== m_pos
|| ((size_t)(ip
- m_pos
) > M4_MAX_OFFSET
))
45 if (m_off
<= M2_MAX_OFFSET
|| m_pos
[3] == ip
[3])
48 dindex
= (dindex
& (D_MASK
& 0x7ff)) ^ (D_HIGH
| 0x1f);
54 if (ip
== m_pos
|| ((size_t)(ip
- m_pos
) > M4_MAX_OFFSET
))
58 if (m_off
<= M2_MAX_OFFSET
|| m_pos
[3] == ip
[3])
64 if (get_unaligned((const unsigned short *)m_pos
)
65 == get_unaligned((const unsigned short *)ip
)) {
66 if (likely(m_pos
[2] == ip
[2]))
73 if (unlikely(ip
>= ip_end
))
102 if (m_pos
[3] != *ip
++ || m_pos
[4] != *ip
++
103 || m_pos
[5] != *ip
++ || m_pos
[6] != *ip
++
104 || m_pos
[7] != *ip
++ || m_pos
[8] != *ip
++) {
108 if (m_off
<= M2_MAX_OFFSET
) {
110 *op
++ = (((m_len
- 1) << 5)
111 | ((m_off
& 7) << 2));
112 *op
++ = (m_off
>> 3);
113 } else if (m_off
<= M3_MAX_OFFSET
) {
115 *op
++ = (M3_MARKER
| (m_len
- 2));
120 *op
++ = (M4_MARKER
| ((m_off
& 0x4000) >> 11)
126 m
= m_pos
+ M2_MAX_LEN
+ 1;
128 while (ip
< end
&& *m
== *ip
) {
134 if (m_off
<= M3_MAX_OFFSET
) {
137 *op
++ = (M3_MARKER
| (m_len
- 2));
140 *op
++ = M3_MARKER
| 0;
145 if (m_len
<= M4_MAX_LEN
) {
147 | ((m_off
& 0x4000) >> 11)
152 | ((m_off
& 0x4000) >> 11));
154 while (m_len
> 255) {
163 *op
++ = ((m_off
& 63) << 2);
164 *op
++ = (m_off
>> 6);
168 if (unlikely(ip
>= ip_end
))
176 int lzo1x_1_compress(const unsigned char *in
, size_t in_len
, unsigned char *out
,
177 size_t *out_len
, void *wrkmem
)
179 const unsigned char *ii
;
180 unsigned char *op
= out
;
183 if (unlikely(in_len
<= M2_MAX_LEN
+ 5)) {
186 t
= _lzo1x_1_do_compress(in
, in_len
, op
, out_len
, wrkmem
);
191 ii
= in
+ in_len
- t
;
193 if (op
== out
&& t
<= 238) {
197 } else if (t
<= 18) {
215 *op
++ = M4_MARKER
| 1;
222 EXPORT_SYMBOL_GPL(lzo1x_1_compress
);
224 MODULE_LICENSE("GPL");
225 MODULE_DESCRIPTION("LZO1X-1 Compressor");