/*#HuffmanRleDecode*/ public static byte[] Decode(HuffmanTree tree, byte[] bytes) { var root = tree.Root; var result = new List<byte>(bytes.Length * 2); int bitPos = 0; while (bytes.Length * 8 - bitPos > 8) { var length = Utils.GetInt(bytes, ref bitPos, 8); if ((length & 128) == 0) { var repeatCount = length + 2; byte value = Utils.GetValue(root, bytes, ref bitPos); for (int j = 0; j < repeatCount; j++) result.Add(value); } else { var notRepeatCount = (127 & length) + 1; for (int j = 0; j < notRepeatCount; j++) { byte value = Utils.GetValue(root, bytes, ref bitPos); result.Add(value); } } } return result.ToArray(); }
public static byte[] Encode(HuffmanTree tree, byte[] bytes) { var result = new byte[bytes.Length * 2]; int curBit = 0; Encode(tree, bytes, ref curBit, result); result = result.Take((curBit + 7) / 8).ToArray(); return result; }
/*ByteCounts#*/ #endregion #region version 1.3 public string Compress_v_1_3(out List <CompressedFrame> compressedFrames, bool reducedLines = true) { var bytesFreqs = GetBytesFreqs(reducedLines, HuffmanRleRepeatedBits); var tree = new HuffmanTree(bytesFreqs); List <int> frameDiffs; var framesChanges = CalculateFrameChanges(); compressedFrames = GetCompressedFrames(tree, reducedLines, framesChanges, out frameDiffs); bytesFreqs = GetBytesFreqs(reducedLines, HuffmanRleRepeatedBits, compressedFrames); tree = new HuffmanTree(bytesFreqs); compressedFrames = GetCompressedFrames(tree, reducedLines, framesChanges, out frameDiffs); var result = new byte[1000000]; int bitPos = 0; Utils.AddInt(result, ref bitPos, bytesFreqs.Length, 8); foreach (var byteCount in bytesFreqs) { Utils.AddInt(result, ref bitPos, byteCount.Byte, 8); Utils.AddInt(result, ref bitPos, byteCount.Count, 24); } Utils.AddInt(result, ref bitPos, frameDiffs.Count, 24); foreach (var diff in frameDiffs) { Utils.AddInt(result, ref bitPos, diff, 9); } foreach (var frame in compressedFrames) { Utils.AddBytes(result, ref bitPos, frame.CompressedBytes); } result = result.Take((bitPos + 7) / 8).ToArray(); return(Convert.ToBase64String(result)); }
private byte[] GetCompressedFrameBytes(HuffmanTree tree, Frame frame, CompressedFrame compressedFrame) { int transBitPos = 0; var transZipBytes = new byte[frame.Bytes.Length * 10]; Utils.AddInt(transZipBytes, ref transBitPos, frame.RepeatCount, 7); Utils.AddInt(transZipBytes, ref transBitPos, (int)compressedFrame.FrameType, 3); Utils.AddInt(transZipBytes, ref transBitPos, compressedFrame.FrameChanges.Count, 7); for (int i = 0; i < compressedFrame.FrameChanges.Count; i++) { var change = compressedFrame.FrameChanges[i]; Utils.AddInt(transZipBytes, ref transBitPos, (int)change.Type, 2); Utils.AddInt(transZipBytes, ref transBitPos, GetPos(change.X, change.Y), 10); if (change.Type == FrameChangeType.One) { Utils.AddIntReversed(transZipBytes, ref transBitPos, tree.CompressedBytes[change.Chars[0]]); } else { Utils.AddInt(transZipBytes, ref transBitPos, change.Length, change.Type == FrameChangeType.Horizontal ? 7 : 4); //HuffmanRle.Encode(tree, change.Chars.Select(c => (byte)c).ToArray(), ref transBitPos, transZipBytes, 5, 4); for (int j = 0; j < change.Chars.Count; j++) { Utils.AddIntReversed(transZipBytes, ref transBitPos, tree.CompressedBytes[change.Chars[j]]); } /*if (i == 0 && compressedFrame.FrameType != FrameType.Basic && compressedFrame.FrameType != FrameType.Transitional) * HuffmanRle.Encode(tree, change.Chars.Select(c => (byte)c).ToArray(), ref transBitPos, transZipBytes, 5, 4); * else * for (int j = 0; j < change.Chars.Count; j++) * Utils.AddIntReversed(transZipBytes, ref transBitPos, tree.CompressedBytes[change.Chars[j]]);*/ } } return(transZipBytes.Take((transBitPos + 7) / 8).ToArray()); }
public void HuffmanRleFull() { var generator = new AsciimationDataGenerator(AsciimationData); var bytesFreqs = generator.GetBytesFreqs(false); var bytes = AsciimationDataGenerator.SerializeByteCount(bytesFreqs); var huffmanTable = Convert.ToBase64String(bytes); var tree = new HuffmanTree(bytesFreqs); var encodedTable = Convert.ToBase64String(bytes); var encodedFrames = new List<string>(); for (int i = 0; i < generator.Frames.Length; i++) { var frame = generator.Frames[i]; encodedFrames.Add(Convert.ToBase64String(HuffmanRle.Encode(tree, frame.Bytes))); } var decodedTree = new HuffmanTree(AsciimationDataGenerator.DeserializeByteCount(Base64.DecodeBase64(encodedTable))); var decodedFrames = new List<string>(); for (int i = 0; i < encodedFrames.Count; i++) { var frame = HuffmanRle.Decode(decodedTree, Base64.DecodeBase64(encodedFrames[i])); CollectionAssert.AreEqual(generator.Frames[i].Bytes, frame); } }
public static void Encode(HuffmanTree tree, byte[] bytes, ref int curBit, byte[] result, int bitsCountPerRepLength = 8, int bitsCountPerNotRepLength = 8) { var maxRepeatCount = (1 << (bitsCountPerRepLength - 1)) + 1; var maxNotRepeatCount = 1 << (bitsCountPerNotRepLength - 1); var compressedBytes = tree.CompressedBytes; int i = 0; while (i < bytes.Length) { int j = i; do j++; while (j != bytes.Length && bytes[j] == bytes[i]); int repeatCount = j - i; if (repeatCount >= 2) { int segmentCount = repeatCount / maxRepeatCount; int rest = repeatCount % maxRepeatCount; for (int k = 0; k < segmentCount; k++) { Utils.AddInt(result, ref curBit, maxRepeatCount - 2, bitsCountPerRepLength); Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i]]); } if (rest >= 2) { Utils.AddInt(result, ref curBit, (rest - 2), bitsCountPerRepLength); Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i]]); i = j; } else i = j - rest; } else { while (j != bytes.Length && bytes[j] != bytes[j - 1]) j++; int nonrepeatCount = j - i; if (j != bytes.Length) nonrepeatCount--; int segmentCount = nonrepeatCount / maxNotRepeatCount; int rest = nonrepeatCount % maxNotRepeatCount; for (int k = 0; k < segmentCount; k++) { Utils.AddInt(result, ref curBit, (1 << bitsCountPerNotRepLength) - 1, bitsCountPerNotRepLength); for (int l = 0; l < maxNotRepeatCount; l++) Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i + k * maxNotRepeatCount + l]]); } if (rest >= 1) { Utils.AddInt(result, ref curBit, (maxNotRepeatCount | (rest - 1)), bitsCountPerNotRepLength); for (int l = 0; l < rest; l++) Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i + segmentCount * maxNotRepeatCount + l]]); } i = j; if (j != bytes.Length) i--; } } }
public static byte[] Decode(HuffmanTree tree, byte[] bytes, ref int curBit, int bytesCount, int bitsCountPerRepLength = 8, int bitsCountPerNotRepLength = 8) { int minLength = Math.Min(bitsCountPerRepLength, bitsCountPerNotRepLength); var maxCount = 1 << (minLength - 1); var root = tree.Root; var result = new List<byte>(bytes.Length * 2); int curBytesCount = 0; int i = 0; while (curBytesCount < bytesCount) { var length = Utils.GetInt(bytes, ref curBit, minLength); if ((length & maxCount) == 0) { curBit -= minLength; length = Utils.GetInt(bytes, ref curBit, bitsCountPerRepLength); var repeatCount = length + 2; byte value = Utils.GetValue(root, bytes, ref curBit); for (int j = 0; j < repeatCount; j++) { result.Add(value); curBytesCount++; } } else { curBit -= minLength; length = Utils.GetInt(bytes, ref curBit, bitsCountPerNotRepLength); var notRepeatCount = (((1 << (bitsCountPerNotRepLength - 1)) - 1) & length) + 1; for (int j = 0; j < notRepeatCount; j++) { byte value = Utils.GetValue(root, bytes, ref curBit); result.Add(value); curBytesCount++; } } i++; } return result.ToArray(); }
public static void Encode(HuffmanTree tree, byte[] bytes, ref int curBit, byte[] result, int bitsCountPerRepLength = 8, int bitsCountPerNotRepLength = 8) { var maxRepeatCount = (1 << (bitsCountPerRepLength - 1)) + 1; var maxNotRepeatCount = 1 << (bitsCountPerNotRepLength - 1); var compressedBytes = tree.CompressedBytes; int i = 0; while (i < bytes.Length) { int j = i; do { j++; }while (j != bytes.Length && bytes[j] == bytes[i]); int repeatCount = j - i; if (repeatCount >= 2) { int segmentCount = repeatCount / maxRepeatCount; int rest = repeatCount % maxRepeatCount; for (int k = 0; k < segmentCount; k++) { Utils.AddInt(result, ref curBit, maxRepeatCount - 2, bitsCountPerRepLength); Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i]]); } if (rest >= 2) { Utils.AddInt(result, ref curBit, (rest - 2), bitsCountPerRepLength); Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i]]); i = j; } else { i = j - rest; } } else { while (j != bytes.Length && bytes[j] != bytes[j - 1]) { j++; } int nonrepeatCount = j - i; if (j != bytes.Length) { nonrepeatCount--; } int segmentCount = nonrepeatCount / maxNotRepeatCount; int rest = nonrepeatCount % maxNotRepeatCount; for (int k = 0; k < segmentCount; k++) { Utils.AddInt(result, ref curBit, (1 << bitsCountPerNotRepLength) - 1, bitsCountPerNotRepLength); for (int l = 0; l < maxNotRepeatCount; l++) { Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i + k * maxNotRepeatCount + l]]); } } if (rest >= 1) { Utils.AddInt(result, ref curBit, (maxNotRepeatCount | (rest - 1)), bitsCountPerNotRepLength); for (int l = 0; l < rest; l++) { Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i + segmentCount * maxNotRepeatCount + l]]); } } i = j; if (j != bytes.Length) { i--; } } } }
public void RleHuffmanEncodeDecodeWithDifferentLengths() { var generator = new AsciimationDataGenerator(AsciimationData); var bytesFreqs = generator.GetBytesFreqs(); var tree = new HuffmanTree(bytesFreqs); for (int i = 0; i < generator.Frames.Length; i++) { var frame = generator.Frames[i]; var orig = frame.Bytes; int curBit = 0; byte[] bytes = new byte[frame.Bytes.Length * 2]; HuffmanRle.Encode(tree, orig, ref curBit, bytes, 8, 4); bytes = bytes.Take((curBit + 7) / 8).ToArray(); curBit = 0; var decoded = HuffmanRle2.Decode(tree, bytes, ref curBit, frame.Bytes.Length, 8, 4); CollectionAssert.AreEqual(orig, decoded); } }
public void RleHuffmanEncodeDecode() { var generator = new AsciimationDataGenerator(AsciimationData); var bytesFreqs = generator.GetBytesFreqs(); var tree = new HuffmanTree(bytesFreqs); for (int i = 0; i < generator.Frames.Length; i++) { var frame = generator.Frames[i]; var orig = frame.Bytes; var encoded = HuffmanRle.Encode(tree, orig); var decoded = HuffmanRle.Decode(tree, encoded); CollectionAssert.AreEqual(orig, decoded); } }
public static string Decompress_v_1_3(string str, int currentFrame) { byte[] bytes = Convert.FromBase64String(str); int bitPos = 0; byte tableLength = (byte)Utils.GetInt(bytes, ref bitPos, 8); var bytesFreqs = new ByteCount[tableLength]; for (int i = 0; i < tableLength; i++) { bytesFreqs[i] = new ByteCount { Byte = (byte)Utils.GetInt(bytes, ref bitPos, 8), Count = Utils.GetInt(bytes, ref bitPos, 24) }; } var tree = new HuffmanTree(bytesFreqs); int frameDiffsCount = Utils.GetInt(bytes, ref bitPos, 24); var frameNumbers = new List<int>(); int sum = 0; frameNumbers.Add(sum); for (int i = 0; i < frameDiffsCount; i++) { sum += Utils.GetInt(bytes, ref bitPos, 9); frameNumbers.Add(sum); } int beginBitPos = bitPos; bitPos = frameNumbers[currentFrame] * 8 + beginBitPos; int repeatCount = Utils.GetInt(bytes, ref bitPos, 7); var frameType = (FrameType)Utils.GetInt(bytes, ref bitPos, 3); if (frameType == FrameType.Basic) { var frameLength = Utils.GetInt(bytes, ref bitPos, BasicBytesLengthBits); var frameBytes = HuffmanRle2.Decode(tree, bytes, ref bitPos, frameLength, HuffmanRleRepeatedBits, HuffmanRleNotRepeatedBits); return CharsToLine(BytesToFrame(frameBytes)); } else { int prevFrame = currentFrame; int prevRepeatCount; FrameType prevFrameType; do { prevFrame--; bitPos = frameNumbers[prevFrame] * 8 + beginBitPos; prevRepeatCount = Utils.GetInt(bytes, ref bitPos, 7); prevFrameType = (FrameType)Utils.GetInt(bytes, ref bitPos, 3); } while (prevFrameType != FrameType.Basic); var frameLength = Utils.GetInt(bytes, ref bitPos, BasicBytesLengthBits); var frame = BytesToFrame(HuffmanRle2.Decode(tree, bytes, ref bitPos, frameLength, HuffmanRleRepeatedBits, HuffmanRleNotRepeatedBits)); do { prevFrame++; bitPos = frameNumbers[prevFrame] * 8 + beginBitPos; prevRepeatCount = Utils.GetInt(bytes, ref bitPos, 7); prevFrameType = (FrameType)Utils.GetInt(bytes, ref bitPos, 3); switch (prevFrameType) { case FrameType.Transitional: break; case FrameType.TransitionalLeft: for (int y = 0; y < FrameHeight; y++) for (int x = 0; x < FrameWidth - 1; x++) frame[y, x] = frame[y, x + 1]; break; case FrameType.TransitionalRight: for (int y = 0; y < FrameHeight; y++) for (int x = FrameWidth - 1; x >= 1; x--) frame[y, x] = frame[y, x - 1]; break; case FrameType.TransitionalTop: for (int y = 0; y < FrameHeight - 1; y++) for (int x = 0; x < FrameWidth; x++) frame[y, x] = frame[y + 1, x]; break; case FrameType.TransitionalBottom: for (int y = FrameHeight - 1; y >= 1; y--) for (int x = 0; x < FrameWidth; x++) frame[y, x] = frame[y - 1, x]; break; } var frameChangesCount = Utils.GetInt(bytes, ref bitPos, 7); for (int i = 0; i < frameChangesCount; i++) { var frameChangeType = (FrameChangeType)Utils.GetInt(bytes, ref bitPos, 2); var position = Utils.GetInt(bytes, ref bitPos, 10); int length; if (frameChangeType == FrameChangeType.One) length = 1; else length = Utils.GetInt(bytes, ref bitPos, frameChangeType == FrameChangeType.Horizontal ? 7 : 4); for (int j = 0; j < length; j++) { frame[GetY(position), GetX(position)] = (char)Utils.GetValue(tree.Root, bytes, ref bitPos); position += frameChangeType == FrameChangeType.Horizontal ? 1 : FrameWidth; } } } while (prevFrame != currentFrame); return CharsToLine(frame).ToString(); } }
private List<CompressedFrame> GetCompressedFrames(HuffmanTree tree, bool reducedLines, List<Dictionary<FrameType, CompressedFrame>> framesChanges, out List<int> frameDiffs) { var compressedFrames = new List<CompressedFrame>(); int currentFrame = 0; frameDiffs = new List<int>(); for (int i = 0; i < Frames.Length; i++) { var frame = Frames[i]; var frameChanges = framesChanges[i]; int basisBitPos = 0; byte[] basisBytes = null; byte[] transBytes, transLeftBytes, transRightBytes, transTopBytes, transBottomBytes; transBytes = transLeftBytes = transRightBytes = transTopBytes = transBottomBytes = null; int frameTypeBit; basisBytes = new byte[frame.Bytes.Length * 2]; Utils.AddInt(basisBytes, ref basisBitPos, frame.RepeatCount, 7); frameTypeBit = basisBitPos; Utils.AddInt(basisBytes, ref basisBitPos, (int)FrameType.Basic, 3); Utils.AddInt(basisBytes, ref basisBitPos, frame.ReducedBytes.Length, BasicBytesLengthBits); HuffmanRle.Encode(tree, reducedLines ? frame.ReducedBytes : frame.Bytes, ref basisBitPos, basisBytes, HuffmanRleRepeatedBits, HuffmanRleNotRepeatedBits); basisBytes = basisBytes.Take((basisBitPos + 7) / 8).ToArray(); if (i != 0) { transBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.Transitional]); transLeftBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalLeft]); transRightBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalRight]); transTopBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalTop]); transBottomBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalBottom]); } var typesBytes = new Dictionary<FrameType, byte[]>() { { FrameType.Basic, basisBytes }, { FrameType.Transitional, transBytes }, { FrameType.TransitionalLeft, transLeftBytes }, { FrameType.TransitionalRight, transRightBytes }, { FrameType.TransitionalTop, transTopBytes }, { FrameType.TransitionalBottom, transBottomBytes }, }; var minLengthBytesKey = typesBytes.Where(tb => tb.Value != null) .Aggregate((a, b) => a.Value.Length < b.Value.Length ? a : b).Key; Utils.AddInt(typesBytes[minLengthBytesKey], ref frameTypeBit, (int)minLengthBytesKey, 3); compressedFrames.Add(new CompressedFrame { CompressedBytes = typesBytes[minLengthBytesKey], FrameType = minLengthBytesKey, FrameChanges = !frameChanges.ContainsKey(minLengthBytesKey) ? null : frameChanges[minLengthBytesKey].FrameChanges }); currentFrame += typesBytes[minLengthBytesKey].Length; frameDiffs.Add(typesBytes[minLengthBytesKey].Length); } return compressedFrames; }
private byte[] GetCompressedFrameBytes(HuffmanTree tree, Frame frame, CompressedFrame compressedFrame) { int transBitPos = 0; var transZipBytes = new byte[frame.Bytes.Length * 10]; Utils.AddInt(transZipBytes, ref transBitPos, frame.RepeatCount, 7); Utils.AddInt(transZipBytes, ref transBitPos, (int)compressedFrame.FrameType, 3); Utils.AddInt(transZipBytes, ref transBitPos, compressedFrame.FrameChanges.Count, 7); for (int i = 0; i < compressedFrame.FrameChanges.Count; i++) { var change = compressedFrame.FrameChanges[i]; Utils.AddInt(transZipBytes, ref transBitPos, (int)change.Type, 2); Utils.AddInt(transZipBytes, ref transBitPos, GetPos(change.X, change.Y), 10); if (change.Type == FrameChangeType.One) Utils.AddIntReversed(transZipBytes, ref transBitPos, tree.CompressedBytes[change.Chars[0]]); else { Utils.AddInt(transZipBytes, ref transBitPos, change.Length, change.Type == FrameChangeType.Horizontal ? 7 : 4); //HuffmanRle.Encode(tree, change.Chars.Select(c => (byte)c).ToArray(), ref transBitPos, transZipBytes, 5, 4); for (int j = 0; j < change.Chars.Count; j++) Utils.AddIntReversed(transZipBytes, ref transBitPos, tree.CompressedBytes[change.Chars[j]]); /*if (i == 0 && compressedFrame.FrameType != FrameType.Basic && compressedFrame.FrameType != FrameType.Transitional) HuffmanRle.Encode(tree, change.Chars.Select(c => (byte)c).ToArray(), ref transBitPos, transZipBytes, 5, 4); else for (int j = 0; j < change.Chars.Count; j++) Utils.AddIntReversed(transZipBytes, ref transBitPos, tree.CompressedBytes[change.Chars[j]]);*/ } } return transZipBytes.Take((transBitPos + 7) / 8).ToArray(); }
public string Compress_v_1_3(out List<CompressedFrame> compressedFrames, bool reducedLines = true) { var bytesFreqs = GetBytesFreqs(reducedLines, HuffmanRleRepeatedBits); var tree = new HuffmanTree(bytesFreqs); List<int> frameDiffs; var framesChanges = CalculateFrameChanges(); compressedFrames = GetCompressedFrames(tree, reducedLines, framesChanges, out frameDiffs); bytesFreqs = GetBytesFreqs(reducedLines, HuffmanRleRepeatedBits, compressedFrames); tree = new HuffmanTree(bytesFreqs); compressedFrames = GetCompressedFrames(tree, reducedLines, framesChanges, out frameDiffs); var result = new byte[1000000]; int bitPos = 0; Utils.AddInt(result, ref bitPos, bytesFreqs.Length, 8); foreach (var byteCount in bytesFreqs) { Utils.AddInt(result, ref bitPos, byteCount.Byte, 8); Utils.AddInt(result, ref bitPos, byteCount.Count, 24); } Utils.AddInt(result, ref bitPos, frameDiffs.Count, 24); foreach (var diff in frameDiffs) Utils.AddInt(result, ref bitPos, diff, 9); foreach (var frame in compressedFrames) Utils.AddBytes(result, ref bitPos, frame.CompressedBytes); result = result.Take((bitPos + 7) / 8).ToArray(); return Convert.ToBase64String(result); }
public static string Decompress_v_1_3(string str, int currentFrame) { byte[] bytes = Convert.FromBase64String(str); int bitPos = 0; byte tableLength = (byte)Utils.GetInt(bytes, ref bitPos, 8); var bytesFreqs = new ByteCount[tableLength]; for (int i = 0; i < tableLength; i++) { bytesFreqs[i] = new ByteCount { Byte = (byte)Utils.GetInt(bytes, ref bitPos, 8), Count = Utils.GetInt(bytes, ref bitPos, 24) }; } var tree = new HuffmanTree(bytesFreqs); int frameDiffsCount = Utils.GetInt(bytes, ref bitPos, 24); var frameNumbers = new List <int>(); int sum = 0; frameNumbers.Add(sum); for (int i = 0; i < frameDiffsCount; i++) { sum += Utils.GetInt(bytes, ref bitPos, 9); frameNumbers.Add(sum); } int beginBitPos = bitPos; bitPos = frameNumbers[currentFrame] * 8 + beginBitPos; int repeatCount = Utils.GetInt(bytes, ref bitPos, 7); var frameType = (FrameType)Utils.GetInt(bytes, ref bitPos, 3); if (frameType == FrameType.Basic) { var frameLength = Utils.GetInt(bytes, ref bitPos, BasicBytesLengthBits); var frameBytes = HuffmanRle2.Decode(tree, bytes, ref bitPos, frameLength, HuffmanRleRepeatedBits, HuffmanRleNotRepeatedBits); return(CharsToLine(BytesToFrame(frameBytes))); } else { int prevFrame = currentFrame; int prevRepeatCount; FrameType prevFrameType; do { prevFrame--; bitPos = frameNumbers[prevFrame] * 8 + beginBitPos; prevRepeatCount = Utils.GetInt(bytes, ref bitPos, 7); prevFrameType = (FrameType)Utils.GetInt(bytes, ref bitPos, 3); }while (prevFrameType != FrameType.Basic); var frameLength = Utils.GetInt(bytes, ref bitPos, BasicBytesLengthBits); var frame = BytesToFrame(HuffmanRle2.Decode(tree, bytes, ref bitPos, frameLength, HuffmanRleRepeatedBits, HuffmanRleNotRepeatedBits)); do { prevFrame++; bitPos = frameNumbers[prevFrame] * 8 + beginBitPos; prevRepeatCount = Utils.GetInt(bytes, ref bitPos, 7); prevFrameType = (FrameType)Utils.GetInt(bytes, ref bitPos, 3); switch (prevFrameType) { case FrameType.Transitional: break; case FrameType.TransitionalLeft: for (int y = 0; y < FrameHeight; y++) { for (int x = 0; x < FrameWidth - 1; x++) { frame[y, x] = frame[y, x + 1]; } } break; case FrameType.TransitionalRight: for (int y = 0; y < FrameHeight; y++) { for (int x = FrameWidth - 1; x >= 1; x--) { frame[y, x] = frame[y, x - 1]; } } break; case FrameType.TransitionalTop: for (int y = 0; y < FrameHeight - 1; y++) { for (int x = 0; x < FrameWidth; x++) { frame[y, x] = frame[y + 1, x]; } } break; case FrameType.TransitionalBottom: for (int y = FrameHeight - 1; y >= 1; y--) { for (int x = 0; x < FrameWidth; x++) { frame[y, x] = frame[y - 1, x]; } } break; } var frameChangesCount = Utils.GetInt(bytes, ref bitPos, 7); for (int i = 0; i < frameChangesCount; i++) { var frameChangeType = (FrameChangeType)Utils.GetInt(bytes, ref bitPos, 2); var position = Utils.GetInt(bytes, ref bitPos, 10); int length; if (frameChangeType == FrameChangeType.One) { length = 1; } else { length = Utils.GetInt(bytes, ref bitPos, frameChangeType == FrameChangeType.Horizontal ? 7 : 4); } for (int j = 0; j < length; j++) { frame[GetY(position), GetX(position)] = (char)Utils.GetValue(tree.Root, bytes, ref bitPos); position += frameChangeType == FrameChangeType.Horizontal ? 1 : FrameWidth; } } }while (prevFrame != currentFrame); return(CharsToLine(frame).ToString()); } }
private List <CompressedFrame> GetCompressedFrames(HuffmanTree tree, bool reducedLines, List <Dictionary <FrameType, CompressedFrame> > framesChanges, out List <int> frameDiffs) { var compressedFrames = new List <CompressedFrame>(); int currentFrame = 0; frameDiffs = new List <int>(); for (int i = 0; i < Frames.Length; i++) { var frame = Frames[i]; var frameChanges = framesChanges[i]; int basisBitPos = 0; byte[] basisBytes = null; byte[] transBytes, transLeftBytes, transRightBytes, transTopBytes, transBottomBytes; transBytes = transLeftBytes = transRightBytes = transTopBytes = transBottomBytes = null; int frameTypeBit; basisBytes = new byte[frame.Bytes.Length * 2]; Utils.AddInt(basisBytes, ref basisBitPos, frame.RepeatCount, 7); frameTypeBit = basisBitPos; Utils.AddInt(basisBytes, ref basisBitPos, (int)FrameType.Basic, 3); Utils.AddInt(basisBytes, ref basisBitPos, frame.ReducedBytes.Length, BasicBytesLengthBits); HuffmanRle.Encode(tree, reducedLines ? frame.ReducedBytes : frame.Bytes, ref basisBitPos, basisBytes, HuffmanRleRepeatedBits, HuffmanRleNotRepeatedBits); basisBytes = basisBytes.Take((basisBitPos + 7) / 8).ToArray(); if (i != 0) { transBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.Transitional]); transLeftBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalLeft]); transRightBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalRight]); transTopBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalTop]); transBottomBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalBottom]); } var typesBytes = new Dictionary <FrameType, byte[]>() { { FrameType.Basic, basisBytes }, { FrameType.Transitional, transBytes }, { FrameType.TransitionalLeft, transLeftBytes }, { FrameType.TransitionalRight, transRightBytes }, { FrameType.TransitionalTop, transTopBytes }, { FrameType.TransitionalBottom, transBottomBytes }, }; var minLengthBytesKey = typesBytes.Where(tb => tb.Value != null) .Aggregate((a, b) => a.Value.Length < b.Value.Length ? a : b).Key; Utils.AddInt(typesBytes[minLengthBytesKey], ref frameTypeBit, (int)minLengthBytesKey, 3); compressedFrames.Add(new CompressedFrame { CompressedBytes = typesBytes[minLengthBytesKey], FrameType = minLengthBytesKey, FrameChanges = !frameChanges.ContainsKey(minLengthBytesKey) ? null : frameChanges[minLengthBytesKey].FrameChanges }); currentFrame += typesBytes[minLengthBytesKey].Length; frameDiffs.Add(typesBytes[minLengthBytesKey].Length); } return(compressedFrames); }