예제 #1
0
HRESULT CDecoder::ReadCoderProperties(ISequentialInStream *anInStream)
{
  UINT32 aNumPosStateBits;
  UINT32 aLiteralPosStateBits;
  UINT32 aLiteralContextBits;
  UINT32 aDictionarySize;

   UINT32 aProcessesedSize;

  BYTE aByte;
  RETURN_IF_NOT_S_OK(anInStream->Read(&aByte, sizeof(aByte), &aProcessesedSize));
  if (aProcessesedSize != sizeof(aByte))
    return E_INVALIDARG;

  aLiteralContextBits = aByte % 9;
  BYTE aRemainder = aByte / 9;
  aLiteralPosStateBits = aRemainder % 5;
  aNumPosStateBits = aRemainder / 5;

  UINT8 uint_buffer[UINT_SIZE];
  RETURN_IF_NOT_S_OK(anInStream->Read(uint_buffer, sizeof(aDictionarySize), &aProcessesedSize));
  aDictionarySize = charp_to_uint(uint_buffer);

  if (aProcessesedSize != sizeof(aDictionarySize))
    return E_INVALIDARG;

  RETURN_IF_NOT_S_OK(SetDictionarySize(aDictionarySize));
  RETURN_IF_NOT_S_OK(SetLiteralProperties(aLiteralPosStateBits, aLiteralContextBits));
  RETURN_IF_NOT_S_OK(SetPosBitsProperties(aNumPosStateBits));

  return S_OK;
}
예제 #2
0
HRESULT CIn::ReadBlock()
{
  if(m_StreamEndWasReached)
    return S_OK;
  while(true)
  {
    INT aSize = (m_BufferBase + m_BlockSize) - (m_Buffer + m_StreamPos);
    if(aSize == 0)
      return S_OK;
    INT aNumReadBytes;
    RETURN_IF_NOT_S_OK(m_Stream->Read(m_Buffer + m_StreamPos,
        aSize, &aNumReadBytes));
    if(aNumReadBytes == 0)
    {
      m_PosLimit = m_StreamPos;
      const BYTE *aPointerToPostion = m_Buffer + m_PosLimit;
      if(aPointerToPostion > m_PointerToLastSafePosition)
        m_PosLimit = m_PointerToLastSafePosition - m_Buffer;
      m_StreamEndWasReached = true;
      return S_OK;
    }
    m_StreamPos += aNumReadBytes;
    if(m_StreamPos >= m_Pos + m_KeepSizeAfter)
    {
      m_PosLimit = m_StreamPos - m_KeepSizeAfter;
      return S_OK;
    }
  }
}
예제 #3
0
HRESULT LzmaDecoderReadCoderProperties(LzmaDecoder *lzmaDecoder)
{
    UINT32 aNumPosStateBits;
    UINT32 aLiteralPosStateBits;
    UINT32 aLiteralContextBits;
    UINT32 aDictionarySize;
    BYTE   aRemainder;
    UINT32 aProcessesedSize;

    BYTE aByte;
    RETURN_IF_NOT_S_OK(InStreamRead(&aByte,
                                    sizeof(aByte),
                                    &aProcessesedSize));

    if (aProcessesedSize != sizeof(aByte))
        return E_INVALIDARG;

    aLiteralContextBits   = aByte % 9;
    aRemainder            = aByte / 9;
    aLiteralPosStateBits  = aRemainder % 5;
    aNumPosStateBits      = aRemainder / 5;

    RETURN_IF_NOT_S_OK(InStreamRead(&aDictionarySize,
                                    sizeof(aDictionarySize),
                                    &aProcessesedSize));

    if (aProcessesedSize != sizeof(aDictionarySize))
        return E_INVALIDARG;

    RETURN_IF_NOT_S_OK( LzmaDecoderSetDictionarySize(lzmaDecoder,
                        aDictionarySize) );
    RETURN_IF_NOT_S_OK( LzmaDecoderSetLiteralProperties(lzmaDecoder,
                        aLiteralPosStateBits,
                        aLiteralContextBits) );
    RETURN_IF_NOT_S_OK( LzmaDecoderSetPosBitsProperties(lzmaDecoder,
                        aNumPosStateBits) );

    return S_OK;
}
예제 #4
0
HRESULT CCoder::CodeReal(ISequentialInStream *anInStream, ISequentialOutStream *anOutStream, const UINT64 *anInSize)
{
  if (!m_Created)
  {
    RETURN_IF_NOT_S_OK(Create());
    m_Created = true;
  }

  UINT64 aNowPos = 0;
  m_FinderPos = 0;

  RETURN_IF_NOT_S_OK(m_MatchFinder.Init(anInStream));
  m_OutStream.Init(anOutStream);
  m_ReverseOutStream.Init(&m_OutStream);

  InitStructures();

  while(true)
  {
    int aCurrentPassIndex = 0;
    bool aNoMoreBytes;
    while (true)
    {
      while(true)
      {
        aNoMoreBytes = (m_AdditionalOffset == 0 && m_MatchFinder.GetNumAvailableBytes() == 0);
  
        if (((m_CurrentBlockUncompressedSize >= kBlockUncompressedSizeThreshold || 
                 m_ValueIndex >= kValueBlockSize) && 
              (m_OptimumEndIndex == m_OptimumCurrentIndex)) 
            || aNoMoreBytes)
          break;
        UINT32 aPos;
        UINT32 aLen = GetOptimal(aPos);
        if (aLen >= kMatchMinLen)
        {
          UINT32 aNewLen = aLen - kMatchMinLen;
          m_Values[m_ValueIndex].Flag = kFlagLenPos;
          m_Values[m_ValueIndex].Len = BYTE(aNewLen);
          UINT32 aLenSlot = g_LenSlots[aNewLen];
          m_MainCoder.AddSymbol(kMatchNumber + aLenSlot);
          m_Values[m_ValueIndex].Pos = UINT16(aPos);
          UINT32 aPosSlot = GetPosSlot(aPos);
          m_DistCoder.AddSymbol(aPosSlot);
        }
        else if (aLen == 1)  
        {
          BYTE aByte = m_MatchFinder.GetIndexByte(0 - m_AdditionalOffset);
          aLen = 1;
          m_MainCoder.AddSymbol(aByte);
          m_Values[m_ValueIndex].Flag = kFlagImm;
          m_Values[m_ValueIndex].Imm = aByte;
        }
        else
          throw E_INTERNAL_ERROR;
        m_ValueIndex++;
        m_AdditionalOffset -= aLen;
        aNowPos += aLen;
        m_CurrentBlockUncompressedSize += aLen;
        
      }
      aCurrentPassIndex++;
      bool aWriteMode = (aCurrentPassIndex == m_NumPasses);
      WriteBlockData(aWriteMode, aNoMoreBytes);
      if (aWriteMode)
        break;
      aNowPos = m_BlockStartPostion;
      m_AdditionalOffset = UINT32(m_FinderPos - m_BlockStartPostion);
      m_CurrentBlockUncompressedSize = 0;
    }
    m_BlockStartPostion += m_CurrentBlockUncompressedSize;
    m_CurrentBlockUncompressedSize = 0;
    if (aNoMoreBytes)
      break;
  }
  return  m_OutStream.Flush();
}