dreamstack/devices/waveshare-p4-panel/main/ds_codec.c

56 lines
1.7 KiB
C

/**
* DreamStack Delta Codec — C port for ESP32-P4
*
* Ported from engine/ds-stream/src/codec.rs (lines 109-179)
* Exact same encoding: 0x00 + 2-byte LE count = zero run.
*/
#include "ds_codec.h"
#include <string.h>
size_t ds_rle_decode(const uint8_t *compressed, size_t comp_len,
uint8_t *output, size_t out_cap) {
size_t i = 0; // input position
size_t o = 0; // output position
while (i < comp_len) {
if (compressed[i] == 0x00) {
// Zero run: 0x00 + count_lo + count_hi
if (i + 2 >= comp_len) break;
uint16_t count = (uint16_t)compressed[i + 1]
| ((uint16_t)compressed[i + 2] << 8);
if (o + count > out_cap) return 0; // overflow
memset(output + o, 0, count);
o += count;
i += 3;
} else {
// Literal byte
if (o >= out_cap) return 0;
output[o++] = compressed[i++];
}
}
return o;
}
void ds_xor_apply(uint8_t *framebuffer, const uint8_t *delta, size_t len) {
// Process 4 bytes at a time for speed on 32-bit RISC-V
size_t i = 0;
size_t aligned = len & ~3u;
for (; i < aligned; i += 4) {
*(uint32_t *)(framebuffer + i) ^= *(const uint32_t *)(delta + i);
}
for (; i < len; i++) {
framebuffer[i] ^= delta[i];
}
}
int ds_apply_delta_rle(uint8_t *framebuffer, size_t fb_len,
const uint8_t *compressed, size_t comp_len,
uint8_t *scratch) {
size_t decoded_len = ds_rle_decode(compressed, comp_len, scratch, fb_len);
if (decoded_len == 0 || decoded_len != fb_len) {
return -1;
}
ds_xor_apply(framebuffer, scratch, fb_len);
return 0;
}