From 88f662842340c6b9082b4ea9ea99bf24aefd2da7 Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Mon, 19 Dec 2022 21:12:07 -0500 Subject: consolidate bmp_read function between icons and skin_parser uses fd now rather than opening file twice Change-Id: If35418cbc77adacf5e96fb6aa0fc8ffef2fffcbd --- apps/gui/icon.c | 48 +++++------------------ apps/gui/skin_engine/skin_parser.c | 79 +++++++++++++++----------------------- apps/misc.c | 69 ++++++++++++++++++++++++++++++++- apps/misc.h | 11 ++++++ 4 files changed, 119 insertions(+), 88 deletions(-) diff --git a/apps/gui/icon.c b/apps/gui/icon.c index 9deb1a0c65..7a59a72151 100644 --- a/apps/gui/icon.c +++ b/apps/gui/icon.c @@ -167,57 +167,27 @@ static int buflib_move_callback(int handle, void* current, void* new) } return BUFLIB_CB_OK; } -static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL}; static void load_icons(const char* filename, enum Iconset iconset, enum screen_type screen) { - ssize_t size_read; - ssize_t buf_size; - int fd; - int bmpformat = (FORMAT_ANY|FORMAT_DITHER|FORMAT_TRANSPARENT); + static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL}; + const int bmpformat = (FORMAT_ANY|FORMAT_DITHER|FORMAT_TRANSPARENT); struct iconset *ic = &iconsets[iconset][screen]; + ssize_t buf_reqd; ic->loaded = false; - ic->handle = 0; + ic->handle = CLB_ALOC_ERR; if (filename[0] && filename[0] != '-') { char fname[MAX_PATH]; - fd = open_pathfmt(fname, sizeof(fname), O_RDONLY, - ICON_DIR "/%s.bmp", filename); - if (fd < 0) - return; - buf_size = read_bmp_fd(fd, &ic->bmp, 0, - bmpformat|FORMAT_RETURN_SIZE, NULL); - if (buf_size > 0) - ic->handle = core_alloc_ex(filename, (size_t) buf_size, &buflib_ops); - - if (ic->handle <= 0) - { - /* error */ - goto finished; - } - lseek(fd, 0, SEEK_SET); - core_pin(ic->handle); - ic->bmp.data = core_get_data(ic->handle); - size_read = read_bmp_fd(fd, &ic->bmp, buf_size, bmpformat, NULL); - core_unpin(ic->handle); - - if (size_read < 0) + snprintf(fname, sizeof(fname), ICON_DIR "/%s.bmp", filename); + ic->handle = core_load_bmp(fname, &ic->bmp, bmpformat, &buf_reqd, &buflib_ops); + if (ic->handle != CLB_ALOC_ERR) { - /* error */ - size_read = 0; - } - /* free unused alpha channel, if any */ - core_shrink(ic->handle, ic->bmp.data, size_read); - - if (size_read == 0) - ic->handle = core_free(ic->handle); - else + ic->bmp.data = core_get_data(ic->handle); ic->loaded = true; -finished: - close(fd); - return; + } } } diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index ad5fa48756..9495e34f5b 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -1908,77 +1908,60 @@ static int buflib_move_callback(int handle, void* current, void* new) return BUFLIB_CB_OK; } -static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL}; #endif static int load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* bmpdir) { + static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL}; (void)wps_data; /* only needed for remote targets */ char img_path[MAX_PATH]; - int fd; - int handle; + get_image_filename(bitmap->data, bmpdir, img_path, sizeof(img_path)); - /* load the image */ - int format; -#ifdef HAVE_REMOTE_LCD - if (curr_screen == SCREEN_REMOTE) - format = FORMAT_ANY|FORMAT_REMOTE; - else -#endif - format = FORMAT_ANY|FORMAT_TRANSPARENT; - - fd = open(img_path, O_RDONLY); +#ifdef __PCTOOL__ /* just check if image exists */ + int fd = open(img_path, O_RDONLY); if (fd < 0) { DEBUGF("Couldn't open %s\n", img_path); return fd; } -#ifndef __PCTOOL__ - int buf_size = read_bmp_fd(fd, bitmap, 0, - format|FORMAT_RETURN_SIZE, NULL); - if(buf_size < 0) - { - close(fd); - return buf_size; - } + close(fd); + return 1; +#else /* load the image */ + int handle; + int bmpformat; + ssize_t buf_reqd; +#ifdef HAVE_REMOTE_LCD + if (curr_screen == SCREEN_REMOTE) + bmpformat = FORMAT_ANY|FORMAT_REMOTE; + else +#endif + bmpformat = FORMAT_ANY|FORMAT_TRANSPARENT; - handle = core_alloc_ex(bitmap->data, buf_size, &buflib_ops); - if (handle <= 0) + handle = core_load_bmp(img_path, bitmap, bmpformat, &buf_reqd, &buflib_ops); + if (handle != CLB_ALOC_ERR) { - DEBUGF("Not enough skin buffer: need %zd more.\n", - buf_size - skin_buffer_freespace()); - close(fd); + /* NOTE!: bitmap->data == NULL to force a crash later if the + caller doesnt call core_get_data() */ + _stats->buflib_handles++; + _stats->images_size += buf_reqd; return handle; } - _stats->buflib_handles++; - _stats->images_size += buf_size; - lseek(fd, 0, SEEK_SET); - core_pin(handle); - bitmap->data = core_get_data(handle); - int ret = read_bmp_fd(fd, bitmap, buf_size, format, NULL); - bitmap->data = NULL; /* do this to force a crash later if the - caller doesnt call core_get_data() */ - core_unpin(handle); - close(fd); - if (ret > 0) + + if (buf_reqd == CLB_READ_ERR) { - /* free unused alpha channel, if any */ - core_shrink(handle, core_get_data(handle), ret); - return handle; + /* Abort if we can't load an image */ + DEBUGF("Couldn't load '%s' (%ld)\n", img_path, buf_reqd); } else { - /* Abort if we can't load an image */ - DEBUGF("Couldn't load '%s'\n", img_path); - core_free(handle); - return -1; + DEBUGF("Not enough skin buffer: need %zd more.\n", + buf_reqd - skin_buffer_freespace()); } -#else /* !__PCTOOL__ */ - close(fd); - return 1; -#endif + + return -1; +#endif/* !__PCTOOL__ */ } static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir) diff --git a/apps/misc.c b/apps/misc.c index f878bad833..36f45d46e0 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -99,6 +99,10 @@ #endif #endif +#ifndef PLUGIN +#include "core_alloc.h" /*core_load_bmp()*/ +#endif + #ifdef HAVE_HARDWARE_CLICK #include "piezo.h" #endif @@ -1572,4 +1576,67 @@ enum current_activity get_current_activity(void) return current_activity[current_activity_top?current_activity_top-1:0]; } -#endif +/* core_load_bmp opens bitmp filename and allocates space for it +* you must set bm->data with the result from core_get_data(handle) +* you must also call core_free(handle) when finished with the bitmap +* returns handle, ALOC_ERR(0) on failure +* ** Extended error info truth table ** +* [ Handle ][buf_reqd] +* [ > 0 ][ > 0 ] buf_reqd indicates how many bytes were used +* [ALOC_ERR][ > 0 ] buf_reqd indicates how many bytes are needed +* [ALOC_ERR][READ_ERR] there was an error reading the file or it is empty +*/ +int core_load_bmp(const char * filename, struct bitmap *bm, const int bmformat, + ssize_t *buf_reqd, struct buflib_callbacks *ops) +{ + ssize_t buf_size; + ssize_t size_read = 0; + int handle = CLB_ALOC_ERR; + + int fd = open(filename, O_RDONLY); + *buf_reqd = CLB_READ_ERR; + + if (fd < 0) /* Exit if file opening failed */ + { + DEBUGF("read_bmp_file: can't open '%s', rc: %d\n", filename, fd); + return CLB_ALOC_ERR; + } + + buf_size = read_bmp_fd(fd, bm, 0, bmformat|FORMAT_RETURN_SIZE, NULL); + + if (buf_size > 0) + { + + handle = core_alloc_ex(filename, (size_t) buf_size, ops); + + if (handle > 0) + { + core_pin(handle); + bm->data = core_get_data(handle); + lseek(fd, 0, SEEK_SET); /* reset to beginning of file */ + size_read = read_bmp_fd(fd, bm, buf_size, bmformat, NULL); + + if (size_read > 0) /* free unused alpha channel, if any */ + { + core_shrink(handle, bm->data, size_read); + *buf_reqd = size_read; + } + bm->data = NULL; /* do this to force a crash later if the + caller doesnt call core_get_data() */ + core_unpin(handle); + } + else + *buf_reqd = buf_size; /* couldn't allocate pass bytes needed */ + + if (size_read <= 0) + { + /* error reading file */ + core_free(handle); /* core_free() ignores free handles (<= 0) */ + handle = CLB_ALOC_ERR; + } + } + + close(fd); + return handle; +} +#endif /* ndef __PCTOOL__ */ diff --git a/apps/misc.h b/apps/misc.h index e2e856f212..df2c649b0e 100644 --- a/apps/misc.h +++ b/apps/misc.h @@ -222,4 +222,15 @@ enum current_activity get_current_activity(void); /* format a sound value like: -1.05 dB */ int format_sound_value(char *buf, size_t len, int snd, int val); +#ifndef PLUGIN +enum core_load_bmp_error +{ + CLB_ALOC_ERR = 0, + CLB_READ_ERR = -1, +}; +struct buflib_callbacks; +int core_load_bmp(const char *filename, struct bitmap *bm, const int bmformat, + ssize_t *buf_reqd, struct buflib_callbacks *ops); +#endif + #endif /* MISC_H */ -- cgit v1.2.3