Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 58768
b: refs/heads/master
c: 64c70b1
h: refs/heads/master
v: v3
  • Loading branch information
Richard Purdie authored and Linus Torvalds committed Jul 11, 2007
1 parent 4bf45c9 commit f33ca8f
Show file tree
Hide file tree
Showing 8 changed files with 581 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4c75f7416f51b0c6855952467a5db04f9c598f09
refs/heads/master: 64c70b1cf43de158282bc1675918d503e5b15cc1
44 changes: 44 additions & 0 deletions trunk/include/linux/lzo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#ifndef __LZO_H__
#define __LZO_H__
/*
* LZO Public Kernel Interface
* A mini subset of the LZO real-time data compression library
*
* Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
*
* The full LZO package can be found at:
* http://www.oberhumer.com/opensource/lzo/
*
* Changed for kernel use by:
* Nitin Gupta <nitingupta910@gmail.com>
* Richard Purdie <rpurdie@openedhand.com>
*/

#define LZO1X_MEM_COMPRESS (16384 * sizeof(unsigned char *))
#define LZO1X_1_MEM_COMPRESS LZO1X_MEM_COMPRESS

#define lzo1x_worst_compress(x) (x + (x / 64) + 16 + 3)

/* This requires 'workmem' of size LZO1X_1_MEM_COMPRESS */
int lzo1x_1_compress(const unsigned char *src, size_t src_len,
unsigned char *dst, size_t *dst_len, void *wrkmem);

/* safe decompression with overrun testing */
int lzo1x_decompress_safe(const unsigned char *src, size_t src_len,
unsigned char *dst, size_t *dst_len);

/*
* Return values (< 0 = Error)
*/
#define LZO_E_OK 0
#define LZO_E_ERROR (-1)
#define LZO_E_OUT_OF_MEMORY (-2)
#define LZO_E_NOT_COMPRESSIBLE (-3)
#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)

#endif
6 changes: 6 additions & 0 deletions trunk/lib/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ config ZLIB_INFLATE
config ZLIB_DEFLATE
tristate

config LZO_COMPRESS
tristate

config LZO_DECOMPRESS
tristate

#
# Generic allocator support is selected if needed
#
Expand Down
2 changes: 2 additions & 0 deletions trunk/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o
obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/
obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/
obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
obj-$(CONFIG_LZO_COMPRESS) += lzo/
obj-$(CONFIG_LZO_DECOMPRESS) += lzo/

obj-$(CONFIG_TEXTSEARCH) += textsearch.o
obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o
Expand Down
5 changes: 5 additions & 0 deletions trunk/lib/lzo/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
lzo_compress-objs := lzo1x_compress.o
lzo_decompress-objs := lzo1x_decompress.o

obj-$(CONFIG_LZO_COMPRESS) += lzo_compress.o
obj-$(CONFIG_LZO_DECOMPRESS) += lzo_decompress.o
226 changes: 226 additions & 0 deletions trunk/lib/lzo/lzo1x_compress.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
/*
* LZO1X Compressor from MiniLZO
*
* Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
*
* The full LZO package can be found at:
* http://www.oberhumer.com/opensource/lzo/
*
* Changed for kernel use by:
* Nitin Gupta <nitingupta910@gmail.com>
* Richard Purdie <rpurdie@openedhand.com>
*/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/lzo.h>
#include <asm/unaligned.h>
#include "lzodefs.h"

