Esempio n. 1
0
        public BigHuffmanTree(BitStream bs, int allocSize)
        {
            _bs = bs;
            uint bit = _bs.GetBit();

            if (bit == 0)
            {
                _tree    = new uint[1];
                _tree[0] = 0;
                _last[0] = _last[1] = _last[2] = 0;
                return;
            }

            for (uint i = 0; i < 256; ++i)
            {
                _prefixtree[i] = _prefixlength[i] = 0;
            }

            _loBytes = new SmallHuffmanTree(_bs);
            _hiBytes = new SmallHuffmanTree(_bs);

            _markers[0] = _bs.GetBits(16);
            _markers[1] = _bs.GetBits(16);
            _markers[2] = _bs.GetBits(16);

            _last[0] = _last[1] = _last[2] = 0xffffffff;

            _treeSize = 0;
            _tree     = new uint[allocSize / 4];
            DecodeTree(0, 0);
            bit = _bs.GetBit();
            Debug.Assert(bit == 0);

            for (uint i = 0; i < 3; ++i)
            {
                if (_last[i] == 0xffffffff)
                {
                    _last[i]           = _treeSize;
                    _tree[_treeSize++] = 0;
                }
            }
        }
Esempio n. 2
0
        public BigHuffmanTree(BitStream bs, int allocSize)
        {
            _bs = bs;
            uint bit = _bs.GetBit();
            if (bit == 0)
            {
                _tree = new uint[1];
                _tree[0] = 0;
                _last[0] = _last[1] = _last[2] = 0;
                return;
            }

            for (uint i = 0; i < 256; ++i)
                _prefixtree[i] = _prefixlength[i] = 0;

            _loBytes = new SmallHuffmanTree(_bs);
            _hiBytes = new SmallHuffmanTree(_bs);

            _markers[0] = _bs.GetBits(16);
            _markers[1] = _bs.GetBits(16);
            _markers[2] = _bs.GetBits(16);

            _last[0] = _last[1] = _last[2] = 0xffffffff;

            _treeSize = 0;
            _tree = new uint[allocSize / 4];
            DecodeTree(0, 0);
            bit = _bs.GetBit();
            Debug.Assert(bit == 0);

            for (uint i = 0; i < 3; ++i)
            {
                if (_last[i] == 0xffffffff)
                {
                    _last[i] = _treeSize;
                    _tree[_treeSize++] = 0;
                }
            }
        }
Esempio n. 3
0
        public void QueueCompressedBuffer(byte[] buffer, int bufferSize, int unpackedSize)
        {
            using (var ms = new MemoryStream(buffer, 0, bufferSize))
            {
                var audioBS = BitStream.Create8Lsb(ms);

                bool dataPresent = audioBS.GetBit() != 0;

                if (!dataPresent)
                    return;

                bool isStereo = audioBS.GetBit() != 0;
                Debug.Assert(isStereo == _audioInfo.isStereo);
                bool is16Bits = audioBS.GetBit() != 0;
                Debug.Assert(is16Bits == _audioInfo.is16Bits);

                int numBytes = 1 * (isStereo ? 2 : 1) * (is16Bits ? 2 : 1);

                byte[] unpackedBuffer = new byte[unpackedSize];
                var curPointer = 0;
                var curPos = 0;

                SmallHuffmanTree[] audioTrees = new SmallHuffmanTree[4];
                for (int k = 0; k < numBytes; k++)
                    audioTrees[k] = new SmallHuffmanTree(audioBS);

                // Base values, stored as big endian

                int[] bases = new int[2];

                if (isStereo)
                {
                    if (is16Bits)
                    {
                        bases[1] = ScummHelper.SwapBytes((ushort)audioBS.GetBits(16));
                    }
                    else
                    {
                        bases[1] = (int)audioBS.GetBits(8);
                    }
                }

                if (is16Bits)
                {
                    bases[0] = ScummHelper.SwapBytes((ushort)audioBS.GetBits(16));
                }
                else
                {
                    bases[0] = (int)audioBS.GetBits(8);
                }

                // The bases are the first samples, too
                for (int i = 0;
                    i < (isStereo ? 2 : 1);
                    i++, curPointer += (is16Bits ? 2 : 1), curPos += (is16Bits ? 2 : 1))
                {
                    if (is16Bits)
                        unpackedBuffer.WriteUInt16BigEndian(curPointer, (ushort)bases[i]);
                    else
                        unpackedBuffer[curPointer] = (byte)((bases[i] & 0xFF) ^ 0x80);
                }

                // Next follow the deltas, which are added to the corresponding base values and
                // are stored as little endian
                // We store the unpacked bytes in big endian format

                while (curPos < unpackedSize)
                {
                    // If the sample is stereo, the data is stored for the left and right channel, respectively
                    // (the exact opposite to the base values)
                    if (!is16Bits)
                    {
                        for (int k = 0; k < (isStereo ? 2 : 1); k++)
                        {
                            sbyte delta = (sbyte)((short)audioTrees[k].GetCode(audioBS));
                            bases[k] = (bases[k] + delta) & 0xFF;
                            unpackedBuffer[curPointer++] = (byte)(bases[k] ^ 0x80);
                            curPos++;
                        }
                    }
                    else
                    {
                        for (int k = 0; k < (isStereo ? 2 : 1); k++)
                        {
                            byte lo = (byte)audioTrees[k * 2].GetCode(audioBS);
                            byte hi = (byte)audioTrees[k * 2 + 1].GetCode(audioBS);
                            bases[k] += (short)(lo | (hi << 8));

                            unpackedBuffer.WriteUInt16BigEndian(curPointer, (ushort)bases[k]);
                            curPointer += 2;
                            curPos += 2;
                        }
                    }

                }

                QueuePCM(unpackedBuffer, unpackedSize);
            }
        }
