I dunno man

This commit is contained in:
Lani Aung
2024-10-06 23:12:50 -06:00
parent 9c44ec0156
commit e3f23389da
6 changed files with 97 additions and 46 deletions
@@ -39,7 +39,7 @@ public class BitStreamTests
}
[Test]
public void TestReadLong()
public void TestReadInt()
{
var random = (uint)Random.Shared.Next();
var bytes = BitConverter.GetBytes(random);
+4 -25
View File
@@ -1,4 +1,3 @@
using fxl.codes.kisekae.data.Archives;
using fxl.codes.kisekae.data.Archives.Algorithms;
namespace fxl.codes.kisekae.data.test;
@@ -20,30 +19,10 @@ public class LZWTests
{
Assert.Multiple(() =>
{
Assert.That(_lzw.Encode(_unencoded), Is.EqualTo(_encoded), "Encoding failed");
Assert.That(_lzw.Decode(_encoded), Is.EqualTo(_unencoded), "Decoding failed");
var streamUnencoded = new MemoryStream(_unencoded);
var streamEncoded = new MemoryStream(_encoded);
Assert.That(_lzw.Encode(streamUnencoded), Is.EqualTo(_encoded), "Encoding failed");
Assert.That(_lzw.Decode(streamEncoded), Is.EqualTo(_unencoded), "Decoding failed");
});
}
[Test]
public void TestDecompressLzh()
{
var assembly = typeof(LZWTests).Assembly;
foreach (var resource in assembly.GetManifestResourceNames())
{
using var stream = assembly.GetManifestResourceStream(resource);
if (stream == null) continue;
var files = LhCodecService.GetFiles(in stream);
foreach (var file in files)
Assert.Multiple(() =>
{
Assert.That(file.CompressedFile, Is.Not.Null);
Assert.That(file.CompressedFile, Is.Not.Empty);
var decompressed = _lzw.Decode(file.CompressedFile);
Assert.That(decompressed, Is.Not.Null);
});
}
}
}
@@ -0,0 +1,47 @@
namespace fxl.codes.kisekae.data.Archives.Algorithms;
public class Huffman
{
private readonly List<HuffmanNode> Nodes;
public Huffman()
{
Nodes = new List<HuffmanNode>();
for (var i = char.MinValue; i < char.MaxValue; i++) Nodes.Add(new HuffmanNode(i, 1));
}
}
internal class HuffmanNode
{
public readonly char Value;
public HuffmanNode Left;
public HuffmanNode Parent;
public HuffmanNode Right;
public HuffmanSide Side;
public int Weight;
public HuffmanNode(char value, int weight = 0)
{
Value = value;
Weight = weight;
}
public HuffmanNode(HuffmanNode left, HuffmanNode right)
{
Left = left;
Left.Side = HuffmanSide.Left;
Left.Parent = this;
Right = right;
Right.Side = HuffmanSide.Right;
Right.Parent = this;
Weight = left.Weight + right.Weight;
}
}
internal enum HuffmanSide
{
Left,
Right
}
@@ -2,6 +2,6 @@ namespace fxl.codes.kisekae.data.Archives.Algorithms;
public interface IAlgorithm
{
byte[] Encode(ReadOnlySpan<byte> stream);
byte[] Decode(ReadOnlySpan<byte> stream);
byte[] Encode(Stream stream);
byte[] Decode(Stream stream, int bitLength);
}
@@ -4,24 +4,38 @@ namespace fxl.codes.kisekae.data.Archives.Algorithms;
internal class LZW : IAlgorithm
{
private static readonly Dictionary<uint, string> DecodeDictionary;
private static readonly Dictionary<string, uint> EncodeDictionary;
private readonly int Max;
static LZW()
{
DecodeDictionary = new Dictionary<uint, string>();
EncodeDictionary = new Dictionary<string, uint>();
for (uint i = 0; i <= byte.MaxValue; i++)
{
var value = $"{(char)i}";
DecodeDictionary.Add(i, value);
EncodeDictionary.Add(value, i);
}
}
internal LZW(int max = short.MaxValue)
{
Max = max;
}
public byte[] Decode(ReadOnlySpan<byte> stream)
public byte[] Decode(Stream stream, int bitLength = 32)
{
var dictionary = DecodeDictionary.ToDictionary(x => x.Key, x => x.Value);
uint next = byte.MaxValue + 1;
var dictionary = new Dictionary<uint, string>();
for (uint i = 0; i <= byte.MaxValue; i++) dictionary.Add(i, $"{(char)i}");
var buffer = "";
var decoded = new List<string>();
for (var i = 0; i < stream.Length; i += 4)
var bitStream = new BitStream(stream);
while (bitStream.Position < bitStream.Length)
{
var code = BitConverter.ToUInt32(stream[i..(i + 4)]);
var code = bitStream.ReadBits(bitLength);
if (!dictionary.ContainsKey(code)) dictionary[code] = buffer + buffer[0];
decoded.Add(dictionary[code]);
@@ -33,17 +47,18 @@ internal class LZW : IAlgorithm
return decoded.SelectMany(Encoding.UTF8.GetBytes).ToArray();
}
public byte[] Encode(ReadOnlySpan<byte> stream)
public byte[] Encode(Stream stream)
{
var next = byte.MaxValue + 1;
var dictionary = new Dictionary<string, int>();
for (var i = 0; i <= byte.MaxValue; i++) dictionary.Add($"{(char)i}", i);
uint next = byte.MaxValue + 1;
var dictionary = EncodeDictionary.ToDictionary(x => x.Key, x => x.Value);
var buffer = "";
var encoded = new List<int>();
foreach (var part in stream)
var encoded = new List<uint>();
while (true)
{
var charValue = (char)part;
if (stream.Position >= stream.Length) break;
var charValue = (char)stream.ReadByte();
buffer += charValue;
if (dictionary.ContainsKey(buffer)) continue;
if (next <= Max) dictionary.Add(buffer, next++);
+13 -3
View File
@@ -41,17 +41,27 @@ public class BitStream : Stream
}
var buffer = _bitBuffer;
if (bitLength < 32)
{
buffer >>= 32 - bitLength;
#if DEBUG
Console.WriteLine($"BitStream buffer: {_bitBuffer:b}, extracted number: {buffer:b}");
#endif
_bitBuffer <<= bitLength;
}
else
{
_bitBuffer = 0;
}
Position += bitLength;
_bitBufferCount -= bitLength;
return buffer;
}
public override int ReadByte()
{
return (int)ReadBits(8);
}
public override void Flush()
{
throw new NotImplementedException();