How to preload image resources from FATFS to PSRAM

Description

I have a project that will switch between a lot of relatively large images. Because the spiflash-based FATFS is used on the hardware, the loading speed is estimated to be slower, which is not very friendly to interaction. So I want to preload the picture bin file in FATFS into PSRAM.

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

Windows simulator。
ESP32S3 N16R8

What LVGL version are you using?

v8.3.0

What do you want to achieve?

preload images from fatfs

What have you tried so far?

I tried it on a windows simulator:

    FILE* f = fopen("E:\\**\\**.bin", "rb");
    if (f == NULL)
    {
        printf("can't open file\n");
        exit(1);
    }
    fseek(f, 0, SEEK_END);
    size_t fSize = ftell(f);
    fseek(f, 0, SEEK_SET);

    char* buffer = (char*)malloc(sizeof(char) * fSize);
    if (buffer == NULL)
    {
        printf("can't malloc buffer\n");
        exit(1);
    }

    size_t result = fread(buffer, 1, fSize, f);
    if (result != fSize)
    {
        printf("can't load data\n");
        exit(1);
    }

    lv_img_dsc_t* img_dsc = (lv_img_dsc_t*)buffer;
    lv_obj_t* img = lv_img_create(lv_scr_act());
    lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
    lv_img_set_src(img, img_dsc);

But the picture is not displayed. Through breakpoint debugging, I found that img_dsc->header reads the width and height of the picture correctly, but the value of img_dsc->data_size is 0, and img_dsc->data points to NULL

Code to reproduce

As shown above

Screenshot and/or video

Solved.

lv_img_dsc_t* lv_img_dsc_load_src(const char* src)
{
    lv_fs_res_t res = LV_FS_RES_OK;

    lv_fs_file_t f;
    uint32_t fSize = 0;
    res = lv_fs_open(&f, src, LV_FS_MODE_RD);
    if (res != LV_FS_RES_OK)
    {
        LV_LOG_ERROR("[Preload] (%s) FS open failed.", src);
        return NULL;
    }
    res = lv_fs_seek(&f, 0, LV_FS_SEEK_END);
    if (res != LV_FS_RES_OK)
    {
        LV_LOG_ERROR("[Preload] (%s) Seek end failed.", src);
        lv_fs_close(&f);
        return NULL;
    }
    res = lv_fs_tell(&f, &fSize);
    if (res != LV_FS_RES_OK)
    {
        LV_LOG_ERROR("[Preload] (%s) Get size failed.", src);
        lv_fs_close(&f);
        return NULL;
    }
    res = lv_fs_seek(&f, 0, LV_FS_SEEK_SET);
    if (res != LV_FS_RES_OK)
    {
        LV_LOG_ERROR("[Preload] (%s) Seek start failed.", src);
        lv_fs_close(&f);
        return NULL;
    }
    uint32_t rd = 0;
    uint8_t* buf = (uint8_t*)lv_mem_alloc(fSize);
    res = lv_fs_read(&f, buf, fSize, &rd);
    if (res != LV_FS_RES_OK || rd != fSize)
    {
        LV_LOG_ERROR("[Preload] (%s) Read failed.", src);
        lv_fs_close(&f);
        return NULL;
    }

    lv_img_dsc_t* img_dsc = (lv_img_dsc_t*)buf;
    img_dsc->data_size = lv_img_buf_get_img_size(img_dsc->header.w, img_dsc->header.h, img_dsc->header.cf);
    img_dsc->data = (uint8_t*)buf + sizeof(lv_img_header_t);

    lv_fs_close(&f);

    return img_dsc;
}