xref: /freebsd/sbin/hastd/lzf.h (revision 136a9bb4e348d4dd1edf6e3d1e092bfa074fac3e)
11de7b4b8SPedro F. Giffuni /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni  *
48cd3d45aSPawel Jakub Dawidek  * Copyright (c) 2000-2008 Marc Alexander Lehmann <schmorp@schmorp.de>
58cd3d45aSPawel Jakub Dawidek  *
68cd3d45aSPawel Jakub Dawidek  * Redistribution and use in source and binary forms, with or without modifica-
78cd3d45aSPawel Jakub Dawidek  * tion, are permitted provided that the following conditions are met:
88cd3d45aSPawel Jakub Dawidek  *
98cd3d45aSPawel Jakub Dawidek  *   1.  Redistributions of source code must retain the above copyright notice,
108cd3d45aSPawel Jakub Dawidek  *       this list of conditions and the following disclaimer.
118cd3d45aSPawel Jakub Dawidek  *
128cd3d45aSPawel Jakub Dawidek  *   2.  Redistributions in binary form must reproduce the above copyright
138cd3d45aSPawel Jakub Dawidek  *       notice, this list of conditions and the following disclaimer in the
148cd3d45aSPawel Jakub Dawidek  *       documentation and/or other materials provided with the distribution.
158cd3d45aSPawel Jakub Dawidek  *
168cd3d45aSPawel Jakub Dawidek  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
178cd3d45aSPawel Jakub Dawidek  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
188cd3d45aSPawel Jakub Dawidek  * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
198cd3d45aSPawel Jakub Dawidek  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
208cd3d45aSPawel Jakub Dawidek  * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
218cd3d45aSPawel Jakub Dawidek  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
228cd3d45aSPawel Jakub Dawidek  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
238cd3d45aSPawel Jakub Dawidek  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
248cd3d45aSPawel Jakub Dawidek  * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
258cd3d45aSPawel Jakub Dawidek  * OF THE POSSIBILITY OF SUCH DAMAGE.
268cd3d45aSPawel Jakub Dawidek  *
278cd3d45aSPawel Jakub Dawidek  * Alternatively, the contents of this file may be used under the terms of
288cd3d45aSPawel Jakub Dawidek  * the GNU General Public License ("GPL") version 2 or any later version,
298cd3d45aSPawel Jakub Dawidek  * in which case the provisions of the GPL are applicable instead of
308cd3d45aSPawel Jakub Dawidek  * the above. If you wish to allow the use of your version of this file
318cd3d45aSPawel Jakub Dawidek  * only under the terms of the GPL and not to allow others to use your
328cd3d45aSPawel Jakub Dawidek  * version of this file under the BSD license, indicate your decision
338cd3d45aSPawel Jakub Dawidek  * by deleting the provisions above and replace them with the notice
348cd3d45aSPawel Jakub Dawidek  * and other provisions required by the GPL. If you do not delete the
358cd3d45aSPawel Jakub Dawidek  * provisions above, a recipient may use your version of this file under
368cd3d45aSPawel Jakub Dawidek  * either the BSD or the GPL.
378cd3d45aSPawel Jakub Dawidek  */
388cd3d45aSPawel Jakub Dawidek 
398cd3d45aSPawel Jakub Dawidek #ifndef LZF_H
408cd3d45aSPawel Jakub Dawidek #define LZF_H
418cd3d45aSPawel Jakub Dawidek 
428cd3d45aSPawel Jakub Dawidek /***********************************************************************
438cd3d45aSPawel Jakub Dawidek **
448cd3d45aSPawel Jakub Dawidek **	lzf -- an extremely fast/free compression/decompression-method
458cd3d45aSPawel Jakub Dawidek **	http://liblzf.plan9.de/
468cd3d45aSPawel Jakub Dawidek **
478cd3d45aSPawel Jakub Dawidek **	This algorithm is believed to be patent-free.
488cd3d45aSPawel Jakub Dawidek **
498cd3d45aSPawel Jakub Dawidek ***********************************************************************/
508cd3d45aSPawel Jakub Dawidek 
518cd3d45aSPawel Jakub Dawidek #define LZF_VERSION 0x0105 /* 1.5, API version */
528cd3d45aSPawel Jakub Dawidek 
538cd3d45aSPawel Jakub Dawidek /*
548cd3d45aSPawel Jakub Dawidek  * Compress in_len bytes stored at the memory block starting at
558cd3d45aSPawel Jakub Dawidek  * in_data and write the result to out_data, up to a maximum length
568cd3d45aSPawel Jakub Dawidek  * of out_len bytes.
578cd3d45aSPawel Jakub Dawidek  *
588cd3d45aSPawel Jakub Dawidek  * If the output buffer is not large enough or any error occurs return 0,
598cd3d45aSPawel Jakub Dawidek  * otherwise return the number of bytes used, which might be considerably
608cd3d45aSPawel Jakub Dawidek  * more than in_len (but less than 104% of the original size), so it
618cd3d45aSPawel Jakub Dawidek  * makes sense to always use out_len == in_len - 1), to ensure _some_
628cd3d45aSPawel Jakub Dawidek  * compression, and store the data uncompressed otherwise (with a flag, of
638cd3d45aSPawel Jakub Dawidek  * course.
648cd3d45aSPawel Jakub Dawidek  *
658cd3d45aSPawel Jakub Dawidek  * lzf_compress might use different algorithms on different systems and
668cd3d45aSPawel Jakub Dawidek  * even different runs, thus might result in different compressed strings
678cd3d45aSPawel Jakub Dawidek  * depending on the phase of the moon or similar factors. However, all
688cd3d45aSPawel Jakub Dawidek  * these strings are architecture-independent and will result in the
698cd3d45aSPawel Jakub Dawidek  * original data when decompressed using lzf_decompress.
708cd3d45aSPawel Jakub Dawidek  *
718cd3d45aSPawel Jakub Dawidek  * The buffers must not be overlapping.
728cd3d45aSPawel Jakub Dawidek  *
738cd3d45aSPawel Jakub Dawidek  * If the option LZF_STATE_ARG is enabled, an extra argument must be
748cd3d45aSPawel Jakub Dawidek  * supplied which is not reflected in this header file. Refer to lzfP.h
758cd3d45aSPawel Jakub Dawidek  * and lzf_c.c.
768cd3d45aSPawel Jakub Dawidek  *
778cd3d45aSPawel Jakub Dawidek  */
788cd3d45aSPawel Jakub Dawidek unsigned int
798cd3d45aSPawel Jakub Dawidek lzf_compress (const void *const in_data,  unsigned int in_len,
808cd3d45aSPawel Jakub Dawidek               void             *out_data, unsigned int out_len);
818cd3d45aSPawel Jakub Dawidek 
828cd3d45aSPawel Jakub Dawidek /*
838cd3d45aSPawel Jakub Dawidek  * Decompress data compressed with some version of the lzf_compress
848cd3d45aSPawel Jakub Dawidek  * function and stored at location in_data and length in_len. The result
858cd3d45aSPawel Jakub Dawidek  * will be stored at out_data up to a maximum of out_len characters.
868cd3d45aSPawel Jakub Dawidek  *
878cd3d45aSPawel Jakub Dawidek  * If the output buffer is not large enough to hold the decompressed
888cd3d45aSPawel Jakub Dawidek  * data, a 0 is returned and errno is set to E2BIG. Otherwise the number
898cd3d45aSPawel Jakub Dawidek  * of decompressed bytes (i.e. the original length of the data) is
908cd3d45aSPawel Jakub Dawidek  * returned.
918cd3d45aSPawel Jakub Dawidek  *
928cd3d45aSPawel Jakub Dawidek  * If an error in the compressed data is detected, a zero is returned and
938cd3d45aSPawel Jakub Dawidek  * errno is set to EINVAL.
948cd3d45aSPawel Jakub Dawidek  *
958cd3d45aSPawel Jakub Dawidek  * This function is very fast, about as fast as a copying loop.
968cd3d45aSPawel Jakub Dawidek  */
978cd3d45aSPawel Jakub Dawidek unsigned int
988cd3d45aSPawel Jakub Dawidek lzf_decompress (const void *const in_data,  unsigned int in_len,
998cd3d45aSPawel Jakub Dawidek                 void             *out_data, unsigned int out_len);
1008cd3d45aSPawel Jakub Dawidek 
1018cd3d45aSPawel Jakub Dawidek /*
1028cd3d45aSPawel Jakub Dawidek  * Size of hashtable is (1 << HLOG) * sizeof (char *)
1038cd3d45aSPawel Jakub Dawidek  * decompression is independent of the hash table size
1048cd3d45aSPawel Jakub Dawidek  * the difference between 15 and 14 is very small
1058cd3d45aSPawel Jakub Dawidek  * for small blocks (and 14 is usually a bit faster).
1068cd3d45aSPawel Jakub Dawidek  * For a low-memory/faster configuration, use HLOG == 13;
1078cd3d45aSPawel Jakub Dawidek  * For best compression, use 15 or 16 (or more, up to 23).
1088cd3d45aSPawel Jakub Dawidek  */
1098cd3d45aSPawel Jakub Dawidek #ifndef HLOG
1108cd3d45aSPawel Jakub Dawidek # define HLOG 16
1118cd3d45aSPawel Jakub Dawidek #endif
1128cd3d45aSPawel Jakub Dawidek 
1138cd3d45aSPawel Jakub Dawidek /*
1148cd3d45aSPawel Jakub Dawidek  * Sacrifice very little compression quality in favour of compression speed.
1158cd3d45aSPawel Jakub Dawidek  * This gives almost the same compression as the default code, and is
1168cd3d45aSPawel Jakub Dawidek  * (very roughly) 15% faster. This is the preferred mode of operation.
1178cd3d45aSPawel Jakub Dawidek  */
1188cd3d45aSPawel Jakub Dawidek #ifndef VERY_FAST
1198cd3d45aSPawel Jakub Dawidek # define VERY_FAST 1
1208cd3d45aSPawel Jakub Dawidek #endif
1218cd3d45aSPawel Jakub Dawidek 
1228cd3d45aSPawel Jakub Dawidek /*
1238cd3d45aSPawel Jakub Dawidek  * Sacrifice some more compression quality in favour of compression speed.
1248cd3d45aSPawel Jakub Dawidek  * (roughly 1-2% worse compression for large blocks and
1258cd3d45aSPawel Jakub Dawidek  * 9-10% for small, redundant, blocks and >>20% better speed in both cases)
1268cd3d45aSPawel Jakub Dawidek  * In short: when in need for speed, enable this for binary data,
1278cd3d45aSPawel Jakub Dawidek  * possibly disable this for text data.
1288cd3d45aSPawel Jakub Dawidek  */
1298cd3d45aSPawel Jakub Dawidek #ifndef ULTRA_FAST
1308cd3d45aSPawel Jakub Dawidek # define ULTRA_FAST 0
1318cd3d45aSPawel Jakub Dawidek #endif
1328cd3d45aSPawel Jakub Dawidek 
1338cd3d45aSPawel Jakub Dawidek /*
1348cd3d45aSPawel Jakub Dawidek  * Unconditionally aligning does not cost very much, so do it if unsure
1358cd3d45aSPawel Jakub Dawidek  */
1368cd3d45aSPawel Jakub Dawidek #ifndef STRICT_ALIGN
1371fc157aeSDimitry Andric # if !(defined(__i386) || defined (__amd64))
1381fc157aeSDimitry Andric #  define STRICT_ALIGN 1
1391fc157aeSDimitry Andric # else
1401fc157aeSDimitry Andric #  define STRICT_ALIGN 0
1411fc157aeSDimitry Andric # endif
1428cd3d45aSPawel Jakub Dawidek #endif
1438cd3d45aSPawel Jakub Dawidek 
1448cd3d45aSPawel Jakub Dawidek /*
1458cd3d45aSPawel Jakub Dawidek  * You may choose to pre-set the hash table (might be faster on some
1468cd3d45aSPawel Jakub Dawidek  * modern cpus and large (>>64k) blocks, and also makes compression
1478cd3d45aSPawel Jakub Dawidek  * deterministic/repeatable when the configuration otherwise is the same).
1488cd3d45aSPawel Jakub Dawidek  */
1498cd3d45aSPawel Jakub Dawidek #ifndef INIT_HTAB
1508cd3d45aSPawel Jakub Dawidek # define INIT_HTAB 1
1518cd3d45aSPawel Jakub Dawidek #endif
1528cd3d45aSPawel Jakub Dawidek 
1538cd3d45aSPawel Jakub Dawidek /*
1548cd3d45aSPawel Jakub Dawidek  * Avoid assigning values to errno variable? for some embedding purposes
1554b85a12fSUlrich Spörlein  * (linux kernel for example), this is necessary. NOTE: this breaks
1568cd3d45aSPawel Jakub Dawidek  * the documentation in lzf.h.
1578cd3d45aSPawel Jakub Dawidek  */
1588cd3d45aSPawel Jakub Dawidek #ifndef AVOID_ERRNO
1598cd3d45aSPawel Jakub Dawidek # define AVOID_ERRNO 0
1608cd3d45aSPawel Jakub Dawidek #endif
1618cd3d45aSPawel Jakub Dawidek 
1628cd3d45aSPawel Jakub Dawidek /*
163*136a9bb4SElyes Haouas  * Whether to pass the LZF_STATE variable as argument, or allocate it
1648cd3d45aSPawel Jakub Dawidek  * on the stack. For small-stack environments, define this to 1.
1658cd3d45aSPawel Jakub Dawidek  * NOTE: this breaks the prototype in lzf.h.
1668cd3d45aSPawel Jakub Dawidek  */
1678cd3d45aSPawel Jakub Dawidek #ifndef LZF_STATE_ARG
1688cd3d45aSPawel Jakub Dawidek # define LZF_STATE_ARG 0
1698cd3d45aSPawel Jakub Dawidek #endif
1708cd3d45aSPawel Jakub Dawidek 
1718cd3d45aSPawel Jakub Dawidek /*
172*136a9bb4SElyes Haouas  * Whether to add extra checks for input validity in lzf_decompress
1738cd3d45aSPawel Jakub Dawidek  * and return EINVAL if the input stream has been corrupted. This
1748cd3d45aSPawel Jakub Dawidek  * only shields against overflowing the input buffer and will not
1758cd3d45aSPawel Jakub Dawidek  * detect most corrupted streams.
1764b85a12fSUlrich Spörlein  * This check is not normally noticeable on modern hardware
1778cd3d45aSPawel Jakub Dawidek  * (<1% slowdown), but might slow down older cpus considerably.
1788cd3d45aSPawel Jakub Dawidek  */
1798cd3d45aSPawel Jakub Dawidek #ifndef CHECK_INPUT
1808cd3d45aSPawel Jakub Dawidek # define CHECK_INPUT 1
1818cd3d45aSPawel Jakub Dawidek #endif
1828cd3d45aSPawel Jakub Dawidek 
1838cd3d45aSPawel Jakub Dawidek /*****************************************************************************/
1848cd3d45aSPawel Jakub Dawidek /* nothing should be changed below */
1858cd3d45aSPawel Jakub Dawidek 
1868cd3d45aSPawel Jakub Dawidek typedef unsigned char u8;
1878cd3d45aSPawel Jakub Dawidek 
1888cd3d45aSPawel Jakub Dawidek typedef const u8 *LZF_STATE[1 << (HLOG)];
1898cd3d45aSPawel Jakub Dawidek 
1908cd3d45aSPawel Jakub Dawidek #if !STRICT_ALIGN
1918cd3d45aSPawel Jakub Dawidek /* for unaligned accesses we need a 16 bit datatype. */
1928cd3d45aSPawel Jakub Dawidek # include <limits.h>
1938cd3d45aSPawel Jakub Dawidek # if USHRT_MAX == 65535
1948cd3d45aSPawel Jakub Dawidek     typedef unsigned short u16;
1958cd3d45aSPawel Jakub Dawidek # elif UINT_MAX == 65535
1968cd3d45aSPawel Jakub Dawidek     typedef unsigned int u16;
1978cd3d45aSPawel Jakub Dawidek # else
1988cd3d45aSPawel Jakub Dawidek #  undef STRICT_ALIGN
1998cd3d45aSPawel Jakub Dawidek #  define STRICT_ALIGN 1
2008cd3d45aSPawel Jakub Dawidek # endif
2018cd3d45aSPawel Jakub Dawidek #endif
2028cd3d45aSPawel Jakub Dawidek 
2038cd3d45aSPawel Jakub Dawidek #if ULTRA_FAST
2048cd3d45aSPawel Jakub Dawidek # if defined(VERY_FAST)
2058cd3d45aSPawel Jakub Dawidek #  undef VERY_FAST
2068cd3d45aSPawel Jakub Dawidek # endif
2078cd3d45aSPawel Jakub Dawidek #endif
2088cd3d45aSPawel Jakub Dawidek 
2098cd3d45aSPawel Jakub Dawidek #if INIT_HTAB
2108cd3d45aSPawel Jakub Dawidek # ifdef __cplusplus
2118cd3d45aSPawel Jakub Dawidek #  include <cstring>
2128cd3d45aSPawel Jakub Dawidek # else
2138cd3d45aSPawel Jakub Dawidek #  include <string.h>
2148cd3d45aSPawel Jakub Dawidek # endif
2158cd3d45aSPawel Jakub Dawidek #endif
2168cd3d45aSPawel Jakub Dawidek 
2178cd3d45aSPawel Jakub Dawidek #endif
218