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); } }
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); }