public unsafe byte[] Decompress(byte[] sourceBytes, int sourceIndex, int beforeGap, int afterGap) { if (sourceBytes == null) { AcedMCException.ThrowArgumentNullException("sourceBytes"); } else { int byteCount; fixed(byte *pSrcBytes = &sourceBytes[sourceIndex]) byteCount = *((int *)pSrcBytes); if (byteCount < 0) { byteCount = -byteCount; } var result = new byte[byteCount + beforeGap + afterGap]; if (byteCount != 0) { Decompress(sourceBytes, sourceIndex, result, beforeGap); } return(result); } return(null); }
private unsafe int GetBit() { uint hold = (uint)_hold; int bits = _bits; if (bits != 0) { bits--; } else if (_srcIndex < _break32Offset) { _srcIndex += 4; hold = *((uint *)_pSrcBytes); _pSrcBytes += 4; bits = 31; } else if (_srcIndex < _breakOffset) { _srcIndex++; hold = (uint)(*_pSrcBytes); _pSrcBytes++; bits = 7; } else { AcedMCException.ThrowReadBeyondTheEndException(); } _hold = (int)(hold >> 1); _bits = bits; return((int)(hold & 1)); }
private unsafe int GetNBits(int n) { int hold = _hold; int bits = _bits; while (bits < n) { if (bits < 8 && _srcIndex < _break32Offset) { _srcIndex += 3; hold |= (_pSrcBytes[0] | (_pSrcBytes[1] << 8) | (_pSrcBytes[2] << 16)) << bits; _pSrcBytes += 3; bits += 24; } else if (_srcIndex < _breakOffset) { _srcIndex++; hold |= (*_pSrcBytes) << bits; _pSrcBytes++; bits += 8; } else { AcedMCException.ThrowReadBeyondTheEndException(); } } _hold = hold >> n; _bits = bits - n; return(hold & ((1 << n) - 1)); }
private unsafe int GetCode(int *tree) { int code = 1; int hold = _hold; do { while (_bits != 0) { code = tree[code + (hold & 1)]; hold >>= 1; _bits--; if (code <= 0) { goto CodeFound; } } if (_srcIndex < _break32Offset) { _srcIndex += 4; hold = *((int *)_pSrcBytes); _pSrcBytes += 4; code = tree[code + (hold & 1)]; hold = (int)((uint)hold >> 1); _bits = 31; } else if (_srcIndex < _breakOffset) { _srcIndex++; hold = (int)(*_pSrcBytes); _pSrcBytes++; code = tree[code + (hold & 1)]; hold >>= 1; _bits = 7; } else { AcedMCException.ThrowReadBeyondTheEndException(); } } while (code > 0); CodeFound: _hold = hold; return(-code); }
public static unsafe int GetDecompressedLength(byte[] sourceBytes, int sourceIndex) { if (sourceBytes == null) { AcedMCException.ThrowArgumentNullException("sourceBytes"); } else fixed(byte *pSrcBytes = &sourceBytes[sourceIndex]) { var result = *((int *)pSrcBytes); if (result >= 0) { return(result); } return(-result); } return(0); }
private unsafe void ReadNonCompressedBlock() { _inCounter += GetNBits(8); var bits = _bits; while (_inCounter > 0 && _outCounter > 0) { var hold = _hold; if (bits < 8) { if (_srcIndex < _break32Offset) { _srcIndex += 3; hold |= (_pSrcBytes[0] | (_pSrcBytes[1] << 8) | (_pSrcBytes[2] << 16)) << bits; _pSrcBytes += 3; bits += 24; } else if (_srcIndex < _breakOffset) { _srcIndex++; hold |= (*_pSrcBytes) << bits; _pSrcBytes++; bits += 8; } else { AcedMCException.ThrowReadBeyondTheEndException(); } } _hold = hold >> 8; bits -= 8; *_pDstBytes = (byte)hold; _inCounter--; _outCounter--; _pDstBytes++; } _bits = bits; }
public unsafe int Decompress(byte[] sourceBytes, int sourceIndex, byte[] destinationBytes, int destinationIndex) { if (sourceBytes == null) { AcedMCException.ThrowArgumentNullException("sourceBytes"); } else { if (destinationBytes == null) return(GetDecompressedLength(sourceBytes, sourceIndex)); fixed(byte *pSrcBytes = &sourceBytes[sourceIndex], pDstBytes = &destinationBytes[destinationIndex]) { _pSrcBytes = pSrcBytes; _pDstBytes = pDstBytes; var byteCount = *((int *)_pSrcBytes); if (byteCount <= 0) { byteCount = -byteCount; if (destinationBytes.Length - destinationIndex < byteCount) { AcedMCException.ThrowNoPlaceToStoreDecompressedDataException(); } if (byteCount > 0) { Buffer.BlockCopy(sourceBytes, sourceIndex + 4, destinationBytes, destinationIndex, byteCount); } return(byteCount); } if (destinationBytes.Length - destinationIndex < byteCount) AcedMCException.ThrowNoPlaceToStoreDecompressedDataException(); fixed(int *pCharTree = &_charTree[0], pDistTree = &_distTree[0], pChLenTree = &_chLenTree[0], pBitLen = &_bitLen[0], pBitCount = &_bitCount[0], pNextCode = &_nextCode[0], pCharExBitLength = &AcedConsts.CharExBitLength[0], pCharExBitBase = &AcedConsts.CharExBitBase[0], pDistExBitLength = &AcedConsts.DistExBitLength[0], pDistExBitBase = &AcedConsts.DistExBitBase[0]) { _pCharTree = pCharTree; _pDistTree = pDistTree; _pChLenTree = pChLenTree; _pBitLen = pBitLen; _pBitCount = pBitCount; _pNextCode = pNextCode; _pCharExBitLength = pCharExBitLength; _pCharExBitBase = pCharExBitBase; _pDistExBitLength = pDistExBitLength; _pDistExBitBase = pDistExBitBase; _bits = 0; _hold = 0; _srcIndex = sourceIndex + 4; _pSrcBytes += 4; _breakOffset = sourceBytes.Length; _break32Offset = _breakOffset - 3; int length1, distance1; _outCounter = byteCount; while (_outCounter > 0) { ReadBlockHeader(); while (_inCounter > 0 && _outCounter > 0) { var c = GetCode(_pCharTree); _inCounter--; if (c < AcedConsts.FirstLengthChar) { *_pDstBytes = (byte)c; _outCounter--; _pDstBytes++; } else { c -= AcedConsts.FirstCharWithExBit; if (c < 0) { length1 = c + 19; } else { length1 = GetNBits(_pCharExBitLength[c]) + _pCharExBitBase[c]; } c = GetCode(_pDistTree); if (c < 3) { switch (c) { case 0: distance1 = _r0; break; case 1: distance1 = _r1; _r1 = _r0; _r0 = distance1; break; default: distance1 = _r2; _r2 = _r0; _r0 = distance1; break; } } else { distance1 = _pDistExBitBase[c]; if (c >= AcedConsts.FirstDistWithExBit) { distance1 += GetNBits(_pDistExBitLength[c]); _r2 = _r1; _r1 = _r0; _r0 = distance1; } } AcedUtils.CopyBytes(_pDstBytes - distance1, _pDstBytes, length1); _outCounter -= length1; _pDstBytes += length1; } } } } return(byteCount); } } return(0); }