private BestResult FindBest(byte[] window, byte[] nextBytes) { BestResult result = new BestResult(); result.Length = 1; result.Character = nextBytes[0]; for (int i = window.Length - 1; i >= 0; i--) { //if window matches first next byte if (window[i] == nextBytes[0]) { ushort length = 1; List <byte> expandingWindow = new List <byte>(window); expandingWindow.Add(nextBytes[0]); for (int j = 1; j < nextBytes.Length; j++) { if (expandingWindow[i + j] != nextBytes[j]) { break; } expandingWindow.Add(nextBytes[j]); length++; } if (length > result.Length) { result.Length = length; result.Offset = (ushort)i; } } } result.IsCompressed = result.Length != 1; return(result); }
private void compress_Mode(byte[] buffer, byte mode, ushort windowSize) { int restBytes = (int)(16 - Math.Log(windowSize, 2)); int nextBytesSize = (int)Math.Pow(2, restBytes) + 1; using (BinaryWriter writer = new BinaryWriter(new FileStream(FilePath, FileMode.Create))) { writer.Write(LZSSHeader.GetBytes(), 0, 16); writer.Write(buffer[0]); byte[] chunk = new byte[17]; byte chunkLength = 1; sbyte flagpos = 7; for (int i = 1; i < buffer.Length; i++) { if (flagpos == -1) { writer.Write(chunk, 0, chunkLength); flagpos = 7; chunkLength = 1; chunk[0] = 0; } byte[] window; if (i < windowSize) { window = new byte[i]; } else { window = new byte[windowSize]; } if (i > windowSize) { Array.Copy(buffer, i - windowSize, window, 0, window.Length); } else { Array.Copy(buffer, 0, window, 0, window.Length); } byte[] nextBytes = new byte[nextBytesSize]; if (i + nextBytesSize > buffer.Length) { Array.Copy(buffer, i, nextBytes, 0, buffer.Length - i); } else { Array.Copy(buffer, i, nextBytes, 0, nextBytesSize); } BestResult result = FindBest(window, nextBytes); if (result.IsCompressed) { if (result.Length + i > buffer.Length) { result.Length = (byte)(buffer.Length - i); } CompressedWord word = new CompressedWord(result.Offset, result.Length); byte[] wordBytes = word.GetBytes(mode); Array.Copy(wordBytes, 0, chunk, chunkLength, 2); chunkLength += 2; chunk[0] |= (byte)(1 << flagpos); i += result.Length - 1; } else { byte[] compressed = new byte[1]; compressed[0] = result.Character; Array.Copy(compressed, 0, chunk, chunkLength, 1); chunkLength += 1; } flagpos--; } if (flagpos != -1) { writer.Write(chunk, 0, chunkLength); } } }