From 12450f38753699b0e606c3ad542892752da6aca8 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Sun, 18 Jun 2017 16:23:19 +0100 Subject: Support loading image data from stdin --- src/imv.c | 43 +++++++++++++++++++++++++++++++++---------- src/loader.c | 2 ++ src/util.c | 2 +- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/imv.c b/src/imv.c index 656b3a5..368973b 100644 --- a/src/imv.c +++ b/src/imv.c @@ -75,6 +75,8 @@ struct imv { struct imv_commands *commands; struct imv_texture *texture; struct imv_viewport *view; + void *stdin_image_data; + size_t stdin_image_data_len; char *input_buffer; char *starting_path; struct pollfd stdin_fd; @@ -121,6 +123,8 @@ struct imv *imv_create(void) imv->navigator = imv_navigator_create(); imv->loader = imv_loader_create(); imv->commands = imv_commands_create(); + imv->stdin_image_data = NULL; + imv->stdin_image_data_len = 0; imv->input_buffer = NULL; imv->starting_path = NULL; imv->window = NULL; @@ -154,6 +158,9 @@ void imv_free(struct imv *imv) imv_navigator_free(imv->navigator); imv_loader_free(imv->loader); imv_commands_free(imv->commands); + if(imv->stdin_image_data) { + free(imv->stdin_image_data); + } if(imv->input_buffer) { free(imv->input_buffer); } @@ -265,7 +272,23 @@ bool imv_parse_args(struct imv *imv, int argc, char **argv) imv->paths_from_stdin = true; } else { /* otherwise, add the paths */ + bool data_from_stdin = false; for(int i = 0; i < argc; ++i) { + + /* Special case: '-' denotes reading image data from stdin */ + if(!strcmp("-", argv[i])) { + if(imv->paths_from_stdin) { + fprintf(stderr, "Can't read paths AND image data from stdin. Aborting.\n"); + return false; + } else if(data_from_stdin) { + fprintf(stderr, "Can't read image data from stdin twice. Aborting.\n"); + return false; + } + data_from_stdin = true; + + imv->stdin_image_data_len = read_from_stdin(&imv->stdin_image_data); + } + imv_add_path(imv, argv[i]); } } @@ -366,15 +389,14 @@ bool imv_run(struct imv *imv) imv_navigator_remove(imv->navigator, err_path); /* special case: the image came from stdin */ - /* if (strncmp(err_path, "-", 2) == 0) { */ - /* free(stdin_buffer); */ - /* stdin_buffer_size = 0; */ - /* if (stdin_error != 0) { */ - /* errno = stdin_error; */ - /* perror("Failed to load image from standard input"); */ - /* errno = 0; */ - /* } */ - /* } */ + if(strncmp(err_path, "-", 2) == 0) { + if(imv->stdin_image_data) { + free(imv->stdin_image_data); + imv->stdin_image_data = NULL; + imv->stdin_image_data_len = 0; + } + fprintf(stderr, "Failed to load image from stdin.\n"); + } free(err_path); } @@ -400,7 +422,8 @@ bool imv_run(struct imv *imv) scaling_label[imv->scaling_mode]); imv_viewport_set_title(imv->view, title); - imv_loader_load(imv->loader, current_path, "", 0 /*stdin_buffer, stdin_buffer_size*/); + imv_loader_load(imv->loader, current_path, + imv->stdin_image_data, imv->stdin_image_data_len); imv->view->playing = true; } diff --git a/src/loader.c b/src/loader.c index e85050b..b21b140 100644 --- a/src/loader.c +++ b/src/loader.c @@ -98,6 +98,7 @@ void imv_loader_load(struct imv_loader *ldr, const char *path, ldr->buffer_size = buffer_size; } else if (ldr->fi_buffer != NULL) { FreeImage_CloseMemory(ldr->fi_buffer); + ldr->fi_buffer = NULL; } pthread_create(&ldr->bg_thread, NULL, &bg_new_img, ldr); pthread_mutex_unlock(&ldr->lock); @@ -191,6 +192,7 @@ static void *bg_new_img(void *data) if (from_stdin) { pthread_mutex_lock(&ldr->lock); FreeImage_CloseMemory(ldr->fi_buffer); + ldr->fi_buffer = NULL; pthread_mutex_unlock(&ldr->lock); } error_occurred(ldr); diff --git a/src/util.c b/src/util.c index 9b2b867..71d4c14 100644 --- a/src/util.c +++ b/src/util.c @@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. size_t read_from_stdin(void **buffer) { size_t len = 0; ssize_t r; - size_t step = 1024; /* Arbitrary value of 1 KiB */ + size_t step = 4096; /* Arbitrary value of 4 KiB */ void *p; errno = 0; /* clear errno */ -- cgit v1.2.3