mirror of
https://github.com/whowechina/aic_pico.git
synced 2024-11-12 00:40:47 +01:00
Bitwidth support for rle
This commit is contained in:
parent
c785454607
commit
37859d664d
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user