From 8419a8a8e2bdc01aa37e475d3a83a2a4a9a4bdf8 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Sat, 28 Nov 2015 00:07:50 +0000 Subject: Load still images in the background --- src/loader.c | 50 ++++++++++++++++++++++++++++++++++++++-------- src/loader.h | 2 +- src/main.c | 61 +++++++++++++++++++++------------------------------------ src/navigator.c | 6 ------ src/texture.c | 3 +-- 5 files changed, 66 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/loader.c b/src/loader.c index 6c071c2..34641f1 100644 --- a/src/loader.c +++ b/src/loader.c @@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "texture.h" #include #include +#include void imv_init_loader(struct imv_loader *ldr) { @@ -59,19 +60,16 @@ static void *imv_loader_bg_next_frame(void *data); void imv_loader_load_path(struct imv_loader *ldr, const char *path) { - pthread_mutex_lock(&ldr->lock); - /* cancel existing thread if already running */ if(ldr->bg_thread) { - /* TODO - change to signal */ - pthread_cancel(ldr->bg_thread); + pthread_kill(ldr->bg_thread, SIGUSR1); + pthread_join(ldr->bg_thread, NULL); } /* kick off a new thread to load the image */ + /* no need to lock as we're the only thread at this point */ ldr->path = strdup(path); pthread_create(&ldr->bg_thread, NULL, &imv_loader_bg_new_img, ldr); - - pthread_mutex_unlock(&ldr->lock); } FIBITMAP *imv_loader_get_image(struct imv_loader *ldr) @@ -102,7 +100,7 @@ char *imv_loader_get_error(struct imv_loader *ldr) return err; } -void imv_loader_next_frame(struct imv_loader *ldr) +void imv_loader_load_next_frame(struct imv_loader *ldr) { pthread_mutex_lock(&ldr->lock); /* TODO */ @@ -126,8 +124,26 @@ void imv_loader_error_occurred(struct imv_loader *ldr) pthread_mutex_unlock(&ldr->lock); } +static void setup_thread_cancellation() +{ + sigset_t sigmask; + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGUSR1); + /* block USR1 delivery so we can poll for it */ + sigprocmask(SIG_SETMASK, &sigmask, NULL); +} + +static int is_thread_cancelled() +{ + sigset_t sigmask; + sigpending(&sigmask); + return sigismember(&sigmask, SIGUSR1); +} + static void *imv_loader_bg_new_img(void *data) { + setup_thread_cancellation(); + struct imv_loader *ldr = data; pthread_mutex_lock(&ldr->lock); @@ -142,6 +158,11 @@ static void *imv_loader_bg_new_img(void *data) return 0; } + if(is_thread_cancelled()) { + free(path); + return 0; + } + int num_frames = 1; FIMULTIBITMAP *mbmp = NULL; FIBITMAP *bmp = NULL; @@ -158,6 +179,12 @@ static void *imv_loader_bg_new_img(void *data) imv_loader_error_occurred(ldr); return 0; } + + if(is_thread_cancelled()) { + FreeImage_CloseMultiBitmap(mbmp, 0); + return 0; + } + num_frames = FreeImage_GetPageCount(mbmp); FIBITMAP *frame = FreeImage_LockPage(mbmp, 0); @@ -172,6 +199,10 @@ static void *imv_loader_bg_new_img(void *data) imv_loader_error_occurred(ldr); return 0; } + if(is_thread_cancelled()) { + FreeImage_Unload(image); + return 0; + } width = FreeImage_GetWidth(bmp); height = FreeImage_GetHeight(bmp); bmp = FreeImage_ConvertTo32Bits(image); @@ -191,7 +222,10 @@ static void *imv_loader_bg_new_img(void *data) ldr->mbmp = mbmp; ldr->bmp = bmp; - ldr->out_bmp = bmp; + if(ldr->out_bmp) { + FreeImage_Unload(ldr->out_bmp); + } + ldr->out_bmp = FreeImage_Clone(bmp); ldr->width = width; ldr->height = height; ldr->cur_frame = 0; diff --git a/src/loader.h b/src/loader.h index 84c8b4d..625dce5 100644 --- a/src/loader.h +++ b/src/loader.h @@ -48,7 +48,7 @@ void imv_loader_load_path(struct imv_loader *ldr, const char *path); FIBITMAP *imv_loader_get_image(struct imv_loader *ldr); char *imv_loader_get_error(struct imv_loader *ldr); -/* void imv_loader_next_frame(struct imv_loader *ldr); */ +void imv_loader_load_next_frame(struct imv_loader *ldr); /* void imv_loader_time_passed(struct imv_loader *ldr, double dt); */ #endif diff --git a/src/main.c b/src/main.c index 3552a6b..78cc758 100644 --- a/src/main.c +++ b/src/main.c @@ -352,8 +352,14 @@ int main(int argc, char** argv) break; } - while(imv_navigator_has_changed(&nav)) { - const char* current_path = imv_navigator_get_current_path(&nav); + char *err_path = imv_loader_get_error(&ldr); + if(err_path) { + imv_navigator_remove_path(&nav, err_path); + free(err_path); + } + + if(imv_navigator_has_changed(&nav)) { + const char *current_path = imv_navigator_get_current_path(&nav); char title[256]; snprintf(&title[0], sizeof(title), "imv - [%i/%i] [LOADING] %s", nav.cur_path + 1, nav.num_paths, current_path); @@ -364,49 +370,26 @@ int main(int argc, char** argv) exit(1); } - if(imv_loader_load(&ldr, current_path) != 0) { - imv_navigator_remove_current_path(&nav); - } else { - snprintf(&title[0], sizeof(title), "imv - [%i/%i] [%ix%i] %s", - nav.cur_path + 1, nav.num_paths, - ldr.width, ldr.height, current_path); - imv_viewport_set_title(&view, title); - imv_viewport_scale_to_window(&view, &ldr); - - if(overlay_surf) { - free(overlay_surf); - overlay_surf = NULL; - } - if(overlay_tex) { - SDL_DestroyTexture(overlay_tex); - overlay_tex = NULL; - } + imv_loader_load_path(&ldr, current_path); + } - if(font) { - snprintf(&title[0], sizeof(title), "[%i/%i] %s", - nav.cur_path + 1, nav.num_paths, current_path); - SDL_Color w = {255,255,255,255}; - overlay_surf = TTF_RenderUTF8_Blended(font, &title[0], w); - overlay_tex = SDL_CreateTextureFromSurface(renderer, overlay_surf); - } - } + FIBITMAP *bmp = imv_loader_get_image(&ldr); + if(bmp) { + imv_texture_set_image(&tex, bmp); + FreeImage_Unload(bmp); + const char *current_path = imv_navigator_get_current_path(&nav); + char title[256]; + snprintf(&title[0], sizeof(title), "imv - [%i/%i] [%ix%i] %s", + nav.cur_path + 1, nav.num_paths, + tex.width, tex.height, current_path); + imv_viewport_set_title(&view, title); + imv_viewport_scale_to_window(&view, &tex); if(g_options.actual) { - imv_viewport_scale_to_actual(&view, &ldr); + imv_viewport_scale_to_actual(&view, &tex); } } - if(view.playing) { - double cur_time = SDL_GetTicks() / 1000.0; - double dt = cur_time - last_time; - last_time = SDL_GetTicks() / 1000.0; - imv_loader_play(&ldr, dt); - } - - if(imv_loader_has_changed(&ldr)) { - imv_texture_set_image(&tex, ldr.cur_bmp); - imv_viewport_set_redraw(&view); - } if(view.redraw) { if(g_options.solid_bg) { diff --git a/src/navigator.c b/src/navigator.c index 49a9858..290c764 100644 --- a/src/navigator.c +++ b/src/navigator.c @@ -43,14 +43,8 @@ void imv_destroy_navigator(struct imv_navigator *nav) nav->num_paths = 0; } -int imv_can_load_image(const char* path); - static void add_item(struct imv_navigator *nav, const char *path) { - if(!imv_can_load_image(path)) { - return; - } - if(nav->buf_size == nav->num_paths) { int new_buf_size = nav->buf_size * 2; char **new_paths = malloc(sizeof(char*) * new_buf_size); diff --git a/src/texture.c b/src/texture.c index aa5a4f0..5b03708 100644 --- a/src/texture.c +++ b/src/texture.c @@ -19,9 +19,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. void imv_init_texture(struct imv_texture *tex, SDL_Renderer *r) { + memset(tex, 0, sizeof(struct imv_texture)); tex->renderer = r; - tex->num_chunks = 0; - tex->chunks = NULL; SDL_RendererInfo ri; SDL_GetRendererInfo(r, &ri); -- cgit v1.2.3