예제 #1
0
 private static void Push(UInt8_NE_H_OutputBitStream bitStream, bool bit, Stream destination, MemoryStream data)
 {
     if (bitStream.Push(bit))
     {
         byte[] bytes = data.ToArray();
         destination.Write(bytes, 0, bytes.Length);
         data.SetLength(0);
     }
 }
예제 #2
0
        private static void EncodeInternal(Stream destination, byte[] buffer, long pos, long slidingWindow, long recLength, long size)
        {
            UInt8_NE_H_OutputBitStream bitStream = new UInt8_NE_H_OutputBitStream(destination);
            MemoryStream data = new MemoryStream();

            if (size > 0)
            {
                long bPointer = 1, iOffset = 0;
                bitStream.Push(true);
                NeutralEndian.Write1(data, buffer[pos]);

                while (bPointer < size)
                {
                    long iCount = Math.Min(recLength, size - bPointer);
                    long iMax   = Math.Max(bPointer - slidingWindow, 0);
                    long k      = 1;
                    long i      = bPointer - 1;

                    do
                    {
                        long j = 0;
                        while (buffer[pos + i + j] == buffer[pos + bPointer + j])
                        {
                            if (++j >= iCount)
                            {
                                break;
                            }
                        }

                        if (j > k)
                        {
                            k       = j;
                            iOffset = i;
                        }
                    } while (i-- > iMax);

                    iCount = k;

                    if (iCount == 1)
                    {
                        Push(bitStream, true, destination, data);
                        NeutralEndian.Write1(data, buffer[pos + bPointer]);
                    }
                    else if (iCount == 2 && bPointer - iOffset > 256)
                    {
                        Push(bitStream, true, destination, data);
                        NeutralEndian.Write1(data, buffer[pos + bPointer]);
                        --iCount;
                    }
                    else if (iCount < 6 && bPointer - iOffset <= 256)
                    {
                        Push(bitStream, false, destination, data);
                        Push(bitStream, false, destination, data);
                        Push(bitStream, (((iCount - 2) >> 1) & 1) != 0, destination, data);
                        Push(bitStream, ((iCount - 2) & 1) != 0, destination, data);
                        NeutralEndian.Write1(data, (byte)(~(bPointer - iOffset - 1)));
                    }
                    else
                    {
                        Push(bitStream, false, destination, data);
                        Push(bitStream, true, destination, data);

                        long   off  = bPointer - iOffset - 1;
                        ushort info = (ushort)(~((off << 8) | (off >> 5)) & 0xFFF8);

                        if (iCount < 10) // iCount - 2 < 8
                        {
                            info |= (ushort)(iCount - 2);
                            BigEndian.Write2(data, info);
                        }
                        else
                        {
                            BigEndian.Write2(data, info);
                            NeutralEndian.Write1(data, (byte)(iCount - 9));
                        }
                    }

                    bPointer += iCount;
                }
            }

            Push(bitStream, false, destination, data);
            Push(bitStream, true, destination, data);

            NeutralEndian.Write1(data, 0);
            NeutralEndian.Write1(data, 0xF0);
            NeutralEndian.Write1(data, 0);
            bitStream.Flush(true);

            byte[] bytes = data.ToArray();
            destination.Write(bytes, 0, bytes.Length);
        }