aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHarry Jeffery <harry@exec64.co.uk>2017-06-18 16:23:19 +0100
committerHarry Jeffery <harry@exec64.co.uk>2017-06-18 16:23:19 +0100
commit12450f38753699b0e606c3ad542892752da6aca8 (patch)
tree113e09b6386ad4b69ddb00fb8e6e41fe31261320 /src
parent29888f9f042e49a9b991ca2e6e790d808a3b74e9 (diff)
downloadimv-12450f38753699b0e606c3ad542892752da6aca8.tar.gz
Support loading image data from stdin
Diffstat (limited to 'src')
-rw-r--r--src/imv.c43
-rw-r--r--src/loader.c2
-rw-r--r--src/util.c2
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 */