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

📄 lzo1a.c

📁 lzo-1.08-src.zip 高效的压缩解压代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* lzo1a.c -- implementation of the LZO1A 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 <lzo1a.h>#include "lzo_conf.h"/***********************************************************************// The next two defines can be changed to customize LZO1A.// The default version is LZO1A-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/* Collect statistics */#if 0 && !defined(LZO_COLLECT_STATS)#  define LZO_COLLECT_STATS#endif/***********************************************************************// You should not have to change anything below this line.************************************************************************//* check configuration */#if (RBITS < 3 || RBITS > 5)#  error "invalid RBITS"#endif#if (CLEVEL < 1 || CLEVEL > 9)#  error "invalid CLEVEL"#endif/***********************************************************************// 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#include "lzo1a_de.h"#include "stats1a.h"#include "lzo_util.h"/* check other constants */#if (LBITS < 5 || LBITS > 8)#  error "invalid LBITS"#endif#if defined(LZO_COLLECT_STATS)   static lzo1a_stats_t lzo_statistics;   lzo1a_stats_t *lzo1a_stats = &lzo_statistics;#  define lzo_stats lzo1a_stats#endif/***********************************************************************// get algorithm info, return memory required for compression************************************************************************/LZO_EXTERN(lzo_uint) lzo1a_info ( int *rbits, int *clevel );LZO_PUBLIC(lzo_uint)lzo1a_info ( int *rbits, int *clevel ){	if (rbits)		*rbits = RBITS;	if (clevel)		*clevel = CLEVEL;	return D_SIZE * lzo_sizeof(lzo_byte *);}/***********************************************************************// LZO1A decompress a block of data.//// Could be easily translated into assembly code.************************************************************************/LZO_PUBLIC(int)lzo1a_decompress ( const lzo_byte *in , lzo_uint  in_len,                         lzo_byte *out, lzo_uintp out_len,                         lzo_voidp wrkmem ){#if defined(LZO_OPTIMIZE_GNUC_i386)	register lzo_byte *op __asm__("%edi");	register const lzo_byte *ip __asm__("%esi");	register lzo_uint t __asm__("%ecx");	register const lzo_byte *m_pos __asm__("%ebx");#else	register lzo_byte *op;	register const lzo_byte *ip;	register lzo_uint t;	register const lzo_byte *m_pos;#endif	const lzo_byte * const ip_end = in + in_len;	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 */		LZO_STATS(lzo_stats->marker[t]++);		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;			goto literal;		}		else if (t < R0MIN)		/* a short literal run */		{literal:			MEMCPY_DS(op,ip,t);		/* after a literal a match must follow */			while (ip < ip_end)			{				t = *ip++;			/* get R1 marker */				if (t >= R0MIN)					goto match;			/* R1 match - a context sensitive 3 byte match + 1 byte literal */				assert((t & OMASK) == t);				m_pos = op - MIN_OFFSET;				m_pos -= t | (((lzo_uint) *ip++) << OBITS);				assert(m_pos >= out); assert(m_pos < op);				*op++ = *m_pos++;				*op++ = *m_pos++;				*op++ = *m_pos++;				*op++ = *ip++;			}		}		else					/* a match */		{match:			/* get match offset */			m_pos = op - MIN_OFFSET;			m_pos -= (t & OMASK) | (((lzo_uint) *ip++) << OBITS);			assert(m_pos >= out); assert(m_pos < op);			/* get match len */			if (t < ((MSIZE - 1) << OBITS))			/* a short match */			{				t >>= OBITS;				*op++ = *m_pos++;				*op++ = *m_pos++;				MEMMOVE_DS(op,m_pos,t);			}			else									 /* a long match */			{#if (LBITS < 8)				t = (MIN_MATCH_LONG - THRESHOLD) + ((lzo_uint)(*ip++) & LMASK);#else				t = (MIN_MATCH_LONG - THRESHOLD) + (lzo_uint)(*ip++);#endif				*op++ = *m_pos++;				*op++ = *m_pos++;				MEMMOVE_DS(op,m_pos,t);#if (LBITS < 8)				/* a very short literal following a long match */				t = ip[-1] >> LBITS;				if (t) do					*op++ = *ip++;				while (--t);#endif			}		}	}	*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));}/***********************************************************************// LZO1A compress a block of data.//// I apologize for the spaghetti code, but it really helps the optimizer.************************************************************************/#include "lzo1a_cr.ch"static intdo_compress    ( const lzo_byte *in , lzo_uint  in_len,                       lzo_byte *out, lzo_uintp out_len,                       lzo_voidp wrkmem ){#if defined(LZO_OPTIMIZE_GNUC_i386)	register const lzo_byte *ip __asm__("%esi");#else	register const lzo_byte *ip;#endif#if defined(__LZO_HASH_INCREMENTAL)	lzo_uint32 dv;#endif	const lzo_byte *m_pos;	lzo_byte *op;	const lzo_byte * const ip_end = in+in_len - DVAL_LEN - MIN_MATCH_LONG;	const lzo_byte * const in_end = in+in_len - DVAL_LEN;	const lzo_byte *ii;	lzo_dict_p const dict = (lzo_dict_p) wrkmem;	const lzo_byte *r1 = ip_end;	/* pointer for R1 match (none yet) */#if (LBITS < 8)	const lzo_byte *im = ip_end;	/* pointer to last match start */#endif#if !defined(NDEBUG)	const lzo_byte *m_pos_sav;#endif	op = out;	ip = in;	ii = ip;			/* point to start of current literal run */	/* init dictionary */#if defined(LZO_DETERMINISTIC)	BZERO8_PTR(wrkmem,sizeof(lzo_dict_t),D_SIZE);#endif	DVAL_FIRST(dv,ip); UPDATE_D(dict,0,dv,ip,in); ip++;	DVAL_NEXT(dv,ip);	do {		lzo_moff_t m_off;		lzo_uint dindex;		DINDEX1(dindex,ip);		GINDEX(m_pos,m_off,dict,dindex,in);		if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,MAX_OFFSET))			goto literal;		if (m_pos[0] == ip[0] && m_pos[1] == ip[1] && m_pos[2] == ip[2])			goto match;		DINDEX2(dindex,ip);		GINDEX(m_pos,m_off,dict,dindex,in);		if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,MAX_OFFSET))			goto literal;		if (m_pos[0] == ip[0] && m_pos[1] == ip[1] && m_pos[2] == ip[2])			goto match;		goto literal;literal:		UPDATE_I(dict,0,dindex,ip,in);		if (++ip >= ip_end)			break;		continue;match:		UPDATE_I(dict,0,dindex,ip,in);#if !defined(NDEBUG) && defined(LZO_DICT_USE_PTR)		assert(m_pos == NULL || m_pos >= in);		m_pos_sav = m_pos;#endif		m_pos += 3;		{	/* we have found a match (of at least length 3) */#if !defined(NDEBUG) && !defined(LZO_DICT_USE_PTR)			assert((m_pos_sav = ip - m_off) == (m_pos - 3));#endif

⌨️ 快捷键说明

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