static noinline size_t
_lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
unsigned char *out, size_t *out_len, void *wrkmem)
{
const unsigned char * const in_end = in + in_len;
const unsigned char * const ip_end = in + in_len - M2_MAX_LEN - 5;
const unsigned char ** const dict = wrkmem;
const unsigned char *ip = in, *ii = ip;
const unsigned char *end, *m, *m_pos;
size_t m_off, m_len, dindex;
unsigned char *op = out;

ip += 4;

for (;;) {
dindex = ((0x21 * DX3(ip, 5, 5, 6)) >> 5) & D_MASK;
m_pos = dict[dindex];

if (m_pos < in)
goto literal;

if (ip == m_pos || (ip - m_pos) > M4_MAX_OFFSET)
goto literal;

m_off = ip - m_pos;
if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
goto try_match;

dindex = (dindex & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f);
m_pos = dict[dindex];

if (m_pos < in)
goto literal;

if (ip == m_pos || (ip - m_pos) > M4_MAX_OFFSET)
goto literal;

m_off = ip - m_pos;
if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
goto try_match;

goto literal;

try_match:
if (get_unaligned((const unsigned short *)m_pos)
== get_unaligned((const unsigned short *)ip)) {
if (likely(m_pos[2] == ip[2]))
goto match;
}

literal:
dict[dindex] = ip;
++ip;
if (unlikely(ip >= ip_end))
break;
continue;

match:
dict[dindex] = ip;
if (ip != ii) {
size_t t = ip - ii;

if (t <= 3) {
op[-2] |= t;
} else if (t <= 18) {
*op++ = (t - 3);
} else {
size_t tt = t - 18;

*op++ = 0;
while (tt > 255) {
tt -= 255;
*op++ = 0;
}
*op++ = tt;
}
do {
*op++ = *ii++;
} while (--t > 0);
}

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++) {
--ip;
m_len = ip - ii;

if (m_off <= M2_MAX_OFFSET) {
m_off -= 1;
*op++ = (((m_len - 1) << 5)
| ((m_off & 7) << 2));
*op++ = (m_off >> 3);
} else if (m_off <= M3_MAX_OFFSET) {
m_off -= 1;
*op++ = (M3_MARKER | (m_len - 2));
goto m3_m4_offset;
} else {
m_off -= 0x4000;

*op++ = (M4_MARKER | ((m_off & 0x4000) >> 11)
| (m_len - 2));
goto m3_m4_offset;
}
} else {
end = in_end;
m = m_pos + M2_MAX_LEN + 1;

while (ip < end && *m == *ip) {
m++;
ip++;
}
m_len = ip - ii;

if (m_off <= M3_MAX_OFFSET) {
m_off -= 1;
if (m_len <= 33) {
*op++ = (M3_MARKER | (m_len - 2));
} else {
m_len -= 33;
*op++ = M3_MARKER | 0;
goto m3_m4_len;
}
} else {
m_off -= 0x4000;
if (m_len <= M4_MAX_LEN) {
*op++ = (M4_MARKER
| ((m_off & 0x4000) >> 11)
| (m_len - 2));
} else {
m_len -= M4_MAX_LEN;
*op++ = (M4_MARKER
| ((m_off & 0x4000) >> 11));
m3_m4_len:
while (m_len > 255) {
m_len -= 255;
*op++ = 0;
}

*op++ = (m_len);
}
}
m3_m4_offset:
*op++ = ((m_off & 63) << 2);
*op++ = (m_off >> 6);
}

ii = ip;
if (unlikely(ip >= ip_end))
break;
}

*out_len = op - out;
return in_end - ii;
}

int lzo1x_1_compress(const unsigned char *in, size_t in_len, unsigned char *out,
size_t *out_len, void *wrkmem)
{
const unsigned char *ii;
unsigned char *op = out;
size_t t;

if (unlikely(in_len <= M2_MAX_LEN + 5)) {
t = in_len;
} else {
t = _lzo1x_1_do_compress(in, in_len, op, out_len, wrkmem);
op += *out_len;
}

if (t > 0) {
ii = in + in_len - t;

if (op == out && t <= 238) {
*op++ = (17 + t);
} else if (t <= 3) {
op[-2] |= t;
} else if (t <= 18) {
*op++ = (t - 3);
} else {
size_t tt = t - 18;

*op++ = 0;
while (tt > 255) {
tt -= 255;
*op++ = 0;
}

*op++ = tt;
}
do {
*op++ = *ii++;
} while (--t > 0);
}

*op++ = M4_MARKER | 1;
*op++ = 0;
*op++ = 0;

*out_len = op - out;
return LZO_E_OK;
}
EXPORT_SYMBOL_GPL(lzo1x_1_compress);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("LZO1X-1 Compressor");

Loading

0 comments on commit f33ca8f

Please sign in to comment.