aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHarry Jeffery <harry@exec64.co.uk>2015-11-28 00:07:50 +0000
committerHarry Jeffery <harry@exec64.co.uk>2015-11-28 00:07:50 +0000
commit8419a8a8e2bdc01aa37e475d3a83a2a4a9a4bdf8 (patch)
tree2f54eb1cba42869d364aa94153f1c29385c5c34a /src
parent548677824437a1338fdd253b1d978fec6c7fbd4e (diff)
downloadimv-8419a8a8e2bdc01aa37e475d3a83a2a4a9a4bdf8.tar.gz
Load still images in the background
Diffstat (limited to 'src')
-rw-r--r--src/loader.c50
-rw-r--r--src/loader.h2
-rw-r--r--src/main.c61
-rw-r--r--src/navigator.c6
-rw-r--r--src/texture.c3
5 files changed, 66 insertions, 56 deletions
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 <stdlib.h>
#include <pthread.h>
+#include <signal.h>
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);