Code refactor and cleanup.

This commit is contained in:
2022-12-02 15:33:35 +00:00
parent b1b002b15f
commit 3b83219146
33 changed files with 6879 additions and 6995 deletions

View File

@@ -24,141 +24,139 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Runtime.CompilerServices;
namespace Aaru6.Compression
namespace Aaru6.Compression;
/// <summary>Implements the Apple version of RLE</summary>
public class ADC
{
/// <summary>Implements the Apple version of RLE</summary>
public class ADC
const int PLAIN = 1;
const int TWO_BYTE = 2;
const int THREE_BYTE = 3;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetChunkType(byte byt) => (byt & 0x80) == 0x80
? PLAIN
: (byt & 0x40) == 0x40
? THREE_BYTE
: TWO_BYTE;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetChunkSize(byte byt) => GetChunkType(byt) switch
{
const int PLAIN = 1;
const int TWO_BYTE = 2;
const int THREE_BYTE = 3;
PLAIN => (byt & 0x7F) + 1,
TWO_BYTE => ((byt & 0x3F) >> 2) + 3,
THREE_BYTE => (byt & 0x3F) + 4,
_ => -1
};
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetChunkType(byte byt) => (byt & 0x80) == 0x80
? PLAIN
: (byt & 0x40) == 0x40
? THREE_BYTE
: TWO_BYTE;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetOffset(ReadOnlySpan<byte> chunk) => GetChunkType(chunk[0]) switch
{
PLAIN => 0,
TWO_BYTE => ((chunk[0] & 0x03) << 8) + chunk[1],
THREE_BYTE => (chunk[1] << 8) + chunk[2],
_ => -1
};
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetChunkSize(byte byt) => GetChunkType(byt) switch
/// <summary>Decompresses a byte buffer that's compressed with ADC</summary>
/// <param name="source">Compressed buffer</param>
/// <param name="destination">Buffer to hold decompressed data</param>
/// <returns>How many bytes are stored on <paramref name="destination" /></returns>
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
public static int DecodeBuffer(byte[] source, byte[] destination)
{
int inputPosition = 0;
int chunkSize;
int offset;
int chunkType;
int outPosition = 0;
Span<byte> temp = stackalloc byte[3];
while(inputPosition < source.Length)
{
PLAIN => (byt & 0x7F) + 1,
TWO_BYTE => ((byt & 0x3F) >> 2) + 3,
THREE_BYTE => (byt & 0x3F) + 4,
_ => -1
};
byte readByte = source[inputPosition++];
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetOffset(ReadOnlySpan<byte> chunk) => GetChunkType(chunk[0]) switch
{
PLAIN => 0,
TWO_BYTE => ((chunk[0] & 0x03) << 8) + chunk[1],
THREE_BYTE => (chunk[1] << 8) + chunk[2],
_ => -1
};
chunkType = GetChunkType(readByte);
/// <summary>Decompresses a byte buffer that's compressed with ADC</summary>
/// <param name="source">Compressed buffer</param>
/// <param name="destination">Buffer to hold decompressed data</param>
/// <returns>How many bytes are stored on <paramref name="destination" /></returns>
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
public static int DecodeBuffer(byte[] source, byte[] destination)
{
int inputPosition = 0;
int chunkSize;
int offset;
int chunkType;
int outPosition = 0;
Span<byte> temp = stackalloc byte[3];
while(inputPosition < source.Length)
switch(chunkType)
{
byte readByte = source[inputPosition++];
case PLAIN:
chunkSize = GetChunkSize(readByte);
chunkType = GetChunkType(readByte);
if(outPosition + chunkSize > destination.Length)
goto finished;
switch(chunkType)
{
case PLAIN:
chunkSize = GetChunkSize(readByte);
Array.Copy(source, inputPosition, destination, outPosition, chunkSize);
outPosition += chunkSize;
inputPosition += chunkSize;
if(outPosition + chunkSize > destination.Length)
goto finished;
break;
case TWO_BYTE:
chunkSize = GetChunkSize(readByte);
temp[0] = readByte;
temp[1] = source[inputPosition++];
offset = GetOffset(temp);
Array.Copy(source, inputPosition, destination, outPosition, chunkSize);
outPosition += chunkSize;
inputPosition += chunkSize;
if(outPosition + chunkSize > destination.Length)
goto finished;
break;
case TWO_BYTE:
chunkSize = GetChunkSize(readByte);
temp[0] = readByte;
temp[1] = source[inputPosition++];
offset = GetOffset(temp);
if(offset == 0)
{
byte lastByte = destination[outPosition - 1];
if(outPosition + chunkSize > destination.Length)
goto finished;
if(offset == 0)
for(int i = 0; i < chunkSize; i++)
{
byte lastByte = destination[outPosition - 1];
for(int i = 0; i < chunkSize; i++)
{
destination[outPosition] = lastByte;
outPosition++;
}
destination[outPosition] = lastByte;
outPosition++;
}
else
}
else
{
for(int i = 0; i < chunkSize; i++)
{
for(int i = 0; i < chunkSize; i++)
{
destination[outPosition] = destination[outPosition - offset - 1];
outPosition++;
}
destination[outPosition] = destination[outPosition - offset - 1];
outPosition++;
}
}
break;
case THREE_BYTE:
chunkSize = GetChunkSize(readByte);
temp[0] = readByte;
temp[1] = source[inputPosition++];
temp[2] = source[inputPosition++];
offset = GetOffset(temp);
break;
case THREE_BYTE:
chunkSize = GetChunkSize(readByte);
temp[0] = readByte;
temp[1] = source[inputPosition++];
temp[2] = source[inputPosition++];
offset = GetOffset(temp);
if(outPosition + chunkSize > destination.Length)
goto finished;
if(outPosition + chunkSize > destination.Length)
goto finished;
if(offset == 0)
if(offset == 0)
{
byte lastByte = destination[outPosition - 1];
for(int i = 0; i < chunkSize; i++)
{
byte lastByte = destination[outPosition - 1];
for(int i = 0; i < chunkSize; i++)
{
destination[outPosition] = lastByte;
outPosition++;
}
destination[outPosition] = lastByte;
outPosition++;
}
else
}
else
{
for(int i = 0; i < chunkSize; i++)
{
for(int i = 0; i < chunkSize; i++)
{
destination[outPosition] = destination[outPosition - offset - 1];
outPosition++;
}
destination[outPosition] = destination[outPosition - offset - 1];
outPosition++;
}
}
break;
}
break;
}
finished:
return outPosition;
}
finished:
return outPosition;
}
}