diff --git a/src/lv_draw/lv_img_decoder.c b/src/lv_draw/lv_img_decoder.c index e52a170b5..5c1144124 100644 --- a/src/lv_draw/lv_img_decoder.c +++ b/src/lv_draw/lv_img_decoder.c @@ -277,13 +277,12 @@ lv_res_t lv_img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * s } #if LV_USE_FILESYSTEM else if(src_type == LV_IMG_SRC_FILE) { - lv_fs_file_t file; - lv_fs_res_t res; + lv_fs_file_t * f; uint32_t rn; - res = lv_fs_open(&file, src, LV_FS_MODE_RD); - if(res == LV_FS_RES_OK) { - res = lv_fs_read(&file, header, sizeof(lv_img_header_t), &rn); - lv_fs_close(&file); + f = lv_fs_open(src, LV_FS_MODE_RD); + if(f) { + lv_fs_res_t res = lv_fs_read(f, header, sizeof(lv_img_header_t), &rn); + lv_fs_close(f); if(res != LV_FS_RES_OK || rn != sizeof(lv_img_header_t)) { LV_LOG_WARN("Image get info get read file header"); return LV_RES_INV; @@ -325,9 +324,8 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder /*Support only "*.bin" files*/ if(strcmp(lv_fs_get_ext(dsc->src), "bin")) return LV_RES_INV; - lv_fs_file_t f; - lv_fs_res_t res = lv_fs_open(&f, dsc->src, LV_FS_MODE_RD); - if(res != LV_FS_RES_OK) { + lv_fs_file_t * f = lv_fs_open(dsc->src, LV_FS_MODE_RD); + if(f == NULL) { LV_LOG_WARN("Built-in image decoder can't open the file"); return LV_RES_INV; } @@ -344,16 +342,7 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder } lv_img_decoder_built_in_data_t * user_data = dsc->user_data; - user_data->f = lv_mem_alloc(sizeof(f)); - LV_ASSERT_MEM(user_data->f); - if(user_data->f == NULL) { - LV_LOG_ERROR("img_decoder_built_in_open: out of memory"); - lv_img_decoder_built_in_close(decoder, dsc); - return LV_RES_INV; - } - - _lv_memcpy_small(user_data->f, &f, sizeof(f)); - + user_data->f = f; #else LV_LOG_WARN("Image built-in decoder cannot read file because LV_USE_FILESYSTEM = 0"); return LV_RES_INV; @@ -415,7 +404,7 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder if(dsc->src_type == LV_IMG_SRC_FILE) { /*Read the palette from file*/ #if LV_USE_FILESYSTEM - lv_fs_seek(user_data->f, 4); /*Skip the header*/ + lv_fs_seek(user_data->f, 4, LV_FS_SEEK_SET); /*Skip the header*/ lv_color32_t cur_color; uint32_t i; for(i = 0; i < palette_size; i++) { @@ -525,7 +514,6 @@ void lv_img_decoder_built_in_close(lv_img_decoder_t * decoder, lv_img_decoder_ds #if LV_USE_FILESYSTEM if(user_data->f) { lv_fs_close(user_data->f); - lv_mem_free(user_data->f); } #endif if(user_data->palette) lv_mem_free(user_data->palette); @@ -552,7 +540,7 @@ static lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * d uint32_t pos = ((y * dsc->header.w + x) * px_size) >> 3; pos += 4; /*Skip the header*/ - res = lv_fs_seek(user_data->f, pos); + res = lv_fs_seek(user_data->f, pos, LV_FS_SEEK_SET); if(res != LV_FS_RES_OK) { LV_LOG_WARN("Built-in image decoder seek failed"); return LV_RES_INV; @@ -654,7 +642,7 @@ static lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, l } else { #if LV_USE_FILESYSTEM - lv_fs_seek(user_data->f, ofs + 4); /*+4 to skip the header*/ + lv_fs_seek(user_data->f, ofs + 4, LV_FS_SEEK_SET); /*+4 to skip the header*/ lv_fs_read(user_data->f, fs_buf, w, NULL); data_tmp = fs_buf; #else @@ -740,7 +728,7 @@ static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc, } else { #if LV_USE_FILESYSTEM - lv_fs_seek(user_data->f, ofs + 4); /*+4 to skip the header*/ + lv_fs_seek(user_data->f, ofs + 4, LV_FS_SEEK_SET); /*+4 to skip the header*/ lv_fs_read(user_data->f, fs_buf, w, NULL); data_tmp = fs_buf; #else diff --git a/src/lv_font/lv_font_loader.c b/src/lv_font/lv_font_loader.c index 7cde8370d..8c45611ce 100644 --- a/src/lv_font/lv_font_loader.c +++ b/src/lv_font/lv_font_loader.c @@ -93,11 +93,11 @@ lv_font_t * lv_font_load(const char * font_name) lv_font_t * font = lv_mem_alloc(sizeof(lv_font_t)); memset(font, 0, sizeof(lv_font_t)); - lv_fs_file_t file; - lv_fs_res_t res = lv_fs_open(&file, font_name, LV_FS_MODE_RD); + lv_fs_file_t * file; + file = lv_fs_open(font_name, LV_FS_MODE_RD); - if(res == LV_FS_RES_OK) { - success = lvgl_load_font(&file, font); + if(file) { + success = lvgl_load_font(file, font); } if(!success) { @@ -111,7 +111,7 @@ lv_font_t * lv_font_load(const char * font_name) font = NULL; } - lv_fs_close(&file); + lv_fs_close(file); return font; } @@ -234,7 +234,7 @@ static int read_bits_signed(bit_iterator_t * it, int n_bits, lv_fs_res_t * res) static int read_label(lv_fs_file_t * fp, int start, const char * label) { - lv_fs_seek(fp, start); + lv_fs_seek(fp, start, LV_FS_SEEK_SET); uint32_t length; char buf[4]; @@ -265,7 +265,7 @@ static bool load_cmaps_tables(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_ds } for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) { - lv_fs_res_t res = lv_fs_seek(fp, cmaps_start + cmap_table[i].data_offset); + lv_fs_res_t res = lv_fs_seek(fp, cmaps_start + cmap_table[i].data_offset, LV_FS_SEEK_SET); if(res != LV_FS_RES_OK) { return false; } @@ -379,7 +379,7 @@ static int32_t load_glyph(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, for(unsigned int i = 0; i < loca_count; ++i) { lv_font_fmt_txt_glyph_dsc_t * gdsc = &glyph_dsc[i]; - lv_fs_res_t res = lv_fs_seek(fp, start + glyph_offset[i]); + lv_fs_res_t res = lv_fs_seek(fp, start + glyph_offset[i], LV_FS_SEEK_SET); if(res != LV_FS_RES_OK) { return -1; } @@ -445,7 +445,7 @@ static int32_t load_glyph(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, cur_bmp_size = 0; for(unsigned int i = 1; i < loca_count; ++i) { - lv_fs_res_t res = lv_fs_seek(fp, start + glyph_offset[i]); + lv_fs_res_t res = lv_fs_seek(fp, start + glyph_offset[i], LV_FS_SEEK_SET); if(res != LV_FS_RES_OK) { return -1; } diff --git a/src/lv_misc/lv_fs.c b/src/lv_misc/lv_fs.c index 475fcab52..fbf6e7de0 100644 --- a/src/lv_misc/lv_fs.c +++ b/src/lv_misc/lv_fs.c @@ -83,51 +83,52 @@ bool lv_fs_is_ready(char letter) * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR * @return LV_FS_RES_OK or any error from lv_fs_res_t enum */ -lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode) +void * lv_fs_open(const char * path, lv_fs_mode_t mode) { - file_p->drv = NULL; - file_p->file_d = NULL; - - if(path == NULL) return LV_FS_RES_INV_PARAM; - - char letter = path[0]; - - file_p->drv = lv_fs_get_drv(letter); - - if(file_p->drv == NULL) { - file_p->file_d = NULL; - return LV_FS_RES_NOT_EX; + if(path == NULL) { + LV_LOG_WARN("Can't open file: path is NULL"); + return NULL; } - if(file_p->drv->ready_cb != NULL) { - if(file_p->drv->ready_cb(file_p->drv) == false) { - file_p->drv = NULL; - file_p->file_d = NULL; - return LV_FS_RES_HW_ERR; + char letter = path[0]; + lv_fs_drv_t * drv = lv_fs_get_drv(letter); + + + if(drv == NULL) { + LV_LOG_WARN("Can't open file (%s): unknown driver letter", path); + return NULL; + } + + if(drv->ready_cb) { + if(drv->ready_cb(drv) == false) { + LV_LOG_WARN("Can't open file (%s): driver not ready", path); + return NULL; } } - file_p->file_d = lv_mem_alloc(file_p->drv->file_size); - LV_ASSERT_MEM(file_p->file_d); - if(file_p->file_d == NULL) { - file_p->drv = NULL; - return LV_FS_RES_OUT_OF_MEM; /* Out of memory */ + if(drv->open_cb == NULL) { + LV_LOG_WARN("Can't open file (%s): open function not exists", path); + return NULL; } - if(file_p->drv->open_cb == NULL) { - return LV_FS_RES_NOT_IMP; + lv_fs_file_t * file_p = lv_mem_alloc(sizeof(lv_fs_file_t)); + if(file_p == NULL) { + LV_LOG_WARN("Can't open file (%s): out of memory", path); + return NULL; } + file_p->drv = drv; + file_p->file_d = NULL; + const char * real_path = lv_fs_get_real_path(path); - lv_fs_res_t res = file_p->drv->open_cb(file_p->drv, file_p->file_d, real_path, mode); + file_p->file_d = drv->open_cb(drv, real_path, mode); - if(res != LV_FS_RES_OK) { - lv_mem_free(file_p->file_d); - file_p->file_d = NULL; - file_p->drv = NULL; + if(file_p->file_d == NULL || file_p->file_d == (void*)(-1)) { + lv_mem_free(file_p); + return NULL; } - return res; + return file_p; } /** @@ -147,10 +148,7 @@ lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p) lv_fs_res_t res = file_p->drv->close_cb(file_p->drv, file_p->file_d); - lv_mem_free(file_p->file_d); /*Clean up*/ - file_p->file_d = NULL; - file_p->drv = NULL; - file_p->file_d = NULL; + lv_mem_free(file_p); /*Clean up*/ return res; } @@ -234,7 +232,7 @@ lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, u * @param pos the new position expressed in bytes index (0: start of file) * @return LV_FS_RES_OK or any error from lv_fs_res_t enum */ -lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos) +lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whence) { if(file_p->drv == NULL) { return LV_FS_RES_INV_PARAM; @@ -244,7 +242,7 @@ lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos) return LV_FS_RES_NOT_IMP; } - lv_fs_res_t res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, pos); + lv_fs_res_t res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, pos, whence); return res; } diff --git a/src/lv_misc/lv_fs.h b/src/lv_misc/lv_fs.h index 5000d8c20..00eebadc1 100644 --- a/src/lv_misc/lv_fs.h +++ b/src/lv_misc/lv_fs.h @@ -52,7 +52,7 @@ enum { typedef uint8_t lv_fs_res_t; /** - * Filesystem mode. + * File open mode. */ enum { LV_FS_MODE_WR = 0x01, @@ -60,18 +60,28 @@ enum { }; typedef uint8_t lv_fs_mode_t; + +/** + * Seek modes. + */ +enum { + LV_FS_SEEK_SET = 0x00, + LV_FS_SEEK_CUR = 0x01, + LV_FS_SEEK_END = 0x02, +}; +typedef uint8_t lv_fs_whence_t; + typedef struct _lv_fs_drv_t { char letter; - uint16_t file_size; uint16_t rddir_size; bool (*ready_cb)(struct _lv_fs_drv_t * drv); - lv_fs_res_t (*open_cb)(struct _lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode); + void * (*open_cb)(struct _lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode); lv_fs_res_t (*close_cb)(struct _lv_fs_drv_t * drv, void * file_p); lv_fs_res_t (*remove_cb)(struct _lv_fs_drv_t * drv, const char * fn); lv_fs_res_t (*read_cb)(struct _lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br); lv_fs_res_t (*write_cb)(struct _lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw); - lv_fs_res_t (*seek_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t pos); + lv_fs_res_t (*seek_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence); lv_fs_res_t (*tell_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); lv_fs_res_t (*trunc_cb)(struct _lv_fs_drv_t * drv, void * file_p); lv_fs_res_t (*size_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t * size_p); @@ -143,7 +153,7 @@ bool lv_fs_is_ready(char letter); * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR * @return LV_FS_RES_OK or any error from lv_fs_res_t enum */ -lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode); +void * lv_fs_open(const char * path, lv_fs_mode_t mode); /** * Close an already opened file @@ -185,7 +195,7 @@ lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, u * @param pos the new position expressed in bytes index (0: start of file) * @return LV_FS_RES_OK or any error from lv_fs_res_t enum */ -lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos); +lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whence); /** * Give the position of the read write pointer diff --git a/tests/lv_test_core/lv_test_font_loader.c b/tests/lv_test_core/lv_test_font_loader.c index 56a42c2d8..6cb64866a 100644 --- a/tests/lv_test_core/lv_test_font_loader.c +++ b/tests/lv_test_core/lv_test_font_loader.c @@ -51,9 +51,9 @@ extern lv_font_t font_3; void lv_test_font_loader(void) { #if LV_USE_FILESYSTEM - lv_font_t * font_1_bin = lv_font_load("f:font_1.fnt"); - lv_font_t * font_2_bin = lv_font_load("f:font_2.fnt"); - lv_font_t * font_3_bin = lv_font_load("f:font_3.fnt"); + lv_font_t * font_1_bin = lv_font_load("F:font_1.fnt"); + lv_font_t * font_2_bin = lv_font_load("F:font_2.fnt"); + lv_font_t * font_3_bin = lv_font_load("F:font_3.fnt"); compare_fonts(&font_1, font_1_bin); compare_fonts(&font_2, font_2_bin); diff --git a/tests/lv_test_main.c b/tests/lv_test_main.c index f1fd224cc..beaa4685d 100644 --- a/tests/lv_test_main.c +++ b/tests/lv_test_main.c @@ -28,23 +28,21 @@ int main(void) #if LV_USE_FILESYSTEM -static lv_fs_res_t open_cb(struct _lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode) +static void * open_cb(struct _lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) { (void) drv; (void) mode; FILE * fp = fopen(path, "rb"); // only reading is supported - *((FILE **)file_p) = fp; - return NULL == fp ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; + return fp; } static lv_fs_res_t close_cb(struct _lv_fs_drv_t * drv, void * file_p) { (void) drv; - FILE * fp = *((FILE **) file_p); - fclose(fp); + fclose(file_p); return LV_FS_RES_OK; } @@ -52,17 +50,30 @@ static lv_fs_res_t read_cb(struct _lv_fs_drv_t * drv, void * file_p, void * buf, { (void) drv; - FILE * fp = *((FILE **) file_p); - *br = fread(buf, 1, btr, fp); + *br = fread(buf, 1, btr, file_p); return (*br <= 0) ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; } -static lv_fs_res_t seek_cb(struct _lv_fs_drv_t * drv, void * file_p, uint32_t pos) +static lv_fs_res_t seek_cb(struct _lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t w) { (void) drv; - FILE * fp = *((FILE **) file_p); - fseek (fp, pos, SEEK_SET); + uint32_t w2; + switch(w) { + case LV_FS_SEEK_SET: + w2 = SEEK_SET; + break; + case LV_FS_SEEK_CUR: + w2 = SEEK_CUR; + break; + case LV_FS_SEEK_END: + w2 = SEEK_END; + break; + default: + w2 = SEEK_SET; + } + + fseek (file_p, pos, w2); return LV_FS_RES_OK; } @@ -71,17 +82,11 @@ static lv_fs_res_t tell_cb(struct _lv_fs_drv_t * drv, void * file_p, uint32_t * { (void) drv; - FILE * fp = *((FILE **) file_p); - *pos_p = ftell(fp); + *pos_p = ftell(file_p); return LV_FS_RES_OK; } -static bool ready_cb(struct _lv_fs_drv_t * drv) -{ - (void) drv; - return true; -} #endif static void hal_init(void) @@ -101,9 +106,7 @@ static void hal_init(void) lv_fs_drv_t drv; lv_fs_drv_init(&drv); /*Basic initialization*/ - drv.letter = 'f'; /*An uppercase letter to identify the drive */ - drv.file_size = sizeof(FILE *); /*Size required to store a file object*/ - drv.ready_cb = ready_cb; /*Callback to tell if the drive is ready to use */ + drv.letter = 'F'; /*An uppercase letter to identify the drive */ drv.open_cb = open_cb; /*Callback to open a file */ drv.close_cb = close_cb; /*Callback to close a file */ drv.read_cb = read_cb; /*Callback to read a file */