⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lzo1.c

📁 lzo-1.08-src.zip 高效的压缩解压代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* lzo1.c -- implementation of the LZO1 algorithm   This file is 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> */#include <lzo1.h>#include "lzo_conf.h"/***********************************************************************// The next two defines can be changed to customize LZO1.// The default version is LZO1-5/1.************************************************************************//* run bits (3 - 5) - the compressor and the decompressor * must use the same value. */#if !defined(RBITS)#  define RBITS		5#endif/* compression level (1 - 9) - this only affects the compressor. * 1 is fastest, 9 is best compression ratio */#if !defined(CLEVEL)#  define CLEVEL	1			/* fastest by default */#endif/* check configuration */#if (RBITS < 3 || RBITS > 5)#  error "invalid RBITS"#endif#if (CLEVEL < 1 || CLEVEL > 9)#  error "invalid CLEVEL"#endif/***********************************************************************// You should not have to change anything below this line.************************************************************************/#include "lzo_util.h"/***********************************************************************//************************************************************************//*     Format of the marker byte	 76543210	 --------	 00000000	a long run (a 'R0' run) - there are short and long R0 runs	 000rrrrr	a short run with len r	 mmmooooo	a short match (len = 2+m, o = offset low bits)	 111ooooo	a long match (o = offset low bits)*/#define RSIZE	(1 << RBITS)#define RMASK	(RSIZE - 1)#define OBITS	RBITS				/* offset and run-length use same bits */#define OSIZE	(1 << OBITS)#define OMASK	(OSIZE - 1)#define MBITS	(8 - OBITS)#define MSIZE	(1 << MBITS)#define MMASK	(MSIZE - 1)/* sanity checks */#if (OBITS < 3 || OBITS > 5)#  error "invalid OBITS"#endif#if (MBITS < 3 || MBITS > 5)#  error "invalid MBITS"#endif/***********************************************************************// some macros to improve readability************************************************************************//* Minimum len of a match */#define	MIN_MATCH			3#define	THRESHOLD			(MIN_MATCH - 1)/* Minimum len of match coded in 2 bytes */#define	MIN_MATCH_SHORT		MIN_MATCH/* Maximum len of match coded in 2 bytes */#define	MAX_MATCH_SHORT		(THRESHOLD + (MSIZE - 2))/* MSIZE - 2: 0 is used to indicate runs, *            MSIZE-1 is used to indicate a long match *//* Minimum len of match coded in 3 bytes */#define	MIN_MATCH_LONG		(MAX_MATCH_SHORT + 1)/* Maximum len of match coded in 3 bytes */#define	MAX_MATCH_LONG		(MIN_MATCH_LONG + 255)/* Maximum offset of a match */#define	MAX_OFFSET			(1 << (8 + OBITS))/*RBITS | MBITS  MIN  THR.  MSIZE  MAXS  MINL  MAXL   MAXO  R0MAX R0FAST======+===============================================================  3   |   5      3    2     32    32    33    288   2048    263   256  4   |   4      3    2     16    16    17    272   4096    271   264  5   |   3      3    2      8     8     9    264   8192    287   280 *//***********************************************************************// internal configuration// all of these affect compression only************************************************************************//* return -1 instead of copying if the data cannot be compressed */#undef LZO_RETURN_IF_NOT_COMPRESSIBLE/* choose the hashing strategy */#ifndef LZO_HASH#define LZO_HASH	LZO_HASH_LZO_INCREMENTAL_A#endif#define D_INDEX1(d,p)		d = DM((0x21*DX2(p,5,5)) >> 5)#define D_INDEX2(d,p)		d = d ^ D_MASK#define DBITS		(8 + RBITS)#include "lzo_dict.h"#define DVAL_LEN	DVAL_LOOKAHEAD/***********************************************************************// get algorithm info, return memory required for compression************************************************************************/LZO_EXTERN(lzo_uint) lzo1_info ( int *rbits, int *clevel );LZO_PUBLIC(lzo_uint)lzo1_info ( int *rbits, int *clevel ){	if (rbits)		*rbits = RBITS;	if (clevel)		*clevel = CLEVEL;	return D_SIZE * lzo_sizeof(lzo_byte *);}/***********************************************************************// decode a R0 literal run (a long run)************************************************************************/#define	R0MIN	(RSIZE)				/* Minimum len of R0 run of literals */#define	R0MAX	(R0MIN + 255)		/* Maximum len of R0 run of literals */#define	R0FAST	(R0MAX & ~7u)		/* R0MAX aligned to 8 byte boundary */#if (R0MAX - R0FAST != 7) || ((R0FAST & 7) != 0)#  error "something went wrong"#endif/* 7 special codes from R0FAST+1 .. R0MAX * these codes mean long R0 runs with lengths * 512, 1024, 2048, 4096, 8192, 16384, 32768 *//***********************************************************************// LZO1 decompress a block of data.//// Could be easily translated into assembly code.************************************************************************/LZO_PUBLIC(int)lzo1_decompress  ( const lzo_byte *in , lzo_uint  in_len,                         lzo_byte *out, lzo_uintp out_len,                         lzo_voidp wrkmem ){	lzo_byte *op;	const lzo_byte *ip;	const lzo_byte * const ip_end = in + in_len;	lzo_uint t;	LZO_UNUSED(wrkmem);#if defined(__LZO_QUERY_DECOMPRESS)	if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem))		return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0);#endif	op = out;	ip = in;	while (ip < ip_end)	{		t = *ip++;	/* get marker */		if (t < R0MIN)			/* a literal run */		{			if (t == 0)				/* a R0 literal run */			{				t = *ip++;				if (t >= R0FAST - R0MIN)			/* a long R0 run */				{					t -= R0FAST - R0MIN;					if (t == 0)						t = R0FAST;					else					{#if 0						t = 256u << ((unsigned) t);#else						/* help the optimizer */						lzo_uint tt = 256;						do tt <<= 1; while (--t > 0);						t = tt;#endif					}					MEMCPY8_DS(op,ip,t);					continue;				}				t += R0MIN;			}			MEMCPY_DS(op,ip,t);		}		else					/* a match */		{			lzo_uint tt;			/* get match offset */			const lzo_byte *m_pos = op - 1;			m_pos -= (lzo_uint)(t & OMASK) | (((lzo_uint) *ip++) << OBITS);			/* get match len */			if (t >= ((MSIZE - 1) << OBITS))				/* all m-bits set */				tt = (MIN_MATCH_LONG - THRESHOLD) + *ip++;	/* a long match */			else				tt = t >> OBITS;							/* a short match */			assert(m_pos >= out);			assert(m_pos <  op);			/* a half unrolled loop */			*op++ = *m_pos++;			*op++ = *m_pos++;			MEMMOVE_DS(op,m_pos,tt);		}	}	*out_len = op - out;	/* the next line is the only check in the decompressor ! */	return (ip == ip_end ? LZO_E_OK :	       (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));}/***********************************************************************// code a literal run************************************************************************/static lzo_byte *store_run(lzo_byte *op, const lzo_byte *ii, lzo_uint r_len){	assert(r_len > 0);	/* code a long R0 run */	if (r_len >= 512)	{		unsigned r_bits = 7;		/* 256 << 7 == 32768 */		do {			while (r_len >= (256u << r_bits))			{				r_len -= (256u << r_bits);				*op++ = 0; *op++ = LZO_BYTE((R0FAST - R0MIN) + r_bits);				MEMCPY8_DS(op, ii, (256u << r_bits));			}		} while (--r_bits > 0);	}	while (r_len >= R0FAST)	{		r_len -= R0FAST;		*op++ = 0; *op++ = R0FAST - R0MIN;		MEMCPY8_DS(op, ii, R0FAST);	}	if (r_len >= R0MIN)	{		/* code a short R0 run */		*op++ = 0; *op++ = LZO_BYTE(r_len - R0MIN);		MEMCPY_DS(op, ii, r_len);	}	else if (r_len > 0)	{		/* code a 'normal' run */		*op++ = LZO_BYTE(r_len);		MEMCPY_DS(op, ii, r_len);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -