コード例 #1
0
ファイル: Rar20Crypto.cpp プロジェクト: Bernieboy/nds4ios
void CData::CryptBlock(Byte *buf, bool encrypt)
{
  Byte inBuf[16];
  UInt32 A, B, C, D, T, TA, TB;

  A = GetUi32(buf +  0) ^ Keys[0];
  B = GetUi32(buf +  4) ^ Keys[1];
  C = GetUi32(buf +  8) ^ Keys[2];
  D = GetUi32(buf + 12) ^ Keys[3];

  if (!encrypt)
    memcpy(inBuf, buf, sizeof(inBuf));
  
  for (int i = 0; i < kNumRounds; i++)
  {
    UInt32 key = Keys[(encrypt ? i : (kNumRounds - 1 - i)) & 3];
    T = ((C + rotlFixed(D, 11)) ^ key);
    TA = A ^ SubstLong(T);
    T = ((D ^ rotlFixed(C, 17)) + key);
    TB = B ^ SubstLong(T);
    A = C;
    B = D;
    C = TA;
    D = TB;
  }

  SetUi32(buf +  0, C ^ Keys[0]);
  SetUi32(buf +  4, D ^ Keys[1]);
  SetUi32(buf +  8, A ^ Keys[2]);
  SetUi32(buf + 12, B ^ Keys[3]);

  UpdateKeys(encrypt ? buf : inBuf);
}
コード例 #2
0
ファイル: Aes.c プロジェクト: Ando02/wubiuefi
UInt32 MY_FAST_CALL AesCbcDecode(CAesCbc *cbc, Byte *data, UInt32 size)
{
  UInt32 i;
  UInt32 in[4], out[4];
  if (size == 0)
    return 0;
  if (size < AES_BLOCK_SIZE)
    return AES_BLOCK_SIZE;
  size -= AES_BLOCK_SIZE;
  for (i = 0; i <= size; i += AES_BLOCK_SIZE, data += AES_BLOCK_SIZE)
  {
    in[0] = GetUi32(data);
    in[1] = GetUi32(data + 4);
    in[2] = GetUi32(data + 8);
    in[3] = GetUi32(data + 12);
    
    AesDecode32(in, out, cbc->aes.rkey, cbc->aes.numRounds2);
    
    SetUi32(data,      cbc->prev[0] ^ out[0]);
    SetUi32(data + 4,  cbc->prev[1] ^ out[1]);
    SetUi32(data + 8,  cbc->prev[2] ^ out[2]);
    SetUi32(data + 12, cbc->prev[3] ^ out[3]);
    
    cbc->prev[0] = in[0];
    cbc->prev[1] = in[1];
    cbc->prev[2] = in[2];
    cbc->prev[3] = in[3];
  }
  return i;
}
コード例 #3
0
ファイル: Aes.cpp プロジェクト: daoluong/zpack-library
SizeT AesCbc_Decode(CAesCbc *p, Byte *data, SizeT size)
{
  if (size == 0)
    return 0;
  if (size < AES_BLOCK_SIZE)
    return AES_BLOCK_SIZE;
  size -= AES_BLOCK_SIZE;

  SizeT i;
  UInt32 in[4], out[4];

  for (i = 0; i <= size; i += AES_BLOCK_SIZE, data += AES_BLOCK_SIZE)
  {
    in[0] = GetUi32(data);
    in[1] = GetUi32(data + 4);
    in[2] = GetUi32(data + 8);
    in[3] = GetUi32(data + 12);
    
    AesDecode32(out, in, p->aes.rkey, p->aes.numRounds2);
    
    SetUi32(data,      p->prev[0] ^ out[0]);
    SetUi32(data + 4,  p->prev[1] ^ out[1]);
    SetUi32(data + 8,  p->prev[2] ^ out[2]);
    SetUi32(data + 12, p->prev[3] ^ out[3]);
    
    p->prev[0] = in[0];
    p->prev[1] = in[1];
    p->prev[2] = in[2];
    p->prev[3] = in[3];
  }

  return i;
}
コード例 #4
0
ファイル: Bra.c プロジェクト: ArchangelSDY/Qt7z
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{
  Byte *p;
  const Byte *lim;
  size &= ~(size_t)3;
  ip += 4;
  p = data;
  lim = data + size;

  if (encoding)

  for (;;)
  {
    for (;;)
    {
      if (p >= lim)
        return p - data;
      p += 4;
      if (p[-1] == 0xEB)
        break;
    }
    {
      UInt32 v = GetUi32(p - 4);
      v <<= 2;
        v += ip + (UInt32)(p - data);
      v >>= 2;
      v &= 0x00FFFFFF;
      v |= 0xEB000000;
      SetUi32(p - 4, v);
    }
  }

  for (;;)
  {
    for (;;)
    {
      if (p >= lim)
        return p - data;
      p += 4;
      if (p[-1] == 0xEB)
        break;
    }
    {
      UInt32 v = GetUi32(p - 4);
      v <<= 2;
        v -= ip + (UInt32)(p - data);
      v >>= 2;
      v &= 0x00FFFFFF;
      v |= 0xEB000000;
      SetUi32(p - 4, v);
    }
  }
}
コード例 #5
0
ファイル: ZipStrong.cpp プロジェクト: mcmilk/7-Zip-zstd
HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize)
{
  Byte temp[4];
  RINOK(ReadStream_FALSE(inStream, temp, 2));
  _ivSize = GetUi16(temp);
  if (_ivSize == 0)
  {
    memset(_iv, 0, 16);
    SetUi32(_iv + 0, crc);
    SetUi64(_iv + 4, unpackSize);
    _ivSize = 12;
  }
  else if (_ivSize == 16)
  {
    RINOK(ReadStream_FALSE(inStream, _iv, _ivSize));
  }
  else
    return E_NOTIMPL;
  RINOK(ReadStream_FALSE(inStream, temp, 4));
  _remSize = GetUi32(temp);
  // const UInt32 kAlign = 16;
  if (_remSize < 16 || _remSize > (1 << 18))
    return E_NOTIMPL;
  if (_remSize > _bufAligned.Size())
  {
    _bufAligned.AllocAtLeast(_remSize);
    if (!(Byte *)_bufAligned)
      return E_OUTOFMEMORY;
  }
  return ReadStream_FALSE(inStream, _bufAligned, _remSize);
}
コード例 #6
0
ファイル: XzEnc.c プロジェクト: Ander-son/libretro-mame
SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
{
	Byte header[XZ_BLOCK_HEADER_SIZE_MAX];

	unsigned pos = 1;
	int numFilters, i;
	header[pos++] = p->flags;

	if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize);
	if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize);
	numFilters = XzBlock_GetNumFilters(p);
	for (i = 0; i < numFilters; i++)
	{
	const CXzFilter *f = &p->filters[i];
	pos += Xz_WriteVarInt(header + pos, f->id);
	pos += Xz_WriteVarInt(header + pos, f->propsSize);
	memcpy(header + pos, f->props, f->propsSize);
	pos += f->propsSize;
	}
	while((pos & 3) != 0)
	header[pos++] = 0;
	header[0] = (Byte)(pos >> 2);
	SetUi32(header + pos, CrcCalc(header, pos));
	return WriteBytes(s, header, pos + 4);
}
コード例 #7
0
ファイル: ZipStrong.cpp プロジェクト: farruggia/7zip
HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize)
{
  Byte temp[4];
  RINOK(ReadStream_FALSE(inStream, temp, 2));
  _ivSize = GetUi16(temp);
  if (_ivSize == 0)
  {
    memset(_iv, 0, 16);
    SetUi32(_iv + 0, crc);
    SetUi64(_iv + 4, unpackSize);
    _ivSize = 12;
  }
  else if (_ivSize == 16)
  {
    RINOK(ReadStream_FALSE(inStream, _iv, _ivSize));
  }
  else
    return E_NOTIMPL;
  RINOK(ReadStream_FALSE(inStream, temp, 4));
  _remSize = GetUi32(temp);
  const UInt32 kAlign = 16;
  if (_remSize < 16 || _remSize > (1 << 18))
    return E_NOTIMPL;
  if (_remSize + kAlign > _buf.Size())
  {
    _buf.Alloc(_remSize + kAlign);
    _bufAligned = (Byte *)((ptrdiff_t)((Byte *)_buf + kAlign - 1) & ~(ptrdiff_t)(kAlign - 1));
  }
  return ReadStream_FALSE(inStream, _bufAligned, _remSize);
}
コード例 #8
0
ファイル: Xz.c プロジェクト: wodeaei/VC-Project
int XzCheck_Final(CXzCheck *p, Byte *digest)
{
  switch (p->mode)
  {
    case XZ_CHECK_CRC32:
      SetUi32(digest, CRC_GET_DIGEST(p->crc));
      break;
    case XZ_CHECK_CRC64:
    {
      int i;
      UInt64 v = CRC64_GET_DIGEST(p->crc64);
      for (i = 0; i < 8; i++, v >>= 8)
        digest[i] = (Byte)(v & 0xFF);
      break;
    }
    case XZ_CHECK_SHA256:
      if (!(p->sha))
          return 0;

      cl_finish_hash(p->sha, digest);
      break;
    default:
      return 0;
  }
  return 1;
}
コード例 #9
0
ファイル: PpmdEncoder.cpp プロジェクト: Alexander-r/physfs
STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
{
  const UInt32 kPropSize = 5;
  Byte props[kPropSize];
  props[0] = (Byte)_props.Order;
  SetUi32(props + 1, _props.MemSize);
  return WriteStream(outStream, props, kPropSize);
}
コード例 #10
0
ファイル: Aes.c プロジェクト: Dabil/puNES
void MY_FAST_CALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks)
{
  for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE)
  {
    p[0] ^= GetUi32(data);
    p[1] ^= GetUi32(data + 4);
    p[2] ^= GetUi32(data + 8);
    p[3] ^= GetUi32(data + 12);
    
    Aes_Encode(p + 4, p, p);
    
    SetUi32(data,      p[0]);
    SetUi32(data + 4,  p[1]);
    SetUi32(data + 8,  p[2]);
    SetUi32(data + 12, p[3]);
  }
}
コード例 #11
0
ファイル: Aes.c プロジェクト: Dabil/puNES
void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks)
{
  for (; numBlocks != 0; numBlocks--)
  {
    UInt32 temp[4];
    Byte buf[16];
    int i;
    if (++p[0] == 0)
      p[1]++;
    Aes_Encode(p + 4, temp, p);
    SetUi32(buf,      temp[0]);
    SetUi32(buf + 4,  temp[1]);
    SetUi32(buf + 8,  temp[2]);
    SetUi32(buf + 12, temp[3]);
    for (i = 0; i < 16; i++)
      *data++ ^= buf[i];
  }
}
コード例 #12
0
ファイル: XzEnc.c プロジェクト: Ander-son/libretro-mame
SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
{
	Byte buf[32];
	UInt64 globalPos;
	{
	UInt32 crc = CRC_INIT_VAL;
	unsigned pos = 1 + Xz_WriteVarInt(buf + 1, p->numBlocks);
	size_t i;

	globalPos = pos;
	buf[0] = 0;
	RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
	for (i = 0; i < p->numBlocks; i++)
	{
		const CXzBlockSizes *block = &p->blocks[i];
		pos = Xz_WriteVarInt(buf, block->totalSize);
		pos += Xz_WriteVarInt(buf + pos, block->unpackSize);
		globalPos += pos;
		RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
	}
	pos = ((unsigned)globalPos & 3);
	if (pos != 0)
	{
		buf[0] = buf[1] = buf[2] = 0;
		RINOK(WriteBytesAndCrc(s, buf, 4 - pos, &crc));
		globalPos += 4 - pos;
	}
	{
		SetUi32(buf, CRC_GET_DIGEST(crc));
		RINOK(WriteBytes(s, buf, 4));
		globalPos += 4;
	}
	}

	{
	UInt32 indexSize = (UInt32)((globalPos >> 2) - 1);
	SetUi32(buf + 4, indexSize);
	buf[8] = (Byte)(p->flags >> 8);
	buf[9] = (Byte)(p->flags & 0xFF);
	SetUi32(buf, CrcCalc(buf + 4, 6));
	memcpy(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE);
	return WriteBytes(s, buf, 12);
	}
}
コード例 #13
0
ファイル: XzEnc.c プロジェクト: Ander-son/libretro-mame
SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
{
	UInt32 crc;
	Byte header[XZ_STREAM_HEADER_SIZE];
	memcpy(header, XZ_SIG, XZ_SIG_SIZE);
	header[XZ_SIG_SIZE] = (Byte)(f >> 8);
	header[XZ_SIG_SIZE + 1] = (Byte)(f & 0xFF);
	crc = CrcCalc(header + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE);
	SetUi32(header + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE, crc);
	return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE);
}
コード例 #14
0
ファイル: Rar5Aes.cpp プロジェクト: ismail/7-zip
UInt32 CDecoder::Hmac_Convert_Crc32(UInt32 crc) const
{
  NSha256::CHmac ctx;
  ctx.SetKey(_hashKey, NSha256::kDigestSize);
  Byte v[4];
  SetUi32(v, crc);
  ctx.Update(v, 4);
  Byte h[NSha256::kDigestSize];
  ctx.Final(h);
  crc = 0;
  for (unsigned i = 0; i < NSha256::kDigestSize; i++)
    crc ^= (UInt32)h[i] << ((i & 3) * 8);
  return crc;
};
コード例 #15
0
ファイル: Aes.c プロジェクト: Dabil/puNES
void MY_FAST_CALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks)
{
  UInt32 in[4], out[4];
  for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE)
  {
    in[0] = GetUi32(data);
    in[1] = GetUi32(data + 4);
    in[2] = GetUi32(data + 8);
    in[3] = GetUi32(data + 12);

    Aes_Decode(p + 4, out, in);

    SetUi32(data,      p[0] ^ out[0]);
    SetUi32(data + 4,  p[1] ^ out[1]);
    SetUi32(data + 8,  p[2] ^ out[2]);
    SetUi32(data + 12, p[3] ^ out[3]);
    
    p[0] = in[0];
    p[1] = in[1];
    p[2] = in[2];
    p[3] = in[3];
  }
}
コード例 #16
0
ファイル: Aes.c プロジェクト: Ando02/wubiuefi
UInt32 MY_FAST_CALL AesCbcEncode(CAesCbc *cbc, Byte *data, UInt32 size)
{
  UInt32 i;
  if (size == 0)
    return 0;
  if (size < AES_BLOCK_SIZE)
    return AES_BLOCK_SIZE;
  size -= AES_BLOCK_SIZE;
  for (i = 0; i <= size; i += AES_BLOCK_SIZE, data += AES_BLOCK_SIZE)
  {
    cbc->prev[0] ^= GetUi32(data);
    cbc->prev[1] ^= GetUi32(data + 4);
    cbc->prev[2] ^= GetUi32(data + 8);
    cbc->prev[3] ^= GetUi32(data + 12);
    
    AesEncode32(cbc->prev, cbc->prev, cbc->aes.rkey, cbc->aes.numRounds2);
    
    SetUi32(data,      cbc->prev[0]);
    SetUi32(data + 4,  cbc->prev[1]);
    SetUi32(data + 8,  cbc->prev[2]);
    SetUi32(data + 12, cbc->prev[3]);
  }
  return i;
}
コード例 #17
0
ファイル: Aes.cpp プロジェクト: daoluong/zpack-library
SizeT AesCbc_Encode(CAesCbc *p, Byte *data, SizeT size)
{
  SizeT i;
  if (size == 0)
    return 0;
  if (size < AES_BLOCK_SIZE)
    return AES_BLOCK_SIZE;
  size -= AES_BLOCK_SIZE;
  for (i = 0; i <= size; i += AES_BLOCK_SIZE, data += AES_BLOCK_SIZE)
  {
    p->prev[0] ^= GetUi32(data);
    p->prev[1] ^= GetUi32(data + 4);
    p->prev[2] ^= GetUi32(data + 8);
    p->prev[3] ^= GetUi32(data + 12);
    
    AesEncode32(p->prev, p->prev, p->aes.rkey, p->aes.numRounds2);
    
    SetUi32(data,      p->prev[0]);
    SetUi32(data + 4,  p->prev[1]);
    SetUi32(data + 8,  p->prev[2]);
    SetUi32(data + 12, p->prev[3]);
  }
  return i;
}
コード例 #18
0
ファイル: XzEnc.c プロジェクト: Ander-son/libretro-mame
static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
	ISeqOutStream *outStream, ISeqInStream *inStream,
	const CXzProps *props, ICompressProgress *progress)
{
	xz->flags = (Byte)props->checkId;

	RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, props->lzma2Props));
	RINOK(Xz_WriteHeader(xz->flags, outStream));

	{
	CSeqCheckInStream checkInStream;
	CSeqSizeOutStream seqSizeOutStream;
	CXzBlock block;
	int filterIndex = 0;
	CXzFilter *filter = NULL;
	const CXzFilterProps *fp = props->filterProps;

	XzBlock_ClearFlags(&block);
	XzBlock_SetNumFilters(&block, 1 + (fp ? 1 : 0));

	if (fp)
	{
		filter = &block.filters[filterIndex++];
		filter->id = fp->id;
		filter->propsSize = 0;
		if (fp->id == XZ_ID_Delta)
		{
		filter->props[0] = (Byte)(fp->delta - 1);
		filter->propsSize = 1;
		}
		else if (fp->ipDefined)
		{
		SetUi32(filter->props, fp->ip);
		filter->propsSize = 4;
		}
	}

	{
		CXzFilter *f = &block.filters[filterIndex++];
		f->id = XZ_ID_LZMA2;
		f->propsSize = 1;
		f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2);
	}

	seqSizeOutStream.p.Write = MyWrite;
	seqSizeOutStream.realStream = outStream;
	seqSizeOutStream.processed = 0;

	RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.p));

	checkInStream.p.Read = SeqCheckInStream_Read;
	checkInStream.realStream = inStream;
	SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags));

	if (fp)
	{
		#ifdef USE_SUBBLOCK
		if (fp->id == XZ_ID_Subblock)
		{
		lzmaf->sb.inStream = &checkInStream.p;
		RINOK(SbEncInStream_Init(&lzmaf->sb));
		}
		else
		#endif
		{
		lzmaf->filter.realStream = &checkInStream.p;
		RINOK(SeqInFilter_Init(&lzmaf->filter, filter));
		}
	}

	{
		UInt64 packPos = seqSizeOutStream.processed;
		SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
		fp ?
		#ifdef USE_SUBBLOCK
		(fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
		#endif
		&lzmaf->filter.p:
		&checkInStream.p,
		progress);
		RINOK(res);
		block.unpackSize = checkInStream.processed;
		block.packSize = seqSizeOutStream.processed - packPos;
	}

	{
		unsigned padSize = 0;
		Byte buf[128];
		while((((unsigned)block.packSize + padSize) & 3) != 0)
		buf[padSize++] = 0;
		SeqCheckInStream_GetDigest(&checkInStream, buf + padSize);
		RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags)));
		RINOK(Xz_AddIndexRecord(xz, block.unpackSize, seqSizeOutStream.processed - padSize, &g_Alloc));
	}
	}
	return Xz_WriteFooter(xz, outStream);
}
コード例 #19
0
STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest)
{
  UInt32 val = CRC_GET_DIGEST(_crc);
  SetUi32(digest, val);
}
コード例 #20
0
ファイル: Bcj2.c プロジェクト: Kaldaien/TSF
SRes Bcj2Dec_Decode(CBcj2Dec *p)
{
  if (p->range <= 5)
  {
    p->state = BCJ2_DEC_STATE_OK;
    for (; p->range != 5; p->range++)
    {
      if (p->range == 1 && p->code != 0)
        return SZ_ERROR_DATA;
      
      if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
      {
        p->state = BCJ2_STREAM_RC;
        return SZ_OK;
      }

      p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
    }
    
    if (p->code == 0xFFFFFFFF)
      return SZ_ERROR_DATA;
    
    p->range = 0xFFFFFFFF;
  }
  else if (p->state >= BCJ2_DEC_STATE_ORIG_0)
  {
    while (p->state <= BCJ2_DEC_STATE_ORIG_3)
    {
      Byte *dest = p->dest;
      if (dest == p->destLim)
        return SZ_OK;
      *dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0];
      p->dest = dest + 1;
    }
  }

  /*
  if (BCJ2_IS_32BIT_STREAM(p->state))
  {
    const Byte *cur = p->bufs[p->state];
    if (cur == p->lims[p->state])
      return SZ_OK;
    p->bufs[p->state] = cur + 4;
    
    {
      UInt32 val;
      Byte *dest;
      SizeT rem;
      
      p->ip += 4;
      val = GetBe32(cur) - p->ip;
      dest = p->dest;
      rem = p->destLim - dest;
      if (rem < 4)
      {
        SizeT i;
        SetUi32(p->temp, val);
        for (i = 0; i < rem; i++)
          dest[i] = p->temp[i];
        p->dest = dest + rem;
        p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
        return SZ_OK;
      }
      SetUi32(dest, val);
      p->temp[3] = (Byte)(val >> 24);
      p->dest = dest + 4;
      p->state = BCJ2_DEC_STATE_OK;
    }
  }
  */

  for (;;)
  {
    if (BCJ2_IS_32BIT_STREAM(p->state))
      p->state = BCJ2_DEC_STATE_OK;
    else
    {
      if (p->range < kTopValue)
      {
        if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
        {
          p->state = BCJ2_STREAM_RC;
          return SZ_OK;
        }
        p->range <<= 8;
        p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
      }

      {
        const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
        const Byte *srcLim;
        Byte *dest;
        SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
        
        if (num == 0)
        {
          p->state = BCJ2_STREAM_MAIN;
          return SZ_OK;
        }
        
        dest = p->dest;
        if (num > (SizeT)(p->destLim - dest))
        {
          num = p->destLim - dest;
          if (num == 0)
          {
            p->state = BCJ2_DEC_STATE_ORIG;
            return SZ_OK;
          }
        }
       
        srcLim = src + num;

        if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
          *dest = src[0];
        else for (;;)
        {
          Byte b = *src;
          *dest = b;
          if (b != 0x0F)
          {
            if ((b & 0xFE) == 0xE8)
              break;
            dest++;
            if (++src != srcLim)
              continue;
            break;
          }
          dest++;
          if (++src == srcLim)
            break;
          if ((*src & 0xF0) != 0x80)
            continue;
          *dest = *src;
          break;
        }
        
        num = src - p->bufs[BCJ2_STREAM_MAIN];
        
        if (src == srcLim)
        {
          p->temp[3] = src[-1];
          p->bufs[BCJ2_STREAM_MAIN] = src;
          p->ip += (UInt32)num;
          p->dest += num;
          p->state =
            p->bufs[BCJ2_STREAM_MAIN] ==
            p->lims[BCJ2_STREAM_MAIN] ?
              (unsigned)BCJ2_STREAM_MAIN :
              (unsigned)BCJ2_DEC_STATE_ORIG;
          return SZ_OK;
        }
        
        {
          UInt32 bound, ttt;
          CProb *prob;
          Byte b = src[0];
          Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
          
          p->temp[3] = b;
          p->bufs[BCJ2_STREAM_MAIN] = src + 1;
          num++;
          p->ip += (UInt32)num;
          p->dest += num;
          
          prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
          
          _IF_BIT_0
          {
            _UPDATE_0
            continue;
          }
          _UPDATE_1
            
        }
      }
    }

    {
      UInt32 val;
      unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
      const Byte *cur = p->bufs[cj];
      Byte *dest;
      SizeT rem;
      
      if (cur == p->lims[cj])
      {
        p->state = cj;
        break;
      }
      
      val = GetBe32(cur);
      p->bufs[cj] = cur + 4;

      p->ip += 4;
      val -= p->ip;
      dest = p->dest;
      rem = p->destLim - dest;
      
      if (rem < 4)
      {
        SizeT i;
        SetUi32(p->temp, val);
        for (i = 0; i < rem; i++)
          dest[i] = p->temp[i];
        p->dest = dest + rem;
        p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
        break;
      }
      
      SetUi32(dest, val);
      p->temp[3] = (Byte)(val >> 24);
      p->dest = dest + 4;
    }
  }

  if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])
  {
    p->range <<= 8;
    p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
  }

  return SZ_OK;
}