/** * 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 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; }