自行封装的LZMA接口库,用于unity,包括win平台的dll,安卓的so动态库和iOS的.a静态库
LZMA是目前压缩比最高的压缩算法,官方提供了多种语言的版本,unity中可以直接使用C#版,但是实际证明纯C版的压缩速度是C#版的四五倍。
封装工程介绍
LZMA(Xcode)是一个iOS的静态库工程,直接在xcode中run一下即可得到对应的.a静态库,顶层接口封装在LZMALib.c中;
LZMA(AndroidStudio)是一个支持runtime C++的安卓工程,顶层接口封装在LZMALib.c中,build一下对应的.so库会装进apk包中,解压apk可以得到里面的LZMA so库(apk路径:..\app\build\outputs\apk\debug)。
7zSDK(VS)是LZMA官方完整的SDK和源码工程,编译LZMA动态库的工程是其中的LZMALib工程,路径为:..\C\Util\LzmaLib,顶层接口封装在LZMALib.c中。
封装接口预览
最顶层封装了两个接口,用于压缩和解压,压缩参数默认封在了接口内,如果要更改需要在相应的封装工程中修改并编译出新库:
- // 自定义接口
- MY_STDAPI DefaultLzmaCompress(const unsigned char *src,const size_t srcLen,unsigned char *dest,size_t *destLen);
- MY_STDAPI DefaultLzmaUncompress(const unsigned char *src,size_t *srcLen,size_t *destLen);
- //MY_STDAPI LZMAAdd(int x); // 测试用
- /* LzmaLib.c -- LZMA library wrapper #include "Alloc.h" #include "LzmaDec.h" #include "LzmaEnc.h" #include "LzmaLib.h" unsigned char outProps[LZMA_PROPS_SIZE]; size_t outPropsSize = LZMA_PROPS_SIZE; MY_STDAPI LzmaCompress(unsigned char *dest,size_t *destLen,const unsigned char *src,size_t srcLen,unsigned char *outProps,size_t *outPropsSize,int level,/* 0 <= level <= 9,default = 5 */
- unsigned dictSize,/* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
- int lc,/* 0 <= lc <= 8,default = 3 */
- int lp,/* 0 <= lp <= 4,default = 0 */
- int pb,/* 0 <= pb <= 4,default = 2 */
- int fb,/* 5 <= fb <= 273,default = 32 */
- int numThreads /* 1 or 2,default = 2 */
- )
- {
- CLzmaEncProps props;
- LzmaEncProps_Init(&props);
- props.level = level;
- props.dictSize = dictSize;
- props.lc = lc;
- props.lp = lp;
- props.pb = pb;
- props.fb = fb;
- props.numThreads = numThreads;
-
- return LzmaEncode(dest,destLen,src,srcLen,&props,outProps,outPropsSize,0,NULL,&g_Alloc,&g_Alloc);
- }
-
- MY_STDAPI LzmaUncompress(unsigned char *dest,const unsigned char *src,const unsigned char *props,size_t propsSize)
- {
- ELzmaStatus status;
- return LzmaDecode(dest,props,(unsigned)propsSize,LZMA_FINISH_ANY,&status,&g_Alloc);
- }
-
-
- // 自定义接口
- MY_STDAPI DefaultLzmaCompress(const unsigned char *src,size_t *destLen)
- {
- int level = 5;
- unsigned dictSize = 1 << 23;
- int lc = 3;
- int lp = 0;
- int pb = 2;
- int fb = 128;
- int numThreads = 1;
- return LzmaCompress(dest,&outPropsSize,level,dictSize,lc,lp,pb,fb,numThreads);
- }
-
- MY_STDAPI DefaultLzmaUncompress(const unsigned char *src,size_t *destLen)
- {
- return LzmaUncompress(dest,outPropsSize);
- }
-
- MY_STDAPI LZMAAdd(int x)
- {
- return x + 1;
- }
使用方法示例
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using System.Runtime.InteropServices;
- using UnityEngine.UI;
- public class Compress : MonoBehavIoUr {
- public Text text = null;
- [DllImport("LZMA")]
- public static extern int LZMAAdd(int x);
- [DllImport("LZMA")]
- public static extern int DefaultLzmaCompress(byte[] src,int srcLen,byte[] dest,ref int destLen);
- [DllImport("LZMA")]
- public static extern int DefaultLzmaUncompress(byte[] src,ref int srcLen,ref int destLen);
- // Use this for initialization
- void Start () {
- // 压缩
- string input = "122333444455555666666777777788888888999999999";
- byte[] src = System.Text.Encoding.Default.GetBytes(input);
- byte[] dest = new byte[src.Length];
- int srcLen = src.Length;
- int destLen = dest.Length;
- int compressRes = DefaultLzmaCompress(src,dest,ref destLen); // 压缩成功compressRes会返回0,destLen的值会变成压缩后的数据长度
-
- // 解压
- byte[] unsrc = new byte[destLen];
- for (int i = 0; i < destLen; i++) {
- unsrc[i] = dest[i]; // 将压缩后得到的dest数据复制到解压的src数据缓冲中
- }
- srcLen = destLen;
- destLen = src.Length;
- byte[] undest = new byte[destLen];
- int uncompressRes = DefaultLzmaUncompress(unsrc,ref srcLen,undest,ref destLen);
- string output = System.Text.Encoding.Default.GetString(undest); // 解压成功output应该和input值相同
- }
-
- // Update is called once per frame
- void Update () {
-
- }
- }