72 lines
1.5 KiB
C++
72 lines
1.5 KiB
C++
#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;
|
|
}
|