HRESULT CDecoder::DecodeFile(ICompressProgressInfo *progress) { Progress = progress; #ifndef _7ZIP_ST RINOK(Create()); for (UInt32 t = 0; t < NumThreads; t++) { CState &s = m_States[t]; if (!s.Alloc()) return E_OUTOFMEMORY; if (MtMode) { RINOK(s.StreamWasFinishedEvent.Reset()); RINOK(s.WaitingWasStartedEvent.Reset()); RINOK(s.CanWriteEvent.Reset()); } } #else if (!m_States[0].Alloc()) return E_OUTOFMEMORY; #endif IsBz = false; /* if (Base.BitDecoder.ExtraBitsWereRead()) return E_FAIL; */ Byte s[4]; int i; for (i = 0; i < 4; i++) s[i] = ReadByte(); if (Base.BitDecoder.ExtraBitsWereRead()) return S_FALSE; if (s[0] != kArSig0 || s[1] != kArSig1 || s[2] != kArSig2 || s[3] <= kArSig3 || s[3] > kArSig3 + kBlockSizeMultMax) return S_FALSE; UInt32 dicSize = (UInt32)(s[3] - kArSig3) * kBlockSizeStep; CombinedCrc.Init(); #ifndef _7ZIP_ST if (MtMode) { NextBlockIndex = 0; StreamWasFinished1 = StreamWasFinished2 = false; CloseThreads = false; CanStartWaitingEvent.Reset(); m_States[0].CanWriteEvent.Set(); BlockSizeMax = dicSize; Result1 = Result2 = S_OK; CanProcessEvent.Set(); UInt32 t; for (t = 0; t < NumThreads; t++) m_States[t].StreamWasFinishedEvent.Lock(); CanProcessEvent.Reset(); CanStartWaitingEvent.Set(); for (t = 0; t < NumThreads; t++) m_States[t].WaitingWasStartedEvent.Lock(); CanStartWaitingEvent.Reset(); RINOK(Result2); RINOK(Result1); } else #endif { CState &state = m_States[0]; for (;;) { RINOK(SetRatioProgress(Base.BitDecoder.GetProcessedSize())); UInt32 crc; RINOK(ReadSignature(crc)); if (BzWasFinished) return S_OK; CBlockProps props; props.randMode = true; RINOK(Base.ReadBlock(state.Counters, dicSize, &props)); DecodeBlock1(state.Counters, props.blockSize); if (DecodeBlock(props, state.Counters + 256, m_OutStream) != crc) { CrcError = true; return S_FALSE; } } } return SetRatioProgress(Base.BitDecoder.GetProcessedSize()); }
HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress) { Progress = progress; #ifndef _7ZIP_ST RINOK(Create()); for (UInt32 t = 0; t < NumThreads; t++) { CState &s = m_States[t]; if (!s.Alloc()) return E_OUTOFMEMORY; if (MtMode) { RINOK(s.StreamWasFinishedEvent.Reset()); RINOK(s.WaitingWasStartedEvent.Reset()); RINOK(s.CanWriteEvent.Reset()); } } #else if (!m_States[0].Alloc()) return E_OUTOFMEMORY; #endif isBZ = false; Byte s[6]; int i; for (i = 0; i < 4; i++) s[i] = ReadByte(); if (s[0] != kArSig0 || s[1] != kArSig1 || s[2] != kArSig2 || s[3] <= kArSig3 || s[3] > kArSig3 + kBlockSizeMultMax) return S_OK; isBZ = true; UInt32 dicSize = (UInt32)(s[3] - kArSig3) * kBlockSizeStep; CombinedCrc.Init(); #ifndef _7ZIP_ST if (MtMode) { NextBlockIndex = 0; StreamWasFinished1 = StreamWasFinished2 = false; CloseThreads = false; CanStartWaitingEvent.Reset(); m_States[0].CanWriteEvent.Set(); BlockSizeMax = dicSize; Result1 = Result2 = S_OK; CanProcessEvent.Set(); UInt32 t; for (t = 0; t < NumThreads; t++) m_States[t].StreamWasFinishedEvent.Lock(); CanProcessEvent.Reset(); CanStartWaitingEvent.Set(); for (t = 0; t < NumThreads; t++) m_States[t].WaitingWasStartedEvent.Lock(); CanStartWaitingEvent.Reset(); RINOK(Result2); RINOK(Result1); } else #endif { CState &state = m_States[0]; for (;;) { RINOK(SetRatioProgress(m_InStream.GetProcessedSize())); bool wasFinished; UInt32 crc; RINOK(ReadSignatures(wasFinished, crc)); if (wasFinished) return S_OK; UInt32 blockSize, origPtr; bool randMode; RINOK(ReadBlock(&m_InStream, state.Counters, dicSize, m_Selectors, m_HuffmanDecoders, &blockSize, &origPtr, &randMode)); DecodeBlock1(state.Counters, blockSize); if ((randMode ? DecodeBlock2Rand(state.Counters + 256, blockSize, origPtr, m_OutStream) : DecodeBlock2(state.Counters + 256, blockSize, origPtr, m_OutStream)) != crc) return S_FALSE; } } return SetRatioProgress(m_InStream.GetProcessedSize()); }