mirror of
https://github.com/aaru-dps/Aaru.Compression.Native.git
synced 2025-12-16 19:24:31 +00:00
Change Apple RLE algorithm for a faster version.
This commit is contained in:
59
apple_rle.c
59
apple_rle.c
@@ -23,55 +23,51 @@
|
|||||||
#include "library.h"
|
#include "library.h"
|
||||||
#include "apple_rle.h"
|
#include "apple_rle.h"
|
||||||
|
|
||||||
// readonly Stream _inStream;
|
AARU_EXPORT int32_t AARU_CALL apple_rle_decode_buffer(uint8_t* dst_buffer,
|
||||||
static int32_t count;
|
int32_t dst_size,
|
||||||
static bool nextA; // true if A, false if B
|
const uint8_t* src_buffer,
|
||||||
static uint8_t repeatedByteA, repeatedByteB;
|
int32_t src_size)
|
||||||
static bool repeatMode; // true if we're repeating, false if we're just copying
|
|
||||||
|
|
||||||
/// <summary>Initializes a decompressor for the specified stream</summary>
|
|
||||||
/// <param name="stream">Stream containing the compressed data</param>
|
|
||||||
AARU_EXPORT void AARU_CALL apple_rle_reset()
|
|
||||||
{
|
{
|
||||||
repeatedByteA = repeatedByteB = 0;
|
static int32_t count = 0;
|
||||||
count = 0;
|
static bool nextA = true; // true if A, false if B
|
||||||
nextA = true;
|
static uint8_t repeatedByteA = 0, repeatedByteB = 0;
|
||||||
repeatMode = false;
|
static bool repeatMode = false; // true if we're repeating, false if we're just copying
|
||||||
}
|
int32_t in_pos = 0, out_pos = 0;
|
||||||
|
|
||||||
/// <summary>Decompresses a byte</summary>
|
while(in_pos <= src_size && out_pos <= dst_size)
|
||||||
/// <returns>Decompressed byte</returns>
|
|
||||||
AARU_EXPORT int32_t AARU_CALL apple_rle_produce_byte(const uint8_t* buffer, int32_t length, int32_t* position)
|
|
||||||
{
|
{
|
||||||
if(repeatMode && count > 0)
|
if(repeatMode && count > 0)
|
||||||
{
|
{
|
||||||
count--;
|
(count)--;
|
||||||
|
|
||||||
if(nextA)
|
if(nextA)
|
||||||
{
|
{
|
||||||
nextA = false;
|
nextA = false;
|
||||||
|
|
||||||
return repeatedByteA;
|
dst_buffer[out_pos++] = repeatedByteA;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextA = true;
|
nextA = true;
|
||||||
|
|
||||||
return repeatedByteB;
|
dst_buffer[out_pos++] = repeatedByteB;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!repeatMode && count > 0)
|
if(!repeatMode && count > 0)
|
||||||
{
|
{
|
||||||
count--;
|
count--;
|
||||||
|
|
||||||
return buffer[(*position)++];
|
dst_buffer[out_pos++] = src_buffer[in_pos++];
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*position == length) return -1;
|
if(in_pos == src_size) break;
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
uint8_t b1 = buffer[(*position)++];
|
uint8_t b1 = src_buffer[in_pos++];
|
||||||
uint8_t b2 = buffer[(*position)++];
|
uint8_t b2 = src_buffer[in_pos++];
|
||||||
int16_t s = (int16_t)((b1 << 8) | b2);
|
int16_t s = (int16_t)((b1 << 8) | b2);
|
||||||
|
|
||||||
if(s == 0 || s >= DART_CHUNK || s <= -DART_CHUNK) continue;
|
if(s == 0 || s >= DART_CHUNK || s <= -DART_CHUNK) continue;
|
||||||
@@ -79,19 +75,22 @@ AARU_EXPORT int32_t AARU_CALL apple_rle_produce_byte(const uint8_t* buffer, int3
|
|||||||
if(s < 0)
|
if(s < 0)
|
||||||
{
|
{
|
||||||
repeatMode = true;
|
repeatMode = true;
|
||||||
repeatedByteA = buffer[(*position)++];
|
repeatedByteA = src_buffer[in_pos++];
|
||||||
repeatedByteB = buffer[(*position)++];
|
repeatedByteB = src_buffer[in_pos++];
|
||||||
count = (-s * 2) - 1;
|
count = (-s * 2) - 1;
|
||||||
nextA = false;
|
nextA = false;
|
||||||
|
|
||||||
return repeatedByteA;
|
dst_buffer[out_pos++] = repeatedByteA;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s <= 0) continue;
|
|
||||||
|
|
||||||
repeatMode = false;
|
repeatMode = false;
|
||||||
count = (s * 2) - 1;
|
count = (s * 2) - 1;
|
||||||
|
|
||||||
return buffer[(*position)++];
|
dst_buffer[out_pos++] = src_buffer[in_pos++];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return out_pos;
|
||||||
|
}
|
||||||
@@ -21,7 +21,9 @@
|
|||||||
|
|
||||||
#define DART_CHUNK 20960
|
#define DART_CHUNK 20960
|
||||||
|
|
||||||
AARU_EXPORT void AARU_CALL apple_rle_reset();
|
AARU_EXPORT int32_t AARU_CALL apple_rle_decode_buffer(uint8_t* dst_buffer,
|
||||||
AARU_EXPORT int32_t AARU_CALL apple_rle_produce_byte(const uint8_t* buffer, int32_t length, int32_t* position);
|
int32_t dst_size,
|
||||||
|
const uint8_t* src_buffer,
|
||||||
|
int32_t src_size);
|
||||||
|
|
||||||
#endif // AARU_CHECKSUMS_NATIVE__APPLE_RLE_H_
|
#endif // AARU_CHECKSUMS_NATIVE__APPLE_RLE_H_
|
||||||
|
|||||||
@@ -67,13 +67,11 @@ class apple_rleFixture : public ::testing::Test
|
|||||||
|
|
||||||
TEST_F(apple_rleFixture, apple_rle)
|
TEST_F(apple_rleFixture, apple_rle)
|
||||||
{
|
{
|
||||||
auto *outBuf = (uint8_t*)malloc(20960);
|
auto *outBuf = (uint8_t*)malloc(32768);
|
||||||
int32_t position = 0;
|
|
||||||
|
|
||||||
apple_rle_reset();
|
auto decoded = apple_rle_decode_buffer(outBuf, 32768, buffer, 1102);
|
||||||
|
|
||||||
for(int i = 0; i < 20960; i++)
|
EXPECT_EQ(decoded, 20960);
|
||||||
outBuf[i] = (uint8_t)apple_rle_produce_byte(buffer, 1102, &position);
|
|
||||||
|
|
||||||
auto crc = crc32_data(outBuf, 20960);
|
auto crc = crc32_data(outBuf, 20960);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user