大佬教程收集整理的这篇文章主要介绍了C LZMA SDK:LZMA2压缩文件的解压缩功能,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
这是压缩功能:
static void Compress2Inc(std::vector<unsigned char> &outBuf,const std::vector<unsigned char> &inBuf) { CLzma2EncHandle enc = Lzma2Enc_Create(&SzAllocForLzma,&SzAllocForLzma2); assert(enc); CLzma2EncProps props; Lzma2EncProps_Init(&props); props.lzmaProps.writeEndMark = 1; // 0 or 1 SRes res = Lzma2Enc_SetProps(enc,&props); assert(res == SZ_OK); unsigned propsSize = LZMA_PROPS_SIZE; outBuf.resize(propsSizE); res = Lzma2Enc_WriteProperties(enc); //cout << res; //assert(res == SZ_OK && propsSize == LZMA_PROPS_SIZE); Vectorinstream instream = { &Vectorinstream_Read,&inBuf,0 }; VectorOutStream outStream = { &VectorOutStream_Write,&outBuf }; res = Lzma2Enc_Encode(enc,(ISeqOutStream*)&outStream,(ISeqinstream*)&instream,0); assert(res == SZ_OK); Lzma2Enc_Destroy(enc); }
哪里:
static void *AllocForLzma2(void *,size_t sizE) { return BigAlloc(sizE); } static void FreeForLzma2(void *,void *address) { BigFree(address); } static ISzAlloc SzAllocForLzma2 = { AllocForLzma2,FreeForLzma2 }; static void *AllocForLzma(void *,size_t sizE) { return MyAlloc(sizE); } static void FreeForLzma(void *,void *address) { MyFree(address); } static ISzAlloc SzAllocForLzma = { AllocForLzma,FreeForLzma }; typedef struct { ISeqinstream Seqinstream; const std::vector<unsigned char> *Buf; unsigned BufPos; } Vectorinstream; SRes Vectorinstream_Read(void *p,void *buf,size_t *sizE) { Vectorinstream *ctx = (Vectorinstream*)p; *size = min(*size,ctx->Buf->size() - ctx->BufPos); if (*sizE) memcpy(buf,&(*ctx->Buf)[ctx->BufPos],*sizE); ctx->BufPos += *size; return SZ_OK; } typedef struct { ISeqOutStream SeqOutStream; std::vector<unsigned char> *Buf; } VectorOutStream; size_t VectorOutStream_Write(void *p,const void *buf,size_t sizE) { VectorOutStream *ctx = (VectorOutStream*)p; if (sizE) { unsigned oldSize = ctx->Buf->size(); ctx->Buf->resize(oldSize + sizE); memcpy(&(*ctx->Buf)[oldSize],buf,sizE); } return size; }
这是我到目前为止使用uncompression函数,但Lzma2Dec_DecodeToBuf函数返回错误代码1(SZ_ERROR_DATA),我在网上找不到任何关于此的内容.
static void Uncompress2Inc(std::vector<unsigned char> &outBuf,const std::vector<unsigned char> &inBuf) { CLzma2Dec dec; Lzma2Dec_Construct(&dec); SRes res = Lzma2Dec_Allocate(&dec,outBuf.size(),&SzAllocForLzma); assert(res == SZ_OK); Lzma2Dec_Init(&dec); outBuf.resize(UNCOMPRESSED_SIZE); unsigned outPos = 0,inPos = LZMA_PROPS_SIZE; ELzmaStatus status; const unsigned BUF_SIZE = 10240; while (outPos < outBuf.size()) { unsigned destLen = min(BUF_SIZE,outBuf.size() - outPos); unsigned srcLen = min(BUF_SIZE,inBuf.size() - inPos); unsigned srcLenOld = srcLen,destLenOld = destLen; res = Lzma2Dec_DecodeToBuf(&dec,&outBuf[outPos],&destLen,&inBuf[inPos],&srcLen,(outPos + destLen == outBuf.size()) ? LZMA_FINISH_END : LZMA_FINISH_ANY,&status); assert(res == SZ_OK); inPos += srcLen; outPos += destLen; if (status == LZMA_STATUS_FINISHED_WITH_MARK) break; } Lzma2Dec_Free(&dec,&SzAllocForLzma); outBuf.resize(outPos); }
我正在使用从here下载的Visual studio 2008和LZMA SDK.有人here有完全相同的问题,但我无法使用他的代码……
有没有人使用LZMA SDK成功解压缩LZMA2压缩文件?
请帮忙!
第一个错误是Lzma2Enc_WriteProperties不返回结果,而是返回属性字节,该字节必须用作Uncompress2Inc函数中Lzma2Dec_Allocate调用的第二个参数.因此,我们用属性字节替换幻数8,一切都按预期工作.
为了实现这一点,必须将5字节标题添加到将在解码功能中提取的编码数据中.这是一个可以在VS2008中运行的示例(不是最完美的代码,但它可以工作……我会稍后回来,当我有时间时,有一个更好的例子):
void Lzma2Benchmark::compressChunk(std::vector<unsigned char> &outBuf,const std::vector<unsigned char> &inBuf) { //! \todo This is a temporary workaround,size needs to be added to the m_uncompressedSize = inBuf.size(); std::cout << "Uncompressed size is: " << inBuf.size() << std::endl; DWORD tickCountBeforeCompression = GetTickCount(); CLzma2EncHandle enc = Lzma2Enc_Create(&m_szAllocForLzma,&m_szAllocForLzma2); assert(enc); CLzma2EncProps props; Lzma2EncProps_Init(&props); props.lzmaProps.writeEndMark = 1; // 0 or 1 props.lzmaProps.level = 9; props.lzmaProps.numThreads = 3; //props.num@R_103_10586@lThreads = 2; SRes res = Lzma2Enc_SetProps(enc,&props); assert(res == SZ_OK); // LZMA_PROPS_SIZE == 5 bytes unsigned propsSize = LZMA_PROPS_SIZE; outBuf.resize(propsSizE); // I think Lzma2Enc_WriteProperties returns the encoding properties in 1 Byte Byte properties = Lzma2Enc_WriteProperties(enc); //! \todo This is a temporary workaround m_propByte = properties; //! \todo Here m_propByte and m_uncompressedSize need to be added to outBuf's 5 byte header so simply add those 2 values to outBuf and start the encoding from there. BenchmarkUtils::Vectorinstream instream = { &BenchmarkUtils::Vectorinstream_Read,0 }; BenchmarkUtils::VectorOutStream outStream = { &BenchmarkUtils::VectorOutStream_Write,0); std::cout << "Compress time is: " << GetTickCount() - tickCountBeforeCompression << " milliseconds.\n"; assert(res == SZ_OK); Lzma2Enc_Destroy(enc); std::cout << "Compressed size is: " << outBuf.size() << std::endl; } void Lzma2Benchmark::unCompressChunk(std::vector<unsigned char> &outBuf,const std::vector<unsigned char> &inBuf) { DWORD tickCountBeforeUncompression = GetTickCount(); CLzma2Dec dec; Lzma2Dec_Construct(&dec); //! \todo Heere the property size and the uncompressed size need to be extracted from inBuf,which is the compressed data. // The second parameter is a temporary workaround. SRes res = Lzma2Dec_Allocate(&dec,m_propByte/*8*/,&m_szAllocForLzma); assert(res == SZ_OK); Lzma2Dec_Init(&dec); outBuf.resize(m_uncompressedSizE); unsigned outPos = 0,inPos = LZMA_PROPS_SIZE; ELzmaStatus status; const unsigned BUF_SIZE = 10240; while(outPos < outBuf.size()) { SizeT destLen = std::min(BUF_SIZE,outBuf.size() - outPos); SizeT srcLen = std::min(BUF_SIZE,inBuf.size() - inPos); SizeT srcLenOld = srcLen,&status); assert(res == SZ_OK); inPos += srcLen; outPos += destLen; if(status == LZMA_STATUS_FINISHED_WITH_MARK) { break; } } Lzma2Dec_Free(&dec,&m_szAllocForLzma); outBuf.resize(outPos); std::cout << "Uncompress time is: " << GetTickCount() - tickCountBeforeUncompression << " milliseconds.\n"; }
以上是大佬教程为你收集整理的C LZMA SDK:LZMA2压缩文件的解压缩功能全部内容,希望文章能够帮你解决C LZMA SDK:LZMA2压缩文件的解压缩功能所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。