1
0
mirror of https://github.com/whowechina/aic_pico.git synced 2024-09-23 18:48:24 +02:00

Bitwidth support for rle

This commit is contained in:
whowechina 2024-06-16 22:19:34 +08:00
parent c785454607
commit 37859d664d
4 changed files with 49 additions and 24 deletions

View File

@ -28,14 +28,13 @@ void gfx_anima_draw(const anima_t *ani, int x, int y, int frame, const uint16_t
rle_decoder_t rle;
rle_init(&rle,
&(rle_src_t){ ani->data + ani->index[frame % ani->frames],
RLE_RLE_X, ani->size, 0x00 }
RLE_RLE_X, 4, ani->size, 0x00 }
);
for (int j = 0; j < ani->height; j++) {
for (int i = 0; i < ani->width / 2; i++) {
uint8_t value = rle_get_uint8(&rle);
st7789_pixel_raw(x + i * 2, y + j, pallete[value >> 4]);
st7789_pixel_raw(x + i * 2 + 1, y + j, pallete[value & 0x0f]);
for (int i = 0; i < ani->width; i++) {
uint8_t value = rle_get_uint4(&rle);
st7789_pixel_raw(x + i, y + j, pallete[value]);
}
}
}
@ -45,14 +44,13 @@ void gfx_anima_mix(const anima_t *ani, int x, int y, int frame, uint16_t color)
rle_decoder_t rle;
rle_init(&rle,
&(rle_src_t){ ani->data + ani->index[frame % ani->frames],
RLE_RLE_X, ani->size, 0x00 }
RLE_RLE_X, 4, ani->size, 0x00 }
);
for (int j = 0; j < ani->height; j++) {
for (int i = 0; i < ani->width / 2; i++) {
uint8_t value = rle_get_uint8(&rle);
st7789_pixel(x + i * 2, y + j, color, value >> 4 << 4);
st7789_pixel(x + i * 2 + 1, y + j, color, (value & 0x0f) << 4);
for (int i = 0; i < ani->width; i++) {
uint8_t value = rle_get_uint4(&rle);
st7789_pixel(x + i, y + j, color, value);
}
}
}
@ -64,22 +62,22 @@ void gfx_img_draw(int x, int y, const image_t *img)
rle_init(&pixels_rle, &img->pixels);
if (!img->pallete && img->alpha.input) {
if (img->alpha.input) {
rle_init(&alpha_rle, &img->alpha);
}
for (int i = 0; i < img->height; i++) {
for (int j = 0; j < img->width; j++) {
uint16_t pixel;
uint8_t mix;
uint32_t pixel = rle_get(&pixels_rle);
uint32_t mix = img->alpha.input ? rle_get(&alpha_rle) : 0xff;
if (img->pallete) {
uint32_t color = img->pallete[rle_get_uint8(&pixels_rle)];
pixel = (uint16_t)color;
mix = color >> 16;
} else {
pixel = rle_get_uint16(&pixels_rle);
mix = img->alpha.input ? rle_get_uint8(&alpha_rle) : 0xff;
pixel = img->pallete[pixel];
if (!img->alpha.input) {
mix = pixel >> 16;
}
}
st7789_pixel(x + j, y + i, pixel, mix);
}
}

View File

@ -16,10 +16,9 @@ typedef struct {
typedef struct {
uint16_t width;
uint16_t height;
rle_src_t pixels;
const uint32_t *pallete; // always 256 colors, RGB565 (bits 0..15) + alpha (bits 16..23)
rle_src_t alpha; // ignored when pallete exists
rle_src_t alpha; // ignored when pallete exists, always 4bpp
} image_t;
extern const uint16_t white_pallete[16];

View File

@ -16,7 +16,7 @@ void rle_init(rle_decoder_t *rle, const rle_src_t *src)
bool rle_eof(rle_decoder_t *rle)
{
return (!rle->counter) && (rle->pos >= rle->src.size);
return (!rle->remaining) && (!rle->counter) && (rle->pos >= rle->src.size);
}
#define RLE_GET_TEMPLATE(type) \
@ -30,17 +30,41 @@ bool rle_eof(rle_decoder_t *rle)
if ((rle->src.encoding == RLE_RLE) || (rle->value == rle->src.x)) { \
rle->counter = ((const type *)rle->src.input)[rle->pos++]; \
} \
} \
return rle->value;
}
uint8_t rle_get_uint8(rle_decoder_t *rle)
{
RLE_GET_TEMPLATE(uint8_t);
return rle->value;
}
uint16_t rle_get_uint16(rle_decoder_t *rle)
{
RLE_GET_TEMPLATE(uint16_t);
return rle->value;
}
uint8_t rle_get_uint4(rle_decoder_t *rle)
{
if (rle->remaining) {
rle->remaining = false;
return rle->value & 0x0f;
}
RLE_GET_TEMPLATE(uint8_t);
rle->remaining = true;
return rle->value >> 4;
}
uint32_t rle_get(rle_decoder_t *rle)
{
if (rle->src.bits == 4) {
return rle_get_uint4(rle);
} else if (rle->src.bits == 8) {
return rle_get_uint8(rle);
} else {
return rle_get_uint16(rle);
}
}
#define PUSH_DATA(data) \

View File

@ -19,6 +19,7 @@ typedef enum {
typedef struct {
const uint8_t *input;
rle_encoding_t encoding;
size_t bits;
size_t size;
uint32_t x;
} rle_src_t;
@ -28,6 +29,7 @@ typedef struct {
int pos;
uint32_t value;
uint32_t counter;
bool remaining;
} rle_decoder_t;
void rle_init(rle_decoder_t *rle, const rle_src_t *src);
@ -36,6 +38,8 @@ bool rle_eof(rle_decoder_t *rle);
uint8_t rle_get_uint8(rle_decoder_t *rle);
uint16_t rle_get_uint16(rle_decoder_t *rle);
uint8_t rle_get_uint4(rle_decoder_t *rle);
uint32_t rle_get(rle_decoder_t *rle);
/* No protection, make sure output is large enough */
size_t rle_encode_uint8(uint8_t *output, const uint8_t *input, size_t size);