bool LZMADecodeFile ( const char *fromFile, const char *toFile, CProgressInfo7Zip *progress ) { CMyComPtr<ISequentialInStream> inStream; CInFileStream *inStreamSpec = new CInFileStream; inStream = inStreamSpec; if ( !inStreamSpec->Open ( GetSystemString(fromFile) ) ) return false; CMyComPtr<ISequentialOutStream> outStream; COutFileStream *outStreamSpec = new COutFileStream; outStream = outStreamSpec; if ( !outStreamSpec->Create ( GetSystemString(toFile), true ) ) return false; NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder; CMyComPtr<ICompressCoder> decoder = decoderSpec; const UInt32 kPropertiesSize = 5; Byte properties[kPropertiesSize]; UInt32 processedSize; if ( ReadStream (inStream, properties, kPropertiesSize, &processedSize) != S_OK ) return false; if ( processedSize != kPropertiesSize ) return false; if ( decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK ) return false; UInt64 fileSize = 0; for (int i = 0; i < 8; i++) { Byte b; if ( inStream->Read(&b, 1, &processedSize) != S_OK ) return false; if ( processedSize != 1 ) return false; fileSize |= ((UInt64)b) << (8 * i); } if ( progress ) { progress->Init(); progress->ApprovedStart = 1 << 21; progress->SetMax ( fileSize ); } if ( decoder->Code(inStream, outStream, 0, &fileSize, progress) != S_OK ) // decoder error return false; return true; }
unsigned char *LZMADecodeData ( unsigned char *fromData, long fromSize, long &toSize, CProgressInfo7Zip *progress ) { CMyComPtr<ISequentialInStream> inStream; CInDataStream *inStreamSpec = new CInDataStream; inStream = inStreamSpec; inStreamSpec->LoadData ( fromData, fromSize ); NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder; CMyComPtr<ICompressCoder> decoder = decoderSpec; const UInt32 kPropertiesSize = 5; Byte properties[kPropertiesSize]; UInt32 processedSize; if ( ReadStream (inStream, properties, kPropertiesSize, &processedSize) != S_OK ) return NULL; if ( processedSize != kPropertiesSize ) return NULL; if ( decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK ) return NULL; UInt64 fileSize = 0; for (int i = 0; i < 8; i++) { Byte b; if ( inStream->Read(&b, 1, &processedSize) != S_OK ) return NULL; if ( processedSize != 1 ) return NULL; fileSize |= ((UInt64)b) << (8 * i); } CMyComPtr<ISequentialOutStream> outStream; COutDataStream *outStreamSpec = new COutDataStream; outStream = outStreamSpec; outStreamSpec->Create ( fileSize ); // CProgressInfo *progressInfoSpec = new CProgressInfo; // CMyComPtr<ICompressProgressInfo> progressInfo = progress; if ( progress ) { progress->Init(); progress->ApprovedStart = 1 << 21; progress->SetMax ( fileSize ); } if ( decoder->Code(inStream, outStream, 0, &fileSize, progress) != S_OK ) // decoder error return NULL; toSize = outStreamSpec->GetCurrentSize (); return outStreamSpec->GetData (); }
HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream, ICompressProgressInfo *progress) { if (header.FilterID > 1) return E_NOTIMPL; RINOK(_lzmaDecoderSpec->SetDecoderProperties2(header.LzmaProps, 5)); bool filteredMode = (header.FilterID == 1); if (filteredMode) { RINOK(_filterCoder->SetOutStream(outStream)); outStream = _bcjStream; RINOK(_filterCoder->SetOutStreamSize(NULL)); } const UInt64 *Size = header.HasSize() ? &header.Size : NULL; HRESULT res = _lzmaDecoderSpec->CodeResume(outStream, Size, progress); if (filteredMode) { { HRESULT res2 = _filterCoder->OutStreamFinish(); if (res == S_OK) res = res2; } HRESULT res2 = _filterCoder->ReleaseOutStream(); if (res == S_OK) res = res2; } RINOK(res); if (header.HasSize()) if (_lzmaDecoderSpec->GetOutputProcessedSize() != header.Size) return S_FALSE; return S_OK; }