.osr 文件格式解析(五) - 回放数据ReplayData

按照ppy的描述,ReplayData是经过Lzma压缩后的数据,压缩前也是一串逗号分隔的字符串。

##LZMA
####LZMA简介
以下摘自7-Zip官网

  • LZMA是7-Zip程序中7z格式的默认压缩算法。LZMA能提供给用户极高的压缩比及较快的压缩速度,它非常适合与应用程序集成。
  • 压缩速度在双核处理器上可以达到 2 MB/秒。
  • 解压缩速度在英特尔酷睿2 或 AMD 速龙 64 上可以达到 20-30 MB/秒。
  • 较小的解压缩内存需求:8-32 KB(依赖于字典大小)
  • 较小的解压缩代码:2-8 KB
  • LZMA 解码器仅使用整数运算,可以在任何主流的 32 位处理器(或在一定条件下的 16 或处理器)下运行。

####LZMA SDK
SDK下载LZMA SDK

LzmaLib编译
解压SDK后,在C\Util\LzmaLib下可以找到LzmaLib.dsw工程,VC6可以编译通过,生成LZMA.lib和LZMA.dll(如果没改输出路径,dll可能在C盘根目录)。然后把LzmaLib.h、Types.h、LZMA.lib和LZMA.dll复制到自己工程的根目录,准备工作就可以说是完成了。

LZMA的使用
LZMA就2个函数,一个用于压缩,一个用于解压:
MY_STDAPI LzmaCompress(…);
MY_STDAPI LzmaUncompress(…);
在要使用lzma的地方,加上如下代码,就可以了

	#include "LzmaLib.h"
	#pragma comment(lib,"LZMA.lib")

LzmaCompress

	std::string str="aaabbbcccdddeee";		//假定要压缩的字符串

	byte *src = (byte*)str.c_str();			//原始数据的字节数组
	size_t srcLen = str.length();			//原始数据的长度
	size_t destLen = str.length();			//输出数据的长度
	byte *dest = new byte[destLen];			//储存压缩结果的数组
	byte props[5] = { 0 };					//5字节props数据
	size_t propsSize = LZMA_PROPS_SIZE;		//props的长度,LZMA_PROPS_SIZE=5

	ZeroMemory(dest, destLen);

	//LzmaCompress压缩
    //LzmaCompress 有很多压缩参数,使用默认值则填-1,具体的参数说明见LzmaLib.h
	int res = LzmaCompress(dest, &destLen, src, srcLen, props, &propsSize, -1, 1 << 24 ,- 1, -1, -1, -1, -1);

	res返回值校验,返回0则表示压缩成功
	//switch (res)
	//{
	//case SZ_OK:					//0 - OK
	//case SZ_ERROR_DATA:			//1 - Data error
	//case SZ_ERROR_MEM:			//2 - Memory allocation arror
	//case SZ_ERROR_UNSUPPORTED:	//4 - Unsupported properties
	//case SZ_ERROR_INPUT_EOF:		//6 - it needs more bytes in input buffer(src)
	//	break;
	//}

压缩完毕后,dest里的就是压缩后的数据,destLen则是压缩后的长度,props里记录了压缩时所选的参数。

Lzma数据的保存
通常用以下结构来将压缩后结构保存到文件:

	struct LzmaData{
    	int lzmaLength;
        byte props[5];
        __int64 srcLen;
        byte *dest;
    }

经LzmaCompress压缩后,props、srcLen和dest,这三样数据都是需要保留的,在解压时要依靠着三部分的数据来完成解压。LzmaLength则是三部分数据加起来的长度。

LzmaUncompress

	LzmaData lzmaData;						//假如已经从文件中读取了要解压的数据

	byte *src = (byte*)data.dest;			//获取要解压的数据的字节数组
	size_t srcLen = data.lzmaLength-13;		//解压数据的长度(总数据长度减去props和srcLen的长得,即减13)
	size_t destLen = data.srcLen;			//压缩文件原来的长度(解压后的大小)
	byte *dest = new byte[destLen];			//用来保存解压后的数据
	byte *props = data.props;				//5字节props数据
	size_t propsSize = LZMA_PROPS_SIZE;		//props的长度,LZMA_PROPS_SIZE=5

	ZeroMemory(dest, destLen);

	int res = LzmaUncompress(dest, &destLen, src, &srcLen, props, propsSize);

解压后dest里即是原本的数据。

##ReplayData
运用Lzma算法我们就可以把第三章取出来的int ReplayDataLength和byte *ReplayData还原成原来的数据了。
其中:

  • LzmaData.lzmaLength对应int ReplayDataLength
  • LzmaData.props对应ReplayData[0-4]字节
  • LzmaData.srcLen对应ReplayData[5-12]字节
  • LzmaData.dest 对应ReplayData[13]以后剩下字节
    (其实,如果内存对齐是1的话,可以对整块数据进行内存拷贝的)

####真正的回放数据————osrReplayData
我们从ReplayData中得到了dest,这也是个文本,形如 w | x | y | z这样的以逗号分隔的数据。
所有使用和osrLifeBar一样的方式用split进行分割就好了,这里就不再赘述了。

osrReplayData定义如下:

    struct osrReplayData
    {
        __int64 delay;	//距离上个动作的时间(毫秒)
        float X;		//鼠标的X坐标(从0到512)
        float Y;		//鼠标的Y坐标(从0到384)
        int key;		//鼠标、键盘按键的组合 (M1 = 1, M2 = 2, K1 = 5, K2 = 10)
	};
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值