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。


