consolidate bmp_read function between icons and skin_parser

uses fd now rather than opening file twice

Change-Id: If35418cbc77adacf5e96fb6aa0fc8ffef2fffcbd
This commit is contained in:
William Wilgus 2022-12-19 21:12:07 -05:00
parent 2b4a4070c9
commit 88f6628423
4 changed files with 120 additions and 89 deletions

View file

@ -167,57 +167,27 @@ static int buflib_move_callback(int handle, void* current, void* new)
} }
return BUFLIB_CB_OK; 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, static void load_icons(const char* filename, enum Iconset iconset,
enum screen_type screen) enum screen_type screen)
{ {
ssize_t size_read; static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL};
ssize_t buf_size; const int bmpformat = (FORMAT_ANY|FORMAT_DITHER|FORMAT_TRANSPARENT);
int fd;
int bmpformat = (FORMAT_ANY|FORMAT_DITHER|FORMAT_TRANSPARENT);
struct iconset *ic = &iconsets[iconset][screen]; struct iconset *ic = &iconsets[iconset][screen];
ssize_t buf_reqd;
ic->loaded = false; ic->loaded = false;
ic->handle = 0; ic->handle = CLB_ALOC_ERR;
if (filename[0] && filename[0] != '-') if (filename[0] && filename[0] != '-')
{ {
char fname[MAX_PATH]; char fname[MAX_PATH];
fd = open_pathfmt(fname, sizeof(fname), O_RDONLY, snprintf(fname, sizeof(fname), ICON_DIR "/%s.bmp", filename);
ICON_DIR "/%s.bmp", filename); ic->handle = core_load_bmp(fname, &ic->bmp, bmpformat, &buf_reqd, &buflib_ops);
if (fd < 0) if (ic->handle != CLB_ALOC_ERR)
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); 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)
{
/* 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->loaded = true; ic->loaded = true;
finished: }
close(fd);
return;
} }
} }

View file

@ -1908,77 +1908,60 @@ static int buflib_move_callback(int handle, void* current, void* new)
return BUFLIB_CB_OK; return BUFLIB_CB_OK;
} }
static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL};
#endif #endif
static int load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* bmpdir) 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 */ (void)wps_data; /* only needed for remote targets */
char img_path[MAX_PATH]; char img_path[MAX_PATH];
int fd;
int handle;
get_image_filename(bitmap->data, bmpdir, get_image_filename(bitmap->data, bmpdir,
img_path, sizeof(img_path)); img_path, sizeof(img_path));
/* load the image */ #ifdef __PCTOOL__ /* just check if image exists */
int format; int fd = open(img_path, O_RDONLY);
#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);
if (fd < 0) if (fd < 0)
{ {
DEBUGF("Couldn't open %s\n", img_path); DEBUGF("Couldn't open %s\n", img_path);
return fd; return fd;
} }
#ifndef __PCTOOL__
int buf_size = read_bmp_fd(fd, bitmap, 0,
format|FORMAT_RETURN_SIZE, NULL);
if(buf_size < 0)
{
close(fd); close(fd);
return buf_size; 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_load_bmp(img_path, bitmap, bmpformat, &buf_reqd, &buflib_ops);
if (handle != CLB_ALOC_ERR)
{
/* 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;
} }
handle = core_alloc_ex(bitmap->data, buf_size, &buflib_ops); if (buf_reqd == CLB_READ_ERR)
if (handle <= 0)
{ {
DEBUGF("Not enough skin buffer: need %zd more.\n", /* Abort if we can't load an image */
buf_size - skin_buffer_freespace()); DEBUGF("Couldn't load '%s' (%ld)\n", img_path, buf_reqd);
close(fd);
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)
{
/* free unused alpha channel, if any */
core_shrink(handle, core_get_data(handle), ret);
return handle;
} }
else else
{ {
/* Abort if we can't load an image */ DEBUGF("Not enough skin buffer: need %zd more.\n",
DEBUGF("Couldn't load '%s'\n", img_path); buf_reqd - skin_buffer_freespace());
core_free(handle);
return -1;
} }
#else /* !__PCTOOL__ */
close(fd); return -1;
return 1; #endif/* !__PCTOOL__ */
#endif
} }
static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir) static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)

View file

@ -99,6 +99,10 @@
#endif #endif
#endif #endif
#ifndef PLUGIN
#include "core_alloc.h" /*core_load_bmp()*/
#endif
#ifdef HAVE_HARDWARE_CLICK #ifdef HAVE_HARDWARE_CLICK
#include "piezo.h" #include "piezo.h"
#endif #endif
@ -1572,4 +1576,67 @@ enum current_activity get_current_activity(void)
return current_activity[current_activity_top?current_activity_top-1:0]; 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__ */

View file

@ -222,4 +222,15 @@ enum current_activity get_current_activity(void);
/* format a sound value like: -1.05 dB */ /* format a sound value like: -1.05 dB */
int format_sound_value(char *buf, size_t len, int snd, int val); 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 */ #endif /* MISC_H */