libc/lzf: Add Marc Alexander Lehmann's LIBLZF3.6 librrary
This commit is contained in:
parent
9c1efc7ab9
commit
25eb417c12
100
include/lzf.h
Normal file
100
include/lzf.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2008 Marc Alexander Lehmann <schmorp@schmorp.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modifica-
|
||||
* tion, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
||||
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
|
||||
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
|
||||
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License ("GPL") version 2 or any later version,
|
||||
* in which case the provisions of the GPL are applicable instead of
|
||||
* the above. If you wish to allow the use of your version of this file
|
||||
* only under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the BSD license, indicate your decision
|
||||
* by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete the
|
||||
* provisions above, a recipient may use your version of this file under
|
||||
* either the BSD or the GPL.
|
||||
*/
|
||||
|
||||
#ifndef LZF_H
|
||||
#define LZF_H
|
||||
|
||||
/***********************************************************************
|
||||
**
|
||||
** lzf -- an extremely fast/free compression/decompression-method
|
||||
** http://liblzf.plan9.de/
|
||||
**
|
||||
** This algorithm is believed to be patent-free.
|
||||
**
|
||||
***********************************************************************/
|
||||
|
||||
#define LZF_VERSION 0x0105 /* 1.5, API version */
|
||||
|
||||
/*
|
||||
* Compress in_len bytes stored at the memory block starting at
|
||||
* in_data and write the result to out_data, up to a maximum length
|
||||
* of out_len bytes.
|
||||
*
|
||||
* If the output buffer is not large enough or any error occurs return 0,
|
||||
* otherwise return the number of bytes used, which might be considerably
|
||||
* more than in_len (but less than 104% of the original size), so it
|
||||
* makes sense to always use out_len == in_len - 1), to ensure _some_
|
||||
* compression, and store the data uncompressed otherwise (with a flag, of
|
||||
* course.
|
||||
*
|
||||
* lzf_compress might use different algorithms on different systems and
|
||||
* even different runs, thus might result in different compressed strings
|
||||
* depending on the phase of the moon or similar factors. However, all
|
||||
* these strings are architecture-independent and will result in the
|
||||
* original data when decompressed using lzf_decompress.
|
||||
*
|
||||
* The buffers must not be overlapping.
|
||||
*
|
||||
* If the option LZF_STATE_ARG is enabled, an extra argument must be
|
||||
* supplied which is not reflected in this header file. Refer to lzfP.h
|
||||
* and lzf_c.c.
|
||||
*
|
||||
*/
|
||||
unsigned int
|
||||
lzf_compress (const void *const in_data, unsigned int in_len,
|
||||
void *out_data, unsigned int out_len);
|
||||
|
||||
/*
|
||||
* Decompress data compressed with some version of the lzf_compress
|
||||
* function and stored at location in_data and length in_len. The result
|
||||
* will be stored at out_data up to a maximum of out_len characters.
|
||||
*
|
||||
* If the output buffer is not large enough to hold the decompressed
|
||||
* data, a 0 is returned and errno is set to E2BIG. Otherwise the number
|
||||
* of decompressed bytes (i.e. the original length of the data) is
|
||||
* returned.
|
||||
*
|
||||
* If an error in the compressed data is detected, a zero is returned and
|
||||
* errno is set to EINVAL.
|
||||
*
|
||||
* This function is very fast, about as fast as a copying loop.
|
||||
*/
|
||||
unsigned int
|
||||
lzf_decompress (const void *const in_data, unsigned int in_len,
|
||||
void *out_data, unsigned int out_len);
|
||||
|
||||
#endif
|
||||
|
@ -15,6 +15,7 @@ source libc/dllfcn/Kconfig
|
||||
source libc/modlib/Kconfig
|
||||
source libc/wchar/Kconfig
|
||||
source libc/locale/Kconfig
|
||||
source libc/lzf/Kconfig
|
||||
source libc/time/Kconfig
|
||||
source libc/tls/Kconfig
|
||||
source libc/net/Kconfig
|
||||
|
@ -62,6 +62,7 @@ include hex2bin/Make.defs
|
||||
include inttypes/Make.defs
|
||||
include libgen/Make.defs
|
||||
include locale/Make.defs
|
||||
include lzf/Make.defs
|
||||
include machine/Make.defs
|
||||
include math/Make.defs
|
||||
include misc/Make.defs
|
||||
|
@ -33,6 +33,7 @@ we have:
|
||||
hex2bin - hex2bin.h
|
||||
libgen - libgen.h
|
||||
locale - locale.h
|
||||
lzf - lzf.h
|
||||
fixedmath - fixedmath.h
|
||||
inttypes - inttypes.h
|
||||
machine - Various architecture-specific implementations.
|
||||
|
39
libc/lzf/Kconfig
Normal file
39
libc/lzf/Kconfig
Normal file
@ -0,0 +1,39 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
config LIBC_LZF
|
||||
bool "LZF compression"
|
||||
default n
|
||||
---help---
|
||||
Enable the LZF compression library from Marc Alexander Lehmann
|
||||
|
||||
if LIBC_LZF
|
||||
|
||||
choice
|
||||
prompt "Compression options"
|
||||
default LIBC_LZF_SMALL
|
||||
---help---
|
||||
Trade-offs between faster and smaller compression. These sections
|
||||
have no effect on decompression.
|
||||
|
||||
config LIBC_LZF_SMALL
|
||||
bool "Better compression"
|
||||
|
||||
config LIBC_LZF_FAST
|
||||
bool "Faster compression"
|
||||
|
||||
config LIBC_LZF_FASTEST
|
||||
bool "Fastest compression"
|
||||
|
||||
endchoice # Compression options
|
||||
|
||||
config LIBC_LZF_ALIGN
|
||||
bool "Strict alignment"
|
||||
default y
|
||||
---help---
|
||||
Unconditionally aligning does not cost very much, so do it if unsure.
|
||||
|
||||
endif # LIBC_LZF
|
||||
|
47
libc/lzf/Make.defs
Normal file
47
libc/lzf/Make.defs
Normal file
@ -0,0 +1,47 @@
|
||||
############################################################################
|
||||
# libc/lzf/Make.defs
|
||||
#
|
||||
# Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifeq ($(CONFIG_LIBC_LZF),y)
|
||||
|
||||
# Add the internal C files to the build
|
||||
|
||||
CSRCS += lzf_c.c lzf_d.c
|
||||
|
||||
# Add the userfs directory to the build
|
||||
|
||||
DEPPATH += --dep-path lzf
|
||||
VPATH += :lzf
|
||||
|
||||
endif
|
123
libc/lzf/lzfP.h
Normal file
123
libc/lzf/lzfP.h
Normal file
@ -0,0 +1,123 @@
|
||||
/****************************************************************************
|
||||
* libc/lzf/lzf_c.c
|
||||
*
|
||||
* Copyright (c) 2000-2007 Marc Alexander Lehmann <schmorp@schmorp.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modifica-
|
||||
* tion, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
||||
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
|
||||
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
|
||||
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __LIBC_LZF_LZFP_H
|
||||
#define __LIBC_LZF_LZFP_H 1
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
# include <cstdint>
|
||||
# include <cstring>
|
||||
# include <climits>
|
||||
# include <cerrno>
|
||||
using namespace std;
|
||||
#else
|
||||
# include <stdint.h>
|
||||
# include <string.h>
|
||||
# include <limits.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
#include <lzf.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Size of hashtable is (1 << HLOG) * sizeof (char *). Decompression is
|
||||
* independent of the hash table size the difference between 15 and 14 is
|
||||
* very small for small blocks (and 14 is usually a bit faster). For a
|
||||
* low-memory/faster configuration, use HLOG == 13; For best compression,
|
||||
* use 15 or 16 (or more, up to 22).
|
||||
*/
|
||||
|
||||
#ifndef HLOG
|
||||
# define HLOG 13
|
||||
#endif
|
||||
|
||||
/* You may choose to pre-set the hash table (might be faster on some modern
|
||||
* CPUs and large (>>64k) blocks, and also makes compression deterministic/
|
||||
* repeatable when the configuration otherwise is the same).
|
||||
*/
|
||||
|
||||
#ifndef INIT_HTAB
|
||||
# define INIT_HTAB 0
|
||||
#endif
|
||||
|
||||
/* Whether to pass the LZF_STATE variable as argument, or allocate it
|
||||
* on the stack. For small-stack environments, define this to 1.
|
||||
* NOTE: this breaks the prototype in lzf.h.
|
||||
*/
|
||||
|
||||
#ifndef LZF_STATE_ARG
|
||||
# define LZF_STATE_ARG 0
|
||||
#endif
|
||||
|
||||
/* Whether to add extra checks for input validity in lzf_decompress
|
||||
* and return EINVAL if the input stream has been corrupted. This
|
||||
* only shields against overflowing the input buffer and will not
|
||||
* detect most corrupted streams.
|
||||
* This check is not normally noticeable on modern hardware
|
||||
* (<1% slowdown), but might slow down older cpus considerably.
|
||||
*/
|
||||
|
||||
#ifndef CHECK_INPUT
|
||||
# define CHECK_INPUT 1
|
||||
#endif
|
||||
|
||||
/* Whether to store pointers or offsets inside the hash table. On
|
||||
* 64 bit architectures, pointers take up twice as much space,
|
||||
* and might also be slower. Default is to autodetect.
|
||||
*/
|
||||
|
||||
/*#define LZF_USER_OFFSETS autodetect */
|
||||
|
||||
#ifndef LZF_USE_OFFSETS
|
||||
# define LZF_USE_OFFSETS (UINTPTR_MAX > 0xffffffffU)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#if LZF_USE_OFFSETS
|
||||
# define LZF_HSLOT_BIAS ((const uint8_t *)in_data)
|
||||
typedef unsigned int LZF_HSLOT;
|
||||
#else
|
||||
# define LZF_HSLOT_BIAS 0
|
||||
typedef const uint8_t *LZF_HSLOT;
|
||||
#endif
|
||||
|
||||
typedef LZF_HSLOT LZF_STATE[1 << (HLOG)];
|
||||
|
||||
#endif /* __LIBC_LZF_LZFP_H */
|
394
libc/lzf/lzf_c.c
Normal file
394
libc/lzf/lzf_c.c
Normal file
@ -0,0 +1,394 @@
|
||||
/****************************************************************************
|
||||
* libc/lzf/lzf_c.c
|
||||
*
|
||||
* Copyright (c) 2000-2010 Marc Alexander Lehmann <schmorp@schmorp.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modifica-
|
||||
* tion, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
||||
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
|
||||
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
|
||||
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "lzf/lzfP.h"
|
||||
|
||||
#ifdef CONFIG_LIBC_LZF
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define HSIZE (1 << (HLOG))
|
||||
|
||||
/* Don't play with this unless you benchmark! The data format is not
|
||||
* dependent on the hash function. The hash function might seem strange, just
|
||||
* believe me, it works ;)
|
||||
*/
|
||||
|
||||
#ifndef FRST
|
||||
# define FRST(p) (((p[0]) << 8) | p[1])
|
||||
# define NEXT(v,p) (((v) << 8) | p[2])
|
||||
# if defined(CONFIG_LIBC_LZF_FASTEST)
|
||||
# define IDX(h) ((( h >> (3*8 - HLOG)) - h ) & (HSIZE - 1))
|
||||
# elif defined(CONFIG_LIBC_LZF_FAST)
|
||||
# define IDX(h) ((( h >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
|
||||
# else
|
||||
# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* IDX works because it is very similar to a multiplicative hash, e.g.
|
||||
* ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1))
|
||||
* the latter is also quite fast on newer CPUs, and compresses similarly.
|
||||
*
|
||||
* the next one is also quite good, albeit slow ;)
|
||||
* (int)(cos(h & 0xffffff) * 1e6)
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/* original lzv-like hash function, much worse and thus slower */
|
||||
|
||||
# define FRST(p) (p[0] << 5) ^ p[1]
|
||||
# define NEXT(v,p) ((v) << 5) ^ p[2]
|
||||
# define IDX(h) ((h) & (HSIZE - 1))
|
||||
#endif
|
||||
|
||||
#define MAX_LIT (1 << 5)
|
||||
#define MAX_OFF (1 << 13)
|
||||
#define MAX_REF ((1 << 8) + (1 << 3))
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
# define expect(expr,value) __builtin_expect ((expr),(value))
|
||||
# define inline inline
|
||||
#else
|
||||
# define expect(expr,value) (expr)
|
||||
# define inline static
|
||||
#endif
|
||||
|
||||
#define expect_false(expr) expect ((expr) != 0, 0)
|
||||
#define expect_true(expr) expect ((expr) != 0, 1)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Compressed format
|
||||
*
|
||||
* 000LLLLL <L+1> ; literal, L+1=1..33 octets
|
||||
* LLLooooo oooooooo ; backref L+1=1..7 octets, o+1=1..4096 offset
|
||||
* 111ooooo LLLLLLLL oooooooo ; backref L+8 octets, o+1=1..4096 offset
|
||||
*
|
||||
*/
|
||||
|
||||
unsigned int lzf_compress(FAR const void *const in_data, unsigned int in_len,
|
||||
FAR void *out_data, unsigned int out_len
|
||||
#if LZF_STATE_ARG
|
||||
, LZF_STATE htab
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#if !LZF_STATE_ARG
|
||||
LZF_STATE htab;
|
||||
#endif
|
||||
FAR const uint8_t *ip = (const uint8_t *)in_data;
|
||||
FAR uint8_t *op = (uint8_t *)out_data;
|
||||
FAR const uint8_t *in_end = ip + in_len;
|
||||
FAR uint8_t *out_end = op + out_len;
|
||||
FAR const uint8_t *ref;
|
||||
|
||||
/* off requires a type wide enough to hold a general pointer difference.
|
||||
* ISO C doesn't have that (size_t might not be enough and ptrdiff_t only
|
||||
* works for differences within a single object). We also assume that no
|
||||
* no bit pattern traps. Since the only platform that is both non-POSIX
|
||||
* and fails to support both assumptions is windows 64 bit, we make a
|
||||
* special workaround for it.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_HAVE_LONG_LONG
|
||||
uint64_t off; /* Workaround for missing POSIX compliance */
|
||||
#else
|
||||
unsigned long off;
|
||||
#endif
|
||||
unsigned int hval;
|
||||
int lit;
|
||||
|
||||
if (!in_len || !out_len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if INIT_HTAB
|
||||
memset(htab, 0, sizeof (htab));
|
||||
#endif
|
||||
|
||||
lit = 0; /* start run */
|
||||
op++;
|
||||
|
||||
hval = FRST (ip);
|
||||
while (ip < in_end - 2)
|
||||
{
|
||||
LZF_HSLOT *hslot;
|
||||
|
||||
hval = NEXT (hval, ip);
|
||||
hslot = htab + IDX (hval);
|
||||
ref = *hslot + LZF_HSLOT_BIAS; *hslot = ip - LZF_HSLOT_BIAS;
|
||||
|
||||
if (1
|
||||
#if INIT_HTAB
|
||||
&& ref < ip /* the next test will actually take care of this, but this is faster */
|
||||
#endif
|
||||
&& (off = ip - ref - 1) < MAX_OFF
|
||||
&& ref > (uint8_t *)in_data
|
||||
&& ref[2] == ip[2]
|
||||
#ifdef CONFIG_LIBC_LZF_ALIGN
|
||||
&& ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0])
|
||||
#else
|
||||
&& *(uin16_t *)ref == *(uin16_t *)ip
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/* Match found at *ref++ */
|
||||
|
||||
unsigned int len = 2;
|
||||
unsigned int maxlen = in_end - ip - len;
|
||||
maxlen = maxlen > MAX_REF ? MAX_REF : maxlen;
|
||||
|
||||
/* First a faster conservative test */
|
||||
|
||||
if (expect_false (op + 3 + 1 >= out_end))
|
||||
{
|
||||
/* Second the exact but rare test */
|
||||
|
||||
if (op - !lit + 3 + 1 >= out_end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
op [- lit - 1] = lit - 1; /* Stop run */
|
||||
op -= !lit; /* Undo run if length is zero */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (expect_true (maxlen > 16))
|
||||
{
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
if (ref [len] != ip [len])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
len++;
|
||||
}
|
||||
while (len < maxlen && ref[len] == ip[len]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
len -= 2; /* len is now #octets - 1 */
|
||||
ip++;
|
||||
|
||||
if (len < 7)
|
||||
{
|
||||
*op++ = (off >> 8) + (len << 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = (off >> 8) + ( 7 << 5);
|
||||
*op++ = len - 7;
|
||||
}
|
||||
|
||||
*op++ = off;
|
||||
|
||||
lit = 0; op++; /* start run */
|
||||
|
||||
ip += len + 1;
|
||||
|
||||
if (expect_false (ip >= in_end - 2))
|
||||
break;
|
||||
|
||||
#if defined(CONFIG_LIBC_LZF_FASTEST) || defined(CONFIG_LIBC_LZF_FAST)
|
||||
--ip;
|
||||
# if defined(CONFIG_LIBC_LZF_FAST) && !defined(CONFIG_LIBC_LZF_FASTEST)
|
||||
--ip;
|
||||
# endif
|
||||
hval = FRST (ip);
|
||||
|
||||
hval = NEXT (hval, ip);
|
||||
htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
|
||||
ip++;
|
||||
|
||||
# if defined(CONFIG_LIBC_LZF_FAST) && !defined(CONFIG_LIBC_LZF_FASTEST)
|
||||
hval = NEXT (hval, ip);
|
||||
htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
|
||||
ip++;
|
||||
# endif
|
||||
#else
|
||||
ip -= len + 1;
|
||||
|
||||
do
|
||||
{
|
||||
hval = NEXT (hval, ip);
|
||||
htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
|
||||
ip++;
|
||||
}
|
||||
while (len--);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* One more literal byte we must copy */
|
||||
|
||||
if (expect_false (op >= out_end))
|
||||
return 0;
|
||||
|
||||
lit++;
|
||||
*op++ = *ip++;
|
||||
|
||||
if (expect_false (lit == MAX_LIT))
|
||||
{
|
||||
op [- lit - 1] = lit - 1; /* stop run */
|
||||
lit = 0; op++; /* start run */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* At most 3 bytes can be missing here */
|
||||
|
||||
if (op + 3 > out_end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (ip < in_end)
|
||||
{
|
||||
lit++; *op++ = *ip++;
|
||||
|
||||
if (expect_false (lit == MAX_LIT))
|
||||
{
|
||||
op [- lit - 1] = lit - 1; /* Stop run */
|
||||
lit = 0; /* Start run */
|
||||
op++;
|
||||
}
|
||||
}
|
||||
|
||||
op [- lit - 1] = lit - 1; /* End run */
|
||||
op -= !lit; /* Undo run if length is zero */
|
||||
|
||||
return op - (uint8_t *)out_data;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_LIBC_LZF */
|
279
libc/lzf/lzf_d.c
Normal file
279
libc/lzf/lzf_d.c
Normal file
@ -0,0 +1,279 @@
|
||||
/****************************************************************************
|
||||
* libc/lzf/lzf_c.c
|
||||
*
|
||||
* Copyright (c) 2000-2010 Marc Alexander Lehmann <schmorp@schmorp.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modifica-
|
||||
* tion, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
||||
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
|
||||
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
|
||||
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "lzf/lzfP.h"
|
||||
|
||||
#ifdef CONFIG_LIBC_LZF
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int lzf_decompress (FAR const void *const in_data,
|
||||
unsigned int in_len, FAR void *out_data,
|
||||
unsigned int out_len)
|
||||
{
|
||||
FAR uint8_t const *ip = (const uint8_t *)in_data;
|
||||
FAR uint8_t *op = (uint8_t *)out_data;
|
||||
FAR uint8_t const *const in_end = ip + in_len;
|
||||
FAR uint8_t *const out_end = op + out_len;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned int ctrl = *ip++;
|
||||
|
||||
if (ctrl < (1 << 5)) /* literal run */
|
||||
{
|
||||
ctrl++;
|
||||
|
||||
if (op + ctrl > out_end)
|
||||
{
|
||||
set_errno(E2BIG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CHECK_INPUT
|
||||
if (ip + ctrl > in_end)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef lzf_movsb
|
||||
lzf_movsb(op, ip, ctrl);
|
||||
#else
|
||||
switch (ctrl)
|
||||
{
|
||||
case 32:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 31:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 30:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 29:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 28:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 27:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 26:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 25:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 24:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 23:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 22:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 21:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 20:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 19:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 18:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 17:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 16:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 15:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 14:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 13:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 12:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 11:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 10:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 9:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 8:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 7:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 6:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 5:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 4:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 3:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 2:
|
||||
*op++ = *ip++;
|
||||
|
||||
case 1:
|
||||
*op++ = *ip++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else /* back reference */
|
||||
{
|
||||
unsigned int len = ctrl >> 5;
|
||||
|
||||
FAR uint8_t *ref = op - ((ctrl & 0x1f) << 8) - 1;
|
||||
|
||||
#if CHECK_INPUT
|
||||
if (ip >= in_end)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (len == 7)
|
||||
{
|
||||
len += *ip++;
|
||||
#if CHECK_INPUT
|
||||
if (ip >= in_end)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ref -= *ip++;
|
||||
|
||||
if (op + len + 2 > out_end)
|
||||
{
|
||||
set_errno(E2BIG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ref < (uint8_t *)out_data)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef lzf_movsb
|
||||
len += 2;
|
||||
lzf_movsb (op, ref, len);
|
||||
#else
|
||||
switch (len)
|
||||
{
|
||||
default:
|
||||
len += 2;
|
||||
|
||||
if (op >= ref + len)
|
||||
{
|
||||
/* Disjunct areas */
|
||||
|
||||
memcpy (op, ref, len);
|
||||
op += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Overlapping, use octte by octte copying */
|
||||
|
||||
do
|
||||
*op++ = *ref++;
|
||||
while (--len);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 9:
|
||||
*op++ = *ref++;
|
||||
|
||||
case 8:
|
||||
*op++ = *ref++;
|
||||
|
||||
case 7:
|
||||
*op++ = *ref++;
|
||||
|
||||
case 6:
|
||||
*op++ = *ref++;
|
||||
|
||||
case 5:
|
||||
*op++ = *ref++;
|
||||
|
||||
case 4:
|
||||
*op++ = *ref++;
|
||||
|
||||
case 3:
|
||||
*op++ = *ref++;
|
||||
|
||||
case 2:
|
||||
*op++ = *ref++;
|
||||
|
||||
case 1:
|
||||
case 0:
|
||||
/* two octets more */
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
while (ip < in_end);
|
||||
|
||||
return op - (uint8_t *)out_data;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_LIBC_LZF */
|
Loading…
Reference in New Issue
Block a user