Initial commit
This commit is contained in:
71
src/compressor.cpp
Normal file
71
src/compressor.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "compressor.h"
|
||||
|
||||
static constexpr uint8_t RLE_MARKER = 0xFF;
|
||||
|
||||
bool compressBuffer(const uint8_t *in, size_t in_len, uint8_t *out, size_t out_max, size_t &out_len) {
|
||||
out_len = 0;
|
||||
if (!in || !out) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
while (i < in_len) {
|
||||
uint8_t value = in[i];
|
||||
size_t run = 1;
|
||||
while (i + run < in_len && in[i + run] == value && run < 255) {
|
||||
run++;
|
||||
}
|
||||
|
||||
if (value == RLE_MARKER || run >= 4) {
|
||||
if (out_len + 3 > out_max) {
|
||||
return false;
|
||||
}
|
||||
out[out_len++] = RLE_MARKER;
|
||||
out[out_len++] = static_cast<uint8_t>(run);
|
||||
out[out_len++] = value;
|
||||
} else {
|
||||
if (out_len + run > out_max) {
|
||||
return false;
|
||||
}
|
||||
for (size_t j = 0; j < run; ++j) {
|
||||
out[out_len++] = value;
|
||||
}
|
||||
}
|
||||
|
||||
i += run;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool decompressBuffer(const uint8_t *in, size_t in_len, uint8_t *out, size_t out_max, size_t &out_len) {
|
||||
out_len = 0;
|
||||
if (!in || !out) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
while (i < in_len) {
|
||||
uint8_t value = in[i++];
|
||||
if (value == RLE_MARKER) {
|
||||
if (i + 1 >= in_len) {
|
||||
return false;
|
||||
}
|
||||
uint8_t run = in[i++];
|
||||
uint8_t data = in[i++];
|
||||
if (out_len + run > out_max) {
|
||||
return false;
|
||||
}
|
||||
for (uint8_t j = 0; j < run; ++j) {
|
||||
out[out_len++] = data;
|
||||
}
|
||||
} else {
|
||||
if (out_len + 1 > out_max) {
|
||||
return false;
|
||||
}
|
||||
out[out_len++] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user