Esempio n. 4
0
        public void QueueCompressedBuffer(byte[] buffer, int bufferSize, int unpackedSize)
        {
            using (var ms = new MemoryStream(buffer, 0, bufferSize))
            {
                var audioBS = BitStream.Create8Lsb(ms);

                bool dataPresent = audioBS.GetBit() != 0;

                if (!dataPresent)
                {
                    return;
                }

                bool isStereo = audioBS.GetBit() != 0;
                Debug.Assert(isStereo == _audioInfo.isStereo);
                bool is16Bits = audioBS.GetBit() != 0;
                Debug.Assert(is16Bits == _audioInfo.is16Bits);

                int numBytes = 1 * (isStereo ? 2 : 1) * (is16Bits ? 2 : 1);

                byte[] unpackedBuffer = new byte[unpackedSize];
                var    curPointer     = 0;
                var    curPos         = 0;

                SmallHuffmanTree[] audioTrees = new SmallHuffmanTree[4];
                for (int k = 0; k < numBytes; k++)
                {
                    audioTrees[k] = new SmallHuffmanTree(audioBS);
                }

                // Base values, stored as big endian

                int[] bases = new int[2];

                if (isStereo)
                {
                    if (is16Bits)
                    {
                        bases[1] = ScummHelper.SwapBytes((ushort)audioBS.GetBits(16));
                    }
                    else
                    {
                        bases[1] = (int)audioBS.GetBits(8);
                    }
                }

                if (is16Bits)
                {
                    bases[0] = ScummHelper.SwapBytes((ushort)audioBS.GetBits(16));
                }
                else
                {
                    bases[0] = (int)audioBS.GetBits(8);
                }

                // The bases are the first samples, too
                for (int i = 0;
                     i < (isStereo ? 2 : 1);
                     i++, curPointer += (is16Bits ? 2 : 1), curPos += (is16Bits ? 2 : 1))
                {
                    if (is16Bits)
                    {
                        unpackedBuffer.WriteUInt16BigEndian(curPointer, (ushort)bases[i]);
                    }
                    else
                    {
                        unpackedBuffer[curPointer] = (byte)((bases[i] & 0xFF) ^ 0x80);
                    }
                }

                // Next follow the deltas, which are added to the corresponding base values and
                // are stored as little endian
                // We store the unpacked bytes in big endian format

                while (curPos < unpackedSize)
                {
                    // If the sample is stereo, the data is stored for the left and right channel, respectively
                    // (the exact opposite to the base values)
                    if (!is16Bits)
                    {
                        for (int k = 0; k < (isStereo ? 2 : 1); k++)
                        {
                            sbyte delta = (sbyte)((short)audioTrees[k].GetCode(audioBS));
                            bases[k] = (bases[k] + delta) & 0xFF;
                            unpackedBuffer[curPointer++] = (byte)(bases[k] ^ 0x80);
                            curPos++;
                        }
                    }
                    else
                    {
                        for (int k = 0; k < (isStereo ? 2 : 1); k++)
                        {
                            byte lo = (byte)audioTrees[k * 2].GetCode(audioBS);
                            byte hi = (byte)audioTrees[k * 2 + 1].GetCode(audioBS);
                            bases[k] += (short)(lo | (hi << 8));

                            unpackedBuffer.WriteUInt16BigEndian(curPointer, (ushort)bases[k]);
                            curPointer += 2;
                            curPos     += 2;
                        }
                    }
                }

                QueuePCM(unpackedBuffer, unpackedSize);
            }
        }