SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder, #ifdef _LZMA_IN_CB ISzInStream *inStream, CFileSize startPos, #else const Byte *inBuffer, #endif Byte *outBuffer, size_t outSize, ISzAlloc *allocMain, Byte *tempBuf[]) { UInt32 ci; size_t tempSizes[3] = { 0, 0, 0}; size_t tempSize3 = 0; Byte *tempBuf3 = 0; RINOK(CheckSupportedFolder(folder)); for (ci = 0; ci < folder->NumCoders; ci++) { CCoderInfo *coder = &folder->Coders[ci]; if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA) { UInt32 si = 0; CFileSize offset; CFileSize inSize; Byte *outBufCur = outBuffer; size_t outSizeCur = outSize; if (folder->NumCoders == 4) { UInt32 indices[] = { 3, 2, 0 }; CFileSize unpackSize = folder->UnPackSizes[ci]; si = indices[ci]; if (ci < 2) { Byte *temp; outSizeCur = (size_t)unpackSize; if (outSizeCur != unpackSize) return SZE_OUTOFMEMORY; temp = (Byte *)allocMain->Alloc(outSizeCur); if (temp == 0 && outSizeCur != 0) return SZE_OUTOFMEMORY; outBufCur = tempBuf[1 - ci] = temp; tempSizes[1 - ci] = outSizeCur; } else if (ci == 2) { if (unpackSize > outSize) return SZE_OUTOFMEMORY; tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); tempSize3 = outSizeCur = (size_t)unpackSize; } else return SZE_NOTIMPL; } offset = GetSum(packSizes, si); inSize = packSizes[si]; #ifdef _LZMA_IN_CB RINOK(inStream->Seek(inStream, startPos + offset)); #endif if (coder->MethodID == k_Copy) { if (inSize != outSizeCur) return SZE_DATA_ERROR; #ifdef _LZMA_IN_CB RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); #else memcpy(outBufCur, inBuffer + (size_t)offset, (size_t)inSize); #endif } else { SZ_RESULT res = SzDecodeLzma(coder, inSize, #ifdef _LZMA_IN_CB inStream, #else inBuffer + (size_t)offset, #endif outBufCur, outSizeCur, allocMain); RINOK(res) } } else if (coder->MethodID == k_BCJ)
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes, ILookInStream *inStream, UInt64 startPos, Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, Byte *tempBuf[]) { UInt32 ci; SizeT tempSizes[3] = { 0, 0, 0}; SizeT tempSize3 = 0; Byte *tempBuf3 = 0; RINOK(CheckSupportedFolder(folder)); for (ci = 0; ci < folder->NumCoders; ci++) { CSzCoderInfo *coder = &folder->Coders[ci]; if (IS_MAIN_METHOD((UInt32)coder->MethodID)) { UInt32 si = 0; UInt64 offset; UInt64 inSize; Byte *outBufCur = outBuffer; SizeT outSizeCur = outSize; if (folder->NumCoders == 4) { UInt32 indices[] = { 3, 2, 0 }; UInt64 unpackSize = folder->UnpackSizes[ci]; si = indices[ci]; if (ci < 2) { Byte *temp; outSizeCur = (SizeT)unpackSize; if (outSizeCur != unpackSize) return SZ_ERROR_MEM; temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); if (temp == 0 && outSizeCur != 0) return SZ_ERROR_MEM; outBufCur = tempBuf[1 - ci] = temp; tempSizes[1 - ci] = outSizeCur; } else if (ci == 2) { if (unpackSize > outSize) /* check it */ return SZ_ERROR_PARAM; tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); tempSize3 = outSizeCur = (SizeT)unpackSize; } else return SZ_ERROR_UNSUPPORTED; } offset = GetSum(packSizes, si); inSize = packSizes[si]; RINOK(LookInStream_SeekTo(inStream, startPos + offset)); if (coder->MethodID == k_Copy) { if (inSize != outSizeCur) /* check it */ return SZ_ERROR_DATA; RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); } else if (coder->MethodID == k_LZMA) { RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); } else if (coder->MethodID == k_LZMA2) { #ifdef _7ZIP_LZMA2_SUPPPORT RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); #else return SZ_ERROR_UNSUPPORTED; #endif } else { #ifdef _7ZIP_PPMD_SUPPPORT RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); #else return SZ_ERROR_UNSUPPORTED; #endif } } else if (coder->MethodID == k_BCJ2) { UInt64 offset = GetSum(packSizes, 1); UInt64 s3Size = packSizes[1]; SRes res; if (ci != 3) return SZ_ERROR_UNSUPPORTED; RINOK(LookInStream_SeekTo(inStream, startPos + offset)); tempSizes[2] = (SizeT)s3Size; if (tempSizes[2] != s3Size) return SZ_ERROR_MEM; tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); if (tempBuf[2] == 0 && tempSizes[2] != 0) return SZ_ERROR_MEM; res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); RINOK(res) res = Bcj2_Decode( tempBuf3, tempSize3, tempBuf[0], tempSizes[0], tempBuf[1], tempSizes[1], tempBuf[2], tempSizes[2], outBuffer, outSize); RINOK(res) } else { if (ci != 1)
SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder, /* #ifdef _LZMA_IN_CB */ ISzInStream *inStream, CFileSize startPos, /* #else const Byte *inBuffer, #endif */ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain, Byte *tempBuf[]) { UInt32 ci; size_t tempSizes[3] = { 0, 0, 0}; size_t tempSize3 = 0; Byte *tempBuf3 = 0; RINOK(CheckSupportedFolder(folder)); for (ci = 0; ci < folder->NumCoders; ci++) { CSzCoderInfo *coder = &folder->Coders[ci]; if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA || coder->MethodID == k_BZ2 || coder->MethodID == k_PPMD) { UInt32 si = 0; CFileSize offset; CFileSize inSize; Byte *outBufCur = outBuffer; size_t outSizeCur = outSize; if (folder->NumCoders == 4) { UInt32 indices[] = { 3, 2, 0 }; CFileSize unpackSize = folder->UnpackSizes[ci]; si = indices[ci]; if (ci < 2) { Byte *temp; outSizeCur = (size_t)unpackSize; if (outSizeCur != unpackSize) return SZ_ERROR_MEM; temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); if (temp == 0 && outSizeCur != 0) return SZ_ERROR_MEM; outBufCur = tempBuf[1 - ci] = temp; tempSizes[1 - ci] = outSizeCur; } else if (ci == 2) { if (unpackSize > outSize) // check it return SZ_ERROR_PARAM; // check it tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); tempSize3 = outSizeCur = (size_t)unpackSize; } else return SZ_ERROR_UNSUPPORTED; } offset = GetSum(packSizes, si); inSize = packSizes[si]; /* #ifdef _LZMA_IN_CB */ RINOK(inStream->Seek(inStream, startPos + offset, SZ_SEEK_SET)); /* #endif */ if (coder->MethodID == k_Copy) { if (inSize != outSizeCur) // check it return SZ_ERROR_DATA; /* #ifdef _LZMA_IN_CB */ RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); /* #else memcpy(outBufCur, inBuffer + (size_t)offset, (size_t)inSize); #endif */ } else if(coder->MethodID == k_PPMD) { SRes res = SZ_OK; struct PPMdProps pprops; pprops.maxorder = coder->Props.data[0]; pprops.suballocsize = (coder->Props.data[1]) | (coder->Props.data[2] << 8) | (coder->Props.data[3] << 16) | (coder->Props.data[4] << 24); PPMdSubAllocatorVariantH *alloc=CreateSubAllocatorVariantH(pprops.suballocsize); PPMdModelVariantH model; StartPPMdModelVariantH(&model,inStream,alloc,pprops.maxorder,TRUE); outSizeCur = 0; while(outSizeCur < outSize) { int byte=NextPPMdVariantHByte(&model); if(byte<0) break; *outBufCur = byte; outBufCur++; outSizeCur++; } FreeSubAllocatorVariantH(alloc); // RINOK(res) } else if(coder->MethodID == k_BZ2) { int bzres = BZ_OK; SRes res = SZ_OK; bz_stream bzstrm; bzstrm.bzalloc = BzAlloc; bzstrm.bzfree = BzFree; bzstrm.opaque = NULL; void *inBuffer = NULL; size_t size = inSize; bzres = BZ2_bzDecompressInit(&bzstrm,0,0); if(bzres == BZ_OK) res = SZ_OK; else res=SZ_ERROR_MEM; RINOK(res) bzstrm.next_out = outBufCur; bzstrm.avail_out = outSizeCur; do { size=inSize; RINOK(inStream->Read(inStream, (void **)&inBuffer, &size)); inSize -= size; bzstrm.next_in = (char *)(inBuffer); bzstrm.avail_in = size; do { bzres = BZ2_bzDecompress(&bzstrm); }while(bzstrm.avail_in>0 && bzres==BZ_OK); }while (bzres==BZ_OK); BZ2_bzDecompressEnd(&bzstrm); switch(bzres) { case BZ_CONFIG_ERROR: case BZ_PARAM_ERROR: res=SZ_ERROR_FAIL; break; case BZ_MEM_ERROR: case BZ_OUTBUFF_FULL: res=SZ_ERROR_MEM; break; case BZ_DATA_ERROR_MAGIC: case BZ_UNEXPECTED_EOF: res=SZ_ERROR_DATA; break; case BZ_DATA_ERROR: res=SZ_ERROR_CRC; break; case BZ_OK: res=SZ_OK; break; default: res=SZ_OK; break; } RINOK(res) } else {