diff --git a/Aaru6.Compression/AppleRle.cs b/Aaru6.Compression/AppleRle.cs
index d43e251..c4cf908 100644
--- a/Aaru6.Compression/AppleRle.cs
+++ b/Aaru6.Compression/AppleRle.cs
@@ -31,8 +31,6 @@
// Copyright © 2018-2019 David Ryskalczyk
// ****************************************************************************/
-using System.IO;
-
namespace Aaru6.Compression
{
/// Implements the Apple version of RLE
@@ -40,89 +38,87 @@ namespace Aaru6.Compression
{
const uint DART_CHUNK = 20960;
- readonly Stream _inStream;
- int _count;
- bool _nextA; // true if A, false if B
- byte _repeatedByteA, _repeatedByteB;
- bool _repeatMode; // true if we're repeating, false if we're just copying
-
- /// Initializes a decompressor for the specified stream
- /// Stream containing the compressed data
- public AppleRle(Stream stream)
+ /// Decodes a buffer compressed with Apple RLE
+ /// Encoded buffer
+ /// Buffer where to write the decoded data
+ /// The number of decoded bytes
+ public static int DecodeBuffer(byte[] source, byte[] destination)
{
- _inStream = stream;
- Reset();
- }
+ int count = 0;
+ bool nextA = true; // true if A, false if B
+ byte repeatedByteA = 0, repeatedByteB = 0;
+ bool repeatMode = false; // true if we're repeating, false if we're just copying
+ int inPosition = 0, outPosition = 0;
- void Reset()
- {
- _repeatedByteA = _repeatedByteB = 0;
- _count = 0;
- _nextA = true;
- _repeatMode = false;
- }
-
- /// Decompresses a byte
- /// Decompressed byte
- public int ProduceByte()
- {
- if(_repeatMode && _count > 0)
+ while(inPosition <= source.Length &&
+ outPosition <= destination.Length)
{
- _count--;
-
- if(_nextA)
+ switch(repeatMode)
{
- _nextA = false;
+ case true when count > 0:
+ {
+ count--;
- return _repeatedByteA;
+ if(nextA)
+ {
+ nextA = false;
+
+ destination[outPosition++] = repeatedByteA;
+
+ continue;
+ }
+
+ nextA = true;
+
+ destination[outPosition++] = repeatedByteB;
+
+ continue;
+ }
+ case false when count > 0:
+ count--;
+
+ destination[outPosition++] = source[inPosition++];
+
+ continue;
}
- _nextA = true;
+ if(inPosition == source.Length)
+ break;
- return _repeatedByteB;
- }
-
- if(!_repeatMode &&
- _count > 0)
- {
- _count--;
-
- return _inStream.ReadByte();
- }
-
- if(_inStream.Position == _inStream.Length)
- return -1;
-
- while(true)
- {
- byte b1 = (byte)_inStream.ReadByte();
- byte b2 = (byte)_inStream.ReadByte();
- short s = (short)((b1 << 8) | b2);
-
- if(s == 0 ||
- s >= DART_CHUNK ||
- s <= -DART_CHUNK)
- continue;
-
- if(s < 0)
+ while(true)
{
- _repeatMode = true;
- _repeatedByteA = (byte)_inStream.ReadByte();
- _repeatedByteB = (byte)_inStream.ReadByte();
- _count = (-s * 2) - 1;
- _nextA = false;
+ byte b1 = source[inPosition++];
+ byte b2 = source[inPosition++];
+ short s = (short)((b1 << 8) | b2);
- return _repeatedByteA;
+ if(s == 0 ||
+ s >= DART_CHUNK ||
+ s <= -DART_CHUNK)
+ continue;
+
+ if(s < 0)
+ {
+ repeatMode = true;
+ repeatedByteA = source[inPosition++];
+ repeatedByteB = source[inPosition++];
+ count = (-s * 2) - 1;
+ nextA = false;
+
+ destination[outPosition++] = repeatedByteA;
+
+ break;
+ }
+
+ repeatMode = false;
+ count = (s * 2) - 1;
+
+ destination[outPosition++] = source[inPosition++];
+
+ break;
}
-
- if(s <= 0)
- continue;
-
- _repeatMode = false;
- _count = (s * 2) - 1;
-
- return _inStream.ReadByte();
}
+
+ return outPosition;
}
}
}
\ No newline at end of file
diff --git a/AaruBenchmark/Benchs.cs b/AaruBenchmark/Benchs.cs
index 8c90483..e477eba 100644
--- a/AaruBenchmark/Benchs.cs
+++ b/AaruBenchmark/Benchs.cs
@@ -12,7 +12,7 @@ namespace AaruBenchmark
public void Aaru() => Compression.Aaru.AppleRle();
[Benchmark]
- public void Aaru6() => Compression.Aaru6.AppleRle();
+ public void Aaru6() => Aaru6Compressions.AppleRle();
}
[SimpleJob(RuntimeMoniker.Net60)]
@@ -22,7 +22,7 @@ namespace AaruBenchmark
public void Aaru() => Compression.Aaru.TeleDiskLzh();
[Benchmark]
- public void Aaru6() => Compression.Aaru6.TeleDiskLzh();
+ public void Aaru6() => Aaru6Compressions.TeleDiskLzh();
}
[SimpleJob(RuntimeMoniker.Net60)]
diff --git a/AaruBenchmark/Compression/Aaru6.cs b/AaruBenchmark/Compression/Aaru6Compressions.cs
similarity index 83%
rename from AaruBenchmark/Compression/Aaru6.cs
rename to AaruBenchmark/Compression/Aaru6Compressions.cs
index a6b9750..d4c6f5e 100644
--- a/AaruBenchmark/Compression/Aaru6.cs
+++ b/AaruBenchmark/Compression/Aaru6Compressions.cs
@@ -4,11 +4,11 @@ using Aaru6.Compression;
namespace AaruBenchmark.Compression
{
- public class Aaru6
+ public class Aaru6Compressions
{
public static void AppleRle()
{
- const int bufferSize = 20960;
+ const int bufferSize = 32768;
byte[] input = new byte[1102];
var fs = new FileStream(Path.Combine(Program.Folder, "apple_rle.bin"), FileMode.Open, FileAccess.Read);
@@ -19,12 +19,12 @@ namespace AaruBenchmark.Compression
byte[] output = new byte[bufferSize];
- var rle = new AppleRle(new MemoryStream(input));
+ int realSize = Aaru6.Compression.AppleRle.DecodeBuffer(input, output);
- for(int i = 0; i < bufferSize; i++)
- output[i] = (byte)rle.ProduceByte();
+ if(realSize != 20960)
+ throw new InvalidDataException("Incorrect decompressed size");
- string crc = Crc32Context.Data(output, out _);
+ string crc = Crc32Context.Data(output, (uint)realSize, out _);
if(crc != "3525ef06")
throw new InvalidDataException("Incorrect decompressed checksum");
diff --git a/Benchmarks.ods b/Benchmarks.ods
index 6bd76e4..7fa0b63 100644
Binary files a/Benchmarks.ods and b/Benchmarks.ods differ