mirror of
https://github.com/whowechina/aic_pico.git
synced 2024-11-14 17:47:35 +01:00
Support images with indexed colors
This commit is contained in:
parent
b7bbb51c52
commit
0daccd65d3
@ -25,16 +25,15 @@ const uint16_t white_pallete[16] = {
|
|||||||
|
|
||||||
void gfx_anima_draw(const anima_t *ani, int x, int y, int frame, const uint16_t pallete[16])
|
void gfx_anima_draw(const anima_t *ani, int x, int y, int frame, const uint16_t pallete[16])
|
||||||
{
|
{
|
||||||
uint16_t width = ani->width;
|
rle_decoder_t rle;
|
||||||
uint16_t height = ani->height;
|
rle_init(&rle,
|
||||||
frame = frame % ani->frames;
|
&(rle_src_t){ ani->data + ani->index[frame % ani->frames],
|
||||||
|
RLE_RLE_X, ani->size, 0x00 }
|
||||||
|
);
|
||||||
|
|
||||||
rle_t rle;
|
for (int j = 0; j < ani->height; j++) {
|
||||||
rle_x_init(&rle, ani->data + ani->index[frame], ani->size, 0);
|
for (int i = 0; i < ani->width / 2; i++) {
|
||||||
|
uint8_t value = rle_get_uint8(&rle);
|
||||||
for (int j = 0; j < height; j++) {
|
|
||||||
for (int i = 0; i < width / 2; i++) {
|
|
||||||
uint8_t value = rle_x_get_uint8(&rle);
|
|
||||||
st7789_pixel_raw(x + i * 2, y + j, pallete[value >> 4]);
|
st7789_pixel_raw(x + i * 2, y + j, pallete[value >> 4]);
|
||||||
st7789_pixel_raw(x + i * 2 + 1, y + j, pallete[value & 0x0f]);
|
st7789_pixel_raw(x + i * 2 + 1, y + j, pallete[value & 0x0f]);
|
||||||
}
|
}
|
||||||
@ -43,51 +42,44 @@ void gfx_anima_draw(const anima_t *ani, int x, int y, int frame, const uint16_t
|
|||||||
|
|
||||||
void gfx_anima_mix(const anima_t *ani, int x, int y, int frame, uint16_t color)
|
void gfx_anima_mix(const anima_t *ani, int x, int y, int frame, uint16_t color)
|
||||||
{
|
{
|
||||||
uint16_t width = ani->width;
|
rle_decoder_t rle;
|
||||||
uint16_t height = ani->height;
|
rle_init(&rle,
|
||||||
frame = frame % ani->frames;
|
&(rle_src_t){ ani->data + ani->index[frame % ani->frames],
|
||||||
|
RLE_RLE_X, ani->size, 0x00 }
|
||||||
|
);
|
||||||
|
|
||||||
rle_t rle;
|
for (int j = 0; j < ani->height; j++) {
|
||||||
rle_x_init(&rle, ani->data + ani->index[frame], ani->size, 0);
|
for (int i = 0; i < ani->width / 2; i++) {
|
||||||
for (int j = 0; j < height; j++) {
|
uint8_t value = rle_get_uint8(&rle);
|
||||||
for (int i = 0; i < width / 2; i++) {
|
|
||||||
uint8_t value = rle_x_get_uint8(&rle);
|
|
||||||
st7789_pixel(x + i * 2, y + j, color, value >> 4 << 4);
|
st7789_pixel(x + i * 2, y + j, color, value >> 4 << 4);
|
||||||
st7789_pixel(x + i * 2 + 1, y + j, color, (value & 0x0f) << 4);
|
st7789_pixel(x + i * 2 + 1, y + j, color, (value & 0x0f) << 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static rle_t pixels_rle;
|
|
||||||
static rle_t alpha_rle;
|
|
||||||
static int pixels_pos;
|
|
||||||
static int alpha_pos;
|
|
||||||
|
|
||||||
#define INIT_RLE(which) \
|
|
||||||
if (img->which##_rle_x) { \
|
|
||||||
rle_x_init(&which##_rle, img->which, img->width * img->height, img->which##_x); \
|
|
||||||
} else if (img->which##_rle) { \
|
|
||||||
rle_init(&which##_rle, img->which, img->width * img->height); \
|
|
||||||
} else { \
|
|
||||||
which##_pos = 0; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GET_DATA(which, type) \
|
|
||||||
(img->which##_rle_x ? \
|
|
||||||
rle_x_get_##type(&which##_rle) : \
|
|
||||||
img->which##_rle ? \
|
|
||||||
rle_get_##type(&which##_rle) :\
|
|
||||||
img->which[which##_pos++])
|
|
||||||
|
|
||||||
void gfx_img_draw(int x, int y, const image_t *img)
|
void gfx_img_draw(int x, int y, const image_t *img)
|
||||||
{
|
{
|
||||||
INIT_RLE(pixels);
|
rle_decoder_t pixels_rle;
|
||||||
INIT_RLE(alpha);
|
rle_decoder_t alpha_rle;
|
||||||
|
|
||||||
|
rle_init(&pixels_rle, &img->pixels);
|
||||||
|
|
||||||
|
if (!img->pallete && img->alpha.input) {
|
||||||
|
rle_init(&alpha_rle, &img->alpha);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < img->height; i++) {
|
for (int i = 0; i < img->height; i++) {
|
||||||
for (int j = 0; j < img->width; j++) {
|
for (int j = 0; j < img->width; j++) {
|
||||||
uint16_t pixel = GET_DATA(pixels, uint16);
|
uint16_t pixel;
|
||||||
uint8_t mix = img->alpha ? GET_DATA(alpha, uint8) : 0xff;
|
uint8_t mix;
|
||||||
|
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;
|
||||||
|
}
|
||||||
st7789_pixel(x + j, y + i, pixel, mix);
|
st7789_pixel(x + j, y + i, pixel, mix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define GFX_H
|
#define GFX_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "rle.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t width;
|
uint16_t width;
|
||||||
@ -16,15 +17,9 @@ typedef struct {
|
|||||||
uint16_t width;
|
uint16_t width;
|
||||||
uint16_t height;
|
uint16_t height;
|
||||||
|
|
||||||
const uint16_t *pixels;
|
rle_src_t pixels;
|
||||||
bool pixels_rle;
|
const uint32_t *pallete; // always 256 colors, RGB565 (bits 0..15) + alpha (bits 16..23)
|
||||||
bool pixels_rle_x;
|
rle_src_t alpha; // ignored when pallete exists
|
||||||
uint16_t pixels_x;
|
|
||||||
|
|
||||||
const uint8_t *alpha;
|
|
||||||
bool alpha_rle;
|
|
||||||
bool alpha_rle_x;
|
|
||||||
uint8_t alpha_x;
|
|
||||||
} image_t;
|
} image_t;
|
||||||
|
|
||||||
extern const uint16_t white_pallete[16];
|
extern const uint16_t white_pallete[16];
|
||||||
|
@ -7,57 +7,40 @@
|
|||||||
|
|
||||||
#include "rle.h"
|
#include "rle.h"
|
||||||
|
|
||||||
void rle_init(rle_t *rle, const void *input, size_t size)
|
void rle_init(rle_decoder_t *rle, const rle_src_t *src)
|
||||||
{
|
{
|
||||||
rle->src = input;
|
rle->src = *src;
|
||||||
rle->size = size;
|
|
||||||
rle->pos = 0;
|
rle->pos = 0;
|
||||||
rle->counter = 0;
|
rle->counter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rle_x_init(rle_t *rle, const void *input, size_t size, uint32_t x)
|
bool rle_eof(rle_decoder_t *rle)
|
||||||
{
|
{
|
||||||
rle->x = x;
|
return (!rle->counter) && (rle->pos >= rle->src.size);
|
||||||
rle_init(rle, input, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rle_eof(rle_t *rle)
|
#define RLE_GET_TEMPLATE(type) \
|
||||||
{
|
if (rle->src.encoding == RLE_NONE) { \
|
||||||
return (!rle->counter) && (rle->pos >= rle->size);
|
return ((const type *)rle->src.input)[rle->pos++]; \
|
||||||
}
|
} \
|
||||||
|
|
||||||
#define RLE_GET_TEMPLATE(type, condition) \
|
|
||||||
if (rle->counter) { \
|
if (rle->counter) { \
|
||||||
rle->counter--; \
|
rle->counter--; \
|
||||||
} else if (rle->pos < rle->size) { \
|
} else if (rle->pos < rle->src.size) { \
|
||||||
rle->value = ((const type *)rle->src)[rle->pos++]; \
|
rle->value = ((const type *)rle->src.input)[rle->pos++]; \
|
||||||
if (condition) { \
|
if ((rle->src.encoding == RLE_RLE) || (rle->value == rle->src.x)) { \
|
||||||
rle->counter = ((const type *)rle->src)[rle->pos++]; \
|
rle->counter = ((const type *)rle->src.input)[rle->pos++]; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
return rle->value;
|
return rle->value;
|
||||||
|
|
||||||
#define RLE_GET(type) RLE_GET_TEMPLATE(type, true)
|
uint8_t rle_get_uint8(rle_decoder_t *rle)
|
||||||
#define RLE_GET_X(type) RLE_GET_TEMPLATE(type, rle->value == rle->x)
|
|
||||||
|
|
||||||
uint8_t rle_get_uint8(rle_t *rle)
|
|
||||||
{
|
{
|
||||||
RLE_GET(uint8_t);
|
RLE_GET_TEMPLATE(uint8_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t rle_get_uint16(rle_t *rle)
|
uint16_t rle_get_uint16(rle_decoder_t *rle)
|
||||||
{
|
{
|
||||||
RLE_GET(uint16_t);
|
RLE_GET_TEMPLATE(uint16_t);
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t rle_x_get_uint8(rle_t *rle)
|
|
||||||
{
|
|
||||||
RLE_GET_X(uint8_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t rle_x_get_uint16(rle_t *rle)
|
|
||||||
{
|
|
||||||
RLE_GET_X(uint16_t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PUSH_DATA(data) \
|
#define PUSH_DATA(data) \
|
||||||
|
@ -10,25 +10,32 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RLE_NONE,
|
||||||
|
RLE_RLE,
|
||||||
|
RLE_RLE_X
|
||||||
|
} rle_encoding_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const void *src;
|
const uint8_t *input;
|
||||||
|
rle_encoding_t encoding;
|
||||||
size_t size;
|
size_t size;
|
||||||
int pos;
|
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
|
} rle_src_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
rle_src_t src;
|
||||||
|
int pos;
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
uint32_t counter;
|
uint32_t counter;
|
||||||
} rle_t;
|
} rle_decoder_t;
|
||||||
|
|
||||||
void rle_init(rle_t *rle, const void *input, size_t size);
|
void rle_init(rle_decoder_t *rle, const rle_src_t *src);
|
||||||
void rle_x_init(rle_t *rle, const void *input, size_t size, uint32_t x);
|
|
||||||
|
|
||||||
bool rle_eof(rle_t *rle);
|
bool rle_eof(rle_decoder_t *rle);
|
||||||
|
|
||||||
uint8_t rle_get_uint8(rle_t *rle);
|
uint8_t rle_get_uint8(rle_decoder_t *rle);
|
||||||
uint16_t rle_get_uint16(rle_t *rle);
|
uint16_t rle_get_uint16(rle_decoder_t *rle);
|
||||||
|
|
||||||
uint8_t rle_x_get_uint8(rle_t *rle);
|
|
||||||
uint16_t rle_x_get_uint16(rle_t *rle);
|
|
||||||
|
|
||||||
/* No protection, make sure output is large enough */
|
/* No protection, make sure output is large enough */
|
||||||
size_t rle_encode_uint8(uint8_t *output, const uint8_t *input, size_t size);
|
size_t rle_encode_uint8(uint8_t *output, const uint8_t *input, size_t size);
|
||||||
|
Loading…
Reference in New Issue
Block a user