Beispiel #1
0
        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);
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
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;
        }
Beispiel #7
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);
        }