Store and display image with 1BPP

Description

Hi,
I am trying to implement lvgl on a black/white screen.

What MCU/Processor/Board and compiler are you using?

TI CC1354 with TI-RTOS7 and TI Clang v4.0.1.LTS

What LVGL version are you using?

9.2.2

What do you want to achieve?

display 1BPP images stored in flash.

What have you tried so far?

I managed to display some texts using lvgl. Therefore the spi communication to the display as well as lvgl itself seem to be working. I configured LV_COLOR_DEPTH to 1. I also store the images as 1BPP top-down left-right (exactly as the image data needs to be sent to the display controller). I directly sent the image data (const uint8_t image_map) to the display controller and it will be displayed just fine.
the lv_image_dsc_t struct looks like this:
const lv_image_dsc_t StartUpScreen = {
.header.cf = LV_COLOR_FORMAT_I1,
.header.magic = LV_IMAGE_HEADER_MAGIC,
.header.w = 400,
.header.h = 300,
.data_size = 15000,
.data = StartUpScreen_map,
};

Code to reproduce

#include "gui.h"	//LV_IMG_DECLARE for all images
#include "main_tirtos.h"
#include "lvgl/lvgl.h"

#define Source_Pixel        400
#define Gate_Pixel          300
#define Picture_length      Source_Pixel/8*Gate_Pixel   // 400*300/8=15000bytes
#define GUI_BUFFER_SIZE     Picture_length + 8 //2x4 Bytes as palette

static lv_display_t * display1;
static lv_obj_t * active_screen = NULL;

static uint8_t buf1[GUI_BUFFER_SIZE], buf2[GUI_BUFFER_SIZE];    //make sure the horizontal width is 8bit aligned, since LVGL can not handle fractional width

static int GUI_getTicksMs(void)
{
    return (Clock_getTicks() * Clock_tickPeriod / 1000);
}

static void ScreenHandler(void) {
    static int i = 0;
    lv_obj_t *obj;
    int temp;
    char tmp_str[64];
	
	if (active_screen == NULL) {
		active_screen = lv_obj_create(NULL);
		obj = lv_img_create(active_screen);
		lv_img_set_src(obj, &StartUpScreen);
		obj = lv_label_create(active_screen);
		lv_obj_set_width(obj, Source_Pixel);
		lv_label_set_long_mode(obj, LV_LABEL_LONG_WRAP);     /*Break the long lines*/
		sprintf(tmp_str, "APP CC1354\n%s %s", __DATE__, __TIME__);
		lv_label_set_text(obj, tmp_str);
		lv_obj_align(obj, LV_ALIGN_BOTTOM_LEFT, 5, -5);
		lv_screen_load(active_screen);
	}
}

int guiInit(void)
{
    lv_init();

    display1 = lv_display_create(Source_Pixel, Gate_Pixel);
    lv_display_set_buffers(display1, buf1, buf2, GUI_BUFFER_SIZE, LV_DISPLAY_RENDER_MODE_FULL);
    lv_display_set_flush_cb(display1, guiFlushDisplayCB);
    lv_display_set_flush_wait_cb(display1, guiFlushDisplayReadyCB);
	
    return (0);
}

void *guiThread(void *arg0)
{
    int temp;
    int ticks;
    int ticksOld = 0;

    while(1)
    {
        ScreenHandler();
        ticks = GUI_getTicksMs();
        temp = ticks - ticksOld;
        lv_tick_inc(temp);
        ticksOld = ticks;
        temp = lv_timer_handler();
        usleep(temp*1000);	//RTOS function
    }
}

Regards,
Stefan

Was stuck on this myself, turns out 1bpp format images are still index palette encoded. So you need to prefix the image data with two palette colors, e.g.

static const uint8_t crosshatch_map[] = {
    // palette bytes
    0xFF, 0xFF, 0xFF, 0xFF, // ARGB8888 white
    0xFF, 0x00, 0x00, 0x00, // black
    0x81, // first row
    0x42,
    0x24,
    0x18,
    0x18,
    0x24,
    0x42,
    0x81  // eighth row
};

static lv_image_dsc_t crosshatch_img_dsc = {
    .header = {
        .magic = LV_IMAGE_HEADER_MAGIC,
        .cf = LV_COLOR_FORMAT_I1,
        .flags = 0,
        .w = 8,
        .h = 8,
        .stride = 1
    },
    .data_size = 8 + 8,
    .data = crosshatch_map
};