用于Unity(windows\iOS\安卓)的纯C版LZMA压缩算法库(dll .so和.a)

自行封装的LZMA接口库,用于unity,包括win平台的dll,安卓的so动态库和iOS的.a静态库

LZMA是目前压缩比最高的压缩算法,官方提供了多种语言的版本,unity中可以直接使用C#版,但是实际证明纯C版的压缩速度是C#版的四五倍。

封装工程介绍

  1. LZMA(Xcode)是一个iOS的静态库工程,直接在xcode中run一下即可得到对应的.a静态库,顶层接口封装在LZMALib.c中;

  2. LZMA(AndroidStudio)是一个支持runtime C++的安卓工程,顶层接口封装在LZMALib.c中,build一下对应的.so库会装进apk包中,解压apk可以得到里面的LZMA so库(apk路径:..\app\build\outputs\apk\debug)。

  3. 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, unsigned char *dest, 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, size_t *destLen, const unsigned char *src, size_t *srcLen,
  const unsigned char *props, size_t propsSize)
{
  ELzmaStatus status;
  return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc);
}


// 自定义接口
MY_STDAPI DefaultLzmaCompress(const unsigned char *src, const size_t srcLen, unsigned char *dest, 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, destLen, src, srcLen, outProps, &outPropsSize, level, dictSize, lc, lp, pb, fb, numThreads);
}

MY_STDAPI DefaultLzmaUncompress(const unsigned char *src, size_t *srcLen, unsigned char *dest, size_t *destLen)
{
    return LzmaUncompress(dest, destLen, src, srcLen, outProps, 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, byte[] dest, 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, srcLen, 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 () {

    }
}

工程地址(包括编译好的各平台的库,各平台的库工程和使用示例)

https://github.com/jiangxh1992/XHLZMA

猜你喜欢

转载自blog.csdn.net/cordova/article/details/80712810