bzip数据压缩 C调用
来源:互联网 发布:怎么用淘宝客赚钱 编辑:程序博客网 时间:2024/04/29 19:16
bzip官网:http://www.bzip.org/ 有源码及英文文档。
官网的英文文档比较齐全,可就是没有找到类似的demo代码,没办法,只能结合已有的官方文档,自己摸索了。
由于需要对内存的数据进行加压解压处理,因此调用的是bzip提供的低级接口:
typedef struct { char *next_in; // 输入指针 unsigned int avail_in; // 输入数据长 unsigned int total_in_lo32; unsigned int total_in_hi32; char *next_out; // 输出指针 unsigned int avail_out; // 输出缓冲大小 unsigned int total_out_lo32; unsigned int total_out_hi32; void *state; void *(*bzalloc)(void *,int,int); void (*bzfree)(void *,void *); void *opaque;} bz_stream;int BZ2_bzCompressInit ( bz_stream *strm, int blockSize100k, int verbosity, int workFactor );//一般使用默认推荐参数:BZ2_bzCompressInit(strm,5,2,30);int BZ2_bzCompress ( bz_stream *strm, int action );int BZ2_bzCompressEnd ( bz_stream *strm );int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );// 一般使用默认推荐参数:BZ2_bzDecompressInit(strm,2,1);int BZ2_bzDecompress ( bz_stream *strm );int BZ2_bzDecompressEnd ( bz_stream *strm );
压缩过程:
1. 初始化压缩参数,分配资源。
2. 对数据进行压缩,输出压缩后的数据。
压缩的过程实际上是一个有限状态机处理过程,看英文文档感觉比较绕,比较麻烦。
3. 销毁释放分配的资源。
压缩过程的有限状态机:
RUNNING - 输入数据进行压缩。
FLUSHING - 输出压缩后的数据。
FINISHING - 没有输入,只有输出。
IDLE - 压缩未开始或者压缩结束。
压缩遵循的原则:
1. 进入压缩,即进入RUNNING状态,输入待压缩数据,如果BZ2_bzCompress ( bz_stream *strm, int action )返回BZ_RUN_OK,则继续输入。直到返回非BZ_RUN_OK或者没有更多的输入。
2. 如果上面返回的是BZ_FLUSH_OK,进入FLUSHING状态,输出压缩后的数据。
3. 如果返回的是BZ_FINISH_OK,进入FINISHING状态,进行输出,直到返回BZ_STREAM_END结束。
在压缩的过程中,如果出现错误或者异常,如果捕获到其他异常,压缩过程应该就是失败的了。具体异常返回查看BZIP官网。
解压过程也是类似的。
下面直接上代码:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "bzlib.h"#define BZ_GROUP_MAX_LENGTH10240//#define BZ_DEBUG(format,args...){fprintf(stderr,format,args);}#define BZ_DEBUG(format,args...){}int my_bz_compress(char *src,int *src_len,char *dst,int *dst_len){ int ret = 0; bz_stream *strm=NULL; strm = (bz_stream *)malloc(sizeof(bz_stream)); if(strm == NULL){BZ_DEBUG("%s malloc (bz_stream) failed!\n","");ret = -1;return ret; } memset(strm,0,sizeof(bz_stream)); ret = BZ2_bzCompressInit(strm,5,2,30); if(ret != BZ_OK){BZ_DEBUG("%s bzcompressinit failed!\n","");ret = -1;return ret; } BZ_DEBUG("bzcommpressinit success %s !\n",""); int src_ptr = 0,src_last = *src_len; int dst_ptr = 0,dst_last = *dst_len; int src_tmp = 0,dst_tmp = 0; ret = BZ_RUN_OK; while(ret == BZ_RUN_OK || ret == BZ_FLUSH_OK || ret == BZ_FINISH_OK){while(ret == BZ_RUN_OK){ if(src_ptr < (*src_len)){//if(strm->avail_in < 1){ src_last = (*src_len) - src_ptr; src_tmp = src_last > BZ_GROUP_MAX_LENGTH ? BZ_GROUP_MAX_LENGTH : src_last; strm->avail_in = src_tmp; strm->next_in = (char *)(src + src_ptr);//}else{// src_tmp = strm->avail_in;// strm->next_in = (char *)(src + src_ptr);//}dst_last = (*dst_len) - dst_ptr;dst_tmp = dst_last > BZ_GROUP_MAX_LENGTH ? BZ_GROUP_MAX_LENGTH : dst_last;strm->avail_out = dst_tmp;strm->next_out = (dst+dst_ptr); ret = BZ2_bzCompress(strm,BZ_RUN);src_ptr = src_ptr + src_tmp - strm->avail_in;dst_ptr = dst_ptr + dst_tmp - strm->avail_out;BZ_DEBUG("runing ret [%d] src_ptr[%d] src_tmp[%d] in[%d] src_len[%d] dst_ptr[%d] dst_tmp[%d] out[%d] dst_len[%d]\n",ret,src_ptr,src_tmp,strm->avail_in,*src_len,dst_ptr,dst_tmp,strm->avail_out,*dst_len);//if(strm->avail_in > 0) // ret = BZ_FLUSH_OK; }else{ret = BZ_FINISH_OK; }}while(ret == BZ_FLUSH_OK){ if(dst_ptr < (*dst_len)){dst_last = (*dst_len) - dst_ptr;dst_tmp = dst_last > BZ_GROUP_MAX_LENGTH ? BZ_GROUP_MAX_LENGTH : dst_last;strm->avail_out = dst_tmp; strm->next_out = (dst + dst_ptr);ret = BZ2_bzCompress(strm,BZ_FLUSH);dst_ptr = dst_ptr + dst_tmp - strm->avail_out;BZ_DEBUG("flush ret[%d] dst_ptr[%d] dst_tmp[%d] out[%d] dst_len[%d]\n",ret,dst_ptr,dst_tmp,strm->avail_out,*dst_len); }else{ret = -1; }}while(ret == BZ_FINISH_OK){ if(dst_ptr < (*dst_len)){dst_last = (*dst_len) - dst_ptr;dst_tmp = dst_last > BZ_GROUP_MAX_LENGTH ? BZ_GROUP_MAX_LENGTH : dst_last;strm->avail_out = dst_tmp;strm->next_out = (dst + dst_ptr);ret = BZ2_bzCompress(strm,BZ_FINISH);dst_ptr = dst_ptr + dst_tmp - strm->avail_out;BZ_DEBUG("finish ret[%d] dst_ptr[%d] dst_tmp[%d] out[%d] dst_len[%d]\n",ret,dst_ptr,dst_tmp,strm->avail_out,*dst_len); }else{ret = -1; }} } *dst_len = dst_ptr; BZ2_bzCompressEnd(strm);//destroy bzcommoress if(ret == BZ_STREAM_END){BZ_DEBUG("bz_compress success %s !\n","");ret = 0; }else{BZ_DEBUG("bz_compress failed %s !\n","");ret = -1; } return ret;}int my_bz_decompress(char *src,int *src_len,char *dst,int *dst_len){ int ret = 0; if((*src_len) < 1){BZ_DEBUG("src_len is zero %s !\n","");ret = -1;return ret; } bz_stream *strm = NULL; strm = (bz_stream *)malloc(sizeof(bz_stream)); if(strm == NULL){BZ_DEBUG("malloc() bz_stream failed %s !\n","");ret = -1;return ret; } memset(strm,0,sizeof(bz_stream)); ret = BZ2_bzDecompressInit(strm,2,1); if(ret != BZ_OK){BZ_DEBUG("BZ2_bzDecompressInit failed %s !\n","");ret = -1;return ret; } BZ_DEBUG("BZ2_bzDecompressInit success %s !\n",""); int src_ptr = 0,src_last = *src_len; int dst_ptr = 0,dst_last = *dst_len; int src_tmp = 0,dst_tmp = 0; ret = BZ_OK; while(ret == BZ_OK){src_last = (*src_len) - src_ptr;src_tmp = src_last > BZ_GROUP_MAX_LENGTH ? BZ_GROUP_MAX_LENGTH : src_last;strm->avail_in = src_tmp;strm->next_in = (char *)(src + src_ptr);dst_last = (*dst_len) - dst_ptr;dst_tmp = dst_last > BZ_GROUP_MAX_LENGTH ? BZ_GROUP_MAX_LENGTH : dst_last;if(dst_tmp <1){ BZ_DEBUG("dst space is not enough %s !\n",""); ret = -1; break;} strm->avail_out = dst_tmp;strm->next_out = (char *)(dst + dst_ptr); ret = BZ2_bzDecompress(strm);src_ptr = src_ptr + src_tmp - strm->avail_in;dst_ptr = dst_ptr + dst_tmp - strm->avail_out;BZ_DEBUG("decompress:ret[%d] src_tmp[%d] in[%d] src_ptr[%d] src_len[%d] dst_tmp[%d] out[%d] dst_ptr[%d] dst_len[%d]\n",ret,src_tmp,strm->avail_in,src_ptr,*src_len,dst_tmp,strm->avail_out,dst_ptr,*dst_len);//if(strm->avail_out >0) // break; } *dst_len = dst_ptr; BZ2_bzDecompressEnd(strm);//destroy bzcommoress if(ret == BZ_STREAM_END){ BZ_DEBUG("bz_decompress success %s !\n",""); ret = 0; }else{ BZ_DEBUG("bz_decompress failed %s !\n",""); ret = -1; } return ret;}#include <unistd.h>#define TEST_BUF_LEN100*1024int main(int argc ,char ** argv){ char file_path[256]; memset(file_path,0,256); int ch; opterr = 0; while((ch= getopt(argc,argv,"c:vVh"))!=-1){switch(ch){ case 'V': case 'v':{printf("test bzip v1.0\n");return 0; } case 'h':{printf("BZ_OK:[%d]\n",BZ_OK);printf("BZ_RUN_OK:[%d]\n",BZ_RUN_OK);printf("BZ_FLUSH_OK:[%d]\n",BZ_FLUSH_OK);printf("BZ_FINISH_OK:[%d]\n",BZ_FINISH_OK);printf("BZ_STREAM_END:[%d]\n",BZ_STREAM_END);printf("");return 0; } case 'c':{strncpy(file_path,optarg,255);break; }default:{printf("par error!\n");return 0 ; }} } char *buf1 = NULL; char *buf2 = NULL; char *buf3 = NULL; FILE *fp = NULL; fp = fopen(file_path,"rb"); fseek(fp,0,SEEK_END); long len = ftell(fp); printf("file[%s] len[%ld]\n",file_path,len); buf1 = (char *)malloc(len+1); buf2 = (char *)malloc(2*len+1); buf3 = (char *)malloc(2*len+1); memset(buf1,0,len+1); memset(buf2,0,2*len+1); memset(buf3,0,2*len+1); fseek(fp,0,SEEK_SET); int ret = fread(buf1,1,len,fp); printf("fread len[%ld]\n",ret); fclose(fp); int src_len,dst_len; src_len = len; dst_len = 2*len; ret = my_bz_compress(buf1,&src_len,buf2,&dst_len); printf("\nmy_bz_compress ret[%d] src_len[%d] dst_len[%d] len[%d]\n",ret,src_len,dst_len,len); if(ret != 0) return 0; int write_len = dst_len; src_len = dst_len; dst_len = 2*len; ret = my_bz_decompress(buf2,&src_len,buf3,&dst_len); printf("\nmy_bz_decompress ret[%d] src_len[%d] dst_len[%d] len[%d]\n",ret,src_len,dst_len,len); //ret = strcmp(buf1,buf3); //printf("strcmp ret[%d] len_buf1[%d] len_buf3[%d]\n",ret,len,dst_len); printf("\n===================================\n"); if(len != dst_len ){printf("compress-decompress len is not equal - failed!\n");return 0; } for(ret = 0;ret<len;ret++){if(buf1[ret] != buf3[ret]){ printf("strcmp failed! index[%d]\n",ret); return 0;} } printf("compress-decompress success!\n"); printf("pre_len[%d] next_len[%d] rate[%f] multiple[%f]\n",len,src_len,(double)src_len/len,(double)len/src_len); /* write the result to file */ fp = fopen("./out.bzip2","wb"); fwrite(buf2,1,write_len,fp); fclose(fp); return ret;}
0 0
- bzip数据压缩 C调用
- 数据压缩
- 数据压缩
- 数据压缩
- 数据压缩
- 数据压缩
- 数据压缩
- 数据压缩
- 数据压缩
- 数据压缩
- 数据压缩
- 数据压缩解析及C语言实现介绍
- linux tar gzip bzip
- gzip,tar,bzip,xz
- linux 命令 之 tar gzip zip bzip
- linux下面tar gzip zip bzip使用指南
- Linux基础——bzip压缩工具
- 【数据压缩】调用VFW库对无压缩avi的解封装
- Maven最佳实践:划分模块
- 深入理解Linux网络技术内幕——Notification内核通知表链
- c++实现程序自删除
- Android之Adapter用法总结
- hibernate jpa 注解 @Temporal(TemporalType.DATE) 格式化时间日期,页面直接得到格式化类型的值
- bzip数据压缩 C调用
- 上课笔记--台大政治学基础之选举行为
- C++ 获取汉字拼音首字母(支持GBK)QT版
- pyqt添加资源
- Android 第三方类库的一些建议性用法
- PHP 定时执行操作
- RTLabel常见的设置标签
- lua io哈书说明
- 设备唯一标示符