diff --git a/src/rle.c b/src/rle.c new file mode 100644 index 0000000..74e3d6d --- /dev/null +++ b/src/rle.c @@ -0,0 +1,66 @@ + +#include "rle.h" +#include "fileops.h" + +uint8_t rle_file_getc() { + static uint16_t rle_filled = 0; + static uint8_t data; + if(!rle_filled) { + data = file_getc(); + switch(data) { + case RLE_RUN: + data = file_getc(); + rle_filled = file_getc()-1; + break; + case RLE_RUNLONG: + data = file_getc(); + rle_filled = file_getc(); + rle_filled |= file_getc() << 8; + rle_filled--; + break; + case RLE_ESC: + data = file_getc(); + break; + } + } else { + rle_filled--; + } + if(file_status || file_res) rle_filled = 0; + return data; +} + +void rle_mem_init(const uint8_t* address, uint32_t len) { + rle_mem_ptr = address; + rle_mem_endptr = address+len; + rle_state = 0; +} + +uint8_t rle_mem_getc() { + static uint16_t rle_mem_filled = 0; + static uint8_t rle_mem_data; + if(!rle_mem_filled) { + rle_mem_data = *(rle_mem_ptr++); + switch(rle_mem_data) { + case RLE_RUN: + rle_mem_data = *(rle_mem_ptr)++; + rle_mem_filled = *(rle_mem_ptr)++ - 1; + break; + case RLE_RUNLONG: + rle_mem_data = *(rle_mem_ptr)++; + rle_mem_filled = *(rle_mem_ptr)++; + rle_mem_filled |= *(rle_mem_ptr)++ << 8; + rle_mem_filled--; + break; + case RLE_ESC: + rle_mem_data = *(rle_mem_ptr)++; + break; + } + } else { + rle_mem_filled--; + } + if(rle_mem_ptr>=rle_mem_endptr){ + rle_mem_filled = 0; + rle_state = 1; + } + return rle_mem_data; +} diff --git a/src/rle.h b/src/rle.h new file mode 100644 index 0000000..9747043 --- /dev/null +++ b/src/rle.h @@ -0,0 +1,17 @@ +#ifndef RLE_H +#define RLE_H + +#include + +#define RLE_ESC (0x9b) +#define RLE_RUN (0x5b) +#define RLE_RUNLONG (0x77) + +uint8_t rle_file_getc(void); +uint8_t rle_mem_getc(void); +void rle_mem_init(const uint8_t *address, uint32_t len); +const uint8_t *rle_mem_ptr; +const uint8_t *rle_mem_endptr; +uint8_t rle_state; + +#endif