Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / fs / jffs2 / compr_lzo.c
diff --git a/qemu/roms/u-boot/fs/jffs2/compr_lzo.c b/qemu/roms/u-boot/fs/jffs2/compr_lzo.c
new file mode 100644 (file)
index 0000000..e648ec4
--- /dev/null
@@ -0,0 +1,401 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2004 Patrik Kluba,
+ *                   University of Szeged, Hungary
+ *
+ * For licensing information, see the file 'LICENCE' in the
+ * jffs2 directory.
+ *
+ * $Id: compr_lzo.c,v 1.3 2004/06/23 16:34:39 havasi Exp $
+ *
+ */
+
+/*
+   LZO1X-1 (and -999) compression module for jffs2
+   based on the original LZO sources
+*/
+
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+
+/*
+   Original copyright notice follows:
+
+   lzo1x_9x.c -- implementation of the LZO1X-999 compression algorithm
+   lzo_ptr.h -- low-level pointer constructs
+   lzo_swd.ch -- sliding window dictionary
+   lzoconf.h -- configuration for the LZO real-time data compression library
+   lzo_mchw.ch -- matching functions using a window
+   minilzo.c -- mini subset of the LZO real-time data compression library
+   config1x.h -- configuration for the LZO1X algorithm
+   lzo1x.h -- public interface of the LZO1X compression algorithm
+
+   These files are part of the LZO real-time data compression library.
+
+   Copyright (C) 1996-2002 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.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Markus F.X.J. Oberhumer
+   <markus@oberhumer.com>
+*/
+
+/*
+
+       2004-02-16  pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu>
+                               Initial release
+                                       -removed all 16 bit code
+                                       -all sensitive data will be on 4 byte boundary
+                                       -removed check parts for library use
+                                       -removed all but LZO1X-* compression
+
+*/
+
+
+#include <config.h>
+#include <linux/stddef.h>
+#include <jffs2/jffs2.h>
+#include <jffs2/compr_rubin.h>
+
+/* Integral types that have *exactly* the same number of bits as a lzo_voidp */
+typedef unsigned long lzo_ptr_t;
+typedef long lzo_sptr_t;
+
+/* data type definitions */
+#define U32 unsigned long
+#define S32 signed long
+#define I32 long
+#define U16 unsigned short
+#define S16 signed short
+#define I16 short
+#define U8 unsigned char
+#define S8 signed char
+#define I8 char
+
+#define M1_MAX_OFFSET  0x0400
+#define M2_MAX_OFFSET  0x0800
+#define M3_MAX_OFFSET  0x4000
+#define M4_MAX_OFFSET  0xbfff
+
+#define __COPY4(dst,src)  * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
+#define COPY4(dst,src) __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src))
+
+#define TEST_IP                (ip < ip_end)
+#define TEST_OP                (op <= op_end)
+
+#define NEED_IP(x) \
+           if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x))  goto input_overrun
+#define NEED_OP(x) \
+           if ((lzo_uint)(op_end - op) < (lzo_uint)(x))  goto output_overrun
+#define TEST_LOOKBEHIND(m_pos,out)    if (m_pos < out) goto lookbehind_overrun
+
+typedef U32 lzo_uint32;
+typedef I32 lzo_int32;
+typedef U32 lzo_uint;
+typedef I32 lzo_int;
+typedef int lzo_bool;
+
+#define lzo_byte               U8
+#define lzo_bytep              U8 *
+#define lzo_charp              char *
+#define lzo_voidp              void *
+#define lzo_shortp             short *
+#define lzo_ushortp            unsigned short *
+#define lzo_uint32p            lzo_uint32 *
+#define lzo_int32p             lzo_int32 *
+#define lzo_uintp              lzo_uint *
+#define lzo_intp               lzo_int *
+#define lzo_voidpp             lzo_voidp *
+#define lzo_bytepp             lzo_bytep *
+#define lzo_sizeof_dict_t              sizeof(lzo_bytep)
+
+#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 PTR(a)                         ((lzo_ptr_t) (a))
+#define PTR_LINEAR(a)          PTR(a)
+#define PTR_ALIGNED_4(a)       ((PTR_LINEAR(a) & 3) == 0)
+#define PTR_ALIGNED_8(a)       ((PTR_LINEAR(a) & 7) == 0)
+#define PTR_ALIGNED2_4(a,b)    (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0)
+#define PTR_ALIGNED2_8(a,b)    (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0)
+#define PTR_LT(a,b)                    (PTR(a) < PTR(b))
+#define PTR_GE(a,b)                    (PTR(a) >= PTR(b))
+#define PTR_DIFF(a,b)          ((lzo_ptrdiff_t) (PTR(a) - PTR(b)))
+#define pd(a,b)                        ((lzo_uint) ((a)-(b)))
+
+typedef ptrdiff_t lzo_ptrdiff_t;
+
+static int
+lzo1x_decompress (const lzo_byte * in, lzo_uint in_len,
+                 lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem)
+{
+       register lzo_byte *op;
+       register const lzo_byte *ip;
+       register lzo_uint t;
+
+       register const lzo_byte *m_pos;
+
+       const lzo_byte *const ip_end = in + in_len;
+       lzo_byte *const op_end = out + *out_len;
+
+       *out_len = 0;
+
+       op = out;
+       ip = in;
+
+       if (*ip > 17)
+       {
+               t = *ip++ - 17;
+               if (t < 4)
+                       goto match_next;
+               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;
+               if (t == 0)
+               {
+                       NEED_IP (1);
+                       while (*ip == 0)
+                       {
+                               t += 255;
+                               ip++;
+                               NEED_IP (1);
+                       }
+                       t += 15 + *ip++;
+               }
+               NEED_OP (t + 3);
+               NEED_IP (t + 4);
+               if (PTR_ALIGNED2_4 (op, ip))
+               {
+                       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);
+                       }
+               }
+               else
+               {
+                       *op++ = *ip++;
+                       *op++ = *ip++;
+                       *op++ = *ip++;
+                       do
+                               *op++ = *ip++;
+                       while (--t > 0);
+               }
+             first_literal_run:
+
+               t = *ip++;
+               if (t >= 16)
+                       goto match;
+
+               m_pos = op - (1 + M2_MAX_OFFSET);
+               m_pos -= t >> 2;
+               m_pos -= *ip++ << 2;
+               TEST_LOOKBEHIND (m_pos, out);
+               NEED_OP (3);
+               *op++ = *m_pos++;
+               *op++ = *m_pos++;
+               *op++ = *m_pos;
+
+               goto match_done;
+
+               while (TEST_IP && TEST_OP)
+               {
+                     match:
+                       if (t >= 64)
+                       {
+                               m_pos = op - 1;
+                               m_pos -= (t >> 2) & 7;
+                               m_pos -= *ip++ << 3;
+                               t = (t >> 5) - 1;
+                               TEST_LOOKBEHIND (m_pos, out);
+                               NEED_OP (t + 3 - 1);
+                               goto copy_match;
+
+                       }
+                       else if (t >= 32)
+                       {
+                               t &= 31;
+                               if (t == 0)
+                               {
+                                       NEED_IP (1);
+                                       while (*ip == 0)
+                                       {
+                                               t += 255;
+                                               ip++;
+                                               NEED_IP (1);
+                                       }
+                                       t += 31 + *ip++;
+                               }
+
+                               m_pos = op - 1;
+                               m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+
+                               ip += 2;
+                       }
+                       else if (t >= 16)
+                       {
+                               m_pos = op;
+                               m_pos -= (t & 8) << 11;
+
+                               t &= 7;
+                               if (t == 0)
+                               {
+                                       NEED_IP (1);
+                                       while (*ip == 0)
+                                       {
+                                               t += 255;
+                                               ip++;
+                                               NEED_IP (1);
+                                       }
+                                       t += 7 + *ip++;
+                               }
+
+                               m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+
+                               ip += 2;
+                               if (m_pos == op)
+                                       goto eof_found;
+                               m_pos -= 0x4000;
+                       }
+                       else
+                       {
+
+                               m_pos = op - 1;
+                               m_pos -= t >> 2;
+                               m_pos -= *ip++ << 2;
+                               TEST_LOOKBEHIND (m_pos, out);
+                               NEED_OP (2);
+                               *op++ = *m_pos++;
+                               *op++ = *m_pos;
+
+                               goto match_done;
+                       }
+
+                       TEST_LOOKBEHIND (m_pos, out);
+                       NEED_OP (t + 3 - 1);
+                       if (t >= 2 * 4 - (3 - 1)
+                           && PTR_ALIGNED2_4 (op, m_pos))
+                       {
+                               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
+
+                       {
+                             copy_match:
+                               *op++ = *m_pos++;
+                               *op++ = *m_pos++;
+                               do
+                                       *op++ = *m_pos++;
+                               while (--t > 0);
+                       }
+
+                     match_done:
+                       t = ip[-2] & 3;
+
+                       if (t == 0)
+                               break;
+
+                     match_next:
+                       NEED_OP (t);
+                       NEED_IP (t + 1);
+                       do
+                               *op++ = *ip++;
+                       while (--t > 0);
+                       t = *ip++;
+               }
+       }
+       *out_len = op - out;
+       return LZO_E_EOF_NOT_FOUND;
+
+      eof_found:
+       *out_len = op - out;
+       return (ip == ip_end ? LZO_E_OK :
+               (ip <
+                ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
+
+      input_overrun:
+       *out_len = op - out;
+       return LZO_E_INPUT_OVERRUN;
+
+      output_overrun:
+       *out_len = op - out;
+       return LZO_E_OUTPUT_OVERRUN;
+
+      lookbehind_overrun:
+       *out_len = op - out;
+       return LZO_E_LOOKBEHIND_OVERRUN;
+}
+
+int lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,
+                     u32 srclen, u32 destlen)
+{
+       lzo_uint outlen = destlen;
+       return lzo1x_decompress (data_in, srclen, cpage_out, &outlen, NULL);
+}