7z压缩 lzma流式压缩、解压缩的实现 C语言
最近项目中遇到OTA固件升级,压缩由上位机实现,解压缩在boot启动时,读取固件内容后边解压边加载数据的方式启动。
前期预研了三种压缩方案,分别是lz4、zip、7z,代码仓库放在下面,三者各自的原理可自行百度了解。
- lz4
- zip
- 7z
一、lzma的使用
由于项目中要求对所升级的固件压缩比的最大化,因此选择了7z中的lzma算法,版本为1900
LzmaUtil.c文件中完整实现了针对一个流式文件的压缩以及解压缩。实验环境为Ubuntu20.04。
- 编译
修改Lzma文件夹下的makefile.gcc,将编译器修改为gcc。在当前目录下输入make -f makefile.gcc
编译生成lzma可执行文件
PROG = lzma
CXX = gcc
LIB =
RM = rm -f
CFLAGS = -c -O2 -Wall -D_7ZIP_ST
压缩
./lzma e *要压缩的文件* *目标文件*
第二个参数(e)不区分大小写./lzma e makefile.gcc makefile_compr
解压
./lzma d *要解压的文件* *目标文件*
同样,第二个参数不区分大小写./lzma d makefile_compr makefile_decompr
解压后可以对比makefile_decompr与原始文件makefile.gcc内容是否一致
二、lzma的深入理解
- lzma压缩文件的特征
Offset Size Description0 1 Special LZMA properties (lc,lp, pb in encoded form)1 4 Dictionary size (little endian)5 8 Uncompressed size (little endian). -1 means unknown size13 Compressed data
以二进制的方式打开一个用lzma压缩算法压缩后的文件,其文件格式为文件头(13bytes)+ 压缩数据大小
,第一个字节是压缩文件的属性,后四个字节是字典的大小,再往后8个字节是未压缩数据的大小,它们都用小端(little endian)表示。
第一个字节属性,三个取值分别如下:
name Range Descriptionlc [0, 8] the number of "literal context" bitslp [0, 4] the number of "literal pos" bitspb [0, 4] the number of "pos" bits
- 代码详解
简单了解一下lzma压缩后的文件特征,现在回到LzmaUtil.c来看看具体的压缩与解压缩是怎样实现的。
main2()
CFileSeqInStream inStream;CFileOutStream outStream;
这两个结构体可以等同于文件IO中的fread和fwrite函数来理解,用来打开一个文件和向文件中写入内容。接下来是关于入参的一些判断很好理解。通过encodeMode
的真假来决定是压缩还是解压缩。
Encode()
压缩
static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize, char *rs)
*outStream:压缩后的数据
*inStream:源数据
fileSize:源数据的大小
lzma属性相关参数结构体:
typedef struct _CLzmaEncProps
{int level; /* 0 <= level <= 9 */UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version(1 << 12) <= dictSize <= (3 << 29) for 64-bit versiondefault = (1 << 24) */int lc; /* 0 <= lc <= 8, default = 3 */int lp; /* 0 <= lp <= 4, default = 0 */int pb; /* 0 <= pb <= 4, default = 2 */int algo; /* 0 - fast, 1 - normal, default = 1 */int fb; /* 5 <= fb <= 273, default = 32 */int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */int numHashBytes; /* 2, 3 or 4, default = 4 */UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */int numThreads; /* 1 or 2, default = 2 */UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1.Encoder uses this value to reduce dictionary size */
} CLzmaEncProps;
Encode
中设置了lzma的属性,并将其写入文件头然后压缩,这里贴出属性的初始化函数的实现(属性设置的太长了,大家可以自行查看,实现原理很简单)。
void LzmaEncProps_Init(CLzmaEncProps *p)
{p->level = 5;p->dictSize = p->mc = 0;p->reduceSize = (UInt64)(Int64)-1;p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;p->writeEndMark = 0;
}
压缩所用到的结构体CLzmaEnc
大小为123k,因此在单片机上实现压缩功能是很困难
Decode()
解压缩
static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream)
*outStream:解压后的数据
*inStream:源数据
该函数会首先解析压缩文件的文件头,然后申请解压所需的内存空间,接下来进入Decode2
开始解压缩。
static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 unpackSize)
Decode2
中解压缩的逻辑不难理解,可以根据自己的硬件资源调整两个缓存的大小,同时需要关注属性设置时字典的大小避免资源不足无法完成解压。
最后,可根据自己项目的实际情况更改文件读写的接口、lzma的属性等参数来实现压缩、解压缩。
7z压缩 lzma流式压缩、解压缩的实现 C语言相关推荐
- linux lzma命令,Ubuntu: 压缩与解压缩LZMA文件
什么是LZMA格式呢?当遇到LZMA格式的压缩文档时我们该怎么解压呢?如果我们想创建LZMA该用什么工具呢?就让我们快速浏览一下吧. 1.什么是LZMA格式 LZMA(Lempel-Ziv-Marko ...
- mac 命令行 解压7z文件_命令行压缩解压缩一 7z
命令行压缩解压缩一 7z 1) 简介 7z,全称7-Zip, 是一款开源软件.是目前公认的压缩比例最大的压缩解压缩软件. 主页:http://www.7-zip.org/ 中文主页:http://7z ...
- mac 命令行 解压7z文件_命令行压缩解压7z
命令行压缩解压一 7z 1) 简介7z,全称7-Zip, 是一款开源软件.是目前公认的压缩比例最大的压缩解压软件.主页:http://www.7-zip.org/中文主页:http://7z.spar ...
- java视频压缩 lz4_关于LZMA和LZ4压缩的疑惑解析
原标题:关于LZMA和LZ4压缩的疑惑解析 这是第112篇UWA技术知识分享的推送.今天我们继续为大家精选了若干和开发.优化相关的问题,建议阅读时间10分钟,认真读完必有收获. UWA QQ群:465 ...
- Unity加载优化-将基于LZMA的ab压缩方案修改为LZ4压缩的过程
# 观前提示 本文适合需要了解LZMA以及LZ4进行ab打包方案同学,以及会将一些资源管理的方案.如果恰好你也用xlua-framework,那就更适合你了. # 优化起因 最近新游戏在Iphone6 ...
- lzma和gzip压缩命令简介
一.lzma LZMA (Lempel-Ziv-Markov chain-Algorithm) 基于著名的LZ77压缩算法改进的压缩/解压工具,特点:高压缩率,高解压速度,低内存消耗,lzma命 ...
- 【步兵 工具篇】lzma算法,压缩字节流
[步兵 工具篇]lzma算法,压缩字节流 by EOS. 本来上周就打算写的,不过孩子连续高烧,住院了一个礼拜.一个礼拜没回家,还写什么博客. 虽然花了不少钱,好在孩子也恢复过来了,继续努力,挣钱养家 ...
- Java基础19:IO流—缓冲流、转换流、序列化、打印流、压缩流和解压流
IO流中的一些其他流:缓冲流.转换流.序列化.打印流.压缩流和解压流 1. 缓冲流 IO流除了一些基本的流,还有在此基础上发展出来的一些更强大的流.比如能够高效读写的缓冲流,能够转换编码的转换流,能够 ...
- Java基础(二):集合、IO流(Zip压缩输入/输出流等)、File文件类、反射、枚举
Java基础(一):编译和解释.数据类型.变量作用域.String常用方法.数组.面向对象.异常 Java基础(二):集合.IO流(Zip压缩输入/输出流等).File文件类.反射.枚举 Java异常 ...
最新文章
- Java 四种引用类型:强引用、软引用、弱引用、虚引用
- TensorFlow学习笔记(九)tf搭建神经网络基本流程
- Dubbo(七)之自动加载环境变量
- mysql命令行导入url_Mysql 导入数据,推荐Source命令,太快了
- layui时间日期控件使用
- 恒企自考_自考,一个月时间要怎么复习?
- fidde调试手机_实操:手机上用Fiddler调试页面(嘎)
- C++ 採集音频流(PCM裸流)实现录音功能
- ios app被自己从应用商店下架后可以再恢復上架吗
- “独裁者”Google:开发者别无他选!| 极客头条
- game with probability problem
- arcgis中python批处理_基于Python的ArcGIS空间数据格式批处理转换工具开发
- python函数式编程:apply, map, lambda和偏函数
- 关闭eslink:报错:Unexpected tab character no-tabs
- 今日芯声 | 马赛克一键变高清!神奇的AI“无损放大”工具
- 半导体芯片行业的运作模式(IDM/Fabless/Foundry模式)
- wpf给模板控件添加事件一
- Java查找算法-17-二分查找
- 深度学习在训练时对图片随机剪裁(random crop)
- 手机屏幕坐标获取方法