请教压缩和解压缩算法 LZMA.dll 测试程序

bao20080513shengbin 2009-09-02 08:43:49
我现在想使用 LZMA 压缩算法中的 LZMA.dll ,但总是调试不出来 LzmaCompress zmaUncompress 这两个函数不知参数如何给。请大家帮忙看看
这是压缩部分 我感觉可能主要是参数问题
	HINSTANCE hInst;
hInst = LoadLibrary("LZMA.dll");

typedef int (_stdcall *FuncCompress)(unsigned char *dest,
size_t *destLen,
const unsigned char *src,
size_t srcLen,
unsigned char *outProps,
size_t *outPropsSize, /* *outPropsSize must be = 5 */
int level, /* 0 <= level <= 9, default = 5 */
unsigned dictSize, /* default = (1 << 24) */
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 */
);

FuncCompress MyCompress = (FuncCompress)GetProcAddress(hInst, "LzmaCompress");

if(!MyCompress)
{
MessageBox("获取compress函数地址失败! ");
return;
}

unsigned int dlen = sizeof(m_ucdecompress); //m_ucdecompress 压缩后的数据存储区
size_t *destLen = &dlen; //认为压缩后的数据长度

const unsigned char srcarr[] = "12ac56";//hello hello hello world hello hello hello world
const unsigned char *src = srcarr;
size_t srcLen = sizeof(srcarr);
m_unCompressLen = srcLen; //要压缩的数据长度,在解压时做为解压后的数据长度


unsigned char outpprops[1024]; //这个参数不知什么作用,不知给什么值合适
unsigned char *outProps = outpprops;

unsigned int PropsSize = 5; //这个参数也不知什么作用,其值要求必须是 5
size_t *outPropsSize = &PropsSize; // outPropsSize must be = 5

int level = 5; // 0 <= level <= 9, default = 5
unsigned dictSize = 1 << 24; // default = (1 << 24) 16777216 1000000000000000000000000
int lc = 3; // 0 <= lc <= 8, default = 3
int lp = 0; // 0 <= lp <= 4, default = 0
int pb = 2; // 0 <= pb <= 4, default = 2
int fb = 32; // 5 <= fb <= 273, default = 32
int numThreads = 2; // 1 or 2, default = 2


int status = MyCompress(m_ucdecompress,
destLen,
src,
srcLen,
outProps,
outPropsSize,
level,
dictSize,
lc,
lp,
pb,
fb,
numThreads );

//解压部分不能解压正确 下面是解压部分

HINSTANCE hInst;
hInst = LoadLibrary("LZMA.dll");

typedef int (_stdcall *FuncUnCompress)(unsigned char *dest,
size_t *destLen,
const unsigned char *src,
size_t *srcLen,
const unsigned char *props,
size_t propsSize
);

FuncUnCompress MyUnCompress = (FuncUnCompress)GetProcAddress(hInst, "LzmaUncompress");

if(!MyUnCompress)
{
MessageBox("获取uncompress函数地址失败! ");
return;
}


unsigned char destarr[1024];
unsigned int dlen = m_unCompressLen; // 解压缩后的数据长度 即原文长度
unsigned char *dest = destarr;
size_t *destLen = &dlen;

size_t usrcLen = m_unDeCompressLen; //要解压数据长度
size_t *srcLen = &usrcLen;


const unsigned char outProps[12] = "12345678910"; //这个参数不知何用 也不知给值多少
size_t outPropsSize = 5; // outPropsSize must be = 5

int status = MyUnCompress(dest,
destLen,
m_ucdecompress, //解压数据
srcLen,
outProps,
outPropsSize
);


...全文
480 点赞 收藏 11
写回复
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
haiphong_0 2010-09-10
int main(int argc, char* argv[])
{
unsigned char szPackebuf[1024];
unsigned char m_pData[90];
unsigned char m_DecData[1024];
unsigned char outProps[5];
size_t outPropsSize = 5;
memset(m_pData,0x12,100);
size_t dstLen = 1024;
int nZRet = LzmaCompress(szPackebuf, &dstLen, m_pData ,100,
outProps,// 这个给解压用的
&outPropsSize,
5,
1 << 24,
3,
0,
2,
32,
1
);
printf("LzmaCompress ret=[%d] NewLen[%d]!\n",nZRet,dstLen);
SizeT destNewLen = 1024;// 这个值如果不改源码 就会得不到正确结果,
// 在不改源码情况下如果 大于上面压缩的长度100 就返回 SZ_ERROR_INPUT_EOF 错
// 如果小于100 返回SZ_OK 但长度是不变的不会是100
unsigned char* destNewSrc = m_DecData;
nZRet = LzmaUncompress(destNewSrc, &destNewLen, szPackebuf, &dstLen,
outProps, 5);
printf("LzmaUncompress ret=[%d] NewLen[%d]!\n",nZRet,destNewLen);
getchar();
return 0;
}
LzmaDec_DecodeToDic 里修改了下

SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT inSize = *srcLen;
(*srcLen) = 0;
LzmaDec_WriteRem(p, dicLimit);

*status = LZMA_STATUS_NOT_SPECIFIED;

while (p->remainLen != kMatchSpecLenStart)
{
int checkEndMarkNow;

if (p->needFlush != 0)
{
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++;
if (p->tempBufSize < RC_INIT_SIZE)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
if (p->tempBuf[0] != 0)
return SZ_ERROR_DATA;

LzmaDec_InitRc(p, p->tempBuf);
p->tempBufSize = 0;
}

checkEndMarkNow = 0;
if (p->dicPos >= dicLimit)
{
if (p->remainLen == 0 && p->code == 0)
{
*status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
return SZ_OK;
}
if (finishMode == LZMA_FINISH_ANY)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_ERROR_OUTPUT_EOF;
}
if (p->remainLen != 0)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_ERROR_DATA;
}
checkEndMarkNow = 1;
}

if (p->needInitState)
LzmaDec_InitStateReal(p);

if (p->tempBufSize == 0)
{
SizeT processed;
const Byte *bufLimit;
if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
{
int dummyRes = LzmaDec_TryDummy(p, src, inSize);
if (dummyRes == DUMMY_ERROR)
{
memcpy(p->tempBuf, src, inSize);
p->tempBufSize = (unsigned)inSize;
(*srcLen) += inSize;
if(inSize)
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_ERROR_DATA;
}
bufLimit = src;
}
else
bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
p->buf = src;
if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
return SZ_ERROR_DATA;
processed = (SizeT)(p->buf - src);
(*srcLen) += processed;
src += processed;
inSize -= processed;
}
else
{
unsigned rem = p->tempBufSize, lookAhead = 0;
while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
p->tempBuf[rem++] = src[lookAhead++];
p->tempBufSize = rem;
if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
{
int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
if (dummyRes == DUMMY_ERROR)
{
(*srcLen) += lookAhead;
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_ERROR_DATA;
}
}
p->buf = p->tempBuf;
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
return SZ_ERROR_DATA;
lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
(*srcLen) += lookAhead;
src += lookAhead;
inSize -= lookAhead;
p->tempBufSize = 0;
}
}
if (p->code == 0)
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
}
回复
haiphong_0 2010-09-10
LzmaUncompress 这个源代码有问题,当你的解压目标空间长度 不等于 未压缩的长度就回报7或6,当目标空间长度过小居然也是0返回。 修改主要是在LzmaDec_DecodeToDic 里改下就可以。outProps 这个参数是你压缩时候的这个,outProps 在你压缩后返回的
回复
ys19011 2010-06-02
outProps数组中的值,前后不一致,导致解压不成功。
压缩的时候,LZMA会生成几个值,在解压缩的时候也需要使用到这几个来判别在词典中Jump的距离。
回复
jzp12 2009-09-30
代码比较乱,MS参数用错了:
m_ucdecompress初始值多少?开辟了多大的空间?
把代码发给我,我帮你看看。邮箱是:jingzhongping@163.com
回复
问题没有解决,换用了 fengrx 的算法。有知道的朋友们说一下呀。
回复
我试过了还是不行,解压不正确,这两个参数到底给什么值合适呢。

压缩数据长度 7
压缩后的数据长度 12
压缩数据: 12ac56
压缩后数据: 寛?)Q暋€

解压数据长度: 12
解压后的数据长度 7
解压数据: 寛?)Q暋€
解压后的数据: 12^=Ul

结果就是前两个个字符是正确的,后面都不正确,解压中的outProps参数 对这个结果也有影响。有谁知道看看呀。
回复
danxuezx 2009-09-02
直接调用系统的压缩解压不可以吗……
回复
nihaoyiyou019 2009-09-02
没用过这个动态库,但是看了你贴上来的程序,我觉得应该是你的outProps参数的问题,初步觉得这个参数应该是解压的时候一个编码/解码过程中要用到的编码/解码的中间状态的缓冲区。再有就是你的解压数据的存储缓冲区应该在解压之前将m_ucdecompress用memset进行置零操作
回复
fengrx 2009-09-02
没有使用过这个库,但使用过zlib库,很好用,压缩解压缩很方便。
压缩:
compress2(dstbuffer, &streamlen, buffer, buffersize, Z_BEST_COMPRESSION);
看下定义:
ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen,
int level));
当然也可以使用compress,定义如下:
ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));

解压缩uncompress,看定义:
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
回复
大家帮忙看看呀。
回复
Conry 2009-09-02
这样看不出什么来,最好打包代码传上来
回复
发动态
发帖子
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
社区公告
暂无公告