Beispiel #1
0
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());
}
Beispiel #2
0
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());
}