注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

BCB-DG's Blog

...

 
 
 

日志

 
 

使用miniLZO  

2014-11-10 15:16:51|  分类: Linux |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
//edsionte

miniLZO是一种轻量级的压缩和解压缩库,它是基于LZO压缩和解压缩算法实现的。LZO虽然功能强大,但是编译后的库文件较大,而minilzo编译后的库则小于5kb,因此miniLZO为那些仅需要简单压缩和解压缩功能的程序而设计。

实现miniLZO的源码很简单,包含如下文件:

edsionte@virtualPC ~/minilzo-2.06 $ tree
.
├── COPYING
├── lzoconf.h
├── lzodefs.h
├── Makefile
├── minilzo.c
├── minilzo.h
├── README.LZO
└── testmini.c

在程序中加入miniLZO压缩和解压缩功能的方法很简单,只需将源文件minilzo.c和头文件lzoconf.h,lzodefs.h和minilzo.h拷贝到源文件目录下,在源代码中加入头文件minilzo.h,并且在编译时加入miniloz.c。

如何在源程序中具体使用miniLZO的压缩和解压缩功能?下面将给出一个简单的实例程序来说明使用方法。该程序所演示的功能是:首先利用 minilzo提供的压缩API将指定文件的前1024字节进行压缩,并将压缩后的内容保存在cfile文件中;然后将该压缩文件的内容再进行解压缩,并 存入另一个文件dcfile中。

正如上面所描述的那样,要使用miniLZO,必须加入头文件minilzo.h。

#include "minilzo.h"

#define MAX_LEN 1024

#define HEAP_ALLOC(var,size) \
    lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]

//the wkmem is used for compressed
static HEAP_ALLOC(wkmem, LZO1X_1_MEM_COMPRESS);

除此之外,定义一个宏HEAP_ALLOC,它为压缩提供一个内存空间。要使用压缩或解压缩功能,必须先通过lzo_init()对miniLZO对应的库进行初始化。

int main()
{
	int fd;
	char *srcbuffer = NULL, *destbuffer = NULL;
	lzo_uint inlen = MAX_LEN;
	lzo_uint outlen = 0;
	lzo_uint newlen = 0;

	//init the lzo lib
	if (lzo_init() != LZO_E_OK) {
		printf("lzo_init error.\n");
		return -1;
	}

打开要压缩的文件,将数据读入内存的缓冲区中。

	if ((fd = open("./minilzo.c", O_RDONLY)) < 0) {
		printerror(__LINE__, errno, "open");
	}

	//alloc the src buffer and dest buffer
	if ((srcbuffer = malloc(MAX_LEN)) < 0) {
		printerror(__LINE__, errno, "malloc");
	}
	if ((destbuffer = malloc(MAX_LEN)) < 0) {
		printerror(__LINE__, errno, "malloc");
	}
	memset(srcbuffer, 0, MAX_LEN);
	memset(destbuffer, 0, MAX_LEN);

	if (read(fd, srcbuffer, MAX_LEN) < 0) {
		printerror(__LINE__, errno, "read");
	}

利用压缩接口lzo1x_1_compress()将srcbuffer中长度为inlen的数据进行压缩,并将压缩后的数据保存在destbuffer中,其压缩数据的长度返回到值结果参数outlen中。其中wkmem为压缩数据时所需要的内存空间。

	int ret;
	if ((ret = lzo1x_1_compress(srcbuffer, inlen, destbuffer, &outlen, wkmem)) != LZO_E_OK) {
		printf("compress error:%d.\n", ret);
		return -1;
	} else {
		printf("compress %lu bytes into %lu bytes.\n", (unsigned long)inlen, (unsigned long)outlen);
	}

	if (outlen >= inlen) {
		printf("This block contains incompressible data.\n");
		return 0;
	}

下面将压缩后的数据保存到新文件cfile中。

	int cfd;
	if ((cfd = open("./cfile", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0) {
		printerror(__LINE__, errno, "open");
	}

	if (write(cfd, destbuffer, outlen) < 0) {
		printerror(__LINE__, errno, "write");
	}

接着进行解压缩过程,利用lzo1x_decompress()则可以完成。各个参数的意义与压缩时相同,只不过要调整源数据和目的数据之间的方向。

	memset(srcbuffer, 0, MAX_LEN);
	if ((ret = lzo1x_decompress(destbuffer, outlen, srcbuffer, &newlen, NULL)) != LZO_E_OK) {
		printf("decompress error:%d.\n", ret);
		return -1;
	} else if ( inlen == newlen) {
		printf("decompress %lu bytes into %lu bytes.\n", (unsigned long)outlen, (unsigned long)newlen);
	}

最后将解压缩的数据写入新文件对此dcfile中。

	int dcfd;
	if ((dcfd = open("./dcfile", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0) {
		printerror(__LINE__, errno, "open");
	}

	if (write(dcfd, srcbuffer, newlen) < 0) {
		printerror(__LINE__, errno, "write");
	}

	close(fd);
	close(cfd);
	close(dcfd);
	printf("compress success!\n");
	return 0;
}

上述为源代码,如果使用make编译文件,则Makefile为:

edsionte@virtualPC ~/edsionte-code/lzo $ cat Makefile
target:=testlzo
source:=testlzo.c minilzo.c

default:
	gcc -o $(target) $(source)
clean:
	rm $(target)

执行后,可查看两个文件的大小差异:

edsionte@virtualPC ~/edsionte-code/lzo $ ls -l cfile dcfile
-rw------- 1 edsionte edsionte  265  6月 19 10:23 cfile
-rw------- 1 edsionte edsionte 1024  6月 19 10:23 dcfile

可以看出minilzo的压缩率大约为1:4。

  评论这张
 
阅读(1129)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017