private unsafe void LoadDistTree() { int n, m, p, code; AcedUtils.Fill(0, _pBitLen, AcedConsts.DistCount); LoadCharDistLengths(GetNBits(6) + 1); AcedUtils.Fill(0, _pDistTree, AcedConsts.DistTreeSize); _pNextCode[1] = 0; _pNextCode[2] = n = _pBitCount[1] << 1; _pNextCode[3] = n = (n + _pBitCount[2]) << 1; _pNextCode[4] = n = (n + _pBitCount[3]) << 1; _pNextCode[5] = n = (n + _pBitCount[4]) << 1; _pNextCode[6] = n = (n + _pBitCount[5]) << 1; _pNextCode[7] = n = (n + _pBitCount[6]) << 1; _pNextCode[8] = n = (n + _pBitCount[7]) << 1; _pNextCode[9] = n = (n + _pBitCount[8]) << 1; _pNextCode[10] = n = (n + _pBitCount[9]) << 1; _pNextCode[11] = n = (n + _pBitCount[10]) << 1; _pNextCode[12] = n = (n + _pBitCount[11]) << 1; _pNextCode[13] = n = (n + _pBitCount[12]) << 1; _pNextCode[14] = n = (n + _pBitCount[13]) << 1; var treeLen = 2; for (var i = 0; i < AcedConsts.DistCount; i++) { n = _pBitLen[i]; if (n == 0) { continue; } m = _pNextCode[n]; code = (int)AcedUtils.ReverseBits((uint)m, n); _pNextCode[n] = m + 1; p = 1; while (true) { p += code & 1; code >>= 1; n--; if (n != 0) { m = p; p = _pDistTree[p]; if (p != 0) { continue; } p = treeLen + 1; treeLen = p + 1; _pDistTree[m] = p; } else { _pDistTree[p] = -i; break; } } } }
private unsafe void LoadChLenTree() { int n, m, p, i, code; AcedUtils.Fill(0, _pBitCount, AcedConsts.MaxChLenBits + 1); for (i = 0; i < AcedConsts.ChLenCount; i++) { n = GetNBits(3); _pBitLen[i] = n; _pBitCount[n]++; } AcedUtils.Fill(0, _pChLenTree, AcedConsts.ChLenTreeSize); _pNextCode[1] = 0; _pNextCode[2] = n = _pBitCount[1] << 1; _pNextCode[3] = n = (n + _pBitCount[2]) << 1; _pNextCode[4] = n = (n + _pBitCount[3]) << 1; _pNextCode[5] = n = (n + _pBitCount[4]) << 1; _pNextCode[6] = n = (n + _pBitCount[5]) << 1; _pNextCode[7] = n = (n + _pBitCount[6]) << 1; var treeLen = 2; for (i = 0; i < AcedConsts.ChLenCount; i++) { n = _pBitLen[i]; if (n == 0) { continue; } m = _pNextCode[n]; code = (int)AcedUtils.ReverseBits((uint)m, n); _pNextCode[n] = m + 1; p = 1; while (true) { p += code & 1; code >>= 1; n--; if (n != 0) { m = p; p = _pChLenTree[p]; if (p != 0) { continue; } p = treeLen + 1; treeLen = p + 1; _pChLenTree[m] = p; } else { _pChLenTree[p] = -i; break; } } } }
private unsafe void LoadCharDistLengths(int count) { int c, lastLen = 0; var p = _pBitLen; AcedUtils.Fill(0, _pBitCount, AcedConsts.MaxBits + 1); while (count > 0) { c = GetCode(_pChLenTree); if (c < 15) { *p = c; _pBitCount[c]++; p++; lastLen = c; count--; } else { if (c < 17) { if (c == 15) { c = 2; } else { c = GetBit() + 3; } } else if (c == 17) { c = GetNBits(2) + 5; } else if (c == 18) { c = GetNBits(3) + 9; } else { c = GetNBits(7) + 17; } count -= c; _pBitCount[lastLen] += c; do { c--; *p = lastLen; p++; } while (c != 0); } } }
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); }