Commit 14d9754e authored by Mateusz Zalega's avatar Mateusz Zalega Committed by Rahix

feat(gfx): Moved RLE decoding code to lib/gfx

Signed-off-by: Mateusz Zalega's avatarMateusz Zalega <mateusz@appliedsourcery.com>
parent ee45bbd8
......@@ -6,31 +6,18 @@
#include "gfx.h"
#include "display.h"
/*
* "Decompress" splash-screen image. The algorithm works as follows:
*
* Each byte encodes up to 127 pixels in either white or black. The most
* significant bit determines the color, the remaining 7 bits determine the
* amount.
*/
static void bootloader_display_splash(void)
{
int idx = 0;
Color white = gfx_color(&display_screen, WHITE);
Color black = gfx_color(&display_screen, BLACK);
for (int i = 0; i < sizeof(splash); i++) {
Color color = (splash[i] & 0x80) ? white : black;
uint8_t length = splash[i] & 0x7f;
for (int j = 0; j < length; j++) {
uint16_t x = idx % 160;
uint16_t y = idx / 160;
gfx_setpixel(&display_screen, x, y, color);
idx++;
}
}
gfx_copy_region(
&display_screen,
0,
0,
160,
80,
GFX_RLE_MONO,
sizeof(splash),
(const void *)(splash)
);
gfx_update(&display_screen);
}
......
......@@ -34,8 +34,15 @@ int main(void)
mxc_delay(500000);
epic_disp_clear(0x0000);
if (strcmp(CARD10_VERSION, "v1.10") == 0) {
gfx_copy_region_raw(
&display_screen, 0, 0, 160, 80, 2, version_splash
gfx_copy_region(
&display_screen,
0,
0,
160,
80,
GFX_RAW,
sizeof(version_splash),
version_splash
);
} else {
const int off = (160 - (int)strlen(version_buf) * 14) / 2;
......
......@@ -3,27 +3,34 @@
******************************************************************************/
/***** Includes *****/
#include "pmic.h"
#include "leds.h"
#include "card10.h"
#include "leds.h"
#include "pmic.h"
#include "gfx.h"
#include "display.h"
#include "gfx.h"
#include "tmr_utils.h"
#include <stdio.h>
#include <Heart.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <Heart.h>
int main(void)
{
card10_init();
card10_diag();
gfx_copy_region_raw(
&display_screen, 0, 0, 160, 80, 2, (const void *)(Heart)
gfx_copy_region(
&display_screen,
0,
0,
160,
80,
GFX_RAW,
sizeof(Heart),
(const void *)(Heart)
);
gfx_update(&display_screen);
......
......@@ -30,8 +30,15 @@ int main(void)
card10_init();
card10_diag();
gfx_copy_region_raw(
&display_screen, 0, 0, 160, 80, 2, (const void *)(Heart)
gfx_copy_region(
&display_screen,
0,
0,
160,
80,
GFX_RAW,
sizeof(Heart),
(const void *)(Heart)
);
gfx_update(&display_screen);
......
......@@ -37,22 +37,24 @@ int main(void)
gfx_line(&display_screen, 100, 10, 70, 40, 2, yellow);
gfx_circle(&display_screen, 85, 25, 22, 2, green);
gfx_copy_region_raw(
gfx_copy_region(
&display_screen,
120,
0,
40,
40,
2,
GFX_RAW,
40 * 40 * 2,
(const void *)(gImage_40X40)
);
gfx_copy_region_raw(
gfx_copy_region(
&display_screen,
0,
0,
160,
80,
2,
GFX_RAW,
160 * 80 * 2,
(const void *)(gImage_160X80)
);
gfx_update(&display_screen);
......
......@@ -273,15 +273,17 @@ Color gfx_color(struct gfx_region *reg, enum gfx_color color)
return gfx_color_rgb(reg, c->r, c->g, c->b);
}
void gfx_copy_region_raw(
static void gfx_copy_region_raw(
struct gfx_region *reg,
int x,
int y,
int w,
int h,
size_t bpp,
size_t size,
const void *p
) {
size_t bpp = size / (w * h);
for (int y_ = 0; y_ < h; y_++) {
for (int x_ = 0; x_ < w; x_++) {
Color c;
......@@ -299,6 +301,96 @@ void gfx_copy_region_raw(
}
}
static void gfx_copy_region_mono(
struct gfx_region *reg,
int x,
int y,
int w,
int h,
size_t size,
const void *p
) {
const char *bp = p;
int bit = 0;
Color white = gfx_color(reg, WHITE);
Color black = gfx_color(reg, BLACK);
for (int y_ = 0; y_ < h; y_++) {
for (int x_ = 0; x_ < w; x_++) {
int value = *bp & (1 << bit);
if (++bit >= 8) {
bp++;
bit %= 8;
if ((const void *)(bp) >= (p + size))
return;
}
Color c = value ? white : black;
gfx_setpixel(reg, x + x_, y + y_, c);
}
}
}
/*
* "Decompress" the image. The algorithm works as follows:
*
* Each byte encodes up to 127 pixels in either white or black. The most
* significant bit determines the color, the remaining 7 bits determine the
* amount.
*/
static void gfx_copy_region_rle_mono(
struct gfx_region *reg,
int x,
int y,
int w,
int h,
size_t size,
const void *p
) {
const char *data = p;
int idx = 0;
Color white = gfx_color(reg, WHITE);
Color black = gfx_color(reg, BLACK);
for (int i = 0; i < size; i++) {
Color color = (data[i] & 0x80) ? white : black;
uint8_t length = data[i] & 0x7f;
for (int j = 0; j < length; j++) {
uint16_t x = idx % w;
uint16_t y = idx / w;
gfx_setpixel(reg, x, y, color);
idx++;
}
}
}
void gfx_copy_region(
struct gfx_region *reg,
int x,
int y,
int w,
int h,
enum gfx_encoding encoding,
size_t size,
const void *p
) {
switch (encoding) {
case GFX_RAW:
gfx_copy_region_raw(reg, x, y, w, h, size, p);
break;
case GFX_MONO:
gfx_copy_region_mono(reg, x, y, w, h, size, p);
break;
case GFX_RLE_MONO:
gfx_copy_region_rle_mono(reg, x, y, w, h, size, p);
break;
default:
break;
}
}
void gfx_copy_raw(struct gfx_region *reg, const void *p, size_t size)
{
fb_copy_raw(reg->fb, p, size);
......
......@@ -43,6 +43,12 @@ enum gfx_color {
COLORS
};
enum gfx_encoding {
GFX_RAW,
GFX_MONO,
GFX_RLE_MONO
};
struct gfx_color_rgb {
uint8_t r;
uint8_t g;
......@@ -51,8 +57,9 @@ struct gfx_color_rgb {
Color gfx_color(struct gfx_region *reg, enum gfx_color color);
void gfx_copy_region_raw(struct gfx_region *reg, int x, int y, int w, int h,
size_t bpp, const void *p);
void gfx_copy_region(struct gfx_region *reg, int x, int y, int w, int h,
enum gfx_encoding encoding, size_t size,
const void *p);
void gfx_copy_raw(struct gfx_region *reg, const void *p, size_t size);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment